Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

700 lines
16 KiB

  1. /*++
  2. *
  3. * Windows NT v5.0 WOW
  4. *
  5. * Copyright (c) 1997, Microsoft Corporation
  6. *
  7. * WIN95.C
  8. *
  9. * WOW32 Hand-coded (as opposed to interpreted) thunks for new-for-Win95
  10. * exports.
  11. *
  12. * History:
  13. * 16 Feb 97 Created davehart
  14. --*/
  15. #include "precomp.h"
  16. #pragma hdrstop
  17. MODNAME(win95.c);
  18. ULONG FASTCALL WU32TileWindows(PVDMFRAME pFrame)
  19. {
  20. return W32TileOrCascadeWindows(pFrame, TileWindows);
  21. }
  22. ULONG FASTCALL WU32CascadeWindows(PVDMFRAME pFrame)
  23. {
  24. return W32TileOrCascadeWindows(pFrame, CascadeWindows);
  25. }
  26. ULONG FASTCALL W32TileOrCascadeWindows(PVDMFRAME pFrame, PFNTILECASCADEWINDOWS pfnWin32)
  27. {
  28. register PCASCADEWINDOWS16 parg16;
  29. ULONG ul;
  30. RECT rc;
  31. PRECT prc;
  32. HWND ahwnd[8];
  33. DWORD chwnd;
  34. HWND16 UNALIGNED *phwnd16;
  35. HWND *phwnd;
  36. GETARGPTR(pFrame, sizeof(*parg16), parg16);
  37. chwnd = parg16->chwnd;
  38. if (parg16->lpRect) {
  39. GETRECT16(parg16->lpRect, &rc);
  40. prc = &rc;
  41. } else {
  42. prc = NULL;
  43. }
  44. if (parg16->ahwnd) {
  45. phwnd = STACKORHEAPALLOC( chwnd * sizeof(HWND), sizeof(ahwnd), ahwnd);
  46. phwnd16 = VDMPTR(parg16->ahwnd, chwnd * sizeof(HWND16));
  47. for (ul = 0; ul < chwnd; ul++) {
  48. phwnd[ul] = HWND32(phwnd16[ul]);
  49. }
  50. FREEVDMPTR(phwnd16);
  51. } else {
  52. phwnd = NULL;
  53. }
  54. ul = (*pfnWin32)(
  55. HWND32(parg16->hwndParent),
  56. parg16->wFlags,
  57. prc,
  58. chwnd,
  59. phwnd
  60. );
  61. //
  62. // Memory movement may have occurred due to message activity,
  63. // so throw away flat pointers to 16-bit memory.
  64. //
  65. FREEARGPTR(parg16);
  66. if (phwnd) {
  67. STACKORHEAPFREE(phwnd, ahwnd);
  68. }
  69. return ul;
  70. }
  71. ULONG FASTCALL WU32DrawAnimatedRects(PVDMFRAME pFrame)
  72. {
  73. register PDRAWANIMATEDRECTS16 parg16;
  74. ULONG ul;
  75. RECT rcFrom, rcTo;
  76. GETARGPTR(pFrame, sizeof(*parg16), parg16);
  77. GETRECT16(parg16->lprcStart, &rcFrom);
  78. GETRECT16(parg16->lprcEnd, &rcTo);
  79. ul = DrawAnimatedRects(
  80. HWND32(parg16->hwndClip),
  81. parg16->idAnimation,
  82. &rcFrom,
  83. &rcTo
  84. );
  85. FREEARGPTR(parg16);
  86. return ul;
  87. }
  88. ULONG FASTCALL WU32DrawCaption(PVDMFRAME pFrame)
  89. {
  90. register PDRAWCAPTION16 parg16;
  91. ULONG ul;
  92. RECT rc;
  93. GETARGPTR(pFrame, sizeof(*parg16), parg16);
  94. GETRECT16(parg16->lprc, &rc);
  95. ul = DrawCaption(
  96. HWND32(parg16->hwnd),
  97. HDC32(parg16->hdc),
  98. &rc,
  99. parg16->wFlags
  100. );
  101. FREEARGPTR(parg16);
  102. return ul;
  103. }
  104. ULONG FASTCALL WU32DrawEdge(PVDMFRAME pFrame)
  105. {
  106. return W32DrawEdgeOrFrameControl(pFrame, DrawEdge);
  107. }
  108. ULONG FASTCALL WU32DrawFrameControl(PVDMFRAME pFrame)
  109. {
  110. return W32DrawEdgeOrFrameControl(pFrame, DrawFrameControl);
  111. }
  112. ULONG FASTCALL W32DrawEdgeOrFrameControl(PVDMFRAME pFrame, PFNDRAWEDGEFRAMECONTROL pfnWin32)
  113. {
  114. register PDRAWEDGE16 parg16;
  115. ULONG ul;
  116. RECT rc;
  117. GETARGPTR(pFrame, sizeof(*parg16), parg16);
  118. GETRECT16(parg16->lprc, &rc);
  119. ul = (*pfnWin32)(
  120. HDC32(parg16->hdc),
  121. &rc,
  122. parg16->wEdge,
  123. parg16->wFlags
  124. );
  125. PUTRECT16(parg16->lprc, &rc);
  126. FREEARGPTR(parg16);
  127. return ul;
  128. }
  129. ULONG FASTCALL WU32DrawTextEx(PVDMFRAME pFrame)
  130. {
  131. register PDRAWTEXTEX16 parg16;
  132. ULONG ul;
  133. PSZ psz;
  134. RECT rc;
  135. DRAWTEXTPARAMS dtp, *pdtp;
  136. PDRAWTEXTPARAMS16 pdtp16;
  137. GETARGPTR(pFrame, sizeof(*parg16), parg16);
  138. GETVARSTRPTR(parg16->lpchText, parg16->cchText, psz);
  139. GETRECT16(parg16->lprc, &rc);
  140. if ( (parg16->lpDTparams) &&
  141. (pdtp16 = VDMPTR(parg16->lpDTparams, sizeof(DRAWTEXTPARAMS16))) ) {
  142. pdtp = &dtp;
  143. dtp.cbSize = sizeof(dtp);
  144. dtp.iTabLength = pdtp16->iTabLength;
  145. dtp.iLeftMargin = pdtp16->iLeftMargin;
  146. dtp.iRightMargin = pdtp16->iRightMargin;
  147. dtp.uiLengthDrawn = 0;
  148. } else {
  149. pdtp = NULL;
  150. }
  151. ul = DrawTextEx(
  152. HDC32(parg16->hdc),
  153. psz,
  154. parg16->cchText,
  155. &rc,
  156. parg16->dwDTformat,
  157. pdtp
  158. );
  159. if (pdtp) {
  160. pdtp16->uiLengthDrawn = (WORD)dtp.uiLengthDrawn;
  161. }
  162. FREEVDMPTR(pdtp16);
  163. FREEVDMPTR(psz);
  164. FREEARGPTR(parg16);
  165. return ul;
  166. }
  167. ULONG FASTCALL WU32GetIconInfo(PVDMFRAME pFrame)
  168. {
  169. register PGETICONINFO16 parg16;
  170. ULONG ul;
  171. ICONINFO ii;
  172. PICONINFO16 pii16;
  173. GETARGPTR(pFrame, sizeof(*parg16), parg16);
  174. ul = GetIconInfo(
  175. HICON32(parg16->hicon),
  176. &ii
  177. );
  178. pii16 = VDMPTR(parg16->lpiconinfo, sizeof(*pii16));
  179. pii16->fIcon = (BOOL16)ii.fIcon;
  180. pii16->xHotspot = (INT16)ii.xHotspot;
  181. pii16->yHotspot = (INT16)ii.yHotspot;
  182. pii16->hbmMask = GETHBITMAP16(ii.hbmMask);
  183. pii16->hbmColor = GETHBITMAP16(ii.hbmColor);
  184. FREEVDMPTR(pii16);
  185. FREEARGPTR(pFrame);
  186. return ul;
  187. }
  188. ULONG FASTCALL WU32GetMenuItemInfo(PVDMFRAME pFrame)
  189. {
  190. register PGETMENUITEMINFO16 parg16;
  191. ULONG ul;
  192. MENUITEMINFO mii;
  193. PMENUITEMINFO16 pmii16;
  194. GETARGPTR(pFrame, sizeof(*parg16), parg16);
  195. GETVDMPTR(parg16->lpmii, sizeof(*pmii16), pmii16);
  196. mii.cbSize = sizeof(mii);
  197. mii.fMask = pmii16->fMask;
  198. FREEVDMPTR(pmii16);
  199. ul = GetMenuItemInfo(
  200. HMENU32(parg16->hmenu),
  201. parg16->wIndex,
  202. parg16->fByPosition,
  203. &mii
  204. );
  205. putmenuiteminfo16(parg16->lpmii, &mii);
  206. FREEARGPTR(pFrame);
  207. return ul;
  208. }
  209. ULONG FASTCALL WU32InsertMenuItem(PVDMFRAME pFrame)
  210. {
  211. register PINSERTMENUITEM16 parg16;
  212. ULONG ul;
  213. MENUITEMINFO mii;
  214. GETARGPTR(pFrame, sizeof(*parg16), parg16);
  215. getmenuiteminfo16(parg16->lpmii, &mii);
  216. ul = InsertMenuItem(
  217. HMENU32(parg16->hmenu),
  218. parg16->wIndex,
  219. parg16->fByPosition,
  220. &mii
  221. );
  222. FREEARGPTR(pFrame);
  223. return ul;
  224. }
  225. ULONG FASTCALL WU32SetMenuItemInfo(PVDMFRAME pFrame)
  226. {
  227. register PSETMENUITEMINFO16 parg16;
  228. ULONG ul;
  229. MENUITEMINFO mii;
  230. GETARGPTR(pFrame, sizeof(*parg16), parg16);
  231. getmenuiteminfo16(parg16->lpmii, &mii);
  232. ul = SetMenuItemInfo(
  233. HMENU32(parg16->hmenu),
  234. parg16->wIndex,
  235. parg16->fByPosition,
  236. &mii
  237. );
  238. FREEARGPTR(pFrame);
  239. return ul;
  240. }
  241. ULONG FASTCALL WU32GetMenuItemRect(PVDMFRAME pFrame)
  242. {
  243. register PGETMENUITEMRECT16 parg16;
  244. ULONG ul;
  245. RECT rc;
  246. GETARGPTR(pFrame, sizeof(*parg16), parg16);
  247. ul = GetMenuItemRect(
  248. HWND32(parg16->hwnd),
  249. HMENU32(parg16->hmenu),
  250. parg16->wIndex,
  251. &rc
  252. );
  253. PUTRECT16(parg16->lprcScreen, &rc);
  254. FREEARGPTR(pFrame);
  255. return ul;
  256. }
  257. ULONG FASTCALL WU32TrackPopupMenuEx(PVDMFRAME pFrame)
  258. {
  259. register PTRACKPOPUPMENUEX16 parg16;
  260. ULONG ul;
  261. TPMPARAMS tpmp;
  262. LPTPMPARAMS lptpmp;
  263. VPRECT16 vprcExclude;
  264. GETARGPTR(pFrame, sizeof(*parg16), parg16);
  265. if (parg16->lpTpm) {
  266. lptpmp = &tpmp;
  267. tpmp.cbSize = sizeof(tpmp);
  268. vprcExclude = parg16->lpTpm + offsetof(TPMPARAMS16, rcExclude);
  269. GETRECT16(vprcExclude, &tpmp.rcExclude);
  270. } else {
  271. lptpmp = NULL;
  272. }
  273. ul = TrackPopupMenuEx(
  274. HMENU32(parg16->hmenu),
  275. parg16->wFlags,
  276. parg16->x,
  277. parg16->y,
  278. HWND32(parg16->hwndOwner),
  279. lptpmp
  280. );
  281. FREEARGPTR(pFrame);
  282. return ul;
  283. }
  284. ULONG FASTCALL WG32GetCharacterPlacement(PVDMFRAME pFrame)
  285. {
  286. register PGETCHARACTERPLACEMENT16 parg16;
  287. ULONG ul;
  288. PSZ pszText;
  289. PGCP_RESULTS16 pgcp16;
  290. GCP_RESULTS gcp;
  291. //
  292. // Thankfully on Win95 the 16-bit GCP_RESULTS structure
  293. // points to 32-bit ints, so the structure thunking
  294. // is trivial.
  295. //
  296. GETARGPTR(pFrame, sizeof(*parg16), parg16);
  297. GETPSZPTR(parg16->lpszText, pszText);
  298. GETVDMPTR(parg16->lpResults, sizeof(*pgcp16), pgcp16);
  299. gcp.lStructSize = sizeof gcp;
  300. gcp.nGlyphs = pgcp16->nGlyphs;
  301. gcp.nMaxFit = pgcp16->nMaxFit;
  302. GETOPTPTR(pgcp16->lpOutString, 1, gcp.lpOutString);
  303. GETOPTPTR(pgcp16->lpOrder, 4, gcp.lpOrder);
  304. GETOPTPTR(pgcp16->lpDx, 4, gcp.lpDx);
  305. GETOPTPTR(pgcp16->lpCaretPos, 4, gcp.lpCaretPos);
  306. GETOPTPTR(pgcp16->lpClass, 1, gcp.lpClass);
  307. GETOPTPTR(pgcp16->lpGlyphs, 4, gcp.lpGlyphs);
  308. ul = GetCharacterPlacement(
  309. HDC32(parg16->hdc),
  310. pszText,
  311. parg16->wCount,
  312. parg16->wMaxExtent,
  313. &gcp,
  314. parg16->dwFlags
  315. );
  316. pgcp16->nGlyphs = (SHORT)gcp.nGlyphs;
  317. pgcp16->nMaxFit = (SHORT)gcp.nMaxFit;
  318. FREEARGPTR(pFrame);
  319. return ul;
  320. }
  321. //
  322. // On Win95, GetProductName returns "Windows 95".
  323. // We'll return "Windows NT" unless something forces us
  324. // to be identical.
  325. //
  326. // Two flavors: call with cbBuffer == 0 and it returns
  327. // the length required minus 1 (a bug I think). Call with
  328. // cbBuffer > 0 and it copies as much as possible and returns
  329. // lpBuffer.
  330. //
  331. ULONG FASTCALL WK32GetProductName(PVDMFRAME pFrame)
  332. {
  333. register PGETPRODUCTNAME16 parg16;
  334. ULONG ul;
  335. PSZ pszBuffer;
  336. static char szProductName[] = "Windows NT";
  337. GETARGPTR(pFrame, sizeof(*parg16), parg16);
  338. if (0 == parg16->cbBuffer) {
  339. ul = (sizeof szProductName) - 1;
  340. } else {
  341. GETVDMPTR(parg16->lpBuffer, parg16->cbBuffer, pszBuffer);
  342. WOW32VERIFY(pszBuffer == lstrcpyn(pszBuffer, szProductName, parg16->cbBuffer));
  343. FREEVDMPTR(pszBuffer);
  344. ul = parg16->lpBuffer;
  345. }
  346. FREEARGPTR(pFrame);
  347. return ul;
  348. }
  349. typedef struct _tagWOWDRAWSTATECALLBACK {
  350. VPVOID vpfnCallback;
  351. LPARAM lparamUser;
  352. } WOWDRAWSTATECALLBACK, *PWOWDRAWSTATECALLBACK;
  353. BOOL CALLBACK WOWDrawStateCallback(HDC hdc, LPARAM lData, WPARAM wData, int cx, int cy)
  354. {
  355. PWOWDRAWSTATECALLBACK pwds = (PWOWDRAWSTATECALLBACK) lData;
  356. ULONG ul;
  357. WORD awCallbackArgs[6];
  358. awCallbackArgs[0] = (WORD)(SHORT)cy;
  359. awCallbackArgs[1] = (WORD)(SHORT)cx;
  360. awCallbackArgs[2] = (WORD)wData;
  361. awCallbackArgs[3] = LOWORD(pwds->lparamUser);
  362. awCallbackArgs[4] = HIWORD(pwds->lparamUser);
  363. awCallbackArgs[5] = GETHDC16(hdc);
  364. WOWCallback16Ex(
  365. pwds->vpfnCallback,
  366. WCB16_PASCAL,
  367. sizeof awCallbackArgs,
  368. awCallbackArgs,
  369. &ul // retcode filled into ul
  370. );
  371. return LOWORD(ul);
  372. }
  373. ULONG FASTCALL WU32DrawState(PVDMFRAME pFrame)
  374. {
  375. register PDRAWSTATE16 parg16;
  376. ULONG ul;
  377. WOWDRAWSTATECALLBACK wds;
  378. DRAWSTATEPROC pDrawStateCallback = NULL;
  379. LPARAM lData;
  380. HBRUSH hbr;
  381. GETARGPTR(pFrame, sizeof(*parg16), parg16);
  382. switch (parg16->uFlags & DST_TYPEMASK) {
  383. case DST_COMPLEX:
  384. if (parg16->pfnCallBack) {
  385. wds.vpfnCallback = parg16->pfnCallBack;
  386. wds.lparamUser = parg16->lData;
  387. lData = (LPARAM) &wds;
  388. pDrawStateCallback = (DRAWSTATEPROC) WOWDrawStateCallback;
  389. }
  390. break;
  391. case DST_TEXT:
  392. case DST_PREFIXTEXT:
  393. lData = (LPARAM) VDMPTR(parg16->lData, parg16->wData);
  394. break;
  395. case DST_ICON:
  396. lData = (LPARAM) HICON32( (WORD) parg16->lData );
  397. break;
  398. case DST_BITMAP:
  399. lData = (LPARAM) HBITMAP32(parg16->lData);
  400. break;
  401. default:
  402. WOW32WARNMSGF(FALSE, ("WOW32: Unknown DST_ code to DrawState %x.\n",
  403. parg16->uFlags & DST_TYPEMASK));
  404. }
  405. hbr = (parg16->uFlags & DSS_MONO)
  406. ? HBRUSH32(parg16->hbrFore)
  407. : NULL;
  408. ul = GETBOOL16(DrawState(
  409. HDC32(parg16->hdcDraw),
  410. hbr,
  411. pDrawStateCallback,
  412. lData,
  413. parg16->wData,
  414. parg16->x,
  415. parg16->y,
  416. parg16->cx,
  417. parg16->cy,
  418. parg16->uFlags
  419. ));
  420. FREEARGPTR(pFrame);
  421. return ul;
  422. }
  423. ULONG FASTCALL WU32GetAppVer(PVDMFRAME pFrame)
  424. {
  425. return ((PTDB)SEGPTR(pFrame->wTDB,0))->TDB_ExpWinVer;
  426. }
  427. ULONG FASTCALL WU32CopyImage(PVDMFRAME pFrame)
  428. {
  429. register PCOPYIMAGE16 parg16;
  430. ULONG ul;
  431. BOOL fIconCursor; // as opposed to bitmap
  432. GETARGPTR(pFrame, sizeof(*parg16), parg16);
  433. //
  434. // NOTE first parameter to Win16 CopyImage is hinstOwner,
  435. // which isn't a parameter to Win32 CopyImage. It may
  436. // be that we'll need to special-case LR_COPYFROMRESOURCE
  437. // to work correctly.
  438. //
  439. fIconCursor = (parg16->wType != IMAGE_BITMAP);
  440. ul = (ULONG) CopyImage(
  441. (fIconCursor)
  442. ? HICON32(parg16->hImage)
  443. : HBITMAP32(parg16->hImage),
  444. parg16->wType,
  445. parg16->cxNew,
  446. parg16->cyNew,
  447. parg16->wFlags
  448. );
  449. ul = (fIconCursor)
  450. ? GETHICON16(ul)
  451. : GETHBITMAP16(ul);
  452. return ul;
  453. }
  454. //
  455. // WowMsgBoxIndirectCallback is called by User32 when a 16-bit app
  456. // calls MessageBoxIndirect and specifies a help callback proc.
  457. // User32 passes the 16:16 callback address to us along with a
  458. // flat pointer to the HELPINFO structure to pass to the callback.
  459. //
  460. VOID FASTCALL WowMsgBoxIndirectCallback(DWORD vpfnCallback, LPHELPINFO lpHelpInfo)
  461. {
  462. VPVOID vpHelpInfo16;
  463. LPHELPINFO lpHelpInfo16;
  464. //
  465. // As best as I can tell Win95 passes the WIN32 HELPINFO struct back to the
  466. // 16-bit callback proc (i.e. there is no HELPINFO16).
  467. //
  468. // be sure allocation size matches stackfree16() size below
  469. vpHelpInfo16 = stackalloc16( sizeof(*lpHelpInfo16) );
  470. GETVDMPTR(vpHelpInfo16, sizeof(*lpHelpInfo16), lpHelpInfo16);
  471. RtlCopyMemory(lpHelpInfo16, lpHelpInfo, sizeof(*lpHelpInfo16));
  472. FREEVDMPTR(lpHelpInfo16);
  473. WOWCallback16(
  474. vpfnCallback,
  475. vpHelpInfo16
  476. );
  477. if(vpHelpInfo16) {
  478. stackfree16(vpHelpInfo16, sizeof(*lpHelpInfo16));
  479. }
  480. }
  481. ULONG FASTCALL WU32MessageBoxIndirect(PVDMFRAME pFrame)
  482. {
  483. register PMESSAGEBOXINDIRECT16 parg16;
  484. ULONG ul;
  485. PMSGBOXPARAMS16 pmbp16;
  486. MSGBOXPARAMS mbp;
  487. GETARGPTR(pFrame, sizeof(*parg16), parg16);
  488. GETVDMPTR(parg16->lpmbp, sizeof *pmbp16, pmbp16);
  489. mbp.cbSize = sizeof mbp;
  490. mbp.hwndOwner = HWND32(pmbp16->hwndOwner);
  491. mbp.hInstance = HINSTRES32(pmbp16->hInstance);
  492. GETPSZIDPTR(pmbp16->lpszText, mbp.lpszText);
  493. GETPSZIDPTR(pmbp16->lpszCaption, mbp.lpszCaption);
  494. mbp.dwStyle = pmbp16->dwStyle;
  495. GETPSZIDPTR(pmbp16->lpszIcon, mbp.lpszIcon);
  496. mbp.dwContextHelpId = pmbp16->dwContextHelpId;
  497. if (pmbp16->vpfnMsgBoxCallback) {
  498. MarkWOWProc(pmbp16->vpfnMsgBoxCallback, mbp.lpfnMsgBoxCallback)
  499. } else {
  500. mbp.lpfnMsgBoxCallback = 0;
  501. }
  502. mbp.dwLanguageId = pmbp16->dwLanguageId;
  503. ul = GETINT16( MessageBoxIndirect(&mbp) );
  504. FREEARGPTR(pFrame);
  505. return ul;
  506. }
  507. //
  508. // was in wow.it: HGDI CreateEnhMetaFile(HGDI, PTR, PTR, PTR);
  509. // Using real thunk to ensure Win32 curdir matches Win16.
  510. //
  511. ULONG FASTCALL WG32CreateEnhMetaFile(PVDMFRAME pFrame)
  512. {
  513. register PCREATEENHMETAFILE16 parg16;
  514. ULONG ul;
  515. LPCSTR lpszFile, lpszDescription;
  516. CONST RECT *prclFrame;
  517. GETARGPTR(pFrame, sizeof(*parg16), parg16);
  518. GETVDMPTR(parg16->lpszFile, 1, lpszFile);
  519. // note lpszDescription is really two SZs with extra terminator
  520. GETVDMPTR(parg16->lpszDescription, 3, lpszDescription);
  521. // note lprclFrame is a LPRECTL, a Win32 RECT
  522. GETVDMPTR(parg16->lprclFrame, sizeof(*prclFrame), prclFrame);
  523. //
  524. // Make sure the Win32 current directory matches this task's.
  525. //
  526. UpdateDosCurrentDirectory(DIR_DOS_TO_NT);
  527. ul = GETHDC16(CreateEnhMetaFile(
  528. HDC32(parg16->hdcRef),
  529. lpszFile,
  530. prclFrame,
  531. lpszDescription
  532. ));
  533. FREEVDMPTR(prclFrame);
  534. FREEVDMPTR(lpszDescription);
  535. FREEVDMPTR(lpszFile);
  536. return ul;
  537. }