ReactOS  0.4.15-dev-3453-gff89651
printprocessors.c File Reference
#include "precomp.h"
Include dependency graph for printprocessors.c:

Go to the source code of this file.

Functions

_OpenEnvironment

Checks a supplied pEnvironment variable for validity and opens its registry key.

Parameters
pEnvironmentThe pEnvironment variable to check.
hKeyOn success, this variable will contain a HKEY to the opened registry key of the environment. You can use it for further tasks and have to close it with RegCloseKey.
Returns
A Windows Error Code indicating success or failure.
static DWORD _OpenEnvironment (PCWSTR pEnvironment, PHKEY hKey)
 
BOOL FindDatatype (const PLOCAL_PRINT_PROCESSOR pPrintProcessor, PCWSTR pwszDatatype)
 
PLOCAL_PRINT_PROCESSOR FindPrintProcessor (PCWSTR pwszName)
 
InitializePrintProcessorList

Initializes a singly linked list of locally available Print Processors.

BOOL InitializePrintProcessorList (void)
 
LocalEnumPrintProcessorDatatypes

Obtains an array of all datatypes supported by a particular Print Processor. Print Provider function for EnumPrintProcessorDatatypesA/EnumPrintProcessorDatatypesW.

Parameters
pNameServer Name. Ignored here, because every caller of LocalEnumPrintProcessorDatatypes is interested in the local directory.
pPrintProcessorNameThe (case-insensitive) name of the Print Processor to query.
LevelThe level of the structure supplied through pDatatypes. This must be 1.
pDatatypesPointer to the buffer that receives an array of DATATYPES_INFO_1W structures. Can be NULL if you just want to know the required size of the buffer.
cbBufSize of the buffer you supplied for pDatatypes, in bytes.
pcbNeededPointer to a variable that receives the required size of the buffer for pDatatypes, in bytes. This parameter mustn't be NULL!
pcReturnedPointer to a variable that receives the number of elements of the DATATYPES_INFO_1W array. This parameter mustn't be NULL!
Returns
TRUE if we successfully copied the array into pDatatypes, FALSE otherwise. A more specific error code can be obtained through GetLastError.
BOOL WINAPI LocalEnumPrintProcessorDatatypes (LPWSTR pName, LPWSTR pPrintProcessorName, DWORD Level, LPBYTE pDatatypes, DWORD cbBuf, LPDWORD pcbNeeded, LPDWORD pcReturned)
 
LocalEnumPrintProcessors

Obtains an array of all available Print Processors on this computer. Print Provider function for EnumPrintProcessorsA/EnumPrintProcessorsW.

Parameters
pNameServer Name. Ignored here, because every caller of LocalEnumPrintProcessors is interested in the local directory.
pEnvironmentOne of the predefined operating system and architecture "environment" strings (like "Windows NT x86"). Alternatively, NULL to output the Print Processor directory of the current environment.
LevelThe level of the structure supplied through pPrintProcessorInfo. This must be 1.
pPrintProcessorInfoPointer to the buffer that receives an array of PRINTPROCESSOR_INFO_1W structures. Can be NULL if you just want to know the required size of the buffer.
cbBufSize of the buffer you supplied for pPrintProcessorInfo, in bytes.
pcbNeededPointer to a variable that receives the required size of the buffer for pPrintProcessorInfo, in bytes. This parameter mustn't be NULL!
pcReturnedPointer to a variable that receives the number of elements of the PRINTPROCESSOR_INFO_1W array. This parameter mustn't be NULL!
Returns
TRUE if we successfully copied the array into pPrintProcessorInfo, FALSE otherwise. A more specific error code can be obtained through GetLastError.
BOOL WINAPI LocalEnumPrintProcessors (LPWSTR pName, LPWSTR pEnvironment, DWORD Level, LPBYTE pPrintProcessorInfo, DWORD cbBuf, LPDWORD pcbNeeded, LPDWORD pcReturned)
 
LocalGetPrintProcessorDirectory

Obtains the path to the local Print Processor directory. Print Provider function for GetPrintProcessorDirectoryA/GetPrintProcessorDirectoryW.

Parameters
pNameServer Name. Ignored here, because every caller of LocalGetPrintProcessorDirectory is interested in the local directory.
pEnvironmentOne of the predefined operating system and architecture "environment" strings (like "Windows NT x86").
LevelThe level of the (non-existing) structure supplied through pPrintProcessorInfo. This must be 1.
pPrintProcessorInfoPointer to the buffer that receives the full path to the Print Processor directory. Can be NULL if you just want to know the required size of the buffer.
cbBufSize of the buffer you supplied for pPrintProcessorInfo, in bytes.
pcbNeededPointer to a variable that receives the required size of the buffer for pPrintProcessorInfo, in bytes. This parameter mustn't be NULL!
Returns
TRUE if we successfully copied the directory into pPrintProcessorInfo, FALSE otherwise. A more specific error code can be obtained through GetLastError.
BOOL WINAPI LocalGetPrintProcessorDirectory (PWSTR pName, PWSTR pEnvironment, DWORD Level, PBYTE pPrintProcessorInfo, DWORD cbBuf, PDWORD pcbNeeded)
 

Variables

static LIST_ENTRY _PrintProcessorList
 

Function Documentation

◆ _OpenEnvironment()

static DWORD _OpenEnvironment ( PCWSTR  pEnvironment,
PHKEY  hKey 
)
static

Definition at line 30 of file printprocessors.c.

