|
|
//************************************************************************
// 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_NT4;
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; }
|