ReactOS  0.4.14-dev-833-g5f692ed
main.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: Main functions
5  * COPYRIGHT: Copyright 2015 Colin Finck (colin@reactos.org)
6  */
7 
8 #include "precomp.h"
9 
10 // Global Variables
13 
14 
15 static DWORD
17 {
18  DWORD dwErrorCode;
19  HINSTANCE hinstPrintProvider;
20  PInitializePrintProvidor pfnInitializePrintProvidor;
21  PSPOOLSS_PRINT_PROVIDER pPrintProvider = NULL;
22 
23  // Try to load it.
24  hinstPrintProvider = LoadLibraryW(pwszFileName);
25  if (!hinstPrintProvider)
26  {
27  dwErrorCode = GetLastError();
28  ERR("LoadLibraryW failed for \"%S\" with error %lu!\n", pwszFileName, dwErrorCode);
29  goto Cleanup;
30  }
31 
32  // Get the initialization routine.
33  pfnInitializePrintProvidor = (PInitializePrintProvidor)GetProcAddress(hinstPrintProvider, "InitializePrintProvidor");
34  if (!pfnInitializePrintProvidor)
35  {
36  dwErrorCode = GetLastError();
37  ERR("GetProcAddress failed for \"%S\" with error %lu!\n", pwszFileName, dwErrorCode);
38  goto Cleanup;
39  }
40 
41  // Create a new SPOOLSS_PRINT_PROVIDER structure for it.
42  pPrintProvider = DllAllocSplMem(sizeof(SPOOLSS_PRINT_PROVIDER));
43  if (!pPrintProvider)
44  {
45  dwErrorCode = ERROR_NOT_ENOUGH_MEMORY;
46  ERR("DllAllocSplMem failed!\n");
47  goto Cleanup;
48  }
49 
50  // Call the Print Provider initialization function.
51  if (!pfnInitializePrintProvidor(&pPrintProvider->PrintProvider, sizeof(PRINTPROVIDOR), NULL))
52  {
53  dwErrorCode = GetLastError();
54  ERR("InitializePrintProvidor failed for \"%S\" with error %lu!\n", pwszFileName, dwErrorCode);
55  goto Cleanup;
56  }
57 
58  // Add this Print Provider to the list.
59  InsertTailList(&PrintProviderList, &pPrintProvider->Entry);
60 
61  // Don't let the cleanup routine free this.
62  pPrintProvider = NULL;
63  dwErrorCode = ERROR_SUCCESS;
64 
65 Cleanup:
66  if (pPrintProvider)
67  DllFreeSplMem(pPrintProvider);
68 
69  return dwErrorCode;
70 }
71 
72 static BOOL
74 {
75  DWORD cbFileName;
76  DWORD cchMaxSubKey;
77  DWORD cchPrintProviderName;
78  DWORD dwErrorCode;
79  DWORD dwSubKeys;
80  DWORD i;
81  HKEY hKey = NULL;
82  HKEY hSubKey = NULL;
83  PWSTR pwszPrintProviderName = NULL;
85 
86  // Initialize an empty list for our Print Providers.
88 
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)
93  {
94  ERR("The Local Spooler could not be loaded!\n");
95  goto Cleanup;
96  }
97 
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)
102  {
103  ERR("RegOpenKeyExW failed with status %lu!\n", dwErrorCode);
104  goto Cleanup;
105  }
106 
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)
110  {
111  ERR("RegQueryInfoKeyW failed with status %lu!\n", dwErrorCode);
112  goto Cleanup;
113  }
114 
115  // Allocate a temporary buffer for the Print Provider names.
116  pwszPrintProviderName = DllAllocSplMem((cchMaxSubKey + 1) * sizeof(WCHAR));
117  if (!pwszPrintProviderName)
118  {
119  dwErrorCode = ERROR_NOT_ENOUGH_MEMORY;
120  ERR("DllAllocSplMem failed!\n");
121  goto Cleanup;
122  }
123 
124  // Loop through all available Print Providers.
125  for (i = 0; i < dwSubKeys; i++)
126  {
127  // Cleanup tasks from the previous run
128  if (hSubKey)
129  {
130  RegCloseKey(hSubKey);
131  hSubKey = NULL;
132  }
133 
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)
138  {
139  ERR("RegEnumKeyExW failed for iteration %lu with status %lu!\n", i, dwErrorCode);
140  continue;
141  }
142 
143  // Open this Print Provider's registry key.
144  dwErrorCode = (DWORD)RegOpenKeyExW(hKey, pwszPrintProviderName, 0, KEY_READ, &hSubKey);
145  if (dwErrorCode != ERROR_SUCCESS)
146  {
147  ERR("RegOpenKeyExW failed for Print Provider \"%S\" with status %lu!\n", pwszPrintProviderName, dwErrorCode);
148  continue;
149  }
150 
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)
155  {
156  ERR("RegQueryValueExW failed with status %lu!\n", dwErrorCode);
157  continue;
158  }
159 
160  // Load and add it to the list.
161  dwErrorCode = _AddPrintProviderToList(wszFileName);
162  if (dwErrorCode != ERROR_SUCCESS)
163  continue;
164  }
165 
166  dwErrorCode = ERROR_SUCCESS;
167 
168 Cleanup:
169  // Inside the loop
170  if (hSubKey)
171  RegCloseKey(hSubKey);
172 
173  // Outside the loop
174  if (pwszPrintProviderName)
175  DllFreeSplMem(pwszPrintProviderName);
176 
177  if (hKey)
178  RegCloseKey(hKey);
179 
180  SetLastError(dwErrorCode);
181  return (dwErrorCode == ERROR_SUCCESS);
182 }
183 
184 BOOL WINAPI
185 DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
186 {
187  switch (fdwReason)
188  {
189  case DLL_PROCESS_ATTACH:
190  DisableThreadLibraryCalls(hinstDLL);
192  break;
193  }
194 
195  return TRUE;
196 }
197 
198 BOOL WINAPI
199 InitializeRouter(HANDLE SpoolerStatusHandle)
200 {
202 }
203 
204 BOOL WINAPI
206 {
207  HINSTANCE hWinspool;
208  int i;
209 
210  hWinspool = LoadLibraryW(L"winspool.drv");
211  if (!hWinspool)
212  {
213  ERR("Could not load winspool.drv, last error is %lu!\n", GetLastError());
214  return FALSE;
215  }
216 
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);
227 
228  // Verify that all calls succeeded.
229  for (i = 0; i < 9; i++)
230  {
231  if (!pTable[i])
232  {
233  FreeLibrary(hWinspool);
234  return FALSE;
235  }
236  }
237 
238  return TRUE;
239 }
240 
241 BOOL WINAPI
243 {
244  return FALSE;
245 }
246 
247 BOOL WINAPI
249 {
250  // Nothing to do here yet
252  return TRUE;
253 }
254 
255 BOOL WINAPI
257 {
258  FIXME("(%p, %p) stub\n", ptr1, ptr2);
259 
260  *ptr1 = NULL;
261  *ptr2 = NULL;
262  return FALSE;
263 }
264 
static WCHAR wszFileName[MAX_PATH]
Definition: wordpad.c:70
static BOOL _InitializePrintProviderList(VOID)
Definition: main.c:73
const uint16_t * PCWSTR
Definition: typedefs.h:55
#define TRUE
Definition: types.h:120
#define ERROR_SUCCESS
Definition: deptool.c:10
BOOL WINAPI BuildOtherNamesFromMachineName(LPVOID *ptr1, LPVOID *ptr2)
Definition: main.c:256
#define KEY_READ
Definition: nt_native.h:1023
uint16_t * PWSTR
Definition: typedefs.h:54
BOOL WINAPI DllFreeSplMem(PVOID pMem)
Definition: memory.c:112
BOOL WINAPI DisableThreadLibraryCalls(IN HMODULE hLibModule)
Definition: loader.c:85
static DWORD _AddPrintProviderToList(PCWSTR pwszFileName)
Definition: main.c:16
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
#define DLL_PROCESS_ATTACH
Definition: compat.h:120
#define InsertTailList(ListHead, Entry)
char * LPSTR
Definition: xmlstorage.h:182
#define DWORD
Definition: nt_native.h:44
static IN DWORD IN LPVOID lpvReserved
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
LONG WINAPI RegCloseKey(HKEY hKey)
Definition: reg.c:423
unsigned int BOOL
Definition: ntddk_ex.h:94
#define FIXME(fmt,...)
Definition: debug.h:110
#define LoadLibraryW(x)
Definition: compat.h:412
smooth NULL
Definition: ftsmooth.c:416
BOOL WINAPI SplInitializeWinSpoolDrv(PVOID *pTable)
Definition: main.c:205
#define FreeLibrary(x)
Definition: compat.h:413
BOOL(WINAPI * PInitializePrintProvidor)(LPPRINTPROVIDOR, DWORD, LPWSTR)
#define GetProcessHeap()
Definition: compat.h:403
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4116
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define MAX_PATH
Definition: compat.h:26
#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:417
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:3686
static const WCHAR L[]
Definition: oid.c:1250
Definition: typedefs.h:117
static const WCHAR Cleanup[]
Definition: register.c:80
HANDLE hProcessHeap
Definition: main.c:13
#define ERR(fmt,...)
Definition: debug.h:109
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
BOOL WINAPI SpoolerInit(VOID)
Definition: main.c:248
BOOL WINAPI InitializeRouter(HANDLE SpoolerStatusHandle)
Definition: main.c:199
BOOL WINAPI SplIsUpgrade(VOID)
Definition: main.c:242
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3366
static const EHCI_PERIOD pTable[]
Definition: usbehci.c:29
#define GetProcAddress(x, y)
Definition: compat.h:418
PRINTPROVIDOR PrintProvider
Definition: precomp.h:36
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
BYTE * PBYTE
Definition: pedump.c:66
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
Definition: main.c:26
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
LIST_ENTRY Entry
Definition: precomp.h:35