31 {
32  const WCHAR wszEnvironmentsKey[] = L"SYSTEM\\CurrentControlSet\\Control\\Print\\Environments\\";
33  const DWORD cchEnvironmentsKey = _countof(wszEnvironmentsKey) - 1;
34 
35  DWORD cchEnvironment;
36  DWORD dwErrorCode;
37  PWSTR pwszEnvironmentKey = NULL;
38 
39  // Sanity checks
40  if (!pEnvironment)
41  {
42  dwErrorCode = ERROR_INVALID_ENVIRONMENT;
43  goto Cleanup;
44  }
45 
46  // Construct the registry key of the demanded environment.
47  cchEnvironment = wcslen(pEnvironment);
48  pwszEnvironmentKey = DllAllocSplMem((cchEnvironmentsKey + cchEnvironment + 1) * sizeof(WCHAR));
49  if (!pwszEnvironmentKey)
50  {
51  dwErrorCode = ERROR_NOT_ENOUGH_MEMORY;
52  ERR("DllAllocSplMem failed!\n");
53  goto Cleanup;
54  }
55 
56  CopyMemory(pwszEnvironmentKey, wszEnvironmentsKey, cchEnvironmentsKey * sizeof(WCHAR));
57  CopyMemory(&pwszEnvironmentKey[cchEnvironmentsKey], pEnvironment, (cchEnvironment + 1) * sizeof(WCHAR));
58 
59  // Open the registry key.
60  dwErrorCode = (DWORD)RegOpenKeyExW(HKEY_LOCAL_MACHINE, pwszEnvironmentKey, 0, KEY_READ, hKey);
61  if (dwErrorCode == ERROR_FILE_NOT_FOUND)
62  {
63  dwErrorCode = ERROR_INVALID_ENVIRONMENT;
64  goto Cleanup;
65  }
66  else if (dwErrorCode != ERROR_SUCCESS)
67  {
68  ERR("RegOpenKeyExW failed with status %lu!\n", dwErrorCode);
69  goto Cleanup;
70  }
71 
72 Cleanup:
73  if (pwszEnvironmentKey)
74  DllFreeSplMem(pwszEnvironmentKey);
75 
76  return dwErrorCode;
77 }
#define ERROR_SUCCESS
Definition: deptool.c:10
#define KEY_READ
Definition: nt_native.h:1023
uint16_t * PWSTR
Definition: typedefs.h:56
BOOL WINAPI DllFreeSplMem(PVOID pMem)
Definition: memory.c:112
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
#define DWORD
Definition: nt_native.h:44
#define L(x)
Definition: ntvdm.h:50
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define _countof(array)
Definition: sndvol32.h:68
#define CopyMemory
Definition: winbase.h:1662
unsigned long DWORD
Definition: ntddk_ex.h:95
static const WCHAR Cleanup[]
Definition: register.c:80
#define ERR(fmt,...)
Definition: debug.h:110
FxAutoRegKey hKey
#define NULL
Definition: types.h:112
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3356
PVOID WINAPI DllAllocSplMem(DWORD dwBytes)
Definition: memory.c:95
#define ERROR_INVALID_ENVIRONMENT
Definition: winerror.h:1112
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12

Referenced by InitializePrintProcessorList(), LocalEnumPrintProcessors(), and LocalGetPrintProcessorDirectory().

◆ FindDatatype()

BOOL FindDatatype ( const PLOCAL_PRINT_PROCESSOR  pPrintProcessor,
PCWSTR  pwszDatatype 
)

Definition at line 80 of file printprocessors.c.

81 {
82  DWORD i;
83  PDATATYPES_INFO_1W pCurrentDatatype = pPrintProcessor->pDatatypesInfo1;
84 
85  TRACE("FindDatatype(%p, %S)\n", pPrintProcessor, pwszDatatype);
86 
87  if (!pwszDatatype)
88  return FALSE;
89 
90  for (i = 0; i < pPrintProcessor->dwDatatypeCount; i++)
91  {
92  if (wcsicmp(pCurrentDatatype->pName, pwszDatatype) == 0)
93  return TRUE;
94 
95  ++pCurrentDatatype;
96  }
97 
98  return FALSE;
99 }
PDATATYPES_INFO_1W pDatatypesInfo1
Definition: precomp.h:102
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define TRACE(s)
Definition: solgame.cpp:4
unsigned long DWORD
Definition: ntddk_ex.h:95
#define wcsicmp
Definition: compat.h:15
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248

Referenced by _LocalOpenPrinterHandle(), _LocalSetJobLevel1(), _LocalSetJobLevel2(), InitializePrinterList(), and LocalStartDocPrinter().

◆ FindPrintProcessor()

PLOCAL_PRINT_PROCESSOR FindPrintProcessor ( PCWSTR  pwszName)

Definition at line 102 of file printprocessors.c.

103 {
105  PLOCAL_PRINT_PROCESSOR pPrintProcessor;
106 
107  TRACE("FindPrintProcessor(%S)\n", pwszName);
108 
109  if (!pwszName)
110  return NULL;
111 
113  {
115 
116  if (wcsicmp(pPrintProcessor->pwszName, pwszName) == 0)
117  return pPrintProcessor;
118  }
119 
120  return NULL;
121 }
static LIST_ENTRY _PrintProcessorList
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
#define wcsicmp
Definition: compat.h:15
Definition: typedefs.h:119
#define NULL
Definition: types.h:112
PLIST_ENTRY pEntry
Definition: fxioqueue.cpp:4484
base of all file and directory entries
Definition: entries.h:82

Referenced by _LocalSetJobLevel2(), InitializePrinterList(), LocalEnumPrintProcessorDatatypes(), and ReadJobShadowFile().

