Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

handles.c

Go to the documentation of this file.
00001 /****************************** Module Header ******************************\ 00002 * Module Name: handles.c 00003 * 00004 * Copyright (c) 1985 - 1999, Microsoft Corporation 00005 * 00006 * HANDLES.C - Data handle manager 00007 * 00008 * 00009 * This module allows a 32 bit value to be converted into a handle that 00010 * can be validated with a high probability of correctness. 00011 * 00012 * A handle array is kept which contains the 32 bit data associated with 00013 * it, and a copy of the correect handle value. The handle itself is 00014 * composed of a combination of the index into the array for the associated 00015 * data, the instance value, a type value and a DDEML instance value. 00016 * 00017 * The HIWORD of a handle is guarenteed not to be 0. 00018 * 00019 * History: 00020 * 10-28-91 Sanfords Created 00021 \***************************************************************************/ 00022 00023 #include "precomp.h" 00024 #pragma hdrstop 00025 00026 // globals 00027 00028 PCHANDLEENTRY aHandleEntry = NULL; 00029 00030 // statics 00031 00032 int cHandlesAllocated = 0; 00033 int iFirstFree = 0; 00034 DWORD nextId = 1; 00035 00036 #define GROW_COUNT 16 00037 // #define TESTING 00038 #ifdef TESTING 00039 VOID CheckHandleTable() 00040 { 00041 int i; 00042 00043 for (i = 0; i < cHandlesAllocated; i++) { 00044 if (aHandleEntry[i].handle && aHandleEntry[i].dwData) { 00045 switch (TypeFromHandle(aHandleEntry[i].handle)) { 00046 case HTYPE_INSTANCE: 00047 UserAssert(((PCL_INSTANCE_INFO)aHandleEntry[i].dwData)->hInstClient == aHandleEntry[i].handle); 00048 break; 00049 00050 case HTYPE_CLIENT_CONVERSATION: 00051 case HTYPE_SERVER_CONVERSATION: 00052 UserAssert(((PCONV_INFO)aHandleEntry[i].dwData)->hConv == (HCONV)aHandleEntry[i].handle || 00053 ((PCONV_INFO)aHandleEntry[i].dwData)->hConv == 0); 00054 break; 00055 } 00056 } 00057 } 00058 } 00059 #else 00060 #define CheckHandleTable() 00061 #endif // TESTING 00062 00063 00064 /***************************************************************************\ 00065 * CreateHandle 00066 * 00067 * Description: 00068 * Creates a client side handle. 00069 * 00070 * Returns 0 on error. 00071 * 00072 * History: 00073 * 11-1-91 sanfords Created. 00074 \***************************************************************************/ 00075 HANDLE CreateHandle( 00076 ULONG_PTR dwData, 00077 DWORD type, 00078 DWORD inst) 00079 { 00080 HANDLE h; 00081 int i, iNextFree; 00082 PCHANDLEENTRY phe; 00083 00084 if (iFirstFree >= cHandlesAllocated) { 00085 if (cHandlesAllocated == 0) { 00086 aHandleEntry = (PCHANDLEENTRY)DDEMLAlloc(sizeof(CHANDLEENTRY) * GROW_COUNT); 00087 } else { 00088 aHandleEntry = (PCHANDLEENTRY)DDEMLReAlloc(aHandleEntry, 00089 sizeof(CHANDLEENTRY) * (cHandlesAllocated + GROW_COUNT)); 00090 } 00091 if (aHandleEntry == NULL) { 00092 return (0); 00093 } 00094 i = cHandlesAllocated; 00095 cHandlesAllocated += GROW_COUNT; 00096 phe = &aHandleEntry[i]; 00097 while (i < cHandlesAllocated) { 00098 // phe->handle = 0; // indicates empty - ZERO init. 00099 phe->dwData = ++i; // index to next free spot. 00100 phe++; 00101 } 00102 } 00103 h = aHandleEntry[iFirstFree].handle = (HANDLE)LongToHandle( 00104 HandleFromId(nextId) | 00105 HandleFromIndex(iFirstFree) | 00106 HandleFromType(type) | 00107 HandleFromInst(inst) ); 00108 iNextFree = (int)aHandleEntry[iFirstFree].dwData; 00109 aHandleEntry[iFirstFree].dwData = dwData; 00110 nextId++; 00111 if (nextId == 0) { // guarentees HIWORD of handle != 0 00112 nextId++; 00113 } 00114 iFirstFree = iNextFree; 00115 00116 CheckHandleTable(); 00117 return (h); 00118 } 00119 00120 00121 /***************************************************************************\ 00122 * DestroyHandle 00123 * 00124 * Description: 00125 * Frees up a handle. 00126 * 00127 * Assumptions: 00128 * The handle is valid. 00129 * Critical Section is entered. 00130 * 00131 * Returns: 00132 * Data in handle before destruction. 00133 * 00134 * History: 00135 * 11-1-91 sanfords Created. 00136 \***************************************************************************/ 00137 ULONG_PTR DestroyHandle( 00138 HANDLE h) 00139 { 00140 register int i; 00141 register ULONG_PTR dwRet; 00142 00143 CheckHandleTable(); 00144 00145 i = IndexFromHandle(h); 00146 UserAssert(aHandleEntry[i].handle == h); 00147 aHandleEntry[i].handle = 0; 00148 dwRet = aHandleEntry[i].dwData; 00149 aHandleEntry[i].dwData = iFirstFree; 00150 iFirstFree = i; 00151 00152 return (dwRet); 00153 } 00154 00155 00156 /***************************************************************************\ 00157 * GetHandleData 00158 * 00159 * Description: 00160 * A quick way to retrieve a valid handle's data 00161 * 00162 * History: 00163 * 11-19-91 sanfords Created. 00164 \***************************************************************************/ 00165 ULONG_PTR GetHandleData( 00166 HANDLE h) 00167 { 00168 register ULONG_PTR dwRet; 00169 00170 CheckHandleTable(); 00171 dwRet = aHandleEntry[IndexFromHandle(h)].dwData; 00172 return (dwRet); 00173 } 00174 00175 00176 /***************************************************************************\ 00177 * SetHandleData 00178 * 00179 * Description: 00180 * A quick way to change a valid handle's data. 00181 * 00182 * History: 00183 * 11-19-91 sanfords Created. 00184 \***************************************************************************/ 00185 VOID SetHandleData( 00186 HANDLE h, 00187 ULONG_PTR dwData) 00188 { 00189 aHandleEntry[IndexFromHandle(h)].dwData = dwData; 00190 } 00191 00192 00193 /***************************************************************************\ 00194 * ValidateCHandle 00195 * 00196 * Description: 00197 * General handle validation routine. ExpectedType or ExpectedInstance 00198 * can be HTYPE_ANY/HINST_ANY. (note Expected Instance is an instance 00199 * index into the aInstance array, NOT a instance handle. 00200 * 00201 * History: 00202 * 11-19-91 sanfords Created. 00203 \***************************************************************************/ 00204 ULONG_PTR ValidateCHandle( 00205 HANDLE h, 00206 DWORD ExpectedType, 00207 DWORD ExpectedInstance) 00208 { 00209 register int i; 00210 register ULONG_PTR dwRet; 00211 00212 CheckHandleTable(); 00213 dwRet = 0; 00214 i = IndexFromHandle(h); 00215 if (i < cHandlesAllocated && 00216 aHandleEntry[i].handle == h && 00217 (ExpectedType == -1 || ExpectedType == TypeFromHandle(h)) && 00218 (ExpectedInstance == -1 || ExpectedInstance == InstFromHandle(h))) { 00219 dwRet = aHandleEntry[i].dwData; 00220 } 00221 00222 return (dwRet); 00223 } 00224 00225 00226 PCL_INSTANCE_INFO PciiFromHandle( 00227 HANDLE h) 00228 { 00229 PCHANDLEENTRY phe; 00230 00231 CheckDDECritIn; 00232 00233 if (!cHandlesAllocated) { 00234 return(NULL); 00235 } 00236 phe = &aHandleEntry[cHandlesAllocated]; 00237 00238 do { 00239 phe--; 00240 if (phe->handle != 0 && 00241 TypeFromHandle(phe->handle) == HTYPE_INSTANCE && 00242 (InstFromHandle(phe->handle) == InstFromHandle(h))) { 00243 return(((PCL_INSTANCE_INFO)phe->dwData)->tid == GetCurrentThreadId() ? 00244 (PCL_INSTANCE_INFO)phe->dwData : NULL); 00245 } 00246 } while (phe != aHandleEntry); 00247 return(NULL); 00248 } 00249 00250 00251 00252 /***************************************************************************\ 00253 * ApplyFunctionToObjects 00254 * 00255 * Description: 00256 * Used for cleanup, this allows the handle array to be scanned for 00257 * handles meeting the ExpectedType and ExpectedInstance criteria 00258 * and apply the given function to each handle. 00259 * 00260 * History: 00261 * 11-19-91 sanfords Created. 00262 \***************************************************************************/ 00263 VOID ApplyFunctionToObjects( 00264 DWORD ExpectedType, 00265 DWORD ExpectedInstance, 00266 PFNHANDLEAPPLY pfn) 00267 { 00268 PCHANDLEENTRY phe; 00269 00270 CheckDDECritIn; 00271 00272 if (!cHandlesAllocated) { 00273 return; 00274 } 00275 phe = &aHandleEntry[cHandlesAllocated]; 00276 00277 do { 00278 phe--; 00279 if (phe->handle != 0 && 00280 (ExpectedType == HTYPE_ANY || 00281 ExpectedType == TypeFromHandle(phe->handle)) && 00282 (ExpectedInstance == HTYPE_ANY || 00283 ExpectedInstance == InstFromHandle(phe->handle))) { 00284 LeaveDDECrit; 00285 CheckDDECritOut; 00286 (*pfn)(phe->handle); 00287 EnterDDECrit; 00288 } 00289 } while (phe != aHandleEntry); 00290 } 00291 00292 00293 DWORD GetFullUserHandle(WORD wHandle) 00294 { 00295 DWORD dwHandle; 00296 PHE phe; 00297 00298 dwHandle = HMIndexFromHandle(wHandle); 00299 00300 if (dwHandle < gpsi->cHandleEntries) { 00301 00302 phe = &gSharedInfo.aheList[dwHandle]; 00303 00304 if (phe->bType == TYPE_WINDOW) 00305 return(MAKELONG(dwHandle, phe->wUniq)); 00306 } 00307 00308 /* 00309 * object may be gone, but we must pass something. 00310 * DDE terminates will fail if we don't map this right even after 00311 * the window is dead! 00312 * 00313 * NOTE: This fix will only work for WOW apps, but since the 32bit 00314 * tracking layer locks dde windows until the last terminate is 00315 * received, we won't see this problem on the 32bit side. 00316 * 00317 * BUG: We WILL see a problem for OLE32 thunked DDE though. 00318 */ 00319 return(wHandle); 00320 } 00321 00322 00323 00324 /***************************************************************************\ 00325 * BestSetLastDDEMLError 00326 * 00327 * Description: 00328 * This sets the LastError field of all instances that belong to the 00329 * current thread. This is used to get error information to applications 00330 * which generated an error where the exact instance could not be 00331 * determined. 00332 * 00333 * History: 00334 * 11-12-91 sanfords Created. 00335 \***************************************************************************/ 00336 VOID BestSetLastDDEMLError( 00337 DWORD error) 00338 { 00339 PCHANDLEENTRY phe; 00340 00341 CheckDDECritIn; 00342 00343 if (!cHandlesAllocated) { 00344 return; 00345 } 00346 phe = &aHandleEntry[cHandlesAllocated]; 00347 do { 00348 phe--; 00349 if (phe->handle != 0 && TypeFromHandle(phe->handle) == HTYPE_INSTANCE) { 00350 SetLastDDEMLError((PCL_INSTANCE_INFO)phe->dwData, error); 00351 } 00352 } while (phe != aHandleEntry); 00353 }

Generated on Sat May 15 19:40:14 2004 for test by doxygen 1.3.7