ULONG GPHandler(PEXCEPTIONREPORTRECORD pX) { ULONG ulAttribs; /* Memory attributes */ ULONG ulSize; /* Range in pages */ if (pX->ExceptionNum == /* If guard page exception */ XCPT_GUARD_PAGE_VIOLATION) { ulSize=1L; /* One page */ DosQueryMem( /* Query memory attributes */ (PVOID)pX->ExceptionInfo[1], /* Page base address */ &ulSize, /* Single page */ &ulAttribs); /* Memory attributes */ if (((ulAttrs & PAG_FREE) || /* If page is available */ (ulAttrs & PAG_COMMIT))==0) /* but is not committed */ { DosSetMem( /* Commit page */ (PVOID)pX->ExceptionInfo[1], /* Page base address */ 1L, /* Single page only */ PAG_DEFAULT | /* Default attributes */ PAG_COMMIT); /* Set commit flag */ return(XCPT_CONTINUE_EXECUTION); /* Done */ } } if (pX->ExceptionNum == /* If access violation */ XCPT_ACCESS_VIOLATION) { if (pX->ExceptionInfo[1]) /* If page address not NULL */ { ulSize=1L; /* One page */ DosQueryMem( /* Query memory attributes */ (PVOID)pX->ExceptionInfo[1], /* Page base address */ &ulSize, /* Single page */ &ulAttribs); /* Memory attributes */ if (((ulAttrs & PAG_FREE) || /* If page is available */ (ulAttrs & PAG_COMMIT))==0) /* but is not committed */ { DosSetMem( /* Commit page */ (PVOID)pX->ExceptionInfo[1], /* Page base address */ 1L, /* Single page only */ PAG_DEFAULT | /* Default attributes */ PAG_COMMIT); /* Set commit flag */ return(XCPT_CONTINUE_EXECUTION); /* Done */ } } } return(XCPT_CONTINUE_SEARCH); /* Chain to next handler if */ } /* any other exception */
This exception handler also handles the situation where an application writes directly to an uncommitted page rather than to the guard page, as is possible with non-sequential write operations.