◆ InitializePrintProcessorList()

BOOL InitializePrintProcessorList ( void  )

Definition at line 129 of file printprocessors.c.

130 {
131  DWORD cbDatatypes;
132  DWORD cbFileName;
133  DWORD cchPrintProcessorPath;
134  DWORD cchMaxSubKey;
135  DWORD cchPrintProcessorName;
136  DWORD dwErrorCode;
137  DWORD dwSubKeys;
138  DWORD i;
139  HINSTANCE hinstPrintProcessor;
140  HKEY hKey = NULL;
141  HKEY hSubKey = NULL;
142  HKEY hSubSubKey = NULL;
143  PLOCAL_PRINT_PROCESSOR pPrintProcessor = NULL;
145  WCHAR wszPrintProcessorPath[MAX_PATH];
146 
147  TRACE("InitializePrintProcessorList()\n");
148 
149  // Initialize an empty list for our Print Processors.
151 
152  // Prepare the path to the Print Processor directory.
153  if (!LocalGetPrintProcessorDirectory(NULL, (PWSTR)wszCurrentEnvironment, 1, (PBYTE)wszPrintProcessorPath, sizeof(wszPrintProcessorPath), &cchPrintProcessorPath))
154  {
155  dwErrorCode = GetLastError();
156  goto Cleanup;
157  }
158 
159  // LocalGetPrintProcessorDirectory returns the number of copied bytes. Convert this into a number of characters without the terminating null-character.
160  cchPrintProcessorPath /= sizeof(WCHAR);
161  --cchPrintProcessorPath;
162 
163  // Append a trailing backslash.
164  wszPrintProcessorPath[cchPrintProcessorPath] = L'\\';
165  ++cchPrintProcessorPath;
166 
167  // Open the environment registry key.
169  if (dwErrorCode != ERROR_SUCCESS)
170  goto Cleanup;
171 
172  // Open the "Print Processors" subkey.
173  dwErrorCode = (DWORD)RegOpenKeyExW(hKey, L"Print Processors", 0, KEY_READ, &hSubKey);
174  if (dwErrorCode != ERROR_SUCCESS)
175  {
176  ERR("RegOpenKeyExW failed with status %lu!\n", dwErrorCode);
177  goto Cleanup;
178  }
179 
180  // Get the number of Print Processors and maximum sub key length.
181  dwErrorCode = (DWORD)RegQueryInfoKeyW(hSubKey, NULL, NULL, NULL, &dwSubKeys, &cchMaxSubKey, NULL, NULL, NULL, NULL, NULL, NULL);
182  if (dwErrorCode != ERROR_SUCCESS)
183  {
184  ERR("RegQueryInfoKeyW failed with status %lu!\n", dwErrorCode);
185  goto Cleanup;
186  }
187 
188  // Loop through all available local Print Processors.
189  for (i = 0; i < dwSubKeys; i++)
190  {
191  // Cleanup tasks from the previous run
192  if (hSubSubKey)
193  {
194  RegCloseKey(hSubSubKey);
195  hSubSubKey = NULL;
196  }
197 
198  if (pPrintProcessor)
199  {
200  if (pPrintProcessor->pwszName)
201  DllFreeSplStr(pPrintProcessor->pwszName);
202 
203  if (pPrintProcessor->pDatatypesInfo1)
204  DllFreeSplMem(pPrintProcessor->pDatatypesInfo1);
205 
206  DllFreeSplMem(pPrintProcessor);
207  pPrintProcessor = NULL;
208  }
209 
210  // Create a new LOCAL_PRINT_PROCESSOR structure for it.
211  pPrintProcessor = DllAllocSplMem(sizeof(LOCAL_PRINT_PROCESSOR));
212  if (!pPrintProcessor)
213  {
214  dwErrorCode = ERROR_NOT_ENOUGH_MEMORY;
215  ERR("DllAllocSplMem failed!\n");
216  goto Cleanup;
217  }
218 
219  // Allocate memory for the Print Monitor Name.
220  pPrintProcessor->pwszName = DllAllocSplMem((cchMaxSubKey + 1) * sizeof(WCHAR));
221  if (!pPrintProcessor->pwszName)
222  {
223  dwErrorCode = ERROR_NOT_ENOUGH_MEMORY;
224  ERR("DllAllocSplMem failed!\n");
225  goto Cleanup;
226  }
227 
228  // Get the name of this Print Processor.
229  cchPrintProcessorName = cchMaxSubKey + 1;
230  dwErrorCode = (DWORD)RegEnumKeyExW(hSubKey, i, pPrintProcessor->pwszName, &cchPrintProcessorName, NULL, NULL, NULL, NULL);
231  if (dwErrorCode != ERROR_SUCCESS)
232  {
233  ERR("RegEnumKeyExW failed with status %ld!\n", dwErrorCode);
234  continue;
235  }
236 
237  // Open this Print Processor's registry key.
238  dwErrorCode = (DWORD)RegOpenKeyExW(hSubKey, pPrintProcessor->pwszName, 0, KEY_READ, &hSubSubKey);
239  if (dwErrorCode != ERROR_SUCCESS)
240  {
241  ERR("RegOpenKeyExW failed for Print Processor \"%S\" with status %lu!\n", pPrintProcessor->pwszName, dwErrorCode);
242  continue;
243  }
244 
245  // Get the file name of the Print Processor.
246  cbFileName = sizeof(wszFileName);
247  dwErrorCode = (DWORD)RegQueryValueExW(hSubSubKey, L"Driver", NULL, NULL, (PBYTE)wszFileName, &cbFileName);
248  if (dwErrorCode != ERROR_SUCCESS)
249  {
250  ERR("RegQueryValueExW failed for Print Processor \"%S\" with status %lu!\n", pPrintProcessor->pwszName, dwErrorCode);
251  continue;
252  }
253 
254  // Verify that our buffer is large enough.
255  if (cchPrintProcessorPath + cbFileName / sizeof(WCHAR) > MAX_PATH)
256  {
257  ERR("Print Processor directory \"%S\" for Print Processor \"%S\" is too long!\n", wszFileName, pPrintProcessor->pwszName);
258  continue;
259  }
260 
261  // Construct the full path to the Print Processor.
262  CopyMemory(&wszPrintProcessorPath[cchPrintProcessorPath], wszFileName, cbFileName);
263 
264  // Try to load it.
265  hinstPrintProcessor = LoadLibraryW(wszPrintProcessorPath);
266  if (!hinstPrintProcessor)
267  {
268  ERR("LoadLibraryW failed for \"%S\" with error %lu!\n", wszPrintProcessorPath, GetLastError());
269  continue;
270  }
271 
272  // Get and verify all its function pointers.
273  pPrintProcessor->pfnClosePrintProcessor = (PClosePrintProcessor)GetProcAddress(hinstPrintProcessor, "ClosePrintProcessor");
274  if (!pPrintProcessor->pfnClosePrintProcessor)
275  {
276  ERR("Print Processor \"%S\" exports no ClosePrintProcessor!\n", wszPrintProcessorPath);
277  continue;
278  }
279 
280  pPrintProcessor->pfnControlPrintProcessor = (PControlPrintProcessor)GetProcAddress(hinstPrintProcessor, "ControlPrintProcessor");
281  if (!pPrintProcessor->pfnControlPrintProcessor)
282  {
283  ERR("Print Processor \"%S\" exports no ControlPrintProcessor!\n", wszPrintProcessorPath);
284  continue;
285  }
286 
287  pPrintProcessor->pfnEnumPrintProcessorDatatypesW = (PEnumPrintProcessorDatatypesW)GetProcAddress(hinstPrintProcessor, "EnumPrintProcessorDatatypesW");
288  if (!pPrintProcessor->pfnEnumPrintProcessorDatatypesW)
289  {
290  ERR("Print Processor \"%S\" exports no EnumPrintProcessorDatatypesW!\n", wszPrintProcessorPath);
291  continue;
292  }
293 
294  pPrintProcessor->pfnGetPrintProcessorCapabilities = (PGetPrintProcessorCapabilities)GetProcAddress(hinstPrintProcessor, "GetPrintProcessorCapabilities");
295  if (!pPrintProcessor->pfnGetPrintProcessorCapabilities)
296  {
297  ERR("Print Processor \"%S\" exports no GetPrintProcessorCapabilities!\n", wszPrintProcessorPath);
298  continue;
299  }
300 
301  pPrintProcessor->pfnOpenPrintProcessor = (POpenPrintProcessor)GetProcAddress(hinstPrintProcessor, "OpenPrintProcessor");
302  if (!pPrintProcessor->pfnOpenPrintProcessor)
303  {
304  ERR("Print Processor \"%S\" exports no OpenPrintProcessor!\n", wszPrintProcessorPath);
305  continue;
306  }
307 
308  pPrintProcessor->pfnPrintDocumentOnPrintProcessor = (PPrintDocumentOnPrintProcessor)GetProcAddress(hinstPrintProcessor, "PrintDocumentOnPrintProcessor");
309  if (!pPrintProcessor->pfnPrintDocumentOnPrintProcessor)
310  {
311  ERR("Print Processor \"%S\" exports no PrintDocumentOnPrintProcessor!\n", wszPrintProcessorPath);
312  continue;
313  }
314 
315  // Get all supported datatypes.
316  pPrintProcessor->pfnEnumPrintProcessorDatatypesW(NULL, NULL, 1, NULL, 0, &cbDatatypes, &pPrintProcessor->dwDatatypeCount);
317  pPrintProcessor->pDatatypesInfo1 = DllAllocSplMem(cbDatatypes);
318  if (!pPrintProcessor->pDatatypesInfo1)
319  {
320  dwErrorCode = ERROR_NOT_ENOUGH_MEMORY;
321  ERR("DllAllocSplMem failed!\n");
322  goto Cleanup;
323  }
324 
325  if (!pPrintProcessor->pfnEnumPrintProcessorDatatypesW(NULL, NULL, 1, (PBYTE)pPrintProcessor->pDatatypesInfo1, cbDatatypes, &cbDatatypes, &pPrintProcessor->dwDatatypeCount))
326  {
327  ERR("EnumPrintProcessorDatatypesW failed for Print Processor \"%S\" with error %lu!\n", wszPrintProcessorPath, GetLastError());
328  continue;
329  }
330 
331  // Add the Print Processor to the list.
332  InsertTailList(&_PrintProcessorList, &pPrintProcessor->Entry);
333 
334  // Don't let the cleanup routines free this.
335  pPrintProcessor = NULL;
336  }
337 
338  dwErrorCode = ERROR_SUCCESS;
339 
340 Cleanup:
341  // Inside the loop
342  if (hSubSubKey)
343  RegCloseKey(hSubSubKey);
344 
345  if (pPrintProcessor)
346  {
347  if (pPrintProcessor->pwszName)
348  DllFreeSplStr(pPrintProcessor->pwszName);
349 
350  if (pPrintProcessor->pDatatypesInfo1)
351  DllFreeSplMem(pPrintProcessor->pDatatypesInfo1);
352 
353  DllFreeSplMem(pPrintProcessor);
354  }
355 
356  // Outside the loop
357  if (hSubKey)
358  RegCloseKey(hSubKey);
359 
360  if (hKey)
361  RegCloseKey(hKey);
362 
363  SetLastError(dwErrorCode);
364  return (dwErrorCode == ERROR_SUCCESS);
365 }
static WCHAR wszFileName[MAX_PATH]
Definition: wordpad.c:71
#define ERROR_SUCCESS
Definition: deptool.c:10
PDATATYPES_INFO_1W pDatatypesInfo1
Definition: precomp.h:102
PEnumPrintProcessorDatatypesW pfnEnumPrintProcessorDatatypesW
Definition: precomp.h:106
PPrintDocumentOnPrintProcessor pfnPrintDocumentOnPrintProcessor
Definition: precomp.h:109
#define KEY_READ
Definition: nt_native.h:1023
uint16_t * PWSTR
Definition: typedefs.h:56
BOOL WINAPI DllFreeSplMem(PVOID pMem)
Definition: memory.c:112
static LIST_ENTRY _PrintProcessorList
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1040
static DWORD _OpenEnvironment(PCWSTR pEnvironment, PHKEY hKey)
#define InsertTailList(ListHead, Entry)
#define DWORD
Definition: nt_native.h:44
DWORD(WINAPI * PGetPrintProcessorCapabilities)(LPWSTR, DWORD, LPBYTE, DWORD, LPDWORD)
Definition: precomp.h:48
const WCHAR wszCurrentEnvironment[]
Definition: prtprocenv.h:11
#define L(x)
Definition: ntvdm.h:50
BOOL WINAPI LocalGetPrintProcessorDirectory(PWSTR pName, PWSTR pEnvironment, DWORD Level, PBYTE pPrintProcessorInfo, DWORD cbBuf, PDWORD pcbNeeded)
#define LoadLibraryW(x)
Definition: compat.h:606
#define TRACE(s)
Definition: solgame.cpp:4
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4120
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define MAX_PATH
Definition: compat.h:34
#define CopyMemory
Definition: winbase.h:1662
unsigned long DWORD
Definition: ntddk_ex.h:95
#define SetLastError(x)
Definition: compat.h:611
LONG WINAPI RegQueryInfoKeyW(HKEY hKey, LPWSTR lpClass, LPDWORD lpcClass, LPDWORD lpReserved, LPDWORD lpcSubKeys, LPDWORD lpcMaxSubKeyLen, LPDWORD lpcMaxClassLen, LPDWORD lpcValues, LPDWORD lpcMaxValueNameLen, LPDWORD lpcMaxValueLen, LPDWORD lpcbSecurityDescriptor, PFILETIME lpftLastWriteTime)
Definition: reg.c:3690
LIST_ENTRY Entry
Definition: precomp.h:100
PClosePrintProcessor pfnClosePrintProcessor
Definition: precomp.h:104
static const WCHAR Cleanup[]
Definition: register.c:80
BOOL(WINAPI * PEnumPrintProcessorDatatypesW)(LPWSTR, LPWSTR, DWORD, LPBYTE, DWORD, LPDWORD, LPDWORD)
BOOL(WINAPI * PControlPrintProcessor)(HANDLE, DWORD)
Definition: precomp.h:46
#define ERR(fmt,...)
Definition: debug.h:110
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
FxAutoRegKey hKey
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
PGetPrintProcessorCapabilities pfnGetPrintProcessorCapabilities
Definition: precomp.h:107
BOOL(WINAPI * PPrintDocumentOnPrintProcessor)(HANDLE, LPWSTR)
Definition: precomp.h:50
#define NULL
Definition: types.h:112
BOOL WINAPI DllFreeSplStr(PWSTR pwszString)
Definition: memory.c:130
HANDLE(WINAPI * POpenPrintProcessor)(LPWSTR, PPRINTPROCESSOROPENDATA)
Definition: precomp.h:49
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3356
#define GetProcAddress(x, y)
Definition: compat.h:612
LONG WINAPI RegEnumKeyExW(_In_ HKEY hKey, _In_ DWORD dwIndex, _Out_ LPWSTR lpName, _Inout_ LPDWORD lpcbName, _Reserved_ LPDWORD lpReserved, _Out_opt_ LPWSTR lpClass, _Inout_opt_ LPDWORD lpcbClass, _Out_opt_ PFILETIME lpftLastWriteTime)
Definition: reg.c:2527
PVOID WINAPI DllAllocSplMem(DWORD dwBytes)
Definition: memory.c:95
POpenPrintProcessor pfnOpenPrintProcessor
Definition: precomp.h:108
PControlPrintProcessor pfnControlPrintProcessor
Definition: precomp.h:105
BYTE * PBYTE
Definition: pedump.c:66
BOOL(WINAPI * PClosePrintProcessor)(HANDLE)
Definition: precomp.h:45
#define RegCloseKey(hKey)
Definition: registry.h:40

