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.

2071 lines
66 KiB

  1. //*****************************************************************************
  2. //
  3. // HOOKS -
  4. //
  5. // 32bit stubs and thunks for 16bit hooks
  6. //
  7. //
  8. // 01-07-92 NanduriR Created.
  9. //
  10. //*****************************************************************************
  11. #include "precomp.h"
  12. #pragma hdrstop
  13. MODNAME(wowhooks.c);
  14. //*****************************************************************************
  15. //
  16. // Global data. Data is valid only in WOW process context. DLL Data is not
  17. // Shared amongst various processes. If a WOW hook is set WIN32 USER will call
  18. // the hookproc in the context of the thread that has the hook set. This implies
  19. // that all the global data in this DLL is acessible by every WOW thread.
  20. //
  21. // Just reaffirming: since USER will call the hookprocs in our process/thread
  22. // context there is no need for this data to be available
  23. // in shared memory.
  24. //
  25. //*****************************************************************************
  26. HOOKPERPROCESSDATA vaHookPPData = { NULL, 0};
  27. //
  28. // In SetWindowsHook we return an index into this array if it was
  29. // successful. Since NULL implies an error, we cannot use the Zeroth element
  30. // in this array. So we set its 'InUse' flag to TRUE.
  31. //
  32. HOOKSTATEDATA vaHookStateData[] = {
  33. 0, TRUE, 0, NULL, (HKPROC)NULL, 0, 0, 0, NULL,
  34. 0, FALSE, 0, NULL, (HKPROC)WU32SubStdHookProc01,0, 0, 0, NULL,
  35. 0, FALSE, 0, NULL, (HKPROC)WU32SubStdHookProc02,0, 0, 0, NULL,
  36. 0, FALSE, 0, NULL, (HKPROC)WU32SubStdHookProc03,0, 0, 0, NULL,
  37. 0, FALSE, 0, NULL, (HKPROC)WU32SubStdHookProc04,0, 0, 0, NULL,
  38. 0, FALSE, 0, NULL, (HKPROC)WU32SubStdHookProc05,0, 0, 0, NULL,
  39. 0, FALSE, 0, NULL, (HKPROC)WU32SubStdHookProc06,0, 0, 0, NULL,
  40. 0, FALSE, 0, NULL, (HKPROC)WU32SubStdHookProc07,0, 0, 0, NULL,
  41. 0, FALSE, 0, NULL, (HKPROC)WU32SubStdHookProc08,0, 0, 0, NULL,
  42. 0, FALSE, 0, NULL, (HKPROC)WU32SubStdHookProc09,0, 0, 0, NULL,
  43. 0, FALSE, 0, NULL, (HKPROC)WU32SubStdHookProc10,0, 0, 0, NULL,
  44. 0, FALSE, 0, NULL, (HKPROC)WU32SubStdHookProc11,0, 0, 0, NULL,
  45. 0, FALSE, 0, NULL, (HKPROC)WU32SubStdHookProc12,0, 0, 0, NULL,
  46. 0, FALSE, 0, NULL, (HKPROC)WU32SubStdHookProc13,0, 0, 0, NULL,
  47. 0, FALSE, 0, NULL, (HKPROC)WU32SubStdHookProc14,0, 0, 0, NULL,
  48. 0, FALSE, 0, NULL, (HKPROC)WU32SubStdHookProc15,0, 0, 0, NULL,
  49. 0, FALSE, 0, NULL, (HKPROC)WU32SubStdHookProc16,0, 0, 0, NULL,
  50. 0, FALSE, 0, NULL, (HKPROC)WU32SubStdHookProc17,0, 0, 0, NULL,
  51. 0, FALSE, 0, NULL, (HKPROC)WU32SubStdHookProc18,0, 0, 0, NULL,
  52. 0, FALSE, 0, NULL, (HKPROC)WU32SubStdHookProc19,0, 0, 0, NULL,
  53. 0, FALSE, 0, NULL, (HKPROC)WU32SubStdHookProc20,0, 0, 0, NULL,
  54. 0, FALSE, 0, NULL, (HKPROC)WU32SubStdHookProc21,0, 0, 0, NULL,
  55. 0, FALSE, 0, NULL, (HKPROC)WU32SubStdHookProc22,0, 0, 0, NULL,
  56. 0, FALSE, 0, NULL, (HKPROC)WU32SubStdHookProc23,0, 0, 0, NULL,
  57. 0, FALSE, 0, NULL, (HKPROC)WU32SubStdHookProc24,0, 0, 0, NULL,
  58. 0, FALSE, 0, NULL, (HKPROC)WU32SubStdHookProc25,0, 0, 0, NULL,
  59. 0, FALSE, 0, NULL, (HKPROC)WU32SubStdHookProc26,0, 0, 0, NULL,
  60. 0, FALSE, 0, NULL, (HKPROC)WU32SubStdHookProc27,0, 0, 0, NULL,
  61. 0, FALSE, 0, NULL, (HKPROC)WU32SubStdHookProc28,0, 0, 0, NULL,
  62. 0, FALSE, 0, NULL, (HKPROC)WU32SubStdHookProc29,0, 0, 0, NULL,
  63. 0, FALSE, 0, NULL, (HKPROC)WU32SubStdHookProc30,0, 0, 0, NULL,
  64. 0, FALSE, 0, NULL, (HKPROC)WU32SubStdHookProc31,0, 0, 0, NULL,
  65. 0, FALSE, 0, NULL, (HKPROC)WU32SubStdHookProc32,0, 0, 0, NULL
  66. };
  67. HOOKPARAMS vHookParams = {0, 0, 0};
  68. INT viCurrentHookStateDataIndex = 0;
  69. // this is used when 'DefHookProc' is called.
  70. //*****************************************************************************
  71. // Sub-Standard Hook Procs -
  72. //
  73. // Hook Stubs. The 'index' (the fourth parameter) is an index into the
  74. // the HookStateData array. All needed info is available in this array.
  75. // The hook stubs need to be exported.
  76. //
  77. //*****************************************************************************
  78. LONG APIENTRY WU32SubStdHookProc01(INT nCode, LONG wParam, LONG lParam)
  79. {
  80. return WU32StdHookProc(nCode, wParam, lParam, 0x01);
  81. }
  82. LONG APIENTRY WU32SubStdHookProc02(INT nCode, LONG wParam, LONG lParam)
  83. {
  84. return WU32StdHookProc(nCode, wParam, lParam, 0x02);
  85. }
  86. LONG APIENTRY WU32SubStdHookProc03(INT nCode, LONG wParam, LONG lParam)
  87. {
  88. return WU32StdHookProc(nCode, wParam, lParam, 0x03);
  89. }
  90. LONG APIENTRY WU32SubStdHookProc04(INT nCode, LONG wParam, LONG lParam)
  91. {
  92. return WU32StdHookProc(nCode, wParam, lParam, 0x04);
  93. }
  94. LONG APIENTRY WU32SubStdHookProc05(INT nCode, LONG wParam, LONG lParam)
  95. {
  96. return WU32StdHookProc(nCode, wParam, lParam, 0x05);
  97. }
  98. LONG APIENTRY WU32SubStdHookProc06(INT nCode, LONG wParam, LONG lParam)
  99. {
  100. return WU32StdHookProc(nCode, wParam, lParam, 0x06);
  101. }
  102. LONG APIENTRY WU32SubStdHookProc07(INT nCode, LONG wParam, LONG lParam)
  103. {
  104. return WU32StdHookProc(nCode, wParam, lParam, 0x07);
  105. }
  106. LONG APIENTRY WU32SubStdHookProc08(INT nCode, LONG wParam, LONG lParam)
  107. {
  108. return WU32StdHookProc(nCode, wParam, lParam, 0x08);
  109. }
  110. LONG APIENTRY WU32SubStdHookProc09(INT nCode, LONG wParam, LONG lParam)
  111. {
  112. return WU32StdHookProc(nCode, wParam, lParam, 0x09);
  113. }
  114. LONG APIENTRY WU32SubStdHookProc10(INT nCode, LONG wParam, LONG lParam)
  115. {
  116. return WU32StdHookProc(nCode, wParam, lParam, 0x0a);
  117. }
  118. LONG APIENTRY WU32SubStdHookProc11(INT nCode, LONG wParam, LONG lParam)
  119. {
  120. return WU32StdHookProc(nCode, wParam, lParam, 0x0b);
  121. }
  122. LONG APIENTRY WU32SubStdHookProc12(INT nCode, LONG wParam, LONG lParam)
  123. {
  124. return WU32StdHookProc(nCode, wParam, lParam, 0x0c);
  125. }
  126. LONG APIENTRY WU32SubStdHookProc13(INT nCode, LONG wParam, LONG lParam)
  127. {
  128. return WU32StdHookProc(nCode, wParam, lParam, 0x0d);
  129. }
  130. LONG APIENTRY WU32SubStdHookProc14(INT nCode, LONG wParam, LONG lParam)
  131. {
  132. return WU32StdHookProc(nCode, wParam, lParam, 0x0e);
  133. }
  134. LONG APIENTRY WU32SubStdHookProc15(INT nCode, LONG wParam, LONG lParam)
  135. {
  136. return WU32StdHookProc(nCode, wParam, lParam, 0x0f);
  137. }
  138. LONG APIENTRY WU32SubStdHookProc16(INT nCode, LONG wParam, LONG lParam)
  139. {
  140. return WU32StdHookProc(nCode, wParam, lParam, 0x10);
  141. }
  142. LONG APIENTRY WU32SubStdHookProc17(INT nCode, LONG wParam, LONG lParam)
  143. {
  144. return WU32StdHookProc(nCode, wParam, lParam, 0x11);
  145. }
  146. LONG APIENTRY WU32SubStdHookProc18(INT nCode, LONG wParam, LONG lParam)
  147. {
  148. return WU32StdHookProc(nCode, wParam, lParam, 0x12);
  149. }
  150. LONG APIENTRY WU32SubStdHookProc19(INT nCode, LONG wParam, LONG lParam)
  151. {
  152. return WU32StdHookProc(nCode, wParam, lParam, 0x13);
  153. }
  154. LONG APIENTRY WU32SubStdHookProc20(INT nCode, LONG wParam, LONG lParam)
  155. {
  156. return WU32StdHookProc(nCode, wParam, lParam, 0x14);
  157. }
  158. LONG APIENTRY WU32SubStdHookProc21(INT nCode, LONG wParam, LONG lParam)
  159. {
  160. return WU32StdHookProc(nCode, wParam, lParam, 0x15);
  161. }
  162. LONG APIENTRY WU32SubStdHookProc22(INT nCode, LONG wParam, LONG lParam)
  163. {
  164. return WU32StdHookProc(nCode, wParam, lParam, 0x16);
  165. }
  166. LONG APIENTRY WU32SubStdHookProc23(INT nCode, LONG wParam, LONG lParam)
  167. {
  168. return WU32StdHookProc(nCode, wParam, lParam, 0x17);
  169. }
  170. LONG APIENTRY WU32SubStdHookProc24(INT nCode, LONG wParam, LONG lParam)
  171. {
  172. return WU32StdHookProc(nCode, wParam, lParam, 0x18);
  173. }
  174. LONG APIENTRY WU32SubStdHookProc25(INT nCode, LONG wParam, LONG lParam)
  175. {
  176. return WU32StdHookProc(nCode, wParam, lParam, 0x19);
  177. }
  178. LONG APIENTRY WU32SubStdHookProc26(INT nCode, LONG wParam, LONG lParam)
  179. {
  180. return WU32StdHookProc(nCode, wParam, lParam, 0x1a);
  181. }
  182. LONG APIENTRY WU32SubStdHookProc27(INT nCode, LONG wParam, LONG lParam)
  183. {
  184. return WU32StdHookProc(nCode, wParam, lParam, 0x1b);
  185. }
  186. LONG APIENTRY WU32SubStdHookProc28(INT nCode, LONG wParam, LONG lParam)
  187. {
  188. return WU32StdHookProc(nCode, wParam, lParam, 0x1c);
  189. }
  190. LONG APIENTRY WU32SubStdHookProc29(INT nCode, LONG wParam, LONG lParam)
  191. {
  192. return WU32StdHookProc(nCode, wParam, lParam, 0x1d);
  193. }
  194. LONG APIENTRY WU32SubStdHookProc30(INT nCode, LONG wParam, LONG lParam)
  195. {
  196. return WU32StdHookProc(nCode, wParam, lParam, 0x1e);
  197. }
  198. LONG APIENTRY WU32SubStdHookProc31(INT nCode, LONG wParam, LONG lParam)
  199. {
  200. return WU32StdHookProc(nCode, wParam, lParam, 0x1f);
  201. }
  202. LONG APIENTRY WU32SubStdHookProc32(INT nCode, LONG wParam, LONG lParam)
  203. {
  204. return WU32StdHookProc(nCode, wParam, lParam, 0x20);
  205. }
  206. //*****************************************************************************
  207. // W32InitHookState:
  208. //
  209. // Initializes the global data. Note that this data is initialized for every
  210. // Process that loads this DLL. However data that is visible only to the 'WOW'
  211. // process is what we care about.
  212. //
  213. //*****************************************************************************
  214. BOOL W32InitHookState(HANDLE hMod)
  215. {
  216. INT i;
  217. vaHookPPData.hMod = hMod;
  218. vaHookPPData.cHookProcs = sizeof(vaHookStateData) /
  219. sizeof(vaHookStateData[0]);
  220. for (i = 0; i < vaHookPPData.cHookProcs; i++) {
  221. vaHookStateData[i].iIndex = (BYTE)i;
  222. vaHookStateData[i].hMod = hMod;
  223. }
  224. return TRUE;
  225. }
  226. //*****************************************************************************
  227. // W32GetNotInUseHookStateData:
  228. //
  229. // Steps through the Global HookStateData and returns a pointer to an 'unused'
  230. // element. This is called only when the Hook is being Set.
  231. //
  232. //*****************************************************************************
  233. BOOL W32GetNotInUseHookStateData(LPHOOKSTATEDATA lpData)
  234. {
  235. INT i;
  236. for (i = 0; i < vaHookPPData.cHookProcs; i++) {
  237. if (!vaHookStateData[i].InUse) {
  238. vaHookStateData[i].InUse = TRUE;
  239. *lpData = vaHookStateData[i];
  240. return TRUE;
  241. }
  242. }
  243. LOGDEBUG(LOG_ALWAYS, ("W32GetNotInUseHookStateData: All thunk hook procs in use.\n"));
  244. return FALSE;
  245. }
  246. //*****************************************************************************
  247. // W32SetHookStateData:
  248. //
  249. // Writes into the global data structure at the specified index.
  250. //
  251. //*****************************************************************************
  252. BOOL W32SetHookStateData(LPHOOKSTATEDATA lpData)
  253. {
  254. vaHookStateData[lpData->iIndex] = *lpData;
  255. return TRUE;
  256. }
  257. //*****************************************************************************
  258. // W32GetHookStateData:
  259. //
  260. // Retrieves data from the global data structure at the specified index.
  261. //
  262. //*****************************************************************************
  263. BOOL W32GetHookStateData(LPHOOKSTATEDATA lpData)
  264. {
  265. if ( lpData->iIndex >= 0 && lpData->iIndex < vaHookPPData.cHookProcs ) {
  266. *lpData = vaHookStateData[lpData->iIndex];
  267. return TRUE;
  268. } else {
  269. return FALSE;
  270. }
  271. }
  272. //*****************************************************************************
  273. // W32GetThunkHookProc:
  274. //
  275. // Its callled to find a 32stub for the hook that is being set.
  276. // Returns TRUE if successful else FALSE.
  277. // The data is partially updated to reflect the characteristics of the hook
  278. // that is being set.
  279. //
  280. //*****************************************************************************
  281. BOOL W32GetThunkHookProc(INT iHook, DWORD Proc16, LPHOOKSTATEDATA lpData)
  282. {
  283. register PTD ptd = CURRENTPTD();
  284. if (W32GetNotInUseHookStateData(lpData)) {
  285. lpData->iHook = iHook;
  286. lpData->Proc16 = Proc16;
  287. lpData->TaskId = ptd->htask16 ;
  288. W32SetHookStateData(lpData);
  289. return TRUE;
  290. }
  291. else
  292. return FALSE;
  293. }
  294. //*****************************************************************************
  295. // W32IsDuplicateHook:
  296. //
  297. // Verifies if the given hook has already been set. This is to catch
  298. // certain apps which go on Setting the same hook without Unhooking the
  299. // previous hook.
  300. //
  301. // Returns the 'stubindex' if hook already exists else 0;
  302. //
  303. //*****************************************************************************
  304. INT W32IsDuplicateHook(INT iHook, DWORD Proc16, INT TaskId)
  305. {
  306. INT i;
  307. for (i = 0; i < vaHookPPData.cHookProcs; i++) {
  308. if (vaHookStateData[i].InUse &&
  309. vaHookStateData[i].iHook == iHook &&
  310. vaHookStateData[i].TaskId == TaskId &&
  311. vaHookStateData[i].Proc16 == Proc16 ) {
  312. return i;
  313. }
  314. }
  315. return 0;
  316. }
  317. //*****************************************************************************
  318. // W32FreeHHook:
  319. //
  320. // The state of the specified hook is set to 'Not in use'.
  321. // Returns hHook of the hook being freed.
  322. //
  323. //*****************************************************************************
  324. HHOOK W32FreeHHook(INT iHook, DWORD Proc16)
  325. {
  326. register PTD ptd = CURRENTPTD();
  327. INT i;
  328. for (i = 0; i < vaHookPPData.cHookProcs; i++) {
  329. if (vaHookStateData[i].InUse &&
  330. vaHookStateData[i].iHook == iHook &&
  331. vaHookStateData[i].TaskId == (INT)ptd->htask16 &&
  332. vaHookStateData[i].Proc16 == Proc16) {
  333. vaHookStateData[i].InUse = FALSE;
  334. return vaHookStateData[i].hHook;
  335. }
  336. }
  337. LOGDEBUG(LOG_ALWAYS, ("W32FreeHHook: Couldn't locate the specified hook."));
  338. return (HHOOK)NULL;
  339. }
  340. //*****************************************************************************
  341. // W32FreeHHookOfIndex:
  342. //
  343. // The state of the specified hook is set to 'Not in use'.
  344. // Returns hHook of the hook being freed.
  345. //
  346. //*****************************************************************************
  347. HHOOK W32FreeHHookOfIndex(INT iFunc)
  348. {
  349. register PTD ptd = CURRENTPTD();
  350. if (iFunc && iFunc < vaHookPPData.cHookProcs)
  351. if (vaHookStateData[iFunc].InUse &&
  352. vaHookStateData[iFunc].TaskId == (INT)ptd->htask16) {
  353. vaHookStateData[iFunc].InUse = FALSE;
  354. return vaHookStateData[iFunc].hHook;
  355. }
  356. LOGDEBUG(LOG_ALWAYS, ("W32FreeHHookOfIndex: Couldn't locate the specified hook."));
  357. return (HHOOK)NULL;
  358. }
  359. //*****************************************************************************
  360. // W32GetHookParams:
  361. //
  362. // Returns the 32bit hookparams of the current hook.
  363. //
  364. //*****************************************************************************
  365. BOOL W32GetHookParams(LPHOOKPARAMS lpHookParams)
  366. {
  367. if (lpHookParams) {
  368. *lpHookParams = vHookParams;
  369. }
  370. return (BOOL)lpHookParams;
  371. }
  372. //*****************************************************************************
  373. // W32StdHookProc: (Standard Hook Proc)
  374. //
  375. // All the stubs call this proc.
  376. // Return value is dependent on the hook type.
  377. //
  378. //*****************************************************************************
  379. LONG APIENTRY WU32StdHookProc(INT nCode, LONG wParam, LONG lParam, INT iFunc)
  380. {
  381. //
  382. // USER will call us in WOW context. Just Verify.
  383. //
  384. if (!vaHookStateData[iFunc].InUse) {
  385. // DbgPrint("WU32StdHookProc:Stub %04x called in WRONG process\n", iFunc);
  386. return FALSE;
  387. }
  388. //
  389. // USER can call us even if we have GP Faulted - so just ignore the input
  390. //
  391. if (CURRENTPTD()->dwFlags & TDF_IGNOREINPUT) {
  392. LOGDEBUG(LOG_ALWAYS,("WU32StdHookProc Ignoring Input\n"));
  393. WOW32ASSERTMSG(gfIgnoreInputAssertGiven,
  394. "WU32StdHookProc: TDF_IGNOREINPUT hack was used, shouldn't be, "
  395. "please email DOSWOW with repro instructions. Hit 'g' to ignore this "
  396. "and suppress this assertion from now on.\n");
  397. gfIgnoreInputAssertGiven = TRUE;
  398. return FALSE;
  399. }
  400. //
  401. // store the stubindex. If the hookproc calls the DefHookProc() we will
  402. // be able to findout the Hook Type.
  403. //
  404. viCurrentHookStateDataIndex = iFunc;
  405. //
  406. // store the hook params. These will be used if DefHookProc gets called
  407. // by the 16bit stub. We are interested only in lParam.
  408. //
  409. vHookParams.nCode = nCode;
  410. vHookParams.wParam = wParam;
  411. vHookParams.lParam = lParam;
  412. switch (vaHookStateData[iFunc].iHook) {
  413. case WH_CALLWNDPROC:
  414. return ThunkCallWndProcHook(nCode, wParam, (LPCWPSTRUCT)lParam,
  415. &vaHookStateData[iFunc]);
  416. case WH_CBT:
  417. return ThunkCbtHook(nCode, wParam, lParam,
  418. &vaHookStateData[iFunc]);
  419. case WH_KEYBOARD:
  420. return ThunkKeyBoardHook(nCode, wParam, lParam,
  421. &vaHookStateData[iFunc]);
  422. case WH_MSGFILTER:
  423. // This code is TEMP only and must be fixed. ChandanC 5/2/92.
  424. if ((WORD)vaHookStateData[iFunc].TaskId !=
  425. (WORD)((PTD)CURRENTPTD())->htask16)
  426. break;
  427. WOW32ASSERT((WORD)vaHookStateData[iFunc].TaskId ==
  428. (WORD)((PTD)CURRENTPTD())->htask16);
  429. case WH_SYSMSGFILTER:
  430. case WH_GETMESSAGE:
  431. return ThunkMsgFilterHook(nCode, wParam, (LPMSG)lParam,
  432. &vaHookStateData[iFunc]);
  433. break;
  434. case WH_JOURNALPLAYBACK:
  435. case WH_JOURNALRECORD:
  436. return ThunkJournalHook(nCode, wParam, (LPEVENTMSG)lParam,
  437. &vaHookStateData[iFunc]);
  438. case WH_DEBUG:
  439. return ThunkDebugHook(nCode, wParam, lParam,
  440. &vaHookStateData[iFunc]);
  441. case WH_MOUSE:
  442. return ThunkMouseHook(nCode, wParam, (LPMOUSEHOOKSTRUCT)lParam,
  443. &vaHookStateData[iFunc]);
  444. case WH_SHELL:
  445. return ThunkShellHook(nCode, wParam, lParam,
  446. &vaHookStateData[iFunc]);
  447. default:
  448. LOGDEBUG(LOG_ALWAYS,("W32StdHookProc: Unknown Hook type."));
  449. }
  450. return (LONG)FALSE;
  451. }
  452. //*****************************************************************************
  453. //
  454. // ThunkHookProc for Hooks of type WH_CALLWNDPROC -
  455. //
  456. // Return type is VOID.
  457. //
  458. //*****************************************************************************
  459. LONG ThunkCallWndProcHook(INT nCode, LONG wParam, LPCWPSTRUCT lpCwpStruct,
  460. LPHOOKSTATEDATA lpHSData)
  461. {
  462. VPVOID vp;
  463. PCWPSTRUCT16 pCwpStruct16;
  464. PARM16 Parm16;
  465. WM32MSGPARAMEX wm32mpex;
  466. BOOL fMessageNeedsThunking;
  467. wm32mpex.Parm16.WndProc.wMsg = (WORD) lpCwpStruct->message;
  468. wm32mpex.Parm16.WndProc.wParam = (WORD) lpCwpStruct->wParam;
  469. wm32mpex.Parm16.WndProc.lParam = (LONG) lpCwpStruct->lParam;
  470. fMessageNeedsThunking = (lpCwpStruct->message < 0x400) &&
  471. (aw32Msg[lpCwpStruct->message].lpfnM32 != WM32NoThunking);
  472. // This call to stackalloc16() needs to occur before the call to the message
  473. // thunking function call below ((wm32mpex.lpfnM32)(&wm32mpex)) because the
  474. // message thunks for some messages may also call stackalloc16(). This will
  475. // ensure proper nesting of stackalloc16() & stackfree16() calls.
  476. // Be sure allocation size matches stackfree16() size below
  477. vp = stackalloc16(sizeof(CWPSTRUCT16));
  478. if (fMessageNeedsThunking) {
  479. LOGDEBUG(3,("%04X (%s)\n", CURRENTPTD()->htask16, (aw32Msg[lpCwpStruct->message].lpszW32)));
  480. wm32mpex.fThunk = THUNKMSG;
  481. wm32mpex.hwnd = lpCwpStruct->hwnd;
  482. wm32mpex.uMsg = lpCwpStruct->message;
  483. wm32mpex.uParam = lpCwpStruct->wParam;
  484. wm32mpex.lParam = lpCwpStruct->lParam;
  485. wm32mpex.lpfnM32 = aw32Msg[wm32mpex.uMsg].lpfnM32;
  486. wm32mpex.pww = (PWW)NULL;
  487. wm32mpex.fFree = TRUE;
  488. // note: this may call stackalloc16() and/or callback into 16-bit code
  489. if (!(wm32mpex.lpfnM32)(&wm32mpex)) {
  490. LOGDEBUG(LOG_ALWAYS,("ThunkCallWndProcHook: cannot thunk 32-bit message %04x\n",
  491. lpCwpStruct->message));
  492. }
  493. }
  494. // don't call GETMISCPTR(vp..) until after returning from the thunk function
  495. // above. If the thunk function calls back into 16-bit code, the flat ptr
  496. // for vp could become invalid.
  497. GETMISCPTR(vp, pCwpStruct16);
  498. if(pCwpStruct16) {
  499. STOREWORD(pCwpStruct16->hwnd, GETHWND16(lpCwpStruct->hwnd));
  500. STOREWORD(pCwpStruct16->message, wm32mpex.Parm16.WndProc.wMsg );
  501. STOREWORD(pCwpStruct16->wParam, wm32mpex.Parm16.WndProc.wParam);
  502. STORELONG(pCwpStruct16->lParam, wm32mpex.Parm16.WndProc.lParam);
  503. FLUSHVDMPTR(vp, sizeof(CWPSTRUCT16), pCwpStruct16);
  504. FREEVDMPTR(pCwpStruct16);
  505. }
  506. else {
  507. WOW32WARNMSG((FALSE),"WOW::ThunkCallWndProcHook:can't get flat pointer to struct!\n");
  508. }
  509. Parm16.HookProc.nCode = (SHORT)nCode;
  510. Parm16.HookProc.wParam = (SHORT)wParam;
  511. Parm16.HookProc.lParam = vp;
  512. CallBack16(RET_HOOKPROC, &Parm16, lpHSData->Proc16, (PVPVOID)&wm32mpex.lReturn);
  513. #ifdef DEBUG
  514. GETMISCPTR(vp, pCwpStruct16);
  515. if (pCwpStruct16->message != wm32mpex.Parm16.WndProc.wMsg)
  516. LOGDEBUG(LOG_ALWAYS,("ThunkCallWndProcHook: IN message != OUT message"));
  517. FREEVDMPTR(pCwpStruct16);
  518. #endif
  519. if (fMessageNeedsThunking) {
  520. wm32mpex.fThunk = UNTHUNKMSG;
  521. // Note: If the thunk of this message called stackalloc16() this unthunk
  522. // call should call stackfree16()
  523. (wm32mpex.lpfnM32)(&wm32mpex);
  524. }
  525. if(vp) {
  526. // this stackfree16() call must come after the above message unthunk
  527. // call to give the unthunk the opportunity to call stackfree16() also.
  528. // this will preserve proper nesting of stackalloc16 & stackfree16 calls
  529. stackfree16(vp, sizeof(CWPSTRUCT16));
  530. }
  531. return (LONG)FALSE; // return value doesn't matter
  532. }
  533. //*****************************************************************************
  534. //
  535. // ThunkHookProc for Hooks of type WH_CBT -
  536. //
  537. // Return type is BOOL.
  538. //
  539. //*****************************************************************************
  540. LONG ThunkCbtHook(INT nCode, LONG wParam, LONG lParam,
  541. LPHOOKSTATEDATA lpHSData)
  542. {
  543. LONG lReturn = FALSE;
  544. PARM16 Parm16;
  545. VPVOID vp;
  546. PMOUSEHOOKSTRUCT16 pMHStruct16;
  547. PCBTACTIVATESTRUCT16 pCbtAStruct16;
  548. VPCREATESTRUCT16 vpcs16;
  549. PCBT_CREATEWND16 pCbtCWnd16;
  550. WM32MSGPARAMEX wm32mpex;
  551. Parm16.HookProc.nCode = (SHORT)nCode;
  552. Parm16.HookProc.wParam = (SHORT)wParam;
  553. Parm16.HookProc.lParam = lParam;
  554. switch(nCode) {
  555. case HCBT_MOVESIZE:
  556. // wParam = HWND, lParam = LPRECT
  557. Parm16.HookProc.wParam = GETHWND16(wParam);
  558. // be sure allocation size matches stackfree16() size below
  559. vp = stackalloc16(sizeof(RECT16));
  560. PUTRECT16(vp, (LPRECT)lParam);
  561. Parm16.HookProc.lParam = vp;
  562. break;
  563. case HCBT_MINMAX:
  564. // wParam = HWND, lParam = SW_* --- a command
  565. Parm16.HookProc.wParam = GETHWND16(wParam);
  566. break;
  567. case HCBT_QS:
  568. // wParam = 0, lParam = 0
  569. break;
  570. case HCBT_CREATEWND:
  571. // This stackalloc16() call needs to occur before the WM32Create()
  572. // call below to ensure proper nesting of stackalloc16 & stackfree16
  573. // calls.
  574. // Be sure allocation size matches stackfree16() size(s) below
  575. vp = stackalloc16(sizeof(CBT_CREATEWND16));
  576. // wParam = HWND, lParam = LPCBT_CREATEWND
  577. wm32mpex.fThunk = THUNKMSG;
  578. wm32mpex.hwnd = (HWND)wParam;
  579. wm32mpex.uMsg = 0;
  580. wm32mpex.uParam = 0;
  581. wm32mpex.lParam = (LONG)((LPCBT_CREATEWND)lParam)->lpcs;
  582. wm32mpex.pww = (PWW)GetWindowLong((HWND)wParam, GWL_WOWWORDS);
  583. /*
  584. * WM32Create now requires that pww be initialized
  585. * WM32Create calls stackalloc16()!!
  586. */
  587. if (!wm32mpex.pww || !WM32Create(&wm32mpex)) {
  588. stackfree16(vp, sizeof(CBT_CREATEWND16));
  589. return FALSE;
  590. }
  591. vpcs16 = wm32mpex.Parm16.WndProc.lParam;
  592. lReturn = wm32mpex.lReturn;
  593. GETMISCPTR(vp, pCbtCWnd16);
  594. STOREDWORD(pCbtCWnd16->vpcs, vpcs16);
  595. STOREWORD(pCbtCWnd16->hwndInsertAfter,
  596. GETHWNDIA16(((LPCBT_CREATEWND)lParam)->hwndInsertAfter));
  597. Parm16.HookProc.wParam = GETHWND16(wParam);
  598. Parm16.HookProc.lParam = vp;
  599. FLUSHVDMPTR(vp, sizeof(CBT_CREATEWND16), pCbtCWnd16);
  600. FREEVDMPTR(pCbtCWnd16);
  601. break;
  602. case HCBT_DESTROYWND:
  603. // wParam = HWND, lParam = 0
  604. Parm16.HookProc.wParam = GETHWND16(wParam);
  605. break;
  606. case HCBT_ACTIVATE:
  607. // wParam = HWND, lParam = LPCBTACTIVATESTRUCT
  608. // be sure allocation size matches stackfree16() size below
  609. vp = stackalloc16(sizeof(CBTACTIVATESTRUCT16));
  610. GETMISCPTR(vp, pCbtAStruct16);
  611. PUTCBTACTIVATESTRUCT16(pCbtAStruct16, ((LPCBTACTIVATESTRUCT)lParam));
  612. Parm16.HookProc.wParam = GETHWND16(wParam);
  613. Parm16.HookProc.lParam = vp;
  614. FLUSHVDMPTR(vp, sizeof(CBTACTIVATESTRUCT16), pCbtAStruct16);
  615. FREEVDMPTR(pCbtAStruct16);
  616. break;
  617. case HCBT_CLICKSKIPPED:
  618. // wParam = mouse message, lParam = LPMOUSEHOOKSTRUCT
  619. // be sure allocation size matches stackfree16() size below
  620. vp = stackalloc16(sizeof(MOUSEHOOKSTRUCT16));
  621. GETMISCPTR(vp, pMHStruct16);
  622. PUTMOUSEHOOKSTRUCT16(pMHStruct16, (LPMOUSEHOOKSTRUCT)lParam);
  623. Parm16.HookProc.lParam = vp;
  624. FLUSHVDMPTR(vp, sizeof(MOUSEHOOKSTRUCT16), pMHStruct16);
  625. FREEVDMPTR(pMHStruct16);
  626. break;
  627. case HCBT_KEYSKIPPED:
  628. // wParam, lParam -- keyup/down message params
  629. break;
  630. case HCBT_SYSCOMMAND:
  631. // wParam = SC_ syscomand, lParam = DWORD(x,y)
  632. break;
  633. case HCBT_SETFOCUS:
  634. // wParam = HWND, lParam = HWND
  635. Parm16.HookProc.wParam = GETHWND16(wParam);
  636. Parm16.HookProc.lParam = GETHWND16(lParam);
  637. break;
  638. default:
  639. LOGDEBUG(LOG_ALWAYS, ("ThunkCbtHook: Unknown HCBT_ code\n"));
  640. break;
  641. }
  642. CallBack16(RET_HOOKPROC, &Parm16, lpHSData->Proc16, (PVPVOID)&lReturn);
  643. switch(nCode) {
  644. case HCBT_MOVESIZE:
  645. GETRECT16(vp, (LPRECT)lParam);
  646. stackfree16(vp, sizeof(RECT16));
  647. break;
  648. case HCBT_CREATEWND:
  649. GETMISCPTR(vp, pCbtCWnd16);
  650. ((LPCBT_CREATEWND)lParam)->hwndInsertAfter =
  651. HWNDIA32(FETCHWORD(pCbtCWnd16->hwndInsertAfter));
  652. FREEVDMPTR(pCbtCWnd16);
  653. wm32mpex.fThunk = UNTHUNKMSG;
  654. wm32mpex.lReturn = lReturn;
  655. WM32Create(&wm32mpex); // this calls stackfree16()!!!
  656. lReturn = wm32mpex.lReturn;
  657. // this must be after call to WM32Create()
  658. stackfree16(vp, sizeof(CBT_CREATEWND16));
  659. break;
  660. case HCBT_ACTIVATE:
  661. GETMISCPTR(vp, pCbtAStruct16);
  662. GETCBTACTIVATESTRUCT16(pCbtAStruct16, (LPCBTACTIVATESTRUCT)lParam);
  663. FREEVDMPTR(pCbtAStruct16);
  664. stackfree16(vp, sizeof(CBTACTIVATESTRUCT16));
  665. break;
  666. case HCBT_CLICKSKIPPED:
  667. GETMISCPTR(vp, pMHStruct16);
  668. GETMOUSEHOOKSTRUCT16(pMHStruct16, (LPMOUSEHOOKSTRUCT)lParam);
  669. FREEVDMPTR(pMHStruct16);
  670. stackfree16(vp, sizeof(MOUSEHOOKSTRUCT16));
  671. break;
  672. // case HCBT_MINMAX:
  673. // case HCBT_QS:
  674. // case HCBT_DESTROYWND:
  675. // case HCBT_KEYSKIPPED:
  676. // case HCBT_SYSCOMMAND:
  677. // case HCBT_SETFOCUS:
  678. default:
  679. break;
  680. }
  681. // the value in LOWORD is the valid return value
  682. return (LONG)(BOOL)LOWORD(lReturn);
  683. }
  684. //*****************************************************************************
  685. //
  686. // ThunkHookProc for Hooks of type WH_KEYBOARD -
  687. //
  688. // Return type is BOOL.
  689. //
  690. //*****************************************************************************
  691. LONG ThunkKeyBoardHook(INT nCode, LONG wParam, LONG lParam,
  692. LPHOOKSTATEDATA lpHSData)
  693. {
  694. LONG lReturn;
  695. PARM16 Parm16;
  696. Parm16.HookProc.nCode = (SHORT)nCode;
  697. Parm16.HookProc.wParam = (SHORT)wParam;
  698. Parm16.HookProc.lParam = lParam;
  699. CallBack16(RET_HOOKPROC, &Parm16, lpHSData->Proc16, (PVPVOID)&lReturn);
  700. // the value in LOWORD is the valid return value
  701. return (LONG)(BOOL)LOWORD(lReturn);
  702. }
  703. //*****************************************************************************
  704. //
  705. // ThunkHookProc for Hooks of type WH_GETMESSAGE -
  706. // WH_MSGFILTER -
  707. // WH_SYSMSGFILTER -
  708. //
  709. // WARNING: May cause 16-bit memory movement, invalidating flat pointers.
  710. //
  711. // Return type is BOOL.
  712. //
  713. //*****************************************************************************
  714. LONG ThunkMsgFilterHook(INT nCode, LONG wParam, LPMSG lpMsg,
  715. LPHOOKSTATEDATA lpHSData)
  716. {
  717. VPVOID vp;
  718. PMSG16 pMsg16;
  719. PARM16 Parm16;
  720. WM32MSGPARAMEX wm32mpex;
  721. BOOL fHookModifiedLpMsg;
  722. HWND hwnd32;
  723. MSGPARAMEX mpex;
  724. BOOL fUseOld;
  725. static MSG msgSave;
  726. static int cRecurse = 0;
  727. static PARM16 Parm16Save;
  728. BOOL fMessageNeedsThunking;
  729. // This should be removed when all thunk functions appropiately fill these
  730. // in, till then we must have these 3 lines before calling thunk functions !
  731. // ChandanC, 2/28/92
  732. //
  733. wm32mpex.Parm16.WndProc.wMsg = (WORD) lpMsg->message;
  734. wm32mpex.Parm16.WndProc.wParam = (WORD) lpMsg->wParam;
  735. wm32mpex.Parm16.WndProc.lParam = (LONG) lpMsg->lParam;
  736. fMessageNeedsThunking = (lpMsg->message < 0x400) &&
  737. (aw32Msg[lpMsg->message].lpfnM32 != WM32NoThunking);
  738. fThunkDDEmsg = FALSE;
  739. if (fMessageNeedsThunking) {
  740. LOGDEBUG(3,("%04X (%s)\n", CURRENTPTD()->htask16,
  741. (aw32Msg[lpMsg->message].lpszW32)));
  742. wm32mpex.fThunk = THUNKMSG;
  743. wm32mpex.hwnd = lpMsg->hwnd;
  744. wm32mpex.uMsg = lpMsg->message;
  745. wm32mpex.uParam = lpMsg->wParam;
  746. wm32mpex.lParam = lpMsg->lParam;
  747. wm32mpex.pww = (PWW)NULL;
  748. wm32mpex.fFree = FALSE;
  749. wm32mpex.lpfnM32 = aw32Msg[wm32mpex.uMsg].lpfnM32;
  750. if (!((wm32mpex.lpfnM32)(&wm32mpex))) {
  751. LOGDEBUG(LOG_ALWAYS,("ThunkMsgFilterHook: cannot thunk 32-bit message %04x\n",
  752. lpMsg->message));
  753. }
  754. }
  755. fThunkDDEmsg = TRUE;
  756. //
  757. // Check to see if we've recursed into this routine. If so and the message
  758. // contents are the same, use the last message pointer we gave the 16
  759. // bit app rather than allocating a new one. Need this to solve the
  760. // SoundBits Browser problem. It checks to see if the lpmsg passed
  761. // is the same as it got last time - if so, it doesn't call this other
  762. // function that causes recursion.
  763. //
  764. fUseOld = FALSE;
  765. if (cRecurse != 0 && lpMsg->hwnd == msgSave.hwnd &&
  766. lpMsg->message == msgSave.message &&
  767. lpMsg->wParam == msgSave.wParam &&
  768. lpMsg->lParam == msgSave.lParam &&
  769. lpMsg->time == msgSave.time &&
  770. lpMsg->pt.x == msgSave.pt.x &&
  771. lpMsg->pt.y == msgSave.pt.y) {
  772. fUseOld = TRUE;
  773. } else {
  774. //
  775. // Not the same... reset this thing in case the count is screwed
  776. // up. Also remember this message, in case we do recurse.
  777. //
  778. cRecurse = 0;
  779. msgSave = *lpMsg;
  780. }
  781. if (!fUseOld) {
  782. vp = malloc16(sizeof(MSG16));
  783. if (vp == (VPVOID)NULL)
  784. return FALSE;
  785. GETMISCPTR(vp, pMsg16);
  786. STOREWORD(pMsg16->hwnd, GETHWND16((lpMsg)->hwnd));
  787. STOREWORD(pMsg16->message, wm32mpex.Parm16.WndProc.wMsg );
  788. STOREWORD(pMsg16->wParam, wm32mpex.Parm16.WndProc.wParam);
  789. STORELONG(pMsg16->lParam, wm32mpex.Parm16.WndProc.lParam);
  790. STORELONG(pMsg16->time, (lpMsg)->time);
  791. STOREWORD(pMsg16->pt.x, (lpMsg)->pt.x);
  792. STOREWORD(pMsg16->pt.y, (lpMsg)->pt.y);
  793. Parm16.HookProc.nCode = (SHORT)nCode;
  794. Parm16.HookProc.wParam = (SHORT)wParam;
  795. Parm16.HookProc.lParam = vp;
  796. //
  797. // Remember Parm16 in case we need to use it again due to the recursion
  798. // case.
  799. //
  800. Parm16Save = Parm16;
  801. } else {
  802. //
  803. // Use old message contents.
  804. //
  805. Parm16 = Parm16Save;
  806. vp = (VPVOID)Parm16Save.HookProc.lParam;
  807. GETMISCPTR(vp, pMsg16);
  808. }
  809. FLUSHVDMPTR(vp, sizeof(MSG16), pMsg16);
  810. //
  811. // Count how many times we recurse through this hook proc. Need this count
  812. // to solve the SoundBits Browser problem. It checks to see if the lpMsg
  813. // passed is the same as it got last time - if so, it doesn't call this
  814. // other function that causes recursion.
  815. //
  816. cRecurse++;
  817. CallBack16(RET_HOOKPROC, &Parm16, lpHSData->Proc16, (PVPVOID)&wm32mpex.lReturn);
  818. cRecurse--;
  819. // set the correct return value BEFORE unthunking
  820. wm32mpex.lReturn = (LONG)(BOOL)LOWORD(wm32mpex.lReturn);
  821. //
  822. // Free the 32 pointer to 16 bit args and get it again in case underlying
  823. // memory movement occured.
  824. //
  825. FREEVDMPTR(pMsg16);
  826. GETMISCPTR(vp, pMsg16);
  827. fThunkDDEmsg = FALSE;
  828. // Theoretically an app can change the lpMsg and return a totall different
  829. // data altogether. In practice most apps don't do anything so it is pretty
  830. // expensive to go through the 'unthunk' procedure all the time. So here is
  831. // a compromise. We copy the message params only if the output message is
  832. // different from the input message.
  833. //
  834. // (davehart) Polaris PackRat modifies WM_KEYDOWN messages sent to its
  835. // multiline "Note" edit control in its Phone Book Entry dialog box.
  836. // It changes wParam (the VK_ code) from 0xD (VK_RETURN) to 0xA, which
  837. // is understood by the edit control to be identical to VK_RETURN but
  838. // won't cause the dialog box to close. So we special-case here
  839. // WM_KEYDOWN where the hook proc changed the virtual key (in wParam)
  840. // and unthunk it properly.
  841. fHookModifiedLpMsg = (pMsg16->message != wm32mpex.Parm16.WndProc.wMsg) ||
  842. (wm32mpex.Parm16.WndProc.wMsg == WM_KEYDOWN &&
  843. pMsg16->wParam != wm32mpex.Parm16.WndProc.wParam) ||
  844. (pMsg16->hwnd != GETHWND16(lpMsg->hwnd));
  845. if (fHookModifiedLpMsg) {
  846. mpex.Parm16.WndProc.hwnd = pMsg16->hwnd;
  847. mpex.Parm16.WndProc.wMsg = pMsg16->message;
  848. mpex.Parm16.WndProc.wParam = pMsg16->wParam;
  849. mpex.Parm16.WndProc.lParam = pMsg16->lParam,
  850. mpex.iMsgThunkClass = WOWCLASS_WIN16;
  851. hwnd32 = ThunkMsg16(&mpex);
  852. //
  853. // Free the 32 pointer to 16 bit args and get it again in case
  854. // underlying memory movement occured.
  855. //
  856. FREEVDMPTR(pMsg16);
  857. GETMISCPTR(vp, pMsg16);
  858. // reset flag if message thunking failed.
  859. if (!hwnd32)
  860. fHookModifiedLpMsg = FALSE;
  861. }
  862. if (fMessageNeedsThunking) {
  863. wm32mpex.fThunk = UNTHUNKMSG;
  864. (wm32mpex.lpfnM32)(&wm32mpex);
  865. //
  866. // Free the 32 pointer to 16 bit args and get it again in case
  867. // underlying memory movement occured.
  868. //
  869. FREEVDMPTR(pMsg16);
  870. GETMISCPTR(vp, pMsg16);
  871. }
  872. fThunkDDEmsg = TRUE;
  873. if (fHookModifiedLpMsg) {
  874. lpMsg->hwnd = hwnd32;
  875. lpMsg->message = mpex.uMsg;
  876. lpMsg->wParam = mpex.uParam;
  877. lpMsg->lParam = mpex.lParam;
  878. lpMsg->time = FETCHLONG(pMsg16->time);
  879. lpMsg->pt.x = FETCHSHORT(pMsg16->pt.x);
  880. lpMsg->pt.y = FETCHSHORT(pMsg16->pt.y);
  881. }
  882. FREEVDMPTR(pMsg16);
  883. if (!fUseOld) {
  884. free16(vp);
  885. }
  886. // the value in LOWORD is the valid return value
  887. return (LONG)(BOOL)LOWORD(wm32mpex.lReturn);
  888. }
  889. //*****************************************************************************
  890. //
  891. // ThunkHookProc for Hooks of type WH_JOURNALPLAYBACK -
  892. // WH_JOUNRALRECORD -
  893. //
  894. // Return type is DWORD.
  895. //
  896. //*****************************************************************************
  897. LONG ThunkJournalHook(INT nCode, LONG wParam, LPEVENTMSG lpEventMsg,
  898. LPHOOKSTATEDATA lpHSData)
  899. {
  900. LONG lReturn;
  901. VPVOID vp;
  902. PEVENTMSG16 pEventMsg16;
  903. PARM16 Parm16;
  904. if ( lpEventMsg ) {
  905. // be sure allocation size matches stackfree16() size below
  906. vp = stackalloc16(sizeof(EVENTMSG16));
  907. // The WIN32 EVENTMSG structure has an additional field 'hwnd', which
  908. // is not there in WIN31 EVENTMSG structure. This field can be ignored
  909. // without any repercussions.
  910. if (lpHSData->iHook == WH_JOURNALRECORD) {
  911. GETMISCPTR(vp, pEventMsg16);
  912. PUTEVENTMSG16(pEventMsg16, lpEventMsg);
  913. FLUSHVDMPTR(vp, sizeof(EVENTMSG16), pEventMsg16);
  914. FREEVDMPTR(pEventMsg16);
  915. }
  916. } else {
  917. // lpEventMsg can be NULL indicating that no message data is requested.
  918. // If this is the case, there is no need to copy data for either
  919. // journal record or playback.
  920. vp = (VPVOID)0;
  921. }
  922. Parm16.HookProc.nCode = (SHORT)nCode;
  923. Parm16.HookProc.wParam = (SHORT)wParam;
  924. Parm16.HookProc.lParam = vp;
  925. CallBack16(RET_HOOKPROC, &Parm16, lpHSData->Proc16, (PVPVOID)&lReturn);
  926. if ( lpEventMsg ) {
  927. GETMISCPTR(vp, pEventMsg16);
  928. if (lpHSData->iHook == WH_JOURNALPLAYBACK) {
  929. GetEventMessage16(pEventMsg16, lpEventMsg);
  930. #ifdef FE_SB
  931. switch (lpEventMsg->message) {
  932. case WM_CHAR:
  933. case WM_CHARTOITEM:
  934. case WM_DEADCHAR:
  935. case WM_KEYDOWN:
  936. case WM_KEYUP:
  937. case WM_MENUCHAR:
  938. case WM_SYSCHAR:
  939. case WM_SYSDEADCHAR:
  940. case WM_SYSKEYDOWN:
  941. case WM_SYSKEYUP:
  942. case WM_VKEYTOITEM:
  943. // only virtual key, not use scan code
  944. lpEventMsg->paramL &= 0x0ff;
  945. }
  946. #endif // FE_SB
  947. #ifdef DEBUG
  948. if (MessageNeedsThunking(lpEventMsg->message)) {
  949. LOGDEBUG(LOG_ALWAYS, ("ThunkJournalHook: Playing back unexpected message 0x%x", lpEventMsg->message));
  950. }
  951. #endif
  952. } else {
  953. WOW32ASSERT(lpHSData->iHook == WH_JOURNALRECORD);
  954. WOW32ASSERT(aw32Msg[FETCHWORD(pEventMsg16->message)].lpfnM32 == WM32NoThunking);
  955. // If the app modified the message then copy the new message info
  956. // (rather than copying it every time we only copy it if the
  957. // app change the message)
  958. if (FETCHWORD(pEventMsg16->message) != lpEventMsg->message) {
  959. GetEventMessage16(pEventMsg16, lpEventMsg);
  960. }
  961. }
  962. FREEVDMPTR(pEventMsg16);
  963. if(vp) {
  964. stackfree16(vp, sizeof(EVENTMSG16));
  965. }
  966. }
  967. return lReturn;
  968. }
  969. //*****************************************************************************
  970. //
  971. // ThunkHookProc for Hooks of type WH_DEBUG -
  972. //
  973. // Return type is BOOL.
  974. //
  975. //*****************************************************************************
  976. LONG ThunkDebugHook(INT nCode, LONG wParam, LONG lParam,
  977. LPHOOKSTATEDATA lpHSData)
  978. {
  979. LONG lReturn;
  980. lReturn = TRUE;
  981. UNREFERENCED_PARAMETER(nCode);
  982. UNREFERENCED_PARAMETER(wParam);
  983. UNREFERENCED_PARAMETER(lParam);
  984. UNREFERENCED_PARAMETER(lpHSData);
  985. LOGDEBUG(LOG_ALWAYS, ("ThunkDebugHook:Not implemented.\n"));
  986. // the value in LOWORD is the valid return value
  987. return (LONG)(BOOL)LOWORD(lReturn);
  988. }
  989. //*****************************************************************************
  990. //
  991. // ThunkHookProc for Hooks of type WH_MOUSE -
  992. //
  993. // Return type is BOOL.
  994. //
  995. //*****************************************************************************
  996. LONG ThunkMouseHook(INT nCode, LONG wParam, LPMOUSEHOOKSTRUCT lpMHStruct,
  997. LPHOOKSTATEDATA lpHSData)
  998. {
  999. LONG lReturn;
  1000. VPVOID vp;
  1001. PMOUSEHOOKSTRUCT16 pMHStruct16;
  1002. PARM16 Parm16;
  1003. // be sure allocation size matches stackfree16() size below
  1004. vp = stackalloc16(sizeof(MOUSEHOOKSTRUCT16));
  1005. GETMISCPTR(vp, pMHStruct16);
  1006. PUTMOUSEHOOKSTRUCT16(pMHStruct16, lpMHStruct);
  1007. Parm16.HookProc.nCode = (SHORT)nCode;
  1008. Parm16.HookProc.wParam = (SHORT)wParam;
  1009. Parm16.HookProc.lParam = vp;
  1010. FLUSHVDMPTR(vp, sizeof(MOUSEHOOKSTRUCT16), pMHStruct16);
  1011. FREEVDMPTR(pMHStruct16);
  1012. CallBack16(RET_HOOKPROC, &Parm16, lpHSData->Proc16, (PVPVOID)&lReturn);
  1013. GETMISCPTR(vp, pMHStruct16);
  1014. GETMOUSEHOOKSTRUCT16(pMHStruct16, lpMHStruct);
  1015. FREEVDMPTR(pMHStruct16);
  1016. if(vp) {
  1017. stackfree16(vp, sizeof(MOUSEHOOKSTRUCT16));
  1018. }
  1019. return (LONG)(BOOL)LOWORD(lReturn);
  1020. }
  1021. //*****************************************************************************
  1022. //
  1023. // ThunkHookProc for Hooks of type WH_SHELL -
  1024. //
  1025. // Return value apparently is zero.
  1026. //
  1027. //*****************************************************************************
  1028. LONG ThunkShellHook(INT nCode, LONG wParam, LONG lParam,
  1029. LPHOOKSTATEDATA lpHSData)
  1030. {
  1031. LONG lReturn;
  1032. PARM16 Parm16;
  1033. Parm16.HookProc.nCode = (SHORT)nCode;
  1034. Parm16.HookProc.lParam = lParam;
  1035. switch (nCode) {
  1036. case HSHELL_WINDOWCREATED:
  1037. case HSHELL_WINDOWDESTROYED:
  1038. Parm16.HookProc.wParam = (SHORT)GETHWND16(wParam);
  1039. break;
  1040. case HSHELL_ACTIVATESHELLWINDOW:
  1041. // fall thru
  1042. default:
  1043. Parm16.HookProc.wParam = (SHORT)wParam;
  1044. break;
  1045. }
  1046. CallBack16(RET_HOOKPROC, &Parm16, lpHSData->Proc16, (PVPVOID)&lReturn);
  1047. // lReturn = 0?
  1048. return (LONG)lReturn;
  1049. }
  1050. //*****************************************************************************
  1051. // W32UnhookHooks:
  1052. //
  1053. // Scans the list of active hooks for those for the passed in handle.
  1054. // Those that match are unhooked.
  1055. //
  1056. //*****************************************************************************
  1057. VOID W32UnhookHooks( HAND16 hMod16, BOOL fQueue )
  1058. {
  1059. INT i;
  1060. for (i = 0; i < vaHookPPData.cHookProcs; i++) {
  1061. if (vaHookStateData[i].InUse ) {
  1062. if ( !fQueue && ((HAND16)(vaHookStateData[i].hMod16) == hMod16) ) {
  1063. //
  1064. // Unhook this guy!
  1065. //
  1066. if (UnhookWindowsHookEx(vaHookStateData[i].hHook)) {
  1067. LOGDEBUG(7, ("W32FreeModuleHooks: Freed iHook (WH_*) %04x\n",
  1068. vaHookStateData[i].iHook));
  1069. }
  1070. else {
  1071. LOGDEBUG(LOG_ALWAYS, ("W32FreeModuleHooks: ERROR Freeing iHook (WH_*) %04x\n",
  1072. vaHookStateData[i].iHook));
  1073. }
  1074. // reset the state, even if Unhooking failed.
  1075. vaHookStateData[i].TaskId = 0;
  1076. vaHookStateData[i].InUse = FALSE;
  1077. }
  1078. }
  1079. }
  1080. }
  1081. //*****************************************************************************
  1082. // W32FreeOwnedHooks -
  1083. //
  1084. // Called during thread exit time. Frees all hooks set by specified thread.
  1085. //
  1086. //*****************************************************************************
  1087. BOOL W32FreeOwnedHooks(INT iTaskId)
  1088. {
  1089. INT i;
  1090. for (i = 0; i < vaHookPPData.cHookProcs; i++) {
  1091. if (vaHookStateData[i].InUse &&
  1092. vaHookStateData[i].TaskId == iTaskId) {
  1093. if (UnhookWindowsHookEx(vaHookStateData[i].hHook)) {
  1094. LOGDEBUG(7, ("W32FreeOwnedHooks: Freed iHook (WH_*) %04x\n",
  1095. vaHookStateData[i].iHook));
  1096. }
  1097. else {
  1098. LOGDEBUG(LOG_ALWAYS, ("W32FreeOwnedHooks: ERROR Freeing iHook (WH_*) %04x\n",
  1099. vaHookStateData[i].iHook));
  1100. }
  1101. // reset the state, even if Unhooking failed.
  1102. vaHookStateData[i].TaskId = 0;
  1103. vaHookStateData[i].InUse = FALSE;
  1104. }
  1105. }
  1106. return TRUE;
  1107. }
  1108. //*****************************************************************************
  1109. // W32StdDefHookProc: (Standard Def Hook Proc)
  1110. //
  1111. // WU32DefHookProc is called here.
  1112. // WARNING: May cause 16-bit memory movement, invalidating flat pointers.
  1113. // Return value is the new lParam.
  1114. //
  1115. //*****************************************************************************
  1116. LONG APIENTRY WU32StdDefHookProc(INT nCode, LONG wParam, LONG lParam, INT iFunc)
  1117. {
  1118. switch (vaHookStateData[iFunc].iHook) {
  1119. case WH_CALLWNDPROC:
  1120. return ThunkCallWndProcHook16(nCode, wParam, (VPVOID)lParam,
  1121. &vaHookStateData[iFunc]);
  1122. case WH_CBT:
  1123. return ThunkCbtHook16(nCode, wParam, (VPVOID)lParam,
  1124. &vaHookStateData[iFunc]);
  1125. case WH_KEYBOARD:
  1126. return ThunkKeyBoardHook16(nCode, wParam, lParam,
  1127. &vaHookStateData[iFunc]);
  1128. case WH_MSGFILTER:
  1129. case WH_SYSMSGFILTER:
  1130. case WH_GETMESSAGE:
  1131. return ThunkMsgFilterHook16(nCode, wParam, (VPVOID)lParam,
  1132. &vaHookStateData[iFunc]);
  1133. case WH_JOURNALPLAYBACK:
  1134. case WH_JOURNALRECORD:
  1135. return ThunkJournalHook16(nCode, wParam, (VPVOID)lParam,
  1136. &vaHookStateData[iFunc]);
  1137. case WH_DEBUG:
  1138. return ThunkDebugHook16(nCode, wParam, lParam,
  1139. &vaHookStateData[iFunc]);
  1140. case WH_MOUSE:
  1141. return ThunkMouseHook16(nCode, wParam, (VPVOID)lParam,
  1142. &vaHookStateData[iFunc]);
  1143. case WH_SHELL:
  1144. return ThunkShellHook16(nCode, wParam, lParam,
  1145. &vaHookStateData[iFunc]);
  1146. default:
  1147. LOGDEBUG(LOG_ALWAYS,("WU32StdDefHookProc: Unknown Hook type.\n"));
  1148. }
  1149. return (LONG)FALSE;
  1150. }
  1151. //*****************************************************************************
  1152. //
  1153. // 16->32 ThunkHookProc for Hooks of type WH_CALLWNDPROC -
  1154. //
  1155. // Return type is VOID.
  1156. //
  1157. //*****************************************************************************
  1158. LONG ThunkCallWndProcHook16(INT nCode, LONG wParam, VPVOID vpCwpStruct,
  1159. LPHOOKSTATEDATA lpHSData)
  1160. {
  1161. CWPSTRUCT CwpStruct;
  1162. PCWPSTRUCT16 pCwpStruct16;
  1163. MSGPARAMEX mpex;
  1164. GETMISCPTR(vpCwpStruct, pCwpStruct16);
  1165. mpex.Parm16.WndProc.hwnd = pCwpStruct16->hwnd;
  1166. mpex.Parm16.WndProc.wMsg = pCwpStruct16->message;
  1167. mpex.Parm16.WndProc.wParam = pCwpStruct16->wParam;
  1168. mpex.Parm16.WndProc.lParam = pCwpStruct16->lParam,
  1169. mpex.iMsgThunkClass = WOWCLASS_WIN16;
  1170. mpex.hwnd = ThunkMsg16(&mpex);
  1171. // memory may have moved
  1172. FREEVDMPTR(pCwpStruct16);
  1173. CwpStruct.message = mpex.uMsg;
  1174. CwpStruct.wParam = mpex.uParam;
  1175. CwpStruct.lParam = mpex.lParam;
  1176. CwpStruct.hwnd = mpex.hwnd;
  1177. mpex.lReturn = CallNextHookEx(lpHSData->hHook, nCode, wParam,
  1178. (LPARAM)&CwpStruct);
  1179. if (MSG16NEEDSTHUNKING(&mpex)) {
  1180. mpex.uMsg = CwpStruct.message;
  1181. mpex.uParam = CwpStruct.wParam;
  1182. mpex.lParam = CwpStruct.lParam;
  1183. (mpex.lpfnUnThunk16)(&mpex);
  1184. }
  1185. return mpex.lReturn;
  1186. }
  1187. //*****************************************************************************
  1188. //
  1189. // 16->32 ThunkHookProc for Hooks of type WH_CBT -
  1190. //
  1191. // Return type is BOOL.
  1192. //
  1193. //*****************************************************************************
  1194. LONG ThunkCbtHook16(INT nCode, LONG wParam, VPVOID lParam,
  1195. LPHOOKSTATEDATA lpHSData)
  1196. {
  1197. LONG lReturn = FALSE;
  1198. WPARAM wParamNew;
  1199. LPARAM lParamNew;
  1200. MSGPARAMEX mpex;
  1201. PMOUSEHOOKSTRUCT16 pMHStruct16;
  1202. PCBTACTIVATESTRUCT16 pCbtAStruct16;
  1203. PCBT_CREATEWND16 pCbtCWnd16;
  1204. PRECT16 pRect16;
  1205. MOUSEHOOKSTRUCT MHStruct;
  1206. RECT Rect;
  1207. CBTACTIVATESTRUCT CbtAStruct;
  1208. CBT_CREATEWND CbtCWnd;
  1209. // SudeepB 28-May-1996 updated DaveHart 16-July-96 to fix limit assertions.
  1210. //
  1211. // Some apps like SureTrack project management package are passing
  1212. // corrupted values in lParam. GETVDMPTR returns 0 for such an lParam.
  1213. // Using this 0 on X86 causes corruption of IVT and on RISC causes an
  1214. // AV in wow32 as zero is not a valid linear address. Such apps get
  1215. // away from such criminal acts on win3.1/Win95 as no thunking is needed
  1216. // there. So all the thunking below explicitly checks for GETVDMPTR
  1217. // returning 0 and in that case just leaves lParam unthunked.
  1218. wParamNew = (WPARAM) wParam;
  1219. lParamNew = (LPARAM) lParam;
  1220. switch(nCode) {
  1221. //
  1222. // These don't have a pointer in lParam.
  1223. //
  1224. case HCBT_SETFOCUS: // wParam = HWND, lParam = HWND
  1225. // fall through to set wParamNew & lParamNew,
  1226. // this counts on HWND32 zero-extending.
  1227. case HCBT_MINMAX: // wParam = HWND, lParam = SW_* --- a command
  1228. // fall through to set wParamNew & lParamNew.
  1229. // this counts on HWND32 zero-extending.
  1230. case HCBT_DESTROYWND: // wParam = HWND, lParam = 0
  1231. // fall through to set wParamNew & lParamNew.
  1232. // this counts on HWND32 zero-extending.
  1233. WOW32ASSERTMSG((HWND32(0x1234) == (HWND)0x1234),
  1234. "Code depending on HWND32 zero-extending needs revision.\n");
  1235. case HCBT_QS: // wParam = 0, lParam = 0
  1236. case HCBT_KEYSKIPPED: // wParam = VK_ keycode, lParam = WM_KEYUP/DOWN lParam
  1237. case HCBT_SYSCOMMAND: // wParam = SC_ syscomand, lParam = DWORD(x,y) if mouse
  1238. // lParamNew and wParamNew are initialized above with no thunking.
  1239. break;
  1240. //
  1241. // These use lParam as a pointer.
  1242. //
  1243. case HCBT_MOVESIZE: // wParam = HWND, lParam = LPRECT
  1244. #if 0 // HWND32 is a no-op, wParamNew already initialized.
  1245. wParamNew = (WPARAM) HWND32(wParam);
  1246. #endif
  1247. GETVDMPTR(lParam, sizeof(*pRect16), pRect16);
  1248. if (pRect16) {
  1249. GETRECT16(lParam, &Rect);
  1250. lParamNew = (LPARAM)&Rect;
  1251. FREEVDMPTR(pRect16);
  1252. }
  1253. break;
  1254. case HCBT_CREATEWND: // wParam = HWND, lParam = LPCBT_CREATEWND
  1255. #if 0 // HWND32 is a no-op, wParamNew already initialized.
  1256. wParamNew = (WPARAM) HWND32(wParam);
  1257. #endif
  1258. GETVDMPTR(lParam, sizeof(*pCbtCWnd16), pCbtCWnd16);
  1259. if (pCbtCWnd16) {
  1260. lParamNew = (LPARAM)&CbtCWnd;
  1261. mpex.Parm16.WndProc.hwnd = LOWORD(wParam);
  1262. mpex.Parm16.WndProc.wMsg = WM_CREATE;
  1263. mpex.Parm16.WndProc.wParam = 0;
  1264. mpex.Parm16.WndProc.lParam = FETCHDWORD(pCbtCWnd16->vpcs);
  1265. mpex.iMsgThunkClass = 0;
  1266. ThunkMsg16(&mpex);
  1267. //
  1268. // Memory movement can occur on the 16-bit side.
  1269. //
  1270. FREEVDMPTR(pCbtCWnd16);
  1271. GETVDMPTR(lParam, sizeof(*pCbtCWnd16), pCbtCWnd16);
  1272. (LONG)CbtCWnd.lpcs = mpex.lParam;
  1273. CbtCWnd.hwndInsertAfter =
  1274. HWNDIA32(FETCHWORD(pCbtCWnd16->hwndInsertAfter));
  1275. FREEVDMPTR(pCbtCWnd16);
  1276. }
  1277. break;
  1278. case HCBT_ACTIVATE: // wParam = HWND, lParam = LPCBTACTIVATESTRUCT
  1279. #if 0 // HWND32 is a no-op, wParamNew already initialized.
  1280. wParamNew = (WPARAM) HWND32(wParam);
  1281. #endif
  1282. GETVDMPTR(lParam, sizeof(*pCbtAStruct16), pCbtAStruct16);
  1283. if (pCbtAStruct16) {
  1284. lParamNew = (LPARAM)&CbtAStruct;
  1285. GETCBTACTIVATESTRUCT16(pCbtAStruct16, &CbtAStruct);
  1286. FREEVDMPTR(pCbtAStruct16);
  1287. }
  1288. break;
  1289. case HCBT_CLICKSKIPPED: // wParam = mouse message, lParam = LPMOUSEHOOKSTRUCT
  1290. GETVDMPTR(lParam, sizeof(*pMHStruct16), pMHStruct16);
  1291. if (pMHStruct16) {
  1292. lParamNew = (LPARAM)&MHStruct;
  1293. GETMOUSEHOOKSTRUCT16(pMHStruct16, &MHStruct);
  1294. FREEVDMPTR(pMHStruct16);
  1295. }
  1296. break;
  1297. default:
  1298. LOGDEBUG(LOG_ALWAYS, ("ThunkCbtHook: Unknown HCBT_ code 0x%x\n", nCode));
  1299. break;
  1300. }
  1301. //
  1302. // Call the hook, memory movement can occur.
  1303. //
  1304. lReturn = CallNextHookEx(lpHSData->hHook, nCode, wParamNew, lParamNew);
  1305. switch(nCode) {
  1306. //
  1307. // These don't have a pointer in lParam.
  1308. //
  1309. // case HCBT_SETFOCUS: // wParam = HWND, lParam = HWND
  1310. // case HCBT_MINMAX: // wParam = HWND, lParam = SW_* --- a command
  1311. // case HCBT_DESTROYWND: // wParam = HWND, lParam = 0
  1312. // case HCBT_QS: // wParam = 0, lParam = 0
  1313. // case HCBT_KEYSKIPPED: // wParam = VK_ keycode, lParam = WM_KEYUP/DOWN lParam
  1314. // case HCBT_SYSCOMMAND: // wParam = SC_ syscomand, lParam = DWORD(x,y) if mouse
  1315. // break;
  1316. //
  1317. // These use lParam as a pointer.
  1318. //
  1319. case HCBT_MOVESIZE: // wParam = HWND, lParam = LPRECT
  1320. PUTRECT16(lParam, (LPRECT)lParamNew);
  1321. break;
  1322. case HCBT_CREATEWND: // wParam = HWND, lParam = LPCBT_CREATEWND
  1323. GETVDMPTR(lParam, sizeof(*pCbtCWnd16), pCbtCWnd16);
  1324. if (pCbtCWnd16) {
  1325. mpex.lParam = (LONG)CbtCWnd.lpcs;
  1326. mpex.lReturn = lReturn;
  1327. WOW32ASSERT(MSG16NEEDSTHUNKING(&mpex));
  1328. (mpex.lpfnUnThunk16)(&mpex);
  1329. lReturn = mpex.lReturn;
  1330. STOREWORD(pCbtCWnd16->hwndInsertAfter,
  1331. GETHWNDIA16(((LPCBT_CREATEWND)lParamNew)->
  1332. hwndInsertAfter));
  1333. FLUSHVDMPTR((VPVOID)lParam, sizeof(CBT_CREATEWND16), pCbtCWnd16);
  1334. FREEVDMPTR(pCbtCWnd16);
  1335. }
  1336. break;
  1337. case HCBT_ACTIVATE: // wParam = HWND, lParam = LPCBTACTIVATESTRUCT
  1338. GETVDMPTR(lParam, sizeof(*pCbtAStruct16), pCbtAStruct16);
  1339. if (pCbtAStruct16) {
  1340. PUTCBTACTIVATESTRUCT16(pCbtAStruct16, (LPCBTACTIVATESTRUCT)lParamNew);
  1341. FLUSHVDMPTR((VPVOID)lParam, sizeof(CBTACTIVATESTRUCT16),
  1342. pCbtAStruct16);
  1343. FREEVDMPTR(pCbtAStruct16);
  1344. }
  1345. break;
  1346. case HCBT_CLICKSKIPPED: // wParam = mouse message, lParam = LPMOUSEHOOKSTRUCT
  1347. GETVDMPTR(lParam, sizeof(*pMHStruct16), pMHStruct16);
  1348. if (pMHStruct16) {
  1349. PUTMOUSEHOOKSTRUCT16(pMHStruct16, (LPMOUSEHOOKSTRUCT)lParamNew);
  1350. FLUSHVDMPTR((VPVOID)lParam, sizeof(MOUSEHOOKSTRUCT16),
  1351. pMHStruct16);
  1352. FREEVDMPTR(pMHStruct16);
  1353. }
  1354. break;
  1355. }
  1356. // the value in LOWORD is the valid return value
  1357. return (LONG)(BOOL)LOWORD(lReturn);
  1358. }
  1359. //*****************************************************************************
  1360. //
  1361. // 16->32 ThunkHookProc for Hooks of type WH_KEYBOARD -
  1362. //
  1363. // Return type is BOOL.
  1364. //
  1365. //*****************************************************************************
  1366. LONG ThunkKeyBoardHook16(INT nCode, LONG wParam, LONG lParam,
  1367. LPHOOKSTATEDATA lpHSData)
  1368. {
  1369. LONG lReturn;
  1370. lReturn = CallNextHookEx(lpHSData->hHook, nCode, wParam,
  1371. (LPARAM)lParam);
  1372. // the value in LOWORD is the valid return value
  1373. return (LONG)(BOOL)LOWORD(lReturn);
  1374. }
  1375. //*****************************************************************************
  1376. //
  1377. // 16->32 ThunkHookProc for Hooks of type WH_GETMESSAGE -
  1378. // WH_MSGFILTER -
  1379. // WH_SYSMSGFILTER -
  1380. //
  1381. // Return type is BOOL.
  1382. //
  1383. //*****************************************************************************
  1384. LONG ThunkMsgFilterHook16(INT nCode, LONG wParam, VPVOID vpMsg,
  1385. LPHOOKSTATEDATA lpHSData)
  1386. {
  1387. PMSG16 pMsg16;
  1388. MSG Msg;
  1389. MSGPARAMEX mpex;
  1390. GETMISCPTR(vpMsg, pMsg16);
  1391. fThunkDDEmsg = FALSE;
  1392. mpex.Parm16.WndProc.hwnd = pMsg16->hwnd;
  1393. mpex.Parm16.WndProc.wMsg = pMsg16->message;
  1394. mpex.Parm16.WndProc.wParam = pMsg16->wParam;
  1395. mpex.Parm16.WndProc.lParam = pMsg16->lParam;
  1396. mpex.iMsgThunkClass = 0;
  1397. ThunkMsg16(&mpex);
  1398. //
  1399. // Memory movement can occur on the 16-bit side.
  1400. //
  1401. FREEVDMPTR(pMsg16);
  1402. GETMISCPTR(vpMsg, pMsg16);
  1403. fThunkDDEmsg = TRUE;
  1404. Msg.message = mpex.uMsg;
  1405. Msg.wParam = mpex.uParam;
  1406. Msg.lParam = mpex.lParam;
  1407. Msg.hwnd = HWND32(FETCHWORD(pMsg16->hwnd));
  1408. Msg.time = FETCHLONG(pMsg16->time);
  1409. Msg.pt.x = FETCHSHORT(pMsg16->pt.x);
  1410. Msg.pt.y = FETCHSHORT(pMsg16->pt.y);
  1411. FREEVDMPTR(pMsg16);
  1412. mpex.lReturn = CallNextHookEx(lpHSData->hHook, nCode, wParam,
  1413. (LPARAM)&Msg);
  1414. GETMISCPTR(vpMsg, pMsg16);
  1415. if (MSG16NEEDSTHUNKING(&mpex)) {
  1416. mpex.uMsg = Msg.message;
  1417. mpex.uParam = Msg.wParam;
  1418. mpex.lParam = Msg.lParam;
  1419. FREEVDMPTR(pMsg16); // invalidate 16-bit ptr: memory may move
  1420. (mpex.lpfnUnThunk16)(&mpex);
  1421. GETMISCPTR(vpMsg, pMsg16); // refresh 16-bit ptr
  1422. }
  1423. STORELONG(pMsg16->time, Msg.time);
  1424. STOREWORD(pMsg16->pt.x, Msg.pt.x);
  1425. STOREWORD(pMsg16->pt.y, Msg.pt.y);
  1426. FLUSHVDMPTR(vpMsg, sizeof(MSG16), pMsg16);
  1427. FREEVDMPTR(pMsg16);
  1428. // the value in LOWORD is the valid return value
  1429. return (LONG)(BOOL)LOWORD(mpex.lReturn);
  1430. }
  1431. //*****************************************************************************
  1432. //
  1433. // 16->32 ThunkHookProc for Hooks of type WH_JOURNALPLAYBACK -
  1434. // WH_JOUNRALRECORD -
  1435. //
  1436. // Return type is DWORD.
  1437. //
  1438. //*****************************************************************************
  1439. LONG ThunkJournalHook16(INT nCode, LONG wParam, VPVOID vpEventMsg,
  1440. LPHOOKSTATEDATA lpHSData)
  1441. {
  1442. LONG lReturn;
  1443. PEVENTMSG16 pEventMsg16;
  1444. EVENTMSG EventMsg;
  1445. LPEVENTMSG lpEventMsg;
  1446. if ( vpEventMsg ) {
  1447. // The WIN32 EVENTMSG structure has an additional field 'hwnd', which
  1448. // is not there in WIN31 EVENTMSG structure. This field can be ignored
  1449. // without any repercussions.
  1450. if (lpHSData->iHook == WH_JOURNALRECORD) {
  1451. GETMISCPTR(vpEventMsg, pEventMsg16);
  1452. GetEventMessage16(pEventMsg16, &EventMsg);
  1453. EventMsg.hwnd = (HWND)0;
  1454. FREEVDMPTR(pEventMsg16);
  1455. }
  1456. lpEventMsg = &EventMsg;
  1457. } else {
  1458. lpEventMsg = NULL;
  1459. }
  1460. lReturn = CallNextHookEx(lpHSData->hHook, nCode, wParam, (LPARAM)lpEventMsg );
  1461. if ( vpEventMsg ) {
  1462. if (lpHSData->iHook == WH_JOURNALPLAYBACK) {
  1463. GETMISCPTR(vpEventMsg, pEventMsg16);
  1464. PUTEVENTMSG16(pEventMsg16, &EventMsg);
  1465. FLUSHVDMPTR(vpEventMsg, sizeof(EVENTMSG16), pEventMsg16);
  1466. FREEVDMPTR(pEventMsg16);
  1467. }
  1468. }
  1469. return lReturn;
  1470. }
  1471. //*****************************************************************************
  1472. //
  1473. // 16->32 ThunkHookProc for Hooks of type WH_DEBUG -
  1474. //
  1475. // Return type is BOOL.
  1476. //
  1477. //*****************************************************************************
  1478. LONG ThunkDebugHook16(INT nCode, LONG wParam, LONG lParam,
  1479. LPHOOKSTATEDATA lpHSData)
  1480. {
  1481. LONG lReturn;
  1482. lReturn = TRUE;
  1483. UNREFERENCED_PARAMETER(nCode);
  1484. UNREFERENCED_PARAMETER(wParam);
  1485. UNREFERENCED_PARAMETER(lParam);
  1486. UNREFERENCED_PARAMETER(lpHSData);
  1487. LOGDEBUG(LOG_ALWAYS, ("ThunkDebugHook16:Not implemented.\n"));
  1488. // the value in LOWORD is the valid return value
  1489. return (LONG)(BOOL)LOWORD(lReturn);
  1490. }
  1491. //*****************************************************************************
  1492. //
  1493. // 16->32 ThunkHookProc for Hooks of type WH_MOUSE -
  1494. //
  1495. // Return type is BOOL.
  1496. //
  1497. //*****************************************************************************
  1498. LONG ThunkMouseHook16(INT nCode, LONG wParam, VPVOID vpMHStruct,
  1499. LPHOOKSTATEDATA lpHSData)
  1500. {
  1501. LONG lReturn;
  1502. PMOUSEHOOKSTRUCT16 pMHStruct16;
  1503. MOUSEHOOKSTRUCT MHStruct;
  1504. GETMISCPTR(vpMHStruct, pMHStruct16);
  1505. GETMOUSEHOOKSTRUCT16(pMHStruct16, &MHStruct);
  1506. FREEVDMPTR(pMHStruct16);
  1507. lReturn = CallNextHookEx(lpHSData->hHook, nCode, wParam,
  1508. (LPARAM)&MHStruct);
  1509. GETMISCPTR(vpMHStruct, pMHStruct16);
  1510. PUTMOUSEHOOKSTRUCT16(pMHStruct16, &MHStruct);
  1511. FLUSHVDMPTR((VPVOID)vpMHStruct, sizeof(MOUSEHOOKSTRUCT16), pMHStruct16);
  1512. FREEVDMPTR(pMHStruct16);
  1513. return (LONG)(BOOL)LOWORD(lReturn);
  1514. }
  1515. //*****************************************************************************
  1516. //
  1517. // 16->32 ThunkHookProc for Hooks of type WH_SHELL -
  1518. //
  1519. // Return value is apparently zero.
  1520. //
  1521. //*****************************************************************************
  1522. LONG ThunkShellHook16(INT nCode, LONG wParam, LONG lParam,
  1523. LPHOOKSTATEDATA lpHSData)
  1524. {
  1525. LONG lReturn;
  1526. switch (nCode) {
  1527. case HSHELL_WINDOWCREATED:
  1528. case HSHELL_WINDOWDESTROYED:
  1529. wParam = (LONG)HWND32(wParam);
  1530. break;
  1531. case HSHELL_ACTIVATESHELLWINDOW:
  1532. // fall thru
  1533. default:
  1534. break;
  1535. }
  1536. lReturn = CallNextHookEx(lpHSData->hHook, nCode, wParam,
  1537. (LPARAM)lParam);
  1538. // lReturn = 0?
  1539. return (LONG)lReturn;
  1540. }
  1541. //*****************************************************************************
  1542. // W32GetHookDDEMsglParam:
  1543. //
  1544. // Returns the lParam of the actual hook message. called for dde messages
  1545. // only. returns valid lParam else 0.
  1546. //
  1547. //*****************************************************************************
  1548. DWORD W32GetHookDDEMsglParam()
  1549. {
  1550. INT iFunc;
  1551. LONG lParam;
  1552. iFunc = viCurrentHookStateDataIndex;
  1553. lParam = vHookParams.lParam;
  1554. if (lParam) {
  1555. switch (vaHookStateData[iFunc].iHook) {
  1556. case WH_CALLWNDPROC:
  1557. lParam = ((LPCWPSTRUCT)lParam)->lParam;
  1558. break;
  1559. case WH_MSGFILTER:
  1560. case WH_SYSMSGFILTER:
  1561. case WH_GETMESSAGE:
  1562. lParam = ((LPMSG)lParam)->lParam;
  1563. break;
  1564. default:
  1565. lParam = 0;
  1566. }
  1567. }
  1568. return lParam;
  1569. }
  1570. //*****************************************************************************
  1571. // GetEventMessage16:
  1572. //
  1573. //*****************************************************************************
  1574. VOID GetEventMessage16(PEVENTMSG16 pEventMsg16, LPEVENTMSG lpEventMsg)
  1575. {
  1576. lpEventMsg->message = FETCHWORD(pEventMsg16->message);
  1577. lpEventMsg->time = FETCHLONG(pEventMsg16->time);
  1578. if ((lpEventMsg->message >= WM_KEYFIRST) && (lpEventMsg->message <= WM_KEYLAST)) {
  1579. // Key event
  1580. lpEventMsg->paramL = FETCHWORD(pEventMsg16->paramL);
  1581. lpEventMsg->paramH = FETCHWORD(pEventMsg16->paramH) & 0x8000;
  1582. lpEventMsg->paramH |= (lpEventMsg->paramL & 0xFF00) >> 8;
  1583. lpEventMsg->paramL &= 0xFF;
  1584. }
  1585. else {
  1586. // Mouse event
  1587. lpEventMsg->paramL = FETCHWORD(pEventMsg16->paramL);
  1588. lpEventMsg->paramH = FETCHWORD(pEventMsg16->paramH);
  1589. }
  1590. }