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.

373 lines
10 KiB

  1. /*++ BUILD Version: 0001
  2. *
  3. * WOW v1.0
  4. *
  5. * Copyright (c) 1991, Microsoft Corporation
  6. *
  7. * WMMALIAS.C
  8. * WOW32 16-bit handle alias support
  9. *
  10. * History:
  11. * Created Sept-1-1992 by Chandan Chauhan (ChandanC)
  12. * Modified 12-May-1992 by Mike Tricker (miketri) to add MultiMedia support
  13. --*/
  14. #include "precomp.h"
  15. #pragma hdrstop
  16. #include "wmmalias.h"
  17. MODNAME(wmmalias.c);
  18. HINFO hiMMedia; // MultiMedia handle alias info - MikeTri 12-May-1992
  19. HINFO hiWinsock; // Winsock handle alias info - DavidTr 4-Oct-1992
  20. #ifdef DEBUG
  21. INT nAliases;
  22. #endif
  23. INT iLargestListSlot;
  24. extern CRITICAL_SECTION mmHandleCriticalSection;
  25. #ifdef DEBUG
  26. extern BOOL fSkipLog; // TRUE to temporarily skip certain logging
  27. #endif
  28. /*
  29. * Added MultiMedia functions - MikeTri 12-May-1992
  30. */
  31. HAND16 GetMMedia16(HAND32 h32, INT iClass)
  32. {
  33. PHMAP phm;
  34. EnterCriticalSection( &mmHandleCriticalSection );
  35. if (phm = FindHMap32(h32, &hiMMedia, iClass)) {
  36. LeaveCriticalSection( &mmHandleCriticalSection );
  37. return phm->h16;
  38. }
  39. LeaveCriticalSection( &mmHandleCriticalSection );
  40. return (HAND16)h32;
  41. }
  42. VOID FreeMMedia16(HAND16 h16)
  43. {
  44. EnterCriticalSection( &mmHandleCriticalSection );
  45. FreeHMap16(h16, &hiMMedia);
  46. LeaveCriticalSection( &mmHandleCriticalSection );
  47. }
  48. HAND32 GetMMedia32(HAND16 h16)
  49. {
  50. PHMAP phm;
  51. EnterCriticalSection( &mmHandleCriticalSection );
  52. if (phm = FindHMap16(h16, &hiMMedia)) {
  53. LeaveCriticalSection( &mmHandleCriticalSection );
  54. return phm->h32;
  55. }
  56. LeaveCriticalSection( &mmHandleCriticalSection );
  57. return NULL;
  58. // return (HAND32)INT32(h16);
  59. }
  60. PHMAP FindHMap32(HAND32 h32, PHINFO phi, INT iClass)
  61. {
  62. INT iHash;
  63. #ifndef NEWALIAS
  64. INT iList, iListEmpty;
  65. #endif
  66. register PHMAP phm, phmPrev, phmEmpty;
  67. if (!h32 || (INT)h32 == 0xFFFF || (INT)h32 == -1)
  68. return NULL;
  69. // If we don't have a hash table yet, allocate one
  70. if (!phi->pphmHash) {
  71. if (!(phi->pphmHash = malloc_w(HASH_SLOTS*sizeof(PHMAP)))) {
  72. LOGDEBUG(0,(" FindHMap32 ERROR: cannot allocate hash table\n"));
  73. return NULL;
  74. }
  75. RtlZeroMemory(phi->pphmHash, HASH_SLOTS*sizeof(PHMAP));
  76. }
  77. // Compute the index into the hash table, and retrieve from it
  78. // the initial HMAP pointer
  79. iHash = HASH32(h32);
  80. phmPrev = (PHMAP)(phi->pphmHash + iHash);
  81. // Start walking the HMAP list, looking for a match (and keeping
  82. // track of any free entries we may find in case we decide to reuse it)
  83. #ifndef NEWALIAS
  84. iList = 1;
  85. #endif
  86. phmEmpty = NULL;
  87. while (phm = phmPrev->phmNext) {
  88. if (MASK32(phm->h32) == MASK32(h32)) {
  89. break;
  90. }
  91. if (phm->h32 == NULL && !phmEmpty) {
  92. phmEmpty = phm;
  93. #ifndef NEWALIAS
  94. iListEmpty = iList;
  95. #endif
  96. }
  97. phmPrev = phm;
  98. #ifndef NEWALIAS
  99. iList++;
  100. #endif
  101. }
  102. // If we couldn't find a match but we did find an empty HMAP structure
  103. // on the list, reuse it
  104. if (!phm && phmEmpty) {
  105. phm = phmEmpty;
  106. #ifndef NEWALIAS
  107. iList = iListEmpty;
  108. #endif
  109. }
  110. // If we have to allocate a new HMAP, here's where we do it
  111. if (!phm) {
  112. #ifndef NEWALIAS
  113. if (iList > LIST_SLOTS) {
  114. LOGDEBUG(0,(" FindHMap32 ERROR: out of list slots for hash slot %d\n", iHash));
  115. return NULL;
  116. }
  117. #else
  118. // If we don't have an alias table yet, allocate one
  119. if (!phi->pphmAlias) {
  120. if (!(phi->pphmAlias = malloc_w(ALIAS_SLOTS*sizeof(PHMAP)))) {
  121. LOGDEBUG(0,(" FindHMap32 ERROR: cannot allocate alias table\n"));
  122. return NULL;
  123. }
  124. RtlZeroMemory(phi->pphmAlias, ALIAS_SLOTS*sizeof(PHMAP));
  125. phi->nAliasEntries = ALIAS_SLOTS;
  126. }
  127. // If the current hint is in use, then look for the next free one
  128. if (phi->pphmAlias[phi->iAliasHint] &&
  129. !((INT)phi->pphmAlias[phi->iAliasHint]&1)) {
  130. INT i;
  131. LOGDEBUG(13,(" FindHMap32: alias hint failed, scanning...\n"));
  132. for (i=phi->iAliasHint+1; i<phi->nAliasEntries; i++) {
  133. if (!phi->pphmAlias[i] || ((INT)phi->pphmAlias[i]&1))
  134. goto Break;
  135. }
  136. for (i=0; i<phi->iAliasHint; i++) {
  137. if (!phi->pphmAlias[i] || ((INT)phi->pphmAlias[i]&1))
  138. goto Break;
  139. }
  140. Break:
  141. phi->iAliasHint = i;
  142. // If we've exhausted all the slots in the existing table, grow it
  143. if (phi->pphmAlias[i] && !((INT)phi->pphmAlias[i]&1)) {
  144. PPHMAP p;
  145. if (phi->nAliasEntries >= (1<<(16-RES_BITS))) {
  146. LOGDEBUG(0,(" FindHMap32 ERROR: at 16-bit handle limit\n"));
  147. return NULL;
  148. }
  149. LOGDEBUG(1,(" FindHMap32: growing handle alias array\n"));
  150. if (!(p = realloc(phi->pphmAlias, (phi->nAliasEntries+ALIAS_SLOTS)*sizeof(PHMAP)))) {
  151. LOGDEBUG(0,(" FindHMap32 ERROR: cannot grow alias table\n"));
  152. return NULL;
  153. }
  154. phi->pphmAlias = p;
  155. RtlZeroMemory(phi->pphmAlias+phi->nAliasEntries, ALIAS_SLOTS*sizeof(PHMAP));
  156. phi->iAliasHint = phi->nAliasEntries;
  157. phi->nAliasEntries += ALIAS_SLOTS;
  158. }
  159. }
  160. #endif
  161. phm = malloc_w(sizeof(HMAP));
  162. if (!phm) {
  163. LOGDEBUG(0,(" FindHMap32 ERROR: cannot allocate new list entry\n"));
  164. return NULL;
  165. }
  166. phm->h32 = NULL;
  167. #ifdef NEWALIAS
  168. // Record the new list entry in the alias table
  169. phm->h16 = (HAND16)(++phi->iAliasHint << RES_BITS);
  170. if (phi->iAliasHint >= phi->nAliasEntries)
  171. phi->iAliasHint = 0;
  172. // New entries can simply be inserted at the head of the list,
  173. // because their position in the list has no relationship to the aliases
  174. phm->phmNext = phi->pphmHash[iHash];
  175. phi->pphmHash[iHash] = phm;
  176. #else
  177. #ifdef DEBUG
  178. nAliases++;
  179. if (iList > iLargestListSlot) {
  180. iLargestListSlot = iList;
  181. LOGDEBUG(1,(" FindHMap32: largest list slot is now %d\n", iLargestListSlot));
  182. }
  183. #endif
  184. phm->h16 = (HAND16)((iHash | (iList << HASH_BITS)) << RES_BITS);
  185. // New entries must be appended rather than inserted, because
  186. // our phoney 16-bit handles are dependent on position in the list
  187. phm->phmNext = NULL;
  188. phmPrev->phmNext = phm;
  189. #endif
  190. }
  191. // If this a new entry, initialize it
  192. if (!phm->h32) {
  193. #ifdef DEBUG
  194. if (!fSkipLog) {
  195. LOGDEBUG(7,(" Adding %s alias %04x for %08lx\n",
  196. GetHMapNameM(phi, iClass), phm->h16, h32));
  197. }
  198. #endif
  199. // Insure that the alias pointer is valid
  200. #ifdef NEWALIAS
  201. phi->pphmAlias[(phm->h16>>RES_BITS)-1] = phm;
  202. #endif
  203. phm->h32 = h32;
  204. phm->htask16 = FETCHWORD(CURRENTPTD()->htask16);
  205. phm->iClass = iClass;
  206. phm->dwStyle = 0;
  207. phm->vpfnWndProc = 0;
  208. phm->pwcd = 0;
  209. }
  210. return phm;
  211. }
  212. PHMAP FindHMap16(HAND16 h16, PHINFO phi)
  213. {
  214. #ifndef NEWALIAS
  215. INT i, iHash, iList;
  216. #endif
  217. register PHMAP phm;
  218. #ifdef HACK32
  219. static HMAP hmDummy = {NULL, NULL, 0, 0, 0, 0, NULL, 0};
  220. #endif
  221. if (!h16 || h16 == 0xFFFF)
  222. return NULL;
  223. #ifdef HACK32
  224. if (h16 == TRUE)
  225. return &hmDummy;
  226. #endif
  227. // Verify all the RES_BITS are clear
  228. if (h16 & ((1 << RES_BITS)-1)) {
  229. WOW32ASSERT(FALSE);
  230. return NULL;
  231. }
  232. h16 >>= RES_BITS;
  233. #ifdef NEWALIAS
  234. // Verify the handle is within range
  235. WOW32ASSERT((INT)h16 <= phi->nAliasEntries);
  236. // This can happen if we haven't allocated any aliases yet
  237. if (!phi->pphmAlias)
  238. return NULL;
  239. phm = phi->pphmAlias[h16-1];
  240. if ((INT)phm & 1) {
  241. (INT)phm &= ~1;
  242. LOGDEBUG(0,(" FindHMap16 WARNING: defunct alias %04x reused\n", h16<<RES_BITS));
  243. }
  244. #else
  245. iHash = h16 & HASH_MASK;
  246. iList = (h16 & LIST_MASK) >> HASH_BITS;
  247. phm = (PHMAP)(phi->pphmHash + iHash);
  248. i = iList;
  249. while (i-- && phm) {
  250. phm = phm->phmNext;
  251. }
  252. #endif
  253. if (!phm) {
  254. LOGDEBUG(0,(" FindHMap16 ERROR: could not find %04x\n", h16<<RES_BITS));
  255. return NULL;
  256. }
  257. // Verify requested handle is same as stored in alias
  258. if (h16 != (HAND16)(phm->h16>>RES_BITS)) {
  259. LOGDEBUG(0, ("FindHMap16: Got bad H16\n"));
  260. WOW32ASSERT(FALSE);
  261. return NULL;
  262. }
  263. #ifdef DEBUG
  264. if (!fSkipLog) {
  265. LOGDEBUG(9,(" Found %s %08lx for alias %04x\n",
  266. GetHMapNameM(phi, phm->iClass), phm->h32, h16<<RES_BITS));
  267. }
  268. #endif
  269. return phm;
  270. }
  271. VOID FreeHMap16(HAND16 h16, PHINFO phi)
  272. {
  273. register PHMAP phm;
  274. if (phm = FindHMap16(h16, phi)) {
  275. LOGDEBUG(7,(" Freeing %s alias %04x for %08lx\n",
  276. GetHMapNameM(phi, phm->iClass), phm->h16, phm->h32));
  277. // if (phm->iClass == WOWCLASS_WIN16)
  278. // phm->pwcd->nWindows--;
  279. // BUGBUG -- We'll eventually want some garbage collection... -JTP
  280. phm->h32 = NULL;
  281. #ifdef NEWALIAS
  282. // We don't want to totally zap the alias' hmap pointer yet, because
  283. // if we're dealing with an app that is using cached handles after
  284. // it has technically freed them, we want to try to reassociate their
  285. // handle with a new 32-bit handle. So we'll just set the low bit
  286. // of the alias hmap pointer and leave the hint index alone; we will
  287. // still try to reuse entries with the low bit set however.
  288. //
  289. // phi->iAliasHint = (h16>>RES_BITS)-1;
  290. // phi->pphmAlias[phi->iAliasHint] = NULL;
  291. (INT)phi->pphmAlias[(h16>>RES_BITS)-1] |= 1;
  292. #endif
  293. return;
  294. }
  295. LOGDEBUG(1,(" FreeHMap16: handle alias %04x not found\n"));
  296. }
  297. PSZ GetHMapNameM(PHINFO phi, INT iClass)
  298. {
  299. return "MMEDIA";
  300. }