Referenced by _InitializeLocalSpooler().

◆ LocalEnumPrintProcessorDatatypes()

BOOL WINAPI LocalEnumPrintProcessorDatatypes ( LPWSTR  pName,
LPWSTR  pPrintProcessorName,
DWORD  Level,
LPBYTE  pDatatypes,
DWORD  cbBuf,
LPDWORD  pcbNeeded,
LPDWORD  pcReturned 
)

Definition at line 402 of file printprocessors.c.

403 {
404  DWORD dwErrorCode;
405  PLOCAL_PRINT_PROCESSOR pPrintProcessor;
406 
407  TRACE("LocalEnumPrintProcessorDatatypes(%S, %S, %lu, %p, %lu, %p, %p)\n", pName, pPrintProcessorName, Level, pDatatypes, cbBuf, pcbNeeded, pcReturned);
408 
409  // Sanity checks
410  if (Level != 1)
411  {
412  dwErrorCode = ERROR_INVALID_LEVEL;
413  goto Cleanup;
414  }
415 
416  // Try to find the Print Processor.
417  pPrintProcessor = FindPrintProcessor(pPrintProcessorName);
418  if (!pPrintProcessor)
419  {
420  dwErrorCode = ERROR_UNKNOWN_PRINTPROCESSOR;
421  goto Cleanup;
422  }
423 
424  // Call its EnumPrintProcessorDatatypesW function.
425  if (pPrintProcessor->pfnEnumPrintProcessorDatatypesW(pName, pPrintProcessorName, Level, pDatatypes, cbBuf, pcbNeeded, pcReturned))
426  dwErrorCode = ERROR_SUCCESS;
427  else
428  dwErrorCode = GetLastError();
429 
430 Cleanup:
431  SetLastError(dwErrorCode);
432  return (dwErrorCode == ERROR_SUCCESS);
433 }
#define ERROR_SUCCESS
Definition: deptool.c:10
PEnumPrintProcessorDatatypesW pfnEnumPrintProcessorDatatypesW
Definition: precomp.h:106
PLOCAL_PRINT_PROCESSOR FindPrintProcessor(PCWSTR pwszName)
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1040
_IRQL_requires_same_ typedef _In_ ULONG _In_ UCHAR Level
Definition: wmitypes.h:55
#define TRACE(s)
Definition: solgame.cpp:4
static LPSTR pName
Definition: security.c:75
unsigned long DWORD
Definition: ntddk_ex.h:95
#define SetLastError(x)
Definition: compat.h:611
static const WCHAR Cleanup[]
Definition: register.c:80
#define ERROR_UNKNOWN_PRINTPROCESSOR
Definition: winerror.h:1105
_In_ DWORD _Out_ PDWORD pcbNeeded
Definition: winddi.h:3827
#define ERROR_INVALID_LEVEL
Definition: winerror.h:196

