281 lines
6.1 KiB
C
281 lines
6.1 KiB
C
|
||
/*++
|
||
|
||
Copyright (c) 1990-1999 Microsoft Corporation
|
||
|
||
|
||
Module Name:
|
||
|
||
escape.c
|
||
|
||
|
||
Abstract:
|
||
|
||
This module contains the code to implement the DrvEscape() driver call
|
||
|
||
|
||
Author:
|
||
|
||
15:30 on Mon 06 Dec 1993 -by- JB
|
||
Created it
|
||
|
||
|
||
[Environment:]
|
||
|
||
GDI Device Driver - Plotter.
|
||
|
||
|
||
[Notes:]
|
||
|
||
|
||
Revision History:
|
||
|
||
|
||
--*/
|
||
|
||
#include "precomp.h"
|
||
#pragma hdrstop
|
||
|
||
#define DBG_PLOTFILENAME DbgEscape
|
||
|
||
#define DBG_DRVESCAPE 0x00000001
|
||
|
||
|
||
DEFINE_DBGVAR(0);
|
||
|
||
|
||
|
||
#define pbIn ((BYTE *)pvIn)
|
||
#define pdwIn ((DWORD *)pvIn)
|
||
#define pdwOut ((DWORD *)pvOut)
|
||
|
||
|
||
|
||
ULONG
|
||
DrvEscape(
|
||
SURFOBJ *pso,
|
||
ULONG iEsc,
|
||
ULONG cjIn,
|
||
PVOID pvIn,
|
||
ULONG cjOut,
|
||
PVOID pvOut
|
||
)
|
||
|
||
/*++
|
||
|
||
Routine Description:
|
||
|
||
Performs the escape functions. Currently, only 3 are defined -
|
||
one to query the escapes supported, the other for raw data, and the
|
||
last for setting the COPYCOUNT.
|
||
|
||
|
||
Arguments:
|
||
|
||
pso - The surface object interested
|
||
|
||
iEsc - The function requested
|
||
|
||
cjIn - Number of bytes in the following
|
||
|
||
pvIn - Location of input data
|
||
|
||
cjOut - Number of bytes in the following
|
||
|
||
pvOut - Location of output area
|
||
|
||
|
||
Return Value:
|
||
|
||
ULONG depends on the escape
|
||
|
||
|
||
Author:
|
||
|
||
05-Jul-1996 Fri 13:18:54 created -by- DC
|
||
Re-write comment, and fix the PASSTHROUGH problem
|
||
|
||
Revision History:
|
||
|
||
|
||
--*/
|
||
|
||
{
|
||
ULONG ulRes;
|
||
PPDEV pPDev;
|
||
DWORD cbWritten;
|
||
|
||
|
||
UNREFERENCED_PARAMETER( cjOut );
|
||
UNREFERENCED_PARAMETER( pvOut );
|
||
|
||
|
||
if (!(pPDev = SURFOBJ_GETPDEV(pso))) {
|
||
|
||
PLOTERR(("DrvEscape: Invalid pPDev"));
|
||
return(FALSE);
|
||
}
|
||
|
||
ulRes = 0; /* Return failure, by default */
|
||
|
||
switch (iEsc) {
|
||
|
||
case QUERYESCSUPPORT:
|
||
|
||
PLOTDBG(DBG_DRVESCAPE, ("DrvEscape: in QUERYESCAPESUPPORT"));
|
||
|
||
if ((cjIn == 4) && (pvIn)) {
|
||
|
||
//
|
||
// Data may be valid, so check for supported function
|
||
//
|
||
|
||
switch (*pdwIn) {
|
||
|
||
case QUERYESCSUPPORT:
|
||
case PASSTHROUGH:
|
||
|
||
ulRes = 1; /* ALWAYS supported */
|
||
break;
|
||
|
||
case SETCOPYCOUNT:
|
||
|
||
//
|
||
// if the target device actually allows us to tell it
|
||
// how many copies to print of a document, then pass
|
||
// that information back to the caller.
|
||
//
|
||
|
||
if (pPDev->pPlotGPC->MaxCopies > 1) {
|
||
|
||
ulRes = 1;
|
||
}
|
||
|
||
break;
|
||
}
|
||
}
|
||
|
||
break;
|
||
|
||
case PASSTHROUGH:
|
||
|
||
PLOTDBG(DBG_DRVESCAPE, ("DrvEscape: in PASSTHROUGH"));
|
||
|
||
//
|
||
// 05-Jul-1996 Fri 12:59:31 updated -by- DC
|
||
//
|
||
// This simply passes the RAW data to the target device, untouched.
|
||
//
|
||
// Win 3.1 actually uses the first 2 bytes as a count of the number of
|
||
// bytes that follow! So we will check if cjIn represents more data
|
||
// than the first WORD of pvIn
|
||
//
|
||
|
||
if (EngCheckAbort(pPDev->pso)) {
|
||
|
||
//
|
||
// Set the cancel DOC flag
|
||
//
|
||
|
||
pPDev->Flags |= PDEVF_CANCEL_JOB;
|
||
|
||
PLOTERR(("DrvEscape(PASSTHROUGH): Job Canceled"));
|
||
|
||
} else if ((cjIn <= sizeof(WORD)) || (pvIn == NULL)) {
|
||
|
||
SetLastError(ERROR_INVALID_PARAMETER);
|
||
|
||
PLOTERR(("DrvEscape(PASSTHROUGH): cjIn <= 2 or pvIn=NULL, nothing to output"));
|
||
|
||
} else {
|
||
|
||
union {
|
||
WORD wCount;
|
||
BYTE bCount[2];
|
||
} u;
|
||
|
||
u.bCount[0] = pbIn[0];
|
||
u.bCount[1] = pbIn[1];
|
||
cbWritten = 0;
|
||
|
||
if ((u.wCount == 0) ||
|
||
((cjIn - sizeof(WORD)) < (DWORD)u.wCount)) {
|
||
|
||
PLOTERR(("DrvEscape(PASSTHROUGH): cjIn to small OR wCount is zero/too big"));
|
||
|
||
SetLastError(ERROR_INVALID_DATA);
|
||
|
||
} else if ((WritePrinter(pPDev->hPrinter,
|
||
(LPVOID)(pbIn + 2),
|
||
(DWORD)u.wCount,
|
||
&cbWritten)) &&
|
||
((DWORD)u.wCount == cbWritten)) {
|
||
|
||
ulRes = (DWORD)u.wCount;
|
||
|
||
} else {
|
||
|
||
PLOTERR(("DrvEscape(PASSTHROUGH): WritePrinter() FAILED, cbWritten=%ld bytes",
|
||
cbWritten));
|
||
}
|
||
}
|
||
|
||
break;
|
||
|
||
case SETCOPYCOUNT:
|
||
|
||
//
|
||
// Input data is a DWORD count of copies
|
||
//
|
||
|
||
PLOTDBG(DBG_DRVESCAPE, ("DrvEscape: in SETCOPYCOUNT"));
|
||
|
||
if ((pdwIn) && (*pdwIn)) {
|
||
|
||
//
|
||
// Load the value of current copies since we will, and Check that
|
||
// is within the printers range, and truncate if it is not.
|
||
// The device information structure, tells us the maximum amount
|
||
// of copies the device can generate on its own. We save this new
|
||
// Copy amount inside of our current DEVMODE that we have stored,
|
||
// as part of our PDEV. The copy count actually gets output
|
||
// later to the target device.
|
||
//
|
||
|
||
pPDev->PlotDM.dm.dmCopies = (SHORT)*pdwIn;
|
||
|
||
if ((WORD)pPDev->PlotDM.dm.dmCopies > pPDev->pPlotGPC->MaxCopies) {
|
||
|
||
pPDev->PlotDM.dm.dmCopies = (SHORT)pPDev->pPlotGPC->MaxCopies;
|
||
}
|
||
|
||
if ((pdwOut) && (cjOut)) {
|
||
|
||
cbWritten = (DWORD)pPDev->PlotDM.dm.dmCopies;
|
||
|
||
CopyMemory(pdwOut,
|
||
&cbWritten,
|
||
(cjOut >= sizeof(DWORD)) ? sizeof(DWORD) : cjOut);
|
||
}
|
||
|
||
|
||
//
|
||
// Success!
|
||
//
|
||
|
||
ulRes = 1;
|
||
}
|
||
|
||
break;
|
||
|
||
default:
|
||
|
||
PLOTERR(("DrvEscape: Unsupported Escape Code : %d\n", iEsc ));
|
||
|
||
SetLastError(ERROR_INVALID_FUNCTION);
|
||
break;
|
||
}
|
||
|
||
return(ulRes);
|
||
}
|