Source code of Windows XP (NT5)
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.

2064 lines
64 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. STOREWORD(pCwpStruct16->hwnd, GETHWND16(lpCwpStruct->hwnd));
  499. STOREWORD(pCwpStruct16->message, wm32mpex.Parm16.WndProc.wMsg );
  500. STOREWORD(pCwpStruct16->wParam, wm32mpex.Parm16.WndProc.wParam);
  501. STORELONG(pCwpStruct16->lParam, wm32mpex.Parm16.WndProc.lParam);
  502. FLUSHVDMPTR(vp, sizeof(CWPSTRUCT16), pCwpStruct16);
  503. FREEVDMPTR(pCwpStruct16);
  504. Parm16.HookProc.nCode = (SHORT)nCode;
  505. Parm16.HookProc.wParam = (SHORT)wParam;
  506. Parm16.HookProc.lParam = vp;
  507. CallBack16(RET_HOOKPROC, &Parm16, lpHSData->Proc16, (PVPVOID)&wm32mpex.lReturn);
  508. #ifdef DEBUG
  509. GETMISCPTR(vp, pCwpStruct16);
  510. if (pCwpStruct16->message != wm32mpex.Parm16.WndProc.wMsg)
  511. LOGDEBUG(LOG_ALWAYS,("ThunkCallWndProcHook: IN message != OUT message"));
  512. FREEVDMPTR(pCwpStruct16);
  513. #endif
  514. if (fMessageNeedsThunking) {
  515. wm32mpex.fThunk = UNTHUNKMSG;
  516. // Note: If the thunk of this message called stackalloc16() this unthunk
  517. // call should call stackfree16()
  518. (wm32mpex.lpfnM32)(&wm32mpex);
  519. }
  520. if(vp) {
  521. // this stackfree16() call must come after the above message unthunk
  522. // call to give the unthunk the opportunity to call stackfree16() also.
  523. // this will preserve proper nesting of stackalloc16 & stackfree16 calls
  524. stackfree16(vp, sizeof(CWPSTRUCT16));
  525. }
  526. return (LONG)FALSE; // return value doesn't matter
  527. }
  528. //*****************************************************************************
  529. //
  530. // ThunkHookProc for Hooks of type WH_CBT -
  531. //
  532. // Return type is BOOL.
  533. //
  534. //*****************************************************************************
  535. LONG ThunkCbtHook(INT nCode, LONG wParam, LONG lParam,
  536. LPHOOKSTATEDATA lpHSData)
  537. {
  538. LONG lReturn = FALSE;
  539. PARM16 Parm16;
  540. VPVOID vp;
  541. PMOUSEHOOKSTRUCT16 pMHStruct16;
  542. PCBTACTIVATESTRUCT16 pCbtAStruct16;
  543. VPCREATESTRUCT16 vpcs16;
  544. PCBT_CREATEWND16 pCbtCWnd16;
  545. WM32MSGPARAMEX wm32mpex;
  546. Parm16.HookProc.nCode = (SHORT)nCode;
  547. Parm16.HookProc.wParam = (SHORT)wParam;
  548. Parm16.HookProc.lParam = lParam;
  549. switch(nCode) {
  550. case HCBT_MOVESIZE:
  551. // wParam = HWND, lParam = LPRECT
  552. Parm16.HookProc.wParam = GETHWND16(wParam);
  553. // be sure allocation size matches stackfree16() size below
  554. vp = stackalloc16(sizeof(RECT16));
  555. PUTRECT16(vp, (LPRECT)lParam);
  556. Parm16.HookProc.lParam = vp;
  557. break;
  558. case HCBT_MINMAX:
  559. // wParam = HWND, lParam = SW_* --- a command
  560. Parm16.HookProc.wParam = GETHWND16(wParam);
  561. break;
  562. case HCBT_QS:
  563. // wParam = 0, lParam = 0
  564. break;
  565. case HCBT_CREATEWND:
  566. // This stackalloc16() call needs to occur before the WM32Create()
  567. // call below to ensure proper nesting of stackalloc16 & stackfree16
  568. // calls.
  569. // Be sure allocation size matches stackfree16() size(s) below
  570. vp = stackalloc16(sizeof(CBT_CREATEWND16));
  571. // wParam = HWND, lParam = LPCBT_CREATEWND
  572. wm32mpex.fThunk = THUNKMSG;
  573. wm32mpex.hwnd = (HWND)wParam;
  574. wm32mpex.uMsg = 0;
  575. wm32mpex.uParam = 0;
  576. wm32mpex.lParam = (LONG)((LPCBT_CREATEWND)lParam)->lpcs;
  577. wm32mpex.pww = (PWW)GetWindowLong((HWND)wParam, GWL_WOWWORDS);
  578. /*
  579. * WM32Create now requires that pww be initialized
  580. * WM32Create calls stackalloc16()!!
  581. */
  582. if (!wm32mpex.pww || !WM32Create(&wm32mpex)) {
  583. stackfree16(vp, sizeof(CBT_CREATEWND16));
  584. return FALSE;
  585. }
  586. vpcs16 = wm32mpex.Parm16.WndProc.lParam;
  587. lReturn = wm32mpex.lReturn;
  588. GETMISCPTR(vp, pCbtCWnd16);
  589. STOREDWORD(pCbtCWnd16->vpcs, vpcs16);
  590. STOREWORD(pCbtCWnd16->hwndInsertAfter,
  591. GETHWNDIA16(((LPCBT_CREATEWND)lParam)->hwndInsertAfter));
  592. Parm16.HookProc.wParam = GETHWND16(wParam);
  593. Parm16.HookProc.lParam = vp;
  594. FLUSHVDMPTR(vp, sizeof(CBT_CREATEWND16), pCbtCWnd16);
  595. FREEVDMPTR(pCbtCWnd16);
  596. break;
  597. case HCBT_DESTROYWND:
  598. // wParam = HWND, lParam = 0
  599. Parm16.HookProc.wParam = GETHWND16(wParam);
  600. break;
  601. case HCBT_ACTIVATE:
  602. // wParam = HWND, lParam = LPCBTACTIVATESTRUCT
  603. // be sure allocation size matches stackfree16() size below
  604. vp = stackalloc16(sizeof(CBTACTIVATESTRUCT16));
  605. GETMISCPTR(vp, pCbtAStruct16);
  606. PUTCBTACTIVATESTRUCT16(pCbtAStruct16, ((LPCBTACTIVATESTRUCT)lParam));
  607. Parm16.HookProc.wParam = GETHWND16(wParam);
  608. Parm16.HookProc.lParam = vp;
  609. FLUSHVDMPTR(vp, sizeof(CBTACTIVATESTRUCT16), pCbtAStruct16);
  610. FREEVDMPTR(pCbtAStruct16);
  611. break;
  612. case HCBT_CLICKSKIPPED:
  613. // wParam = mouse message, lParam = LPMOUSEHOOKSTRUCT
  614. // be sure allocation size matches stackfree16() size below
  615. vp = stackalloc16(sizeof(MOUSEHOOKSTRUCT16));
  616. GETMISCPTR(vp, pMHStruct16);
  617. PUTMOUSEHOOKSTRUCT16(pMHStruct16, (LPMOUSEHOOKSTRUCT)lParam);
  618. Parm16.HookProc.lParam = vp;
  619. FLUSHVDMPTR(vp, sizeof(MOUSEHOOKSTRUCT16), pMHStruct16);
  620. FREEVDMPTR(pMHStruct16);
  621. break;
  622. case HCBT_KEYSKIPPED:
  623. // wParam, lParam -- keyup/down message params
  624. break;
  625. case HCBT_SYSCOMMAND:
  626. // wParam = SC_ syscomand, lParam = DWORD(x,y)
  627. break;
  628. case HCBT_SETFOCUS:
  629. // wParam = HWND, lParam = HWND
  630. Parm16.HookProc.wParam = GETHWND16(wParam);
  631. Parm16.HookProc.lParam = GETHWND16(lParam);
  632. break;
  633. default:
  634. LOGDEBUG(LOG_ALWAYS, ("ThunkCbtHook: Unknown HCBT_ code\n"));
  635. break;
  636. }
  637. CallBack16(RET_HOOKPROC, &Parm16, lpHSData->Proc16, (PVPVOID)&lReturn);
  638. switch(nCode) {
  639. case HCBT_MOVESIZE:
  640. GETRECT16(vp, (LPRECT)lParam);
  641. stackfree16(vp, sizeof(RECT16));
  642. break;
  643. case HCBT_CREATEWND:
  644. GETMISCPTR(vp, pCbtCWnd16);
  645. ((LPCBT_CREATEWND)lParam)->hwndInsertAfter =
  646. HWNDIA32(FETCHWORD(pCbtCWnd16->hwndInsertAfter));
  647. FREEVDMPTR(pCbtCWnd16);
  648. wm32mpex.fThunk = UNTHUNKMSG;
  649. wm32mpex.lReturn = lReturn;
  650. WM32Create(&wm32mpex); // this calls stackfree16()!!!
  651. lReturn = wm32mpex.lReturn;
  652. // this must be after call to WM32Create()
  653. stackfree16(vp, sizeof(CBT_CREATEWND16));
  654. break;
  655. case HCBT_ACTIVATE:
  656. GETMISCPTR(vp, pCbtAStruct16);
  657. GETCBTACTIVATESTRUCT16(pCbtAStruct16, (LPCBTACTIVATESTRUCT)lParam);
  658. FREEVDMPTR(pCbtAStruct16);
  659. stackfree16(vp, sizeof(CBTACTIVATESTRUCT16));
  660. break;
  661. case HCBT_CLICKSKIPPED:
  662. GETMISCPTR(vp, pMHStruct16);
  663. GETMOUSEHOOKSTRUCT16(pMHStruct16, (LPMOUSEHOOKSTRUCT)lParam);
  664. FREEVDMPTR(pMHStruct16);
  665. stackfree16(vp, sizeof(MOUSEHOOKSTRUCT16));
  666. break;
  667. // case HCBT_MINMAX:
  668. // case HCBT_QS:
  669. // case HCBT_DESTROYWND:
  670. // case HCBT_KEYSKIPPED:
  671. // case HCBT_SYSCOMMAND:
  672. // case HCBT_SETFOCUS:
  673. default:
  674. break;
  675. }
  676. // the value in LOWORD is the valid return value
  677. return (LONG)(BOOL)LOWORD(lReturn);
  678. }
  679. //*****************************************************************************
  680. //
  681. // ThunkHookProc for Hooks of type WH_KEYBOARD -
  682. //
  683. // Return type is BOOL.
  684. //
  685. //*****************************************************************************
  686. LONG ThunkKeyBoardHook(INT nCode, LONG wParam, LONG lParam,
  687. LPHOOKSTATEDATA lpHSData)
  688. {
  689. LONG lReturn;
  690. PARM16 Parm16;
  691. Parm16.HookProc.nCode = (SHORT)nCode;
  692. Parm16.HookProc.wParam = (SHORT)wParam;
  693. Parm16.HookProc.lParam = lParam;
  694. CallBack16(RET_HOOKPROC, &Parm16, lpHSData->Proc16, (PVPVOID)&lReturn);
  695. // the value in LOWORD is the valid return value
  696. return (LONG)(BOOL)LOWORD(lReturn);
  697. }
  698. //*****************************************************************************
  699. //
  700. // ThunkHookProc for Hooks of type WH_GETMESSAGE -
  701. // WH_MSGFILTER -
  702. // WH_SYSMSGFILTER -
  703. //
  704. // WARNING: May cause 16-bit memory movement, invalidating flat pointers.
  705. //
  706. // Return type is BOOL.
  707. //
  708. //*****************************************************************************
  709. LONG ThunkMsgFilterHook(INT nCode, LONG wParam, LPMSG lpMsg,
  710. LPHOOKSTATEDATA lpHSData)
  711. {
  712. VPVOID vp;
  713. PMSG16 pMsg16;
  714. PARM16 Parm16;
  715. WM32MSGPARAMEX wm32mpex;
  716. BOOL fHookModifiedLpMsg;
  717. HWND hwnd32;
  718. MSGPARAMEX mpex;
  719. BOOL fUseOld;
  720. static MSG msgSave;
  721. static int cRecurse = 0;
  722. static PARM16 Parm16Save;
  723. BOOL fMessageNeedsThunking;
  724. // This should be removed when all thunk functions appropiately fill these
  725. // in, till then we must have these 3 lines before calling thunk functions !
  726. // ChandanC, 2/28/92
  727. //
  728. wm32mpex.Parm16.WndProc.wMsg = (WORD) lpMsg->message;
  729. wm32mpex.Parm16.WndProc.wParam = (WORD) lpMsg->wParam;
  730. wm32mpex.Parm16.WndProc.lParam = (LONG) lpMsg->lParam;
  731. fMessageNeedsThunking = (lpMsg->message < 0x400) &&
  732. (aw32Msg[lpMsg->message].lpfnM32 != WM32NoThunking);
  733. fThunkDDEmsg = FALSE;
  734. if (fMessageNeedsThunking) {
  735. LOGDEBUG(3,("%04X (%s)\n", CURRENTPTD()->htask16,
  736. (aw32Msg[lpMsg->message].lpszW32)));
  737. wm32mpex.fThunk = THUNKMSG;
  738. wm32mpex.hwnd = lpMsg->hwnd;
  739. wm32mpex.uMsg = lpMsg->message;
  740. wm32mpex.uParam = lpMsg->wParam;
  741. wm32mpex.lParam = lpMsg->lParam;
  742. wm32mpex.pww = (PWW)NULL;
  743. wm32mpex.fFree = FALSE;
  744. wm32mpex.lpfnM32 = aw32Msg[wm32mpex.uMsg].lpfnM32;
  745. if (!((wm32mpex.lpfnM32)(&wm32mpex))) {
  746. LOGDEBUG(LOG_ALWAYS,("ThunkMsgFilterHook: cannot thunk 32-bit message %04x\n",
  747. lpMsg->message));
  748. }
  749. }
  750. fThunkDDEmsg = TRUE;
  751. //
  752. // Check to see if we've recursed into this routine. If so and the message
  753. // contents are the same, use the last message pointer we gave the 16
  754. // bit app rather than allocating a new one. Need this to solve the
  755. // SoundBits Browser problem. It checks to see if the lpmsg passed
  756. // is the same as it got last time - if so, it doesn't call this other
  757. // function that causes recursion.
  758. //
  759. fUseOld = FALSE;
  760. if (cRecurse != 0 && lpMsg->hwnd == msgSave.hwnd &&
  761. lpMsg->message == msgSave.message &&
  762. lpMsg->wParam == msgSave.wParam &&
  763. lpMsg->lParam == msgSave.lParam &&
  764. lpMsg->time == msgSave.time &&
  765. lpMsg->pt.x == msgSave.pt.x &&
  766. lpMsg->pt.y == msgSave.pt.y) {
  767. fUseOld = TRUE;
  768. } else {
  769. //
  770. // Not the same... reset this thing in case the count is screwed
  771. // up. Also remember this message, in case we do recurse.
  772. //
  773. cRecurse = 0;
  774. msgSave = *lpMsg;
  775. }
  776. if (!fUseOld) {
  777. vp = malloc16(sizeof(MSG16));
  778. if (vp == (VPVOID)NULL)
  779. return FALSE;
  780. GETMISCPTR(vp, pMsg16);
  781. STOREWORD(pMsg16->hwnd, GETHWND16((lpMsg)->hwnd));
  782. STOREWORD(pMsg16->message, wm32mpex.Parm16.WndProc.wMsg );
  783. STOREWORD(pMsg16->wParam, wm32mpex.Parm16.WndProc.wParam);
  784. STORELONG(pMsg16->lParam, wm32mpex.Parm16.WndProc.lParam);
  785. STORELONG(pMsg16->time, (lpMsg)->time);
  786. STOREWORD(pMsg16->pt.x, (lpMsg)->pt.x);
  787. STOREWORD(pMsg16->pt.y, (lpMsg)->pt.y);
  788. Parm16.HookProc.nCode = (SHORT)nCode;
  789. Parm16.HookProc.wParam = (SHORT)wParam;
  790. Parm16.HookProc.lParam = vp;
  791. //
  792. // Remember Parm16 in case we need to use it again due to the recursion
  793. // case.
  794. //
  795. Parm16Save = Parm16;
  796. } else {
  797. //
  798. // Use old message contents.
  799. //
  800. Parm16 = Parm16Save;
  801. vp = (VPVOID)Parm16Save.HookProc.lParam;
  802. GETMISCPTR(vp, pMsg16);
  803. }
  804. FLUSHVDMPTR(vp, sizeof(MSG16), pMsg16);
  805. //
  806. // Count how many times we recurse through this hook proc. Need this count
  807. // to solve the SoundBits Browser problem. It checks to see if the lpMsg
  808. // passed is the same as it got last time - if so, it doesn't call this
  809. // other function that causes recursion.
  810. //
  811. cRecurse++;
  812. CallBack16(RET_HOOKPROC, &Parm16, lpHSData->Proc16, (PVPVOID)&wm32mpex.lReturn);
  813. cRecurse--;
  814. // set the correct return value BEFORE unthunking
  815. wm32mpex.lReturn = (LONG)(BOOL)LOWORD(wm32mpex.lReturn);
  816. //
  817. // Free the 32 pointer to 16 bit args and get it again in case underlying
  818. // memory movement occured.
  819. //
  820. FREEVDMPTR(pMsg16);
  821. GETMISCPTR(vp, pMsg16);
  822. fThunkDDEmsg = FALSE;
  823. // Theoretically an app can change the lpMsg and return a totall different
  824. // data altogether. In practice most apps don't do anything so it is pretty
  825. // expensive to go through the 'unthunk' procedure all the time. So here is
  826. // a compromise. We copy the message params only if the output message is
  827. // different from the input message.
  828. //
  829. // (davehart) Polaris PackRat modifies WM_KEYDOWN messages sent to its
  830. // multiline "Note" edit control in its Phone Book Entry dialog box.
  831. // It changes wParam (the VK_ code) from 0xD (VK_RETURN) to 0xA, which
  832. // is understood by the edit control to be identical to VK_RETURN but
  833. // won't cause the dialog box to close. So we special-case here
  834. // WM_KEYDOWN where the hook proc changed the virtual key (in wParam)
  835. // and unthunk it properly.
  836. fHookModifiedLpMsg = (pMsg16->message != wm32mpex.Parm16.WndProc.wMsg) ||
  837. (wm32mpex.Parm16.WndProc.wMsg == WM_KEYDOWN &&
  838. pMsg16->wParam != wm32mpex.Parm16.WndProc.wParam) ||
  839. (pMsg16->hwnd != GETHWND16(lpMsg->hwnd));
  840. if (fHookModifiedLpMsg) {
  841. mpex.Parm16.WndProc.hwnd = pMsg16->hwnd;
  842. mpex.Parm16.WndProc.wMsg = pMsg16->message;
  843. mpex.Parm16.WndProc.wParam = pMsg16->wParam;
  844. mpex.Parm16.WndProc.lParam = pMsg16->lParam,
  845. mpex.iMsgThunkClass = WOWCLASS_WIN16;
  846. hwnd32 = ThunkMsg16(&mpex);
  847. //
  848. // Free the 32 pointer to 16 bit args and get it again in case
  849. // underlying memory movement occured.
  850. //
  851. FREEVDMPTR(pMsg16);
  852. GETMISCPTR(vp, pMsg16);
  853. // reset flag if message thunking failed.
  854. if (!hwnd32)
  855. fHookModifiedLpMsg = FALSE;
  856. }
  857. if (fMessageNeedsThunking) {
  858. wm32mpex.fThunk = UNTHUNKMSG;
  859. (wm32mpex.lpfnM32)(&wm32mpex);
  860. //
  861. // Free the 32 pointer to 16 bit args and get it again in case
  862. // underlying memory movement occured.
  863. //
  864. FREEVDMPTR(pMsg16);
  865. GETMISCPTR(vp, pMsg16);
  866. }
  867. fThunkDDEmsg = TRUE;
  868. if (fHookModifiedLpMsg) {
  869. lpMsg->hwnd = hwnd32;
  870. lpMsg->message = mpex.uMsg;
  871. lpMsg->wParam = mpex.uParam;
  872. lpMsg->lParam = mpex.lParam;
  873. lpMsg->time = FETCHLONG(pMsg16->time);
  874. lpMsg->pt.x = FETCHSHORT(pMsg16->pt.x);
  875. lpMsg->pt.y = FETCHSHORT(pMsg16->pt.y);
  876. }
  877. FREEVDMPTR(pMsg16);
  878. if (!fUseOld) {
  879. free16(vp);
  880. }
  881. // the value in LOWORD is the valid return value
  882. return (LONG)(BOOL)LOWORD(wm32mpex.lReturn);
  883. }
  884. //*****************************************************************************
  885. //
  886. // ThunkHookProc for Hooks of type WH_JOURNALPLAYBACK -
  887. // WH_JOUNRALRECORD -
  888. //
  889. // Return type is DWORD.
  890. //
  891. //*****************************************************************************
  892. LONG ThunkJournalHook(INT nCode, LONG wParam, LPEVENTMSG lpEventMsg,
  893. LPHOOKSTATEDATA lpHSData)
  894. {
  895. LONG lReturn;
  896. VPVOID vp;
  897. PEVENTMSG16 pEventMsg16;
  898. PARM16 Parm16;
  899. if ( lpEventMsg ) {
  900. // be sure allocation size matches stackfree16() size below
  901. vp = stackalloc16(sizeof(EVENTMSG16));
  902. // The WIN32 EVENTMSG structure has an additional field 'hwnd', which
  903. // is not there in WIN31 EVENTMSG structure. This field can be ignored
  904. // without any repercussions.
  905. if (lpHSData->iHook == WH_JOURNALRECORD) {
  906. GETMISCPTR(vp, pEventMsg16);
  907. PUTEVENTMSG16(pEventMsg16, lpEventMsg);
  908. FLUSHVDMPTR(vp, sizeof(EVENTMSG16), pEventMsg16);
  909. FREEVDMPTR(pEventMsg16);
  910. }
  911. } else {
  912. // lpEventMsg can be NULL indicating that no message data is requested.
  913. // If this is the case, there is no need to copy data for either
  914. // journal record or playback.
  915. vp = (VPVOID)0;
  916. }
  917. Parm16.HookProc.nCode = (SHORT)nCode;
  918. Parm16.HookProc.wParam = (SHORT)wParam;
  919. Parm16.HookProc.lParam = vp;
  920. CallBack16(RET_HOOKPROC, &Parm16, lpHSData->Proc16, (PVPVOID)&lReturn);
  921. if ( lpEventMsg ) {
  922. GETMISCPTR(vp, pEventMsg16);
  923. if (lpHSData->iHook == WH_JOURNALPLAYBACK) {
  924. GetEventMessage16(pEventMsg16, lpEventMsg);
  925. #ifdef FE_SB
  926. switch (lpEventMsg->message) {
  927. case WM_CHAR:
  928. case WM_CHARTOITEM:
  929. case WM_DEADCHAR:
  930. case WM_KEYDOWN:
  931. case WM_KEYUP:
  932. case WM_MENUCHAR:
  933. case WM_SYSCHAR:
  934. case WM_SYSDEADCHAR:
  935. case WM_SYSKEYDOWN:
  936. case WM_SYSKEYUP:
  937. case WM_VKEYTOITEM:
  938. // only virtual key, not use scan code
  939. lpEventMsg->paramL &= 0x0ff;
  940. }
  941. #endif // FE_SB
  942. #ifdef DEBUG
  943. if (MessageNeedsThunking(lpEventMsg->message)) {
  944. LOGDEBUG(LOG_ALWAYS, ("ThunkJournalHook: Playing back unexpected message 0x%x", lpEventMsg->message));
  945. }
  946. #endif
  947. } else {
  948. WOW32ASSERT(lpHSData->iHook == WH_JOURNALRECORD);
  949. WOW32ASSERT(aw32Msg[FETCHWORD(pEventMsg16->message)].lpfnM32 == WM32NoThunking);
  950. // If the app modified the message then copy the new message info
  951. // (rather than copying it every time we only copy it if the
  952. // app change the message)
  953. if (FETCHWORD(pEventMsg16->message) != lpEventMsg->message) {
  954. GetEventMessage16(pEventMsg16, lpEventMsg);
  955. }
  956. }
  957. FREEVDMPTR(pEventMsg16);
  958. if(vp) {
  959. stackfree16(vp, sizeof(EVENTMSG16));
  960. }
  961. }
  962. return lReturn;
  963. }
  964. //*****************************************************************************
  965. //
  966. // ThunkHookProc for Hooks of type WH_DEBUG -
  967. //
  968. // Return type is BOOL.
  969. //
  970. //*****************************************************************************
  971. LONG ThunkDebugHook(INT nCode, LONG wParam, LONG lParam,
  972. LPHOOKSTATEDATA lpHSData)
  973. {
  974. LONG lReturn;
  975. lReturn = TRUE;
  976. UNREFERENCED_PARAMETER(nCode);
  977. UNREFERENCED_PARAMETER(wParam);
  978. UNREFERENCED_PARAMETER(lParam);
  979. UNREFERENCED_PARAMETER(lpHSData);
  980. LOGDEBUG(LOG_ALWAYS, ("ThunkDebugHook:Not implemented.\n"));
  981. // the value in LOWORD is the valid return value
  982. return (LONG)(BOOL)LOWORD(lReturn);
  983. }
  984. //*****************************************************************************
  985. //
  986. // ThunkHookProc for Hooks of type WH_MOUSE -
  987. //
  988. // Return type is BOOL.
  989. //
  990. //*****************************************************************************
  991. LONG ThunkMouseHook(INT nCode, LONG wParam, LPMOUSEHOOKSTRUCT lpMHStruct,
  992. LPHOOKSTATEDATA lpHSData)
  993. {
  994. LONG lReturn;
  995. VPVOID vp;
  996. PMOUSEHOOKSTRUCT16 pMHStruct16;
  997. PARM16 Parm16;
  998. // be sure allocation size matches stackfree16() size below
  999. vp = stackalloc16(sizeof(MOUSEHOOKSTRUCT16));
  1000. GETMISCPTR(vp, pMHStruct16);
  1001. PUTMOUSEHOOKSTRUCT16(pMHStruct16, lpMHStruct);
  1002. Parm16.HookProc.nCode = (SHORT)nCode;
  1003. Parm16.HookProc.wParam = (SHORT)wParam;
  1004. Parm16.HookProc.lParam = vp;
  1005. FLUSHVDMPTR(vp, sizeof(MOUSEHOOKSTRUCT16), pMHStruct16);
  1006. FREEVDMPTR(pMHStruct16);
  1007. CallBack16(RET_HOOKPROC, &Parm16, lpHSData->Proc16, (PVPVOID)&lReturn);
  1008. GETMISCPTR(vp, pMHStruct16);
  1009. GETMOUSEHOOKSTRUCT16(pMHStruct16, lpMHStruct);
  1010. FREEVDMPTR(pMHStruct16);
  1011. if(vp) {
  1012. stackfree16(vp, sizeof(MOUSEHOOKSTRUCT16));
  1013. }
  1014. return (LONG)(BOOL)LOWORD(lReturn);
  1015. }
  1016. //*****************************************************************************
  1017. //
  1018. // ThunkHookProc for Hooks of type WH_SHELL -
  1019. //
  1020. // Return value apparently is zero.
  1021. //
  1022. //*****************************************************************************
  1023. LONG ThunkShellHook(INT nCode, LONG wParam, LONG lParam,
  1024. LPHOOKSTATEDATA lpHSData)
  1025. {
  1026. LONG lReturn;
  1027. PARM16 Parm16;
  1028. Parm16.HookProc.nCode = (SHORT)nCode;
  1029. Parm16.HookProc.lParam = lParam;
  1030. switch (nCode) {
  1031. case HSHELL_WINDOWCREATED:
  1032. case HSHELL_WINDOWDESTROYED:
  1033. Parm16.HookProc.wParam = (SHORT)GETHWND16(wParam);
  1034. break;
  1035. case HSHELL_ACTIVATESHELLWINDOW:
  1036. // fall thru
  1037. default:
  1038. Parm16.HookProc.wParam = (SHORT)wParam;
  1039. break;
  1040. }
  1041. CallBack16(RET_HOOKPROC, &Parm16, lpHSData->Proc16, (PVPVOID)&lReturn);
  1042. // lReturn = 0?
  1043. return (LONG)lReturn;
  1044. }
  1045. //*****************************************************************************
  1046. // W32UnhookHooks:
  1047. //
  1048. // Scans the list of active hooks for those for the passed in handle.
  1049. // Those that match are unhooked.
  1050. //
  1051. //*****************************************************************************
  1052. VOID W32UnhookHooks( HAND16 hMod16, BOOL fQueue )
  1053. {
  1054. INT i;
  1055. for (i = 0; i < vaHookPPData.cHookProcs; i++) {
  1056. if (vaHookStateData[i].InUse ) {
  1057. if ( !fQueue && ((HAND16)(vaHookStateData[i].hMod16) == hMod16) ) {
  1058. //
  1059. // Unhook this guy!
  1060. //
  1061. if (UnhookWindowsHookEx(vaHookStateData[i].hHook)) {
  1062. LOGDEBUG(7, ("W32FreeModuleHooks: Freed iHook (WH_*) %04x\n",
  1063. vaHookStateData[i].iHook));
  1064. }
  1065. else {
  1066. LOGDEBUG(LOG_ALWAYS, ("W32FreeModuleHooks: ERROR Freeing iHook (WH_*) %04x\n",
  1067. vaHookStateData[i].iHook));
  1068. }
  1069. // reset the state, even if Unhooking failed.
  1070. vaHookStateData[i].TaskId = 0;
  1071. vaHookStateData[i].InUse = FALSE;
  1072. }
  1073. }
  1074. }
  1075. }
  1076. //*****************************************************************************
  1077. // W32FreeOwnedHooks -
  1078. //
  1079. // Called during thread exit time. Frees all hooks set by specified thread.
  1080. //
  1081. //*****************************************************************************
  1082. BOOL W32FreeOwnedHooks(INT iTaskId)
  1083. {
  1084. INT i;
  1085. for (i = 0; i < vaHookPPData.cHookProcs; i++) {
  1086. if (vaHookStateData[i].InUse &&
  1087. vaHookStateData[i].TaskId == iTaskId) {
  1088. if (UnhookWindowsHookEx(vaHookStateData[i].hHook)) {
  1089. LOGDEBUG(7, ("W32FreeOwnedHooks: Freed iHook (WH_*) %04x\n",
  1090. vaHookStateData[i].iHook));
  1091. }
  1092. else {
  1093. LOGDEBUG(LOG_ALWAYS, ("W32FreeOwnedHooks: ERROR Freeing iHook (WH_*) %04x\n",
  1094. vaHookStateData[i].iHook));
  1095. }
  1096. // reset the state, even if Unhooking failed.
  1097. vaHookStateData[i].TaskId = 0;
  1098. vaHookStateData[i].InUse = FALSE;
  1099. }
  1100. }
  1101. return TRUE;
  1102. }
  1103. //*****************************************************************************
  1104. // W32StdDefHookProc: (Standard Def Hook Proc)
  1105. //
  1106. // WU32DefHookProc is called here.
  1107. // WARNING: May cause 16-bit memory movement, invalidating flat pointers.
  1108. // Return value is the new lParam.
  1109. //
  1110. //*****************************************************************************
  1111. LONG APIENTRY WU32StdDefHookProc(INT nCode, LONG wParam, LONG lParam, INT iFunc)
  1112. {
  1113. switch (vaHookStateData[iFunc].iHook) {
  1114. case WH_CALLWNDPROC:
  1115. return ThunkCallWndProcHook16(nCode, wParam, (VPVOID)lParam,
  1116. &vaHookStateData[iFunc]);
  1117. case WH_CBT:
  1118. return ThunkCbtHook16(nCode, wParam, (VPVOID)lParam,
  1119. &vaHookStateData[iFunc]);
  1120. case WH_KEYBOARD:
  1121. return ThunkKeyBoardHook16(nCode, wParam, lParam,
  1122. &vaHookStateData[iFunc]);
  1123. case WH_MSGFILTER:
  1124. case WH_SYSMSGFILTER:
  1125. case WH_GETMESSAGE:
  1126. return ThunkMsgFilterHook16(nCode, wParam, (VPVOID)lParam,
  1127. &vaHookStateData[iFunc]);
  1128. case WH_JOURNALPLAYBACK:
  1129. case WH_JOURNALRECORD:
  1130. return ThunkJournalHook16(nCode, wParam, (VPVOID)lParam,
  1131. &vaHookStateData[iFunc]);
  1132. case WH_DEBUG:
  1133. return ThunkDebugHook16(nCode, wParam, lParam,
  1134. &vaHookStateData[iFunc]);
  1135. case WH_MOUSE:
  1136. return ThunkMouseHook16(nCode, wParam, (VPVOID)lParam,
  1137. &vaHookStateData[iFunc]);
  1138. case WH_SHELL:
  1139. return ThunkShellHook16(nCode, wParam, lParam,
  1140. &vaHookStateData[iFunc]);
  1141. default:
  1142. LOGDEBUG(LOG_ALWAYS,("WU32StdDefHookProc: Unknown Hook type.\n"));
  1143. }
  1144. return (LONG)FALSE;
  1145. }
  1146. //*****************************************************************************
  1147. //
  1148. // 16->32 ThunkHookProc for Hooks of type WH_CALLWNDPROC -
  1149. //
  1150. // Return type is VOID.
  1151. //
  1152. //*****************************************************************************
  1153. LONG ThunkCallWndProcHook16(INT nCode, LONG wParam, VPVOID vpCwpStruct,
  1154. LPHOOKSTATEDATA lpHSData)
  1155. {
  1156. CWPSTRUCT CwpStruct;
  1157. PCWPSTRUCT16 pCwpStruct16;
  1158. MSGPARAMEX mpex;
  1159. GETMISCPTR(vpCwpStruct, pCwpStruct16);
  1160. mpex.Parm16.WndProc.hwnd = pCwpStruct16->hwnd;
  1161. mpex.Parm16.WndProc.wMsg = pCwpStruct16->message;
  1162. mpex.Parm16.WndProc.wParam = pCwpStruct16->wParam;
  1163. mpex.Parm16.WndProc.lParam = pCwpStruct16->lParam,
  1164. mpex.iMsgThunkClass = WOWCLASS_WIN16;
  1165. mpex.hwnd = ThunkMsg16(&mpex);
  1166. // memory may have moved
  1167. FREEVDMPTR(pCwpStruct16);
  1168. CwpStruct.message = mpex.uMsg;
  1169. CwpStruct.wParam = mpex.uParam;
  1170. CwpStruct.lParam = mpex.lParam;
  1171. CwpStruct.hwnd = mpex.hwnd;
  1172. mpex.lReturn = CallNextHookEx(lpHSData->hHook, nCode, wParam,
  1173. (LPARAM)&CwpStruct);
  1174. if (MSG16NEEDSTHUNKING(&mpex)) {
  1175. mpex.uMsg = CwpStruct.message;
  1176. mpex.uParam = CwpStruct.wParam;
  1177. mpex.lParam = CwpStruct.lParam;
  1178. (mpex.lpfnUnThunk16)(&mpex);
  1179. }
  1180. return mpex.lReturn;
  1181. }
  1182. //*****************************************************************************
  1183. //
  1184. // 16->32 ThunkHookProc for Hooks of type WH_CBT -
  1185. //
  1186. // Return type is BOOL.
  1187. //
  1188. //*****************************************************************************
  1189. LONG ThunkCbtHook16(INT nCode, LONG wParam, VPVOID lParam,
  1190. LPHOOKSTATEDATA lpHSData)
  1191. {
  1192. LONG lReturn = FALSE;
  1193. WPARAM wParamNew;
  1194. LPARAM lParamNew;
  1195. MSGPARAMEX mpex;
  1196. PMOUSEHOOKSTRUCT16 pMHStruct16;
  1197. PCBTACTIVATESTRUCT16 pCbtAStruct16;
  1198. PCBT_CREATEWND16 pCbtCWnd16;
  1199. PRECT16 pRect16;
  1200. MOUSEHOOKSTRUCT MHStruct;
  1201. RECT Rect;
  1202. CBTACTIVATESTRUCT CbtAStruct;
  1203. CBT_CREATEWND CbtCWnd;
  1204. // SudeepB 28-May-1996 updated DaveHart 16-July-96 to fix limit assertions.
  1205. //
  1206. // Some apps like SureTrack project management package are passing
  1207. // corrupted values in lParam. GETVDMPTR returns 0 for such an lParam.
  1208. // Using this 0 on X86 causes corruption of IVT and on RISC causes an
  1209. // AV in wow32 as zero is not a valid linear address. Such apps get
  1210. // away from such criminal acts on win3.1/Win95 as no thunking is needed
  1211. // there. So all the thunking below explicitly checks for GETVDMPTR
  1212. // returning 0 and in that case just leaves lParam unthunked.
  1213. wParamNew = (WPARAM) wParam;
  1214. lParamNew = (LPARAM) lParam;
  1215. switch(nCode) {
  1216. //
  1217. // These don't have a pointer in lParam.
  1218. //
  1219. case HCBT_SETFOCUS: // wParam = HWND, lParam = HWND
  1220. // fall through to set wParamNew & lParamNew,
  1221. // this counts on HWND32 zero-extending.
  1222. case HCBT_MINMAX: // wParam = HWND, lParam = SW_* --- a command
  1223. // fall through to set wParamNew & lParamNew.
  1224. // this counts on HWND32 zero-extending.
  1225. case HCBT_DESTROYWND: // wParam = HWND, lParam = 0
  1226. // fall through to set wParamNew & lParamNew.
  1227. // this counts on HWND32 zero-extending.
  1228. WOW32ASSERTMSG((HWND32(0x1234) == (HWND)0x1234),
  1229. "Code depending on HWND32 zero-extending needs revision.\n");
  1230. case HCBT_QS: // wParam = 0, lParam = 0
  1231. case HCBT_KEYSKIPPED: // wParam = VK_ keycode, lParam = WM_KEYUP/DOWN lParam
  1232. case HCBT_SYSCOMMAND: // wParam = SC_ syscomand, lParam = DWORD(x,y) if mouse
  1233. // lParamNew and wParamNew are initialized above with no thunking.
  1234. break;
  1235. //
  1236. // These use lParam as a pointer.
  1237. //
  1238. case HCBT_MOVESIZE: // wParam = HWND, lParam = LPRECT
  1239. #if 0 // HWND32 is a no-op, wParamNew already initialized.
  1240. wParamNew = (WPARAM) HWND32(wParam);
  1241. #endif
  1242. GETVDMPTR(lParam, sizeof(*pRect16), pRect16);
  1243. if (pRect16) {
  1244. GETRECT16(lParam, &Rect);
  1245. lParamNew = (LPARAM)&Rect;
  1246. FREEVDMPTR(pRect16);
  1247. }
  1248. break;
  1249. case HCBT_CREATEWND: // wParam = HWND, lParam = LPCBT_CREATEWND
  1250. #if 0 // HWND32 is a no-op, wParamNew already initialized.
  1251. wParamNew = (WPARAM) HWND32(wParam);
  1252. #endif
  1253. GETVDMPTR(lParam, sizeof(*pCbtCWnd16), pCbtCWnd16);
  1254. if (pCbtCWnd16) {
  1255. lParamNew = (LPARAM)&CbtCWnd;
  1256. mpex.Parm16.WndProc.hwnd = LOWORD(wParam);
  1257. mpex.Parm16.WndProc.wMsg = WM_CREATE;
  1258. mpex.Parm16.WndProc.wParam = 0;
  1259. mpex.Parm16.WndProc.lParam = FETCHDWORD(pCbtCWnd16->vpcs);
  1260. mpex.iMsgThunkClass = 0;
  1261. ThunkMsg16(&mpex);
  1262. //
  1263. // Memory movement can occur on the 16-bit side.
  1264. //
  1265. FREEVDMPTR(pCbtCWnd16);
  1266. GETVDMPTR(lParam, sizeof(*pCbtCWnd16), pCbtCWnd16);
  1267. (LONG)CbtCWnd.lpcs = mpex.lParam;
  1268. CbtCWnd.hwndInsertAfter =
  1269. HWNDIA32(FETCHWORD(pCbtCWnd16->hwndInsertAfter));
  1270. FREEVDMPTR(pCbtCWnd16);
  1271. }
  1272. break;
  1273. case HCBT_ACTIVATE: // wParam = HWND, lParam = LPCBTACTIVATESTRUCT
  1274. #if 0 // HWND32 is a no-op, wParamNew already initialized.
  1275. wParamNew = (WPARAM) HWND32(wParam);
  1276. #endif
  1277. GETVDMPTR(lParam, sizeof(*pCbtAStruct16), pCbtAStruct16);
  1278. if (pCbtAStruct16) {
  1279. lParamNew = (LPARAM)&CbtAStruct;
  1280. GETCBTACTIVATESTRUCT16(pCbtAStruct16, &CbtAStruct);
  1281. FREEVDMPTR(pCbtAStruct16);
  1282. }
  1283. break;
  1284. case HCBT_CLICKSKIPPED: // wParam = mouse message, lParam = LPMOUSEHOOKSTRUCT
  1285. GETVDMPTR(lParam, sizeof(*pMHStruct16), pMHStruct16);
  1286. if (pMHStruct16) {
  1287. lParamNew = (LPARAM)&MHStruct;
  1288. GETMOUSEHOOKSTRUCT16(pMHStruct16, &MHStruct);
  1289. FREEVDMPTR(pMHStruct16);
  1290. }
  1291. break;
  1292. default:
  1293. LOGDEBUG(LOG_ALWAYS, ("ThunkCbtHook: Unknown HCBT_ code 0x%x\n", nCode));
  1294. break;
  1295. }
  1296. //
  1297. // Call the hook, memory movement can occur.
  1298. //
  1299. lReturn = CallNextHookEx(lpHSData->hHook, nCode, wParamNew, lParamNew);
  1300. switch(nCode) {
  1301. //
  1302. // These don't have a pointer in lParam.
  1303. //
  1304. // case HCBT_SETFOCUS: // wParam = HWND, lParam = HWND
  1305. // case HCBT_MINMAX: // wParam = HWND, lParam = SW_* --- a command
  1306. // case HCBT_DESTROYWND: // wParam = HWND, lParam = 0
  1307. // case HCBT_QS: // wParam = 0, lParam = 0
  1308. // case HCBT_KEYSKIPPED: // wParam = VK_ keycode, lParam = WM_KEYUP/DOWN lParam
  1309. // case HCBT_SYSCOMMAND: // wParam = SC_ syscomand, lParam = DWORD(x,y) if mouse
  1310. // break;
  1311. //
  1312. // These use lParam as a pointer.
  1313. //
  1314. case HCBT_MOVESIZE: // wParam = HWND, lParam = LPRECT
  1315. PUTRECT16(lParam, (LPRECT)lParamNew);
  1316. break;
  1317. case HCBT_CREATEWND: // wParam = HWND, lParam = LPCBT_CREATEWND
  1318. GETVDMPTR(lParam, sizeof(*pCbtCWnd16), pCbtCWnd16);
  1319. if (pCbtCWnd16) {
  1320. mpex.lParam = (LONG)CbtCWnd.lpcs;
  1321. mpex.lReturn = lReturn;
  1322. WOW32ASSERT(MSG16NEEDSTHUNKING(&mpex));
  1323. (mpex.lpfnUnThunk16)(&mpex);
  1324. lReturn = mpex.lReturn;
  1325. STOREWORD(pCbtCWnd16->hwndInsertAfter,
  1326. GETHWNDIA16(((LPCBT_CREATEWND)lParamNew)->
  1327. hwndInsertAfter));
  1328. FLUSHVDMPTR((VPVOID)lParam, sizeof(CBT_CREATEWND16), pCbtCWnd16);
  1329. FREEVDMPTR(pCbtCWnd16);
  1330. }
  1331. break;
  1332. case HCBT_ACTIVATE: // wParam = HWND, lParam = LPCBTACTIVATESTRUCT
  1333. GETVDMPTR(lParam, sizeof(*pCbtAStruct16), pCbtAStruct16);
  1334. if (pCbtAStruct16) {
  1335. PUTCBTACTIVATESTRUCT16(pCbtAStruct16, (LPCBTACTIVATESTRUCT)lParamNew);
  1336. FLUSHVDMPTR((VPVOID)lParam, sizeof(CBTACTIVATESTRUCT16),
  1337. pCbtAStruct16);
  1338. FREEVDMPTR(pCbtAStruct16);
  1339. }
  1340. break;
  1341. case HCBT_CLICKSKIPPED: // wParam = mouse message, lParam = LPMOUSEHOOKSTRUCT
  1342. GETVDMPTR(lParam, sizeof(*pMHStruct16), pMHStruct16);
  1343. if (pMHStruct16) {
  1344. PUTMOUSEHOOKSTRUCT16(pMHStruct16, (LPMOUSEHOOKSTRUCT)lParamNew);
  1345. FLUSHVDMPTR((VPVOID)lParam, sizeof(MOUSEHOOKSTRUCT16),
  1346. pMHStruct16);
  1347. FREEVDMPTR(pMHStruct16);
  1348. }
  1349. break;
  1350. }
  1351. // the value in LOWORD is the valid return value
  1352. return (LONG)(BOOL)LOWORD(lReturn);
  1353. }
  1354. //*****************************************************************************
  1355. //
  1356. // 16->32 ThunkHookProc for Hooks of type WH_KEYBOARD -
  1357. //
  1358. // Return type is BOOL.
  1359. //
  1360. //*****************************************************************************
  1361. LONG ThunkKeyBoardHook16(INT nCode, LONG wParam, LONG lParam,
  1362. LPHOOKSTATEDATA lpHSData)
  1363. {
  1364. LONG lReturn;
  1365. lReturn = CallNextHookEx(lpHSData->hHook, nCode, wParam,
  1366. (LPARAM)lParam);
  1367. // the value in LOWORD is the valid return value
  1368. return (LONG)(BOOL)LOWORD(lReturn);
  1369. }
  1370. //*****************************************************************************
  1371. //
  1372. // 16->32 ThunkHookProc for Hooks of type WH_GETMESSAGE -
  1373. // WH_MSGFILTER -
  1374. // WH_SYSMSGFILTER -
  1375. //
  1376. // Return type is BOOL.
  1377. //
  1378. //*****************************************************************************
  1379. LONG ThunkMsgFilterHook16(INT nCode, LONG wParam, VPVOID vpMsg,
  1380. LPHOOKSTATEDATA lpHSData)
  1381. {
  1382. PMSG16 pMsg16;
  1383. MSG Msg;
  1384. MSGPARAMEX mpex;
  1385. GETMISCPTR(vpMsg, pMsg16);
  1386. fThunkDDEmsg = FALSE;
  1387. mpex.Parm16.WndProc.hwnd = pMsg16->hwnd;
  1388. mpex.Parm16.WndProc.wMsg = pMsg16->message;
  1389. mpex.Parm16.WndProc.wParam = pMsg16->wParam;
  1390. mpex.Parm16.WndProc.lParam = pMsg16->lParam;
  1391. mpex.iMsgThunkClass = 0;
  1392. ThunkMsg16(&mpex);
  1393. //
  1394. // Memory movement can occur on the 16-bit side.
  1395. //
  1396. FREEVDMPTR(pMsg16);
  1397. GETMISCPTR(vpMsg, pMsg16);
  1398. fThunkDDEmsg = TRUE;
  1399. Msg.message = mpex.uMsg;
  1400. Msg.wParam = mpex.uParam;
  1401. Msg.lParam = mpex.lParam;
  1402. Msg.hwnd = HWND32(FETCHWORD(pMsg16->hwnd));
  1403. Msg.time = FETCHLONG(pMsg16->time);
  1404. Msg.pt.x = FETCHSHORT(pMsg16->pt.x);
  1405. Msg.pt.y = FETCHSHORT(pMsg16->pt.y);
  1406. FREEVDMPTR(pMsg16);
  1407. mpex.lReturn = CallNextHookEx(lpHSData->hHook, nCode, wParam,
  1408. (LPARAM)&Msg);
  1409. GETMISCPTR(vpMsg, pMsg16);
  1410. if (MSG16NEEDSTHUNKING(&mpex)) {
  1411. mpex.uMsg = Msg.message;
  1412. mpex.uParam = Msg.wParam;
  1413. mpex.lParam = Msg.lParam;
  1414. (mpex.lpfnUnThunk16)(&mpex);
  1415. GETMISCPTR(vpMsg, pMsg16);
  1416. }
  1417. STORELONG(pMsg16->time, Msg.time);
  1418. STOREWORD(pMsg16->pt.x, Msg.pt.x);
  1419. STOREWORD(pMsg16->pt.y, Msg.pt.y);
  1420. FLUSHVDMPTR(vpMsg, sizeof(MSG16), pMsg16);
  1421. FREEVDMPTR(pMsg16);
  1422. // the value in LOWORD is the valid return value
  1423. return (LONG)(BOOL)LOWORD(mpex.lReturn);
  1424. }
  1425. //*****************************************************************************
  1426. //
  1427. // 16->32 ThunkHookProc for Hooks of type WH_JOURNALPLAYBACK -
  1428. // WH_JOUNRALRECORD -
  1429. //
  1430. // Return type is DWORD.
  1431. //
  1432. //*****************************************************************************
  1433. LONG ThunkJournalHook16(INT nCode, LONG wParam, VPVOID vpEventMsg,
  1434. LPHOOKSTATEDATA lpHSData)
  1435. {
  1436. LONG lReturn;
  1437. PEVENTMSG16 pEventMsg16;
  1438. EVENTMSG EventMsg;
  1439. LPEVENTMSG lpEventMsg;
  1440. if ( vpEventMsg ) {
  1441. // The WIN32 EVENTMSG structure has an additional field 'hwnd', which
  1442. // is not there in WIN31 EVENTMSG structure. This field can be ignored
  1443. // without any repercussions.
  1444. if (lpHSData->iHook == WH_JOURNALRECORD) {
  1445. GETMISCPTR(vpEventMsg, pEventMsg16);
  1446. GetEventMessage16(pEventMsg16, &EventMsg);
  1447. EventMsg.hwnd = (HWND)0;
  1448. FREEVDMPTR(pEventMsg16);
  1449. }
  1450. lpEventMsg = &EventMsg;
  1451. } else {
  1452. lpEventMsg = NULL;
  1453. }
  1454. lReturn = CallNextHookEx(lpHSData->hHook, nCode, wParam, (LPARAM)lpEventMsg );
  1455. if ( vpEventMsg ) {
  1456. if (lpHSData->iHook == WH_JOURNALPLAYBACK) {
  1457. GETMISCPTR(vpEventMsg, pEventMsg16);
  1458. PUTEVENTMSG16(pEventMsg16, &EventMsg);
  1459. FLUSHVDMPTR(vpEventMsg, sizeof(EVENTMSG16), pEventMsg16);
  1460. FREEVDMPTR(pEventMsg16);
  1461. }
  1462. }
  1463. return lReturn;
  1464. }
  1465. //*****************************************************************************
  1466. //
  1467. // 16->32 ThunkHookProc for Hooks of type WH_DEBUG -
  1468. //
  1469. // Return type is BOOL.
  1470. //
  1471. //*****************************************************************************
  1472. LONG ThunkDebugHook16(INT nCode, LONG wParam, LONG lParam,
  1473. LPHOOKSTATEDATA lpHSData)
  1474. {
  1475. LONG lReturn;
  1476. lReturn = TRUE;
  1477. UNREFERENCED_PARAMETER(nCode);
  1478. UNREFERENCED_PARAMETER(wParam);
  1479. UNREFERENCED_PARAMETER(lParam);
  1480. UNREFERENCED_PARAMETER(lpHSData);
  1481. LOGDEBUG(LOG_ALWAYS, ("ThunkDebugHook16:Not implemented.\n"));
  1482. // the value in LOWORD is the valid return value
  1483. return (LONG)(BOOL)LOWORD(lReturn);
  1484. }
  1485. //*****************************************************************************
  1486. //
  1487. // 16->32 ThunkHookProc for Hooks of type WH_MOUSE -
  1488. //
  1489. // Return type is BOOL.
  1490. //
  1491. //*****************************************************************************
  1492. LONG ThunkMouseHook16(INT nCode, LONG wParam, VPVOID vpMHStruct,
  1493. LPHOOKSTATEDATA lpHSData)
  1494. {
  1495. LONG lReturn;
  1496. PMOUSEHOOKSTRUCT16 pMHStruct16;
  1497. MOUSEHOOKSTRUCT MHStruct;
  1498. GETMISCPTR(vpMHStruct, pMHStruct16);
  1499. GETMOUSEHOOKSTRUCT16(pMHStruct16, &MHStruct);
  1500. FREEVDMPTR(pMHStruct16);
  1501. lReturn = CallNextHookEx(lpHSData->hHook, nCode, wParam,
  1502. (LPARAM)&MHStruct);
  1503. GETMISCPTR(vpMHStruct, pMHStruct16);
  1504. PUTMOUSEHOOKSTRUCT16(pMHStruct16, &MHStruct);
  1505. FLUSHVDMPTR((VPVOID)vpMHStruct, sizeof(MOUSEHOOKSTRUCT16), pMHStruct16);
  1506. FREEVDMPTR(pMHStruct16);
  1507. return (LONG)(BOOL)LOWORD(lReturn);
  1508. }
  1509. //*****************************************************************************
  1510. //
  1511. // 16->32 ThunkHookProc for Hooks of type WH_SHELL -
  1512. //
  1513. // Return value is apparently zero.
  1514. //
  1515. //*****************************************************************************
  1516. LONG ThunkShellHook16(INT nCode, LONG wParam, LONG lParam,
  1517. LPHOOKSTATEDATA lpHSData)
  1518. {
  1519. LONG lReturn;
  1520. switch (nCode) {
  1521. case HSHELL_WINDOWCREATED:
  1522. case HSHELL_WINDOWDESTROYED:
  1523. wParam = (LONG)HWND32(wParam);
  1524. break;
  1525. case HSHELL_ACTIVATESHELLWINDOW:
  1526. // fall thru
  1527. default:
  1528. break;
  1529. }
  1530. lReturn = CallNextHookEx(lpHSData->hHook, nCode, wParam,
  1531. (LPARAM)lParam);
  1532. // lReturn = 0?
  1533. return (LONG)lReturn;
  1534. }
  1535. //*****************************************************************************
  1536. // W32GetHookDDEMsglParam:
  1537. //
  1538. // Returns the lParam of the actual hook message. called for dde messages
  1539. // only. returns valid lParam else 0.
  1540. //
  1541. //*****************************************************************************
  1542. DWORD W32GetHookDDEMsglParam()
  1543. {
  1544. INT iFunc;
  1545. LONG lParam;
  1546. iFunc = viCurrentHookStateDataIndex;
  1547. lParam = vHookParams.lParam;
  1548. if (lParam) {
  1549. switch (vaHookStateData[iFunc].iHook) {
  1550. case WH_CALLWNDPROC:
  1551. lParam = ((LPCWPSTRUCT)lParam)->lParam;
  1552. break;
  1553. case WH_MSGFILTER:
  1554. case WH_SYSMSGFILTER:
  1555. case WH_GETMESSAGE:
  1556. lParam = ((LPMSG)lParam)->lParam;
  1557. break;
  1558. default:
  1559. lParam = 0;
  1560. }
  1561. }
  1562. return lParam;
  1563. }
  1564. //*****************************************************************************
  1565. // GetEventMessage16:
  1566. //
  1567. //*****************************************************************************
  1568. VOID GetEventMessage16(PEVENTMSG16 pEventMsg16, LPEVENTMSG lpEventMsg)
  1569. {
  1570. lpEventMsg->message = FETCHWORD(pEventMsg16->message);
  1571. lpEventMsg->time = FETCHLONG(pEventMsg16->time);
  1572. if ((lpEventMsg->message >= WM_KEYFIRST) && (lpEventMsg->message <= WM_KEYLAST)) {
  1573. // Key event
  1574. lpEventMsg->paramL = FETCHWORD(pEventMsg16->paramL);
  1575. lpEventMsg->paramH = FETCHWORD(pEventMsg16->paramH) & 0x8000;
  1576. lpEventMsg->paramH |= (lpEventMsg->paramL & 0xFF00) >> 8;
  1577. lpEventMsg->paramL &= 0xFF;
  1578. }
  1579. else {
  1580. // Mouse event
  1581. lpEventMsg->paramL = FETCHWORD(pEventMsg16->paramL);
  1582. lpEventMsg->paramH = FETCHWORD(pEventMsg16->paramH);
  1583. }
  1584. }