◆ LocalEnumPrintProcessors()

BOOL WINAPI LocalEnumPrintProcessors ( LPWSTR  pName,
LPWSTR  pEnvironment,
DWORD  Level,
LPBYTE  pPrintProcessorInfo,
DWORD  cbBuf,
LPDWORD  pcbNeeded,
LPDWORD  pcReturned 
)

Definition at line 471 of file printprocessors.c.

472 {
473  DWORD cchMaxSubKey;
474  DWORD cchPrintProcessor;
475  DWORD dwErrorCode;
476  DWORD dwPrintProcessorCount;
477  DWORD i;
478  HKEY hKey = NULL;
479  HKEY hSubKey = NULL;
480  PBYTE pCurrentOutputPrintProcessor;
481  PBYTE pCurrentOutputPrintProcessorInfo;
482  PRINTPROCESSOR_INFO_1W PrintProcessorInfo1;
483  PWSTR pwszTemp = NULL;
484 
485  TRACE("LocalEnumPrintProcessors(%S, %S, %lu, %p, %lu, %p, %p)\n", pName, pEnvironment, Level, pPrintProcessorInfo, cbBuf, pcbNeeded, pcReturned);
486 
487  // Sanity checks
488  if (Level != 1)
489  {
490  dwErrorCode = ERROR_INVALID_LEVEL;
491  goto Cleanup;
492  }
493 
494  if (!pcbNeeded || !pcReturned)
495  {
496  // This error is also caught by RPC and returned as RPC_X_NULL_REF_POINTER.
497  dwErrorCode = ERROR_INVALID_PARAMETER;
498  goto Cleanup;
499  }
500 
501  // Verify pEnvironment and open its registry key.
502  // We use the registry and not the PrintProcessorList here, because the caller may request information about a different environment.
503  dwErrorCode = _OpenEnvironment(pEnvironment, &hKey);
504  if (dwErrorCode != ERROR_SUCCESS)
505  goto Cleanup;
506 
507  // Open the "Print Processors" subkey.
508  dwErrorCode = (DWORD)RegOpenKeyExW(hKey, L"Print Processors", 0, KEY_READ, &hSubKey);
509  if (dwErrorCode != ERROR_SUCCESS)
510  {
511  ERR("RegOpenKeyExW failed with status %lu!\n", dwErrorCode);
512  goto Cleanup;
513  }
514 
515  // Get the number of Print Processors and maximum sub key length.
516  dwErrorCode = (DWORD)RegQueryInfoKeyW(hSubKey, NULL, NULL, NULL, &dwPrintProcessorCount, &cchMaxSubKey, NULL, NULL, NULL, NULL, NULL, NULL);
517  if (dwErrorCode != ERROR_SUCCESS)
518  {
519  ERR("RegQueryInfoKeyW failed with status %lu!\n", dwErrorCode);
520  goto Cleanup;
521  }
522 
523  // Allocate a temporary buffer to let RegEnumKeyExW succeed.
524  pwszTemp = DllAllocSplMem((cchMaxSubKey + 1) * sizeof(WCHAR));
525  if (!pwszTemp)
526  {
527  dwErrorCode = ERROR_NOT_ENOUGH_MEMORY;
528  ERR("DllAllocSplMem failed!\n");
529  goto Cleanup;
530  }
531 
532  // Determine the required size of the output buffer.
533  *pcbNeeded = 0;
534 
535  for (i = 0; i < dwPrintProcessorCount; i++)
536  {
537  // RegEnumKeyExW sucks! Unlike similar API functions, it only returns the actual numbers of characters copied when you supply a buffer large enough.
538  // So use pwszTemp with its size cchMaxSubKey for this.
539  cchPrintProcessor = cchMaxSubKey + 1;
540  dwErrorCode = (DWORD)RegEnumKeyExW(hSubKey, i, pwszTemp, &cchPrintProcessor, NULL, NULL, NULL, NULL);
541  if (dwErrorCode != ERROR_SUCCESS)
542  {
543  ERR("RegEnumKeyExW failed with status %lu!\n", dwErrorCode);
544  goto Cleanup;
545  }
546 
547  *pcbNeeded += sizeof(PRINTPROCESSOR_INFO_1W) + (cchPrintProcessor + 1) * sizeof(WCHAR);
548  }
549 
550  // Check if the supplied buffer is large enough.
551  if (cbBuf < *pcbNeeded)
552  {
553  dwErrorCode = ERROR_INSUFFICIENT_BUFFER;
554  goto Cleanup;
555  }
556 
557  // Put the Print Processor strings right after the last PRINTPROCESSOR_INFO_1W structure.
558  pCurrentOutputPrintProcessorInfo = pPrintProcessorInfo;
559  pCurrentOutputPrintProcessor = pPrintProcessorInfo + dwPrintProcessorCount * sizeof(PRINTPROCESSOR_INFO_1W);
560 
561  // Copy over all Print Processors.
562  for (i = 0; i < dwPrintProcessorCount; i++)
563  {
564  // This isn't really correct, but doesn't cause any harm, because we've extensively checked the size of the supplied buffer above.
565  cchPrintProcessor = cchMaxSubKey + 1;
566 
567  // Copy the Print Processor name.
568  dwErrorCode = (DWORD)RegEnumKeyExW(hSubKey, i, (PWSTR)pCurrentOutputPrintProcessor, &cchPrintProcessor, NULL, NULL, NULL, NULL);
569  if (dwErrorCode != ERROR_SUCCESS)
570  {
571  ERR("RegEnumKeyExW failed with status %lu!\n", dwErrorCode);
572  goto Cleanup;
573  }
574 
575  // Fill and copy the PRINTPROCESSOR_INFO_1W structure belonging to this Print Processor.
576  PrintProcessorInfo1.pName = (PWSTR)pCurrentOutputPrintProcessor;
577  CopyMemory(pCurrentOutputPrintProcessorInfo, &PrintProcessorInfo1, sizeof(PRINTPROCESSOR_INFO_1W));
578 
579  // Advance to the next PRINTPROCESSOR_INFO_1W location and string location in the output buffer.
580  pCurrentOutputPrintProcessor += (cchPrintProcessor + 1) * sizeof(WCHAR);
581  pCurrentOutputPrintProcessorInfo += sizeof(PRINTPROCESSOR_INFO_1W);
582  }
583 
584  // We've finished successfully!
585  *pcReturned = dwPrintProcessorCount;
586  dwErrorCode = ERROR_SUCCESS;
587 
588 Cleanup:
589  if (pwszTemp)
590  DllFreeSplMem(pwszTemp);
591 
592  if (hSubKey)
593  RegCloseKey(hSubKey);
594 
595  if (hKey)
596  RegCloseKey(hKey);
597 
598  SetLastError(dwErrorCode);
599  return (dwErrorCode == ERROR_SUCCESS);
600 }
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define ERROR_SUCCESS
Definition: deptool.c:10
#define KEY_READ
Definition: nt_native.h:1023
uint16_t * PWSTR
Definition: typedefs.h:56
BOOL WINAPI DllFreeSplMem(PVOID pMem)
Definition: memory.c:112
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
static DWORD _OpenEnvironment(PCWSTR pEnvironment, PHKEY hKey)
_IRQL_requires_same_ typedef _In_ ULONG _In_ UCHAR Level
Definition: wmitypes.h:55
#define DWORD
Definition: nt_native.h:44
struct _PRINTPROCESSOR_INFO_1W PRINTPROCESSOR_INFO_1W
#define L(x)
Definition: ntvdm.h:50
#define TRACE(s)
Definition: solgame.cpp:4
static LPSTR pName
Definition: security.c:75
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define CopyMemory
Definition: winbase.h:1662
unsigned long DWORD
Definition: ntddk_ex.h:95
#define SetLastError(x)
Definition: compat.h:611
LONG WINAPI RegQueryInfoKeyW(HKEY hKey, LPWSTR lpClass, LPDWORD lpcClass, LPDWORD lpReserved, LPDWORD lpcSubKeys, LPDWORD lpcMaxSubKeyLen, LPDWORD lpcMaxClassLen, LPDWORD lpcValues, LPDWORD lpcMaxValueNameLen, LPDWORD lpcMaxValueLen, LPDWORD lpcbSecurityDescriptor, PFILETIME lpftLastWriteTime)
Definition: reg.c:3690
static const WCHAR Cleanup[]
Definition: register.c:80
#define ERR(fmt,...)
Definition: debug.h:110
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
_In_ DWORD _Out_ PDWORD pcbNeeded
Definition: winddi.h:3827
FxAutoRegKey hKey
#define NULL
Definition: types.h:112
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3356
LONG WINAPI RegEnumKeyExW(_In_ HKEY hKey, _In_ DWORD dwIndex, _Out_ LPWSTR lpName, _Inout_ LPDWORD lpcbName, _Reserved_ LPDWORD lpReserved, _Out_opt_ LPWSTR lpClass, _Inout_opt_ LPDWORD lpcbClass, _Out_opt_ PFILETIME lpftLastWriteTime)
Definition: reg.c:2527
PVOID WINAPI DllAllocSplMem(DWORD dwBytes)
Definition: memory.c:95
#define ERROR_INVALID_LEVEL
Definition: winerror.h:196
BYTE * PBYTE
Definition: pedump.c:66
#define RegCloseKey(hKey)
Definition: registry.h:40
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10

