[WIN32K]
[reactos.git] / reactos / dll / win32 / winspool / info.c
1 /*
2 * WINSPOOL functions
3 *
4 * Copyright 1996 John Harvey
5 * Copyright 1998 Andreas Mohr
6 * Copyright 1999 Klaas van Gend
7 * Copyright 1999, 2000 Huw D M Davies
8 * Copyright 2001 Marcus Meissner
9 *
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2.1 of the License, or (at your option) any later version.
14 *
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with this library; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 */
24
25 #include "precomp.h"
26
27 #include <winreg.h>
28 #include <winnls.h>
29 #include <shlwapi.h>
30
31 /******************************************************************************
32 * GetDefaultPrinterA (WINSPOOL.@)
33 */
34 BOOL WINAPI GetDefaultPrinterA(LPSTR name, LPDWORD namesize)
35 {
36 char *ptr;
37
38 if (*namesize < 1)
39 {
40 SetLastError (ERROR_INSUFFICIENT_BUFFER);
41 return FALSE;
42 }
43
44 if (!GetProfileStringA ("windows", "device", "", name, *namesize))
45 {
46 SetLastError (ERROR_FILE_NOT_FOUND);
47 return FALSE;
48 }
49
50 if ((ptr = strchr (name, ',')) == NULL)
51 {
52 SetLastError (ERROR_FILE_NOT_FOUND);
53 return FALSE;
54 }
55
56 *ptr = '\0';
57 *namesize = strlen (name) + 1;
58 return TRUE;
59 }
60
61
62 /******************************************************************************
63 * GetDefaultPrinterW (WINSPOOL.@)
64 */
65 BOOL WINAPI GetDefaultPrinterW(LPWSTR name, LPDWORD namesize)
66 {
67 char *buf;
68 BOOL ret;
69
70 if (*namesize < 1)
71 {
72 SetLastError (ERROR_INSUFFICIENT_BUFFER);
73 return FALSE;
74 }
75
76 buf = HeapAlloc (GetProcessHeap (), 0, *namesize);
77 ret = GetDefaultPrinterA (buf, namesize);
78 if (ret)
79 {
80 DWORD len = MultiByteToWideChar (CP_ACP, 0, buf, -1, name, *namesize);
81 if (!len)
82 {
83 SetLastError (ERROR_INSUFFICIENT_BUFFER);
84 ret = FALSE;
85 }
86 else *namesize = len;
87 }
88
89 HeapFree (GetProcessHeap (), 0, buf);
90 return ret;
91 }
92
93 /******************************************************************************
94 * AddPrintProvidorA (WINSPOOL.@)
95 */
96 BOOL
97 WINAPI
98 AddPrintProvidorA(LPSTR Name, DWORD Level, PBYTE Buffer)
99 {
100 if (Name || Level > 2 || Buffer == NULL)
101 {
102 SetLastError(ERROR_INVALID_PARAMETER);
103 return FALSE;
104 }
105
106 if (Level == 1)
107 {
108 BOOL bRet;
109 PROVIDOR_INFO_1W Provider;
110 PROVIDOR_INFO_1A *Prov = (PROVIDOR_INFO_1A*)Buffer;
111
112 if (Prov->pName == NULL || Prov->pDLLName == NULL || Prov->pEnvironment == NULL)
113 {
114 return FALSE;
115 }
116
117 Provider.pDLLName = HeapAlloc(GetProcessHeap(), 0, (strlen(Prov->pDLLName)+1) * sizeof(WCHAR));
118 if (Provider.pDLLName)
119 {
120 MultiByteToWideChar(CP_ACP, 0, Prov->pDLLName, -1, Provider.pDLLName, strlen(Prov->pDLLName)+1);
121 Provider.pDLLName[strlen(Prov->pDLLName)] = L'\0';
122 }
123
124 Provider.pEnvironment = HeapAlloc(GetProcessHeap(), 0, (strlen(Prov->pEnvironment)+1) * sizeof(WCHAR));
125 if (Provider.pEnvironment)
126 {
127 MultiByteToWideChar(CP_ACP, 0, Prov->pEnvironment, -1, Provider.pEnvironment, strlen(Prov->pEnvironment)+1);
128 Provider.pEnvironment[strlen(Prov->pEnvironment)] = L'\0';
129 }
130
131 Provider.pName = HeapAlloc(GetProcessHeap(), 0, (strlen(Prov->pName)+1) * sizeof(WCHAR));
132 if (Provider.pName)
133 {
134 MultiByteToWideChar(CP_ACP, 0, Prov->pName, -1, Provider.pName, strlen(Prov->pName)+1);
135 Provider.pName[strlen(Prov->pName)] = L'\0';
136 }
137
138 bRet = AddPrintProvidorW(NULL, Level, (LPBYTE)&Provider);
139
140 if (Provider.pDLLName)
141 HeapFree(GetProcessHeap(), 0, Provider.pDLLName);
142
143 if (Provider.pEnvironment)
144 HeapFree(GetProcessHeap(), 0, Provider.pEnvironment);
145
146 if (Provider.pName)
147 HeapFree(GetProcessHeap(), 0, Provider.pName);
148
149 return bRet;
150 }
151 else
152 {
153 PROVIDOR_INFO_2W Provider;
154 PROVIDOR_INFO_2A *Prov = (PROVIDOR_INFO_2A*)Buffer;
155
156 Provider.pOrder = HeapAlloc(GetProcessHeap(), 0, (strlen(Prov->pOrder)+1) * sizeof(WCHAR));
157 if (Provider.pOrder)
158 {
159 BOOL bRet;
160 MultiByteToWideChar(CP_ACP, 0, Prov->pOrder, -1, Provider.pOrder, strlen(Prov->pOrder)+1);
161 Provider.pOrder[strlen(Prov->pOrder)] = L'\0';
162
163 bRet = AddPrintProvidorW(NULL, Level, (LPBYTE)&Provider);
164 HeapFree(GetProcessHeap(), 0, Provider.pOrder);
165 return bRet;
166 }
167 }
168
169 return FALSE;
170 }
171
172
173 /******************************************************************************
174 * AddPrintProvidorW (WINSPOOL.@)
175 */
176 BOOL
177 WINAPI
178 AddPrintProvidorW(LPWSTR Name, DWORD Level, PBYTE Buffer)
179 {
180 HKEY hKey;
181 LPWSTR pOrder;
182 DWORD dwSize, dwType;
183 BOOL bRet = FALSE;
184
185 if (Name || Level > 2 || Buffer == NULL)
186 {
187 SetLastError(ERROR_INVALID_PARAMETER);
188 return FALSE;
189 }
190
191
192 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Control\\Print\\Providers", 0, KEY_READ | KEY_WRITE, &hKey) != ERROR_SUCCESS)
193 {
194 return FALSE;
195 }
196
197 if (RegQueryValueExW(hKey, L"Order", NULL, &dwType, NULL, &dwSize) != ERROR_SUCCESS || dwType != REG_MULTI_SZ)
198 {
199 RegCloseKey(hKey);
200 return FALSE;
201 }
202
203 pOrder = HeapAlloc(GetProcessHeap(), 0, dwSize);
204 if (!pOrder)
205 {
206 RegCloseKey(hKey);
207 return FALSE;
208 }
209
210 if (RegQueryValueExW(hKey, L"Order", NULL, &dwType, (LPBYTE)pOrder, &dwSize) != ERROR_SUCCESS || dwType != REG_MULTI_SZ)
211 {
212 RegCloseKey(hKey);
213 return FALSE;
214 }
215
216 if (Level == 1)
217 {
218 LPWSTR pBuffer;
219 BOOL bFound = FALSE;
220 PROVIDOR_INFO_1W * Prov = (PROVIDOR_INFO_1W*)Buffer;
221
222 if (Prov->pName == NULL || Prov->pDLLName == NULL || Prov->pEnvironment == NULL)
223 {
224 SetLastError(ERROR_INVALID_PARAMETER);
225 RegCloseKey(hKey);
226 return FALSE;
227 }
228
229 pBuffer = pOrder;
230
231 while(pBuffer[0])
232 {
233 if (!wcsicmp(pBuffer, Prov->pName))
234 {
235 bFound = TRUE;
236 break;
237 }
238 pBuffer += wcslen(pBuffer) + 1;
239 }
240
241 if (!bFound)
242 {
243 HKEY hSubKey;
244 DWORD dwFullSize = dwSize + (wcslen(Prov->pName)+1) * sizeof(WCHAR);
245
246 if (RegCreateKeyExW(hKey, Prov->pName, 0, NULL, 0, KEY_WRITE, NULL, &hSubKey, NULL) == ERROR_SUCCESS)
247 {
248 RegSetValueExW(hSubKey, L"Name", 0, REG_SZ, (LPBYTE)Prov->pDLLName, (wcslen(Prov->pDLLName)+1) * sizeof(WCHAR));
249 RegCloseKey(hSubKey);
250 }
251
252 pBuffer = HeapAlloc(GetProcessHeap(), 0, dwFullSize);
253 if (pBuffer)
254 {
255 CopyMemory(pBuffer, pOrder, dwSize);
256 wcscpy(&pBuffer[(dwSize/sizeof(WCHAR))-1], Prov->pName);
257 pBuffer[(dwSize/sizeof(WCHAR)) + wcslen(Prov->pName)] = L'\0';
258 RegSetValueExW(hKey, L"Order", 0, REG_MULTI_SZ, (LPBYTE)pBuffer, dwFullSize);
259 HeapFree(GetProcessHeap(), 0, pBuffer);
260 }
261 bRet = TRUE;
262 }
263
264 }
265
266 RegCloseKey(hKey);
267 HeapFree(GetProcessHeap(), 0, pOrder);
268
269 return bRet;
270 }
271
272 /******************************************************************************
273 * DeletePrintProvidorA (WINSPOOL.@)
274 */
275 BOOL
276 WINAPI
277 DeletePrintProvidorA(LPSTR Name, LPSTR Environment, LPSTR PrintProvidor)
278 {
279 BOOL bRet;
280 LPWSTR Env, Prov;
281
282 if (Name || !Environment || !PrintProvidor)
283 {
284 SetLastError(ERROR_INVALID_PARAMETER);
285 return FALSE;
286 }
287
288 Env = HeapAlloc(GetProcessHeap(), 0, (strlen(Environment)+1) * sizeof(WCHAR));
289 if (!Env)
290 {
291 return FALSE;
292 }
293
294 MultiByteToWideChar(CP_ACP, 0, Environment, -1, Env, strlen(Environment)+1);
295 Env[strlen(Environment)] = L'\0';
296
297 Prov = HeapAlloc(GetProcessHeap(), 0, (strlen(PrintProvidor)+1) * sizeof(WCHAR));
298 if (!Prov)
299 {
300 HeapFree(GetProcessHeap(), 0, Env);
301 return FALSE;
302 }
303
304 MultiByteToWideChar(CP_ACP, 0, PrintProvidor, -1, Prov, strlen(PrintProvidor)+1);
305 Prov[strlen(PrintProvidor)] = L'\0';
306
307 bRet = DeletePrintProvidorW(NULL, Env, Prov);
308 HeapFree(GetProcessHeap(), 0, Env);
309 HeapFree(GetProcessHeap(), 0, Prov);
310
311 return bRet;
312 }
313
314 /*
315 * @unimplemented
316 */
317 BOOL
318 WINAPI
319 DeletePrintProvidorW(LPWSTR Name, LPWSTR Environment, LPWSTR PrintProvidor)
320 {
321 HKEY hKey;
322 BOOL bFound;
323 DWORD dwType, dwSize, dwOffset, dwLength;
324 LPWSTR pOrder, pBuffer, pNew;
325
326 if (Name || !Environment || !PrintProvidor)
327 {
328 SetLastError(ERROR_INVALID_PARAMETER);
329 return FALSE;
330 }
331
332 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Control\\Print\\Providers", 0, KEY_READ | KEY_WRITE, &hKey) != ERROR_SUCCESS)
333 {
334 return FALSE;
335 }
336
337 if (RegQueryValueExW(hKey, L"Order", NULL, &dwType, NULL, &dwSize) != ERROR_SUCCESS || dwType != REG_MULTI_SZ)
338 {
339 RegCloseKey(hKey);
340 return FALSE;
341 }
342
343 pOrder = HeapAlloc(GetProcessHeap(), 0, dwSize);
344 if (!pOrder)
345 {
346 RegCloseKey(hKey);
347 return FALSE;
348 }
349
350 if (RegQueryValueExW(hKey, L"Order", NULL, &dwType, (LPBYTE)pOrder, &dwSize) != ERROR_SUCCESS || dwType != REG_MULTI_SZ)
351 {
352 RegCloseKey(hKey);
353 return FALSE;
354 }
355
356
357 pBuffer = pOrder;
358 bFound = FALSE;
359 while(pBuffer[0])
360 {
361 if (!wcsicmp(pBuffer, PrintProvidor))
362 {
363 bFound = TRUE;
364 break;
365 }
366 pBuffer += wcslen(pBuffer) + 1;
367 }
368
369 if (!bFound)
370 {
371 RegCloseKey(hKey);
372 HeapFree(GetProcessHeap(), 0, pOrder);
373 return FALSE;
374 }
375
376 pNew = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwSize);
377 if (!pNew)
378 {
379 RegCloseKey(hKey);
380 HeapFree(GetProcessHeap(), 0, pOrder);
381 return FALSE;
382 }
383
384 dwOffset = pBuffer - pOrder;
385 dwLength = (dwSize / sizeof(WCHAR)) - (dwOffset + wcslen(pBuffer) + 1);
386 CopyMemory(pNew, pOrder, dwOffset * sizeof(WCHAR));
387 CopyMemory(&pNew[dwOffset], pBuffer + wcslen(pBuffer) + 1, dwLength);
388
389 RegSetValueExW(hKey, L"Order", 0, REG_MULTI_SZ, (LPBYTE)pNew, (dwOffset + dwLength) * sizeof(WCHAR));
390 RegDeleteKey(hKey, PrintProvidor);
391
392 HeapFree(GetProcessHeap(), 0, pOrder);
393 HeapFree(GetProcessHeap(), 0, pNew);
394 RegCloseKey(hKey);
395
396 return TRUE;
397 }
398
399 /*
400 * @unimplemented
401 */
402 BOOL
403 WINAPI
404 AddMonitorA(LPSTR Name, DWORD Level, PBYTE Monitors)
405 {
406 LPWSTR szName = NULL;
407 MONITOR_INFO_2W Monitor;
408 MONITOR_INFO_2A *pMonitor;
409 BOOL bRet = FALSE;
410
411 if (Level != 2 || !Monitors)
412 {
413 SetLastError(ERROR_INVALID_PARAMETER);
414 return FALSE;
415 }
416
417 pMonitor = (MONITOR_INFO_2A*)Monitors;
418 if (pMonitor->pDLLName == NULL || pMonitor->pName == NULL)
419 {
420 SetLastError(ERROR_INVALID_PARAMETER);
421 return FALSE;
422 }
423
424 ZeroMemory(&Monitor, sizeof(Monitor));
425
426 if (Name)
427 {
428 szName = HeapAlloc(GetProcessHeap(), 0, (strlen(Name) + 1) * sizeof(WCHAR));
429 if (!szName)
430 {
431 return FALSE;
432 }
433 MultiByteToWideChar(CP_ACP, 0, Name, -1, szName, strlen(Name)+1);
434 szName[strlen(Name)] = L'\0';
435 }
436
437 Monitor.pDLLName = HeapAlloc(GetProcessHeap(), 0, (strlen(pMonitor->pDLLName)+1) * sizeof(WCHAR));
438 if (!Monitor.pDLLName)
439 {
440 goto cleanup;
441 }
442 MultiByteToWideChar(CP_ACP, 0, pMonitor->pDLLName, -1, Monitor.pDLLName, strlen(pMonitor->pDLLName)+1);
443 pMonitor->pDLLName[strlen(pMonitor->pDLLName)] = L'\0';
444
445 Monitor.pName = HeapAlloc(GetProcessHeap(), 0, (strlen(pMonitor->pName)+1) * sizeof(WCHAR));
446 if (!Monitor.pName)
447 {
448 goto cleanup;
449 }
450 MultiByteToWideChar(CP_ACP, 0, pMonitor->pName, -1, Monitor.pName, strlen(pMonitor->pName)+1);
451 pMonitor->pName[strlen(pMonitor->pName)] = L'\0';
452
453
454 if (pMonitor->pEnvironment)
455 {
456 Monitor.pEnvironment = HeapAlloc(GetProcessHeap(), 0, (strlen(pMonitor->pEnvironment)+1) * sizeof(WCHAR));
457 if (!Monitor.pEnvironment)
458 {
459 goto cleanup;
460 }
461 MultiByteToWideChar(CP_ACP, 0, pMonitor->pEnvironment, -1, Monitor.pEnvironment, strlen(pMonitor->pEnvironment)+1);
462 pMonitor->pEnvironment[strlen(pMonitor->pEnvironment)] = L'\0';
463 }
464
465 bRet = AddMonitorW(szName, Level, (LPBYTE)&Monitor);
466
467 cleanup:
468
469 if (szName)
470 HeapFree(GetProcessHeap(), 0, szName);
471
472 if (Monitor.pDLLName)
473 HeapFree(GetProcessHeap(), 0, Monitor.pDLLName);
474
475 if (Monitor.pEnvironment)
476 HeapFree(GetProcessHeap(), 0, Monitor.pEnvironment);
477
478 if (Monitor.pName)
479 HeapFree(GetProcessHeap(), 0, Monitor.pName);
480
481 return bRet;
482 }
483
484
485 /*
486 * @unimplemented
487 */
488 BOOL
489 WINAPI
490 AddMonitorW(LPWSTR Name, DWORD Level, PBYTE Monitors)
491 {
492 WCHAR szPath[MAX_PATH];
493 HMODULE hLibrary = NULL;
494 FARPROC InitProc;
495 HKEY hKey, hSubKey;
496 MONITOR_INFO_2W * pMonitor;
497
498
499 if (Level != 2 || !Monitors)
500 {
501 SetLastError(ERROR_INVALID_PARAMETER);
502 return FALSE;
503 }
504
505 pMonitor = (MONITOR_INFO_2W*)Monitors;
506
507 if (pMonitor->pDLLName == NULL || pMonitor->pName == NULL)
508 {
509 SetLastError(ERROR_INVALID_PARAMETER);
510 return FALSE;
511 }
512
513 if (wcschr(pMonitor->pDLLName, L'\\'))
514 {
515 hLibrary = LoadLibraryExW(pMonitor->pDLLName, NULL, 0);
516 }
517 else if (GetSystemDirectoryW(szPath, MAX_PATH) && PathAddBackslashW(szPath))
518 {
519 wcscat(szPath, pMonitor->pDLLName);
520 hLibrary = LoadLibraryExW(szPath, NULL, 0);
521 }
522
523 if (!hLibrary)
524 {
525 return FALSE;
526 }
527
528 InitProc = GetProcAddress(hLibrary, "InitializePrintMonitor");
529 if (!InitProc)
530 {
531 InitProc = GetProcAddress(hLibrary, "InitializePrintMonitor2");
532 if (!InitProc)
533 {
534 FreeLibrary(hLibrary);
535 SetLastError(ERROR_PROC_NOT_FOUND);
536 return FALSE;
537 }
538 }
539
540 // FIXME
541 // Initialize monitor
542 FreeLibrary(hLibrary);
543
544 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Control\\Print\\Monitors", 0, KEY_WRITE, &hKey) == ERROR_SUCCESS)
545 {
546 if (RegCreateKeyExW(hKey, pMonitor->pName, 0, NULL, 0, KEY_WRITE, NULL, &hSubKey, NULL) == ERROR_SUCCESS)
547 {
548 RegSetValueExW(hSubKey, L"Driver", 0, REG_SZ, (LPBYTE)pMonitor->pDLLName, (wcslen(pMonitor->pDLLName)+1)*sizeof(WCHAR));
549 RegCloseKey(hSubKey);
550 }
551 RegCloseKey(hKey);
552 }
553 return TRUE;
554 }
555