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.

1163 lines
34 KiB

  1. //*****************************************************************************
  2. //
  3. // Cursor and Icon compatibility Support -
  4. //
  5. // Support for apps - which do a GlobalLock on Cursors and Icons to
  6. // create headaches for us.
  7. //
  8. // A compatibility issue.
  9. //
  10. //
  11. // 21-Apr-92 NanduriR Created.
  12. //
  13. //*****************************************************************************
  14. #include "precomp.h"
  15. #pragma hdrstop
  16. MODNAME(wcuricon.c);
  17. extern void FreeAccelAliasEntry(LPACCELALIAS lpT);
  18. LPCURSORICONALIAS lpCIAlias = NULL;
  19. UINT cPendingCursorIconUpdates = 0;
  20. //*****************************************************************************
  21. //
  22. // W32CreateCursorIcon32 -
  23. //
  24. // Creates a 32bit Cursor or Icon given a WIN31 Cursor or Icon HANDLE.
  25. // The Cursor of Icon handle must correspond to an object that has
  26. // been created (like CreateIcon). That is because the format of a
  27. // resource cursor differs from that of a 'created' cursor.
  28. //
  29. // Returns the 32bit handle
  30. //
  31. //*****************************************************************************
  32. HANDLE W32CreateCursorIcon32(LPCURSORICONALIAS lpCIAliasIn)
  33. {
  34. HANDLE hT;
  35. PCURSORSHAPE16 pcurs16;
  36. UINT flType;
  37. int nWidth;
  38. int nHeight;
  39. int nPlanes;
  40. int nBitsPixel;
  41. DWORD nBytesAND;
  42. LPBYTE lpBitsAND;
  43. LPBYTE lpBitsXOR;
  44. int ScanLen16;
  45. pcurs16 = (PCURSORSHAPE16)lpCIAliasIn->pbDataNew;
  46. flType = lpCIAliasIn->flType;
  47. if (flType & HANDLE_TYPE_UNKNOWN) {
  48. if (PROBABLYCURSOR(FETCHWORD(pcurs16->BitsPixel),
  49. FETCHWORD(pcurs16->Planes)))
  50. flType = HANDLE_TYPE_CURSOR;
  51. else
  52. flType = HANDLE_TYPE_ICON;
  53. }
  54. nWidth = INT32(FETCHWORD(pcurs16->cx));
  55. nHeight = INT32(FETCHWORD(pcurs16->cy));
  56. nPlanes = 1;
  57. nBitsPixel = 1; // Monochrome
  58. // Get the AND mask bits
  59. ScanLen16 = (((nWidth*nBitsPixel)+15)/16) * 2 ; // bytes/scan in 16 bit world
  60. // effectively nBitsPixel is 1
  61. nBytesAND = ScanLen16*nHeight*nPlanes;
  62. lpBitsAND = (LPBYTE)pcurs16 + sizeof(CURSORSHAPE16);
  63. // Get the XOR mask bits
  64. if (flType == HANDLE_TYPE_ICON) {
  65. nPlanes = INT32(FETCHWORD(pcurs16->Planes));
  66. nBitsPixel = INT32(FETCHWORD(pcurs16->BitsPixel)); // the actual value
  67. }
  68. lpBitsXOR = (LPBYTE)lpBitsAND + nBytesAND;
  69. lpCIAliasIn->flType = (BYTE)flType;
  70. if (flType & HANDLE_TYPE_CURSOR) {
  71. hT = CreateCursor(HMODINST32(lpCIAliasIn->hInst16),
  72. (INT)FETCHWORD(pcurs16->xHotSpot),
  73. (INT)FETCHWORD(pcurs16->yHotSpot),
  74. nWidth, nHeight, lpBitsAND, lpBitsXOR);
  75. }
  76. else if (flType & HANDLE_TYPE_ICON) {
  77. hT = CreateIcon(HMODINST32(lpCIAliasIn->hInst16), nWidth, nHeight,
  78. (BYTE)nPlanes, (BYTE)nBitsPixel, lpBitsAND, lpBitsXOR);
  79. }
  80. return hT;
  81. }
  82. //*****************************************************************************
  83. //
  84. // W32Create16BitCursorIcon -
  85. //
  86. // Creates a WIN31 compatible Cursor or Icon given the full 16bit
  87. // definition of the object to be created.
  88. //
  89. //
  90. //*****************************************************************************
  91. HAND16 W32Create16BitCursorIcon(HAND16 hInst16, INT xHotSpot, INT yHotSpot,
  92. INT nWidth, INT nHeight,
  93. INT nPlanes, INT nBitsPixel,
  94. LPBYTE lpBitsAND, LPBYTE lpBitsXOR,
  95. INT nBytesAND, INT nBytesXOR )
  96. {
  97. WORD h16 = 0;
  98. WORD wTotalSize;
  99. PCURSORSHAPE16 pcshape16;
  100. VPVOID vp;
  101. LPBYTE lpT;
  102. UNREFERENCED_PARAMETER(hInst16);
  103. wTotalSize = (WORD)(sizeof(CURSORSHAPE16) + nBytesAND + nBytesXOR);
  104. vp = GlobalAllocLock16(GMEM_MOVEABLE | GMEM_ZEROINIT | GMEM_SHARE,
  105. wTotalSize, &h16);
  106. if (vp != (VPVOID)NULL) {
  107. GETVDMPTR(vp, wTotalSize, pcshape16);
  108. STOREWORD(pcshape16->xHotSpot, xHotSpot);
  109. STOREWORD(pcshape16->yHotSpot, yHotSpot);
  110. STOREWORD(pcshape16->cx, nWidth);
  111. STOREWORD(pcshape16->cy, nHeight);
  112. STOREWORD(pcshape16->cbWidth, (((nWidth + 0x0F) & ~0x0F) >> 3));
  113. pcshape16->Planes = (BYTE)nPlanes;
  114. pcshape16->BitsPixel = (BYTE)nBitsPixel;
  115. lpT = (LPBYTE)pcshape16 + sizeof(CURSORSHAPE16);
  116. RtlCopyMemory(lpT, lpBitsAND, nBytesAND);
  117. RtlCopyMemory(lpT+nBytesAND, lpBitsXOR, nBytesXOR);
  118. FLUSHVDMPTR(vp, wTotalSize, pcshape16);
  119. FREEVDMPTR(pcshape16);
  120. }
  121. GlobalUnlock16(h16);
  122. return (HAND16)h16;
  123. }
  124. //*****************************************************************************
  125. //
  126. // GetCursorIconAlias32 -
  127. //
  128. // Returns a 32bit handle given a 16bit Cursor or Icon HANDLE
  129. // Creates the 32bit Cursor or Icon if necessary.
  130. //
  131. // Returns the 32bit handle
  132. //
  133. //*****************************************************************************
  134. HANDLE GetCursorIconAlias32(HAND16 h16, UINT flType)
  135. {
  136. LPCURSORICONALIAS lpT;
  137. VPVOID vp;
  138. UINT cb;
  139. PCURSORSHAPE16 pcurs16;
  140. if (h16 == (HAND16)0)
  141. return (ULONG)NULL;
  142. lpT = FindCursorIconAlias((ULONG)h16, HANDLE_16BIT);
  143. if (lpT) {
  144. return lpT->h32;
  145. }
  146. else {
  147. //
  148. // BEGIN: Check for Bogus handle
  149. //
  150. if (BOGUSHANDLE(h16))
  151. return (HANDLE)NULL;
  152. #if defined(FE_SB)
  153. //In Excel95, XLVISEX.EXE use wrong cursor handle
  154. //that is already freed. So, we double check this handle
  155. //whether it is valid or not. 09/27/96 bklee.
  156. if (!FindCursorIconAliasInUse((ULONG)h16))
  157. return (HANDLE)NULL;
  158. #endif
  159. vp = RealLockResource16(h16, (PINT)&cb);
  160. if (vp == (VPVOID)NULL)
  161. return (ULONG)NULL;
  162. GETVDMPTR(vp, cb, pcurs16);
  163. if (pcurs16->cbWidth != (SHORT)(((pcurs16->cx + 0x0f) & ~0x0f) >> 3))
  164. return (ULONG)NULL;
  165. //
  166. // END: Check for Bogus handle
  167. //
  168. lpT = AllocCursorIconAlias();
  169. if (!lpT) {
  170. return (ULONG)NULL;
  171. }
  172. lpT->h16 = h16;
  173. lpT->hTask16 = CURRENTPTD()->htask16;
  174. lpT->vpData = vp;
  175. lpT->cbData = (WORD)cb;
  176. lpT->pbDataNew = (LPBYTE)pcurs16;
  177. lpT->pbDataOld = malloc_w(cb);
  178. if (lpT->pbDataOld) {
  179. RtlCopyMemory(lpT->pbDataOld, lpT->pbDataNew, cb);
  180. }
  181. lpT->h32 = (HAND32)W32CreateCursorIcon32(lpT);
  182. GlobalUnlock16(h16);
  183. FREEVDMPTR(pcurs16);
  184. lpT->pbDataNew = (LPBYTE)NULL;
  185. if (lpT->h32) {
  186. lpT->fInUse = TRUE;
  187. SetCursorIconFlag(h16, TRUE);
  188. }
  189. else
  190. lpT->fInUse = FALSE;
  191. return lpT->h32;
  192. }
  193. }
  194. //*****************************************************************************
  195. //
  196. // GetCursorIconAlias16 -
  197. //
  198. // Returns a 16bit handle given a 32bit Cursor or Icon HANDLE
  199. // Creates the 16bit Cursor or Icon if necessary.
  200. //
  201. // Returns the 16bit handle
  202. //
  203. //*****************************************************************************
  204. HAND16 GetCursorIconAlias16(HAND32 h32, UINT flType)
  205. {
  206. LPCURSORICONALIAS lpT;
  207. if (h32 == (HAND32)0)
  208. return (HAND16)NULL;
  209. lpT = FindCursorIconAlias((ULONG)h32, HANDLE_32BIT);
  210. if (lpT) {
  211. return lpT->h16;
  212. }
  213. else {
  214. HAND16 h16;
  215. // HACK:
  216. // From experience: numeric values of 32bit standard cursors and icons
  217. // are very small. so check for these handles.
  218. // we should not create aliases for standard cursors and
  219. // icons here.
  220. WOW32ASSERT((UINT)h32 >= 100);
  221. //
  222. // Always generate valid handles.
  223. //
  224. h16 = W32Create16BitCursorIconFrom32BitHandle(h32, (HAND16)NULL,
  225. (PUINT)NULL);
  226. if (h16) {
  227. h16 = SetupCursorIconAlias((HAND16)NULL, h32, h16, flType,
  228. NULL, (WORD)NULL);
  229. }
  230. return h16;
  231. }
  232. }
  233. //*****************************************************************************
  234. //
  235. // AllocCursorIconAlias -
  236. //
  237. // Allocates and reurns pointer to CURSORICONALIAS buffer.
  238. //
  239. //*****************************************************************************
  240. LPCURSORICONALIAS AllocCursorIconAlias()
  241. {
  242. LPCURSORICONALIAS lpT;
  243. for (lpT = lpCIAlias; lpT != NULL; lpT = lpT->lpNext) {
  244. if (!lpT->fInUse)
  245. break;
  246. }
  247. if (lpT == NULL) {
  248. lpT = (LPCURSORICONALIAS)malloc_w_small(sizeof(CURSORICONALIAS));
  249. if (lpT) {
  250. lpT->lpNext = lpCIAlias;
  251. lpCIAlias = lpT;
  252. }
  253. else {
  254. LOGDEBUG(0, ("AllocCursorIconAlias: malloc_w_small for alias failed\n"));
  255. }
  256. }
  257. if (lpT != NULL) {
  258. lpT->fInUse = TRUE;
  259. lpT->h16 = (HAND16)0;
  260. lpT->h32 = (HAND32)0;
  261. lpT->vpData = (VPVOID)NULL;
  262. lpT->cLock = 0;
  263. lpT->cbData = 0;
  264. lpT->pbDataOld = (LPBYTE)NULL;
  265. lpT->pbDataNew = (LPBYTE)NULL;
  266. lpT->lpszName = (LPBYTE)NULL;
  267. lpT->flType = HANDLE_TYPE_UNKNOWN;
  268. lpT->hInst16 = (HAND16)0;
  269. lpT->hMod16 = (HAND16)0;
  270. lpT->hTask16 = (HTASK16)0;
  271. lpT->hRes16 = 0;
  272. }
  273. return lpT;
  274. }
  275. //*****************************************************************************
  276. //
  277. // FindCursorIconAlias -
  278. //
  279. // Searches for the given handle and returns corresponding
  280. // LPCURSORICONALIAS.
  281. //
  282. //*****************************************************************************
  283. LPCURSORICONALIAS FindCursorIconAlias(ULONG hCI, UINT flHandleSize)
  284. {
  285. LPCURSORICONALIAS lpT;
  286. LPCURSORICONALIAS lpTprev;
  287. lpTprev = (LPCURSORICONALIAS)NULL;
  288. for (lpT = lpCIAlias; lpT != NULL; lpTprev = lpT, lpT = lpT->lpNext) {
  289. if (lpT->fInUse) {
  290. if ((flHandleSize == HANDLE_16BIT && lpT->h16 == (HAND16)hCI) ||
  291. (flHandleSize == HANDLE_32BIT && lpT->h32 == (HAND32)hCI))
  292. break;
  293. else if (flHandleSize == HANDLE_16BITRES && lpT->hRes16 &&
  294. (lpT->hRes16 == (HAND16)hCI))
  295. break;
  296. }
  297. }
  298. if (lpT) {
  299. if (lpTprev) {
  300. lpTprev->lpNext = lpT->lpNext;
  301. lpT->lpNext = lpCIAlias;
  302. lpCIAlias = lpT;
  303. }
  304. }
  305. return lpT;
  306. }
  307. #if defined(FE_SB)
  308. //*****************************************************************************
  309. //
  310. // FindCursorIconAliasInUse -
  311. //
  312. // Searches for the given handle and returns corresponding
  313. // lpT->fInUse.
  314. //
  315. // 09/27/96 bklee
  316. //*****************************************************************************
  317. BOOL FindCursorIconAliasInUse(ULONG hCI)
  318. {
  319. LPCURSORICONALIAS lpT;
  320. LPCURSORICONALIAS lpTprev;
  321. lpTprev = (LPCURSORICONALIAS)NULL;
  322. for (lpT = lpCIAlias; lpT != NULL; lpTprev = lpT, lpT = lpT->lpNext) {
  323. if (lpT->h16 == (HAND16)hCI)
  324. return lpT->fInUse;
  325. }
  326. return TRUE;
  327. }
  328. #endif
  329. //*****************************************************************************
  330. //
  331. // DeleteCursorIconAlias -
  332. //
  333. // Searches for the given handle and if a 16bit handle frees the memory
  334. // allocated for the Object. The alias table is not freed.
  335. //
  336. //*****************************************************************************
  337. BOOL DeleteCursorIconAlias(ULONG hCI, UINT flHandleSize)
  338. {
  339. LPCURSORICONALIAS lpT;
  340. WOW32ASSERT(flHandleSize == HANDLE_16BIT);
  341. for (lpT = lpCIAlias; lpT != NULL; lpT = lpT->lpNext) {
  342. if (lpT->fInUse && !(lpT->flType & HANDLE_TYPE_WOWGLOBAL)) {
  343. // Have we found the handle mapping?
  344. if (flHandleSize == HANDLE_16BIT && lpT->h16 == (HAND16)hCI) {
  345. if (lpT->hTask16) {
  346. // We don't want to free the handle mapping when
  347. // the handle corresponds to a 16-bit resource, i.e.
  348. // hRes16 is non-null.
  349. if (!(lpT->hRes16)) {
  350. SetCursorIconFlag(lpT->h16, FALSE);
  351. GlobalUnlockFree16(RealLockResource16((HMEM16)hCI, NULL));
  352. free_w(lpT->pbDataOld);
  353. lpT->fInUse = FALSE;
  354. return TRUE;
  355. }
  356. }
  357. else {
  358. WOW32ASSERT(FALSE);
  359. }
  360. break;
  361. }
  362. }
  363. }
  364. return FALSE;
  365. }
  366. //*****************************************************************************
  367. //
  368. // FreeCursorIconAlias -
  369. //
  370. // Frees all Cursors and Icons of the specified task.
  371. //
  372. //
  373. //*****************************************************************************
  374. BOOL FreeCursorIconAlias(HAND16 hand16, ULONG ulFlags)
  375. {
  376. LPCURSORICONALIAS lpT;
  377. for (lpT = lpCIAlias; lpT != NULL; lpT = lpT->lpNext) {
  378. if (lpT->fInUse &&
  379. (((ulFlags & CIALIAS_HMOD) && (lpT->hMod16 == hand16)) ||
  380. ((ulFlags & CIALIAS_HTASK) && (lpT->hTask16 == hand16)))) {
  381. if (ulFlags & CIALIAS_TASKISGONE) {
  382. // We're here if this function is called after the task
  383. // cleanup on the 16bit side... then we really can't
  384. // callback. Setting appropriate fields to NULL will
  385. // avoid callbacks, but will leak the corresponding
  386. // memory. The asserts will catch this on a checked
  387. // build.
  388. WOW32ASSERT(lpT->h16==(HAND16)NULL);
  389. WOW32ASSERT(lpT->hRes16==(HAND16)NULL);
  390. lpT->h16 = (HAND16)NULL;
  391. lpT->hRes16 = (HAND16)NULL;
  392. }
  393. InvalidateCursorIconAlias(lpT);
  394. }
  395. }
  396. return TRUE;
  397. }
  398. //*****************************************************************************
  399. //
  400. // SetupCursorIconAlias -
  401. //
  402. // Sets up association (alias) between a 32bit and a 16bit handle.
  403. // given both the handles.
  404. //
  405. //
  406. //*****************************************************************************
  407. HAND16 SetupCursorIconAlias(HAND16 hInst16, HAND32 h32, HAND16 h16, UINT flType,
  408. LPBYTE lpResName, WORD hRes16)
  409. {
  410. LPCURSORICONALIAS lpT;
  411. VPVOID vp;
  412. INT cb;
  413. lpT = AllocCursorIconAlias();
  414. // paranoid check for memory exaust
  415. if (!lpT) {
  416. return (HAND16)NULL;
  417. }
  418. lpT->fInUse = TRUE;
  419. lpT->h16 = h16;
  420. lpT->h32 = h32;
  421. lpT->flType = (BYTE)flType;
  422. if (!(flType & HANDLE_TYPE_WOWGLOBAL)) {
  423. lpT->hInst16 = hInst16;
  424. lpT->hMod16 = GETHMOD16(HMODINST32(hInst16));
  425. lpT->hTask16 = CURRENTPTD()->htask16;
  426. lpT->hRes16 = hRes16;
  427. vp = RealLockResource16(h16, &cb);
  428. if (vp == (VPVOID)NULL)
  429. return (HAND16)NULL;
  430. lpT->vpData = vp;
  431. lpT->cbData = (WORD)cb;
  432. GETVDMPTR(vp, cb, lpT->pbDataNew);
  433. lpT->pbDataOld = malloc_w(cb);
  434. if (lpT->pbDataOld) {
  435. RtlCopyMemory(lpT->pbDataOld, lpT->pbDataNew, cb);
  436. }
  437. if (hRes16) {
  438. lpT->lpszName = lpResName;
  439. // if this is a string...
  440. if ((WORD)HIWORD(lpResName) != (WORD)NULL) {
  441. UINT cbStr;
  442. cbStr = strlen(lpResName)+1;
  443. // note: strlen+1 will force memcpy to copy the null from the
  444. // src string.
  445. if (lpT->lpszName = malloc_w_small(cbStr)) {
  446. memcpy (lpT->lpszName, lpResName, cbStr);
  447. }
  448. }
  449. }
  450. }
  451. // the alias has been setup. Now turn on the GAH_CURSORICON flag.
  452. SetCursorIconFlag(h16, TRUE);
  453. return h16;
  454. }
  455. //*****************************************************************************
  456. //
  457. // SetupResCursorIconAlias -
  458. //
  459. // Sets up association (alias) between a 32bit and a 16bit handle.
  460. // given the 32bit handle and a handle to a 16bit resource.
  461. //
  462. //
  463. //*****************************************************************************
  464. HAND16 SetupResCursorIconAlias(HAND16 hInst16, HAND32 h32, LPBYTE lpResName, WORD hRes16, UINT flType)
  465. {
  466. LPCURSORICONALIAS lpT;
  467. HAND16 h16 = 0;
  468. HAND16 h16Res = 0;
  469. UINT cb;
  470. if (hRes16) {
  471. // 16bit resource has been loaded. We always want to return the
  472. // SAME 16bit handle no matter howmany times the 'LoadIcon' or
  473. // LoadCursor has been called.
  474. h16Res = LOWORD(hRes16);
  475. lpT = FindCursorIconAlias(h16Res, HANDLE_16BITRES);
  476. }
  477. else {
  478. // Resource handle is NULL. The Resource must have been a
  479. // standard predefined resource like ARROW etc.
  480. lpT = FindCursorIconAlias((ULONG)h32, HANDLE_32BIT);
  481. flType |= HANDLE_TYPE_WOWGLOBAL;
  482. }
  483. if (lpT == NULL) {
  484. h16 = W32Create16BitCursorIconFrom32BitHandle(h32, hInst16, &cb);
  485. h16 = SetupCursorIconAlias(hInst16, h32, h16, flType, lpResName, hRes16);
  486. }
  487. else {
  488. if (lpT->flType & HANDLE_TYPE_WOWGLOBAL) {
  489. // eachtime we should get the same h32 from usersrv.
  490. //
  491. WOW32ASSERT(lpT->h32 == h32);
  492. }
  493. else {
  494. if (lpT->h32 != h32) {
  495. if (lpT->flType == HANDLE_TYPE_CURSOR)
  496. DestroyCursor(h32);
  497. else
  498. DestroyIcon(h32);
  499. }
  500. ReplaceCursorIcon(lpT);
  501. }
  502. h16 = lpT->h16;
  503. }
  504. return h16;
  505. }
  506. //*****************************************************************************
  507. //
  508. // SetCursorIconFlag -
  509. //
  510. // Sets/Clears the GAH_CURSORICONFLAG in the global arean header. This flag
  511. // is used to identify Cursors and Icon when they are GlobaLocked and
  512. // GlobalUnlocked
  513. //
  514. //*****************************************************************************
  515. ULONG SetCursorIconFlag(HAND16 h16, BOOL fSet)
  516. {
  517. PARM16 Parm16;
  518. VPVOID vp = 0;
  519. Parm16.WndProc.wParam = h16;
  520. Parm16.WndProc.wMsg = (WORD)fSet;
  521. CallBack16(RET_SETCURSORICONFLAG, &Parm16, 0, &vp);
  522. return (ULONG)0;
  523. }
  524. //*****************************************************************************
  525. //
  526. // UpdateCursorIcon -
  527. //
  528. // Compares the new object data with the old. If any of the bytes differ
  529. // the old object is replaced with the new.
  530. //
  531. //*****************************************************************************
  532. VOID UpdateCursorIcon()
  533. {
  534. LPCURSORICONALIAS lpT;
  535. UINT cbData;
  536. LPBYTE lpBitsNew, lpBitsOld;
  537. UINT i = 0;
  538. for (lpT = lpCIAlias; lpT != NULL ; lpT = lpT->lpNext) {
  539. if (lpT->fInUse && lpT->cLock) {
  540. GETVDMPTR(lpT->vpData, lpT->cbData, lpT->pbDataNew);
  541. if (lpT->hRes16) {
  542. if (lpT->flType == HANDLE_TYPE_ICON) {
  543. lpBitsNew = lpT->pbDataNew + sizeof(BITMAPINFOHEADER16);
  544. lpBitsOld = lpT->pbDataOld + sizeof(BITMAPINFOHEADER16);
  545. cbData = lpT->cbData - sizeof(BITMAPINFOHEADER16);
  546. }
  547. else {
  548. lpBitsNew = lpT->pbDataNew + sizeof(CURSORRESOURCE16);
  549. lpBitsOld = lpT->pbDataOld + sizeof(CURSORRESOURCE16);
  550. cbData = lpT->cbData - sizeof(CURSORRESOURCE16);
  551. }
  552. }
  553. else {
  554. lpBitsNew = lpT->pbDataNew + sizeof(CURSORSHAPE16);
  555. lpBitsOld = lpT->pbDataOld + sizeof(CURSORSHAPE16);
  556. cbData = lpT->cbData - sizeof(CURSORSHAPE16);
  557. }
  558. if (! RtlEqualMemory(lpBitsNew, lpBitsOld, cbData))
  559. ReplaceCursorIcon(lpT);
  560. if (cPendingCursorIconUpdates == ++i)
  561. break;
  562. }
  563. }
  564. }
  565. //*****************************************************************************
  566. //
  567. // ReplaceCursorIcon -
  568. //
  569. // Updates the current cursor or icon. Creates a new icon or cursor and
  570. // replaces the contents of the old handle with that of the new.
  571. //
  572. // returns TRUE for success.
  573. //
  574. //*****************************************************************************
  575. BOOL ReplaceCursorIcon(LPCURSORICONALIAS lpIn)
  576. {
  577. HANDLE hT32;
  578. if (lpIn != NULL) {
  579. // Get the data
  580. GETVDMPTR(lpIn->vpData, lpIn->cbData, lpIn->pbDataNew);
  581. // Create the object
  582. hT32 = (HAND32)W32CreateCursorIcon32(lpIn);
  583. // SetCursorConents will replace the contents of OLD cursor/icon
  584. // with that of the new handle and destroy the new handle
  585. SetCursorContents(lpIn->h32, hT32);
  586. // replace the old object data with the new
  587. RtlCopyMemory(lpIn->pbDataOld, lpIn->pbDataNew, lpIn->cbData);
  588. FREEVDMPTR(lpIn->pbDataNew);
  589. lpIn->pbDataNew = (LPBYTE)NULL;
  590. }
  591. return (BOOL)TRUE;
  592. }
  593. //*****************************************************************************
  594. //
  595. // WK32WowCursorIconOp -
  596. //
  597. // Gets called when/from GlobalLock or GlobalUnlock are called. The fLock
  598. // flag is TRUE if called from GlobalLock else it is FALSE.
  599. //
  600. //*****************************************************************************
  601. BOOL FASTCALL WK32WowCursorIconOp(PVDMFRAME pFrame)
  602. {
  603. PWOWCURSORICONOP16 prci16;
  604. HAND16 h16;
  605. LPCURSORICONALIAS lpT;
  606. BOOL fLock;
  607. WORD wFuncId;
  608. UINT cLockT;
  609. GETARGPTR(pFrame, sizeof(WOWCURSORICONOP16), prci16);
  610. wFuncId = FETCHWORD(prci16->wFuncId);
  611. h16 = (HAND16)FETCHWORD(prci16->h16);
  612. lpT = FindCursorIconAlias((ULONG)h16, HANDLE_16BIT);
  613. // This is a Cursor or Icon
  614. if (lpT != NULL) {
  615. if (wFuncId == FUN_GLOBALLOCK || wFuncId == FUN_GLOBALUNLOCK) {
  616. if (!(lpT->flType & HANDLE_TYPE_WOWGLOBAL)) {
  617. fLock = (wFuncId == FUN_GLOBALLOCK);
  618. // Store the current lockcount.
  619. cLockT = lpT->cLock;
  620. // Update the Lock count
  621. lpT->cLock = fLock ? ++lpT->cLock : --lpT->cLock;
  622. if (lpT->cLock == 0) {
  623. // New lock count == 0 implies that it was decremented from
  624. // 1 to 0 thereby impling that it was one of the cursors that
  625. // was being updated regularly.
  626. // Decrement the global count and update the cursor one last
  627. // time
  628. cPendingCursorIconUpdates--;
  629. ReplaceCursorIcon(lpT);
  630. }
  631. else if (fLock && cLockT == 0) {
  632. // If previous Lockcount was zero and the object is being locked
  633. // then it means that this is the very first time that the object
  634. // is being locked
  635. cPendingCursorIconUpdates++;
  636. }
  637. }
  638. }
  639. else if (wFuncId == FUN_GLOBALFREE) {
  640. // The h16 has not yet been GlobalFreed. We return TRUE if h16 can
  641. // be freed else FALSE. The h16 can be freed only if it is not a
  642. // global handle. ie, it doesn't correspond to a predefined cursor
  643. // Also we donot free the handle if h16 corresponds to a resource.
  644. // CorelDraw 3.0 calls FreeResource(h16) and then SetCursor(h16)
  645. // thus GPing.
  646. BOOL fFree;
  647. fFree = !((lpT->flType & HANDLE_TYPE_WOWGLOBAL) || lpT->hRes16);
  648. if (fFree) {
  649. // Set handle to NULL so that InvalidateCursorIconAlias
  650. // doesn't try to free it.
  651. lpT->h16 = 0;
  652. InvalidateCursorIconAlias(lpT);
  653. }
  654. return (BOOL)fFree;
  655. }
  656. else {
  657. LOGDEBUG(0, ("WK32WowCursorIconOp: Unknown Func Id\n"));
  658. }
  659. }
  660. // else if this is a GlobalFree call
  661. else if (wFuncId == FUN_GLOBALFREE) {
  662. // and if this is a handle to an accelerator
  663. if(lpT = (LPCURSORICONALIAS)FindAccelAlias((HANDLE)h16, HANDLE_16BIT)) {
  664. // free it from the accelerator alias list
  665. FreeAccelAliasEntry((LPACCELALIAS) lpT);
  666. // cause this hMem16 to really be free'd in 16-bit GlobalFree
  667. return TRUE;
  668. }
  669. }
  670. return TRUE;
  671. }
  672. //*****************************************************************************
  673. //
  674. // W32Create16BitResCursorIconFrom32BitHandle -
  675. //
  676. // Creates a WIN31 compatible Cursor or Icon given a 32bit cursor or icon
  677. // handle. This is primarily used to create a 16bit Cursor or Icon which
  678. // has been loaded from a 16bit resource.
  679. //
  680. //
  681. // returns 16bit handle
  682. //*****************************************************************************
  683. HAND16 W32Create16BitCursorIconFrom32BitHandle(HANDLE h32, HAND16 hInst16,
  684. PUINT pcbData)
  685. {
  686. HAND16 h16 = 0;
  687. ICONINFO iinfo;
  688. BITMAP bm;
  689. BITMAP bmClr;
  690. UINT nBytesAND = 0;
  691. UINT nBytesXOR = 0;
  692. LPBYTE lpBitsAND, lpBitsXOR;
  693. if (GetIconInfo(h32, &iinfo)) {
  694. if (GetObject(iinfo.hbmMask, sizeof(BITMAP), &bm)) {
  695. nBytesAND = GetBitmapBits(iinfo.hbmMask, 0, (LPBYTE)NULL);
  696. WOW32WARNMSG(nBytesAND,("WOW: W32C16BCIFBH: nBytesAND == 0\n"));
  697. if (iinfo.hbmColor) {
  698. GetObject(iinfo.hbmColor, sizeof(BITMAP), &bmClr);
  699. nBytesXOR = GetBitmapBits(iinfo.hbmColor, 0, (LPBYTE)NULL);
  700. WOW32WARNMSG(nBytesXOR,("WOW: W32C16BCIFBH: nBytesAND == 0\n"));
  701. }
  702. else {
  703. bm.bmHeight /= 2;
  704. nBytesAND /= 2;
  705. nBytesXOR = nBytesAND;
  706. }
  707. if (pcbData) {
  708. *pcbData = nBytesAND + nBytesXOR + sizeof(CURSORSHAPE16);
  709. }
  710. lpBitsAND = malloc_w(nBytesAND + nBytesXOR);
  711. if (lpBitsAND != NULL) {
  712. lpBitsXOR = lpBitsAND + nBytesAND;
  713. GetBitmapBits(iinfo.hbmMask,
  714. (iinfo.hbmColor) ? nBytesAND : (nBytesAND * 2),
  715. lpBitsAND);
  716. if (iinfo.hbmColor)
  717. GetBitmapBits(iinfo.hbmColor, nBytesXOR, lpBitsXOR);
  718. h16 = W32Create16BitCursorIcon(hInst16,
  719. iinfo.xHotspot, iinfo.yHotspot,
  720. bm.bmWidth, bm.bmHeight,
  721. (iinfo.hbmColor) ? bmClr.bmPlanes :
  722. bm.bmPlanes,
  723. (iinfo.hbmColor) ? bmClr.bmBitsPixel :
  724. bm.bmBitsPixel,
  725. lpBitsAND, lpBitsXOR,
  726. (INT)nBytesAND, (INT)nBytesXOR);
  727. free_w(lpBitsAND);
  728. }
  729. }
  730. DeleteObject(iinfo.hbmMask);
  731. if (iinfo.hbmColor) {
  732. DeleteObject(iinfo.hbmColor);
  733. }
  734. }
  735. return h16;
  736. }
  737. //*****************************************************************************
  738. //
  739. // GetClassCursorIconAlias32 -
  740. //
  741. // Returns a 32bit handle given a 16bit Cursor or Icon HANDLE
  742. // DOES NOT Create the 32bit Cursor or Icon if there is no alias.
  743. // This is called in RegisterClass only - to support those apps which
  744. // pass a bogus handle for WNDCLASS.hIcon.
  745. //
  746. // Returns the 32bit handle
  747. //
  748. //*****************************************************************************
  749. HANDLE GetClassCursorIconAlias32(HAND16 h16)
  750. {
  751. LPCURSORICONALIAS lpT;
  752. if (h16 == (HAND16)0)
  753. return (ULONG)NULL;
  754. lpT = FindCursorIconAlias((ULONG)h16, HANDLE_16BIT);
  755. if (lpT) {
  756. return lpT->h32;
  757. }
  758. else
  759. return (HANDLE)NULL;
  760. }
  761. //*****************************************************************************
  762. //
  763. // InvalidateCursorIconAlias -
  764. //
  765. // Frees the allocated objects.
  766. //
  767. //*****************************************************************************
  768. VOID InvalidateCursorIconAlias(LPCURSORICONALIAS lpT)
  769. {
  770. VPVOID vp=0;
  771. PARM16 Parm16;
  772. if (!lpT->fInUse)
  773. return;
  774. if (lpT->h16) {
  775. SetCursorIconFlag(lpT->h16, FALSE);
  776. GlobalUnlockFree16(RealLockResource16((HMEM16)lpT->h16, NULL));
  777. }
  778. if (lpT->hRes16) {
  779. Parm16.WndProc.wParam = (HAND16) lpT->hRes16;
  780. CallBack16(RET_FREERESOURCE, &Parm16, 0, &vp);
  781. }
  782. if (lpT->h32) {
  783. if (lpT->flType == HANDLE_TYPE_CURSOR)
  784. DestroyCursor(lpT->h32);
  785. else
  786. DestroyIcon(lpT->h32);
  787. }
  788. if (lpT->pbDataOld)
  789. free_w(lpT->pbDataOld);
  790. if (lpT->cLock)
  791. cPendingCursorIconUpdates--;
  792. if ((WORD)HIWORD(lpT->lpszName) != (WORD)NULL) {
  793. free_w_small ((PVOID)lpT->lpszName);
  794. }
  795. lpT->fInUse = FALSE;
  796. }
  797. //*****************************************************************************
  798. //
  799. // InitStdCursorIconAlias -
  800. //
  801. // Creates the aliases of standard cursors and icons.
  802. //
  803. // NOTES:
  804. //
  805. // The idea is to createaliases for all the standard cursors and icons to
  806. // make sure that we indeed generate valid handles.
  807. //
  808. // This problem cameup because of the following scenario
  809. // the app turbotax does the following:
  810. //
  811. // h16Cursor1 = GetClassWord(hwndEditControl, GCL_HCURSOR);
  812. // (bydefault, this is an I-beam)
  813. // .....
  814. // h16Cursor2 = LoadCursor(NULL, IDC_IBEAM);
  815. // Because of the way we create and maintain our 32-16 alias hCursor1 is a
  816. // a WOW bogus handle (ie > 0xf000) and since by default the "Edit" class is
  817. // registered with hCursor = IDC_IBEAM, the h32s are same ie.
  818. //
  819. // GetClassWord(hwndEditControl, GCL_HCURSOR) == LoadCursor(..IDC_IBEAM);
  820. //
  821. // Thus h16Cursor2 will be same as h16Cursor1 and that's a problem because we
  822. // are NOT returning a valid wow handle for a predefined cursor.
  823. //
  824. //
  825. // The solution is to createaliases for all standard cursors and icons during
  826. // init time so that we don't run into this problem. However I think this
  827. // approach as wasteful and am creating the alias for the only known case
  828. // ie IDC_IBEAM.
  829. //
  830. // - Nanduri Ramakrishna
  831. //*****************************************************************************
  832. DWORD InitCursorIds[] = {
  833. (DWORD)IDC_ARROW,
  834. (DWORD)IDC_IBEAM,
  835. (DWORD)IDC_WAIT,
  836. (DWORD)IDC_CROSS,
  837. (DWORD)IDC_UPARROW,
  838. (DWORD)IDC_SIZE,
  839. (DWORD)IDC_ICON,
  840. (DWORD)IDC_SIZENWSE,
  841. (DWORD)IDC_SIZENESW,
  842. (DWORD)IDC_SIZEWE,
  843. (DWORD)IDC_SIZENS
  844. };
  845. BOOL InitStdCursorIconAlias()
  846. {
  847. HCURSOR h32;
  848. UINT i;
  849. for (i = 0; i < (sizeof(InitCursorIds) / sizeof(DWORD)); i++) {
  850. //
  851. // Create the alias for each standard cursor in the list
  852. //
  853. h32 = (HCURSOR)LoadCursor((HINSTANCE)NULL, (LPCSTR)InitCursorIds[i]);
  854. WOW32ASSERT(h32);
  855. if (h32) {
  856. SetupResCursorIconAlias((HAND16)NULL, (HAND32)h32, NULL, (WORD)NULL,
  857. HANDLE_TYPE_CURSOR);
  858. }
  859. }
  860. //
  861. // Add similar lines for standard icons.
  862. //
  863. return TRUE;
  864. }
  865. //*****************************************************************************
  866. //
  867. // W32CheckIfAlreadyLoaded -
  868. //
  869. // returns h16 if a cursoricon has previously been loaded.
  870. //
  871. //*****************************************************************************
  872. HAND16 W32CheckIfAlreadyLoaded(VPVOID pData, WORD ResType)
  873. {
  874. LPCURSORICONALIAS lpT;
  875. PICONCUR16 parg16;
  876. PSZ psz;
  877. GETMISCPTR(pData, parg16);
  878. GETPSZIDPTR(parg16->lpStr, psz);
  879. ResType = (ResType == NW_LOADCURSOR) ? HANDLE_TYPE_CURSOR : HANDLE_TYPE_ICON;
  880. for (lpT = lpCIAlias; lpT != NULL; lpT = lpT->lpNext) {
  881. if (lpT->fInUse) {
  882. LPBYTE lpszNameT = lpT->lpszName;
  883. if (lpszNameT && (lpT->flType & ResType) &&
  884. lpT->hInst16 == parg16->hInst) {
  885. WOW32ASSERT(!(lpT->flType & HANDLE_TYPE_WOWGLOBAL));
  886. if (HIWORD(lpszNameT) && HIWORD(psz)) {
  887. if (!(WOW32_stricmp(psz, (LPSTR)lpszNameT)))
  888. break;
  889. }
  890. else if (lpszNameT == psz) {
  891. break;
  892. }
  893. }
  894. }
  895. }
  896. FREEPSZIDPTR(psz);
  897. FREEMISCPTR(parg16);
  898. if (lpT && lpT->cLock)
  899. ReplaceCursorIcon(lpT);
  900. return (lpT ? lpT->h16 : 0);
  901. }