📄 separatorpp.cpp
字号:
if (!pPrinterInfo2) {
ODS(("GetPrinter failed - falling back to 1 copy\n"));
pData->Copies = 1;
}
else {
if (pPrinterInfo2->Attributes & PRINTER_ATTRIBUTE_DIRECT) {
pData->Copies = 1;
}
FreeSplMem((PUCHAR)pPrinterInfo2);
}
/** If we just opened the printer, close it **/
if (uDatatype != PRINTPROCESSOR_TYPE_RAW
) {
ClosePrinter(hPrinter);
}
}
else {
pData->Copies = 1;
}
}
return (HANDLE)pData;
Fail:
BReleasePPData(&pData);
return FALSE;
}
/*++
*******************************************************************
P r i n t D o c u m e n t O n P r i n t P r o c e s s o r
Routine Description:
Arguments:
hPrintProcessor
pDocumentName
Return Value:
TRUE if successful
FALSE if failed - GetLastError() will return reason
*******************************************************************
--*/
BOOL
PrintDocumentOnPrintProcessor(
HANDLE hPrintProcessor,
LPWSTR pDocumentName
)
{
PPRINTPROCESSORDATA pData;
/**
Make sure the handle is valid and pick up
the Print Processors data area.
**/
if (!(pData = ValidateHandle(hPrintProcessor))) {
return FALSE;
}
/**
Print the job based on its data type.
**/
switch (pData->uDatatype) {
case PRINTPROCESSOR_TYPE_EMF_50_1:
case PRINTPROCESSOR_TYPE_EMF_50_2:
case PRINTPROCESSOR_TYPE_EMF_50_3:
return PrintEMFJob( pData, pDocumentName );
break;
case PRINTPROCESSOR_TYPE_RAW:
return PrintRawJob(pData, pDocumentName, pData->uDatatype);
break;
case PRINTPROCESSOR_TYPE_TEXT:
return PrintTextJob(pData, pDocumentName);
break;
} /* Case on data type */
/** Return success **/
return TRUE;
}
/*++
*******************************************************************
C l o s e P r i n t P r o c e s s o r
Routine Description:
Frees the resources used by an open print processor.
Arguments:
hPrintProcessor (HANDLE) => print processor to close
Return Value:
TRUE if successful
FALSE if failed - caller uses GetLastError for reason.
*******************************************************************
--*/
BOOL
ClosePrintProcessor(
HANDLE hPrintProcessor
)
{
PPRINTPROCESSORDATA pData;
/**
Make sure the handle is valid and pick up
the Print Processors data area.
**/
if (!(pData= ValidateHandle(hPrintProcessor))) {
return FALSE;
}
return BReleasePPData(&pData);
}
BOOL BReleasePPData(
IN PPRINTPROCESSORDATA * ppData )
{
PPRINTPROCESSORDATA pData = NULL;
if ( NULL == ppData || NULL == *ppData)
{
return FALSE;
}
pData = *ppData;
pData->signature = 0;
/* Release any allocated resources */
if (pData->hPrinter)
ClosePrinter(pData->hPrinter);
if (pData->hDC)
DeleteDC(pData->hDC);
if (pData->pDevmode)
FreeSplMem(pData->pDevmode);
if (pData->pPrinterNameFromOpenData)
FreeSplStr(pData->pPrinterNameFromOpenData);
if (pData->semPaused)
CloseHandle(pData->semPaused);
if (pData->pPrinterName)
FreeSplStr(pData->pPrinterName);
if (pData->pDatatype)
FreeSplStr(pData->pDatatype);
if (pData->pDocument)
FreeSplStr(pData->pDocument);
if (pData->pOutputFile)
FreeSplStr(pData->pOutputFile);
if (pData->pParameters)
FreeSplStr(pData->pParameters);
ZeroMemory ( pData, sizeof (PRINTPROCESSORDATA) );
FreeSplMem(pData);
*ppData = pData = NULL;
return TRUE;
}
/*++
*******************************************************************
C o n t r o l P r i n t P r o c e s s o r
Routine Description:
Handles commands to pause, resume, and cancel print jobs.
Arguments:
hPrintProcessor = HANDLE to the PrintProcessor the
command is issued for.
Return Value:
TRUE if command succeeded
FALSE if command failed (invalid command)
*******************************************************************
--*/
BOOL
ControlPrintProcessor(
HANDLE hPrintProcessor,
DWORD Command
)
{
PPRINTPROCESSORDATA pData;
/**
Make sure the handle is valid and pick up
the Print Processors data area.
**/
if (pData = ValidateHandle(hPrintProcessor)) {
switch (Command) {
case JOB_CONTROL_PAUSE:
ResetEvent(pData->semPaused);
pData->fsStatus |= PRINTPROCESSOR_PAUSED;
return TRUE;
break;
case JOB_CONTROL_CANCEL:
pData->fsStatus |= PRINTPROCESSOR_ABORTED;
if ((pData->uDatatype == PRINTPROCESSOR_TYPE_EMF_50_1) ||
(pData->uDatatype == PRINTPROCESSOR_TYPE_EMF_50_2) ||
(pData->uDatatype == PRINTPROCESSOR_TYPE_EMF_50_3))
CancelDC(pData->hDC);
/* Fall through to release job if paused */
case JOB_CONTROL_RESUME:
if (pData->fsStatus & PRINTPROCESSOR_PAUSED) {
SetEvent(pData->semPaused);
pData->fsStatus &= ~PRINTPROCESSOR_PAUSED;
}
return TRUE;
break;
default:
return FALSE;
break;
}
}
return FALSE;
}
/*++
*******************************************************************
V a l i d a t e H a n d l e
Routine Description:
Validates the given Print Processor HANDLE (which is
really a pointer to the Print Processor's data) by
checking for our signature.
Arguments:
hQProc (HANDLE) => Print Processor data structure. This
is verified as really being a pointer to the Print
Processor's data.
Return Value:
PPRINTPROCESSORDATA if successful (valid pointer passed)
NULL if failed - pointer was not valid
*******************************************************************
--*/
PPRINTPROCESSORDATA
ValidateHandle(
HANDLE hQProc
)
{
/** Pick up the pointer **/
PPRINTPROCESSORDATA pData = (PPRINTPROCESSORDATA)hQProc;
//
// Note that spooler has to leave the critical section to call into print
// proc. So the handle passed by spooler could be invalid since one
// thread could call SetJob to pause/resume a job while port thread
// is printing it
//
__try {
/** See if our signature exists in the suspected data region **/
if (pData && pData->signature != PRINTPROCESSORDATA_SIGNATURE) {
/** Bad pointer - return failed **/
pData = NULL;
}
}__except (1) {
/** Bad pointer - return failed **/
pData = NULL;
}
if ( pData == NULL )
SetLastError( ERROR_INVALID_HANDLE );
return pData;
}
DWORD
GetPrintProcessorCapabilities(
LPTSTR pValueName,
DWORD dwAttributes,
LPBYTE pData,
DWORD nSize,
LPDWORD pcbNeeded
)
/*++
Function Description: GetPrintProcessorCapabilities returns information about the
options supported by the print processor for the given datatype
in a PRINTPROCESSOR_CAPS_1 struct.
Parameters: pValueName -- datatype like RAW|NT EMF 1.006|TEXT|...
dwAttributes -- printer attributes
pData -- pointer to the buffer
nSize -- size of the buffer
pcbNeeded -- pointer to the variable to store the required buffer size
Return Values: Error Codes.
--*/
{
LPWSTR *pDatatypes = Datatypes;
DWORD dwDatatype = 0;
DWORD dwReturn;
PPRINTPROCESSOR_CAPS_1 ppcInfo;
// Check for valid parameters.
if ( !pcbNeeded || !pData || !pValueName) {
dwReturn = ERROR_INVALID_PARAMETER;
goto CleanUp;
}
*pcbNeeded = sizeof(PRINTPROCESSOR_CAPS_1);
// Check for sufficient buffer.
if (nSize < *pcbNeeded) {
dwReturn = ERROR_MORE_DATA;
goto CleanUp;
}
// Loop to find the index of the datatype.
while (*pDatatypes) {
if (!_wcsicmp(*pDatatypes,pValueName)) {
break;
}
pDatatypes++;
dwDatatype++;
}
ppcInfo = (PPRINTPROCESSOR_CAPS_1) pData;
// Level is 1 for PRINTPROCESSOR_CAPS_1.
ppcInfo->dwLevel = 1;
switch (dwDatatype) {
case PRINTPROCESSOR_TYPE_RAW:
case PRINTPROCESSOR_TYPE_TEXT:
ppcInfo->dwNupOptions = 1;
ppcInfo->dwNumberOfCopies = 0xffffffff; // maximum number of copies.
ppcInfo->dwPageOrderFlags = NORMAL_PRINT;
break;
case PRINTPROCESSOR_TYPE_EMF_50_1:
case PRINTPROCESSOR_TYPE_EMF_50_2:
case PRINTPROCESSOR_TYPE_EMF_50_3:
// For direct printing, masq. printers and print RAW only,
// EMF is not spooled. Dont expose EMF features in the UI.
if ((dwAttributes & PRINTER_ATTRIBUTE_DIRECT) ||
(dwAttributes & PRINTER_ATTRIBUTE_RAW_ONLY) ||
((dwAttributes & PRINTER_ATTRIBUTE_LOCAL) &&
(dwAttributes & PRINTER_ATTRIBUTE_NETWORK))) {
ppcInfo->dwNupOptions = 1;
ppcInfo->dwNumberOfCopies = 1;
ppcInfo->dwPageOrderFlags = NORMAL_PRINT;
} else {
ppcInfo->dwNupOptions = 0x0000812b; // for 1,2,4,6,9,16 up options.
ppcInfo->dwNumberOfCopies = 0xffffffff; // maximum number of copies.
ppcInfo->dwPageOrderFlags = REVERSE_PRINT | BOOKLET_PRINT;
}
break;
default:
// Should not happen since the spooler must check if the datatype is
// supported before calling this print processor.
dwReturn = ERROR_INVALID_DATATYPE;
goto CleanUp;
}
dwReturn = ERROR_SUCCESS;
CleanUp:
return dwReturn;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -