📄 separatorpp.cpp
字号:
/*++
Copyright (c) 1990-2003 Microsoft Corporation
All Rights Reserved
Abstract:
Win32 print processor support functions.
--*/
#include "local.h"
#include <excpt.h>
LPWSTR Datatypes[]={
L"RAW",
L"NT EMF 1.006",
L"NT EMF 1.007",
L"NT EMF 1.008",
L"TEXT",
0};
/** Misc. constants **/
#define BASE_TAB_SIZE 8
/**
* For localization:
**/
PWCHAR pTabsKey = L"TABS";
PWCHAR pCopiesKey = L"COPIES";
/**
Prototypes
**/
/** Functions found in parsparm.c **/
extern USHORT GetKeyValue(
IN PWCHAR,
IN PWCHAR,
IN USHORT,
IN OUT PUSHORT,
OUT PVOID);
/** Functions found in raw.c **/
extern BOOL PrintRawJob(
IN PPRINTPROCESSORDATA,
IN LPWSTR,
IN UINT);
/** Functions found in text.c **/
extern BOOL PrintTextJob(
IN PPRINTPROCESSORDATA,
IN LPWSTR);
/** Functions found in emf.c */
extern BOOL PrintEMFJob(
IN PPRINTPROCESSORDATA,
IN LPWSTR);
/** Functions found in support.c **/
extern PUCHAR GetPrinterInfo(
IN HANDLE hPrinter,
IN ULONG,
OUT PULONG);
BOOL BReleasePPData(
IN PPRINTPROCESSORDATA * ppData );
BOOL
__stdcall
DllMain(
HANDLE hModule,
DWORD dwReason,
LPVOID lpRes
)
{
return TRUE;
}
/*++
*******************************************************************
E n u m P r i n t P r o c e s s o r D a t a t y p e s W
Routine Description:
Enumerates the data types supported by the print processor.
Arguments:
pName => server name
pPrintProcessorName => print processor name
Level => level of data to return (must be 1)
pDatatypes => structure array to fill in
cbBuf => length of structure array in bytes
pcbNeeded => buffer length copied/required
pcReturned => number of structures returned
Return Value:
TRUE if successful
FALSE if failed - caller must use GetLastError for reason
*******************************************************************
--*/
BOOL
EnumPrintProcessorDatatypes(
IN LPWSTR pName,
IN LPWSTR pPrintProcessorName,
IN DWORD Level,
OUT LPBYTE pDatatypes,
IN DWORD cbBuf,
OUT LPDWORD pcbNeeded,
OUT LPDWORD pcReturned
)
{
DATATYPES_INFO_1 *pInfo1 = (DATATYPES_INFO_1 *)pDatatypes;
LPWSTR *pMyDatatypes = Datatypes;
DWORD cbTotal=0;
ULONG cchBuf =0;
LPBYTE pEnd;
if ( NULL == pcbNeeded ||
NULL == pcReturned )
{
return FALSE;
SetLastError (ERROR_INVALID_PARAMETER);
}
/** Start assuming failure, no entries returned **/
*pcReturned = 0;
/** Add up the minimum buffer required **/
while (*pMyDatatypes) {
cbTotal += wcslen(*pMyDatatypes) * sizeof(WCHAR) + sizeof(WCHAR) +
sizeof(DATATYPES_INFO_1);
pMyDatatypes++;
}
/** Set the buffer length returned/required **/
*pcbNeeded = cbTotal;
/** Fill in the array only if there is sufficient space **/
if (cbTotal <= cbBuf) {
if ( NULL == pInfo1 ) //pInfo1 is same as pDatatypes
{
SetLastError (ERROR_INVALID_PARAMETER);
return FALSE;
}
/** Pick up pointer to end of the given buffer **/
pEnd = (LPBYTE)pInfo1 + cbBuf;
/** Pick up our list of supported data types **/
pMyDatatypes = Datatypes;
/**
Fill in the given buffer. We put the data names at the end of
the buffer, working towards the front. The structures are put
at the front, working towards the end.
**/
while (*pMyDatatypes) {
cchBuf = wcslen(*pMyDatatypes) + 1; //+1 is for \0.
pEnd -= cchBuf*sizeof(WCHAR);
StringCchCopy ( (LPWSTR)pEnd, cchBuf, *pMyDatatypes);
pInfo1->pName = (LPWSTR)pEnd;
pInfo1++;
(*pcReturned)++;
pMyDatatypes++;
}
} else {
/** Caller didn't have large enough buffer, set error and return **/
SetLastError(ERROR_INSUFFICIENT_BUFFER);
return FALSE;
}
/** Return success **/
return TRUE;
}
/*++
*******************************************************************
O p e n P r i n t P r o c e s s o r
Routine Description:
Arguments:
pPrinterName => name of printer we are
opening for
pPrintProcessorOpenData => information used for opening
the print processor
Return Value:
PPRINTPROCESSORDATA => processor data of opened
processor if successful
NULL if failed - caller uses GetLastError for reason
NOTE: OpenPrinter will be called iff this returns a valid handle
(and we're not journal)
*******************************************************************
--*/
HANDLE
OpenPrintProcessor(
LPWSTR pPrinterName,
PPRINTPROCESSOROPENDATA pPrintProcessorOpenData
)
{
PPRINTPROCESSORDATA pData;
LPWSTR *pMyDatatypes=Datatypes;
DWORD uDatatype=0;
HANDLE hPrinter=0;
HDC hDC = 0;
PDEVMODEW pDevmode = NULL;
/** If the caller passed a NULL for the open data, fail the call.
pPrintProcessorOpenData->pDevMode can be NULL **/
if (!pPrintProcessorOpenData ||
!pPrintProcessorOpenData->pDatatype ||
!*pPrintProcessorOpenData->pDatatype) {
SetLastError(ERROR_INVALID_PARAMETER);
return NULL;
}
/** Search for the data type index we are opening for **/
while (*pMyDatatypes) {
if (!_wcsicmp(*pMyDatatypes,pPrintProcessorOpenData->pDatatype)) {
break;
}
pMyDatatypes++;
uDatatype++;
}
/** Allocate a buffer for the print processor data to return **/
pData = (PPRINTPROCESSORDATA)AllocSplMem(sizeof(PRINTPROCESSORDATA));
if (!pData) {
ODS(("Alloc failed in OpenPrintProcessor, while printing on %ws\n", pPrinterName));
return NULL;
}
ZeroMemory ( pData, sizeof (PRINTPROCESSORDATA) );
/** Open the processor accordingly **/
switch (uDatatype) {
case PRINTPROCESSOR_TYPE_RAW:
if (!OpenPrinter(pPrinterName, &hPrinter, NULL))
goto Fail;
break;
case PRINTPROCESSOR_TYPE_EMF_50_1:
case PRINTPROCESSOR_TYPE_EMF_50_2:
case PRINTPROCESSOR_TYPE_EMF_50_3:
if(pPrintProcessorOpenData->pDevMode)
{
if(!(pDevmode=(DEVMODEW*)AllocSplMem(pPrintProcessorOpenData->pDevMode->dmSize+
pPrintProcessorOpenData->pDevMode->dmDriverExtra)))
{
goto Fail;
}
memcpy(pDevmode,
pPrintProcessorOpenData->pDevMode,
pPrintProcessorOpenData->pDevMode->dmSize+
pPrintProcessorOpenData->pDevMode->dmDriverExtra);
}
break;
case PRINTPROCESSOR_TYPE_TEXT:
if (!(hDC = CreateDC(L"", pPrinterName, L"",
pPrintProcessorOpenData->pDevMode)))
goto Fail;
break;
default:
SetLastError(ERROR_INVALID_DATATYPE);
goto Fail;
}
/** Fill in the print processors information **/
pData->cb = sizeof(PRINTPROCESSORDATA);
pData->signature = PRINTPROCESSORDATA_SIGNATURE;
pData->JobId = pPrintProcessorOpenData->JobId;
pData->hPrinter = hPrinter;
pData->semPaused = CreateEvent(NULL, TRUE, TRUE,NULL);
pData->uDatatype = uDatatype;
pData->hDC = hDC;
pData->Copies = 1;
pData->TabSize = BASE_TAB_SIZE;
/** Allocate and fill in the processors strings **/
pData->pPrinterName = AllocSplStr(pPrinterName);
pData->pDatatype = AllocSplStr(pPrintProcessorOpenData->pDatatype);
pData->pDocument = AllocSplStr(pPrintProcessorOpenData->pDocumentName);
pData->pOutputFile = AllocSplStr(pPrintProcessorOpenData->pOutputFile);
pData->pParameters = AllocSplStr(pPrintProcessorOpenData->pParameters);
pData->pDevmode = pDevmode;
pData->pPrinterNameFromOpenData = AllocSplStr(pPrintProcessorOpenData->pPrinterName);
//
// Check for validity of pData. In the AllocSplStr above, if RHS is non-null, then LHS
// should be non-null.
//
if ( NULL == pData->semPaused ||
( NULL != pPrinterName && NULL == pData->pPrinterName ) ||
( NULL != pPrintProcessorOpenData->pDatatype && NULL == pData->pDatatype ) ||
( NULL != pPrintProcessorOpenData->pDocumentName && NULL == pData->pDocument ) ||
( NULL != pPrintProcessorOpenData->pOutputFile && NULL == pData->pOutputFile ) ||
( NULL != pPrintProcessorOpenData->pParameters && NULL == pData->pParameters ) ||
( NULL != pPrintProcessorOpenData->pPrinterName && NULL == pData->pPrinterNameFromOpenData)
)
{
goto Fail;
}
/** Parse the parameters string **/
if (pData->pParameters) {
ULONG value;
USHORT length = sizeof(ULONG);
/**
Look to see if there is a COPIES=n key/value in the
Parameters field of this job. This tells us the number
of times to play the data.
**/
if (pData->pParameters) {
GetKeyValue(pData->pParameters,
pCopiesKey,
VALUE_ULONG,
&length,
&value);
if (length == sizeof(ULONG)) {
pData->Copies = value;
}
}
/** If this is a text job, see if the tab size is in there **/
if (uDatatype == PRINTPROCESSOR_TYPE_TEXT) {
length = sizeof(ULONG);
GetKeyValue(pData->pParameters,
pTabsKey,
VALUE_ULONG,
&length,
&value);
if ((length == sizeof(ULONG)) && value) {
pData->TabSize = value;
}
}
} /* If we have a parameter string */
/**
If we are doing copies, we need to check to see if
this is a direct or spooled job. If it is direct, then
we can't do copies because we can't rewind the data stream.
**/
if (pData->Copies > 1) {
ULONG Error;
PPRINTER_INFO_2 pPrinterInfo2;
/** If we don't already have the printer open, open it **/
if (uDatatype != PRINTPROCESSOR_TYPE_RAW
) {
OpenPrinter(pPrinterName, &hPrinter, NULL);
}
if (hPrinter && hPrinter != INVALID_HANDLE_VALUE) {
/** Get the printer info - this returns an allocated buffer **/
pPrinterInfo2 = (PPRINTER_INFO_2)GetPrinterInfo(hPrinter, 2, &Error);
/** If we couldn't get the info, be safe and don't do copies **/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -