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.

1816 lines
56 KiB

  1. /*++
  2. *
  3. * WOW v1.0
  4. *
  5. * Copyright (c) 1991, Microsoft Corporation
  6. *
  7. * WSTRUC.C
  8. * WOW32 16-bit structure conversion support
  9. *
  10. * History:
  11. * Created 27-Jan-1991 by Jeff Parsons (jeffpar)
  12. * Wrote DDE data conversion routines, etc Chandan CHauhan (ChandanC)
  13. *
  14. --*/
  15. #include "precomp.h"
  16. #pragma hdrstop
  17. #include "wowshlp.h"
  18. #ifdef FE_IME
  19. #include "ime.h"
  20. #endif // FE_IME
  21. MODNAME(wstruc.c);
  22. /* Structure copying functions
  23. *
  24. * For input structures, there are GETxxxx16 macros; for output structures
  25. * there are PUTxxxx16 macros. Most or all of these macros will simply call
  26. * the corresponding function below. Nothing magical here....
  27. */
  28. VOID getstr16(VPSZ vpszSrc, LPSZ lpszDst, INT cb)
  29. {
  30. PSZ pszSrc;
  31. if (cb == 0)
  32. return;
  33. if (cb != -1)
  34. GETVDMPTR(vpszSrc, cb, pszSrc);
  35. else {
  36. GETPSZPTR(vpszSrc, pszSrc);
  37. cb = strlen(pszSrc)+1;
  38. }
  39. RtlCopyMemory(lpszDst, pszSrc, cb);
  40. FREEVDMPTR(pszSrc);
  41. RETURN(NOTHING);
  42. }
  43. VOID putstr16(VPSZ vpszDst, LPCSTR lpszSrc, INT cb)
  44. {
  45. PSZ pszDst;
  46. if (cb == 0)
  47. return;
  48. if (cb == -1)
  49. cb = strlen(lpszSrc)+1;
  50. GETVDMPTR(vpszDst, cb, pszDst);
  51. RtlCopyMemory(pszDst, lpszSrc, cb);
  52. FLUSHVDMPTR(vpszDst, cb, pszDst);
  53. FREEVDMPTR(pszDst);
  54. RETURN(NOTHING);
  55. }
  56. LPRECT getrect16(VPRECT16 vpRect, LPRECT lpRect)
  57. {
  58. register PRECT16 pRect16;
  59. // Some APIs (eg, InvalidateRect) have OPTIONAL input pointers -JTP
  60. if (vpRect) {
  61. GETVDMPTR(vpRect, sizeof(RECT16), pRect16);
  62. lpRect->left = FETCHSHORT(pRect16->left);
  63. lpRect->top = FETCHSHORT(pRect16->top);
  64. lpRect->right = FETCHSHORT(pRect16->right);
  65. lpRect->bottom = FETCHSHORT(pRect16->bottom);
  66. FREEVDMPTR(pRect16);
  67. } else {
  68. lpRect = NULL;
  69. }
  70. return lpRect;
  71. }
  72. VOID putrect16(VPRECT16 vpRect, LPRECT lpRect)
  73. {
  74. register PRECT16 pRect16;
  75. // Some APIs (ScrollDC may be the only one) have OPTIONAL output pointers
  76. if (vpRect) {
  77. GETVDMPTR(vpRect, sizeof(RECT16), pRect16);
  78. STORESHORT(pRect16->left, (SHORT)lpRect->left);
  79. STORESHORT(pRect16->top, (SHORT)lpRect->top);
  80. STORESHORT(pRect16->right, (SHORT)lpRect->right);
  81. STORESHORT(pRect16->bottom, (SHORT)lpRect->bottom);
  82. FLUSHVDMPTR(vpRect, sizeof(RECT16), pRect16);
  83. FREEVDMPTR(pRect16);
  84. }
  85. }
  86. VOID getpoint16(VPPOINT16 vpPoint, INT c, LPPOINT lpPoint)
  87. {
  88. register PPOINT16 pPoint16;
  89. // The assumption here is that no APIs have OPTIONAL POINT pointers
  90. // (regardless of whether they're input or output) -JTP
  91. WOW32ASSERT(vpPoint);
  92. if (lpPoint) {
  93. GETVDMPTR(vpPoint, sizeof(POINT16), pPoint16);
  94. while (c--) {
  95. lpPoint->x = pPoint16->x;
  96. lpPoint->y = pPoint16->y;
  97. lpPoint++;
  98. pPoint16++; // ZOWIE Batman, you wouldn't be able to increment
  99. } // this pointer if FREEVDMPTR wasn't a no-op! -JTP
  100. FREEVDMPTR(pPoint16);
  101. }
  102. }
  103. VOID putpoint16(VPPOINT16 vpPoint, INT c, LPPOINT lpPoint)
  104. {
  105. INT cb;
  106. PPOINT16 pPoint16ptr;
  107. register PPOINT16 pPoint16;
  108. // The assumption here is that no APIs have OPTIONAL POINT pointers
  109. // (regardless of whether they're input or output) -JTP
  110. WOW32ASSERT(vpPoint);
  111. if (lpPoint) {
  112. GETVDMPTR(vpPoint, sizeof(POINT16), pPoint16);
  113. cb = c;
  114. pPoint16ptr = pPoint16;
  115. while (c--) {
  116. if (lpPoint->x > (LONG)0x7fff)
  117. pPoint16->x = (SHORT)0x7fff;
  118. else if (lpPoint->x < (LONG)0xffff8000)
  119. pPoint16->x = (SHORT)0x8000;
  120. else
  121. pPoint16->x = (SHORT)lpPoint->x;
  122. if (lpPoint->y > (LONG)0x7fff)
  123. pPoint16->y = (SHORT)0x7fff;
  124. else if (lpPoint->y < (LONG)0xffff8000)
  125. pPoint16->y = (SHORT)0x8000;
  126. else
  127. pPoint16->y = (SHORT)lpPoint->y;
  128. lpPoint++;
  129. pPoint16++;
  130. }
  131. FLUSHVDMPTR(vpPoint, cb*sizeof(POINT16), pPoint16ptr);
  132. FREEVDMPTR(pPoint16ptr);
  133. }
  134. }
  135. VOID getintarray16(VPINT16 vpInt, INT c, LPINT lpInt)
  136. {
  137. INT i;
  138. register INT16 *pInt16;
  139. if (lpInt && GETVDMPTR(vpInt, sizeof(INT16)*c, pInt16)) {
  140. for (i=0; i < c; i++) {
  141. lpInt[i] = FETCHSHORT(pInt16[i]);
  142. }
  143. }
  144. FREEVDMPTR(pInt16);
  145. }
  146. //
  147. // getuintarray16
  148. //
  149. // copies an array of 16-bit unsigned words to an array of 32-bit unsigned
  150. // words. the pointer to 32-bit array must be freed by the caller.
  151. //
  152. VOID getuintarray16(VPWORD vp, INT c, PUINT pu)
  153. {
  154. register WORD *pW16;
  155. if (pu && GETVDMPTR(vp, sizeof(WORD)*c, pW16)) {
  156. while (c--) {
  157. pu[c] = FETCHWORD(pW16[c]);
  158. }
  159. FREEVDMPTR(pW16);
  160. }
  161. }
  162. VOID putintarray16(VPINT16 vpInt, INT c, LPINT lpInt)
  163. {
  164. INT i;
  165. register INT16 *pInt16;
  166. if (lpInt && GETVDMPTR(vpInt, sizeof(INT16)*c, pInt16)) {
  167. for (i=0; i < c; i++) {
  168. STOREWORD(pInt16[i], lpInt[i]);
  169. }
  170. FLUSHVDMPTR(vpInt, sizeof(INT16)*c, pInt16);
  171. FREEVDMPTR(pInt16);
  172. }
  173. }
  174. VOID putkerningpairs16(VPKERNINGPAIR16 vpKrn, UINT c, LPKERNINGPAIR lpKrn)
  175. {
  176. UINT i;
  177. register PKERNINGPAIR16 pKrn16;
  178. WOW32ASSERT(vpKrn);
  179. GETVDMPTR(vpKrn, sizeof(KERNINGPAIR16), pKrn16);
  180. for (i=0; i < c; i++) {
  181. pKrn16[i].wFirst = (WORD) lpKrn[i].wFirst;
  182. pKrn16[i].wSecond = (WORD) lpKrn[i].wSecond;
  183. pKrn16[i].iKernAmount = (INT16) lpKrn[i].iKernAmount;
  184. }
  185. FLUSHVDMPTR(vpKrn, sizeof(KERNINGPAIR16), pKrn16);
  186. FREEVDMPTR(pKrn16);
  187. }
  188. // Fill in a 32 bit DRAWITEMSTRUCT from a 16 bit one
  189. VOID getdrawitem16(VPDRAWITEMSTRUCT16 vpDI16, LPDRAWITEMSTRUCT lpDI)
  190. {
  191. register PDRAWITEMSTRUCT16 pDI16;
  192. GETVDMPTR(vpDI16, sizeof(DRAWITEMSTRUCT16), pDI16);
  193. lpDI->CtlType = FETCHWORD(pDI16->CtlType);
  194. lpDI->CtlID = FETCHWORD(pDI16->CtlID);
  195. if ((SHORT)(lpDI->itemID = FETCHWORD(pDI16->itemID)) == -1) {
  196. lpDI->itemID = (UINT)-1;
  197. }
  198. lpDI->itemAction = FETCHWORD(pDI16->itemAction);
  199. lpDI->itemState = FETCHWORD(pDI16->itemState);
  200. lpDI->hwndItem = HWND32(FETCHWORD(pDI16->hwndItem));
  201. lpDI->hDC = HDC32(FETCHWORD(pDI16->hDC));
  202. lpDI->rcItem.left = (SHORT)pDI16->rcItem.left;
  203. lpDI->rcItem.top = (SHORT)pDI16->rcItem.top;
  204. lpDI->rcItem.right = (SHORT)pDI16->rcItem.right;
  205. lpDI->rcItem.bottom = (SHORT)pDI16->rcItem.bottom;
  206. lpDI->itemData = FETCHDWORD(pDI16->itemData);
  207. FREEVDMPTR(pDI16);
  208. return;
  209. }
  210. // Fill in a 16 bit DRAWITEMSTRUCT from a 32 bit one
  211. VOID putdrawitem16(VPDRAWITEMSTRUCT16 vpDI16, LPDRAWITEMSTRUCT lpDI)
  212. {
  213. register PDRAWITEMSTRUCT16 pDI16;
  214. GETVDMPTR(vpDI16, sizeof(DRAWITEMSTRUCT16), pDI16);
  215. STOREWORD(pDI16->CtlType, lpDI->CtlType);
  216. STOREWORD(pDI16->CtlID, lpDI->CtlID);
  217. STOREWORD(pDI16->itemID, lpDI->itemID);
  218. STOREWORD(pDI16->itemAction, lpDI->itemAction);
  219. STOREWORD(pDI16->itemState, lpDI->itemState);
  220. STOREWORD(pDI16->hwndItem, GETHWND16(lpDI->hwndItem));
  221. STOREWORD(pDI16->hDC, GETHDC16(lpDI->hDC));
  222. pDI16->rcItem.left = (SHORT)lpDI->rcItem.left;
  223. pDI16->rcItem.top = (SHORT)lpDI->rcItem.top;
  224. pDI16->rcItem.right = (SHORT)lpDI->rcItem.right;
  225. pDI16->rcItem.bottom = (SHORT)lpDI->rcItem.bottom;
  226. STOREDWORD(pDI16->itemData, lpDI->itemData);
  227. FREEVDMPTR(pDI16);
  228. return;
  229. }
  230. #ifdef NOTUSED
  231. //
  232. // Allocate and fill a 32bit DropFileStruct based on a 16bit one.
  233. // 16 bit structure is not freed.
  234. //
  235. BOOL getdropfilestruct16(HAND16 hand16, PHANDLE phand32)
  236. {
  237. PDROPFILESTRUCT16 lpdfs16;
  238. LPDROPFILESTRUCT lpdfs32;
  239. VPVOID vp;
  240. INT cb;
  241. vp = GlobalLock16(hand16, &cb);
  242. if (vp) {
  243. GETMISCPTR(vp, lpdfs16);
  244. *phand32 = WOWGLOBALALLOC(GMEM_DDESHARE,
  245. cb-sizeof(DROPFILESTRUCT16)+
  246. sizeof(DROPFILESTRUCT));
  247. if (*phand32) {
  248. lpdfs32 = GlobalLock(*phand32);
  249. lpdfs32->pFiles = sizeof(DROPFILESTRUCT);
  250. lpdfs32->pt.x = lpdfs16->x;
  251. lpdfs32->pt.y = lpdfs16->y;
  252. lpdfs32->fNC = lpdfs16->fNC;
  253. lpdfs32->fWide = FALSE;
  254. RtlCopyMemory((LPBYTE)lpdfs32+lpdfs32->pFiles,
  255. (LPBYTE)lpdfs16+lpdfs16->pFiles,
  256. cb-sizeof(DROPFILESTRUCT16));
  257. FREEMISCPTR(lpdfs16);
  258. GlobalUnlock16(hand16);
  259. GlobalUnlock(*phand32);
  260. return TRUE;
  261. } else {
  262. FREEMISCPTR(lpdfs16);
  263. GlobalUnlock16(hand16);
  264. return FALSE;
  265. }
  266. } else {
  267. *phand32 = NULL;
  268. }
  269. return FALSE;
  270. }
  271. #endif
  272. INT GetBMI16Size(PVPVOID vpbmi16, WORD fuColorUse, LPDWORD lpdwClrUsed)
  273. {
  274. int nHdrSize;
  275. int nEntSize;
  276. int nEntries;
  277. int nBitCount;
  278. int nClrUsed = 0;
  279. register PBITMAPINFOHEADER16 pbmi16;
  280. GETVDMPTR(vpbmi16, sizeof(BITMAPINFO16), pbmi16);
  281. nHdrSize = (int) FETCHDWORD(pbmi16->biSize);
  282. if ( fuColorUse == DIB_RGB_COLORS ) {
  283. nEntSize = sizeof(RGBQUAD);
  284. if ( nHdrSize == sizeof(BITMAPCOREHEADER) ) {
  285. nEntSize = sizeof(RGBTRIPLE);
  286. }
  287. }
  288. else {
  289. nEntSize = sizeof(USHORT);
  290. }
  291. if( nHdrSize == sizeof(BITMAPINFOHEADER) ) {
  292. nBitCount = FETCHWORD (pbmi16->biBitCount);
  293. nClrUsed = FETCHDWORD(pbmi16->biClrUsed);
  294. *lpdwClrUsed = nClrUsed;
  295. }
  296. else {
  297. nBitCount = FETCHWORD(((LPBITMAPCOREHEADER)pbmi16)->bcBitCount);
  298. *lpdwClrUsed = 0;
  299. }
  300. /* the following block of code should be this:
  301. *
  302. * if ( nBitCount >= 9 ) { // this is how Win3.1 code says == 24
  303. * nEntries = 1;
  304. * }
  305. * else if ( dwClrUsed ) {
  306. * nEntries = dwClrUsed;
  307. * }
  308. * else {
  309. * nEntries = 1 << nBitCount;
  310. * }
  311. *
  312. * but due to the fact that many apps don't initialize the biBitCount &
  313. * biClrUsed fields (especially biClrUsed) we have to do the following
  314. * sanity checking instead. cmjones
  315. */
  316. if ( nBitCount <= 8 ) {
  317. nEntries = 1 << nBitCount;
  318. // for selected apps ? What apps will be broken by this ?
  319. if (nClrUsed > 0 && nClrUsed < nEntries)
  320. nEntries = nClrUsed;
  321. }
  322. else if (( nBitCount == 16 ) || ( nBitCount == 32)) {
  323. nEntries = 3;
  324. }
  325. // everything else including (nBitCount == 24)
  326. else {
  327. nEntries = 0;
  328. }
  329. // if this asserts it's an app bug
  330. // Changed assert to warning at Craig's request - DaveHart
  331. #ifdef DEBUG
  332. if (!(nEntries > 1) && !(nBitCount == 24)) {
  333. LOGDEBUG(LOG_ALWAYS, ("WOW::GetBMI16Size:bad BitCount:cmjones\n"));
  334. }
  335. #endif
  336. // this will never be true for a CORE type DIB
  337. if(*lpdwClrUsed > (DWORD)nEntries) {
  338. *lpdwClrUsed = nEntries;
  339. }
  340. FREEVDMPTR(pbmi16);
  341. return ( nHdrSize + (nEntries * nEntSize) );
  342. }
  343. INT GetBMI32Size(LPBITMAPINFO lpbmi32, WORD fuColorUse)
  344. {
  345. int nHdrSize;
  346. int nEntSize;
  347. int nEntries;
  348. int nBitCount;
  349. DWORD dwClrUsed;
  350. nHdrSize = (int)((LPBITMAPINFOHEADER)lpbmi32)->biSize;
  351. if ( fuColorUse == DIB_RGB_COLORS ) {
  352. nEntSize = sizeof(RGBQUAD);
  353. if ( nHdrSize == sizeof(BITMAPCOREHEADER) ) {
  354. nEntSize = sizeof(RGBTRIPLE);
  355. }
  356. }
  357. else {
  358. nEntSize = sizeof(USHORT);
  359. }
  360. if( nHdrSize == sizeof(BITMAPINFOHEADER) ) {
  361. nBitCount = ((LPBITMAPINFOHEADER)lpbmi32)->biBitCount;
  362. dwClrUsed = ((LPBITMAPINFOHEADER)lpbmi32)->biClrUsed;
  363. }
  364. else {
  365. nBitCount = (int)((LPBITMAPCOREHEADER)lpbmi32)->bcBitCount;
  366. dwClrUsed = 0;
  367. }
  368. nEntries = 0;
  369. if ( nBitCount < 9 ) {
  370. if((nBitCount == 4) || (nBitCount == 8) || (nBitCount == 1)) {
  371. nEntries = 1 << nBitCount;
  372. }
  373. else if (( nBitCount == 16 ) || ( nBitCount == 32)) {
  374. nEntries = 3;
  375. }
  376. // if this asserts it's an app bug -- we'll try to salvage things
  377. WOW32ASSERTMSG((nEntries > 1),
  378. ("WOW::GetBMI32Size:bad BitCount: cmjones\n"));
  379. // sanity check for apps (lots) that don't init the dwClrUsed field
  380. if(dwClrUsed) {
  381. nEntries = (int)min((DWORD)nEntries, dwClrUsed);
  382. }
  383. }
  384. return ( nHdrSize + (nEntries * nEntSize) );
  385. }
  386. LPBITMAPINFO CopyBMI16ToBMI32(PVPVOID vpbmi16, LPBITMAPINFO lpbmi32, WORD fuColorUse)
  387. {
  388. INT nbmiSize = 0;
  389. DWORD dwClrUsed;
  390. register LPVOID pbmi16;
  391. if(vpbmi16) {
  392. if((nbmiSize = GetBMI16Size(vpbmi16, fuColorUse, &dwClrUsed)) != 0) {
  393. GETVDMPTR(vpbmi16, nbmiSize, pbmi16);
  394. // We can't trust the size we get since apps don't fill in the
  395. // structure correctly so we do a try except around the copy
  396. // to the 32 bit structure. That way if we go off the end of
  397. // memory it doesn't matter, we continue going. - mattfe june 93
  398. try {
  399. RtlCopyMemory ((VOID *)lpbmi32, (CONST VOID *)pbmi16, nbmiSize);
  400. } except (TRUE) {
  401. // Continue if we wen't off the end of 16 bit memory
  402. }
  403. // patch color use field in 32-bit BMIH
  404. // INFO headers only - CORE headers will have dwClrUsed == 0
  405. if(dwClrUsed) {
  406. ((LPBITMAPINFOHEADER)lpbmi32)->biClrUsed = dwClrUsed;
  407. }
  408. FREEVDMPTR(pbmi16);
  409. return (lpbmi32);
  410. }
  411. }
  412. return (NULL);
  413. }
  414. LPBITMAPINFOHEADER CopyBMIH16ToBMIH32(PVPVOID vpbmih16, LPBITMAPINFOHEADER lpbmih32)
  415. {
  416. DWORD dwHeaderSize = 0L;
  417. register PBITMAPINFOHEADER16 pbmih16;
  418. if(vpbmih16) {
  419. GETVDMPTR(vpbmih16, sizeof(BITMAPINFOHEADER16), pbmih16);
  420. dwHeaderSize = FETCHDWORD(pbmih16->biSize);
  421. RtlCopyMemory((VOID *)lpbmih32,(CONST VOID *)pbmih16,(int)dwHeaderSize);
  422. FREEVDMPTR(pbmih16);
  423. return(lpbmih32);
  424. }
  425. return(NULL);
  426. }
  427. // Fill in a 32 bit MEASUREITEMSTRUCT from a 16 bit one
  428. VOID getmeasureitem16(VPMEASUREITEMSTRUCT16 vpMI16, LPMEASUREITEMSTRUCT lpMI, HWND16 hwnd16 )
  429. {
  430. register PMEASUREITEMSTRUCT16 pMI16;
  431. DWORD dw;
  432. BOOL fHasStrings;
  433. GETVDMPTR(vpMI16, sizeof(MEASUREITEMSTRUCT16), pMI16);
  434. lpMI->CtlType = FETCHWORD(pMI16->CtlType);
  435. lpMI->CtlID = FETCHWORD(pMI16->CtlID);
  436. lpMI->itemID = FETCHWORD(pMI16->itemID);
  437. lpMI->itemWidth = FETCHWORD(pMI16->itemWidth);
  438. lpMI->itemHeight = FETCHWORD(pMI16->itemHeight);
  439. fHasStrings = FALSE;
  440. if ( lpMI->CtlType == ODT_COMBOBOX ) {
  441. dw = GetWindowLong( GetDlgItem(HWND32(hwnd16),lpMI->CtlID), GWL_STYLE );
  442. fHasStrings = (dw & CBS_HASSTRINGS);
  443. }
  444. if ( lpMI->CtlType == ODT_LISTBOX ) {
  445. dw = GetWindowLong( GetDlgItem(HWND32(hwnd16),lpMI->CtlID), GWL_STYLE );
  446. fHasStrings = (dw & LBS_HASSTRINGS);
  447. }
  448. if ( fHasStrings ) {
  449. GETPSZPTR(pMI16->itemData, (PVOID)lpMI->itemData);
  450. } else {
  451. lpMI->itemData = FETCHDWORD(pMI16->itemData);
  452. }
  453. FREEVDMPTR(pMI16);
  454. return;
  455. }
  456. // Fill in a 16 bit MEASUREITEMSTRUCT from a 32 bit one
  457. VOID putmeasureitem16(VPMEASUREITEMSTRUCT16 vpMI16, LPMEASUREITEMSTRUCT lpMI)
  458. {
  459. register PMEASUREITEMSTRUCT16 pMI16;
  460. GETVDMPTR(vpMI16, sizeof(MEASUREITEMSTRUCT16), pMI16);
  461. STOREWORD(pMI16->CtlType, lpMI->CtlType);
  462. STOREWORD(pMI16->CtlID, lpMI->CtlID);
  463. STOREWORD(pMI16->itemID, lpMI->itemID);
  464. STOREWORD(pMI16->itemWidth, lpMI->itemWidth);
  465. STOREWORD(pMI16->itemHeight, lpMI->itemHeight);
  466. STOREDWORD(pMI16->itemData, lpMI->itemData);
  467. FREEVDMPTR(pMI16);
  468. return;
  469. }
  470. // Fill in a 32 bit DELETEITEMSTRUCT from a 16 bit one
  471. VOID getdeleteitem16(VPDELETEITEMSTRUCT16 vpDI16, LPDELETEITEMSTRUCT lpDI)
  472. {
  473. register PDELETEITEMSTRUCT16 pDI16;
  474. GETVDMPTR(vpDI16, sizeof(DELETEITEMSTRUCT16), pDI16);
  475. lpDI->CtlType = FETCHWORD(pDI16->CtlType);
  476. lpDI->CtlID = FETCHWORD(pDI16->CtlID);
  477. lpDI->itemID = FETCHWORD(pDI16->itemID);
  478. lpDI->hwndItem = HWND32(FETCHWORD(pDI16->hwndItem));
  479. lpDI->itemData = FETCHDWORD(pDI16->itemData);
  480. FREEVDMPTR(pDI16);
  481. return;
  482. }
  483. // Fill in a 16 bit DELETEITEMSTRUCT from a 32 bit one
  484. VOID putdeleteitem16(VPDELETEITEMSTRUCT16 vpDI16, LPDELETEITEMSTRUCT lpDI)
  485. {
  486. register PDELETEITEMSTRUCT16 pDI16;
  487. GETVDMPTR(vpDI16, sizeof(DELETEITEMSTRUCT16), pDI16);
  488. STOREWORD(pDI16->CtlType, lpDI->CtlType);
  489. STOREWORD(pDI16->CtlID, lpDI->CtlID);
  490. STOREWORD(pDI16->itemID, lpDI->itemID);
  491. STOREWORD(pDI16->hwndItem, GETHWND16(lpDI->hwndItem));
  492. FLUSHVDMPTR(vpDI16, sizeof(DELETEITEMSTRUCT16), pDI16);
  493. FREEVDMPTR(pDI16);
  494. return;
  495. }
  496. // Fill in a 32 bit COMPAREITEMSTRUCT from a 16 bit one
  497. VOID getcompareitem16(VPCOMPAREITEMSTRUCT16 vpCI16, LPCOMPAREITEMSTRUCT lpCI)
  498. {
  499. register PCOMPAREITEMSTRUCT16 pCI16;
  500. GETVDMPTR(vpCI16, sizeof(COMPAREITEMSTRUCT16), pCI16);
  501. lpCI->CtlType = FETCHWORD (pCI16->CtlType);
  502. lpCI->CtlID = FETCHWORD (pCI16->CtlID);
  503. lpCI->hwndItem = HWND32(pCI16->hwndItem);
  504. lpCI->itemID1 = FETCHWORD (pCI16->itemID1);
  505. lpCI->itemID2 = FETCHWORD (pCI16->itemID2);
  506. lpCI->itemData1 = FETCHDWORD(pCI16->itemData1);
  507. lpCI->itemData2 = FETCHDWORD(pCI16->itemData2);
  508. FREEVDMPTR(pCI16);
  509. return;
  510. }
  511. // Fill in a 16 bit COMPAREITEMSTRUCT from a 32 bit one
  512. VOID putcompareitem16(VPCOMPAREITEMSTRUCT16 vpCI16, LPCOMPAREITEMSTRUCT lpCI)
  513. {
  514. register PCOMPAREITEMSTRUCT16 pCI16;
  515. GETVDMPTR(vpCI16, sizeof(COMPAREITEMSTRUCT16), pCI16);
  516. STOREWORD (pCI16->CtlType, (lpCI)->CtlType);
  517. STOREWORD (pCI16->CtlID, (lpCI)->CtlID);
  518. STOREWORD (pCI16->hwndItem, GETHWND16((lpCI)->hwndItem));
  519. STOREWORD (pCI16->itemID1, (lpCI)->itemID1);
  520. STOREWORD (pCI16->itemID2, (lpCI)->itemID2);
  521. STOREDWORD(pCI16->itemData1, (lpCI)->itemData1);
  522. STOREDWORD(pCI16->itemData2, (lpCI)->itemData2);
  523. FLUSHVDMPTR(vpCI16, sizeof(COMPAREITEMSTRUCT16), pCI16);
  524. FREEVDMPTR(pCI16);
  525. return;
  526. }
  527. // NOTE: The below two routines are useful to changing a simple 16-bit message
  528. // into a 32-bit message and vice-versa. The routines take into account only
  529. // those messages which can be returned from GetMessage(), or passed to
  530. // DispatchMessage(), etc. Normally these are only input messages (all other
  531. // messages are sent rather than posted. This type of message has been
  532. // extended to include DDE messages (they are posted too) and WM_TIMER messages.
  533. // If you question this ability, please talk with me. -BobDay
  534. // These routines should only be called from these routines:
  535. // CallMsgFilter
  536. // DispatchMessage
  537. // GetMessage
  538. // IsDialogMessage
  539. // TranslateAccelerator
  540. // TranslateMDISysAccel
  541. // TranslateMessage
  542. // PeekMessage
  543. // WM32GetDlgCode
  544. // ThunkWMMsg16
  545. // Don't call them from any other function!
  546. //
  547. // WARNING: May cause 16-bit memory movement, invalidating flat pointers.
  548. // Fill in a 32 bit MSG from a 16 bit one
  549. // See NOTE above!
  550. VOID getmsg16(VPMSG16 vpmsg16, LPMSG lpmsg, LPMSGPARAMEX lpmpex)
  551. {
  552. register PMSG16 pmsg16;
  553. UINT message;
  554. HWND16 hwnd16;
  555. WPARAM wParam;
  556. LPARAM lParam;
  557. WPARAM uParam;
  558. GETVDMPTR(vpmsg16, sizeof(MSG16), pmsg16);
  559. hwnd16 = FETCHWORD(pmsg16->hwnd);
  560. message = FETCHWORD(pmsg16->message);
  561. wParam = FETCHWORD(pmsg16->wParam);
  562. lParam = FETCHLONG(pmsg16->lParam);
  563. uParam = INT32(wParam); // default thunking - sign extend
  564. #ifdef DEBUG
  565. if (HIWORD(wParam) &&
  566. !((message == WM_TIMER ||
  567. message == WM_COMMAND ||
  568. message == WM_DROPFILES ||
  569. message == WM_HSCROLL ||
  570. message == WM_VSCROLL ||
  571. message == WM_MENUSELECT ||
  572. message == WM_MENUCHAR ||
  573. message == WM_ACTIVATEAPP ||
  574. message == WM_ACTIVATE) ||
  575. (message >= WM_DDE_FIRST && message <= WM_DDE_LAST))) {
  576. LOGDEBUG(LOG_ALWAYS,("WOW: getmsg16 - losing HIWORD(wParam)!"));
  577. WOW32ASSERT(FALSE);
  578. }
  579. #endif
  580. if ( message == WM_TIMER ) {
  581. HAND16 htask16;
  582. PTMR ptmr;
  583. WORD wIDEvent;
  584. htask16 = CURRENTPTD()->htask16;
  585. wIDEvent = (WORD)wParam;
  586. ptmr = FindTimer16( hwnd16, htask16, wIDEvent );
  587. if ( !ptmr ) {
  588. LOGDEBUG(LOG_TRACE,(" getmsg16 WARNING: cannot find timer %04x\n", wIDEvent));
  589. } else {
  590. uParam = (WPARAM)wIDEvent; // wParam is unsigned word
  591. lParam = ptmr->dwTimerProc32; // 32-bit proc or NULL
  592. }
  593. } else if ((message == WM_SYSCOMMAND ||
  594. message == WM_COMMAND ||
  595. message == WM_DROPFILES ||
  596. message == WM_HSCROLL ||
  597. message == WM_VSCROLL ||
  598. message == WM_MENUSELECT ||
  599. message == WM_MENUCHAR ||
  600. message == WM_ACTIVATEAPP ||
  601. message == WM_ACTIVATE) ||
  602. (message >= WM_DDE_FIRST && message <= WM_DDE_LAST)) {
  603. HWND hwnd32;
  604. lpmpex->Parm16.WndProc.hwnd = hwnd16;
  605. lpmpex->Parm16.WndProc.wMsg = (WORD)message;
  606. lpmpex->Parm16.WndProc.wParam = (WORD)wParam;
  607. lpmpex->Parm16.WndProc.lParam = lParam;
  608. lpmpex->iMsgThunkClass = WOWCLASS_WIN16;
  609. hwnd32 = ThunkMsg16(lpmpex);
  610. // memory may have moved
  611. FREEVDMPTR(pmsg16);
  612. GETVDMPTR(vpmsg16, sizeof(MSG16), pmsg16);
  613. lParam = lpmpex->lParam;
  614. lpmsg->hwnd = hwnd32;
  615. lpmsg->message = lpmpex->uMsg;
  616. lpmsg->wParam = lpmpex->uParam;
  617. if (message == WM_DDE_INITIATE) {
  618. LOGDEBUG(LOG_ALWAYS,("WOW::getmsg16:*** ERROR: saw WM_DDE_INITIATE message %04x\n", message));
  619. WI32DDEDeleteInitiator((HAND16) FETCHWORD(pmsg16->wParam));
  620. }
  621. goto finish_up;
  622. } else if (message == WM_SYSTIMER) {
  623. uParam = UINT32(wParam); // un-sign extend this
  624. } else if (message == WM_SETTEXT) {
  625. LONG lParamMap;
  626. LOGDEBUG(LOG_ALWAYS, ("WOW::Warning::getmsg16 processing WM_SETTEXT\n"));
  627. LOGDEBUG(LOG_ALWAYS, ("WOW::Check for possible rogue PostMessage\n"));
  628. // this is thy meaning: we have a message that comes from the 32-bit world
  629. // yet carries 16-bit payload. We have an option of converting this
  630. // to 32-bits at this very point via the param tracking mechanism
  631. GETPSZPTR(lParam, (LPSZ)lParamMap);
  632. lParam = (LPARAM)AddParamMap(lParamMap, lParam);
  633. if (lParam != lParamMap) {
  634. FREEPSZPTR((LPSZ)lParamMap);
  635. }
  636. //
  637. // now lParam is a "normal" 32-bit lParam with a map entry and
  638. // a ref count of "0" (meaning undead) so it could be deleted
  639. // later (during the thunking)
  640. //
  641. SetParamRefCount(lParam, PARAM_32, 0);
  642. }
  643. lpmsg->hwnd = HWND32(hwnd16);
  644. lpmsg->message = message;
  645. lpmsg->wParam = uParam;
  646. finish_up:
  647. lpmsg->lParam = lParam;
  648. lpmsg->time = FETCHLONG(pmsg16->time);
  649. lpmsg->pt.x = FETCHSHORT(pmsg16->pt.x);
  650. lpmsg->pt.y = FETCHSHORT(pmsg16->pt.y);
  651. FREEVDMPTR(pmsg16);
  652. return;
  653. }
  654. /*
  655. * Int 16 state key state bits (in order of Int 16 flags)
  656. */
  657. BYTE abStateVK[] = { VK_RSHIFT,
  658. VK_LSHIFT,
  659. VK_CONTROL,
  660. VK_MENU} ;
  661. /*
  662. * Int 16 state key toggle bits (in order of Int 16 flags)
  663. */
  664. BYTE abToggleVK[] = { VK_SCROLL,
  665. VK_NUMLOCK,
  666. VK_CAPITAL,
  667. VK_INSERT};
  668. // Updates the Int16 bios shift key state info
  669. // (uses "synchronous" key state)
  670. // GetKeyState is a very fast call (GetAsyncKeyState is not)
  671. void UpdateInt16State(void)
  672. {
  673. BYTE bInt16State = 0;
  674. LPBYTE lpbInt16Data;
  675. int iBit;
  676. /*
  677. * Get the toggled keys and OR in their toggle state
  678. */
  679. for( iBit = sizeof(abToggleVK)/sizeof(abToggleVK[0])-1;
  680. iBit >= 0; iBit--) {
  681. bInt16State = bInt16State << 1;
  682. if (GetKeyState(abToggleVK[iBit]) & 1)
  683. bInt16State |= 1;
  684. }
  685. /*
  686. * Get the state keys and OR in their current state
  687. */
  688. for( iBit = sizeof(abStateVK)/sizeof(abStateVK[0])-1;
  689. iBit >= 0; iBit--) {
  690. bInt16State = bInt16State << 1;
  691. if (GetKeyState(abStateVK[iBit]) & 0x8000)
  692. bInt16State |= 1;
  693. }
  694. // Int 16 keyboard state is at 40:17
  695. //
  696. // We need to update this address with the current state of
  697. // the keyboard buffer.
  698. lpbInt16Data = (LPBYTE)GetRModeVDMPointer(0x400017);
  699. *lpbInt16Data = bInt16State;
  700. }
  701. // Fill in a 16 bit MSG from a 32 bit one
  702. // See NOTE above!
  703. ULONG putmsg16(VPMSG16 vpmsg16, LPMSG lpmsg)
  704. {
  705. register PMSG16 pmsg16;
  706. UINT message;
  707. WPARAM wParam;
  708. LPARAM lParam;
  709. WM32MSGPARAMEX wm32mpex;
  710. ULONG ulReturn = 0;
  711. message = lpmsg->message;
  712. wParam = lpmsg->wParam;
  713. lParam = lpmsg->lParam;
  714. if (message == WM_TIMER) {
  715. PTMR ptmr;
  716. ptmr = FindTimer32((HWND16)(GETHWND16(lpmsg->hwnd)), (DWORD)wParam);
  717. if ( !ptmr ) {
  718. LOGDEBUG(LOG_TRACE,(" putmsg16 ERROR: cannot find timer %08x\n", lpmsg->wParam));
  719. } else {
  720. lParam = ptmr->vpfnTimerProc; // 16-bit address or NULL
  721. }
  722. }
  723. else if ((message == WM_COMMAND ||
  724. message == WM_DROPFILES ||
  725. message == WM_HSCROLL ||
  726. message == WM_VSCROLL ||
  727. message == WM_MENUSELECT ||
  728. message == WM_MENUCHAR ||
  729. message == WM_ACTIVATEAPP ||
  730. message == WM_ACTIVATE) ||
  731. (message >= WM_DDE_FIRST && message <= WM_DDE_LAST)) {
  732. WORD wParamNew = (WORD)wParam;
  733. LONG lParamNew = (LONG)lParam;
  734. wm32mpex.Parm16.WndProc.wParam = (WORD)wParam;
  735. wm32mpex.Parm16.WndProc.lParam = (LONG)lParam;
  736. wm32mpex.fThunk = THUNKMSG;
  737. wm32mpex.hwnd = lpmsg->hwnd;
  738. wm32mpex.uMsg = message;
  739. wm32mpex.uParam = wParam;
  740. wm32mpex.lParam = lParam;
  741. wm32mpex.pww = (PWW)NULL;
  742. wm32mpex.fFree = FALSE;
  743. wm32mpex.lpfnM32 = aw32Msg[message].lpfnM32;
  744. ulReturn = (wm32mpex.lpfnM32)(&wm32mpex);
  745. if (ulReturn) {
  746. wParam = (WPARAM) wm32mpex.Parm16.WndProc.wParam;
  747. lParam = (LPARAM) wm32mpex.Parm16.WndProc.lParam;
  748. }
  749. else {
  750. if ((message == WM_DDE_DATA) || (message == WM_DDE_POKE)) {
  751. wParam = (WPARAM) wm32mpex.Parm16.WndProc.wParam;
  752. lParam = (LPARAM) wm32mpex.Parm16.WndProc.lParam;
  753. }
  754. }
  755. } else if (message >= WM_KEYFIRST && message <= WM_KEYLAST) {
  756. UpdateInt16State();
  757. #ifdef FE_IME
  758. // WM_IMEKEYDOWN & WM_IMEKEYUP 32 -> 16
  759. // 32bit:wParam HIWORD charactor code, LOWORD virtual key
  760. // 16bit:wParam HIBYTE charactor code, LOBYTE virtual key
  761. // kksuzuka:#4281 1994.11.19 MSKK V-HIDEKK
  762. } else if (message >= WM_IMEKEYDOWN && message <= WM_IMEKEYUP) {
  763. LONG wParamNew = wParam;
  764. wParamNew >>= 8;
  765. wParamNew |= (0xffff & wParam);
  766. wParam = wParamNew;
  767. #endif // FE_IME
  768. } else if (message & WOWPRIVATEMSG) {
  769. LOGDEBUG(LOG_ALWAYS, ("WOW::Warning::putmsg16 caught private message 0x%lx\n", message));
  770. message &= ~WOWPRIVATEMSG; // clear the private bit...
  771. /* If we had some special processing to do for private msgs sent with
  772. a WOWPRIVATEMSG flag the code here would look like
  773. if (WM_SETTEXT == message) {
  774. //
  775. // this message is already equipped with 16-bit lParam
  776. //
  777. }
  778. */
  779. }
  780. GETVDMPTR(vpmsg16, sizeof(MSG16), pmsg16);
  781. STOREWORD(pmsg16->hwnd, GETHWND16(lpmsg->hwnd));
  782. STOREWORD(pmsg16->message, message);
  783. STOREWORD(pmsg16->wParam, wParam);
  784. STORELONG(pmsg16->lParam, lParam);
  785. STORELONG(pmsg16->time, lpmsg->time);
  786. STOREWORD(pmsg16->pt.x, lpmsg->pt.x);
  787. STOREWORD(pmsg16->pt.y, lpmsg->pt.y);
  788. FLUSHVDMPTR(vpmsg16, sizeof(MSG16), pmsg16);
  789. FREEVDMPTR(pmsg16);
  790. return (ulReturn);
  791. }
  792. // Fill in a 32 bit LOGFONT from a 16 bit LOGFONT
  793. VOID getlogfont16(VPLOGFONT16 vplf, LPLOGFONT lplf)
  794. {
  795. register PLOGFONT16 plf16;
  796. // PBYTE p1, p2;
  797. // The assumption here is that no APIs have OPTIONAL LOGFONT pointers
  798. WOW32WARNMSG((vplf),("WOW:getlogfont16: NULL 16:16 logfont ptr\n"));
  799. GETVDMPTR(vplf, sizeof(LOGFONT16), plf16);
  800. if(plf16) {
  801. lplf->lfHeight = FETCHSHORT(plf16->lfHeight);
  802. lplf->lfWidth = FETCHSHORT(plf16->lfWidth);
  803. lplf->lfEscapement = FETCHSHORT(plf16->lfEscapement);
  804. lplf->lfOrientation = FETCHSHORT(plf16->lfOrientation);
  805. lplf->lfWeight = FETCHSHORT(plf16->lfWeight);
  806. lplf->lfItalic = plf16->lfItalic;
  807. lplf->lfUnderline = plf16->lfUnderline;
  808. lplf->lfStrikeOut = plf16->lfStrikeOut;
  809. lplf->lfCharSet = plf16->lfCharSet;
  810. lplf->lfOutPrecision = plf16->lfOutPrecision;
  811. lplf->lfClipPrecision = plf16->lfClipPrecision;
  812. lplf->lfQuality = plf16->lfQuality;
  813. lplf->lfPitchAndFamily = plf16->lfPitchAndFamily;
  814. #if 0
  815. //
  816. // can't do it this way, an app can have an unitialized lfFaceName
  817. // that's a looong stream of non-null chars, in which case we blow
  818. // out our stack.
  819. //
  820. p1 = lplf->lfFaceName;
  821. p2 = plf16->lfFaceName;
  822. while (*p1++ = *p2++);
  823. #else
  824. #if (LF_FACESIZE != 32)
  825. #error Win16/Win32 LF_FACESIZE constants differ
  826. #endif
  827. WOW32_strncpy(lplf->lfFaceName, (const char *)plf16->lfFaceName, LF_FACESIZE);
  828. #endif
  829. // if (*p2) {
  830. // i = 0;
  831. // while ((i < LF_FACESIZE) && (*p2)) {
  832. // *p1++ = *p2++;
  833. // i++;
  834. // }
  835. // *p1 = *p2;
  836. //
  837. // } else {
  838. // lstrcpy(lplf->lfFaceName, "System");
  839. // }
  840. FREEVDMPTR(plf16);
  841. }
  842. }
  843. // Fill in a 16 bit LOGFONT from a 32 bit LOGFONT
  844. VOID putlogfont16(VPLOGFONT16 vplf, INT cb, LPLOGFONT lplf)
  845. {
  846. register PLOGFONT16 plf16;
  847. PBYTE p1, p2;
  848. INT cbCopied;
  849. // The assumption here is that no APIs have OPTIONAL LOGFONT pointers
  850. WOW32WARNMSG((vplf),("WOW:putlogfont16: NULL 16:16 logfont ptr\n"));
  851. GETVDMPTR(vplf, sizeof(LOGFONT16), plf16);
  852. if(plf16) {
  853. switch (cb)
  854. {
  855. default:
  856. plf16->lfPitchAndFamily = lplf->lfPitchAndFamily;
  857. case 17:
  858. plf16->lfQuality = lplf->lfQuality;
  859. case 16:
  860. plf16->lfClipPrecision = lplf->lfClipPrecision;
  861. case 15:
  862. plf16->lfOutPrecision = lplf->lfOutPrecision;
  863. case 14:
  864. plf16->lfCharSet = lplf->lfCharSet;
  865. case 13:
  866. plf16->lfStrikeOut = lplf->lfStrikeOut;
  867. case 12:
  868. plf16->lfUnderline = lplf->lfUnderline;
  869. case 11:
  870. plf16->lfItalic = lplf->lfItalic;
  871. case 10:
  872. STORESHORT(plf16->lfWeight, lplf->lfWeight);
  873. case 9:
  874. case 8:
  875. STORESHORT(plf16->lfOrientation,lplf->lfOrientation);
  876. case 7:
  877. case 6:
  878. STORESHORT(plf16->lfEscapement, lplf->lfEscapement);
  879. case 5:
  880. case 4:
  881. STORESHORT(plf16->lfWidth, lplf->lfWidth);
  882. case 3:
  883. case 2:
  884. STORESHORT(plf16->lfHeight, lplf->lfHeight);
  885. case 1:
  886. break;
  887. }
  888. p1 = lplf->lfFaceName;
  889. p2 = (PBYTE)plf16->lfFaceName;
  890. cbCopied = 18;
  891. while ((++cbCopied <= cb) && (*p2++ = *p1++));
  892. FLUSHVDMPTR(vplf, sizeof(LOGFONT16), plf16);
  893. FREEVDMPTR(plf16);
  894. }
  895. }
  896. // Fill in a 16 bit ENUMLOGFONT from a 32 bit ENUMLOGFONT
  897. VOID putenumlogfont16(VPENUMLOGFONT16 vpelf, LPENUMLOGFONT lpelf)
  898. {
  899. register PENUMLOGFONT16 pelf16;
  900. PBYTE p1, p2;
  901. // The assumption here is that no APIs have OPTIONAL ENUMLOGFONT pointers
  902. WOW32ASSERT(vpelf);
  903. GETVDMPTR(vpelf, sizeof(ENUMLOGFONT16), pelf16);
  904. STORESHORT(pelf16->elfLogFont.lfHeight, lpelf->elfLogFont.lfHeight);
  905. STORESHORT(pelf16->elfLogFont.lfWidth, lpelf->elfLogFont.lfWidth);
  906. STORESHORT(pelf16->elfLogFont.lfEscapement, lpelf->elfLogFont.lfEscapement);
  907. STORESHORT(pelf16->elfLogFont.lfOrientation,lpelf->elfLogFont.lfOrientation);
  908. STORESHORT(pelf16->elfLogFont.lfWeight, lpelf->elfLogFont.lfWeight);
  909. pelf16->elfLogFont.lfItalic = lpelf->elfLogFont.lfItalic;
  910. pelf16->elfLogFont.lfUnderline = lpelf->elfLogFont.lfUnderline;
  911. pelf16->elfLogFont.lfStrikeOut = lpelf->elfLogFont.lfStrikeOut;
  912. pelf16->elfLogFont.lfCharSet = lpelf->elfLogFont.lfCharSet;
  913. pelf16->elfLogFont.lfOutPrecision = lpelf->elfLogFont.lfOutPrecision;
  914. pelf16->elfLogFont.lfClipPrecision = lpelf->elfLogFont.lfClipPrecision;
  915. pelf16->elfLogFont.lfQuality = lpelf->elfLogFont.lfQuality;
  916. pelf16->elfLogFont.lfPitchAndFamily = lpelf->elfLogFont.lfPitchAndFamily;
  917. p1 = lpelf->elfLogFont.lfFaceName;
  918. p2 = (PBYTE)pelf16->elfLogFont.lfFaceName;
  919. while ((*p2++ = *p1++) != '\0');
  920. p1 = lpelf->elfFullName;
  921. p2 = (PBYTE)pelf16->elfFullName;
  922. while ((*p2++ = *p1++) != '\0');
  923. p1 = lpelf->elfStyle;
  924. p2 = (PBYTE)pelf16->elfStyle;
  925. while ((*p2++ = *p1++) != '\0');
  926. FLUSHVDMPTR(vpelf, sizeof(ENUMLOGFONT16), pelf16);
  927. FREEVDMPTR(pelf16);
  928. }
  929. VOID puttextmetric16(VPTEXTMETRIC16 vptm, LPTEXTMETRIC lptm)
  930. {
  931. register PTEXTMETRIC16 ptm16;
  932. // The assumption here is that no APIs have OPTIONAL TEXTMETRIC pointers
  933. WOW32ASSERT(vptm);
  934. GETVDMPTR(vptm, sizeof(TEXTMETRIC16), ptm16);
  935. STORESHORT(ptm16->tmHeight, (lptm)->tmHeight);
  936. STORESHORT(ptm16->tmAscent, (lptm)->tmAscent);
  937. STORESHORT(ptm16->tmDescent, (lptm)->tmDescent);
  938. STORESHORT(ptm16->tmInternalLeading,(lptm)->tmInternalLeading);
  939. STORESHORT(ptm16->tmExternalLeading,(lptm)->tmExternalLeading);
  940. STORESHORT(ptm16->tmAveCharWidth, (lptm)->tmAveCharWidth);
  941. STORESHORT(ptm16->tmMaxCharWidth, (lptm)->tmMaxCharWidth);
  942. STORESHORT(ptm16->tmWeight, (lptm)->tmWeight);
  943. ptm16->tmItalic = (lptm)->tmItalic;
  944. ptm16->tmUnderlined = (lptm)->tmUnderlined;
  945. ptm16->tmStruckOut = (lptm)->tmStruckOut;
  946. ptm16->tmFirstChar = (lptm)->tmFirstChar;
  947. ptm16->tmLastChar = (lptm)->tmLastChar;
  948. ptm16->tmDefaultChar = (lptm)->tmDefaultChar;
  949. ptm16->tmBreakChar = (lptm)->tmBreakChar;
  950. ptm16->tmPitchAndFamily = (lptm)->tmPitchAndFamily;
  951. ptm16->tmCharSet = (lptm)->tmCharSet;
  952. STORESHORT(ptm16->tmOverhang, (lptm)->tmOverhang);
  953. STORESHORT(ptm16->tmDigitizedAspectX,(lptm)->tmDigitizedAspectX);
  954. STORESHORT(ptm16->tmDigitizedAspectY,(lptm)->tmDigitizedAspectY);
  955. FLUSHVDMPTR(vptm, sizeof(TEXTMETRIC16), ptm16);
  956. FREEVDMPTR(ptm16);
  957. }
  958. VOID putnewtextmetric16(VPNEWTEXTMETRIC16 vpntm, LPNEWTEXTMETRIC lpntm)
  959. {
  960. register PNEWTEXTMETRIC16 pntm16;
  961. // The assumption here is that no APIs have OPTIONAL TEXTMETRIC pointers
  962. WOW32ASSERT(vpntm);
  963. GETVDMPTR(vpntm, sizeof(NEWTEXTMETRIC16), pntm16);
  964. STORESHORT(pntm16->tmHeight, (lpntm)->tmHeight);
  965. STORESHORT(pntm16->tmAscent, (lpntm)->tmAscent);
  966. STORESHORT(pntm16->tmDescent, (lpntm)->tmDescent);
  967. STORESHORT(pntm16->tmInternalLeading, (lpntm)->tmInternalLeading);
  968. STORESHORT(pntm16->tmExternalLeading, (lpntm)->tmExternalLeading);
  969. STORESHORT(pntm16->tmAveCharWidth, (lpntm)->tmAveCharWidth);
  970. STORESHORT(pntm16->tmMaxCharWidth, (lpntm)->tmMaxCharWidth);
  971. STORESHORT(pntm16->tmWeight, (lpntm)->tmWeight);
  972. pntm16->tmItalic = (lpntm)->tmItalic;
  973. pntm16->tmUnderlined = (lpntm)->tmUnderlined;
  974. pntm16->tmStruckOut = (lpntm)->tmStruckOut;
  975. pntm16->tmFirstChar = (lpntm)->tmFirstChar;
  976. pntm16->tmLastChar = (lpntm)->tmLastChar;
  977. pntm16->tmDefaultChar = (lpntm)->tmDefaultChar;
  978. pntm16->tmBreakChar = (lpntm)->tmBreakChar;
  979. pntm16->tmPitchAndFamily = (lpntm)->tmPitchAndFamily;
  980. pntm16->tmCharSet = (lpntm)->tmCharSet;
  981. STORESHORT(pntm16->tmOverhang, (lpntm)->tmOverhang);
  982. STORESHORT(pntm16->tmDigitizedAspectX, (lpntm)->tmDigitizedAspectX);
  983. STORESHORT(pntm16->tmDigitizedAspectY, (lpntm)->tmDigitizedAspectY);
  984. STOREDWORD(pntm16->ntmFlags, (lpntm)->ntmFlags);
  985. STOREWORD( pntm16->ntmSizeEM, (WORD)((lpntm)->ntmSizeEM));
  986. STOREWORD( pntm16->ntmCellHeight, (WORD)((lpntm)->ntmCellHeight));
  987. STOREWORD( pntm16->ntmAvgWidth, (WORD)((lpntm)->ntmAvgWidth));
  988. FLUSHVDMPTR(vpntm, sizeof(NEWTEXTMETRIC16), pntm16);
  989. FREEVDMPTR(pntm16);
  990. }
  991. VOID putoutlinetextmetric16(VPOUTLINETEXTMETRIC16 vpotm, INT cb, LPOUTLINETEXTMETRIC lpotm)
  992. {
  993. register POUTLINETEXTMETRIC16 potm16;
  994. OUTLINETEXTMETRIC16 otm16;
  995. int count;
  996. GETVDMPTR(vpotm, cb, potm16);
  997. otm16.otmSize = (WORD)lpotm->otmSize;
  998. /*
  999. ** Copy the TEXTMETRIC structure
  1000. */
  1001. otm16.otmTextMetrics.tmHeight = (SHORT)lpotm->otmTextMetrics.tmHeight;
  1002. otm16.otmTextMetrics.tmAscent = (SHORT)lpotm->otmTextMetrics.tmAscent;
  1003. otm16.otmTextMetrics.tmDescent = (SHORT)lpotm->otmTextMetrics.tmDescent;
  1004. otm16.otmTextMetrics.tmInternalLeading = (SHORT)lpotm->otmTextMetrics.tmInternalLeading;
  1005. otm16.otmTextMetrics.tmExternalLeading = (SHORT)lpotm->otmTextMetrics.tmExternalLeading;
  1006. otm16.otmTextMetrics.tmAveCharWidth = (SHORT)lpotm->otmTextMetrics.tmAveCharWidth;
  1007. otm16.otmTextMetrics.tmMaxCharWidth = (SHORT)lpotm->otmTextMetrics.tmMaxCharWidth;
  1008. otm16.otmTextMetrics.tmWeight = (SHORT)lpotm->otmTextMetrics.tmWeight;
  1009. otm16.otmTextMetrics.tmItalic = lpotm->otmTextMetrics.tmItalic;
  1010. otm16.otmTextMetrics.tmUnderlined = lpotm->otmTextMetrics.tmUnderlined;
  1011. otm16.otmTextMetrics.tmStruckOut = lpotm->otmTextMetrics.tmStruckOut;
  1012. otm16.otmTextMetrics.tmFirstChar = lpotm->otmTextMetrics.tmFirstChar;
  1013. otm16.otmTextMetrics.tmLastChar = lpotm->otmTextMetrics.tmLastChar;
  1014. otm16.otmTextMetrics.tmDefaultChar = lpotm->otmTextMetrics.tmDefaultChar;
  1015. otm16.otmTextMetrics.tmBreakChar = lpotm->otmTextMetrics.tmBreakChar;
  1016. otm16.otmTextMetrics.tmPitchAndFamily = lpotm->otmTextMetrics.tmPitchAndFamily;
  1017. otm16.otmTextMetrics.tmCharSet = lpotm->otmTextMetrics.tmCharSet;
  1018. otm16.otmTextMetrics.tmOverhang = (SHORT)lpotm->otmTextMetrics.tmOverhang;
  1019. otm16.otmTextMetrics.tmDigitizedAspectX = (SHORT)lpotm->otmTextMetrics.tmDigitizedAspectX;
  1020. otm16.otmTextMetrics.tmDigitizedAspectY = (SHORT)lpotm->otmTextMetrics.tmDigitizedAspectY;
  1021. otm16.otmFiller = lpotm->otmFiller;
  1022. /*
  1023. ** Panose
  1024. */
  1025. otm16.otmPanoseNumber.bFamilyType = lpotm->otmPanoseNumber.bFamilyType;
  1026. otm16.otmPanoseNumber.bSerifStyle = lpotm->otmPanoseNumber.bSerifStyle;
  1027. otm16.otmPanoseNumber.bWeight = lpotm->otmPanoseNumber.bWeight;
  1028. otm16.otmPanoseNumber.bProportion = lpotm->otmPanoseNumber.bProportion;
  1029. otm16.otmPanoseNumber.bContrast = lpotm->otmPanoseNumber.bContrast;
  1030. otm16.otmPanoseNumber.bStrokeVariation = lpotm->otmPanoseNumber.bStrokeVariation;
  1031. otm16.otmPanoseNumber.bArmStyle = lpotm->otmPanoseNumber.bArmStyle;
  1032. otm16.otmPanoseNumber.bMidline = lpotm->otmPanoseNumber.bMidline;
  1033. otm16.otmPanoseNumber.bXHeight = lpotm->otmPanoseNumber.bXHeight;
  1034. otm16.otmfsSelection = (WORD)lpotm->otmfsSelection;
  1035. otm16.otmfsType = (WORD)lpotm->otmfsType;
  1036. otm16.otmsCharSlopeRise = (SHORT)lpotm->otmsCharSlopeRise;
  1037. otm16.otmsCharSlopeRun = (SHORT)lpotm->otmsCharSlopeRun;
  1038. otm16.otmItalicAngle = (SHORT)lpotm->otmItalicAngle;
  1039. otm16.otmEMSquare = (WORD)lpotm->otmEMSquare;
  1040. otm16.otmAscent = (SHORT)lpotm->otmAscent;
  1041. otm16.otmDescent = (SHORT)lpotm->otmDescent;
  1042. otm16.otmLineGap = (WORD)lpotm->otmLineGap;
  1043. otm16.otmsCapEmHeight = (WORD)lpotm->otmsCapEmHeight;
  1044. otm16.otmsXHeight = (WORD)lpotm->otmsXHeight;
  1045. /*
  1046. ** Font Box Rectangle (ZOWIE!, I sure wish I could use putrect16 but alas!)
  1047. */
  1048. otm16.otmrcFontBox.left = (SHORT)lpotm->otmrcFontBox.left;
  1049. otm16.otmrcFontBox.top = (SHORT)lpotm->otmrcFontBox.top;
  1050. otm16.otmrcFontBox.right = (SHORT)lpotm->otmrcFontBox.right;
  1051. otm16.otmrcFontBox.bottom = (SHORT)lpotm->otmrcFontBox.bottom;
  1052. otm16.otmMacAscent = (SHORT)lpotm->otmMacAscent;
  1053. otm16.otmMacDescent = (SHORT)lpotm->otmMacDescent;
  1054. otm16.otmMacLineGap = (WORD)lpotm->otmMacLineGap;
  1055. otm16.otmusMinimumPPEM = (WORD)lpotm->otmusMinimumPPEM;
  1056. otm16.otmptSubscriptSize.x = (SHORT)lpotm->otmptSubscriptSize.x;
  1057. otm16.otmptSubscriptSize.y = (SHORT)lpotm->otmptSubscriptSize.y;
  1058. otm16.otmptSubscriptOffset.x = (SHORT)lpotm->otmptSubscriptOffset.x;
  1059. otm16.otmptSubscriptOffset.y = (SHORT)lpotm->otmptSubscriptOffset.y;
  1060. otm16.otmptSuperscriptSize.x = (SHORT)lpotm->otmptSuperscriptSize.x;
  1061. otm16.otmptSuperscriptSize.y = (SHORT)lpotm->otmptSuperscriptSize.y;
  1062. otm16.otmptSuperscriptOffset.x = (SHORT)lpotm->otmptSuperscriptOffset.x;
  1063. otm16.otmptSuperscriptOffset.y = (SHORT)lpotm->otmptSuperscriptOffset.y;
  1064. otm16.otmsStrikeoutSize = (WORD)lpotm->otmsStrikeoutSize;
  1065. otm16.otmsStrikeoutPosition = (SHORT)lpotm->otmsStrikeoutPosition;
  1066. otm16.otmsUnderscorePosition = (SHORT)lpotm->otmsUnderscorePosition;
  1067. otm16.otmsUnderscoreSize = (SHORT)lpotm->otmsUnderscoreSize;
  1068. otm16.otmpFamilyName = (WORD) (lpotm->otmpFamilyName -
  1069. sizeof(OUTLINETEXTMETRIC) + sizeof(OUTLINETEXTMETRIC16));
  1070. otm16.otmpFaceName = (WORD) (lpotm->otmpFaceName -
  1071. sizeof(OUTLINETEXTMETRIC) + sizeof(OUTLINETEXTMETRIC16));
  1072. otm16.otmpStyleName = (WORD) (lpotm->otmpStyleName -
  1073. sizeof(OUTLINETEXTMETRIC) + sizeof(OUTLINETEXTMETRIC16));
  1074. otm16.otmpFullName = (WORD) (lpotm->otmpFullName -
  1075. sizeof(OUTLINETEXTMETRIC) + sizeof(OUTLINETEXTMETRIC16));
  1076. count = sizeof(OUTLINETEXTMETRIC16);
  1077. if ( cb <= count ) {
  1078. count = cb;
  1079. } else {
  1080. /*
  1081. ** Copy the rest of the buffer (strings, etc.) over verbatim.
  1082. */
  1083. RtlCopyMemory( (LPSTR)potm16 + sizeof(OUTLINETEXTMETRIC16),
  1084. (LPSTR)lpotm + sizeof(OUTLINETEXTMETRIC),
  1085. cb - sizeof(OUTLINETEXTMETRIC16) );
  1086. }
  1087. /*
  1088. ** Now really copy it (the structure portion) into the 16-bit memory
  1089. */
  1090. RtlCopyMemory((VOID *)potm16, (CONST VOID *)&otm16, count );
  1091. FLUSHVDMPTR(vpotm, cb, potm16);
  1092. FREEVDMPTR(potm16);
  1093. }
  1094. // Converts a 16 bit handle table to 32 bit
  1095. VOID gethandletable16(VPWORD vpht, UINT c, LPHANDLETABLE lpht)
  1096. {
  1097. PHANDLETABLE16 pht16;
  1098. WORD w;
  1099. GETVDMPTR(vpht, sizeof(HAND16)*c, pht16);
  1100. // be careful, we need to get the correct 32 obj handle from alias
  1101. while (c--)
  1102. {
  1103. w = FETCHWORD(pht16->objectHandle[c]);
  1104. if (w)
  1105. lpht->objectHandle[c] = HOBJ32(w);
  1106. else
  1107. lpht->objectHandle[c] = (HANDLE)NULL;
  1108. }
  1109. FREEVDMPTR(pht16);
  1110. }
  1111. // Converts a 32 bit handle table to 16 bit
  1112. VOID puthandletable16(VPWORD vpht, UINT c, LPHANDLETABLE lpht)
  1113. {
  1114. PHANDLETABLE16 pht16;
  1115. DWORD dw;
  1116. GETVDMPTR(vpht, sizeof(HAND16)*c, pht16);
  1117. // be careful, we need to get the correct 16 alias the 32 obj handle
  1118. while (c--) {
  1119. dw = FETCHDWORD(lpht->objectHandle[c]);
  1120. if (dw) {
  1121. pht16->objectHandle[c] = GETHOBJ16((HAND32)dw);
  1122. }
  1123. else {
  1124. pht16->objectHandle[c] = (HAND16)NULL;
  1125. }
  1126. }
  1127. FREEVDMPTR(pht16);
  1128. }
  1129. /*
  1130. * To solve a ton of devmode compatibility issues we are now going to return
  1131. * Win3.1 devmodes to 16-bit apps instead of NT devmodes.
  1132. *
  1133. * The most common problem we encounter is that apps determine the size to
  1134. * allocate for a DEVMODE buffer by: sizeof(DEVMODE) + dm->dmDriverExtra
  1135. * Apps seem to handle the DriverExtra stuff pretty well but there is a wide-
  1136. * spread belief that the public DEVMODE structure is a fixed size.
  1137. * We hide the NT specific DEVMODE stuff and the WOW devmode thunk info in
  1138. * what the app thinks is the DriverExtra part of the devmode:
  1139. *
  1140. * ____________________________ _____
  1141. * | Win 3.1 DEVMODE | |
  1142. * | dmSize = sizeof(DEVMODE31) | |
  1143. * | dmDriverExtra = | |
  1144. * ___|__/ (sizeof(DEVMODENT) - | Win 3.1 DEVMODE
  1145. * | | \ sizeof(DEVMODE31)) + | |
  1146. * -|---|--- original DriverExtra + | |
  1147. * | | _|__/ sizeof(DWORD) + | |
  1148. * | | | | \ (sizeof(WORD) * 3) | |
  1149. * | | | |____________________________| _____| <-- where app thinks driver
  1150. * | | | | NT DEVMODE stuff not in | | extra starts
  1151. * | `-->| the Win3.1 DEVMODE struct | NT specific DEVMODE stuff
  1152. * | | |____________________________| _____| <-- where driver extra really
  1153. * `---->| actual NT driver extra | starts
  1154. * | |____________________________| <-- where WOWDM31 struct starts
  1155. * | | DWORD with "DM31" | <--- WOW DEVMODE31 signature
  1156. * ->| WORD original dmSpecVersion|\
  1157. * | WORD original dmSize | <--- values returned by the driver
  1158. * | WORD original dmDriverExtra|/
  1159. * | WORD to pad to even DWORD | <--- requried for ptr arithmetic
  1160. * |____________________________|
  1161. *
  1162. * NOTE: We may see Win3.0 & Win3.1 DevModes that are returned by 16-bit fax
  1163. * drivers.
  1164. *
  1165. */
  1166. LPDEVMODE ThunkDevMode16to32(VPDEVMODE31 vpdm16)
  1167. {
  1168. INT nSize, nDriverExtra;
  1169. LPDEVMODE lpdm32;
  1170. PDEVMODE31 pdm16;
  1171. PWOWDM31 pWOWDM31;
  1172. if(FETCHDWORD(vpdm16) == 0L) {
  1173. return(NULL);
  1174. }
  1175. GETVDMPTR(vpdm16, sizeof(DEVMODE31), pdm16);
  1176. // we will generally see only Win3.1 DevMode's here but 16-bit fax
  1177. // drivers can return a Win3.0 DevMode.
  1178. nSize = FETCHWORD(pdm16->dmSize);
  1179. WOW32WARNMSGF((nSize==sizeof(DEVMODE31)),
  1180. ("ThunkDevMode16to32: Unexpected dmSize(16) = %d\n", nSize));
  1181. // check for bad DEVMODE (PageMaker & MSProfit are known culprits)
  1182. // (PageMaker 5.0a passes a 16:16 ptr to NULL!!)
  1183. // this test taken from gdi\client\object.c!bConvertToDevmodeW
  1184. if ( (nSize < (offsetof(DEVMODE, dmDriverExtra) + sizeof(WORD))) ||
  1185. (nSize > sizeof(DEVMODE)) ) {
  1186. LOGDEBUG(LOG_ALWAYS,("WOW::ThunkDevMode16to32:Bail out case!!\n"));
  1187. return(NULL);
  1188. }
  1189. // note this might include the "extra" DriverExtra we added in
  1190. // ThunkDevMode32to16()
  1191. nDriverExtra = FETCHWORD(pdm16->dmDriverExtra);
  1192. // allocate 32-bit DEVMODE -- don't worry if we alloc a little too much due
  1193. // to the WOW stuff we added to the end of the driver extra
  1194. if(lpdm32 = malloc_w(nSize + nDriverExtra)) {
  1195. // fill in the 32-bit devmode
  1196. RtlCopyMemory((VOID *)lpdm32,(CONST VOID *)pdm16, nSize + nDriverExtra);
  1197. // if this is a Win3.1 size DEVMODE, it may be one of our special ones
  1198. if(nSize == sizeof(DEVMODE31)) {
  1199. // see if it has our "DM31" signature at the end of the DEVMODE
  1200. pWOWDM31 = (PWOWDM31)((PBYTE)lpdm32 +
  1201. sizeof(DEVMODE31) +
  1202. nDriverExtra -
  1203. sizeof(WOWDM31));
  1204. // if it does, adjust the dmSpecVersion, dmSize & dmDriverExtra
  1205. // back to the values we got from the driver
  1206. if(pWOWDM31->dwWOWSig == WOW_DEVMODE31SIG) {
  1207. lpdm32->dmSpecVersion = pWOWDM31->dmSpecVersion;
  1208. lpdm32->dmSize = pWOWDM31->dmSize;
  1209. lpdm32->dmDriverExtra = pWOWDM31->dmDriverExtra;
  1210. }
  1211. #ifdef DEBUG
  1212. // somehow the app got a DEVMODE and either lost our thunking info
  1213. // or threw it away (#205327)
  1214. else {
  1215. LOGDEBUG(LOG_ALWAYS, ("WOW::ThunkDevMode16to32: Signature missing from DEVMODE!!\n"));
  1216. }
  1217. #endif
  1218. }
  1219. }
  1220. FREEVDMPTR(pdm16);
  1221. return(lpdm32);
  1222. }
  1223. BOOL ThunkDevMode32to16(VPDEVMODE31 vpdm16, LPDEVMODE lpdm32, UINT nBytes)
  1224. {
  1225. WORD nSize, nDriverExtra;
  1226. PDEVMODE31 pdm16;
  1227. PWOWDM31 pWOWDM31;
  1228. GETVDMPTR(vpdm16, sizeof(DEVMODE31), pdm16);
  1229. if((FETCHDWORD(vpdm16) == 0L) || (!lpdm32) || (!pdm16)) {
  1230. return(FALSE);
  1231. }
  1232. nSize = lpdm32->dmSize;
  1233. // We should only see DevModes of the current NT size because the spooler
  1234. // converts all devmodes to the current version
  1235. WOW32WARNMSGF((nSize==sizeof(DEVMODE)),
  1236. ("ThunkDevMode32to16: Unexpected devmode size = %d\n",nSize));
  1237. nDriverExtra = lpdm32->dmDriverExtra;
  1238. // fill in the 16-bit devmode
  1239. RtlCopyMemory((VOID *)pdm16,
  1240. (CONST VOID *)lpdm32,
  1241. min((nSize + nDriverExtra), (WORD)nBytes));
  1242. // Convert NT sized devmodes to Win3.1 devmodes.
  1243. // Note: Winfax.drv passes back an NT size DevMode with dmSpecVersion=0x300
  1244. // also it passes a hard coded 0xa9 to GetEnvironment() as the max
  1245. // size of its buffer (see GetEnvironment() notes in wgdi.c)
  1246. // If there is a buffer constraint, we'll just have to be satisfied
  1247. // with copying the nBytes worth of the devmode which should work
  1248. // in the case of WinFax.
  1249. if((nSize == sizeof(DEVMODE)) && ((nSize + nDriverExtra) <= (WORD)nBytes)) {
  1250. // save our signature along with the original dmSpecVersion, dmSize,
  1251. // and dmDriverExtra at the end of the DriverExtra memory
  1252. pWOWDM31 = (PWOWDM31)((PBYTE)pdm16 +
  1253. sizeof(DEVMODE) +
  1254. nDriverExtra);
  1255. pWOWDM31->dwWOWSig = WOW_DEVMODE31SIG;
  1256. pWOWDM31->dmSpecVersion = lpdm32->dmSpecVersion;
  1257. pWOWDM31->dmSize = nSize;
  1258. pWOWDM31->dmDriverExtra = nDriverExtra;
  1259. // Make our special adjustments to the public devmode stuff.
  1260. // We can't tell an app a Win3.0 DevMode is a Win3.1 version or it might
  1261. // try to write to the new Win3.1 fields
  1262. if(lpdm32->dmSpecVersion > WOW_DEVMODE31SPEC) {
  1263. pdm16->dmSpecVersion = WOW_DEVMODE31SPEC;
  1264. }
  1265. pdm16->dmSize = sizeof(DEVMODE31);
  1266. pdm16->dmDriverExtra += WOW_DEVMODEEXTRA;
  1267. }
  1268. FLUSHVDMPTR(vpdm16, sizeof(DEVMODE31), pdm16);
  1269. FREEVDMPTR(pdm16);
  1270. return(TRUE);
  1271. }
  1272. VOID getwindowpos16( VPWINDOWPOS16 vpwp, LPWINDOWPOS lpwp )
  1273. {
  1274. register PWINDOWPOS16 pwp16;
  1275. GETVDMPTR(vpwp, sizeof(WINDOWPOS16), pwp16);
  1276. lpwp->hwnd = HWND32(pwp16->hwnd);
  1277. lpwp->hwndInsertAfter = HWNDIA32(pwp16->hwndInsertAfter);
  1278. lpwp->x = (INT) FETCHSHORT(pwp16->x);
  1279. lpwp->y = (INT) FETCHSHORT(pwp16->y);
  1280. lpwp->cx = (INT) FETCHSHORT(pwp16->cx);
  1281. lpwp->cy = (INT) FETCHSHORT(pwp16->cy);
  1282. lpwp->flags = (WORD) FETCHWORD(pwp16->flags);
  1283. FREEVDMPTR(pwp16);
  1284. }
  1285. VOID putwindowpos16( VPWINDOWPOS16 vpwp, LPWINDOWPOS lpwp )
  1286. {
  1287. register PWINDOWPOS16 pwp16;
  1288. GETVDMPTR(vpwp, sizeof(WINDOWPOS16), pwp16);
  1289. STOREWORD(pwp16->hwnd, GETHWND16(lpwp->hwnd));
  1290. STOREWORD(pwp16->hwndInsertAfter, GETHWNDIA16(lpwp->hwndInsertAfter));
  1291. STORESHORT(pwp16->x, lpwp->x);
  1292. STORESHORT(pwp16->y, lpwp->y);
  1293. STORESHORT(pwp16->cx, lpwp->cx);
  1294. STORESHORT(pwp16->cy, lpwp->cy);
  1295. STOREWORD(pwp16->flags, lpwp->flags);
  1296. FLUSHVDMPTR(vpwp, sizeof(WINDOWPOS16), pwp16);
  1297. FREEVDMPTR(pwp16);
  1298. }
  1299. VOID W32CopyMsgStruct(VPMSG16 vpmsg16, LPMSG lpmsg, BOOL fThunk16To32)
  1300. {
  1301. register PMSG16 pmsg16;
  1302. GETVDMPTR(vpmsg16, sizeof(MSG16), pmsg16);
  1303. if (fThunk16To32) {
  1304. lpmsg->hwnd = HWND32(pmsg16->hwnd);
  1305. lpmsg->message = pmsg16->message;
  1306. lpmsg->wParam = pmsg16->wParam;
  1307. lpmsg->lParam = pmsg16->lParam;
  1308. lpmsg->time = pmsg16->time;
  1309. lpmsg->pt.x = pmsg16->pt.x;
  1310. lpmsg->pt.y = pmsg16->pt.y;
  1311. }
  1312. else {
  1313. // for later use.
  1314. }
  1315. FREEVDMPTR(pmsg16);
  1316. return;
  1317. }
  1318. VOID getpaintstruct16(VPVOID vp, LPPAINTSTRUCT lp)
  1319. {
  1320. PPAINTSTRUCT16 pps16;
  1321. GETVDMPTR(vp, sizeof(PAINTSTRUCT16), pps16);
  1322. (lp)->hdc = HDC32(FETCHWORD(pps16->hdc));
  1323. (lp)->fErase = FETCHSHORT(pps16->fErase);
  1324. (lp)->rcPaint.left = FETCHSHORT(pps16->rcPaint.left);
  1325. (lp)->rcPaint.top = FETCHSHORT(pps16->rcPaint.top);
  1326. (lp)->rcPaint.right = FETCHSHORT(pps16->rcPaint.right);
  1327. (lp)->rcPaint.bottom= FETCHSHORT(pps16->rcPaint.bottom);
  1328. (lp)->fRestore = FETCHSHORT(pps16->fRestore);
  1329. (lp)->fIncUpdate = FETCHSHORT(pps16->fIncUpdate);
  1330. RtlCopyMemory((lp)->rgbReserved,
  1331. pps16->rgbReserved, sizeof(pps16->rgbReserved));
  1332. FREEVDMPTR(pps16);
  1333. }
  1334. VOID putpaintstruct16(VPVOID vp, LPPAINTSTRUCT lp)
  1335. {
  1336. PPAINTSTRUCT16 pps16;
  1337. GETVDMPTR(vp, sizeof(PAINTSTRUCT16), pps16);
  1338. STOREWORD(pps16->hdc, GETHDC16((lp)->hdc));
  1339. STORESHORT(pps16->fErase, (lp)->fErase);
  1340. STORESHORT(pps16->rcPaint.left, (lp)->rcPaint.left);
  1341. STORESHORT(pps16->rcPaint.top, (lp)->rcPaint.top);
  1342. STORESHORT(pps16->rcPaint.right, (lp)->rcPaint.right);
  1343. STORESHORT(pps16->rcPaint.bottom, (lp)->rcPaint.bottom);
  1344. STORESHORT(pps16->fRestore, (lp)->fRestore);
  1345. STORESHORT(pps16->fIncUpdate, (lp)->fIncUpdate);
  1346. RtlCopyMemory(pps16->rgbReserved,
  1347. (lp)->rgbReserved, sizeof(pps16->rgbReserved));
  1348. FLUSHVDMPTR(vp, sizeof(PAINTSTRUCT16), pps16);
  1349. FREEVDMPTR(pps16);
  1350. }
  1351. VOID FASTCALL getmenuiteminfo16(VPVOID vp, LPMENUITEMINFO pmii32)
  1352. {
  1353. PMENUITEMINFO16 pmii16;
  1354. GETVDMPTR(vp, sizeof(*pmii16), pmii16);
  1355. pmii32->cbSize = sizeof(*pmii32);
  1356. pmii32->fMask = pmii16->fMask;
  1357. if (pmii32->fMask & MIIM_CHECKMARKS) {
  1358. pmii32->hbmpChecked = HBITMAP32(pmii16->hbmpChecked);
  1359. pmii32->hbmpUnchecked = HBITMAP32(pmii16->hbmpUnchecked);
  1360. } else {
  1361. pmii32->hbmpChecked = pmii32->hbmpUnchecked = NULL;
  1362. }
  1363. pmii32->dwItemData = (pmii32->fMask & MIIM_DATA)
  1364. ? pmii16->dwItemData
  1365. : 0;
  1366. pmii32->wID = (pmii32->fMask & MIIM_ID)
  1367. ? pmii16->wID
  1368. : 0;
  1369. pmii32->fState = (pmii32->fMask & MIIM_STATE)
  1370. ? pmii16->fState
  1371. : 0;
  1372. pmii32->hSubMenu = (pmii32->fMask & MIIM_SUBMENU)
  1373. ? HMENU32(pmii16->hSubMenu)
  1374. : NULL;
  1375. if (pmii32->fMask & MIIM_TYPE) {
  1376. pmii32->fType = pmii16->fType;
  1377. if (pmii32->fType & MFT_BITMAP) {
  1378. pmii32->dwTypeData = (LPTSTR) HBITMAP32(pmii16->dwTypeData);
  1379. } else if (!(pmii32->fType & MFT_NONSTRING)) { // like (pmii32->fType & MFT_STRING) but MFT_STRING is zero
  1380. GETPSZPTR(pmii16->dwTypeData, pmii32->dwTypeData);
  1381. AddParamMap( (DWORD) pmii32->dwTypeData, pmii16->dwTypeData);
  1382. } else {
  1383. pmii32->dwTypeData = (LPTSTR) pmii16->dwTypeData;
  1384. }
  1385. } else {
  1386. pmii32->dwTypeData = (LPSTR) pmii32->fType = 0;
  1387. }
  1388. pmii32->cch = pmii16->cch;
  1389. FREEVDMPTR(pmii16);
  1390. }
  1391. VOID FASTCALL putmenuiteminfo16(VPVOID vp, LPMENUITEMINFO pmii32)
  1392. {
  1393. PMENUITEMINFO16 pmii16;
  1394. GETVDMPTR(vp, sizeof(*pmii16), pmii16);
  1395. pmii16->cbSize = sizeof(*pmii16);
  1396. pmii16->fMask = (WORD) pmii32->fMask;
  1397. if (pmii32->fMask & MIIM_CHECKMARKS) {
  1398. pmii16->hbmpChecked = GETHBITMAP16(pmii32->hbmpChecked);
  1399. pmii16->hbmpUnchecked = GETHBITMAP16(pmii32->hbmpUnchecked);
  1400. }
  1401. if (pmii32->fMask & MIIM_DATA) {
  1402. pmii16->dwItemData = pmii32->dwItemData;
  1403. }
  1404. if (pmii32->fMask & MIIM_ID) {
  1405. pmii16->wID = (WORD) pmii32->wID;
  1406. }
  1407. if (pmii32->fMask & MIIM_STATE) {
  1408. pmii16->fState = (WORD) pmii32->fState;
  1409. }
  1410. if (pmii32->fMask & MIIM_SUBMENU) {
  1411. pmii16->hSubMenu = GETHMENU16(pmii32->hSubMenu);
  1412. }
  1413. if (pmii32->fMask & MIIM_TYPE) {
  1414. pmii16->fType = (WORD) pmii32->fType;
  1415. if (pmii32->fType & MFT_BITMAP) {
  1416. pmii16->dwTypeData = GETHBITMAP16(pmii32->dwTypeData);
  1417. } else if (!(pmii32->fType & MFT_NONSTRING)) { // like (pmii32->fType & MFT_STRING) but MFT_STRING is zero
  1418. pmii16->dwTypeData = GetParam16( (DWORD) pmii32->dwTypeData);
  1419. } else {
  1420. pmii16->dwTypeData = (VPSTR) pmii32->dwTypeData;
  1421. }
  1422. }
  1423. FREEVDMPTR(pmii16);
  1424. }