mirror of
https://github.com/reactos/reactos.git
synced 2024-12-29 10:35:28 +00:00
9393fc320e
Excluded: 3rd-party code (incl. wine) and most of the win32ss.
100 lines
2.8 KiB
C
100 lines
2.8 KiB
C
/*
|
|
* PROJECT: ReactOS Standard Print Processor
|
|
* LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
|
|
* PURPOSE: Printing a job with RAW datatype
|
|
* COPYRIGHT: Copyright 2015 Colin Finck (colin@reactos.org)
|
|
*/
|
|
|
|
#include "precomp.h"
|
|
|
|
/**
|
|
* @name PrintRawJob
|
|
*
|
|
* @param pHandle
|
|
* Pointer to a WINPRINT_HANDLE structure containing information about this job.
|
|
*
|
|
* @param pwszPrinterAndJob
|
|
* String in the format "Printer, Job N" that is passed to OpenPrinterW to read from the spooled print job.
|
|
*
|
|
* @return
|
|
* An error code indicating success or failure.
|
|
*/
|
|
DWORD
|
|
PrintRawJob(PWINPRINT_HANDLE pHandle, PWSTR pwszPrinterAndJob)
|
|
{
|
|
// Use a read buffer of 256 KB size like Windows does.
|
|
const DWORD cbReadBuffer = 262144;
|
|
|
|
BOOL bStartedDoc = FALSE;
|
|
DOC_INFO_1W DocInfo1;
|
|
DWORD cbRead;
|
|
DWORD cbWritten;
|
|
DWORD dwErrorCode;
|
|
HANDLE hPrintJob;
|
|
HANDLE hPrintMonitor = NULL;
|
|
PBYTE pBuffer = NULL;
|
|
|
|
// Open the spooled job to read from it.
|
|
if (!OpenPrinterW(pwszPrinterAndJob, &hPrintJob, NULL))
|
|
{
|
|
dwErrorCode = GetLastError();
|
|
ERR("OpenPrinterW failed for \"%S\" with error %lu!\n", pwszPrinterAndJob, GetLastError());
|
|
goto Cleanup;
|
|
}
|
|
|
|
// Open a Print Monitor handle to write to it.
|
|
if (!OpenPrinterW(pHandle->pwszPrinterPort, &hPrintMonitor, NULL))
|
|
{
|
|
dwErrorCode = GetLastError();
|
|
ERR("OpenPrinterW failed for \"%S\" with error %lu!\n", pHandle->pwszPrinterPort, GetLastError());
|
|
goto Cleanup;
|
|
}
|
|
|
|
// Fill the Document Information.
|
|
DocInfo1.pDatatype = pHandle->pwszDatatype;
|
|
DocInfo1.pDocName = pHandle->pwszDocumentName;
|
|
DocInfo1.pOutputFile = pHandle->pwszOutputFile;
|
|
|
|
// Tell the Print Monitor that we're starting a new document.
|
|
if (!StartDocPrinterW(hPrintMonitor, 1, (PBYTE)&DocInfo1))
|
|
{
|
|
dwErrorCode = GetLastError();
|
|
ERR("StartDocPrinterW failed with error %lu!\n", GetLastError());
|
|
goto Cleanup;
|
|
}
|
|
|
|
bStartedDoc = TRUE;
|
|
|
|
// Allocate a read buffer on the heap. This would easily exceed the stack size.
|
|
pBuffer = DllAllocSplMem(cbReadBuffer);
|
|
if (!pBuffer)
|
|
{
|
|
dwErrorCode = ERROR_NOT_ENOUGH_MEMORY;
|
|
ERR("DllAllocSplMem failed with error %lu!\n", GetLastError());
|
|
goto Cleanup;
|
|
}
|
|
|
|
// Loop as long as data is available.
|
|
while (ReadPrinter(hPrintJob, pBuffer, cbReadBuffer, &cbRead) && cbRead)
|
|
{
|
|
// Write it to the Print Monitor.
|
|
WritePrinter(hPrintMonitor, pBuffer, cbRead, &cbWritten);
|
|
}
|
|
|
|
dwErrorCode = ERROR_SUCCESS;
|
|
|
|
Cleanup:
|
|
if (pBuffer)
|
|
DllFreeSplMem(pBuffer);
|
|
|
|
if (bStartedDoc)
|
|
EndDocPrinter(hPrintMonitor);
|
|
|
|
if (hPrintMonitor)
|
|
ClosePrinter(hPrintMonitor);
|
|
|
|
if (hPrintJob)
|
|
ClosePrinter(hPrintJob);
|
|
|
|
return dwErrorCode;
|
|
}
|