1 /*
2  * PROJECT:     ReactOS Local Spooler
3  * LICENSE:     GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4  * PURPOSE:     Precompiled Header for all source files
5  * COPYRIGHT:   Copyright 2015-2017 Colin Finck (colin@reactos.org)
6  */
7 
8 #ifndef _PRECOMP_H
9 #define _PRECOMP_H
10 
11 #define WIN32_NO_STATUS
12 #include <limits.h>
13 #include <stdlib.h>
14 #include <wchar.h>
15 
16 #include <lmcons.h>
17 #include <rpc.h>
18 #include <strsafe.h>
19 #include <windef.h>
20 #include <winbase.h>
21 #include <wingdi.h>
22 #include <winreg.h>
23 #include <winspool.h>
24 #include <winsplp.h>
25 #include <dsrole.h>
26 #include <secext.h>
27 #include <ndk/rtlfuncs.h>
28 
29 #define SKIPLIST_LEVELS 16
30 #include <skiplist.h>
31 #include <spoolss.h>
32 
33 #include <wine/debug.h>
34 WINE_DEFAULT_DEBUG_CHANNEL(localspl);
35 
36 // Macros
37 #define IS_VALID_JOB_ID(ID)     (ID >= 1 && ID <= 99999)
38 #define IS_VALID_PRIORITY(P)    (P >= MIN_PRIORITY && P <= MAX_PRIORITY)
39 
40 // Constants
41 #define SHD_WIN2003_SIGNATURE   0x4968
42 
43 // Function pointers
44 typedef BOOL (WINAPI *PClosePrintProcessor)(HANDLE);
45 typedef BOOL (WINAPI *PControlPrintProcessor)(HANDLE, DWORD);
46 typedef BOOL (WINAPI *PEnumPrintProcessorDatatypesW)(LPWSTR, LPWSTR, DWORD, LPBYTE, DWORD, LPDWORD, LPDWORD);
47 typedef DWORD (WINAPI *PGetPrintProcessorCapabilities)(LPWSTR, DWORD, LPBYTE, DWORD, LPDWORD);
48 typedef HANDLE (WINAPI *POpenPrintProcessor)(LPWSTR, PPRINTPROCESSOROPENDATA);
49 typedef BOOL (WINAPI *PPrintDocumentOnPrintProcessor)(HANDLE, LPWSTR);
50 typedef LPMONITOREX(WINAPI *PInitializePrintMonitor)(PWSTR);
51 typedef LPMONITOR2(WINAPI *PInitializePrintMonitor2)(PMONITORINIT, PHANDLE);
52 
53 // Forward declarations
54 typedef struct _LOCAL_HANDLE            LOCAL_HANDLE, *PLOCAL_HANDLE;
55 typedef struct _LOCAL_JOB               LOCAL_JOB, *PLOCAL_JOB;
56 typedef struct _LOCAL_PORT              LOCAL_PORT, *PLOCAL_PORT;
57 typedef struct _LOCAL_PORT_HANDLE       LOCAL_PORT_HANDLE, *PLOCAL_PORT_HANDLE;
58 typedef struct _LOCAL_PRINT_MONITOR     LOCAL_PRINT_MONITOR, *PLOCAL_PRINT_MONITOR;
59 typedef struct _LOCAL_PRINT_PROCESSOR   LOCAL_PRINT_PROCESSOR, *PLOCAL_PRINT_PROCESSOR;
60 typedef struct _LOCAL_PRINTER           LOCAL_PRINTER, *PLOCAL_PRINTER;
61 typedef struct _LOCAL_PRINTER_HANDLE    LOCAL_PRINTER_HANDLE, *PLOCAL_PRINTER_HANDLE;
62 typedef struct _LOCAL_XCV_HANDLE        LOCAL_XCV_HANDLE, *PLOCAL_XCV_HANDLE;
63 typedef struct _SHD_HEADER              SHD_HEADER, *PSHD_HEADER;
64 
65 // Structures
66 /**
67  * Describes a Print Monitor.
68  */
69 struct _LOCAL_PRINT_MONITOR
70 {
71     LIST_ENTRY Entry;
72     PWSTR pwszName;                             /** Name of the Print Monitor as read from the registry. */
73     PWSTR pwszFileName;                         /** DLL File Name of the Print Monitor. */
74     BOOL bIsLevel2;                             /** Whether this Print Monitor supplies an InitializePrintMonitor2 API (preferred) instead of InitializePrintMonitor. */
75     PVOID pMonitor;                             /** For bIsLevel2 == TRUE:  LPMONITOR2 pointer returned by InitializePrintMonitor2.
76                                                     For bIsLevel2 == FALSE: LPMONITOREX pointer returned by InitializePrintMonitor. */
77     HANDLE hMonitor;                            /** Only used when bIsLevel2 == TRUE: Handle returned by InitializePrintMonitor2. */
78 };
79 
80 /**
81  * Describes a Port handled by a Print Monitor.
82  */
83 struct _LOCAL_PORT
84 {
85     LIST_ENTRY Entry;
86     PWSTR pwszName;                             /** The name of the port (including the trailing colon). */
87     PLOCAL_PRINT_MONITOR pPrintMonitor;         /** The Print Monitor handling this port. */
88     PLOCAL_JOB pNextJobToProcess;               /** The Print Job that will be processed by the next created Port handle. */
89 };
90 
91 /**
92  * Describes a Print Processor.
93  */
94 struct _LOCAL_PRINT_PROCESSOR
95 {
96     LIST_ENTRY Entry;
97     PWSTR pwszName;
98     PDATATYPES_INFO_1W pDatatypesInfo1;
99     DWORD dwDatatypeCount;
100     PClosePrintProcessor pfnClosePrintProcessor;
101     PControlPrintProcessor pfnControlPrintProcessor;
102     PEnumPrintProcessorDatatypesW pfnEnumPrintProcessorDatatypesW;
103     PGetPrintProcessorCapabilities pfnGetPrintProcessorCapabilities;
104     POpenPrintProcessor pfnOpenPrintProcessor;
105     PPrintDocumentOnPrintProcessor pfnPrintDocumentOnPrintProcessor;
106 };
107 
108 /**
109  * Describes a printer and manages its print jobs.
110  * Created once for every printer at startup.
111  */
112 struct _LOCAL_PRINTER
113 {
114     // This sort key must be the first element for LookupElementSkiplist to work!
115     PWSTR pwszPrinterName;
116 
117     DWORD dwAttributes;
118     DWORD dwStatus;
119     PWSTR pwszLocation;
120     PWSTR pwszPrinterDriver;
121     PWSTR pwszDescription;
122     PWSTR pwszDefaultDatatype;
123     PDEVMODEW pDefaultDevMode;
124     PLOCAL_PRINT_PROCESSOR pPrintProcessor;
125     PLOCAL_PORT pPort;
126     SKIPLIST JobList;
127 };
128 
129 /**
130  * Describes an entire print job associated to a specific printer through the Printer member.
131  * Created with every valid call to LocalStartDocPrinter.
132  */
133 struct _LOCAL_JOB
134 {
135     // This sort key must be the first element for LookupElementSkiplist to work!
136     DWORD dwJobID;                              /** Internal and external ID of this Job */
137 
138     BOOL bAddedJob : 1;                         /** Whether AddJob has already been called on this Job. */
139     HANDLE hPrintProcessor;                     /** Handle returned by OpenPrintProcessor while the Job is printing. */
140     PLOCAL_PRINTER pPrinter;                    /** Associated Printer to this Job */
141     PLOCAL_PRINT_PROCESSOR pPrintProcessor;     /** Associated Print Processor to this Job */
142     DWORD dwPriority;                           /** Priority of this Job from MIN_PRIORITY to MAX_PRIORITY, default being DEF_PRIORITY */
143     SYSTEMTIME stSubmitted;                     /** Time of the submission of this Job */
144     PWSTR pwszUserName;                         /** Optional; User that submitted the Job */
145     PWSTR pwszNotifyName;                       /** Optional; User that shall be notified about the status of the Job */
146     PWSTR pwszDocumentName;                     /** Optional; Name of the Document that is printed */
147     PWSTR pwszDatatype;                         /** Datatype of the Document */
148     PWSTR pwszOutputFile;                       /** Output File to spool the Job to */
149     PWSTR pwszPrintProcessorParameters;         /** Optional; Parameters for the chosen Print Processor */
150     PWSTR pwszStatus;                           /** Optional; a Status Message for the Job */
151     DWORD dwTotalPages;                         /** Total pages of the Document */
152     DWORD dwPagesPrinted;                       /** Number of pages that have already been printed */
153     DWORD dwStartTime;                          /** Earliest time in minutes since 12:00 AM UTC when this document can be printed */
154     DWORD dwUntilTime;                          /** Latest time in minutes since 12:00 AM UTC when this document can be printed */
155     DWORD dwStatus;                             /** JOB_STATUS_* flags of the Job */
156     PWSTR pwszMachineName;                      /** Name of the machine that submitted the Job (prepended with two backslashes) */
157     PDEVMODEW pDevMode;                         /** Associated Device Mode to this Job */
158 };
159 
160 /**
161  * Specific handle returned by LocalOpenPrinter for every valid call that opens a Printer or Print Job.
162  */
163 struct _LOCAL_PRINTER_HANDLE
164 {
165     BOOL bStartedDoc : 1;                       /** Whether StartDocPrinter has already been called. */
166     HANDLE hSPLFile;                            /** Handle to an opened SPL file for Printer Job handles. */
167     PLOCAL_PRINTER pPrinter;                    /** Printer associated with this handle. */
168     PLOCAL_JOB pJob;                            /** Print Job associated with this handle. This can be the specified Job if this is a Print Job handle or the started job through LocalStartDocPrinter. */
169     PWSTR pwszDatatype;                         /** Datatype used for newly started jobs. */
170     PDEVMODEW pDevMode;                         /** DevMode used for newly started jobs. */
171 };
172 
173 /**
174  * Specific handle returned by LocalOpenPrinter for every valid call that opens a Port.
175  */
176 struct _LOCAL_PORT_HANDLE
177 {
178     HANDLE hPort;                               /** Handle returned by pfnOpenPort. */
179     PLOCAL_PORT pPort;                          /** Port associated with this handle. */
180 };
181 
182 /**
183  * Specific handle returned by LocalOpenPrinter for every valid call that opens an XcvMonitor or XcvPort.
184  */
185 struct _LOCAL_XCV_HANDLE
186 {
187     HANDLE hXcv;                                /** Handle returned by pfnXcvOpenPort. */
188     PLOCAL_PRINT_MONITOR pPrintMonitor;         /** Print Monitor associated with this handle. */
189 };
190 
191 /**
192  * Describes a handle returned by LocalOpenPrinter.
193  * Suitable for all things that can be opened through LocalOpenPrinter.
194  */
195 struct _LOCAL_HANDLE
196 {
197     enum {
198         HandleType_Port,                        /** pSpecificHandle is a PLOCAL_PORT_HANDLE. */
199         HandleType_Printer,                     /** pSpecificHandle is a PLOCAL_PRINTER_HANDLE. */
200         HandleType_PrintServer,                 /** pSpecificHandle is NULL (no additional information needed for a handle to the Print Server) */
201         HandleType_Xcv                          /** pSpecificHandle is a PLOCAL_XCV_HANDLE. */
202     }
203     HandleType;
204     PVOID pSpecificHandle;
205 };
206 
207 /**
208  * Describes the header of a print job serialized into a shadow file (.SHD)
209  * Documented in http://www.undocprint.org/formats/winspool/shd
210  * Compatible with Windows Server 2003
211  */
212 struct _SHD_HEADER
213 {
214     DWORD dwSignature;
215     DWORD cbHeader;
216     WORD wStatus;
217     WORD wUnknown1;
218     DWORD dwJobID;
219     DWORD dwPriority;
220     DWORD offUserName;
221     DWORD offNotifyName;
222     DWORD offDocumentName;
223     DWORD offPort;
224     DWORD offPrinterName;
225     DWORD offDriverName;
226     DWORD offDevMode;
227     DWORD offPrintProcessor;
228     DWORD offDatatype;
229     DWORD offPrintProcessorParameters;
230     SYSTEMTIME stSubmitted;
231     DWORD dwStartTime;
232     DWORD dwUntilTime;
233     DWORD dwUnknown6;
234     DWORD dwTotalPages;
235     DWORD cbSecurityDescriptor;
236     DWORD offSecurityDescriptor;
237     DWORD dwUnknown3;
238     DWORD dwUnknown4;
239     DWORD dwUnknown5;
240     DWORD offMachineName;
241     DWORD dwSPLSize;
242 };
243 
244 // jobs.c
245 extern SKIPLIST GlobalJobList;
246 DWORD WINAPI CreateJob(PLOCAL_PRINTER_HANDLE pPrinterHandle);
247 void FreeJob(PLOCAL_JOB pJob);
248 DWORD GetJobFilePath(PCWSTR pwszExtension, DWORD dwJobID, PWSTR pwszOutput);
249 BOOL InitializeGlobalJobList(VOID);
250 void InitializePrinterJobList(PLOCAL_PRINTER pPrinter);
251 BOOL WINAPI LocalAddJob(HANDLE hPrinter, DWORD Level, LPBYTE pData, DWORD cbBuf, LPDWORD pcbNeeded);
252 BOOL WINAPI LocalEnumJobs(HANDLE hPrinter, DWORD FirstJob, DWORD NoJobs, DWORD Level, PBYTE pStart, DWORD cbBuf, LPDWORD pcbNeeded, LPDWORD pcReturned);
253 BOOL WINAPI LocalGetJob(HANDLE hPrinter, DWORD JobId, DWORD Level, PBYTE pStart, DWORD cbBuf, LPDWORD pcbNeeded);
254 BOOL WINAPI LocalScheduleJob(HANDLE hPrinter, DWORD dwJobID);
255 BOOL WINAPI LocalSetJob(HANDLE hPrinter, DWORD JobId, DWORD Level, PBYTE pJobInfo, DWORD Command);
256 PLOCAL_JOB ReadJobShadowFile(PCWSTR pwszFilePath);
257 BOOL WriteJobShadowFile(PWSTR pwszFilePath, const PLOCAL_JOB pJob);
258 
259 // main.c
260 extern const WCHAR wszCurrentEnvironment[];
261 extern const DWORD cbCurrentEnvironment;
262 extern const DWORD dwSpoolerMajorVersion;
263 extern const DWORD dwSpoolerMinorVersion;
264 extern const WCHAR wszDefaultDocumentName[];
265 extern HKEY hPrintKey;
266 extern HKEY hPrintersKey;
267 extern PWSTR wszPrintProviderInfo[3];
268 extern WCHAR wszJobDirectory[MAX_PATH];
269 extern DWORD cchJobDirectory;
270 extern WCHAR wszSpoolDirectory[MAX_PATH];
271 extern DWORD cchSpoolDirectory;
272 
273 // monitors.c
274 extern LIST_ENTRY PrintMonitorList;
275 PLOCAL_PRINT_MONITOR FindPrintMonitor(PCWSTR pwszName);
276 BOOL InitializePrintMonitorList(void);
277 BOOL WINAPI LocalEnumMonitors(PWSTR pName, DWORD Level, PBYTE pMonitors, DWORD cbBuf, PDWORD pcbNeeded, PDWORD pcReturned);
278 
279 // ports.c
280 PLOCAL_PORT FindPort(PCWSTR pwszName);
281 BOOL InitializePortList(void);
282 BOOL WINAPI LocalEnumPorts(PWSTR pName, DWORD Level, PBYTE pPorts, DWORD cbBuf, PDWORD pcbNeeded, PDWORD pcReturned);
283 
284 // printerdata.c
285 DWORD WINAPI LocalGetPrinterData(HANDLE hPrinter, PWSTR pValueName, PDWORD pType, PBYTE pData, DWORD nSize, PDWORD pcbNeeded);
286 DWORD WINAPI LocalGetPrinterDataEx(HANDLE hPrinter, PCWSTR pKeyName, PCWSTR pValueName, PDWORD pType, PBYTE pData, DWORD nSize, PDWORD pcbNeeded);
287 DWORD WINAPI LocalSetPrinterData(HANDLE hPrinter, PWSTR pValueName, DWORD Type, PBYTE pData, DWORD cbData);
288 DWORD WINAPI LocalSetPrinterDataEx(HANDLE hPrinter, LPCWSTR pKeyName, LPCWSTR pValueName, DWORD Type, LPBYTE pData, DWORD cbData);
289 
290 // printers.c
291 extern SKIPLIST PrinterList;
292 BOOL InitializePrinterList(void);
293 BOOL WINAPI LocalEnumPrinters(DWORD Flags, LPWSTR Name, DWORD Level, LPBYTE pPrinterEnum, DWORD cbBuf, LPDWORD pcbNeeded, LPDWORD pcReturned);
294 BOOL WINAPI LocalGetPrinter(HANDLE hPrinter, DWORD Level, LPBYTE pPrinter, DWORD cbBuf, LPDWORD pcbNeeded);
295 BOOL WINAPI LocalOpenPrinter(PWSTR lpPrinterName, HANDLE* phPrinter, PPRINTER_DEFAULTSW pDefault);
296 BOOL WINAPI LocalReadPrinter(HANDLE hPrinter, PVOID pBuf, DWORD cbBuf, PDWORD pNoBytesRead);
297 DWORD WINAPI LocalStartDocPrinter(HANDLE hPrinter, DWORD Level, LPBYTE pDocInfo);
298 BOOL WINAPI LocalStartPagePrinter(HANDLE hPrinter);
299 BOOL WINAPI LocalWritePrinter(HANDLE hPrinter, LPVOID pBuf, DWORD cbBuf, LPDWORD pcWritten);
300 BOOL WINAPI LocalEndPagePrinter(HANDLE hPrinter);
301 BOOL WINAPI LocalEndDocPrinter(HANDLE hPrinter);
302 BOOL WINAPI LocalClosePrinter(HANDLE hPrinter);
303 
304 // printingthread.c
305 DWORD WINAPI PrintingThreadProc(PLOCAL_JOB pJob);
306 
307 // printprocessors.c
308 BOOL FindDatatype(const PLOCAL_PRINT_PROCESSOR pPrintProcessor, PCWSTR pwszDatatype);
309 PLOCAL_PRINT_PROCESSOR FindPrintProcessor(PCWSTR pwszName);
310 BOOL InitializePrintProcessorList(void);
311 BOOL WINAPI LocalEnumPrintProcessorDatatypes(LPWSTR pName, LPWSTR pPrintProcessorName, DWORD Level, LPBYTE pDatatypes, DWORD cbBuf, LPDWORD pcbNeeded, LPDWORD pcReturned);
312 BOOL WINAPI LocalEnumPrintProcessors(LPWSTR pName, LPWSTR pEnvironment, DWORD Level, LPBYTE pPrintProcessorInfo, DWORD cbBuf, LPDWORD pcbNeeded, LPDWORD pcReturned);
313 BOOL WINAPI LocalGetPrintProcessorDirectory(LPWSTR pName, LPWSTR pEnvironment, DWORD Level, LPBYTE pPrintProcessorInfo, DWORD cbBuf, LPDWORD pcbNeeded);
314 
315 // tools.c
316 PWSTR AllocAndRegQueryWSZ(HKEY hKey, PCWSTR pwszValueName);
317 PDEVMODEW DuplicateDevMode(PDEVMODEW pInput);
318 
319 #endif
320