2 * PROJECT: ReactOS Spooler Router
3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4 * PURPOSE: Main functions
5 * COPYRIGHT: Copyright 2015 Colin Finck (colin@reactos.org)
12 LIST_ENTRY PrintProviderList
;
16 _AddPrintProviderToList(PCWSTR pwszFileName
)
19 HINSTANCE hinstPrintProvider
;
20 PInitializePrintProvidor pfnInitializePrintProvidor
;
21 PSPOOLSS_PRINT_PROVIDER pPrintProvider
= NULL
;
24 hinstPrintProvider
= LoadLibraryW(pwszFileName
);
25 if (!hinstPrintProvider
)
27 dwErrorCode
= GetLastError();
28 ERR("LoadLibraryW failed for \"%S\" with error %lu!\n", pwszFileName
, dwErrorCode
);
32 // Get the initialization routine.
33 pfnInitializePrintProvidor
= (PInitializePrintProvidor
)GetProcAddress(hinstPrintProvider
, "InitializePrintProvidor");
34 if (!pfnInitializePrintProvidor
)
36 dwErrorCode
= GetLastError();
37 ERR("GetProcAddress failed for \"%S\" with error %lu!\n", pwszFileName
, dwErrorCode
);
41 // Create a new SPOOLSS_PRINT_PROVIDER structure for it.
42 pPrintProvider
= DllAllocSplMem(sizeof(SPOOLSS_PRINT_PROVIDER
));
45 dwErrorCode
= ERROR_NOT_ENOUGH_MEMORY
;
46 ERR("DllAllocSplMem failed!\n");
50 // Call the Print Provider initialization function.
51 if (!pfnInitializePrintProvidor(&pPrintProvider
->PrintProvider
, sizeof(PRINTPROVIDOR
), NULL
))
53 dwErrorCode
= GetLastError();
54 ERR("InitializePrintProvidor failed for \"%S\" with error %lu!\n", pwszFileName
, dwErrorCode
);
58 // Add this Print Provider to the list.
59 InsertTailList(&PrintProviderList
, &pPrintProvider
->Entry
);
61 // Don't let the cleanup routine free this.
62 pPrintProvider
= NULL
;
63 dwErrorCode
= ERROR_SUCCESS
;
67 DllFreeSplMem(pPrintProvider
);
73 _InitializePrintProviderList()
77 DWORD cchPrintProviderName
;
83 PWSTR pwszPrintProviderName
= NULL
;
84 WCHAR wszFileName
[MAX_PATH
];
86 // Initialize an empty list for our Print Providers.
87 InitializeListHead(&PrintProviderList
);
89 // First add the Local Spooler.
90 // This one must exist and must be the first one in the list.
91 dwErrorCode
= _AddPrintProviderToList(L
"localspl");
92 if (dwErrorCode
!= ERROR_SUCCESS
)
94 ERR("The Local Spooler could not be loaded!\n");
98 // Now add additional Print Providers from the registry.
99 // First of all, open the key containing print providers.
100 dwErrorCode
= (DWORD
)RegOpenKeyExW(HKEY_LOCAL_MACHINE
, L
"SYSTEM\\CurrentControlSet\\Control\\Print\\Providers", 0, KEY_READ
, &hKey
);
101 if (dwErrorCode
!= ERROR_SUCCESS
)
103 ERR("RegOpenKeyExW failed with status %lu!\n", dwErrorCode
);
107 // Get the number of Print Providers and maximum sub key length.
108 dwErrorCode
= (DWORD
)RegQueryInfoKeyW(hKey
, NULL
, NULL
, NULL
, &dwSubKeys
, &cchMaxSubKey
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
);
109 if (dwErrorCode
!= ERROR_SUCCESS
)
111 ERR("RegQueryInfoKeyW failed with status %lu!\n", dwErrorCode
);
115 // Allocate a temporary buffer for the Print Provider names.
116 pwszPrintProviderName
= DllAllocSplMem((cchMaxSubKey
+ 1) * sizeof(WCHAR
));
117 if (!pwszPrintProviderName
)
119 dwErrorCode
= ERROR_NOT_ENOUGH_MEMORY
;
120 ERR("DllAllocSplMem failed!\n");
124 // Loop through all available Print Providers.
125 for (i
= 0; i
< dwSubKeys
; i
++)
127 // Cleanup tasks from the previous run
130 RegCloseKey(hSubKey
);
134 // Get the name of this Print Provider.
135 cchPrintProviderName
= cchMaxSubKey
+ 1;
136 dwErrorCode
= (DWORD
)RegEnumKeyExW(hKey
, i
, pwszPrintProviderName
, &cchPrintProviderName
, NULL
, NULL
, NULL
, NULL
);
137 if (dwErrorCode
!= ERROR_SUCCESS
)
139 ERR("RegEnumKeyExW failed for iteration %lu with status %lu!\n", i
, dwErrorCode
);
143 // Open this Print Provider's registry key.
144 dwErrorCode
= (DWORD
)RegOpenKeyExW(hKey
, pwszPrintProviderName
, 0, KEY_READ
, &hSubKey
);
145 if (dwErrorCode
!= ERROR_SUCCESS
)
147 ERR("RegOpenKeyExW failed for Print Provider \"%S\" with status %lu!\n", pwszPrintProviderName
, dwErrorCode
);
151 // Get the file name of the Print Provider.
152 cbFileName
= MAX_PATH
* sizeof(WCHAR
);
153 dwErrorCode
= (DWORD
)RegQueryValueExW(hKey
, L
"Driver", NULL
, NULL
, (PBYTE
)wszFileName
, &cbFileName
);
154 if (dwErrorCode
!= ERROR_SUCCESS
)
156 ERR("RegQueryValueExW failed with status %lu!\n", dwErrorCode
);
160 // Load and add it to the list.
161 dwErrorCode
= _AddPrintProviderToList(wszFileName
);
162 if (dwErrorCode
!= ERROR_SUCCESS
)
166 dwErrorCode
= ERROR_SUCCESS
;
171 RegCloseKey(hSubKey
);
174 if (pwszPrintProviderName
)
175 DllFreeSplMem(pwszPrintProviderName
);
180 SetLastError(dwErrorCode
);
181 return (dwErrorCode
== ERROR_SUCCESS
);
185 DllMain(HINSTANCE hinstDLL
, DWORD fdwReason
, LPVOID lpvReserved
)
189 case DLL_PROCESS_ATTACH
:
190 DisableThreadLibraryCalls(hinstDLL
);
191 hProcessHeap
= GetProcessHeap();
199 InitializeRouter(HANDLE SpoolerStatusHandle
)
201 return _InitializePrintProviderList();
205 SplInitializeWinSpoolDrv(PVOID
* pTable
)
210 hWinspool
= LoadLibraryW(L
"winspool.drv");
213 ERR("Could not load winspool.drv, last error is %lu!\n", GetLastError());
217 // Get the function pointers which are meant to be returned by this function.
218 pTable
[0] = GetProcAddress(hWinspool
, "OpenPrinterW");
219 pTable
[1] = GetProcAddress(hWinspool
, "ClosePrinter");
220 pTable
[2] = GetProcAddress(hWinspool
, "SpoolerDevQueryPrintW");
221 pTable
[3] = GetProcAddress(hWinspool
, "SpoolerPrinterEvent");
222 pTable
[4] = GetProcAddress(hWinspool
, "DocumentPropertiesW");
223 pTable
[5] = GetProcAddress(hWinspool
, (LPSTR
)212);
224 pTable
[6] = GetProcAddress(hWinspool
, (LPSTR
)213);
225 pTable
[7] = GetProcAddress(hWinspool
, (LPSTR
)214);
226 pTable
[8] = GetProcAddress(hWinspool
, (LPSTR
)215);
228 // Verify that all calls succeeded.
229 for (i
= 0; i
< 9; i
++)
245 // Nothing to do here yet
246 SetLastError(ERROR_SUCCESS
);
251 BuildOtherNamesFromMachineName(LPVOID
* ptr1
, LPVOID
* ptr2
)
253 FIXME("(%p, %p) stub\n", ptr1
, ptr2
);