INF: Validating Local Handles

ID Number: Q80864

3.00

WINDOWS

Summary:

In Windows version 3.0, the local memory manager functions

LocalFlags(), LocalLock(), LocalReAlloc(), LocalSize(), and

LocalUnlock(), are documented to return NULL if passed an invalid

handle. However, under Windows 3.0, passing an invalid handle to one

of these functions can result in a non-NULL return value or an

unrecoverable application error (UAE).

This article demonstrates a technique that an application can use to

avoid this type of error.

More Information:

Although Windows does not automatically verify local memory handles,

it is possible to verify structures in the local heap by placing a

verification number in the structure. To verify the structure, check

the value of this special number. The following code demonstrates this

technique:

// Declare the structure

#define VERIFY 47

typedef struct tagDataStruct {

int nData; // Declare the data

int nVerify; // Declare the verification number

} DataStruct;

// Allocate a structure

HANDLE AllocStruct(WORD wFlags)

{

HANDLE hLMem;

DataStruct *pLMem;

// Allocate the structure

if (!(hLMem = LocalAlloc(wFlags, sizeof(DataStruct))))

return 0;

if (pLMem = (DataStruct *) LocalLock(hLMem))

{

pLMem->nVerify = VERIFY;

LocalUnlock(hLMem);

return hLMem;

}

return 0;

}

// Verify a handle to the structure

BOOL IsValidStruct(HANDLE hStruct)

{

WORD wDS;

WORD wDSSize;

DataStruct *pStruct;

BOOL bReturn;

// Get the size of the Data Segment

// This is used to make sure that handles and pointers are

// within the Data Segment to avoid UAEs

_asm {

mov ax, ds

mov wDS, ax

}

wDSSize = (WORD)GlobalSize(LOWORD(GlobalHandle(wDS)));

// Check that the handle is in the DS

if (wDS < hStruct)

return FALSE;

// Lock the handle

pStruct = (DataStruct *)LocalLock(hStruct);

// Check that the pointer + (the size of the structure) is in

// the DS and that pStruct is not NULL

if (wDS < (WORD)pStruct + sizeof(DataStruct) || !pStruct)

{

LocalUnlock(hStruct);

return FALSE;

}

// Check the verification number

if (pStruct->nVerify == VERIFY)

bReturn = TRUE;

else

bReturn = FALSE;

LocalUnlock(hStruct);

return bReturn;

}

Additional reference words: 3.00