32 const WCHAR wszEnvironmentsKey[] =
L"SYSTEM\\CurrentControlSet\\Control\\Print\\Environments\\";
33 const DWORD cchEnvironmentsKey =
_countof(wszEnvironmentsKey) - 1;
47 cchEnvironment =
wcslen(pEnvironment);
48 pwszEnvironmentKey =
DllAllocSplMem((cchEnvironmentsKey + cchEnvironment + 1) *
sizeof(
WCHAR));
49 if (!pwszEnvironmentKey)
52 ERR(
"DllAllocSplMem failed!\n");
56 CopyMemory(pwszEnvironmentKey, wszEnvironmentsKey, cchEnvironmentsKey *
sizeof(
WCHAR));
57 CopyMemory(&pwszEnvironmentKey[cchEnvironmentsKey], pEnvironment, (cchEnvironment + 1) *
sizeof(
WCHAR));
68 ERR(
"RegOpenKeyExW failed with status %lu!\n", dwErrorCode);
73 if (pwszEnvironmentKey)
85 TRACE(
"FindDatatype(%p, %S)\n", pPrintProcessor, pwszDatatype);
107 TRACE(
"FindPrintProcessor(%S)\n", pwszName);
117 return pPrintProcessor;
133 DWORD cchPrintProcessorPath;
135 DWORD cchPrintProcessorName;
147 TRACE(
"InitializePrintProcessorList()\n");
160 cchPrintProcessorPath /=
sizeof(
WCHAR);
161 --cchPrintProcessorPath;
164 wszPrintProcessorPath[cchPrintProcessorPath] =
L'\\';
165 ++cchPrintProcessorPath;
176 ERR(
"RegOpenKeyExW failed with status %lu!\n", dwErrorCode);
181 dwErrorCode = (
DWORD)
RegQueryInfoKeyW(hSubKey,
NULL,
NULL,
NULL, &dwSubKeys, &cchMaxSubKey,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL);
184 ERR(
"RegQueryInfoKeyW failed with status %lu!\n", dwErrorCode);
189 for (
i = 0;
i < dwSubKeys;
i++)
207 pPrintProcessor =
NULL;
212 if (!pPrintProcessor)
215 ERR(
"DllAllocSplMem failed!\n");
224 ERR(
"DllAllocSplMem failed!\n");
229 cchPrintProcessorName = cchMaxSubKey + 1;
233 ERR(
"RegEnumKeyExW failed with status %ld!\n", dwErrorCode);
241 ERR(
"RegOpenKeyExW failed for Print Processor \"%S\" with status %lu!\n", pPrintProcessor->
pwszName, dwErrorCode);
250 ERR(
"RegQueryValueExW failed for Print Processor \"%S\" with status %lu!\n", pPrintProcessor->
pwszName, dwErrorCode);
255 if (cchPrintProcessorPath + cbFileName /
sizeof(
WCHAR) >
MAX_PATH)
257 ERR(
"Print Processor directory \"%S\" for Print Processor \"%S\" is too long!\n",
wszFileName, pPrintProcessor->
pwszName);
265 hinstPrintProcessor =
LoadLibraryW(wszPrintProcessorPath);
266 if (!hinstPrintProcessor)
268 ERR(
"LoadLibraryW failed for \"%S\" with error %lu!\n", wszPrintProcessorPath,
GetLastError());
276 ERR(
"Print Processor \"%S\" exports no ClosePrintProcessor!\n", wszPrintProcessorPath);
283 ERR(
"Print Processor \"%S\" exports no ControlPrintProcessor!\n", wszPrintProcessorPath);
290 ERR(
"Print Processor \"%S\" exports no EnumPrintProcessorDatatypesW!\n", wszPrintProcessorPath);
297 ERR(
"Print Processor \"%S\" exports no GetPrintProcessorCapabilities!\n", wszPrintProcessorPath);
304 ERR(
"Print Processor \"%S\" exports no OpenPrintProcessor!\n", wszPrintProcessorPath);
311 ERR(
"Print Processor \"%S\" exports no PrintDocumentOnPrintProcessor!\n", wszPrintProcessorPath);
321 ERR(
"DllAllocSplMem failed!\n");
327 ERR(
"EnumPrintProcessorDatatypesW failed for Print Processor \"%S\" with error %lu!\n", wszPrintProcessorPath,
GetLastError());
335 pPrintProcessor =
NULL;
407 TRACE(
"LocalEnumPrintProcessorDatatypes(%S, %S, %lu, %p, %lu, %p, %p)\n",
pName, pPrintProcessorName,
Level, pDatatypes, cbBuf,
pcbNeeded, pcReturned);
418 if (!pPrintProcessor)
474 DWORD cchPrintProcessor;
476 DWORD dwPrintProcessorCount;
480 PBYTE pCurrentOutputPrintProcessor;
481 PBYTE pCurrentOutputPrintProcessorInfo;
485 TRACE(
"LocalEnumPrintProcessors(%S, %S, %lu, %p, %lu, %p, %p)\n",
pName, pEnvironment,
Level, pPrintProcessorInfo, cbBuf,
pcbNeeded, pcReturned);
511 ERR(
"RegOpenKeyExW failed with status %lu!\n", dwErrorCode);
516 dwErrorCode = (
DWORD)
RegQueryInfoKeyW(hSubKey,
NULL,
NULL,
NULL, &dwPrintProcessorCount, &cchMaxSubKey,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL);
519 ERR(
"RegQueryInfoKeyW failed with status %lu!\n", dwErrorCode);
528 ERR(
"DllAllocSplMem failed!\n");
535 for (
i = 0;
i < dwPrintProcessorCount;
i++)
539 cchPrintProcessor = cchMaxSubKey + 1;
543 ERR(
"RegEnumKeyExW failed with status %lu!\n", dwErrorCode);
558 pCurrentOutputPrintProcessorInfo = pPrintProcessorInfo;
559 pCurrentOutputPrintProcessor = pPrintProcessorInfo + dwPrintProcessorCount *
sizeof(
PRINTPROCESSOR_INFO_1W);
562 for (
i = 0;
i < dwPrintProcessorCount;
i++)
565 cchPrintProcessor = cchMaxSubKey + 1;
571 ERR(
"RegEnumKeyExW failed with status %lu!\n", dwErrorCode);
576 PrintProcessorInfo1.
pName = (
PWSTR)pCurrentOutputPrintProcessor;
580 pCurrentOutputPrintProcessor += (cchPrintProcessor + 1) *
sizeof(
WCHAR);
585 *pcReturned = dwPrintProcessorCount;
635 const WCHAR wszPath[] =
L"\\PRTPROCS\\";
638 DWORD cbDirectoryName;
641 PWSTR pwszDirectory = (
PWSTR)pPrintProcessorInfo;
643 TRACE(
"LocalGetPrintProcessorDirectory(%S, %S, %lu, %p, %lu, %p)\n",
pName, pEnvironment,
Level, pPrintProcessorInfo, cbBuf,
pcbNeeded);
649 ERR(
"_OpenEnvironment failed with error %lu!\n", dwErrorCode);
657 ERR(
"RegQueryValueExW failed with status %lu!\n", dwErrorCode);
678 ERR(
"RegQueryValueExW failed with status %lu!\n", dwErrorCode);
BOOL(WINAPI * PEnumPrintProcessorDatatypesW)(LPWSTR, LPWSTR, DWORD, LPBYTE, DWORD, LPDWORD, LPDWORD)
static WCHAR wszFileName[MAX_PATH]
const WCHAR wszCurrentEnvironment[]
#define RegCloseKey(hKey)
#define ERROR_NOT_ENOUGH_MEMORY
#define ERROR_INSUFFICIENT_BUFFER
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
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)
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)
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
#define ERROR_INVALID_PARAMETER
#define GetProcAddress(x, y)
static const WCHAR Cleanup[]
#define InsertTailList(ListHead, Entry)
#define InitializeListHead(ListHead)
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
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define ERROR_FILE_NOT_FOUND
BOOL InitializePrintProcessorList(void)
BOOL WINAPI LocalEnumPrintProcessors(LPWSTR pName, LPWSTR pEnvironment, DWORD Level, LPBYTE pPrintProcessorInfo, DWORD cbBuf, LPDWORD pcbNeeded, LPDWORD pcReturned)
BOOL WINAPI LocalGetPrintProcessorDirectory(PWSTR pName, PWSTR pEnvironment, DWORD Level, PBYTE pPrintProcessorInfo, DWORD cbBuf, PDWORD pcbNeeded)
static LIST_ENTRY _PrintProcessorList
PLOCAL_PRINT_PROCESSOR FindPrintProcessor(PCWSTR pwszName)
static DWORD _OpenEnvironment(PCWSTR pEnvironment, PHKEY hKey)
BOOL FindDatatype(const PLOCAL_PRINT_PROCESSOR pPrintProcessor, PCWSTR pwszDatatype)
BOOL WINAPI LocalEnumPrintProcessorDatatypes(LPWSTR pName, LPWSTR pPrintProcessorName, DWORD Level, LPBYTE pDatatypes, DWORD cbBuf, LPDWORD pcbNeeded, LPDWORD pcReturned)
_Check_return_ _CRTIMP int __cdecl _wcsicmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
base of all file and directory entries
struct _LIST_ENTRY * Flink
PEnumPrintProcessorDatatypesW pfnEnumPrintProcessorDatatypesW
PGetPrintProcessorCapabilities pfnGetPrintProcessorCapabilities
PControlPrintProcessor pfnControlPrintProcessor
PPrintDocumentOnPrintProcessor pfnPrintDocumentOnPrintProcessor
PClosePrintProcessor pfnClosePrintProcessor
POpenPrintProcessor pfnOpenPrintProcessor
PDATATYPES_INFO_1W pDatatypesInfo1
#define CONTAINING_RECORD(address, type, field)
BOOL WINAPI DllFreeSplMem(PVOID pMem)
PVOID WINAPI DllAllocSplMem(DWORD dwBytes)
BOOL WINAPI DllFreeSplStr(PWSTR pwszString)
WCHAR wszSpoolDirectory[MAX_PATH]
BOOL(WINAPI * PControlPrintProcessor)(HANDLE, DWORD)
BOOL(WINAPI * PClosePrintProcessor)(HANDLE)
DWORD(WINAPI * PGetPrintProcessorCapabilities)(LPWSTR, DWORD, LPBYTE, DWORD, LPDWORD)
BOOL(WINAPI * PPrintDocumentOnPrintProcessor)(HANDLE, LPWSTR)
HANDLE(WINAPI * POpenPrintProcessor)(LPWSTR, PPRINTPROCESSOROPENDATA)
DWORD WINAPI GetLastError(void)
_In_ DWORD _Out_ PDWORD pcbNeeded
#define ERROR_INVALID_LEVEL
#define ERROR_INVALID_ENVIRONMENT
#define ERROR_UNKNOWN_PRINTPROCESSOR
#define HKEY_LOCAL_MACHINE
struct _PRINTPROCESSOR_INFO_1W PRINTPROCESSOR_INFO_1W
_IRQL_requires_same_ typedef _In_ ULONG _In_ UCHAR Level