ReactOS  0.4.15-dev-1150-g593bcce
printerdrivers.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS Spooler Router
3  * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4  * PURPOSE: Functions related to Printer Configuration Data
5  * COPYRIGHT: Copyright 2020 ReactOS
6  */
7 
8 #include "precomp.h"
9 
11 AddPrinterDriverExW(PWSTR pName, DWORD Level, PBYTE pDriverInfo, DWORD dwFileCopyFlags)
12 {
13  BOOL bReturnValue;
14  DWORD dwErrorCode = ERROR_INVALID_PRINTER_NAME;
15  PLIST_ENTRY pEntry;
16  PSPOOLSS_PRINT_PROVIDER pPrintProvider;
17 
18  // Loop through all Print Providers.
19  for (pEntry = PrintProviderList.Flink; pEntry != &PrintProviderList; pEntry = pEntry->Flink)
20  {
21  pPrintProvider = CONTAINING_RECORD(pEntry, SPOOLSS_PRINT_PROVIDER, Entry);
22 
23  bReturnValue = pPrintProvider->PrintProvider.fpAddPrinterDriverEx(pName, Level, pDriverInfo, dwFileCopyFlags);
24 
25  if (bReturnValue == ROUTER_SUCCESS)
26  {
27  dwErrorCode = ERROR_SUCCESS;
28  goto Cleanup;
29  }
30  else if (bReturnValue == ROUTER_STOP_ROUTING)
31  {
32  ERR("A Print Provider returned ROUTER_STOP_ROUTING for Printer \"%S\"!\n", pName);
33  dwErrorCode = GetLastError();
34  goto Cleanup;
35  }
36  }
37 
38 Cleanup:
39  // ERROR_INVALID_NAME by the Print Provider is translated to ERROR_INVALID_PRINTER_NAME here, but not in other APIs as far as I know.
40  if (dwErrorCode == ERROR_INVALID_NAME)
41  dwErrorCode = ERROR_INVALID_PRINTER_NAME;
42 
43  SetLastError(dwErrorCode);
44  return (dwErrorCode == ERROR_SUCCESS);
45 }
46 
49 {
50  TRACE("AddPrinterDriverW(%S, %lu, %p)\n", pName, Level, pDriverInfo);
51  return AddPrinterDriverExW(pName, Level, pDriverInfo, APD_COPY_NEW_FILES);
52 }
53 
55 DeletePrinterDriverExW(PWSTR pName, PWSTR pEnvironment, PWSTR pDriverName, DWORD dwDeleteFlag, DWORD dwVersionFlag)
56 {
57  BOOL bReturnValue;
58  DWORD dwErrorCode = ERROR_INVALID_PRINTER_NAME;
59  PLIST_ENTRY pEntry;
60  PSPOOLSS_PRINT_PROVIDER pPrintProvider;
61 
62  // Loop through all Print Providers.
63  for (pEntry = PrintProviderList.Flink; pEntry != &PrintProviderList; pEntry = pEntry->Flink)
64  {
65  pPrintProvider = CONTAINING_RECORD(pEntry, SPOOLSS_PRINT_PROVIDER, Entry);
66 
67  bReturnValue = pPrintProvider->PrintProvider.fpDeletePrinterDriverEx(pName, pEnvironment, pDriverName, dwDeleteFlag, dwVersionFlag);
68 
69  if (bReturnValue == ROUTER_SUCCESS)
70  {
71  dwErrorCode = ERROR_SUCCESS;
72  goto Cleanup;
73  }
74  else if (bReturnValue == ROUTER_STOP_ROUTING)
75  {
76  ERR("A Print Provider returned ROUTER_STOP_ROUTING for Printer \"%S\"!\n", pName);
77  dwErrorCode = GetLastError();
78  goto Cleanup;
79  }
80  }
81 
82 Cleanup:
83  // ERROR_INVALID_NAME by the Print Provider is translated to ERROR_INVALID_PRINTER_NAME here, but not in other APIs as far as I know.
84  if (dwErrorCode == ERROR_INVALID_NAME)
85  dwErrorCode = ERROR_INVALID_PRINTER_NAME;
86 
87  SetLastError(dwErrorCode);
88  return (dwErrorCode == ERROR_SUCCESS);
89 }
90 
92 DeletePrinterDriverW(PWSTR pName, PWSTR pEnvironment, PWSTR pDriverName)
93 {
94  TRACE("DeletePrinterDriverW(%S, %S, %S)\n", pName, pEnvironment, pDriverName);
95  return DeletePrinterDriverExW(pName, pEnvironment, pDriverName, 0, 0);
96 }
97 
99 EnumPrinterDriversW(PWSTR pName, PWSTR pEnvironment, DWORD Level, PBYTE pDriverInfo, DWORD cbBuf, PDWORD pcbNeeded, PDWORD pcReturned)
100 {
101  DWORD cbCallBuffer;
102  DWORD cbNeeded;
103  DWORD dwErrorCode = MAXDWORD;
104  DWORD dwReturned;
105  PBYTE pCallBuffer;
106  BOOL Ret = FALSE;
107  PSPOOLSS_PRINT_PROVIDER pPrintProvider;
108  PLIST_ENTRY pEntry;
109 
110  // Begin counting.
111  *pcbNeeded = 0;
112  *pcReturned = 0;
113 
114  if ( cbBuf && !pDriverInfo )
115  {
116  dwErrorCode = ERROR_INVALID_USER_BUFFER;
117  goto Cleanup;
118  }
119 
120  // At the beginning, we have the full buffer available.
121  cbCallBuffer = cbBuf;
122  pCallBuffer = pDriverInfo;
123 
124  // Loop through all Print Providers.
125  for (pEntry = PrintProviderList.Flink; pEntry != &PrintProviderList; pEntry = pEntry->Flink)
126  {
127  pPrintProvider = CONTAINING_RECORD(pEntry, SPOOLSS_PRINT_PROVIDER, Entry);
128 
129  // Call the EnumPrinters function of this Print Provider.
130  cbNeeded = 0;
131  dwReturned = 0;
132 
133  Ret = pPrintProvider->PrintProvider.fpEnumPrinterDrivers( pName, pEnvironment, Level, pCallBuffer, cbCallBuffer, &cbNeeded, &dwReturned);
134 
135  if ( !Ret )
136  {
137  dwErrorCode = GetLastError();
138  }
139 
140  // Add the returned counts to the total values.
141  *pcbNeeded += cbNeeded;
142  *pcReturned += dwReturned;
143 
144  // Reduce the available buffer size for the next call without risking an underflow.
145  if (cbNeeded < cbCallBuffer)
146  cbCallBuffer -= cbNeeded;
147  else
148  cbCallBuffer = 0;
149 
150  // Advance the buffer if the caller provided it.
151  if (pCallBuffer)
152  pCallBuffer += cbNeeded;
153 
154  // dwErrorCode shall not be overwritten if a previous EnumPrinters call already succeeded.
155  if (dwErrorCode != ERROR_SUCCESS)
156  dwErrorCode = GetLastError();
157  }
158 
159 Cleanup:
160  SetLastError(dwErrorCode);
161  return (dwErrorCode == ERROR_SUCCESS);
162 }
163 
164 BOOL WINAPI
165 GetPrinterDriverW(HANDLE hPrinter, PWSTR pEnvironment, DWORD Level, PBYTE pDriverInfo, DWORD cbBuf, PDWORD pcbNeeded)
166 {
168 
169  // Sanity checks.
170  if (!pHandle)
171  {
173  return FALSE;
174  }
175 
176  return pHandle->pPrintProvider->PrintProvider.fpGetPrinterDriver(pHandle->hPrinter, pEnvironment, Level, pDriverInfo, cbBuf, pcbNeeded);
177 }
178 
179 
180 BOOL WINAPI
182  HANDLE hPrinter,
183  LPWSTR pEnvironment,
184  DWORD Level,
185  LPBYTE pDriverInfo,
186  DWORD cbBuf,
188  DWORD dwClientMajorVersion,
189  DWORD dwClientMinorVersion,
190  PDWORD pdwServerMajorVersion,
191  PDWORD pdwServerMinorVersion )
192 {
194 
195  FIXME("GetPrinterDriverExW(%p, %lu, %lu, %p, %lu, %p, %lu, %lu, %p, %p)\n", hPrinter, pEnvironment, Level, pDriverInfo, cbBuf, pcbNeeded, dwClientMajorVersion, dwClientMinorVersion, pdwServerMajorVersion, pdwServerMinorVersion);
196 
197  // Sanity checks.
198  if (!pHandle)
199  {
201  return FALSE;
202  }
203 
204  if ( cbBuf && !pDriverInfo )
205  {
207  return FALSE;
208  }
209 
210  return pHandle->pPrintProvider->PrintProvider.fpGetPrinterDriverEx(pHandle->hPrinter, pEnvironment, Level, pDriverInfo, cbBuf, pcbNeeded, dwClientMajorVersion, dwClientMinorVersion, pdwServerMajorVersion, pdwServerMinorVersion);
211 }
212 
213 BOOL WINAPI
215 {
216  BOOL bReturnValue;
217  DWORD dwErrorCode = ERROR_INVALID_PRINTER_NAME;
218  PLIST_ENTRY pEntry;
219  PSPOOLSS_PRINT_PROVIDER pPrintProvider;
220 
221  if ( cbBuf && !pDriverDirectory )
222  {
224  return FALSE;
225  }
226 
227  // Loop through all Print Providers.
228  for (pEntry = PrintProviderList.Flink; pEntry != &PrintProviderList; pEntry = pEntry->Flink)
229  {
230  pPrintProvider = CONTAINING_RECORD(pEntry, SPOOLSS_PRINT_PROVIDER, Entry);
231 
232  bReturnValue = pPrintProvider->PrintProvider.fpGetPrinterDriverDirectory(pName, pEnvironment, Level, pDriverDirectory, cbBuf, pcbNeeded);
233 
234  if (bReturnValue == ROUTER_SUCCESS)
235  {
236  dwErrorCode = ERROR_SUCCESS;
237  goto Cleanup;
238  }
239  else if (bReturnValue == ROUTER_STOP_ROUTING)
240  {
241  ERR("A Print Provider returned ROUTER_STOP_ROUTING for Printer \"%S\"!\n", pName);
242  dwErrorCode = GetLastError();
243  goto Cleanup;
244  }
245  }
246 
247 Cleanup:
248  // ERROR_INVALID_NAME by the Print Provider is translated to ERROR_INVALID_PRINTER_NAME here, but not in other APIs as far as I know.
249  if (dwErrorCode == ERROR_INVALID_NAME)
250  dwErrorCode = ERROR_INVALID_PRINTER_NAME;
251 
252  SetLastError(dwErrorCode);
253  return (dwErrorCode == ERROR_SUCCESS);
254 }
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define ERROR_SUCCESS
Definition: deptool.c:10
BOOL WINAPI GetPrinterDriverDirectoryW(PWSTR pName, PWSTR pEnvironment, DWORD Level, PBYTE pDriverDirectory, DWORD cbBuf, PDWORD pcbNeeded)
uint16_t * PWSTR
Definition: typedefs.h:56
#define ROUTER_SUCCESS
Definition: winsplp.h:41
BOOL WINAPI GetPrinterDriverExW(HANDLE hPrinter, LPWSTR pEnvironment, DWORD Level, LPBYTE pDriverInfo, DWORD cbBuf, LPDWORD pcbNeeded, DWORD dwClientMajorVersion, DWORD dwClientMinorVersion, PDWORD pdwServerMajorVersion, PDWORD pdwServerMinorVersion)
BOOL WINAPI AddPrinterDriverExW(PWSTR pName, DWORD Level, PBYTE pDriverInfo, DWORD dwFileCopyFlags)
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1044
_IRQL_requires_same_ typedef _In_ ULONG _In_ UCHAR Level
Definition: wmitypes.h:55
struct _SPOOLSS_PRINTER_HANDLE * PSPOOLSS_PRINTER_HANDLE
BOOL WINAPI DeletePrinterDriverW(PWSTR pName, PWSTR pEnvironment, PWSTR pDriverName)
#define ERROR_INVALID_USER_BUFFER
Definition: winerror.h:1091
unsigned char * LPBYTE
Definition: typedefs.h:53
#define FALSE
Definition: types.h:117
unsigned int BOOL
Definition: ntddk_ex.h:94
#define APD_COPY_NEW_FILES
Definition: winspool.h:606
#define FIXME(fmt,...)
Definition: debug.h:111
#define ROUTER_STOP_ROUTING
Definition: winsplp.h:42
BOOL WINAPI AddPrinterDriverW(PWSTR pName, DWORD Level, PBYTE pDriverInfo)
#define MAXDWORD
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define TRACE(s)
Definition: solgame.cpp:4
static LPSTR pName
Definition: security.c:75
#define WINAPI
Definition: msvc.h:6
LIST_ENTRY PrintProviderList
Definition: main.c:12
unsigned long DWORD
Definition: ntddk_ex.h:95
#define SetLastError(x)
Definition: compat.h:500
BOOL WINAPI DeletePrinterDriverExW(PWSTR pName, PWSTR pEnvironment, PWSTR pDriverName, DWORD dwDeleteFlag, DWORD dwVersionFlag)
Definition: typedefs.h:119
static const WCHAR Cleanup[]
Definition: register.c:80
#define ERROR_INVALID_PRINTER_NAME
Definition: winerror.h:1108
#define ERR(fmt,...)
Definition: debug.h:110
_In_ DWORD _Out_ PDWORD pcbNeeded
Definition: winddi.h:3827
DWORD * PDWORD
Definition: pedump.c:68
uint32_t * LPDWORD
Definition: typedefs.h:59
BOOL WINAPI EnumPrinterDriversW(PWSTR pName, PWSTR pEnvironment, DWORD Level, PBYTE pDriverInfo, DWORD cbBuf, PDWORD pcbNeeded, PDWORD pcReturned)
#define ERROR_INVALID_NAME
Definition: compat.h:103
PRINTPROVIDOR PrintProvider
Definition: precomp.h:36
WCHAR * LPWSTR
Definition: xmlstorage.h:184
BOOL WINAPI GetPrinterDriverW(HANDLE hPrinter, PWSTR pEnvironment, DWORD Level, PBYTE pDriverInfo, DWORD cbBuf, PDWORD pcbNeeded)
BYTE * PBYTE
Definition: pedump.c:66
base of all file and directory entries
Definition: entries.h:82
PSPOOLSS_PRINT_PROVIDER pPrintProvider
Definition: precomp.h:46