diff options
Diffstat (limited to 'private/mvdm/fax/wowfax/wowfax.c')
-rw-r--r-- | private/mvdm/fax/wowfax/wowfax.c | 461 |
1 files changed, 461 insertions, 0 deletions
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; +} + + |