You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
810 lines
22 KiB
810 lines
22 KiB
/******************************Module*Header*******************************\
|
|
* Module Name: verifier.cxx
|
|
*
|
|
* GRE DriverVerifier support.
|
|
*
|
|
* If DriverVerifier is enabled for a particular component, the loader will
|
|
* substitute VerifierEngAllocMem for EngAllocMem, etc. The VerifierEngXX
|
|
* functions will help test the robustness of components that use EngXX calls
|
|
* by injecting random failures and using special pool (i.e., test low-mem
|
|
* behavior and check for buffer overruns).
|
|
*
|
|
* See ntos\mm\verifier.c for further details on DriverVerifier support in
|
|
* the memory manager.
|
|
*
|
|
* See sdk\inc\ntexapi.h for details on the DriverVerifier flags.
|
|
*
|
|
* Created: 19-Jan-1999 11:51:51
|
|
* Author: Gilman Wong [gilmanw]
|
|
*
|
|
* Copyright (c) 1999 Microsoft Corporation
|
|
*
|
|
\**************************************************************************/
|
|
|
|
#include "precomp.hxx"
|
|
#include "muclean.hxx"
|
|
#include "verifier.hxx"
|
|
|
|
extern BOOL G_fConsole; // gre\misc.cxx
|
|
|
|
//
|
|
// Amount of elapsed time before we begin random failures.
|
|
// Gives system time to stabilize.
|
|
//
|
|
// Taken from ntos\mm\verifier.c
|
|
//
|
|
|
|
LARGE_INTEGER GreBootTime;
|
|
const LARGE_INTEGER VerifierRequiredTimeSinceBoot = {(ULONG)(40 * 1000 * 1000 * 10), 1};
|
|
|
|
//
|
|
// Global verifier state.
|
|
//
|
|
|
|
VSTATE gvs = {
|
|
0, // fl
|
|
FALSE, // bSystemStable
|
|
0, // ulRandomSeed
|
|
0xf, // ulFailureMask
|
|
0, // ulDebugLevel
|
|
(HSEMAPHORE) NULL // hsemPoolTracker
|
|
};
|
|
|
|
//
|
|
// Put initialization functions in the INIT segment.
|
|
//
|
|
|
|
#pragma alloc_text(INIT, VerifierInitialization)
|
|
|
|
|
|
/******************************Public*Routine******************************\
|
|
* VerifierInitialization
|
|
*
|
|
* Initializes the DriverVerifier support in GRE. The loader will actually
|
|
* handle the fixup of the EngAllocMem, etc. during the loading of components
|
|
* listed as under the verifier.
|
|
*
|
|
* History:
|
|
* 19-Jan-1999 -by- Gilman Wong [gilmanw]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
#define VERIFIERFUNC(pfn) ((PDRIVER_VERIFIER_THUNK_ROUTINE)(pfn))
|
|
|
|
const DRIVER_VERIFIER_THUNK_PAIRS gaVerifierFunctionTable[] = {
|
|
{VERIFIERFUNC(EngAllocMem ), VERIFIERFUNC(VerifierEngAllocMem )},
|
|
{VERIFIERFUNC(EngFreeMem ), VERIFIERFUNC(VerifierEngFreeMem )},
|
|
{VERIFIERFUNC(EngAllocUserMem ), VERIFIERFUNC(VerifierEngAllocUserMem )},
|
|
{VERIFIERFUNC(EngFreeUserMem ), VERIFIERFUNC(VerifierEngFreeUserMem )},
|
|
{VERIFIERFUNC(EngCreateBitmap ), VERIFIERFUNC(VerifierEngCreateBitmap )},
|
|
{VERIFIERFUNC(EngCreateDeviceSurface), VERIFIERFUNC(VerifierEngCreateDeviceSurface)},
|
|
{VERIFIERFUNC(EngCreateDeviceBitmap ), VERIFIERFUNC(VerifierEngCreateDeviceBitmap )},
|
|
{VERIFIERFUNC(EngCreatePalette ), VERIFIERFUNC(VerifierEngCreatePalette )},
|
|
{VERIFIERFUNC(EngCreateClip ), VERIFIERFUNC(VerifierEngCreateClip )},
|
|
{VERIFIERFUNC(EngCreatePath ), VERIFIERFUNC(VerifierEngCreatePath )},
|
|
{VERIFIERFUNC(EngCreateWnd ), VERIFIERFUNC(VerifierEngCreateWnd )},
|
|
{VERIFIERFUNC(EngCreateDriverObj ), VERIFIERFUNC(VerifierEngCreateDriverObj )},
|
|
{VERIFIERFUNC(BRUSHOBJ_pvAllocRbrush), VERIFIERFUNC(VerifierBRUSHOBJ_pvAllocRbrush)},
|
|
{VERIFIERFUNC(CLIPOBJ_ppoGetPath ), VERIFIERFUNC(VerifierCLIPOBJ_ppoGetPath )}
|
|
};
|
|
|
|
BOOL
|
|
VerifierInitialization()
|
|
{
|
|
BOOL bRet = FALSE;
|
|
NTSTATUS Status;
|
|
ULONG Level;
|
|
|
|
#ifdef VERIFIER_STATISTICS
|
|
//
|
|
// Clear statistics.
|
|
//
|
|
|
|
RtlZeroMemory((VOID *) gvs.avs, sizeof(VSTATS) * VERIFIER_INDEX_LAST);
|
|
|
|
#endif
|
|
|
|
//
|
|
// Get the DriverVerifier flags. No point in going on if we can't
|
|
// get this.
|
|
//
|
|
|
|
Status = MmIsVerifierEnabled (&Level);
|
|
|
|
if ((NT_SUCCESS(Status) || (Status == STATUS_INFO_LENGTH_MISMATCH)) &&
|
|
(Level & DRIVER_VERIFIER_GRE_MASK))
|
|
{
|
|
//
|
|
// Some things should only be done once, during system initalization.
|
|
// So don't do them for Hydra sessions.
|
|
//
|
|
|
|
if (G_fConsole)
|
|
{
|
|
//
|
|
// Remember the boot time. We do not allow random failures for
|
|
// a period time right after boot to allow the system time to
|
|
// become quiescent.
|
|
//
|
|
|
|
KeQuerySystemTime(&GreBootTime);
|
|
|
|
//
|
|
// Give loader Verifier function substitution table.
|
|
//
|
|
|
|
Status = MmAddVerifierThunks ((VOID *) gaVerifierFunctionTable,
|
|
sizeof(gaVerifierFunctionTable));
|
|
|
|
if (NT_SUCCESS(Status))
|
|
{
|
|
VERIFIERWARNING(1, "VerifierInitialization: thunks accepted\n");
|
|
bRet = TRUE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//
|
|
// On Hydra systems, allow failures during GRE initialization.
|
|
// So disable the check that allows the system time to stabilize.
|
|
//
|
|
|
|
gvs.bSystemStable = TRUE;
|
|
Level &= ~DRIVER_VERIFIER_TRACK_POOL_ALLOCATIONS;
|
|
bRet = TRUE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
WARNING("VerifierInitialization: failed to get info from ntoskrnl\n");
|
|
}
|
|
|
|
//
|
|
// Disable pool tracking always for graphic drivers. (NTBUG:421768)
|
|
//
|
|
|
|
Level &= ~DRIVER_VERIFIER_TRACK_POOL_ALLOCATIONS;
|
|
|
|
// //
|
|
// // Initialize pool tracking if needed.
|
|
// //
|
|
// if (Level & DRIVER_VERIFIER_TRACK_POOL_ALLOCATIONS)
|
|
// {
|
|
// //
|
|
// // Initialize doubly linked list used to track pool allocations.
|
|
// //
|
|
//
|
|
// InitializeListHead(&gvs.lePoolTrackerHead);
|
|
//
|
|
// //
|
|
// // Initialize the tracking list lock. Turn off pool allocations
|
|
// // if semaphore creation fails.
|
|
// //
|
|
//
|
|
// gvs.hsemPoolTracker = GreCreateSemaphore();
|
|
// if (!gvs.hsemPoolTracker)
|
|
// Level &= ~DRIVER_VERIFIER_TRACK_POOL_ALLOCATIONS;
|
|
// }
|
|
|
|
//
|
|
// Keep a local copy of the DriverVerifier flags.
|
|
//
|
|
// Note that the DriverVerifier flags can change on the fly without
|
|
// rebooting so this is a very transient copy.
|
|
//
|
|
// Wait until we know everthing is OK.
|
|
//
|
|
|
|
gvs.fl = (bRet) ? Level : 0;
|
|
|
|
return bRet;
|
|
}
|
|
|
|
|
|
/******************************Public*Routine******************************\
|
|
* VerifierRandomFailure
|
|
*
|
|
* Occasionally returns TRUE, indicating that Verifier should inject an
|
|
* allocation failure.
|
|
*
|
|
* See ntos\mm\verifier.c for further details.
|
|
*
|
|
* History:
|
|
* 19-Jan-1999 -by- Gilman Wong [gilmanw]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
BOOL FASTCALL
|
|
VerifierRandomFailure(ULONG ulEntry)
|
|
{
|
|
BOOL bRet = FALSE;
|
|
LARGE_INTEGER CurrentTime;
|
|
|
|
#ifdef VERIFIER_STATISTICS
|
|
ASSERTGDI(ulEntry < VERIFIER_INDEX_LAST,
|
|
"VerifierRandomFailure: bad index\n");
|
|
#else
|
|
DONTUSE(ulEntry);
|
|
#endif
|
|
|
|
//
|
|
// Check if random failures enabled.
|
|
//
|
|
|
|
if (gvs.fl & DRIVER_VERIFIER_INJECT_ALLOCATION_FAILURES)
|
|
{
|
|
//
|
|
// Don't fail any requests in the first 7 or 8 minutes as we want to
|
|
// give the system enough time to boot.
|
|
//
|
|
|
|
if (gvs.bSystemStable == FALSE)
|
|
{
|
|
KeQuerySystemTime(&CurrentTime);
|
|
if (CurrentTime.QuadPart > (GreBootTime.QuadPart + VerifierRequiredTimeSinceBoot.QuadPart))
|
|
{
|
|
//
|
|
// Enough time has elapsed to begin failures.
|
|
//
|
|
|
|
VERIFIERWARNING(1, "VerifierRandomFailure: injected failures enabled\n");
|
|
gvs.bSystemStable = TRUE;
|
|
gvs.ulRandomSeed = CurrentTime.LowPart;
|
|
|
|
#ifdef VERIFIER_STATISTICS
|
|
//
|
|
// Reset statistics.
|
|
//
|
|
|
|
RtlZeroMemory((VOID *) gvs.avs, sizeof(VSTATS) * VERIFIER_INDEX_LAST);
|
|
|
|
#endif
|
|
}
|
|
}
|
|
|
|
#ifdef VERIFIER_STATISTICS
|
|
//
|
|
// Record number of attempts.
|
|
//
|
|
|
|
InterlockedIncrement((LONG *) &gvs.avs[ulEntry].ulAttempts);
|
|
|
|
#endif
|
|
|
|
//
|
|
// Once system is stable, randomly enable failure.
|
|
//
|
|
|
|
if (gvs.bSystemStable)
|
|
{
|
|
if ((RtlRandom(&gvs.ulRandomSeed) & gvs.ulFailureMask) == 0)
|
|
{
|
|
bRet = TRUE;
|
|
|
|
#ifdef VERIFIER_STATISTICS
|
|
//
|
|
// Record number of injected failures.
|
|
//
|
|
|
|
InterlockedIncrement((LONG *) &gvs.avs[ulEntry].ulFailures);
|
|
|
|
#endif
|
|
}
|
|
}
|
|
}
|
|
|
|
return bRet;
|
|
}
|
|
|
|
|
|
/******************************Public*Routine******************************\
|
|
* VerifierEngAllocMem
|
|
*
|
|
* VerifierEngAllocMem can put allocations under special pool, track
|
|
* allocations, and inject random allocation failures.
|
|
*
|
|
* History:
|
|
* 19-Jan-1999 -by- Gilman Wong [gilmanw]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
PVOID APIENTRY
|
|
VerifierEngAllocMem(
|
|
ULONG fl,
|
|
ULONG cj,
|
|
ULONG tag
|
|
)
|
|
{
|
|
PVOID pvRet;
|
|
POOL_TYPE poolType;
|
|
EX_POOL_PRIORITY poolPriority;
|
|
ULONG cjOrig = cj;
|
|
|
|
//
|
|
// Inject random failures.
|
|
//
|
|
|
|
if (VerifierRandomFailure(VERIFIER_INDEX_EngAllocMem))
|
|
{
|
|
VERIFIERWARNING(1, "VerifierEngAllocMem: inject failure\n");
|
|
return NULL;
|
|
}
|
|
|
|
//
|
|
// Check if special pool is enabled.
|
|
//
|
|
|
|
if (gvs.fl & DRIVER_VERIFIER_SPECIAL_POOLING)
|
|
poolPriority = (EX_POOL_PRIORITY) (HighPoolPrioritySpecialPoolOverrun | POOL_SPECIAL_POOL_BIT);
|
|
else
|
|
poolPriority = HighPoolPrioritySpecialPoolOverrun;
|
|
|
|
//
|
|
// Don't trust the driver to only ask for non-zero length buffers.
|
|
//
|
|
|
|
if (cj == 0)
|
|
return NULL;
|
|
|
|
//
|
|
// Adjust size to include VERIFIERTRACKHDR.
|
|
//
|
|
|
|
if (gvs.fl & DRIVER_VERIFIER_TRACK_POOL_ALLOCATIONS)
|
|
{
|
|
if (cj <= (MAXULONG - sizeof(VERIFIERTRACKHDR)))
|
|
cj += ((ULONG) sizeof(VERIFIERTRACKHDR));
|
|
else
|
|
return NULL;
|
|
}
|
|
|
|
//
|
|
// Adjust size to include ENGTRACKHDR header.
|
|
//
|
|
// Sundown note: sizeof(ENGTRACKHDR) will fit in 32-bit, so ULONG cast OK
|
|
//
|
|
|
|
|
|
if (cj <= (MAXULONG - sizeof(ENGTRACKHDR)))
|
|
cj += ((ULONG) sizeof(ENGTRACKHDR));
|
|
else
|
|
return NULL;
|
|
|
|
if (cj >= (PAGE_SIZE * 10000))
|
|
{
|
|
WARNING("EngAllocMem: temp buffer >= 10000 pages");
|
|
return NULL;
|
|
}
|
|
|
|
//
|
|
// Need to call GdiAllocPoolNonPagedWithPriority or GdiAllocPoolWithPriority, which allows for
|
|
// special pool allocations.
|
|
//
|
|
if (fl & FL_NONPAGED_MEMORY) {
|
|
pvRet = GdiAllocPoolNonPagedWithPriority(cj, tag, poolPriority);
|
|
} else {
|
|
pvRet = GdiAllocPoolWithPriority(cj, tag, poolPriority);
|
|
}
|
|
|
|
if (pvRet)
|
|
{
|
|
if (fl & FL_ZERO_MEMORY)
|
|
{
|
|
RtlZeroMemory(pvRet, cj);
|
|
}
|
|
|
|
//
|
|
// Hydra pool tracking.
|
|
//
|
|
|
|
//
|
|
// Add allocation to the tracking list.
|
|
//
|
|
|
|
ENGTRACKHDR *pethNew = (ENGTRACKHDR *) pvRet;
|
|
MultiUserGreTrackAddEngResource(pethNew, ENGTRACK_VERIFIERALLOCMEM);
|
|
|
|
//
|
|
// Adjust return pointer to hide the LIST_ENTRY header.
|
|
//
|
|
|
|
pvRet = (PVOID) (pethNew + 1);
|
|
|
|
//
|
|
// Verifier pool tracking. Separate from Hydra
|
|
// pool tracking which handles session cleanup.
|
|
//
|
|
|
|
if (gvs.fl & DRIVER_VERIFIER_TRACK_POOL_ALLOCATIONS)
|
|
{
|
|
//
|
|
// Add to the tracking list.
|
|
//
|
|
|
|
VERIFIERTRACKHDR *pvthNew = (VERIFIERTRACKHDR *) pvRet;
|
|
|
|
pvthNew->ulSize = cjOrig;
|
|
pvthNew->ulTag = tag;
|
|
|
|
GreAcquireSemaphore(gvs.hsemPoolTracker);
|
|
InsertTailList(&gvs.lePoolTrackerHead, ((PLIST_ENTRY) pvthNew));
|
|
GreReleaseSemaphore(gvs.hsemPoolTracker);
|
|
|
|
//
|
|
// Adjust return pointer to hide the header.
|
|
//
|
|
|
|
pvRet = (PVOID) (pvthNew + 1);
|
|
}
|
|
|
|
}
|
|
|
|
return pvRet;
|
|
}
|
|
|
|
|
|
/******************************Public*Routine******************************\
|
|
* VerifierEngFreeMem
|
|
*
|
|
* History:
|
|
* 19-Jan-1999 -by- Gilman Wong [gilmanw]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
VOID APIENTRY
|
|
VerifierEngFreeMem(
|
|
PVOID pv
|
|
)
|
|
{
|
|
if (pv)
|
|
{
|
|
//
|
|
// Verifier pool tracking.
|
|
//
|
|
|
|
if (gvs.fl & DRIVER_VERIFIER_TRACK_POOL_ALLOCATIONS)
|
|
{
|
|
//
|
|
// Remove victim from tracking list.
|
|
//
|
|
|
|
VERIFIERTRACKHDR *pvthVictim = ((VERIFIERTRACKHDR *) pv) - 1;
|
|
|
|
GreAcquireSemaphore(gvs.hsemPoolTracker);
|
|
RemoveEntryList(((PLIST_ENTRY) pvthVictim));
|
|
GreReleaseSemaphore(gvs.hsemPoolTracker);
|
|
|
|
//
|
|
// Adjust pointer to the header. This is base of allocation
|
|
// if not hydra.
|
|
//
|
|
|
|
pv = (PVOID) pvthVictim;
|
|
}
|
|
|
|
//
|
|
// Hydra pool tracking.
|
|
//
|
|
|
|
//
|
|
// Remove victim from tracking list.
|
|
//
|
|
|
|
ENGTRACKHDR *pethVictim = ((ENGTRACKHDR *) pv) - 1;
|
|
MultiUserGreTrackRemoveEngResource(pethVictim);
|
|
|
|
//
|
|
// Adjust pointer to the header. This is base of allocation if
|
|
// hydra.
|
|
//
|
|
|
|
pv = (PVOID) pethVictim;
|
|
|
|
GdiFreePool(pv);
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
/******************************Public*Routine******************************\
|
|
* VerififierEngAllocUserMem
|
|
*
|
|
* This routine allocates a piece of memory for USER mode and locks it
|
|
* down. A driver must be very careful with this memory as it is only
|
|
* valid for this process.
|
|
*
|
|
* History:
|
|
* 19-Jan-1999 -by- Gilman Wong [gilmanw]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
PVOID APIENTRY
|
|
VerifierEngAllocUserMem(
|
|
SIZE_T cj,
|
|
ULONG tag
|
|
)
|
|
{
|
|
//
|
|
// Inject random failures.
|
|
//
|
|
|
|
if (VerifierRandomFailure(VERIFIER_INDEX_EngAllocUserMem))
|
|
{
|
|
VERIFIERWARNING(1, "VerifierEngAllocUserMem: inject failure\n");
|
|
return NULL;
|
|
}
|
|
else
|
|
return EngAllocUserMem(cj, tag);
|
|
}
|
|
|
|
|
|
/******************************Public*Routine******************************\
|
|
* VerifierEngFreeUserMem
|
|
*
|
|
* History:
|
|
* 19-Jan-1999 -by- Gilman Wong [gilmanw]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
VOID APIENTRY
|
|
VerifierEngFreeUserMem(
|
|
PVOID pv
|
|
)
|
|
{
|
|
//
|
|
// Right now, there is no difference between this and EngFreeUserMem.
|
|
// However, we may soon add some tracking info, so here is a stub.
|
|
//
|
|
|
|
EngFreeUserMem(pv);
|
|
|
|
return;
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
* VerifierEngCreateBitmap
|
|
*
|
|
* Only supports random failure.
|
|
*
|
|
* History:
|
|
* 02-Feb-1999 -by- Gilman Wong [gilmanw]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
HBITMAP APIENTRY VerifierEngCreateBitmap(
|
|
SIZEL sizl,
|
|
LONG lWidth,
|
|
ULONG iFormat,
|
|
FLONG fl,
|
|
PVOID pvBits
|
|
)
|
|
{
|
|
if (VerifierRandomFailure(VERIFIER_INDEX_EngCreateBitmap))
|
|
{
|
|
VERIFIERWARNING(1, "VerifierEngCreateBitmap: inject failure\n");
|
|
return NULL;
|
|
}
|
|
else
|
|
return EngCreateBitmap(sizl, lWidth, iFormat, fl, pvBits);
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
* VerifierEngCreateDeviceSurface
|
|
*
|
|
* Only supports random failure.
|
|
*
|
|
* History:
|
|
* 02-Feb-1999 -by- Gilman Wong [gilmanw]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
HSURF APIENTRY VerifierEngCreateDeviceSurface(
|
|
DHSURF dhsurf,
|
|
SIZEL sizl,
|
|
ULONG iFormatCompat
|
|
)
|
|
{
|
|
if (VerifierRandomFailure(VERIFIER_INDEX_EngCreateDeviceSurface))
|
|
{
|
|
VERIFIERWARNING(1, "VerifierEngCreateDeviceSurface: inject failure\n");
|
|
return NULL;
|
|
}
|
|
else
|
|
return EngCreateDeviceSurface(dhsurf, sizl, iFormatCompat);
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
* VerifierEngCreateDeviceBitmap
|
|
*
|
|
* Only supports random failure.
|
|
*
|
|
* History:
|
|
* 02-Feb-1999 -by- Gilman Wong [gilmanw]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
HBITMAP APIENTRY VerifierEngCreateDeviceBitmap(
|
|
DHSURF dhsurf,
|
|
SIZEL sizl,
|
|
ULONG iFormatCompat
|
|
)
|
|
{
|
|
if (VerifierRandomFailure(VERIFIER_INDEX_EngCreateDeviceBitmap))
|
|
{
|
|
VERIFIERWARNING(1, "VerifierEngCreateDeviceBitmap: inject failure\n");
|
|
return NULL;
|
|
}
|
|
else
|
|
return EngCreateDeviceBitmap(dhsurf, sizl, iFormatCompat);
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
* VerifierEngCreatePalette
|
|
*
|
|
* Only supports random failure.
|
|
*
|
|
* History:
|
|
* 02-Feb-1999 -by- Gilman Wong [gilmanw]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
HPALETTE APIENTRY VerifierEngCreatePalette(
|
|
ULONG iMode,
|
|
ULONG cColors,
|
|
ULONG *pulColors,
|
|
FLONG flRed,
|
|
FLONG flGreen,
|
|
FLONG flBlue
|
|
)
|
|
{
|
|
if (VerifierRandomFailure(VERIFIER_INDEX_EngCreatePalette))
|
|
{
|
|
VERIFIERWARNING(1, "VerifierEngCreatePalette: inject failure\n");
|
|
return NULL;
|
|
}
|
|
else
|
|
return EngCreatePalette(iMode, cColors, pulColors,
|
|
flRed, flGreen, flBlue);
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
* VerifierEngCreateClip
|
|
*
|
|
* Only supports random failure.
|
|
*
|
|
* History:
|
|
* 02-Feb-1999 -by- Gilman Wong [gilmanw]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
CLIPOBJ * APIENTRY VerifierEngCreateClip()
|
|
{
|
|
if (VerifierRandomFailure(VERIFIER_INDEX_EngCreateClip))
|
|
{
|
|
VERIFIERWARNING(1, "VerifierEngCreateClip: inject failure\n");
|
|
return NULL;
|
|
}
|
|
else
|
|
return EngCreateClip();
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
* VerifierEngCreatePath
|
|
*
|
|
* Only supports random failure.
|
|
*
|
|
* History:
|
|
* 02-Feb-1999 -by- Gilman Wong [gilmanw]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
PATHOBJ * APIENTRY VerifierEngCreatePath()
|
|
{
|
|
if (VerifierRandomFailure(VERIFIER_INDEX_EngCreatePath))
|
|
{
|
|
VERIFIERWARNING(1, "VerifierEngCreatePath: inject failure\n");
|
|
return NULL;
|
|
}
|
|
else
|
|
return EngCreatePath();
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
* VerifierEngCreateWnd
|
|
*
|
|
* Only supports random failure.
|
|
*
|
|
* History:
|
|
* 02-Feb-1999 -by- Gilman Wong [gilmanw]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
WNDOBJ * APIENTRY VerifierEngCreateWnd(
|
|
SURFOBJ *pso,
|
|
HWND hwnd,
|
|
WNDOBJCHANGEPROC pfn,
|
|
FLONG fl,
|
|
int iPixelFormat
|
|
)
|
|
{
|
|
if (VerifierRandomFailure(VERIFIER_INDEX_EngCreateWnd))
|
|
{
|
|
VERIFIERWARNING(1, "VerifierEngCreateWnd: inject failure\n");
|
|
return NULL;
|
|
}
|
|
else
|
|
return EngCreateWnd(pso, hwnd, pfn, fl, iPixelFormat);
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
* VerifierEngCreateDriverObj
|
|
*
|
|
* Only supports random failure.
|
|
*
|
|
* History:
|
|
* 02-Feb-1999 -by- Gilman Wong [gilmanw]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
HDRVOBJ APIENTRY VerifierEngCreateDriverObj(
|
|
PVOID pvObj,
|
|
FREEOBJPROC pFreeObjProc,
|
|
HDEV hdev
|
|
)
|
|
{
|
|
if (VerifierRandomFailure(VERIFIER_INDEX_EngCreateDriverObj))
|
|
{
|
|
VERIFIERWARNING(1, "VerifierEngCreateDriverObj: inject failure\n");
|
|
return NULL;
|
|
}
|
|
else
|
|
return EngCreateDriverObj(pvObj, pFreeObjProc, hdev);
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
* VerifierBRUSHOBJ_pvAllocRbrush
|
|
*
|
|
* Only supports random failure.
|
|
*
|
|
* History:
|
|
* 02-Feb-1999 -by- Gilman Wong [gilmanw]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
PVOID APIENTRY VerifierBRUSHOBJ_pvAllocRbrush(
|
|
BRUSHOBJ *pbo,
|
|
ULONG cj
|
|
)
|
|
{
|
|
if (VerifierRandomFailure(VERIFIER_INDEX_BRUSHOBJ_pvAllocRbrush))
|
|
{
|
|
VERIFIERWARNING(1, "VerifierBRUSHOBJ_pvAllocRbrush: inject failure\n");
|
|
return NULL;
|
|
}
|
|
else
|
|
return BRUSHOBJ_pvAllocRbrush(pbo, cj);
|
|
}
|
|
|
|
/******************************Public*Routine******************************\
|
|
* VerifierCLIPOBJ_ppoGetPath
|
|
*
|
|
* Only supports random failure.
|
|
*
|
|
* History:
|
|
* 02-Feb-1999 -by- Gilman Wong [gilmanw]
|
|
* Wrote it.
|
|
\**************************************************************************/
|
|
|
|
PATHOBJ* APIENTRY VerifierCLIPOBJ_ppoGetPath(
|
|
CLIPOBJ* pco
|
|
)
|
|
{
|
|
if (VerifierRandomFailure(VERIFIER_INDEX_CLIPOBJ_ppoGetPath))
|
|
{
|
|
VERIFIERWARNING(1, "VerifierCLIPOBJ_ppoGetPath: inject failure\n");
|
|
return NULL;
|
|
}
|
|
else
|
|
return CLIPOBJ_ppoGetPath(pco);
|
|
}
|