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.

361 lines
9.6 KiB

  1. /****************************** Module Header ******************************\
  2. * Module Name: handles.c
  3. *
  4. * Copyright (c) 1985 - 1999, Microsoft Corporation
  5. *
  6. * HANDLES.C - Data handle manager
  7. *
  8. *
  9. * This module allows a 32 bit value to be converted into a handle that
  10. * can be validated with a high probability of correctness.
  11. *
  12. * A handle array is kept which contains the 32 bit data associated with
  13. * it, and a copy of the correect handle value. The handle itself is
  14. * composed of a combination of the index into the array for the associated
  15. * data, the instance value, a type value and a DDEML instance value.
  16. *
  17. * The HIWORD of a handle is guarenteed not to be 0.
  18. *
  19. * History:
  20. * 10-28-91 Sanfords Created
  21. \***************************************************************************/
  22. #include "precomp.h"
  23. #pragma hdrstop
  24. // globals
  25. PCHANDLEENTRY aHandleEntry = NULL;
  26. // statics
  27. int cHandlesAllocated = 0;
  28. int iFirstFree = 0;
  29. DWORD nextId = 1;
  30. #define GROW_COUNT 16
  31. // #define TESTING
  32. #ifdef TESTING
  33. VOID CheckHandleTable()
  34. {
  35. int i;
  36. for (i = 0; i < cHandlesAllocated; i++) {
  37. if (aHandleEntry[i].handle && aHandleEntry[i].dwData) {
  38. switch (TypeFromHandle(aHandleEntry[i].handle)) {
  39. case HTYPE_INSTANCE:
  40. UserAssert(((PCL_INSTANCE_INFO)aHandleEntry[i].dwData)->hInstClient == aHandleEntry[i].handle);
  41. break;
  42. case HTYPE_CLIENT_CONVERSATION:
  43. case HTYPE_SERVER_CONVERSATION:
  44. UserAssert(((PCONV_INFO)aHandleEntry[i].dwData)->hConv == (HCONV)aHandleEntry[i].handle ||
  45. ((PCONV_INFO)aHandleEntry[i].dwData)->hConv == 0);
  46. break;
  47. }
  48. }
  49. }
  50. }
  51. #else
  52. #define CheckHandleTable()
  53. #endif // TESTING
  54. /***************************************************************************\
  55. * CreateHandle
  56. *
  57. * Description:
  58. * Creates a client side handle.
  59. *
  60. * Returns 0 on error.
  61. *
  62. * History:
  63. * 11-1-91 sanfords Created.
  64. \***************************************************************************/
  65. HANDLE CreateHandle(
  66. ULONG_PTR dwData,
  67. DWORD type,
  68. DWORD inst)
  69. {
  70. HANDLE h;
  71. int i, iNextFree;
  72. PCHANDLEENTRY phe, pheTemp;
  73. if (iFirstFree >= cHandlesAllocated) {
  74. if (cHandlesAllocated == 0) {
  75. aHandleEntry = (PCHANDLEENTRY)DDEMLAlloc(sizeof(CHANDLEENTRY) * GROW_COUNT);
  76. } else {
  77. pheTemp = (PCHANDLEENTRY)DDEMLReAlloc(aHandleEntry,
  78. sizeof(CHANDLEENTRY) * (cHandlesAllocated + GROW_COUNT));
  79. /*
  80. * If the realloc failed, free the old ptr. We continue
  81. * on in order to maintain compatibility with previous DDE code.
  82. */
  83. if (pheTemp == NULL) {
  84. DDEMLFree(aHandleEntry);
  85. }
  86. aHandleEntry = pheTemp;
  87. }
  88. if (aHandleEntry == NULL) {
  89. return (0);
  90. }
  91. i = cHandlesAllocated;
  92. cHandlesAllocated += GROW_COUNT;
  93. phe = &aHandleEntry[i];
  94. while (i < cHandlesAllocated) {
  95. // phe->handle = 0; // indicates empty - ZERO init.
  96. phe->dwData = ++i; // index to next free spot.
  97. phe++;
  98. }
  99. }
  100. h = aHandleEntry[iFirstFree].handle = (HANDLE)LongToHandle(
  101. HandleFromId(nextId) |
  102. HandleFromIndex(iFirstFree) |
  103. HandleFromType(type) |
  104. HandleFromInst(inst) );
  105. iNextFree = (int)aHandleEntry[iFirstFree].dwData;
  106. aHandleEntry[iFirstFree].dwData = dwData;
  107. nextId++;
  108. if (nextId == 0) { // guarentees HIWORD of handle != 0
  109. nextId++;
  110. }
  111. iFirstFree = iNextFree;
  112. CheckHandleTable();
  113. return (h);
  114. }
  115. /***************************************************************************\
  116. * DestroyHandle
  117. *
  118. * Description:
  119. * Frees up a handle.
  120. *
  121. * Assumptions:
  122. * The handle is valid.
  123. * Critical Section is entered.
  124. *
  125. * Returns:
  126. * Data in handle before destruction.
  127. *
  128. * History:
  129. * 11-1-91 sanfords Created.
  130. \***************************************************************************/
  131. ULONG_PTR DestroyHandle(
  132. HANDLE h)
  133. {
  134. register int i;
  135. register ULONG_PTR dwRet;
  136. CheckHandleTable();
  137. i = IndexFromHandle(h);
  138. UserAssert(aHandleEntry[i].handle == h);
  139. aHandleEntry[i].handle = 0;
  140. dwRet = aHandleEntry[i].dwData;
  141. aHandleEntry[i].dwData = iFirstFree;
  142. iFirstFree = i;
  143. return (dwRet);
  144. }
  145. /***************************************************************************\
  146. * GetHandleData
  147. *
  148. * Description:
  149. * A quick way to retrieve a valid handle's data
  150. *
  151. * History:
  152. * 11-19-91 sanfords Created.
  153. \***************************************************************************/
  154. ULONG_PTR GetHandleData(
  155. HANDLE h)
  156. {
  157. register ULONG_PTR dwRet;
  158. CheckHandleTable();
  159. dwRet = aHandleEntry[IndexFromHandle(h)].dwData;
  160. return (dwRet);
  161. }
  162. /***************************************************************************\
  163. * SetHandleData
  164. *
  165. * Description:
  166. * A quick way to change a valid handle's data.
  167. *
  168. * History:
  169. * 11-19-91 sanfords Created.
  170. \***************************************************************************/
  171. VOID SetHandleData(
  172. HANDLE h,
  173. ULONG_PTR dwData)
  174. {
  175. aHandleEntry[IndexFromHandle(h)].dwData = dwData;
  176. }
  177. /***************************************************************************\
  178. * ValidateCHandle
  179. *
  180. * Description:
  181. * General handle validation routine. ExpectedType or ExpectedInstance
  182. * can be HTYPE_ANY/HINST_ANY. (note Expected Instance is an instance
  183. * index into the aInstance array, NOT a instance handle.
  184. *
  185. * History:
  186. * 11-19-91 sanfords Created.
  187. \***************************************************************************/
  188. ULONG_PTR ValidateCHandle(
  189. HANDLE h,
  190. DWORD ExpectedType,
  191. DWORD ExpectedInstance)
  192. {
  193. register int i;
  194. register ULONG_PTR dwRet;
  195. CheckHandleTable();
  196. dwRet = 0;
  197. i = IndexFromHandle(h);
  198. if (i < cHandlesAllocated &&
  199. aHandleEntry[i].handle == h &&
  200. (ExpectedType == -1 || ExpectedType == TypeFromHandle(h)) &&
  201. (ExpectedInstance == -1 || ExpectedInstance == InstFromHandle(h))) {
  202. dwRet = aHandleEntry[i].dwData;
  203. }
  204. return (dwRet);
  205. }
  206. PCL_INSTANCE_INFO PciiFromHandle(
  207. HANDLE h)
  208. {
  209. PCHANDLEENTRY phe;
  210. CheckDDECritIn;
  211. if (!cHandlesAllocated) {
  212. return(NULL);
  213. }
  214. phe = &aHandleEntry[cHandlesAllocated];
  215. do {
  216. phe--;
  217. if (phe->handle != 0 &&
  218. TypeFromHandle(phe->handle) == HTYPE_INSTANCE &&
  219. (InstFromHandle(phe->handle) == InstFromHandle(h))) {
  220. return(((PCL_INSTANCE_INFO)phe->dwData)->tid == GetCurrentThreadId() ?
  221. (PCL_INSTANCE_INFO)phe->dwData : NULL);
  222. }
  223. } while (phe != aHandleEntry);
  224. return(NULL);
  225. }
  226. /***************************************************************************\
  227. * ApplyFunctionToObjects
  228. *
  229. * Description:
  230. * Used for cleanup, this allows the handle array to be scanned for
  231. * handles meeting the ExpectedType and ExpectedInstance criteria
  232. * and apply the given function to each handle.
  233. *
  234. * History:
  235. * 11-19-91 sanfords Created.
  236. \***************************************************************************/
  237. VOID ApplyFunctionToObjects(
  238. DWORD ExpectedType,
  239. DWORD ExpectedInstance,
  240. PFNHANDLEAPPLY pfn)
  241. {
  242. PCHANDLEENTRY phe;
  243. CheckDDECritIn;
  244. if (!cHandlesAllocated) {
  245. return;
  246. }
  247. phe = &aHandleEntry[cHandlesAllocated];
  248. do {
  249. phe--;
  250. if (phe->handle != 0 &&
  251. (ExpectedType == HTYPE_ANY ||
  252. ExpectedType == TypeFromHandle(phe->handle)) &&
  253. (ExpectedInstance == HTYPE_ANY ||
  254. ExpectedInstance == InstFromHandle(phe->handle))) {
  255. LeaveDDECrit;
  256. CheckDDECritOut;
  257. (*pfn)(phe->handle);
  258. EnterDDECrit;
  259. }
  260. } while (phe != aHandleEntry);
  261. }
  262. DWORD GetFullUserHandle(WORD wHandle)
  263. {
  264. DWORD dwHandle;
  265. PHE phe;
  266. dwHandle = HMIndexFromHandle(wHandle);
  267. if (dwHandle < gpsi->cHandleEntries) {
  268. phe = &gSharedInfo.aheList[dwHandle];
  269. if (phe->bType == TYPE_WINDOW)
  270. return(MAKELONG(dwHandle, phe->wUniq));
  271. }
  272. /*
  273. * object may be gone, but we must pass something.
  274. * DDE terminates will fail if we don't map this right even after
  275. * the window is dead!
  276. *
  277. * NOTE: This fix will only work for WOW apps, but since the 32bit
  278. * tracking layer locks dde windows until the last terminate is
  279. * received, we won't see this problem on the 32bit side.
  280. *
  281. * BUG: We WILL see a problem for OLE32 thunked DDE though.
  282. */
  283. return(wHandle);
  284. }
  285. /***************************************************************************\
  286. * BestSetLastDDEMLError
  287. *
  288. * Description:
  289. * This sets the LastError field of all instances that belong to the
  290. * current thread. This is used to get error information to applications
  291. * which generated an error where the exact instance could not be
  292. * determined.
  293. *
  294. * History:
  295. * 11-12-91 sanfords Created.
  296. \***************************************************************************/
  297. VOID BestSetLastDDEMLError(
  298. DWORD error)
  299. {
  300. PCHANDLEENTRY phe;
  301. CheckDDECritIn;
  302. if (!cHandlesAllocated) {
  303. return;
  304. }
  305. phe = &aHandleEntry[cHandlesAllocated];
  306. do {
  307. phe--;
  308. if (phe->handle != 0 && TypeFromHandle(phe->handle) == HTYPE_INSTANCE) {
  309. SetLastDDEMLError((PCL_INSTANCE_INFO)phe->dwData, error);
  310. }
  311. } while (phe != aHandleEntry);
  312. }