Leaked source code of windows server 2003
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.
|
|
/****************************** Module Header ******************************\
* Module Name: handles.c * * Copyright (c) 1985 - 1999, Microsoft Corporation * * HANDLES.C - Data handle manager * * * This module allows a 32 bit value to be converted into a handle that * can be validated with a high probability of correctness. * * A handle array is kept which contains the 32 bit data associated with * it, and a copy of the correect handle value. The handle itself is * composed of a combination of the index into the array for the associated * data, the instance value, a type value and a DDEML instance value. * * The HIWORD of a handle is guarenteed not to be 0. * * History: * 10-28-91 Sanfords Created \***************************************************************************/
#include "precomp.h"
#pragma hdrstop
// globals
PCHANDLEENTRY aHandleEntry = NULL;
// statics
int cHandlesAllocated = 0; int iFirstFree = 0; DWORD nextId = 1;
#define GROW_COUNT 16
// #define TESTING
#ifdef TESTING
VOID CheckHandleTable() { int i;
for (i = 0; i < cHandlesAllocated; i++) { if (aHandleEntry[i].handle && aHandleEntry[i].dwData) { switch (TypeFromHandle(aHandleEntry[i].handle)) { case HTYPE_INSTANCE: UserAssert(((PCL_INSTANCE_INFO)aHandleEntry[i].dwData)->hInstClient == aHandleEntry[i].handle); break;
case HTYPE_CLIENT_CONVERSATION: case HTYPE_SERVER_CONVERSATION: UserAssert(((PCONV_INFO)aHandleEntry[i].dwData)->hConv == (HCONV)aHandleEntry[i].handle || ((PCONV_INFO)aHandleEntry[i].dwData)->hConv == 0); break; } } } } #else
#define CheckHandleTable()
#endif // TESTING
/***************************************************************************\
* CreateHandle * * Description: * Creates a client side handle. * * Returns 0 on error. * * History: * 11-1-91 sanfords Created. \***************************************************************************/ HANDLE CreateHandle( ULONG_PTR dwData, DWORD type, DWORD inst) { HANDLE h; int i, iNextFree; PCHANDLEENTRY phe, pheTemp;
if (iFirstFree >= cHandlesAllocated) { if (cHandlesAllocated == 0) { aHandleEntry = (PCHANDLEENTRY)DDEMLAlloc(sizeof(CHANDLEENTRY) * GROW_COUNT); } else { pheTemp = (PCHANDLEENTRY)DDEMLReAlloc(aHandleEntry, sizeof(CHANDLEENTRY) * (cHandlesAllocated + GROW_COUNT)); /*
* If the realloc failed, free the old ptr. We continue * on in order to maintain compatibility with previous DDE code. */ if (pheTemp == NULL) { DDEMLFree(aHandleEntry); } aHandleEntry = pheTemp; } if (aHandleEntry == NULL) { return (0); } i = cHandlesAllocated; cHandlesAllocated += GROW_COUNT; phe = &aHandleEntry[i]; while (i < cHandlesAllocated) { // phe->handle = 0; // indicates empty - ZERO init.
phe->dwData = ++i; // index to next free spot.
phe++; } } h = aHandleEntry[iFirstFree].handle = (HANDLE)LongToHandle( HandleFromId(nextId) | HandleFromIndex(iFirstFree) | HandleFromType(type) | HandleFromInst(inst) ); iNextFree = (int)aHandleEntry[iFirstFree].dwData; aHandleEntry[iFirstFree].dwData = dwData; nextId++; if (nextId == 0) { // guarentees HIWORD of handle != 0
nextId++; } iFirstFree = iNextFree;
CheckHandleTable(); return (h); }
/***************************************************************************\
* DestroyHandle * * Description: * Frees up a handle. * * Assumptions: * The handle is valid. * Critical Section is entered. * * Returns: * Data in handle before destruction. * * History: * 11-1-91 sanfords Created. \***************************************************************************/ ULONG_PTR DestroyHandle( HANDLE h) { register int i; register ULONG_PTR dwRet;
CheckHandleTable();
i = IndexFromHandle(h); UserAssert(aHandleEntry[i].handle == h); aHandleEntry[i].handle = 0; dwRet = aHandleEntry[i].dwData; aHandleEntry[i].dwData = iFirstFree; iFirstFree = i;
return (dwRet); }
/***************************************************************************\
* GetHandleData * * Description: * A quick way to retrieve a valid handle's data * * History: * 11-19-91 sanfords Created. \***************************************************************************/ ULONG_PTR GetHandleData( HANDLE h) { register ULONG_PTR dwRet;
CheckHandleTable(); dwRet = aHandleEntry[IndexFromHandle(h)].dwData; return (dwRet); }
/***************************************************************************\
* SetHandleData * * Description: * A quick way to change a valid handle's data. * * History: * 11-19-91 sanfords Created. \***************************************************************************/ VOID SetHandleData( HANDLE h, ULONG_PTR dwData) { aHandleEntry[IndexFromHandle(h)].dwData = dwData; }
/***************************************************************************\
* ValidateCHandle * * Description: * General handle validation routine. ExpectedType or ExpectedInstance * can be HTYPE_ANY/HINST_ANY. (note Expected Instance is an instance * index into the aInstance array, NOT a instance handle. * * History: * 11-19-91 sanfords Created. \***************************************************************************/ ULONG_PTR ValidateCHandle( HANDLE h, DWORD ExpectedType, DWORD ExpectedInstance) { register int i; register ULONG_PTR dwRet;
CheckHandleTable(); dwRet = 0; i = IndexFromHandle(h); if (i < cHandlesAllocated && aHandleEntry[i].handle == h && (ExpectedType == -1 || ExpectedType == TypeFromHandle(h)) && (ExpectedInstance == -1 || ExpectedInstance == InstFromHandle(h))) { dwRet = aHandleEntry[i].dwData; }
return (dwRet); }
PCL_INSTANCE_INFO PciiFromHandle( HANDLE h) { PCHANDLEENTRY phe;
CheckDDECritIn;
if (!cHandlesAllocated) { return(NULL); } phe = &aHandleEntry[cHandlesAllocated];
do { phe--; if (phe->handle != 0 && TypeFromHandle(phe->handle) == HTYPE_INSTANCE && (InstFromHandle(phe->handle) == InstFromHandle(h))) { return(((PCL_INSTANCE_INFO)phe->dwData)->tid == GetCurrentThreadId() ? (PCL_INSTANCE_INFO)phe->dwData : NULL); } } while (phe != aHandleEntry); return(NULL); }
/***************************************************************************\
* ApplyFunctionToObjects * * Description: * Used for cleanup, this allows the handle array to be scanned for * handles meeting the ExpectedType and ExpectedInstance criteria * and apply the given function to each handle. * * History: * 11-19-91 sanfords Created. \***************************************************************************/ VOID ApplyFunctionToObjects( DWORD ExpectedType, DWORD ExpectedInstance, PFNHANDLEAPPLY pfn) { PCHANDLEENTRY phe;
CheckDDECritIn;
if (!cHandlesAllocated) { return; } phe = &aHandleEntry[cHandlesAllocated];
do { phe--; if (phe->handle != 0 && (ExpectedType == HTYPE_ANY || ExpectedType == TypeFromHandle(phe->handle)) && (ExpectedInstance == HTYPE_ANY || ExpectedInstance == InstFromHandle(phe->handle))) { LeaveDDECrit; CheckDDECritOut; (*pfn)(phe->handle); EnterDDECrit; } } while (phe != aHandleEntry); }
DWORD GetFullUserHandle(WORD wHandle) { DWORD dwHandle; PHE phe;
dwHandle = HMIndexFromHandle(wHandle);
if (dwHandle < gpsi->cHandleEntries) {
phe = &gSharedInfo.aheList[dwHandle];
if (phe->bType == TYPE_WINDOW) return(MAKELONG(dwHandle, phe->wUniq)); }
/*
* object may be gone, but we must pass something. * DDE terminates will fail if we don't map this right even after * the window is dead! * * NOTE: This fix will only work for WOW apps, but since the 32bit * tracking layer locks dde windows until the last terminate is * received, we won't see this problem on the 32bit side. * * BUG: We WILL see a problem for OLE32 thunked DDE though. */ return(wHandle); }
/***************************************************************************\
* BestSetLastDDEMLError * * Description: * This sets the LastError field of all instances that belong to the * current thread. This is used to get error information to applications * which generated an error where the exact instance could not be * determined. * * History: * 11-12-91 sanfords Created. \***************************************************************************/ VOID BestSetLastDDEMLError( DWORD error) { PCHANDLEENTRY phe;
CheckDDECritIn;
if (!cHandlesAllocated) { return; } phe = &aHandleEntry[cHandlesAllocated]; do { phe--; if (phe->handle != 0 && TypeFromHandle(phe->handle) == HTYPE_INSTANCE) { SetLastDDEMLError((PCL_INSTANCE_INFO)phe->dwData, error); } } while (phe != aHandleEntry); }
|