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.

3516 lines
105 KiB

  1. /*++
  2. *
  3. * WOW v1.0
  4. *
  5. * Copyright (c) 1991, Microsoft Corporation
  6. *
  7. * WMDISP32.C
  8. * WOW32 32-bit message thunks
  9. *
  10. * History:
  11. * Created 19-Feb-1992 by Chandan S. Chauhan (ChandanC)
  12. * Changed 12-May-1992 by Mike Tricker (MikeTri) Added MultiMedia thunks
  13. * Changed 09-Jul-1992 by v-cjones Added msg profiling debugger extension
  14. --*/
  15. #include "precomp.h"
  16. #pragma hdrstop
  17. #ifdef FE_IME
  18. #include "wownls.h"
  19. #include "ime.h"
  20. #include "prshtp.h"
  21. #endif // FE_IME
  22. MODNAME(wmdisp32.c);
  23. BOOL fThunkDDEmsg = TRUE;
  24. extern WORD msgFINDREPLACE; // see WCOMMDLG.C
  25. #ifdef WOWPROFILE // for MSG profiling only (debugger extension)
  26. INT fWMsgProfRT = 0;
  27. #endif
  28. BOOL W32Win16DlgProcEx(HWND hdlg, UINT uMsg, UINT uParam, LONG lParam,
  29. VPWNDPROC vpDlgProc16, // Next WndProc to call or NULL if default
  30. PWW pww) // hwnd's PWW if already known or NULL
  31. {
  32. BOOL fSuccess;
  33. register PTD ptd;
  34. WM32MSGPARAMEX wm32mpex;
  35. BOOL fMessageNeedsThunking;
  36. #ifdef WOWPROFILE // for MSG profiling only (debugger extension)
  37. DWORD dwTics;
  38. #endif
  39. ptd = CURRENTPTD();
  40. WOW32ASSERT(vpDlgProc16);
  41. // take out the marker bits and fix the RPL bits
  42. UnMarkWOWProc (vpDlgProc16,vpDlgProc16);
  43. // If the app has GP Faulted we don't want to pass it any more input
  44. // This should be removed when USER32 does clean up on task death so
  45. // it doesn't call us - mattfe june 24 92 HACK32
  46. if (ptd->dwFlags & TDF_IGNOREINPUT) {
  47. LOGDEBUG(6,(" W32Dlg16WndProc Ignoring Input Messsage %04X\n",uMsg));
  48. WOW32ASSERTMSG(gfIgnoreInputAssertGiven,
  49. "W32Dlg16WndProc: TDF_IGNOREINPUT hack was used, shouldn't be, "
  50. "please email DaveHart with repro instructions. Hit 'g' to ignore this "
  51. "and suppress this assertion from now on.\n");
  52. gfIgnoreInputAssertGiven = TRUE;
  53. return FALSE;
  54. }
  55. wm32mpex.Parm16.WndProc.hwnd = GETHWND16(hdlg);
  56. wm32mpex.Parm16.WndProc.wMsg = (WORD)uMsg;
  57. wm32mpex.Parm16.WndProc.wParam = (WORD)uParam;
  58. wm32mpex.Parm16.WndProc.lParam = (LONG)lParam;
  59. wm32mpex.Parm16.WndProc.hInst = 0; // Forces AX = SS on WndProc entry,
  60. // for Win 3.1 compatibility.
  61. fMessageNeedsThunking = (uMsg < 0x400) &&
  62. (aw32Msg[uMsg].lpfnM32 != WM32NoThunking);
  63. if (fMessageNeedsThunking) {
  64. LOGDEBUG(3,("%04X (%s)\n", CURRENTPTD()->htask16, (aw32Msg[uMsg].lpszW32)));
  65. #ifdef WOWPROFILE // for MSG profiling only (debugger extension)
  66. dwTics = GetWOWTicDiff(0L);
  67. #endif
  68. wm32mpex.fThunk = THUNKMSG;
  69. wm32mpex.hwnd = hdlg;
  70. wm32mpex.uMsg = uMsg;
  71. wm32mpex.uParam = uParam;
  72. wm32mpex.lParam = lParam;
  73. wm32mpex.pww = pww;
  74. wm32mpex.fFree = TRUE;
  75. wm32mpex.lpfnM32 = aw32Msg[uMsg].lpfnM32;
  76. if (!(wm32mpex.lpfnM32)(&wm32mpex)) {
  77. LOGDEBUG(LOG_ERROR,(" W32Win16DlgProcEx ERROR: cannot thunk 32-bit message %04x\n", uMsg));
  78. goto Error;
  79. }
  80. #ifdef WOWPROFILE // for MSG profiling only (debugger extension)
  81. if( !fWMsgProfRT ) { // only if not profiling round trip
  82. aw32Msg[uMsg].cTics += GetWOWTicDiff(dwTics);
  83. }
  84. #endif
  85. }
  86. else {
  87. LOGDEBUG(6,(" No Thunking was required for the 32-bit message %s(%04x)\n", (LPSZ)GetWMMsgName(uMsg), uMsg));
  88. }
  89. BlockWOWIdle(FALSE);
  90. fSuccess = CallBack16(RET_WNDPROC, &wm32mpex.Parm16, vpDlgProc16, (PVPVOID)&wm32mpex.lReturn);
  91. BlockWOWIdle(TRUE);
  92. // the callback function of a dialog is of type FARPROC whose return value
  93. // is of type 'int'. Since dx:ax is copied into lReturn in the above
  94. // CallBack16 call, we need to zero out the hiword, otherwise we will be
  95. // returning an erroneous value.
  96. wm32mpex.lReturn = (LONG)((SHORT)(LOWORD(wm32mpex.lReturn)));
  97. if (fMessageNeedsThunking) {
  98. #ifdef WOWPROFILE // for MSG profiling only (debugger extension)
  99. if( !fWMsgProfRT ) { // only if not round trip profiling
  100. dwTics = GetWOWTicDiff(0L);
  101. }
  102. #endif // WOWPROFILE
  103. //
  104. // if you send a message to a dialog what gets returned
  105. // to the caller is the dlg's msgresult window long.
  106. // app dialog functions will call
  107. // SetWindowLong(hdlg, DWL_MSGRESULT, n);
  108. // during message processing so the right thing gets returned.
  109. // scottlu says we only need to do this for wm_gettext, it's
  110. // the only message whose result is an output count.
  111. //
  112. if (uMsg == WM_GETTEXT && wm32mpex.lReturn != 0) {
  113. wm32mpex.lReturn = GetWindowLong(hdlg, DWL_MSGRESULT);
  114. }
  115. wm32mpex.fThunk = UNTHUNKMSG;
  116. (wm32mpex.lpfnM32)(&wm32mpex);
  117. #ifdef WOWPROFILE // for MSG profiling only (debugger extension)
  118. aw32Msg[uMsg].cTics += GetWOWTicDiff(dwTics);
  119. aw32Msg[uMsg].cCalls++; // increment # times message passed
  120. #endif // WOWPROFILE
  121. }
  122. if (!fSuccess)
  123. goto Error;
  124. Done:
  125. return wm32mpex.lReturn;
  126. Error:
  127. LOGDEBUG(6,(" W32Win16DlgProcEx WARNING: cannot call back, using default message handling\n"));
  128. wm32mpex.lReturn = 0;
  129. goto Done;
  130. }
  131. LONG W32Win16WndProcEx(HWND hwnd, UINT uMsg, UINT uParam, LONG lParam,
  132. VPWNDPROC vpWndProc16, // Next WndProc to call or NULL if default
  133. PWW pww) // hwnd's PWW if already known or NULL
  134. {
  135. BOOL fSuccess;
  136. LONG ulReturn;
  137. register PTD ptd;
  138. WM32MSGPARAMEX wm32mpex;
  139. BOOL fMessageNeedsThunking;
  140. //#ifdef DEBUG
  141. // CHAR szClassName[80];
  142. //#endif
  143. #ifdef WOWPROFILE // for MSG profiling only (debugger extension)
  144. DWORD dwTics;
  145. #endif
  146. ptd = CURRENTPTD();
  147. WOW32ASSERT(vpWndProc16);
  148. // take out the marker bits and fix the RPL bits
  149. UnMarkWOWProc (vpWndProc16,vpWndProc16);
  150. //
  151. // If the app has GP Faulted we don't want to pass it any more input
  152. // This should be removed when USER32 does clean up on task death so
  153. // it doesn't call us - mattfe june 24 92 HACK32
  154. //
  155. // It's not a problem if the callback is going to a 16:16 proc in user.exe
  156. // like DefWindowProc.
  157. //
  158. if (ptd->dwFlags & TDF_IGNOREINPUT &&
  159. HIWORD(vpWndProc16) != HIWORD(gpfn16GetProcModule)) {
  160. LOGDEBUG(6,(" W32Win16WndProcEx Ignoring Input Messsage %04X\n",uMsg));
  161. WOW32ASSERTMSG(gfIgnoreInputAssertGiven,
  162. "W32Win16WndProcEx: TDF_IGNOREINPUT hack was used, shouldn't be, "
  163. "please email DaveHart with repro instructions. Hit 'g' to ignore this "
  164. "and suppress this assertion from now on.\n");
  165. gfIgnoreInputAssertGiven = TRUE;
  166. goto SilentError;
  167. }
  168. //
  169. // Don't send WM_DEVMODECHANGE if TDF_EATDEVMODEMSG is set
  170. // access2.0 faults if it is in EnumMetaFile and receives WM_DEVMODECHANGE
  171. // while in it whistler bug 189703
  172. //
  173. if (( ptd->dwFlags & TDF_EATDEVMODEMSG ) && ( uMsg == WM_DEVMODECHANGE )) {
  174. return 0;
  175. }
  176. //
  177. // Figure out the class for this hwnd if we haven't seen it before
  178. //
  179. if (!pww) {
  180. if (!(pww = (PWW) GetWindowLong(hwnd, GWL_WOWWORDS))) {
  181. LOGDEBUG(LOG_ALWAYS,("WOW :: W32Win16WndProcEx ERROR: GetWindowLong(0x%x, GWL_WOWWORDS) fails\n", hwnd));
  182. goto Error;
  183. }
  184. }
  185. #ifdef FE_IME
  186. if (( uMsg == WM_IME_REPORT ) && ( uParam == IR_STRINGEX )) {
  187. HANDLE hInstance;
  188. hInstance = (HANDLE)(ULONG)GetWindowLong(hwnd, GWL_HINSTANCE);
  189. hInstance = (HANDLE)(ULONG)VALIDHMOD(hInstance);
  190. if (W32GetExpWinVer(hInstance) < 0x030a)
  191. return 0;
  192. }
  193. //
  194. // Don't dispatch Version 4.0 IMM Messages to 16bit apps.
  195. //
  196. // WM_IME_STARTCOMPOSITION 0x010D
  197. // WM_IME_ENDCOMPOSITION 0x010E
  198. // WM_IME_COMPOSITION 0x010F
  199. // WM_IME_SETCONTEXT 0x0281
  200. // WM_IME_NOTIFY 0x0282
  201. // WM_IME_CONTROL 0x0283
  202. // WM_IME_COMPOSITIONFULL 0x0284
  203. // WM_IME_SELECT 0x0285
  204. // WM_IME_CHAR 0x0286
  205. // WM_IME_SYSTEM 0x0287
  206. //
  207. if ((( uMsg >= WM_IME_STARTCOMPOSITION ) && ( uMsg <= WM_IME_COMPOSITION )) ||
  208. (( uMsg >= WM_IME_SETCONTEXT ) && (uMsg <= WM_IME_SYSTEM ))) {
  209. // Korean Edit conrol need to dispatch new IMM messages.
  210. if ( !(GetStdClassWndProc(WOWCLASS_EDIT) && GetSystemDefaultLangID()==0x412) ) {
  211. HANDLE hInstance;
  212. hInstance = (HANDLE)(ULONG)GetWindowLong(hwnd, GWL_HINSTANCE);
  213. hInstance = (HANDLE)(ULONG)VALIDHMOD(hInstance);
  214. if (W32GetExpWinVer(hInstance) < 0x0400)
  215. goto Error;
  216. }
  217. }
  218. #endif // FE_IME
  219. // This message is WIN32 only. It is sent by WOW32 during the processing
  220. // of an EM_SETSEL in WU32Send/PostMessage. If an MLE is subclassed the
  221. // message will come through here attempting to travel back to the 16-bit
  222. // app's wndproc. Instead of sending back a message that the 16-bit app
  223. // doesn't understand it will be intercepted here and sent directly to the
  224. // standard EditWindowProc. I'm not adding a Thunk because it shouldn't
  225. // go to the app.
  226. if (uMsg == EM_SCROLLCARET) {
  227. WNDPROC EditWndProc;
  228. // find the 32-bit EditWindowProc
  229. // We should only be in this state if the app has subclassed so this
  230. // call should be safe.
  231. EditWndProc = (WNDPROC)GetStdClassWndProc(WOWCLASS_EDIT);
  232. if (EditWndProc) {
  233. CallWindowProc(EditWndProc, hwnd, EM_SCROLLCARET, 0, 0);
  234. }
  235. else {
  236. LOGDEBUG(LOG_ALWAYS,(" W32Win16WndProcEx ERROR: cannot find 32-bit EditWindowProc\n"));
  237. }
  238. return 0; // notification message, no return code
  239. }
  240. // Thunk this 32 bit message to 16 bit message
  241. LOGDEBUG(6,(" Thunking window %x message %s\n", hwnd, GetWMMsgName(uMsg)));
  242. #ifdef DEBUG
  243. if((uMsg & WOWPRIVATEMSG) && ((uMsg & ~WOWPRIVATEMSG) < 0x400)) {
  244. LOGDEBUG(6,(" -- private WOW bit set for %s\n", GetWMMsgName(uMsg & ~WOWPRIVATEMSG)));
  245. }
  246. #endif
  247. wm32mpex.Parm16.WndProc.hwnd = GETHWND16(hwnd);
  248. wm32mpex.Parm16.WndProc.wMsg = (WORD)uMsg;
  249. wm32mpex.Parm16.WndProc.wParam = (WORD)uParam;
  250. wm32mpex.Parm16.WndProc.lParam = (LONG)lParam;
  251. wm32mpex.Parm16.WndProc.hInst = LOWORD(pww->hModule);
  252. // An app can send one of its private class windows a message say 401.
  253. // This message will not be thunked in WMSG16.C because the
  254. // messages >= 0x400 and we did not want to thunk it in WMSG16.C
  255. //
  256. fMessageNeedsThunking = (uMsg < 0x400) &&
  257. (aw32Msg[uMsg].lpfnM32 != WM32NoThunking);
  258. if (fMessageNeedsThunking) {
  259. LOGDEBUG(6,("%04X (%s)\n", ptd->htask16, (aw32Msg[uMsg].lpszW32)));
  260. #ifdef WOWPROFILE // for MSG profiling only (debugger extension)
  261. dwTics = GetWOWTicDiff(0L);
  262. #endif
  263. wm32mpex.fThunk = THUNKMSG;
  264. wm32mpex.hwnd = hwnd;
  265. wm32mpex.uMsg = uMsg;
  266. wm32mpex.uParam = uParam;
  267. wm32mpex.lParam = lParam;
  268. wm32mpex.pww = pww;
  269. wm32mpex.fFree = TRUE;
  270. wm32mpex.lpfnM32 = aw32Msg[uMsg].lpfnM32;
  271. ulReturn = (wm32mpex.lpfnM32)(&wm32mpex);
  272. #ifdef WOWPROFILE // for MSG profiling only (debugger extension)
  273. if( !fWMsgProfRT ) { // only if not profiling round trip
  274. aw32Msg[uMsg].cTics += GetWOWTicDiff(dwTics);
  275. }
  276. #endif
  277. if (!ulReturn) {
  278. LOGDEBUG(LOG_ALWAYS,(" W32Win16WndProcEx ERROR: cannot thunk 32-bit message %s (%x)\n", GetWMMsgName(uMsg), uMsg));
  279. goto Error;
  280. }
  281. }
  282. if (vpWndProc16 == (VPVOID)NULL) {
  283. WOW32ASSERT(vpWndProc16);
  284. goto SilentError;
  285. }
  286. LOGDEBUG(6,("16-bit Window Proc = %08lX\n", vpWndProc16));
  287. BlockWOWIdle(FALSE);
  288. fSuccess = CallBack16(RET_WNDPROC, &wm32mpex.Parm16, vpWndProc16, (PVPVOID)&wm32mpex.lReturn);
  289. BlockWOWIdle(TRUE);
  290. // During CreateWindow some apps draw their own non-client area and don't
  291. // pass WM_NCCALCSIZE to DefWindowProc which causes Win 95 and NT's user to
  292. // not set some needed window flags. Mavis Beacon is an example. We'll pass
  293. // the message for them.
  294. if (uMsg == WM_NCCALCSIZE) {
  295. if (CURRENTPTD()->dwWOWCompatFlagsEx & WOWCFEX_DEFWNDPROCNCCALCSIZE) {
  296. DefWindowProc(hwnd, uMsg, uParam, lParam);
  297. }
  298. }
  299. // UnThunk this 32 bit message
  300. LOGDEBUG(6,(" UnThunking window %x message %s\n", hwnd, (LPSZ)GetWMMsgName(uMsg)));
  301. #ifdef DEBUG
  302. if((uMsg & WOWPRIVATEMSG) && ((uMsg - WOWPRIVATEMSG) < 0x400)) {
  303. LOGDEBUG(6,(" -- private WOW bit set for %s\n", (LPSZ)GetWMMsgName(uMsg)));
  304. }
  305. #endif
  306. if (fMessageNeedsThunking) {
  307. #ifdef WOWPROFILE // for MSG profiling only (debugger extension)
  308. if( !fWMsgProfRT ) { // only if not profiling round trip
  309. dwTics = GetWOWTicDiff(0L);
  310. }
  311. #endif
  312. wm32mpex.fThunk = UNTHUNKMSG;
  313. (wm32mpex.lpfnM32)(&wm32mpex);
  314. #ifdef WOWPROFILE // for MSG profiling only (debugger extension)
  315. aw32Msg[uMsg].cTics += GetWOWTicDiff(dwTics);
  316. aw32Msg[uMsg].cCalls++; // increment # times message passed
  317. #endif
  318. }
  319. if (!fSuccess) {
  320. goto Error;
  321. }
  322. return (wm32mpex.lReturn);
  323. Error:
  324. LOGDEBUG(LOG_ALWAYS,(" W32Win16WndProcEx ERROR: cannot call back, using default message handling\n"));
  325. SilentError:
  326. return DefWindowProc(hwnd, uMsg, uParam, lParam);
  327. }
  328. // The following functions are used to "thunk" a 32 bit message to 16 bit
  329. // message.
  330. //
  331. // To add a thunk function for a 32 bit message,
  332. // - Modify the entry for the message in "aw32Msg" function array
  333. // (in wmtbl32.c) to point to the new thunk function.
  334. // - Define the new thunk function in this file.
  335. //
  336. // These messages do not require any thunking so just copy the 32 bit wParam
  337. // and lParam to 16 bit wParam and lParam.
  338. //
  339. //
  340. // WM_CANCELMODE
  341. // WM_CHAR
  342. // WM_CHILDACTIVATE
  343. // WM_CLEAR
  344. // WM_CLOSE
  345. // WM_COMMNOTIFY
  346. // WM_COMPACTING
  347. // WM_COPY
  348. // WM_CUT
  349. // WM_DEADCHAR
  350. // WM_DESTROY
  351. // WM_DRAWCLIPBOARD
  352. // WM_ENABLE
  353. // WM_ENDSESSION
  354. // WM_FONTCHANGE
  355. // WM_GETFONT
  356. // WM_GETTEXTLENGTH
  357. // WM_HOTKEY
  358. // WM_INPUTFOCUS
  359. // WM_ISACTIVEICON (undocumented)
  360. // WM_KEYDOWN
  361. // WM_KEYUP
  362. // WM_LBTRACKPOINT (undocumented)
  363. // WM_LBUTTONDBLCLK
  364. // WM_LBUTTONDOWN
  365. // WM_LBUTTONUP
  366. // WM_MBUTTONDBLCLK
  367. // WM_MBUTTONDOWN
  368. // WM_MBUTTONUP
  369. // WM_MDICASCADE
  370. // WM_MDIICONARRANGE
  371. // WM_MDINEXT
  372. // WM_MDITILE
  373. // WM_MOUSEENTER
  374. // WM_MOUSELEAVE
  375. // WM_MOUSEMOVE
  376. // WM_MOVE
  377. // WM_NCCALCRGN
  378. // WM_NCDESTROY
  379. // WM_NCHITTEST
  380. // WM_NCLBUTTONDBLCLK
  381. // WM_NCLBUTTONDOWN
  382. // WM_NCLBUTTONUP
  383. // WM_NCMBUTTONDBLCLK
  384. // WM_NCMBUTTONDOWN
  385. // WM_NCMBUTTONUP
  386. // WM_NCMOUSEMOVE
  387. // WM_NCRBUTTONDBLCLK
  388. // WM_NCRBUTTONDOWN
  389. // WM_NCRBUTTONUP
  390. // WM_PAINTICON
  391. // WM_PASTE
  392. // WM_POWER
  393. // WM_QUERYENDSESSION
  394. // WM_QUERYNEWPALETTE
  395. // WM_QUERYOPEN
  396. // WM_QUERYPARKICON (undocumented)
  397. // WM_QUEUESYNC
  398. // WM_QUIT
  399. // WM_RBUTTONDBLCLK
  400. // WM_RBUTTONDOWN
  401. // WM_RBUTTONUP
  402. // WM_RENDERALLFORMATS
  403. // WM_RENDERFORMAT
  404. // WM_SETREDRAW
  405. // WM_SHOWWINDOW
  406. // WM_SIZE
  407. // WM_SPOOLERSTATUS (double-check lParam conversion on this one -JTP)
  408. // WM_SYSCHAR
  409. // WM_SYSCOLORCHANGE
  410. // WM_SYSCOMMAND
  411. // WM_SYSDEADCHAR
  412. // WM_SYSKEYDOWN
  413. // WM_SYSKEYUP
  414. // WM_SYSTEMERROR
  415. // WM_TIMECHANGE
  416. // WM_UNDO
  417. // MM_JOY1BUTTONDOWN - MultiMedia messages
  418. // MM_JOY1BUTTONUP
  419. // MM_JOY1MOVE
  420. // MM_JOY1ZMOVE
  421. // MM_JOY2BUTTONDOWN
  422. // MM_JOY2BUTTONUP
  423. // MM_JOY2MOVE
  424. // MM_JOY2ZMOVE
  425. // MM_MCINOTIFY - MultiMedia messages
  426. BOOL FASTCALL WM32NoThunking(LPWM32MSGPARAMEX lpwm32mpex)
  427. {
  428. #if 0
  429. //
  430. // this routine is never called! It's used as a placeholder.
  431. // if you want to make a change here, you have to make the change
  432. // to the places where we compare the thunk routine to WM32NoThunking
  433. // and only call the thunk routine if it's not this. also make sure
  434. // that this 'default' thunking happens for NoThunking messages.
  435. //
  436. if (lpwm32mpex->fThunk) {
  437. LOGDEBUG(6,(" No Thunking was required for the 32-bit message %s(%04x)\n", (LPSZ)GetWMMsgName(lpwm32mpex->uMsg), lpwm32mpex->uMsg));
  438. lpwm32mpex->Parm16.WndProc.wMsg = (WORD)lpwm32mpex->uMsg;
  439. lpwm32mpex->Parm16.WndProc.wParam = (WORD)lpwm32mpex->uParam;
  440. lpwm32mpex->Parm16.WndProc.lParam = (LONG)lpwm32mpex->lParam;
  441. }
  442. //
  443. // this routine is never called! It's used as a placeholder.
  444. // if you want to make a change here, you have to make the change
  445. // to the places where we compare the thunk routine to WM32NoThunking
  446. // and only call the thunk routine if it's not this.
  447. //
  448. #endif
  449. //
  450. // Return FALSE, so if for some reason this routine gets used
  451. // the failure to thunk will be apparent.
  452. //
  453. return FALSE;
  454. }
  455. #ifdef DEBUG // see the macro WM32UNDOCUMENTED
  456. // These are undocumented messages for Win 3.0 so take a look at the app
  457. // who is using them.
  458. BOOL FASTCALL WM32Undocumented(LPWM32MSGPARAMEX lpwm32mpex)
  459. {
  460. if (lpwm32mpex->fThunk) {
  461. LOGDEBUG(3,(" Window %08lX is receiving Undocumented Message %s\n", lpwm32mpex->hwnd, (LPSZ)GetWMMsgName(lpwm32mpex->uMsg), lpwm32mpex->uMsg));
  462. lpwm32mpex->Parm16.WndProc.wMsg = (WORD)lpwm32mpex->uMsg;
  463. lpwm32mpex->Parm16.WndProc.wParam = (WORD)lpwm32mpex->uParam;
  464. lpwm32mpex->Parm16.WndProc.lParam = (LONG)lpwm32mpex->lParam;
  465. }
  466. return (TRUE);
  467. }
  468. #endif
  469. // This function thunks the messages,
  470. //
  471. // WM_CREATE
  472. // WM_NCCREATE
  473. //
  474. BOOL FASTCALL WM32Create(LPWM32MSGPARAMEX lpwm32mpex)
  475. {
  476. INT cb;
  477. VPVOID vpClass = 0;
  478. VPVOID vpName = 0;
  479. VPVOID vpCreateParams = 0;
  480. register PCREATESTRUCT16 pcws16;
  481. LPCREATESTRUCT lParam = (LPCREATESTRUCT) lpwm32mpex->lParam;
  482. if (lpwm32mpex->fThunk) {
  483. if (HIWORD(lParam)) {
  484. // BUGBUG -- The assumption here is that GlobalAlloc will never
  485. // return a memory object that isn't word-aligned, so that we can
  486. // assign word-aligned words directly; we have no idea whether the
  487. // memory is dword-aligned or not however, so dwords must always
  488. // be paranoidly stored with the STOREDWORD/STORELONG macros -JTP
  489. if (lParam->lpszClass) {
  490. if ( HIWORD(lParam->lpszClass) == 0 ) {
  491. vpClass = (VPVOID)lParam->lpszClass;
  492. }
  493. else {
  494. cb = strlen(lParam->lpszClass)+1;
  495. if (!(vpClass = malloc16(cb)))
  496. goto Error;
  497. putstr16(vpClass, lParam->lpszClass, cb);
  498. }
  499. }
  500. if (lParam->lpszName) {
  501. cb = strlen(lParam->lpszName)+1;
  502. if (!(vpName = malloc16(cb)))
  503. goto Error;
  504. putstr16(vpName, lParam->lpszName, cb);
  505. }
  506. if (lpwm32mpex->pww == NULL) {
  507. lpwm32mpex->pww = (PWW)GetWindowLong(lpwm32mpex->hwnd, GWL_WOWWORDS);
  508. if (lpwm32mpex->pww == NULL)
  509. return FALSE; // Window is dead
  510. }
  511. if (lParam->lpCreateParams && (lpwm32mpex->pww->ExStyle & WS_EX_MDICHILD) ) {
  512. // This works because wm32mdicreate thunk doesn't use any
  513. // parameters except lParam
  514. WM32MSGPARAMEX wm32mpexT;
  515. wm32mpexT.fThunk = lpwm32mpex->fThunk;
  516. wm32mpexT.hwnd = lpwm32mpex->hwnd;
  517. wm32mpexT.uMsg = WM_MDICREATE;
  518. wm32mpexT.uParam = lpwm32mpex->uParam;
  519. wm32mpexT.lParam = (LONG)lParam->lpCreateParams;
  520. wm32mpexT.pww = lpwm32mpex->pww;
  521. wm32mpexT.fFree = lpwm32mpex->fFree;
  522. wm32mpexT.Parm16.WndProc.lParam = 0;
  523. WM32MDICreate(&wm32mpexT);
  524. lpwm32mpex->dwParam = wm32mpexT.dwParam;
  525. vpCreateParams = wm32mpexT.Parm16.WndProc.lParam;
  526. }
  527. else {
  528. vpCreateParams = (VPVOID)lParam->lpCreateParams;
  529. }
  530. // be sure allocation size matches stackfree16() size below
  531. if (!(lpwm32mpex->Parm16.WndProc.lParam = stackalloc16(sizeof(CREATESTRUCT16))))
  532. return FALSE;
  533. GETVDMPTR(lpwm32mpex->Parm16.WndProc.lParam, sizeof(CREATESTRUCT16), pcws16);
  534. STOREDWORD(pcws16->vpszClass, vpClass);
  535. STOREDWORD(pcws16->vpszWindow, vpName);
  536. STOREDWORD(pcws16->vpCreateParams, vpCreateParams);
  537. lpwm32mpex->dwTmp[0] = vpClass; // store for later freeing
  538. lpwm32mpex->dwTmp[1] = vpName;
  539. // BUGBUG 08-Apr-91 JeffPar -- What if hModule is for a 32-bit task?
  540. pcws16->hInstance = GETHINST16(lParam->hInstance);
  541. pcws16->hMenu = GETHMENU16(lParam->hMenu);
  542. pcws16->hwndParent = GETHWND16(lParam->hwndParent);
  543. pcws16->cy = (SHORT)lParam->cy;
  544. pcws16->cx = (SHORT)lParam->cx;
  545. pcws16->y = (SHORT)lParam->y;
  546. pcws16->x = (SHORT)lParam->x;
  547. STOREDWORD(pcws16->dwStyle, lParam->style);
  548. STOREDWORD(pcws16->dwExStyle, lParam->dwExStyle);
  549. FLUSHVDMPTR(lpwm32mpex->Parm16.WndProc.lParam, sizeof(CREATESTRUCT16), pcws16);
  550. FREEVDMPTR(pcws16);
  551. return TRUE;
  552. Error:
  553. LOGDEBUG(LOG_ALWAYS,(" !!!! WM32Create, WM_CREATE thunking failed !!!! Window %08lX ", lpwm32mpex->hwnd));
  554. if (HIW(vpClass)) free16(vpClass);
  555. if (vpName) free16(vpName);
  556. return (FALSE);
  557. // do some clean up
  558. // UnThunkWMCreate32(lParam, lpwm32mpex->Parm16.WndProc.lParam);
  559. } else {
  560. return TRUE;
  561. }
  562. }
  563. else {
  564. if (lpwm32mpex->Parm16.WndProc.lParam) {
  565. if (lpwm32mpex->pww == NULL) {
  566. lpwm32mpex->pww = (PWW)GetWindowLong(lpwm32mpex->hwnd, GWL_WOWWORDS);
  567. if (lpwm32mpex->pww == NULL)
  568. return FALSE; // Window is dead
  569. }
  570. if (lParam->lpCreateParams && (lpwm32mpex->pww->ExStyle & WS_EX_MDICHILD) ) {
  571. WM32MSGPARAMEX wm32mpexT;
  572. GETVDMPTR(lpwm32mpex->Parm16.WndProc.lParam, sizeof(CREATESTRUCT16), pcws16);
  573. wm32mpexT.fThunk = lpwm32mpex->fThunk;
  574. wm32mpexT.hwnd = lpwm32mpex->hwnd;
  575. wm32mpexT.uMsg = WM_MDICREATE;
  576. wm32mpexT.uParam = lpwm32mpex->uParam;
  577. wm32mpexT.lParam = (LONG)lParam->lpCreateParams;
  578. wm32mpexT.pww = lpwm32mpex->pww;
  579. wm32mpexT.fFree = lpwm32mpex->fFree;
  580. wm32mpexT.Parm16.WndProc.lParam = (VPVOID)FETCHDWORD(pcws16->vpCreateParams);
  581. wm32mpexT.lReturn = 0;
  582. wm32mpexT.dwParam = lpwm32mpex->dwParam;
  583. WM32MDICreate(&wm32mpexT);
  584. FREEVDMPTR(pcws16);
  585. }
  586. vpClass = lpwm32mpex->dwTmp[0];
  587. vpName = lpwm32mpex->dwTmp[1];
  588. // if HIWORD(class) is zero, class is an atom, else a pointer.
  589. if (HIW16(vpClass)) {
  590. free16(vpClass);
  591. }
  592. if (vpName) {
  593. free16(vpName);
  594. }
  595. stackfree16((VPVOID) lpwm32mpex->Parm16.WndProc.lParam,
  596. sizeof(CREATESTRUCT16));
  597. }
  598. return TRUE;
  599. }
  600. }
  601. // This function thunks the messages,
  602. //
  603. // WM_NCACTIVATE
  604. // WM_ACTIVATE
  605. //
  606. BOOL FASTCALL WM32Activate(LPWM32MSGPARAMEX lpwm32mpex)
  607. {
  608. if (lpwm32mpex->fThunk) {
  609. lpwm32mpex->Parm16.WndProc.wParam = LOWORD(lpwm32mpex->uParam);
  610. LOW(lpwm32mpex->Parm16.WndProc.lParam) = GETHWND16(lpwm32mpex->lParam);
  611. HIW(lpwm32mpex->Parm16.WndProc.lParam) = HIWORD(lpwm32mpex->uParam);
  612. }
  613. return (TRUE);
  614. }
  615. // This function thunks the messages,
  616. //
  617. // WM_VKEYTOITEM
  618. // WM_CHARTOITEM
  619. // WM_BEGINDRAG
  620. //
  621. BOOL FASTCALL WM32VKeyToItem(LPWM32MSGPARAMEX lpwm32mpex)
  622. {
  623. if (lpwm32mpex->fThunk) {
  624. LOW(lpwm32mpex->Parm16.WndProc.lParam) = GETHWND16(lpwm32mpex->lParam);
  625. HIW(lpwm32mpex->Parm16.WndProc.lParam) = HIWORD(lpwm32mpex->uParam);
  626. }
  627. else {
  628. lpwm32mpex->lReturn = (INT)(SHORT)(lpwm32mpex->lReturn); // sign extend.
  629. }
  630. return (TRUE);
  631. }
  632. // This function thunks the messages,
  633. //
  634. // WM_SETFOCUS
  635. // WM_KILLFOCUS
  636. // WM_SETCURSOR
  637. // WM_MOUSEACTIVATE
  638. // WM_MDIDESTROY
  639. // WM_MDIRESTORE
  640. // WM_MDIMAXIMIZE
  641. // WM_VSCROLLCLIPBOARD
  642. // WM_HSCROLLCLIPBOARD
  643. // WM_PALETTECHANGED
  644. // WM_PALETTEISCHANGING
  645. // WM_INITDIALOG
  646. //
  647. BOOL FASTCALL WM32SetFocus(LPWM32MSGPARAMEX lpwm32mpex)
  648. {
  649. if (lpwm32mpex->fThunk) {
  650. lpwm32mpex->Parm16.WndProc.wParam = GETHWND16(lpwm32mpex->uParam);
  651. }
  652. return (TRUE);
  653. }
  654. // This function thunks the messages,
  655. //
  656. // WM_SETTEXT
  657. // WM_WININICHANGE
  658. // WM_DEVMODECHANGE
  659. //
  660. BOOL FASTCALL WM32SetText(LPWM32MSGPARAMEX lpwm32mpex)
  661. {
  662. INT cb;
  663. if (lpwm32mpex->fThunk) {
  664. if (lpwm32mpex->lParam) {
  665. LONG lParam = (LONG)GetParam16(lpwm32mpex->lParam);
  666. if (lParam) {
  667. lpwm32mpex->Parm16.WndProc.lParam = lParam;
  668. return (TRUE);
  669. }
  670. cb = strlen((LPSZ)lpwm32mpex->lParam)+1;
  671. lpwm32mpex->dwTmp[0] = (DWORD)cb;
  672. // winworks2.0a requires DS based string pointers for this message
  673. if (CURRENTPTD()->dwWOWCompatFlags & WOWCF_DSBASEDSTRINGPOINTERS) {
  674. // be sure allocation size matches stackfree16() size below
  675. if (!(lpwm32mpex->Parm16.WndProc.lParam = stackalloc16(cb)))
  676. return FALSE;
  677. } else {
  678. if (!(lpwm32mpex->Parm16.WndProc.lParam = malloc16(cb)))
  679. return FALSE;
  680. }
  681. putstr16((VPSZ)lpwm32mpex->Parm16.WndProc.lParam, (LPSZ)lpwm32mpex->lParam, cb);
  682. }
  683. }
  684. else {
  685. // BUGBUG 09-Apr-91 -- Should I copy back?
  686. if (DeleteParamMap(lpwm32mpex->Parm16.WndProc.lParam, PARAM_16, NULL)) {
  687. return TRUE;
  688. }
  689. if (lpwm32mpex->Parm16.WndProc.lParam) {
  690. if (CURRENTPTD()->dwWOWCompatFlags & WOWCF_DSBASEDSTRINGPOINTERS) {
  691. stackfree16((VPVOID) lpwm32mpex->Parm16.WndProc.lParam,
  692. ((UINT)lpwm32mpex->dwTmp[0]));
  693. } else {
  694. free16((VPVOID) lpwm32mpex->Parm16.WndProc.lParam);
  695. }
  696. }
  697. }
  698. return (TRUE);
  699. }
  700. // This function thunks the message,
  701. //
  702. // WM_GETTEXT
  703. //
  704. BOOL FASTCALL WM32GetText(LPWM32MSGPARAMEX lpwm32mpex)
  705. {
  706. INT cb;
  707. LPSTR psz;
  708. INT cbWrote;
  709. if (lpwm32mpex->fThunk) {
  710. if (CURRENTPTD()->dwWOWCompatFlags & WOWCF_DSBASEDSTRINGPOINTERS) {
  711. //
  712. // msworks 2.0a has a wndproc called EdWnProc() which when it gets
  713. // a WM_GETTEXT, assumes lParam is a based pointer whose segment
  714. // value is equal to winwork's ds. That is true under win3.1, but
  715. // if wow calls malloc16, it'll have a different segment value.
  716. // so instead alloc the space on the caller's stack. Since most
  717. // apps have SS == DS, this will fix apps that do this, including
  718. // msworks 2.0a.
  719. //
  720. // be sure allocation size matches stackfree16() size below
  721. lpwm32mpex->dwTmp[0] = (DWORD)lpwm32mpex->Parm16.WndProc.wParam;
  722. lpwm32mpex->Parm16.WndProc.lParam = stackalloc16(lpwm32mpex->dwTmp[0]);
  723. } else {
  724. lpwm32mpex->Parm16.WndProc.lParam = malloc16(lpwm32mpex->Parm16.WndProc.wParam);
  725. }
  726. //
  727. // non-zero fill to detect people who write more than they
  728. // say that they do!
  729. //
  730. GETVDMPTR(lpwm32mpex->Parm16.WndProc.lParam, lpwm32mpex->Parm16.WndProc.wParam, psz);
  731. RtlFillMemory(psz, lpwm32mpex->Parm16.WndProc.wParam, 0xff);
  732. FLUSHVDMPTR(lpwm32mpex->Parm16.WndProc.lParam, lpwm32mpex->Parm16.WndProc.wParam, psz);
  733. FREEVDMPTR(psz);
  734. return (BOOL)lpwm32mpex->Parm16.WndProc.lParam;
  735. }
  736. else {
  737. // some apps return garbage in the high word. safely assume
  738. // that cbWindowText < 64K
  739. HIW(lpwm32mpex->lReturn) = 0;
  740. // it is necessary to check the length of the buffer, specified in
  741. // lpwm32mpex->uParam. if number of bytes (lpwm32mpex->lReturn) that are to be copied is
  742. // EQUAL to the length of the buffer, then copy ONLY the bytes EQUAL
  743. // to the length of the buffer.
  744. //
  745. // Paradox is one of the apps where this condition is hit.
  746. // bug # 4272.
  747. //
  748. if (lpwm32mpex->Parm16.WndProc.lParam) {
  749. cb = lpwm32mpex->lReturn + 1;
  750. if (lpwm32mpex->uParam == 0) {
  751. // cb = 0 if lReturn == 0 && uParam == 0
  752. if (cb == 1)
  753. cb--;
  754. }
  755. else if (cb == 2 || cb == 1) {
  756. // Here only if uParam != 0
  757. //
  758. // Determine how much of the buffer they touched!
  759. //
  760. // MyAdvancedLabelMaker returns 1 when they really return
  761. // more than 1. Since the return 1, cb will be 2. Then
  762. // We check to see how much of the buffer they really modified.
  763. // Then we lie and say that they really filled in that much
  764. // of the buffer.
  765. //
  766. // Sql administator also does this, except it returns 0
  767. // bug 7731
  768. GETVDMPTR(lpwm32mpex->Parm16.WndProc.lParam, lpwm32mpex->Parm16.WndProc.wParam, psz);
  769. cbWrote = lpwm32mpex->uParam;
  770. while (cbWrote && (psz[cbWrote-1] == '\xff')) {
  771. cbWrote--;
  772. }
  773. // copy out as many bytes as they wrote
  774. // distinguish between 'zerobytes written vs. one byte written'
  775. lpwm32mpex->lReturn = (cbWrote) ? (cbWrote - 1) : 0;
  776. cb = cbWrote;
  777. FREEVDMPTR(psz);
  778. }
  779. // cb = min(cb, wparam) only if wparam != 0
  780. // MSPROFIT: does
  781. // ret = sendmessage(hwnd, wm_gettest, wparam = 0, lparam);
  782. // where ret != 0. so we have to copy the necessary bytes into
  783. // lparam eventhough wparam is zero. It does this for reading
  784. // those ominprseent "$0.00" strings in the app (ledgers etc).
  785. //
  786. // - nanduri
  787. if (lpwm32mpex->uParam && (UINT)cb > lpwm32mpex->uParam) {
  788. cb = lpwm32mpex->uParam;
  789. }
  790. getstr16((VPSZ)lpwm32mpex->Parm16.WndProc.lParam, (LPSZ)lpwm32mpex->lParam, cb);
  791. if (CURRENTPTD()->dwWOWCompatFlags & WOWCF_DSBASEDSTRINGPOINTERS) {
  792. stackfree16((VPVOID) lpwm32mpex->Parm16.WndProc.lParam,
  793. ((UINT)lpwm32mpex->dwTmp[0]));
  794. } else {
  795. free16((VPVOID) lpwm32mpex->Parm16.WndProc.lParam);
  796. }
  797. }
  798. }
  799. return (TRUE);
  800. }
  801. // This function thunks the messages,
  802. //
  803. // WM_ERASEBKGND
  804. // WM_ICONERASEBKGND
  805. //
  806. BOOL FASTCALL WM32EraseBkGnd(LPWM32MSGPARAMEX lpwm32mpex)
  807. {
  808. if (lpwm32mpex->fThunk) {
  809. lpwm32mpex->Parm16.WndProc.wParam = GETHDC16(lpwm32mpex->uParam);
  810. }
  811. return (TRUE);
  812. }
  813. // This function thunks the message
  814. //
  815. // WM_CHANGEUISTATE
  816. // WM_UPDATEUISTATE
  817. // WM_QUERYUISTATE
  818. //
  819. BOOL FASTCALL WM32xxxUIState(LPWM32MSGPARAMEX lpwm32mpex)
  820. {
  821. // just copy the wParam into the lParam
  822. if (lpwm32mpex->fThunk) {
  823. lpwm32mpex->Parm16.WndProc.lParam = (LONG)lpwm32mpex->uParam;
  824. lpwm32mpex->Parm16.WndProc.wParam = 0;
  825. // this is here because there is talk that they might extend this
  826. // message to use lParam -- heck, they didn't even tell us that they
  827. // implemented this message in the first place!! (shame on shell!!)
  828. WOW32WARNMSG((lpwm32mpex->lParam == 0),
  829. ("WOW::WM32xxxUIState:lParam != 0. Better investigate!\n"));
  830. }
  831. // now just reverse the process
  832. else {
  833. lpwm32mpex->uParam = (UINT)lpwm32mpex->Parm16.WndProc.lParam;
  834. lpwm32mpex->lParam = 0;
  835. }
  836. return (TRUE);
  837. }
  838. // This function thunks the messages,
  839. //
  840. // WM_ACTIVATEAPP
  841. //
  842. BOOL FASTCALL WM32ActivateApp(LPWM32MSGPARAMEX lpwm32mpex)
  843. {
  844. extern void UpdateInt16State(void);
  845. if (lpwm32mpex->fThunk) {
  846. LOW(lpwm32mpex->Parm16.WndProc.lParam) =
  847. lpwm32mpex->lParam
  848. ? ThreadID32toHtask16((DWORD)lpwm32mpex->lParam)
  849. : 0;
  850. // We need to update wow int 16 bios when I wow app gets the focus.
  851. UpdateInt16State();
  852. }
  853. return (TRUE);
  854. }
  855. // This function thunks the messages,
  856. //
  857. // WM_GETMINMAXINFO
  858. //
  859. BOOL FASTCALL WM32GetMinMaxInfo(LPWM32MSGPARAMEX lpwm32mpex)
  860. {
  861. LPPOINT lParam = (LPPOINT) lpwm32mpex->lParam;
  862. if (lpwm32mpex->fThunk) {
  863. if (lParam) {
  864. // be sure allocation size matches stackfree16() size below
  865. lpwm32mpex->Parm16.WndProc.lParam = stackalloc16(sizeof(POINT16)*5);
  866. UnThunkWMGetMinMaxInfo16(lpwm32mpex->Parm16.WndProc.lParam, lParam);
  867. }
  868. }
  869. else {
  870. ThunkWMGetMinMaxInfo16(lpwm32mpex->Parm16.WndProc.lParam, &lParam);
  871. if(lpwm32mpex->Parm16.WndProc.lParam) {
  872. stackfree16((VPVOID) lpwm32mpex->Parm16.WndProc.lParam,
  873. sizeof(POINT16)*5);
  874. }
  875. }
  876. return(TRUE);
  877. }
  878. // This function thunks the messages,
  879. //
  880. // WM_NCPAINT
  881. //
  882. BOOL FASTCALL WM32NCPaint(LPWM32MSGPARAMEX lpwm32mpex)
  883. {
  884. if (lpwm32mpex->fThunk) {
  885. lpwm32mpex->Parm16.WndProc.wParam = (lpwm32mpex->uParam == 1) ? 1 :
  886. GETHDC16(lpwm32mpex->uParam);
  887. }
  888. return (TRUE);
  889. }
  890. // This function thunks the messages,
  891. //
  892. // WM_NCDESTROY
  893. //
  894. BOOL FASTCALL WM32NCDestroy(LPWM32MSGPARAMEX lpwm32mpex)
  895. {
  896. // destroy any timers associated with this window
  897. if (!lpwm32mpex->fThunk) {
  898. FreeWindowTimers16(lpwm32mpex->hwnd);
  899. }
  900. return (TRUE);
  901. }
  902. // This function thunks the messages,
  903. //
  904. // WM_GETDLGCODE
  905. //
  906. BOOL FASTCALL WM32GetDlgCode(LPWM32MSGPARAMEX lpwm32mpex)
  907. {
  908. if (lpwm32mpex->fThunk) {
  909. if (lpwm32mpex->lParam) {
  910. // BUGBUG -- The assumption here is that GlobalAlloc will never
  911. // return a memory object that isn't word-aligned, so that we can
  912. // assign word-aligned words directly; we have no idea whether the
  913. // memory is dword-aligned or not however, so dwords must always
  914. // be paranoidly stored with the STOREDWORD/STORELONG macros -JTP
  915. if (!(lpwm32mpex->Parm16.WndProc.lParam = malloc16(sizeof(MSG16))))
  916. return FALSE;
  917. putmsg16(lpwm32mpex->Parm16.WndProc.lParam, (LPMSG)lpwm32mpex->lParam);
  918. return TRUE;
  919. }
  920. }
  921. else {
  922. // Message structure doesn't need to be copied back does it? -Bob
  923. if (lpwm32mpex->Parm16.WndProc.lParam) {
  924. free16((VPVOID) lpwm32mpex->Parm16.WndProc.lParam);
  925. }
  926. }
  927. return (TRUE);
  928. }
  929. // This function thunks the messages,
  930. //
  931. // WM_NEXTDLGCTL
  932. //
  933. BOOL FASTCALL WM32NextDlgCtl(LPWM32MSGPARAMEX lpwm32mpex)
  934. {
  935. if (lpwm32mpex->fThunk) {
  936. if (lpwm32mpex->lParam) {
  937. lpwm32mpex->Parm16.WndProc.wParam = GETHWND16(lpwm32mpex->uParam);
  938. }
  939. }
  940. return (TRUE);
  941. }
  942. // This function thunks the messages,
  943. //
  944. // WM_DRAWITEM
  945. //
  946. BOOL FASTCALL WM32DrawItem(LPWM32MSGPARAMEX lpwm32mpex)
  947. {
  948. LPDRAWITEMSTRUCT lParam = (LPDRAWITEMSTRUCT) lpwm32mpex->lParam;
  949. if (lpwm32mpex->fThunk) {
  950. if (lParam) {
  951. // be sure allocation size matches stackfree16() size below
  952. lpwm32mpex->Parm16.WndProc.lParam = stackalloc16(sizeof(DRAWITEMSTRUCT16));
  953. putdrawitem16(lpwm32mpex->Parm16.WndProc.lParam, lParam);
  954. }
  955. }
  956. else {
  957. // BUGBUG 08-Apr-91 JeffPar -- Reflect changes back to 32-bit structure?
  958. if (lpwm32mpex->Parm16.WndProc.lParam)
  959. stackfree16((VPVOID) lpwm32mpex->Parm16.WndProc.lParam,
  960. sizeof(DRAWITEMSTRUCT16));
  961. }
  962. return(TRUE);
  963. }
  964. // This function thunks the messages,
  965. //
  966. // WM_MEASUREITEM
  967. //
  968. BOOL FASTCALL WM32MeasureItem(LPWM32MSGPARAMEX lpwm32mpex)
  969. {
  970. PMEASUREITEMSTRUCT16 pmis16;
  971. LPMEASUREITEMSTRUCT lParam = (LPMEASUREITEMSTRUCT) lpwm32mpex->lParam;
  972. BOOL fHasStrings;
  973. DWORD cSize;
  974. //
  975. // Compatibility hack
  976. //
  977. // CrossTalk 2.0 has a bug where it fails to distinguish between
  978. // WM_MEASUREITEM and WM_INITDIALOG when doing file.open
  979. // on WM_MEASUREITEM it calls CallWindowProc() to send what it
  980. // thinks is lpOpenFileName->lpCust but is really random stack.
  981. // currently the high word of this random pointer is an hInstance
  982. // and gets through the validation layer, whereas on Win31 it doesn't.
  983. // if this WM_MEASUREITEM gets to the app's proc then the app will
  984. // initialize incorrectly and take a GP. i have increased the stack
  985. // allocation by XTALKHACK to ensure that the random data does is not
  986. // a valid pointer.
  987. //
  988. #define XTALKHACK (sizeof(OPENFILENAME16)-sizeof(MEASUREITEMSTRUCT16))
  989. if (lpwm32mpex->fThunk) {
  990. if (lParam) {
  991. fHasStrings = FALSE;
  992. if ( lParam->CtlType == ODT_COMBOBOX || lParam->CtlType == ODT_LISTBOX ) {
  993. if (lParam->itemWidth == MIFLAG_FLAT) {
  994. fHasStrings = TRUE;
  995. }
  996. }
  997. cSize = sizeof(MEASUREITEMSTRUCT16);
  998. if ( fHasStrings ) {
  999. cSize += strlen((LPSTR)lParam->itemData) + 1;
  1000. }
  1001. if ( cSize < XTALKHACK+sizeof(MEASUREITEMSTRUCT16) ) {
  1002. cSize = XTALKHACK+sizeof(MEASUREITEMSTRUCT16);
  1003. }
  1004. // be sure allocation size matches stackfree16() size below
  1005. lpwm32mpex->dwTmp[0] = cSize;
  1006. if ( !(lpwm32mpex->Parm16.WndProc.lParam = stackalloc16(cSize)) )
  1007. return FALSE;
  1008. GETVDMPTR(lpwm32mpex->Parm16.WndProc.lParam, cSize, pmis16);
  1009. pmis16->CtlType = (WORD)lParam->CtlType;
  1010. pmis16->CtlID = (WORD)lParam->CtlID;
  1011. pmis16->itemID = (WORD)lParam->itemID;
  1012. pmis16->itemWidth = (WORD)lParam->itemWidth;
  1013. pmis16->itemHeight = (WORD)lParam->itemHeight;
  1014. #ifdef XTALKHACK
  1015. ((POPENFILENAME16)pmis16)->lCustData = 7; // invalid far pointer
  1016. #endif
  1017. if ( fHasStrings ) {
  1018. pmis16->itemData = lpwm32mpex->Parm16.WndProc.lParam+sizeof(MEASUREITEMSTRUCT16);
  1019. strcpy( (LPSTR)(pmis16+1), (LPSTR)lParam->itemData );
  1020. } else {
  1021. STOREDWORD(pmis16->itemData, lParam->itemData);
  1022. }
  1023. WOW32ASSERT(HIWORD(cSize) == 0);
  1024. FLUSHVDMPTR(lpwm32mpex->Parm16.WndProc.lParam, (USHORT) cSize, pmis16);
  1025. FREEVDMPTR(pmis16);
  1026. }
  1027. }
  1028. else {
  1029. if (lpwm32mpex->Parm16.WndProc.lParam) {
  1030. GETVDMPTR(lpwm32mpex->Parm16.WndProc.lParam, sizeof(MEASUREITEMSTRUCT16), pmis16);
  1031. lParam->CtlType = WORD32(pmis16->CtlType);
  1032. lParam->CtlID = WORD32(pmis16->CtlID);
  1033. lParam->itemID = WORD32(pmis16->itemID);
  1034. // itemWidth must sign extend (PPT3 bug & Win3.1 treats it as signed!)
  1035. lParam->itemWidth = INT32(pmis16->itemWidth);
  1036. lParam->itemHeight = WORD32(pmis16->itemHeight);
  1037. lParam->itemData = pmis16->itemData;
  1038. FREEVDMPTR(pmis16);
  1039. stackfree16((VPVOID) lpwm32mpex->Parm16.WndProc.lParam,
  1040. ((UINT)lpwm32mpex->dwTmp[0]));
  1041. }
  1042. }
  1043. return(TRUE);
  1044. }
  1045. // This function thunks the messages,
  1046. //
  1047. // WM_DELETEITEM
  1048. //
  1049. BOOL FASTCALL WM32DeleteItem(LPWM32MSGPARAMEX lpwm32mpex)
  1050. {
  1051. register PDELETEITEMSTRUCT16 pdes16;
  1052. LPDELETEITEMSTRUCT lParam = (LPDELETEITEMSTRUCT) lpwm32mpex->lParam;
  1053. if (lpwm32mpex->fThunk) {
  1054. if (lParam) {
  1055. // BUGBUG -- The assumption here is that GlobalAlloc will never
  1056. // return a memory object that isn't word-aligned, so that we can
  1057. // assign word-aligned words directly; we have no idea whether the
  1058. // memory is dword-aligned or not however, so dwords must always
  1059. // be paranoidly stored with the STOREDWORD/STORELONG macros -JTP
  1060. // be sure allocation size matches stackfree16() size below
  1061. lpwm32mpex->Parm16.WndProc.lParam = stackalloc16(sizeof(DELETEITEMSTRUCT16));
  1062. GETVDMPTR(lpwm32mpex->Parm16.WndProc.lParam, sizeof(DELETEITEMSTRUCT16), pdes16);
  1063. pdes16->CtlType = (WORD)lParam->CtlType;
  1064. pdes16->CtlID = (WORD)lParam->CtlID;
  1065. pdes16->itemID = (WORD)lParam->itemID;
  1066. pdes16->hwndItem = GETHWND16(lParam->hwndItem);
  1067. STOREDWORD(pdes16->itemData, lParam->itemData);
  1068. FLUSHVDMPTR(lpwm32mpex->Parm16.WndProc.lParam, sizeof(DELETEITEMSTRUCT16), pdes16);
  1069. FREEVDMPTR(pdes16);
  1070. }
  1071. }
  1072. else {
  1073. if (lpwm32mpex->Parm16.WndProc.lParam)
  1074. stackfree16((VPVOID) lpwm32mpex->Parm16.WndProc.lParam,
  1075. sizeof(DELETEITEMSTRUCT16));
  1076. }
  1077. return(TRUE);
  1078. }
  1079. // This function thunks the messages,
  1080. //
  1081. // WM_SETFONT
  1082. //
  1083. BOOL FASTCALL WM32SetFont(LPWM32MSGPARAMEX lpwm32mpex)
  1084. {
  1085. if (lpwm32mpex->fThunk) {
  1086. lpwm32mpex->Parm16.WndProc.wParam = GETHFONT16(lpwm32mpex->uParam);
  1087. }
  1088. return (TRUE);
  1089. }
  1090. // This function thunks the messages,
  1091. //
  1092. // WM_QUERYDRAGICON
  1093. BOOL FASTCALL WM32QueryDragIcon(LPWM32MSGPARAMEX lpwm32mpex)
  1094. {
  1095. if (!lpwm32mpex->fThunk) {
  1096. lpwm32mpex->lReturn = (LONG)HICON32(lpwm32mpex->lReturn);
  1097. }
  1098. return (TRUE);
  1099. }
  1100. // This function thunks the messages,
  1101. //
  1102. // WM_COMPAREITEM
  1103. //
  1104. BOOL FASTCALL WM32CompareItem(LPWM32MSGPARAMEX lpwm32mpex)
  1105. {
  1106. LPCOMPAREITEMSTRUCT lParam = (LPCOMPAREITEMSTRUCT) lpwm32mpex->lParam;
  1107. if (lpwm32mpex->fThunk) {
  1108. if (lParam) {
  1109. // BUGBUG -- The assumption here is that GlobalAlloc will never
  1110. // return a memory object that isn't word-aligned, so that we can
  1111. // assign word-aligned words directly; we have no idea whether the
  1112. // memory is dword-aligned or not however, so dwords must always
  1113. // be paranoidly stored with the STOREDWORD/STORELONG macros -JTP
  1114. // be sure allocation size matches stackfree16() size below
  1115. lpwm32mpex->Parm16.WndProc.lParam = stackalloc16(sizeof(COMPAREITEMSTRUCT16));
  1116. putcompareitem16(lpwm32mpex->Parm16.WndProc.lParam, lParam);
  1117. }
  1118. }
  1119. else {
  1120. // BUGBUG 08-Apr-91 JeffPar -- Reflect changes back to 32-bit structure?
  1121. if (lpwm32mpex->Parm16.WndProc.lParam)
  1122. stackfree16((VPVOID) lpwm32mpex->Parm16.WndProc.lParam,
  1123. sizeof(COMPAREITEMSTRUCT16));
  1124. }
  1125. return (TRUE);
  1126. }
  1127. // This function thunks the messages,
  1128. //
  1129. // WM_SIZING
  1130. //
  1131. BOOL FASTCALL WM32Sizing(LPWM32MSGPARAMEX lpwm32mpex)
  1132. {
  1133. VPRECT16 vpRect16;
  1134. if (lpwm32mpex->fThunk) {
  1135. if (lpwm32mpex->lParam) {
  1136. // be sure allocation size matches stackfree16() size below
  1137. vpRect16 = (VPVOID)stackalloc16(sizeof(RECT16));
  1138. if(vpRect16) {
  1139. putrect16(vpRect16, (LPRECT)lpwm32mpex->lParam);
  1140. lpwm32mpex->Parm16.WndProc.lParam = (LONG)vpRect16;
  1141. }
  1142. }
  1143. }
  1144. else {
  1145. if (lpwm32mpex->lParam) {
  1146. vpRect16 = (VPVOID)lpwm32mpex->Parm16.WndProc.lParam;
  1147. if(vpRect16) {
  1148. getrect16(vpRect16, (LPRECT)lpwm32mpex->lParam);
  1149. stackfree16(vpRect16, sizeof(RECT16));
  1150. }
  1151. }
  1152. }
  1153. return (TRUE);
  1154. }
  1155. // This function thunks the messages,
  1156. //
  1157. // WM_NCCALCSIZE
  1158. //
  1159. BOOL FASTCALL WM32NCCalcSize(LPWM32MSGPARAMEX lpwm32mpex)
  1160. {
  1161. PNCCALCSIZE_PARAMS16 pnc16;
  1162. PNCCALCSIZE_PARAMS16 lpnc16;
  1163. VPWINDOWPOS16 vpwp16;
  1164. LPNCCALCSIZE_PARAMS lParam = (LPNCCALCSIZE_PARAMS)lpwm32mpex->lParam;
  1165. UINT cb;
  1166. VPVOID vp;
  1167. // lpwm32mpex->uParam == TRUE ? (lParam is LPNCCALCSIZE_PARAMS) : (lParam is LPRECT);
  1168. //
  1169. if (lpwm32mpex->fThunk) {
  1170. if (lParam) {
  1171. if (lpwm32mpex->uParam)
  1172. cb = sizeof(NCCALCSIZE_PARAMS16) + sizeof(WINDOWPOS16);
  1173. else
  1174. cb = sizeof(RECT16);
  1175. // be sure allocation size matches stackfree16() size below
  1176. lpwm32mpex->dwTmp[0] = cb;
  1177. vp = (VPVOID)stackalloc16(cb);
  1178. lpwm32mpex->Parm16.WndProc.lParam = (LONG)vp;
  1179. putrect16((VPRECT16)vp, (LPRECT)lParam);
  1180. if (lpwm32mpex->uParam) {
  1181. pnc16 = (PNCCALCSIZE_PARAMS16)vp;
  1182. putrect16((VPRECT16)(&pnc16->rgrc[1]), &lParam->rgrc[1]);
  1183. putrect16((VPRECT16)(&pnc16->rgrc[2]), &lParam->rgrc[2]);
  1184. GETVDMPTR( pnc16, sizeof(NCCALCSIZE_PARAMS16), lpnc16 );
  1185. vpwp16 = (VPWINDOWPOS16)(pnc16+1);
  1186. lpnc16->lppos = (PWINDOWPOS16)vpwp16;
  1187. FREEVDMPTR( lpnc16 );
  1188. putwindowpos16( vpwp16, lParam->lppos );
  1189. }
  1190. }
  1191. }
  1192. else {
  1193. vp = (VPVOID)lpwm32mpex->Parm16.WndProc.lParam;
  1194. getrect16((VPRECT16)vp, (LPRECT)lParam);
  1195. if (lpwm32mpex->uParam) {
  1196. pnc16 = (PNCCALCSIZE_PARAMS16)vp;
  1197. getrect16((VPRECT16)(&pnc16->rgrc[1]), &lParam->rgrc[1]);
  1198. getrect16((VPRECT16)(&pnc16->rgrc[2]), &lParam->rgrc[2]);
  1199. GETVDMPTR( pnc16, sizeof(NCCALCSIZE_PARAMS16), lpnc16 );
  1200. vpwp16 = (VPWINDOWPOS16)lpnc16->lppos;
  1201. FREEVDMPTR( lpnc16 );
  1202. getwindowpos16( vpwp16, lParam->lppos );
  1203. }
  1204. if(vp) {
  1205. stackfree16(vp, ((UINT)lpwm32mpex->dwTmp[0]));
  1206. }
  1207. }
  1208. return (TRUE);
  1209. }
  1210. // This function thunks the messages,
  1211. //
  1212. // WM_COMMAND
  1213. //
  1214. BOOL FASTCALL WM32Command(LPWM32MSGPARAMEX lpwm32mpex)
  1215. {
  1216. if (lpwm32mpex->fThunk) {
  1217. // it's from a control
  1218. HIW(lpwm32mpex->Parm16.WndProc.lParam) = HIWORD(lpwm32mpex->uParam);
  1219. LOW(lpwm32mpex->Parm16.WndProc.lParam) = GETHWND16(lpwm32mpex->lParam);
  1220. }
  1221. return (TRUE);
  1222. }
  1223. // This function thunks the messages,
  1224. //
  1225. // WM_TIMER
  1226. //
  1227. BOOL FASTCALL WM32Timer(LPWM32MSGPARAMEX lpwm32mpex)
  1228. {
  1229. if (lpwm32mpex->fThunk) {
  1230. /*
  1231. ** map the timer number and the timer proc address (cause its easy)
  1232. */
  1233. PTMR ptmr;
  1234. ptmr = FindTimer32((HAND16)GETHWND16(lpwm32mpex->hwnd), lpwm32mpex->uParam);
  1235. if ( !ptmr ) {
  1236. /*
  1237. ** Edit controls create their own timer, which can safely be
  1238. ** thunked to itself.
  1239. */
  1240. if ( lpwm32mpex->lParam || HIWORD(lpwm32mpex->uParam) ) {
  1241. LOGDEBUG(LOG_WARNING,(" WM32Timer ERROR: cannot find timer %08x\n", lpwm32mpex->uParam));
  1242. }
  1243. return TRUE;
  1244. }
  1245. lpwm32mpex->Parm16.WndProc.lParam = ptmr->vpfnTimerProc;
  1246. }
  1247. return (TRUE);
  1248. }
  1249. // This function thunks the messages,
  1250. //
  1251. // WM_HSCROLL
  1252. // WM_VSCROLL
  1253. //
  1254. BOOL FASTCALL WM32HScroll(LPWM32MSGPARAMEX lpwm32mpex)
  1255. {
  1256. if (lpwm32mpex->fThunk) {
  1257. LOW(lpwm32mpex->Parm16.WndProc.lParam) = HIWORD(lpwm32mpex->uParam);
  1258. HIW(lpwm32mpex->Parm16.WndProc.lParam) = GETHWND16(lpwm32mpex->lParam);
  1259. }
  1260. return (TRUE);
  1261. }
  1262. // This function thunks the messages,
  1263. //
  1264. // WM_INITMENU
  1265. // WM_INITMENUPOPUP
  1266. //
  1267. BOOL FASTCALL WM32InitMenu(LPWM32MSGPARAMEX lpwm32mpex)
  1268. {
  1269. if (lpwm32mpex->fThunk) {
  1270. lpwm32mpex->Parm16.WndProc.wParam = GETHMENU16(lpwm32mpex->uParam);
  1271. }
  1272. return (TRUE);
  1273. }
  1274. // This function thunks the messages,
  1275. //
  1276. // WM_MENUSELECT
  1277. //
  1278. BOOL FASTCALL WM32MenuSelect(LPWM32MSGPARAMEX lpwm32mpex)
  1279. {
  1280. if (lpwm32mpex->fThunk) {
  1281. // Copy the menu flags
  1282. LOW(lpwm32mpex->Parm16.WndProc.lParam) = HIWORD(lpwm32mpex->uParam);
  1283. // Copy the "main" menu
  1284. HIW(lpwm32mpex->Parm16.WndProc.lParam) = GETHMENU16(lpwm32mpex->lParam);
  1285. if (HIWORD(lpwm32mpex->uParam) == 0xFFFF || !(HIWORD(lpwm32mpex->uParam) & MF_POPUP)) {
  1286. lpwm32mpex->Parm16.WndProc.wParam = LOWORD(lpwm32mpex->uParam); // Its an ID
  1287. }
  1288. else {
  1289. // convert menu index into menu handle
  1290. lpwm32mpex->Parm16.WndProc.wParam = GETHMENU16(GetSubMenu((HMENU)lpwm32mpex->lParam, LOWORD(lpwm32mpex->uParam)));
  1291. }
  1292. }
  1293. return (TRUE);
  1294. }
  1295. // This function thunks the messages,
  1296. //
  1297. // WM_MENUCHAR
  1298. //
  1299. BOOL FASTCALL WM32MenuChar(LPWM32MSGPARAMEX lpwm32mpex)
  1300. {
  1301. if (lpwm32mpex->fThunk) {
  1302. LOW(lpwm32mpex->Parm16.WndProc.lParam) = HIWORD(lpwm32mpex->uParam);
  1303. HIW(lpwm32mpex->Parm16.WndProc.lParam) = GETHMENU16(lpwm32mpex->lParam);
  1304. }
  1305. return (TRUE);
  1306. }
  1307. // This function thunks the messages,
  1308. //
  1309. // WM_ENTERIDLE
  1310. //
  1311. BOOL FASTCALL WM32EnterIdle(LPWM32MSGPARAMEX lpwm32mpex)
  1312. {
  1313. if (lpwm32mpex->fThunk) {
  1314. if ((lpwm32mpex->uParam == MSGF_DIALOGBOX) || (lpwm32mpex->uParam == MSGF_MENU)) {
  1315. LOW(lpwm32mpex->Parm16.WndProc.lParam) = GETHWND16(lpwm32mpex->lParam);
  1316. HIW(lpwm32mpex->Parm16.WndProc.lParam) = 0;
  1317. }
  1318. else {
  1319. LOGDEBUG(LOG_ALWAYS,(" WOW::WM_ENTERIDLE: wParam has unknown value, wParam=%08x, Contact ChandanC\n", lpwm32mpex->uParam));
  1320. }
  1321. }
  1322. return (TRUE);
  1323. }
  1324. // This function thunks the messages,
  1325. //
  1326. // WM_PARENTNOTIFY
  1327. //
  1328. BOOL FASTCALL WM32ParentNotify(LPWM32MSGPARAMEX lpwm32mpex)
  1329. {
  1330. if (lpwm32mpex->fThunk) {
  1331. if ((LOWORD(lpwm32mpex->uParam) == WM_CREATE) || (LOWORD(lpwm32mpex->uParam) == WM_DESTROY)) {
  1332. HIW(lpwm32mpex->Parm16.WndProc.lParam) = HIWORD(lpwm32mpex->uParam);
  1333. LOW(lpwm32mpex->Parm16.WndProc.lParam) = GETHWND16(lpwm32mpex->lParam);
  1334. }
  1335. }
  1336. return (TRUE);
  1337. }
  1338. // This function thunks the messages,
  1339. //
  1340. // WM_MDICreate
  1341. //
  1342. BOOL FASTCALL WM32MDICreate(LPWM32MSGPARAMEX lpwm32mpex)
  1343. {
  1344. INT cb;
  1345. VPVOID vp;
  1346. register PMDICREATESTRUCT16 pmcs16;
  1347. LPMDICREATESTRUCT lParam = (LPMDICREATESTRUCT) lpwm32mpex->lParam;
  1348. if (lpwm32mpex->fThunk) {
  1349. if (lParam) {
  1350. lpwm32mpex->dwParam = (DWORD)0;
  1351. if (lParam->szClass) {
  1352. if ( HIWORD(lParam->szClass) == 0 ) {
  1353. vp = (VPVOID)lParam->szClass;
  1354. }
  1355. else {
  1356. cb = strlen(lParam->szClass)+1;
  1357. if (!(vp = malloc16(cb)))
  1358. goto Error;
  1359. putstr16(vp, lParam->szClass, cb);
  1360. }
  1361. }
  1362. else {
  1363. vp = (VPVOID)NULL;
  1364. }
  1365. //
  1366. // pfs:windowsworks overwrite pszclass, so we need to save the
  1367. // so that we can free the memory we just alloced
  1368. //
  1369. lpwm32mpex->dwParam = (DWORD)vp;
  1370. if (lParam->szTitle) {
  1371. cb = strlen(lParam->szTitle)+1;
  1372. if (!(vp = malloc16(cb)))
  1373. goto Error;
  1374. putstr16(vp, lParam->szTitle, cb);
  1375. }
  1376. else {
  1377. vp = (VPVOID)NULL;
  1378. }
  1379. // BUGBUG -- The assumption here is that GlobalAlloc will never
  1380. // return a memory object that isn't word-aligned, so that we can
  1381. // assign word-aligned words directly; we have no idea whether the
  1382. // memory is dword-aligned or not however, so dwords must always
  1383. // be paranoidly stored with the STOREDWORD/STORELONG macros -JTP
  1384. if (!(lpwm32mpex->Parm16.WndProc.lParam = malloc16(sizeof(MDICREATESTRUCT16))))
  1385. goto Error;
  1386. GETVDMPTR(lpwm32mpex->Parm16.WndProc.lParam, sizeof(MDICREATESTRUCT16), pmcs16);
  1387. STOREDWORD(pmcs16->vpszClass, lpwm32mpex->dwParam);
  1388. STOREDWORD(pmcs16->vpszTitle, vp);
  1389. pmcs16->hOwner = GETHINST16(lParam->hOwner);
  1390. pmcs16->x = (SHORT)lParam->x;
  1391. pmcs16->y = (SHORT)lParam->y;
  1392. pmcs16->cx = (SHORT)lParam->cx;
  1393. pmcs16->cy = (SHORT)lParam->cy;
  1394. STORELONG(pmcs16->style, lParam->style);
  1395. STORELONG(pmcs16->lParam, lParam->lParam);
  1396. FLUSHVDMPTR(lpwm32mpex->Parm16.WndProc.lParam, sizeof(MDICREATESTRUCT16), pmcs16);
  1397. FREEVDMPTR(pmcs16);
  1398. return (TRUE);
  1399. Error:
  1400. LOGDEBUG(LOG_ALWAYS,(" !!!! WM32MDICreate, WM_MDICREATE thunking failed !!!! Window %08lX ", lpwm32mpex->hwnd));
  1401. if (HIW16(lpwm32mpex->dwParam)) free16(lpwm32mpex->dwParam);
  1402. if (vp) free16(vp);
  1403. return FALSE;
  1404. }
  1405. }
  1406. else {
  1407. if (lpwm32mpex->Parm16.WndProc.lParam) {
  1408. GETVDMPTR(lpwm32mpex->Parm16.WndProc.lParam, sizeof(MDICREATESTRUCT16), pmcs16);
  1409. if (FETCHDWORD(pmcs16->vpszTitle)) {
  1410. free16(FETCHDWORD(pmcs16->vpszTitle));
  1411. }
  1412. FREEVDMPTR(pmcs16);
  1413. // if HIWORD(class) is zero, class is an atom, else a pointer.
  1414. if (HIW16(lpwm32mpex->dwParam)) {
  1415. free16(lpwm32mpex->dwParam);
  1416. }
  1417. lpwm32mpex->lReturn = (LONG)HWND32(LOWORD(lpwm32mpex->lReturn));
  1418. free16((VPVOID) lpwm32mpex->Parm16.WndProc.lParam);
  1419. }
  1420. }
  1421. return (TRUE);
  1422. }
  1423. // This function thunks the messages,
  1424. //
  1425. // WM_MDIActivate
  1426. //
  1427. BOOL FASTCALL WM32MDIActivate(LPWM32MSGPARAMEX lpwm32mpex)
  1428. {
  1429. BOOL fHwndIsMdiChild;
  1430. if (lpwm32mpex->fThunk) {
  1431. // the format of the message is different based on the window that's
  1432. // receiving the message. If 'hwnd' is a MdiClient window it is of one
  1433. // form and if 'hwnd' is MdiChild it is of another form. We need to
  1434. // distinguish between the formats to correctly thunk the message.
  1435. //
  1436. // NOTE: we donot make calls like GetClassName because they are
  1437. // expensive and also I think we came across a case where a
  1438. // window of 'wow private class' processes these messages
  1439. //
  1440. // - Nanduri
  1441. if (lpwm32mpex->lParam) {
  1442. // lParam != NULL. The message is definitely going to a MdiChild.
  1443. //
  1444. fHwndIsMdiChild = TRUE;
  1445. }
  1446. else {
  1447. // lParam == NULL, doesnot necessarily mean that the message is
  1448. // going to a MdiClient window. So distinguish...
  1449. if (lpwm32mpex->uParam && (GETHWND16(lpwm32mpex->hwnd) ==
  1450. GETHWND16(lpwm32mpex->uParam))) {
  1451. // if hwnd is same as uParam then definitely hwnd is a MdiChild
  1452. // window. (because if hwnd is a MdiClient then uParam will be
  1453. // a MdiChild and thus they will not be equal)
  1454. fHwndIsMdiChild = TRUE;
  1455. }
  1456. else {
  1457. fHwndIsMdiChild = FALSE;
  1458. }
  1459. }
  1460. if (fHwndIsMdiChild) {
  1461. lpwm32mpex->Parm16.WndProc.wParam =
  1462. (WORD)(GETHWND16(lpwm32mpex->hwnd) == GETHWND16(lpwm32mpex->lParam));
  1463. LOW(lpwm32mpex->Parm16.WndProc.lParam) = GETHWND16(lpwm32mpex->lParam);
  1464. HIW(lpwm32mpex->Parm16.WndProc.lParam) = GETHWND16(lpwm32mpex->uParam);
  1465. } else {
  1466. lpwm32mpex->Parm16.WndProc.wParam = GETHWND16(lpwm32mpex->uParam);
  1467. lpwm32mpex->Parm16.WndProc.lParam = 0;
  1468. }
  1469. }
  1470. return (TRUE);
  1471. }
  1472. // This function thunks the messages,
  1473. //
  1474. // WM_MDIGETACTIVE
  1475. //
  1476. BOOL FASTCALL WM32MDIGetActive(LPWM32MSGPARAMEX lpwm32mpex)
  1477. {
  1478. if (lpwm32mpex->fThunk) {
  1479. lpwm32mpex->Parm16.WndProc.lParam = 0;
  1480. }
  1481. else {
  1482. if (lpwm32mpex->lParam != 0)
  1483. *((LPBOOL)lpwm32mpex->lParam) = (BOOL)HIWORD(lpwm32mpex->lReturn);
  1484. lpwm32mpex->lReturn = (LONG)HWND32(LOWORD(lpwm32mpex->lReturn));
  1485. }
  1486. return (TRUE);
  1487. }
  1488. // This function thunks the messages,
  1489. //
  1490. // WM_MDISETMENU
  1491. //
  1492. BOOL FASTCALL WM32MDISetMenu(LPWM32MSGPARAMEX lpwm32mpex)
  1493. {
  1494. if (lpwm32mpex->fThunk) {
  1495. if (lpwm32mpex->uMsg == WM_MDIREFRESHMENU) {
  1496. lpwm32mpex->Parm16.WndProc.wParam = TRUE;
  1497. lpwm32mpex->Parm16.WndProc.wMsg = WM_MDISETMENU;
  1498. }
  1499. else {
  1500. lpwm32mpex->Parm16.WndProc.wParam = 0;
  1501. }
  1502. LOW(lpwm32mpex->Parm16.WndProc.lParam) = GETHMENU16(lpwm32mpex->uParam);
  1503. HIW(lpwm32mpex->Parm16.WndProc.lParam) = GETHMENU16(lpwm32mpex->lParam);
  1504. }
  1505. else {
  1506. lpwm32mpex->lReturn = (LONG)HMENU32(lpwm32mpex->lReturn);
  1507. }
  1508. return (TRUE);
  1509. }
  1510. // This function thunks the messages,
  1511. //
  1512. // WM_SIZECLIPBOARD
  1513. // WM_PAINTCLIPBOARD
  1514. //
  1515. BOOL FASTCALL WM32SizeClipBoard(LPWM32MSGPARAMEX lpwm32mpex)
  1516. {
  1517. HAND16 hMem16 = 0;
  1518. VPVOID vp;
  1519. LPRECT lp;
  1520. if (lpwm32mpex->fThunk) {
  1521. lpwm32mpex->Parm16.WndProc.wParam = GETHWND16(lpwm32mpex->uParam);
  1522. vp = GlobalAllocLock16(GMEM_MOVEABLE, (lpwm32mpex->uMsg == WM_SIZECLIPBOARD) ?
  1523. sizeof(RECT) : sizeof(PAINTSTRUCT), &hMem16);
  1524. if (vp) {
  1525. if (lp = (LPRECT) GlobalLock((HANDLE) lpwm32mpex->lParam)) {
  1526. if (lpwm32mpex->uMsg == WM_SIZECLIPBOARD) {
  1527. PUTRECT16(vp, lp);
  1528. }
  1529. else {
  1530. putpaintstruct16(vp, (LPPAINTSTRUCT) lp);
  1531. }
  1532. GlobalUnlock((HANDLE) lpwm32mpex->lParam);
  1533. }
  1534. else {
  1535. LOGDEBUG(LOG_ALWAYS, ("WOW::WM32SizeClipboard: Couldn't lock 32 bit memory handle!\n"));
  1536. // WOW32ASSERT (FALSE);
  1537. }
  1538. GlobalUnlock16(hMem16);
  1539. }
  1540. else {
  1541. hMem16 = 0;
  1542. LOGDEBUG(LOG_ALWAYS, ("WOW::WM32SizeClipboard: Couldn't allocate memory !\n"));
  1543. WOW32ASSERT (FALSE);
  1544. }
  1545. LOW(lpwm32mpex->Parm16.WndProc.lParam) = (WORD) hMem16;
  1546. }
  1547. else {
  1548. if (LOW(lpwm32mpex->Parm16.WndProc.lParam)) {
  1549. GlobalUnlockFree16(GlobalLock16(LOW(lpwm32mpex->Parm16.WndProc.lParam), NULL));
  1550. }
  1551. }
  1552. return (TRUE);
  1553. }
  1554. // This function thunks the messages,
  1555. //
  1556. // WM_ASKCBFORMATNAME
  1557. //
  1558. BOOL FASTCALL WM32AskCBFormatName(LPWM32MSGPARAMEX lpwm32mpex)
  1559. {
  1560. if (lpwm32mpex->fThunk) {
  1561. lpwm32mpex->Parm16.WndProc.lParam = malloc16(lpwm32mpex->Parm16.WndProc.wParam);
  1562. if (lpwm32mpex->Parm16.WndProc.lParam) {
  1563. putstr16((VPSZ)lpwm32mpex->Parm16.WndProc.lParam, (LPSZ)lpwm32mpex->lParam, lpwm32mpex->uParam);
  1564. }
  1565. return (BOOL)lpwm32mpex->Parm16.WndProc.lParam;
  1566. }
  1567. else {
  1568. if (lpwm32mpex->Parm16.WndProc.lParam) {
  1569. getstr16((VPSZ)lpwm32mpex->Parm16.WndProc.lParam, (LPSZ)lpwm32mpex->lParam, lpwm32mpex->uParam);
  1570. free16((VPVOID) lpwm32mpex->Parm16.WndProc.lParam);
  1571. }
  1572. }
  1573. return (TRUE);
  1574. }
  1575. // This function thunks the messages,
  1576. //
  1577. // WM_CHANGECBCHAIN
  1578. //
  1579. BOOL FASTCALL WM32ChangeCBChain(LPWM32MSGPARAMEX lpwm32mpex)
  1580. {
  1581. if (lpwm32mpex->fThunk) {
  1582. lpwm32mpex->Parm16.WndProc.wParam = GETHWND16(lpwm32mpex->uParam);
  1583. lpwm32mpex->Parm16.WndProc.lParam = GETHWND16(lpwm32mpex->lParam);
  1584. }
  1585. return (TRUE);
  1586. }
  1587. // This function thunks the messages,
  1588. //
  1589. // WM_DDEINITIATE
  1590. //
  1591. BOOL FASTCALL WM32DDEInitiate(LPWM32MSGPARAMEX lpwm32mpex)
  1592. {
  1593. if (lpwm32mpex->fThunk) {
  1594. lpwm32mpex->Parm16.WndProc.wParam = GETHWND16(lpwm32mpex->uParam);
  1595. lpwm32mpex->Parm16.WndProc.lParam = lpwm32mpex->lParam;
  1596. WI32DDEAddInitiator(lpwm32mpex->Parm16.WndProc.wParam);
  1597. }
  1598. else {
  1599. WI32DDEDeleteInitiator((HAND16)GETHWND16(lpwm32mpex->uParam));
  1600. }
  1601. return (TRUE);
  1602. }
  1603. // This function thunks the messages,
  1604. //
  1605. // WM_DDEACK
  1606. //
  1607. BOOL FASTCALL WM32DDEAck(LPWM32MSGPARAMEX lpwm32mpex)
  1608. {
  1609. if (lpwm32mpex->fThunk) {
  1610. lpwm32mpex->Parm16.WndProc.wParam = GETHWND16(lpwm32mpex->uParam);
  1611. if (WI32DDEInitiate((HAND16)GETHWND16(lpwm32mpex->hwnd))) {
  1612. //
  1613. // Initiate ACK
  1614. //
  1615. lpwm32mpex->Parm16.WndProc.lParam = lpwm32mpex->lParam;
  1616. }
  1617. else {
  1618. //
  1619. // NON-Initiate ACK
  1620. //
  1621. UINT lLo = 0;
  1622. UINT lHi = 0;
  1623. PHDDE pDdeNode;
  1624. UnpackDDElParam(lpwm32mpex->uMsg, lpwm32mpex->lParam, &lLo, &lHi);
  1625. if (!HIWORD(lHi)) {
  1626. //
  1627. // NON-Execute ACK
  1628. //
  1629. HIW(lpwm32mpex->Parm16.WndProc.lParam) = (WORD) lHi;
  1630. }
  1631. else {
  1632. //
  1633. // Execute ACK
  1634. //
  1635. //
  1636. // The order of To_hwnd and From_hwnd is reversed in the following
  1637. // DDEFirstPair16(), below. This is done to locate the h32.
  1638. //
  1639. pDdeNode = DDEFindAckNode ((HAND16)lpwm32mpex->Parm16.WndProc.wParam,
  1640. (HAND16)GETHWND16(lpwm32mpex->hwnd),
  1641. (HANDLE) lHi);
  1642. if (!pDdeNode) {
  1643. //
  1644. // When ShellExecute does DDE_EXECUTE to open a document,
  1645. // we don't see its Win32 PostMessage calls so we have no
  1646. // record of the conversation. This is our first opportunity
  1647. // to rectify that, the context of WU32GetMessage thunking
  1648. // a WM_DDE_ACK message. We could also get here for other
  1649. // kinds of ACKs, fortunately the Win32 message alone gives
  1650. // enough context to distinguish the various flavors, unlike
  1651. // the Win16 WM_DDE_ACK.
  1652. //
  1653. if (lpwm32mpex->lParam >= 0xc0000000) {
  1654. //
  1655. // ack responding to initiate
  1656. //
  1657. lpwm32mpex->Parm16.WndProc.lParam = lpwm32mpex->lParam;
  1658. }
  1659. if (lHi > 0xffff) {
  1660. //
  1661. // ack responding to execute: global handle in hiword
  1662. //
  1663. HAND16 h16 = 0;
  1664. DWORD cb;
  1665. VPVOID vp;
  1666. LPBYTE lpMem16, lpMem32;
  1667. DDEINFO DdeInfo;
  1668. if (!lpwm32mpex->fFree) {
  1669. cb = GlobalSize((HANDLE)lHi);
  1670. vp = GlobalAllocLock16(GMEM_DDESHARE, cb, &h16);
  1671. if (vp) {
  1672. GETMISCPTR(vp, lpMem16);
  1673. lpMem32 = GlobalLock((HANDLE)lHi);
  1674. RtlCopyMemory(lpMem16, lpMem32, cb);
  1675. GlobalUnlock((HANDLE)lHi);
  1676. GlobalUnlock16(h16);
  1677. FREEMISCPTR(lpMem16);
  1678. DdeInfo.Msg = WM_DDE_EXECUTE;
  1679. DdeInfo.Format = 0;
  1680. DdeInfo.Flags = DDE_PACKET;
  1681. DdeInfo.h16 = 0;
  1682. DDEAddhandle(
  1683. lpwm32mpex->Parm16.WndProc.wParam,
  1684. GETHWND16(lpwm32mpex->hwnd),
  1685. h16,
  1686. (HANDLE)lHi,
  1687. &DdeInfo
  1688. );
  1689. pDdeNode = DDEFindAckNode (
  1690. (HAND16)lpwm32mpex->Parm16.WndProc.wParam,
  1691. (HAND16)GETHWND16(lpwm32mpex->hwnd),
  1692. (HANDLE) lHi);
  1693. WOW32ASSERTMSG(pDdeNode, "WM32DDEAck: Can't find just-added DDE node.\n");
  1694. }
  1695. }
  1696. lpwm32mpex->Parm16.WndProc.lParam = MAKELONG(LOWORD(lLo), h16);
  1697. } else {
  1698. //
  1699. // All other acks have same form: status in loword and
  1700. // item atom in hiword.
  1701. //
  1702. lpwm32mpex->Parm16.WndProc.lParam = MAKELONG(LOWORD(lLo), lHi);
  1703. }
  1704. }
  1705. if (pDdeNode && pDdeNode->DdeMsg == WM_DDE_EXECUTE) {
  1706. HIW(lpwm32mpex->Parm16.WndProc.lParam) = pDdeNode->hMem16;
  1707. if (lpwm32mpex->fFree) {
  1708. if (lHi) {
  1709. if (pDdeNode->DdeFlags & DDE_EXECUTE_FREE_MEM) {
  1710. LOGDEBUG (12, ("WOW::W32DDEAck : Freeing EXECUTE pair h16 = %04x, h32 = %08x\n",
  1711. pDdeNode->hMem16, lHi));
  1712. W32UnMarkDDEHandle (pDdeNode->hMem16);
  1713. GlobalUnlockFree16(GlobalLock16(pDdeNode->hMem16, NULL));
  1714. if (DDEDeletehandle(pDdeNode->hMem16, (HANDLE) lHi)) {
  1715. WOWGLOBALFREE((HANDLE)lHi);
  1716. }
  1717. else {
  1718. LOGDEBUG (0, ("WOW::DDE Ack : Ack can't find 16 - 32 aliasing : %04x, %04x, %04x, %08lx, %08lx\n",
  1719. lpwm32mpex->hwnd,
  1720. lpwm32mpex->uMsg,
  1721. lpwm32mpex->Parm16.WndProc.wParam,
  1722. lpwm32mpex->Parm16.WndProc.lParam,
  1723. lHi
  1724. ));
  1725. }
  1726. }
  1727. else {
  1728. if (pDdeNode->DdeFlags & DDE_EXECUTE_FREE_H16) {
  1729. W32UnMarkDDEHandle (pDdeNode->hMem16);
  1730. GlobalUnlockFree16(GlobalLock16(pDdeNode->hMem16, NULL));
  1731. HIW(lpwm32mpex->Parm16.WndProc.lParam) = pDdeNode->h16;
  1732. }
  1733. if (DDEDeletehandle(pDdeNode->hMem16, (HANDLE) lHi)) {
  1734. WOWGLOBALFREE((HANDLE)lHi);
  1735. }
  1736. else {
  1737. LOGDEBUG (0, ("WOW::DDE Ack : Ack can't find 16 - 32 aliasing : %04x, %04x, %04x, %08lx, %08lx\n",
  1738. lpwm32mpex->hwnd,
  1739. lpwm32mpex->uMsg,
  1740. lpwm32mpex->Parm16.WndProc.wParam,
  1741. lpwm32mpex->Parm16.WndProc.lParam,
  1742. lHi
  1743. ));
  1744. }
  1745. }
  1746. }
  1747. else {
  1748. LOGDEBUG (2, ("WOW::W32DDEAck : h32 is NULL \n"));
  1749. WOW32ASSERT (FALSE);
  1750. }
  1751. }
  1752. }
  1753. else {
  1754. LOGDEBUG (2, ("WOW::DDE Ack : Ack received unexpectedly : %x, %04x, %04x, %08lx, %08lx\n", lpwm32mpex->hwnd, lpwm32mpex->uMsg, lpwm32mpex->Parm16.WndProc.wParam, lpwm32mpex->Parm16.WndProc.lParam, lHi));
  1755. }
  1756. }
  1757. LOW(lpwm32mpex->Parm16.WndProc.lParam) = (WORD) lLo;
  1758. if (fThunkDDEmsg) {
  1759. FreeDDElParam(lpwm32mpex->uMsg, lpwm32mpex->lParam);
  1760. }
  1761. LOGDEBUG (12, ("WOW::DDE Ack : %04x, %04x, %04x, %08lx, %08lx\n", lpwm32mpex->hwnd, lpwm32mpex->uMsg, lpwm32mpex->Parm16.WndProc.wParam, lpwm32mpex->Parm16.WndProc.lParam, lHi));
  1762. }
  1763. }
  1764. else {
  1765. //
  1766. // We will execute this scenario only if the app ate the message,
  1767. // because we need to free up the memory.
  1768. //
  1769. if (!fThunkDDEmsg) {
  1770. if (lpwm32mpex->lReturn) {
  1771. FreeDDElParam(lpwm32mpex->uMsg, lpwm32mpex->lParam);
  1772. }
  1773. }
  1774. }
  1775. return (TRUE);
  1776. }
  1777. // This function thunks the messages,
  1778. //
  1779. // WM_DDEREQUEST
  1780. // WM_DDETERMINATE
  1781. // WM_DDEUNADVISE
  1782. //
  1783. BOOL FASTCALL WM32DDERequest(LPWM32MSGPARAMEX lpwm32mpex)
  1784. {
  1785. if (lpwm32mpex->fThunk) {
  1786. lpwm32mpex->Parm16.WndProc.wParam = GETHWND16(lpwm32mpex->uParam);
  1787. }
  1788. return (TRUE);
  1789. }
  1790. // This function thunks the messages,
  1791. //
  1792. // WM_DDEADVISE
  1793. //
  1794. BOOL FASTCALL WM32DDEAdvise(LPWM32MSGPARAMEX lpwm32mpex)
  1795. {
  1796. HAND16 h16;
  1797. VPVOID vp;
  1798. LPBYTE lpMem16;
  1799. LPBYTE lpMem32;
  1800. UINT lLo = 0;
  1801. UINT lHi = 0;
  1802. DDEINFO DdeInfo;
  1803. if (lpwm32mpex->fThunk) {
  1804. UnpackDDElParam(lpwm32mpex->uMsg, lpwm32mpex->lParam, &lLo, &lHi);
  1805. lpwm32mpex->Parm16.WndProc.wParam = GETHWND16(lpwm32mpex->uParam);
  1806. if (h16 = DDEFindPair16((HAND16)GETHWND16(lpwm32mpex->hwnd),
  1807. (HAND16)lpwm32mpex->Parm16.WndProc.wParam,
  1808. (HANDLE) lLo)) {
  1809. LOW(lpwm32mpex->Parm16.WndProc.lParam) = h16;
  1810. } else {
  1811. vp = GlobalAllocLock16(GMEM_DDESHARE, sizeof(DDEADVISE), &h16);
  1812. if (vp) {
  1813. GETMISCPTR(vp, lpMem16);
  1814. lpMem32 = GlobalLock((HANDLE) lLo);
  1815. RtlCopyMemory(lpMem16, lpMem32, sizeof(DDEADVISE));
  1816. GlobalUnlock((HANDLE) lLo);
  1817. GlobalUnlock16(h16);
  1818. DdeInfo.Msg = LOW(lpwm32mpex->uMsg);
  1819. DdeInfo.Format = 0;
  1820. DdeInfo.Flags = DDE_PACKET;
  1821. DdeInfo.h16 = 0;
  1822. DDEAddhandle((HAND16)GETHWND16(lpwm32mpex->hwnd),
  1823. (HAND16)lpwm32mpex->Parm16.WndProc.wParam,
  1824. h16,
  1825. (HANDLE) lLo,
  1826. &DdeInfo);
  1827. LOW(lpwm32mpex->Parm16.WndProc.lParam) = h16;
  1828. }
  1829. }
  1830. HIW(lpwm32mpex->Parm16.WndProc.lParam) = (WORD) lHi;
  1831. if (fThunkDDEmsg) {
  1832. FreeDDElParam(lpwm32mpex->uMsg, lpwm32mpex->lParam);
  1833. }
  1834. }
  1835. else {
  1836. //
  1837. // We will execute this scenario only if the app ate the message,
  1838. // because we need to free up the memory.
  1839. //
  1840. if (!fThunkDDEmsg) {
  1841. if (lpwm32mpex->lReturn) {
  1842. FreeDDElParam(lpwm32mpex->uMsg, lpwm32mpex->lParam);
  1843. }
  1844. }
  1845. }
  1846. return (TRUE);
  1847. }
  1848. // This function thunks the messages,
  1849. //
  1850. // WM_DDEDATA
  1851. //
  1852. BOOL FASTCALL WM32DDEData(LPWM32MSGPARAMEX lpwm32mpex)
  1853. {
  1854. HAND16 h16;
  1855. UINT lLo = 0;
  1856. UINT lHi = 0;
  1857. DDEINFO DdeInfo;
  1858. if (lpwm32mpex->fThunk) {
  1859. UnpackDDElParam(lpwm32mpex->uMsg, lpwm32mpex->lParam, &lLo, &lHi);
  1860. lpwm32mpex->Parm16.WndProc.wParam = GETHWND16(lpwm32mpex->uParam);
  1861. if (!lLo) {
  1862. LOW(lpwm32mpex->Parm16.WndProc.lParam) = 0;
  1863. } else if (h16 = DDEFindPair16((HAND16)GETHWND16(lpwm32mpex->hwnd),
  1864. (HAND16)lpwm32mpex->Parm16.WndProc.wParam,
  1865. (HANDLE) lLo)) {
  1866. LOW(lpwm32mpex->Parm16.WndProc.lParam) = h16;
  1867. } else {
  1868. DdeInfo.Msg = LOW(lpwm32mpex->uMsg);
  1869. h16 = DDECopyhData16((HAND16)GETHWND16(lpwm32mpex->hwnd),
  1870. (HAND16)lpwm32mpex->Parm16.WndProc.wParam,
  1871. (HANDLE) lLo,
  1872. &DdeInfo);
  1873. //
  1874. // If we could not allocate 16 bit memory, then return NULL to the
  1875. // caller.
  1876. //
  1877. if (!h16) {
  1878. if (fThunkDDEmsg) {
  1879. FreeDDElParam(lpwm32mpex->uMsg, lpwm32mpex->lParam);
  1880. }
  1881. lpwm32mpex->Parm16.WndProc.wParam = (WORD) lHi;
  1882. lpwm32mpex->Parm16.WndProc.lParam = lLo;
  1883. return (0);
  1884. }
  1885. DdeInfo.Flags = DDE_PACKET;
  1886. DdeInfo.h16 = 0;
  1887. DDEAddhandle((HAND16)GETHWND16(lpwm32mpex->hwnd),
  1888. (HAND16)lpwm32mpex->Parm16.WndProc.wParam,
  1889. h16,
  1890. (HANDLE) lLo,
  1891. &DdeInfo);
  1892. LOW(lpwm32mpex->Parm16.WndProc.lParam) = h16;
  1893. }
  1894. HIW(lpwm32mpex->Parm16.WndProc.lParam) = (WORD) lHi;
  1895. if (fThunkDDEmsg) {
  1896. FreeDDElParam(lpwm32mpex->uMsg, lpwm32mpex->lParam);
  1897. }
  1898. }
  1899. else {
  1900. //
  1901. // We will execute this scenario only if the app ate the message,
  1902. // because we need to free up the memory.
  1903. //
  1904. if (!fThunkDDEmsg) {
  1905. if (lpwm32mpex->lReturn) {
  1906. FreeDDElParam(lpwm32mpex->uMsg, lpwm32mpex->lParam);
  1907. }
  1908. }
  1909. }
  1910. return (TRUE);
  1911. }
  1912. // This function thunks the messages,
  1913. //
  1914. // WM_POKE
  1915. //
  1916. BOOL FASTCALL WM32DDEPoke(LPWM32MSGPARAMEX lpwm32mpex)
  1917. {
  1918. HAND16 h16;
  1919. UINT lLo = 0;
  1920. UINT lHi = 0;
  1921. DDEINFO DdeInfo;
  1922. if (lpwm32mpex->fThunk) {
  1923. UnpackDDElParam(lpwm32mpex->uMsg, lpwm32mpex->lParam, &lLo, &lHi);
  1924. lpwm32mpex->Parm16.WndProc.wParam = GETHWND16(lpwm32mpex->uParam);
  1925. // sudeepb 03-Apr-1996
  1926. // House Design Gold Edition sends a DDE_POKE message with lParam
  1927. // being 0. We are suppose to thunk this message with lParam being
  1928. // zero. Without this check, the below code will fail this call
  1929. // and the message will not be thunked to the app.
  1930. if (lLo == 0) {
  1931. LOW(lpwm32mpex->Parm16.WndProc.lParam) = 0;
  1932. HIW(lpwm32mpex->Parm16.WndProc.lParam) = (WORD) lHi;
  1933. return (TRUE);
  1934. }
  1935. if (h16 = DDEFindPair16((HAND16)GETHWND16(lpwm32mpex->hwnd),
  1936. (HAND16)lpwm32mpex->Parm16.WndProc.wParam,
  1937. (HANDLE) lLo)) {
  1938. LOW(lpwm32mpex->Parm16.WndProc.lParam) = h16;
  1939. } else {
  1940. DdeInfo.Msg = LOW(lpwm32mpex->uMsg);
  1941. h16 = DDECopyhData16((HAND16)GETHWND16(lpwm32mpex->hwnd),
  1942. (HAND16)lpwm32mpex->Parm16.WndProc.wParam,
  1943. (HANDLE) lLo,
  1944. &DdeInfo);
  1945. //
  1946. // If we could not allocate 16 bit memory, then return NULL to the
  1947. // caller.
  1948. //
  1949. if (!h16) {
  1950. if (fThunkDDEmsg) {
  1951. FreeDDElParam(lpwm32mpex->uMsg, lpwm32mpex->lParam);
  1952. }
  1953. lpwm32mpex->Parm16.WndProc.lParam = lLo;
  1954. return (0);
  1955. }
  1956. DdeInfo.Flags = DDE_PACKET;
  1957. DdeInfo.h16 = 0;
  1958. DDEAddhandle((HAND16)GETHWND16(lpwm32mpex->hwnd),
  1959. (HAND16)lpwm32mpex->Parm16.WndProc.wParam,
  1960. h16,
  1961. (HANDLE) lLo,
  1962. &DdeInfo);
  1963. LOW(lpwm32mpex->Parm16.WndProc.lParam) = h16;
  1964. }
  1965. HIW(lpwm32mpex->Parm16.WndProc.lParam) = (WORD) lHi;
  1966. if (fThunkDDEmsg) {
  1967. FreeDDElParam(lpwm32mpex->uMsg, lpwm32mpex->lParam);
  1968. }
  1969. }
  1970. else {
  1971. //
  1972. // We will execute this scenario only if the app ate the message,
  1973. // because we need to free up the memory.
  1974. //
  1975. if (!fThunkDDEmsg) {
  1976. if (lpwm32mpex->lReturn) {
  1977. FreeDDElParam(lpwm32mpex->uMsg, lpwm32mpex->lParam);
  1978. }
  1979. }
  1980. }
  1981. return (TRUE);
  1982. }
  1983. // This function thunks the messages,
  1984. //
  1985. // WM_DDE_EXECUTE
  1986. //
  1987. BOOL FASTCALL WM32DDEExecute(LPWM32MSGPARAMEX lpwm32mpex)
  1988. {
  1989. HAND16 h16;
  1990. VPVOID vp;
  1991. LPBYTE lpMem16;
  1992. LPBYTE lpMem32;
  1993. DDEINFO DdeInfo;
  1994. if (lpwm32mpex->fThunk) {
  1995. lpwm32mpex->Parm16.WndProc.wParam = GETHWND16(lpwm32mpex->uParam);
  1996. if (h16 = DDEFindPair16((HAND16)GETHWND16(lpwm32mpex->hwnd),
  1997. (HAND16)lpwm32mpex->Parm16.WndProc.wParam,
  1998. (HANDLE) lpwm32mpex->lParam)) {
  1999. HIW(lpwm32mpex->Parm16.WndProc.lParam) = h16;
  2000. } else {
  2001. vp = GlobalAllocLock16(GMEM_DDESHARE, GlobalSize((HANDLE) lpwm32mpex->lParam), &h16);
  2002. if (vp) {
  2003. GETMISCPTR(vp, lpMem16);
  2004. lpMem32 = GlobalLock((HANDLE) lpwm32mpex->lParam);
  2005. RtlCopyMemory(lpMem16, lpMem32, GlobalSize((HANDLE) lpwm32mpex->lParam));
  2006. GlobalUnlock((HANDLE) lpwm32mpex->lParam);
  2007. GlobalUnlock16(h16);
  2008. DdeInfo.Msg = LOW(lpwm32mpex->uMsg);
  2009. DdeInfo.Format = 0;
  2010. DdeInfo.Flags = DDE_PACKET;
  2011. DdeInfo.h16 = 0;
  2012. DDEAddhandle((HAND16)GETHWND16(lpwm32mpex->hwnd),
  2013. (HAND16)lpwm32mpex->Parm16.WndProc.wParam,
  2014. h16,
  2015. (HANDLE) lpwm32mpex->lParam,
  2016. &DdeInfo);
  2017. HIW(lpwm32mpex->Parm16.WndProc.lParam) = h16;
  2018. }
  2019. }
  2020. LOW(lpwm32mpex->Parm16.WndProc.lParam) = 0;
  2021. }
  2022. return (TRUE);
  2023. }
  2024. // This function thunks the messages,
  2025. //
  2026. // WM_CTLCOLORMSGBOX
  2027. // WM_CTLCOLOREDIT
  2028. // WM_CTLCOLORLISTBOX
  2029. // WM_CTLCOLORBTN
  2030. // WM_CTLCOLORDLG
  2031. // WM_CTLCOLORSCROLLBAR
  2032. // WM_CTLCOLORSTATIC
  2033. //
  2034. // into WM_CTLCOLOR and the high word of lParam specifies the
  2035. // control type.
  2036. //
  2037. BOOL FASTCALL WM32CtlColor(LPWM32MSGPARAMEX lpwm32mpex)
  2038. {
  2039. if (lpwm32mpex->fThunk) {
  2040. lpwm32mpex->Parm16.WndProc.wMsg = WM_CTLCOLOR;
  2041. if(lpwm32mpex->uMsg != WM_CTLCOLOR) { // see 16-bit thunk for this special case
  2042. lpwm32mpex->Parm16.WndProc.wParam = GETHDC16(lpwm32mpex->uParam);
  2043. LOW(lpwm32mpex->Parm16.WndProc.lParam) = GETHWND16(lpwm32mpex->lParam);
  2044. HIW(lpwm32mpex->Parm16.WndProc.lParam) = (WORD) (lpwm32mpex->uMsg - WM_CTLCOLORMSGBOX);
  2045. }
  2046. }
  2047. else {
  2048. if ((ULONG)lpwm32mpex->lReturn > COLOR_ENDCOLORS) {
  2049. lpwm32mpex->lReturn = (LONG) HBRUSH32(lpwm32mpex->lReturn);
  2050. }
  2051. }
  2052. return (TRUE);
  2053. }
  2054. // This function thunks the messages,
  2055. //
  2056. // WM_GETFONT
  2057. //
  2058. BOOL FASTCALL WM32GetFont(LPWM32MSGPARAMEX lpwm32mpex)
  2059. {
  2060. if (!lpwm32mpex->fThunk) {
  2061. lpwm32mpex->lReturn = (LONG)HFONT32(lpwm32mpex->lReturn);
  2062. }
  2063. return (TRUE);
  2064. }
  2065. // This function thunks the messages,
  2066. //
  2067. // WM_NEXTMENU
  2068. //
  2069. // Win16 NT
  2070. // wParam VK_KEY VK_KEY
  2071. // lParam.l hmenu PMDINEXTMENU
  2072. // lParam.h 0
  2073. // return.l menu BOOL
  2074. // return.h window
  2075. //
  2076. BOOL FASTCALL WM32NextMenu(LPWM32MSGPARAMEX lpwm32mpex)
  2077. {
  2078. if (lpwm32mpex->fThunk) {
  2079. if (lpwm32mpex->lParam) {
  2080. LOW(lpwm32mpex->Parm16.WndProc.lParam) = GETHMENU16(((PMDINEXTMENU)lpwm32mpex->lParam)->hmenuIn);
  2081. HIW(lpwm32mpex->Parm16.WndProc.lParam) = 0;
  2082. }
  2083. } else {
  2084. if (lpwm32mpex->lParam) {
  2085. ((PMDINEXTMENU)lpwm32mpex->lParam)->hmenuNext = HMENU32(LOWORD(lpwm32mpex->lReturn));
  2086. ((PMDINEXTMENU)lpwm32mpex->lParam)->hwndNext = HWND32(HIWORD(lpwm32mpex->lReturn));
  2087. lpwm32mpex->lReturn = TRUE;
  2088. } else {
  2089. lpwm32mpex->lReturn = FALSE;
  2090. }
  2091. }
  2092. return (TRUE);
  2093. }
  2094. BOOL FASTCALL WM32Destroy (LPWM32MSGPARAMEX lpwm32mpex)
  2095. {
  2096. if (!lpwm32mpex->fThunk) {
  2097. if (CACHENOTEMPTY()) {
  2098. // because of our method of window aliasing, 'hwnd' may or may
  2099. // not be a real 32bit handle. ie. it may be (hwnd16 | 0xffff0000).
  2100. // So always use hwnd16.
  2101. ReleaseCachedDCs((CURRENTPTD())->htask16, GETHWND16(lpwm32mpex->hwnd), 0,
  2102. (HWND)0, SRCHDC_TASK16_HWND16);
  2103. }
  2104. }
  2105. return (TRUE);
  2106. }
  2107. // This function thunks the messages,
  2108. // WM_DROPFILES
  2109. BOOL FASTCALL WM32DropFiles(LPWM32MSGPARAMEX lpwm32mpex)
  2110. {
  2111. if (lpwm32mpex->fThunk) {
  2112. return (BOOL)(lpwm32mpex->Parm16.WndProc.wParam = GETHDROP16(lpwm32mpex->uParam));
  2113. }
  2114. return (TRUE);
  2115. }
  2116. // This function thunks the messages,
  2117. // WM_PRINT
  2118. // WM_PRINTCLIENT
  2119. BOOL FASTCALL WM32PrintClient(LPWM32MSGPARAMEX lpwm32mpex)
  2120. {
  2121. if (lpwm32mpex->fThunk) {
  2122. return (BOOL)(lpwm32mpex->Parm16.WndProc.wParam = GETHDC16(lpwm32mpex->uParam));
  2123. }
  2124. return (TRUE);
  2125. }
  2126. // This function thunks the messages,
  2127. //
  2128. // WM_DROPOBJECT
  2129. // WM_QUERYDROPOBJECT
  2130. // WM_DRAGLOOP
  2131. // WM_DRAGSELECT
  2132. // WM_DRAGMOVE
  2133. //
  2134. BOOL FASTCALL WM32DropObject(LPWM32MSGPARAMEX lpwm32mpex)
  2135. {
  2136. register PDROPSTRUCT16 pds16;
  2137. register LPDROPSTRUCT lParam = (LPDROPSTRUCT)lpwm32mpex->lParam;
  2138. if (lpwm32mpex->fThunk) {
  2139. lpwm32mpex->Parm16.WndProc.wParam = (WORD)lpwm32mpex->uParam;
  2140. // BUGBUG -- The assumption here is that GlobalAlloc will never
  2141. // return a memory object that isn't word-aligned, so that we can
  2142. // assign word-aligned words directly; we have no idea whether the
  2143. // memory is dword-aligned or not however, so dwords must always
  2144. // be paranoidly stored with the STOREDWORD/STORELONG macros -JTP
  2145. if (!(lpwm32mpex->Parm16.WndProc.lParam = malloc16(sizeof(DROPSTRUCT16))))
  2146. return FALSE;
  2147. GETVDMPTR(lpwm32mpex->Parm16.WndProc.lParam, sizeof(DROPSTRUCT16), pds16);
  2148. pds16->hwndSource = GETHWND16(lParam->hwndSource);
  2149. pds16->hwndSink = GETHWND16(lParam->hwndSink);
  2150. pds16->wFmt = (WORD) lParam->wFmt;
  2151. STOREDWORD(pds16->dwData, lParam->dwData);
  2152. pds16->ptDrop.x = (SHORT)lParam->ptDrop.x;
  2153. pds16->ptDrop.y = (SHORT)lParam->ptDrop.y;
  2154. STOREDWORD(pds16->dwControlData, lParam->dwControlData);
  2155. FLUSHVDMPTR(lpwm32mpex->Parm16.WndProc.lParam, sizeof(DROPSTRUCT16), pds16);
  2156. FREEVDMPTR(pds16);
  2157. } else {
  2158. free16((VPVOID) lpwm32mpex->Parm16.WndProc.lParam);
  2159. if (lpwm32mpex->uMsg == WM_QUERYDROPOBJECT) {
  2160. //
  2161. // Return value is either TRUE, FALSE,
  2162. // or a cursor!
  2163. //
  2164. if (lpwm32mpex->lReturn && lpwm32mpex->lReturn != (LONG)TRUE) {
  2165. lpwm32mpex->lReturn = (LONG)HCURSOR32(lpwm32mpex->lReturn);
  2166. }
  2167. }
  2168. }
  2169. return (TRUE);
  2170. }
  2171. // This function thunks the messages,
  2172. //
  2173. // WM_WINDOWPOSCHANGING
  2174. // WM_WINDOWPOSCHANGED
  2175. //
  2176. BOOL FASTCALL WM32WindowPosChanging (LPWM32MSGPARAMEX lpwm32mpex)
  2177. {
  2178. LPWINDOWPOS lParam = (LPWINDOWPOS) lpwm32mpex->lParam;
  2179. if (lpwm32mpex->fThunk) {
  2180. // be sure allocation size matches stackfree16() size below
  2181. lpwm32mpex->Parm16.WndProc.lParam = stackalloc16(sizeof(WINDOWPOS16));
  2182. putwindowpos16( (VPWINDOWPOS16)lpwm32mpex->Parm16.WndProc.lParam, lParam );
  2183. }
  2184. else {
  2185. getwindowpos16( (VPWINDOWPOS16)lpwm32mpex->Parm16.WndProc.lParam, lParam );
  2186. if(lpwm32mpex->Parm16.WndProc.lParam) {
  2187. stackfree16((VPVOID) lpwm32mpex->Parm16.WndProc.lParam,
  2188. sizeof(WINDOWPOS16));
  2189. }
  2190. }
  2191. return (TRUE);
  2192. }
  2193. // This function thunks the message,
  2194. //
  2195. // WM_COPYDATA
  2196. //
  2197. BOOL FASTCALL WM32CopyData (LPWM32MSGPARAMEX lpwm32mpex)
  2198. {
  2199. HAND16 h16;
  2200. HAND16 hMem16;
  2201. VPVOID vpCDS16;
  2202. VPVOID vpData16;
  2203. LPBYTE lpMem16;
  2204. PCOPYDATASTRUCT lpCDS32;
  2205. PCOPYDATASTRUCT lpCDS16;
  2206. PCPDATA pTemp;
  2207. if (lpwm32mpex->fThunk) {
  2208. lpwm32mpex->Parm16.WndProc.wParam = GETHWND16(lpwm32mpex->uParam);
  2209. if (vpCDS16 = CopyDataFindData16 (GETHWND16(lpwm32mpex->hwnd), lpwm32mpex->Parm16.WndProc.wParam, lpwm32mpex->lParam)) {
  2210. lpwm32mpex->Parm16.WndProc.lParam = vpCDS16;
  2211. }
  2212. else {
  2213. vpCDS16 = GlobalAllocLock16(GMEM_DDESHARE, sizeof(COPYDATASTRUCT), &h16);
  2214. if (vpCDS16) {
  2215. GETMISCPTR(vpCDS16, lpCDS16);
  2216. lpCDS32 = (PCOPYDATASTRUCT) lpwm32mpex->lParam;
  2217. lpCDS16->dwData = lpCDS32->dwData;
  2218. if (lpCDS16->cbData = lpCDS32->cbData) {
  2219. FREEMISCPTR(lpCDS16);
  2220. vpData16 = GlobalAllocLock16(GMEM_DDESHARE, lpCDS32->cbData, &hMem16);
  2221. GETMISCPTR(vpData16, lpMem16);
  2222. if (lpMem16 && lpCDS32->lpData) {
  2223. RtlCopyMemory(lpMem16, lpCDS32->lpData, lpCDS32->cbData);
  2224. CopyDataAddNode (GETHWND16(lpwm32mpex->hwnd), lpwm32mpex->Parm16.WndProc.wParam, vpData16, (DWORD) lpCDS32->lpData, 0);
  2225. }
  2226. FREEMISCPTR(lpMem16);
  2227. GETMISCPTR(vpCDS16, lpCDS16);
  2228. lpCDS16->lpData = (PVOID) vpData16;
  2229. }
  2230. else {
  2231. lpCDS16->lpData = NULL;
  2232. }
  2233. FREEMISCPTR(lpCDS16);
  2234. }
  2235. lpwm32mpex->Parm16.WndProc.lParam = vpCDS16;
  2236. CopyDataAddNode (GETHWND16(lpwm32mpex->hwnd), lpwm32mpex->Parm16.WndProc.wParam, vpCDS16, lpwm32mpex->lParam, 0);
  2237. }
  2238. }
  2239. else {
  2240. if (lpwm32mpex->fFree) {
  2241. pTemp = CopyDataFindData32 (GETHWND16(lpwm32mpex->hwnd), GETHWND16(lpwm32mpex->uParam), lpwm32mpex->Parm16.WndProc.lParam);
  2242. if (pTemp && (!(pTemp->Flags))) {
  2243. GETMISCPTR(lpwm32mpex->Parm16.WndProc.lParam, lpCDS16);
  2244. GlobalUnlockFree16 ((VPVOID)lpCDS16->lpData);
  2245. CopyDataDeleteNode (GETHWND16(lpwm32mpex->hwnd), lpwm32mpex->Parm16.WndProc.wParam, (DWORD) ((PCOPYDATASTRUCT)lpwm32mpex->lParam)->lpData);
  2246. GlobalUnlockFree16 ((VPVOID)lpwm32mpex->Parm16.WndProc.lParam);
  2247. CopyDataDeleteNode (GETHWND16(lpwm32mpex->hwnd), lpwm32mpex->Parm16.WndProc.wParam, (DWORD) lpwm32mpex->lParam);
  2248. FREEMISCPTR(lpCDS16);
  2249. }
  2250. }
  2251. }
  2252. return (TRUE);
  2253. }
  2254. // This function thunks the message,
  2255. //
  2256. // WM_WINHELP
  2257. //
  2258. BOOL FASTCALL WM32WinHelp (LPWM32MSGPARAMEX lpwm32mpex)
  2259. {
  2260. static WORD msgWinHelp = 0;
  2261. if (lpwm32mpex->fThunk) {
  2262. lpwm32mpex->Parm16.WndProc.wMsg = msgWinHelp ? msgWinHelp : (msgWinHelp = (WORD)RegisterWindowMessage("WM_WINHELP"));
  2263. lpwm32mpex->Parm16.WndProc.wParam = GETHWND16(lpwm32mpex->uParam);
  2264. if (lpwm32mpex->lParam) {
  2265. // lpwm32mpex->lParam is LPHLP - however we need only the firstword,ie the size of data
  2266. HAND16 hMem16;
  2267. VPVOID vp;
  2268. LPBYTE lpT;
  2269. WORD cb;
  2270. cb = ((LPHLP)lpwm32mpex->lParam)->cbData;
  2271. if (vp = GlobalAllocLock16(GMEM_DDESHARE | GMEM_MOVEABLE, cb, &hMem16)) {
  2272. GETMISCPTR(vp, lpT);
  2273. RtlCopyMemory(lpT, (PVOID)lpwm32mpex->lParam, cb);
  2274. FREEMISCPTR(lpT);
  2275. }
  2276. lpwm32mpex->Parm16.WndProc.lParam = hMem16;
  2277. lpwm32mpex->dwParam = vp;
  2278. }
  2279. }
  2280. else {
  2281. // Make sure WinHelp is in the foreground
  2282. SetForegroundWindow(lpwm32mpex->hwnd);
  2283. if (lpwm32mpex->Parm16.WndProc.lParam) {
  2284. GlobalUnlockFree16((VPVOID)lpwm32mpex->dwParam);
  2285. }
  2286. }
  2287. return (TRUE);
  2288. }
  2289. //
  2290. // Thunk the undocumented MM_CALCSCROLL MDI message. Message has no parameters,
  2291. // but has different message values; 32-bit msg: 0x3F, 16-bit msg: 0x10AC.
  2292. //
  2293. BOOL FASTCALL WM32MMCalcScroll (LPWM32MSGPARAMEX lpwm32mpex)
  2294. {
  2295. if ( lpwm32mpex->fThunk ) {
  2296. lpwm32mpex->Parm16.WndProc.wMsg = (WORD) WIN31_MM_CALCSCROLL;
  2297. }
  2298. return (TRUE);
  2299. }
  2300. // Calculate the size of the structure passed with WM_NOTIFY based
  2301. // on the code field in NMHDR.
  2302. // NOTE: Do NOT rely on the documentation for the size of the struct passed in
  2303. // lParam. In some cases the struct is actually part of a larger struct
  2304. // and we need to copy all of it. See PSN_xxxx codes in comctl32\prsht.c
  2305. // They are documented to be NMHDR but are really a PSHNOTIFY which has
  2306. // NMHDR as the first field. Also watch for some of the WIDE UNICODE
  2307. // char cases -- the struct may or may not be the same size as the ANSI
  2308. // version of the struct.
  2309. // Heaven help us when they start adding more of these codes!
  2310. UINT GetNMHDRextensionSize(LPNMHDR pnmhdr32)
  2311. {
  2312. #ifdef DEBUG
  2313. char szLabel[40] = " WOW:WM_NOTIFY code: ";
  2314. #endif
  2315. // Caller already checked against NM_LAST.
  2316. if (pnmhdr32->code >= LVN_LAST) {
  2317. LOGDEBUG(2,("%sLVN_ %x\n", szLabel, pnmhdr32->code));
  2318. switch (pnmhdr32->code) {
  2319. case LVN_ITEMCHANGING:
  2320. case LVN_ITEMCHANGED:
  2321. case LVN_INSERTITEM:
  2322. case LVN_DELETEITEM:
  2323. case LVN_DELETEALLITEMS:
  2324. case LVN_COLUMNCLICK:
  2325. case LVN_BEGINDRAG:
  2326. case LVN_BEGINRDRAG:
  2327. case LVN_HOTTRACK:
  2328. return sizeof(NM_LISTVIEW);
  2329. case LVN_BEGINLABELEDITA:
  2330. case LVN_ENDLABELEDITA:
  2331. case LVN_GETDISPINFOA:
  2332. case LVN_SETDISPINFOA:
  2333. case LVN_BEGINLABELEDITW:
  2334. case LVN_ENDLABELEDITW:
  2335. case LVN_GETDISPINFOW:
  2336. case LVN_SETDISPINFOW:
  2337. return sizeof(LV_DISPINFO);
  2338. case LVN_KEYDOWN:
  2339. return sizeof(LV_KEYDOWN);
  2340. case LVN_ODCACHEHINT:
  2341. return sizeof(NM_CACHEHINT);
  2342. case LVN_ODFINDITEMA:
  2343. case LVN_ODFINDITEMW:
  2344. return sizeof(NM_FINDITEM);
  2345. case LVN_ODSTATECHANGED:
  2346. return sizeof(NM_ODSTATECHANGE);
  2347. case LVN_ITEMACTIVATE:
  2348. return sizeof(NMKEY);
  2349. default:
  2350. goto unknown_nmhdr_code;
  2351. }
  2352. }
  2353. if (pnmhdr32->code >= PSN_LAST) {
  2354. LOGDEBUG(2,("%sPSN_ %x\n", szLabel, pnmhdr32->code));
  2355. switch (pnmhdr32->code) {
  2356. case PSN_SETACTIVE:
  2357. case PSN_KILLACTIVE:
  2358. case PSN_APPLY:
  2359. case PSN_RESET:
  2360. case PSN_HELP:
  2361. case PSN_WIZBACK:
  2362. case PSN_WIZNEXT:
  2363. case PSN_WIZFINISH:
  2364. case PSN_QUERYCANCEL:
  2365. case PSN_TRANSLATEACCELERATOR:
  2366. case PSN_QUERYINITIALFOCUS:
  2367. case PSN_HASHELP: // this one "is dead" - RaymondC
  2368. return sizeof(PSHNOTIFY);
  2369. case PSN_GETOBJECT:
  2370. return sizeof(NMOBJECTNOTIFY);
  2371. case PSN_LASTCHANCEAPPLY: // this is undocumented
  2372. return sizeof(NMHDR); // (in widows\inc\prshtp.h)
  2373. default:
  2374. goto unknown_nmhdr_code;
  2375. }
  2376. }
  2377. if (pnmhdr32->code >= HDN_LAST) {
  2378. LOGDEBUG(2,("%sHDN_ %x\n", szLabel, pnmhdr32->code));
  2379. switch (pnmhdr32->code) {
  2380. case HDN_ITEMCHANGINGA:
  2381. case HDN_ITEMCHANGEDA:
  2382. case HDN_ITEMCLICKA:
  2383. case HDN_DIVIDERDBLCLICKA:
  2384. case HDN_BEGINTRACKA:
  2385. case HDN_ENDTRACKA:
  2386. case HDN_TRACKA:
  2387. case HDN_ITEMCHANGINGW:
  2388. case HDN_ITEMCHANGEDW:
  2389. case HDN_ITEMCLICKW:
  2390. case HDN_DIVIDERDBLCLICKW:
  2391. case HDN_BEGINTRACKW:
  2392. case HDN_ENDTRACKW:
  2393. case HDN_TRACKW:
  2394. case HDN_BEGINDRAG:
  2395. case HDN_ENDDRAG:
  2396. case HDN_ITEMDBLCLICKA:
  2397. case HDN_ITEMDBLCLICKW:
  2398. return sizeof(HD_NOTIFY);
  2399. case HDN_GETDISPINFOA:
  2400. case HDN_GETDISPINFOW:
  2401. return sizeof(NMHDDISPINFO);
  2402. default:
  2403. goto unknown_nmhdr_code;
  2404. }
  2405. }
  2406. if (pnmhdr32->code >= TVN_LAST) {
  2407. LOGDEBUG(2,("%sTVN_ %x\n", szLabel, pnmhdr32->code));
  2408. switch (pnmhdr32->code) {
  2409. case TVN_SELCHANGINGA:
  2410. case TVN_SELCHANGEDA:
  2411. case TVN_ITEMEXPANDINGA:
  2412. case TVN_ITEMEXPANDEDA:
  2413. case TVN_BEGINDRAGA:
  2414. case TVN_BEGINRDRAGA:
  2415. case TVN_DELETEITEMA:
  2416. case TVN_SELCHANGINGW:
  2417. case TVN_SELCHANGEDW:
  2418. case TVN_ITEMEXPANDINGW:
  2419. case TVN_ITEMEXPANDEDW:
  2420. case TVN_BEGINDRAGW:
  2421. case TVN_BEGINRDRAGW:
  2422. case TVN_DELETEITEMW:
  2423. case TVN_SINGLEEXPAND:
  2424. return sizeof(NM_TREEVIEW);
  2425. case TVN_GETDISPINFOA:
  2426. case TVN_SETDISPINFOA:
  2427. case TVN_BEGINLABELEDITA:
  2428. case TVN_ENDLABELEDITA:
  2429. case TVN_GETDISPINFOW:
  2430. case TVN_SETDISPINFOW:
  2431. case TVN_BEGINLABELEDITW:
  2432. case TVN_ENDLABELEDITW:
  2433. return sizeof(TV_DISPINFO);
  2434. case TVN_KEYDOWN:
  2435. return sizeof(TV_KEYDOWN);
  2436. case TVN_GETINFOTIPA:
  2437. case TVN_GETINFOTIPW:
  2438. return sizeof(NMTVGETINFOTIP);
  2439. default:
  2440. goto unknown_nmhdr_code;
  2441. }
  2442. }
  2443. if (pnmhdr32->code >= TTN_LAST) {
  2444. LOGDEBUG(2,("%sTTN_ %x\n", szLabel, pnmhdr32->code));
  2445. switch (pnmhdr32->code) {
  2446. case TTN_NEEDTEXTA: // (aka TTN_GETDISPINFO)
  2447. return sizeof(TOOLTIPTEXTA);
  2448. case TTN_NEEDTEXTW:
  2449. return sizeof(TOOLTIPTEXTW);
  2450. case TTN_SHOW:
  2451. case TTN_POP:
  2452. return sizeof(NMHDR);
  2453. default:
  2454. goto unknown_nmhdr_code;
  2455. }
  2456. }
  2457. if (pnmhdr32->code >= TCN_LAST) {
  2458. LOGDEBUG(2,("%sTCN_ %x\n", szLabel, pnmhdr32->code));
  2459. switch (pnmhdr32->code) {
  2460. case TCN_KEYDOWN:
  2461. return sizeof(TC_KEYDOWN);
  2462. case TCN_SELCHANGE:
  2463. case TCN_SELCHANGING:
  2464. return sizeof(NMHDR);
  2465. default:
  2466. goto unknown_nmhdr_code;
  2467. }
  2468. }
  2469. if (pnmhdr32->code >= UDN_LAST) {
  2470. LOGDEBUG(2,("%sUDN_ %x\n", szLabel, pnmhdr32->code));
  2471. switch (pnmhdr32->code) {
  2472. case UDN_DELTAPOS:
  2473. return sizeof(NM_UPDOWN);
  2474. default:
  2475. goto unknown_nmhdr_code;
  2476. }
  2477. }
  2478. unknown_nmhdr_code:
  2479. LOGDEBUG(LOG_ALWAYS, ("WOW:GetNMHDRextensionSize unknown nmhdr->code: %d!\n", pnmhdr32->code));
  2480. WOW32ASSERT(FALSE);
  2481. return sizeof(NMHDR); // the first field of most of the structs is NMHDR
  2482. }
  2483. //
  2484. // This function thunks the 32-bit message WM_NOTIFY. This message existed
  2485. // but was undocumented in Win3.1. Win95 thunks it by translating lParam
  2486. // from a flat to 16:16 pointer without thunking the contents. That's tricky
  2487. // for us since on RISC we can't map random linear memory into the VDM without
  2488. // a lot of overhead. We'll use the code field in NMHDR to calculate the size
  2489. // of the passed structure.
  2490. //
  2491. BOOL FASTCALL WM32Notify(LPWM32MSGPARAMEX lpwm32mpex)
  2492. {
  2493. LPNMHDR pnmhdr32;
  2494. LPNMHDR pnmhdr16;
  2495. if (lpwm32mpex->fThunk) {
  2496. pnmhdr32 = (LPNMHDR) lpwm32mpex->Parm16.WndProc.lParam;
  2497. // Save the original 32-bit flat pointer for unthunking.
  2498. lpwm32mpex->dwTmp[0] = (DWORD) pnmhdr32;
  2499. // If this 32bit message came from WOW, we have the original
  2500. // 16:16 lparam squirrelled away. (mapped to the original 32-bit lParam)
  2501. // Note: If the mapping is found, the ref count gets incremented.
  2502. lpwm32mpex->Parm16.WndProc.lParam = (LONG)GetParam16(lpwm32mpex->lParam);
  2503. // if we don't already have a 16:16 ptr for this -- create one
  2504. // This means we are seeing this message for the 1st time -- coming
  2505. // from the 32-bit world.
  2506. if ( ! lpwm32mpex->Parm16.WndProc.lParam) {
  2507. if (pnmhdr32->code >= NM_LAST) {
  2508. lpwm32mpex->dwParam = sizeof(NMHDR);
  2509. }
  2510. else {
  2511. lpwm32mpex->dwParam = GetNMHDRextensionSize(pnmhdr32);
  2512. }
  2513. // be sure allocation size matches stackfree16() size below
  2514. lpwm32mpex->dwTmp[1] = (DWORD)lpwm32mpex->dwParam;
  2515. lpwm32mpex->Parm16.WndProc.lParam = stackalloc16(lpwm32mpex->dwTmp[1]);
  2516. GETVDMPTR(lpwm32mpex->Parm16.WndProc.lParam, lpwm32mpex->dwParam, pnmhdr16);
  2517. CopyMemory(pnmhdr16, pnmhdr32, lpwm32mpex->dwParam);
  2518. FREEVDMPTR(pnmhdr16);
  2519. // else don't allocate (or free) another 16:16 ptr
  2520. } else {
  2521. // set to FALSE so we don't free this thing too soon
  2522. lpwm32mpex->fFree = FALSE;
  2523. }
  2524. } else {
  2525. if (lpwm32mpex->fFree) {
  2526. GETVDMPTR(lpwm32mpex->Parm16.WndProc.lParam, lpwm32mpex->dwParam, pnmhdr16);
  2527. // retrieve original 32-bit pointer
  2528. pnmhdr32 = (LPNMHDR) lpwm32mpex->dwTmp[0];
  2529. CopyMemory(pnmhdr32, pnmhdr16, lpwm32mpex->dwParam);
  2530. FREEVDMPTR(pnmhdr16);
  2531. if(lpwm32mpex->Parm16.WndProc.lParam) {
  2532. stackfree16(lpwm32mpex->Parm16.WndProc.lParam, lpwm32mpex->dwTmp[1]);
  2533. }
  2534. } else {
  2535. // Decrement the ref count. If the ref count goes to zero, the
  2536. // mapping is nuked.
  2537. DeleteParamMap(lpwm32mpex->Parm16.WndProc.lParam, PARAM_16, NULL);
  2538. }
  2539. }
  2540. return TRUE;
  2541. }
  2542. // This function thunks the 32-bit message WM_NOTIFYWOW.
  2543. // uParam dictates where the notification should be dispatched.
  2544. //
  2545. BOOL FASTCALL WM32NotifyWow(LPWM32MSGPARAMEX lpwm32mpex)
  2546. {
  2547. switch (lpwm32mpex->uParam) {
  2548. case WMNW_UPDATEFINDREPLACE:
  2549. if (lpwm32mpex->fThunk) {
  2550. // Update the 16-bit FINDREPLACE struct.
  2551. lpwm32mpex->Parm16.WndProc.lParam = WCD32UpdateFindReplaceTextAndFlags(lpwm32mpex->hwnd, lpwm32mpex->lParam);
  2552. lpwm32mpex->Parm16.WndProc.wMsg = msgFINDREPLACE;
  2553. return(TRUE);
  2554. }
  2555. break;
  2556. default:
  2557. LOGDEBUG(LOG_ALWAYS, ("WOW::WM32NotifyWow: Unknown dispatch parameter!\n"));
  2558. WOW32ASSERT (FALSE);
  2559. }
  2560. return (FALSE);
  2561. }
  2562. //
  2563. // In ThunkMsg16 we use the data in 32->16 message thunk table to optimize
  2564. // thunking process based on 'WM32NoThunking'.
  2565. //
  2566. // This is place holder for those messages which need nothunking on 32-16
  2567. // trasitions but need some kind of thunking on 16->32 transistions.
  2568. //
  2569. // So this marks the message as 'this message needs 16-32 thunking but
  2570. // not 32-16 thunking'
  2571. //
  2572. // - nanduri
  2573. BOOL FASTCALL WM32Thunk16To32(LPWM32MSGPARAMEX lpwm32mpex)
  2574. {
  2575. return (TRUE);
  2576. }
  2577. #ifdef FE_IME
  2578. //
  2579. // This function thunks the messages,
  2580. //
  2581. // WM_IME_REPORT
  2582. /*
  2583. BOOL FASTCALL WM32IMEReport (HWND hwnd, UINT uMsg, UINT uParam, LONG lParam,
  2584. PWORD pwMsgNew, PWORD pwParamNew, PLONG plParamNew,
  2585. PLONG plReturn, BOOL fThunk, LPWM32MSGPARAMEX lpwm32mpex)
  2586. */
  2587. BOOL FASTCALL WM32IMEReport (LPWM32MSGPARAMEX lpwm32mpex)
  2588. {
  2589. //lpwm32mpex->hwnd
  2590. //lpwm32mpex->uMsg
  2591. //lpwm32mpex->uParam
  2592. //lpwm32mpex->lParam
  2593. //lpwm32mpex->Param16.WndProc.wMsg
  2594. //lpwm32mpex->Param16.WndProc.wParam
  2595. //lpwm32mpex->Param16.WndProc.lParam
  2596. //&lpwm32mpex->lReturn
  2597. //lpwm32mpex->fThunk
  2598. //
  2599. INT cb;
  2600. INT i;
  2601. HMEM16 hMem16 = 0;
  2602. LPBYTE lpMem32 = 0;
  2603. LPBYTE lpMem16 = 0;
  2604. VPVOID vp;
  2605. if (lpwm32mpex->fThunk) {
  2606. if (lpwm32mpex->uParam == IR_STRING) {
  2607. lpMem32 = GlobalLock((HANDLE)lpwm32mpex->lParam);
  2608. if (lpMem32 == NULL)
  2609. goto Err;
  2610. cb = strlen( lpMem32 ) + 1;
  2611. if (!(lpwm32mpex->Parm16.WndProc.lParam = GlobalAllocLock16(GMEM_MOVEABLE | GMEM_SHARE | GMEM_ZEROINIT, cb, &hMem16 )))
  2612. goto Err;
  2613. putstr16((VPSZ)lpwm32mpex->Parm16.WndProc.lParam, lpMem32, cb);
  2614. LOW( lpwm32mpex->Parm16.WndProc.lParam ) = hMem16;
  2615. HIW( lpwm32mpex->Parm16.WndProc.lParam ) = 0; // must be zero
  2616. GlobalUnlock( (HANDLE)lpwm32mpex->lParam );
  2617. GlobalUnlock16( hMem16 );
  2618. }
  2619. /**** IR_STRINGEX ****/
  2620. else if ( lpwm32mpex->uParam == IR_STRINGEX ) {
  2621. LPSTRINGEXSTRUCT pss32;
  2622. PSTRINGEXSTRUCT16 pss16;
  2623. lpMem32 = GlobalLock((HANDLE)lpwm32mpex->lParam);
  2624. if (lpMem32 == NULL)
  2625. goto Err;
  2626. pss32 = (LPSTRINGEXSTRUCT)lpMem32;
  2627. cb = pss32->dwSize;
  2628. if ( cb >= ( 64 * K )) {
  2629. // It's problem !
  2630. LOGDEBUG(0,(" WOW:: WM_IME_REPORT:IR_STRINGEX data size must be less than 64K on WOW. cb = %d\n", cb ));
  2631. /** goto Err; **/
  2632. }
  2633. // Shuld I pack size of this structure ?
  2634. if (!(vp = GlobalAllocLock16(GMEM_MOVEABLE | GMEM_SHARE | GMEM_ZEROINIT, cb, &hMem16 )))
  2635. return FALSE;
  2636. GETVDMPTR(vp, cb, lpMem16 );
  2637. pss16 = (PSTRINGEXSTRUCT16)lpMem16;
  2638. STOREDWORD( pss16->dwSize, pss32->dwSize );
  2639. STOREWORD( pss16->uDeterminePos, pss32->uDeterminePos );
  2640. STOREWORD( pss16->uDetermineDelimPos, pss32->uDetermineDelimPos );
  2641. STOREWORD( pss16->uYomiPos, pss32->uYomiPos );
  2642. STOREWORD( pss16->uYomiDelimPos, pss32->uYomiDelimPos );
  2643. if ( pss32->uDeterminePos ) {
  2644. cb = strlen( (LPBYTE)&lpMem32[ pss32->uDeterminePos ] );
  2645. RtlCopyMemory( &lpMem16[ pss16->uDeterminePos ],
  2646. &lpMem32[ pss32->uDeterminePos ], cb + 1 );
  2647. if ( pss32->uDetermineDelimPos ) {
  2648. for ( i = 0; pss32->uDetermineDelimPos + i * sizeof(INT) < pss32->dwSize; i++ ) {
  2649. WORDOF16( lpMem16[ pss16->uDetermineDelimPos ], i ) = (WORD)
  2650. INTOF( lpMem32[ pss32->uDetermineDelimPos ], i );
  2651. if ( INTOF( lpMem32[ pss32->uDetermineDelimPos ], i ) >= cb )
  2652. break;
  2653. }
  2654. }
  2655. }
  2656. if ( pss32->uYomiPos ) {
  2657. cb = strlen( (LPBYTE)&lpMem32[ pss32->uYomiPos ] );
  2658. RtlCopyMemory( &lpMem16[ pss16->uYomiPos ],
  2659. &lpMem32[ pss32->uYomiPos ], cb + 1 );
  2660. if ( pss32->uYomiDelimPos ) {
  2661. for ( i = 0; pss32->uYomiDelimPos + i * sizeof(INT) < pss32->dwSize; i++ ) {
  2662. WORDOF16( lpMem16[ pss16->uYomiDelimPos ], i ) = (WORD)
  2663. INTOF( lpMem32[ pss32->uYomiDelimPos ], i );
  2664. if ( INTOF( lpMem32[ pss32->uYomiDelimPos ], i ) >= cb )
  2665. break;
  2666. }
  2667. }
  2668. }
  2669. FLUSHVDMPTR(vp, cb, lpMem16);
  2670. FREEVDMPTR(lpMem16);
  2671. LOW( lpwm32mpex->Parm16.WndProc.lParam ) = hMem16;
  2672. HIW( lpwm32mpex->Parm16.WndProc.lParam ) = 0; // must be zero
  2673. GlobalUnlock( (HANDLE)lpwm32mpex->lParam );
  2674. GlobalUnlock16( hMem16 );
  2675. }
  2676. /**** IR_UNDETERMINE ****/
  2677. else if (lpwm32mpex->uParam == IR_UNDETERMINE) {
  2678. PUNDETERMINESTRUCT16 pus16;
  2679. LPUNDETERMINESTRUCT pus32;
  2680. lpMem32 = GlobalLock( (HANDLE)lpwm32mpex->lParam );
  2681. if (lpMem32 == NULL)
  2682. goto Err;
  2683. pus32 = (LPUNDETERMINESTRUCT)lpMem32;
  2684. cb = pus32->dwSize;
  2685. if ( cb >= ( 64 * K )) {
  2686. // It's problem !
  2687. LOGDEBUG(0,(" WOW:: WM_IME_REPORT:IR_UNDETERMINE data size must be less than 64K on WOW. cb = %d\n", cb ));
  2688. /** goto Err; **/
  2689. }
  2690. if (!( vp = GlobalAllocLock16(GMEM_MOVEABLE | GMEM_SHARE | GMEM_ZEROINIT, cb, &hMem16 )))
  2691. goto Err;
  2692. GETVDMPTR(vp, cb, lpMem16 );
  2693. pus16 = (PUNDETERMINESTRUCT16)lpMem16;
  2694. STOREDWORD( pus16->dwSize, (pus32)->dwSize );
  2695. STOREWORD( pus16->uDefIMESize, (pus32)->uDefIMESize );
  2696. STOREWORD( pus16->uDefIMEPos, (pus32)->uDefIMEPos );
  2697. STOREWORD( pus16->uUndetTextLen, (pus32)->uUndetTextLen );
  2698. STOREWORD( pus16->uUndetTextPos, (pus32)->uUndetTextPos );
  2699. STOREWORD( pus16->uUndetAttrPos, (pus32)->uUndetAttrPos );
  2700. STOREWORD( pus16->uCursorPos, (pus32)->uCursorPos );
  2701. STOREWORD( pus16->uDeltaStart, (pus32)->uDeltaStart );
  2702. STOREWORD( pus16->uDetermineTextLen, (pus32)->uDetermineTextLen );
  2703. STOREWORD( pus16->uDetermineTextPos, (pus32)->uDetermineTextPos );
  2704. STOREWORD( pus16->uDetermineDelimPos, (pus32)->uDetermineDelimPos );
  2705. STOREWORD( pus16->uYomiTextLen, (pus32)->uYomiTextLen );
  2706. STOREWORD( pus16->uYomiTextPos, (pus32)->uYomiTextPos );
  2707. STOREWORD( pus16->uYomiDelimPos, (pus32)->uYomiDelimPos );
  2708. // dada copy
  2709. RtlCopyMemory( &lpMem16[ sizeof(UNDETERMINESTRUCT) ],
  2710. &lpMem32[ sizeof(UNDETERMINESTRUCT) ],
  2711. cb - sizeof( UNDETERMINESTRUCT ));
  2712. //adjustment
  2713. if ( pus32->uDetermineDelimPos ) {
  2714. cb = pus32->uDetermineTextLen;
  2715. for ( i = 0; pus32->uDetermineDelimPos + i * sizeof(INT) < pus32->dwSize; i++ ) {
  2716. INTOF( lpMem16[ pus16->uDetermineDelimPos ], i ) = 0;
  2717. WORDOF16( lpMem16[ pus16->uDetermineDelimPos ], i ) = (WORD)
  2718. INTOF( lpMem32[ pus32->uDetermineDelimPos ], i );
  2719. if ( INTOF( lpMem32[ pus32->uDetermineDelimPos ], i ) >= cb )
  2720. break;
  2721. }
  2722. }
  2723. if ( pus32->uYomiDelimPos ) {
  2724. cb = pus32->uYomiTextLen;
  2725. for ( i = 0; pus32->uYomiDelimPos + i * sizeof(INT) < pus32->dwSize; i++ ) {
  2726. INTOF( lpMem16[ pus16->uYomiDelimPos ], i ) = 0;
  2727. WORDOF16( lpMem16[ pus16->uYomiDelimPos ], i ) = (WORD)
  2728. INTOF( lpMem32[ pus32->uYomiDelimPos ], i );
  2729. if ( INTOF( lpMem32[ pus32->uYomiDelimPos ], i ) >= cb )
  2730. break;
  2731. }
  2732. }
  2733. FLUSHVDMPTR(vp, cb, lpMem16);
  2734. FREEVDMPTR(lpMem16);
  2735. LOW( lpwm32mpex->Parm16.WndProc.lParam ) = hMem16;
  2736. HIW( lpwm32mpex->Parm16.WndProc.lParam ) = 0; // must be zero
  2737. GlobalUnlock( (HANDLE)lpwm32mpex->lParam );
  2738. GlobalUnlock16( hMem16 );
  2739. }
  2740. }
  2741. else { // fThunk
  2742. if (lpwm32mpex->Parm16.WndProc.lParam) {
  2743. GlobalUnlockFree16(GlobalLock16(LOW(lpwm32mpex->Parm16.WndProc.lParam), NULL));
  2744. }
  2745. }
  2746. return (TRUE);
  2747. Err:
  2748. if ( lpMem32 && lpwm32mpex->lParam )
  2749. GlobalUnlock( (HANDLE)lpwm32mpex->lParam );
  2750. return FALSE;
  2751. }
  2752. #endif // FE_IME