Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

3762 lines
118 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. LONGLONG 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(0I64);
  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(0I64);
  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. LONGLONG 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(0I64);
  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(0I64);
  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. HAND16 hdc16;
  809. BOOL bNotThere;
  810. if (lpwm32mpex->fThunk) {
  811. // Query to see if we've mapped hDC32 in uParam. If not, it means that
  812. // hDC32 was created outside this VDM process and we will have to
  813. // delete it from our table when un-thunking this message.
  814. lpwm32mpex->dwTmp[0] = 0;
  815. bNotThere = FALSE;
  816. if(!IsGDIh32Mapped((HANDLE)lpwm32mpex->uParam)) {
  817. bNotThere = TRUE;
  818. }
  819. // GETHDC16() may cause a new handle to be added to our handle table.
  820. hdc16 = GETHDC16(lpwm32mpex->uParam);
  821. // save the 32-bit & new 16-bit GDI handles for unthunking
  822. if(bNotThere) {
  823. lpwm32mpex->dwTmp[0] = (DWORD)hdc16;
  824. lpwm32mpex->dwTmp[1] = lpwm32mpex->uParam;
  825. }
  826. lpwm32mpex->Parm16.WndProc.wParam = hdc16;
  827. }
  828. else {
  829. // If this is !0, it means that the handle hadn't been mapped in our
  830. // table at the time of the IsGDIh32Mapped() call above.
  831. if(lpwm32mpex->dwTmp[0]) {
  832. // Remove the hdc that was added to our table by the GETHDC16 macro
  833. // in the inbound thunk of this message above.
  834. hdc16 = (HAND16)LOWORD(lpwm32mpex->dwTmp[0]);
  835. DeleteWOWGdiHandle((HANDLE)lpwm32mpex->dwTmp[1], hdc16);
  836. }
  837. }
  838. return (TRUE);
  839. }
  840. // This function thunks the message
  841. //
  842. // WM_CHANGEUISTATE
  843. // WM_UPDATEUISTATE
  844. // WM_QUERYUISTATE
  845. //
  846. BOOL FASTCALL WM32xxxUIState(LPWM32MSGPARAMEX lpwm32mpex)
  847. {
  848. // just copy the wParam into the lParam
  849. if (lpwm32mpex->fThunk) {
  850. lpwm32mpex->Parm16.WndProc.lParam = (LONG)lpwm32mpex->uParam;
  851. lpwm32mpex->Parm16.WndProc.wParam = 0;
  852. // this is here because there is talk that they might extend this
  853. // message to use lParam -- heck, they didn't even tell us that they
  854. // implemented this message in the first place!! (shame on shell!!)
  855. WOW32WARNMSG((lpwm32mpex->lParam == 0),
  856. ("WOW::WM32xxxUIState:lParam != 0. Better investigate!\n"));
  857. }
  858. // now just reverse the process
  859. else {
  860. lpwm32mpex->uParam = (UINT)lpwm32mpex->Parm16.WndProc.lParam;
  861. lpwm32mpex->lParam = 0;
  862. }
  863. return (TRUE);
  864. }
  865. // This function thunks the messages,
  866. //
  867. // WM_ACTIVATEAPP
  868. //
  869. BOOL FASTCALL WM32ActivateApp(LPWM32MSGPARAMEX lpwm32mpex)
  870. {
  871. extern void UpdateInt16State(void);
  872. if (lpwm32mpex->fThunk) {
  873. LOW(lpwm32mpex->Parm16.WndProc.lParam) =
  874. lpwm32mpex->lParam
  875. ? ThreadID32toHtask16((DWORD)lpwm32mpex->lParam)
  876. : 0;
  877. // We need to update wow int 16 bios when I wow app gets the focus.
  878. UpdateInt16State();
  879. }
  880. return (TRUE);
  881. }
  882. // This function thunks the messages,
  883. //
  884. // WM_GETMINMAXINFO
  885. //
  886. BOOL FASTCALL WM32GetMinMaxInfo(LPWM32MSGPARAMEX lpwm32mpex)
  887. {
  888. LPPOINT lParam = (LPPOINT) lpwm32mpex->lParam;
  889. if (lpwm32mpex->fThunk) {
  890. if (lParam) {
  891. // be sure allocation size matches stackfree16() size below
  892. lpwm32mpex->Parm16.WndProc.lParam = stackalloc16(sizeof(POINT16)*5);
  893. UnThunkWMGetMinMaxInfo16(lpwm32mpex->Parm16.WndProc.lParam, lParam);
  894. }
  895. }
  896. else {
  897. ThunkWMGetMinMaxInfo16(lpwm32mpex->Parm16.WndProc.lParam, &lParam);
  898. if(lpwm32mpex->Parm16.WndProc.lParam) {
  899. stackfree16((VPVOID) lpwm32mpex->Parm16.WndProc.lParam,
  900. sizeof(POINT16)*5);
  901. }
  902. }
  903. return(TRUE);
  904. }
  905. // This function thunks the messages,
  906. //
  907. // WM_NCPAINT
  908. // WM_PAINT
  909. //
  910. BOOL FASTCALL WM32NCPaint(LPWM32MSGPARAMEX lpwm32mpex)
  911. {
  912. HAND16 hrgn16;
  913. BOOL bNotThere;
  914. if (lpwm32mpex->fThunk) {
  915. lpwm32mpex->dwTmp[0] = 0;
  916. if(lpwm32mpex->uParam == 1) {
  917. lpwm32mpex->Parm16.WndProc.wParam = 1;
  918. }
  919. else if(lpwm32mpex->uMsg == WM_NCPAINT) {
  920. // Query to see if we've already mapped the hrgn32 in uParam. If
  921. // not, it means that hrgn32 was created outside this vdm and we'll
  922. // have to delete it from our table when un-thunking this message.
  923. bNotThere = FALSE;
  924. if(!IsGDIh32Mapped((HANDLE)lpwm32mpex->uParam)) {
  925. bNotThere = TRUE;
  926. }
  927. hrgn16 = GETHRGN16(lpwm32mpex->uParam);
  928. lpwm32mpex->Parm16.WndProc.wParam = hrgn16;
  929. // save the 32-bit & new 16-bit GDI handles for unthunking
  930. if(bNotThere) {
  931. lpwm32mpex->dwTmp[0] = (DWORD)hrgn16;
  932. lpwm32mpex->dwTmp[1] = lpwm32mpex->uParam;
  933. }
  934. }
  935. }
  936. else {
  937. // If this is !0, it means that the handle hadn't been mapped in our
  938. // table at the time of the IsGDIh32Mapped() call above.
  939. if(lpwm32mpex->dwTmp[0]) {
  940. // Remove the hrgn that was added to our table by the GETRGN16 macro
  941. // in the inbound thunk of this message above.
  942. hrgn16 = (HAND16)LOWORD(lpwm32mpex->dwTmp[0]);
  943. DeleteWOWGdiHandle((HANDLE)lpwm32mpex->dwTmp[1], hrgn16);
  944. }
  945. }
  946. return (TRUE);
  947. }
  948. // This function thunks the messages,
  949. //
  950. // WM_NCDESTROY
  951. //
  952. BOOL FASTCALL WM32NCDestroy(LPWM32MSGPARAMEX lpwm32mpex)
  953. {
  954. // destroy any timers associated with this window
  955. if (!lpwm32mpex->fThunk) {
  956. FreeWindowTimers16(lpwm32mpex->hwnd);
  957. }
  958. return (TRUE);
  959. }
  960. // This function thunks the messages,
  961. //
  962. // WM_GETDLGCODE
  963. //
  964. BOOL FASTCALL WM32GetDlgCode(LPWM32MSGPARAMEX lpwm32mpex)
  965. {
  966. if (lpwm32mpex->fThunk) {
  967. if (lpwm32mpex->lParam) {
  968. // BUGBUG -- The assumption here is that GlobalAlloc will never
  969. // return a memory object that isn't word-aligned, so that we can
  970. // assign word-aligned words directly; we have no idea whether the
  971. // memory is dword-aligned or not however, so dwords must always
  972. // be paranoidly stored with the STOREDWORD/STORELONG macros -JTP
  973. if (!(lpwm32mpex->Parm16.WndProc.lParam = malloc16(sizeof(MSG16))))
  974. return FALSE;
  975. putmsg16(lpwm32mpex->Parm16.WndProc.lParam, (LPMSG)lpwm32mpex->lParam);
  976. return TRUE;
  977. }
  978. }
  979. else {
  980. // Message structure doesn't need to be copied back does it? -Bob
  981. if (lpwm32mpex->Parm16.WndProc.lParam) {
  982. free16((VPVOID) lpwm32mpex->Parm16.WndProc.lParam);
  983. }
  984. }
  985. return (TRUE);
  986. }
  987. // This function thunks the messages,
  988. //
  989. // WM_NEXTDLGCTL
  990. //
  991. BOOL FASTCALL WM32NextDlgCtl(LPWM32MSGPARAMEX lpwm32mpex)
  992. {
  993. if (lpwm32mpex->fThunk) {
  994. if (lpwm32mpex->lParam) {
  995. lpwm32mpex->Parm16.WndProc.wParam = GETHWND16(lpwm32mpex->uParam);
  996. }
  997. }
  998. return (TRUE);
  999. }
  1000. // This function thunks the messages,
  1001. //
  1002. // WM_DRAWITEM
  1003. //
  1004. BOOL FASTCALL WM32DrawItem(LPWM32MSGPARAMEX lpwm32mpex)
  1005. {
  1006. HAND16 hdc16;
  1007. BOOL bNotThere;
  1008. LPDRAWITEMSTRUCT lParam = (LPDRAWITEMSTRUCT) lpwm32mpex->lParam;
  1009. if (lpwm32mpex->fThunk) {
  1010. lpwm32mpex->dwTmp[0] = 0;
  1011. if (lParam) {
  1012. // be sure allocation size matches stackfree16() size below
  1013. lpwm32mpex->Parm16.WndProc.lParam = stackalloc16(sizeof(DRAWITEMSTRUCT16));
  1014. // Query to see if we've already mapped the DRAWITEM->hDC. If not,
  1015. // it means that the hDC was created outside the app and we will
  1016. // have to delete it from our table when un-thunking this message.
  1017. bNotThere = FALSE;
  1018. if(!IsGDIh32Mapped(((LPDRAWITEMSTRUCT)lParam)->hDC)) {
  1019. bNotThere = TRUE;
  1020. }
  1021. // The call to putdrawitem16() may add a GDI handle mapping entry
  1022. // for the hDC in our mapping table (via the GETHDC16 macro)
  1023. hdc16 = putdrawitem16(lpwm32mpex->Parm16.WndProc.lParam, lParam);
  1024. // save the 32-bit & new 16-bit GDI handles for unthunking
  1025. if(bNotThere) {
  1026. lpwm32mpex->dwTmp[0] = (DWORD)hdc16;
  1027. lpwm32mpex->dwTmp[1] = (DWORD)((LPDRAWITEMSTRUCT)lParam)->hDC;
  1028. }
  1029. }
  1030. }
  1031. else {
  1032. // BUGBUG 08-Apr-91 JeffPar -- Reflect changes back to 32-bit structure?
  1033. if (lpwm32mpex->Parm16.WndProc.lParam) {
  1034. stackfree16((VPVOID) lpwm32mpex->Parm16.WndProc.lParam,
  1035. sizeof(DRAWITEMSTRUCT16));
  1036. // If this is !0, it means that the handle hadn't been mapped in our
  1037. // table at the time of the IsGDIh32Mapped() call above.
  1038. if(lpwm32mpex->dwTmp[0]) {
  1039. hdc16 = (HAND16)LOWORD(lpwm32mpex->dwTmp[0]);
  1040. DeleteWOWGdiHandle((HANDLE)lpwm32mpex->dwTmp[1], hdc16);
  1041. }
  1042. }
  1043. }
  1044. return(TRUE);
  1045. }
  1046. // This function thunks the messages,
  1047. //
  1048. // WM_MEASUREITEM
  1049. //
  1050. BOOL FASTCALL WM32MeasureItem(LPWM32MSGPARAMEX lpwm32mpex)
  1051. {
  1052. PMEASUREITEMSTRUCT16 pmis16;
  1053. LPMEASUREITEMSTRUCT lParam = (LPMEASUREITEMSTRUCT) lpwm32mpex->lParam;
  1054. BOOL fHasStrings;
  1055. DWORD cSize;
  1056. //
  1057. // Compatibility hack
  1058. //
  1059. // CrossTalk 2.0 has a bug where it fails to distinguish between
  1060. // WM_MEASUREITEM and WM_INITDIALOG when doing file.open
  1061. // on WM_MEASUREITEM it calls CallWindowProc() to send what it
  1062. // thinks is lpOpenFileName->lpCust but is really random stack.
  1063. // currently the high word of this random pointer is an hInstance
  1064. // and gets through the validation layer, whereas on Win31 it doesn't.
  1065. // if this WM_MEASUREITEM gets to the app's proc then the app will
  1066. // initialize incorrectly and take a GP. i have increased the stack
  1067. // allocation by XTALKHACK to ensure that the random data does is not
  1068. // a valid pointer.
  1069. //
  1070. #define XTALKHACK (sizeof(OPENFILENAME16)-sizeof(MEASUREITEMSTRUCT16))
  1071. if (lpwm32mpex->fThunk) {
  1072. if (lParam) {
  1073. fHasStrings = FALSE;
  1074. if ( lParam->CtlType == ODT_COMBOBOX || lParam->CtlType == ODT_LISTBOX ) {
  1075. if (lParam->itemWidth == MIFLAG_FLAT) {
  1076. fHasStrings = TRUE;
  1077. }
  1078. }
  1079. cSize = sizeof(MEASUREITEMSTRUCT16);
  1080. if ( fHasStrings ) {
  1081. cSize += strlen((LPSTR)lParam->itemData) + 1;
  1082. }
  1083. if ( cSize < XTALKHACK+sizeof(MEASUREITEMSTRUCT16) ) {
  1084. cSize = XTALKHACK+sizeof(MEASUREITEMSTRUCT16);
  1085. }
  1086. // be sure allocation size matches stackfree16() size below
  1087. lpwm32mpex->dwTmp[0] = cSize;
  1088. if ( !(lpwm32mpex->Parm16.WndProc.lParam = stackalloc16(cSize)) )
  1089. return FALSE;
  1090. GETVDMPTR(lpwm32mpex->Parm16.WndProc.lParam, cSize, pmis16);
  1091. pmis16->CtlType = (WORD)lParam->CtlType;
  1092. pmis16->CtlID = (WORD)lParam->CtlID;
  1093. pmis16->itemID = (WORD)lParam->itemID;
  1094. pmis16->itemWidth = (WORD)lParam->itemWidth;
  1095. pmis16->itemHeight = (WORD)lParam->itemHeight;
  1096. #ifdef XTALKHACK
  1097. ((POPENFILENAME16)pmis16)->lCustData = 7; // invalid far pointer
  1098. #endif
  1099. if ( fHasStrings ) {
  1100. pmis16->itemData = lpwm32mpex->Parm16.WndProc.lParam+sizeof(MEASUREITEMSTRUCT16);
  1101. strcpy( (LPSTR)(pmis16+1), (LPSTR)lParam->itemData );
  1102. } else {
  1103. STOREDWORD(pmis16->itemData, lParam->itemData);
  1104. }
  1105. WOW32ASSERT(HIWORD(cSize) == 0);
  1106. FLUSHVDMPTR(lpwm32mpex->Parm16.WndProc.lParam, (USHORT) cSize, pmis16);
  1107. FREEVDMPTR(pmis16);
  1108. }
  1109. }
  1110. else {
  1111. if (lpwm32mpex->Parm16.WndProc.lParam) {
  1112. GETVDMPTR(lpwm32mpex->Parm16.WndProc.lParam, sizeof(MEASUREITEMSTRUCT16), pmis16);
  1113. lParam->CtlType = WORD32(pmis16->CtlType);
  1114. lParam->CtlID = WORD32(pmis16->CtlID);
  1115. lParam->itemID = WORD32(pmis16->itemID);
  1116. // itemWidth must sign extend (PPT3 bug & Win3.1 treats it as signed!)
  1117. lParam->itemWidth = INT32(pmis16->itemWidth);
  1118. lParam->itemHeight = WORD32(pmis16->itemHeight);
  1119. lParam->itemData = pmis16->itemData;
  1120. FREEVDMPTR(pmis16);
  1121. stackfree16((VPVOID) lpwm32mpex->Parm16.WndProc.lParam,
  1122. ((UINT)lpwm32mpex->dwTmp[0]));
  1123. }
  1124. }
  1125. return(TRUE);
  1126. }
  1127. // This function thunks the messages,
  1128. //
  1129. // WM_DELETEITEM
  1130. //
  1131. BOOL FASTCALL WM32DeleteItem(LPWM32MSGPARAMEX lpwm32mpex)
  1132. {
  1133. register PDELETEITEMSTRUCT16 pdes16;
  1134. LPDELETEITEMSTRUCT lParam = (LPDELETEITEMSTRUCT) lpwm32mpex->lParam;
  1135. if (lpwm32mpex->fThunk) {
  1136. if (lParam) {
  1137. // BUGBUG -- The assumption here is that GlobalAlloc will never
  1138. // return a memory object that isn't word-aligned, so that we can
  1139. // assign word-aligned words directly; we have no idea whether the
  1140. // memory is dword-aligned or not however, so dwords must always
  1141. // be paranoidly stored with the STOREDWORD/STORELONG macros -JTP
  1142. // be sure allocation size matches stackfree16() size below
  1143. lpwm32mpex->Parm16.WndProc.lParam = stackalloc16(sizeof(DELETEITEMSTRUCT16));
  1144. GETVDMPTR(lpwm32mpex->Parm16.WndProc.lParam, sizeof(DELETEITEMSTRUCT16), pdes16);
  1145. pdes16->CtlType = (WORD)lParam->CtlType;
  1146. pdes16->CtlID = (WORD)lParam->CtlID;
  1147. pdes16->itemID = (WORD)lParam->itemID;
  1148. pdes16->hwndItem = GETHWND16(lParam->hwndItem);
  1149. STOREDWORD(pdes16->itemData, lParam->itemData);
  1150. FLUSHVDMPTR(lpwm32mpex->Parm16.WndProc.lParam, sizeof(DELETEITEMSTRUCT16), pdes16);
  1151. FREEVDMPTR(pdes16);
  1152. }
  1153. }
  1154. else {
  1155. if (lpwm32mpex->Parm16.WndProc.lParam)
  1156. stackfree16((VPVOID) lpwm32mpex->Parm16.WndProc.lParam,
  1157. sizeof(DELETEITEMSTRUCT16));
  1158. }
  1159. return(TRUE);
  1160. }
  1161. // This function thunks the messages,
  1162. //
  1163. // WM_SETFONT
  1164. //
  1165. BOOL FASTCALL WM32SetFont(LPWM32MSGPARAMEX lpwm32mpex)
  1166. {
  1167. HAND16 hfont16;
  1168. BOOL bNotThere;
  1169. if (lpwm32mpex->fThunk) {
  1170. lpwm32mpex->dwTmp[0] = 0;
  1171. bNotThere = FALSE;
  1172. // Query to see if we've mapped the hfont. If not, it means that the
  1173. // hFont was created outside this VDM process and we will have to delete
  1174. // it from our table when un-thunking this message.
  1175. if(!IsGDIh32Mapped((HANDLE)lpwm32mpex->uParam)) {
  1176. bNotThere = TRUE;
  1177. }
  1178. hfont16 = GETHFONT16(lpwm32mpex->uParam);
  1179. lpwm32mpex->Parm16.WndProc.wParam = hfont16;
  1180. // save the 32-bit & new 16-bit GDI handles for unthunking
  1181. if(bNotThere) {
  1182. lpwm32mpex->dwTmp[0] = (DWORD)hfont16;
  1183. lpwm32mpex->dwTmp[1] = (DWORD)lpwm32mpex->uParam;
  1184. }
  1185. }
  1186. else {
  1187. // If this is !0, it means that the handle hadn't been mapped in our
  1188. // table at the time of the IsGDIh32Mapped() call above.
  1189. if(lpwm32mpex->dwTmp[0]) {
  1190. hfont16 = (HAND16)LOWORD(lpwm32mpex->dwTmp[0]);
  1191. DeleteWOWGdiHandle((HANDLE)lpwm32mpex->dwTmp[1], hfont16);
  1192. }
  1193. }
  1194. return (TRUE);
  1195. }
  1196. // This function thunks the messages,
  1197. //
  1198. // WM_QUERYDRAGICON
  1199. BOOL FASTCALL WM32QueryDragIcon(LPWM32MSGPARAMEX lpwm32mpex)
  1200. {
  1201. if (!lpwm32mpex->fThunk) {
  1202. lpwm32mpex->lReturn = (LONG)HICON32(lpwm32mpex->lReturn);
  1203. }
  1204. return (TRUE);
  1205. }
  1206. // This function thunks the messages,
  1207. //
  1208. // WM_COMPAREITEM
  1209. //
  1210. BOOL FASTCALL WM32CompareItem(LPWM32MSGPARAMEX lpwm32mpex)
  1211. {
  1212. LPCOMPAREITEMSTRUCT lParam = (LPCOMPAREITEMSTRUCT) lpwm32mpex->lParam;
  1213. if (lpwm32mpex->fThunk) {
  1214. if (lParam) {
  1215. // BUGBUG -- The assumption here is that GlobalAlloc will never
  1216. // return a memory object that isn't word-aligned, so that we can
  1217. // assign word-aligned words directly; we have no idea whether the
  1218. // memory is dword-aligned or not however, so dwords must always
  1219. // be paranoidly stored with the STOREDWORD/STORELONG macros -JTP
  1220. // be sure allocation size matches stackfree16() size below
  1221. lpwm32mpex->Parm16.WndProc.lParam = stackalloc16(sizeof(COMPAREITEMSTRUCT16));
  1222. putcompareitem16(lpwm32mpex->Parm16.WndProc.lParam, lParam);
  1223. }
  1224. }
  1225. else {
  1226. // BUGBUG 08-Apr-91 JeffPar -- Reflect changes back to 32-bit structure?
  1227. if (lpwm32mpex->Parm16.WndProc.lParam)
  1228. stackfree16((VPVOID) lpwm32mpex->Parm16.WndProc.lParam,
  1229. sizeof(COMPAREITEMSTRUCT16));
  1230. }
  1231. return (TRUE);
  1232. }
  1233. // This function thunks the messages,
  1234. //
  1235. // WM_SIZING
  1236. //
  1237. BOOL FASTCALL WM32Sizing(LPWM32MSGPARAMEX lpwm32mpex)
  1238. {
  1239. VPRECT16 vpRect16;
  1240. if (lpwm32mpex->fThunk) {
  1241. if (lpwm32mpex->lParam) {
  1242. // be sure allocation size matches stackfree16() size below
  1243. vpRect16 = (VPVOID)stackalloc16(sizeof(RECT16));
  1244. if(vpRect16) {
  1245. putrect16(vpRect16, (LPRECT)lpwm32mpex->lParam);
  1246. lpwm32mpex->Parm16.WndProc.lParam = (LONG)vpRect16;
  1247. }
  1248. }
  1249. }
  1250. else {
  1251. if (lpwm32mpex->lParam) {
  1252. vpRect16 = (VPVOID)lpwm32mpex->Parm16.WndProc.lParam;
  1253. if(vpRect16) {
  1254. getrect16(vpRect16, (LPRECT)lpwm32mpex->lParam);
  1255. stackfree16(vpRect16, sizeof(RECT16));
  1256. }
  1257. }
  1258. }
  1259. return (TRUE);
  1260. }
  1261. // This function thunks the messages,
  1262. //
  1263. // WM_NCCALCSIZE
  1264. //
  1265. BOOL FASTCALL WM32NCCalcSize(LPWM32MSGPARAMEX lpwm32mpex)
  1266. {
  1267. PNCCALCSIZE_PARAMS16 pnc16;
  1268. PNCCALCSIZE_PARAMS16 lpnc16;
  1269. VPWINDOWPOS16 vpwp16;
  1270. LPNCCALCSIZE_PARAMS lParam = (LPNCCALCSIZE_PARAMS)lpwm32mpex->lParam;
  1271. UINT cb;
  1272. VPVOID vp;
  1273. // lpwm32mpex->uParam == TRUE ? (lParam is LPNCCALCSIZE_PARAMS) : (lParam is LPRECT);
  1274. //
  1275. if (lpwm32mpex->fThunk) {
  1276. if (lParam) {
  1277. if (lpwm32mpex->uParam)
  1278. cb = sizeof(NCCALCSIZE_PARAMS16) + sizeof(WINDOWPOS16);
  1279. else
  1280. cb = sizeof(RECT16);
  1281. // be sure allocation size matches stackfree16() size below
  1282. lpwm32mpex->dwTmp[0] = cb;
  1283. vp = (VPVOID)stackalloc16(cb);
  1284. lpwm32mpex->Parm16.WndProc.lParam = (LONG)vp;
  1285. putrect16((VPRECT16)vp, (LPRECT)lParam);
  1286. if (lpwm32mpex->uParam) {
  1287. pnc16 = (PNCCALCSIZE_PARAMS16)vp;
  1288. putrect16((VPRECT16)(&pnc16->rgrc[1]), &lParam->rgrc[1]);
  1289. putrect16((VPRECT16)(&pnc16->rgrc[2]), &lParam->rgrc[2]);
  1290. GETVDMPTR( pnc16, sizeof(NCCALCSIZE_PARAMS16), lpnc16 );
  1291. vpwp16 = (VPWINDOWPOS16)(pnc16+1);
  1292. lpnc16->lppos = (PWINDOWPOS16)vpwp16;
  1293. FREEVDMPTR( lpnc16 );
  1294. putwindowpos16( vpwp16, lParam->lppos );
  1295. }
  1296. }
  1297. }
  1298. else {
  1299. vp = (VPVOID)lpwm32mpex->Parm16.WndProc.lParam;
  1300. getrect16((VPRECT16)vp, (LPRECT)lParam);
  1301. if (lpwm32mpex->uParam) {
  1302. pnc16 = (PNCCALCSIZE_PARAMS16)vp;
  1303. getrect16((VPRECT16)(&pnc16->rgrc[1]), &lParam->rgrc[1]);
  1304. getrect16((VPRECT16)(&pnc16->rgrc[2]), &lParam->rgrc[2]);
  1305. GETVDMPTR( pnc16, sizeof(NCCALCSIZE_PARAMS16), lpnc16 );
  1306. vpwp16 = (VPWINDOWPOS16)lpnc16->lppos;
  1307. FREEVDMPTR( lpnc16 );
  1308. getwindowpos16( vpwp16, lParam->lppos );
  1309. }
  1310. if(vp) {
  1311. stackfree16(vp, ((UINT)lpwm32mpex->dwTmp[0]));
  1312. }
  1313. }
  1314. return (TRUE);
  1315. }
  1316. // This function thunks the messages,
  1317. //
  1318. // WM_COMMAND
  1319. //
  1320. BOOL FASTCALL WM32Command(LPWM32MSGPARAMEX lpwm32mpex)
  1321. {
  1322. if (lpwm32mpex->fThunk) {
  1323. // it's from a control
  1324. HIW(lpwm32mpex->Parm16.WndProc.lParam) = HIWORD(lpwm32mpex->uParam);
  1325. LOW(lpwm32mpex->Parm16.WndProc.lParam) = GETHWND16(lpwm32mpex->lParam);
  1326. }
  1327. return (TRUE);
  1328. }
  1329. // This function thunks the messages,
  1330. //
  1331. // WM_TIMER
  1332. //
  1333. BOOL FASTCALL WM32Timer(LPWM32MSGPARAMEX lpwm32mpex)
  1334. {
  1335. if (lpwm32mpex->fThunk) {
  1336. /*
  1337. ** map the timer number and the timer proc address (cause its easy)
  1338. */
  1339. PTMR ptmr;
  1340. ptmr = FindTimer32((HAND16)GETHWND16(lpwm32mpex->hwnd), lpwm32mpex->uParam);
  1341. if ( !ptmr ) {
  1342. /*
  1343. ** Edit controls create their own timer, which can safely be
  1344. ** thunked to itself.
  1345. */
  1346. if ( lpwm32mpex->lParam || HIWORD(lpwm32mpex->uParam) ) {
  1347. LOGDEBUG(LOG_WARNING,(" WM32Timer ERROR: cannot find timer %08x\n", lpwm32mpex->uParam));
  1348. }
  1349. return TRUE;
  1350. }
  1351. lpwm32mpex->Parm16.WndProc.lParam = ptmr->vpfnTimerProc;
  1352. }
  1353. return (TRUE);
  1354. }
  1355. // This function thunks the messages,
  1356. //
  1357. // WM_HSCROLL
  1358. // WM_VSCROLL
  1359. //
  1360. BOOL FASTCALL WM32HScroll(LPWM32MSGPARAMEX lpwm32mpex)
  1361. {
  1362. if (lpwm32mpex->fThunk) {
  1363. LOW(lpwm32mpex->Parm16.WndProc.lParam) = HIWORD(lpwm32mpex->uParam);
  1364. HIW(lpwm32mpex->Parm16.WndProc.lParam) = GETHWND16(lpwm32mpex->lParam);
  1365. }
  1366. return (TRUE);
  1367. }
  1368. // This function thunks the messages,
  1369. //
  1370. // WM_INITMENU
  1371. // WM_INITMENUPOPUP
  1372. //
  1373. BOOL FASTCALL WM32InitMenu(LPWM32MSGPARAMEX lpwm32mpex)
  1374. {
  1375. if (lpwm32mpex->fThunk) {
  1376. lpwm32mpex->Parm16.WndProc.wParam = GETHMENU16(lpwm32mpex->uParam);
  1377. }
  1378. return (TRUE);
  1379. }
  1380. // This function thunks the messages,
  1381. //
  1382. // WM_MENUSELECT
  1383. //
  1384. BOOL FASTCALL WM32MenuSelect(LPWM32MSGPARAMEX lpwm32mpex)
  1385. {
  1386. if (lpwm32mpex->fThunk) {
  1387. // Copy the menu flags
  1388. LOW(lpwm32mpex->Parm16.WndProc.lParam) = HIWORD(lpwm32mpex->uParam);
  1389. // Copy the "main" menu
  1390. HIW(lpwm32mpex->Parm16.WndProc.lParam) = GETHMENU16(lpwm32mpex->lParam);
  1391. if (HIWORD(lpwm32mpex->uParam) == 0xFFFF || !(HIWORD(lpwm32mpex->uParam) & MF_POPUP)) {
  1392. lpwm32mpex->Parm16.WndProc.wParam = LOWORD(lpwm32mpex->uParam); // Its an ID
  1393. }
  1394. else {
  1395. // convert menu index into menu handle
  1396. lpwm32mpex->Parm16.WndProc.wParam = GETHMENU16(GetSubMenu((HMENU)lpwm32mpex->lParam, LOWORD(lpwm32mpex->uParam)));
  1397. }
  1398. }
  1399. return (TRUE);
  1400. }
  1401. // This function thunks the messages,
  1402. //
  1403. // WM_MENUCHAR
  1404. //
  1405. BOOL FASTCALL WM32MenuChar(LPWM32MSGPARAMEX lpwm32mpex)
  1406. {
  1407. if (lpwm32mpex->fThunk) {
  1408. LOW(lpwm32mpex->Parm16.WndProc.lParam) = HIWORD(lpwm32mpex->uParam);
  1409. HIW(lpwm32mpex->Parm16.WndProc.lParam) = GETHMENU16(lpwm32mpex->lParam);
  1410. }
  1411. return (TRUE);
  1412. }
  1413. // This function thunks the messages,
  1414. //
  1415. // WM_ENTERIDLE
  1416. //
  1417. BOOL FASTCALL WM32EnterIdle(LPWM32MSGPARAMEX lpwm32mpex)
  1418. {
  1419. if (lpwm32mpex->fThunk) {
  1420. if ((lpwm32mpex->uParam == MSGF_DIALOGBOX) || (lpwm32mpex->uParam == MSGF_MENU)) {
  1421. LOW(lpwm32mpex->Parm16.WndProc.lParam) = GETHWND16(lpwm32mpex->lParam);
  1422. HIW(lpwm32mpex->Parm16.WndProc.lParam) = 0;
  1423. }
  1424. else {
  1425. LOGDEBUG(LOG_ALWAYS,(" WOW::WM_ENTERIDLE: wParam has unknown value, wParam=%08x, Contact ChandanC\n", lpwm32mpex->uParam));
  1426. }
  1427. }
  1428. return (TRUE);
  1429. }
  1430. // This function thunks the messages,
  1431. //
  1432. // WM_PARENTNOTIFY
  1433. //
  1434. BOOL FASTCALL WM32ParentNotify(LPWM32MSGPARAMEX lpwm32mpex)
  1435. {
  1436. if (lpwm32mpex->fThunk) {
  1437. if ((LOWORD(lpwm32mpex->uParam) == WM_CREATE) || (LOWORD(lpwm32mpex->uParam) == WM_DESTROY)) {
  1438. HIW(lpwm32mpex->Parm16.WndProc.lParam) = HIWORD(lpwm32mpex->uParam);
  1439. LOW(lpwm32mpex->Parm16.WndProc.lParam) = GETHWND16(lpwm32mpex->lParam);
  1440. }
  1441. }
  1442. return (TRUE);
  1443. }
  1444. // This function thunks the messages,
  1445. //
  1446. // WM_MDICreate
  1447. //
  1448. BOOL FASTCALL WM32MDICreate(LPWM32MSGPARAMEX lpwm32mpex)
  1449. {
  1450. INT cb;
  1451. VPVOID vp;
  1452. register PMDICREATESTRUCT16 pmcs16;
  1453. LPMDICREATESTRUCT lParam = (LPMDICREATESTRUCT) lpwm32mpex->lParam;
  1454. if (lpwm32mpex->fThunk) {
  1455. if (lParam) {
  1456. lpwm32mpex->dwParam = (DWORD)0;
  1457. if (lParam->szClass) {
  1458. if ( HIWORD(lParam->szClass) == 0 ) {
  1459. vp = (VPVOID)lParam->szClass;
  1460. }
  1461. else {
  1462. cb = strlen(lParam->szClass)+1;
  1463. if (!(vp = malloc16(cb)))
  1464. goto Error;
  1465. putstr16(vp, lParam->szClass, cb);
  1466. }
  1467. }
  1468. else {
  1469. vp = (VPVOID)NULL;
  1470. }
  1471. //
  1472. // pfs:windowsworks overwrite pszclass, so we need to save the
  1473. // so that we can free the memory we just alloced
  1474. //
  1475. lpwm32mpex->dwParam = (DWORD)vp;
  1476. if (lParam->szTitle) {
  1477. cb = strlen(lParam->szTitle)+1;
  1478. if (!(vp = malloc16(cb)))
  1479. goto Error;
  1480. putstr16(vp, lParam->szTitle, cb);
  1481. }
  1482. else {
  1483. vp = (VPVOID)NULL;
  1484. }
  1485. // BUGBUG -- The assumption here is that GlobalAlloc will never
  1486. // return a memory object that isn't word-aligned, so that we can
  1487. // assign word-aligned words directly; we have no idea whether the
  1488. // memory is dword-aligned or not however, so dwords must always
  1489. // be paranoidly stored with the STOREDWORD/STORELONG macros -JTP
  1490. if (!(lpwm32mpex->Parm16.WndProc.lParam = malloc16(sizeof(MDICREATESTRUCT16))))
  1491. goto Error;
  1492. GETVDMPTR(lpwm32mpex->Parm16.WndProc.lParam, sizeof(MDICREATESTRUCT16), pmcs16);
  1493. STOREDWORD(pmcs16->vpszClass, lpwm32mpex->dwParam);
  1494. STOREDWORD(pmcs16->vpszTitle, vp);
  1495. pmcs16->hOwner = GETHINST16(lParam->hOwner);
  1496. pmcs16->x = (SHORT)lParam->x;
  1497. pmcs16->y = (SHORT)lParam->y;
  1498. pmcs16->cx = (SHORT)lParam->cx;
  1499. pmcs16->cy = (SHORT)lParam->cy;
  1500. STORELONG(pmcs16->style, lParam->style);
  1501. STORELONG(pmcs16->lParam, lParam->lParam);
  1502. FLUSHVDMPTR(lpwm32mpex->Parm16.WndProc.lParam, sizeof(MDICREATESTRUCT16), pmcs16);
  1503. FREEVDMPTR(pmcs16);
  1504. return (TRUE);
  1505. Error:
  1506. LOGDEBUG(LOG_ALWAYS,(" !!!! WM32MDICreate, WM_MDICREATE thunking failed !!!! Window %08lX ", lpwm32mpex->hwnd));
  1507. if (HIW16(lpwm32mpex->dwParam)) free16(lpwm32mpex->dwParam);
  1508. if (vp) free16(vp);
  1509. return FALSE;
  1510. }
  1511. }
  1512. else {
  1513. if (lpwm32mpex->Parm16.WndProc.lParam) {
  1514. GETVDMPTR(lpwm32mpex->Parm16.WndProc.lParam, sizeof(MDICREATESTRUCT16), pmcs16);
  1515. if (FETCHDWORD(pmcs16->vpszTitle)) {
  1516. free16(FETCHDWORD(pmcs16->vpszTitle));
  1517. }
  1518. FREEVDMPTR(pmcs16);
  1519. // if HIWORD(class) is zero, class is an atom, else a pointer.
  1520. if (HIW16(lpwm32mpex->dwParam)) {
  1521. free16(lpwm32mpex->dwParam);
  1522. }
  1523. lpwm32mpex->lReturn = (LONG)HWND32(LOWORD(lpwm32mpex->lReturn));
  1524. free16((VPVOID) lpwm32mpex->Parm16.WndProc.lParam);
  1525. }
  1526. }
  1527. return (TRUE);
  1528. }
  1529. // This function thunks the messages,
  1530. //
  1531. // WM_MDIActivate
  1532. //
  1533. BOOL FASTCALL WM32MDIActivate(LPWM32MSGPARAMEX lpwm32mpex)
  1534. {
  1535. BOOL fHwndIsMdiChild;
  1536. if (lpwm32mpex->fThunk) {
  1537. // the format of the message is different based on the window that's
  1538. // receiving the message. If 'hwnd' is a MdiClient window it is of one
  1539. // form and if 'hwnd' is MdiChild it is of another form. We need to
  1540. // distinguish between the formats to correctly thunk the message.
  1541. //
  1542. // NOTE: we donot make calls like GetClassName because they are
  1543. // expensive and also I think we came across a case where a
  1544. // window of 'wow private class' processes these messages
  1545. //
  1546. // - Nanduri
  1547. if (lpwm32mpex->lParam) {
  1548. // lParam != NULL. The message is definitely going to a MdiChild.
  1549. //
  1550. fHwndIsMdiChild = TRUE;
  1551. }
  1552. else {
  1553. // lParam == NULL, doesnot necessarily mean that the message is
  1554. // going to a MdiClient window. So distinguish...
  1555. if (lpwm32mpex->uParam && (GETHWND16(lpwm32mpex->hwnd) ==
  1556. GETHWND16(lpwm32mpex->uParam))) {
  1557. // if hwnd is same as uParam then definitely hwnd is a MdiChild
  1558. // window. (because if hwnd is a MdiClient then uParam will be
  1559. // a MdiChild and thus they will not be equal)
  1560. fHwndIsMdiChild = TRUE;
  1561. }
  1562. else {
  1563. fHwndIsMdiChild = FALSE;
  1564. }
  1565. }
  1566. if (fHwndIsMdiChild) {
  1567. lpwm32mpex->Parm16.WndProc.wParam =
  1568. (WORD)(GETHWND16(lpwm32mpex->hwnd) == GETHWND16(lpwm32mpex->lParam));
  1569. LOW(lpwm32mpex->Parm16.WndProc.lParam) = GETHWND16(lpwm32mpex->lParam);
  1570. HIW(lpwm32mpex->Parm16.WndProc.lParam) = GETHWND16(lpwm32mpex->uParam);
  1571. } else {
  1572. lpwm32mpex->Parm16.WndProc.wParam = GETHWND16(lpwm32mpex->uParam);
  1573. lpwm32mpex->Parm16.WndProc.lParam = 0;
  1574. }
  1575. }
  1576. return (TRUE);
  1577. }
  1578. // This function thunks the messages,
  1579. //
  1580. // WM_MDIGETACTIVE
  1581. //
  1582. BOOL FASTCALL WM32MDIGetActive(LPWM32MSGPARAMEX lpwm32mpex)
  1583. {
  1584. if (lpwm32mpex->fThunk) {
  1585. lpwm32mpex->Parm16.WndProc.lParam = 0;
  1586. }
  1587. else {
  1588. if (lpwm32mpex->lParam != 0)
  1589. *((LPBOOL)lpwm32mpex->lParam) = (BOOL)HIWORD(lpwm32mpex->lReturn);
  1590. lpwm32mpex->lReturn = (LONG)HWND32(LOWORD(lpwm32mpex->lReturn));
  1591. }
  1592. return (TRUE);
  1593. }
  1594. // This function thunks the messages,
  1595. //
  1596. // WM_MDISETMENU
  1597. //
  1598. BOOL FASTCALL WM32MDISetMenu(LPWM32MSGPARAMEX lpwm32mpex)
  1599. {
  1600. if (lpwm32mpex->fThunk) {
  1601. if (lpwm32mpex->uMsg == WM_MDIREFRESHMENU) {
  1602. lpwm32mpex->Parm16.WndProc.wParam = TRUE;
  1603. lpwm32mpex->Parm16.WndProc.wMsg = WM_MDISETMENU;
  1604. }
  1605. else {
  1606. lpwm32mpex->Parm16.WndProc.wParam = 0;
  1607. }
  1608. LOW(lpwm32mpex->Parm16.WndProc.lParam) = GETHMENU16(lpwm32mpex->uParam);
  1609. HIW(lpwm32mpex->Parm16.WndProc.lParam) = GETHMENU16(lpwm32mpex->lParam);
  1610. }
  1611. else {
  1612. lpwm32mpex->lReturn = (LONG)HMENU32(lpwm32mpex->lReturn);
  1613. }
  1614. return (TRUE);
  1615. }
  1616. // This function thunks the messages,
  1617. //
  1618. // WM_SIZECLIPBOARD
  1619. // WM_PAINTCLIPBOARD
  1620. //
  1621. BOOL FASTCALL WM32SizeClipBoard(LPWM32MSGPARAMEX lpwm32mpex)
  1622. {
  1623. HAND16 hMem16 = 0;
  1624. VPVOID vp;
  1625. LPRECT lp;
  1626. HAND16 hdc16;
  1627. BOOL bNotThere;
  1628. if (lpwm32mpex->fThunk) {
  1629. lpwm32mpex->dwTmp[0] = 0;
  1630. lpwm32mpex->Parm16.WndProc.wParam = GETHWND16(lpwm32mpex->uParam);
  1631. vp = GlobalAllocLock16(GMEM_MOVEABLE, (lpwm32mpex->uMsg == WM_SIZECLIPBOARD) ?
  1632. sizeof(RECT) : sizeof(PAINTSTRUCT), &hMem16);
  1633. if (vp) {
  1634. if (lp = (LPRECT) GlobalLock((HANDLE) lpwm32mpex->lParam)) {
  1635. if (lpwm32mpex->uMsg == WM_SIZECLIPBOARD) {
  1636. PUTRECT16(vp, lp);
  1637. }
  1638. // else handle WM_PAINTCLIPBOARD message
  1639. else {
  1640. bNotThere = FALSE;
  1641. // Query to see if we've mapped the PAINTSTRUCT->hDC. If
  1642. // not, it means that the hDC was created outside this VDM
  1643. // process and we will have to delete it from our table when
  1644. // un-thunking this message.
  1645. if(!IsGDIh32Mapped(((LPPAINTSTRUCT)lp)->hdc)) {
  1646. bNotThere = TRUE;
  1647. }
  1648. // The call to putpaintstruct16() may add a GDI handle
  1649. // mapping entry for the hDC in our mapping table (via the
  1650. // GETHDC16 macro)
  1651. hdc16 = putpaintstruct16(vp, (LPPAINTSTRUCT) lp);
  1652. // save the 32-bit & new 16-bit GDI handles for unthunking
  1653. if(bNotThere) {
  1654. lpwm32mpex->dwTmp[0] = (DWORD)hdc16;
  1655. lpwm32mpex->dwTmp[1] = (DWORD)((LPPAINTSTRUCT)lp)->hdc;
  1656. }
  1657. }
  1658. GlobalUnlock((HANDLE) lpwm32mpex->lParam);
  1659. }
  1660. else {
  1661. LOGDEBUG(LOG_ALWAYS, ("WOW::WM32SizeClipboard: Couldn't lock 32 bit memory handle!\n"));
  1662. // WOW32ASSERT (FALSE);
  1663. }
  1664. GlobalUnlock16(hMem16);
  1665. }
  1666. else {
  1667. hMem16 = 0;
  1668. LOGDEBUG(LOG_ALWAYS, ("WOW::WM32SizeClipboard: Couldn't allocate memory !\n"));
  1669. WOW32ASSERT (FALSE);
  1670. }
  1671. LOW(lpwm32mpex->Parm16.WndProc.lParam) = (WORD) hMem16;
  1672. }
  1673. else {
  1674. // Get rid of the hDC added to our table by the call to putpaintstruct16
  1675. // call in the inbound thunk of this message above.
  1676. if (lpwm32mpex->uMsg == WM_PAINTCLIPBOARD) {
  1677. // If this is !0, it means that the handle hadn't been mapped in our
  1678. // table at the time of the IsGDIh32Mapped() call above.
  1679. if(lpwm32mpex->dwTmp[0]) {
  1680. hdc16 = (HAND16)LOWORD(lpwm32mpex->dwTmp[0]);
  1681. DeleteWOWGdiHandle((HANDLE)lpwm32mpex->dwTmp[1], hdc16);
  1682. }
  1683. }
  1684. if (LOW(lpwm32mpex->Parm16.WndProc.lParam)) {
  1685. GlobalUnlockFree16(GlobalLock16(LOW(lpwm32mpex->Parm16.WndProc.lParam), NULL));
  1686. }
  1687. }
  1688. return (TRUE);
  1689. }
  1690. // This function thunks the messages,
  1691. //
  1692. // WM_ASKCBFORMATNAME
  1693. //
  1694. BOOL FASTCALL WM32AskCBFormatName(LPWM32MSGPARAMEX lpwm32mpex)
  1695. {
  1696. if (lpwm32mpex->fThunk) {
  1697. lpwm32mpex->Parm16.WndProc.lParam = malloc16(lpwm32mpex->Parm16.WndProc.wParam);
  1698. if (lpwm32mpex->Parm16.WndProc.lParam) {
  1699. putstr16((VPSZ)lpwm32mpex->Parm16.WndProc.lParam, (LPSZ)lpwm32mpex->lParam, lpwm32mpex->uParam);
  1700. }
  1701. return (BOOL)lpwm32mpex->Parm16.WndProc.lParam;
  1702. }
  1703. else {
  1704. if (lpwm32mpex->Parm16.WndProc.lParam) {
  1705. getstr16((VPSZ)lpwm32mpex->Parm16.WndProc.lParam, (LPSZ)lpwm32mpex->lParam, lpwm32mpex->uParam);
  1706. free16((VPVOID) lpwm32mpex->Parm16.WndProc.lParam);
  1707. }
  1708. }
  1709. return (TRUE);
  1710. }
  1711. // This function thunks the messages,
  1712. //
  1713. // WM_CHANGECBCHAIN
  1714. //
  1715. BOOL FASTCALL WM32ChangeCBChain(LPWM32MSGPARAMEX lpwm32mpex)
  1716. {
  1717. if (lpwm32mpex->fThunk) {
  1718. lpwm32mpex->Parm16.WndProc.wParam = GETHWND16(lpwm32mpex->uParam);
  1719. lpwm32mpex->Parm16.WndProc.lParam = GETHWND16(lpwm32mpex->lParam);
  1720. }
  1721. return (TRUE);
  1722. }
  1723. // This function thunks the messages,
  1724. //
  1725. // WM_DDEINITIATE
  1726. //
  1727. BOOL FASTCALL WM32DDEInitiate(LPWM32MSGPARAMEX lpwm32mpex)
  1728. {
  1729. if (lpwm32mpex->fThunk) {
  1730. lpwm32mpex->Parm16.WndProc.wParam = GETHWND16(lpwm32mpex->uParam);
  1731. lpwm32mpex->Parm16.WndProc.lParam = lpwm32mpex->lParam;
  1732. WI32DDEAddInitiator(lpwm32mpex->Parm16.WndProc.wParam);
  1733. }
  1734. else {
  1735. WI32DDEDeleteInitiator((HAND16)GETHWND16(lpwm32mpex->uParam));
  1736. }
  1737. return (TRUE);
  1738. }
  1739. // This function thunks the messages,
  1740. //
  1741. // WM_DDEACK
  1742. //
  1743. BOOL FASTCALL WM32DDEAck(LPWM32MSGPARAMEX lpwm32mpex)
  1744. {
  1745. if (lpwm32mpex->fThunk) {
  1746. lpwm32mpex->Parm16.WndProc.wParam = GETHWND16(lpwm32mpex->uParam);
  1747. if (WI32DDEInitiate((HAND16)GETHWND16(lpwm32mpex->hwnd))) {
  1748. //
  1749. // Initiate ACK
  1750. //
  1751. lpwm32mpex->Parm16.WndProc.lParam = lpwm32mpex->lParam;
  1752. }
  1753. else {
  1754. //
  1755. // NON-Initiate ACK
  1756. //
  1757. UINT lLo = 0;
  1758. UINT lHi = 0;
  1759. PHDDE pDdeNode;
  1760. UnpackDDElParam(lpwm32mpex->uMsg, lpwm32mpex->lParam, &lLo, &lHi);
  1761. if (!HIWORD(lHi)) {
  1762. //
  1763. // NON-Execute ACK
  1764. //
  1765. HIW(lpwm32mpex->Parm16.WndProc.lParam) = (WORD) lHi;
  1766. }
  1767. else {
  1768. //
  1769. // Execute ACK
  1770. //
  1771. //
  1772. // The order of To_hwnd and From_hwnd is reversed in the following
  1773. // DDEFirstPair16(), below. This is done to locate the h32.
  1774. //
  1775. pDdeNode = DDEFindAckNode ((HAND16)lpwm32mpex->Parm16.WndProc.wParam,
  1776. (HAND16)GETHWND16(lpwm32mpex->hwnd),
  1777. (HANDLE) lHi);
  1778. if (!pDdeNode) {
  1779. //
  1780. // When ShellExecute does DDE_EXECUTE to open a document,
  1781. // we don't see its Win32 PostMessage calls so we have no
  1782. // record of the conversation. This is our first opportunity
  1783. // to rectify that, the context of WU32GetMessage thunking
  1784. // a WM_DDE_ACK message. We could also get here for other
  1785. // kinds of ACKs, fortunately the Win32 message alone gives
  1786. // enough context to distinguish the various flavors, unlike
  1787. // the Win16 WM_DDE_ACK.
  1788. //
  1789. if (lpwm32mpex->lParam >= 0xc0000000) {
  1790. //
  1791. // ack responding to initiate
  1792. //
  1793. lpwm32mpex->Parm16.WndProc.lParam = lpwm32mpex->lParam;
  1794. }
  1795. if (lHi > 0xffff) {
  1796. //
  1797. // ack responding to execute: global handle in hiword
  1798. //
  1799. HAND16 h16 = 0;
  1800. DWORD cb;
  1801. VPVOID vp;
  1802. LPBYTE lpMem16, lpMem32;
  1803. DDEINFO DdeInfo;
  1804. if (!lpwm32mpex->fFree) {
  1805. cb = GlobalSize((HANDLE)lHi);
  1806. vp = GlobalAllocLock16(GMEM_DDESHARE, cb, &h16);
  1807. if (vp) {
  1808. GETMISCPTR(vp, lpMem16);
  1809. lpMem32 = GlobalLock((HANDLE)lHi);
  1810. RtlCopyMemory(lpMem16, lpMem32, cb);
  1811. GlobalUnlock((HANDLE)lHi);
  1812. GlobalUnlock16(h16);
  1813. FREEMISCPTR(lpMem16);
  1814. DdeInfo.Msg = WM_DDE_EXECUTE;
  1815. DdeInfo.Format = 0;
  1816. DdeInfo.Flags = DDE_PACKET;
  1817. DdeInfo.h16 = 0;
  1818. DDEAddhandle(
  1819. lpwm32mpex->Parm16.WndProc.wParam,
  1820. GETHWND16(lpwm32mpex->hwnd),
  1821. h16,
  1822. (HANDLE)lHi,
  1823. &DdeInfo
  1824. );
  1825. pDdeNode = DDEFindAckNode (
  1826. (HAND16)lpwm32mpex->Parm16.WndProc.wParam,
  1827. (HAND16)GETHWND16(lpwm32mpex->hwnd),
  1828. (HANDLE) lHi);
  1829. WOW32ASSERTMSG(pDdeNode, "WM32DDEAck: Can't find just-added DDE node.\n");
  1830. }
  1831. }
  1832. lpwm32mpex->Parm16.WndProc.lParam = MAKELONG(LOWORD(lLo), h16);
  1833. } else {
  1834. //
  1835. // All other acks have same form: status in loword and
  1836. // item atom in hiword.
  1837. //
  1838. lpwm32mpex->Parm16.WndProc.lParam = MAKELONG(LOWORD(lLo), lHi);
  1839. }
  1840. }
  1841. if (pDdeNode && pDdeNode->DdeMsg == WM_DDE_EXECUTE) {
  1842. HIW(lpwm32mpex->Parm16.WndProc.lParam) = pDdeNode->hMem16;
  1843. if (lpwm32mpex->fFree) {
  1844. if (lHi) {
  1845. if (pDdeNode->DdeFlags & DDE_EXECUTE_FREE_MEM) {
  1846. LOGDEBUG (12, ("WOW::W32DDEAck : Freeing EXECUTE pair h16 = %04x, h32 = %08x\n",
  1847. pDdeNode->hMem16, lHi));
  1848. W32UnMarkDDEHandle (pDdeNode->hMem16);
  1849. GlobalUnlockFree16(GlobalLock16(pDdeNode->hMem16, NULL));
  1850. if (DDEDeletehandle(pDdeNode->hMem16, (HANDLE) lHi)) {
  1851. WOWGLOBALFREE((HANDLE)lHi);
  1852. }
  1853. else {
  1854. LOGDEBUG (0, ("WOW::DDE Ack : Ack can't find 16 - 32 aliasing : %04x, %04x, %04x, %08lx, %08lx\n",
  1855. lpwm32mpex->hwnd,
  1856. lpwm32mpex->uMsg,
  1857. lpwm32mpex->Parm16.WndProc.wParam,
  1858. lpwm32mpex->Parm16.WndProc.lParam,
  1859. lHi
  1860. ));
  1861. }
  1862. }
  1863. else {
  1864. if (pDdeNode->DdeFlags & DDE_EXECUTE_FREE_H16) {
  1865. W32UnMarkDDEHandle (pDdeNode->hMem16);
  1866. GlobalUnlockFree16(GlobalLock16(pDdeNode->hMem16, NULL));
  1867. HIW(lpwm32mpex->Parm16.WndProc.lParam) = pDdeNode->h16;
  1868. }
  1869. if (DDEDeletehandle(pDdeNode->hMem16, (HANDLE) lHi)) {
  1870. WOWGLOBALFREE((HANDLE)lHi);
  1871. }
  1872. else {
  1873. LOGDEBUG (0, ("WOW::DDE Ack : Ack can't find 16 - 32 aliasing : %04x, %04x, %04x, %08lx, %08lx\n",
  1874. lpwm32mpex->hwnd,
  1875. lpwm32mpex->uMsg,
  1876. lpwm32mpex->Parm16.WndProc.wParam,
  1877. lpwm32mpex->Parm16.WndProc.lParam,
  1878. lHi
  1879. ));
  1880. }
  1881. }
  1882. }
  1883. else {
  1884. LOGDEBUG (2, ("WOW::W32DDEAck : h32 is NULL \n"));
  1885. WOW32ASSERT (FALSE);
  1886. }
  1887. }
  1888. }
  1889. else {
  1890. 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));
  1891. }
  1892. }
  1893. LOW(lpwm32mpex->Parm16.WndProc.lParam) = (WORD) lLo;
  1894. if (fThunkDDEmsg) {
  1895. FreeDDElParam(lpwm32mpex->uMsg, lpwm32mpex->lParam);
  1896. }
  1897. LOGDEBUG (12, ("WOW::DDE Ack : %04x, %04x, %04x, %08lx, %08lx\n", lpwm32mpex->hwnd, lpwm32mpex->uMsg, lpwm32mpex->Parm16.WndProc.wParam, lpwm32mpex->Parm16.WndProc.lParam, lHi));
  1898. }
  1899. }
  1900. else {
  1901. //
  1902. // We will execute this scenario only if the app ate the message,
  1903. // because we need to free up the memory.
  1904. //
  1905. if (!fThunkDDEmsg) {
  1906. if (lpwm32mpex->lReturn) {
  1907. FreeDDElParam(lpwm32mpex->uMsg, lpwm32mpex->lParam);
  1908. }
  1909. }
  1910. }
  1911. return (TRUE);
  1912. }
  1913. // This function thunks the messages,
  1914. //
  1915. // WM_DDE_REQUEST
  1916. // WM_DDE_TERMINATE
  1917. // WM_DDE_UNADVISE
  1918. //
  1919. BOOL FASTCALL WM32DDERequest(LPWM32MSGPARAMEX lpwm32mpex)
  1920. {
  1921. if (lpwm32mpex->fThunk) {
  1922. lpwm32mpex->Parm16.WndProc.wParam = GETHWND16(lpwm32mpex->uParam);
  1923. }
  1924. return (TRUE);
  1925. }
  1926. // This function thunks the messages,
  1927. //
  1928. // WM_DDEADVISE
  1929. //
  1930. BOOL FASTCALL WM32DDEAdvise(LPWM32MSGPARAMEX lpwm32mpex)
  1931. {
  1932. HAND16 h16;
  1933. VPVOID vp;
  1934. LPBYTE lpMem16;
  1935. LPBYTE lpMem32;
  1936. UINT lLo = 0;
  1937. UINT lHi = 0;
  1938. DDEINFO DdeInfo;
  1939. if (lpwm32mpex->fThunk) {
  1940. UnpackDDElParam(lpwm32mpex->uMsg, lpwm32mpex->lParam, &lLo, &lHi);
  1941. lpwm32mpex->Parm16.WndProc.wParam = GETHWND16(lpwm32mpex->uParam);
  1942. if (h16 = DDEFindPair16((HAND16)GETHWND16(lpwm32mpex->hwnd),
  1943. (HAND16)lpwm32mpex->Parm16.WndProc.wParam,
  1944. (HANDLE) lLo)) {
  1945. LOW(lpwm32mpex->Parm16.WndProc.lParam) = h16;
  1946. } else {
  1947. vp = GlobalAllocLock16(GMEM_DDESHARE, sizeof(DDEADVISE), &h16);
  1948. if (vp) {
  1949. GETMISCPTR(vp, lpMem16);
  1950. lpMem32 = GlobalLock((HANDLE) lLo);
  1951. RtlCopyMemory(lpMem16, lpMem32, sizeof(DDEADVISE));
  1952. GlobalUnlock((HANDLE) lLo);
  1953. GlobalUnlock16(h16);
  1954. DdeInfo.Msg = LOW(lpwm32mpex->uMsg);
  1955. DdeInfo.Format = 0;
  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. }
  1966. HIW(lpwm32mpex->Parm16.WndProc.lParam) = (WORD) lHi;
  1967. if (fThunkDDEmsg) {
  1968. FreeDDElParam(lpwm32mpex->uMsg, lpwm32mpex->lParam);
  1969. }
  1970. }
  1971. else {
  1972. //
  1973. // We will execute this scenario only if the app ate the message,
  1974. // because we need to free up the memory.
  1975. //
  1976. if (!fThunkDDEmsg) {
  1977. if (lpwm32mpex->lReturn) {
  1978. FreeDDElParam(lpwm32mpex->uMsg, lpwm32mpex->lParam);
  1979. }
  1980. }
  1981. }
  1982. return (TRUE);
  1983. }
  1984. // This function thunks the messages,
  1985. //
  1986. // WM_DDEDATA
  1987. //
  1988. BOOL FASTCALL WM32DDEData(LPWM32MSGPARAMEX lpwm32mpex)
  1989. {
  1990. HAND16 h16;
  1991. UINT lLo = 0;
  1992. UINT lHi = 0;
  1993. DDEINFO DdeInfo;
  1994. if (lpwm32mpex->fThunk) {
  1995. UnpackDDElParam(lpwm32mpex->uMsg, lpwm32mpex->lParam, &lLo, &lHi);
  1996. lpwm32mpex->Parm16.WndProc.wParam = GETHWND16(lpwm32mpex->uParam);
  1997. if (!lLo) {
  1998. LOW(lpwm32mpex->Parm16.WndProc.lParam) = 0;
  1999. } else if (h16 = DDEFindPair16((HAND16)GETHWND16(lpwm32mpex->hwnd),
  2000. (HAND16)lpwm32mpex->Parm16.WndProc.wParam,
  2001. (HANDLE) lLo)) {
  2002. LOW(lpwm32mpex->Parm16.WndProc.lParam) = h16;
  2003. } else {
  2004. DdeInfo.Msg = LOW(lpwm32mpex->uMsg);
  2005. h16 = DDECopyhData16((HAND16)GETHWND16(lpwm32mpex->hwnd),
  2006. (HAND16)lpwm32mpex->Parm16.WndProc.wParam,
  2007. (HANDLE) lLo,
  2008. &DdeInfo);
  2009. //
  2010. // If we could not allocate 16 bit memory, then return NULL to the
  2011. // caller.
  2012. //
  2013. if (!h16) {
  2014. if (fThunkDDEmsg) {
  2015. FreeDDElParam(lpwm32mpex->uMsg, lpwm32mpex->lParam);
  2016. }
  2017. lpwm32mpex->Parm16.WndProc.wParam = (WORD) lHi;
  2018. lpwm32mpex->Parm16.WndProc.lParam = lLo;
  2019. return (0);
  2020. }
  2021. DdeInfo.Flags = DDE_PACKET;
  2022. DdeInfo.h16 = 0;
  2023. DDEAddhandle((HAND16)GETHWND16(lpwm32mpex->hwnd),
  2024. (HAND16)lpwm32mpex->Parm16.WndProc.wParam,
  2025. h16,
  2026. (HANDLE) lLo,
  2027. &DdeInfo);
  2028. LOW(lpwm32mpex->Parm16.WndProc.lParam) = h16;
  2029. }
  2030. HIW(lpwm32mpex->Parm16.WndProc.lParam) = (WORD) lHi;
  2031. if (fThunkDDEmsg) {
  2032. FreeDDElParam(lpwm32mpex->uMsg, lpwm32mpex->lParam);
  2033. }
  2034. }
  2035. else {
  2036. //
  2037. // We will execute this scenario only if the app ate the message,
  2038. // because we need to free up the memory.
  2039. //
  2040. if (!fThunkDDEmsg) {
  2041. if (lpwm32mpex->lReturn) {
  2042. FreeDDElParam(lpwm32mpex->uMsg, lpwm32mpex->lParam);
  2043. }
  2044. }
  2045. }
  2046. return (TRUE);
  2047. }
  2048. // This function thunks the messages,
  2049. //
  2050. // WM_POKE
  2051. //
  2052. BOOL FASTCALL WM32DDEPoke(LPWM32MSGPARAMEX lpwm32mpex)
  2053. {
  2054. HAND16 h16;
  2055. UINT lLo = 0;
  2056. UINT lHi = 0;
  2057. DDEINFO DdeInfo;
  2058. if (lpwm32mpex->fThunk) {
  2059. UnpackDDElParam(lpwm32mpex->uMsg, lpwm32mpex->lParam, &lLo, &lHi);
  2060. lpwm32mpex->Parm16.WndProc.wParam = GETHWND16(lpwm32mpex->uParam);
  2061. // sudeepb 03-Apr-1996
  2062. // House Design Gold Edition sends a DDE_POKE message with lParam
  2063. // being 0. We are suppose to thunk this message with lParam being
  2064. // zero. Without this check, the below code will fail this call
  2065. // and the message will not be thunked to the app.
  2066. if (lLo == 0) {
  2067. LOW(lpwm32mpex->Parm16.WndProc.lParam) = 0;
  2068. HIW(lpwm32mpex->Parm16.WndProc.lParam) = (WORD) lHi;
  2069. return (TRUE);
  2070. }
  2071. if (h16 = DDEFindPair16((HAND16)GETHWND16(lpwm32mpex->hwnd),
  2072. (HAND16)lpwm32mpex->Parm16.WndProc.wParam,
  2073. (HANDLE) lLo)) {
  2074. LOW(lpwm32mpex->Parm16.WndProc.lParam) = h16;
  2075. } else {
  2076. DdeInfo.Msg = LOW(lpwm32mpex->uMsg);
  2077. h16 = DDECopyhData16((HAND16)GETHWND16(lpwm32mpex->hwnd),
  2078. (HAND16)lpwm32mpex->Parm16.WndProc.wParam,
  2079. (HANDLE) lLo,
  2080. &DdeInfo);
  2081. //
  2082. // If we could not allocate 16 bit memory, then return NULL to the
  2083. // caller.
  2084. //
  2085. if (!h16) {
  2086. if (fThunkDDEmsg) {
  2087. FreeDDElParam(lpwm32mpex->uMsg, lpwm32mpex->lParam);
  2088. }
  2089. lpwm32mpex->Parm16.WndProc.lParam = lLo;
  2090. return (0);
  2091. }
  2092. DdeInfo.Flags = DDE_PACKET;
  2093. DdeInfo.h16 = 0;
  2094. DDEAddhandle((HAND16)GETHWND16(lpwm32mpex->hwnd),
  2095. (HAND16)lpwm32mpex->Parm16.WndProc.wParam,
  2096. h16,
  2097. (HANDLE) lLo,
  2098. &DdeInfo);
  2099. LOW(lpwm32mpex->Parm16.WndProc.lParam) = h16;
  2100. }
  2101. HIW(lpwm32mpex->Parm16.WndProc.lParam) = (WORD) lHi;
  2102. if (fThunkDDEmsg) {
  2103. FreeDDElParam(lpwm32mpex->uMsg, lpwm32mpex->lParam);
  2104. }
  2105. }
  2106. else {
  2107. //
  2108. // We will execute this scenario only if the app ate the message,
  2109. // because we need to free up the memory.
  2110. //
  2111. if (!fThunkDDEmsg) {
  2112. if (lpwm32mpex->lReturn) {
  2113. FreeDDElParam(lpwm32mpex->uMsg, lpwm32mpex->lParam);
  2114. }
  2115. }
  2116. }
  2117. return (TRUE);
  2118. }
  2119. // This function thunks the messages,
  2120. //
  2121. // WM_DDE_EXECUTE
  2122. //
  2123. BOOL FASTCALL WM32DDEExecute(LPWM32MSGPARAMEX lpwm32mpex)
  2124. {
  2125. HAND16 h16;
  2126. VPVOID vp;
  2127. LPBYTE lpMem16;
  2128. LPBYTE lpMem32;
  2129. DDEINFO DdeInfo;
  2130. if (lpwm32mpex->fThunk) {
  2131. lpwm32mpex->Parm16.WndProc.wParam = GETHWND16(lpwm32mpex->uParam);
  2132. if (h16 = DDEFindPair16((HAND16)GETHWND16(lpwm32mpex->hwnd),
  2133. (HAND16)lpwm32mpex->Parm16.WndProc.wParam,
  2134. (HANDLE) lpwm32mpex->lParam)) {
  2135. HIW(lpwm32mpex->Parm16.WndProc.lParam) = h16;
  2136. } else {
  2137. vp = GlobalAllocLock16(GMEM_DDESHARE, GlobalSize((HANDLE) lpwm32mpex->lParam), &h16);
  2138. if (vp) {
  2139. GETMISCPTR(vp, lpMem16);
  2140. lpMem32 = GlobalLock((HANDLE) lpwm32mpex->lParam);
  2141. RtlCopyMemory(lpMem16, lpMem32, GlobalSize((HANDLE) lpwm32mpex->lParam));
  2142. GlobalUnlock((HANDLE) lpwm32mpex->lParam);
  2143. GlobalUnlock16(h16);
  2144. DdeInfo.Msg = LOW(lpwm32mpex->uMsg);
  2145. DdeInfo.Format = 0;
  2146. DdeInfo.Flags = DDE_PACKET;
  2147. DdeInfo.h16 = 0;
  2148. DDEAddhandle((HAND16)GETHWND16(lpwm32mpex->hwnd),
  2149. (HAND16)lpwm32mpex->Parm16.WndProc.wParam,
  2150. h16,
  2151. (HANDLE) lpwm32mpex->lParam,
  2152. &DdeInfo);
  2153. HIW(lpwm32mpex->Parm16.WndProc.lParam) = h16;
  2154. }
  2155. }
  2156. LOW(lpwm32mpex->Parm16.WndProc.lParam) = 0;
  2157. }
  2158. return (TRUE);
  2159. }
  2160. // This function thunks the messages,
  2161. //
  2162. // WM_CTLCOLORMSGBOX
  2163. // WM_CTLCOLOREDIT
  2164. // WM_CTLCOLORLISTBOX
  2165. // WM_CTLCOLORBTN
  2166. // WM_CTLCOLORDLG
  2167. // WM_CTLCOLORSCROLLBAR
  2168. // WM_CTLCOLORSTATIC
  2169. //
  2170. // into WM_CTLCOLOR and the high word of lParam specifies the
  2171. // control type.
  2172. //
  2173. BOOL FASTCALL WM32CtlColor(LPWM32MSGPARAMEX lpwm32mpex)
  2174. {
  2175. HAND16 hdc16;
  2176. BOOL bNotThere;
  2177. if (lpwm32mpex->fThunk) {
  2178. lpwm32mpex->dwTmp[0] = 0;
  2179. lpwm32mpex->Parm16.WndProc.wMsg = WM_CTLCOLOR;
  2180. if(lpwm32mpex->uMsg != WM_CTLCOLOR) { // see 16-bit thunk for this special case
  2181. // Query to see if we've mapped the hDC32 in uParam. If not, it
  2182. // means that hDC32 was created outside this VDM and we will have
  2183. // to delete it from our table when un-thunking this message.
  2184. bNotThere = FALSE;
  2185. if(!IsGDIh32Mapped((HANDLE)lpwm32mpex->uParam)) {
  2186. bNotThere = TRUE;
  2187. }
  2188. // The GetHDC16 macro may cause the hDC to be added to our mapping
  2189. // table if it wasn't already there.
  2190. hdc16 = GETHDC16(lpwm32mpex->uParam);
  2191. lpwm32mpex->Parm16.WndProc.wParam = hdc16;
  2192. // save the 32-bit & new 16-bit GDI handles for unthunking
  2193. if(bNotThere) {
  2194. lpwm32mpex->dwTmp[0] = (DWORD)hdc16;
  2195. lpwm32mpex->dwTmp[1] = lpwm32mpex->uParam;
  2196. }
  2197. LOW(lpwm32mpex->Parm16.WndProc.lParam) = GETHWND16(lpwm32mpex->lParam);
  2198. HIW(lpwm32mpex->Parm16.WndProc.lParam) = (WORD) (lpwm32mpex->uMsg - WM_CTLCOLORMSGBOX);
  2199. }
  2200. }
  2201. else {
  2202. if ((ULONG)lpwm32mpex->lReturn > COLOR_ENDCOLORS) {
  2203. lpwm32mpex->lReturn = (LONG) HBRUSH32(lpwm32mpex->lReturn);
  2204. }
  2205. // If this is !0, it means that the handle hadn't been mapped in our
  2206. // table at the time of the IsGDIh32Mapped() call above.
  2207. if(lpwm32mpex->dwTmp[0]) {
  2208. // Remove the hdc that was added to our table by the GETHDC16 macro
  2209. // in the inbound thunk of this message above.
  2210. hdc16 = (HAND16)LOWORD(lpwm32mpex->dwTmp[0]);
  2211. DeleteWOWGdiHandle((HANDLE)lpwm32mpex->dwTmp[1], hdc16);
  2212. }
  2213. }
  2214. return (TRUE);
  2215. }
  2216. // This function thunks the messages,
  2217. //
  2218. // WM_GETFONT
  2219. //
  2220. BOOL FASTCALL WM32GetFont(LPWM32MSGPARAMEX lpwm32mpex)
  2221. {
  2222. if (!lpwm32mpex->fThunk) {
  2223. // This might be a possible GDI handle mapping table leak if the
  2224. // HFONT was created outside of this VDM process. In this case, the
  2225. // HFONT32 macro will cause the h32 to be added to our mapping table. We
  2226. // don't have any clues when to remove it. Not much we can do except
  2227. // remove it at reclaim time if it is no longer valid.
  2228. lpwm32mpex->lReturn = (LONG)HFONT32(lpwm32mpex->lReturn);
  2229. }
  2230. return (TRUE);
  2231. }
  2232. // This function thunks the messages,
  2233. //
  2234. // WM_NEXTMENU
  2235. //
  2236. // Win16 NT
  2237. // wParam VK_KEY VK_KEY
  2238. // lParam.l hmenu PMDINEXTMENU
  2239. // lParam.h 0
  2240. // return.l menu BOOL
  2241. // return.h window
  2242. //
  2243. BOOL FASTCALL WM32NextMenu(LPWM32MSGPARAMEX lpwm32mpex)
  2244. {
  2245. if (lpwm32mpex->fThunk) {
  2246. if (lpwm32mpex->lParam) {
  2247. LOW(lpwm32mpex->Parm16.WndProc.lParam) = GETHMENU16(((PMDINEXTMENU)lpwm32mpex->lParam)->hmenuIn);
  2248. HIW(lpwm32mpex->Parm16.WndProc.lParam) = 0;
  2249. }
  2250. } else {
  2251. if (lpwm32mpex->lParam) {
  2252. ((PMDINEXTMENU)lpwm32mpex->lParam)->hmenuNext = HMENU32(LOWORD(lpwm32mpex->lReturn));
  2253. ((PMDINEXTMENU)lpwm32mpex->lParam)->hwndNext = HWND32(HIWORD(lpwm32mpex->lReturn));
  2254. lpwm32mpex->lReturn = TRUE;
  2255. } else {
  2256. lpwm32mpex->lReturn = FALSE;
  2257. }
  2258. }
  2259. return (TRUE);
  2260. }
  2261. BOOL FASTCALL WM32Destroy (LPWM32MSGPARAMEX lpwm32mpex)
  2262. {
  2263. if (!lpwm32mpex->fThunk) {
  2264. if (CACHENOTEMPTY()) {
  2265. // because of our method of window aliasing, 'hwnd' may or may
  2266. // not be a real 32bit handle. ie. it may be (hwnd16 | 0xffff0000).
  2267. // So always use hwnd16.
  2268. ReleaseCachedDCs((CURRENTPTD())->htask16, GETHWND16(lpwm32mpex->hwnd), 0,
  2269. (HWND)0, SRCHDC_TASK16_HWND16);
  2270. }
  2271. }
  2272. return (TRUE);
  2273. }
  2274. // This function thunks the messages,
  2275. // WM_DROPFILES
  2276. BOOL FASTCALL WM32DropFiles(LPWM32MSGPARAMEX lpwm32mpex)
  2277. {
  2278. if (lpwm32mpex->fThunk) {
  2279. return (BOOL)(lpwm32mpex->Parm16.WndProc.wParam = GETHDROP16(lpwm32mpex->uParam));
  2280. }
  2281. return (TRUE);
  2282. }
  2283. // This function thunks the messages,
  2284. // WM_PRINT
  2285. // WM_PRINTCLIENT
  2286. BOOL FASTCALL WM32PrintClient(LPWM32MSGPARAMEX lpwm32mpex)
  2287. {
  2288. HAND16 hdc16;
  2289. BOOL bNotThere;
  2290. if (lpwm32mpex->fThunk) {
  2291. // Query to see if we've mapped hDC32 in uParam. If not, it means that
  2292. // hDC32 was created outside this VDM process and we will have to
  2293. // delete it from our table when un-thunking this message.
  2294. bNotThere = FALSE;
  2295. lpwm32mpex->dwTmp[0] = 0;
  2296. if(!IsGDIh32Mapped((HANDLE)lpwm32mpex->uParam)) {
  2297. bNotThere = TRUE;
  2298. }
  2299. // GETHDC16() may cause a new handle to be added to our handle table.
  2300. hdc16 = GETHDC16(lpwm32mpex->uParam);
  2301. // save the 32-bit & new 16-bit GDI handles for unthunking
  2302. if(bNotThere) {
  2303. lpwm32mpex->dwTmp[0] = (DWORD)hdc16;
  2304. lpwm32mpex->dwTmp[1] = lpwm32mpex->uParam;
  2305. }
  2306. lpwm32mpex->Parm16.WndProc.wParam = hdc16;
  2307. return ((BOOL)hdc16);
  2308. }
  2309. // unthunk
  2310. else {
  2311. // If this is !0, it means that the handle hadn't been mapped in our
  2312. // table at the time of the IsGDIh32Mapped() call above.
  2313. if(lpwm32mpex->dwTmp[0]) {
  2314. // Remove the hdc that was added to our table by the GETHDC16 macro
  2315. // in the inbound thunk of this message above.
  2316. hdc16 = (HAND16)LOWORD(lpwm32mpex->dwTmp[0]);
  2317. DeleteWOWGdiHandle((HANDLE)lpwm32mpex->dwTmp[1], hdc16);
  2318. }
  2319. }
  2320. return (TRUE);
  2321. }
  2322. // This function thunks the messages,
  2323. //
  2324. // WM_DROPOBJECT
  2325. // WM_QUERYDROPOBJECT
  2326. // WM_DRAGLOOP
  2327. // WM_DRAGSELECT
  2328. // WM_DRAGMOVE
  2329. //
  2330. BOOL FASTCALL WM32DropObject(LPWM32MSGPARAMEX lpwm32mpex)
  2331. {
  2332. register PDROPSTRUCT16 pds16;
  2333. register LPDROPSTRUCT lParam = (LPDROPSTRUCT)lpwm32mpex->lParam;
  2334. if (lpwm32mpex->fThunk) {
  2335. lpwm32mpex->Parm16.WndProc.wParam = (WORD)lpwm32mpex->uParam;
  2336. // BUGBUG -- The assumption here is that GlobalAlloc will never
  2337. // return a memory object that isn't word-aligned, so that we can
  2338. // assign word-aligned words directly; we have no idea whether the
  2339. // memory is dword-aligned or not however, so dwords must always
  2340. // be paranoidly stored with the STOREDWORD/STORELONG macros -JTP
  2341. if (!(lpwm32mpex->Parm16.WndProc.lParam = malloc16(sizeof(DROPSTRUCT16))))
  2342. return FALSE;
  2343. GETVDMPTR(lpwm32mpex->Parm16.WndProc.lParam, sizeof(DROPSTRUCT16), pds16);
  2344. pds16->hwndSource = GETHWND16(lParam->hwndSource);
  2345. pds16->hwndSink = GETHWND16(lParam->hwndSink);
  2346. pds16->wFmt = (WORD) lParam->wFmt;
  2347. STOREDWORD(pds16->dwData, lParam->dwData);
  2348. pds16->ptDrop.x = (SHORT)lParam->ptDrop.x;
  2349. pds16->ptDrop.y = (SHORT)lParam->ptDrop.y;
  2350. STOREDWORD(pds16->dwControlData, lParam->dwControlData);
  2351. FLUSHVDMPTR(lpwm32mpex->Parm16.WndProc.lParam, sizeof(DROPSTRUCT16), pds16);
  2352. FREEVDMPTR(pds16);
  2353. } else {
  2354. free16((VPVOID) lpwm32mpex->Parm16.WndProc.lParam);
  2355. if (lpwm32mpex->uMsg == WM_QUERYDROPOBJECT) {
  2356. //
  2357. // Return value is either TRUE, FALSE,
  2358. // or a cursor!
  2359. //
  2360. if (lpwm32mpex->lReturn && lpwm32mpex->lReturn != (LONG)TRUE) {
  2361. lpwm32mpex->lReturn = (LONG)HCURSOR32(lpwm32mpex->lReturn);
  2362. }
  2363. }
  2364. }
  2365. return (TRUE);
  2366. }
  2367. // This function thunks the messages,
  2368. //
  2369. // WM_WINDOWPOSCHANGING
  2370. // WM_WINDOWPOSCHANGED
  2371. //
  2372. BOOL FASTCALL WM32WindowPosChanging (LPWM32MSGPARAMEX lpwm32mpex)
  2373. {
  2374. LPWINDOWPOS lParam = (LPWINDOWPOS) lpwm32mpex->lParam;
  2375. if (lpwm32mpex->fThunk) {
  2376. // be sure allocation size matches stackfree16() size below
  2377. lpwm32mpex->Parm16.WndProc.lParam = stackalloc16(sizeof(WINDOWPOS16));
  2378. putwindowpos16( (VPWINDOWPOS16)lpwm32mpex->Parm16.WndProc.lParam, lParam );
  2379. }
  2380. else {
  2381. getwindowpos16( (VPWINDOWPOS16)lpwm32mpex->Parm16.WndProc.lParam, lParam );
  2382. if(lpwm32mpex->Parm16.WndProc.lParam) {
  2383. stackfree16((VPVOID) lpwm32mpex->Parm16.WndProc.lParam,
  2384. sizeof(WINDOWPOS16));
  2385. }
  2386. }
  2387. return (TRUE);
  2388. }
  2389. // This function thunks the message,
  2390. //
  2391. // WM_COPYDATA
  2392. //
  2393. BOOL FASTCALL WM32CopyData (LPWM32MSGPARAMEX lpwm32mpex)
  2394. {
  2395. HAND16 h16;
  2396. HAND16 hMem16;
  2397. VPVOID vpCDS16;
  2398. VPVOID vpData16;
  2399. LPBYTE lpMem16;
  2400. PCOPYDATASTRUCT lpCDS32;
  2401. PCOPYDATASTRUCT lpCDS16;
  2402. PCPDATA pTemp;
  2403. if (lpwm32mpex->fThunk) {
  2404. lpwm32mpex->Parm16.WndProc.wParam = GETHWND16(lpwm32mpex->uParam);
  2405. if (vpCDS16 = CopyDataFindData16 (GETHWND16(lpwm32mpex->hwnd), lpwm32mpex->Parm16.WndProc.wParam, lpwm32mpex->lParam)) {
  2406. lpwm32mpex->Parm16.WndProc.lParam = vpCDS16;
  2407. }
  2408. else {
  2409. vpCDS16 = GlobalAllocLock16(GMEM_DDESHARE, sizeof(COPYDATASTRUCT), &h16);
  2410. if (vpCDS16) {
  2411. GETMISCPTR(vpCDS16, lpCDS16);
  2412. lpCDS32 = (PCOPYDATASTRUCT) lpwm32mpex->lParam;
  2413. lpCDS16->dwData = lpCDS32->dwData;
  2414. if (lpCDS16->cbData = lpCDS32->cbData) {
  2415. FREEMISCPTR(lpCDS16);
  2416. vpData16 = GlobalAllocLock16(GMEM_DDESHARE, lpCDS32->cbData, &hMem16);
  2417. GETMISCPTR(vpData16, lpMem16);
  2418. if (lpMem16 && lpCDS32->lpData) {
  2419. RtlCopyMemory(lpMem16, lpCDS32->lpData, lpCDS32->cbData);
  2420. CopyDataAddNode (GETHWND16(lpwm32mpex->hwnd), lpwm32mpex->Parm16.WndProc.wParam, vpData16, (DWORD) lpCDS32->lpData, 0);
  2421. }
  2422. FREEMISCPTR(lpMem16);
  2423. GETMISCPTR(vpCDS16, lpCDS16);
  2424. lpCDS16->lpData = (PVOID) vpData16;
  2425. }
  2426. else {
  2427. lpCDS16->lpData = NULL;
  2428. }
  2429. FREEMISCPTR(lpCDS16);
  2430. }
  2431. lpwm32mpex->Parm16.WndProc.lParam = vpCDS16;
  2432. CopyDataAddNode (GETHWND16(lpwm32mpex->hwnd), lpwm32mpex->Parm16.WndProc.wParam, vpCDS16, lpwm32mpex->lParam, 0);
  2433. }
  2434. }
  2435. else {
  2436. if (lpwm32mpex->fFree) {
  2437. pTemp = CopyDataFindData32 (GETHWND16(lpwm32mpex->hwnd), GETHWND16(lpwm32mpex->uParam), lpwm32mpex->Parm16.WndProc.lParam);
  2438. if (pTemp && (!(pTemp->Flags))) {
  2439. GETMISCPTR(lpwm32mpex->Parm16.WndProc.lParam, lpCDS16);
  2440. GlobalUnlockFree16 ((VPVOID)lpCDS16->lpData);
  2441. CopyDataDeleteNode (GETHWND16(lpwm32mpex->hwnd), lpwm32mpex->Parm16.WndProc.wParam, (DWORD) ((PCOPYDATASTRUCT)lpwm32mpex->lParam)->lpData);
  2442. GlobalUnlockFree16 ((VPVOID)lpwm32mpex->Parm16.WndProc.lParam);
  2443. CopyDataDeleteNode (GETHWND16(lpwm32mpex->hwnd), lpwm32mpex->Parm16.WndProc.wParam, (DWORD) lpwm32mpex->lParam);
  2444. FREEMISCPTR(lpCDS16);
  2445. }
  2446. }
  2447. }
  2448. return (TRUE);
  2449. }
  2450. // This function thunks the message,
  2451. //
  2452. // WM_WINHELP
  2453. //
  2454. BOOL FASTCALL WM32WinHelp (LPWM32MSGPARAMEX lpwm32mpex)
  2455. {
  2456. static WORD msgWinHelp = 0;
  2457. if (lpwm32mpex->fThunk) {
  2458. lpwm32mpex->Parm16.WndProc.wMsg = msgWinHelp ? msgWinHelp : (msgWinHelp = (WORD)RegisterWindowMessage("WM_WINHELP"));
  2459. lpwm32mpex->Parm16.WndProc.wParam = GETHWND16(lpwm32mpex->uParam);
  2460. if (lpwm32mpex->lParam) {
  2461. // lpwm32mpex->lParam is LPHLP - however we need only the firstword,ie the size of data
  2462. HAND16 hMem16 = 0;
  2463. VPVOID vp;
  2464. LPBYTE lpT;
  2465. WORD cb;
  2466. cb = ((LPHLP)lpwm32mpex->lParam)->cbData;
  2467. if (vp = GlobalAllocLock16(GMEM_DDESHARE | GMEM_MOVEABLE, cb, &hMem16)) {
  2468. GETMISCPTR(vp, lpT);
  2469. RtlCopyMemory(lpT, (PVOID)lpwm32mpex->lParam, cb);
  2470. FREEMISCPTR(lpT);
  2471. }
  2472. lpwm32mpex->Parm16.WndProc.lParam = hMem16;
  2473. lpwm32mpex->dwParam = vp;
  2474. }
  2475. }
  2476. else {
  2477. // Make sure WinHelp is in the foreground
  2478. SetForegroundWindow(lpwm32mpex->hwnd);
  2479. if (lpwm32mpex->Parm16.WndProc.lParam) {
  2480. GlobalUnlockFree16((VPVOID)lpwm32mpex->dwParam);
  2481. }
  2482. }
  2483. return (TRUE);
  2484. }
  2485. //
  2486. // Thunk the undocumented MM_CALCSCROLL MDI message. Message has no parameters,
  2487. // but has different message values; 32-bit msg: 0x3F, 16-bit msg: 0x10AC.
  2488. //
  2489. BOOL FASTCALL WM32MMCalcScroll (LPWM32MSGPARAMEX lpwm32mpex)
  2490. {
  2491. if ( lpwm32mpex->fThunk ) {
  2492. lpwm32mpex->Parm16.WndProc.wMsg = (WORD) WIN31_MM_CALCSCROLL;
  2493. }
  2494. return (TRUE);
  2495. }
  2496. // Calculate the size of the structure passed with WM_NOTIFY based
  2497. // on the code field in NMHDR.
  2498. // NOTE: Do NOT rely on the documentation for the size of the struct passed in
  2499. // lParam. In some cases the struct is actually part of a larger struct
  2500. // and we need to copy all of it. See PSN_xxxx codes in comctl32\prsht.c
  2501. // They are documented to be NMHDR but are really a PSHNOTIFY which has
  2502. // NMHDR as the first field. Also watch for some of the WIDE UNICODE
  2503. // char cases -- the struct may or may not be the same size as the ANSI
  2504. // version of the struct.
  2505. // Heaven help us when they start adding more of these codes!
  2506. UINT GetNMHDRextensionSize(LPNMHDR pnmhdr32)
  2507. {
  2508. #ifdef DEBUG
  2509. char szLabel[40] = " WOW:WM_NOTIFY code: ";
  2510. #endif
  2511. // Caller already checked against NM_LAST.
  2512. if (pnmhdr32->code >= LVN_LAST) {
  2513. LOGDEBUG(2,("%sLVN_ %x\n", szLabel, pnmhdr32->code));
  2514. switch (pnmhdr32->code) {
  2515. case LVN_ITEMCHANGING:
  2516. case LVN_ITEMCHANGED:
  2517. case LVN_INSERTITEM:
  2518. case LVN_DELETEITEM:
  2519. case LVN_DELETEALLITEMS:
  2520. case LVN_COLUMNCLICK:
  2521. case LVN_BEGINDRAG:
  2522. case LVN_BEGINRDRAG:
  2523. case LVN_HOTTRACK:
  2524. return sizeof(NM_LISTVIEW);
  2525. case LVN_BEGINLABELEDITA:
  2526. case LVN_ENDLABELEDITA:
  2527. case LVN_GETDISPINFOA:
  2528. case LVN_SETDISPINFOA:
  2529. case LVN_BEGINLABELEDITW:
  2530. case LVN_ENDLABELEDITW:
  2531. case LVN_GETDISPINFOW:
  2532. case LVN_SETDISPINFOW:
  2533. return sizeof(LV_DISPINFO);
  2534. case LVN_KEYDOWN:
  2535. return sizeof(LV_KEYDOWN);
  2536. case LVN_ODCACHEHINT:
  2537. return sizeof(NM_CACHEHINT);
  2538. case LVN_ODFINDITEMA:
  2539. case LVN_ODFINDITEMW:
  2540. return sizeof(NM_FINDITEM);
  2541. case LVN_ODSTATECHANGED:
  2542. return sizeof(NM_ODSTATECHANGE);
  2543. case LVN_ITEMACTIVATE:
  2544. return sizeof(NMKEY);
  2545. default:
  2546. goto unknown_nmhdr_code;
  2547. }
  2548. }
  2549. if (pnmhdr32->code >= PSN_LAST) {
  2550. LOGDEBUG(2,("%sPSN_ %x\n", szLabel, pnmhdr32->code));
  2551. switch (pnmhdr32->code) {
  2552. case PSN_SETACTIVE:
  2553. case PSN_KILLACTIVE:
  2554. case PSN_APPLY:
  2555. case PSN_RESET:
  2556. case PSN_HELP:
  2557. case PSN_WIZBACK:
  2558. case PSN_WIZNEXT:
  2559. case PSN_WIZFINISH:
  2560. case PSN_QUERYCANCEL:
  2561. case PSN_TRANSLATEACCELERATOR:
  2562. case PSN_QUERYINITIALFOCUS:
  2563. case PSN_HASHELP: // this one "is dead" - RaymondC
  2564. return sizeof(PSHNOTIFY);
  2565. case PSN_GETOBJECT:
  2566. return sizeof(NMOBJECTNOTIFY);
  2567. case PSN_LASTCHANCEAPPLY: // this is undocumented
  2568. return sizeof(NMHDR); // (in widows\inc\prshtp.h)
  2569. default:
  2570. goto unknown_nmhdr_code;
  2571. }
  2572. }
  2573. if (pnmhdr32->code >= HDN_LAST) {
  2574. LOGDEBUG(2,("%sHDN_ %x\n", szLabel, pnmhdr32->code));
  2575. switch (pnmhdr32->code) {
  2576. case HDN_ITEMCHANGINGA:
  2577. case HDN_ITEMCHANGEDA:
  2578. case HDN_ITEMCLICKA:
  2579. case HDN_DIVIDERDBLCLICKA:
  2580. case HDN_BEGINTRACKA:
  2581. case HDN_ENDTRACKA:
  2582. case HDN_TRACKA:
  2583. case HDN_ITEMCHANGINGW:
  2584. case HDN_ITEMCHANGEDW:
  2585. case HDN_ITEMCLICKW:
  2586. case HDN_DIVIDERDBLCLICKW:
  2587. case HDN_BEGINTRACKW:
  2588. case HDN_ENDTRACKW:
  2589. case HDN_TRACKW:
  2590. case HDN_BEGINDRAG:
  2591. case HDN_ENDDRAG:
  2592. case HDN_ITEMDBLCLICKA:
  2593. case HDN_ITEMDBLCLICKW:
  2594. return sizeof(HD_NOTIFY);
  2595. case HDN_GETDISPINFOA:
  2596. case HDN_GETDISPINFOW:
  2597. return sizeof(NMHDDISPINFO);
  2598. default:
  2599. goto unknown_nmhdr_code;
  2600. }
  2601. }
  2602. if (pnmhdr32->code >= TVN_LAST) {
  2603. LOGDEBUG(2,("%sTVN_ %x\n", szLabel, pnmhdr32->code));
  2604. switch (pnmhdr32->code) {
  2605. case TVN_SELCHANGINGA:
  2606. case TVN_SELCHANGEDA:
  2607. case TVN_ITEMEXPANDINGA:
  2608. case TVN_ITEMEXPANDEDA:
  2609. case TVN_BEGINDRAGA:
  2610. case TVN_BEGINRDRAGA:
  2611. case TVN_DELETEITEMA:
  2612. case TVN_SELCHANGINGW:
  2613. case TVN_SELCHANGEDW:
  2614. case TVN_ITEMEXPANDINGW:
  2615. case TVN_ITEMEXPANDEDW:
  2616. case TVN_BEGINDRAGW:
  2617. case TVN_BEGINRDRAGW:
  2618. case TVN_DELETEITEMW:
  2619. case TVN_SINGLEEXPAND:
  2620. return sizeof(NM_TREEVIEW);
  2621. case TVN_GETDISPINFOA:
  2622. case TVN_SETDISPINFOA:
  2623. case TVN_BEGINLABELEDITA:
  2624. case TVN_ENDLABELEDITA:
  2625. case TVN_GETDISPINFOW:
  2626. case TVN_SETDISPINFOW:
  2627. case TVN_BEGINLABELEDITW:
  2628. case TVN_ENDLABELEDITW:
  2629. return sizeof(TV_DISPINFO);
  2630. case TVN_KEYDOWN:
  2631. return sizeof(TV_KEYDOWN);
  2632. case TVN_GETINFOTIPA:
  2633. case TVN_GETINFOTIPW:
  2634. return sizeof(NMTVGETINFOTIP);
  2635. default:
  2636. goto unknown_nmhdr_code;
  2637. }
  2638. }
  2639. if (pnmhdr32->code >= TTN_LAST) {
  2640. LOGDEBUG(2,("%sTTN_ %x\n", szLabel, pnmhdr32->code));
  2641. switch (pnmhdr32->code) {
  2642. case TTN_NEEDTEXTA: // (aka TTN_GETDISPINFO)
  2643. return sizeof(TOOLTIPTEXTA);
  2644. case TTN_NEEDTEXTW:
  2645. return sizeof(TOOLTIPTEXTW);
  2646. case TTN_SHOW:
  2647. case TTN_POP:
  2648. return sizeof(NMHDR);
  2649. default:
  2650. goto unknown_nmhdr_code;
  2651. }
  2652. }
  2653. if (pnmhdr32->code >= TCN_LAST) {
  2654. LOGDEBUG(2,("%sTCN_ %x\n", szLabel, pnmhdr32->code));
  2655. switch (pnmhdr32->code) {
  2656. case TCN_KEYDOWN:
  2657. return sizeof(TC_KEYDOWN);
  2658. case TCN_SELCHANGE:
  2659. case TCN_SELCHANGING:
  2660. return sizeof(NMHDR);
  2661. default:
  2662. goto unknown_nmhdr_code;
  2663. }
  2664. }
  2665. if (pnmhdr32->code >= UDN_LAST) {
  2666. LOGDEBUG(2,("%sUDN_ %x\n", szLabel, pnmhdr32->code));
  2667. switch (pnmhdr32->code) {
  2668. case UDN_DELTAPOS:
  2669. return sizeof(NM_UPDOWN);
  2670. default:
  2671. goto unknown_nmhdr_code;
  2672. }
  2673. }
  2674. unknown_nmhdr_code:
  2675. LOGDEBUG(LOG_ALWAYS, ("WOW:GetNMHDRextensionSize unknown nmhdr->code: %d!\n", pnmhdr32->code));
  2676. WOW32ASSERT(FALSE);
  2677. return sizeof(NMHDR); // the first field of most of the structs is NMHDR
  2678. }
  2679. //
  2680. // This function thunks the 32-bit message WM_NOTIFY. This message existed
  2681. // but was undocumented in Win3.1. Win95 thunks it by translating lParam
  2682. // from a flat to 16:16 pointer without thunking the contents. That's tricky
  2683. // for us since on RISC we can't map random linear memory into the VDM without
  2684. // a lot of overhead. We'll use the code field in NMHDR to calculate the size
  2685. // of the passed structure.
  2686. //
  2687. BOOL FASTCALL WM32Notify(LPWM32MSGPARAMEX lpwm32mpex)
  2688. {
  2689. LPNMHDR pnmhdr32;
  2690. LPNMHDR pnmhdr16;
  2691. if (lpwm32mpex->fThunk) {
  2692. pnmhdr32 = (LPNMHDR) lpwm32mpex->Parm16.WndProc.lParam;
  2693. // Save the original 32-bit flat pointer for unthunking.
  2694. lpwm32mpex->dwTmp[0] = (DWORD) pnmhdr32;
  2695. // If this 32bit message came from WOW, we have the original
  2696. // 16:16 lparam squirrelled away. (mapped to the original 32-bit lParam)
  2697. // Note: If the mapping is found, the ref count gets incremented.
  2698. lpwm32mpex->Parm16.WndProc.lParam = (LONG)GetParam16(lpwm32mpex->lParam);
  2699. // if we don't already have a 16:16 ptr for this -- create one
  2700. // This means we are seeing this message for the 1st time -- coming
  2701. // from the 32-bit world.
  2702. if ( ! lpwm32mpex->Parm16.WndProc.lParam) {
  2703. if (pnmhdr32->code >= NM_LAST) {
  2704. lpwm32mpex->dwParam = sizeof(NMHDR);
  2705. }
  2706. else {
  2707. lpwm32mpex->dwParam = GetNMHDRextensionSize(pnmhdr32);
  2708. }
  2709. // be sure allocation size matches stackfree16() size below
  2710. lpwm32mpex->dwTmp[1] = (DWORD)lpwm32mpex->dwParam;
  2711. lpwm32mpex->Parm16.WndProc.lParam = stackalloc16(lpwm32mpex->dwTmp[1]);
  2712. GETVDMPTR(lpwm32mpex->Parm16.WndProc.lParam, lpwm32mpex->dwParam, pnmhdr16);
  2713. CopyMemory(pnmhdr16, pnmhdr32, lpwm32mpex->dwParam);
  2714. FREEVDMPTR(pnmhdr16);
  2715. // else don't allocate (or free) another 16:16 ptr
  2716. } else {
  2717. // set to FALSE so we don't free this thing too soon
  2718. lpwm32mpex->fFree = FALSE;
  2719. }
  2720. } else {
  2721. if (lpwm32mpex->fFree) {
  2722. GETVDMPTR(lpwm32mpex->Parm16.WndProc.lParam, lpwm32mpex->dwParam, pnmhdr16);
  2723. // retrieve original 32-bit pointer
  2724. pnmhdr32 = (LPNMHDR) lpwm32mpex->dwTmp[0];
  2725. CopyMemory(pnmhdr32, pnmhdr16, lpwm32mpex->dwParam);
  2726. FREEVDMPTR(pnmhdr16);
  2727. if(lpwm32mpex->Parm16.WndProc.lParam) {
  2728. stackfree16(lpwm32mpex->Parm16.WndProc.lParam, lpwm32mpex->dwTmp[1]);
  2729. }
  2730. } else {
  2731. // Decrement the ref count. If the ref count goes to zero, the
  2732. // mapping is nuked.
  2733. DeleteParamMap(lpwm32mpex->Parm16.WndProc.lParam, PARAM_16, NULL);
  2734. }
  2735. }
  2736. return TRUE;
  2737. }
  2738. // This function thunks the 32-bit message WM_NOTIFYWOW.
  2739. // uParam dictates where the notification should be dispatched.
  2740. //
  2741. BOOL FASTCALL WM32NotifyWow(LPWM32MSGPARAMEX lpwm32mpex)
  2742. {
  2743. switch (lpwm32mpex->uParam) {
  2744. case WMNW_UPDATEFINDREPLACE:
  2745. if (lpwm32mpex->fThunk) {
  2746. // Update the 16-bit FINDREPLACE struct.
  2747. lpwm32mpex->Parm16.WndProc.lParam = WCD32UpdateFindReplaceTextAndFlags(lpwm32mpex->hwnd, lpwm32mpex->lParam);
  2748. lpwm32mpex->Parm16.WndProc.wMsg = msgFINDREPLACE;
  2749. return(TRUE);
  2750. }
  2751. break;
  2752. default:
  2753. LOGDEBUG(LOG_ALWAYS, ("WOW::WM32NotifyWow: Unknown dispatch parameter!\n"));
  2754. WOW32ASSERT (FALSE);
  2755. }
  2756. return (FALSE);
  2757. }
  2758. //
  2759. // In ThunkMsg16 we use the data in 32->16 message thunk table to optimize
  2760. // thunking process based on 'WM32NoThunking'.
  2761. //
  2762. // This is place holder for those messages which need nothunking on 32-16
  2763. // trasitions but need some kind of thunking on 16->32 transistions.
  2764. //
  2765. // So this marks the message as 'this message needs 16-32 thunking but
  2766. // not 32-16 thunking'
  2767. //
  2768. // - nanduri
  2769. BOOL FASTCALL WM32Thunk16To32(LPWM32MSGPARAMEX lpwm32mpex)
  2770. {
  2771. return (TRUE);
  2772. }
  2773. #ifdef FE_IME
  2774. //
  2775. // This function thunks the messages,
  2776. //
  2777. // WM_IME_REPORT
  2778. /*
  2779. BOOL FASTCALL WM32IMEReport (HWND hwnd, UINT uMsg, UINT uParam, LONG lParam,
  2780. PWORD pwMsgNew, PWORD pwParamNew, PLONG plParamNew,
  2781. PLONG plReturn, BOOL fThunk, LPWM32MSGPARAMEX lpwm32mpex)
  2782. */
  2783. BOOL FASTCALL WM32IMEReport (LPWM32MSGPARAMEX lpwm32mpex)
  2784. {
  2785. //lpwm32mpex->hwnd
  2786. //lpwm32mpex->uMsg
  2787. //lpwm32mpex->uParam
  2788. //lpwm32mpex->lParam
  2789. //lpwm32mpex->Param16.WndProc.wMsg
  2790. //lpwm32mpex->Param16.WndProc.wParam
  2791. //lpwm32mpex->Param16.WndProc.lParam
  2792. //&lpwm32mpex->lReturn
  2793. //lpwm32mpex->fThunk
  2794. //
  2795. INT cb;
  2796. INT i;
  2797. HMEM16 hMem16 = 0;
  2798. LPBYTE lpMem32 = 0;
  2799. LPBYTE lpMem16 = 0;
  2800. VPVOID vp;
  2801. if (lpwm32mpex->fThunk) {
  2802. if (lpwm32mpex->uParam == IR_STRING) {
  2803. lpMem32 = GlobalLock((HANDLE)lpwm32mpex->lParam);
  2804. if (lpMem32 == NULL)
  2805. goto Err;
  2806. cb = strlen( lpMem32 ) + 1;
  2807. if (!(lpwm32mpex->Parm16.WndProc.lParam = GlobalAllocLock16(GMEM_MOVEABLE | GMEM_SHARE | GMEM_ZEROINIT, cb, &hMem16 )))
  2808. goto Err;
  2809. putstr16((VPSZ)lpwm32mpex->Parm16.WndProc.lParam, lpMem32, cb);
  2810. LOW( lpwm32mpex->Parm16.WndProc.lParam ) = hMem16;
  2811. HIW( lpwm32mpex->Parm16.WndProc.lParam ) = 0; // must be zero
  2812. GlobalUnlock( (HANDLE)lpwm32mpex->lParam );
  2813. GlobalUnlock16( hMem16 );
  2814. }
  2815. /**** IR_STRINGEX ****/
  2816. else if ( lpwm32mpex->uParam == IR_STRINGEX ) {
  2817. LPSTRINGEXSTRUCT pss32;
  2818. PSTRINGEXSTRUCT16 pss16;
  2819. lpMem32 = GlobalLock((HANDLE)lpwm32mpex->lParam);
  2820. if (lpMem32 == NULL)
  2821. goto Err;
  2822. pss32 = (LPSTRINGEXSTRUCT)lpMem32;
  2823. cb = pss32->dwSize;
  2824. if ( cb >= ( 64 * K )) {
  2825. // It's problem !
  2826. LOGDEBUG(0,(" WOW:: WM_IME_REPORT:IR_STRINGEX data size must be less than 64K on WOW. cb = %d\n", cb ));
  2827. /** goto Err; **/
  2828. }
  2829. // Shuld I pack size of this structure ?
  2830. if (!(vp = GlobalAllocLock16(GMEM_MOVEABLE | GMEM_SHARE | GMEM_ZEROINIT, cb, &hMem16 )))
  2831. return FALSE;
  2832. GETVDMPTR(vp, cb, lpMem16 );
  2833. pss16 = (PSTRINGEXSTRUCT16)lpMem16;
  2834. STOREDWORD( pss16->dwSize, pss32->dwSize );
  2835. STOREWORD( pss16->uDeterminePos, pss32->uDeterminePos );
  2836. STOREWORD( pss16->uDetermineDelimPos, pss32->uDetermineDelimPos );
  2837. STOREWORD( pss16->uYomiPos, pss32->uYomiPos );
  2838. STOREWORD( pss16->uYomiDelimPos, pss32->uYomiDelimPos );
  2839. if ( pss32->uDeterminePos ) {
  2840. cb = strlen( (LPBYTE)&lpMem32[ pss32->uDeterminePos ] );
  2841. RtlCopyMemory( &lpMem16[ pss16->uDeterminePos ],
  2842. &lpMem32[ pss32->uDeterminePos ], cb + 1 );
  2843. if ( pss32->uDetermineDelimPos ) {
  2844. for ( i = 0; pss32->uDetermineDelimPos + i * sizeof(INT) < pss32->dwSize; i++ ) {
  2845. WORDOF16( lpMem16[ pss16->uDetermineDelimPos ], i ) = (WORD)
  2846. INTOF( lpMem32[ pss32->uDetermineDelimPos ], i );
  2847. if ( INTOF( lpMem32[ pss32->uDetermineDelimPos ], i ) >= cb )
  2848. break;
  2849. }
  2850. }
  2851. }
  2852. if ( pss32->uYomiPos ) {
  2853. cb = strlen( (LPBYTE)&lpMem32[ pss32->uYomiPos ] );
  2854. RtlCopyMemory( &lpMem16[ pss16->uYomiPos ],
  2855. &lpMem32[ pss32->uYomiPos ], cb + 1 );
  2856. if ( pss32->uYomiDelimPos ) {
  2857. for ( i = 0; pss32->uYomiDelimPos + i * sizeof(INT) < pss32->dwSize; i++ ) {
  2858. WORDOF16( lpMem16[ pss16->uYomiDelimPos ], i ) = (WORD)
  2859. INTOF( lpMem32[ pss32->uYomiDelimPos ], i );
  2860. if ( INTOF( lpMem32[ pss32->uYomiDelimPos ], i ) >= cb )
  2861. break;
  2862. }
  2863. }
  2864. }
  2865. FLUSHVDMPTR(vp, cb, lpMem16);
  2866. FREEVDMPTR(lpMem16);
  2867. LOW( lpwm32mpex->Parm16.WndProc.lParam ) = hMem16;
  2868. HIW( lpwm32mpex->Parm16.WndProc.lParam ) = 0; // must be zero
  2869. GlobalUnlock( (HANDLE)lpwm32mpex->lParam );
  2870. GlobalUnlock16( hMem16 );
  2871. }
  2872. /**** IR_UNDETERMINE ****/
  2873. else if (lpwm32mpex->uParam == IR_UNDETERMINE) {
  2874. PUNDETERMINESTRUCT16 pus16;
  2875. LPUNDETERMINESTRUCT pus32;
  2876. lpMem32 = GlobalLock( (HANDLE)lpwm32mpex->lParam );
  2877. if (lpMem32 == NULL)
  2878. goto Err;
  2879. pus32 = (LPUNDETERMINESTRUCT)lpMem32;
  2880. cb = pus32->dwSize;
  2881. if ( cb >= ( 64 * K )) {
  2882. // It's problem !
  2883. LOGDEBUG(0,(" WOW:: WM_IME_REPORT:IR_UNDETERMINE data size must be less than 64K on WOW. cb = %d\n", cb ));
  2884. /** goto Err; **/
  2885. }
  2886. if (!( vp = GlobalAllocLock16(GMEM_MOVEABLE | GMEM_SHARE | GMEM_ZEROINIT, cb, &hMem16 )))
  2887. goto Err;
  2888. GETVDMPTR(vp, cb, lpMem16 );
  2889. pus16 = (PUNDETERMINESTRUCT16)lpMem16;
  2890. STOREDWORD( pus16->dwSize, (pus32)->dwSize );
  2891. STOREWORD( pus16->uDefIMESize, (pus32)->uDefIMESize );
  2892. STOREWORD( pus16->uDefIMEPos, (pus32)->uDefIMEPos );
  2893. STOREWORD( pus16->uUndetTextLen, (pus32)->uUndetTextLen );
  2894. STOREWORD( pus16->uUndetTextPos, (pus32)->uUndetTextPos );
  2895. STOREWORD( pus16->uUndetAttrPos, (pus32)->uUndetAttrPos );
  2896. STOREWORD( pus16->uCursorPos, (pus32)->uCursorPos );
  2897. STOREWORD( pus16->uDeltaStart, (pus32)->uDeltaStart );
  2898. STOREWORD( pus16->uDetermineTextLen, (pus32)->uDetermineTextLen );
  2899. STOREWORD( pus16->uDetermineTextPos, (pus32)->uDetermineTextPos );
  2900. STOREWORD( pus16->uDetermineDelimPos, (pus32)->uDetermineDelimPos );
  2901. STOREWORD( pus16->uYomiTextLen, (pus32)->uYomiTextLen );
  2902. STOREWORD( pus16->uYomiTextPos, (pus32)->uYomiTextPos );
  2903. STOREWORD( pus16->uYomiDelimPos, (pus32)->uYomiDelimPos );
  2904. // dada copy
  2905. RtlCopyMemory( &lpMem16[ sizeof(UNDETERMINESTRUCT) ],
  2906. &lpMem32[ sizeof(UNDETERMINESTRUCT) ],
  2907. cb - sizeof( UNDETERMINESTRUCT ));
  2908. //adjustment
  2909. if ( pus32->uDetermineDelimPos ) {
  2910. cb = pus32->uDetermineTextLen;
  2911. for ( i = 0; pus32->uDetermineDelimPos + i * sizeof(INT) < pus32->dwSize; i++ ) {
  2912. INTOF( lpMem16[ pus16->uDetermineDelimPos ], i ) = 0;
  2913. WORDOF16( lpMem16[ pus16->uDetermineDelimPos ], i ) = (WORD)
  2914. INTOF( lpMem32[ pus32->uDetermineDelimPos ], i );
  2915. if ( INTOF( lpMem32[ pus32->uDetermineDelimPos ], i ) >= cb )
  2916. break;
  2917. }
  2918. }
  2919. if ( pus32->uYomiDelimPos ) {
  2920. cb = pus32->uYomiTextLen;
  2921. for ( i = 0; pus32->uYomiDelimPos + i * sizeof(INT) < pus32->dwSize; i++ ) {
  2922. INTOF( lpMem16[ pus16->uYomiDelimPos ], i ) = 0;
  2923. WORDOF16( lpMem16[ pus16->uYomiDelimPos ], i ) = (WORD)
  2924. INTOF( lpMem32[ pus32->uYomiDelimPos ], i );
  2925. if ( INTOF( lpMem32[ pus32->uYomiDelimPos ], i ) >= cb )
  2926. break;
  2927. }
  2928. }
  2929. FLUSHVDMPTR(vp, cb, lpMem16);
  2930. FREEVDMPTR(lpMem16);
  2931. LOW( lpwm32mpex->Parm16.WndProc.lParam ) = hMem16;
  2932. HIW( lpwm32mpex->Parm16.WndProc.lParam ) = 0; // must be zero
  2933. GlobalUnlock( (HANDLE)lpwm32mpex->lParam );
  2934. GlobalUnlock16( hMem16 );
  2935. }
  2936. }
  2937. else { // fThunk
  2938. if (lpwm32mpex->Parm16.WndProc.lParam) {
  2939. GlobalUnlockFree16(GlobalLock16(LOW(lpwm32mpex->Parm16.WndProc.lParam), NULL));
  2940. }
  2941. }
  2942. return (TRUE);
  2943. Err:
  2944. if ( lpMem32 && lpwm32mpex->lParam )
  2945. GlobalUnlock( (HANDLE)lpwm32mpex->lParam );
  2946. return FALSE;
  2947. }
  2948. #endif // FE_IME