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 <winddiui.h>
26 #include <dsrole.h>
27 #include <secext.h>
28 #include <ndk/rtlfuncs.h>
29 
30 #define SKIPLIST_LEVELS 16
31 #include <skiplist.h>
32 #include <spoolss.h>
33 
34 #include <wine/debug.h>
35 WINE_DEFAULT_DEBUG_CHANNEL(localspl);
36 
37 // Macros
38 #define IS_VALID_JOB_ID(ID)     (ID >= 1 && ID <= 99999)
39 #define IS_VALID_PRIORITY(P)    (P >= MIN_PRIORITY && P <= MAX_PRIORITY)
40 
41 // Constants
42 #define SHD_WIN2003_SIGNATURE   0x4968
43 
44 // Function pointers
45 typedef BOOL (WINAPI *PClosePrintProcessor)(HANDLE);
46 typedef BOOL (WINAPI *PControlPrintProcessor)(HANDLE, DWORD);
47 typedef BOOL (WINAPI *PEnumPrintProcessorDatatypesW)(LPWSTR, LPWSTR, DWORD, LPBYTE, DWORD, LPDWORD, LPDWORD);
48 typedef DWORD (WINAPI *PGetPrintProcessorCapabilities)(LPWSTR, DWORD, LPBYTE, DWORD, LPDWORD);
49 typedef HANDLE (WINAPI *POpenPrintProcessor)(LPWSTR, PPRINTPROCESSOROPENDATA);
50 typedef BOOL (WINAPI *PPrintDocumentOnPrintProcessor)(HANDLE, LPWSTR);
51 typedef LPMONITOREX(WINAPI *PInitializePrintMonitor)(PWSTR);
52 typedef LPMONITOR2(WINAPI *PInitializePrintMonitor2)(PMONITORINIT, PHANDLE);
53 typedef PMONITORUI(WINAPI *PInitializePrintMonitorUI)(VOID);
54 
55 // Forward declarations
56 typedef struct _LOCAL_HANDLE            LOCAL_HANDLE, *PLOCAL_HANDLE;
57 typedef struct _LOCAL_JOB               LOCAL_JOB, *PLOCAL_JOB;
58 typedef struct _LOCAL_PORT              LOCAL_PORT, *PLOCAL_PORT;
59 typedef struct _LOCAL_PORT_HANDLE       LOCAL_PORT_HANDLE, *PLOCAL_PORT_HANDLE;
60 typedef struct _LOCAL_PRINT_MONITOR     LOCAL_PRINT_MONITOR, *PLOCAL_PRINT_MONITOR;
61 typedef struct _LOCAL_PRINT_PROCESSOR   LOCAL_PRINT_PROCESSOR, *PLOCAL_PRINT_PROCESSOR;
62 typedef struct _LOCAL_PRINTER           LOCAL_PRINTER, *PLOCAL_PRINTER;
63 typedef struct _LOCAL_PRINTER_HANDLE    LOCAL_PRINTER_HANDLE, *PLOCAL_PRINTER_HANDLE;
64 typedef struct _LOCAL_XCV_HANDLE        LOCAL_XCV_HANDLE, *PLOCAL_XCV_HANDLE;
65 typedef struct _SHD_HEADER              SHD_HEADER, *PSHD_HEADER;
66 
67 // Structures
68 /**
69  * Describes a Print Monitor.
70  */
71 struct _LOCAL_PRINT_MONITOR
72 {
73     LIST_ENTRY Entry;
74     DWORD refcount;
75     PWSTR pwszName;                             /** Name of the Print Monitor as read from the registry. */
76     PWSTR pwszFileName;                         /** DLL File Name of the Print Monitor. */
77     HMODULE hModule;
78     BOOL bIsLevel2;                             /** Whether this Print Monitor supplies an InitializePrintMonitor2 API (preferred) instead of InitializePrintMonitor. */
79     PVOID pMonitor;                             /** For bIsLevel2 == TRUE:  LPMONITOR2 pointer returned by InitializePrintMonitor2.
80                                                     For bIsLevel2 == FALSE: LPMONITOREX pointer returned by InitializePrintMonitor. */
81     HANDLE hMonitor;                            /** Only used when bIsLevel2 == TRUE: Handle returned by InitializePrintMonitor2. */
82 };
83 
84 /**
85  * Describes a Port handled by a Print Monitor.
86  */
87 struct _LOCAL_PORT
88 {
89     LIST_ENTRY Entry;
90     PWSTR pwszName;                             /** The name of the port (including the trailing colon). */
91     PLOCAL_PRINT_MONITOR pPrintMonitor;         /** The Print Monitor handling this port. */
92     PLOCAL_JOB pNextJobToProcess;               /** The Print Job that will be processed by the next created Port handle. */
93 };
94 
95 /**
96  * Describes a Print Processor.
97  */
98 struct _LOCAL_PRINT_PROCESSOR
99 {
100     LIST_ENTRY Entry;
101     PWSTR pwszName;
102     PDATATYPES_INFO_1W pDatatypesInfo1;
103     DWORD dwDatatypeCount;
104     PClosePrintProcessor pfnClosePrintProcessor;
105     PControlPrintProcessor pfnControlPrintProcessor;
106     PEnumPrintProcessorDatatypesW pfnEnumPrintProcessorDatatypesW;
107     PGetPrintProcessorCapabilities pfnGetPrintProcessorCapabilities;
108     POpenPrintProcessor pfnOpenPrintProcessor;
109     PPrintDocumentOnPrintProcessor pfnPrintDocumentOnPrintProcessor;
110 };
111 
112 /**
113  * Describes a printer and manages its print jobs.
114  * Created once for every printer at startup.
115  */
116 struct _LOCAL_PRINTER
117 {
118     // This sort key must be the first element for LookupElementSkiplist to work!
119     PWSTR pwszPrinterName;
120 
121     DWORD dwAttributes;
122     DWORD dwStatus;
123     PWSTR pwszLocation;
124     PWSTR pwszPrinterDriver;
125     PWSTR pwszDescription;
126     PWSTR pwszDefaultDatatype;
127     PDEVMODEW pDefaultDevMode;
128     PLOCAL_PRINT_PROCESSOR pPrintProcessor;
129     PLOCAL_PORT pPort;
130     SKIPLIST JobList;
131 };
132 
133 /**
134  * Describes an entire print job associated to a specific printer through the Printer member.
135  * Created with every valid call to LocalStartDocPrinter.
136  */
137 struct _LOCAL_JOB
138 {
139     // This sort key must be the first element for LookupElementSkiplist to work!
140     DWORD dwJobID;                              /** Internal and external ID of this Job */
141 
142     BOOL bAddedJob : 1;                         /** Whether AddJob has already been called on this Job. */
143     HANDLE hPrintProcessor;                     /** Handle returned by OpenPrintProcessor while the Job is printing. */
144     PLOCAL_PRINTER pPrinter;                    /** Associated Printer to this Job */
145     PLOCAL_PRINT_PROCESSOR pPrintProcessor;     /** Associated Print Processor to this Job */
146     DWORD dwPriority;                           /** Priority of this Job from MIN_PRIORITY to MAX_PRIORITY, default being DEF_PRIORITY */
147     SYSTEMTIME stSubmitted;                     /** Time of the submission of this Job */
148     PWSTR pwszUserName;                         /** Optional; User that submitted the Job */
149     PWSTR pwszNotifyName;                       /** Optional; User that shall be notified about the status of the Job */
150     PWSTR pwszDocumentName;                     /** Optional; Name of the Document that is printed */
151     PWSTR pwszDatatype;                         /** Datatype of the Document */
152     PWSTR pwszOutputFile;                       /** Output File to spool the Job to */
153     PWSTR pwszPrintProcessorParameters;         /** Optional; Parameters for the chosen Print Processor */
154     PWSTR pwszStatus;                           /** Optional; a Status Message for the Job */
155     DWORD dwTotalPages;                         /** Total pages of the Document */
156     DWORD dwPagesPrinted;                       /** Number of pages that have already been printed */
157     DWORD dwStartTime;                          /** Earliest time in minutes since 12:00 AM UTC when this document can be printed */
158     DWORD dwUntilTime;                          /** Latest time in minutes since 12:00 AM UTC when this document can be printed */
159     DWORD dwStatus;                             /** JOB_STATUS_* flags of the Job */
160     PWSTR pwszMachineName;                      /** Name of the machine that submitted the Job (prepended with two backslashes) */
161     PDEVMODEW pDevMode;                         /** Associated Device Mode to this Job */
162 };
163 
164 /**
165  * Specific handle returned by LocalOpenPrinter for every valid call that opens a Printer or Print Job.
166  */
167 struct _LOCAL_PRINTER_HANDLE
168 {
169     BOOL bStartedDoc : 1;                       /** Whether StartDocPrinter has already been called. */
170     HANDLE hSPLFile;                            /** Handle to an opened SPL file for Printer Job handles. */
171     PLOCAL_PRINTER pPrinter;                    /** Printer associated with this handle. */
172     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. */
173     PWSTR pwszDatatype;                         /** Datatype used for newly started jobs. */
174     PDEVMODEW pDevMode;                         /** DevMode used for newly started jobs. */
175 };
176 
177 /**
178  * Specific handle returned by LocalOpenPrinter for every valid call that opens a Port.
179  */
180 struct _LOCAL_PORT_HANDLE
181 {
182     HANDLE hPort;                               /** Handle returned by pfnOpenPort. */
183     PLOCAL_PORT pPort;                          /** Port associated with this handle. */
184 };
185 
186 /**
187  * Specific handle returned by LocalOpenPrinter for every valid call that opens an XcvMonitor or XcvPort.
188  */
189 struct _LOCAL_XCV_HANDLE
190 {
191     HANDLE hXcv;                                /** Handle returned by pfnXcvOpenPort. */
192     PLOCAL_PRINT_MONITOR pPrintMonitor;         /** Print Monitor associated with this handle. */
193 };
194 
195 /**
196  * Describes a handle returned by LocalOpenPrinter.
197  * Suitable for all things that can be opened through LocalOpenPrinter.
198  */
199 struct _LOCAL_HANDLE
200 {
201     enum {
202         HandleType_Port,                        /** pSpecificHandle is a PLOCAL_PORT_HANDLE. */
203         HandleType_Printer,                     /** pSpecificHandle is a PLOCAL_PRINTER_HANDLE. */
204         HandleType_PrintServer,                 /** pSpecificHandle is NULL (no additional information needed for a handle to the Print Server) */
205         HandleType_Xcv                          /** pSpecificHandle is a PLOCAL_XCV_HANDLE. */
206     }
207     HandleType;
208     PVOID pSpecificHandle;
209 };
210 
211 /**
212  * Describes the header of a print job serialized into a shadow file (.SHD)
213  * Documented in http://www.undocprint.org/formats/winspool/shd
214  * Compatible with Windows Server 2003
215  */
216 struct _SHD_HEADER
217 {
218     DWORD dwSignature;
219     DWORD cbHeader;
220     WORD wStatus;
221     WORD wUnknown1;
222     DWORD dwJobID;
223     DWORD dwPriority;
224     DWORD offUserName;
225     DWORD offNotifyName;
226     DWORD offDocumentName;
227     DWORD offPort;
228     DWORD offPrinterName;
229     DWORD offDriverName;
230     DWORD offDevMode;
231     DWORD offPrintProcessor;
232     DWORD offDatatype;
233     DWORD offPrintProcessorParameters;
234     SYSTEMTIME stSubmitted;
235     DWORD dwStartTime;
236     DWORD dwUntilTime;
237     DWORD dwUnknown6;
238     DWORD dwTotalPages;
239     DWORD cbSecurityDescriptor;
240     DWORD offSecurityDescriptor;
241     DWORD dwUnknown3;
242     DWORD dwUnknown4;
243     DWORD dwUnknown5;
244     DWORD offMachineName;
245     DWORD dwSPLSize;
246 };
247 
248 // forms.c
249 BOOL InitializeFormList(VOID);
250 BOOL WINAPI LocalAddForm(HANDLE hPrinter, DWORD Level, PBYTE pForm);
251 BOOL WINAPI LocalDeleteForm(HANDLE hPrinter, PWSTR pFormName);
252 BOOL WINAPI LocalEnumForms(HANDLE hPrinter, DWORD Level, PBYTE pForm, DWORD cbBuf, PDWORD pcbNeeded, PDWORD pcReturned);
253 BOOL WINAPI LocalGetForm(HANDLE hPrinter, PWSTR pFormName, DWORD Level, PBYTE pForm, DWORD cbBuf, PDWORD pcbNeeded);
254 BOOL WINAPI LocalSetForm(HANDLE hPrinter, PWSTR pFormName, DWORD Level, PBYTE pForm);
255 
256 // jobs.c
257 extern SKIPLIST GlobalJobList;
258 DWORD WINAPI CreateJob(PLOCAL_PRINTER_HANDLE pPrinterHandle);
259 void FreeJob(PLOCAL_JOB pJob);
260 DWORD GetJobFilePath(PCWSTR pwszExtension, DWORD dwJobID, PWSTR pwszOutput);
261 BOOL InitializeGlobalJobList(VOID);
262 void InitializePrinterJobList(PLOCAL_PRINTER pPrinter);
263 BOOL WINAPI LocalAddJob(HANDLE hPrinter, DWORD Level, LPBYTE pData, DWORD cbBuf, LPDWORD pcbNeeded);
264 BOOL WINAPI LocalEnumJobs(HANDLE hPrinter, DWORD FirstJob, DWORD NoJobs, DWORD Level, PBYTE pStart, DWORD cbBuf, LPDWORD pcbNeeded, LPDWORD pcReturned);
265 BOOL WINAPI LocalGetJob(HANDLE hPrinter, DWORD JobId, DWORD Level, PBYTE pStart, DWORD cbBuf, LPDWORD pcbNeeded);
266 BOOL WINAPI LocalScheduleJob(HANDLE hPrinter, DWORD dwJobID);
267 BOOL WINAPI LocalSetJob(HANDLE hPrinter, DWORD JobId, DWORD Level, PBYTE pJobInfo, DWORD Command);
268 PLOCAL_JOB ReadJobShadowFile(PCWSTR pwszFilePath);
269 BOOL WriteJobShadowFile(PWSTR pwszFilePath, const PLOCAL_JOB pJob);
270 
271 // main.c
272 extern const WCHAR wszCurrentEnvironment[];
273 extern const DWORD cbCurrentEnvironment;
274 extern const DWORD dwSpoolerMajorVersion;
275 extern const DWORD dwSpoolerMinorVersion;
276 extern const WCHAR wszDefaultDocumentName[];
277 extern HKEY hPrintKey;
278 extern HKEY hPrintersKey;
279 extern PCWSTR wszPrintProviderInfo[3];
280 extern WCHAR wszJobDirectory[MAX_PATH];
281 extern DWORD cchJobDirectory;
282 extern WCHAR wszSpoolDirectory[MAX_PATH];
283 extern DWORD cchSpoolDirectory;
284 
285 // monitors.c
286 extern LIST_ENTRY PrintMonitorList;
287 PLOCAL_PRINT_MONITOR FindPrintMonitor(PCWSTR pwszName);
288 BOOL InitializePrintMonitorList(void);
289 BOOL WINAPI LocalEnumMonitors(PWSTR pName, DWORD Level, PBYTE pMonitors, DWORD cbBuf, PDWORD pcbNeeded, PDWORD pcReturned);
290 BOOL WINAPI LocalAddMonitor(PWSTR pName, DWORD Level, PBYTE pMonitors);
291 BOOL WINAPI LocalDeleteMonitor(PWSTR pName, PWSTR pEnvironment, PWSTR pMonitorName);
292 
293 // ports.c
294 PLOCAL_PORT FindPort(PCWSTR pwszName);
295 BOOL InitializePortList(void);
296 BOOL WINAPI LocalEnumPorts(PWSTR pName, DWORD Level, PBYTE pPorts, DWORD cbBuf, PDWORD pcbNeeded, PDWORD pcReturned);
297 BOOL WINAPI LocalAddPortEx(PWSTR pName, DWORD Level, PBYTE lpBuffer, PWSTR lpMonitorName);
298 BOOL WINAPI LocalAddPort(LPWSTR pName, HWND hWnd, LPWSTR pMonitorName);
299 BOOL WINAPI LocalConfigurePort(PWSTR pName, HWND hWnd, PWSTR pPortName);
300 BOOL WINAPI LocalDeletePort(PWSTR pName, HWND hWnd, PWSTR pPortName);
301 BOOL WINAPI LocalSetPort(PWSTR pName, PWSTR pPortName, DWORD dwLevel, PBYTE pPortInfo);
302 BOOL CreatePortEntry( PCWSTR pwszName, PLOCAL_PRINT_MONITOR pPrintMonitor );
303 
304 // printerdata.c
305 DWORD WINAPI LocalGetPrinterData(HANDLE hPrinter, PWSTR pValueName, PDWORD pType, PBYTE pData, DWORD nSize, PDWORD pcbNeeded);
306 DWORD WINAPI LocalGetPrinterDataEx(HANDLE hPrinter, PCWSTR pKeyName, PCWSTR pValueName, PDWORD pType, PBYTE pData, DWORD nSize, PDWORD pcbNeeded);
307 DWORD WINAPI LocalSetPrinterData(HANDLE hPrinter, PWSTR pValueName, DWORD Type, PBYTE pData, DWORD cbData);
308 DWORD WINAPI LocalSetPrinterDataEx(HANDLE hPrinter, LPCWSTR pKeyName, LPCWSTR pValueName, DWORD Type, LPBYTE pData, DWORD cbData);
309 
310 // printerdrivers.c
311 BOOL InitializePrinterDrivers(VOID);
312 BOOL WINAPI LocalAddPrinterDriver(LPWSTR pName, DWORD level, LPBYTE pDriverInfo);
313 BOOL WINAPI LocalAddPrinterDriverEx(LPWSTR pName, DWORD level, LPBYTE pDriverInfo, DWORD dwFileCopyFlags);
314 BOOL WINAPI LocalGetPrinterDriver(HANDLE hPrinter, LPWSTR pEnvironment, DWORD Level, LPBYTE pDriverInfo, DWORD cbBuf, LPDWORD pcbNeeded);
315 BOOL WINAPI LocalGetPrinterDriverDirectory(PWSTR pName, PWSTR pEnvironment, DWORD Level, PBYTE pDriverDirectory, DWORD cbBuf, PDWORD pcbNeeded);
316 BOOL WINAPI LocalGetPrinterDriverEx(HANDLE hPrinter,LPWSTR pEnvironment,DWORD Level,LPBYTE pDriverInfo,DWORD cbBuf,LPDWORD pcbNeeded,DWORD dwClientMajorVersion,DWORD dwClientMinorVersion,PDWORD pdwServerMajorVersion,PDWORD pdwServerMinorVersion );
317 BOOL WINAPI LocalEnumPrinterDrivers(PWSTR pName, PWSTR pEnvironment, DWORD Level, PBYTE pDriverInfo, DWORD cbBuf, PDWORD pcbNeeded, PDWORD pcReturned);
318 
319 // wine codes
320 typedef struct _PRINTENV_T
321 {
322     LPCWSTR  envname;
323     LPCWSTR  subdir;
324     DWORD    driverversion;
325     LPCWSTR  versionregpath;
326     LPCWSTR  versionsubdir;
327 } PRINTENV_T, *PPRINTENV_T;
328 
329 PPRINTENV_T validate_envW(LPCWSTR env);
330 
331 // printers.c
332 extern SKIPLIST PrinterList;
333 BOOL InitializePrinterList(void);
334 BOOL WINAPI LocalEnumPrinters(DWORD Flags, LPWSTR Name, DWORD Level, LPBYTE pPrinterEnum, DWORD cbBuf, LPDWORD pcbNeeded, LPDWORD pcReturned);
335 BOOL WINAPI LocalGetPrinter(HANDLE hPrinter, DWORD Level, LPBYTE pPrinter, DWORD cbBuf, LPDWORD pcbNeeded);
336 BOOL WINAPI LocalOpenPrinter(PWSTR lpPrinterName, HANDLE* phPrinter, PPRINTER_DEFAULTSW pDefault);
337 DWORD WINAPI LocalPrinterMessageBox(HANDLE hPrinter, DWORD Error, HWND hWnd, LPWSTR pText, LPWSTR pCaption, DWORD dwType);
338 BOOL WINAPI LocalReadPrinter(HANDLE hPrinter, PVOID pBuf, DWORD cbBuf, PDWORD pNoBytesRead);
339 DWORD WINAPI LocalStartDocPrinter(HANDLE hPrinter, DWORD Level, LPBYTE pDocInfo);
340 BOOL WINAPI LocalStartPagePrinter(HANDLE hPrinter);
341 BOOL WINAPI LocalWritePrinter(HANDLE hPrinter, LPVOID pBuf, DWORD cbBuf, LPDWORD pcWritten);
342 BOOL WINAPI LocalEndPagePrinter(HANDLE hPrinter);
343 BOOL WINAPI LocalEndDocPrinter(HANDLE hPrinter);
344 BOOL WINAPI LocalClosePrinter(HANDLE hPrinter);
345 VOID BroadcastChange(PLOCAL_HANDLE pHandle);
346 
347 // printingthread.c
348 DWORD WINAPI PrintingThreadProc(PLOCAL_JOB pJob);
349 
350 // printprocessors.c
351 BOOL FindDatatype(const PLOCAL_PRINT_PROCESSOR pPrintProcessor, PCWSTR pwszDatatype);
352 PLOCAL_PRINT_PROCESSOR FindPrintProcessor(PCWSTR pwszName);
353 BOOL InitializePrintProcessorList(void);
354 BOOL WINAPI LocalEnumPrintProcessorDatatypes(LPWSTR pName, LPWSTR pPrintProcessorName, DWORD Level, LPBYTE pDatatypes, DWORD cbBuf, LPDWORD pcbNeeded, LPDWORD pcReturned);
355 BOOL WINAPI LocalEnumPrintProcessors(LPWSTR pName, LPWSTR pEnvironment, DWORD Level, LPBYTE pPrintProcessorInfo, DWORD cbBuf, LPDWORD pcbNeeded, LPDWORD pcReturned);
356 BOOL WINAPI LocalGetPrintProcessorDirectory(LPWSTR pName, LPWSTR pEnvironment, DWORD Level, LPBYTE pPrintProcessorInfo, DWORD cbBuf, LPDWORD pcbNeeded);
357 
358 // spoolfile.c
359 BOOL WINAPI LocalGetSpoolFileInfo(HANDLE hPrinter,LPWSTR *pSpoolDir,LPHANDLE phFile,HANDLE hSpoolerProcess,HANDLE hAppProcess);
360 BOOL WINAPI LocalCommitSpoolData(HANDLE hPrinter,DWORD cbCommit);
361 BOOL WINAPI LocalCloseSpoolFileHandle(HANDLE hPrinter);
362 
363 // tools.c
364 PWSTR AllocAndRegQueryWSZ(HKEY hKey, PCWSTR pwszValueName);
365 PDEVMODEW DuplicateDevMode(PDEVMODEW pInput);
366 // wine codes
367 LONG copy_servername_from_name(LPCWSTR name, LPWSTR target);
368 
369 // Xcv.c
370 BOOL WINAPI LocalXcvData(HANDLE hXcv, const WCHAR* pszDataName, BYTE* pInputData, DWORD cbInputData, BYTE* pOutputData, DWORD cbOutputData, DWORD* pcbOutputNeeded, DWORD* pdwStatus);
371 
372 
373 #endif
374