3875 lines
114 KiB
C
3875 lines
114 KiB
C
|
/*++
|
|||
|
|
|||
|
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
|