1 /* 2 * PROJECT: ReactOS Standard Print Processor 3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+) 4 * PURPOSE: Printing a job with RAW datatype 5 * COPYRIGHT: Copyright 2015 Colin Finck (colin@reactos.org) 6 */ 7 8 #include "precomp.h" 9 10 /** 11 * @name PrintRawJob 12 * 13 * @param pHandle 14 * Pointer to a WINPRINT_HANDLE structure containing information about this job. 15 * 16 * @param pwszPrinterAndJob 17 * String in the format "Printer, Job N" that is passed to OpenPrinterW to read from the spooled print job. 18 * 19 * @return 20 * An error code indicating success or failure. 21 */ 22 DWORD 23 PrintRawJob(PWINPRINT_HANDLE pHandle, PWSTR pwszPrinterAndJob) 24 { 25 // Use a read buffer of 256 KB size like Windows does. 26 const DWORD cbReadBuffer = 262144; 27 28 BOOL bStartedDoc = FALSE; 29 DOC_INFO_1W DocInfo1; 30 DWORD cbRead; 31 DWORD cbWritten; 32 DWORD dwErrorCode; 33 HANDLE hPrintJob; 34 HANDLE hPrintMonitor = NULL; 35 PBYTE pBuffer = NULL; 36 37 // Open the spooled job to read from it. 38 if (!OpenPrinterW(pwszPrinterAndJob, &hPrintJob, NULL)) 39 { 40 dwErrorCode = GetLastError(); 41 ERR("OpenPrinterW failed for \"%S\" with error %lu!\n", pwszPrinterAndJob, GetLastError()); 42 goto Cleanup; 43 } 44 45 // Open a Print Monitor handle to write to it. 46 if (!OpenPrinterW(pHandle->pwszPrinterPort, &hPrintMonitor, NULL)) 47 { 48 dwErrorCode = GetLastError(); 49 ERR("OpenPrinterW failed for \"%S\" with error %lu!\n", pHandle->pwszPrinterPort, GetLastError()); 50 goto Cleanup; 51 } 52 53 // Fill the Document Information. 54 DocInfo1.pDatatype = pHandle->pwszDatatype; 55 DocInfo1.pDocName = pHandle->pwszDocumentName; 56 DocInfo1.pOutputFile = pHandle->pwszOutputFile; 57 58 // Tell the Print Monitor that we're starting a new document. 59 if (!StartDocPrinterW(hPrintMonitor, 1, (PBYTE)&DocInfo1)) 60 { 61 dwErrorCode = GetLastError(); 62 ERR("StartDocPrinterW failed with error %lu!\n", GetLastError()); 63 goto Cleanup; 64 } 65 66 bStartedDoc = TRUE; 67 68 // Allocate a read buffer on the heap. This would easily exceed the stack size. 69 pBuffer = DllAllocSplMem(cbReadBuffer); 70 if (!pBuffer) 71 { 72 dwErrorCode = ERROR_NOT_ENOUGH_MEMORY; 73 ERR("DllAllocSplMem failed with error %lu!\n", GetLastError()); 74 goto Cleanup; 75 } 76 77 // Loop as long as data is available. 78 while (ReadPrinter(hPrintJob, pBuffer, cbReadBuffer, &cbRead) && cbRead) 79 { 80 // Write it to the Print Monitor. 81 WritePrinter(hPrintMonitor, pBuffer, cbRead, &cbWritten); 82 } 83 84 dwErrorCode = ERROR_SUCCESS; 85 86 Cleanup: 87 if (pBuffer) 88 DllFreeSplMem(pBuffer); 89 90 if (bStartedDoc) 91 EndDocPrinter(hPrintMonitor); 92 93 if (hPrintMonitor) 94 ClosePrinter(hPrintMonitor); 95 96 if (hPrintJob) 97 ClosePrinter(hPrintJob); 98 99 return dwErrorCode; 100 } 101