windows-nt/Source/XPSP1/NT/base/mvdm/wow32/wcommdlg.c
2020-09-26 16:20:57 +08:00

3875 lines
114 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*++
Copyright (c) 1992 Microsoft Corporation
Module Name:
wcomdlg.c
Abstract:
32-bit support for thunking COMMDLG in WOW
Author:
John Vert (jvert) 31-Dec-1992
Revision History:
John Vert (jvert) 31-Dec-1992
created
--*/
#include "precomp.h"
#pragma hdrstop
#include <cderr.h>
#include <dlgs.h>
#include <wowcmndg.h>
MODNAME(wcommdlg.c);
//
// Debugging stuff...
//
#if DEBUG
void WCDDumpCHOOSECOLORData16(PCHOOSECOLORDATA16 p16);
void WCDDumpCHOOSECOLORData32(CHOOSECOLOR *p32);
void WCDDumpCHOOSEFONTData16(PCHOOSEFONTDATA16 p16);
void WCDDumpCHOOSEFONTData32(CHOOSEFONT *p32);
void WCDDumpFINDREPLACE16(PFINDREPLACE16 p16);
void WCDDumpFINDREPLACE32(FINDREPLACE *p32);
void WCDDumpOPENFILENAME16(POPENFILENAME16 p16);
void WCDDumpOPENFILENAME32(OPENFILENAME *p32);
void WCDDumpPRINTDLGData16(PPRINTDLGDATA16 p16);
void WCDDumpPRINTDLGData32(PRINTDLG *p32);
// macros to dump the 16 & 32 bit structs
#define WCDDUMPCHOOSECOLORDATA16(p16) WCDDumpCHOOSECOLORData16(p16)
#define WCDDUMPCHOOSECOLORDATA32(p32) WCDDumpCHOOSECOLORData32(p32)
#define WCDDUMPCHOOSEFONTDATA16(p16) WCDDumpCHOOSEFONTData16(p16)
#define WCDDUMPCHOOSEFONTDATA32(p32) WCDDumpCHOOSEFONTData32(p32)
#define WCDDUMPFINDREPLACE16(p16) WCDDumpFINDREPLACE16(p16)
#define WCDDUMPFINDREPLACE32(p32) WCDDumpFINDREPLACE32(p32)
#define WCDDUMPOPENFILENAME16(p16) WCDDumpOPENFILENAME16(p16)
#define WCDDUMPOPENFILENAME32(p32) WCDDumpOPENFILENAME32(p32)
#define WCDDUMPPRINTDLGDATA16(p16) WCDDumpPRINTDLGData16(p16)
#define WCDDUMPPRINTDLGDATA32(p32) WCDDumpPRINTDLGData32(p32)
#else // !DEBUG
#define WCDDUMPCHOOSECOLORDATA16(p16)
#define WCDDUMPCHOOSECOLORDATA32(p32)
#define WCDDUMPCHOOSEFONTDATA16(p16)
#define WCDDUMPCHOOSEFONTDATA32(p32)
#define WCDDUMPOPENFILENAME16(p16)
#define WCDDUMPOPENFILENAME32(p32)
#define WCDDUMPPRINTDLGDATA16(p16)
#define WCDDUMPPRINTDLGDATA32(p32)
#define WCDDUMPFINDREPLACE16(p16)
#define WCDDUMPFINDREPLACE32(p32)
#endif // !DEBUG
// global data
WORD msgCOLOROK = 0;
WORD msgFILEOK = 0;
WORD msgWOWLFCHANGE = 0;
WORD msgWOWDIRCHANGE = 0;
WORD msgWOWCHOOSEFONT = 0;
WORD msgSHAREVIOLATION = 0;
WORD msgFINDREPLACE = 0;
/* external global stuff */
extern WORD gwKrnl386CodeSeg1;
extern WORD gwKrnl386CodeSeg2;
extern WORD gwKrnl386CodeSeg3;
extern WORD gwKrnl386DataSeg1;
ULONG dwExtError = 0;
#define SETEXTENDEDERROR(Code) (dwExtError=Code)
/*+++ For reference only -- which flags are set on output
#define FR_OUTPUTFLAGS (FR_DOWN | FR_WHOLEWORD | FR_MATCHCASE | \
FR_FINDNEXT | FR_REPLACE | FR_REPLACEALL | \
FR_DIALOGTERM | FR_SHOWHELP | FR_NOUPDOWN | \
FR_NOMATCHCASE | FR_NOWHOLEWORD | FR_HIDEUPDOWN | \
FR_HIDEMATCHCASE | FR_HIDEWHOLEWORD)
#define PD_OUTPUTFLAGS (PD_ALLPAGES | PD_COLLATE | PD_PAGENUMS | \
PD_PRINTTOFILE | PD_SELECTION)
#define FO_OUTPUTFLAGS (OFN_READONLY | OFN_EXTENSIONDIFFERENT)
#define CF_OUTPUTFLAGS (CF_NOFACESEL | CF_NOSIZESEL | CF_NOSTYLESEL)
---*/
// private typedefs and structs
typedef BOOL (APIENTRY* FILENAMEPROC)(LPOPENFILENAME);
typedef HWND (APIENTRY* FINDREPLACEPROC)(LPFINDREPLACE);
// exported by comdlg32.dll to allow us to ultimately keep 16-bit common dialog
// structs in sync with the UNICODE version maintained by comdlg32.
extern VOID Ssync_ANSI_UNICODE_Struct_For_WOW(HWND hDlg,
BOOL fANSI_To_UNICODE,
DWORD dwID);
// private function prototypes
VOID
Thunk_OFNstrs16to32(IN OPENFILENAME *pOFN32,
IN POPENFILENAME16 pOFN16);
BOOL
Alloc_OFN32_strs(IN OPENFILENAME *pOFN32,
IN POPENFILENAME16 pOFN16);
VOID
Free_OFN32_strs(IN OPENFILENAME *pOFN32);
PCOMMDLGTD
GetCommdlgTd(IN HWND Hwnd32);
HINSTANCE
ThunkCDTemplate16to32(IN HAND16 hInst16,
IN DWORD hPrintTemp16,
IN VPVOID vpTemplateName,
IN DWORD dwFlags16,
IN OUT DWORD *pFlags,
IN DWORD ETFlag,
IN DWORD ETHFlag,
OUT PPRES pRes,
OUT PBOOL fError);
VOID
FreeCDTemplate32(IN PRES pRes,
IN HINSTANCE hInst,
IN BOOL bETFlag,
IN BOOL bETHFlag);
PRES
GetTemplate16(IN HAND16 hInstance,
IN VPCSTR TemplateName,
IN BOOLEAN UseHandle);
HGLOBAL
ThunkhDevMode16to32(IN HAND16 hDevMode16);
VOID
ThunkhDevMode32to16(IN OUT HAND16 *phDevMode16,
IN HANDLE hDevMode32);
HANDLE
ThunkhDevNames16to32(IN HAND16 hDevNames16);
VOID
ThunkhDevNames32to16(IN OUT HAND16 *phDevNames16,
IN HANDLE hDevNames);
VOID
ThunkCHOOSECOLOR16to32(OUT CHOOSECOLOR *pCC32,
IN PCHOOSECOLORDATA16 pCC16);
VOID
ThunkCHOOSECOLOR32to16(OUT PCHOOSECOLORDATA16 pCC16,
IN CHOOSECOLOR *pCC32);
VOID
ThunkCHOOSEFONT16to32(OUT CHOOSEFONT *pCF32,
IN PCHOOSEFONTDATA16 pCF16);
VOID
ThunkCHOOSEFONT32to16(OUT PCHOOSEFONTDATA16 pCF16,
IN CHOOSEFONT *pCF32);
VOID
ThunkFINDREPLACE16to32(OUT FINDREPLACE *pFR32,
IN PFINDREPLACE16 pFR16);
VOID
ThunkFINDREPLACE32to16(OUT PFINDREPLACE16 pFR16,
IN FINDREPLACE *pFR32);
BOOL
ThunkOPENFILENAME16to32(OUT OPENFILENAME *pOFN32,
IN POPENFILENAME16 pOFN16);
VOID
ThunkOPENFILENAME32to16(OUT POPENFILENAME16 pOFN16,
IN OPENFILENAME *pOFN32,
IN BOOLEAN bUpperStrings);
VOID
ThunkPRINTDLG16to32(OUT PRINTDLG *pPD32,
IN PPRINTDLGDATA16 pPD16);
VOID
ThunkPRINTDLG32to16(IN VPVOID vppd,
OUT PRINTDLG *pPD32);
VOID
ThunkCDStruct16to32(IN HWND hDlg,
IN CHOOSECOLOR *pCC,
IN VPVOID vp);
VOID
ThunkCDStruct32to16(IN HWND hDlg,
IN VPVOID vp,
IN CHOOSECOLOR *pCC);
UINT APIENTRY
WCD32CommonDialogProc(HWND hdlg,
UINT uMsg,
WPARAM uParam,
LPARAM lParam,
PCOMMDLGTD pCTD,
VPVOID vpfnHook);
UINT APIENTRY
WCD32PrintSetupDialogProc(HWND hdlg,
UINT uMsg,
WPARAM uParam,
LPARAM lParam);
UINT APIENTRY
WCD32DialogProc(HWND hdlg,
UINT uMsg,
WPARAM uParam,
LPARAM lParam);
ULONG
WCD32GetFileName(IN PVDMFRAME pFrame,
IN FILENAMEPROC Function);
ULONG
WCD32FindReplaceText(IN PVDMFRAME pFrame,
IN FINDREPLACEPROC Function);
UINT APIENTRY
WCD32FindReplaceDialogProc(HWND hdlg,
UINT uMsg,
WPARAM uParam,
LPARAM lParam);
#define VALID_OFN16_FLAGS (OFN_READONLY | \
OFN_OVERWRITEPROMPT | \
OFN_HIDEREADONLY | \
OFN_NOCHANGEDIR | \
OFN_SHOWHELP | \
OFN_ENABLEHOOK | \
OFN_ENABLETEMPLATE | \
OFN_ENABLETEMPLATEHANDLE | \
OFN_NOVALIDATE | \
OFN_ALLOWMULTISELECT | \
OFN_EXTENSIONDIFFERENT | \
OFN_PATHMUSTEXIST | \
OFN_FILEMUSTEXIST | \
OFN_CREATEPROMPT | \
OFN_SHAREAWARE | \
OFN_NOREADONLYRETURN | \
OFN_NOTESTFILECREATE)
//
// unique message thunks
//
// This function thunks the private messages
// msgCOLOROK
BOOL FASTCALL
WM32msgCOLOROK(LPWM32MSGPARAMEX lpwm32mpex)
{
LPCHOOSECOLOR pCC32;
PCHOOSECOLORDATA16 pCC16;
GETVDMPTR((VPVOID)lpwm32mpex->Parm16.WndProc.lParam,
sizeof(CHOOSECOLORDATA16),
pCC16);
pCC32 = (LPCHOOSECOLOR)lpwm32mpex->lParam;
if(pCC16 && pCC32) {
if(lpwm32mpex->fThunk) {
ThunkCHOOSECOLOR32to16(pCC16, pCC32);
}
else {
ThunkCHOOSECOLOR16to32(pCC32, pCC16);
}
}
else {
return(FALSE);
}
FREEVDMPTR(pCC16);
return (TRUE);
}
// This function thunks the private messages
// msgFILEOK
BOOL FASTCALL
WM32msgFILEOK(LPWM32MSGPARAMEX lpwm32mpex)
{
VPOPENFILENAME vpof;
POPENFILENAME16 pOFN16;
OPENFILENAME *pOFN32;
vpof = (VPOPENFILENAME)(GetCommdlgTd(lpwm32mpex->hwnd)->vpData);
pOFN32 = (OPENFILENAME *)lpwm32mpex->lParam;
//
// Approach sends its own fileok message when you click on its
// secret listbox that it displays over lst1 sometimes. It
// sends NULL for the LPARAM instead of the address of the
// openfilename structure.
if(pOFN32 == NULL) {
lpwm32mpex->Parm16.WndProc.lParam = (LPARAM)NULL;
return(TRUE);
}
GETVDMPTR(vpof, sizeof(OPENFILENAME16), pOFN16);
if (lpwm32mpex->fThunk) {
UpdateDosCurrentDirectory(DIR_NT_TO_DOS);
lpwm32mpex->Parm16.WndProc.lParam = (LPARAM)vpof;
// sudeepb 12-Mar-1996
//
// The selected file name needs to be uppercased for
// apps like symanatec QA 4.0. So changed the following parameter
// in ThunkOpenFileName from FALSE to TRUE.
ThunkOPENFILENAME32to16(pOFN16, pOFN32, TRUE);
} else {
ThunkOPENFILENAME16to32(pOFN32, pOFN16);
}
FREEVDMPTR(pOFN16);
return (TRUE);
}
// This function thunks the private messages
// msgWOWDIRCHANGE
BOOL FASTCALL
WM32msgWOWDIRCHANGE(LPWM32MSGPARAMEX lpwm32mpex)
{
if (lpwm32mpex->fThunk) {
UpdateDosCurrentDirectory(DIR_NT_TO_DOS);
}
return (TRUE);
}
// This function thunks the private message
// msgWOWLFCHANGE
BOOL FASTCALL
WM32msgWOWLFCHANGE(LPWM32MSGPARAMEX lpwm32mpex)
{
VPCHOOSEFONTDATA vpcf;
PCHOOSEFONTDATA16 pCF16;
vpcf = (VPCHOOSEFONTDATA)(GetCommdlgTd(lpwm32mpex->hwnd)->vpData);
GETVDMPTR(vpcf, sizeof(CHOOSEFONTDATA16), pCF16);
WOW32ASSERT(pCF16);
if (lpwm32mpex->fThunk) {
PUTLOGFONT16(DWORD32(pCF16->lpLogFont),
sizeof(LOGFONT),
(LPLOGFONT)lpwm32mpex->lParam);
}
FREEVDMPTR(pCF16);
return(TRUE);
}
// This function thunks the private message
// msgSHAREVIOLATION
BOOL FASTCALL
WM32msgSHAREVIOLATION(LPWM32MSGPARAMEX lpwm32mpex)
{
INT cb;
PLONG plParamNew = &lpwm32mpex->Parm16.WndProc.lParam;
if (lpwm32mpex->fThunk) {
if (lpwm32mpex->lParam) {
cb = strlen((LPSZ)lpwm32mpex->lParam)+1;
if (!(*plParamNew = malloc16(cb))) {
return(FALSE);
}
putstr16((VPSZ)*plParamNew, (LPSZ)lpwm32mpex->lParam, cb);
}
} else {
if (*plParamNew) {
free16((VPVOID) *plParamNew);
}
}
return (TRUE);
}
// This function thunks the private messages
// WM_CHOOSEFONT_GETLOGFONT
BOOL FASTCALL
WM32msgCHOOSEFONTGETLOGFONT(LPWM32MSGPARAMEX lpwm32mpex)
{
LOGFONT LogFont32;
// The mere fact that we access the buffer after allowing the 16-bit
// hook proc to step in breaks Serif PagePlus app which wants it's
// hook proc to always have a shot and commdlg to check the return value.
// If hook proc returns TRUE, no further action is taken
//
// This is the message an app sends the dialog if it wants to find
// out what font is currently selected.
//
// We thunk this by sending yet another hackorama message to comdlg32,
// who will then fill in the 32-bit structure we pass in so we can
// thunk it back to the 16-bit structure. Then we return TRUE so
// comdlg32 doesn't reference the 16-bit logfont.
//
if (!lpwm32mpex->fThunk && !lpwm32mpex->lReturn) {
SendMessage(lpwm32mpex->hwnd, msgWOWCHOOSEFONT, 0, (LPARAM)&LogFont32);
PUTLOGFONT16(lpwm32mpex->lParam, sizeof(LOGFONT), &LogFont32);
lpwm32mpex->lReturn = TRUE;
}
return (TRUE);
}
//
// Dialog callback hook thunks
//
UINT APIENTRY
WCD32DialogProc(HWND hdlg,
UINT uMsg,
WPARAM uParam,
LPARAM lParam)
/*++
Routine Description:
This is the hook proc used by ChooseColor, ChooseFont, GetOpenFileName,
GetSaveFileName, and PrintDlg. It pulls the 16-bit callback
out of the thread data and calls the common dialog proc to do
the rest of the work.
--*/
{
PCOMMDLGTD Td;
Td = GetCommdlgTd(hdlg);
if(Td) {
return(WCD32CommonDialogProc(hdlg,
uMsg,
uParam,
lParam,
Td,
Td->vpfnHook));
} else {
return(0);
}
}
UINT APIENTRY
WCD32PrintSetupDialogProc(HWND hdlg,
UINT uMsg,
WPARAM uParam,
LPARAM lParam)
/*++
Routine Description:
This is the hook proc used by PrintSetup. It is only used when
the Setup button on the Print dialog directly creates the PrintSetup
dialog. We find the correct TD by looking for the TD of our owner
window (which is the print dialog)
It calls the common dialog proc to do the rest of the work.
--*/
{
PCOMMDLGTD pTD;
pTD = CURRENTPTD()->CommDlgTd;
if(pTD) {
while (pTD->SetupHwnd != GETHWND16(hdlg)) {
pTD = pTD->Previous;
if(!pTD) {
WOW32ASSERT(FALSE);
return(0);
}
}
return(WCD32CommonDialogProc(hdlg,
uMsg,
uParam,
lParam,
pTD,
pTD->vpfnSetupHook));
} else {
return(0);
}
}
UINT APIENTRY
WCD32FindReplaceDialogProc(HWND hdlg,
UINT uMsg,
WPARAM uParam,
LPARAM lParam)
/*++
Routine Description:
This is the hook proc used by FindText and ReplaceText. It does cleanup
on WM_DESTROY and calls WCD32CommonDialogProc to handle the 16-bit
dialog hook callback on all messages, if needed.
--*/
{
PFINDREPLACE16 pFR16;
VPFINDREPLACE vpfr;
LPFINDREPLACE pFR32;
PCOMMDLGTD ptdDlg;
PCOMMDLGTD ptdOwner;
UINT uRet = FALSE;
// If the ptdDlg is invalid, do nothing.
ptdDlg = GetCommdlgTd(hdlg);
if (ptdDlg == NULL) {
return(uRet);
}
if (uMsg != WM_DESTROY) {
// this will be FALSE if the app didn't specify a 16-bit hookproc
// we always set the 32-bit hookproc in ThunkFINDREPLACE16to32()
if (ptdDlg->vpfnHook) {
uRet = WCD32CommonDialogProc(hdlg,
uMsg,
uParam,
lParam,
ptdDlg,
ptdDlg->vpfnHook);
}
}
else {
pFR32 = (LPFINDREPLACE)ptdDlg->pData32;
// UnLink both per thread data structs from the list.
ptdOwner = GetCommdlgTd(pFR32->hwndOwner);
CURRENTPTD()->CommDlgTd = ptdDlg->Previous;
WOW32ASSERT(ptdOwner->Previous == ptdDlg);
vpfr = ptdDlg->vpData;
GETVDMPTR(vpfr, sizeof(FINDREPLACE16), pFR16);
// CleanUp template if used.
FreeCDTemplate32((PRES)ptdDlg->pRes,
pFR32->hInstance,
DWORD32(pFR16->Flags) & FR_ENABLETEMPLATE,
DWORD32(pFR16->Flags) & FR_ENABLETEMPLATEHANDLE);
FREEVDMPTR(pFR16);
// Free the per thread data structs.
free_w(ptdDlg);
free_w(ptdOwner);
// Free the 32-bit FINDREPLACE structure.
free_w(pFR32->lpstrFindWhat);
free_w(pFR32->lpstrReplaceWith);
free_w(pFR32);
}
if (uMsg == WM_INITDIALOG) {
// Force COMDLG32!FindReplaceDialogProc to handle WM_INITDIALOG.
uRet = TRUE;
}
return(uRet);
}
UINT APIENTRY
WCD32CommonDialogProc(HWND hdlg,
UINT uMsg,
WPARAM uParam,
LPARAM lParam,
PCOMMDLGTD pCTD,
VPVOID vpfnHook)
/*++
Routine Description:
This thunks the 32-bit dialog callback into a 16-bit callback
This is the common code used by all the dialog callback thunks that
actually calls the 16-bit callback.
--*/
{
BOOL fSuccess;
LPFNM32 pfnThunkMsg;
WM32MSGPARAMEX wm32mpex;
BOOL fMessageNeedsThunking;
// If the app has GP Faulted we don't want to pass it any more input
// This should be removed when USER32 does clean up on task death so
// it doesn't call us - mattfe june 24 92
// LOGDEBUG(10, ("CommonDialogProc In: %lX %X %X %lX\n",
// (DWORD)hdlg,
// uMsg,
// uParam,
// lParam));
if(CURRENTPTD()->dwFlags & TDF_IGNOREINPUT) {
LOGDEBUG(6,
(" WCD32OpenFileDialog Ignoring Input Messsage %04X\n",
uMsg));
WOW32ASSERTMSG(gfIgnoreInputAssertGiven,
"WCD32CommonDialogProc: TDF_IGNOREINPUT hack was used, shouldn't be, "
"please email DaveHart with repro instructions. Hit 'g' to ignore "
"this and suppress this assertion from now on.\n");
gfIgnoreInputAssertGiven = TRUE;
goto SilentError;
}
#if DBG
if(pCTD==NULL) {
LOGDEBUG(0,(" WCD32OpenFileDialog ERROR: pCTD==NULL\n"));
goto Error;
}
// If pCTD->vpfnHook is NULL, then something is broken; we
// certainly can't continue because we don't know what 16-bit func to call
if(!vpfnHook) {
LOGDEBUG(0,(" WCD32OpenFileDialog ERROR: no hook proc for message %04x Dlg = %08lx\n", uMsg, hdlg ));
goto Error;
}
#endif
wm32mpex.Parm16.WndProc.hwnd = GETHWND16(hdlg);
wm32mpex.Parm16.WndProc.wMsg = (WORD)uMsg;
wm32mpex.Parm16.WndProc.wParam = (WORD)uParam;
wm32mpex.Parm16.WndProc.lParam = (LONG)lParam;
wm32mpex.Parm16.WndProc.hInst = (WORD)GetWindowLong(hdlg, GWL_HINSTANCE);
// On Win3.1, the app & the system share the ptr to the same structure that
// the app passed to the common dialog API. Therefore, when one side makes
// a change to the struct, the other is aware of the change. This is not
// the case on NT since we thunk the struct into a 32-bit ANSI struct which
// is then thunked into a 32-bit UNICODE struct in the comdlg32 code. We
// attempt to synchronize all these structs by rethunking them for every
// message sent to the 16-bit side & for every API call the app makes.
// See sync code in callback16(), fastwow bopping code, and w32Dispatch().
// ComDlg32 thunks UNICODEtoANSI before calling us & ASNItoUNICODE when we
// return. Ug!!! Apparently a fair number of apps depend on this
// behavior since we've debugged this problem about 6 times to date and
// each time we have put in special hacks for each case. With any luck
// this should be a general fix. 08/97 CMJones
if(uMsg < 0x400) {
LOGDEBUG(3,
("%04X (%s)\n",
CURRENTPTD()->htask16,
(aw32Msg[uMsg].lpszW32)));
pfnThunkMsg = aw32Msg[uMsg].lpfnM32;
if(uMsg == WM_INITDIALOG) {
// The address of the 16-bit structure that the app passed to the
// original common dialog API is passed in lParam in WM_INITDIALOG
// messages in Win 3.1
wm32mpex.Parm16.WndProc.lParam = lParam = (LPARAM)pCTD->vpData;
}
// Check for unique messages
} else if(uMsg >= 0x400) {
if (uMsg == msgFILEOK) {
pfnThunkMsg = WM32msgFILEOK;
} else if(uMsg == msgCOLOROK) {
wm32mpex.Parm16.WndProc.lParam = (LPARAM)pCTD->vpData;
pfnThunkMsg = WM32msgCOLOROK;
} else if(uMsg == msgSHAREVIOLATION) {
pfnThunkMsg = WM32msgSHAREVIOLATION;
} else if(uMsg == msgWOWDIRCHANGE) {
pfnThunkMsg = WM32msgWOWDIRCHANGE;
} else if(uMsg == msgWOWLFCHANGE) {
pfnThunkMsg = WM32msgWOWLFCHANGE;
} else if(pCTD->Flags & WOWCD_ISCHOOSEFONT) {
// special ChooseFont thunks to handle goofy GETLOGFONT message
if(uMsg == WM_CHOOSEFONT_GETLOGFONT) {
pfnThunkMsg = WM32msgCHOOSEFONTGETLOGFONT;
} else if(uMsg == msgWOWCHOOSEFONT) {
//
// no wow app will expect this, so don't send it.
//
return(FALSE);
} else {
pfnThunkMsg = WM32NoThunking;
}
} else {
pfnThunkMsg = WM32NoThunking;
}
}
fMessageNeedsThunking = (pfnThunkMsg != WM32NoThunking);
if(fMessageNeedsThunking) {
wm32mpex.fThunk = THUNKMSG;
wm32mpex.hwnd = hdlg;
wm32mpex.uMsg = uMsg;
wm32mpex.uParam = uParam;
wm32mpex.lParam = lParam;
wm32mpex.pww = NULL;
wm32mpex.lpfnM32 = pfnThunkMsg;
if(!(pfnThunkMsg)(&wm32mpex)) {
LOGDEBUG(LOG_ERROR,(" WCD32OpenFileDialog ERROR: cannot thunk 32-bit message %04x\n", uMsg));
goto Error;
}
} else {
LOGDEBUG(6,("WCD32CommonDialogProc, No Thunking was required for the 32-bit message %s(%04x)\n", (LPSZ)GetWMMsgName(uMsg), uMsg));
}
// this call may cause 16-bit memory to move
// this call will call 32->16 sync code before the callback & the 16->32
// sync upon return from the callback
fSuccess = CallBack16(RET_WNDPROC,
&wm32mpex.Parm16,
vpfnHook,
(PVPVOID)&wm32mpex.lReturn);
// flat ptrs to 16-bit mem are now invalid due to possible memory movement
// the callback function of a dialog is of type FARPROC whose return value
// is of type 'int'. Since dx:ax is copied into lReturn in the above
// CallBack16 call, we need to zero out the hiword, otherwise we will be
// returning an erroneous value.
wm32mpex.lReturn = (LONG)LOWORD(wm32mpex.lReturn);
if(fMessageNeedsThunking) {
wm32mpex.fThunk = UNTHUNKMSG;
(pfnThunkMsg)(&wm32mpex);
}
if(!fSuccess)
goto Error;
Done:
// Uncomment this to receive message on exit
// LOGDEBUG(10, ("CommonDialogProc Out: Return %lX\n", wm32mpex.lReturn));
return wm32mpex.lReturn;
Error:
LOGDEBUG(5,(" WCD32OpenFileDialog WARNING: cannot call back, using default message handling\n"));
SilentError:
wm32mpex.lReturn = 0;
goto Done;
}
ULONG FASTCALL
WCD32ExtendedError( IN PVDMFRAME pFrame )
/*++
Routine Description:
32-bit thunk for CommDlgExtendedError()
Arguments:
pFrame - Supplies 16-bit argument frame
Return Value:
error code to be returned
--*/
{
if (dwExtError != 0) {
return(dwExtError);
}
return(CommDlgExtendedError());
}
ULONG FASTCALL
WCD32ChooseColor(PVDMFRAME pFrame)
/*++
Routine Description:
This routine thunks the 16-bit ChooseColor common dialog to the 32-bit
side.
Arguments:
pFrame - Supplies 16-bit argument frame
Return Value:
16-bit BOOLEAN to be returned.
--*/
{
ULONG ul = GETBOOL16(FALSE);
register PCHOOSECOLOR16 parg16;
VPCHOOSECOLORDATA vpcc;
CHOOSECOLOR CC32;
PCHOOSECOLORDATA16 pCC16;
PRES pRes = NULL;
COMMDLGTD ThreadData;
COLORREF CustColors32[16]; // on stack for DWORD alignment
DWORD dwFlags16;
BOOL fError = FALSE;
GETARGPTR(pFrame, sizeof(CHOOSECOLOR16), parg16);
vpcc = parg16->lpcc;
SETEXTENDEDERROR( 0 );
// invalidate this now
FREEVDMPTR( parg16 );
// initialize unique window message
if (msgCOLOROK == 0) {
if(!(msgCOLOROK = (WORD)RegisterWindowMessage(COLOROKSTRING))) {
SETEXTENDEDERROR( CDERR_REGISTERMSGFAIL );
LOGDEBUG(2,("WCD32ChooseColor:RegisterWindowMessage failed\n"));
return(0);
}
}
GETVDMPTR(vpcc, sizeof(CHOOSECOLORDATA16), pCC16);
WCDDUMPCHOOSECOLORDATA16(pCC16);
if(DWORD32(pCC16->lStructSize) != sizeof(CHOOSECOLORDATA16)) {
SETEXTENDEDERROR( CDERR_STRUCTSIZE );
FREEVDMPTR(pCC16);
return(0);
}
RtlZeroMemory(&ThreadData, sizeof(COMMDLGTD));
ThreadData.Previous = CURRENTPTD()->CommDlgTd;
ThreadData.hdlg = (HWND16)-1;
ThreadData.pData32 = &CC32;
ThreadData.Flags = 0;
if(DWORD32(pCC16->Flags) & CC_ENABLEHOOK) {
ThreadData.vpfnHook = DWORD32(pCC16->lpfnHook);
if(!ThreadData.vpfnHook) {
SETEXTENDEDERROR(CDERR_NOHOOK);
FREEVDMPTR(pCC16);
return(0);
}
ThreadData.vpData = vpcc;
}
else {
STOREDWORD(pCC16->lpfnHook, 0);
}
RtlZeroMemory(&CC32, sizeof(CHOOSECOLOR));
CC32.lpCustColors = CustColors32;
ThunkCHOOSECOLOR16to32(&CC32, pCC16);
dwFlags16 = DWORD32(pCC16->Flags);
// this call invalidates flat ptrs to 16-bit memory
CC32.hInstance = (HWND)ThunkCDTemplate16to32(WORD32(pCC16->hInstance),
0,
DWORD32(pCC16->lpTemplateName),
dwFlags16,
&(CC32.Flags),
CC_ENABLETEMPLATE,
CC_ENABLETEMPLATEHANDLE,
&pRes,
&fError);
if(fError) {
goto ChooseColorExit;
}
// invalidate flat ptrs to 16-bit memory
FREEVDMPTR(pCC16);
WCDDUMPCHOOSECOLORDATA32(&CC32);
// Set this just before the calling into comdlg32. This prevents the
// synchronization stuff from firing until we actually need it.
CURRENTPTD()->CommDlgTd = &ThreadData;
// this call invalidates flat ptrs to 16-bit memory
ul = GETBOOL16(ChooseColor(&CC32));
CURRENTPTD()->CommDlgTd = ThreadData.Previous;
if (ul) {
WCDDUMPCHOOSECOLORDATA32(&CC32);
GETVDMPTR(vpcc, sizeof(CHOOSECOLOR16), pCC16);
ThunkCHOOSECOLOR32to16(pCC16, &CC32);
WCDDUMPCHOOSECOLORDATA16(pCC16);
FREEVDMPTR(pCC16);
}
ChooseColorExit:
FreeCDTemplate32(pRes,
(HINSTANCE)CC32.hInstance,
dwFlags16 & CC_ENABLETEMPLATE,
dwFlags16 & CC_ENABLETEMPLATEHANDLE);
FREEVDMPTR(pCC16);
return(ul);
}
VOID
ThunkCHOOSECOLOR16to32(OUT CHOOSECOLOR *pCC32,
IN PCHOOSECOLORDATA16 pCC16)
{
COLORREF *pCustColors16;
DWORD Flags;
if(pCC16 && pCC32) {
pCC32->lStructSize = sizeof(CHOOSECOLOR);
pCC32->hwndOwner = HWND32(pCC16->hwndOwner);
// hInstance thunked separately
pCC32->rgbResult = DWORD32(pCC16->rgbResult);
if(pCC32->lpCustColors) {
GETVDMPTR(pCC16->lpCustColors, 16*sizeof(COLORREF), pCustColors16);
if(pCustColors16) {
RtlCopyMemory(pCC32->lpCustColors,
pCustColors16,
16*sizeof(COLORREF));
}
FREEVDMPTR(pCustColors16);
}
// preserve the template flag state while copying flags
// 1. save template flag state
// note: we never will have a 32-bit CC_ENABLETEMPLATE flag
// 2. copy flags from 16-bit struct (add the WOWAPP flag)
// 3. turn off all template flags
// 4. restore original template flag state
Flags = pCC32->Flags & CC_ENABLETEMPLATEHANDLE;
pCC32->Flags = DWORD32(pCC16->Flags) | CD_WOWAPP;
pCC32->Flags &= ~(CC_ENABLETEMPLATE | CC_ENABLETEMPLATEHANDLE);
pCC32->Flags |= Flags;
pCC32->lCustData = DWORD32(pCC16->lCustData);
if((DWORD32(pCC16->Flags) & CC_ENABLEHOOK) && DWORD32(pCC16->lpfnHook)){
pCC32->lpfnHook = WCD32DialogProc;
}
// lpTemplateName32 is thunked separately
}
}
VOID
ThunkCHOOSECOLOR32to16(OUT PCHOOSECOLORDATA16 pCC16,
IN CHOOSECOLOR *pCC32)
{
COLORREF *pCustColors16;
DWORD Flags, Flags32;
if(pCC16 && pCC32) {
STOREDWORD(pCC16->rgbResult, pCC32->rgbResult);
// preserve the template flag state while copying flags
// 1. save template flag state
// 2. copy flags from 32-bit struct
// 3. turn off all template flags and the WOWAPP flag
// 4. restore original template flag state
Flags = DWORD32(pCC16->Flags) & (CC_ENABLETEMPLATE |
CC_ENABLETEMPLATEHANDLE);
Flags32 = pCC32->Flags;
Flags32 &= ~(CC_ENABLETEMPLATE | CC_ENABLETEMPLATEHANDLE | CD_WOWAPP);
Flags32 |= Flags;
STOREDWORD(pCC16->Flags, Flags32);
GETVDMPTR(pCC16->lpCustColors, 16*sizeof(COLORREF), pCustColors16);
if(pCustColors16) {
RtlCopyMemory(pCustColors16,
pCC32->lpCustColors,
16*sizeof(COLORREF));
FREEVDMPTR(pCustColors16);
}
}
}
ULONG FASTCALL
WCD32ChooseFont( PVDMFRAME pFrame )
/*++
Routine Description:
This routine thunks the 16-bit ChooseFont common dialog to the 32-bit
side.
Arguments:
pFrame - Supplies 16-bit argument frame
Return Value:
16-bit BOOLEAN to be returned.
--*/
{
ULONG ul = GETBOOL16(FALSE);
register PCHOOSEFONT16 parg16;
VPCHOOSEFONTDATA vpcf;
CHOOSEFONT CF32;
LOGFONT LogFont32;
PCHOOSEFONTDATA16 pCF16;
PRES pRes = NULL;
COMMDLGTD ThreadData;
DWORD dwFlags16;
CHAR sStyle[2 * LF_FACESIZE];
BOOL fError = FALSE;
GETARGPTR(pFrame, sizeof(CHOOSEFONT16), parg16);
vpcf = parg16->lpcf;
SETEXTENDEDERROR( 0 );
// invalidate this now
FREEVDMPTR( parg16 );
// initialize unique window messages
if (msgWOWCHOOSEFONT == 0) {
// private WOW<->comdlg32 message for handling WM_CHOOSEFONT_GETLOGFONT
if(!(msgWOWCHOOSEFONT =
(WORD)RegisterWindowMessage("WOWCHOOSEFONT_GETLOGFONT"))) {
SETEXTENDEDERROR( CDERR_REGISTERMSGFAIL );
LOGDEBUG(2,("WCD32ChooseFont:RegisterWindowMessage failed\n"));
return(0);
}
}
if (msgWOWLFCHANGE == 0) {
// private message for thunking logfont changes
if(!(msgWOWLFCHANGE = (WORD)RegisterWindowMessage("WOWLFChange"))) {
SETEXTENDEDERROR( CDERR_REGISTERMSGFAIL );
LOGDEBUG(2,("WCD32ChooseFont:RegisterWindowMessage 2 failed\n"));
return(0);
}
}
GETVDMPTR(vpcf, sizeof(CHOOSEFONTDATA16), pCF16);
WCDDUMPCHOOSEFONTDATA16(pCF16);
if(DWORD32(pCF16->lStructSize) != sizeof(CHOOSEFONTDATA16)) {
SETEXTENDEDERROR( CDERR_STRUCTSIZE );
FREEVDMPTR(pCF16);
return(0);
}
RtlZeroMemory(&ThreadData, sizeof(COMMDLGTD));
ThreadData.Previous = CURRENTPTD()->CommDlgTd;
ThreadData.hdlg = (HWND16)-1;
ThreadData.pData32 = &CF32;
ThreadData.Flags = WOWCD_ISCHOOSEFONT;
if(DWORD32(pCF16->Flags) & CF_ENABLEHOOK) {
ThreadData.vpfnHook = DWORD32(pCF16->lpfnHook);
if(!ThreadData.vpfnHook) {
SETEXTENDEDERROR(CDERR_NOHOOK);
FREEVDMPTR(pCF16);
return(0);
}
ThreadData.vpData = vpcf;
}
else {
STOREDWORD(pCF16->lpfnHook, 0);
}
RtlZeroMemory(&CF32, sizeof(CHOOSEFONT));
CF32.lpLogFont = &LogFont32;
CF32.lpszStyle = sStyle;
sStyle[0] = '\0';
ThunkCHOOSEFONT16to32(&CF32, pCF16);
dwFlags16 = DWORD32(pCF16->Flags);
// this call invalidates flat ptrs to 16-bit memory
CF32.hInstance = ThunkCDTemplate16to32(WORD32(pCF16->hInstance),
0,
DWORD32(pCF16->lpTemplateName),
dwFlags16,
&(CF32.Flags),
CF_ENABLETEMPLATE,
CF_ENABLETEMPLATEHANDLE,
&pRes,
&fError);
if(fError) {
goto ChooseFontExit;
}
// invalidate flat ptrs to 16-bit memory
FREEVDMPTR(pCF16);
WCDDUMPCHOOSEFONTDATA32(&CF32);
// Set this just before the calling into comdlg32. This prevents the
// synchronization stuff from firing until we actually need it.
CURRENTPTD()->CommDlgTd = &ThreadData;
// this call invalidates flat ptrs to 16-bit memory
ul = GETBOOL16(ChooseFont(&CF32));
CURRENTPTD()->CommDlgTd = ThreadData.Previous;
if (ul) {
WCDDUMPCHOOSEFONTDATA32(&CF32);
GETVDMPTR(vpcf, sizeof(CHOOSEFONT16), pCF16);
ThunkCHOOSEFONT32to16(pCF16, &CF32);
WCDDUMPCHOOSEFONTDATA16(pCF16);
}
ChooseFontExit:
FreeCDTemplate32(pRes,
CF32.hInstance,
dwFlags16 & CF_ENABLETEMPLATE,
dwFlags16 & CF_ENABLETEMPLATEHANDLE);
FREEVDMPTR(pCF16);
return(ul);
}
VOID
ThunkCHOOSEFONT16to32(OUT CHOOSEFONT *pCF32,
IN PCHOOSEFONTDATA16 pCF16)
{
LPSTR lpstr;
DWORD Flags;
if(pCF16 && pCF32) {
pCF32->lStructSize = sizeof(CHOOSEFONT);
pCF32->hwndOwner = HWND32(pCF16->hwndOwner);
if(DWORD32(pCF16->Flags) & CF_PRINTERFONTS) {
pCF32->hDC = HDC32(pCF16->hDC);
}
if(DWORD32(pCF16->lpLogFont) && pCF32->lpLogFont) {
GETLOGFONT16(DWORD32(pCF16->lpLogFont), pCF32->lpLogFont);
}
pCF32->iPointSize = INT32(pCF16->iPointSize);
// preserve the template flag state while copying flags
// 1. save template flag state
// note: we never will have a 32-bit CF_ENABLETEMPLATE flag
// 2. copy flags from 16-bit struct (add the WOWAPP flag)
// 3. turn off all template flags
// 4. restore original template flag state
Flags = pCF32->Flags & CF_ENABLETEMPLATEHANDLE;
pCF32->Flags = DWORD32(pCF16->Flags) | CD_WOWAPP;
pCF32->Flags &= ~(CF_ENABLETEMPLATE | CF_ENABLETEMPLATEHANDLE);
pCF32->Flags |= Flags;
pCF32->rgbColors = DWORD32(pCF16->rgbColors);
pCF32->lCustData = DWORD32(pCF16->lCustData);
if((DWORD32(pCF16->Flags) & CF_ENABLEHOOK) && pCF16->lpfnHook) {
pCF32->lpfnHook = WCD32DialogProc;
}
// lpTemplateName32 is thunked separately
// hInstance thunked separately
// Note: we shouldn't have to free or re-alloc this since they
// will only need LF_FACESIZE bytes to handle the string
GETPSZPTR(pCF16->lpszStyle, lpstr);
if(lpstr && pCF32->lpszStyle) {
if(DWORD32(pCF16->Flags) & CF_USESTYLE) {
strcpy(pCF32->lpszStyle, lpstr);
}
FREEPSZPTR(lpstr);
}
pCF32->nFontType = WORD32(pCF16->nFontType);
pCF32->nSizeMin = INT32(pCF16->nSizeMin);
pCF32->nSizeMax = INT32(pCF16->nSizeMax);
}
}
VOID
ThunkCHOOSEFONT32to16(OUT PCHOOSEFONTDATA16 pCF16,
IN CHOOSEFONT *pCF32)
{
LPSTR lpstr;
DWORD Flags, Flags32;
if(pCF16 && pCF32) {
STOREWORD(pCF16->iPointSize, pCF32->iPointSize);
STOREDWORD(pCF16->rgbColors, pCF32->rgbColors);
STOREWORD(pCF16->nFontType, pCF32->nFontType);
// preserve the template flag state while copying flags
// 1. save template flag state
// 2. copy flags from 32-bit struct
// 3. turn off all template flags and the WOWAPP flag
// 4. restore original template flag state
Flags = DWORD32(pCF16->Flags) & (CF_ENABLETEMPLATE |
CF_ENABLETEMPLATEHANDLE);
Flags32 = pCF32->Flags;
Flags32 &= ~(CF_ENABLETEMPLATE | CF_ENABLETEMPLATEHANDLE | CD_WOWAPP);
Flags32 |= Flags;
STOREDWORD(pCF16->Flags, Flags32);
if(DWORD32(pCF16->lpLogFont) && pCF32->lpLogFont) {
PUTLOGFONT16(DWORD32(pCF16->lpLogFont),
sizeof(LOGFONT),
pCF32->lpLogFont);
}
GETPSZPTR(pCF16->lpszStyle, lpstr);
if(lpstr && pCF32->lpszStyle) {
if(DWORD32(pCF16->Flags) & CF_USESTYLE) {
strcpy(lpstr, pCF32->lpszStyle);
}
FREEPSZPTR(lpstr);
}
}
}
ULONG FASTCALL
WCD32PrintDlg(IN PVDMFRAME pFrame)
/*++
Routine Description:
This routine thunks the 16-bit PrintDlg common dialog to the 32-bit
side.
Arguments:
pFrame - Supplies 16-bit argument frame
Return Value:
16-bit BOOLEAN to be returned
--*/
{
ULONG ul = GETBOOL16(FALSE);
register PPRINTDLG16 parg16;
VPPRINTDLGDATA vppd;
PRINTDLG PD32;
PPRINTDLGDATA16 pPD16;
PRES hSetupRes = NULL;
PRES hPrintRes = NULL;
COMMDLGTD ThreadData;
DWORD dwFlags16;
HMEM16 hDM16;
HMEM16 hDN16;
BOOL fError = FALSE;
GETARGPTR(pFrame, sizeof(PRINTDLG16), parg16);
vppd = parg16->lppd;
// invalidate this now
FREEARGPTR(parg16);
SETEXTENDEDERROR(0);
GETVDMPTR(vppd, sizeof(PRINTDLGDATA16), pPD16);
WCDDUMPPRINTDLGDATA16(pPD16);
if(DWORD32(pPD16->lStructSize) != sizeof(PRINTDLGDATA16)) {
SETEXTENDEDERROR( CDERR_STRUCTSIZE );
FREEVDMPTR(pPD16);
return(0);
}
if(DWORD32(pPD16->Flags) & PD_RETURNDEFAULT) {
// spec says these must be NULL
if(WORD32(pPD16->hDevMode) || WORD32(pPD16->hDevNames)) {
SETEXTENDEDERROR(PDERR_RETDEFFAILURE);
FREEVDMPTR(pPD16);
return(0);
}
}
RtlZeroMemory((PVOID)&PD32, sizeof(PRINTDLG));
RtlZeroMemory((PVOID)&ThreadData, sizeof(COMMDLGTD));
ThreadData.Previous = CURRENTPTD()->CommDlgTd;
ThreadData.hdlg = (HWND16)-1;
ThreadData.pData32 = (PVOID)&PD32;
ThreadData.Flags = 0;
// this flag causes the system to put up the setup dialog rather
// than the print dialog
if(DWORD32(pPD16->Flags) & PD_PRINTSETUP) {
if(DWORD32(pPD16->Flags) & PD_ENABLESETUPHOOK) {
ThreadData.vpfnHook = DWORD32(pPD16->lpfnSetupHook);
if(!ThreadData.vpfnHook) {
SETEXTENDEDERROR(CDERR_NOHOOK);
FREEVDMPTR(pPD16);
return(0);
}
ThreadData.vpData = vppd;
PD32.lpfnSetupHook = WCD32DialogProc;
}
} else {
if (DWORD32(pPD16->Flags) & PD_ENABLEPRINTHOOK) {
ThreadData.vpfnHook = DWORD32(pPD16->lpfnPrintHook);
if(!ThreadData.vpfnHook) {
SETEXTENDEDERROR(CDERR_NOHOOK);
FREEVDMPTR(pPD16);
return(0);
}
ThreadData.vpData = vppd;
PD32.lpfnPrintHook = WCD32DialogProc;
}
if (DWORD32(pPD16->Flags) & PD_ENABLESETUPHOOK) {
ThreadData.vpfnSetupHook = DWORD32(pPD16->lpfnSetupHook);
if(!ThreadData.vpfnSetupHook) {
SETEXTENDEDERROR(CDERR_NOHOOK);
FREEVDMPTR(pPD16);
return(0);
}
ThreadData.vpData = vppd;
ThreadData.SetupHwnd = (HWND16)1;
PD32.lpfnSetupHook = WCD32PrintSetupDialogProc;
}
}
// lock the original 16-bit hDevMode & hDevNames so they won't get thrown
// out by our thunking. (we need to restore them to the original handles
// if there is an error in PrintDlg() ).
hDM16 = WORD32(pPD16->hDevMode);
hDN16 = WORD32(pPD16->hDevNames);
WOWGlobalLock16(hDM16);
WOWGlobalLock16(hDN16);
dwFlags16 = DWORD32(pPD16->Flags);
// get a new 32-bit devmode struct
PD32.hDevMode = ThunkhDevMode16to32(WORD32(pPD16->hDevMode));
// get a new 32-bit devnames struct
PD32.hDevNames = ThunkhDevNames16to32(WORD32(pPD16->hDevNames));
ThunkPRINTDLG16to32(&PD32, pPD16);
GETVDMPTR(vppd, sizeof(PRINTDLGDATA16), pPD16);
// this call invalidates flat ptrs to 16-bit memory
PD32.hPrintTemplate
= ThunkCDTemplate16to32(WORD32(pPD16->hInstance),
MAKELONG(WORD32(pPD16->hPrintTemplate),1),
DWORD32(pPD16->lpPrintTemplateName),
dwFlags16,
&(PD32.Flags),
PD_ENABLEPRINTTEMPLATE,
PD_ENABLEPRINTTEMPLATEHANDLE,
&hPrintRes,
&fError);
if(fError) {
goto PrintDlgError;
}
// memory may have moved - invalidate flat pointers now
FREEVDMPTR(pPD16);
GETVDMPTR(vppd, sizeof(PRINTDLGDATA16), pPD16);
// this call invalidates flat ptrs to 16-bit memory
PD32.hSetupTemplate
= ThunkCDTemplate16to32(WORD32(pPD16->hInstance),
MAKELONG(WORD32(pPD16->hSetupTemplate),1),
DWORD32(pPD16->lpSetupTemplateName),
dwFlags16,
&(PD32.Flags),
PD_ENABLESETUPTEMPLATE,
PD_ENABLESETUPTEMPLATEHANDLE,
&hSetupRes,
&fError);
PrintDlgError:
if(fError) {
WOWGlobalUnlock16(hDM16);
WOWGlobalUnlock16(hDN16);
goto PrintDlgExit;
}
// memory may have moved - invalidate flat pointers now
FREEVDMPTR(pPD16);
WCDDUMPPRINTDLGDATA32(&PD32);
// Set this just before the calling into comdlg32. This prevents the
// synchronization stuff from firing until we actually need it.
CURRENTPTD()->CommDlgTd = &ThreadData;
ul = GETBOOL16(PrintDlg(&PD32));
CURRENTPTD()->CommDlgTd = ThreadData.Previous;
// blow away our locks so these really can be free'd if needed
WOWGlobalUnlock16(hDM16);
WOWGlobalUnlock16(hDN16);
if(ul) {
WCDDUMPPRINTDLGDATA32(&PD32);
// this call invalidates flat ptrs to 16-bit mem
ThunkPRINTDLG32to16(vppd, &PD32);
GETVDMPTR(vppd, sizeof(PRINTDLGDATA16), pPD16);
WCDDUMPPRINTDLGDATA16(pPD16);
// throw out the old ones if the structs were updated
if(WORD32(pPD16->hDevMode) != hDM16) {
WOWGlobalFree16(hDM16);
}
if(WORD32(pPD16->hDevNames) != hDN16) {
WOWGlobalFree16(hDN16);
}
} else {
// throw away any new hDevMode's & hDevNames that we might have created
// as a result of our thunking & restore the originals
GETVDMPTR(vppd, sizeof(PRINTDLGDATA16), pPD16);
if(WORD32(pPD16->hDevMode) != hDM16) {
WOWGlobalFree16(WORD32(pPD16->hDevMode));
STOREWORD(pPD16->hDevMode, hDM16);
}
if(WORD32(pPD16->hDevNames) != hDN16) {
WOWGlobalFree16(WORD32(pPD16->hDevNames));
STOREWORD(pPD16->hDevNames, hDN16);
}
}
PrintDlgExit:
WOWGLOBALFREE(PD32.hDevMode);
WOWGLOBALFREE(PD32.hDevNames);
if(PD32.hPrintTemplate) {
FreeCDTemplate32(hPrintRes,
PD32.hPrintTemplate,
dwFlags16 & PD_ENABLEPRINTTEMPLATE,
dwFlags16 & PD_ENABLEPRINTTEMPLATEHANDLE);
}
if(PD32.hSetupTemplate) {
FreeCDTemplate32(hSetupRes,
PD32.hSetupTemplate,
dwFlags16 & PD_ENABLESETUPTEMPLATE,
dwFlags16 & PD_ENABLESETUPTEMPLATEHANDLE);
}
FREEVDMPTR(pPD16);
return(ul);
}
#define PD_TEMPLATEMASK32 (PD_ENABLEPRINTTEMPLATE | \
PD_ENABLESETUPTEMPLATE)
#define PD_TEMPLATEHANDLEMASK32 (PD_ENABLEPRINTTEMPLATEHANDLE | \
PD_ENABLESETUPTEMPLATEHANDLE)
VOID
ThunkPRINTDLG16to32(OUT PRINTDLG *pPD32,
IN PPRINTDLGDATA16 pPD16)
{
DWORD Flags;
HANDLE h32New;
LPVOID lp32New;
LPVOID lp32Cur;
if(pPD16 && pPD32) {
pPD32->lStructSize = sizeof(PRINTDLG);
pPD32->hwndOwner = HWND32(pPD16->hwndOwner);
// get a new 32-bit devmode thunked from the 16-bit one...
if(h32New = ThunkhDevMode16to32(WORD32(pPD16->hDevMode))) {
lp32New = GlobalLock(h32New);
lp32Cur = GlobalLock(pPD32->hDevMode);
// ...and copy it over the current 32-bit devmode struct
if(lp32New && lp32Cur) {
RtlCopyMemory(lp32Cur,
lp32New,
((LPDEVMODE)lp32New)->dmSize);
GlobalUnlock(pPD32->hDevMode);
GlobalUnlock(h32New);
}
WOWGLOBALFREE(h32New);
}
// we assume that the DEVNAMES struct will never change
// hDC filled on output only
// preserve the template flag state while copying flags
// 1. save original template flags
// note: we never set the 32-bit PD_ENABLExxxxTEMPLATE flags
// 2. copy flags from 16-bit struct (and add WOWAPP flag)
// 3. turn off all template flags
// 4. restore original template flag state
Flags = pPD32->Flags & PD_TEMPLATEHANDLEMASK32;
pPD32->Flags = DWORD32(pPD16->Flags) | CD_WOWAPP;
pPD32->Flags &= ~(PD_TEMPLATEMASK32 | PD_TEMPLATEHANDLEMASK32);
pPD32->Flags |= Flags;
pPD32->nFromPage = WORD32(pPD16->nFromPage);
pPD32->nToPage = WORD32(pPD16->nToPage);
pPD32->nMinPage = WORD32(pPD16->nMinPage);
pPD32->nMaxPage = WORD32(pPD16->nMaxPage);
pPD32->nCopies = WORD32(pPD16->nCopies);
pPD32->lCustData = DWORD32(pPD16->lCustData);
// hInstance thunked separately
// hPrintTemplate & hSetupTemplate thunked separately
}
}
#define PD_TEMPLATEMASK16 (PD_ENABLEPRINTTEMPLATE | \
PD_ENABLESETUPTEMPLATE | \
PD_ENABLEPRINTTEMPLATEHANDLE | \
PD_ENABLESETUPTEMPLATEHANDLE)
VOID
ThunkPRINTDLG32to16(IN VPVOID vppd,
OUT PRINTDLG *pPD32)
{
HAND16 hDevMode16;
HAND16 hDevNames16;
PPRINTDLGDATA16 pPD16;
DWORD Flags, Flags16;
GETVDMPTR(vppd, sizeof(PRINTDLGDATA16), pPD16);
if(pPD16 && pPD32) {
if(pPD32->Flags & (PD_RETURNIC | PD_RETURNDC)) {
STOREWORD(pPD16->hDC, GETHDC16(pPD32->hDC));
}
// thunk 32-bit DEVMODE structure back to 16-bit
// hDevXXXX16 take care of RISC alignment problems
hDevMode16 = WORD32(pPD16->hDevMode);
hDevNames16 = WORD32(pPD16->hDevNames);
// this call invalidates flat ptrs to 16-bit mem
ThunkhDevMode32to16(&hDevMode16, pPD32->hDevMode);
FREEVDMPTR(pPD16);
GETVDMPTR(vppd, sizeof(PRINTDLGDATA16), pPD16);
// this call invalidates flat ptrs to 16-bit mem
ThunkhDevNames32to16(&hDevNames16, pPD32->hDevNames);
FREEVDMPTR(pPD16);
GETVDMPTR(vppd, sizeof(PRINTDLGDATA16), pPD16);
STOREWORD(pPD16->hDevMode, hDevMode16);
STOREWORD(pPD16->hDevNames, hDevNames16);
// preserve the template flag state while copying flags
// 1. save original template flags
// 2. copy flags from 32-bit struct
// 3. turn off all template flags and WOWAPP flag
// 4. restore original template flag state
Flags = DWORD32(pPD16->Flags) & PD_TEMPLATEMASK16;
Flags16 = pPD32->Flags;
Flags16 &= ~(PD_TEMPLATEMASK16 | CD_WOWAPP);
Flags16 |= Flags;
STOREDWORD(pPD16->Flags, Flags16);
STOREWORD(pPD16->nFromPage, GETUINT16(pPD32->nFromPage));
STOREWORD(pPD16->nToPage, GETUINT16(pPD32->nToPage));
STOREWORD(pPD16->nMinPage, GETUINT16(pPD32->nMinPage));
STOREWORD(pPD16->nMaxPage, GETUINT16(pPD32->nMaxPage));
STOREWORD(pPD16->nCopies, GETUINT16(pPD32->nCopies));
FREEVDMPTR(pPD16);
}
}
HGLOBAL
ThunkhDevMode16to32(IN HAND16 hDevMode16)
{
INT nSize;
LPDEVMODE lpdm32, pdm32;
HGLOBAL hDevMode32 = NULL;
VPDEVMODE31 vpDevMode16;
if (hDevMode16) {
vpDevMode16 = GlobalLock16(hDevMode16, NULL);
if(FETCHDWORD(vpDevMode16)) {
if(pdm32 = ThunkDevMode16to32(vpDevMode16)) {
nSize = FETCHWORD(pdm32->dmSize) +
FETCHWORD(pdm32->dmDriverExtra);
hDevMode32 = WOWGLOBALALLOC(GMEM_MOVEABLE, nSize);
if(lpdm32 = GlobalLock(hDevMode32)) {
RtlCopyMemory((PVOID)lpdm32, (PVOID)pdm32, nSize);
GlobalUnlock(hDevMode32);
}
free_w(pdm32);
}
GlobalUnlock16(hDevMode16);
}
}
return(hDevMode32);
}
VOID
ThunkhDevMode32to16(IN OUT HAND16 *phDevMode16,
IN HANDLE hDevMode32)
/*++
Routine Description:
This routine thunks a 32-bit DevMode structure back into the 16-bit one.
It will reallocate the 16-bit global memory block as necessary.
WARNING: This may cause 16-bit memory to move, invalidating flat pointers.
Arguments:
hDevMode - Supplies a handle to a movable global memory object that
contains a 32-bit DEVMODE structure
phDevMode16 - Supplies a pointer to a 16-bit handle to a movable global
memory object that will return the 16-bit DEVMODE structure.
If the handle is NULL, the object will be allocated. It
may also be reallocated if its current size is not enough.
Return Value:
None
--*/
{
UINT CurrentSize;
UINT RequiredSize;
VPDEVMODE31 vpDevMode16;
LPDEVMODE lpDevMode32;
if (hDevMode32 == NULL) {
*phDevMode16 = (HAND16)NULL;
return;
}
lpDevMode32 = GlobalLock(hDevMode32);
if (lpDevMode32==NULL) {
*phDevMode16 = (HAND16)NULL;
return;
}
RequiredSize = lpDevMode32->dmSize +
lpDevMode32->dmDriverExtra +
sizeof(WOWDM31); // see notes in wstruc.c
if (*phDevMode16 == (HAND16)NULL) {
vpDevMode16 = GlobalAllocLock16(GMEM_MOVEABLE,
RequiredSize,
phDevMode16);
} else {
vpDevMode16 = GlobalLock16(*phDevMode16, &CurrentSize);
if (CurrentSize < RequiredSize) {
GlobalUnlockFree16(vpDevMode16);
vpDevMode16 = GlobalAllocLock16(GMEM_MOVEABLE,
RequiredSize,
phDevMode16);
}
}
if(ThunkDevMode32to16(vpDevMode16, lpDevMode32, RequiredSize)) {
GlobalUnlock16(*phDevMode16);
}
else {
*phDevMode16 = (HAND16)NULL;
}
GlobalUnlock(hDevMode32);
}
HANDLE
ThunkhDevNames16to32(IN HAND16 hDevNames16)
{
INT nSize;
HANDLE hDN32 = NULL;
LPDEVNAMES pdn32;
PDEVNAMES16 pdn16;
if(FETCHDWORD(hDevNames16)) {
VPDEVNAMES vpDevNames;
vpDevNames = GlobalLock16(hDevNames16, &nSize);
if(nSize) {
GETVDMPTR(vpDevNames, sizeof(DEVNAMES16), pdn16);
if(pdn16) {
hDN32 = WOWGLOBALALLOC(GMEM_MOVEABLE, nSize);
if(pdn32 = GlobalLock(hDN32)) {
RtlCopyMemory((PVOID)pdn32, (PVOID)pdn16, nSize);
GlobalUnlock(hDN32);
} else {
LOGDEBUG(0, ("ThunkhDEVNAMES16to32, 32-bit allocation(s) failed!\n"));
}
FREEVDMPTR(pdn16);
}
GlobalUnlock16(hDevNames16);
}
}
return(hDN32);
}
VOID
ThunkhDevNames32to16(IN OUT HAND16 *phDevNames16,
IN HANDLE hDevNames)
/*++
Routine Description:
This routine thunks a 32-bit DevNames structure back into the 16-bit one.
It will reallocate the 16-bit global memory block as necessary.
WARNING: This may cause 16-bit memory to move, invalidating flat pointers.
Arguments:
hDevNames - Supplies a handle to a movable global memory object that
contains a 32-bit DEVNAMES structure
phDevNames16 - Supplies a pointer to a 16-bit handle to a movable global
memory object that will return the 16-bit DEVNAMES structure.
If the handle is NULL, the object will be allocated. It
may also be reallocated if its current size is not enough.
Return Value:
None
--*/
{
UINT CurrentSize;
UINT RequiredSize;
UINT CopySize;
UINT MaxOffset;
PDEVNAMES16 pdn16;
VPDEVNAMES DevNames16;
LPDEVNAMES DevNames32;
if (hDevNames==NULL) {
*phDevNames16=(HAND16)NULL;
return;
}
DevNames32 = GlobalLock(hDevNames);
if (DevNames32==NULL) {
*phDevNames16=(HAND16)NULL;
}
MaxOffset = max(max(DevNames32->wDriverOffset,DevNames32->wDeviceOffset),
DevNames32->wOutputOffset);
// ProComm Plus copies 0x48 constant bytes after Print Setup.
CopySize = MaxOffset + strlen((PCHAR)DevNames32+MaxOffset) + 1;
RequiredSize = max(CopySize, 0x48);
if (*phDevNames16==(HAND16)NULL) {
DevNames16 = GlobalAllocLock16(GMEM_MOVEABLE,
RequiredSize,
phDevNames16);
} else {
DevNames16 = GlobalLock16(*phDevNames16, &CurrentSize);
if (CurrentSize < RequiredSize) {
GlobalUnlockFree16(DevNames16);
DevNames16 = GlobalAllocLock16(GMEM_MOVEABLE,
RequiredSize,
phDevNames16);
}
}
GETVDMPTR(DevNames16, RequiredSize, pdn16);
if (pdn16==NULL) {
*phDevNames16=(HAND16)NULL;
GlobalUnlock(hDevNames);
return;
}
RtlCopyMemory(pdn16,DevNames32,CopySize);
FREEVDMPTR(pdn16);
GlobalUnlock16(*phDevNames16);
GlobalUnlock(hDevNames);
}
ULONG FASTCALL
WCD32GetOpenFileName( PVDMFRAME pFrame )
/*++
Routine Description:
This routine thunks the 16-bit GetOpenFileName common dialog to the
32-bit side.
Arguments:
pFrame - Supplies 16-bit argument frame
Return Value:
16-bit BOOLEAN to be returned.
--*/
{
return(WCD32GetFileName(pFrame,GetOpenFileName));
}
ULONG FASTCALL
WCD32GetSaveFileName( PVDMFRAME pFrame )
/*++
Routine Description:
This routine thunks the 16-bit GetOpenFileName common dialog to the
32-bit side.
Arguments:
pFrame - Supplies 16-bit argument frame
Return Value:
16-bit BOOLEAN to be returned.
--*/
{
return(WCD32GetFileName(pFrame,GetSaveFileName));
}
ULONG
WCD32GetFileName(IN PVDMFRAME pFrame,
IN FILENAMEPROC Function)
/*++
Routine Description:
This routine is called by WCD32GetOpenFileName and WCD32GetSaveFileName.
It does all the real thunking work.
Arguments:
pFrame - Supplies 16-bit argument frame
Function - supplies a pointer to the 32-bit function to call (either
GetOpenFileName or GetSaveFileName)
Return Value:
16-bit BOOLEAN to be returned.
--*/
{
ULONG ul = 0;
register PGETOPENFILENAME16 parg16;
VPOPENFILENAME vpof;
OPENFILENAME OFN32;
POPENFILENAME16 pOFN16;
COMMDLGTD ThreadData;
PRES pRes = NULL;
DWORD dwFlags16 = 0;
USHORT cb;
PBYTE lpcb;
BOOL fError = FALSE;
GETARGPTR(pFrame, sizeof(GETOPENFILENAME16), parg16);
vpof = parg16->lpof;
SETEXTENDEDERROR(0);
// invalidate this now
FREEARGPTR(parg16);
// initialize unique window messages
if (msgFILEOK == 0) {
if(!(msgSHAREVIOLATION = (WORD)RegisterWindowMessage(SHAREVISTRING))) {
SETEXTENDEDERROR( CDERR_REGISTERMSGFAIL );
LOGDEBUG(2,("WCD32GetFileName:RegisterWindowMessage failed\n"));
return(0);
}
if(!(msgFILEOK = (WORD)RegisterWindowMessage(FILEOKSTRING))) {
SETEXTENDEDERROR( CDERR_REGISTERMSGFAIL );
LOGDEBUG(2,("WCD32GetFileName:RegisterWindowMessage 2 failed\n"));
return(0);
}
// initialize private WOW-comdlg32 message
msgWOWDIRCHANGE = (WORD)RegisterWindowMessage("WOWDirChange");
}
GETVDMPTR(vpof, sizeof(OPENFILENAME16), pOFN16);
WCDDUMPOPENFILENAME16(pOFN16);
if(DWORD32(pOFN16->lStructSize) != sizeof(OPENFILENAME16)) {
SETEXTENDEDERROR( CDERR_STRUCTSIZE );
FREEVDMPTR(pOFN16);
return(0);
}
RtlZeroMemory(&ThreadData, sizeof(COMMDLGTD));
ThreadData.Previous = CURRENTPTD()->CommDlgTd;
ThreadData.hdlg = (HWND16)-1;
ThreadData.pData32 = (PVOID)&OFN32;
ThreadData.Flags = WOWCD_ISOPENFILE;
if(DWORD32(pOFN16->Flags) & OFN_ENABLEHOOK) {
ThreadData.vpfnHook = DWORD32(pOFN16->lpfnHook);
if(!ThreadData.vpfnHook) {
SETEXTENDEDERROR(CDERR_NOHOOK);
FREEVDMPTR(pOFN16);
return(0);
}
ThreadData.vpData = vpof;
}
RtlZeroMemory(&OFN32, sizeof(OPENFILENAME));
if(!Alloc_OFN32_strs(&OFN32, pOFN16)) {
SETEXTENDEDERROR(CDERR_MEMALLOCFAILURE);
goto GetFileNameExit;
}
// On Win3.1, the system sets these flags in the app's struct under the
// shown conditions so we need to update the 16-bit struct too.
dwFlags16 = DWORD32(pOFN16->Flags);
if(dwFlags16 & OFN_CREATEPROMPT) {
dwFlags16 |= OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST;
}
else if(dwFlags16 & OFN_FILEMUSTEXIST) {
dwFlags16 |= OFN_PATHMUSTEXIST;
}
// A bug in Serif PagePlus 3.0 sets the high word to 0xFFFF which causes
// the new moniker stuff in comdlg32 to break. #148137 - cmjones
// VadimB: the mask below causes apps that do want lfn to break, so check
// for those apps via the compat flag and let them go unpunished
if ((dwFlags16 & OFN_LONGNAMES) &&
(CURRENTPTD()->dwWOWCompatFlagsEx & WOWCFEX_ALLOWLFNDIALOGS)) {
dwFlags16 = (dwFlags16 & VALID_OFN16_FLAGS) | OFN_LONGNAMES;
}
else {
dwFlags16 &= VALID_OFN16_FLAGS;
}
STOREDWORD(pOFN16->Flags, dwFlags16);
if(!ThunkOPENFILENAME16to32(&OFN32, pOFN16)) {
SETEXTENDEDERROR(CDERR_MEMALLOCFAILURE);
goto GetFileNameExit;
}
dwFlags16 = DWORD32(pOFN16->Flags); // get updated flags
// make sure the current directory is up to date
UpdateDosCurrentDirectory(DIR_DOS_TO_NT);
// this call invalidates flat ptrs to 16-bit memory
OFN32.hInstance = ThunkCDTemplate16to32(WORD32(pOFN16->hInstance),
0,
DWORD32(pOFN16->lpTemplateName),
dwFlags16,
&(OFN32.Flags),
OFN_ENABLETEMPLATE,
OFN_ENABLETEMPLATEHANDLE,
&pRes,
&fError);
if(fError) {
goto GetFileNameExit;
}
// memory may move - free flat pointers now
FREEVDMPTR(pOFN16);
WCDDUMPOPENFILENAME32(&OFN32);
// Set this just before the calling into comdlg32. This prevents the
// synchronization stuff from firing until we actually need it.
CURRENTPTD()->CommDlgTd = &ThreadData;
// this call invalidates flat ptrs to 16-bit memory
ul = GETBOOL16((*Function)(&OFN32));
CURRENTPTD()->CommDlgTd = ThreadData.Previous;
WCDDUMPOPENFILENAME32(&OFN32);
UpdateDosCurrentDirectory(DIR_NT_TO_DOS);
GETVDMPTR(vpof, sizeof(OPENFILENAME16), pOFN16);
if (ul) {
ThunkOPENFILENAME32to16(pOFN16, &OFN32, TRUE);
}
// else if the buffer is too small, lpstrFile contains the required buffer
// size for the specified file
else if (CommDlgExtendedError() == FNERR_BUFFERTOOSMALL) {
SETEXTENDEDERROR(FNERR_BUFFERTOOSMALL);
if(OFN32.lpstrFile && pOFN16->lpstrFile) {
cb = *((PUSHORT)(OFN32.lpstrFile)); // is a WORD for comdlg32 too
// 3 is the documented minimum size of the lpstrFile buffer
GETVDMPTR(pOFN16->lpstrFile, 3, lpcb);
// Win3.1 assumes that lpstrFile buffer is at least 3 bytes long
// we'll try to be a little smarter than that...
if(lpcb && (cb > pOFN16->nMaxFile)) {
if(pOFN16->nMaxFile)
lpcb[0] = LOBYTE(cb);
if(pOFN16->nMaxFile > 1)
lpcb[1] = HIBYTE(cb);
if(pOFN16->nMaxFile > 2)
lpcb[2] = 0; // Win3.1 appends a NULL
FREEVDMPTR(lpcb);
}
}
}
WCDDUMPOPENFILENAME16(pOFN16);
GetFileNameExit:
FreeCDTemplate32(pRes,
OFN32.hInstance,
dwFlags16 & OFN_ENABLETEMPLATE,
dwFlags16 & OFN_ENABLETEMPLATEHANDLE);
Free_OFN32_strs(&OFN32);
FREEVDMPTR(pOFN16);
return(ul);
}
BOOL
ThunkOPENFILENAME16to32(OUT OPENFILENAME *pOFN32,
IN POPENFILENAME16 pOFN16)
/*++
Routine Description:
This routine thunks a 16-bit OPENFILENAME structure to the 32-bit
OPENFILENAME structure
Arguments:
pOFN16 - Supplies a flat pointer to the 16-bit OPENFILENAME structure.
pOFN32 - Supplies a pointer to the 32-bit OPENFILENAME structure.
Return Value:
None.
--*/
{
DWORD Flags;
if(pOFN16 && pOFN32) {
// Re-thunk all of the strings!!!
// Persuasion 3.0 changes the various ptrs to strings depending on which
// dialog buttons are pushed so we might have to dynamically re-alloc
// some of the 32-bit string buffers.
Thunk_OFNstrs16to32(pOFN32, pOFN16);
pOFN32->lStructSize = sizeof(OPENFILENAME);
pOFN32->hwndOwner = HWND32(pOFN16->hwndOwner);
// hInstance thunked separately
pOFN32->nMaxCustFilter = DWORD32(pOFN16->nMaxCustFilter);
pOFN32->nFilterIndex = DWORD32(pOFN16->nFilterIndex);
pOFN32->nMaxFile = DWORD32(pOFN16->nMaxFile);
pOFN32->nMaxFileTitle = DWORD32(pOFN16->nMaxFileTitle);
// preserve the template flag state while copying flags
// 1. save template flag state
// note: we never will have a 32-bit OFN_ENABLETEMPLATE flag
// we may or may not have a OFN_ENABLETEMPLATEHANDLE flag
// 2. copy flags from 16-bit struct
// 3. turn off all template flags
// 4. restore original template flag state
// 5. add the WOWAPP and no-long-names flags
Flags = pOFN32->Flags & OFN_ENABLETEMPLATEHANDLE;
pOFN32->Flags = DWORD32(pOFN16->Flags);
pOFN32->Flags &= ~(OFN_ENABLETEMPLATE | OFN_ENABLETEMPLATEHANDLE);
pOFN32->Flags |= Flags;
if ((pOFN32->Flags & OFN_LONGNAMES) &&
(CURRENTPTD()->dwWOWCompatFlagsEx & WOWCFEX_ALLOWLFNDIALOGS)) {
pOFN32->Flags |= CD_WOWAPP;
}
else {
pOFN32->Flags |= (OFN_NOLONGNAMES | CD_WOWAPP);
}
pOFN32->nFileOffset = WORD32(pOFN16->nFileOffset);
pOFN32->nFileExtension = WORD32(pOFN16->nFileExtension);
pOFN32->lCustData = DWORD32(pOFN16->lCustData);
if(DWORD32(pOFN16->Flags) & OFN_ENABLEHOOK) {
pOFN32->lpfnHook = WCD32DialogProc;
}
// lpTemplateName32 is thunked separately
// This is a hack to fix a bug in Win3.1 commdlg.dll.
// Win3.1 doesn't check nMaxFileTitle before copying the FileTitle str.
// (see Win3.1 src's \\pucus\win31aro\src\sdk\commdlg\fileopen.c)
// TaxCut'95 depends on the title string being returned.
if(pOFN32->lpstrFileTitle) {
// if nMaxFileTitle > 0, NT will copy lpstrFileTitle
if(pOFN32->nMaxFileTitle == 0) {
pOFN32->nMaxFileTitle = 13; // 8.3 filename + NULL
}
}
return(TRUE);
}
return(FALSE);
}
VOID
ThunkOPENFILENAME32to16(OUT POPENFILENAME16 pOFN16,
IN OPENFILENAME *pOFN32,
IN BOOLEAN bUpperStrings)
/*++
Routine Description:
This routine thunks a 32-bit OPENFILENAME structure back to a 16-bit
OPENFILENAME structure.
Arguments:
pOFN32 - Supplies a pointer to the 32-bit OPENFILENAME struct.
pOFN16 - Supplies a flat pointer to the 16-bit OPENFILENAME struct
Return Value:
None.
--*/
{
LPSTR lpstr;
DWORD Flags, Flags32;
if(pOFN16 && pOFN32) {
STOREWORD(pOFN16->nFileOffset, pOFN32->nFileOffset);
STOREWORD(pOFN16->nFileExtension, pOFN32->nFileExtension);
STOREDWORD(pOFN16->nFilterIndex, pOFN32->nFilterIndex);
// preserve the template flag state while copying flags
// 1. save template flag state
// 2. copy flags from 32-bit struct
// 3. turn off all template flags and the WOWAPP flag
// 4. restore original template flag state
Flags = DWORD32(pOFN16->Flags) & (OFN_ENABLETEMPLATE |
OFN_ENABLETEMPLATEHANDLE);
Flags32 = pOFN32->Flags;
Flags32 &= ~(OFN_ENABLETEMPLATE | OFN_ENABLETEMPLATEHANDLE | CD_WOWAPP);
Flags32 |= Flags;
STOREDWORD(pOFN16->Flags, Flags32);
if(bUpperStrings && pOFN32->lpstrFile) {
// Note we have to upcase the pOFN32 here because some apps
// (notably QC/Win) do case-sensitive compares on the extension.
// In Win3.1, the upcasing happens as a side-effect of the
// OpenFile call. Here we do it explicitly.
CharUpperBuff(pOFN32->lpstrFile, strlen(pOFN32->lpstrFile));
}
GETPSZPTR(pOFN16->lpstrFile, lpstr);
if(lpstr && pOFN32->lpstrFile) {
strcpy(lpstr, pOFN32->lpstrFile);
FREEPSZPTR(lpstr);
}
GETPSZPTR(pOFN16->lpstrFilter, lpstr);
if(lpstr && pOFN32->lpstrFilter) {
Multi_strcpy(lpstr, pOFN32->lpstrFilter);
FREEPSZPTR(lpstr);
}
GETPSZPTR(pOFN16->lpstrCustomFilter, lpstr);
if(lpstr && pOFN32->lpstrCustomFilter) {
Multi_strcpy(lpstr, pOFN32->lpstrCustomFilter);
FREEPSZPTR(lpstr);
}
if(bUpperStrings && (pOFN32->lpstrFileTitle)) {
// Not sure if we really need to upcase this or not, but I figure
// somewhere there is an app that depends on this being uppercased
// like Win3.1
CharUpperBuff(pOFN32->lpstrFileTitle,
strlen(pOFN32->lpstrFileTitle));
}
GETPSZPTR(pOFN16->lpstrFileTitle , lpstr);
if(lpstr && pOFN32->lpstrFileTitle) {
strcpy(lpstr, pOFN32->lpstrFileTitle);
FREEPSZPTR(lpstr);
}
// even though this is doc'd as being filled by the app only, Adobe
// distiller depends on it being copied back to the app
GETPSZPTR(pOFN16->lpstrInitialDir , lpstr);
if(lpstr && pOFN32->lpstrInitialDir) {
strcpy(lpstr, pOFN32->lpstrInitialDir);
FREEPSZPTR(lpstr);
}
// who knows who depends on this
GETPSZPTR(pOFN16->lpstrTitle, lpstr);
if(lpstr && pOFN32->lpstrTitle) {
strcpy(lpstr, pOFN32->lpstrTitle);
FREEPSZPTR(lpstr);
}
}
}
BOOL
Alloc_OFN32_strs(IN OPENFILENAME *pOFN32,
IN POPENFILENAME16 pOFN16)
{
if(DWORD32(pOFN16->lpstrFilter)) {
if(!(pOFN32->lpstrFilter =
malloc_w_strcpy_vp16to32(DWORD32(pOFN16->lpstrFilter),
TRUE,
0))) {
goto ErrorExit;
}
}
if(DWORD32(pOFN16->lpstrCustomFilter)) {
if(!(pOFN32->lpstrCustomFilter =
malloc_w_strcpy_vp16to32(DWORD32(pOFN16->lpstrCustomFilter),
TRUE,
DWORD32(pOFN16->nMaxCustFilter) ))) {
goto ErrorExit;
}
}
if(DWORD32(pOFN16->lpstrFile)) {
if(!(pOFN32->lpstrFile =
malloc_w_strcpy_vp16to32(DWORD32(pOFN16->lpstrFile),
FALSE,
DWORD32(pOFN16->nMaxFile) ))) {
goto ErrorExit;
}
}
if(DWORD32(pOFN16->lpstrFileTitle)) {
if(!(pOFN32->lpstrFileTitle =
malloc_w_strcpy_vp16to32(DWORD32(pOFN16->lpstrFileTitle),
FALSE,
DWORD32(pOFN16->nMaxFileTitle) ))) {
goto ErrorExit;
}
}
if(DWORD32(pOFN16->lpstrInitialDir)) {
if(!(pOFN32->lpstrInitialDir =
malloc_w_strcpy_vp16to32(DWORD32(pOFN16->lpstrInitialDir),
FALSE,
0))) {
goto ErrorExit;
}
}
if(DWORD32(pOFN16->lpstrTitle)) {
if(!(pOFN32->lpstrTitle =
malloc_w_strcpy_vp16to32(DWORD32(pOFN16->lpstrTitle),
FALSE,
0))) {
goto ErrorExit;
}
}
if(DWORD32(pOFN16->lpstrDefExt)) {
if(!(pOFN32->lpstrDefExt =
malloc_w_strcpy_vp16to32(DWORD32(pOFN16->lpstrDefExt),
FALSE,
0))) {
goto ErrorExit;
}
}
return(TRUE);
ErrorExit:
LOGDEBUG(0, ("Alloc_OFN32_strs, 32-bit allocation(s) failed!\n"));
Free_OFN32_strs(pOFN32);
return(FALSE);
}
VOID
Free_OFN32_strs(IN OPENFILENAME *pOFN32)
{
if(pOFN32->lpstrFilter) {
free_w((PVOID)pOFN32->lpstrFilter);
pOFN32->lpstrFilter = NULL;
}
if(pOFN32->lpstrCustomFilter) {
free_w((PVOID)pOFN32->lpstrCustomFilter);
pOFN32->lpstrCustomFilter = NULL;
}
if(pOFN32->lpstrFile) {
free_w((PVOID)pOFN32->lpstrFile);
pOFN32->lpstrFile = NULL;
}
if(pOFN32->lpstrFileTitle) {
free_w((PVOID)pOFN32->lpstrFileTitle);
pOFN32->lpstrFileTitle = NULL;
}
if(pOFN32->lpstrInitialDir) {
free_w((PVOID)pOFN32->lpstrInitialDir);
pOFN32->lpstrInitialDir = NULL;
}
if(pOFN32->lpstrTitle) {
free_w((PVOID)pOFN32->lpstrTitle);
pOFN32->lpstrTitle = NULL;
}
if(pOFN32->lpstrDefExt) {
free_w((PVOID)pOFN32->lpstrDefExt);
pOFN32->lpstrDefExt = NULL;
}
}
VOID
Thunk_OFNstrs16to32(IN OPENFILENAME *pOFN32,
IN POPENFILENAME16 pOFN16)
{
pOFN32->lpstrFilter
= ThunkStr16toStr32((LPSTR)pOFN32->lpstrFilter,
DWORD32(pOFN16->lpstrFilter),
MAX_PATH,
TRUE);
pOFN32->lpstrCustomFilter
= ThunkStr16toStr32(pOFN32->lpstrCustomFilter,
DWORD32(pOFN16->lpstrCustomFilter),
DWORD32(pOFN16->nMaxCustFilter),
TRUE);
pOFN32->lpstrFile
= ThunkStr16toStr32(pOFN32->lpstrFile,
DWORD32(pOFN16->lpstrFile),
DWORD32(pOFN16->nMaxFile),
FALSE);
pOFN32->lpstrFileTitle
= ThunkStr16toStr32(pOFN32->lpstrFileTitle,
DWORD32(pOFN16->lpstrFileTitle),
DWORD32(pOFN16->nMaxFileTitle),
FALSE);
pOFN32->lpstrInitialDir
= ThunkStr16toStr32((LPSTR)pOFN32->lpstrInitialDir,
DWORD32(pOFN16->lpstrInitialDir),
MAX_PATH,
FALSE);
pOFN32->lpstrTitle
= ThunkStr16toStr32((LPSTR)pOFN32->lpstrTitle,
DWORD32(pOFN16->lpstrTitle),
MAX_PATH,
FALSE);
pOFN32->lpstrDefExt
= ThunkStr16toStr32((LPSTR)pOFN32->lpstrDefExt,
DWORD32(pOFN16->lpstrDefExt),
10,
FALSE);
}
ULONG FASTCALL
WCD32FindText(PVDMFRAME pFrame)
/*++
Routine Description:
This routine thunks the 16-bit FindText common dialog to the
32-bit side.
Arguments:
pFrame - Supplies 16-bit argument frame
Return Value:
16-bit BOOLEAN to be returned.
--*/
{
return(WCD32FindReplaceText(pFrame, FindText));
}
ULONG FASTCALL
WCD32ReplaceText(PVDMFRAME pFrame)
/*++
Routine Description:
This routine thunks the 16-bit ReplaceText common dialog to the
32-bit side.
Arguments:
pFrame - Supplies 16-bit argument frame
Return Value:
16-bit BOOLEAN to be returned.
--*/
{
return(WCD32FindReplaceText(pFrame, ReplaceText));
}
ULONG
WCD32FindReplaceText(IN PVDMFRAME pFrame,
IN FINDREPLACEPROC Function)
/*++
Routine Description:
This routine is called by WCD32FindText and WCD32RepalceText.
It copies a 16-bit FINDREPLACE structure to a 32-bit structure.
Two per thread data entries are maintained. One is indexed by the
owner hwnd, the other is indexed by the dialog hwnd. The dialog is
always hooked by WCD32FindReplaceDialogProc, which dispatches to the
16-bit hookproc, and takes care of clean-up on WM_DESTROY, with dialog
per thread data providing context. WCD32UpdateFindReplaceTextAndFlags
updates the 16-bit FINDREPLACE structure when called by the WOW message
dispatching logic upon reciept of a WM_NOTIFYWOW message from COMDLG32.
The owner per thread data provides context for this operation.
Arguments:
pFrame - Supplies 16-bit argument frame
Function - supplies a pointer to the 32-bit function to call (either
FindText or RepalceText)
Return Value:
16-bit BOOLEAN to be returned.
--*/
{
register PFINDTEXT16 parg16;
VPFINDREPLACE vpfr;
FINDREPLACE *pFR32;
PFINDREPLACE16 pFR16;
PCOMMDLGTD pTDDlg;
PCOMMDLGTD pTDOwner;
HWND hwndDlg = NULL;
DWORD dwFlags16 = 0;
BOOL fError = FALSE;
GETARGPTR(pFrame, sizeof(FINDREPLACE16), parg16);
vpfr = parg16->lpfr;
SETEXTENDEDERROR(0);
// invalidate this now
FREEVDMPTR( parg16 );
GETVDMPTR(vpfr, sizeof(FINDREPLACE16), pFR16);
WCDDUMPFINDREPLACE16(pFR16);
if(DWORD32(pFR16->lStructSize) != sizeof(FINDREPLACE16)) {
SETEXTENDEDERROR( CDERR_STRUCTSIZE );
FREEVDMPTR(pFR16);
return(0);
}
if(!DWORD32(pFR16->lpstrFindWhat) ||
!WORD32(pFR16->wFindWhatLen) ||
!IsWindow(HWND32(pFR16->hwndOwner))) {
SETEXTENDEDERROR(FRERR_BUFFERLENGTHZERO);
FREEVDMPTR(pFR16);
return(0);
}
// check the hook proc
if(DWORD32(pFR16->Flags) & FR_ENABLEHOOK) {
if(!DWORD32(pFR16->lpfnHook)) {
SETEXTENDEDERROR(CDERR_NOHOOK);
FREEVDMPTR(pFR16);
return(0);
}
}
else {
STOREDWORD(pFR16->lpfnHook, 0);
}
// WCD32UpdateFindReplaceTextAndFlags will update the 16-bit FINDREPLACE
// struct and help thunk the WM_NOTIFYWOW message to the
// "commdlg_FindReplace" registered message.
if (msgFINDREPLACE == 0) {
if(!(msgFINDREPLACE = (WORD)RegisterWindowMessage(FINDMSGSTRING))) {
LOGDEBUG(2,("WCD32FindReplaceText:RegisterWindowMessage failed\n"));
SETEXTENDEDERROR( CDERR_REGISTERMSGFAIL );
FREEVDMPTR(pFR16);
return(0);
}
}
// Allocate the required memory
// Note: these can't be alloc'd off our stack since FindText & ReplaceText
// eventually call CreateDialogIndirectParam which returns immediately
// after displaying the dialog box.
pFR32 = (FINDREPLACE *)malloc_w_zero(sizeof(FINDREPLACE));
if(pFR32) {
pFR32->lpstrFindWhat = (LPTSTR)malloc_w(WORD32(pFR16->wFindWhatLen));
pFR32->lpstrReplaceWith
= (LPTSTR)malloc_w(WORD32(pFR16->wReplaceWithLen));
pTDDlg = malloc_w_zero(sizeof(COMMDLGTD));
pTDOwner = malloc_w_zero(sizeof(COMMDLGTD));
}
if( (pFR32 &&
pFR32->lpstrFindWhat &&
pFR32->lpstrReplaceWith &&
pTDDlg &&
pTDOwner) == FALSE) {
LOGDEBUG(0, ("WCD32FindReplaceText, 32-bit allocation(s) failed!\n"));
SETEXTENDEDERROR(CDERR_MEMALLOCFAILURE);
goto FindReplaceError;
}
pTDDlg->pData32 = pTDOwner->pData32 = (PVOID)pFR32;
pTDDlg->vpData = pTDOwner->vpData = vpfr;
// Set the per thread data indicies
pTDDlg->hdlg = (HWND16)-1;
pTDOwner->hdlg = GETHWND16(pFR16->hwndOwner);
// save the hook proc if any
if(DWORD32(pFR16->Flags) & FR_ENABLEHOOK) {
pTDDlg->vpfnHook = pTDOwner->vpfnHook = DWORD32(pFR16->lpfnHook);
}
ThunkFINDREPLACE16to32(pFR32, pFR16);
dwFlags16 = DWORD32(pFR16->Flags);
// this call invalidates flat ptrs to 16-bit memory
pFR32->hInstance = ThunkCDTemplate16to32(WORD32(pFR16->hInstance),
0,
DWORD32(pFR16->lpTemplateName),
dwFlags16,
&(pFR32->Flags),
FR_ENABLETEMPLATE,
FR_ENABLETEMPLATEHANDLE,
&(PRES)(pTDDlg->pRes),
&fError);
if(fError) {
goto FindReplaceError;
}
// invalidate flat ptrs to 16-bit memory
FREEVDMPTR(pFR16);
WCDDUMPFINDREPLACE32(pFR32);
// Link both per thread data structs into the list
// do this just before calling into comdlg32
pTDDlg->Previous = CURRENTPTD()->CommDlgTd;
pTDOwner->Previous = pTDDlg;
CURRENTPTD()->CommDlgTd = pTDOwner;
// this call invalidates flat ptrs to 16-bit memory
hwndDlg = (*Function)(pFR32);
if (hwndDlg) {
pTDDlg->hdlg = (HWND16)hwndDlg;
} else {
FindReplaceError:
LOGDEBUG(0, ("WCD32FindReplaceText, Failed!\n"));
if(pTDDlg) {
CURRENTPTD()->CommDlgTd = pTDDlg->Previous;
FreeCDTemplate32(pTDDlg->pRes,
pFR32->hInstance,
dwFlags16 & FR_ENABLETEMPLATE,
dwFlags16 & FR_ENABLETEMPLATEHANDLE);
free_w(pTDDlg);
}
if(pFR32) {
if(pFR32->lpstrFindWhat)
free_w(pFR32->lpstrFindWhat);
if(pFR32->lpstrReplaceWith)
free_w(pFR32->lpstrReplaceWith);
free_w(pFR32);
}
if(pTDOwner)
free_w(pTDOwner);
}
return(GETHWND16(hwndDlg));
}
VOID
ThunkFINDREPLACE16to32(OUT FINDREPLACE *pFR32,
IN PFINDREPLACE16 pFR16)
/*++
Routine Description:
This routine thunks a 16-bit FINDREPLACE structure to the 32-bit
structure
Arguments:
pFR32 - Supplies a pointer to the 32-bit FINDREPLACE structure.
pFR16 - Supplies a pointer to the 16-bit FINDREPLACE structure.
Return Value:
None.
--*/
{
LPSTR lpstr;
DWORD Flags;
if(pFR16 && pFR32) {
pFR32->lStructSize = sizeof(FINDREPLACE);
pFR32->hwndOwner = HWND32(pFR16->hwndOwner);
// hInstance is thunked separately
// preserve the template flag state while copying flags
// 1. save template flag state
// note: we never will have a 32-bit FR_ENABLETEMPLATE flag
// 2. copy flags from 16-bit struct (add the WOWAPP flag)
// 3. turn off all template flags
// 4. restore original template flag state
Flags = pFR32->Flags & FR_ENABLETEMPLATEHANDLE;
pFR32->Flags = DWORD32(pFR16->Flags) | CD_WOWAPP;
pFR32->Flags &= ~(FR_ENABLETEMPLATE | FR_ENABLETEMPLATEHANDLE);
pFR32->Flags |= Flags;
GETPSZPTR(pFR16->lpstrFindWhat, lpstr);
if(lpstr && pFR32->lpstrFindWhat) {
WOW32_strncpy(pFR32->lpstrFindWhat, lpstr, WORD32(pFR16->wFindWhatLen));
FREEPSZPTR(lpstr);
}
GETPSZPTR(pFR16->lpstrReplaceWith, lpstr);
if(lpstr && pFR32->lpstrReplaceWith) {
WOW32_strncpy(pFR32->lpstrReplaceWith,
lpstr,
WORD32(pFR16->wReplaceWithLen));
FREEPSZPTR(lpstr);
}
pFR32->wFindWhatLen = WORD32(pFR16->wFindWhatLen);
pFR32->wReplaceWithLen = WORD32(pFR16->wReplaceWithLen);
pFR32->lCustData = DWORD32(pFR16->lCustData);
// we always put this WOW hook in so we can destroy the modeless dialog.
// WCD32FindReplaceDialogPRoc will determine whether to really dispatch
// to a 16-bit hookproc or not. pFR16->lpfnHook will be NULL if there
// isn't a 16-bit hook proc
pFR32->lpfnHook = WCD32FindReplaceDialogProc;
pFR32->Flags |= FR_ENABLEHOOK;
// lpTemplateName32 is thunked separately
}
}
VOID
ThunkFINDREPLACE32to16(OUT PFINDREPLACE16 pFR16,
IN FINDREPLACE *pFR32)
{
LPSTR lpstr;
DWORD Flags, Flags32;
if(pFR16 && pFR32) {
// Update the 16-bit structure.
// preserve the template flag state while copying flags
// 1. save template flag state
// 2. copy flags from 32-bit struct
// 3. turn off all template flags and the WOWAPP flag
// 4. restore original template flag state
Flags = DWORD32(pFR16->Flags) & (FR_ENABLETEMPLATE |
FR_ENABLETEMPLATEHANDLE);
Flags32 = pFR32->Flags;
Flags32 &= ~(FR_ENABLETEMPLATE | FR_ENABLETEMPLATEHANDLE | CD_WOWAPP);
Flags32 |= Flags;
// we may have to turn off the hookproc flag if we added it in
// ThunkFINDREPLACE16to32().
if(!DWORD32(pFR16->lpfnHook)) {
Flags32 &= ~FR_ENABLEHOOK;
}
STOREDWORD(pFR16->Flags, Flags32);
GETPSZPTR(pFR16->lpstrFindWhat, lpstr);
if(lpstr && pFR32->lpstrFindWhat) {
WOW32_strncpy(lpstr, pFR32->lpstrFindWhat, WORD32(pFR16->wFindWhatLen));
FREEPSZPTR(lpstr);
}
GETPSZPTR(pFR16->lpstrReplaceWith, lpstr);
if(lpstr && pFR32->lpstrReplaceWith) {
WOW32_strncpy(lpstr,
pFR32->lpstrReplaceWith,
WORD32(pFR16->wReplaceWithLen));
FREEPSZPTR(lpstr);
}
}
}
LONG APIENTRY
WCD32UpdateFindReplaceTextAndFlags(HWND hwndOwner,
LPARAM lParam)
{
PCOMMDLGTD ptdOwner;
PFINDREPLACE16 pFR16;
VPFINDREPLACE vpfr;
LPFINDREPLACE pFR32 = (LPFINDREPLACE) lParam;
LONG lRet = 0;
ptdOwner = GetCommdlgTd(hwndOwner);
WOW32ASSERT(ptdOwner);
vpfr = ptdOwner->vpData;
GETVDMPTR(vpfr, sizeof(FINDREPLACE16), pFR16);
ThunkFINDREPLACE32to16(pFR16, pFR32);
WCDDUMPFINDREPLACE16(pFR16);
FREEVDMPTR(pFR16);
return(vpfr);
}
PCOMMDLGTD
GetCommdlgTd(IN HWND Hwnd32)
/*++
Routine Description:
Searches the thread's chain of commdlg data for the given 32-bit window.
If the window is not already in the chain, it is added.
Arguments:
Hwnd32 - Supplies the 32-bit hwnd that the dialog procedure was called
with.
Return Value:
Pointer to commdlg data.
--*/
{
PCOMMDLGTD pTD;
if ((pTD = CURRENTPTD()->CommDlgTd) == NULL) {
return(NULL);
}
// look for the CommDlgTD struct for this dialog -- usually will be first
// unless there are nested dialogs
while (pTD->hdlg != GETHWND16(Hwnd32)) {
pTD = pTD->Previous;
// If Hwnd32 isn't in the list, we're probably getting called back
// from user32 via WOWTellWOWThehDlg(). This means that the dialog
// window was just created in user32. Note that this can be either a
// new dialog or a PrintSetup dialog.
if (pTD==NULL) {
pTD = CURRENTPTD()->CommDlgTd;
while (pTD->hdlg != (HWND16)-1) {
// Check to see if this is the first call for a PrintSetupHook.
// It will share the same CommDlgTD as the PrintDlgHook.
// Note: SetupHwnd will be 1 if this is the 1st time the user
// clicks the Setup button in the PrintDlg. Otherwise
// it will be the old Hwnd32 from the previous time he
// clicked the Setup button from within the same instance
// of the PrintDlg. Either way it is non-zero.
if(pTD->SetupHwnd) {
// if the current CommDlgTD->hdlg is the owner of Hwnd32,
// we found the CommDlgTD for the PrintSetup dialog.
if(pTD->hdlg == GETHWND16(GetWindow(Hwnd32, GW_OWNER))) {
pTD->SetupHwnd = GETHWND16(Hwnd32);
return(pTD);
}
}
pTD = pTD->Previous;
if(pTD == NULL) {
WOW32ASSERT(FALSE);
return(NULL);
}
}
// set the hdlg for this CommDlgTD
pTD->hdlg = GETHWND16(Hwnd32);
return(pTD);
}
}
return(pTD);
}
// Thunks 16-bit Common dialog templates to 32-bit
// Note: this calls back to 16-bit code causing possible 16-bit memory movement
// Note: GetTemplate16 call SETEXTENDEDERROR for *most* failures
HINSTANCE
ThunkCDTemplate16to32(IN HAND16 hInst16,
IN DWORD hPT16, // for PrintDlg only
IN VPVOID vpTemplateName,
IN DWORD dwFlags16,
IN OUT DWORD *pFlags,
IN DWORD ETFlag, // XX_ENABLETEMPLATE flag
IN DWORD ETHFlag, // XX_ENABLETEMPLATEHANDLE flag
OUT PPRES pRes,
OUT PBOOL fError)
{
// Note: struct->hInstance == NULL if neither xx_ENABLExxx flag is set
HINSTANCE hInst32 = NULL;
HAND16 hPrintTemp16 = (HAND16)NULL;
SETEXTENDEDERROR( CDERR_NOTEMPLATE ); // most common error ret
if(hPT16) {
hPrintTemp16 = (HAND16)LOWORD(hPT16);
}
*pRes = NULL;
if(dwFlags16 & ETFlag) {
if(!vpTemplateName) {
*fError = TRUE;
return(NULL);
}
if(!hInst16) {
SETEXTENDEDERROR( CDERR_NOHINSTANCE );
*fError = TRUE;
return(NULL);
}
// Note: calls to GetTemplate16 may cause 16-bit memory to move
*pRes = GetTemplate16(hInst16, vpTemplateName, FALSE);
if(*pRes == NULL) {
*fError = TRUE;
return(NULL);
}
hInst32 = (HINSTANCE)LockResource16(*pRes);
if(!hInst32) {
*fError = TRUE;
SETEXTENDEDERROR( CDERR_LOCKRESFAILURE );
return(NULL);
}
*pFlags &= ~ETFlag;
*pFlags |= ETHFlag;
} else if(dwFlags16 & ETHFlag) {
// Win'95 does the following if !hInst && ETHFlag.
// Note: the return val == FALSE in all cases except the last PD case
// CC (0x00040) -> CDERR_NOTEMPLATE
// CF (0x00020) -> No error (comdlg32 err = CDERR_LOCKRESFAILURE)
// FR (0x02000) -> CDERR_LOCKRESFAILURE
// OFN (0x00080) -> CDERR_LOCKRESFAILURE
// PD (0x10000) -> CDERR_LOCKRESFAILURE (hInstance)
// PD (0x20040) -> CDERR_LOCKRESFAILURE (with PD_PRINTSETUP)
// PD (0x20000) -> CDERR_LOCKRESFAILURE
//
// I think the error value is probably irrelavant since most of these
// are pathological cases that only developers would see while building
// and debugging their app. In the cases where the Win'95 error code is
// CDERR_LOCKRESFAILURE, comdlg32 sets it to CDERR_NOTEMPLATE (as we
// now return for WOW) for 32-bit apps
// one of the hTemplate's should always be set with the
// ENABLETEMPLATEHANDLE flag
// if it's a printdlg...
if(hPT16) {
// ...the hTemplate should be in either hPrintTemplate or
// hPrintSetupTemplate
if(!hPrintTemp16) {
*fError = TRUE;
}
}
// else for non-printdlg's, the hTemplate should be in hInstance
else {
if(!hInst16) {
*fError = TRUE;
}
}
if(*fError) {
return(NULL);
}
// Note: calls to GetTemplate16 may cause 16-bit memory to move
if(hPT16) {
hInst32 = (HINSTANCE) GetTemplate16(hPrintTemp16,(VPCSTR)NULL,TRUE);
} else {
hInst32 = (HINSTANCE) GetTemplate16(hInst16, (VPCSTR)NULL, TRUE);
}
if(!hInst32) {
*fError = TRUE;
return(NULL);
}
*pFlags |= ETHFlag;
}
SETEXTENDEDERROR( 0 ); // reset to no error
return(hInst32);
}
VOID
FreeCDTemplate32(IN PRES pRes,
IN HINSTANCE hInst,
IN BOOL bETFlag,
IN BOOL bETHFlag)
{
if(pRes && bETFlag) {
UnlockResource16(pRes);
FreeResource16(pRes);
} else if(hInst && bETHFlag) {
free_w((PVOID)hInst);
}
}
PRES
GetTemplate16(IN HAND16 hInstance,
IN VPCSTR lpTemplateName,
IN BOOLEAN UseHandle)
/*++
Routine Description:
Finds and loads the specified 16-bit dialog template.
WARNING: This may cause memory movement, invalidating flat pointers
Arguments:
hInstance - Supplies the data block containing the dialog box template
TemplateName - Supplies the name of the resource file for the dialog
box template. This may be either a null-terminated string or
a numbered resource created with the MAKEINTRESOURCE macro.
UseHandle - Indicates that hInstance identifies a pre-loaded dialog
box template. If this is TRUE, Templatename is ignored.
Return Value:
success - A pointer to the loaded resource
failure - NULL, dwLastError will be set.
--*/
{
LPSZ TemplateName=NULL;
PRES pRes;
PBYTE pDlg = NULL;
INT cb;
INT cb16;
if (!UseHandle) {
GETPSZIDPTR(lpTemplateName, TemplateName);
// Both custom instance handle and the dialog template name are
// specified. Locate the 16-bit dialog resource in the specified
// instance block and load it.
pRes = FindResource16(hInstance,
TemplateName,
(LPSZ)RT_DIALOG);
if (HIWORD(lpTemplateName) != 0) {
FREEVDMPTR(TemplateName);
}
if (!pRes) {
SETEXTENDEDERROR( CDERR_FINDRESFAILURE );
return(NULL);
}
if (!(pRes = LoadResource16(hInstance,pRes))) {
SETEXTENDEDERROR( CDERR_LOADRESFAILURE );
return(NULL);
}
return(pRes);
} else {
VPVOID pDlg16;
if (pDlg16 = RealLockResource16(hInstance, &cb16)) {
cb = ConvertDialog16(NULL, pDlg16, 0, cb16);
if (cb != 0) {
if (pDlg = malloc_w(cb)) {
ConvertDialog16(pDlg, pDlg16, cb, cb16);
}
}
GlobalUnlock16(hInstance);
}
else {
SETEXTENDEDERROR( CDERR_LOCKRESFAILURE );
}
return((PRES)pDlg);
}
}
// When an app calls a ComDlg API it passes a ptr to the appropriate structure.
// On Win3.1 the app & the system share a ptr to the same structure, so when
// either updates the struct, the other is aware of the change. On NT we thunk
// the 16-bit struct to a 32-bit ANSI struct which is then thunked to a 32-bit
// UNICODE struct by the ComDlg32 code. We need a mechanism to put all three
// structs in sync. We attempt to do this by calling ThunkCDStruct32to16()
// from the WCD32xxxxDialogProc()'s (xxxx = Common OR FindReplace) for
// WM_INITDIALOG and WM_COMMAND messages before we callback the 16-bit hook
// proc. We call ThunkCDStruct16to32() when we return from the 16-bit hook.
VOID
ThunkCDStruct16to32(IN HWND hDlg,
IN CHOOSECOLOR *p32,
IN VPVOID vp)
{
PCHOOSECOLORDATA16 p16;
GETVDMPTR(vp, sizeof(CHOOSECOLORDATA16), p16);
if(p16) {
switch(p16->lStructSize) {
case sizeof(CHOOSECOLORDATA16):
ThunkCHOOSECOLOR16to32(p32, p16);
Ssync_ANSI_UNICODE_Struct_For_WOW(hDlg, TRUE, WOW_CHOOSECOLOR);
break;
case sizeof(CHOOSEFONTDATA16):
ThunkCHOOSEFONT16to32((CHOOSEFONT *) p32,
(PCHOOSEFONTDATA16) p16);
Ssync_ANSI_UNICODE_Struct_For_WOW(hDlg, TRUE, WOW_CHOOSEFONT);
break;
case sizeof(FINDREPLACE16):
ThunkFINDREPLACE16to32((FINDREPLACE *) p32,
(PFINDREPLACE16) p16);
// Find/Replace ANSI-UNICODE sync's are handled by
// WCD32UpdateFindReplaceTextAndFlags() mechanism
break;
case sizeof(OPENFILENAME16):
ThunkOPENFILENAME16to32((OPENFILENAME *) p32,
(POPENFILENAME16) p16);
Ssync_ANSI_UNICODE_Struct_For_WOW(hDlg, TRUE, WOW_OPENFILENAME);
break;
case sizeof(PRINTDLGDATA16):
ThunkPRINTDLG16to32((PRINTDLG *) p32, (PPRINTDLGDATA16) p16);
Ssync_ANSI_UNICODE_Struct_For_WOW(hDlg, TRUE, WOW_PRINTDLG);
break;
}
FREEVDMPTR(p16);
}
}
VOID
ThunkCDStruct32to16(IN HWND hDlg,
IN VPVOID vp,
IN CHOOSECOLOR *p32)
{
PCHOOSECOLORDATA16 p16;
GETVDMPTR(vp, sizeof(CHOOSECOLORDATA16), p16);
if(p16) {
switch(p16->lStructSize) {
case sizeof(CHOOSECOLORDATA16):
Ssync_ANSI_UNICODE_Struct_For_WOW(hDlg, FALSE, WOW_CHOOSECOLOR);
ThunkCHOOSECOLOR32to16(p16, p32);
break;
case sizeof(CHOOSEFONTDATA16):
Ssync_ANSI_UNICODE_Struct_For_WOW(hDlg, FALSE, WOW_CHOOSEFONT);
ThunkCHOOSEFONT32to16((PCHOOSEFONTDATA16) p16,
(CHOOSEFONT *) p32);
break;
case sizeof(FINDREPLACE16):
// Find/Replace ANSI-UNICODE sync's are handled by
// WCD32UpdateFindReplaceTextAndFlags() mechanism
ThunkFINDREPLACE32to16((PFINDREPLACE16) p16,
(FINDREPLACE *) p32);
break;
case sizeof(OPENFILENAME16):
Ssync_ANSI_UNICODE_Struct_For_WOW(hDlg, FALSE, WOW_OPENFILENAME);
ThunkOPENFILENAME32to16((POPENFILENAME16) p16,
(OPENFILENAME *) p32,
TRUE);
break;
case sizeof(PRINTDLGDATA16):
Ssync_ANSI_UNICODE_Struct_For_WOW(hDlg, FALSE, WOW_PRINTDLG);
ThunkPRINTDLG32to16(vp, (PRINTDLG *) p32);
break;
}
FREEVDMPTR(p16);
}
}
VOID Multi_strcpy(LPSTR dst, LPCSTR src)
/*++
strcpy for string lists that have several strings that are separated by
a null char and is terminated by two NULL chars.
--*/
{
if(src && dst) {
while(*src) {
while(*dst++ = *src++)
;
}
*dst = '\0';
}
}
INT Multi_strlen(LPCSTR str)
/*++
strlen for string lists that have several strings that are separated by
a null char and is terminated by two NULL chars.
Returns len of str including all NULL *separators* but not the 2nd NULL
terminator. ie. cat0dog00 would return len = 8;
--*/
{
INT i = 0;
if(str) {
while(*str) {
while(*str++)
i++;
i++; // count the NULL separator
}
}
return(i);
}
VOID Ssync_WOW_CommDlg_Structs(PCOMMDLGTD pTDIn,
BOOL f16to32,
DWORD dwThunkCSIP)
{
HWND hDlg;
WORD wCS16;
PCOMMDLGTD pTDPrev;
PCOMMDLGTD pTD = pTDIn;
// we shouldn't sync for calls from krnl386 into wow32 (we found out)
// eg. when kernel is handling segment not present faults etc.
if(dwThunkCSIP) {
wCS16 = HIWORD(dwThunkCSIP);
if((wCS16 == gwKrnl386CodeSeg1) ||
(wCS16 == gwKrnl386CodeSeg2) ||
(wCS16 == gwKrnl386CodeSeg3)) {
return;
}
}
// since we don't have an hwnd to compare with we really don't know which
// PCOMMDLGTD is the one we want -- so we have to sync them all.
// This is only a problem for nested dialogs which is fairly rare.
while(pTD) {
// if this hasn't been initialized yet there is nothing to do
if(pTD->hdlg == (HWND16)-1) {
break;
}
hDlg = HWND32(pTD->hdlg);
WOW32ASSERTMSG(hDlg,
("WOW:Ssync_WOW_CommDlg_Structs: hDlg not found!\n"));
//BlockWOWIdle(TRUE);
if(f16to32) {
ThunkCDStruct16to32(hDlg, (CHOOSECOLOR *)pTD->pData32, pTD->vpData);
}
else {
ThunkCDStruct32to16(hDlg, pTD->vpData, (CHOOSECOLOR *)pTD->pData32);
}
//BlockWOWIdle(FALSE);
pTDPrev = pTD->Previous;
// multiple PCOMMDLGTD's in the list means 1 of 2 things:
// 1. This is a find/replace text dialog
// 2. This is a screwy nested dialog situation
if(pTDPrev) {
// 1. check for find/replace (it uses two PCOMMDLGTD structs and
// shares the same pData32 pointer with both)
if(pTDPrev->pData32 == pTD->pData32) {
// nothing to do -- they share the same data which was thunked
// above so we'll go on to the next PCOMMDLGTD in the list
pTD = pTDPrev->Previous;
}
// 2. there are nested dialogs lurking about & we need to sync
// each one!
else {
pTD = pTDPrev;
}
} else {
break;
}
}
}
// There is a special case issue (we found) where certain dialog box
// API calls can pass a pszptr that is in a common dialog struct ie:
// GetDlgItemText(hDlg, id, OFN16->lpstrFile, size). Our synchronization
// mechanism actually trashes OFN16->lpstrFile when we sync 32->16 upon
// returning from the API call. To avoid this we will sync 16->32 upon
// returning from the API call (if needed as per the conditions below)
// before we sync 32->16 thus preserving the string returned in the 16-bit
// buffer. The special case API's identified so far are:
// GetDlgItemText, GetWindowText(), DlgDirSelectxxxx, and SendDlgItemMessage.
VOID Check_ComDlg_pszptr(PCOMMDLGTD ptd, VPVOID vp)
{
VPVOID vpData;
POPENFILENAME16 p16;
if(ptd) {
vpData = ptd->vpData;
if(vpData) {
GETVDMPTR(vpData, sizeof(CHOOSECOLORDATA16), p16);
if(p16) {
switch(p16->lStructSize) {
// Only these 2 ComDlg structures have OUTPUT buffers.
case sizeof(CHOOSEFONTDATA16):
if((VPVOID)((PCHOOSEFONTDATA16)p16)->lpszStyle == vp) {
Ssync_WOW_CommDlg_Structs(ptd, w16to32, 0);
}
break;
case sizeof(OPENFILENAME16):
if(((VPVOID)p16->lpstrFilter == vp) ||
((VPVOID)p16->lpstrCustomFilter == vp) ||
((VPVOID)p16->lpstrFile == vp) ||
((VPVOID)p16->lpstrFileTitle == vp) ||
((VPVOID)p16->lpstrInitialDir == vp) ||
((VPVOID)p16->lpstrTitle == vp) ||
((VPVOID)p16->lpstrDefExt == vp)) {
Ssync_WOW_CommDlg_Structs(ptd, w16to32, 0);
}
break;
} // end switch
}
}
}
}
VOID FASTCALL WOWTellWOWThehDlg(HWND hDlg)
{
if(CURRENTPTD()->CommDlgTd) {
if(GetCommdlgTd(hDlg) == NULL) {
WOW32WARNMSGF(FALSE,
("WOW::WOWTellWOWThehDlg: No unassigned hDlgs\n"));
}
}
}
#ifdef DEBUG
void WCDDumpCHOOSECOLORData16(PCHOOSECOLORDATA16 p16)
{
if (fLogFilter & FILTER_COMMDLG) {
LOGDEBUG(10, ("CHOOSECOLORDATA16:\n"));
LOGDEBUG(10, ("\tlStructSize = %x\n",(p16)->lStructSize));
LOGDEBUG(10, ("\thwndOwner = %lx\n",(p16)->hwndOwner));
LOGDEBUG(10, ("\thInstance = %lx\n",(p16)->hInstance));
LOGDEBUG(10, ("\trgbResult = %lx\n",(p16)->rgbResult));
LOGDEBUG(10, ("\tlpCustColors = %lx\n",(p16)->lpCustColors));
LOGDEBUG(10, ("\tFlags = %lx\n",(p16)->Flags));
LOGDEBUG(10, ("\tlCustData = %lx\n",(p16)->lCustData));
LOGDEBUG(10, ("\tlpfnHook = %lx\n",(p16)->lpfnHook));
LOGDEBUG(10, ("\tlpTemplateName = %lx\n",(p16)->lpTemplateName));
}
}
void WCDDumpCHOOSECOLORData32(CHOOSECOLOR *p32)
{
if (fLogFilter & FILTER_COMMDLG) {
LOGDEBUG(10, ("CHOOSECOLORDATA32:\n"));
LOGDEBUG(10, ("\tlStructSize = %x\n",(p32)->lStructSize));
LOGDEBUG(10, ("\thwndOwner = %lx\n",(p32)->hwndOwner));
LOGDEBUG(10, ("\thInstance = %lx\n",(p32)->hInstance));
LOGDEBUG(10, ("\trgbResult = %lx\n",(p32)->rgbResult));
LOGDEBUG(10, ("\tlpCustColors = %lx\n",(p32)->lpCustColors));
LOGDEBUG(10, ("\tFlags = %lx\n",(p32)->Flags));
LOGDEBUG(10, ("\tlCustData = %lx\n",(p32)->lCustData));
LOGDEBUG(10, ("\tlpfnHook = %lx\n",(p32)->lpfnHook));
LOGDEBUG(10, ("\tlpTemplateName = %lx\n",(p32)->lpTemplateName));
}
}
void WCDDumpCHOOSEFONTData16(PCHOOSEFONTDATA16 p16)
{
if (fLogFilter & FILTER_COMMDLG) {
LOGDEBUG(10, ("CHOOSEFONT16:\n"));
LOGDEBUG(10, ("\tlStructSize = %lx\n",(p16)->lStructSize));
LOGDEBUG(10, ("\thwndOwner = %lx\n",(p16)->hwndOwner));
LOGDEBUG(10, ("\thDC = %lx\n",(p16)->hDC));
LOGDEBUG(10, ("\tlpLogFont = %lx\n",(p16)->lpLogFont));
LOGDEBUG(10, ("\tiPointSize = %x\n",(p16)->iPointSize));
LOGDEBUG(10, ("\tiFlags = %lx\n",(p16)->Flags));
LOGDEBUG(10, ("\trbgColors = %lx\n",(p16)->rgbColors));
LOGDEBUG(10, ("\tlCustData = %lx\n",(p16)->lCustData));
LOGDEBUG(10, ("\tlpfnHook = %lx\n",(p16)->lpfnHook));
LOGDEBUG(10, ("\tlpTemplateName= %lx\n",(p16)->lpTemplateName));
LOGDEBUG(10, ("\thInstance = %lx\n",(p16)->hInstance));
LOGDEBUG(10, ("\tlpszStyle = %lx\n",(p16)->lpszStyle));
LOGDEBUG(10, ("\tnFontType = %x\n",(p16)->nFontType));
LOGDEBUG(10, ("\tnSizeMin = %x\n",(p16)->nSizeMin));
LOGDEBUG(10, ("\tnSizeMax = %x\n",(p16)->nSizeMax));
}
}
void WCDDumpCHOOSEFONTData32(CHOOSEFONT *p32)
{
if (fLogFilter & FILTER_COMMDLG) {
LOGDEBUG(10, ("CHOOSEFONT32:\n"));
LOGDEBUG(10, ("\tlStructSize = %lx\n",(p32)->lStructSize));
LOGDEBUG(10, ("\thwndOwner = %lx\n",(p32)->hwndOwner));
LOGDEBUG(10, ("\thDC = %lx\n",(p32)->hDC));
LOGDEBUG(10, ("\tlpLogFont = %lx\n",(p32)->lpLogFont));
LOGDEBUG(10, ("\tiPointSize = %lx\n",(p32)->iPointSize));
LOGDEBUG(10, ("\tiFlags = %lx\n",(p32)->Flags));
LOGDEBUG(10, ("\trbgColors = %lx\n",(p32)->rgbColors));
LOGDEBUG(10, ("\tlCustData = %lx\n",(p32)->lCustData));
LOGDEBUG(10, ("\tlpfnHook = %lx\n",(p32)->lpfnHook));
LOGDEBUG(10, ("\tlpTemplateName= %lx\n",(p32)->lpTemplateName));
LOGDEBUG(10, ("\thInstance = %lx\n",(p32)->hInstance));
LOGDEBUG(10, ("\tlpszStyle = %lx\n",(p32)->lpszStyle));
LOGDEBUG(10, ("\tnFontType = %x\n",(p32)->nFontType));
LOGDEBUG(10, ("\tnSizeMin = %lx\n",(p32)->nSizeMin));
LOGDEBUG(10, ("\tnSizeMax = %lx\n",(p32)->nSizeMax));
}
}
void WCDDumpFINDREPLACE16(PFINDREPLACE16 p16)
{
if (fLogFilter & FILTER_COMMDLG) {
LOGDEBUG(10, ("FINDREPLACE16:\n"));
LOGDEBUG(10, ("\tlStructSize = %lx\n",(p16)->lStructSize));
LOGDEBUG(10, ("\thwndOwner = %x\n",(p16)->hwndOwner));
LOGDEBUG(10, ("\thInstance = %x\n",(p16)->hInstance));
LOGDEBUG(10, ("\tFlags = %x\n",(p16)->Flags));
LOGDEBUG(10, ("\tlpstrFindWhat = %lx\n",(p16)->lpstrFindWhat));
LOGDEBUG(10, ("\tlpstrReplaceWith = %lx\n",(p16)->lpstrReplaceWith));
LOGDEBUG(10, ("\twFindWhatLen = %x\n",(p16)->wFindWhatLen));
LOGDEBUG(10, ("\twReplaceWithLen = %x\n",(p16)->wReplaceWithLen));
LOGDEBUG(10, ("\tlCustData = %lx\n",(p16)->lCustData));
LOGDEBUG(10, ("\tlpfnHook = %lx\n",(p16)->lpfnHook));
LOGDEBUG(10, ("\tlpTemplateName= %lx\n",(p16)->lpTemplateName));
}
}
void WCDDumpFINDREPLACE32(FINDREPLACE *p32)
{
if (fLogFilter & FILTER_COMMDLG) {
LOGDEBUG(10, ("FINDREPLACE32:\n"));
LOGDEBUG(10, ("\tlStructSize = %lx\n",(p32)->lStructSize));
LOGDEBUG(10, ("\thwndOwner = %x\n",(p32)->hwndOwner));
LOGDEBUG(10, ("\thInstance = %x\n",(p32)->hInstance));
LOGDEBUG(10, ("\tFlags = %x\n",(p32)->Flags));
LOGDEBUG(10, ("\tlpstrFindWhat = %s\n",(p32)->lpstrFindWhat));
LOGDEBUG(10, ("\tlpstrReplaceWith = %s\n",(p32)->lpstrReplaceWith));
LOGDEBUG(10, ("\twFindWhatLen = %x\n",(p32)->wFindWhatLen));
LOGDEBUG(10, ("\twReplaceWithLen = %x\n",(p32)->wReplaceWithLen));
LOGDEBUG(10, ("\tlCustData = %lx\n",(p32)->lCustData));
LOGDEBUG(10, ("\tlpfnHook = %lx\n",(p32)->lpfnHook));
LOGDEBUG(10, ("\tlpTemplateName= %lx\n",(p32)->lpTemplateName));
}
}
void WCDDumpOPENFILENAME16(POPENFILENAME16 p16)
{
if (fLogFilter & FILTER_COMMDLG) {
LOGDEBUG(10, ("OPENFILENAME16:\n"));
LOGDEBUG(10, ("\tlStructSize = %x\n",(p16)->lStructSize));
LOGDEBUG(10, ("\thwndOwner = %lx\n",(p16)->hwndOwner));
LOGDEBUG(10, ("\thInstance = %lx\n",(p16)->hInstance));
LOGDEBUG(10, ("\tlpstrFilter = %lx\n",(p16)->lpstrFilter));
LOGDEBUG(10, ("\tlpstrCustomFilter= %lx\n",(p16)->lpstrCustomFilter));
LOGDEBUG(10, ("\tnMaxCustFilter = %lx\n",(p16)->nMaxCustFilter));
LOGDEBUG(10, ("\tnFilterIndex = %lx\n",(p16)->nFilterIndex));
LOGDEBUG(10, ("\tlpstrFile = %lx\n",(p16)->lpstrFile));
LOGDEBUG(10, ("\tnMaxFile = %lx\n",(p16)->nMaxFile));
LOGDEBUG(10, ("\tlpstrFileTitle = %lx\n",(p16)->lpstrFileTitle));
LOGDEBUG(10, ("\tnMaxFileTitle = %lx\n",(p16)->nMaxFileTitle));
LOGDEBUG(10, ("\tlpstrInitialDir = %lx\n",(p16)->lpstrInitialDir));
LOGDEBUG(10, ("\tlpstrTitle = %lx\n",(p16)->lpstrTitle));
LOGDEBUG(10, ("\tFlags = %lx\n",(p16)->Flags));
LOGDEBUG(10, ("\tnFileOffset = %lx\n",(p16)->nFileOffset));
LOGDEBUG(10, ("\tnFileExtension = %lx\n",(p16)->nFileExtension));
LOGDEBUG(10, ("\tlpstrDefExt = %lx\n",(p16)->lpstrDefExt));
LOGDEBUG(10, ("\tlCustData = %lx\n",(p16)->lCustData));
LOGDEBUG(10, ("\tlpfnHook = %lx\n",(p16)->lpfnHook));
LOGDEBUG(10, ("\tlpTemplateName = %lx\n",(p16)->lpTemplateName));
}
}
void WCDDumpOPENFILENAME32(OPENFILENAME *p32)
{
if (fLogFilter & FILTER_COMMDLG) {
LOGDEBUG(10, ("OPENFILENAME32:\n"));
LOGDEBUG(10, ("\tlStructSize = %x\n",(p32)->lStructSize));
LOGDEBUG(10, ("\thwndOwner = %lx\n",(p32)->hwndOwner));
LOGDEBUG(10, ("\thInstance = %lx\n",(p32)->hInstance));
LOGDEBUG(10, ("\tlpstrFilter = %s\n",(p32)->lpstrFilter));
LOGDEBUG(10, ("\tlpstrCustomFilter= %s\n",(p32)->lpstrCustomFilter));
LOGDEBUG(10, ("\tnMaxCustFilter = %lx\n",(p32)->nMaxCustFilter));
LOGDEBUG(10, ("\tnFilterIndex = %lx\n",(p32)->nFilterIndex));
LOGDEBUG(10, ("\tlpstrFile = %s\n",(p32)->lpstrFile));
LOGDEBUG(10, ("\tnMaxFile = %lx\n",(p32)->nMaxFile));
LOGDEBUG(10, ("\tlpstrFileTitle = %s\n",(p32)->lpstrFileTitle));
LOGDEBUG(10, ("\tnMaxFileTitle = %lx\n",(p32)->nMaxFileTitle));
LOGDEBUG(10, ("\tlpstrInitialDir = %s\n",(p32)->lpstrInitialDir));
LOGDEBUG(10, ("\tlpstrTitle = %s\n",(p32)->lpstrTitle));
LOGDEBUG(10, ("\tFlags = %lx\n",(p32)->Flags));
LOGDEBUG(10, ("\tnFileOffset = %lx\n",(p32)->nFileOffset));
LOGDEBUG(10, ("\tnFileExtension = %lx\n",(p32)->nFileExtension));
LOGDEBUG(10, ("\tlpstrDefExt = %s\n",(p32)->lpstrDefExt));
LOGDEBUG(10, ("\tlCustData = %lx\n",(p32)->lCustData));
LOGDEBUG(10, ("\tlpfnHook = %lx\n",(p32)->lpfnHook));
LOGDEBUG(10, ("\tlpTemplateName = %lx\n",(p32)->lpTemplateName));
}
}
void WCDDumpPRINTDLGData16(PPRINTDLGDATA16 p16)
{
if (fLogFilter & FILTER_COMMDLG) {
LOGDEBUG(10, ("PRINTDLGData16:\n"));
LOGDEBUG(10, ("\tlStructSize = %x\n",(p16)->lStructSize));
LOGDEBUG(10, ("\thwndOwner = %lx\n",(p16)->hwndOwner));
LOGDEBUG(10, ("\thDevMode = %lx\n",(p16)->hDevMode));
LOGDEBUG(10, ("\thDevNames = %lx\n",(p16)->hDevNames));
LOGDEBUG(10, ("\thDC = %lx\n",(p16)->hDC));
LOGDEBUG(10, ("\tFlags = %lx\n",(p16)->Flags));
LOGDEBUG(10, ("\tnFromPage = %d\n",(p16)->nFromPage));
LOGDEBUG(10, ("\tnToPage = %d\n",(p16)->nToPage));
LOGDEBUG(10, ("\tnMinPage = %d\n",(p16)->nMinPage));
LOGDEBUG(10, ("\tnMaxPage = %d\n",(p16)->nMaxPage));
LOGDEBUG(10, ("\tnCopies = %d\n",(p16)->nCopies));
LOGDEBUG(10, ("\thInstance = %lx\n",(p16)->hInstance));
LOGDEBUG(10, ("\tlCustData = %lx\n",(p16)->lCustData));
LOGDEBUG(10, ("\tlpfnPrintHook = %lx\n",(p16)->lpfnPrintHook));
LOGDEBUG(10, ("\tlpfnSetupHook = %lx\n",(p16)->lpfnSetupHook));
LOGDEBUG(10, ("\tlpPrintTemplateName = %lx\n",(p16)->lpPrintTemplateName));
LOGDEBUG(10, ("\tlpSetupTemplateName = %lx\n",(p16)->lpSetupTemplateName));
LOGDEBUG(10, ("\thPrintTemplate = %lx\n",(p16)->hPrintTemplate));
LOGDEBUG(10, ("\thSetupTemplate = %lx\n",(p16)->hSetupTemplate));
}
}
void WCDDumpPRINTDLGData32(PRINTDLG *p32)
{
if (fLogFilter & FILTER_COMMDLG) {
LOGDEBUG(10, ("PRINTDLGData32:\n"));
LOGDEBUG(10, ("\tlStructSize = %x\n",(p32)->lStructSize));
LOGDEBUG(10, ("\thwndOwner = %lx\n",(p32)->hwndOwner));
LOGDEBUG(10, ("\thDevMode = %lx\n",(p32)->hDevMode));
LOGDEBUG(10, ("\thDevNames = %lx\n",(p32)->hDevNames));
LOGDEBUG(10, ("\thDC = %lx\n",(p32)->hDC));
LOGDEBUG(10, ("\tFlags = %lx\n",(p32)->Flags));
LOGDEBUG(10, ("\tnFromPage = %d\n",(p32)->nFromPage));
LOGDEBUG(10, ("\tnToPage = %d\n",(p32)->nToPage));
LOGDEBUG(10, ("\tnMinPage = %d\n",(p32)->nMinPage));
LOGDEBUG(10, ("\tnMaxPage = %d\n",(p32)->nMaxPage));
LOGDEBUG(10, ("\tnCopies = %d\n",(p32)->nCopies));
LOGDEBUG(10, ("\thInstance = %lx\n",(p32)->hInstance));
LOGDEBUG(10, ("\tlCustData = %lx\n",(p32)->lCustData));
LOGDEBUG(10, ("\tlpfnPrintHook = %lx\n",(p32)->lpfnPrintHook));
LOGDEBUG(10, ("\tlpfnSetupHook = %lx\n",(p32)->lpfnSetupHook));
LOGDEBUG(10, ("\tlpPrintTemplateName = %lx\n",(p32)->lpPrintTemplateName));
LOGDEBUG(10, ("\tlpSetupTemplateName = %lx\n",(p32)->lpSetupTemplateName));
LOGDEBUG(10, ("\thPrintTemplate = %lx\n",(p32)->hPrintTemplate));
LOGDEBUG(10, ("\thSetupTemplate = %lx\n",(p32)->hSetupTemplate));
}
}
#endif // DEBUG