summaryrefslogtreecommitdiffstats
path: root/private/mvdm/fax
diff options
context:
space:
mode:
Diffstat (limited to 'private/mvdm/fax')
-rw-r--r--private/mvdm/fax/dirs6
-rw-r--r--private/mvdm/fax/dummy.hlp1
-rw-r--r--private/mvdm/fax/dummy.ppd1
-rw-r--r--private/mvdm/fax/faxcomm.h64
-rw-r--r--private/mvdm/fax/printer.inf293
-rw-r--r--private/mvdm/fax/wowfax/makefile6
-rw-r--r--private/mvdm/fax/wowfax/sources47
-rw-r--r--private/mvdm/fax/wowfax/wowfax.c461
-rw-r--r--private/mvdm/fax/wowfax/wowfax.def10
-rw-r--r--private/mvdm/fax/wowfax/wowfax.rc12
-rw-r--r--private/mvdm/fax/wowfax/wowfaxdd.h44
-rw-r--r--private/mvdm/fax/wowfaxui/makefile6
-rw-r--r--private/mvdm/fax/wowfaxui/sources60
-rw-r--r--private/mvdm/fax/wowfaxui/wfhelper.c467
-rw-r--r--private/mvdm/fax/wowfaxui/wfsheets.c405
-rw-r--r--private/mvdm/fax/wowfaxui/wfsheets.h33
-rw-r--r--private/mvdm/fax/wowfaxui/wfupgrad.c264
-rw-r--r--private/mvdm/fax/wowfaxui/wowfaxui.c874
-rw-r--r--private/mvdm/fax/wowfaxui/wowfaxui.def16
-rw-r--r--private/mvdm/fax/wowfaxui/wowfaxui.h164
-rw-r--r--private/mvdm/fax/wowfaxui/wowfaxui.rc45
21 files changed, 3279 insertions, 0 deletions
diff --git a/private/mvdm/fax/dirs b/private/mvdm/fax/dirs
new file mode 100644
index 000000000..1545125c6
--- /dev/null
+++ b/private/mvdm/fax/dirs
@@ -0,0 +1,6 @@
+
+DIRS=wowfax \
+ wowfaxui
+
+OPTIONAL_DIRS=
+
diff --git a/private/mvdm/fax/dummy.hlp b/private/mvdm/fax/dummy.hlp
new file mode 100644
index 000000000..4d6a3b44f
--- /dev/null
+++ b/private/mvdm/fax/dummy.hlp
@@ -0,0 +1 @@
+ECHO is on.
diff --git a/private/mvdm/fax/dummy.ppd b/private/mvdm/fax/dummy.ppd
new file mode 100644
index 000000000..4d6a3b44f
--- /dev/null
+++ b/private/mvdm/fax/dummy.ppd
@@ -0,0 +1 @@
+ECHO is on.
diff --git a/private/mvdm/fax/faxcomm.h b/private/mvdm/fax/faxcomm.h
new file mode 100644
index 000000000..df4d7bc05
--- /dev/null
+++ b/private/mvdm/fax/faxcomm.h
@@ -0,0 +1,64 @@
+//************************************************************************
+// Common header file for generic Win 3.1 fax printer driver support.
+//
+// History:
+// 02-jan-95 nandurir created.
+// 01-feb-95 reedb Clean-up, support printer install and bug fixes.
+// 14-mar-95 reedb Use GDI hooks to move most functionality to UI.
+// 16-aug-95 reedb Move to kernel mode. Move many declarations and
+// definitions to WOWFAXDD.H and WOWFAXUI.H.
+//
+//************************************************************************
+
+#include "wowfax.h"
+
+// The following structure ID appears as wfax when dumping byte (db) a FAXDEV:
+#define FAXDEV_ID ((DWORD)'xafw')
+
+//
+// This structure is shared between wowfax and wowfaxui - this keeps
+// the interface reliable, consistent and easy to maintain
+//
+
+typedef struct _FAXDEV {
+ ULONG id; // String to verify what we have
+ struct _FAXDEV *lpNext;
+ struct _FAXDEV *lpClient; // Pointer to client side FAXDEV
+ HDEV hdev; // Engine's handle to this structure
+
+ DWORD idMap; // Unique ID
+ DWORD cbMapLow; // Loword of size of mapped area
+ HANDLE hMap; // Handle to mapped file
+ TCHAR szMap[16]; // Name of mapped file
+
+ LPWOWFAXINFO lpMap;
+ DWORD offbits;
+
+ HBITMAP hbm; // Handle to bitmap for drawing
+ DWORD cPixPerByte;
+ DWORD bmFormat;
+ DWORD bmWidthBytes;
+ HSURF hbmSurf; // Associated surface
+
+ HWND hwnd;
+ DWORD tid;
+ DWORD lpinfo16;
+
+ HANDLE hDriver; // For access to spooler data
+ GDIINFO gdiinfo;
+ DEVINFO devinfo;
+ PDEVMODE pdevmode;
+} FAXDEV, *LPFAXDEV;
+
+// Macro to dword align for RISC
+//#define DRVFAX_DWORDALIGN(dw) ((dw) += ((dw) % 4) ? (4 - ((dw) % 4)) : 0)
+#define DRVFAX_DWORDALIGN(dw) ((dw) = (((dw) + 3) & ~3))
+
+// DrvEscape escape/action codes:
+
+#define DRV_ESC_GET_FAXDEV_PTR 0x8000
+#define DRV_ESC_GET_DEVMODE_PTR 0x8001
+#define DRV_ESC_GET_BITMAP_BITS 0x8002
+#define DRV_ESC_GET_SURF_INFO 0x8003
+
+
diff --git a/private/mvdm/fax/printer.inf b/private/mvdm/fax/printer.inf
new file mode 100644
index 000000000..74909297c
--- /dev/null
+++ b/private/mvdm/fax/printer.inf
@@ -0,0 +1,293 @@
+[Identification]
+ OptionType = PRINTER
+[Options]
+" Windows 3.1 Compatible Fax Driver" = wowfaxui, wowfax, wowfax
+[Identify]
+ read-syms Identification
+ set Status = STATUS_SUCCESSFUL
+ set Identifier = $(OptionType)
+ set Media = #("Source Media Descriptions", 1, 1)
+ Return $(Status) $(Identifier) $(Media)
+[ReturnOptions]
+ set Status = STATUS_FAILED
+ set OptionList = {}
+ set OptionTextList = {}
+ set LanguageList = ^(LanguagesSupported, 1)
+ Ifcontains(i) $($0) in $(LanguageList)
+ goto returnoptions
+ else
+ set Status = STATUS_NOLANGUAGE
+ goto finish_ReturnOptions
+ endif
+returnoptions = +
+ set OptionList = ^(Options, 0)
+ set OptionTextList = ^(OptionsText$($0), 1)
+ set Status = STATUS_SUCCESSFUL
+finish_ReturnOptions = +
+ Return $(Status) $(OptionList) $(OptionTextList)
+[InstallOption]
+ set Status = STATUS_FAILED
+ set Option = $($1)
+ set SrcDir = $($2)
+ set AddCopy = $($3)
+ set DoCopy = $($4)
+ set DoConfig = $($5)
+ set LanguageList = ^(LanguagesSupported, 1)
+ Ifcontains(i) $($0) in $(LanguageList)
+ else
+ set Status = STATUS_NOLANGUAGE
+ goto finish_InstallOption
+ endif
+ read-syms Strings$($0)
+ set OptionList = ^(Options, 0)
+ ifcontains $(Option) in $(OptionList)
+ else
+ goto finish_InstallOption
+ endif
+ set OptionList = ""
+ set ConfigOption = #(Options, $(Option), 1)
+ set DataOption = #(Options, $(Option), 2)
+ set DriverOption = #(Options, $(Option), 3)
+installtheoption = +
+ ifstr(i) $(AddCopy) == "YES"
+ install Install-AddCopyOption
+ ifstr(i) $(STF_INSTALL_OUTCOME) != "STF_SUCCESS"
+ Debug-Output "Adding video files to copy list failed"
+ goto finish_InstallOption
+ endif
+ endif
+ ifstr(i) $(DoCopy) == "YES"
+ read-syms ProgressCopy$($0)
+ install Install-DoCopyOption
+ ifstr(i) $(STF_INSTALL_OUTCOME) == "STF_FAILURE"
+ Debug-Output "Copying files failed"
+ goto finish_InstallOption
+ else-ifstr(i) $(STF_INSTALL_OUTCOME) == "STF_USERQUIT"
+ set Status = STATUS_USERCANCEL
+ goto finish_InstallOption
+ endif
+ endif
+ ifstr(i) $(DoConfig) == "YES"
+ set DriverPath = $(!STF_PRNDRIVERPATH)"\"#(Files-PrinterDriver, $(DriverOption), 2)
+ set DataFilePath = $(!STF_PRNDRIVERPATH)"\"#(Files-PrinterData, $(DataOption), 2)
+ set ConfigFilePath = $(!STF_PRNDRIVERPATH)"\"#(Files-PrinterConfig, $(ConfigOption), 2)
+ LibraryProcedure STATUS,$(!LIBHANDLE),CheckFileExistance $(DriverPath)
+ ifstr(i) $(STATUS) == YES
+ LibraryProcedure STATUS,$(!LIBHANDLE),CheckFileExistance $(DataFilePath)
+ ifstr(i) $(STATUS) == YES
+ LibraryProcedure STATUS,$(!LIBHANDLE),CheckFileExistance $(ConfigFilePath)
+ endif
+ endif
+ ifstr(i) $(STATUS) == NO
+ set OptionText = #(OptionsText$($0), $(Option), 1)
+ shell "subroutn.inf" SetupMessage $($0) "NONFATAL" $(String4)$(OptionText)$(String5)
+ Debug-Output "Copying printer files failed"
+ goto finish_InstallOption
+ endif
+ install Install-Configure
+ ifstr(i) $(STF_INSTALL_OUTCOME) == "STF_FAILURE"
+ Debug-Output "Installing printer driver failed"
+ goto finish_InstallOption
+ else-ifstr(i) $(STF_INSTALL_OUTCOME) == "STF_USERQUIT"
+ set Status = STATUS_USERCANCEL
+ goto finish_InstallOption
+ endif
+ ifstr(i) $(STATUS) != "ADDED"
+ set OptionText = #(OptionsText$($0), $(Option), 1)
+ ifstr(i) $(STATUS) == "PRESENT"
+ shell "subroutn.inf" SetupMessage $($0) "NONFATAL" $(String1)$(OptionText)$(String2)
+ set Status = STATUS_SUCCESSFUL
+ else-ifstr(i) $(STATUS) == "DENIED"
+ shell "subroutn.inf" SetupMessage $($0) "NONFATAL" $(String6)
+ else
+ shell "subroutn.inf" SetupMessage $($0) "NONFATAL" $(String1)$(OptionText)$(String7)
+ endif
+ goto finish_InstallOption
+ endif
+ endif
+ set Status = STATUS_SUCCESSFUL
+finish_InstallOption = +
+ Return $(Status)
+[Install-AddCopyOption]
+ set STF_VITAL = ""
+ set STF_OVERWRITE = "VERIFYSOURCEOLDER"
+ AddSectionKeyFileToCopyList Files-PrinterConfig +
+ $(ConfigOption) +
+ $(SrcDir) +
+ $(!STF_PRNDRIVERPATH)
+ AddSectionKeyFileToCopyList Files-PrinterData +
+ $(DataOption) +
+ $(SrcDir) +
+ $(!STF_PRNDRIVERPATH)
+ AddSectionKeyFileToCopyList Files-PrinterDriver +
+ $(DriverOption) +
+ $(SrcDir) +
+ $(!STF_PRNDRIVERPATH)
+ AddSectionKeyFileToCopyList Files-PrinterDriverHelp +
+ $(DriverOption) +
+ $(SrcDir) +
+ $(!STF_PRNDRIVERPATH)
+ exit
+[Install-DoCopyOption]
+ CopyFilesInCopyList
+ exit
+[Install-Configure]
+ set Model = $(Option)
+ set Driver = #(Files-PrinterDriver, $(DriverOption), 2)
+ set DataFile = #(Files-PrinterData, $(DataOption), 2)
+ set ConfigFile = #(Files-PrinterConfig, $(ConfigOption), 2)
+ LibraryProcedure STATUS,$(!LIBHANDLE), SetupAddPrinterDriver +
+ $(Model) +
+ $(!STF_PRNENVIRONM) +
+ $(Driver) +
+ $(DataFile) +
+ $(ConfigFile) +
+ $(!STF_PRINTSERVER)
+ exit
+[ExternalInstallOption]
+ Set !G:DebugOutputControl = 0
+ set Exit_Code = $(!SETUP_ERROR_GENERAL)
+ set DrivesToFree = {}
+ install LoadSetupLibrary
+ ifstr(i) $(STF_LANGUAGE) == ""
+ goto end
+ else-ifstr(i) $(OPTION) == ""
+ goto end
+ else-ifstr(i) $(ADDCOPY) == ""
+ goto end
+ else-ifstr(i) $(DOCOPY) == ""
+ goto end
+ else-ifstr(i) $(DOCONFIG) == ""
+ goto end
+ endif
+ read-syms PlatformID
+ read-syms ProductType
+ ifstr(i) $(STF_PLATFORM) == $(PlatformID_I386)
+ set STF_PRNPLATFORM = "w32x86"
+ set STF_PRNENVIRONM = "Windows NT x86"
+ else-ifstr(i) $(STF_PLATFORM) == $(PlatformID_Mips)
+ set STF_PRNPLATFORM = "w32mips"
+ set STF_PRNENVIRONM = "Windows NT R4000"
+ else-ifstr(i) $(STF_PLATFORM) == $(PlatformID_PPC)
+ set STF_PRNPLATFORM = "w32ppc"
+ set STF_PRNENVIRONM = "Windows NT PowerPC"
+ else-ifstr(i) $(STF_PLATFORM) == $(PlatformID_Alpha)
+ set STF_PRNPLATFORM = "w32alpha"
+ set STF_PRNENVIRONM = "Windows NT Alpha_AXP"
+ else
+ goto end
+ endif
+ read-syms UiVars
+ detect UiVars
+ read-syms Strings$(STF_LANGUAGE)
+ ifstr(i) $(STF_SRCDIR) != $(STF_CWDDIR)
+ goto skip_asksource
+ endif
+ set STF_SRCDIR = A:\
+ shell "registry.inf" GetNTSource
+ ifint $($ShellCode) != $(!SHELL_CODE_OK)
+ else-ifstr(i) $($R0) != STATUS_SUCCESSFUL
+ else
+ set STF_SRCDIR = $($R1)
+ endif
+ shell "subroutn.inf" DoAskSource $(STF_SRCDIR)
+ ifint $($ShellCode) != $(!SHELL_CODE_OK)
+ Debug-Output "shelling DoAskSource failed"
+ goto end
+ endif
+ ifstr(i) $($R0) == STATUS_SUCCESSFUL
+ set STF_SRCDIR = $($R1)
+ ifstr(i) $($R2) != ""
+ set DrivesToFree = >($(DrivesToFree), $($R2))
+ endif
+ else
+ goto end
+ endif
+skip_asksource = +
+ LibraryProcedure IsFullPath, $(!LIBHANDLE), CheckPathFullPathSpec $(STF_PRNDRIVERPATH)
+ ifstr(i) $(IsFullPath) == "NO"
+ LibraryProcedure STATUS, $(!LIBHANDLE), ProcessForUNC $(STF_PRNDRIVERPATH)
+ ifstr(i) $(STATUS) == "ERROR"
+ shell "subroutn.inf" SetupMessage $(!STF_LANGUAGE) "NONFATAL" $(String3)
+ goto end
+ else-ifstr(i) $(STATUS) == "NOT-UNC"
+ shell "subroutn.inf" SetupMessage $(!STF_LANGUAGE) "NONFATAL" $(String3)
+ goto end
+ else-ifstr(i) $(STATUS) == "UNC-FAILCONNECT"
+ shell "subroutn.inf" SetupMessage $(!STF_LANGUAGE) "NONFATAL" $(String3)
+ goto end
+ else
+ set STF_PRNDRIVERPATH = $(STATUS)
+ endif
+ endif
+ shell "" InstallOption $(STF_LANGUAGE) $(OPTION) $(STF_SRCDIR) $(ADDCOPY) $(DOCOPY) $(DOCONFIG)
+ ifint $($ShellCode) != $(!SHELL_CODE_OK)
+ Debug-Output "Execing InstallOption failed"
+ goto end
+ endif
+ ifstr(i) $($R0) == STATUS_SUCCESSFUL
+ set Exit_Code = $(!SETUP_ERROR_SUCCESS)
+ else-ifstr(i) $($R0) == STATUS_USERCANCEL
+ set Exit_Code = $(!SETUP_ERROR_USERCANCEL)
+ endif
+end =+
+ ForListDo $(DrivesToFree)
+ LibraryProcedure STATUS,$(!LIBHANDLE), DeleteNetConnection $($) "TRUE"
+ EndForListDo
+ install FreeSetupLibrary
+ exit
+[LoadSetupLibrary]
+ LoadLibrary "x" $(!STF_CWDDIR)setupdll.dll !LIBHANDLE
+ exit
+[FreeSetupLibrary]
+ FreeLibrary $(!LIBHANDLE)
+ exit
+[PlatformID]
+ PlatformID_I386 = I386
+ PlatformID_Mips = Mips
+ PlatformID_Alpha = Alpha
+ PlatformID_PPC = ppc
+[UiVars]
+ STF_CONTROLSET = CurrentControlSet
+ STF_WINDOWSPATH = "" ? $(!LIBHANDLE) GetWindowsNtDir
+ STF_WINDOWSSYSPATH = "" ? $(!LIBHANDLE) GetWindowsNtSysDir
+ STF_PRNDRIVERPATH = "" ? $(!LIBHANDLE) GetPrinterDriverDir $(!STF_PRINTSERVER) $(!STF_PRNENVIRONM)
+[Source Media Descriptions]
+ 1 = "Windows NT Workstation CD-ROM" , TAGFILE = cdrom.w
+[Signature]
+ FileType = MICROSOFT_FILE
+[GetSignature]
+ read-syms Signature
+ return $(FileType)
+[ProductType]
+STF_PRODUCT = Winnt
+STF_PLATFORM = I386
+[Files-PrinterConfig]
+wowfaxui = 1,wowfaxui.DLL , SIZE=999
+[Files-PrinterData]
+wowfax = 1, wowfax.DLL, SIZE=999
+[Files-PrinterDriver]
+wowfax = 1,wowfax.DLL , SIZE=999
+[Files-PrinterDriverHelp]
+wowfax = 1,wowfax.hlp, SIZE=999
+[LanguagesSupported]
+ ENG
+[OptionsTextENG]
+"Windows 3.1 Compatible Fax Driver" = "Windows 3.1 Compatible Fax Driver"
+[StringsENG]
+ String1 = "The printer model "
+ String2 = " is already installed."
+ String3 = "Failed to connect to the print server."
+ String4 = "The driver files for the printer model "
+ String5 = " couldn't be copied. Failed to install the printer model."
+ String6 = "Access is denied. You must be logged on as a member of the Administrators "+
+ "group to carry out this operation."
+ String7 = " could not be installed."
+[ProgressCopyENG]
+ ProCaption = "Windows NT Setup"
+ ProCancel = "Cancel"
+ ProCancelMsg = "Windows NT is not correctly installed. Are you sure you want "+
+ "to cancel copying files?"
+ ProCancelCap = "Setup Message"
+ ProText1 = "Copying:"
+ ProText2 = "To:"
diff --git a/private/mvdm/fax/wowfax/makefile b/private/mvdm/fax/wowfax/makefile
new file mode 100644
index 000000000..6ee4f43fa
--- /dev/null
+++ b/private/mvdm/fax/wowfax/makefile
@@ -0,0 +1,6 @@
+#
+# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source
+# file to this component. This file merely indirects to the real make file
+# that is shared by all the components of NT OS/2
+#
+!INCLUDE $(NTMAKEENV)\makefile.def
diff --git a/private/mvdm/fax/wowfax/sources b/private/mvdm/fax/wowfax/sources
new file mode 100644
index 000000000..2d8ee0293
--- /dev/null
+++ b/private/mvdm/fax/wowfax/sources
@@ -0,0 +1,47 @@
+!IF 0
+
+Copyright (c) 1989 - 1991 Microsoft Corporation
+
+Module Name:
+
+ sources.
+
+Abstract:
+
+ This file specifies the target component being built and the list of
+ sources files needed to build that component. Also specifies optional
+ compiler switches and libraries that are unique for the component being
+ built.
+
+
+Author:
+
+ Steve Wood (stevewo) 12-Apr-1990
+
+NOTE: Commented description of this file is in \nt\bak\bin\sources.tpl
+
+!ENDIF
+
+MAJORCOMP=windows
+MINORCOMP=wowfax
+
+TARGETNAME=wowfax
+TARGETPATH=$(BASEDIR)\public\sdk\lib
+TARGETTYPE=GDI_DRIVER
+DLLBASE=@$(BASEDIR)\PUBLIC\SDK\LIB\coffbase.txt,DISPLAY
+
+
+C_DEFINES=$(C_DEFINES) -DNTGDIKM=1 -DNTGDIK=1 -DUNICODE
+
+GDIDIR=$(BASEDIR)\private\ntos\w32\ntgdi
+
+!IFNDEF MSC_WARNING_LEVEL
+MSC_WARNING_LEVEL=/W3
+!ENDIF
+MSC_WARNING_LEVEL=$(MSC_WARNING_LEVEL) /WX
+
+INCLUDES=..\;..\..\inc;$(GDIDIR)\inc;..\..\..\windows\inc
+
+SOURCES= wowfax.c \
+ wowfax.rc
+
diff --git a/private/mvdm/fax/wowfax/wowfax.c b/private/mvdm/fax/wowfax/wowfax.c
new file mode 100644
index 000000000..c6f494b77
--- /dev/null
+++ b/private/mvdm/fax/wowfax/wowfax.c
@@ -0,0 +1,461 @@
+//************************************************************************
+// Generic Win 3.1 fax printer driver support. 32-bit printer driver
+// functions. Runs in the graphics engine context (CSRSS).
+//
+// History:
+// 02-jan-95 nandurir created.
+// 01-feb-95 reedb Clean-up, support printer install and bug fixes.
+// 14-mar-95 reedb Use GDI hooks to move most functionality to UI.
+// 16-aug-95 reedb Move to kernel mode. Debug output and validate
+// functions moved from FAXCOMM.C.
+//
+//************************************************************************
+
+#include "wowfaxdd.h"
+
+//************************************************************************
+// Globals
+//************************************************************************
+
+DRVFN DrvFnTab[] = {
+ {INDEX_DrvEnablePDEV, (PFN)DrvEnablePDEV },
+ {INDEX_DrvDisablePDEV, (PFN)DrvDisablePDEV },
+ {INDEX_DrvCompletePDEV, (PFN)DrvCompletePDEV },
+ {INDEX_DrvEnableSurface, (PFN)DrvEnableSurface },
+ {INDEX_DrvDisableSurface, (PFN)DrvDisableSurface },
+ {INDEX_DrvStartDoc, (PFN)DrvStartDoc },
+ {INDEX_DrvStartPage, (PFN)DrvStartPage },
+ {INDEX_DrvSendPage, (PFN)DrvSendPage },
+ {INDEX_DrvEndDoc, (PFN)DrvEndDoc },
+ {INDEX_DrvDitherColor, (PFN)DrvDitherColor },
+ {INDEX_DrvEscape, (PFN)DrvEscape},
+ };
+
+#define NO_DRVFN (sizeof(DrvFnTab) / sizeof(DrvFnTab[0]))
+
+
+#if DBG
+
+//************************************************************************
+// faxlogprintf - Driver version of the debug output function.
+//
+//************************************************************************
+
+VOID faxlogprintf(PCHAR pszFmt, ...)
+{
+ va_list ap;
+ char buffer[256];
+
+ va_start(ap, pszFmt);
+
+ EngDebugPrint("", pszFmt, ap);
+
+ va_end(ap);
+}
+
+#endif
+
+//************************************************************************
+// ValidateFaxDev - Validates the FAXDEV structure by checking the DWORD
+// signature, which is a known fixed value.
+//
+//************************************************************************
+
+BOOL ValidateFaxDev(LPFAXDEV lpFaxDev)
+{
+ if (lpFaxDev) {
+ if (lpFaxDev->id == FAXDEV_ID) {
+ return TRUE;
+ }
+ LOGDEBUG(("ValidateFaxDev failed, bad id, lpFaxDev: %X\n", lpFaxDev));
+ }
+ else {
+ LOGDEBUG(("ValidateFaxDev failed, lpFaxDev: NULL\n"));
+ }
+ return FALSE;
+}
+
+//************************************************************************
+// DllInitProc
+//************************************************************************
+
+BOOL DllInitProc(HMODULE hModule, DWORD Reason, PCONTEXT pContext)
+{
+ UNREFERENCED_PARAMETER(hModule);
+ UNREFERENCED_PARAMETER(Reason);
+ UNREFERENCED_PARAMETER(pContext);
+
+ return TRUE;
+}
+
+
+//***************************************************************************
+// DrvEnableDriver
+//***************************************************************************
+
+BOOL DrvEnableDriver(ULONG iEngineVersion, ULONG cb, DRVENABLEDATA *pded)
+{
+ LOGDEBUG(("WOWFAX!DrvEnableDriver, iEngineVersion: %X, cb: %X, pded: %X\n", iEngineVersion, cb, pded));
+
+ pded->iDriverVersion = DDI_DRIVER_VERSION;
+
+ if (cb < sizeof(DRVENABLEDATA)) {
+ LOGDEBUG(("WOWFAX!DrvEnableDriver, failed\n"));
+ return FALSE;
+ }
+
+ pded->c = NO_DRVFN;
+ pded->pdrvfn = DrvFnTab;
+
+ return TRUE;
+
+}
+
+//***************************************************************************
+// DrvDisableDriver
+//***************************************************************************
+
+VOID DrvDisableDriver(VOID)
+{
+ LOGDEBUG(("WOWFAX!DrvDisableDriver\n"));
+ return;
+}
+
+//***************************************************************************
+// DrvEnablePDEV
+//***************************************************************************
+DHPDEV DrvEnablePDEV(DEVMODEW *pdevmode, // Driver data, Client FAXDEV
+ PWSTR pwstrPrtName, // Printer's name in CreateDC()
+ ULONG cPatterns, // Count of standard patterns
+ HSURF *phsurfPatterns, // Buffer for standard patterns
+ ULONG cjGdiInfo, // Size of buffer for GdiInfo
+ ULONG *pulGdiInfo, // Buffer for GDIINFO
+ ULONG cjDevInfo, // Number of bytes in devinfo
+ DEVINFO *pdevinfo, // Device info
+ HDEV hdev,
+ PWSTR pwstrDeviceName, // Device Name - "LaserJet II"
+ HANDLE hDriver // Printer handle for spooler access
+)
+{
+ LPFAXDEV lpCliFaxDev, lpSrvFaxDev = NULL;
+
+ LOGDEBUG(("WOWFAX!DrvEnablePDEV, pdevmode: %X, pwstrPrtName: %S\n", pdevmode, pwstrPrtName));
+
+ if (pdevmode) {
+ // Point to the end of the DEVMODE where the FAXDEV is located.
+ lpCliFaxDev = (LPFAXDEV) ((PBYTE)pdevmode + pdevmode->dmSize);
+
+ // Allocate a server side FAXDEV to be passed back to GDI. Copy the
+ // client side FAXDEV to the server side FAXDEV. Note all pointers in
+ // the client FAXDEV reference client side memory and cannot be
+ // dereferenced on the server side.
+ lpSrvFaxDev = (LPFAXDEV)EngAllocMem(0, sizeof(FAXDEV), FAXDEV_ID);
+ LOGDEBUG(("WOWFAX!DrvEnablePDEV, allocated lpSrvFaxDev: %X\n", lpSrvFaxDev));
+
+ if (InitPDEV(lpCliFaxDev, lpSrvFaxDev,
+ cPatterns, phsurfPatterns,
+ cjGdiInfo, pulGdiInfo,
+ cjDevInfo, pdevinfo)) {
+
+ lpSrvFaxDev->hDriver = hDriver;
+ return (DHPDEV)lpSrvFaxDev;
+ }
+ else {
+ LOGDEBUG(("WOWFAX!DrvEnablePDEV, failed\n"));
+ if (lpSrvFaxDev) {
+ EngFreeMem(lpSrvFaxDev);
+ lpSrvFaxDev = NULL;
+ }
+ }
+ }
+ return (DHPDEV)lpSrvFaxDev;
+}
+
+//***************************************************************************
+// InitPDEV - Called by DrvEnablePDEV and DrvRestartPDEV to initialize the
+// server side PDEV/FAXDEV.
+//***************************************************************************
+
+
+BOOL InitPDEV(
+ LPFAXDEV lpCliFaxDev, // Pointer to the client side FAXDEV
+ LPFAXDEV lpSrvFaxDev, // Pointer to the server side FAXDEV
+ ULONG cPatterns, // Count of standard patterns
+ HSURF *phsurfPatterns, // Buffer for standard patterns
+ ULONG cjGdiInfo, // Size of buffer for GdiInfo
+ ULONG *pulGdiInfo, // Buffer for GDIINFO
+ ULONG cjDevInfo, // Number of bytes in devinfo
+ DEVINFO *pdevinfo // Device info
+)
+{
+ PGDIINFO pgdiinfo = (PGDIINFO)pulGdiInfo;
+ ULONG uColors[2];
+
+ if (!ValidateFaxDev(lpCliFaxDev)) {
+ return FALSE;
+ }
+
+ // lpSrvFaxDev hasn't been initialized yet, so just check pointer.
+ if (lpSrvFaxDev == NULL) {
+ LOGDEBUG(("WOWFAX!InitPDEV, failed, NULL lpSrvFaxDev parameter\n"));
+ return FALSE;
+ }
+
+ // Copy client FAXDEV to server.
+ RtlCopyMemory(lpSrvFaxDev, lpCliFaxDev, sizeof(FAXDEV));
+
+ // Copy GDIINFO from client FAXDEV to the GDI buffer for GDIINFO.
+ RtlCopyMemory(pgdiinfo, &(lpCliFaxDev->gdiinfo), sizeof(GDIINFO));
+
+ // Initialize the DEVINFO structure.
+ uColors[0] = RGB(0x00, 0x00, 0x00);
+ uColors[1] = RGB(0xff, 0xff, 0xff);
+
+ pdevinfo->hpalDefault = EngCreatePalette(PAL_INDEXED, 2, uColors, 0, 0, 0);
+ pdevinfo->iDitherFormat = BMF_1BPP;
+
+ // Make sure we don't journal.
+ pdevinfo->flGraphicsCaps |= GCAPS_DONTJOURNAL;
+
+ // Make sure we do dither.
+ pdevinfo->flGraphicsCaps |= GCAPS_HALFTONE | GCAPS_MONO_DITHER |
+ GCAPS_COLOR_DITHER;
+
+ // Copy the DEVINFO data to the server side FAXDEV.
+ RtlCopyMemory(&(lpSrvFaxDev->devinfo), pdevinfo, sizeof(DEVINFO));
+
+ return TRUE;
+}
+
+//***************************************************************************
+// DrvCompletePDEV
+//***************************************************************************
+
+VOID DrvCompletePDEV(DHPDEV dhpdev, HDEV hdev)
+{
+ LPFAXDEV lpSrvFaxDev = (LPFAXDEV) dhpdev;
+
+ LOGDEBUG(("WOWFAX!DrvCompletePDEV, dhpdev %X\n", dhpdev));
+
+ if (ValidateFaxDev(lpSrvFaxDev)) {
+ // Store the gdi handle.
+ lpSrvFaxDev->hdev = hdev;
+ }
+ else {
+ LOGDEBUG(("WOWFAX!DrvCompletePDEV, failed\n"));
+ }
+
+ return;
+}
+
+//***************************************************************************
+// DrvDisablePDEV
+//***************************************************************************
+
+VOID DrvDisablePDEV(DHPDEV dhpdev)
+{
+ LPFAXDEV lpSrvFaxDev = (LPFAXDEV) dhpdev;
+
+ LOGDEBUG(("WOWFAX!DrvDisablePDEV, dhpdev %X\n", dhpdev));
+
+ if (ValidateFaxDev(lpSrvFaxDev)) {
+ if (lpSrvFaxDev->devinfo.hpalDefault) {
+ EngDeletePalette(lpSrvFaxDev->devinfo.hpalDefault);
+ }
+ EngFreeMem(lpSrvFaxDev);
+ LOGDEBUG(("WOWFAX!DrvDisablePDEV, deallocated lpSrvFaxDev: %X\n", lpSrvFaxDev));
+ }
+ else {
+ LOGDEBUG(("WOWFAX!DrvDisablePDEV, failed\n"));
+ }
+ return;
+}
+
+
+//***************************************************************************
+// DrvEnableSurface
+//***************************************************************************
+
+HSURF DrvEnableSurface(DHPDEV dhpdev)
+{
+
+ LPFAXDEV lpFaxDev = (LPFAXDEV)dhpdev;
+ HBITMAP hbm = 0;
+
+ LOGDEBUG(("WOWFAX!DrvEnableSurface, lpFaxDev: %X\n", lpFaxDev));
+
+ if (ValidateFaxDev(lpFaxDev)) {
+ // GDI will allocate space for the bitmap bits. We'll use a DrvEscape
+ // to copy them to the client side.
+ hbm = EngCreateBitmap(lpFaxDev->gdiinfo.szlPhysSize,
+ lpFaxDev->bmWidthBytes,
+ lpFaxDev->bmFormat, BMF_TOPDOWN, NULL);
+ if (hbm) {
+ lpFaxDev->hbm = hbm;
+ EngAssociateSurface((HSURF)hbm, lpFaxDev->hdev, 0);
+ return (HSURF)hbm;
+ }
+ LOGDEBUG(("WOWFAX!DrvEnableSurface, EngCreateBitmap failed\n"));
+ }
+
+ return (HSURF)hbm;
+}
+
+//***************************************************************************
+// DrvDisableSurface
+//***************************************************************************
+
+VOID DrvDisableSurface(
+ DHPDEV dhpdev
+)
+{
+ LPFAXDEV lpFaxDev = (LPFAXDEV)dhpdev;
+
+ LOGDEBUG(("WOWFAX!DrvDisableSurface, lpFaxDev: %X\n", lpFaxDev));
+
+ if (ValidateFaxDev(lpFaxDev)) {
+ if (lpFaxDev->hbm) {
+ EngDeleteSurface((HSURF)lpFaxDev->hbm);
+ lpFaxDev->hbm = 0;
+ return;
+ }
+ }
+ return;
+}
+
+//***************************************************************************
+// DrvStartDoc
+//***************************************************************************
+
+BOOL DrvStartDoc(
+ SURFOBJ *pso,
+ PWSTR pwszDocName,
+ DWORD dwJobId
+)
+{
+ LOGDEBUG(("WOWFAX!DrvStartDoc, pso: %X, pwszDocName: %S, dwJobId: %X\n", pso, pwszDocName, dwJobId));
+ return TRUE;
+}
+
+//***************************************************************************
+// DrvStartPage
+//***************************************************************************
+
+BOOL DrvStartPage(
+ SURFOBJ *pso
+)
+{
+ LPFAXDEV lpFaxDev = (LPFAXDEV)pso->dhpdev;
+ BITMAP bm;
+ RECTL rc;
+
+ LOGDEBUG(("WOWFAX!DrvStartPage, pso: %X\n", pso));
+
+ // Calculate the size of the rectangle based on the input data
+ // in 'pso' - this will ensure that the entire bitmap is erased.
+
+ if (ValidateFaxDev(lpFaxDev)) {
+ rc.left = 0;
+ rc.top = 0;
+ rc.right = pso->lDelta * lpFaxDev->cPixPerByte;
+ rc.bottom = pso->cjBits / pso->lDelta;
+
+ EngEraseSurface(pso, &rc, COLOR_INDEX_WHITE);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+//***************************************************************************
+// DrvSendPage
+//***************************************************************************
+
+BOOL DrvSendPage(SURFOBJ *pso)
+{
+ LOGDEBUG(("WOWFAX!DrvSendPage, pso %X\n", pso));
+ return TRUE;
+}
+
+
+//***************************************************************************
+// DrvEndDoc
+//***************************************************************************
+
+BOOL DrvEndDoc(SURFOBJ *pso, FLONG fl)
+{
+ LOGDEBUG(("WOWFAX!DrvEndDoc, pso %X\n", pso));
+ return TRUE;
+}
+
+ULONG
+DrvDitherColor(
+ DHPDEV dhpdev,
+ ULONG iMode,
+ ULONG rgbColor,
+ ULONG *pulDither
+ )
+
+{
+ return DCR_HALFTONE;
+}
+
+//***************************************************************************
+// DrvEscape - Allows client side to get server side data.
+//***************************************************************************
+
+ULONG DrvEscape(
+ SURFOBJ *pso,
+ ULONG iEsc,
+ ULONG cjIn,
+ PVOID *pvIn,
+ ULONG cjOut,
+ PVOID *pvOut
+)
+{
+ LPFAXDEV lpSrvFaxDev;
+ ULONG ulRet = 0;
+
+ LOGDEBUG(("WOWFAX!DrvEscape, pso %X, iEsc: %X\n", pso, iEsc));
+ if (pso) {
+ lpSrvFaxDev = (LPFAXDEV)pso->dhpdev;
+ if (ValidateFaxDev(lpSrvFaxDev)) {
+ LOGDEBUG(("WOWFAX!DrvEscape, lpSrvFaxDev: %X\n", lpSrvFaxDev));
+ switch (iEsc) {
+ case DRV_ESC_GET_DEVMODE_PTR:
+ return (ULONG) lpSrvFaxDev->pdevmode;
+
+ case DRV_ESC_GET_FAXDEV_PTR:
+ return (ULONG) lpSrvFaxDev->lpClient;
+
+ case DRV_ESC_GET_SURF_INFO:
+ if (pvOut) {
+ if (cjOut == sizeof(LONG)) {
+ (LONG) *pvOut = pso->lDelta;
+ return (ULONG) pso->cjBits;
+ }
+ }
+ break;
+
+ case DRV_ESC_GET_BITMAP_BITS:
+ // Validate the buffer pointer and copy the bits.
+ if (pvOut) {
+ if (cjOut == pso->cjBits) {
+ RtlCopyMemory(pvOut, pso->pvBits, cjOut);
+ return cjOut;
+ }
+ LOGDEBUG(("WOWFAX!DrvEscape, bitmap size mismatch cjIn: %X, pso->cjBits: %X\n", cjIn, pso->cjBits));
+ }
+ break;
+
+// default:
+ LOGDEBUG(("WOWFAX!DrvEscape, unknown escape: %X\n", iEsc));
+ } //switch
+ }
+ }
+ LOGDEBUG(("WOWFAX!DrvEscape, failed\n"));
+
+ return ulRet;
+}
+
+
diff --git a/private/mvdm/fax/wowfax/wowfax.def b/private/mvdm/fax/wowfax/wowfax.def
new file mode 100644
index 000000000..11864890e
--- /dev/null
+++ b/private/mvdm/fax/wowfax/wowfax.def
@@ -0,0 +1,10 @@
+LIBRARY wowfax
+
+DESCRIPTION 'wow fax driver (rasdd)'
+
+
+EXPORTS
+ DrvEnableDriver
+ DrvDisableDriver
+
+PROTMODE
diff --git a/private/mvdm/fax/wowfax/wowfax.rc b/private/mvdm/fax/wowfax/wowfax.rc
new file mode 100644
index 000000000..bf7fdb67d
--- /dev/null
+++ b/private/mvdm/fax/wowfax/wowfax.rc
@@ -0,0 +1,12 @@
+#include "windows.h"
+
+#include <ntverp.h>
+#define VER_FILEVERSION 0, 2, 0, 0
+#define VER_FILETYPE VFT_DRV
+#define VER_FILESUBTYPE VFT2_DRV_PRINTER
+#define VER_FILEDESCRIPTION_STR "Windows 3.1 Compatible Fax Driver DLL"
+#define VER_INTERNALNAME_STR "wowfax.dll"
+#define VER_ORIGINALFILENAME_STR "wowfax.dll"
+
+#include "common.ver"
+
diff --git a/private/mvdm/fax/wowfax/wowfaxdd.h b/private/mvdm/fax/wowfax/wowfaxdd.h
new file mode 100644
index 000000000..1e8631625
--- /dev/null
+++ b/private/mvdm/fax/wowfax/wowfaxdd.h
@@ -0,0 +1,44 @@
+//****************************************************************************
+// Generic Win 3.1 fax printer driver support
+//
+// History:
+// 02-jan-95 nandurir created.
+// 14-mar-95 reedb Use GDI hooks to move most functionality to UI.
+// 16-aug-95 reedb Move to kernel mode. Many declarations and
+// definitions moved from FAXCOMM.H.
+//
+//****************************************************************************
+
+#include "string.h"
+#include "stddef.h"
+#include "windows.h"
+#include "winddi.h"
+#include "faxcomm.h"
+
+BOOL InitPDEV(
+ LPFAXDEV lpCliFaxDev, // Pointer to the client side FAXDEV
+ LPFAXDEV lpSrvFaxDev, // Pointer to the server side FAXDEV
+ ULONG cPatterns, // Count of standard patterns
+ HSURF *phsurfPatterns, // Buffer for standard patterns
+ ULONG cjGdiInfo, // Size of buffer for GdiInfo
+ ULONG *pulGdiInfo, // Buffer for GDIINFO
+ ULONG cjDevInfo, // Number of bytes in devinfo
+ DEVINFO *pdevinfo // Device info
+);
+
+#define COLOR_INDEX_BLACK 0x0
+#define COLOR_INDEX_WHITE 0x1
+
+// user server defn.
+
+#define FW_16BIT 0x1 // look for 16bit windows only
+LPVOID UserServerDllInitialization(LPVOID);
+typedef HWND (*PFNFW)(LPTSTR, LPTSTR, UINT);
+typedef LRESULT (*PFNSM)(HWND, UINT, WPARAM, LPARAM);
+typedef LRESULT (*PFNSNM)(HWND, UINT, WPARAM, LPARAM);
+
+#if DBG
+#define LOGDEBUG(args) {faxlogprintf args;}
+#else
+#define LOGDEBUG(args)
+#endif
diff --git a/private/mvdm/fax/wowfaxui/makefile b/private/mvdm/fax/wowfaxui/makefile
new file mode 100644
index 000000000..6ee4f43fa
--- /dev/null
+++ b/private/mvdm/fax/wowfaxui/makefile
@@ -0,0 +1,6 @@
+#
+# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source
+# file to this component. This file merely indirects to the real make file
+# that is shared by all the components of NT OS/2
+#
+!INCLUDE $(NTMAKEENV)\makefile.def
diff --git a/private/mvdm/fax/wowfaxui/sources b/private/mvdm/fax/wowfaxui/sources
new file mode 100644
index 000000000..9763e73c2
--- /dev/null
+++ b/private/mvdm/fax/wowfaxui/sources
@@ -0,0 +1,60 @@
+!IF 0
+
+Copyright (c) 1989 - 1991 Microsoft Corporation
+
+Module Name:
+
+ sources.
+
+Abstract:
+
+ This file specifies the target component being built and the list of
+ sources files needed to build that component. Also specifies optional
+ compiler switches and libraries that are unique for the component being
+ built.
+
+
+Author:
+
+ Steve Wood (stevewo) 12-Apr-1990
+
+NOTE: Commented description of this file is in \nt\bak\bin\sources.tpl
+
+!ENDIF
+
+MAJORCOMP=windows
+MINORCOMP=wowfaxui
+
+TARGETNAME=wowfaxui
+TARGETPATH=$(BASEDIR)\public\sdk\lib
+TARGETTYPE=DYNLINK
+TARGETLIBS=$(BASEDIR)\public\sdk\lib\*\user32.lib \
+ $(BASEDIR)\public\sdk\lib\*\gdi32.lib \
+ $(BASEDIR)\public\sdk\lib\*\kernel32.lib \
+ $(BASEDIR)\public\sdk\lib\*\winspool.lib \
+ $(BASEDIR)\public\sdk\lib\*\shell32.lib \
+ $(BASEDIR)\public\sdk\lib\*\advapi32.lib
+
+C_DEFINES=-DUNICODE
+
+DLLENTRY=DllInitProc
+
+GDIDIR=$(BASEDIR)\private\ntos\w32\ntgdi
+PRINTERS=$(BASEDIR)\private\ntos\w32\ntgdi\printers
+
+!IFNDEF MSC_WARNING_LEVEL
+MSC_WARNING_LEVEL=/W3
+!ENDIF
+MSC_WARNING_LEVEL=$(MSC_WARNING_LEVEL) /WX
+
+INCLUDES=..;..\wowfax;..\..\inc;$(GDIDIR)\inc;..\..\..\windows\inc;$(PRINTERS)\lib
+
+SOURCES=wfhelper.c \
+ wfsheets.c \
+ wfupgrad.c \
+ wowfaxui.c \
+ wowfaxui.rc
+
+UMTYPE=windows
+UMTEST=
+
diff --git a/private/mvdm/fax/wowfaxui/wfhelper.c b/private/mvdm/fax/wowfaxui/wfhelper.c
new file mode 100644
index 000000000..69a3833c4
--- /dev/null
+++ b/private/mvdm/fax/wowfaxui/wfhelper.c
@@ -0,0 +1,467 @@
+//************************************************************************
+// Generic Win 3.1 fax printer driver support. Helper functions which are
+// called in WOWFAXUI.C
+//
+// History:
+// 14-mar-95 reedb Created. Many of the functions were moved from
+// FAXCOMM.C, since they're no longer called
+// from WOWFAX.DLL.
+// 16-aug-95 reedb Move to kernel mode. Debug output and validate
+// functions moved from FAXCOMM.C.
+//
+//************************************************************************
+
+#include "wowfaxui.h"
+
+extern LPCRITICAL_SECTION lpCriticalSection;
+extern HINSTANCE ghInst;
+
+#if DBG
+
+INT iFaxLogLevel = 20;
+INT iReqFaxLogLevel = 0;
+
+typedef PVOID HANDLE;
+
+
+//************************************************************************
+// faxlogprintf - Two different implementations. One for client side
+// debugging the other for server side.
+//
+//************************************************************************
+
+
+// For Debug logging.
+#define MAX_DISPLAY_LINE 256 // 128 characters.
+
+TCHAR szFaxLogFile[] = L"C:\\FAXLOG.LOG";
+HANDLE hfFaxLog = NULL;
+
+// Defines for iFaxLogMode
+#define NO_LOGGING 0
+#define LOG_TO_FILE 1
+#define OPEN_LOG_FILE 2
+#define CLOSE_LOG_FILE 3
+
+INT iFaxLogMode = NO_LOGGING;
+
+VOID faxlogprintf(LPTSTR pszFmt, ...)
+{
+ DWORD lpBytesWritten;
+ int len;
+ TCHAR szText[1024];
+ va_list arglist;
+
+ va_start(arglist, pszFmt);
+ len = wvsprintf(szText, pszFmt, arglist);
+
+ if (iFaxLogMode > LOG_TO_FILE) {
+ if (iFaxLogMode == OPEN_LOG_FILE) {
+ if((hfFaxLog = CreateFile(szFaxLogFile,
+ GENERIC_WRITE,
+ FILE_SHARE_WRITE,
+ NULL,
+ CREATE_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL)) != INVALID_HANDLE_VALUE) {
+ iFaxLogMode = LOG_TO_FILE;
+ }
+ else {
+ hfFaxLog = NULL;
+ iFaxLogMode = NO_LOGGING;
+ OutputDebugString(L"Couldn't open fax log file!\n");
+ }
+ }
+ else {
+ FlushFileBuffers(hfFaxLog);
+ CloseHandle(hfFaxLog);
+ hfFaxLog = NULL;
+ iFaxLogMode = NO_LOGGING;
+ }
+ }
+
+ if (iFaxLogLevel >= iReqFaxLogLevel) {
+ if (iFaxLogMode) {
+ WriteFile(hfFaxLog, szText, len, &lpBytesWritten, NULL);
+ }
+ else {
+ OutputDebugString(szText);
+ }
+ }
+}
+
+
+VOID LogWowFaxInfo(LPWOWFAXINFO lpWowFaxInfo)
+{
+ faxlogprintf(L"\tlpWowFaxInfo (lpMap): %X\n", lpWowFaxInfo);
+ faxlogprintf(L"\t\thwnd: %X\n", lpWowFaxInfo->hwnd);
+ faxlogprintf(L"\t\ttid: %X\n", lpWowFaxInfo->tid);
+ faxlogprintf(L"\t\tproc16: %X\n", lpWowFaxInfo->proc16);
+ faxlogprintf(L"\t\tlpinfo16: %X\n", lpWowFaxInfo->lpinfo16);
+ faxlogprintf(L"\t\tmsg: %X\n", lpWowFaxInfo->msg);
+ faxlogprintf(L"\t\thdc: %X\n", lpWowFaxInfo->hdc);
+ faxlogprintf(L"\t\twCmd: %X\n", lpWowFaxInfo->wCmd);
+ faxlogprintf(L"\t\tcData: %X\n", lpWowFaxInfo->cData);
+ faxlogprintf(L"\t\thwndui: %X\n", lpWowFaxInfo->hwndui);
+ faxlogprintf(L"\t\tretvalue: %X\n", lpWowFaxInfo->retvalue);
+ faxlogprintf(L"\t\tstatus: %X\n", lpWowFaxInfo->status);
+ if (lpWowFaxInfo->lpDevice) {
+ faxlogprintf(L"\t\tlpDevice: %s\n", lpWowFaxInfo->lpDevice);
+ }
+ else {
+ faxlogprintf(L"\t\tlpDevice: %X\n", lpWowFaxInfo->lpDevice);
+ }
+ if (lpWowFaxInfo->lpDriverName) {
+ faxlogprintf(L"\t\tlpDriverName: %s\n", lpWowFaxInfo->lpDriverName);
+ }
+ else {
+ faxlogprintf(L"\t\tlpDriverName: %X\n", lpWowFaxInfo->lpDriverName);
+ }
+ if (lpWowFaxInfo->lpPortName) {
+ faxlogprintf(L"\t\tlpPortName: %s\n", lpWowFaxInfo->lpPortName);
+ }
+ else {
+ faxlogprintf(L"\t\tlpPortName: %X\n", lpWowFaxInfo->lpPortName);
+ }
+ faxlogprintf(L"\t\tlpIn: %X\n", lpWowFaxInfo->lpIn);
+ faxlogprintf(L"\t\tlpOut: %X\n", lpWowFaxInfo->lpOut);
+ if (lpWowFaxInfo->szDeviceName) {
+ faxlogprintf(L"\t\tszDeviceName: %s\n", lpWowFaxInfo->szDeviceName);
+ }
+ else {
+ faxlogprintf(L"\t\tszDeviceName: %X\n", lpWowFaxInfo->szDeviceName);
+ }
+ faxlogprintf(L"\t\tbmPixPerByte: %X\n", lpWowFaxInfo->bmPixPerByte);
+ faxlogprintf(L"\t\tbmWidthBytes: %X\n", lpWowFaxInfo->bmWidthBytes);
+ faxlogprintf(L"\t\tbmHeight: %X\n", lpWowFaxInfo->bmHeight);
+ faxlogprintf(L"\t\tlpbits: %X\n", lpWowFaxInfo->lpbits);
+}
+
+VOID LogFaxDev(LPTSTR pszTitle, LPFAXDEV lpFaxDev)
+{
+ DWORD dwTmp;
+ CHAR cTmp0, cTmp1, cTmp2, cTmp3;
+
+ faxlogprintf(L"WOWFAXUI!%s: %X\n", pszTitle, lpFaxDev);
+ dwTmp = lpFaxDev->id;
+ cTmp3 = (CHAR) dwTmp & 0xFF;
+ cTmp2 = (CHAR) (dwTmp >> 8) & 0xFF;
+ cTmp1 = (CHAR) (dwTmp >> 16) & 0xFF;
+ cTmp0 = (CHAR) (dwTmp >> 24) & 0xFF;
+ faxlogprintf(L"\tid: %c%c%c%c\n", cTmp3, cTmp2, cTmp1, cTmp0);
+ faxlogprintf(L"\tlpNext: %X\n", lpFaxDev->lpNext);
+ faxlogprintf(L"\tlpClient: %X\n", lpFaxDev->lpClient);
+ faxlogprintf(L"\thdev: %X\n", lpFaxDev->hdev);
+ faxlogprintf(L"\tidMap: %X\n", lpFaxDev->idMap);
+ faxlogprintf(L"\tcbMapLow: %X\n", lpFaxDev->cbMapLow);
+ faxlogprintf(L"\thMap: %X\n", lpFaxDev->hMap);
+ faxlogprintf(L"\tszMap: %s\n", lpFaxDev->szMap);
+ if (lpFaxDev->lpMap) {
+ LogWowFaxInfo(lpFaxDev->lpMap);
+ }
+ else {
+ faxlogprintf(L"\tlpMap: %X\n", lpFaxDev->lpMap);
+ }
+ faxlogprintf(L"\toffbits: %X\n", lpFaxDev->offbits);
+ faxlogprintf(L"\thbm: %X\n", lpFaxDev->hbm);
+ faxlogprintf(L"\tcPixPerByte: %X\n", lpFaxDev->cPixPerByte);
+ faxlogprintf(L"\tbmFormat: %X\n", lpFaxDev->bmFormat);
+ faxlogprintf(L"\tbmWidthBytes: %X\n", lpFaxDev->bmWidthBytes);
+ faxlogprintf(L"\thbmSurf: %X\n", lpFaxDev->hbmSurf);
+ faxlogprintf(L"\thwnd: %X\n", lpFaxDev->hwnd);
+ faxlogprintf(L"\ttid: %X\n", lpFaxDev->tid);
+ faxlogprintf(L"\tlpinfo16: %X\n", lpFaxDev->lpinfo16);
+ faxlogprintf(L"\thDriver: %X\n", lpFaxDev->hDriver);
+ faxlogprintf(L"\tStart of gdiinfo: %X\n", (DWORD)&(lpFaxDev->gdiinfo));
+ faxlogprintf(L"\tStart of devinfo: %X\n", (DWORD)&(lpFaxDev->devinfo));
+ faxlogprintf(L"\tpdevmode: %X\n", lpFaxDev->pdevmode);
+}
+#endif
+
+//************************************************************************
+// ValidateFaxDev - Validates the FAXDEV structure by checking the DWORD
+// signature, which is a known fixed value.
+//
+//************************************************************************
+
+BOOL ValidateFaxDev(LPFAXDEV lpFaxDev)
+{
+ if (lpFaxDev) {
+ if (lpFaxDev->id == FAXDEV_ID) {
+ return TRUE;
+ }
+ LOGDEBUG(0, (L"ValidateFaxDev failed, bad id, lpFaxDev: %X\n", lpFaxDev));
+ }
+ else {
+ LOGDEBUG(0, (L"ValidateFaxDev failed, lpFaxDev: NULL\n"));
+ }
+ return FALSE;
+}
+
+//***************************************************************************
+// WFLocalAlloc - Debug version of LocalAlloc.
+//***************************************************************************
+
+LPVOID WFLocalAlloc(DWORD dwBytes, LPWSTR lpszWhoCalled)
+{
+ LPVOID lpTmp;
+
+ lpTmp = LocalAlloc(LPTR, dwBytes);
+
+ if (lpTmp == NULL){
+ LOGDEBUG(0, (L"WOWFAXUI!%s, failed on memory allocation of %d bytes\n", lpszWhoCalled, dwBytes));
+ }
+ return(lpTmp);
+}
+
+//***************************************************************************
+// FindWowFaxWindow - Put up a message box if you can't.
+//***************************************************************************
+HWND FindWowFaxWindow(void)
+{
+ HWND hwnd;
+ PROCESS_INFORMATION ProcessInformation;
+ STARTUPINFO StartupInfo;
+ DWORD WaitStatus;
+ TCHAR szMsg[WOWFAX_MAX_USER_MSG_LEN];
+ TCHAR szTitle[WOWFAX_MAX_USER_MSG_LEN];
+ WCHAR szWowExec[] = L"WOWEXEC";
+
+ if ((hwnd = FindWindow(WOWFAX_CLASS, NULL)) == NULL) {
+ // You can't find the WowFaxWindow, try to start WOW.
+ RtlZeroMemory((PVOID)&StartupInfo, (DWORD)sizeof(StartupInfo));
+ StartupInfo.cb = sizeof(StartupInfo);
+ StartupInfo.dwFlags = STARTF_USESHOWWINDOW;
+ StartupInfo.wShowWindow = SW_NORMAL;
+
+ if (CreateProcess(NULL,
+ szWowExec,
+ NULL, // security
+ NULL, // security
+ FALSE, // inherit handles
+ CREATE_NEW_CONSOLE | CREATE_DEFAULT_ERROR_MODE,
+ NULL, // environment strings
+ NULL, // current directory
+ &StartupInfo,
+ &ProcessInformation)) {
+
+ WaitForInputIdle(ProcessInformation.hProcess, 10*1000);
+
+ if ((hwnd = FindWindow(WOWFAX_CLASS, NULL)) != NULL) {
+ return(hwnd);
+ }
+ }
+
+ // WOW failed to start. Let user know.
+ if (LoadString(ghInst, WOWFAX_NAME_STR, szTitle, WOWFAX_MAX_USER_MSG_LEN)) {
+ if (LoadString(ghInst, WOWFAX_NOWOW_STR, szMsg, WOWFAX_MAX_USER_MSG_LEN)) {
+ MessageBox(hwnd, szMsg, szTitle, MB_OK);
+ }
+ }
+ }
+ return(hwnd);
+}
+
+//************************************************************************
+// DupTokenW - Helper for Get16BitDriverInfoFromRegistry. Allocate and
+// copy a token, wide format. Allocates storage for duplicate.
+// wcsdup is not present in the run-times we link to.
+//************************************************************************
+
+LPTSTR DupTokenW(LPTSTR lpTok)
+{
+ LPTSTR lpRetVal = NULL;
+
+ if (lpTok != NULL) {
+ lpRetVal = WFLOCALALLOC((wcslen(lpTok) + 1) * sizeof(TCHAR), L"DupTokenW");
+ if (lpRetVal) {
+ wcscpy(lpRetVal, lpTok);
+ }
+ }
+ return(lpRetVal);
+}
+
+//************************************************************************
+// Get16BitDriverInfoFromRegistry - Get the 16-bit driver info (name, port)
+// from the registry where it is written by the 16-bit fax driver
+// install program using an intercepted WriteProfileString. Storage is
+// allocated for the returned info, and must be freed by the caller
+// using Free16BitDriverInfo. See also Set16BitDriverInfoToRegistry
+// in WOW32FAX.C
+//************************************************************************
+
+LPREGFAXDRVINFO16 Get16BitDriverInfoFromRegistry(PWSTR pDeviceName)
+{
+ TCHAR szRetBuf[256];
+ HKEY hKey = 0;
+ DWORD dwType, cbBufSize = 256;
+ LPTSTR lpTok;
+
+ LPREGFAXDRVINFO16 lpRetVal = WFLOCALALLOC(sizeof(REGFAXDRVINFO16), L"Get16BitDriverInfoFromRegistry");
+
+ if ((pDeviceName != NULL) && (lpRetVal != NULL)) {
+ if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
+ L"Software\\Microsoft\\Windows NT\\CurrentVersion\\WOW\\WowFax\\devices",
+ 0, KEY_READ, &hKey ) == ERROR_SUCCESS) {
+
+ if (RegQueryValueEx(hKey, pDeviceName, 0, &dwType, (LPBYTE)szRetBuf, &cbBufSize) == ERROR_SUCCESS) {
+ RegCloseKey(hKey);
+
+ // Make wcstok multi-thread safe, it stores state.
+ EnterCriticalSection(lpCriticalSection);
+ lpTok = wcstok(szRetBuf, L",");
+ LeaveCriticalSection(lpCriticalSection);
+
+ if ((lpRetVal->lpDriverName = DupTokenW(lpTok)) != NULL) {
+ EnterCriticalSection(lpCriticalSection);
+ lpTok = wcstok(NULL, L",");
+ LeaveCriticalSection(lpCriticalSection);
+ lpRetVal->lpPortName = DupTokenW(lpTok);
+ LOGDEBUG(1, (L"WOWFAXUI!Get16BitDriverInfoFromRegistry, Name: %s, Driver: %s, Port: %s\n", pDeviceName, lpRetVal->lpDriverName, lpRetVal->lpPortName));
+ return(lpRetVal);
+ }
+ }
+ RegCloseKey(hKey);
+ }
+ }
+
+ if (pDeviceName) {
+ LOGDEBUG(0, (L"WOWFAXUI!Get16BitDriverInfoFromRegistry, failed Name: %s\n", pDeviceName));
+ }
+ else {
+ LOGDEBUG(0, (L"WOWFAXUI!Get16BitDriverInfoFromRegistry, failed Name: NULL\n"));
+ }
+
+ Free16BitDriverInfo(lpRetVal);
+ return(NULL);
+}
+
+//************************************************************************
+// Free16BitDriverInfo - Free the 16-bit driver info allocated by
+// Get16BitDriverInfoFromRegistry.
+//************************************************************************
+
+VOID Free16BitDriverInfo(LPREGFAXDRVINFO16 lpRegFaxDrvInfo16)
+{
+ if (lpRegFaxDrvInfo16) {
+ if (lpRegFaxDrvInfo16->lpDriverName) {
+ LocalFree(lpRegFaxDrvInfo16->lpDriverName);
+ }
+ if (lpRegFaxDrvInfo16->lpPortName) {
+ LocalFree(lpRegFaxDrvInfo16->lpPortName);
+ }
+ LocalFree(lpRegFaxDrvInfo16);
+ return;
+ }
+}
+
+//***************************************************************************
+// InterProcCommHandler - Handles inter-process communication between
+// WOWFAXUI-WOW32 and WOWFAX-WOW32.
+//***************************************************************************
+
+BOOL InterProcCommHandler(LPFAXDEV lpdev, UINT iAction)
+{
+ LPWOWFAXINFO lpT = lpdev->lpMap;
+ HANDLE hMap = 0;
+ WNDPROC wndproc;
+ MSG msg;
+
+ switch (iAction)
+ {
+ case DRVFAX_SETMAPDATA:
+ if (lpdev->lpMap) {
+ // init map struct
+ lpdev->lpMap->status = FALSE;
+ lpdev->lpMap->retvalue = (DWORD)-1;
+ lpdev->hwnd = FindWowFaxWindow();
+ lpdev->lpMap->hwnd = lpdev->hwnd;
+ lpdev->lpMap->msg = 0;
+ lpdev->lpMap->hdc = (WPARAM)lpdev->idMap;
+ (DWORD)lpdev->lpMap->lpinfo16 = lpdev->lpinfo16;
+ }
+ break;
+
+ case DRVFAX_SENDTOWOW:
+ if (lpdev->lpMap->hwnd) {
+ SendMessage(lpdev->lpMap->hwnd, lpdev->lpMap->msg, (WPARAM)lpdev->idMap, 0);
+ }
+ else {
+ LOGDEBUG(0, (L"WOWFAXUI!InterProcCommHandler, No hwnd to send to.\n"));
+ }
+ break;
+
+ case DRVFAX_CALLWOW:
+ if (lpdev->lpMap->hwnd) {
+ wndproc = (WNDPROC) GetWindowLongA(lpdev->lpMap->hwnd, GWL_WNDPROC);
+ CallWindowProc(wndproc, lpdev->lpMap->hwnd, lpdev->lpMap->msg, (WPARAM)lpdev->idMap, 0);
+ }
+ else {
+ LOGDEBUG(0, (L"WOWFAXUI!InterProcCommHandler, No hwnd to call to.\n"));
+ }
+ break;
+
+ case DRVFAX_SENDNOTIFYWOW:
+ if (lpdev->lpMap->hwnd) {
+ SendNotifyMessage(lpdev->lpMap->hwnd, lpdev->lpMap->msg, (WPARAM)lpdev->idMap, 0);
+
+ // To simulate app-modal dialog, pass message's to this threads
+ // windows to DefWndProc, until 16-bit fax driver UI is dismissed.
+ while (!lpdev->lpMap->status) {
+ if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
+ if (msg.message != WM_PAINT) {
+ DefWindowProc(msg.hwnd, msg.message, msg.wParam, msg.lParam);
+ }
+ else {
+ DispatchMessage(&msg);
+ }
+ }
+ }
+ }
+ break;
+
+ case DRVFAX_CREATEMAP:
+ case DRVFAX_DESTROYMAP:
+ if (lpdev->lpMap) {
+
+ // destroys the current map - for both iActions
+ UnmapViewOfFile(lpdev->lpMap);
+ CloseHandle(lpdev->hMap);
+ lpdev->lpMap = 0;
+ lpdev->hMap = 0;
+ lpT = 0;
+ }
+
+ if (iAction == DRVFAX_CREATEMAP) {
+ // GetFaxDataMapName is WOWFAX_INC_COMMON_CODE in wowfax.h.
+ GetFaxDataMapName((DWORD)lpdev->idMap, lpdev->szMap);
+ hMap = CreateFileMapping((HANDLE)-1, NULL, PAGE_READWRITE,
+ 0, lpdev->cbMapLow, lpdev->szMap);
+ if (hMap) {
+ if (GetLastError() == ERROR_ALREADY_EXISTS) {
+ CloseHandle(hMap);
+ }
+ else {
+ lpT = (LPWOWFAXINFO)MapViewOfFile(hMap, FILE_MAP_WRITE, 0, 0, 0);
+ if (lpT) {
+ lpdev->hMap = hMap;
+ lpdev->lpMap = lpT;
+ }
+ else {
+ LOGDEBUG(0, (L"WOWFAXUI!InterProcCommHandler, MapViewOfFile failed, LastError = %ld\n", GetLastError()));
+ CloseHandle(hMap);
+ }
+ }
+ }
+ else {
+ LOGDEBUG(0, (L"WOWFAXUI!InterProcCommHandler, CreateFileMapping failed, LastError = %ld\n", GetLastError()));
+ }
+ }
+ break;
+
+ } //switch
+
+ return((BOOL)lpT);
+}
+
+
diff --git a/private/mvdm/fax/wowfaxui/wfsheets.c b/private/mvdm/fax/wowfaxui/wfsheets.c
new file mode 100644
index 000000000..f5526faed
--- /dev/null
+++ b/private/mvdm/fax/wowfaxui/wfsheets.c
@@ -0,0 +1,405 @@
+//************************************************************************
+// Generic Win 3.1 fax printer driver support. User Interface functions
+// which are called by WINSPOOL. Support for Two new entry points required
+// by the Win 95 printer UI, DrvDocumentPropertySheets and
+// DrvDevicePropertySheets
+//
+// History:
+// 24-Apr-96 reedb created.
+//
+//************************************************************************
+
+#include "windows.h"
+#include "wowfaxui.h"
+#include "wfsheets.h"
+#include "winspool.h"
+
+//************************************************************************
+// Globals
+//************************************************************************
+
+extern HINSTANCE ghInst;
+
+DEVMODEW gdmDefaultDevMode;
+
+LONG DrvDocumentProperties(HWND hwnd, HANDLE hPrinter, PWSTR pDeviceName, PDEVMODE pdmOut, PDEVMODE pdmIn, DWORD fMode);
+LONG SimpleDocumentProperties(PDOCUMENTPROPERTYHEADER pDPHdr);
+
+//************************************************************************
+// NullDlgProc - Procedure for handling "Printer Properties" property
+// sheet page
+//************************************************************************
+
+BOOL NullDlgProc(HWND hDlg, UINT message, UINT wParam, LONG lParam)
+{
+ return FALSE;
+}
+
+//************************************************************************
+// FaxOptionsProc - Procedure for handling "Fax Options" property
+// sheet page
+//************************************************************************
+
+BOOL FaxOptionsProc(HWND hDlg, UINT message, UINT wParam, LONG lParam)
+{
+ PDEVMODE pdmOut = NULL;
+ PDEVMODE pdmIn = NULL;
+ PUIDATA pUiData;
+ TCHAR szFeedBack[WOWFAX_MAX_USER_MSG_LEN];
+
+ switch (message) {
+ case WM_INITDIALOG:
+ SetWindowLong(hDlg, DWL_USER, ((PROPSHEETPAGE *) lParam)->lParam);
+ return TRUE;
+
+ case WM_COMMAND:
+ if (wParam == IDOK) {
+ SetWindowText(GetDlgItem(hDlg, IDC_FEEDBACK), L"");
+
+ pUiData = (PUIDATA) GetWindowLong(hDlg, DWL_USER);
+ DrvDocumentProperties(hDlg,
+ pUiData->hPrinter,
+ pUiData->pDeviceName,
+ pUiData->pdmOut,
+ pUiData->pdmIn,
+ pUiData->fMode);
+
+ //
+ // Provide user with feedback text.
+ //
+ if (LoadString(ghInst, WOWFAX_ENABLE_CONFIG_STR,
+ szFeedBack, sizeof(szFeedBack))) {
+ SetWindowText(GetDlgItem(hDlg, IDC_FEEDBACK), szFeedBack);
+ }
+ }
+ break;
+
+ case WM_NOTIFY:
+
+ if (((NMHDR *) lParam)->code == PSN_APPLY) {
+
+ pUiData = (PUIDATA) GetWindowLong(hDlg, DWL_USER);
+
+ //
+ // HACK: Inform common UI library that user has pressed OK
+ //
+
+ pUiData->pfnComPropSheet(pUiData->hComPropSheet,
+ CPSFUNC_SET_RESULT,
+ (LONG) pUiData->hFaxOptsPage,
+ CPSUI_OK);
+ return TRUE;
+
+ }
+ break;
+ }
+
+ return FALSE;
+}
+
+//************************************************************************
+// AddDocPropPages -Add our "Document Properties" pages to the property
+// sheet. Returns RUE if successful, FALSE otherwise.
+//************************************************************************
+
+BOOL AddDocPropPages(PUIDATA pUiData)
+{
+ PROPSHEETPAGE psp;
+ LONG result;
+
+ //
+ // "Document Properties" dialog only has one tab - "Fax Options"
+ //
+
+ memset(&psp, 0, sizeof(psp));
+ psp.dwSize = sizeof(PROPSHEETPAGE);
+ psp.dwFlags = 0;
+ psp.hInstance = ghInst;
+ psp.lParam = (LPARAM) pUiData;
+ psp.pszTemplate = MAKEINTRESOURCE(IDD_DOCPROP);
+ psp.pfnDlgProc = FaxOptionsProc;
+
+ pUiData->hFaxOptsPage = (HANDLE)
+ pUiData->pfnComPropSheet(pUiData->hComPropSheet,
+ CPSFUNC_ADD_PROPSHEETPAGE,
+ (LPARAM) &psp,
+ 0);
+
+ return (pUiData->hFaxOptsPage != NULL);
+}
+
+
+//************************************************************************
+// MyGetPrinter - Wrapper function for GetPrinter spooler API. Returns
+// Pointer to a PRINTER_INFO_x structure, NULL if there is an error
+//************************************************************************
+
+PVOID MyGetPrinter(HANDLE hPrinter, DWORD level)
+{
+ PBYTE pPrinterInfo = NULL;
+ DWORD cbNeeded;
+
+ if (!GetPrinter(hPrinter, level, NULL, 0, &cbNeeded) &&
+ GetLastError() == ERROR_INSUFFICIENT_BUFFER &&
+ (pPrinterInfo = LocalAlloc(LPTR, cbNeeded)) &&
+ GetPrinter(hPrinter, level, pPrinterInfo, cbNeeded, &cbNeeded))
+ {
+ return pPrinterInfo;
+ }
+
+ LOGDEBUG(0, (L"GetPrinter failed\n"));
+ LocalFree(pPrinterInfo);
+ return NULL;
+}
+
+//************************************************************************
+// FreeUiData - Free the data structure used by the fax driver user
+// interface.
+//************************************************************************
+
+PUIDATA FreeUiData(PUIDATA pUiData)
+{
+ if (pUiData) {
+ if (pUiData->pDeviceName) LocalFree(pUiData->pDeviceName);
+ if (pUiData->pDriverName) LocalFree(pUiData->pDriverName);
+ }
+ return NULL;
+}
+
+//************************************************************************
+// FillUiData - Fill in the data structure used by the fax driver user
+// interface. Returns pointer to UIDATA structure, NULL if error.
+//************************************************************************
+
+PUIDATA FillUiData(HANDLE hPrinter, PDEVMODE pdmInput, PDEVMODE pdmOutput, DWORD fMode)
+{
+ PRINTER_INFO_2 *pPrinterInfo2;
+ PUIDATA pUiData;
+
+ //
+ // Allocate memory to hold UIDATA structure
+ // Get printer info from the spooler. Copy the driver name.
+ //
+
+ if (! (pUiData = LocalAlloc(LPTR, sizeof(UIDATA))) ||
+ ! (pPrinterInfo2 = MyGetPrinter(hPrinter, 2)) ||
+ ! (pUiData->pDeviceName = DupTokenW(pPrinterInfo2->pPrinterName)) ||
+ ! (pUiData->pDriverName = DupTokenW(pPrinterInfo2->pDriverName))) {
+
+ pUiData = FreeUiData(pUiData);
+ }
+ else {
+ pUiData->pdmIn = pdmInput;
+ pUiData->pdmOut = pdmOutput;
+ pUiData->fMode = fMode;
+
+ pUiData->startUiData = pUiData->endUiData = pUiData;
+ pUiData->hPrinter = hPrinter;
+ }
+
+ if (pPrinterInfo2)
+ LocalFree(pPrinterInfo2);
+
+ return pUiData;
+}
+
+//************************************************************************
+// DrvDocumentPropertySheets - Display "Document Properties" property
+// sheets. Return > 0 if successful, <= 0 if failed.
+//************************************************************************
+
+LONG DrvDocumentPropertySheets(PPROPSHEETUI_INFO pPSUIInfo, LPARAM lParam)
+{
+ PDOCUMENTPROPERTYHEADER pDPHdr;
+ PCOMPROPSHEETUI pCompstui;
+ PUIDATA pUiData;
+ LONG result;
+
+ //
+ // Validate input parameters
+ //
+ if (! (pDPHdr = (PDOCUMENTPROPERTYHEADER) (pPSUIInfo ? pPSUIInfo->lParamInit : lParam))) {
+ return -1;
+ }
+
+ if (pPSUIInfo == NULL) {
+ return SimpleDocumentProperties(pDPHdr);
+ }
+
+ //
+ // Create a UIDATA structure if necessary
+ //
+
+ pUiData = (pPSUIInfo->Reason == PROPSHEETUI_REASON_INIT) ?
+ FillUiData(pDPHdr->hPrinter, pDPHdr->pdmIn, pDPHdr->pdmOut, pDPHdr->fMode) :
+ (PUIDATA) pPSUIInfo->UserData;
+
+ if (! ValidUiData(pUiData))
+ return -1;
+
+ //
+ // Handle various cases for which this function might be called
+ //
+
+ switch (pPSUIInfo->Reason) {
+
+ case PROPSHEETUI_REASON_INIT:
+
+ pUiData->pfnComPropSheet = pPSUIInfo->pfnComPropSheet;
+ pUiData->hComPropSheet = pPSUIInfo->hComPropSheet;
+
+ //
+ // Add our page to the property sheet
+ //
+
+ if (AddDocPropPages(pUiData)) {
+
+ pPSUIInfo->UserData = (DWORD) pUiData;
+ pPSUIInfo->Result = CPSUI_CANCEL;
+ return 1;
+ }
+
+ //
+ // Clean up properly in case of an error
+ //
+
+ FreeUiData(pUiData);
+ break;
+
+ case PROPSHEETUI_REASON_GET_INFO_HEADER:
+
+ { PPROPSHEETUI_INFO_HEADER pPSUIHdr;
+
+ pPSUIHdr = (PPROPSHEETUI_INFO_HEADER) lParam;
+ pPSUIHdr->Flags = PSUIHDRF_PROPTITLE | PSUIHDRF_NOAPPLYNOW;
+ pPSUIHdr->pTitle = pDPHdr->pszPrinterName;
+ pPSUIHdr->hInst = ghInst;
+ pPSUIHdr->IconID = IDI_CPSUI_PRINTER2;
+ }
+ return 1;
+
+ case PROPSHEETUI_REASON_SET_RESULT:
+
+ pPSUIInfo->Result = ((PSETRESULT_INFO) lParam)->Result;
+ return 1;
+
+ case PROPSHEETUI_REASON_DESTROY:
+
+ //
+ // Cleanup properly before exiting
+ //
+
+ FreeUiData(pUiData);
+ return 1;
+ }
+ return -1;
+}
+
+//************************************************************************
+// DrvDevicePropertySheets - Display "Printer Properties" dialog.
+// Return > 0 if successful, <= 0 if failed.
+//************************************************************************
+
+LONG DrvDevicePropertySheets(PPROPSHEETUI_INFO pPSUIInfo, LPARAM lParam)
+{
+ PDEVICEPROPERTYHEADER pDPHdr;
+ PCOMPROPSHEETUI pCompstui;
+ PROPSHEETPAGE psp;
+ LONG result;
+
+ //
+ // Validate input parameters
+ //
+ LOGDEBUG(1,(L"DrvDevicePropertySheets: %d\n", pPSUIInfo->Reason));
+
+ if (!pPSUIInfo || !(pDPHdr = (PDEVICEPROPERTYHEADER) pPSUIInfo->lParamInit)) {
+ return -1;
+ }
+
+ //
+ // Handle various cases for which this function might be called
+ //
+
+ switch (pPSUIInfo->Reason) {
+
+ case PROPSHEETUI_REASON_INIT:
+ //
+ // "Printer Properties" dialog only has one dummy tab
+ //
+
+ memset(&psp, 0, sizeof(psp));
+ psp.dwSize = sizeof(PROPSHEETPAGE);
+ psp.dwFlags = 0;
+ psp.hInstance = ghInst;
+
+ psp.pszTemplate = MAKEINTRESOURCE(IDD_NULLPROP);
+ psp.pfnDlgProc = NullDlgProc;
+
+ if (pPSUIInfo->pfnComPropSheet(pPSUIInfo->hComPropSheet,
+ CPSFUNC_ADD_PROPSHEETPAGE,
+ (LPARAM) &psp,
+ 0))
+ {
+ pPSUIInfo->Result = CPSUI_CANCEL;
+ return 1;
+ }
+ break;
+
+ case PROPSHEETUI_REASON_GET_INFO_HEADER:
+ { PPROPSHEETUI_INFO_HEADER pPSUIHdr;
+
+ pPSUIHdr = (PPROPSHEETUI_INFO_HEADER) lParam;
+ pPSUIHdr->Flags = PSUIHDRF_PROPTITLE | PSUIHDRF_NOAPPLYNOW;
+ pPSUIHdr->pTitle = pDPHdr->pszPrinterName;
+ pPSUIHdr->hInst = ghInst;
+ pPSUIHdr->IconID = IDI_CPSUI_FAX;
+ }
+ return 1;
+
+ case PROPSHEETUI_REASON_SET_RESULT:
+ pPSUIInfo->Result = ((PSETRESULT_INFO) lParam)->Result;
+ return 1;
+
+ case PROPSHEETUI_REASON_DESTROY:
+ return 1;
+ }
+
+ return -1;
+}
+
+LONG
+SimpleDocumentProperties(PDOCUMENTPROPERTYHEADER pDPHdr)
+
+/*++
+
+Routine Description:
+
+ Handle simple "Document Properties" where we don't need to display
+ a dialog and therefore don't have to have common UI library involved
+
+Arguments:
+
+ pDPHdr - Points to a DOCUMENTPROPERTYHEADER structure
+
+Return Value:
+
+ > 0 if successful, <= 0 otherwise
+
+--*/
+
+{
+ LONG lRet;
+
+ lRet = DrvDocumentProperties(NULL,
+ pDPHdr->hPrinter,
+ pDPHdr->pszPrinterName,
+ pDPHdr->pdmOut,
+ pDPHdr->pdmIn,
+ pDPHdr->fMode);
+
+ if (pDPHdr->fMode == 0 || pDPHdr->pdmOut == NULL) {
+ pDPHdr->cbOut = lRet;
+ }
+
+ return lRet;
+}
diff --git a/private/mvdm/fax/wowfaxui/wfsheets.h b/private/mvdm/fax/wowfaxui/wfsheets.h
new file mode 100644
index 000000000..2f59f0293
--- /dev/null
+++ b/private/mvdm/fax/wowfaxui/wfsheets.h
@@ -0,0 +1,33 @@
+//************************************************************************
+// Generic Win 3.1 fax printer driver support. User Interface functions
+// which are called by WINSPOOL. Support for Two new entry points required
+// by the Win 95 printer UI, DrvDocumentPropertySheets and
+// DrvDevicePropertySheets
+//
+// History:
+// 24-Apr-96 reedb created.
+//
+//************************************************************************
+
+#include "winddiui.h"
+
+// Data structure maintained by the fax driver user interface
+typedef struct {
+
+ PVOID startUiData;
+ HANDLE hPrinter;
+ PDEVMODE pdmIn;
+ PDEVMODE pdmOut;
+ DWORD fMode;
+ LPTSTR pDriverName;
+ LPTSTR pDeviceName;
+ PFNCOMPROPSHEET pfnComPropSheet;
+ HANDLE hComPropSheet;
+ HANDLE hFaxOptsPage;
+ PVOID endUiData;
+
+} UIDATA, *PUIDATA;
+
+#define ValidUiData(pUiData) \
+ ((pUiData) && (pUiData) == (pUiData)->startUiData && (pUiData) == (pUiData)->endUiData)
+
diff --git a/private/mvdm/fax/wowfaxui/wfupgrad.c b/private/mvdm/fax/wowfaxui/wfupgrad.c
new file mode 100644
index 000000000..b382d605e
--- /dev/null
+++ b/private/mvdm/fax/wowfaxui/wfupgrad.c
@@ -0,0 +1,264 @@
+//************************************************************************
+// Generic Win 3.1 fax printer driver support. User Interface helper
+// functions which are called in WOWFAXUI.C, helpers used during upgrade.
+//
+// History:
+// 14-mar-95 reedb Created. These were moved from WOWFAXUI.C.
+//
+//************************************************************************
+
+#include "windows.h"
+#include "wowfaxui.h"
+#include "winspool.h"
+
+extern LPCRITICAL_SECTION lpCriticalSection;
+extern HINSTANCE ghInst;
+
+//************************************************************************
+// AllocPathW - Helper for DrvUpgradePrinter and friends.
+//************************************************************************
+
+PWSTR AllocPathW(VOID)
+{
+ PWSTR szTmp;
+
+ szTmp = WFLOCALALLOC((MAX_PATH+1) * sizeof(TCHAR), L"AllocPathW");
+ return(szTmp);
+}
+
+//************************************************************************
+// BuildPathW - Helper for DrvUpgradePrinter and friends.
+//************************************************************************
+
+PWSTR BuildPathW(PWSTR szPath, PWSTR szFileName)
+{
+ PWSTR szTmp;
+
+ if ((szTmp = WFLOCALALLOC((MAX_PATH+1) * sizeof(TCHAR), L"BuildPathW")) != NULL) {
+ wcscpy(szTmp, szPath);
+ wcscat(szTmp, L"\\");
+ wcscat(szTmp, szFileName);
+ return(szTmp);
+ }
+ else {
+ return(NULL);
+ }
+}
+
+//************************************************************************
+// MyGetFileTime - Helper for DrvUpgradePrinter and friends.
+//************************************************************************
+
+BOOL MyGetFileTime(PWSTR szDir, PWSTR szName, LPFILETIME lpFileTime)
+{
+ LPWIN32_FIND_DATA lpfd;
+ HANDLE hfd;
+ PWSTR szTmp;
+ BOOL bRet = FALSE;
+
+
+ szTmp = BuildPathW(szDir, szName);
+ lpfd = WFLOCALALLOC(sizeof(WIN32_FIND_DATA), L"MyGetFileTime");
+
+ if ((szTmp) && (lpfd)) {
+ LOGDEBUG(1, (L"WOWFAXUI!GetFileTime, szTmp: %s\n", szTmp));
+ if ((hfd = FindFirstFile(szTmp, lpfd)) != INVALID_HANDLE_VALUE) {
+ memcpy(lpFileTime, &(lpfd->ftLastWriteTime), sizeof(FILETIME));
+ FindClose(hfd);
+ bRet = TRUE;
+ LOGDEBUG(1, (L"WOWFAXUI!GetFileTime, FileTimeHi: %X FileTimeLo: %X\n", lpFileTime->dwHighDateTime, lpFileTime->dwLowDateTime));
+ }
+ else {
+ LOGDEBUG(0, (L"WOWFAXUI!GetFileTime, file not found: %s\n", szTmp));
+ }
+ }
+
+ if (szTmp) {
+ LocalFree(szTmp);
+ }
+ if (lpfd) {
+ LocalFree(lpfd);
+ }
+ return(bRet);
+}
+
+//************************************************************************
+// CheckForNewerFiles - Helper for DrvUpgradePrinter. Compares the date/time
+// of wowfaxui.dll and wowfax.dll in the two passed directories. Returns
+// FALSE if files in szOldDriverDir are the same or newer than those
+// in szSysDir. Otherwise returns non-zero.
+//************************************************************************
+
+BOOL CheckForNewerFiles(PWSTR szOldDriverDir, PWSTR szSysDir)
+{
+ FILETIME ftSourceDriver, ftCurrentDriver;
+ BOOL bRet = FALSE;
+
+ if ((szOldDriverDir) && (szSysDir)) {
+ if (MyGetFileTime(szOldDriverDir, L"wowfax.dll", &ftCurrentDriver)) {
+ if (MyGetFileTime(szSysDir, L"wowfax.dll", &ftSourceDriver)) {
+ // Check time/date to see if we need to update the drivers.
+ if (CompareFileTime(&ftSourceDriver, &ftCurrentDriver) > 0) {
+ bRet = TRUE;
+ }
+ }
+ }
+ if (MyGetFileTime(szOldDriverDir, L"wowfaxui.dll", &ftCurrentDriver)) {
+ if (MyGetFileTime(szSysDir, L"wowfaxui.dll", &ftSourceDriver)) {
+ if (CompareFileTime(&ftSourceDriver, &ftCurrentDriver) > 0) {
+ bRet = TRUE;
+ }
+ }
+ }
+ }
+ else {
+ LOGDEBUG(0, (L"WOWFAXUI!CheckForNewerFiles: NULL directory parameters\n"));
+ }
+
+ return(bRet);
+}
+
+//************************************************************************
+// DoUpgradePrinter - Called by DrvUpgradePrinter which is called in the
+// system context by the spooler.
+//************************************************************************
+
+BOOL DoUpgradePrinter(DWORD dwLevel, LPDRIVER_UPGRADE_INFO_1W lpDrvUpgradeInfo)
+{
+ static BOOL bDrvUpgradePrinterLock = FALSE;
+ HANDLE hPrinter = NULL;
+ DRIVER_INFO_2 DriverInfo, *pDriverInfo = NULL;
+ DWORD dwNeeded = 0;
+ PWSTR szSysDir = NULL;
+ PWSTR szDstDir = NULL;
+ PWSTR szSrcPath = NULL;
+ PWCHAR pwc;
+ BOOL bRet = FALSE;
+ TCHAR szName[WOWFAX_MAX_USER_MSG_LEN] = L"";
+
+ // Check for correct level for upgrade.
+ if (dwLevel != 1) {
+ LOGDEBUG(0, (L"WOWFAXUI!DrvUpgradePrinter, Bad input Level\n"));
+ SetLastError(ERROR_INVALID_LEVEL);
+ goto DoUpgradePrinterExit;
+ }
+
+ szDstDir = AllocPathW();
+ szSysDir = AllocPathW();
+ if (!szDstDir || !szSysDir) {
+ LOGDEBUG(0, (L"WOWFAXUI!DoUpgradePrinter, work space allocation failed\n"));
+ goto DoUpgradePrinterExit;
+ }
+
+ if (!GetSystemDirectory(szSysDir, MAX_PATH+1)) {
+ LOGDEBUG(0, (L"WOWFAXUI!DoUpgradePrinter, GetSystemDirectory failed\n"));
+ goto DoUpgradePrinterExit;
+ }
+
+ if (!lpDrvUpgradeInfo->pPrinterName) {
+ LOGDEBUG(0, (L"WOWFAXUI!DoUpgradePrinter, pPrinterName is NULL\n"));
+ goto DoUpgradePrinterExit;
+ }
+
+ // Get the paths to the old printer drivers.
+ if (!OpenPrinter(lpDrvUpgradeInfo->pPrinterName, &hPrinter, NULL)) {
+ LOGDEBUG(0, (L"WOWFAXUI!DoUpgradePrinter, Unable to open: %s\n", lpDrvUpgradeInfo->pPrinterName));
+ goto DoUpgradePrinterExit;
+ }
+
+ GetPrinterDriver(hPrinter, NULL, 2, (LPBYTE) pDriverInfo, 0, &dwNeeded);
+
+ if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
+ LOGDEBUG(0, (L"WOWFAXUI!DoUpgradePrinter, GetPrinterDriver failed\n"));
+ goto DoUpgradePrinterExit;
+ }
+
+ if ((pDriverInfo = WFLOCALALLOC(dwNeeded, L"DoUpgradePrinter")) == NULL) {
+ LOGDEBUG(0, (L"WOWFAXUI!DoUpgradePrinter, work space allocation failed\n"));
+ goto DoUpgradePrinterExit;
+ }
+
+ if (!GetPrinterDriver(hPrinter, NULL, 2, (LPBYTE) pDriverInfo, dwNeeded, &dwNeeded)) {
+ LOGDEBUG(0, (L"WOWFAXUI!DoUpgradePrinter, GetPrinterDriver failed, GetLastError: %d\n", GetLastError()));
+ goto DoUpgradePrinterExit;
+ }
+ ClosePrinter(hPrinter);
+
+ // Strip off the file name.
+ if ((pwc = wcsrchr(pDriverInfo->pDriverPath, L'\\')) == NULL) {
+ LOGDEBUG(0, (L"WOWFAXUI!DoUpgradePrinter, unable to strip file name\n"));
+ goto DoUpgradePrinterExit;
+ }
+ *pwc = UNICODE_NULL;
+
+ // Install new printer driver if it's more recent than the old one.
+ if (CheckForNewerFiles(pDriverInfo->pDriverPath, szSysDir)) {
+ LOGDEBUG(1, (L"WOWFAXUI!DoUpgradePrinter, Doing driver update\n"));
+ memset(&DriverInfo, 0, sizeof(DRIVER_INFO_2));
+
+ if (!GetPrinterDriverDirectory(NULL, NULL, 1, (LPBYTE) szDstDir, MAX_PATH, &dwNeeded)) {
+ LOGDEBUG(0, (L"WOWFAXUI!DoUpgradePrinter, GetPrinterDriverDirectory failed\n"));
+ goto DoUpgradePrinterExit;
+ }
+
+ // This is a dummy. We've no data file, but spooler won't take NULL.
+ DriverInfo.pDataFile = BuildPathW(szDstDir, WOWFAX_DLL_NAME);
+ DriverInfo.pDriverPath = BuildPathW(szDstDir, WOWFAX_DLL_NAME);
+ LOGDEBUG(1, (L"WOWFAXUI!DoUpgradePrinter, pDriverPath = %s\n", DriverInfo.pDataFile));
+ if (DriverInfo.pDriverPath) {
+ szSrcPath = BuildPathW(szSysDir, WOWFAX_DLL_NAME);
+ if (szSrcPath) {
+ CopyFile(szSrcPath, DriverInfo.pDriverPath, FALSE);
+ LocalFree(szSrcPath);
+ }
+ }
+
+ DriverInfo.pConfigFile = BuildPathW(szDstDir, WOWFAXUI_DLL_NAME);
+ szSrcPath = BuildPathW(szSysDir, WOWFAXUI_DLL_NAME);
+ if (DriverInfo.pConfigFile) {
+ if (szSrcPath) {
+ CopyFile(szSrcPath, DriverInfo.pConfigFile, FALSE);
+ LocalFree(szSrcPath);
+ }
+ }
+
+ // Install the printer driver.
+ DriverInfo.cVersion = 1;
+ if (LoadString(ghInst, WOWFAX_NAME_STR, szName, WOWFAX_MAX_USER_MSG_LEN)) {
+ DriverInfo.pName = szName;
+ if (AddPrinterDriver(NULL, 2, (LPBYTE) &DriverInfo) == FALSE) {
+ bRet = (GetLastError() == ERROR_PRINTER_DRIVER_ALREADY_INSTALLED);
+ }
+ else {
+ bRet = TRUE;
+ }
+ }
+ if (DriverInfo.pDataFile) {
+ LocalFree(DriverInfo.pDataFile);
+ }
+ if (DriverInfo.pDriverPath) {
+ LocalFree(DriverInfo.pDriverPath);
+ }
+ if (DriverInfo.pConfigFile) {
+ LocalFree(DriverInfo.pConfigFile);
+ }
+ }
+ else {
+ LOGDEBUG(1, (L"WOWFAXUI!DoUpgradePrinter, No driver update\n"));
+ bRet = TRUE;
+ }
+
+DoUpgradePrinterExit:
+ if (szDstDir) {
+ LocalFree(szDstDir);
+ }
+ if (szSysDir) {
+ LocalFree(szSysDir);
+ }
+ if (pDriverInfo) {
+ LocalFree(pDriverInfo);
+ }
+
+ return(bRet);
+}
+
diff --git a/private/mvdm/fax/wowfaxui/wowfaxui.c b/private/mvdm/fax/wowfaxui/wowfaxui.c
new file mode 100644
index 000000000..bace4cff2
--- /dev/null
+++ b/private/mvdm/fax/wowfaxui/wowfaxui.c
@@ -0,0 +1,874 @@
+//************************************************************************
+// Generic Win 3.1 fax printer driver support. User Interface functions
+// which are called by WINSPOOL.
+//
+// I don't think performance is a big issue here. - nandurir
+//
+// History:
+// 02-jan-95 nandurir created.
+// 01-feb-95 reedb Clean-up, support printer install and bug fixes.
+// 14-mar-95 reedb Use GDI hooks to move most functionality to UI.
+//
+//************************************************************************
+
+#define WOWFAX_INC_COMMON_CODE
+
+#include "windows.h"
+#include "wowfaxui.h"
+#include "winspool.h"
+
+#define DEF_DRV_DOCUMENT_EVENT_DBG_STR
+#include "gdispool.h"
+#include "winddiui.h"
+
+//************************************************************************
+// Globals
+//************************************************************************
+
+HINSTANCE ghInst;
+FAXDEV gdev;
+WORD gdmDriverExtra = sizeof(DEVMODEW);
+
+DEVMODEW gdmDefaultDevMode;
+
+CRITICAL_SECTION CriticalSection;
+LPCRITICAL_SECTION lpCriticalSection = &CriticalSection;
+
+//************************************************************************
+// DllInitProc
+//************************************************************************
+
+BOOL DllInitProc(HMODULE hModule, DWORD Reason, PCONTEXT pContext)
+{
+ UNREFERENCED_PARAMETER(pContext);
+
+ if (Reason == DLL_PROCESS_ATTACH) {
+ DisableThreadLibraryCalls(hModule);
+ }
+ InitializeCriticalSection(lpCriticalSection);
+ ghInst = (HINSTANCE) hModule;
+
+ return(TRUE);
+}
+
+//************************************************************************
+// PrinterProperties
+//************************************************************************
+
+BOOL PrinterProperties(HWND hwnd, HANDLE hPrinter)
+{
+ TCHAR szMsg[WOWFAX_MAX_USER_MSG_LEN];
+ TCHAR szTitle[WOWFAX_MAX_USER_MSG_LEN];
+
+ if (LoadString(ghInst, WOWFAX_NAME_STR, szTitle, WOWFAX_MAX_USER_MSG_LEN)) {
+ if (LoadString(ghInst, WOWFAX_SELF_CONFIG_STR, szMsg, WOWFAX_MAX_USER_MSG_LEN)) {
+ MessageBox(hwnd, szMsg, szTitle, MB_OK);
+ }
+ }
+ return TRUE;
+}
+
+//************************************************************************
+// SetupFaxDev - Do some common FaxDev setup: Calculate the size of the
+// mapped file section for use by the inter-process communication
+// handler. Create and set the mapped section. Get the 16-bit driver
+// info from the registry and copy it into the mapped section. Build
+// pointers for variable length stuff we copied to the mapped section.
+// Return zero on failure, or current offset into mapped section.
+//************************************************************************
+
+UINT SetupFaxDev(PWSTR pDeviceName, LPFAXDEV lpdev)
+{
+ LPREGFAXDRVINFO16 lpRegFaxDrvInfo16;
+ DWORD iOffset = 0;
+
+ // Get the driver and port names from the registry where they were written
+ // by the 16-bit fax driver install program using WriteProfileString.
+ if ((lpRegFaxDrvInfo16 = Get16BitDriverInfoFromRegistry(pDeviceName))) {
+
+ //
+ // Count dmDriverExtra twice, once for each devmode. Use cached
+ // gdmDriverExtra value. Normally winspool/common dialogs and others,
+ // call the DocumentProperties with fMode = 0 to get the size. So we
+ // update gdmDriverExtra when such a call is made. We leave extra
+ // room to DWORD align both In and Out pointers.
+ //
+
+ lpdev->cbMapLow = sizeof(FAXDEV);
+ lpdev->cbMapLow += sizeof(DEVMODE) * 2;
+ lpdev->cbMapLow += gdmDriverExtra * 2;
+ lpdev->cbMapLow += sizeof(DWORD) * 2; // Leave room for DWORD align.
+ lpdev->cbMapLow += (lstrlen(lpRegFaxDrvInfo16->lpDriverName) + 1) * sizeof(TCHAR);
+ lpdev->cbMapLow += (lstrlen(lpRegFaxDrvInfo16->lpPortName) + 1) * sizeof(TCHAR);
+
+ lpdev->idMap = GetCurrentThreadId();
+
+ if (InterProcCommHandler(lpdev, DRVFAX_CREATEMAP)) {
+ if (InterProcCommHandler(lpdev, DRVFAX_SETMAPDATA)) {
+
+ // Copy the printer/device name to the WOWFAXINFO struct.
+ lstrcpy(lpdev->lpMap->szDeviceName, pDeviceName);
+
+ // Calculate the pointers into the mapped file section and copy
+ // the variable length data to the mapped file section.
+
+ // Printer driver and port names.
+ iOffset = sizeof(*lpdev->lpMap);
+ lpdev->lpMap->lpDriverName = (LPTSTR) iOffset;
+ (PWSTR)iOffset += lstrlen(lpRegFaxDrvInfo16->lpDriverName) + 1;
+ lstrcpy((PWSTR)((LPBYTE)lpdev->lpMap + (DWORD)lpdev->lpMap->lpDriverName), lpRegFaxDrvInfo16->lpDriverName);
+ lpdev->lpMap->lpPortName = (LPTSTR) iOffset;
+ (PWSTR)iOffset += lstrlen(lpRegFaxDrvInfo16->lpPortName) + 1;
+ lstrcpy((PWSTR)((LPBYTE)lpdev->lpMap + (DWORD)lpdev->lpMap->lpPortName), lpRegFaxDrvInfo16->lpPortName);
+ }
+ }
+ Free16BitDriverInfo(lpRegFaxDrvInfo16);
+ }
+ return iOffset;
+}
+
+//************************************************************************
+// DrvDocumentProperties
+//************************************************************************
+
+LONG DrvDocumentProperties(HWND hwnd, HANDLE hPrinter, PWSTR pDeviceName,
+ PDEVMODE pdmOut, PDEVMODE pdmIn, DWORD fMode)
+{
+ FAXDEV dev = gdev;
+ LPFAXDEV lpdev = &dev;
+ LONG lRet = -1;
+ DWORD iOffset;
+ DWORD cbT;
+ DWORD dwWowProcID, dwCallerProcID;
+ PRINTER_INFO_2 *pPrinterInfo2 = NULL;
+
+ LOGDEBUG(1, (L"WOWFAXUI!DrvDocumentProperties, pdmOut: %X, pdmIn: %X, fMode: %X\n", pdmOut, pdmIn, fMode));
+
+ // Check for get default devmode case, use spooler to get it if possible.
+ if (!pdmIn && pdmOut && !(fMode & DM_IN_PROMPT)) {
+ if (pPrinterInfo2 = MyGetPrinter(hPrinter, 2)) {
+ if (pPrinterInfo2->pDevMode) {
+ LOGDEBUG(1, (L" Using spooler default devmode\n"));
+ cbT = pPrinterInfo2->pDevMode->dmSize +
+ pPrinterInfo2->pDevMode->dmDriverExtra;
+
+ memcpy(pdmOut, pPrinterInfo2->pDevMode, cbT);
+ lRet = IDOK;
+ goto LeaveDDP;
+ }
+ }
+ }
+
+ if (iOffset = SetupFaxDev(pDeviceName, lpdev)) {
+ lpdev->lpMap->msg = WM_DDRV_EXTDMODE;
+
+ // Calculate the pointers into the mapped file section and copy
+ // the variable length data to the mapped file section.
+ DRVFAX_DWORDALIGN(iOffset);
+ lpdev->lpMap->lpIn = (LPDEVMODEW)((pdmIn) ? iOffset : 0);
+ iOffset += sizeof(*pdmIn) + gdmDriverExtra;
+
+ DRVFAX_DWORDALIGN(iOffset);
+ lpdev->lpMap->lpOut = (LPDEVMODEW)((pdmOut) ? iOffset : 0);
+ iOffset += sizeof(*pdmOut) + gdmDriverExtra;
+
+ //
+ // if Input is non-null copy the data even if fMode doesn't
+ // have the appropriate flag.
+ //
+
+ if (pdmIn) {
+ // apps don't pass DM_MODIFY even if they mean it - ie
+ // pdmIn will be non-null but they won't or this flag.
+ // The 32bit rasdd extracts data from pdmIn even if the
+ // DM_MODIFY flag is not set. So we need to do the same
+
+ if (fMode != 0) {
+ fMode |= DM_IN_BUFFER;
+ }
+
+ iOffset = (DWORD)lpdev->lpMap + (DWORD)lpdev->lpMap->lpIn;
+ RtlCopyMemory((LPVOID)iOffset, pdmIn,
+ sizeof(*pdmIn) + min(gdmDriverExtra, pdmIn->dmDriverExtra));
+
+ // reset dmDriverExtra in pdmIn.
+ ((LPDEVMODE)iOffset)->dmDriverExtra =
+ min(gdmDriverExtra, pdmIn->dmDriverExtra);
+ }
+
+ if (!(fMode & (DM_COPY | DM_OUT_BUFFER))) {
+ lpdev->lpMap->lpOut = 0;
+ }
+
+ lpdev->lpMap->wCmd = (WORD)fMode;
+
+ // valid size of this map
+ lpdev->lpMap->cData = lpdev->cbMapLow;
+
+
+ lpdev->lpMap->hwndui = hwnd;
+ if (fMode & DM_IN_PROMPT) {
+ GetWindowThreadProcessId(hwnd, &dwCallerProcID);
+ GetWindowThreadProcessId(lpdev->lpMap->hwnd, &dwWowProcID);
+
+ if (dwWowProcID == dwCallerProcID) {
+
+ // If the calling process is the same as the 'wowfaxclass' window
+ // (WOW/WOWEXEC) use CallWindow instead of SendMessage so we don't
+ // deadlock WOW when trying to put up the 16-bit fax driver UI.
+
+ InterProcCommHandler(lpdev, DRVFAX_CALLWOW);
+ }
+ else {
+ InterProcCommHandler(lpdev, DRVFAX_SENDNOTIFYWOW);
+ }
+ }
+ else {
+ InterProcCommHandler(lpdev, DRVFAX_SENDTOWOW);
+ }
+
+ lRet = (lpdev->lpMap->status) ? (LONG)lpdev->lpMap->retvalue : lRet;
+ if (lRet > 0) {
+ if ((fMode & DM_OUT_BUFFER) && (lRet == IDOK) && pdmOut) {
+ iOffset = (DWORD)lpdev->lpMap + (DWORD)lpdev->lpMap->lpOut;
+ RtlCopyMemory(pdmOut, (LPDEVMODE)iOffset,
+ sizeof(*pdmOut)+ ((LPDEVMODE)iOffset)->dmDriverExtra);
+
+ // LATER : what about the formname etc. fields - new on NT
+ }
+ else if (fMode == 0) {
+ // update our dmDriverExtra
+ gdmDriverExtra = max(lRet, gdmDriverExtra);
+ }
+ }
+ else {
+ LOGDEBUG(0, (L"WOWFAXUI!DrvDocumentProperties failed, lpdev->lpMap->status: %X, lpdev->lpMap->retvalue: %X\n", lpdev->lpMap->status, (LONG)lpdev->lpMap->retvalue));
+ }
+ InterProcCommHandler(lpdev, DRVFAX_DESTROYMAP);
+ }
+
+LeaveDDP:
+ if (pPrinterInfo2) {
+ LocalFree(pPrinterInfo2);
+ }
+
+ LOGDEBUG(1, (L"WOWFAXUI!DrvDocumentProperties returning: %X, pdmOut: %X, pdmIn: %X\n", lRet, pdmOut, pdmIn));
+
+ return(lRet);
+}
+
+//************************************************************************
+// DrvAdvancedDocumentProperties
+//************************************************************************
+
+LONG DrvAdvancedDocumentProperties(HWND hwnd, HANDLE hPrinter, PWSTR pDeviceName,
+ PDEVMODE pdmOut, PDEVMODE pdmIn)
+{
+ // for 16bit drivers this is a NOP.
+
+ return 0;
+}
+
+//************************************************************************
+// DevQueryPrintEx
+//************************************************************************
+
+BOOL DevQueryPrintEx(PDEVQUERYPRINT_INFO pDQPInfo)
+{
+ return TRUE;
+}
+
+//************************************************************************
+// DrvDeviceCapabilities
+//************************************************************************
+
+DWORD DrvDeviceCapabilities(HANDLE hPrinter, PWSTR pDeviceName,
+ WORD iDevCap, VOID *pOut, PDEVMODE pdmIn)
+{
+ FAXDEV dev = gdev;
+ LPFAXDEV lpdev = &dev;
+ LONG lRet = -1;
+ DWORD iOffset;
+ LPBYTE lpSrc;
+
+ LOGDEBUG(1, (L"WOWFAXUI!DrvDeviceCapabilities, iDevCap: %X, pdmIn: %X\n", iDevCap, pdmIn));
+
+ if (iDevCap == DC_SIZE) {
+ return sizeof(DEVMODEW);
+ }
+
+ if (iOffset = SetupFaxDev(pDeviceName, lpdev)) {
+ lpdev->lpMap->msg = WM_DDRV_DEVCAPS;
+
+ // Calculate the pointers into the mapped file section and copy
+ // the variable length data to the mapped file section.
+
+ lpdev->lpMap->lpIn = (LPDEVMODEW)((pdmIn) ? iOffset : 0);
+ iOffset += sizeof(*pdmIn) + gdmDriverExtra;
+
+ // output in lpout: make this the last pointer in the
+ // data so that we can use the rest of the mapped area for copy
+ // on output.
+
+ lpdev->lpMap->lpOut = (LPDEVMODEW)((pOut) ? iOffset : 0);
+ iOffset += sizeof(*pdmIn) + gdmDriverExtra;
+
+
+ if (pdmIn) {
+ iOffset = (DWORD)lpdev->lpMap + (DWORD)lpdev->lpMap->lpIn;
+ RtlCopyMemory((LPVOID)iOffset, pdmIn,
+ sizeof(*pdmIn) + min(gdmDriverExtra, pdmIn->dmDriverExtra));
+
+ // reset dmDriverExtra in pdmIn.
+ ((LPDEVMODE)iOffset)->dmDriverExtra =
+ min(gdmDriverExtra, pdmIn->dmDriverExtra);
+ }
+
+ lpdev->lpMap->wCmd = iDevCap;
+ // valid size of this map
+ lpdev->lpMap->cData = lpdev->cbMapLow;
+
+ InterProcCommHandler(lpdev, DRVFAX_SENDTOWOW);
+ lRet = (lpdev->lpMap->status) ? (LONG)lpdev->lpMap->retvalue : lRet;
+
+ // on return cData is the number of bytes to copy
+
+ if (lpdev->lpMap->lpOut && lpdev->lpMap->cData && lpdev->lpMap->retvalue) {
+ lpSrc = (LPBYTE)lpdev->lpMap + (DWORD)lpdev->lpMap->lpOut;
+ switch (lpdev->lpMap->wCmd) {
+ case DC_PAPERSIZE:
+ case DC_MINEXTENT:
+ case DC_MAXEXTENT:
+ ((LPPOINT)pOut)->x = ((LPPOINTS)lpSrc)->x;
+ ((LPPOINT)pOut)->y = ((LPPOINTS)lpSrc)->y;
+ break;
+
+ default:
+ RtlCopyMemory(pOut, lpSrc, lpdev->lpMap->cData);
+ break;
+ }
+ }
+ InterProcCommHandler(lpdev, DRVFAX_DESTROYMAP);
+ }
+
+ if (lRet < 0) {
+ LOGDEBUG(0, (L"WOWFAXUI!DrvDeviceCapabilities Failing\n"));
+ }
+
+ LOGDEBUG(1, (L"WOWFAXUI!DrvDeviceCapabilities, returning pOut: %X\n", pOut));
+
+ return(lRet);
+}
+
+//************************************************************************
+// DrvUpgradePrinter - Called in the system context by the spooler.
+// Drivers will really only be updated the first time the spooler is
+// started after an upgrade. Calls DoUpgradePrinter to do the work.
+//************************************************************************
+
+BOOL DrvUpgradePrinter(DWORD dwLevel, LPBYTE lpDrvUpgradeInfo)
+{
+ static BOOL bDrvUpgradePrinterLock = FALSE;
+ BOOL bRet;
+
+ LOGDEBUG(1, (L"WOWFAXUI!DrvUpgradePrinter, dwLevel: %X, lpDrvUpgradeInfo: %X\n", dwLevel, lpDrvUpgradeInfo));
+
+ // DrvUpgradePrinter is called during AddPrinterDriver. Don't allow
+ // recursion. Protect lock from other threads.
+ EnterCriticalSection(lpCriticalSection);
+ if (bDrvUpgradePrinterLock) {
+ LeaveCriticalSection(lpCriticalSection);
+ return(TRUE);
+ }
+
+ bDrvUpgradePrinterLock = TRUE;
+ LeaveCriticalSection(lpCriticalSection);
+
+ bRet = DoUpgradePrinter(dwLevel, (LPDRIVER_UPGRADE_INFO_1W)lpDrvUpgradeInfo);
+
+ EnterCriticalSection(lpCriticalSection);
+ bDrvUpgradePrinterLock = FALSE;
+ LeaveCriticalSection(lpCriticalSection);
+
+ return(bRet);
+}
+
+//************************************************************************
+// DrvDocumentEvent - This exported function is used to hook the GDI
+// Display Driver functions. It unpacks and validates the parameters,
+// then dispatches to the appropriate handler, based on the passed
+// iEsc value. The following table provides a mapping of the
+// DrvDocumentEvent escapes to the server side display driver
+// callbacks, and gives the call time relative to the callback:
+//
+// DOCUMENTEVENT_CREATEDCPRE DrvEnablePDEV, before
+// DOCUMENTEVENT_CREATEDCPOST DrvEnablePDEV, after
+// DOCUMENTEVENT_RESETDCPRE DrvRestartPDEV, before
+// DOCUMENTEVENT_RESETDCPOST DrvRestartPDEV, after
+// DOCUMENTEVENT_STARTDOC DrvStartDoc, before
+// DOCUMENTEVENT_STARTPAGE DrvStartPage, before
+// DOCUMENTEVENT_ENDPAGE DrvSendPage, before
+// DOCUMENTEVENT_ENDDOC DrvEndDoc, before
+// DOCUMENTEVENT_ABORTDOC DrvEndDoc, before
+// DOCUMENTEVENT_DELETEDC DrvDisablePDEV, before
+//
+//************************************************************************
+
+int DrvDocumentEvent(
+ HANDLE hPrinter,
+ HDC hdc,
+ int iEsc,
+ ULONG cbIn,
+ PULONG pjIn,
+ ULONG cbOut,
+ PULONG pjOut
+)
+{
+ int iRet = DOCUMENTEVENT_FAILURE;
+
+ if (iEsc < DOCUMENTEVENT_LAST) {
+ LOGDEBUG(1, (L"WOWFAXUI!DrvDocumentEvent, iEsc: %s, hdc: %X\n", szDrvDocumentEventDbgStrings[iEsc], hdc));
+ }
+
+ // Validate HDC for some of the escapes.
+ if ((iEsc >= DOCUMENTEVENT_HDCFIRST) && (iEsc < DOCUMENTEVENT_HDCLAST)) {
+ if (hdc == NULL) {
+ LOGDEBUG(0, (L"WOWFAXUI!DrvDocumentEvent NULL HDC for escape: %X\n", iEsc));
+ return(iRet);
+ }
+ }
+
+ switch (iEsc)
+ {
+ case DOCUMENTEVENT_CREATEDCPRE:
+ iRet = DocEvntCreateDCpre((LPWSTR)*(pjIn+1),
+ (DEVMODEW*)*(pjIn+2),
+ (DEVMODEW**)pjOut);
+ break;
+
+ case DOCUMENTEVENT_CREATEDCPOST:
+ iRet = DocEvntCreateDCpost(hdc, (DEVMODEW*)*pjIn);
+ break;
+
+ case DOCUMENTEVENT_RESETDCPRE:
+ iRet = DocEvntResetDCpre(hdc, (DEVMODEW*)*(pjIn),
+ (DEVMODEW**)pjOut);
+ break;
+
+ case DOCUMENTEVENT_RESETDCPOST:
+ iRet = DocEvntResetDCpost(hdc, (DEVMODEW*)*pjIn);
+ break;
+
+ case DOCUMENTEVENT_STARTDOC:
+ iRet = DocEvntStartDoc(hdc);
+ break;
+
+ case DOCUMENTEVENT_DELETEDC:
+ iRet = DocEvntDeleteDC(hdc);
+ break;
+
+ case DOCUMENTEVENT_ENDDOC:
+ iRet = DocEvntEndDoc(hdc);
+ break;
+
+ case DOCUMENTEVENT_ENDPAGE:
+ iRet = DocEvntEndPage(hdc);
+ break;
+
+ // The following require no client side processing:
+ case DOCUMENTEVENT_ESCAPE:
+ case DOCUMENTEVENT_ABORTDOC:
+ case DOCUMENTEVENT_STARTPAGE:
+ // No Client side processing needed.
+ goto docevnt_unsupported;
+
+ default :
+ LOGDEBUG(0, (L"WOWFAXUI!DrvDocumentEvent unknown escape: %X\n", iEsc));
+docevnt_unsupported:
+ iRet = DOCUMENTEVENT_UNSUPPORTED;
+
+ } // switch
+
+ LOGDEBUG(1, (L"WOWFAXUI!DrvDocumentEvent return: %X\n", iRet));
+ return(iRet);
+
+}
+
+//***************************************************************************
+// DocEvntCreateDCpre - Allocate a DEVMODE which contains a FAXDEV as the
+// dmDriverExtra portion. This DEVMODE will be passed to the
+// DrvEnablePDEV function on the server side.
+//***************************************************************************
+
+int DocEvntCreateDCpre(
+ LPWSTR lpszDevice,
+ DEVMODEW *pDevModIn,
+ DEVMODEW **pDevModOut
+)
+{
+ DWORD iOffset = 0;
+ LPFAXDEV lpFaxDev;
+ PGDIINFO pGdiInfo;
+ DEVMODEW *pTmpDevMode;
+
+ LPREGFAXDRVINFO16 lpRegFaxDrvInfo16;
+
+ int iRet = DOCUMENTEVENT_FAILURE;
+
+ if ((lpszDevice == NULL) || (pDevModOut == NULL)) {
+ LOGDEBUG(0, (L"WOWFAXUI!DocEvntCreateDCpre, failed, NULL parameters\n"));
+ goto DocEvntCreateDCpreFailed;
+ }
+
+ LOGDEBUG(1, (L"WOWFAXUI!DocEvntCreateDCpre, Device: %s, pDevModIn: %X pDevModOut: %X\n", lpszDevice, pDevModIn, pDevModOut));
+
+ // Use our global default devmode if a NULL devmode is passed in from the app.
+ if (pDevModIn == NULL) {
+ gdmDefaultDevMode.dmSize = sizeof(DEVMODEW);
+ pDevModIn = &gdmDefaultDevMode;
+ }
+
+ pTmpDevMode = (DEVMODEW*)WFLOCALALLOC(sizeof(FAXDEV) + sizeof(DEVMODEW),
+ L"DocEvntCreateDCpre");
+
+ LOGDEBUG(2, (L"WOWFAXUI!DocEvntCreateDCpre, pTmpDevMode: %X\n", pTmpDevMode));
+
+ if (pTmpDevMode == NULL) {
+ goto DocEvntCreateDCpreFailed;
+ }
+
+ // Copy pDevModIn to the new DEVMODE.
+ RtlCopyMemory(pTmpDevMode, pDevModIn, sizeof(*pTmpDevMode));
+ pTmpDevMode->dmDriverExtra = sizeof(FAXDEV);
+ pTmpDevMode->dmSize = sizeof(DEVMODEW);
+
+ // Setup some handy pointers.
+ lpFaxDev = (LPFAXDEV) (pTmpDevMode + 1);
+ pGdiInfo = &(lpFaxDev->gdiinfo);
+
+ lpFaxDev->id = FAXDEV_ID;
+
+ // Save a client side pointer to the new DEVMODE and it's embeded FAXDEV.
+ // We'll use ExtEscape to get these pointers back any time we need to
+ // associate driver context with an HDC.
+
+ lpFaxDev->pdevmode = pTmpDevMode;
+ lpFaxDev->lpClient = lpFaxDev;
+
+ // Get the driver and port names from the registry where they were written
+ // by the 16-bit fax driver install program using WriteProfileString.
+
+ if ((lpRegFaxDrvInfo16 = Get16BitDriverInfoFromRegistry(lpszDevice)) == NULL) {
+ goto DocEvntCreateDCpreFailed;
+ }
+
+ if ((lpFaxDev->hwnd = FindWowFaxWindow()) == NULL) {
+ goto DocEvntCreateDCpreFailed;
+ }
+ lpFaxDev->tid = GetWindowThreadProcessId(lpFaxDev->hwnd, 0);
+ lpFaxDev->idMap = (DWORD)lpFaxDev;
+
+ // Calculate the size of the mapped file section for inter process communication.
+ lpFaxDev->cbMapLow = sizeof(DWORD) + // leave room for DWORD align
+ sizeof(*lpFaxDev->lpMap) +
+ sizeof(GDIINFO) +
+ (lstrlen(lpRegFaxDrvInfo16->lpDriverName) + 1) * sizeof(TCHAR) +
+ (lstrlen(lpRegFaxDrvInfo16->lpPortName) + 1) * sizeof(TCHAR) +
+ sizeof(*pDevModIn) +
+ ((pDevModIn) ? pDevModIn->dmDriverExtra : 0);
+ DRVFAX_DWORDALIGN(lpFaxDev->cbMapLow);
+
+ InterProcCommHandler(lpFaxDev, DRVFAX_CREATEMAP);
+
+ if (InterProcCommHandler(lpFaxDev, DRVFAX_SETMAPDATA)) {
+ lpFaxDev->lpMap->msg = WM_DDRV_ENABLE;
+
+ // Copy the printer/device name to the WOWFAXINFO struct.
+ lstrcpy(lpFaxDev->lpMap->szDeviceName, lpszDevice);
+
+ // Calculate the pointers into the mapped file section and copy
+ // the variable length data to the mapped file section.
+
+ // output : gdiinfo
+
+ lpFaxDev->lpMap->lpOut = (LPDEVMODE)(sizeof(*lpFaxDev->lpMap));
+ iOffset = sizeof(*lpFaxDev->lpMap) + sizeof(GDIINFO);
+
+ // Device (printer) and port names.
+
+ lpFaxDev->lpMap->lpDriverName = (LPSTR) iOffset;
+ (PWSTR)iOffset += lstrlen(lpRegFaxDrvInfo16->lpDriverName) + 1;
+ lstrcpy((PWSTR)((LPBYTE)lpFaxDev->lpMap + (DWORD)lpFaxDev->lpMap->lpDriverName), lpRegFaxDrvInfo16->lpDriverName);
+ lpFaxDev->lpMap->lpPortName = (LPVOID) iOffset;
+ (PWSTR)iOffset += lstrlen(lpRegFaxDrvInfo16->lpPortName) + 1;
+ lstrcpy((PWSTR)((LPBYTE)lpFaxDev->lpMap + (DWORD)lpFaxDev->lpMap->lpPortName), lpRegFaxDrvInfo16->lpPortName);
+
+ // input: devmode
+
+ DRVFAX_DWORDALIGN(iOffset);
+ lpFaxDev->lpMap->lpIn = (LPDEVMODE)((pDevModIn) ? iOffset : 0);
+ iOffset += ((pDevModIn) ? sizeof(*pDevModIn) + pDevModIn->dmDriverExtra : 0);
+
+ if (pDevModIn) {
+ RtlCopyMemory((LPBYTE)lpFaxDev->lpMap + (DWORD)lpFaxDev->lpMap->lpIn,
+ pDevModIn, sizeof(*pDevModIn) + pDevModIn->dmDriverExtra);
+ }
+
+ // set the total byte count of data.
+
+ lpFaxDev->lpMap->cData = iOffset;
+
+ // all done - switch to wow
+ InterProcCommHandler(lpFaxDev, DRVFAX_SENDTOWOW);
+ // values returned from wow.
+ lpFaxDev->lpinfo16 = (DWORD)lpFaxDev->lpMap->lpinfo16;
+ iRet = lpFaxDev->lpMap->status && lpFaxDev->lpMap->retvalue;
+ if (iRet) {
+ // Copy GDIINFO from WOW to the client side FAXDEV.
+ RtlCopyMemory(pGdiInfo,
+ (LPBYTE)lpFaxDev->lpMap + (DWORD)lpFaxDev->lpMap->lpOut,
+ sizeof(GDIINFO));
+
+ // Fill in some misc. fields in the client FAXDEV.
+ pGdiInfo->ulHTPatternSize = HT_PATSIZE_DEFAULT;
+ pGdiInfo->ulHTOutputFormat = HT_FORMAT_1BPP;
+
+ lpFaxDev->bmWidthBytes = pGdiInfo->szlPhysSize.cx / 0x8;
+ DRVFAX_DWORDALIGN(lpFaxDev->bmWidthBytes);
+
+ lpFaxDev->bmFormat = BMF_1BPP;
+ lpFaxDev->cPixPerByte = 0x8;
+
+ // Here if success, make pDevModOut point to the new DEVMODE.
+ *pDevModOut = pTmpDevMode;
+
+ }
+ else {
+ LOGDEBUG(0, (L"WOWFAXUI!DocEvntCreateDCpre, WOW returned error\n"));
+ }
+ }
+
+ if (iRet) {
+ goto DocEvntCreateDCpreSuccess;
+ }
+ else {
+ iRet = DOCUMENTEVENT_FAILURE;
+ }
+
+DocEvntCreateDCpreFailed:
+ LOGDEBUG(0, (L"WOWFAXUI!DocEvntCreateDCpre, failed!\n"));
+
+DocEvntCreateDCpreSuccess:
+ LOGDEBUG(1, (L"WOWFAXUI!DocEvntCreateDCpre, iRet: %X\n", iRet));
+ Free16BitDriverInfo(lpRegFaxDrvInfo16);
+ return(iRet);
+}
+
+//***************************************************************************
+// DocEvntResetDCpre -
+//***************************************************************************
+
+int DocEvntResetDCpre(
+ HDC hdc,
+ DEVMODEW *pDevModIn,
+ DEVMODEW **pDevModOut
+)
+{
+ return(DOCUMENTEVENT_FAILURE);
+}
+
+//***************************************************************************
+// DocEvntResetDCpost -
+//***************************************************************************
+
+int DocEvntResetDCpost(
+ HDC hdc,
+ DEVMODEW *pDevModIn
+)
+{
+ return(DOCUMENTEVENT_SUCCESS);
+}
+
+//***************************************************************************
+// DocEvntCreateDCpost -
+//***************************************************************************
+
+int DocEvntCreateDCpost(
+ HDC hdc,
+ DEVMODEW *pDevModIn
+)
+{
+ LOGDEBUG(1, (L"WOWFAXUI!DocEvntCreateDCpost, hdc: %X, pDevModIn: %X\n", hdc, pDevModIn));
+
+ // hdc was zero indicates DrvEnablePDEV failed. Cleanup.
+ if (hdc == NULL) {
+ if (pDevModIn) {
+ LocalFree(pDevModIn);
+ LOGDEBUG(1, (L"WOWFAXUI!DocEvntCreateDCpost, Cleaning up\n"));
+ }
+ }
+ return(DOCUMENTEVENT_SUCCESS);
+}
+
+//***************************************************************************
+// DocEvntStartDoc - hdc was validated by DrvDocumentEvent.
+//***************************************************************************
+
+int DocEvntStartDoc(
+HDC hdc
+)
+{
+ LPFAXDEV lpFaxDev = 0;
+ HBITMAP hbm = 0;
+ DWORD cbOld;
+ int iRet = 0;
+
+ lpFaxDev = (LPFAXDEV)ExtEscape(hdc, DRV_ESC_GET_FAXDEV_PTR, 0, NULL, 0, NULL);
+ if (ValidateFaxDev(lpFaxDev)) {
+ if (InterProcCommHandler(lpFaxDev, DRVFAX_SETMAPDATA)) {
+ lpFaxDev->lpMap->msg = WM_DDRV_STARTDOC;
+ InterProcCommHandler(lpFaxDev, DRVFAX_SENDNOTIFYWOW);
+
+ iRet = ((LONG)lpFaxDev->lpMap->retvalue > 0);
+
+ // Calculate new mapsize - the bitmap bits will be written into
+ // this map with a call to ExtEscape - thus allowing easy access
+ // to the bits from WOW.
+
+ cbOld = lpFaxDev->cbMapLow;
+ lpFaxDev->cbMapLow += lpFaxDev->bmWidthBytes *
+ lpFaxDev->gdiinfo.szlPhysSize.cy;
+ if (InterProcCommHandler(lpFaxDev, DRVFAX_CREATEMAP)) {
+ lpFaxDev->offbits = cbOld;
+ goto DocEvntStartDocSuccess;
+ }
+ }
+ }
+ LOGDEBUG(1, (L"WOWFAXUI!DocEvntStartDoc, failed\n"));
+
+DocEvntStartDocSuccess:
+ if (iRet == 0) {
+ iRet = DOCUMENTEVENT_FAILURE;
+ }
+ return iRet;
+}
+
+//***************************************************************************
+// DocEvntDeleteDC - hdc was validated by DrvDocumentEvent.
+//***************************************************************************
+
+int DocEvntDeleteDC(
+ HDC hdc
+)
+{
+ LPFAXDEV lpFaxDev;
+ DEVMODEW *lpDevMode;
+
+ int iRet = DOCUMENTEVENT_FAILURE;
+
+ lpFaxDev = (LPFAXDEV)ExtEscape(hdc, DRV_ESC_GET_FAXDEV_PTR, 0, NULL, 0, NULL);
+ if (ValidateFaxDev(lpFaxDev)) {
+ // Validate 16-bit FaxWndProc window handle before sending a message.
+ if (lpFaxDev->tid == GetWindowThreadProcessId(lpFaxDev->hwnd, 0)) {
+ if (InterProcCommHandler(lpFaxDev, DRVFAX_SETMAPDATA)) {
+ lpFaxDev->lpMap->msg = WM_DDRV_DISABLE;
+ InterProcCommHandler(lpFaxDev, DRVFAX_SENDTOWOW);
+ }
+ }
+ else {
+ LOGDEBUG(0, (L"WOWFAXUI!DocEvntDeleteDC, unable to validate FaxWndProc\n"));
+ }
+
+ InterProcCommHandler(lpFaxDev, DRVFAX_DESTROYMAP);
+ }
+ else {
+ LOGDEBUG(0, (L"WOWFAXUI!DocEvntDeleteDC, unable to get lpFaxDev\n"));
+ }
+
+ lpDevMode = (DEVMODEW*)ExtEscape(hdc, DRV_ESC_GET_DEVMODE_PTR, 0, NULL, 0, NULL);
+ if (lpDevMode) {
+ LocalFree(lpDevMode);
+ iRet = DOCUMENTEVENT_SUCCESS;
+ }
+ else {
+ LOGDEBUG(0, (L"WOWFAXUI!DocEvntDeleteDC, unable to get lpDevMode\n"));
+ }
+
+ return iRet;
+}
+
+//***************************************************************************
+// DocEvntEndDoc - hdc was validated by DrvDocumentEvent.
+//***************************************************************************
+
+int DocEvntEndDoc(
+HDC hdc
+)
+{
+ LPFAXDEV lpFaxDev;
+ DEVMODEW *lpDevMode;
+
+ int iRet = DOCUMENTEVENT_FAILURE;
+
+ lpFaxDev = (LPFAXDEV)ExtEscape(hdc, DRV_ESC_GET_FAXDEV_PTR, 0, NULL, 0, NULL);
+ if (ValidateFaxDev(lpFaxDev)) {
+ if (InterProcCommHandler(lpFaxDev, DRVFAX_SETMAPDATA)) {
+ lpFaxDev->lpMap->msg = WM_DDRV_ENDDOC;
+ InterProcCommHandler(lpFaxDev, DRVFAX_SENDTOWOW);
+ iRet = lpFaxDev->lpMap->status && ((LONG)lpFaxDev->lpMap->retvalue > 0);
+ goto DocEvntEndDocSuccess;
+ }
+ }
+ LOGDEBUG(1, (L"WOWFAXUI!DocEvntEndDoc, failed\n"));
+
+DocEvntEndDocSuccess:
+ if (iRet == 0) {
+ iRet = DOCUMENTEVENT_FAILURE;
+ }
+ return iRet;
+}
+
+//***************************************************************************
+// DocEvntEndPage - hdc was validated by DrvDocumentEvent.
+//***************************************************************************
+
+int DocEvntEndPage(
+ HDC hdc
+)
+{
+ LPFAXDEV lpFaxDev;
+ LONG lDelta;
+ ULONG cjBits;
+ int iRet = DOCUMENTEVENT_FAILURE;
+
+ lpFaxDev = (LPFAXDEV)ExtEscape(hdc, DRV_ESC_GET_FAXDEV_PTR, 0, NULL, 0, NULL);
+ if (ValidateFaxDev(lpFaxDev)) {
+ if (InterProcCommHandler(lpFaxDev, DRVFAX_SETMAPDATA)) {
+ lpFaxDev->lpMap->msg = WM_DDRV_PRINTPAGE;
+
+ // Get Surface info, cjBits and lDelta.
+ cjBits = ExtEscape(hdc, DRV_ESC_GET_SURF_INFO, 0, NULL,
+ 4, (PVOID)&lDelta);
+ if (cjBits) {
+ lpFaxDev->lpMap->bmWidthBytes = lDelta;
+ lpFaxDev->lpMap->bmHeight = cjBits / lDelta;
+ lpFaxDev->lpMap->bmPixPerByte = lpFaxDev->cPixPerByte;
+ (DWORD)lpFaxDev->lpMap->lpbits = lpFaxDev->offbits;
+ if (ExtEscape(hdc, DRV_ESC_GET_BITMAP_BITS, 0, NULL, cjBits,
+ (LPBYTE)lpFaxDev->lpMap + lpFaxDev->offbits)) {
+ InterProcCommHandler(lpFaxDev, DRVFAX_SENDTOWOW);
+ iRet = lpFaxDev->lpMap->status &&
+ ((LONG)lpFaxDev->lpMap->retvalue > 0);
+ }
+ goto DocEvntEndPageSuccess;
+ }
+ }
+ }
+ LOGDEBUG(1, (L"WOWFAXUI!DocEvntEndPage, failed\n"));
+
+DocEvntEndPageSuccess:
+ if (iRet == 0) {
+ iRet = DOCUMENTEVENT_FAILURE;
+ }
+ return iRet;
+}
diff --git a/private/mvdm/fax/wowfaxui/wowfaxui.def b/private/mvdm/fax/wowfaxui/wowfaxui.def
new file mode 100644
index 000000000..95bdf76d0
--- /dev/null
+++ b/private/mvdm/fax/wowfaxui/wowfaxui.def
@@ -0,0 +1,16 @@
+LIBRARY wowfaxui
+
+DESCRIPTION 'wow fax driver ui (rasddui)'
+
+
+EXPORTS
+ DllInitProc
+ PrinterProperties
+ DrvDocumentProperties
+ DrvAdvancedDocumentProperties
+ DevQueryPrintEx
+ DrvDeviceCapabilities
+ DrvUpgradePrinter
+ DrvDocumentEvent
+ DrvDocumentPropertySheets
+ DrvDevicePropertySheets
diff --git a/private/mvdm/fax/wowfaxui/wowfaxui.h b/private/mvdm/fax/wowfaxui/wowfaxui.h
new file mode 100644
index 000000000..1cca71d96
--- /dev/null
+++ b/private/mvdm/fax/wowfaxui/wowfaxui.h
@@ -0,0 +1,164 @@
+//****************************************************************************
+// Generic Win 3.1 fax printer driver support
+//
+// 02-jan-95 nandurir created.
+// 14-mar-95 reedb Use GDI hooks to move most functionality to UI.
+// 16-aug-95 reedb Move to kernel mode. Many declarations and
+// definitions moved from FAXCOMM.H to this file.
+//
+//****************************************************************************
+
+#include "stddef.h"
+#include "windows.h"
+#include "winddi.h"
+
+#include "faxcomm.h"
+#include "winspool.h"
+
+// The following include is to pickup the definitions for
+// the DrvUpgradePrinter private API. These definitions should be in public.
+
+#include "..\..\..\windows\spooler\inc\splapip.h"
+
+// WOWFAX component file names.
+#define WOWFAX_DLL_NAME L"WOWFAX.DLL"
+#define WOWFAXUI_DLL_NAME L"WOWFAXUI.DLL"
+
+// String table constants:
+#define WOWFAX_MAX_USER_MSG_LEN 256
+
+#define WOWFAX_UNKNOWN_PROB_STR 0x100
+#define WOWFAX_NAME_STR 0x101
+#define WOWFAX_NOWOW_STR 0x102
+#define WOWFAX_SELF_CONFIG_STR 0x103
+#define WOWFAX_ENABLE_CONFIG_STR 0x104
+
+// Dialog constants:
+#define IDD_NULLPROP 0x200
+#define IDD_DOCPROP 0x201
+
+// Text control constants:
+#define IDC_STATIC -1
+#define IDC_FEEDBACK 0x300
+
+// InterProcCommHandler command constants
+#define DRVFAX_SETMAPDATA 0x1
+#define DRVFAX_SENDTOWOW 0x2
+#define DRVFAX_SENDNOTIFYWOW 0x3
+#define DRVFAX_CREATEMAP 0x4
+#define DRVFAX_DESTROYMAP 0x5
+#define DRVFAX_CALLWOW 0x6
+
+// Logging macros
+/* XLATOFF */
+// #define IFLOG(l) if (l==iFaxLogLevel && (iFaxLogLevel&1) || l<=iFaxLogLevel && !(iFaxLogLevel&1) || l == 0)
+
+#undef LOG
+#ifdef NOLOG
+#define LOG(l,args)
+#define SETREQLOG(l)
+#else
+#define SETREQLOG(l) iReqFaxLogLevel = l
+#define LOG(l,args) {SETREQLOG(l) ; faxlogprintf args;}
+#endif
+
+#if DBG
+extern INT iReqFaxLogLevel;
+#define LOGDEBUG(l,args) LOG(l,args)
+#else
+#define LOGDEBUG(l,args)
+#endif
+/* XLATON */
+
+
+//
+// This structure is used to hold 16-bit fax driver data stored
+// in the registry.
+//
+
+typedef struct _REGFAXDRVINFO16 {
+ LPTSTR lpDriverName;
+ LPTSTR lpPortName;
+} REGFAXDRVINFO16, *LPREGFAXDRVINFO16;
+
+// The the escapes in the following escape range all need a valid HDC.
+// Range is inclusive lower, exclusive upper bound. See GDISPOOL.H for
+// the actual escape definitions.
+
+#define DOCUMENTEVENT_HDCFIRST 5
+#define DOCUMENTEVENT_HDCLAST 11
+
+// Prototypes for public functions implemented in WFSHEETS.C:
+PVOID MyGetPrinter(HANDLE hPrinter, DWORD level);
+
+// Prototypes for public functions implemented in WFUPGRAD.C:
+
+BOOL DoUpgradePrinter(DWORD dwLevel, LPDRIVER_UPGRADE_INFO_1W lpDrvUpgradeInfo);
+
+// Prototypes for public functions implemented in WFHELPERS.C:
+
+LPREGFAXDRVINFO16 Get16BitDriverInfoFromRegistry(PWSTR pDeviceName);
+
+VOID faxlogprintf(LPTSTR pszFmt, ...);
+VOID LogFaxDev(LPTSTR pszTitle, LPFAXDEV lpFaxDev);
+VOID LogWowFaxInfo(LPWOWFAXINFO lpWowFaxInfo);
+BOOL ValidateFaxDev(LPFAXDEV lpFaxDev);
+VOID Free16BitDriverInfo(LPREGFAXDRVINFO16 lpRegFaxDrvInfo16);
+BOOL FaxMapHandler(LPFAXDEV lpdev, UINT iAction);
+BOOL InterProcCommHandler(LPFAXDEV lpdev, UINT iAction);
+LPVOID WFHeapAlloc(DWORD dwBytes, LPWSTR lpszWhoCalled);
+LPVOID WFLocalAlloc(DWORD dwBytes, LPWSTR lpszWhoCalled);
+HWND FindWowFaxWindow(void);
+LPTSTR DupTokenW(LPTSTR lpTok);
+
+// Prototypes for functions which DrvDocumentEvent dispatches,
+// implemented in WOWFAXUI.C:
+
+int DocEvntCreateDCpre(
+ LPWSTR lpszDevice,
+ DEVMODEW *pDevModIn,
+ DEVMODEW **pDevModOut
+);
+
+int DocEvntResetDCpre(
+ HDC hdc,
+ DEVMODEW *pDevModIn,
+ DEVMODEW **pDevModOut
+);
+
+int DocEvntCreateDCpost(
+ HDC hdc,
+ DEVMODEW *pDevModIn
+);
+
+int DocEvntResetDCpost(
+ HDC hdc,
+ DEVMODEW *pDevModIn
+);
+
+int DocEvntStartDoc(
+HDC hdc
+);
+
+int DocEvntDeleteDC(
+ HDC hdc
+);
+
+int DocEvntEndPage(
+ HDC hdc
+);
+
+int DocEvntEndDoc(
+HDC hdc
+);
+
+//
+// Memory allocation macro.
+//
+
+#if DBG
+#define WFLOCALALLOC(dwBytes, lpszWhoCalled) WFLocalAlloc(dwBytes, lpszWhoCalled)
+#else
+#define WFLOCALALLOC(dwBytes, lpszWhoCalled) LocalAlloc(LPTR, dwBytes)
+#endif
+
diff --git a/private/mvdm/fax/wowfaxui/wowfaxui.rc b/private/mvdm/fax/wowfaxui/wowfaxui.rc
new file mode 100644
index 000000000..6eaa838ab
--- /dev/null
+++ b/private/mvdm/fax/wowfaxui/wowfaxui.rc
@@ -0,0 +1,45 @@
+#include <windows.h>
+#include "wowfaxui.h"
+
+STRINGTABLE
+
+BEGIN
+ WOWFAX_UNKNOWN_PROB_STR "Unknown print problem"
+ WOWFAX_SELF_CONFIG_STR "This driver is self configuring. No setup is needed."
+ WOWFAX_NAME_STR "Windows 3.1 Compatible Fax Driver"
+ WOWFAX_NOWOW_STR "Unable to start WOW. Verify the ability to run a Win 16 application and retry."
+ WOWFAX_ENABLE_CONFIG_STR "Please click the OK button to enable the configuration settings for the 16-bit Fax Driver."
+END
+
+IDD_DOCPROP DIALOG DISCARDABLE 0, 0, 252, 216
+STYLE WS_CHILD | WS_VISIBLE | WS_CAPTION
+CAPTION "WowFax Options"
+FONT 8, "MS Shell Dlg"
+BEGIN
+ LTEXT "Please press the Configure button to set default options for the 16-bit Fax Driver.",IDC_STATIC,8,12,240,24
+ LTEXT "", IDC_FEEDBACK, 8, 84, 240, 24
+ PUSHBUTTON "Configure", IDOK, 8, 48, 64, 14, WS_GROUP | WS_TABSTOP
+
+END
+
+IDD_NULLPROP DIALOG DISCARDABLE 0, 0, 252, 216
+STYLE WS_CHILD | WS_VISIBLE | WS_CAPTION
+CAPTION "WowFax"
+FONT 8, "MS Shell Dlg"
+BEGIN
+ LTEXT "Global configuration of 16-bit fax drivers is not supported",
+ IDC_STATIC,10,15,230,32
+END
+
+
+#include <ntverp.h>
+#define VER_FILEVERSION 0, 2, 0, 0
+#define VER_FILETYPE VFT_DRV
+#define VER_FILESUBTYPE VFT2_DRV_PRINTER
+#define VER_FILEDESCRIPTION_STR "Windows 3.1 Compatible Fax Driver UI DLL"
+#define VER_INTERNALNAME_STR "wowfaxui.dll"
+#define VER_ORIGINALFILENAME_STR "wowfaxui.dll"
+
+#include "common.ver"
+
+