You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
280 lines
6.1 KiB
280 lines
6.1 KiB
|
|
/*++
|
|
|
|
Copyright (c) 1990-2003 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
|
|
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
|
|
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
|
|
//
|
|
// 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);
|
|
}
|