3be598b957b4d8e0f505006ed82a55cbe6346cd3
[reactos.git] / reactos / win32ss / printing / processors / winprint / raw.c
1 /*
2 * PROJECT: ReactOS Standard Print Processor
3 * LICENSE: GNU LGPL v2.1 or any later version as published by the Free Software Foundation
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;
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 }