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.

3874 lines
114 KiB

  1. /*++
  2. Copyright (c) 1992 Microsoft Corporation
  3. Module Name:
  4. wcomdlg.c
  5. Abstract:
  6. 32-bit support for thunking COMMDLG in WOW
  7. Author:
  8. John Vert (jvert) 31-Dec-1992
  9. Revision History:
  10. John Vert (jvert) 31-Dec-1992
  11. created
  12. --*/
  13. #include "precomp.h"
  14. #pragma hdrstop
  15. #include <cderr.h>
  16. #include <dlgs.h>
  17. #include <wowcmndg.h>
  18. MODNAME(wcommdlg.c);
  19. //
  20. // Debugging stuff...
  21. //
  22. #if DEBUG
  23. void WCDDumpCHOOSECOLORData16(PCHOOSECOLORDATA16 p16);
  24. void WCDDumpCHOOSECOLORData32(CHOOSECOLOR *p32);
  25. void WCDDumpCHOOSEFONTData16(PCHOOSEFONTDATA16 p16);
  26. void WCDDumpCHOOSEFONTData32(CHOOSEFONT *p32);
  27. void WCDDumpFINDREPLACE16(PFINDREPLACE16 p16);
  28. void WCDDumpFINDREPLACE32(FINDREPLACE *p32);
  29. void WCDDumpOPENFILENAME16(POPENFILENAME16 p16);
  30. void WCDDumpOPENFILENAME32(OPENFILENAME *p32);
  31. void WCDDumpPRINTDLGData16(PPRINTDLGDATA16 p16);
  32. void WCDDumpPRINTDLGData32(PRINTDLG *p32);
  33. // macros to dump the 16 & 32 bit structs
  34. #define WCDDUMPCHOOSECOLORDATA16(p16) WCDDumpCHOOSECOLORData16(p16)
  35. #define WCDDUMPCHOOSECOLORDATA32(p32) WCDDumpCHOOSECOLORData32(p32)
  36. #define WCDDUMPCHOOSEFONTDATA16(p16) WCDDumpCHOOSEFONTData16(p16)
  37. #define WCDDUMPCHOOSEFONTDATA32(p32) WCDDumpCHOOSEFONTData32(p32)
  38. #define WCDDUMPFINDREPLACE16(p16) WCDDumpFINDREPLACE16(p16)
  39. #define WCDDUMPFINDREPLACE32(p32) WCDDumpFINDREPLACE32(p32)
  40. #define WCDDUMPOPENFILENAME16(p16) WCDDumpOPENFILENAME16(p16)
  41. #define WCDDUMPOPENFILENAME32(p32) WCDDumpOPENFILENAME32(p32)
  42. #define WCDDUMPPRINTDLGDATA16(p16) WCDDumpPRINTDLGData16(p16)
  43. #define WCDDUMPPRINTDLGDATA32(p32) WCDDumpPRINTDLGData32(p32)
  44. #else // !DEBUG
  45. #define WCDDUMPCHOOSECOLORDATA16(p16)
  46. #define WCDDUMPCHOOSECOLORDATA32(p32)
  47. #define WCDDUMPCHOOSEFONTDATA16(p16)
  48. #define WCDDUMPCHOOSEFONTDATA32(p32)
  49. #define WCDDUMPOPENFILENAME16(p16)
  50. #define WCDDUMPOPENFILENAME32(p32)
  51. #define WCDDUMPPRINTDLGDATA16(p16)
  52. #define WCDDUMPPRINTDLGDATA32(p32)
  53. #define WCDDUMPFINDREPLACE16(p16)
  54. #define WCDDUMPFINDREPLACE32(p32)
  55. #endif // !DEBUG
  56. // global data
  57. WORD msgCOLOROK = 0;
  58. WORD msgFILEOK = 0;
  59. WORD msgWOWLFCHANGE = 0;
  60. WORD msgWOWDIRCHANGE = 0;
  61. WORD msgWOWCHOOSEFONT = 0;
  62. WORD msgSHAREVIOLATION = 0;
  63. WORD msgFINDREPLACE = 0;
  64. /* external global stuff */
  65. extern WORD gwKrnl386CodeSeg1;
  66. extern WORD gwKrnl386CodeSeg2;
  67. extern WORD gwKrnl386CodeSeg3;
  68. extern WORD gwKrnl386DataSeg1;
  69. ULONG dwExtError = 0;
  70. #define SETEXTENDEDERROR(Code) (dwExtError=Code)
  71. /*+++ For reference only -- which flags are set on output
  72. #define FR_OUTPUTFLAGS (FR_DOWN | FR_WHOLEWORD | FR_MATCHCASE | \
  73. FR_FINDNEXT | FR_REPLACE | FR_REPLACEALL | \
  74. FR_DIALOGTERM | FR_SHOWHELP | FR_NOUPDOWN | \
  75. FR_NOMATCHCASE | FR_NOWHOLEWORD | FR_HIDEUPDOWN | \
  76. FR_HIDEMATCHCASE | FR_HIDEWHOLEWORD)
  77. #define PD_OUTPUTFLAGS (PD_ALLPAGES | PD_COLLATE | PD_PAGENUMS | \
  78. PD_PRINTTOFILE | PD_SELECTION)
  79. #define FO_OUTPUTFLAGS (OFN_READONLY | OFN_EXTENSIONDIFFERENT)
  80. #define CF_OUTPUTFLAGS (CF_NOFACESEL | CF_NOSIZESEL | CF_NOSTYLESEL)
  81. ---*/
  82. // private typedefs and structs
  83. typedef BOOL (APIENTRY* FILENAMEPROC)(LPOPENFILENAME);
  84. typedef HWND (APIENTRY* FINDREPLACEPROC)(LPFINDREPLACE);
  85. // exported by comdlg32.dll to allow us to ultimately keep 16-bit common dialog
  86. // structs in sync with the UNICODE version maintained by comdlg32.
  87. extern VOID Ssync_ANSI_UNICODE_Struct_For_WOW(HWND hDlg,
  88. BOOL fANSI_To_UNICODE,
  89. DWORD dwID);
  90. // private function prototypes
  91. VOID
  92. Thunk_OFNstrs16to32(IN OPENFILENAME *pOFN32,
  93. IN POPENFILENAME16 pOFN16);
  94. BOOL
  95. Alloc_OFN32_strs(IN OPENFILENAME *pOFN32,
  96. IN POPENFILENAME16 pOFN16);
  97. VOID
  98. Free_OFN32_strs(IN OPENFILENAME *pOFN32);
  99. PCOMMDLGTD
  100. GetCommdlgTd(IN HWND Hwnd32);
  101. HINSTANCE
  102. ThunkCDTemplate16to32(IN HAND16 hInst16,
  103. IN DWORD hPrintTemp16,
  104. IN VPVOID vpTemplateName,
  105. IN DWORD dwFlags16,
  106. IN OUT DWORD *pFlags,
  107. IN DWORD ETFlag,
  108. IN DWORD ETHFlag,
  109. OUT PPRES pRes,
  110. OUT PBOOL fError);
  111. VOID
  112. FreeCDTemplate32(IN PRES pRes,
  113. IN HINSTANCE hInst,
  114. IN BOOL bETFlag,
  115. IN BOOL bETHFlag);
  116. PRES
  117. GetTemplate16(IN HAND16 hInstance,
  118. IN VPCSTR TemplateName,
  119. IN BOOLEAN UseHandle);
  120. HGLOBAL
  121. ThunkhDevMode16to32(IN HAND16 hDevMode16);
  122. VOID
  123. ThunkhDevMode32to16(IN OUT HAND16 *phDevMode16,
  124. IN HANDLE hDevMode32);
  125. HANDLE
  126. ThunkhDevNames16to32(IN HAND16 hDevNames16);
  127. VOID
  128. ThunkhDevNames32to16(IN OUT HAND16 *phDevNames16,
  129. IN HANDLE hDevNames);
  130. VOID
  131. ThunkCHOOSECOLOR16to32(OUT CHOOSECOLOR *pCC32,
  132. IN PCHOOSECOLORDATA16 pCC16);
  133. VOID
  134. ThunkCHOOSECOLOR32to16(OUT PCHOOSECOLORDATA16 pCC16,
  135. IN CHOOSECOLOR *pCC32);
  136. VOID
  137. ThunkCHOOSEFONT16to32(OUT CHOOSEFONT *pCF32,
  138. IN PCHOOSEFONTDATA16 pCF16);
  139. VOID
  140. ThunkCHOOSEFONT32to16(OUT PCHOOSEFONTDATA16 pCF16,
  141. IN CHOOSEFONT *pCF32);
  142. VOID
  143. ThunkFINDREPLACE16to32(OUT FINDREPLACE *pFR32,
  144. IN PFINDREPLACE16 pFR16);
  145. VOID
  146. ThunkFINDREPLACE32to16(OUT PFINDREPLACE16 pFR16,
  147. IN FINDREPLACE *pFR32);
  148. BOOL
  149. ThunkOPENFILENAME16to32(OUT OPENFILENAME *pOFN32,
  150. IN POPENFILENAME16 pOFN16);
  151. VOID
  152. ThunkOPENFILENAME32to16(OUT POPENFILENAME16 pOFN16,
  153. IN OPENFILENAME *pOFN32,
  154. IN BOOLEAN bUpperStrings);
  155. VOID
  156. ThunkPRINTDLG16to32(OUT PRINTDLG *pPD32,
  157. IN PPRINTDLGDATA16 pPD16);
  158. VOID
  159. ThunkPRINTDLG32to16(IN VPVOID vppd,
  160. OUT PRINTDLG *pPD32);
  161. VOID
  162. ThunkCDStruct16to32(IN HWND hDlg,
  163. IN CHOOSECOLOR *pCC,
  164. IN VPVOID vp);
  165. VOID
  166. ThunkCDStruct32to16(IN HWND hDlg,
  167. IN VPVOID vp,
  168. IN CHOOSECOLOR *pCC);
  169. UINT APIENTRY
  170. WCD32CommonDialogProc(HWND hdlg,
  171. UINT uMsg,
  172. WPARAM uParam,
  173. LPARAM lParam,
  174. PCOMMDLGTD pCTD,
  175. VPVOID vpfnHook);
  176. UINT APIENTRY
  177. WCD32PrintSetupDialogProc(HWND hdlg,
  178. UINT uMsg,
  179. WPARAM uParam,
  180. LPARAM lParam);
  181. UINT APIENTRY
  182. WCD32DialogProc(HWND hdlg,
  183. UINT uMsg,
  184. WPARAM uParam,
  185. LPARAM lParam);
  186. ULONG
  187. WCD32GetFileName(IN PVDMFRAME pFrame,
  188. IN FILENAMEPROC Function);
  189. ULONG
  190. WCD32FindReplaceText(IN PVDMFRAME pFrame,
  191. IN FINDREPLACEPROC Function);
  192. UINT APIENTRY
  193. WCD32FindReplaceDialogProc(HWND hdlg,
  194. UINT uMsg,
  195. WPARAM uParam,
  196. LPARAM lParam);
  197. #define VALID_OFN16_FLAGS (OFN_READONLY | \
  198. OFN_OVERWRITEPROMPT | \
  199. OFN_HIDEREADONLY | \
  200. OFN_NOCHANGEDIR | \
  201. OFN_SHOWHELP | \
  202. OFN_ENABLEHOOK | \
  203. OFN_ENABLETEMPLATE | \
  204. OFN_ENABLETEMPLATEHANDLE | \
  205. OFN_NOVALIDATE | \
  206. OFN_ALLOWMULTISELECT | \
  207. OFN_EXTENSIONDIFFERENT | \
  208. OFN_PATHMUSTEXIST | \
  209. OFN_FILEMUSTEXIST | \
  210. OFN_CREATEPROMPT | \
  211. OFN_SHAREAWARE | \
  212. OFN_NOREADONLYRETURN | \
  213. OFN_NOTESTFILECREATE)
  214. //
  215. // unique message thunks
  216. //
  217. // This function thunks the private messages
  218. // msgCOLOROK
  219. BOOL FASTCALL
  220. WM32msgCOLOROK(LPWM32MSGPARAMEX lpwm32mpex)
  221. {
  222. LPCHOOSECOLOR pCC32;
  223. PCHOOSECOLORDATA16 pCC16;
  224. GETVDMPTR((VPVOID)lpwm32mpex->Parm16.WndProc.lParam,
  225. sizeof(CHOOSECOLORDATA16),
  226. pCC16);
  227. pCC32 = (LPCHOOSECOLOR)lpwm32mpex->lParam;
  228. if(pCC16 && pCC32) {
  229. if(lpwm32mpex->fThunk) {
  230. ThunkCHOOSECOLOR32to16(pCC16, pCC32);
  231. }
  232. else {
  233. ThunkCHOOSECOLOR16to32(pCC32, pCC16);
  234. }
  235. }
  236. else {
  237. return(FALSE);
  238. }
  239. FREEVDMPTR(pCC16);
  240. return (TRUE);
  241. }
  242. // This function thunks the private messages
  243. // msgFILEOK
  244. BOOL FASTCALL
  245. WM32msgFILEOK(LPWM32MSGPARAMEX lpwm32mpex)
  246. {
  247. VPOPENFILENAME vpof;
  248. POPENFILENAME16 pOFN16;
  249. OPENFILENAME *pOFN32;
  250. vpof = (VPOPENFILENAME)(GetCommdlgTd(lpwm32mpex->hwnd)->vpData);
  251. pOFN32 = (OPENFILENAME *)lpwm32mpex->lParam;
  252. //
  253. // Approach sends its own fileok message when you click on its
  254. // secret listbox that it displays over lst1 sometimes. It
  255. // sends NULL for the LPARAM instead of the address of the
  256. // openfilename structure.
  257. if(pOFN32 == NULL) {
  258. lpwm32mpex->Parm16.WndProc.lParam = (LPARAM)NULL;
  259. return(TRUE);
  260. }
  261. GETVDMPTR(vpof, sizeof(OPENFILENAME16), pOFN16);
  262. if (lpwm32mpex->fThunk) {
  263. UpdateDosCurrentDirectory(DIR_NT_TO_DOS);
  264. lpwm32mpex->Parm16.WndProc.lParam = (LPARAM)vpof;
  265. // sudeepb 12-Mar-1996
  266. //
  267. // The selected file name needs to be uppercased for
  268. // apps like symanatec QA 4.0. So changed the following parameter
  269. // in ThunkOpenFileName from FALSE to TRUE.
  270. ThunkOPENFILENAME32to16(pOFN16, pOFN32, TRUE);
  271. } else {
  272. ThunkOPENFILENAME16to32(pOFN32, pOFN16);
  273. }
  274. FREEVDMPTR(pOFN16);
  275. return (TRUE);
  276. }
  277. // This function thunks the private messages
  278. // msgWOWDIRCHANGE
  279. BOOL FASTCALL
  280. WM32msgWOWDIRCHANGE(LPWM32MSGPARAMEX lpwm32mpex)
  281. {
  282. if (lpwm32mpex->fThunk) {
  283. UpdateDosCurrentDirectory(DIR_NT_TO_DOS);
  284. }
  285. return (TRUE);
  286. }
  287. // This function thunks the private message
  288. // msgWOWLFCHANGE
  289. BOOL FASTCALL
  290. WM32msgWOWLFCHANGE(LPWM32MSGPARAMEX lpwm32mpex)
  291. {
  292. VPCHOOSEFONTDATA vpcf;
  293. PCHOOSEFONTDATA16 pCF16;
  294. vpcf = (VPCHOOSEFONTDATA)(GetCommdlgTd(lpwm32mpex->hwnd)->vpData);
  295. GETVDMPTR(vpcf, sizeof(CHOOSEFONTDATA16), pCF16);
  296. WOW32ASSERT(pCF16);
  297. if (lpwm32mpex->fThunk) {
  298. PUTLOGFONT16(DWORD32(pCF16->lpLogFont),
  299. sizeof(LOGFONT),
  300. (LPLOGFONT)lpwm32mpex->lParam);
  301. }
  302. FREEVDMPTR(pCF16);
  303. return(TRUE);
  304. }
  305. // This function thunks the private message
  306. // msgSHAREVIOLATION
  307. BOOL FASTCALL
  308. WM32msgSHAREVIOLATION(LPWM32MSGPARAMEX lpwm32mpex)
  309. {
  310. INT cb;
  311. PLONG plParamNew = &lpwm32mpex->Parm16.WndProc.lParam;
  312. if (lpwm32mpex->fThunk) {
  313. if (lpwm32mpex->lParam) {
  314. cb = strlen((LPSZ)lpwm32mpex->lParam)+1;
  315. if (!(*plParamNew = malloc16(cb))) {
  316. return(FALSE);
  317. }
  318. putstr16((VPSZ)*plParamNew, (LPSZ)lpwm32mpex->lParam, cb);
  319. }
  320. } else {
  321. if (*plParamNew) {
  322. free16((VPVOID) *plParamNew);
  323. }
  324. }
  325. return (TRUE);
  326. }
  327. // This function thunks the private messages
  328. // WM_CHOOSEFONT_GETLOGFONT
  329. BOOL FASTCALL
  330. WM32msgCHOOSEFONTGETLOGFONT(LPWM32MSGPARAMEX lpwm32mpex)
  331. {
  332. LOGFONT LogFont32;
  333. // The mere fact that we access the buffer after allowing the 16-bit
  334. // hook proc to step in breaks Serif PagePlus app which wants it's
  335. // hook proc to always have a shot and commdlg to check the return value.
  336. // If hook proc returns TRUE, no further action is taken
  337. //
  338. // This is the message an app sends the dialog if it wants to find
  339. // out what font is currently selected.
  340. //
  341. // We thunk this by sending yet another hackorama message to comdlg32,
  342. // who will then fill in the 32-bit structure we pass in so we can
  343. // thunk it back to the 16-bit structure. Then we return TRUE so
  344. // comdlg32 doesn't reference the 16-bit logfont.
  345. //
  346. if (!lpwm32mpex->fThunk && !lpwm32mpex->lReturn) {
  347. SendMessage(lpwm32mpex->hwnd, msgWOWCHOOSEFONT, 0, (LPARAM)&LogFont32);
  348. PUTLOGFONT16(lpwm32mpex->lParam, sizeof(LOGFONT), &LogFont32);
  349. lpwm32mpex->lReturn = TRUE;
  350. }
  351. return (TRUE);
  352. }
  353. //
  354. // Dialog callback hook thunks
  355. //
  356. UINT APIENTRY
  357. WCD32DialogProc(HWND hdlg,
  358. UINT uMsg,
  359. WPARAM uParam,
  360. LPARAM lParam)
  361. /*++
  362. Routine Description:
  363. This is the hook proc used by ChooseColor, ChooseFont, GetOpenFileName,
  364. GetSaveFileName, and PrintDlg. It pulls the 16-bit callback
  365. out of the thread data and calls the common dialog proc to do
  366. the rest of the work.
  367. --*/
  368. {
  369. PCOMMDLGTD Td;
  370. Td = GetCommdlgTd(hdlg);
  371. if(Td) {
  372. return(WCD32CommonDialogProc(hdlg,
  373. uMsg,
  374. uParam,
  375. lParam,
  376. Td,
  377. Td->vpfnHook));
  378. } else {
  379. return(0);
  380. }
  381. }
  382. UINT APIENTRY
  383. WCD32PrintSetupDialogProc(HWND hdlg,
  384. UINT uMsg,
  385. WPARAM uParam,
  386. LPARAM lParam)
  387. /*++
  388. Routine Description:
  389. This is the hook proc used by PrintSetup. It is only used when
  390. the Setup button on the Print dialog directly creates the PrintSetup
  391. dialog. We find the correct TD by looking for the TD of our owner
  392. window (which is the print dialog)
  393. It calls the common dialog proc to do the rest of the work.
  394. --*/
  395. {
  396. PCOMMDLGTD pTD;
  397. pTD = CURRENTPTD()->CommDlgTd;
  398. if(pTD) {
  399. while (pTD->SetupHwnd != GETHWND16(hdlg)) {
  400. pTD = pTD->Previous;
  401. if(!pTD) {
  402. WOW32ASSERT(FALSE);
  403. return(0);
  404. }
  405. }
  406. return(WCD32CommonDialogProc(hdlg,
  407. uMsg,
  408. uParam,
  409. lParam,
  410. pTD,
  411. pTD->vpfnSetupHook));
  412. } else {
  413. return(0);
  414. }
  415. }
  416. UINT APIENTRY
  417. WCD32FindReplaceDialogProc(HWND hdlg,
  418. UINT uMsg,
  419. WPARAM uParam,
  420. LPARAM lParam)
  421. /*++
  422. Routine Description:
  423. This is the hook proc used by FindText and ReplaceText. It does cleanup
  424. on WM_DESTROY and calls WCD32CommonDialogProc to handle the 16-bit
  425. dialog hook callback on all messages, if needed.
  426. --*/
  427. {
  428. PFINDREPLACE16 pFR16;
  429. VPFINDREPLACE vpfr;
  430. LPFINDREPLACE pFR32;
  431. PCOMMDLGTD ptdDlg;
  432. PCOMMDLGTD ptdOwner;
  433. UINT uRet = FALSE;
  434. // If the ptdDlg is invalid, do nothing.
  435. ptdDlg = GetCommdlgTd(hdlg);
  436. if (ptdDlg == NULL) {
  437. return(uRet);
  438. }
  439. if (uMsg != WM_DESTROY) {
  440. // this will be FALSE if the app didn't specify a 16-bit hookproc
  441. // we always set the 32-bit hookproc in ThunkFINDREPLACE16to32()
  442. if (ptdDlg->vpfnHook) {
  443. uRet = WCD32CommonDialogProc(hdlg,
  444. uMsg,
  445. uParam,
  446. lParam,
  447. ptdDlg,
  448. ptdDlg->vpfnHook);
  449. }
  450. }
  451. else {
  452. pFR32 = (LPFINDREPLACE)ptdDlg->pData32;
  453. // UnLink both per thread data structs from the list.
  454. ptdOwner = GetCommdlgTd(pFR32->hwndOwner);
  455. CURRENTPTD()->CommDlgTd = ptdDlg->Previous;
  456. WOW32ASSERT(ptdOwner->Previous == ptdDlg);
  457. vpfr = ptdDlg->vpData;
  458. GETVDMPTR(vpfr, sizeof(FINDREPLACE16), pFR16);
  459. // CleanUp template if used.
  460. FreeCDTemplate32((PRES)ptdDlg->pRes,
  461. pFR32->hInstance,
  462. DWORD32(pFR16->Flags) & FR_ENABLETEMPLATE,
  463. DWORD32(pFR16->Flags) & FR_ENABLETEMPLATEHANDLE);
  464. FREEVDMPTR(pFR16);
  465. // Free the per thread data structs.
  466. free_w(ptdDlg);
  467. free_w(ptdOwner);
  468. // Free the 32-bit FINDREPLACE structure.
  469. free_w(pFR32->lpstrFindWhat);
  470. free_w(pFR32->lpstrReplaceWith);
  471. free_w(pFR32);
  472. }
  473. if (uMsg == WM_INITDIALOG) {
  474. // Force COMDLG32!FindReplaceDialogProc to handle WM_INITDIALOG.
  475. uRet = TRUE;
  476. }
  477. return(uRet);
  478. }
  479. UINT APIENTRY
  480. WCD32CommonDialogProc(HWND hdlg,
  481. UINT uMsg,
  482. WPARAM uParam,
  483. LPARAM lParam,
  484. PCOMMDLGTD pCTD,
  485. VPVOID vpfnHook)
  486. /*++
  487. Routine Description:
  488. This thunks the 32-bit dialog callback into a 16-bit callback
  489. This is the common code used by all the dialog callback thunks that
  490. actually calls the 16-bit callback.
  491. --*/
  492. {
  493. BOOL fSuccess;
  494. LPFNM32 pfnThunkMsg;
  495. WM32MSGPARAMEX wm32mpex;
  496. BOOL fMessageNeedsThunking;
  497. // If the app has GP Faulted we don't want to pass it any more input
  498. // This should be removed when USER32 does clean up on task death so
  499. // it doesn't call us - mattfe june 24 92
  500. // LOGDEBUG(10, ("CommonDialogProc In: %lX %X %X %lX\n",
  501. // (DWORD)hdlg,
  502. // uMsg,
  503. // uParam,
  504. // lParam));
  505. if(CURRENTPTD()->dwFlags & TDF_IGNOREINPUT) {
  506. LOGDEBUG(6,
  507. (" WCD32OpenFileDialog Ignoring Input Messsage %04X\n",
  508. uMsg));
  509. WOW32ASSERTMSG(gfIgnoreInputAssertGiven,
  510. "WCD32CommonDialogProc: TDF_IGNOREINPUT hack was used, shouldn't be, "
  511. "please email DaveHart with repro instructions. Hit 'g' to ignore "
  512. "this and suppress this assertion from now on.\n");
  513. gfIgnoreInputAssertGiven = TRUE;
  514. goto SilentError;
  515. }
  516. #if DBG
  517. if(pCTD==NULL) {
  518. LOGDEBUG(0,(" WCD32OpenFileDialog ERROR: pCTD==NULL\n"));
  519. goto Error;
  520. }
  521. // If pCTD->vpfnHook is NULL, then something is broken; we
  522. // certainly can't continue because we don't know what 16-bit func to call
  523. if(!vpfnHook) {
  524. LOGDEBUG(0,(" WCD32OpenFileDialog ERROR: no hook proc for message %04x Dlg = %08lx\n", uMsg, hdlg ));
  525. goto Error;
  526. }
  527. #endif
  528. wm32mpex.Parm16.WndProc.hwnd = GETHWND16(hdlg);
  529. wm32mpex.Parm16.WndProc.wMsg = (WORD)uMsg;
  530. wm32mpex.Parm16.WndProc.wParam = (WORD)uParam;
  531. wm32mpex.Parm16.WndProc.lParam = (LONG)lParam;
  532. wm32mpex.Parm16.WndProc.hInst = (WORD)GetWindowLong(hdlg, GWL_HINSTANCE);
  533. // On Win3.1, the app & the system share the ptr to the same structure that
  534. // the app passed to the common dialog API. Therefore, when one side makes
  535. // a change to the struct, the other is aware of the change. This is not
  536. // the case on NT since we thunk the struct into a 32-bit ANSI struct which
  537. // is then thunked into a 32-bit UNICODE struct in the comdlg32 code. We
  538. // attempt to synchronize all these structs by rethunking them for every
  539. // message sent to the 16-bit side & for every API call the app makes.
  540. // See sync code in callback16(), fastwow bopping code, and w32Dispatch().
  541. // ComDlg32 thunks UNICODEtoANSI before calling us & ASNItoUNICODE when we
  542. // return. Ug!!! Apparently a fair number of apps depend on this
  543. // behavior since we've debugged this problem about 6 times to date and
  544. // each time we have put in special hacks for each case. With any luck
  545. // this should be a general fix. 08/97 CMJones
  546. if(uMsg < 0x400) {
  547. LOGDEBUG(3,
  548. ("%04X (%s)\n",
  549. CURRENTPTD()->htask16,
  550. (aw32Msg[uMsg].lpszW32)));
  551. pfnThunkMsg = aw32Msg[uMsg].lpfnM32;
  552. if(uMsg == WM_INITDIALOG) {
  553. // The address of the 16-bit structure that the app passed to the
  554. // original common dialog API is passed in lParam in WM_INITDIALOG
  555. // messages in Win 3.1
  556. wm32mpex.Parm16.WndProc.lParam = lParam = (LPARAM)pCTD->vpData;
  557. }
  558. // Check for unique messages
  559. } else if(uMsg >= 0x400) {
  560. if (uMsg == msgFILEOK) {
  561. pfnThunkMsg = WM32msgFILEOK;
  562. } else if(uMsg == msgCOLOROK) {
  563. wm32mpex.Parm16.WndProc.lParam = (LPARAM)pCTD->vpData;
  564. pfnThunkMsg = WM32msgCOLOROK;
  565. } else if(uMsg == msgSHAREVIOLATION) {
  566. pfnThunkMsg = WM32msgSHAREVIOLATION;
  567. } else if(uMsg == msgWOWDIRCHANGE) {
  568. pfnThunkMsg = WM32msgWOWDIRCHANGE;
  569. } else if(uMsg == msgWOWLFCHANGE) {
  570. pfnThunkMsg = WM32msgWOWLFCHANGE;
  571. } else if(pCTD->Flags & WOWCD_ISCHOOSEFONT) {
  572. // special ChooseFont thunks to handle goofy GETLOGFONT message
  573. if(uMsg == WM_CHOOSEFONT_GETLOGFONT) {
  574. pfnThunkMsg = WM32msgCHOOSEFONTGETLOGFONT;
  575. } else if(uMsg == msgWOWCHOOSEFONT) {
  576. //
  577. // no wow app will expect this, so don't send it.
  578. //
  579. return(FALSE);
  580. } else {
  581. pfnThunkMsg = WM32NoThunking;
  582. }
  583. } else {
  584. pfnThunkMsg = WM32NoThunking;
  585. }
  586. }
  587. fMessageNeedsThunking = (pfnThunkMsg != WM32NoThunking);
  588. if(fMessageNeedsThunking) {
  589. wm32mpex.fThunk = THUNKMSG;
  590. wm32mpex.hwnd = hdlg;
  591. wm32mpex.uMsg = uMsg;
  592. wm32mpex.uParam = uParam;
  593. wm32mpex.lParam = lParam;
  594. wm32mpex.pww = NULL;
  595. wm32mpex.lpfnM32 = pfnThunkMsg;
  596. if(!(pfnThunkMsg)(&wm32mpex)) {
  597. LOGDEBUG(LOG_ERROR,(" WCD32OpenFileDialog ERROR: cannot thunk 32-bit message %04x\n", uMsg));
  598. goto Error;
  599. }
  600. } else {
  601. LOGDEBUG(6,("WCD32CommonDialogProc, No Thunking was required for the 32-bit message %s(%04x)\n", (LPSZ)GetWMMsgName(uMsg), uMsg));
  602. }
  603. // this call may cause 16-bit memory to move
  604. // this call will call 32->16 sync code before the callback & the 16->32
  605. // sync upon return from the callback
  606. fSuccess = CallBack16(RET_WNDPROC,
  607. &wm32mpex.Parm16,
  608. vpfnHook,
  609. (PVPVOID)&wm32mpex.lReturn);
  610. // flat ptrs to 16-bit mem are now invalid due to possible memory movement
  611. // the callback function of a dialog is of type FARPROC whose return value
  612. // is of type 'int'. Since dx:ax is copied into lReturn in the above
  613. // CallBack16 call, we need to zero out the hiword, otherwise we will be
  614. // returning an erroneous value.
  615. wm32mpex.lReturn = (LONG)LOWORD(wm32mpex.lReturn);
  616. if(fMessageNeedsThunking) {
  617. wm32mpex.fThunk = UNTHUNKMSG;
  618. (pfnThunkMsg)(&wm32mpex);
  619. }
  620. if(!fSuccess)
  621. goto Error;
  622. Done:
  623. // Uncomment this to receive message on exit
  624. // LOGDEBUG(10, ("CommonDialogProc Out: Return %lX\n", wm32mpex.lReturn));
  625. return wm32mpex.lReturn;
  626. Error:
  627. LOGDEBUG(5,(" WCD32OpenFileDialog WARNING: cannot call back, using default message handling\n"));
  628. SilentError:
  629. wm32mpex.lReturn = 0;
  630. goto Done;
  631. }
  632. ULONG FASTCALL
  633. WCD32ExtendedError( IN PVDMFRAME pFrame )
  634. /*++
  635. Routine Description:
  636. 32-bit thunk for CommDlgExtendedError()
  637. Arguments:
  638. pFrame - Supplies 16-bit argument frame
  639. Return Value:
  640. error code to be returned
  641. --*/
  642. {
  643. if (dwExtError != 0) {
  644. return(dwExtError);
  645. }
  646. return(CommDlgExtendedError());
  647. }
  648. ULONG FASTCALL
  649. WCD32ChooseColor(PVDMFRAME pFrame)
  650. /*++
  651. Routine Description:
  652. This routine thunks the 16-bit ChooseColor common dialog to the 32-bit
  653. side.
  654. Arguments:
  655. pFrame - Supplies 16-bit argument frame
  656. Return Value:
  657. 16-bit BOOLEAN to be returned.
  658. --*/
  659. {
  660. ULONG ul = GETBOOL16(FALSE);
  661. register PCHOOSECOLOR16 parg16;
  662. VPCHOOSECOLORDATA vpcc;
  663. CHOOSECOLOR CC32;
  664. PCHOOSECOLORDATA16 pCC16;
  665. PRES pRes = NULL;
  666. COMMDLGTD ThreadData;
  667. COLORREF CustColors32[16]; // on stack for DWORD alignment
  668. DWORD dwFlags16;
  669. BOOL fError = FALSE;
  670. GETARGPTR(pFrame, sizeof(CHOOSECOLOR16), parg16);
  671. vpcc = parg16->lpcc;
  672. SETEXTENDEDERROR( 0 );
  673. // invalidate this now
  674. FREEVDMPTR( parg16 );
  675. // initialize unique window message
  676. if (msgCOLOROK == 0) {
  677. if(!(msgCOLOROK = (WORD)RegisterWindowMessage(COLOROKSTRING))) {
  678. SETEXTENDEDERROR( CDERR_REGISTERMSGFAIL );
  679. LOGDEBUG(2,("WCD32ChooseColor:RegisterWindowMessage failed\n"));
  680. return(0);
  681. }
  682. }
  683. GETVDMPTR(vpcc, sizeof(CHOOSECOLORDATA16), pCC16);
  684. WCDDUMPCHOOSECOLORDATA16(pCC16);
  685. if(DWORD32(pCC16->lStructSize) != sizeof(CHOOSECOLORDATA16)) {
  686. SETEXTENDEDERROR( CDERR_STRUCTSIZE );
  687. FREEVDMPTR(pCC16);
  688. return(0);
  689. }
  690. RtlZeroMemory(&ThreadData, sizeof(COMMDLGTD));
  691. ThreadData.Previous = CURRENTPTD()->CommDlgTd;
  692. ThreadData.hdlg = (HWND16)-1;
  693. ThreadData.pData32 = &CC32;
  694. ThreadData.Flags = 0;
  695. if(DWORD32(pCC16->Flags) & CC_ENABLEHOOK) {
  696. ThreadData.vpfnHook = DWORD32(pCC16->lpfnHook);
  697. if(!ThreadData.vpfnHook) {
  698. SETEXTENDEDERROR(CDERR_NOHOOK);
  699. FREEVDMPTR(pCC16);
  700. return(0);
  701. }
  702. ThreadData.vpData = vpcc;
  703. }
  704. else {
  705. STOREDWORD(pCC16->lpfnHook, 0);
  706. }
  707. RtlZeroMemory(&CC32, sizeof(CHOOSECOLOR));
  708. CC32.lpCustColors = CustColors32;
  709. ThunkCHOOSECOLOR16to32(&CC32, pCC16);
  710. dwFlags16 = DWORD32(pCC16->Flags);
  711. // this call invalidates flat ptrs to 16-bit memory
  712. CC32.hInstance = (HWND)ThunkCDTemplate16to32(WORD32(pCC16->hInstance),
  713. 0,
  714. DWORD32(pCC16->lpTemplateName),
  715. dwFlags16,
  716. &(CC32.Flags),
  717. CC_ENABLETEMPLATE,
  718. CC_ENABLETEMPLATEHANDLE,
  719. &pRes,
  720. &fError);
  721. if(fError) {
  722. goto ChooseColorExit;
  723. }
  724. // invalidate flat ptrs to 16-bit memory
  725. FREEVDMPTR(pCC16);
  726. WCDDUMPCHOOSECOLORDATA32(&CC32);
  727. // Set this just before the calling into comdlg32. This prevents the
  728. // synchronization stuff from firing until we actually need it.
  729. CURRENTPTD()->CommDlgTd = &ThreadData;
  730. // this call invalidates flat ptrs to 16-bit memory
  731. ul = GETBOOL16(ChooseColor(&CC32));
  732. CURRENTPTD()->CommDlgTd = ThreadData.Previous;
  733. if (ul) {
  734. WCDDUMPCHOOSECOLORDATA32(&CC32);
  735. GETVDMPTR(vpcc, sizeof(CHOOSECOLOR16), pCC16);
  736. ThunkCHOOSECOLOR32to16(pCC16, &CC32);
  737. WCDDUMPCHOOSECOLORDATA16(pCC16);
  738. FREEVDMPTR(pCC16);
  739. }
  740. ChooseColorExit:
  741. FreeCDTemplate32(pRes,
  742. (HINSTANCE)CC32.hInstance,
  743. dwFlags16 & CC_ENABLETEMPLATE,
  744. dwFlags16 & CC_ENABLETEMPLATEHANDLE);
  745. FREEVDMPTR(pCC16);
  746. return(ul);
  747. }
  748. VOID
  749. ThunkCHOOSECOLOR16to32(OUT CHOOSECOLOR *pCC32,
  750. IN PCHOOSECOLORDATA16 pCC16)
  751. {
  752. COLORREF *pCustColors16;
  753. DWORD Flags;
  754. if(pCC16 && pCC32) {
  755. pCC32->lStructSize = sizeof(CHOOSECOLOR);
  756. pCC32->hwndOwner = HWND32(pCC16->hwndOwner);
  757. // hInstance thunked separately
  758. pCC32->rgbResult = DWORD32(pCC16->rgbResult);
  759. if(pCC32->lpCustColors) {
  760. GETVDMPTR(pCC16->lpCustColors, 16*sizeof(COLORREF), pCustColors16);
  761. if(pCustColors16) {
  762. RtlCopyMemory(pCC32->lpCustColors,
  763. pCustColors16,
  764. 16*sizeof(COLORREF));
  765. }
  766. FREEVDMPTR(pCustColors16);
  767. }
  768. // preserve the template flag state while copying flags
  769. // 1. save template flag state
  770. // note: we never will have a 32-bit CC_ENABLETEMPLATE flag
  771. // 2. copy flags from 16-bit struct (add the WOWAPP flag)
  772. // 3. turn off all template flags
  773. // 4. restore original template flag state
  774. Flags = pCC32->Flags & CC_ENABLETEMPLATEHANDLE;
  775. pCC32->Flags = DWORD32(pCC16->Flags) | CD_WOWAPP;
  776. pCC32->Flags &= ~(CC_ENABLETEMPLATE | CC_ENABLETEMPLATEHANDLE);
  777. pCC32->Flags |= Flags;
  778. pCC32->lCustData = DWORD32(pCC16->lCustData);
  779. if((DWORD32(pCC16->Flags) & CC_ENABLEHOOK) && DWORD32(pCC16->lpfnHook)){
  780. pCC32->lpfnHook = WCD32DialogProc;
  781. }
  782. // lpTemplateName32 is thunked separately
  783. }
  784. }
  785. VOID
  786. ThunkCHOOSECOLOR32to16(OUT PCHOOSECOLORDATA16 pCC16,
  787. IN CHOOSECOLOR *pCC32)
  788. {
  789. COLORREF *pCustColors16;
  790. DWORD Flags, Flags32;
  791. if(pCC16 && pCC32) {
  792. STOREDWORD(pCC16->rgbResult, pCC32->rgbResult);
  793. // preserve the template flag state while copying flags
  794. // 1. save template flag state
  795. // 2. copy flags from 32-bit struct
  796. // 3. turn off all template flags and the WOWAPP flag
  797. // 4. restore original template flag state
  798. Flags = DWORD32(pCC16->Flags) & (CC_ENABLETEMPLATE |
  799. CC_ENABLETEMPLATEHANDLE);
  800. Flags32 = pCC32->Flags;
  801. Flags32 &= ~(CC_ENABLETEMPLATE | CC_ENABLETEMPLATEHANDLE | CD_WOWAPP);
  802. Flags32 |= Flags;
  803. STOREDWORD(pCC16->Flags, Flags32);
  804. GETVDMPTR(pCC16->lpCustColors, 16*sizeof(COLORREF), pCustColors16);
  805. if(pCustColors16) {
  806. RtlCopyMemory(pCustColors16,
  807. pCC32->lpCustColors,
  808. 16*sizeof(COLORREF));
  809. FREEVDMPTR(pCustColors16);
  810. }
  811. }
  812. }
  813. ULONG FASTCALL
  814. WCD32ChooseFont( PVDMFRAME pFrame )
  815. /*++
  816. Routine Description:
  817. This routine thunks the 16-bit ChooseFont common dialog to the 32-bit
  818. side.
  819. Arguments:
  820. pFrame - Supplies 16-bit argument frame
  821. Return Value:
  822. 16-bit BOOLEAN to be returned.
  823. --*/
  824. {
  825. ULONG ul = GETBOOL16(FALSE);
  826. register PCHOOSEFONT16 parg16;
  827. VPCHOOSEFONTDATA vpcf;
  828. CHOOSEFONT CF32;
  829. LOGFONT LogFont32;
  830. PCHOOSEFONTDATA16 pCF16;
  831. PRES pRes = NULL;
  832. COMMDLGTD ThreadData;
  833. DWORD dwFlags16;
  834. CHAR sStyle[2 * LF_FACESIZE];
  835. BOOL fError = FALSE;
  836. GETARGPTR(pFrame, sizeof(CHOOSEFONT16), parg16);
  837. vpcf = parg16->lpcf;
  838. SETEXTENDEDERROR( 0 );
  839. // invalidate this now
  840. FREEVDMPTR( parg16 );
  841. // initialize unique window messages
  842. if (msgWOWCHOOSEFONT == 0) {
  843. // private WOW<->comdlg32 message for handling WM_CHOOSEFONT_GETLOGFONT
  844. if(!(msgWOWCHOOSEFONT =
  845. (WORD)RegisterWindowMessage("WOWCHOOSEFONT_GETLOGFONT"))) {
  846. SETEXTENDEDERROR( CDERR_REGISTERMSGFAIL );
  847. LOGDEBUG(2,("WCD32ChooseFont:RegisterWindowMessage failed\n"));
  848. return(0);
  849. }
  850. }
  851. if (msgWOWLFCHANGE == 0) {
  852. // private message for thunking logfont changes
  853. if(!(msgWOWLFCHANGE = (WORD)RegisterWindowMessage("WOWLFChange"))) {
  854. SETEXTENDEDERROR( CDERR_REGISTERMSGFAIL );
  855. LOGDEBUG(2,("WCD32ChooseFont:RegisterWindowMessage 2 failed\n"));
  856. return(0);
  857. }
  858. }
  859. GETVDMPTR(vpcf, sizeof(CHOOSEFONTDATA16), pCF16);
  860. WCDDUMPCHOOSEFONTDATA16(pCF16);
  861. if(DWORD32(pCF16->lStructSize) != sizeof(CHOOSEFONTDATA16)) {
  862. SETEXTENDEDERROR( CDERR_STRUCTSIZE );
  863. FREEVDMPTR(pCF16);
  864. return(0);
  865. }
  866. RtlZeroMemory(&ThreadData, sizeof(COMMDLGTD));
  867. ThreadData.Previous = CURRENTPTD()->CommDlgTd;
  868. ThreadData.hdlg = (HWND16)-1;
  869. ThreadData.pData32 = &CF32;
  870. ThreadData.Flags = WOWCD_ISCHOOSEFONT;
  871. if(DWORD32(pCF16->Flags) & CF_ENABLEHOOK) {
  872. ThreadData.vpfnHook = DWORD32(pCF16->lpfnHook);
  873. if(!ThreadData.vpfnHook) {
  874. SETEXTENDEDERROR(CDERR_NOHOOK);
  875. FREEVDMPTR(pCF16);
  876. return(0);
  877. }
  878. ThreadData.vpData = vpcf;
  879. }
  880. else {
  881. STOREDWORD(pCF16->lpfnHook, 0);
  882. }
  883. RtlZeroMemory(&CF32, sizeof(CHOOSEFONT));
  884. CF32.lpLogFont = &LogFont32;
  885. CF32.lpszStyle = sStyle;
  886. sStyle[0] = '\0';
  887. ThunkCHOOSEFONT16to32(&CF32, pCF16);
  888. dwFlags16 = DWORD32(pCF16->Flags);
  889. // this call invalidates flat ptrs to 16-bit memory
  890. CF32.hInstance = ThunkCDTemplate16to32(WORD32(pCF16->hInstance),
  891. 0,
  892. DWORD32(pCF16->lpTemplateName),
  893. dwFlags16,
  894. &(CF32.Flags),
  895. CF_ENABLETEMPLATE,
  896. CF_ENABLETEMPLATEHANDLE,
  897. &pRes,
  898. &fError);
  899. if(fError) {
  900. goto ChooseFontExit;
  901. }
  902. // invalidate flat ptrs to 16-bit memory
  903. FREEVDMPTR(pCF16);
  904. WCDDUMPCHOOSEFONTDATA32(&CF32);
  905. // Set this just before the calling into comdlg32. This prevents the
  906. // synchronization stuff from firing until we actually need it.
  907. CURRENTPTD()->CommDlgTd = &ThreadData;
  908. // this call invalidates flat ptrs to 16-bit memory
  909. ul = GETBOOL16(ChooseFont(&CF32));
  910. CURRENTPTD()->CommDlgTd = ThreadData.Previous;
  911. if (ul) {
  912. WCDDUMPCHOOSEFONTDATA32(&CF32);
  913. GETVDMPTR(vpcf, sizeof(CHOOSEFONT16), pCF16);
  914. ThunkCHOOSEFONT32to16(pCF16, &CF32);
  915. WCDDUMPCHOOSEFONTDATA16(pCF16);
  916. }
  917. ChooseFontExit:
  918. FreeCDTemplate32(pRes,
  919. CF32.hInstance,
  920. dwFlags16 & CF_ENABLETEMPLATE,
  921. dwFlags16 & CF_ENABLETEMPLATEHANDLE);
  922. FREEVDMPTR(pCF16);
  923. return(ul);
  924. }
  925. VOID
  926. ThunkCHOOSEFONT16to32(OUT CHOOSEFONT *pCF32,
  927. IN PCHOOSEFONTDATA16 pCF16)
  928. {
  929. LPSTR lpstr;
  930. DWORD Flags;
  931. if(pCF16 && pCF32) {
  932. pCF32->lStructSize = sizeof(CHOOSEFONT);
  933. pCF32->hwndOwner = HWND32(pCF16->hwndOwner);
  934. if(DWORD32(pCF16->Flags) & CF_PRINTERFONTS) {
  935. pCF32->hDC = HDC32(pCF16->hDC);
  936. }
  937. if(DWORD32(pCF16->lpLogFont) && pCF32->lpLogFont) {
  938. GETLOGFONT16(DWORD32(pCF16->lpLogFont), pCF32->lpLogFont);
  939. }
  940. pCF32->iPointSize = INT32(pCF16->iPointSize);
  941. // preserve the template flag state while copying flags
  942. // 1. save template flag state
  943. // note: we never will have a 32-bit CF_ENABLETEMPLATE flag
  944. // 2. copy flags from 16-bit struct (add the WOWAPP flag)
  945. // 3. turn off all template flags
  946. // 4. restore original template flag state
  947. Flags = pCF32->Flags & CF_ENABLETEMPLATEHANDLE;
  948. pCF32->Flags = DWORD32(pCF16->Flags) | CD_WOWAPP;
  949. pCF32->Flags &= ~(CF_ENABLETEMPLATE | CF_ENABLETEMPLATEHANDLE);
  950. pCF32->Flags |= Flags;
  951. pCF32->rgbColors = DWORD32(pCF16->rgbColors);
  952. pCF32->lCustData = DWORD32(pCF16->lCustData);
  953. if((DWORD32(pCF16->Flags) & CF_ENABLEHOOK) && pCF16->lpfnHook) {
  954. pCF32->lpfnHook = WCD32DialogProc;
  955. }
  956. // lpTemplateName32 is thunked separately
  957. // hInstance thunked separately
  958. // Note: we shouldn't have to free or re-alloc this since they
  959. // will only need LF_FACESIZE bytes to handle the string
  960. GETPSZPTR(pCF16->lpszStyle, lpstr);
  961. if(lpstr && pCF32->lpszStyle) {
  962. if(DWORD32(pCF16->Flags) & CF_USESTYLE) {
  963. strcpy(pCF32->lpszStyle, lpstr);
  964. }
  965. FREEPSZPTR(lpstr);
  966. }
  967. pCF32->nFontType = WORD32(pCF16->nFontType);
  968. pCF32->nSizeMin = INT32(pCF16->nSizeMin);
  969. pCF32->nSizeMax = INT32(pCF16->nSizeMax);
  970. }
  971. }
  972. VOID
  973. ThunkCHOOSEFONT32to16(OUT PCHOOSEFONTDATA16 pCF16,
  974. IN CHOOSEFONT *pCF32)
  975. {
  976. LPSTR lpstr;
  977. DWORD Flags, Flags32;
  978. if(pCF16 && pCF32) {
  979. STOREWORD(pCF16->iPointSize, pCF32->iPointSize);
  980. STOREDWORD(pCF16->rgbColors, pCF32->rgbColors);
  981. STOREWORD(pCF16->nFontType, pCF32->nFontType);
  982. // preserve the template flag state while copying flags
  983. // 1. save template flag state
  984. // 2. copy flags from 32-bit struct
  985. // 3. turn off all template flags and the WOWAPP flag
  986. // 4. restore original template flag state
  987. Flags = DWORD32(pCF16->Flags) & (CF_ENABLETEMPLATE |
  988. CF_ENABLETEMPLATEHANDLE);
  989. Flags32 = pCF32->Flags;
  990. Flags32 &= ~(CF_ENABLETEMPLATE | CF_ENABLETEMPLATEHANDLE | CD_WOWAPP);
  991. Flags32 |= Flags;
  992. STOREDWORD(pCF16->Flags, Flags32);
  993. if(DWORD32(pCF16->lpLogFont) && pCF32->lpLogFont) {
  994. PUTLOGFONT16(DWORD32(pCF16->lpLogFont),
  995. sizeof(LOGFONT),
  996. pCF32->lpLogFont);
  997. }
  998. GETPSZPTR(pCF16->lpszStyle, lpstr);
  999. if(lpstr && pCF32->lpszStyle) {
  1000. if(DWORD32(pCF16->Flags) & CF_USESTYLE) {
  1001. strcpy(lpstr, pCF32->lpszStyle);
  1002. }
  1003. FREEPSZPTR(lpstr);
  1004. }
  1005. }
  1006. }
  1007. ULONG FASTCALL
  1008. WCD32PrintDlg(IN PVDMFRAME pFrame)
  1009. /*++
  1010. Routine Description:
  1011. This routine thunks the 16-bit PrintDlg common dialog to the 32-bit
  1012. side.
  1013. Arguments:
  1014. pFrame - Supplies 16-bit argument frame
  1015. Return Value:
  1016. 16-bit BOOLEAN to be returned
  1017. --*/
  1018. {
  1019. ULONG ul = GETBOOL16(FALSE);
  1020. register PPRINTDLG16 parg16;
  1021. VPPRINTDLGDATA vppd;
  1022. PRINTDLG PD32;
  1023. PPRINTDLGDATA16 pPD16;
  1024. PRES hSetupRes = NULL;
  1025. PRES hPrintRes = NULL;
  1026. COMMDLGTD ThreadData;
  1027. DWORD dwFlags16;
  1028. HMEM16 hDM16;
  1029. HMEM16 hDN16;
  1030. BOOL fError = FALSE;
  1031. GETARGPTR(pFrame, sizeof(PRINTDLG16), parg16);
  1032. vppd = parg16->lppd;
  1033. // invalidate this now
  1034. FREEARGPTR(parg16);
  1035. SETEXTENDEDERROR(0);
  1036. GETVDMPTR(vppd, sizeof(PRINTDLGDATA16), pPD16);
  1037. WCDDUMPPRINTDLGDATA16(pPD16);
  1038. if(DWORD32(pPD16->lStructSize) != sizeof(PRINTDLGDATA16)) {
  1039. SETEXTENDEDERROR( CDERR_STRUCTSIZE );
  1040. FREEVDMPTR(pPD16);
  1041. return(0);
  1042. }
  1043. if(DWORD32(pPD16->Flags) & PD_RETURNDEFAULT) {
  1044. // spec says these must be NULL
  1045. if(WORD32(pPD16->hDevMode) || WORD32(pPD16->hDevNames)) {
  1046. SETEXTENDEDERROR(PDERR_RETDEFFAILURE);
  1047. FREEVDMPTR(pPD16);
  1048. return(0);
  1049. }
  1050. }
  1051. RtlZeroMemory((PVOID)&PD32, sizeof(PRINTDLG));
  1052. RtlZeroMemory((PVOID)&ThreadData, sizeof(COMMDLGTD));
  1053. ThreadData.Previous = CURRENTPTD()->CommDlgTd;
  1054. ThreadData.hdlg = (HWND16)-1;
  1055. ThreadData.pData32 = (PVOID)&PD32;
  1056. ThreadData.Flags = 0;
  1057. // this flag causes the system to put up the setup dialog rather
  1058. // than the print dialog
  1059. if(DWORD32(pPD16->Flags) & PD_PRINTSETUP) {
  1060. if(DWORD32(pPD16->Flags) & PD_ENABLESETUPHOOK) {
  1061. ThreadData.vpfnHook = DWORD32(pPD16->lpfnSetupHook);
  1062. if(!ThreadData.vpfnHook) {
  1063. SETEXTENDEDERROR(CDERR_NOHOOK);
  1064. FREEVDMPTR(pPD16);
  1065. return(0);
  1066. }
  1067. ThreadData.vpData = vppd;
  1068. PD32.lpfnSetupHook = WCD32DialogProc;
  1069. }
  1070. } else {
  1071. if (DWORD32(pPD16->Flags) & PD_ENABLEPRINTHOOK) {
  1072. ThreadData.vpfnHook = DWORD32(pPD16->lpfnPrintHook);
  1073. if(!ThreadData.vpfnHook) {
  1074. SETEXTENDEDERROR(CDERR_NOHOOK);
  1075. FREEVDMPTR(pPD16);
  1076. return(0);
  1077. }
  1078. ThreadData.vpData = vppd;
  1079. PD32.lpfnPrintHook = WCD32DialogProc;
  1080. }
  1081. if (DWORD32(pPD16->Flags) & PD_ENABLESETUPHOOK) {
  1082. ThreadData.vpfnSetupHook = DWORD32(pPD16->lpfnSetupHook);
  1083. if(!ThreadData.vpfnSetupHook) {
  1084. SETEXTENDEDERROR(CDERR_NOHOOK);
  1085. FREEVDMPTR(pPD16);
  1086. return(0);
  1087. }
  1088. ThreadData.vpData = vppd;
  1089. ThreadData.SetupHwnd = (HWND16)1;
  1090. PD32.lpfnSetupHook = WCD32PrintSetupDialogProc;
  1091. }
  1092. }
  1093. // lock the original 16-bit hDevMode & hDevNames so they won't get thrown
  1094. // out by our thunking. (we need to restore them to the original handles
  1095. // if there is an error in PrintDlg() ).
  1096. hDM16 = WORD32(pPD16->hDevMode);
  1097. hDN16 = WORD32(pPD16->hDevNames);
  1098. WOWGlobalLock16(hDM16);
  1099. WOWGlobalLock16(hDN16);
  1100. dwFlags16 = DWORD32(pPD16->Flags);
  1101. // get a new 32-bit devmode struct
  1102. PD32.hDevMode = ThunkhDevMode16to32(WORD32(pPD16->hDevMode));
  1103. // get a new 32-bit devnames struct
  1104. PD32.hDevNames = ThunkhDevNames16to32(WORD32(pPD16->hDevNames));
  1105. ThunkPRINTDLG16to32(&PD32, pPD16);
  1106. GETVDMPTR(vppd, sizeof(PRINTDLGDATA16), pPD16);
  1107. // this call invalidates flat ptrs to 16-bit memory
  1108. PD32.hPrintTemplate
  1109. = ThunkCDTemplate16to32(WORD32(pPD16->hInstance),
  1110. MAKELONG(WORD32(pPD16->hPrintTemplate),1),
  1111. DWORD32(pPD16->lpPrintTemplateName),
  1112. dwFlags16,
  1113. &(PD32.Flags),
  1114. PD_ENABLEPRINTTEMPLATE,
  1115. PD_ENABLEPRINTTEMPLATEHANDLE,
  1116. &hPrintRes,
  1117. &fError);
  1118. if(fError) {
  1119. goto PrintDlgError;
  1120. }
  1121. // memory may have moved - invalidate flat pointers now
  1122. FREEVDMPTR(pPD16);
  1123. GETVDMPTR(vppd, sizeof(PRINTDLGDATA16), pPD16);
  1124. // this call invalidates flat ptrs to 16-bit memory
  1125. PD32.hSetupTemplate
  1126. = ThunkCDTemplate16to32(WORD32(pPD16->hInstance),
  1127. MAKELONG(WORD32(pPD16->hSetupTemplate),1),
  1128. DWORD32(pPD16->lpSetupTemplateName),
  1129. dwFlags16,
  1130. &(PD32.Flags),
  1131. PD_ENABLESETUPTEMPLATE,
  1132. PD_ENABLESETUPTEMPLATEHANDLE,
  1133. &hSetupRes,
  1134. &fError);
  1135. PrintDlgError:
  1136. if(fError) {
  1137. WOWGlobalUnlock16(hDM16);
  1138. WOWGlobalUnlock16(hDN16);
  1139. goto PrintDlgExit;
  1140. }
  1141. // memory may have moved - invalidate flat pointers now
  1142. FREEVDMPTR(pPD16);
  1143. WCDDUMPPRINTDLGDATA32(&PD32);
  1144. // Set this just before the calling into comdlg32. This prevents the
  1145. // synchronization stuff from firing until we actually need it.
  1146. CURRENTPTD()->CommDlgTd = &ThreadData;
  1147. ul = GETBOOL16(PrintDlg(&PD32));
  1148. CURRENTPTD()->CommDlgTd = ThreadData.Previous;
  1149. // blow away our locks so these really can be free'd if needed
  1150. WOWGlobalUnlock16(hDM16);
  1151. WOWGlobalUnlock16(hDN16);
  1152. if(ul) {
  1153. WCDDUMPPRINTDLGDATA32(&PD32);
  1154. // this call invalidates flat ptrs to 16-bit mem
  1155. ThunkPRINTDLG32to16(vppd, &PD32);
  1156. GETVDMPTR(vppd, sizeof(PRINTDLGDATA16), pPD16);
  1157. WCDDUMPPRINTDLGDATA16(pPD16);
  1158. // throw out the old ones if the structs were updated
  1159. if(WORD32(pPD16->hDevMode) != hDM16) {
  1160. WOWGlobalFree16(hDM16);
  1161. }
  1162. if(WORD32(pPD16->hDevNames) != hDN16) {
  1163. WOWGlobalFree16(hDN16);
  1164. }
  1165. } else {
  1166. // throw away any new hDevMode's & hDevNames that we might have created
  1167. // as a result of our thunking & restore the originals
  1168. GETVDMPTR(vppd, sizeof(PRINTDLGDATA16), pPD16);
  1169. if(WORD32(pPD16->hDevMode) != hDM16) {
  1170. WOWGlobalFree16(WORD32(pPD16->hDevMode));
  1171. STOREWORD(pPD16->hDevMode, hDM16);
  1172. }
  1173. if(WORD32(pPD16->hDevNames) != hDN16) {
  1174. WOWGlobalFree16(WORD32(pPD16->hDevNames));
  1175. STOREWORD(pPD16->hDevNames, hDN16);
  1176. }
  1177. }
  1178. PrintDlgExit:
  1179. WOWGLOBALFREE(PD32.hDevMode);
  1180. WOWGLOBALFREE(PD32.hDevNames);
  1181. if(PD32.hPrintTemplate) {
  1182. FreeCDTemplate32(hPrintRes,
  1183. PD32.hPrintTemplate,
  1184. dwFlags16 & PD_ENABLEPRINTTEMPLATE,
  1185. dwFlags16 & PD_ENABLEPRINTTEMPLATEHANDLE);
  1186. }
  1187. if(PD32.hSetupTemplate) {
  1188. FreeCDTemplate32(hSetupRes,
  1189. PD32.hSetupTemplate,
  1190. dwFlags16 & PD_ENABLESETUPTEMPLATE,
  1191. dwFlags16 & PD_ENABLESETUPTEMPLATEHANDLE);
  1192. }
  1193. FREEVDMPTR(pPD16);
  1194. return(ul);
  1195. }
  1196. #define PD_TEMPLATEMASK32 (PD_ENABLEPRINTTEMPLATE | \
  1197. PD_ENABLESETUPTEMPLATE)
  1198. #define PD_TEMPLATEHANDLEMASK32 (PD_ENABLEPRINTTEMPLATEHANDLE | \
  1199. PD_ENABLESETUPTEMPLATEHANDLE)
  1200. VOID
  1201. ThunkPRINTDLG16to32(OUT PRINTDLG *pPD32,
  1202. IN PPRINTDLGDATA16 pPD16)
  1203. {
  1204. DWORD Flags;
  1205. HANDLE h32New;
  1206. LPVOID lp32New;
  1207. LPVOID lp32Cur;
  1208. if(pPD16 && pPD32) {
  1209. pPD32->lStructSize = sizeof(PRINTDLG);
  1210. pPD32->hwndOwner = HWND32(pPD16->hwndOwner);
  1211. // get a new 32-bit devmode thunked from the 16-bit one...
  1212. if(h32New = ThunkhDevMode16to32(WORD32(pPD16->hDevMode))) {
  1213. lp32New = GlobalLock(h32New);
  1214. lp32Cur = GlobalLock(pPD32->hDevMode);
  1215. // ...and copy it over the current 32-bit devmode struct
  1216. if(lp32New && lp32Cur) {
  1217. RtlCopyMemory(lp32Cur,
  1218. lp32New,
  1219. ((LPDEVMODE)lp32New)->dmSize);
  1220. GlobalUnlock(pPD32->hDevMode);
  1221. GlobalUnlock(h32New);
  1222. }
  1223. WOWGLOBALFREE(h32New);
  1224. }
  1225. // we assume that the DEVNAMES struct will never change
  1226. // hDC filled on output only
  1227. // preserve the template flag state while copying flags
  1228. // 1. save original template flags
  1229. // note: we never set the 32-bit PD_ENABLExxxxTEMPLATE flags
  1230. // 2. copy flags from 16-bit struct (and add WOWAPP flag)
  1231. // 3. turn off all template flags
  1232. // 4. restore original template flag state
  1233. Flags = pPD32->Flags & PD_TEMPLATEHANDLEMASK32;
  1234. pPD32->Flags = DWORD32(pPD16->Flags) | CD_WOWAPP;
  1235. pPD32->Flags &= ~(PD_TEMPLATEMASK32 | PD_TEMPLATEHANDLEMASK32);
  1236. pPD32->Flags |= Flags;
  1237. pPD32->nFromPage = WORD32(pPD16->nFromPage);
  1238. pPD32->nToPage = WORD32(pPD16->nToPage);
  1239. pPD32->nMinPage = WORD32(pPD16->nMinPage);
  1240. pPD32->nMaxPage = WORD32(pPD16->nMaxPage);
  1241. pPD32->nCopies = WORD32(pPD16->nCopies);
  1242. pPD32->lCustData = DWORD32(pPD16->lCustData);
  1243. // hInstance thunked separately
  1244. // hPrintTemplate & hSetupTemplate thunked separately
  1245. }
  1246. }
  1247. #define PD_TEMPLATEMASK16 (PD_ENABLEPRINTTEMPLATE | \
  1248. PD_ENABLESETUPTEMPLATE | \
  1249. PD_ENABLEPRINTTEMPLATEHANDLE | \
  1250. PD_ENABLESETUPTEMPLATEHANDLE)
  1251. VOID
  1252. ThunkPRINTDLG32to16(IN VPVOID vppd,
  1253. OUT PRINTDLG *pPD32)
  1254. {
  1255. HAND16 hDevMode16;
  1256. HAND16 hDevNames16;
  1257. PPRINTDLGDATA16 pPD16;
  1258. DWORD Flags, Flags16;
  1259. GETVDMPTR(vppd, sizeof(PRINTDLGDATA16), pPD16);
  1260. if(pPD16 && pPD32) {
  1261. if(pPD32->Flags & (PD_RETURNIC | PD_RETURNDC)) {
  1262. STOREWORD(pPD16->hDC, GETHDC16(pPD32->hDC));
  1263. }
  1264. // thunk 32-bit DEVMODE structure back to 16-bit
  1265. // hDevXXXX16 take care of RISC alignment problems
  1266. hDevMode16 = WORD32(pPD16->hDevMode);
  1267. hDevNames16 = WORD32(pPD16->hDevNames);
  1268. // this call invalidates flat ptrs to 16-bit mem
  1269. ThunkhDevMode32to16(&hDevMode16, pPD32->hDevMode);
  1270. FREEVDMPTR(pPD16);
  1271. GETVDMPTR(vppd, sizeof(PRINTDLGDATA16), pPD16);
  1272. // this call invalidates flat ptrs to 16-bit mem
  1273. ThunkhDevNames32to16(&hDevNames16, pPD32->hDevNames);
  1274. FREEVDMPTR(pPD16);
  1275. GETVDMPTR(vppd, sizeof(PRINTDLGDATA16), pPD16);
  1276. STOREWORD(pPD16->hDevMode, hDevMode16);
  1277. STOREWORD(pPD16->hDevNames, hDevNames16);
  1278. // preserve the template flag state while copying flags
  1279. // 1. save original template flags
  1280. // 2. copy flags from 32-bit struct
  1281. // 3. turn off all template flags and WOWAPP flag
  1282. // 4. restore original template flag state
  1283. Flags = DWORD32(pPD16->Flags) & PD_TEMPLATEMASK16;
  1284. Flags16 = pPD32->Flags;
  1285. Flags16 &= ~(PD_TEMPLATEMASK16 | CD_WOWAPP);
  1286. Flags16 |= Flags;
  1287. STOREDWORD(pPD16->Flags, Flags16);
  1288. STOREWORD(pPD16->nFromPage, GETUINT16(pPD32->nFromPage));
  1289. STOREWORD(pPD16->nToPage, GETUINT16(pPD32->nToPage));
  1290. STOREWORD(pPD16->nMinPage, GETUINT16(pPD32->nMinPage));
  1291. STOREWORD(pPD16->nMaxPage, GETUINT16(pPD32->nMaxPage));
  1292. STOREWORD(pPD16->nCopies, GETUINT16(pPD32->nCopies));
  1293. FREEVDMPTR(pPD16);
  1294. }
  1295. }
  1296. HGLOBAL
  1297. ThunkhDevMode16to32(IN HAND16 hDevMode16)
  1298. {
  1299. INT nSize;
  1300. LPDEVMODE lpdm32, pdm32;
  1301. HGLOBAL hDevMode32 = NULL;
  1302. VPDEVMODE31 vpDevMode16;
  1303. if (hDevMode16) {
  1304. vpDevMode16 = GlobalLock16(hDevMode16, NULL);
  1305. if(FETCHDWORD(vpDevMode16)) {
  1306. if(pdm32 = ThunkDevMode16to32(vpDevMode16)) {
  1307. nSize = FETCHWORD(pdm32->dmSize) +
  1308. FETCHWORD(pdm32->dmDriverExtra);
  1309. hDevMode32 = WOWGLOBALALLOC(GMEM_MOVEABLE, nSize);
  1310. if(lpdm32 = GlobalLock(hDevMode32)) {
  1311. RtlCopyMemory((PVOID)lpdm32, (PVOID)pdm32, nSize);
  1312. GlobalUnlock(hDevMode32);
  1313. }
  1314. free_w(pdm32);
  1315. }
  1316. GlobalUnlock16(hDevMode16);
  1317. }
  1318. }
  1319. return(hDevMode32);
  1320. }
  1321. VOID
  1322. ThunkhDevMode32to16(IN OUT HAND16 *phDevMode16,
  1323. IN HANDLE hDevMode32)
  1324. /*++
  1325. Routine Description:
  1326. This routine thunks a 32-bit DevMode structure back into the 16-bit one.
  1327. It will reallocate the 16-bit global memory block as necessary.
  1328. WARNING: This may cause 16-bit memory to move, invalidating flat pointers.
  1329. Arguments:
  1330. hDevMode - Supplies a handle to a movable global memory object that
  1331. contains a 32-bit DEVMODE structure
  1332. phDevMode16 - Supplies a pointer to a 16-bit handle to a movable global
  1333. memory object that will return the 16-bit DEVMODE structure.
  1334. If the handle is NULL, the object will be allocated. It
  1335. may also be reallocated if its current size is not enough.
  1336. Return Value:
  1337. None
  1338. --*/
  1339. {
  1340. UINT CurrentSize;
  1341. UINT RequiredSize;
  1342. VPDEVMODE31 vpDevMode16;
  1343. LPDEVMODE lpDevMode32;
  1344. if (hDevMode32 == NULL) {
  1345. *phDevMode16 = (HAND16)NULL;
  1346. return;
  1347. }
  1348. lpDevMode32 = GlobalLock(hDevMode32);
  1349. if (lpDevMode32==NULL) {
  1350. *phDevMode16 = (HAND16)NULL;
  1351. return;
  1352. }
  1353. RequiredSize = lpDevMode32->dmSize +
  1354. lpDevMode32->dmDriverExtra +
  1355. sizeof(WOWDM31); // see notes in wstruc.c
  1356. if (*phDevMode16 == (HAND16)NULL) {
  1357. vpDevMode16 = GlobalAllocLock16(GMEM_MOVEABLE,
  1358. RequiredSize,
  1359. phDevMode16);
  1360. } else {
  1361. vpDevMode16 = GlobalLock16(*phDevMode16, &CurrentSize);
  1362. if (CurrentSize < RequiredSize) {
  1363. GlobalUnlockFree16(vpDevMode16);
  1364. vpDevMode16 = GlobalAllocLock16(GMEM_MOVEABLE,
  1365. RequiredSize,
  1366. phDevMode16);
  1367. }
  1368. }
  1369. if(ThunkDevMode32to16(vpDevMode16, lpDevMode32, RequiredSize)) {
  1370. GlobalUnlock16(*phDevMode16);
  1371. }
  1372. else {
  1373. *phDevMode16 = (HAND16)NULL;
  1374. }
  1375. GlobalUnlock(hDevMode32);
  1376. }
  1377. HANDLE
  1378. ThunkhDevNames16to32(IN HAND16 hDevNames16)
  1379. {
  1380. INT nSize;
  1381. HANDLE hDN32 = NULL;
  1382. LPDEVNAMES pdn32;
  1383. PDEVNAMES16 pdn16;
  1384. if(FETCHDWORD(hDevNames16)) {
  1385. VPDEVNAMES vpDevNames;
  1386. vpDevNames = GlobalLock16(hDevNames16, &nSize);
  1387. if(nSize) {
  1388. GETVDMPTR(vpDevNames, sizeof(DEVNAMES16), pdn16);
  1389. if(pdn16) {
  1390. hDN32 = WOWGLOBALALLOC(GMEM_MOVEABLE, nSize);
  1391. if(pdn32 = GlobalLock(hDN32)) {
  1392. RtlCopyMemory((PVOID)pdn32, (PVOID)pdn16, nSize);
  1393. GlobalUnlock(hDN32);
  1394. } else {
  1395. LOGDEBUG(0, ("ThunkhDEVNAMES16to32, 32-bit allocation(s) failed!\n"));
  1396. }
  1397. FREEVDMPTR(pdn16);
  1398. }
  1399. GlobalUnlock16(hDevNames16);
  1400. }
  1401. }
  1402. return(hDN32);
  1403. }
  1404. VOID
  1405. ThunkhDevNames32to16(IN OUT HAND16 *phDevNames16,
  1406. IN HANDLE hDevNames)
  1407. /*++
  1408. Routine Description:
  1409. This routine thunks a 32-bit DevNames structure back into the 16-bit one.
  1410. It will reallocate the 16-bit global memory block as necessary.
  1411. WARNING: This may cause 16-bit memory to move, invalidating flat pointers.
  1412. Arguments:
  1413. hDevNames - Supplies a handle to a movable global memory object that
  1414. contains a 32-bit DEVNAMES structure
  1415. phDevNames16 - Supplies a pointer to a 16-bit handle to a movable global
  1416. memory object that will return the 16-bit DEVNAMES structure.
  1417. If the handle is NULL, the object will be allocated. It
  1418. may also be reallocated if its current size is not enough.
  1419. Return Value:
  1420. None
  1421. --*/
  1422. {
  1423. UINT CurrentSize;
  1424. UINT RequiredSize;
  1425. UINT CopySize;
  1426. UINT MaxOffset;
  1427. PDEVNAMES16 pdn16;
  1428. VPDEVNAMES DevNames16;
  1429. LPDEVNAMES DevNames32;
  1430. if (hDevNames==NULL) {
  1431. *phDevNames16=(HAND16)NULL;
  1432. return;
  1433. }
  1434. DevNames32 = GlobalLock(hDevNames);
  1435. if (DevNames32==NULL) {
  1436. *phDevNames16=(HAND16)NULL;
  1437. }
  1438. MaxOffset = max(max(DevNames32->wDriverOffset,DevNames32->wDeviceOffset),
  1439. DevNames32->wOutputOffset);
  1440. // ProComm Plus copies 0x48 constant bytes after Print Setup.
  1441. CopySize = MaxOffset + strlen((PCHAR)DevNames32+MaxOffset) + 1;
  1442. RequiredSize = max(CopySize, 0x48);
  1443. if (*phDevNames16==(HAND16)NULL) {
  1444. DevNames16 = GlobalAllocLock16(GMEM_MOVEABLE,
  1445. RequiredSize,
  1446. phDevNames16);
  1447. } else {
  1448. DevNames16 = GlobalLock16(*phDevNames16, &CurrentSize);
  1449. if (CurrentSize < RequiredSize) {
  1450. GlobalUnlockFree16(DevNames16);
  1451. DevNames16 = GlobalAllocLock16(GMEM_MOVEABLE,
  1452. RequiredSize,
  1453. phDevNames16);
  1454. }
  1455. }
  1456. GETVDMPTR(DevNames16, RequiredSize, pdn16);
  1457. if (pdn16==NULL) {
  1458. *phDevNames16=(HAND16)NULL;
  1459. GlobalUnlock(hDevNames);
  1460. return;
  1461. }
  1462. RtlCopyMemory(pdn16,DevNames32,CopySize);
  1463. FREEVDMPTR(pdn16);
  1464. GlobalUnlock16(*phDevNames16);
  1465. GlobalUnlock(hDevNames);
  1466. }
  1467. ULONG FASTCALL
  1468. WCD32GetOpenFileName( PVDMFRAME pFrame )
  1469. /*++
  1470. Routine Description:
  1471. This routine thunks the 16-bit GetOpenFileName common dialog to the
  1472. 32-bit side.
  1473. Arguments:
  1474. pFrame - Supplies 16-bit argument frame
  1475. Return Value:
  1476. 16-bit BOOLEAN to be returned.
  1477. --*/
  1478. {
  1479. return(WCD32GetFileName(pFrame,GetOpenFileName));
  1480. }
  1481. ULONG FASTCALL
  1482. WCD32GetSaveFileName( PVDMFRAME pFrame )
  1483. /*++
  1484. Routine Description:
  1485. This routine thunks the 16-bit GetOpenFileName common dialog to the
  1486. 32-bit side.
  1487. Arguments:
  1488. pFrame - Supplies 16-bit argument frame
  1489. Return Value:
  1490. 16-bit BOOLEAN to be returned.
  1491. --*/
  1492. {
  1493. return(WCD32GetFileName(pFrame,GetSaveFileName));
  1494. }
  1495. ULONG
  1496. WCD32GetFileName(IN PVDMFRAME pFrame,
  1497. IN FILENAMEPROC Function)
  1498. /*++
  1499. Routine Description:
  1500. This routine is called by WCD32GetOpenFileName and WCD32GetSaveFileName.
  1501. It does all the real thunking work.
  1502. Arguments:
  1503. pFrame - Supplies 16-bit argument frame
  1504. Function - supplies a pointer to the 32-bit function to call (either
  1505. GetOpenFileName or GetSaveFileName)
  1506. Return Value:
  1507. 16-bit BOOLEAN to be returned.
  1508. --*/
  1509. {
  1510. ULONG ul = 0;
  1511. register PGETOPENFILENAME16 parg16;
  1512. VPOPENFILENAME vpof;
  1513. OPENFILENAME OFN32;
  1514. POPENFILENAME16 pOFN16;
  1515. COMMDLGTD ThreadData;
  1516. PRES pRes = NULL;
  1517. DWORD dwFlags16 = 0;
  1518. USHORT cb;
  1519. PBYTE lpcb;
  1520. BOOL fError = FALSE;
  1521. GETARGPTR(pFrame, sizeof(GETOPENFILENAME16), parg16);
  1522. vpof = parg16->lpof;
  1523. SETEXTENDEDERROR(0);
  1524. // invalidate this now
  1525. FREEARGPTR(parg16);
  1526. // initialize unique window messages
  1527. if (msgFILEOK == 0) {
  1528. if(!(msgSHAREVIOLATION = (WORD)RegisterWindowMessage(SHAREVISTRING))) {
  1529. SETEXTENDEDERROR( CDERR_REGISTERMSGFAIL );
  1530. LOGDEBUG(2,("WCD32GetFileName:RegisterWindowMessage failed\n"));
  1531. return(0);
  1532. }
  1533. if(!(msgFILEOK = (WORD)RegisterWindowMessage(FILEOKSTRING))) {
  1534. SETEXTENDEDERROR( CDERR_REGISTERMSGFAIL );
  1535. LOGDEBUG(2,("WCD32GetFileName:RegisterWindowMessage 2 failed\n"));
  1536. return(0);
  1537. }
  1538. // initialize private WOW-comdlg32 message
  1539. msgWOWDIRCHANGE = (WORD)RegisterWindowMessage("WOWDirChange");
  1540. }
  1541. GETVDMPTR(vpof, sizeof(OPENFILENAME16), pOFN16);
  1542. WCDDUMPOPENFILENAME16(pOFN16);
  1543. if(DWORD32(pOFN16->lStructSize) != sizeof(OPENFILENAME16)) {
  1544. SETEXTENDEDERROR( CDERR_STRUCTSIZE );
  1545. FREEVDMPTR(pOFN16);
  1546. return(0);
  1547. }
  1548. RtlZeroMemory(&ThreadData, sizeof(COMMDLGTD));
  1549. ThreadData.Previous = CURRENTPTD()->CommDlgTd;
  1550. ThreadData.hdlg = (HWND16)-1;
  1551. ThreadData.pData32 = (PVOID)&OFN32;
  1552. ThreadData.Flags = WOWCD_ISOPENFILE;
  1553. if(DWORD32(pOFN16->Flags) & OFN_ENABLEHOOK) {
  1554. ThreadData.vpfnHook = DWORD32(pOFN16->lpfnHook);
  1555. if(!ThreadData.vpfnHook) {
  1556. SETEXTENDEDERROR(CDERR_NOHOOK);
  1557. FREEVDMPTR(pOFN16);
  1558. return(0);
  1559. }
  1560. ThreadData.vpData = vpof;
  1561. }
  1562. RtlZeroMemory(&OFN32, sizeof(OPENFILENAME));
  1563. if(!Alloc_OFN32_strs(&OFN32, pOFN16)) {
  1564. SETEXTENDEDERROR(CDERR_MEMALLOCFAILURE);
  1565. goto GetFileNameExit;
  1566. }
  1567. // On Win3.1, the system sets these flags in the app's struct under the
  1568. // shown conditions so we need to update the 16-bit struct too.
  1569. dwFlags16 = DWORD32(pOFN16->Flags);
  1570. if(dwFlags16 & OFN_CREATEPROMPT) {
  1571. dwFlags16 |= OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST;
  1572. }
  1573. else if(dwFlags16 & OFN_FILEMUSTEXIST) {
  1574. dwFlags16 |= OFN_PATHMUSTEXIST;
  1575. }
  1576. // A bug in Serif PagePlus 3.0 sets the high word to 0xFFFF which causes
  1577. // the new moniker stuff in comdlg32 to break. #148137 - cmjones
  1578. // VadimB: the mask below causes apps that do want lfn to break, so check
  1579. // for those apps via the compat flag and let them go unpunished
  1580. if ((dwFlags16 & OFN_LONGNAMES) &&
  1581. (CURRENTPTD()->dwWOWCompatFlagsEx & WOWCFEX_ALLOWLFNDIALOGS)) {
  1582. dwFlags16 = (dwFlags16 & VALID_OFN16_FLAGS) | OFN_LONGNAMES;
  1583. }
  1584. else {
  1585. dwFlags16 &= VALID_OFN16_FLAGS;
  1586. }
  1587. STOREDWORD(pOFN16->Flags, dwFlags16);
  1588. if(!ThunkOPENFILENAME16to32(&OFN32, pOFN16)) {
  1589. SETEXTENDEDERROR(CDERR_MEMALLOCFAILURE);
  1590. goto GetFileNameExit;
  1591. }
  1592. dwFlags16 = DWORD32(pOFN16->Flags); // get updated flags
  1593. // make sure the current directory is up to date
  1594. UpdateDosCurrentDirectory(DIR_DOS_TO_NT);
  1595. // this call invalidates flat ptrs to 16-bit memory
  1596. OFN32.hInstance = ThunkCDTemplate16to32(WORD32(pOFN16->hInstance),
  1597. 0,
  1598. DWORD32(pOFN16->lpTemplateName),
  1599. dwFlags16,
  1600. &(OFN32.Flags),
  1601. OFN_ENABLETEMPLATE,
  1602. OFN_ENABLETEMPLATEHANDLE,
  1603. &pRes,
  1604. &fError);
  1605. if(fError) {
  1606. goto GetFileNameExit;
  1607. }
  1608. // memory may move - free flat pointers now
  1609. FREEVDMPTR(pOFN16);
  1610. WCDDUMPOPENFILENAME32(&OFN32);
  1611. // Set this just before the calling into comdlg32. This prevents the
  1612. // synchronization stuff from firing until we actually need it.
  1613. CURRENTPTD()->CommDlgTd = &ThreadData;
  1614. // this call invalidates flat ptrs to 16-bit memory
  1615. ul = GETBOOL16((*Function)(&OFN32));
  1616. CURRENTPTD()->CommDlgTd = ThreadData.Previous;
  1617. WCDDUMPOPENFILENAME32(&OFN32);
  1618. UpdateDosCurrentDirectory(DIR_NT_TO_DOS);
  1619. GETVDMPTR(vpof, sizeof(OPENFILENAME16), pOFN16);
  1620. if (ul) {
  1621. ThunkOPENFILENAME32to16(pOFN16, &OFN32, TRUE);
  1622. }
  1623. // else if the buffer is too small, lpstrFile contains the required buffer
  1624. // size for the specified file
  1625. else if (CommDlgExtendedError() == FNERR_BUFFERTOOSMALL) {
  1626. SETEXTENDEDERROR(FNERR_BUFFERTOOSMALL);
  1627. if(OFN32.lpstrFile && pOFN16->lpstrFile) {
  1628. cb = *((PUSHORT)(OFN32.lpstrFile)); // is a WORD for comdlg32 too
  1629. // 3 is the documented minimum size of the lpstrFile buffer
  1630. GETVDMPTR(pOFN16->lpstrFile, 3, lpcb);
  1631. // Win3.1 assumes that lpstrFile buffer is at least 3 bytes long
  1632. // we'll try to be a little smarter than that...
  1633. if(lpcb && (cb > pOFN16->nMaxFile)) {
  1634. if(pOFN16->nMaxFile)
  1635. lpcb[0] = LOBYTE(cb);
  1636. if(pOFN16->nMaxFile > 1)
  1637. lpcb[1] = HIBYTE(cb);
  1638. if(pOFN16->nMaxFile > 2)
  1639. lpcb[2] = 0; // Win3.1 appends a NULL
  1640. FREEVDMPTR(lpcb);
  1641. }
  1642. }
  1643. }
  1644. WCDDUMPOPENFILENAME16(pOFN16);
  1645. GetFileNameExit:
  1646. FreeCDTemplate32(pRes,
  1647. OFN32.hInstance,
  1648. dwFlags16 & OFN_ENABLETEMPLATE,
  1649. dwFlags16 & OFN_ENABLETEMPLATEHANDLE);
  1650. Free_OFN32_strs(&OFN32);
  1651. FREEVDMPTR(pOFN16);
  1652. return(ul);
  1653. }
  1654. BOOL
  1655. ThunkOPENFILENAME16to32(OUT OPENFILENAME *pOFN32,
  1656. IN POPENFILENAME16 pOFN16)
  1657. /*++
  1658. Routine Description:
  1659. This routine thunks a 16-bit OPENFILENAME structure to the 32-bit
  1660. OPENFILENAME structure
  1661. Arguments:
  1662. pOFN16 - Supplies a flat pointer to the 16-bit OPENFILENAME structure.
  1663. pOFN32 - Supplies a pointer to the 32-bit OPENFILENAME structure.
  1664. Return Value:
  1665. None.
  1666. --*/
  1667. {
  1668. DWORD Flags;
  1669. if(pOFN16 && pOFN32) {
  1670. // Re-thunk all of the strings!!!
  1671. // Persuasion 3.0 changes the various ptrs to strings depending on which
  1672. // dialog buttons are pushed so we might have to dynamically re-alloc
  1673. // some of the 32-bit string buffers.
  1674. Thunk_OFNstrs16to32(pOFN32, pOFN16);
  1675. pOFN32->lStructSize = sizeof(OPENFILENAME);
  1676. pOFN32->hwndOwner = HWND32(pOFN16->hwndOwner);
  1677. // hInstance thunked separately
  1678. pOFN32->nMaxCustFilter = DWORD32(pOFN16->nMaxCustFilter);
  1679. pOFN32->nFilterIndex = DWORD32(pOFN16->nFilterIndex);
  1680. pOFN32->nMaxFile = DWORD32(pOFN16->nMaxFile);
  1681. pOFN32->nMaxFileTitle = DWORD32(pOFN16->nMaxFileTitle);
  1682. // preserve the template flag state while copying flags
  1683. // 1. save template flag state
  1684. // note: we never will have a 32-bit OFN_ENABLETEMPLATE flag
  1685. // we may or may not have a OFN_ENABLETEMPLATEHANDLE flag
  1686. // 2. copy flags from 16-bit struct
  1687. // 3. turn off all template flags
  1688. // 4. restore original template flag state
  1689. // 5. add the WOWAPP and no-long-names flags
  1690. Flags = pOFN32->Flags & OFN_ENABLETEMPLATEHANDLE;
  1691. pOFN32->Flags = DWORD32(pOFN16->Flags);
  1692. pOFN32->Flags &= ~(OFN_ENABLETEMPLATE | OFN_ENABLETEMPLATEHANDLE);
  1693. pOFN32->Flags |= Flags;
  1694. if ((pOFN32->Flags & OFN_LONGNAMES) &&
  1695. (CURRENTPTD()->dwWOWCompatFlagsEx & WOWCFEX_ALLOWLFNDIALOGS)) {
  1696. pOFN32->Flags |= CD_WOWAPP;
  1697. }
  1698. else {
  1699. pOFN32->Flags |= (OFN_NOLONGNAMES | CD_WOWAPP);
  1700. }
  1701. pOFN32->nFileOffset = WORD32(pOFN16->nFileOffset);
  1702. pOFN32->nFileExtension = WORD32(pOFN16->nFileExtension);
  1703. pOFN32->lCustData = DWORD32(pOFN16->lCustData);
  1704. if(DWORD32(pOFN16->Flags) & OFN_ENABLEHOOK) {
  1705. pOFN32->lpfnHook = WCD32DialogProc;
  1706. }
  1707. // lpTemplateName32 is thunked separately
  1708. // This is a hack to fix a bug in Win3.1 commdlg.dll.
  1709. // Win3.1 doesn't check nMaxFileTitle before copying the FileTitle str.
  1710. // (see Win3.1 src's \\pucus\win31aro\src\sdk\commdlg\fileopen.c)
  1711. // TaxCut'95 depends on the title string being returned.
  1712. if(pOFN32->lpstrFileTitle) {
  1713. // if nMaxFileTitle > 0, NT will copy lpstrFileTitle
  1714. if(pOFN32->nMaxFileTitle == 0) {
  1715. pOFN32->nMaxFileTitle = 13; // 8.3 filename + NULL
  1716. }
  1717. }
  1718. return(TRUE);
  1719. }
  1720. return(FALSE);
  1721. }
  1722. VOID
  1723. ThunkOPENFILENAME32to16(OUT POPENFILENAME16 pOFN16,
  1724. IN OPENFILENAME *pOFN32,
  1725. IN BOOLEAN bUpperStrings)
  1726. /*++
  1727. Routine Description:
  1728. This routine thunks a 32-bit OPENFILENAME structure back to a 16-bit
  1729. OPENFILENAME structure.
  1730. Arguments:
  1731. pOFN32 - Supplies a pointer to the 32-bit OPENFILENAME struct.
  1732. pOFN16 - Supplies a flat pointer to the 16-bit OPENFILENAME struct
  1733. Return Value:
  1734. None.
  1735. --*/
  1736. {
  1737. LPSTR lpstr;
  1738. DWORD Flags, Flags32;
  1739. if(pOFN16 && pOFN32) {
  1740. STOREWORD(pOFN16->nFileOffset, pOFN32->nFileOffset);
  1741. STOREWORD(pOFN16->nFileExtension, pOFN32->nFileExtension);
  1742. STOREDWORD(pOFN16->nFilterIndex, pOFN32->nFilterIndex);
  1743. // preserve the template flag state while copying flags
  1744. // 1. save template flag state
  1745. // 2. copy flags from 32-bit struct
  1746. // 3. turn off all template flags and the WOWAPP flag
  1747. // 4. restore original template flag state
  1748. Flags = DWORD32(pOFN16->Flags) & (OFN_ENABLETEMPLATE |
  1749. OFN_ENABLETEMPLATEHANDLE);
  1750. Flags32 = pOFN32->Flags;
  1751. Flags32 &= ~(OFN_ENABLETEMPLATE | OFN_ENABLETEMPLATEHANDLE | CD_WOWAPP);
  1752. Flags32 |= Flags;
  1753. STOREDWORD(pOFN16->Flags, Flags32);
  1754. if(bUpperStrings && pOFN32->lpstrFile) {
  1755. // Note we have to upcase the pOFN32 here because some apps
  1756. // (notably QC/Win) do case-sensitive compares on the extension.
  1757. // In Win3.1, the upcasing happens as a side-effect of the
  1758. // OpenFile call. Here we do it explicitly.
  1759. CharUpperBuff(pOFN32->lpstrFile, strlen(pOFN32->lpstrFile));
  1760. }
  1761. GETPSZPTR(pOFN16->lpstrFile, lpstr);
  1762. if(lpstr && pOFN32->lpstrFile) {
  1763. strcpy(lpstr, pOFN32->lpstrFile);
  1764. FREEPSZPTR(lpstr);
  1765. }
  1766. GETPSZPTR(pOFN16->lpstrFilter, lpstr);
  1767. if(lpstr && pOFN32->lpstrFilter) {
  1768. Multi_strcpy(lpstr, pOFN32->lpstrFilter);
  1769. FREEPSZPTR(lpstr);
  1770. }
  1771. GETPSZPTR(pOFN16->lpstrCustomFilter, lpstr);
  1772. if(lpstr && pOFN32->lpstrCustomFilter) {
  1773. Multi_strcpy(lpstr, pOFN32->lpstrCustomFilter);
  1774. FREEPSZPTR(lpstr);
  1775. }
  1776. if(bUpperStrings && (pOFN32->lpstrFileTitle)) {
  1777. // Not sure if we really need to upcase this or not, but I figure
  1778. // somewhere there is an app that depends on this being uppercased
  1779. // like Win3.1
  1780. CharUpperBuff(pOFN32->lpstrFileTitle,
  1781. strlen(pOFN32->lpstrFileTitle));
  1782. }
  1783. GETPSZPTR(pOFN16->lpstrFileTitle , lpstr);
  1784. if(lpstr && pOFN32->lpstrFileTitle) {
  1785. strcpy(lpstr, pOFN32->lpstrFileTitle);
  1786. FREEPSZPTR(lpstr);
  1787. }
  1788. // even though this is doc'd as being filled by the app only, Adobe
  1789. // distiller depends on it being copied back to the app
  1790. GETPSZPTR(pOFN16->lpstrInitialDir , lpstr);
  1791. if(lpstr && pOFN32->lpstrInitialDir) {
  1792. strcpy(lpstr, pOFN32->lpstrInitialDir);
  1793. FREEPSZPTR(lpstr);
  1794. }
  1795. // who knows who depends on this
  1796. GETPSZPTR(pOFN16->lpstrTitle, lpstr);
  1797. if(lpstr && pOFN32->lpstrTitle) {
  1798. strcpy(lpstr, pOFN32->lpstrTitle);
  1799. FREEPSZPTR(lpstr);
  1800. }
  1801. }
  1802. }
  1803. BOOL
  1804. Alloc_OFN32_strs(IN OPENFILENAME *pOFN32,
  1805. IN POPENFILENAME16 pOFN16)
  1806. {
  1807. if(DWORD32(pOFN16->lpstrFilter)) {
  1808. if(!(pOFN32->lpstrFilter =
  1809. malloc_w_strcpy_vp16to32(DWORD32(pOFN16->lpstrFilter),
  1810. TRUE,
  1811. 0))) {
  1812. goto ErrorExit;
  1813. }
  1814. }
  1815. if(DWORD32(pOFN16->lpstrCustomFilter)) {
  1816. if(!(pOFN32->lpstrCustomFilter =
  1817. malloc_w_strcpy_vp16to32(DWORD32(pOFN16->lpstrCustomFilter),
  1818. TRUE,
  1819. DWORD32(pOFN16->nMaxCustFilter) ))) {
  1820. goto ErrorExit;
  1821. }
  1822. }
  1823. if(DWORD32(pOFN16->lpstrFile)) {
  1824. if(!(pOFN32->lpstrFile =
  1825. malloc_w_strcpy_vp16to32(DWORD32(pOFN16->lpstrFile),
  1826. FALSE,
  1827. DWORD32(pOFN16->nMaxFile) ))) {
  1828. goto ErrorExit;
  1829. }
  1830. }
  1831. if(DWORD32(pOFN16->lpstrFileTitle)) {
  1832. if(!(pOFN32->lpstrFileTitle =
  1833. malloc_w_strcpy_vp16to32(DWORD32(pOFN16->lpstrFileTitle),
  1834. FALSE,
  1835. DWORD32(pOFN16->nMaxFileTitle) ))) {
  1836. goto ErrorExit;
  1837. }
  1838. }
  1839. if(DWORD32(pOFN16->lpstrInitialDir)) {
  1840. if(!(pOFN32->lpstrInitialDir =
  1841. malloc_w_strcpy_vp16to32(DWORD32(pOFN16->lpstrInitialDir),
  1842. FALSE,
  1843. 0))) {
  1844. goto ErrorExit;
  1845. }
  1846. }
  1847. if(DWORD32(pOFN16->lpstrTitle)) {
  1848. if(!(pOFN32->lpstrTitle =
  1849. malloc_w_strcpy_vp16to32(DWORD32(pOFN16->lpstrTitle),
  1850. FALSE,
  1851. 0))) {
  1852. goto ErrorExit;
  1853. }
  1854. }
  1855. if(DWORD32(pOFN16->lpstrDefExt)) {
  1856. if(!(pOFN32->lpstrDefExt =
  1857. malloc_w_strcpy_vp16to32(DWORD32(pOFN16->lpstrDefExt),
  1858. FALSE,
  1859. 0))) {
  1860. goto ErrorExit;
  1861. }
  1862. }
  1863. return(TRUE);
  1864. ErrorExit:
  1865. LOGDEBUG(0, ("Alloc_OFN32_strs, 32-bit allocation(s) failed!\n"));
  1866. Free_OFN32_strs(pOFN32);
  1867. return(FALSE);
  1868. }
  1869. VOID
  1870. Free_OFN32_strs(IN OPENFILENAME *pOFN32)
  1871. {
  1872. if(pOFN32->lpstrFilter) {
  1873. free_w((PVOID)pOFN32->lpstrFilter);
  1874. pOFN32->lpstrFilter = NULL;
  1875. }
  1876. if(pOFN32->lpstrCustomFilter) {
  1877. free_w((PVOID)pOFN32->lpstrCustomFilter);
  1878. pOFN32->lpstrCustomFilter = NULL;
  1879. }
  1880. if(pOFN32->lpstrFile) {
  1881. free_w((PVOID)pOFN32->lpstrFile);
  1882. pOFN32->lpstrFile = NULL;
  1883. }
  1884. if(pOFN32->lpstrFileTitle) {
  1885. free_w((PVOID)pOFN32->lpstrFileTitle);
  1886. pOFN32->lpstrFileTitle = NULL;
  1887. }
  1888. if(pOFN32->lpstrInitialDir) {
  1889. free_w((PVOID)pOFN32->lpstrInitialDir);
  1890. pOFN32->lpstrInitialDir = NULL;
  1891. }
  1892. if(pOFN32->lpstrTitle) {
  1893. free_w((PVOID)pOFN32->lpstrTitle);
  1894. pOFN32->lpstrTitle = NULL;
  1895. }
  1896. if(pOFN32->lpstrDefExt) {
  1897. free_w((PVOID)pOFN32->lpstrDefExt);
  1898. pOFN32->lpstrDefExt = NULL;
  1899. }
  1900. }
  1901. VOID
  1902. Thunk_OFNstrs16to32(IN OPENFILENAME *pOFN32,
  1903. IN POPENFILENAME16 pOFN16)
  1904. {
  1905. pOFN32->lpstrFilter
  1906. = ThunkStr16toStr32((LPSTR)pOFN32->lpstrFilter,
  1907. DWORD32(pOFN16->lpstrFilter),
  1908. MAX_PATH,
  1909. TRUE);
  1910. pOFN32->lpstrCustomFilter
  1911. = ThunkStr16toStr32(pOFN32->lpstrCustomFilter,
  1912. DWORD32(pOFN16->lpstrCustomFilter),
  1913. DWORD32(pOFN16->nMaxCustFilter),
  1914. TRUE);
  1915. pOFN32->lpstrFile
  1916. = ThunkStr16toStr32(pOFN32->lpstrFile,
  1917. DWORD32(pOFN16->lpstrFile),
  1918. DWORD32(pOFN16->nMaxFile),
  1919. FALSE);
  1920. pOFN32->lpstrFileTitle
  1921. = ThunkStr16toStr32(pOFN32->lpstrFileTitle,
  1922. DWORD32(pOFN16->lpstrFileTitle),
  1923. DWORD32(pOFN16->nMaxFileTitle),
  1924. FALSE);
  1925. pOFN32->lpstrInitialDir
  1926. = ThunkStr16toStr32((LPSTR)pOFN32->lpstrInitialDir,
  1927. DWORD32(pOFN16->lpstrInitialDir),
  1928. MAX_PATH,
  1929. FALSE);
  1930. pOFN32->lpstrTitle
  1931. = ThunkStr16toStr32((LPSTR)pOFN32->lpstrTitle,
  1932. DWORD32(pOFN16->lpstrTitle),
  1933. MAX_PATH,
  1934. FALSE);
  1935. pOFN32->lpstrDefExt
  1936. = ThunkStr16toStr32((LPSTR)pOFN32->lpstrDefExt,
  1937. DWORD32(pOFN16->lpstrDefExt),
  1938. 10,
  1939. FALSE);
  1940. }
  1941. ULONG FASTCALL
  1942. WCD32FindText(PVDMFRAME pFrame)
  1943. /*++
  1944. Routine Description:
  1945. This routine thunks the 16-bit FindText common dialog to the
  1946. 32-bit side.
  1947. Arguments:
  1948. pFrame - Supplies 16-bit argument frame
  1949. Return Value:
  1950. 16-bit BOOLEAN to be returned.
  1951. --*/
  1952. {
  1953. return(WCD32FindReplaceText(pFrame, FindText));
  1954. }
  1955. ULONG FASTCALL
  1956. WCD32ReplaceText(PVDMFRAME pFrame)
  1957. /*++
  1958. Routine Description:
  1959. This routine thunks the 16-bit ReplaceText common dialog to the
  1960. 32-bit side.
  1961. Arguments:
  1962. pFrame - Supplies 16-bit argument frame
  1963. Return Value:
  1964. 16-bit BOOLEAN to be returned.
  1965. --*/
  1966. {
  1967. return(WCD32FindReplaceText(pFrame, ReplaceText));
  1968. }
  1969. ULONG
  1970. WCD32FindReplaceText(IN PVDMFRAME pFrame,
  1971. IN FINDREPLACEPROC Function)
  1972. /*++
  1973. Routine Description:
  1974. This routine is called by WCD32FindText and WCD32RepalceText.
  1975. It copies a 16-bit FINDREPLACE structure to a 32-bit structure.
  1976. Two per thread data entries are maintained. One is indexed by the
  1977. owner hwnd, the other is indexed by the dialog hwnd. The dialog is
  1978. always hooked by WCD32FindReplaceDialogProc, which dispatches to the
  1979. 16-bit hookproc, and takes care of clean-up on WM_DESTROY, with dialog
  1980. per thread data providing context. WCD32UpdateFindReplaceTextAndFlags
  1981. updates the 16-bit FINDREPLACE structure when called by the WOW message
  1982. dispatching logic upon reciept of a WM_NOTIFYWOW message from COMDLG32.
  1983. The owner per thread data provides context for this operation.
  1984. Arguments:
  1985. pFrame - Supplies 16-bit argument frame
  1986. Function - supplies a pointer to the 32-bit function to call (either
  1987. FindText or RepalceText)
  1988. Return Value:
  1989. 16-bit BOOLEAN to be returned.
  1990. --*/
  1991. {
  1992. register PFINDTEXT16 parg16;
  1993. VPFINDREPLACE vpfr;
  1994. FINDREPLACE *pFR32;
  1995. PFINDREPLACE16 pFR16;
  1996. PCOMMDLGTD pTDDlg;
  1997. PCOMMDLGTD pTDOwner;
  1998. HWND hwndDlg = NULL;
  1999. DWORD dwFlags16 = 0;
  2000. BOOL fError = FALSE;
  2001. GETARGPTR(pFrame, sizeof(FINDREPLACE16), parg16);
  2002. vpfr = parg16->lpfr;
  2003. SETEXTENDEDERROR(0);
  2004. // invalidate this now
  2005. FREEVDMPTR( parg16 );
  2006. GETVDMPTR(vpfr, sizeof(FINDREPLACE16), pFR16);
  2007. WCDDUMPFINDREPLACE16(pFR16);
  2008. if(DWORD32(pFR16->lStructSize) != sizeof(FINDREPLACE16)) {
  2009. SETEXTENDEDERROR( CDERR_STRUCTSIZE );
  2010. FREEVDMPTR(pFR16);
  2011. return(0);
  2012. }
  2013. if(!DWORD32(pFR16->lpstrFindWhat) ||
  2014. !WORD32(pFR16->wFindWhatLen) ||
  2015. !IsWindow(HWND32(pFR16->hwndOwner))) {
  2016. SETEXTENDEDERROR(FRERR_BUFFERLENGTHZERO);
  2017. FREEVDMPTR(pFR16);
  2018. return(0);
  2019. }
  2020. // check the hook proc
  2021. if(DWORD32(pFR16->Flags) & FR_ENABLEHOOK) {
  2022. if(!DWORD32(pFR16->lpfnHook)) {
  2023. SETEXTENDEDERROR(CDERR_NOHOOK);
  2024. FREEVDMPTR(pFR16);
  2025. return(0);
  2026. }
  2027. }
  2028. else {
  2029. STOREDWORD(pFR16->lpfnHook, 0);
  2030. }
  2031. // WCD32UpdateFindReplaceTextAndFlags will update the 16-bit FINDREPLACE
  2032. // struct and help thunk the WM_NOTIFYWOW message to the
  2033. // "commdlg_FindReplace" registered message.
  2034. if (msgFINDREPLACE == 0) {
  2035. if(!(msgFINDREPLACE = (WORD)RegisterWindowMessage(FINDMSGSTRING))) {
  2036. LOGDEBUG(2,("WCD32FindReplaceText:RegisterWindowMessage failed\n"));
  2037. SETEXTENDEDERROR( CDERR_REGISTERMSGFAIL );
  2038. FREEVDMPTR(pFR16);
  2039. return(0);
  2040. }
  2041. }
  2042. // Allocate the required memory
  2043. // Note: these can't be alloc'd off our stack since FindText & ReplaceText
  2044. // eventually call CreateDialogIndirectParam which returns immediately
  2045. // after displaying the dialog box.
  2046. pFR32 = (FINDREPLACE *)malloc_w_zero(sizeof(FINDREPLACE));
  2047. if(pFR32) {
  2048. pFR32->lpstrFindWhat = (LPTSTR)malloc_w(WORD32(pFR16->wFindWhatLen));
  2049. pFR32->lpstrReplaceWith
  2050. = (LPTSTR)malloc_w(WORD32(pFR16->wReplaceWithLen));
  2051. pTDDlg = malloc_w_zero(sizeof(COMMDLGTD));
  2052. pTDOwner = malloc_w_zero(sizeof(COMMDLGTD));
  2053. }
  2054. if( (pFR32 &&
  2055. pFR32->lpstrFindWhat &&
  2056. pFR32->lpstrReplaceWith &&
  2057. pTDDlg &&
  2058. pTDOwner) == FALSE) {
  2059. LOGDEBUG(0, ("WCD32FindReplaceText, 32-bit allocation(s) failed!\n"));
  2060. SETEXTENDEDERROR(CDERR_MEMALLOCFAILURE);
  2061. goto FindReplaceError;
  2062. }
  2063. pTDDlg->pData32 = pTDOwner->pData32 = (PVOID)pFR32;
  2064. pTDDlg->vpData = pTDOwner->vpData = vpfr;
  2065. // Set the per thread data indicies
  2066. pTDDlg->hdlg = (HWND16)-1;
  2067. pTDOwner->hdlg = GETHWND16(pFR16->hwndOwner);
  2068. // save the hook proc if any
  2069. if(DWORD32(pFR16->Flags) & FR_ENABLEHOOK) {
  2070. pTDDlg->vpfnHook = pTDOwner->vpfnHook = DWORD32(pFR16->lpfnHook);
  2071. }
  2072. ThunkFINDREPLACE16to32(pFR32, pFR16);
  2073. dwFlags16 = DWORD32(pFR16->Flags);
  2074. // this call invalidates flat ptrs to 16-bit memory
  2075. pFR32->hInstance = ThunkCDTemplate16to32(WORD32(pFR16->hInstance),
  2076. 0,
  2077. DWORD32(pFR16->lpTemplateName),
  2078. dwFlags16,
  2079. &(pFR32->Flags),
  2080. FR_ENABLETEMPLATE,
  2081. FR_ENABLETEMPLATEHANDLE,
  2082. &(PRES)(pTDDlg->pRes),
  2083. &fError);
  2084. if(fError) {
  2085. goto FindReplaceError;
  2086. }
  2087. // invalidate flat ptrs to 16-bit memory
  2088. FREEVDMPTR(pFR16);
  2089. WCDDUMPFINDREPLACE32(pFR32);
  2090. // Link both per thread data structs into the list
  2091. // do this just before calling into comdlg32
  2092. pTDDlg->Previous = CURRENTPTD()->CommDlgTd;
  2093. pTDOwner->Previous = pTDDlg;
  2094. CURRENTPTD()->CommDlgTd = pTDOwner;
  2095. // this call invalidates flat ptrs to 16-bit memory
  2096. hwndDlg = (*Function)(pFR32);
  2097. if (hwndDlg) {
  2098. pTDDlg->hdlg = (HWND16)hwndDlg;
  2099. } else {
  2100. FindReplaceError:
  2101. LOGDEBUG(0, ("WCD32FindReplaceText, Failed!\n"));
  2102. if(pTDDlg) {
  2103. CURRENTPTD()->CommDlgTd = pTDDlg->Previous;
  2104. FreeCDTemplate32(pTDDlg->pRes,
  2105. pFR32->hInstance,
  2106. dwFlags16 & FR_ENABLETEMPLATE,
  2107. dwFlags16 & FR_ENABLETEMPLATEHANDLE);
  2108. free_w(pTDDlg);
  2109. }
  2110. if(pFR32) {
  2111. if(pFR32->lpstrFindWhat)
  2112. free_w(pFR32->lpstrFindWhat);
  2113. if(pFR32->lpstrReplaceWith)
  2114. free_w(pFR32->lpstrReplaceWith);
  2115. free_w(pFR32);
  2116. }
  2117. if(pTDOwner)
  2118. free_w(pTDOwner);
  2119. }
  2120. return(GETHWND16(hwndDlg));
  2121. }
  2122. VOID
  2123. ThunkFINDREPLACE16to32(OUT FINDREPLACE *pFR32,
  2124. IN PFINDREPLACE16 pFR16)
  2125. /*++
  2126. Routine Description:
  2127. This routine thunks a 16-bit FINDREPLACE structure to the 32-bit
  2128. structure
  2129. Arguments:
  2130. pFR32 - Supplies a pointer to the 32-bit FINDREPLACE structure.
  2131. pFR16 - Supplies a pointer to the 16-bit FINDREPLACE structure.
  2132. Return Value:
  2133. None.
  2134. --*/
  2135. {
  2136. LPSTR lpstr;
  2137. DWORD Flags;
  2138. if(pFR16 && pFR32) {
  2139. pFR32->lStructSize = sizeof(FINDREPLACE);
  2140. pFR32->hwndOwner = HWND32(pFR16->hwndOwner);
  2141. // hInstance is thunked separately
  2142. // preserve the template flag state while copying flags
  2143. // 1. save template flag state
  2144. // note: we never will have a 32-bit FR_ENABLETEMPLATE flag
  2145. // 2. copy flags from 16-bit struct (add the WOWAPP flag)
  2146. // 3. turn off all template flags
  2147. // 4. restore original template flag state
  2148. Flags = pFR32->Flags & FR_ENABLETEMPLATEHANDLE;
  2149. pFR32->Flags = DWORD32(pFR16->Flags) | CD_WOWAPP;
  2150. pFR32->Flags &= ~(FR_ENABLETEMPLATE | FR_ENABLETEMPLATEHANDLE);
  2151. pFR32->Flags |= Flags;
  2152. GETPSZPTR(pFR16->lpstrFindWhat, lpstr);
  2153. if(lpstr && pFR32->lpstrFindWhat) {
  2154. WOW32_strncpy(pFR32->lpstrFindWhat, lpstr, WORD32(pFR16->wFindWhatLen));
  2155. FREEPSZPTR(lpstr);
  2156. }
  2157. GETPSZPTR(pFR16->lpstrReplaceWith, lpstr);
  2158. if(lpstr && pFR32->lpstrReplaceWith) {
  2159. WOW32_strncpy(pFR32->lpstrReplaceWith,
  2160. lpstr,
  2161. WORD32(pFR16->wReplaceWithLen));
  2162. FREEPSZPTR(lpstr);
  2163. }
  2164. pFR32->wFindWhatLen = WORD32(pFR16->wFindWhatLen);
  2165. pFR32->wReplaceWithLen = WORD32(pFR16->wReplaceWithLen);
  2166. pFR32->lCustData = DWORD32(pFR16->lCustData);
  2167. // we always put this WOW hook in so we can destroy the modeless dialog.
  2168. // WCD32FindReplaceDialogPRoc will determine whether to really dispatch
  2169. // to a 16-bit hookproc or not. pFR16->lpfnHook will be NULL if there
  2170. // isn't a 16-bit hook proc
  2171. pFR32->lpfnHook = WCD32FindReplaceDialogProc;
  2172. pFR32->Flags |= FR_ENABLEHOOK;
  2173. // lpTemplateName32 is thunked separately
  2174. }
  2175. }
  2176. VOID
  2177. ThunkFINDREPLACE32to16(OUT PFINDREPLACE16 pFR16,
  2178. IN FINDREPLACE *pFR32)
  2179. {
  2180. LPSTR lpstr;
  2181. DWORD Flags, Flags32;
  2182. if(pFR16 && pFR32) {
  2183. // Update the 16-bit structure.
  2184. // preserve the template flag state while copying flags
  2185. // 1. save template flag state
  2186. // 2. copy flags from 32-bit struct
  2187. // 3. turn off all template flags and the WOWAPP flag
  2188. // 4. restore original template flag state
  2189. Flags = DWORD32(pFR16->Flags) & (FR_ENABLETEMPLATE |
  2190. FR_ENABLETEMPLATEHANDLE);
  2191. Flags32 = pFR32->Flags;
  2192. Flags32 &= ~(FR_ENABLETEMPLATE | FR_ENABLETEMPLATEHANDLE | CD_WOWAPP);
  2193. Flags32 |= Flags;
  2194. // we may have to turn off the hookproc flag if we added it in
  2195. // ThunkFINDREPLACE16to32().
  2196. if(!DWORD32(pFR16->lpfnHook)) {
  2197. Flags32 &= ~FR_ENABLEHOOK;
  2198. }
  2199. STOREDWORD(pFR16->Flags, Flags32);
  2200. GETPSZPTR(pFR16->lpstrFindWhat, lpstr);
  2201. if(lpstr && pFR32->lpstrFindWhat) {
  2202. WOW32_strncpy(lpstr, pFR32->lpstrFindWhat, WORD32(pFR16->wFindWhatLen));
  2203. FREEPSZPTR(lpstr);
  2204. }
  2205. GETPSZPTR(pFR16->lpstrReplaceWith, lpstr);
  2206. if(lpstr && pFR32->lpstrReplaceWith) {
  2207. WOW32_strncpy(lpstr,
  2208. pFR32->lpstrReplaceWith,
  2209. WORD32(pFR16->wReplaceWithLen));
  2210. FREEPSZPTR(lpstr);
  2211. }
  2212. }
  2213. }
  2214. LONG APIENTRY
  2215. WCD32UpdateFindReplaceTextAndFlags(HWND hwndOwner,
  2216. LPARAM lParam)
  2217. {
  2218. PCOMMDLGTD ptdOwner;
  2219. PFINDREPLACE16 pFR16;
  2220. VPFINDREPLACE vpfr;
  2221. LPFINDREPLACE pFR32 = (LPFINDREPLACE) lParam;
  2222. LONG lRet = 0;
  2223. ptdOwner = GetCommdlgTd(hwndOwner);
  2224. WOW32ASSERT(ptdOwner);
  2225. vpfr = ptdOwner->vpData;
  2226. GETVDMPTR(vpfr, sizeof(FINDREPLACE16), pFR16);
  2227. ThunkFINDREPLACE32to16(pFR16, pFR32);
  2228. WCDDUMPFINDREPLACE16(pFR16);
  2229. FREEVDMPTR(pFR16);
  2230. return(vpfr);
  2231. }
  2232. PCOMMDLGTD
  2233. GetCommdlgTd(IN HWND Hwnd32)
  2234. /*++
  2235. Routine Description:
  2236. Searches the thread's chain of commdlg data for the given 32-bit window.
  2237. If the window is not already in the chain, it is added.
  2238. Arguments:
  2239. Hwnd32 - Supplies the 32-bit hwnd that the dialog procedure was called
  2240. with.
  2241. Return Value:
  2242. Pointer to commdlg data.
  2243. --*/
  2244. {
  2245. PCOMMDLGTD pTD;
  2246. if ((pTD = CURRENTPTD()->CommDlgTd) == NULL) {
  2247. return(NULL);
  2248. }
  2249. // look for the CommDlgTD struct for this dialog -- usually will be first
  2250. // unless there are nested dialogs
  2251. while (pTD->hdlg != GETHWND16(Hwnd32)) {
  2252. pTD = pTD->Previous;
  2253. // If Hwnd32 isn't in the list, we're probably getting called back
  2254. // from user32 via WOWTellWOWThehDlg(). This means that the dialog
  2255. // window was just created in user32. Note that this can be either a
  2256. // new dialog or a PrintSetup dialog.
  2257. if (pTD==NULL) {
  2258. pTD = CURRENTPTD()->CommDlgTd;
  2259. while (pTD->hdlg != (HWND16)-1) {
  2260. // Check to see if this is the first call for a PrintSetupHook.
  2261. // It will share the same CommDlgTD as the PrintDlgHook.
  2262. // Note: SetupHwnd will be 1 if this is the 1st time the user
  2263. // clicks the Setup button in the PrintDlg. Otherwise
  2264. // it will be the old Hwnd32 from the previous time he
  2265. // clicked the Setup button from within the same instance
  2266. // of the PrintDlg. Either way it is non-zero.
  2267. if(pTD->SetupHwnd) {
  2268. // if the current CommDlgTD->hdlg is the owner of Hwnd32,
  2269. // we found the CommDlgTD for the PrintSetup dialog.
  2270. if(pTD->hdlg == GETHWND16(GetWindow(Hwnd32, GW_OWNER))) {
  2271. pTD->SetupHwnd = GETHWND16(Hwnd32);
  2272. return(pTD);
  2273. }
  2274. }
  2275. pTD = pTD->Previous;
  2276. if(pTD == NULL) {
  2277. WOW32ASSERT(FALSE);
  2278. return(NULL);
  2279. }
  2280. }
  2281. // set the hdlg for this CommDlgTD
  2282. pTD->hdlg = GETHWND16(Hwnd32);
  2283. return(pTD);
  2284. }
  2285. }
  2286. return(pTD);
  2287. }
  2288. // Thunks 16-bit Common dialog templates to 32-bit
  2289. // Note: this calls back to 16-bit code causing possible 16-bit memory movement
  2290. // Note: GetTemplate16 call SETEXTENDEDERROR for *most* failures
  2291. HINSTANCE
  2292. ThunkCDTemplate16to32(IN HAND16 hInst16,
  2293. IN DWORD hPT16, // for PrintDlg only
  2294. IN VPVOID vpTemplateName,
  2295. IN DWORD dwFlags16,
  2296. IN OUT DWORD *pFlags,
  2297. IN DWORD ETFlag, // XX_ENABLETEMPLATE flag
  2298. IN DWORD ETHFlag, // XX_ENABLETEMPLATEHANDLE flag
  2299. OUT PPRES pRes,
  2300. OUT PBOOL fError)
  2301. {
  2302. // Note: struct->hInstance == NULL if neither xx_ENABLExxx flag is set
  2303. HINSTANCE hInst32 = NULL;
  2304. HAND16 hPrintTemp16 = (HAND16)NULL;
  2305. SETEXTENDEDERROR( CDERR_NOTEMPLATE ); // most common error ret
  2306. if(hPT16) {
  2307. hPrintTemp16 = (HAND16)LOWORD(hPT16);
  2308. }
  2309. *pRes = NULL;
  2310. if(dwFlags16 & ETFlag) {
  2311. if(!vpTemplateName) {
  2312. *fError = TRUE;
  2313. return(NULL);
  2314. }
  2315. if(!hInst16) {
  2316. SETEXTENDEDERROR( CDERR_NOHINSTANCE );
  2317. *fError = TRUE;
  2318. return(NULL);
  2319. }
  2320. // Note: calls to GetTemplate16 may cause 16-bit memory to move
  2321. *pRes = GetTemplate16(hInst16, vpTemplateName, FALSE);
  2322. if(*pRes == NULL) {
  2323. *fError = TRUE;
  2324. return(NULL);
  2325. }
  2326. hInst32 = (HINSTANCE)LockResource16(*pRes);
  2327. if(!hInst32) {
  2328. *fError = TRUE;
  2329. SETEXTENDEDERROR( CDERR_LOCKRESFAILURE );
  2330. return(NULL);
  2331. }
  2332. *pFlags &= ~ETFlag;
  2333. *pFlags |= ETHFlag;
  2334. } else if(dwFlags16 & ETHFlag) {
  2335. // Win'95 does the following if !hInst && ETHFlag.
  2336. // Note: the return val == FALSE in all cases except the last PD case
  2337. // CC (0x00040) -> CDERR_NOTEMPLATE
  2338. // CF (0x00020) -> No error (comdlg32 err = CDERR_LOCKRESFAILURE)
  2339. // FR (0x02000) -> CDERR_LOCKRESFAILURE
  2340. // OFN (0x00080) -> CDERR_LOCKRESFAILURE
  2341. // PD (0x10000) -> CDERR_LOCKRESFAILURE (hInstance)
  2342. // PD (0x20040) -> CDERR_LOCKRESFAILURE (with PD_PRINTSETUP)
  2343. // PD (0x20000) -> CDERR_LOCKRESFAILURE
  2344. //
  2345. // I think the error value is probably irrelavant since most of these
  2346. // are pathological cases that only developers would see while building
  2347. // and debugging their app. In the cases where the Win'95 error code is
  2348. // CDERR_LOCKRESFAILURE, comdlg32 sets it to CDERR_NOTEMPLATE (as we
  2349. // now return for WOW) for 32-bit apps
  2350. // one of the hTemplate's should always be set with the
  2351. // ENABLETEMPLATEHANDLE flag
  2352. // if it's a printdlg...
  2353. if(hPT16) {
  2354. // ...the hTemplate should be in either hPrintTemplate or
  2355. // hPrintSetupTemplate
  2356. if(!hPrintTemp16) {
  2357. *fError = TRUE;
  2358. }
  2359. }
  2360. // else for non-printdlg's, the hTemplate should be in hInstance
  2361. else {
  2362. if(!hInst16) {
  2363. *fError = TRUE;
  2364. }
  2365. }
  2366. if(*fError) {
  2367. return(NULL);
  2368. }
  2369. // Note: calls to GetTemplate16 may cause 16-bit memory to move
  2370. if(hPT16) {
  2371. hInst32 = (HINSTANCE) GetTemplate16(hPrintTemp16,(VPCSTR)NULL,TRUE);
  2372. } else {
  2373. hInst32 = (HINSTANCE) GetTemplate16(hInst16, (VPCSTR)NULL, TRUE);
  2374. }
  2375. if(!hInst32) {
  2376. *fError = TRUE;
  2377. return(NULL);
  2378. }
  2379. *pFlags |= ETHFlag;
  2380. }
  2381. SETEXTENDEDERROR( 0 ); // reset to no error
  2382. return(hInst32);
  2383. }
  2384. VOID
  2385. FreeCDTemplate32(IN PRES pRes,
  2386. IN HINSTANCE hInst,
  2387. IN BOOL bETFlag,
  2388. IN BOOL bETHFlag)
  2389. {
  2390. if(pRes && bETFlag) {
  2391. UnlockResource16(pRes);
  2392. FreeResource16(pRes);
  2393. } else if(hInst && bETHFlag) {
  2394. free_w((PVOID)hInst);
  2395. }
  2396. }
  2397. PRES
  2398. GetTemplate16(IN HAND16 hInstance,
  2399. IN VPCSTR lpTemplateName,
  2400. IN BOOLEAN UseHandle)
  2401. /*++
  2402. Routine Description:
  2403. Finds and loads the specified 16-bit dialog template.
  2404. WARNING: This may cause memory movement, invalidating flat pointers
  2405. Arguments:
  2406. hInstance - Supplies the data block containing the dialog box template
  2407. TemplateName - Supplies the name of the resource file for the dialog
  2408. box template. This may be either a null-terminated string or
  2409. a numbered resource created with the MAKEINTRESOURCE macro.
  2410. UseHandle - Indicates that hInstance identifies a pre-loaded dialog
  2411. box template. If this is TRUE, Templatename is ignored.
  2412. Return Value:
  2413. success - A pointer to the loaded resource
  2414. failure - NULL, dwLastError will be set.
  2415. --*/
  2416. {
  2417. LPSZ TemplateName=NULL;
  2418. PRES pRes;
  2419. PBYTE pDlg = NULL;
  2420. INT cb;
  2421. INT cb16;
  2422. if (!UseHandle) {
  2423. GETPSZIDPTR(lpTemplateName, TemplateName);
  2424. // Both custom instance handle and the dialog template name are
  2425. // specified. Locate the 16-bit dialog resource in the specified
  2426. // instance block and load it.
  2427. pRes = FindResource16(hInstance,
  2428. TemplateName,
  2429. (LPSZ)RT_DIALOG);
  2430. if (HIWORD(lpTemplateName) != 0) {
  2431. FREEVDMPTR(TemplateName);
  2432. }
  2433. if (!pRes) {
  2434. SETEXTENDEDERROR( CDERR_FINDRESFAILURE );
  2435. return(NULL);
  2436. }
  2437. if (!(pRes = LoadResource16(hInstance,pRes))) {
  2438. SETEXTENDEDERROR( CDERR_LOADRESFAILURE );
  2439. return(NULL);
  2440. }
  2441. return(pRes);
  2442. } else {
  2443. VPVOID pDlg16;
  2444. if (pDlg16 = RealLockResource16(hInstance, &cb16)) {
  2445. cb = ConvertDialog16(NULL, pDlg16, 0, cb16);
  2446. if (cb != 0) {
  2447. if (pDlg = malloc_w(cb)) {
  2448. ConvertDialog16(pDlg, pDlg16, cb, cb16);
  2449. }
  2450. }
  2451. GlobalUnlock16(hInstance);
  2452. }
  2453. else {
  2454. SETEXTENDEDERROR( CDERR_LOCKRESFAILURE );
  2455. }
  2456. return((PRES)pDlg);
  2457. }
  2458. }
  2459. // When an app calls a ComDlg API it passes a ptr to the appropriate structure.
  2460. // On Win3.1 the app & the system share a ptr to the same structure, so when
  2461. // either updates the struct, the other is aware of the change. On NT we thunk
  2462. // the 16-bit struct to a 32-bit ANSI struct which is then thunked to a 32-bit
  2463. // UNICODE struct by the ComDlg32 code. We need a mechanism to put all three
  2464. // structs in sync. We attempt to do this by calling ThunkCDStruct32to16()
  2465. // from the WCD32xxxxDialogProc()'s (xxxx = Common OR FindReplace) for
  2466. // WM_INITDIALOG and WM_COMMAND messages before we callback the 16-bit hook
  2467. // proc. We call ThunkCDStruct16to32() when we return from the 16-bit hook.
  2468. VOID
  2469. ThunkCDStruct16to32(IN HWND hDlg,
  2470. IN CHOOSECOLOR *p32,
  2471. IN VPVOID vp)
  2472. {
  2473. PCHOOSECOLORDATA16 p16;
  2474. GETVDMPTR(vp, sizeof(CHOOSECOLORDATA16), p16);
  2475. if(p16) {
  2476. switch(p16->lStructSize) {
  2477. case sizeof(CHOOSECOLORDATA16):
  2478. ThunkCHOOSECOLOR16to32(p32, p16);
  2479. Ssync_ANSI_UNICODE_Struct_For_WOW(hDlg, TRUE, WOW_CHOOSECOLOR);
  2480. break;
  2481. case sizeof(CHOOSEFONTDATA16):
  2482. ThunkCHOOSEFONT16to32((CHOOSEFONT *) p32,
  2483. (PCHOOSEFONTDATA16) p16);
  2484. Ssync_ANSI_UNICODE_Struct_For_WOW(hDlg, TRUE, WOW_CHOOSEFONT);
  2485. break;
  2486. case sizeof(FINDREPLACE16):
  2487. ThunkFINDREPLACE16to32((FINDREPLACE *) p32,
  2488. (PFINDREPLACE16) p16);
  2489. // Find/Replace ANSI-UNICODE sync's are handled by
  2490. // WCD32UpdateFindReplaceTextAndFlags() mechanism
  2491. break;
  2492. case sizeof(OPENFILENAME16):
  2493. ThunkOPENFILENAME16to32((OPENFILENAME *) p32,
  2494. (POPENFILENAME16) p16);
  2495. Ssync_ANSI_UNICODE_Struct_For_WOW(hDlg, TRUE, WOW_OPENFILENAME);
  2496. break;
  2497. case sizeof(PRINTDLGDATA16):
  2498. ThunkPRINTDLG16to32((PRINTDLG *) p32, (PPRINTDLGDATA16) p16);
  2499. Ssync_ANSI_UNICODE_Struct_For_WOW(hDlg, TRUE, WOW_PRINTDLG);
  2500. break;
  2501. }
  2502. FREEVDMPTR(p16);
  2503. }
  2504. }
  2505. VOID
  2506. ThunkCDStruct32to16(IN HWND hDlg,
  2507. IN VPVOID vp,
  2508. IN CHOOSECOLOR *p32)
  2509. {
  2510. PCHOOSECOLORDATA16 p16;
  2511. GETVDMPTR(vp, sizeof(CHOOSECOLORDATA16), p16);
  2512. if(p16) {
  2513. switch(p16->lStructSize) {
  2514. case sizeof(CHOOSECOLORDATA16):
  2515. Ssync_ANSI_UNICODE_Struct_For_WOW(hDlg, FALSE, WOW_CHOOSECOLOR);
  2516. ThunkCHOOSECOLOR32to16(p16, p32);
  2517. break;
  2518. case sizeof(CHOOSEFONTDATA16):
  2519. Ssync_ANSI_UNICODE_Struct_For_WOW(hDlg, FALSE, WOW_CHOOSEFONT);
  2520. ThunkCHOOSEFONT32to16((PCHOOSEFONTDATA16) p16,
  2521. (CHOOSEFONT *) p32);
  2522. break;
  2523. case sizeof(FINDREPLACE16):
  2524. // Find/Replace ANSI-UNICODE sync's are handled by
  2525. // WCD32UpdateFindReplaceTextAndFlags() mechanism
  2526. ThunkFINDREPLACE32to16((PFINDREPLACE16) p16,
  2527. (FINDREPLACE *) p32);
  2528. break;
  2529. case sizeof(OPENFILENAME16):
  2530. Ssync_ANSI_UNICODE_Struct_For_WOW(hDlg, FALSE, WOW_OPENFILENAME);
  2531. ThunkOPENFILENAME32to16((POPENFILENAME16) p16,
  2532. (OPENFILENAME *) p32,
  2533. TRUE);
  2534. break;
  2535. case sizeof(PRINTDLGDATA16):
  2536. Ssync_ANSI_UNICODE_Struct_For_WOW(hDlg, FALSE, WOW_PRINTDLG);
  2537. ThunkPRINTDLG32to16(vp, (PRINTDLG *) p32);
  2538. break;
  2539. }
  2540. FREEVDMPTR(p16);
  2541. }
  2542. }
  2543. VOID Multi_strcpy(LPSTR dst, LPCSTR src)
  2544. /*++
  2545. strcpy for string lists that have several strings that are separated by
  2546. a null char and is terminated by two NULL chars.
  2547. --*/
  2548. {
  2549. if(src && dst) {
  2550. while(*src) {
  2551. while(*dst++ = *src++)
  2552. ;
  2553. }
  2554. *dst = '\0';
  2555. }
  2556. }
  2557. INT Multi_strlen(LPCSTR str)
  2558. /*++
  2559. strlen for string lists that have several strings that are separated by
  2560. a null char and is terminated by two NULL chars.
  2561. Returns len of str including all NULL *separators* but not the 2nd NULL
  2562. terminator. ie. cat0dog00 would return len = 8;
  2563. --*/
  2564. {
  2565. INT i = 0;
  2566. if(str) {
  2567. while(*str) {
  2568. while(*str++)
  2569. i++;
  2570. i++; // count the NULL separator
  2571. }
  2572. }
  2573. return(i);
  2574. }
  2575. VOID Ssync_WOW_CommDlg_Structs(PCOMMDLGTD pTDIn,
  2576. BOOL f16to32,
  2577. DWORD dwThunkCSIP)
  2578. {
  2579. HWND hDlg;
  2580. WORD wCS16;
  2581. PCOMMDLGTD pTDPrev;
  2582. PCOMMDLGTD pTD = pTDIn;
  2583. // we shouldn't sync for calls from krnl386 into wow32 (we found out)
  2584. // eg. when kernel is handling segment not present faults etc.
  2585. if(dwThunkCSIP) {
  2586. wCS16 = HIWORD(dwThunkCSIP);
  2587. if((wCS16 == gwKrnl386CodeSeg1) ||
  2588. (wCS16 == gwKrnl386CodeSeg2) ||
  2589. (wCS16 == gwKrnl386CodeSeg3)) {
  2590. return;
  2591. }
  2592. }
  2593. // since we don't have an hwnd to compare with we really don't know which
  2594. // PCOMMDLGTD is the one we want -- so we have to sync them all.
  2595. // This is only a problem for nested dialogs which is fairly rare.
  2596. while(pTD) {
  2597. // if this hasn't been initialized yet there is nothing to do
  2598. if(pTD->hdlg == (HWND16)-1) {
  2599. break;
  2600. }
  2601. hDlg = HWND32(pTD->hdlg);
  2602. WOW32ASSERTMSG(hDlg,
  2603. ("WOW:Ssync_WOW_CommDlg_Structs: hDlg not found!\n"));
  2604. //BlockWOWIdle(TRUE);
  2605. if(f16to32) {
  2606. ThunkCDStruct16to32(hDlg, (CHOOSECOLOR *)pTD->pData32, pTD->vpData);
  2607. }
  2608. else {
  2609. ThunkCDStruct32to16(hDlg, pTD->vpData, (CHOOSECOLOR *)pTD->pData32);
  2610. }
  2611. //BlockWOWIdle(FALSE);
  2612. pTDPrev = pTD->Previous;
  2613. // multiple PCOMMDLGTD's in the list means 1 of 2 things:
  2614. // 1. This is a find/replace text dialog
  2615. // 2. This is a screwy nested dialog situation
  2616. if(pTDPrev) {
  2617. // 1. check for find/replace (it uses two PCOMMDLGTD structs and
  2618. // shares the same pData32 pointer with both)
  2619. if(pTDPrev->pData32 == pTD->pData32) {
  2620. // nothing to do -- they share the same data which was thunked
  2621. // above so we'll go on to the next PCOMMDLGTD in the list
  2622. pTD = pTDPrev->Previous;
  2623. }
  2624. // 2. there are nested dialogs lurking about & we need to sync
  2625. // each one!
  2626. else {
  2627. pTD = pTDPrev;
  2628. }
  2629. } else {
  2630. break;
  2631. }
  2632. }
  2633. }
  2634. // There is a special case issue (we found) where certain dialog box
  2635. // API calls can pass a pszptr that is in a common dialog struct ie:
  2636. // GetDlgItemText(hDlg, id, OFN16->lpstrFile, size). Our synchronization
  2637. // mechanism actually trashes OFN16->lpstrFile when we sync 32->16 upon
  2638. // returning from the API call. To avoid this we will sync 16->32 upon
  2639. // returning from the API call (if needed as per the conditions below)
  2640. // before we sync 32->16 thus preserving the string returned in the 16-bit
  2641. // buffer. The special case API's identified so far are:
  2642. // GetDlgItemText, GetWindowText(), DlgDirSelectxxxx, and SendDlgItemMessage.
  2643. VOID Check_ComDlg_pszptr(PCOMMDLGTD ptd, VPVOID vp)
  2644. {
  2645. VPVOID vpData;
  2646. POPENFILENAME16 p16;
  2647. if(ptd) {
  2648. vpData = ptd->vpData;
  2649. if(vpData) {
  2650. GETVDMPTR(vpData, sizeof(CHOOSECOLORDATA16), p16);
  2651. if(p16) {
  2652. switch(p16->lStructSize) {
  2653. // Only these 2 ComDlg structures have OUTPUT buffers.
  2654. case sizeof(CHOOSEFONTDATA16):
  2655. if((VPVOID)((PCHOOSEFONTDATA16)p16)->lpszStyle == vp) {
  2656. Ssync_WOW_CommDlg_Structs(ptd, w16to32, 0);
  2657. }
  2658. break;
  2659. case sizeof(OPENFILENAME16):
  2660. if(((VPVOID)p16->lpstrFilter == vp) ||
  2661. ((VPVOID)p16->lpstrCustomFilter == vp) ||
  2662. ((VPVOID)p16->lpstrFile == vp) ||
  2663. ((VPVOID)p16->lpstrFileTitle == vp) ||
  2664. ((VPVOID)p16->lpstrInitialDir == vp) ||
  2665. ((VPVOID)p16->lpstrTitle == vp) ||
  2666. ((VPVOID)p16->lpstrDefExt == vp)) {
  2667. Ssync_WOW_CommDlg_Structs(ptd, w16to32, 0);
  2668. }
  2669. break;
  2670. } // end switch
  2671. }
  2672. }
  2673. }
  2674. }
  2675. VOID FASTCALL WOWTellWOWThehDlg(HWND hDlg)
  2676. {
  2677. if(CURRENTPTD()->CommDlgTd) {
  2678. if(GetCommdlgTd(hDlg) == NULL) {
  2679. WOW32WARNMSGF(FALSE,
  2680. ("WOW::WOWTellWOWThehDlg: No unassigned hDlgs\n"));
  2681. }
  2682. }
  2683. }
  2684. #ifdef DEBUG
  2685. void WCDDumpCHOOSECOLORData16(PCHOOSECOLORDATA16 p16)
  2686. {
  2687. if (fLogFilter & FILTER_COMMDLG) {
  2688. LOGDEBUG(10, ("CHOOSECOLORDATA16:\n"));
  2689. LOGDEBUG(10, ("\tlStructSize = %x\n",(p16)->lStructSize));
  2690. LOGDEBUG(10, ("\thwndOwner = %lx\n",(p16)->hwndOwner));
  2691. LOGDEBUG(10, ("\thInstance = %lx\n",(p16)->hInstance));
  2692. LOGDEBUG(10, ("\trgbResult = %lx\n",(p16)->rgbResult));
  2693. LOGDEBUG(10, ("\tlpCustColors = %lx\n",(p16)->lpCustColors));
  2694. LOGDEBUG(10, ("\tFlags = %lx\n",(p16)->Flags));
  2695. LOGDEBUG(10, ("\tlCustData = %lx\n",(p16)->lCustData));
  2696. LOGDEBUG(10, ("\tlpfnHook = %lx\n",(p16)->lpfnHook));
  2697. LOGDEBUG(10, ("\tlpTemplateName = %lx\n",(p16)->lpTemplateName));
  2698. }
  2699. }
  2700. void WCDDumpCHOOSECOLORData32(CHOOSECOLOR *p32)
  2701. {
  2702. if (fLogFilter & FILTER_COMMDLG) {
  2703. LOGDEBUG(10, ("CHOOSECOLORDATA32:\n"));
  2704. LOGDEBUG(10, ("\tlStructSize = %x\n",(p32)->lStructSize));
  2705. LOGDEBUG(10, ("\thwndOwner = %lx\n",(p32)->hwndOwner));
  2706. LOGDEBUG(10, ("\thInstance = %lx\n",(p32)->hInstance));
  2707. LOGDEBUG(10, ("\trgbResult = %lx\n",(p32)->rgbResult));
  2708. LOGDEBUG(10, ("\tlpCustColors = %lx\n",(p32)->lpCustColors));
  2709. LOGDEBUG(10, ("\tFlags = %lx\n",(p32)->Flags));
  2710. LOGDEBUG(10, ("\tlCustData = %lx\n",(p32)->lCustData));
  2711. LOGDEBUG(10, ("\tlpfnHook = %lx\n",(p32)->lpfnHook));
  2712. LOGDEBUG(10, ("\tlpTemplateName = %lx\n",(p32)->lpTemplateName));
  2713. }
  2714. }
  2715. void WCDDumpCHOOSEFONTData16(PCHOOSEFONTDATA16 p16)
  2716. {
  2717. if (fLogFilter & FILTER_COMMDLG) {
  2718. LOGDEBUG(10, ("CHOOSEFONT16:\n"));
  2719. LOGDEBUG(10, ("\tlStructSize = %lx\n",(p16)->lStructSize));
  2720. LOGDEBUG(10, ("\thwndOwner = %lx\n",(p16)->hwndOwner));
  2721. LOGDEBUG(10, ("\thDC = %lx\n",(p16)->hDC));
  2722. LOGDEBUG(10, ("\tlpLogFont = %lx\n",(p16)->lpLogFont));
  2723. LOGDEBUG(10, ("\tiPointSize = %x\n",(p16)->iPointSize));
  2724. LOGDEBUG(10, ("\tiFlags = %lx\n",(p16)->Flags));
  2725. LOGDEBUG(10, ("\trbgColors = %lx\n",(p16)->rgbColors));
  2726. LOGDEBUG(10, ("\tlCustData = %lx\n",(p16)->lCustData));
  2727. LOGDEBUG(10, ("\tlpfnHook = %lx\n",(p16)->lpfnHook));
  2728. LOGDEBUG(10, ("\tlpTemplateName= %lx\n",(p16)->lpTemplateName));
  2729. LOGDEBUG(10, ("\thInstance = %lx\n",(p16)->hInstance));
  2730. LOGDEBUG(10, ("\tlpszStyle = %lx\n",(p16)->lpszStyle));
  2731. LOGDEBUG(10, ("\tnFontType = %x\n",(p16)->nFontType));
  2732. LOGDEBUG(10, ("\tnSizeMin = %x\n",(p16)->nSizeMin));
  2733. LOGDEBUG(10, ("\tnSizeMax = %x\n",(p16)->nSizeMax));
  2734. }
  2735. }
  2736. void WCDDumpCHOOSEFONTData32(CHOOSEFONT *p32)
  2737. {
  2738. if (fLogFilter & FILTER_COMMDLG) {
  2739. LOGDEBUG(10, ("CHOOSEFONT32:\n"));
  2740. LOGDEBUG(10, ("\tlStructSize = %lx\n",(p32)->lStructSize));
  2741. LOGDEBUG(10, ("\thwndOwner = %lx\n",(p32)->hwndOwner));
  2742. LOGDEBUG(10, ("\thDC = %lx\n",(p32)->hDC));
  2743. LOGDEBUG(10, ("\tlpLogFont = %lx\n",(p32)->lpLogFont));
  2744. LOGDEBUG(10, ("\tiPointSize = %lx\n",(p32)->iPointSize));
  2745. LOGDEBUG(10, ("\tiFlags = %lx\n",(p32)->Flags));
  2746. LOGDEBUG(10, ("\trbgColors = %lx\n",(p32)->rgbColors));
  2747. LOGDEBUG(10, ("\tlCustData = %lx\n",(p32)->lCustData));
  2748. LOGDEBUG(10, ("\tlpfnHook = %lx\n",(p32)->lpfnHook));
  2749. LOGDEBUG(10, ("\tlpTemplateName= %lx\n",(p32)->lpTemplateName));
  2750. LOGDEBUG(10, ("\thInstance = %lx\n",(p32)->hInstance));
  2751. LOGDEBUG(10, ("\tlpszStyle = %lx\n",(p32)->lpszStyle));
  2752. LOGDEBUG(10, ("\tnFontType = %x\n",(p32)->nFontType));
  2753. LOGDEBUG(10, ("\tnSizeMin = %lx\n",(p32)->nSizeMin));
  2754. LOGDEBUG(10, ("\tnSizeMax = %lx\n",(p32)->nSizeMax));
  2755. }
  2756. }
  2757. void WCDDumpFINDREPLACE16(PFINDREPLACE16 p16)
  2758. {
  2759. if (fLogFilter & FILTER_COMMDLG) {
  2760. LOGDEBUG(10, ("FINDREPLACE16:\n"));
  2761. LOGDEBUG(10, ("\tlStructSize = %lx\n",(p16)->lStructSize));
  2762. LOGDEBUG(10, ("\thwndOwner = %x\n",(p16)->hwndOwner));
  2763. LOGDEBUG(10, ("\thInstance = %x\n",(p16)->hInstance));
  2764. LOGDEBUG(10, ("\tFlags = %x\n",(p16)->Flags));
  2765. LOGDEBUG(10, ("\tlpstrFindWhat = %lx\n",(p16)->lpstrFindWhat));
  2766. LOGDEBUG(10, ("\tlpstrReplaceWith = %lx\n",(p16)->lpstrReplaceWith));
  2767. LOGDEBUG(10, ("\twFindWhatLen = %x\n",(p16)->wFindWhatLen));
  2768. LOGDEBUG(10, ("\twReplaceWithLen = %x\n",(p16)->wReplaceWithLen));
  2769. LOGDEBUG(10, ("\tlCustData = %lx\n",(p16)->lCustData));
  2770. LOGDEBUG(10, ("\tlpfnHook = %lx\n",(p16)->lpfnHook));
  2771. LOGDEBUG(10, ("\tlpTemplateName= %lx\n",(p16)->lpTemplateName));
  2772. }
  2773. }
  2774. void WCDDumpFINDREPLACE32(FINDREPLACE *p32)
  2775. {
  2776. if (fLogFilter & FILTER_COMMDLG) {
  2777. LOGDEBUG(10, ("FINDREPLACE32:\n"));
  2778. LOGDEBUG(10, ("\tlStructSize = %lx\n",(p32)->lStructSize));
  2779. LOGDEBUG(10, ("\thwndOwner = %x\n",(p32)->hwndOwner));
  2780. LOGDEBUG(10, ("\thInstance = %x\n",(p32)->hInstance));
  2781. LOGDEBUG(10, ("\tFlags = %x\n",(p32)->Flags));
  2782. LOGDEBUG(10, ("\tlpstrFindWhat = %s\n",(p32)->lpstrFindWhat));
  2783. LOGDEBUG(10, ("\tlpstrReplaceWith = %s\n",(p32)->lpstrReplaceWith));
  2784. LOGDEBUG(10, ("\twFindWhatLen = %x\n",(p32)->wFindWhatLen));
  2785. LOGDEBUG(10, ("\twReplaceWithLen = %x\n",(p32)->wReplaceWithLen));
  2786. LOGDEBUG(10, ("\tlCustData = %lx\n",(p32)->lCustData));
  2787. LOGDEBUG(10, ("\tlpfnHook = %lx\n",(p32)->lpfnHook));
  2788. LOGDEBUG(10, ("\tlpTemplateName= %lx\n",(p32)->lpTemplateName));
  2789. }
  2790. }
  2791. void WCDDumpOPENFILENAME16(POPENFILENAME16 p16)
  2792. {
  2793. if (fLogFilter & FILTER_COMMDLG) {
  2794. LOGDEBUG(10, ("OPENFILENAME16:\n"));
  2795. LOGDEBUG(10, ("\tlStructSize = %x\n",(p16)->lStructSize));
  2796. LOGDEBUG(10, ("\thwndOwner = %lx\n",(p16)->hwndOwner));
  2797. LOGDEBUG(10, ("\thInstance = %lx\n",(p16)->hInstance));
  2798. LOGDEBUG(10, ("\tlpstrFilter = %lx\n",(p16)->lpstrFilter));
  2799. LOGDEBUG(10, ("\tlpstrCustomFilter= %lx\n",(p16)->lpstrCustomFilter));
  2800. LOGDEBUG(10, ("\tnMaxCustFilter = %lx\n",(p16)->nMaxCustFilter));
  2801. LOGDEBUG(10, ("\tnFilterIndex = %lx\n",(p16)->nFilterIndex));
  2802. LOGDEBUG(10, ("\tlpstrFile = %lx\n",(p16)->lpstrFile));
  2803. LOGDEBUG(10, ("\tnMaxFile = %lx\n",(p16)->nMaxFile));
  2804. LOGDEBUG(10, ("\tlpstrFileTitle = %lx\n",(p16)->lpstrFileTitle));
  2805. LOGDEBUG(10, ("\tnMaxFileTitle = %lx\n",(p16)->nMaxFileTitle));
  2806. LOGDEBUG(10, ("\tlpstrInitialDir = %lx\n",(p16)->lpstrInitialDir));
  2807. LOGDEBUG(10, ("\tlpstrTitle = %lx\n",(p16)->lpstrTitle));
  2808. LOGDEBUG(10, ("\tFlags = %lx\n",(p16)->Flags));
  2809. LOGDEBUG(10, ("\tnFileOffset = %lx\n",(p16)->nFileOffset));
  2810. LOGDEBUG(10, ("\tnFileExtension = %lx\n",(p16)->nFileExtension));
  2811. LOGDEBUG(10, ("\tlpstrDefExt = %lx\n",(p16)->lpstrDefExt));
  2812. LOGDEBUG(10, ("\tlCustData = %lx\n",(p16)->lCustData));
  2813. LOGDEBUG(10, ("\tlpfnHook = %lx\n",(p16)->lpfnHook));
  2814. LOGDEBUG(10, ("\tlpTemplateName = %lx\n",(p16)->lpTemplateName));
  2815. }
  2816. }
  2817. void WCDDumpOPENFILENAME32(OPENFILENAME *p32)
  2818. {
  2819. if (fLogFilter & FILTER_COMMDLG) {
  2820. LOGDEBUG(10, ("OPENFILENAME32:\n"));
  2821. LOGDEBUG(10, ("\tlStructSize = %x\n",(p32)->lStructSize));
  2822. LOGDEBUG(10, ("\thwndOwner = %lx\n",(p32)->hwndOwner));
  2823. LOGDEBUG(10, ("\thInstance = %lx\n",(p32)->hInstance));
  2824. LOGDEBUG(10, ("\tlpstrFilter = %s\n",(p32)->lpstrFilter));
  2825. LOGDEBUG(10, ("\tlpstrCustomFilter= %s\n",(p32)->lpstrCustomFilter));
  2826. LOGDEBUG(10, ("\tnMaxCustFilter = %lx\n",(p32)->nMaxCustFilter));
  2827. LOGDEBUG(10, ("\tnFilterIndex = %lx\n",(p32)->nFilterIndex));
  2828. LOGDEBUG(10, ("\tlpstrFile = %s\n",(p32)->lpstrFile));
  2829. LOGDEBUG(10, ("\tnMaxFile = %lx\n",(p32)->nMaxFile));
  2830. LOGDEBUG(10, ("\tlpstrFileTitle = %s\n",(p32)->lpstrFileTitle));
  2831. LOGDEBUG(10, ("\tnMaxFileTitle = %lx\n",(p32)->nMaxFileTitle));
  2832. LOGDEBUG(10, ("\tlpstrInitialDir = %s\n",(p32)->lpstrInitialDir));
  2833. LOGDEBUG(10, ("\tlpstrTitle = %s\n",(p32)->lpstrTitle));
  2834. LOGDEBUG(10, ("\tFlags = %lx\n",(p32)->Flags));
  2835. LOGDEBUG(10, ("\tnFileOffset = %lx\n",(p32)->nFileOffset));
  2836. LOGDEBUG(10, ("\tnFileExtension = %lx\n",(p32)->nFileExtension));
  2837. LOGDEBUG(10, ("\tlpstrDefExt = %s\n",(p32)->lpstrDefExt));
  2838. LOGDEBUG(10, ("\tlCustData = %lx\n",(p32)->lCustData));
  2839. LOGDEBUG(10, ("\tlpfnHook = %lx\n",(p32)->lpfnHook));
  2840. LOGDEBUG(10, ("\tlpTemplateName = %lx\n",(p32)->lpTemplateName));
  2841. }
  2842. }
  2843. void WCDDumpPRINTDLGData16(PPRINTDLGDATA16 p16)
  2844. {
  2845. if (fLogFilter & FILTER_COMMDLG) {
  2846. LOGDEBUG(10, ("PRINTDLGData16:\n"));
  2847. LOGDEBUG(10, ("\tlStructSize = %x\n",(p16)->lStructSize));
  2848. LOGDEBUG(10, ("\thwndOwner = %lx\n",(p16)->hwndOwner));
  2849. LOGDEBUG(10, ("\thDevMode = %lx\n",(p16)->hDevMode));
  2850. LOGDEBUG(10, ("\thDevNames = %lx\n",(p16)->hDevNames));
  2851. LOGDEBUG(10, ("\thDC = %lx\n",(p16)->hDC));
  2852. LOGDEBUG(10, ("\tFlags = %lx\n",(p16)->Flags));
  2853. LOGDEBUG(10, ("\tnFromPage = %d\n",(p16)->nFromPage));
  2854. LOGDEBUG(10, ("\tnToPage = %d\n",(p16)->nToPage));
  2855. LOGDEBUG(10, ("\tnMinPage = %d\n",(p16)->nMinPage));
  2856. LOGDEBUG(10, ("\tnMaxPage = %d\n",(p16)->nMaxPage));
  2857. LOGDEBUG(10, ("\tnCopies = %d\n",(p16)->nCopies));
  2858. LOGDEBUG(10, ("\thInstance = %lx\n",(p16)->hInstance));
  2859. LOGDEBUG(10, ("\tlCustData = %lx\n",(p16)->lCustData));
  2860. LOGDEBUG(10, ("\tlpfnPrintHook = %lx\n",(p16)->lpfnPrintHook));
  2861. LOGDEBUG(10, ("\tlpfnSetupHook = %lx\n",(p16)->lpfnSetupHook));
  2862. LOGDEBUG(10, ("\tlpPrintTemplateName = %lx\n",(p16)->lpPrintTemplateName));
  2863. LOGDEBUG(10, ("\tlpSetupTemplateName = %lx\n",(p16)->lpSetupTemplateName));
  2864. LOGDEBUG(10, ("\thPrintTemplate = %lx\n",(p16)->hPrintTemplate));
  2865. LOGDEBUG(10, ("\thSetupTemplate = %lx\n",(p16)->hSetupTemplate));
  2866. }
  2867. }
  2868. void WCDDumpPRINTDLGData32(PRINTDLG *p32)
  2869. {
  2870. if (fLogFilter & FILTER_COMMDLG) {
  2871. LOGDEBUG(10, ("PRINTDLGData32:\n"));
  2872. LOGDEBUG(10, ("\tlStructSize = %x\n",(p32)->lStructSize));
  2873. LOGDEBUG(10, ("\thwndOwner = %lx\n",(p32)->hwndOwner));
  2874. LOGDEBUG(10, ("\thDevMode = %lx\n",(p32)->hDevMode));
  2875. LOGDEBUG(10, ("\thDevNames = %lx\n",(p32)->hDevNames));
  2876. LOGDEBUG(10, ("\thDC = %lx\n",(p32)->hDC));
  2877. LOGDEBUG(10, ("\tFlags = %lx\n",(p32)->Flags));
  2878. LOGDEBUG(10, ("\tnFromPage = %d\n",(p32)->nFromPage));
  2879. LOGDEBUG(10, ("\tnToPage = %d\n",(p32)->nToPage));
  2880. LOGDEBUG(10, ("\tnMinPage = %d\n",(p32)->nMinPage));
  2881. LOGDEBUG(10, ("\tnMaxPage = %d\n",(p32)->nMaxPage));
  2882. LOGDEBUG(10, ("\tnCopies = %d\n",(p32)->nCopies));
  2883. LOGDEBUG(10, ("\thInstance = %lx\n",(p32)->hInstance));
  2884. LOGDEBUG(10, ("\tlCustData = %lx\n",(p32)->lCustData));
  2885. LOGDEBUG(10, ("\tlpfnPrintHook = %lx\n",(p32)->lpfnPrintHook));
  2886. LOGDEBUG(10, ("\tlpfnSetupHook = %lx\n",(p32)->lpfnSetupHook));
  2887. LOGDEBUG(10, ("\tlpPrintTemplateName = %lx\n",(p32)->lpPrintTemplateName));
  2888. LOGDEBUG(10, ("\tlpSetupTemplateName = %lx\n",(p32)->lpSetupTemplateName));
  2889. LOGDEBUG(10, ("\thPrintTemplate = %lx\n",(p32)->hPrintTemplate));
  2890. LOGDEBUG(10, ("\thSetupTemplate = %lx\n",(p32)->hSetupTemplate));
  2891. }
  2892. }
  2893. #endif // DEBUG