ReactOS 0.4.15-dev-8219-ge8b88cf
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
73 if (pwszEnvironmentKey)
74 DllFreeSplMem(pwszEnvironmentKey);
75
76 return dwErrorCode;
77}
#define ERR(fmt,...)
Definition: debug.h:113
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3333
static const WCHAR Cleanup[]
Definition: register.c:80
unsigned long DWORD
Definition: ntddk_ex.h:95
FxAutoRegKey hKey
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
#define KEY_READ
Definition: nt_native.h:1023
#define DWORD
Definition: nt_native.h:44
#define L(x)
Definition: ntvdm.h:50
#define _countof(array)
Definition: sndvol32.h:70
uint16_t * PWSTR
Definition: typedefs.h:56
BOOL WINAPI DllFreeSplMem(PVOID pMem)
Definition: memory.c:112
PVOID WINAPI DllAllocSplMem(DWORD dwBytes)
Definition: memory.c:95
#define CopyMemory
Definition: winbase.h:1710
#define ERROR_INVALID_ENVIRONMENT
Definition: winerror.h:1112
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
__wchar_t WCHAR
Definition: xmlstorage.h:180

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}
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#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
#define TRACE(s)
Definition: solgame.cpp:4
PDATATYPES_INFO_1W pDatatypesInfo1
Definition: precomp.h:102

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}
PLIST_ENTRY pEntry
Definition: fxioqueue.cpp:4484
static LIST_ENTRY _PrintProcessorList
base of all file and directory entries
Definition: entries.h:83
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260

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
340Cleanup:
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)
362
363 SetLastError(dwErrorCode);
364 return (dwErrorCode == ERROR_SUCCESS);
365}
BOOL(WINAPI * PEnumPrintProcessorDatatypesW)(LPWSTR, LPWSTR, DWORD, LPBYTE, DWORD, LPDWORD, LPDWORD)
static WCHAR wszFileName[MAX_PATH]
Definition: wordpad.c:71
const WCHAR wszCurrentEnvironment[]
Definition: prtprocenv.h:11
#define RegCloseKey(hKey)
Definition: registry.h:49
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:2504
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:3662
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4103
#define SetLastError(x)
Definition: compat.h:752
#define GetProcAddress(x, y)
Definition: compat.h:753
#define MAX_PATH
Definition: compat.h:34
#define LoadLibraryW(x)
Definition: compat.h:747
#define InsertTailList(ListHead, Entry)
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
BYTE * PBYTE
Definition: pedump.c:66
BOOL WINAPI LocalGetPrintProcessorDirectory(PWSTR pName, PWSTR pEnvironment, DWORD Level, PBYTE pPrintProcessorInfo, DWORD cbBuf, PDWORD pcbNeeded)
static DWORD _OpenEnvironment(PCWSTR pEnvironment, PHKEY hKey)
PEnumPrintProcessorDatatypesW pfnEnumPrintProcessorDatatypesW
Definition: precomp.h:106
LIST_ENTRY Entry
Definition: precomp.h:100
PGetPrintProcessorCapabilities pfnGetPrintProcessorCapabilities
Definition: precomp.h:107
PControlPrintProcessor pfnControlPrintProcessor
Definition: precomp.h:105
PPrintDocumentOnPrintProcessor pfnPrintDocumentOnPrintProcessor
Definition: precomp.h:109
PClosePrintProcessor pfnClosePrintProcessor
Definition: precomp.h:104
POpenPrintProcessor pfnOpenPrintProcessor
Definition: precomp.h:108
BOOL WINAPI DllFreeSplStr(PWSTR pwszString)
Definition: memory.c:130
BOOL(WINAPI * PControlPrintProcessor)(HANDLE, DWORD)
Definition: precomp.h:46
BOOL(WINAPI * PClosePrintProcessor)(HANDLE)
Definition: precomp.h:45
DWORD(WINAPI * PGetPrintProcessorCapabilities)(LPWSTR, DWORD, LPBYTE, DWORD, LPDWORD)
Definition: precomp.h:48
BOOL(WINAPI * PPrintDocumentOnPrintProcessor)(HANDLE, LPWSTR)
Definition: precomp.h:50
HANDLE(WINAPI * POpenPrintProcessor)(LPWSTR, PPRINTPROCESSOROPENDATA)
Definition: precomp.h:49
DWORD WINAPI GetLastError(void)
Definition: except.c:1042

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
430Cleanup:
431 SetLastError(dwErrorCode);
432 return (dwErrorCode == ERROR_SUCCESS);
433}
static LPSTR pName
Definition: security.c:75
PLOCAL_PRINT_PROCESSOR FindPrintProcessor(PCWSTR pwszName)
_In_ DWORD _Out_ PDWORD pcbNeeded
Definition: winddi.h:3828
#define ERROR_INVALID_LEVEL
Definition: winerror.h:196
#define ERROR_UNKNOWN_PRINTPROCESSOR
Definition: winerror.h:1105
_IRQL_requires_same_ typedef _In_ ULONG _In_ UCHAR Level
Definition: wmitypes.h:56

◆ 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
588Cleanup:
589 if (pwszTemp)
590 DllFreeSplMem(pwszTemp);
591
592 if (hSubKey)
593 RegCloseKey(hSubKey);
594
595 if (hKey)
597
598 SetLastError(dwErrorCode);
599 return (dwErrorCode == ERROR_SUCCESS);
600}
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
struct _PRINTPROCESSOR_INFO_1W PRINTPROCESSOR_INFO_1W

◆ 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
685Cleanup:
686 if (hKey)
688
689 SetLastError(dwErrorCode);
690 return (dwErrorCode == ERROR_SUCCESS);
691}
DWORD cchSpoolDirectory
Definition: main.c:16
WCHAR wszSpoolDirectory[MAX_PATH]
Definition: main.c:15

Referenced by InitializePrintProcessorList().

Variable Documentation

◆ _PrintProcessorList

LIST_ENTRY _PrintProcessorList
static

Definition at line 12 of file printprocessors.c.

Referenced by FindPrintProcessor(), and InitializePrintProcessorList().