◆ LocalGetPrintProcessorDirectory()

BOOL WINAPI LocalGetPrintProcessorDirectory ( PWSTR  pName,
PWSTR  pEnvironment,
DWORD  Level,
PBYTE  pPrintProcessorInfo,
DWORD  cbBuf,
PDWORD  pcbNeeded 
)

Definition at line 633 of file printprocessors.c.

634 {
635  const WCHAR wszPath[] = L"\\PRTPROCS\\";
636  const DWORD cchPath = _countof(wszPath) - 1;
637 
638  DWORD cbDirectoryName;
639  DWORD dwErrorCode;
640  HKEY hKey = NULL;
641  PWSTR pwszDirectory = (PWSTR)pPrintProcessorInfo;
642 
643  TRACE("LocalGetPrintProcessorDirectory(%S, %S, %lu, %p, %lu, %p)\n", pName, pEnvironment, Level, pPrintProcessorInfo, cbBuf, pcbNeeded);
644 
645  // Verify pEnvironment and open its registry key.
646  dwErrorCode = _OpenEnvironment(pEnvironment, &hKey);
647  if (dwErrorCode != ERROR_SUCCESS)
648  {
649  ERR("_OpenEnvironment failed with error %lu!\n", dwErrorCode);
650  goto Cleanup;
651  }
652 
653  // Determine the size of the required buffer.
654  dwErrorCode = (DWORD)RegQueryValueExW(hKey, L"Directory", NULL, NULL, NULL, &cbDirectoryName);
655  if (dwErrorCode != ERROR_SUCCESS)
656  {
657  ERR("RegQueryValueExW failed with status %lu!\n", dwErrorCode);
658  goto Cleanup;
659  }
660 
661  *pcbNeeded = (cchSpoolDirectory + cchPath) * sizeof(WCHAR) + cbDirectoryName;
662 
663  // Is the supplied buffer large enough?
664  if (cbBuf < *pcbNeeded)
665  {
666  dwErrorCode = ERROR_INSUFFICIENT_BUFFER;
667  goto Cleanup;
668  }
669 
670  // Copy the path to the "prtprocs" directory into pPrintProcessorInfo
671  CopyMemory(pwszDirectory, wszSpoolDirectory, cchSpoolDirectory * sizeof(WCHAR));
672  CopyMemory(&pwszDirectory[cchSpoolDirectory], wszPath, cchPath * sizeof(WCHAR));
673 
674  // Get the directory name from the registry.
675  dwErrorCode = (DWORD)RegQueryValueExW(hKey, L"Directory", NULL, NULL, (PBYTE)&pwszDirectory[cchSpoolDirectory + cchPath], &cbDirectoryName);
676  if (dwErrorCode != ERROR_SUCCESS)
677  {
678  ERR("RegQueryValueExW failed with status %lu!\n", dwErrorCode);
679  goto Cleanup;
680  }
681 
682  // We've finished successfully!
683  dwErrorCode = ERROR_SUCCESS;
684 
685 Cleanup:
686  if (hKey)
687  RegCloseKey(hKey);
688 
689  SetLastError(dwErrorCode);
690  return (dwErrorCode == ERROR_SUCCESS);
691 }
#define ERROR_SUCCESS
Definition: deptool.c:10
uint16_t * PWSTR
Definition: typedefs.h:56
static DWORD _OpenEnvironment(PCWSTR pEnvironment, PHKEY hKey)
_IRQL_requires_same_ typedef _In_ ULONG _In_ UCHAR Level
Definition: wmitypes.h:55
#define DWORD
Definition: nt_native.h:44
#define L(x)
Definition: ntvdm.h:50
DWORD cchSpoolDirectory
Definition: main.c:16
#define TRACE(s)
Definition: solgame.cpp:4
static LPSTR pName
Definition: security.c:75
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4120
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define _countof(array)
Definition: sndvol32.h:68
#define CopyMemory
Definition: winbase.h:1662
unsigned long DWORD
Definition: ntddk_ex.h:95
#define SetLastError(x)
Definition: compat.h:611
static const WCHAR Cleanup[]
Definition: register.c:80
#define ERR(fmt,...)
Definition: debug.h:110
_In_ DWORD _Out_ PDWORD pcbNeeded
Definition: winddi.h:3827
FxAutoRegKey hKey
#define NULL
Definition: types.h:112
WCHAR wszSpoolDirectory[MAX_PATH]
Definition: main.c:15
BYTE * PBYTE
Definition: pedump.c:66
#define RegCloseKey(hKey)
Definition: registry.h:40
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10

Referenced by InitializePrintProcessorList().

Variable Documentation

◆ _PrintProcessorList

LIST_ENTRY _PrintProcessorList
static

Definition at line 12 of file printprocessors.c.

Referenced by FindPrintProcessor(), and InitializePrintProcessorList().