ReactOS 0.4.15-dev-7670-g69b08be
monitors.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS Local Spooler
3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4 * PURPOSE: Functions related to Print Monitors
5 * COPYRIGHT: Copyright 2015-2017 Colin Finck (colin@reactos.org)
6 */
7
8#include "precomp.h"
9
10// Global Variables
12
13// Local Constants
17};
18
21 FIELD_OFFSET(MONITOR_INFO_2W, pEnvironment),
24};
25
26
29{
31 PLOCAL_PRINT_MONITOR pPrintMonitor;
32
33 TRACE("FindPrintMonitor(%S)\n", pwszName);
34
35 if (!pwszName)
36 return NULL;
37
39 {
41
42 if (_wcsicmp(pPrintMonitor->pwszName, pwszName) == 0)
43 return pPrintMonitor;
44 }
45
46 return NULL;
47}
48
49static LONG WINAPI CreateKey(HANDLE hcKey, LPCWSTR pszSubKey, DWORD dwOptions, REGSAM samDesired, PSECURITY_ATTRIBUTES pSecurityAttributes, PHANDLE phckResult, PDWORD pdwDisposition, HANDLE hSpooler)
50{
51 FIXME("stub\n");
53}
54
55static LONG WINAPI OpenKey(HANDLE hcKey, LPCWSTR pszSubKey, REGSAM samDesired, PHANDLE phkResult, HANDLE hSpooler)
56{
57 FIXME("stub\n");
59}
60
61static LONG WINAPI CloseKey(HANDLE hcKey, HANDLE hSpooler)
62{
63 FIXME("stub\n");
65}
66
67static LONG WINAPI DeleteKey(HANDLE hcKey, LPCWSTR pszSubKey, HANDLE hSpooler)
68{
69 FIXME("stub\n");
71}
72
73static LONG WINAPI EnumKey(HANDLE hcKey, DWORD dwIndex, LPWSTR pszName, PDWORD pcchName, PFILETIME pftLastWriteTime, HANDLE hSpooler)
74{
75 FIXME("stub\n");
77}
78
79static LONG WINAPI QueryInfoKey(HANDLE hcKey, PDWORD pcSubKeys, PDWORD pcbKey, PDWORD pcValues, PDWORD pcbValue, PDWORD pcbData, PDWORD pcbSecurityDescriptor, PFILETIME pftLastWriteTime,
80 HANDLE hSpooler)
81{
82 FIXME("stub\n");
84}
85
86static LONG WINAPI SetValue(HANDLE hcKey, LPCWSTR pszValue, DWORD dwType, const BYTE* pData, DWORD cbData, HANDLE hSpooler)
87{
88 FIXME("stub\n");
90}
91
92static LONG WINAPI DeleteValue(HANDLE hcKey, LPCWSTR pszValue, HANDLE hSpooler)
93{
94 FIXME("stub\n");
96}
97
98static LONG WINAPI EnumValue(HANDLE hcKey, DWORD dwIndex, LPWSTR pszValue, PDWORD pcbValue, PDWORD pType, PBYTE pData, PDWORD pcbData, HANDLE hSpooler)
99{
100 FIXME("stub\n");
102}
103
104static LONG WINAPI QueryValue(HANDLE hcKey, LPCWSTR pszValue, PDWORD pType, PBYTE pData, PDWORD pcbData, HANDLE hSpooler)
105{
106 FIXME("stub\n");
108}
109
111{
112 sizeof(MONITORREG),
113 CreateKey,
114 OpenKey,
115 CloseKey,
116 DeleteKey,
117 EnumKey,
119 SetValue,
121 EnumValue,
123};
124
125BOOL
127{
128 const WCHAR wszMonitorsPath[] = L"SYSTEM\\CurrentControlSet\\Control\\Print\\Monitors";
129 const DWORD cchMonitorsPath = _countof(wszMonitorsPath) - 1;
130
131 DWORD cchMaxSubKey;
132 DWORD cchPrintMonitorName;
133 DWORD dwErrorCode;
134 DWORD dwSubKeys;
135 DWORD i;
136 HINSTANCE hinstPrintMonitor = NULL;
137 HKEY hKey = NULL;
138 HKEY hSubKey = NULL;
139 MONITORINIT MonitorInit;
140 PInitializePrintMonitor pfnInitializePrintMonitor;
141 PInitializePrintMonitor2 pfnInitializePrintMonitor2;
142 PLOCAL_PRINT_MONITOR pPrintMonitor = NULL;
143 PWSTR pwszRegistryPath = NULL;
144
145 TRACE("InitializePrintMonitorList()\n");
146
147 // Initialize an empty list for our Print Monitors.
149
150 // Open the key containing Print Monitors.
151 dwErrorCode = (DWORD)RegOpenKeyExW(HKEY_LOCAL_MACHINE, wszMonitorsPath, 0, KEY_READ, &hKey);
152 if (dwErrorCode != ERROR_SUCCESS)
153 {
154 ERR("RegOpenKeyExW failed with status %lu!\n", dwErrorCode);
155 goto Cleanup;
156 }
157
158 // Get the number of Print Providers and maximum sub key length.
159 dwErrorCode = (DWORD)RegQueryInfoKeyW(hKey, NULL, NULL, NULL, &dwSubKeys, &cchMaxSubKey, NULL, NULL, NULL, NULL, NULL, NULL);
160 if (dwErrorCode != ERROR_SUCCESS)
161 {
162 ERR("RegQueryInfoKeyW failed with status %lu!\n", dwErrorCode);
163 goto Cleanup;
164 }
165
166 // Loop through all available Print Providers.
167 for (i = 0; i < dwSubKeys; i++)
168 {
169 // Cleanup tasks from the previous run
170 if (hSubKey)
171 {
172 RegCloseKey(hSubKey);
173 hSubKey = NULL;
174 }
175
176 if (pwszRegistryPath)
177 {
178 DllFreeSplMem(pwszRegistryPath);
179 pwszRegistryPath = NULL;
180 }
181
182 if (pPrintMonitor)
183 {
184 if (pPrintMonitor->pwszFileName)
185 DllFreeSplMem(pPrintMonitor->pwszFileName);
186
187 if (pPrintMonitor->pwszName)
188 DllFreeSplMem(pPrintMonitor->pwszName);
189
190 DllFreeSplMem(pPrintMonitor);
191 pPrintMonitor = NULL;
192 }
193
194 // Create a new LOCAL_PRINT_MONITOR structure for it.
195 pPrintMonitor = DllAllocSplMem(sizeof(LOCAL_PRINT_MONITOR));
196 if (!pPrintMonitor)
197 {
198 dwErrorCode = ERROR_NOT_ENOUGH_MEMORY;
199 ERR("DllAllocSplMem failed!\n");
200 goto Cleanup;
201 }
202
203 memset( pPrintMonitor, 0, sizeof(LOCAL_PRINT_MONITOR));
204
205 // Allocate memory for the Print Monitor Name.
206 pPrintMonitor->pwszName = DllAllocSplMem((cchMaxSubKey + 1) * sizeof(WCHAR));
207 if (!pPrintMonitor->pwszName)
208 {
209 dwErrorCode = ERROR_NOT_ENOUGH_MEMORY;
210 ERR("DllAllocSplMem failed!\n");
211 goto Cleanup;
212 }
213
214 // Get the name of this Print Monitor.
215 cchPrintMonitorName = cchMaxSubKey + 1;
216 dwErrorCode = (DWORD)RegEnumKeyExW(hKey, i, pPrintMonitor->pwszName, &cchPrintMonitorName, NULL, NULL, NULL, NULL);
217 if (dwErrorCode != ERROR_SUCCESS)
218 {
219 ERR("RegEnumKeyExW failed for iteration %lu with status %lu!\n", i, dwErrorCode);
220 continue;
221 }
222
223 // Open this Print Monitor's registry key.
224 dwErrorCode = (DWORD)RegOpenKeyExW(hKey, pPrintMonitor->pwszName, 0, KEY_READ, &hSubKey);
225 if (dwErrorCode != ERROR_SUCCESS)
226 {
227 ERR("RegOpenKeyExW failed for Print Provider \"%S\" with status %lu!\n", pPrintMonitor->pwszName, dwErrorCode);
228 continue;
229 }
230
231 // Get the file name of the Print Monitor.
232 pPrintMonitor->pwszFileName = AllocAndRegQueryWSZ(hSubKey, L"Driver");
233 if (!pPrintMonitor->pwszFileName)
234 continue;
235
236 // Try to load it.
237 hinstPrintMonitor = LoadLibraryW(pPrintMonitor->pwszFileName);
238 if (!hinstPrintMonitor)
239 {
240 ERR("LoadLibraryW failed for \"%S\" with error %lu!\n", pPrintMonitor->pwszFileName, GetLastError());
241 continue;
242 }
243
244 pPrintMonitor->hModule = hinstPrintMonitor;
245
246 // Try to find a Level 2 initialization routine first.
247 pfnInitializePrintMonitor2 = (PInitializePrintMonitor2)GetProcAddress(hinstPrintMonitor, "InitializePrintMonitor2");
248 if (pfnInitializePrintMonitor2)
249 {
250 // Prepare a MONITORINIT structure.
251 MonitorInit.cbSize = sizeof(MONITORINIT);
252 MonitorInit.bLocal = TRUE;
253
254 // TODO: Fill the other fields.
255 MonitorInit.hckRegistryRoot = hKey;
256 MonitorInit.pMonitorReg = &MonReg;
257
258 // Call the Level 2 initialization routine.
259 pPrintMonitor->pMonitor = (PMONITOR2)pfnInitializePrintMonitor2(&MonitorInit, &pPrintMonitor->hMonitor);
260 if (!pPrintMonitor->pMonitor)
261 {
262 ERR("InitializePrintMonitor2 failed for \"%S\" with error %lu!\n", pPrintMonitor->pwszFileName, GetLastError());
263 continue;
264 }
265 FIXME("InitializePrintMonitor2 loaded.\n");
266 pPrintMonitor->bIsLevel2 = TRUE;
267 }
268 else
269 {
270 // Try to find a Level 1 initialization routine then.
271 pfnInitializePrintMonitor = (PInitializePrintMonitor)GetProcAddress(hinstPrintMonitor, "InitializePrintMonitor");
272 if (pfnInitializePrintMonitor)
273 {
274 // Construct the registry path.
275 pwszRegistryPath = DllAllocSplMem((cchMonitorsPath + 1 + cchPrintMonitorName + 1) * sizeof(WCHAR));
276 if (!pwszRegistryPath)
277 {
278 dwErrorCode = ERROR_NOT_ENOUGH_MEMORY;
279 ERR("DllAllocSplMem failed!\n");
280 goto Cleanup;
281 }
282
283 CopyMemory(pwszRegistryPath, wszMonitorsPath, cchMonitorsPath * sizeof(WCHAR));
284 pwszRegistryPath[cchMonitorsPath] = L'\\';
285 CopyMemory(&pwszRegistryPath[cchMonitorsPath + 1], pPrintMonitor->pwszName, (cchPrintMonitorName + 1) * sizeof(WCHAR));
286
287 // Call the Level 1 initialization routine.
288 pPrintMonitor->pMonitor = (LPMONITOREX)pfnInitializePrintMonitor(pwszRegistryPath);
289 if (!pPrintMonitor->pMonitor)
290 {
291 ERR("InitializePrintMonitor failed for \"%S\" with error %lu!\n", pPrintMonitor->pwszFileName, GetLastError());
292 continue;
293 }
294 }
295 else
296 {
297 ERR("No initialization routine found for \"%S\"!\n", pPrintMonitor->pwszFileName);
298 continue;
299 }
300 }
301
302 // Add this Print Monitor to the list.
303 InsertTailList(&PrintMonitorList, &pPrintMonitor->Entry);
304 FIXME("InitializePrintMonitorList Handle %p\n",pPrintMonitor->hMonitor);
305 pPrintMonitor->refcount++;
306
307 // Don't let the cleanup routine free this.
308 pPrintMonitor = NULL;
309 }
310
311 dwErrorCode = ERROR_SUCCESS;
312
313Cleanup:
314 // Inside the loop
315 if (hSubKey)
316 RegCloseKey(hSubKey);
317
318 if (pwszRegistryPath)
319 DllFreeSplMem(pwszRegistryPath);
320
321 if (pPrintMonitor)
322 {
323 if (pPrintMonitor->pwszFileName)
324 DllFreeSplMem(pPrintMonitor->pwszFileName);
325
326 if (pPrintMonitor->pwszName)
327 DllFreeSplMem(pPrintMonitor->pwszName);
328
329 DllFreeSplMem(pPrintMonitor);
330 }
331
332 // Outside the loop
333 if (hKey)
335
336 SetLastError(dwErrorCode);
337 return (dwErrorCode == ERROR_SUCCESS);
338}
339
340
341static void
342_LocalGetMonitorLevel1(PLOCAL_PRINT_MONITOR pPrintMonitor, PMONITOR_INFO_1W* ppMonitorInfo, PBYTE* ppMonitorInfoEnd, PDWORD pcbNeeded)
343{
344 DWORD cbMonitorName;
345 PCWSTR pwszStrings[1];
346
347 // Calculate the string lengths.
348 if (!ppMonitorInfo)
349 {
350 cbMonitorName = (wcslen(pPrintMonitor->pwszName) + 1) * sizeof(WCHAR);
351
352 *pcbNeeded += sizeof(MONITOR_INFO_1W) + cbMonitorName;
353 return;
354 }
355
356 // Set the pName field.
357 pwszStrings[0] = pPrintMonitor->pwszName;
358
359 // Copy the structure and advance to the next one in the output buffer.
360 *ppMonitorInfoEnd = PackStrings(pwszStrings, (PBYTE)(*ppMonitorInfo), dwMonitorInfo1Offsets, *ppMonitorInfoEnd);
361 (*ppMonitorInfo)++;
362}
363
364static void
365_LocalGetMonitorLevel2(PLOCAL_PRINT_MONITOR pPrintMonitor, PMONITOR_INFO_2W* ppMonitorInfo, PBYTE* ppMonitorInfoEnd, PDWORD pcbNeeded)
366{
367 DWORD cbFileName;
368 DWORD cbMonitorName;
369 PCWSTR pwszStrings[3];
370
371 // Calculate the string lengths.
372 if (!ppMonitorInfo)
373 {
374 cbMonitorName = (wcslen(pPrintMonitor->pwszName) + 1) * sizeof(WCHAR);
375 cbFileName = (wcslen(pPrintMonitor->pwszFileName) + 1) * sizeof(WCHAR);
376
377 *pcbNeeded += sizeof(MONITOR_INFO_2W) + cbMonitorName + cbCurrentEnvironment + cbFileName;
378 return;
379 }
380
381 // Set the pName field.
382 pwszStrings[0] = pPrintMonitor->pwszName;
383
384 // Set the pEnvironment field.
385 pwszStrings[1] = (PWSTR)wszCurrentEnvironment;
386
387 // Set the pDLLName field.
388 pwszStrings[2] = pPrintMonitor->pwszFileName;
389
390 // Copy the structure and advance to the next one in the output buffer.
391 *ppMonitorInfoEnd = PackStrings(pwszStrings, (PBYTE)(*ppMonitorInfo), dwMonitorInfo2Offsets, *ppMonitorInfoEnd);
392 (*ppMonitorInfo)++;
393}
394
397{
398 DWORD dwErrorCode;
399 PBYTE pMonitorInfoEnd;
401 PLOCAL_PRINT_MONITOR pPrintMonitor;
402
403 TRACE("LocalEnumMonitors(%S, %lu, %p, %lu, %p, %p)\n", pName, Level, pMonitors, cbBuf, pcbNeeded, pcReturned);
404
405 // Sanity checks.
406 if (Level > 2)
407 {
408 dwErrorCode = ERROR_INVALID_LEVEL;
409 goto Cleanup;
410 }
411
412 // Begin counting.
413 *pcbNeeded = 0;
414 *pcReturned = 0;
415
416 // Count the required buffer size and the number of monitors.
418 {
420
421 if (Level == 1)
422 _LocalGetMonitorLevel1(pPrintMonitor, NULL, NULL, pcbNeeded);
423 else if (Level == 2)
424 _LocalGetMonitorLevel2(pPrintMonitor, NULL, NULL, pcbNeeded);
425 }
426
427 // Check if the supplied buffer is large enough.
428 if (cbBuf < *pcbNeeded)
429 {
430 dwErrorCode = ERROR_INSUFFICIENT_BUFFER;
431 goto Cleanup;
432 }
433
434 // Copy over the Monitor information.
435 pMonitorInfoEnd = &pMonitors[*pcbNeeded];
436
438 {
440
441 if (Level == 1)
442 _LocalGetMonitorLevel1(pPrintMonitor, (PMONITOR_INFO_1W*)&pMonitors, &pMonitorInfoEnd, NULL);
443 else if (Level == 2)
444 _LocalGetMonitorLevel2(pPrintMonitor, (PMONITOR_INFO_2W*)&pMonitors, &pMonitorInfoEnd, NULL);
445
446 (*pcReturned)++;
447 }
448
449 dwErrorCode = ERROR_SUCCESS;
450
451Cleanup:
452 SetLastError(dwErrorCode);
453 return (dwErrorCode == ERROR_SUCCESS);
454}
455
456BOOL
458{
459 const WCHAR wszMonitorsPath[] = L"SYSTEM\\CurrentControlSet\\Control\\Print\\Monitors\\";
460 const DWORD cchMonitorsPath = _countof(wszMonitorsPath) - 1;
461
462 WCHAR wszRegRoot[MAX_PATH] = {0};
463
464 DWORD cchPrintMonitorName;
465 DWORD dwErrorCode;
466 HINSTANCE hinstPrintMonitor = NULL;
467 HKEY hKey = NULL;
468 MONITORINIT MonitorInit;
469 PInitializePrintMonitor pfnInitializePrintMonitor;
470 PInitializePrintMonitor2 pfnInitializePrintMonitor2;
471 PLOCAL_PRINT_MONITOR pPrintMonitor = NULL;
472 PWSTR pwszRegistryPath = NULL;
473
474 FIXME("AddPrintMonitorList( %S, %S)\n",pName, DllName);
475
476 StringCbCopyW(wszRegRoot, sizeof(wszRegRoot), wszMonitorsPath);
477 StringCbCatW(wszRegRoot, sizeof(wszRegRoot), pName);
478
479 // Open the key containing Print Monitors.
480 dwErrorCode = (DWORD)RegOpenKeyW( HKEY_LOCAL_MACHINE, wszRegRoot, &hKey );
481 if (dwErrorCode != ERROR_SUCCESS)
482 {
483 ERR("RegOpenKeyExW %S failed with status %lu!\n", wszRegRoot, dwErrorCode);
484 goto Cleanup;
485 }
486
487 // Create a new LOCAL_PRINT_MONITOR structure for it.
488 pPrintMonitor = DllAllocSplMem(sizeof(LOCAL_PRINT_MONITOR));
489 if (!pPrintMonitor)
490 {
491 dwErrorCode = ERROR_NOT_ENOUGH_MEMORY;
492 ERR("DllAllocSplMem failed!\n");
493 goto Cleanup;
494 }
495
496 memset( pPrintMonitor, 0, sizeof(LOCAL_PRINT_MONITOR));
497
498 // Allocate memory for the Print Monitor Name.
499 pPrintMonitor->pwszName = AllocSplStr( pName );
500 if (!pPrintMonitor->pwszName)
501 {
502 dwErrorCode = ERROR_NOT_ENOUGH_MEMORY;
503 ERR("DllAllocSplMem failed!\n");
504 goto Cleanup;
505 }
506
507 cchPrintMonitorName = wcslen(pPrintMonitor->pwszName);
508
509 if ( DllName == NULL )
510 {
511 DWORD namesize;
512
513 dwErrorCode = RegQueryValueExW( hKey, L"Driver", NULL, NULL, NULL, &namesize );
514
515 if ( dwErrorCode == ERROR_SUCCESS )
516 {
517 DllName = DllAllocSplMem(namesize);
518
519 RegQueryValueExW( hKey, L"Driver", NULL, NULL, (LPBYTE)DllName, &namesize );
520
521 pPrintMonitor->pwszFileName = DllName;
522 }
523 else
524 {
525 ERR("DllName not found\n");
526 goto Cleanup;
527 }
528 }
529 else
530 {
531 pPrintMonitor->pwszFileName = AllocSplStr( DllName );
532 }
533
534 // Try to load it.
535 hinstPrintMonitor = LoadLibraryW(pPrintMonitor->pwszFileName);
536 if (!hinstPrintMonitor)
537 {
538 ERR("LoadLibraryW failed for \"%S\" with error %lu!\n", pPrintMonitor->pwszFileName, GetLastError());
539 dwErrorCode = GetLastError();
540 goto Cleanup;
541 }
542
543 pPrintMonitor->hModule = hinstPrintMonitor;
544
545 // Try to find a Level 2 initialization routine first.
546 pfnInitializePrintMonitor2 = (PInitializePrintMonitor2)GetProcAddress(hinstPrintMonitor, "InitializePrintMonitor2");
547 if (pfnInitializePrintMonitor2)
548 {
549 // Prepare a MONITORINIT structure.
550 MonitorInit.cbSize = sizeof(MONITORINIT);
551 MonitorInit.bLocal = TRUE;
552
553 // TODO: Fill the other fields.
554 MonitorInit.hckRegistryRoot = hKey;
555 MonitorInit.pMonitorReg = &MonReg;
556
557 // Call the Level 2 initialization routine.
558 pPrintMonitor->pMonitor = (PMONITOR2)pfnInitializePrintMonitor2(&MonitorInit, &pPrintMonitor->hMonitor);
559 if (!pPrintMonitor->pMonitor)
560 {
561 ERR("InitializePrintMonitor2 failed for \"%S\" with error %lu!\n", pPrintMonitor->pwszFileName, GetLastError());
562 goto Cleanup;
563 }
564
565 pPrintMonitor->bIsLevel2 = TRUE;
566 }
567 else
568 {
569 // Try to find a Level 1 initialization routine then.
570 pfnInitializePrintMonitor = (PInitializePrintMonitor)GetProcAddress(hinstPrintMonitor, "InitializePrintMonitor");
571 if (pfnInitializePrintMonitor)
572 {
573 // Construct the registry path.
574 pwszRegistryPath = DllAllocSplMem((cchMonitorsPath + 1 + cchPrintMonitorName + 1) * sizeof(WCHAR));
575 if (!pwszRegistryPath)
576 {
577 dwErrorCode = ERROR_NOT_ENOUGH_MEMORY;
578 ERR("DllAllocSplMem failed!\n");
579 goto Cleanup;
580 }
581
582 CopyMemory(pwszRegistryPath, wszMonitorsPath, cchMonitorsPath * sizeof(WCHAR));
583 pwszRegistryPath[cchMonitorsPath] = L'\\';
584 CopyMemory(&pwszRegistryPath[cchMonitorsPath + 1], pPrintMonitor->pwszName, (cchPrintMonitorName + 1) * sizeof(WCHAR));
585
586 // Call the Level 1 initialization routine.
587 pPrintMonitor->pMonitor = (LPMONITOREX)pfnInitializePrintMonitor(pwszRegistryPath);
588 if (!pPrintMonitor->pMonitor)
589 {
590 ERR("InitializePrintMonitor failed for \"%S\" with error %lu!\n", pPrintMonitor->pwszFileName, GetLastError());
591 goto Cleanup;
592 }
593 }
594 else
595 {
596 ERR("No initialization routine found for \"%S\"!\n", pPrintMonitor->pwszFileName);
597 dwErrorCode = ERROR_PROC_NOT_FOUND;
598 goto Cleanup;
599 }
600 }
601 // Add this Print Monitor to the list.
602 InsertTailList(&PrintMonitorList, &pPrintMonitor->Entry);
603 FIXME("AddPrintMonitorList Handle %p\n",pPrintMonitor->hMonitor);
604
605 pPrintMonitor->refcount++;
606
607 // Don't let the cleanup routine free this.
608 pPrintMonitor = NULL;
609
610 dwErrorCode = ERROR_SUCCESS;
611
612Cleanup:
613 if (pwszRegistryPath)
614 DllFreeSplMem(pwszRegistryPath);
615
616 if (pPrintMonitor)
617 {
618 if (pPrintMonitor->pwszFileName)
619 DllFreeSplMem(pPrintMonitor->pwszFileName);
620
621 if (pPrintMonitor->pwszName)
622 DllFreeSplMem(pPrintMonitor->pwszName);
623
624 DllFreeSplMem(pPrintMonitor);
625 }
626
627 // Outside the loop
628 if (hKey)
630
631 SetLastError(dwErrorCode);
632 return (dwErrorCode == ERROR_SUCCESS);
633}
634
637{
640 HKEY hroot = NULL;
641 HKEY hentry = NULL;
642 DWORD disposition;
643 BOOL res = FALSE;
644 const WCHAR wszMonitorsPath[] = L"SYSTEM\\CurrentControlSet\\Control\\Print\\Monitors\\";
645
646 mi2w = (LPMONITOR_INFO_2W) pMonitors;
647
648 FIXME("LocalAddMonitor(%s, %d, %p): %s %s %s\n", debugstr_w(pName), Level, pMonitors,
650
652 {
653 FIXME("server %s not supported\n", debugstr_w(pName));
655 return FALSE;
656 }
657
658 if (!mi2w->pName || (!mi2w->pName[0]) )
659 {
660 FIXME("pName not valid : %s\n", debugstr_w(mi2w->pName));
662 return FALSE;
663 }
664
666 if (!env)
667 return FALSE; /* ERROR_INVALID_ENVIRONMENT */
668
669 if (!mi2w->pDLLName || (!mi2w->pDLLName[0]) )
670 {
671 FIXME("pDLLName not valid : %s\n", debugstr_w(mi2w->pDLLName));
673 return FALSE;
674 }
675
676 if (RegCreateKeyW(HKEY_LOCAL_MACHINE, wszMonitorsPath, &hroot) != ERROR_SUCCESS) {
677 ERR("unable to create key %s\n", debugstr_w(wszMonitorsPath));
678 return FALSE;
679 }
680
681 if (RegCreateKeyExW(hroot, mi2w->pName, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE | KEY_QUERY_VALUE, NULL, &hentry, &disposition) == ERROR_SUCCESS)
682 {
683 /* Some installers set options for the port before calling AddMonitor.
684 We query the "Driver" entry to verify that the monitor is installed,
685 before we return an error.
686 When a user installs two print monitors at the same time with the
687 same name, a race condition is possible but silently ignored. */
688
689 DWORD namesize = 0;
690
691 if ((disposition == REG_OPENED_EXISTING_KEY) &&
692 (RegQueryValueExW(hentry, L"Driver", NULL, NULL, NULL, &namesize) == ERROR_SUCCESS))
693 {
694 FIXME("monitor %s already exists\n", debugstr_w(mi2w->pName));
695 /* 9x use ERROR_ALREADY_EXISTS */
697 }
698 else
699 {
700 INT len = (lstrlenW(mi2w->pDLLName) +1) * sizeof(WCHAR);
701
702 res = (RegSetValueExW(hentry, L"Driver", 0, REG_SZ, (LPBYTE) mi2w->pDLLName, len) == ERROR_SUCCESS);
703
704 /* Load and initialize the monitor. SetLastError() is called on failure */
705
706 res = AddPrintMonitorList( mi2w->pName, mi2w->pDLLName );
707
708 if ( !res )
709 {
710 RegDeleteKeyW(hroot, mi2w->pName);
711 }
712 else
713 SetLastError(ERROR_SUCCESS); /* Monitor installer depends on this */
714 }
715
716 RegCloseKey(hentry);
717 }
718
719 RegCloseKey(hroot);
720 return res;
721}
722
724LocalDeleteMonitor(PWSTR pName, PWSTR pEnvironment, PWSTR pMonitorName)
725{
726 HKEY hroot = NULL;
727 LONG lres;
728 PLOCAL_PRINT_MONITOR pPrintMonitor;
729 const WCHAR wszMonitorsPath[] = L"SYSTEM\\CurrentControlSet\\Control\\Print\\Monitors\\";
730
731 FIXME("LocalDeleteMonitor(%s, %s, %s)\n",debugstr_w(pName),debugstr_w(pEnvironment),
732 debugstr_w(pMonitorName));
733
735 if (lres)
736 {
737 FIXME("server %s not supported\n", debugstr_w(pName));
739 return FALSE;
740 }
741
742 /* pEnvironment is ignored in Windows for the local Computer */
743 if (!pMonitorName || !pMonitorName[0])
744 {
745 ERR("pMonitorName %s is invalid\n", debugstr_w(pMonitorName));
747 return FALSE;
748 }
749
750 pPrintMonitor = FindPrintMonitor( pMonitorName );
751 if ( pPrintMonitor )
752 {
753 if ( pPrintMonitor->refcount ) pPrintMonitor->refcount--;
754
755 if ( pPrintMonitor->refcount == 0 )
756 { /* Unload the monitor if it's loaded */
757 RemoveEntryList(&pPrintMonitor->Entry);
758
759 if ( pPrintMonitor->bIsLevel2 )
760 {
761 PMONITOR2 pm2 = pPrintMonitor->pMonitor;
762 if ( pm2 && pm2->pfnShutdown )
763 {
764 pm2->pfnShutdown(pPrintMonitor->hMonitor);
765 }
766 }
767
768 if ( pPrintMonitor->hModule )
769 FreeLibrary(pPrintMonitor->hModule);
770
771 if (pPrintMonitor->pwszFileName)
772 DllFreeSplStr(pPrintMonitor->pwszFileName);
773
774 if (pPrintMonitor->pwszName)
775 DllFreeSplStr(pPrintMonitor->pwszName);
776
777 DllFreeSplMem(pPrintMonitor);
778 pPrintMonitor = NULL;
779 }
780 }
781 else
782 {
783 FIXME("Could not find %s\n", debugstr_w(pMonitorName));
784 }
785
786 if (RegCreateKeyW(HKEY_LOCAL_MACHINE, wszMonitorsPath, &hroot) != ERROR_SUCCESS)
787 {
788 ERR("unable to create key %s\n", debugstr_w(wszMonitorsPath));
789 return FALSE;
790 }
791
792 if (RegDeleteTreeW(hroot, pMonitorName) == ERROR_SUCCESS)
793 {
794 FIXME("%s deleted\n", debugstr_w(pMonitorName));
795 RegCloseKey(hroot);
796 return TRUE;
797 }
798
799 FIXME("%s does not exist\n", debugstr_w(pMonitorName));
800 RegCloseKey(hroot);
801
802 /* NT: ERROR_UNKNOWN_PRINT_MONITOR (3000), 9x: ERROR_INVALID_PARAMETER (87) */
804 return FALSE;
805}
PBYTE WINAPI PackStrings(PCWSTR *pSource, PBYTE pDest, const DWORD *DestOffsets, PBYTE pEnd)
Definition: tools.c:39
const WCHAR wszCurrentEnvironment[]
Definition: prtprocenv.h:11
#define FIXME(fmt,...)
Definition: debug.h:111
#define ERR(fmt,...)
Definition: debug.h:110
#define RegCloseKey(hKey)
Definition: registry.h:49
LSTATUS WINAPI RegDeleteTreeW(_In_ HKEY, _In_opt_ LPCWSTR)
static LPCWSTR LPCWSTR LPCWSTR env
Definition: db.cpp:170
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
LONG WINAPI RegCreateKeyExW(_In_ HKEY hKey, _In_ LPCWSTR lpSubKey, _In_ DWORD Reserved, _In_opt_ LPWSTR lpClass, _In_ DWORD dwOptions, _In_ REGSAM samDesired, _In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes, _Out_ PHKEY phkResult, _Out_opt_ LPDWORD lpdwDisposition)
Definition: reg.c:1096
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3362
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:2533
LONG WINAPI RegOpenKeyW(HKEY hKey, LPCWSTR lpSubKey, PHKEY phkResult)
Definition: reg.c:3297
LONG WINAPI RegSetValueExW(_In_ HKEY hKey, _In_ LPCWSTR lpValueName, _In_ DWORD Reserved, _In_ DWORD dwType, _In_ CONST BYTE *lpData, _In_ DWORD cbData)
Definition: reg.c:4911
LONG WINAPI RegDeleteKeyW(_In_ HKEY hKey, _In_ LPCWSTR lpSubKey)
Definition: reg.c:1239
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:3691
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4132
LONG WINAPI RegCreateKeyW(HKEY hKey, LPCWSTR lpSubKey, PHKEY phkResult)
Definition: reg.c:1201
#define ERROR_CALL_NOT_IMPLEMENTED
Definition: compat.h:102
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define SetLastError(x)
Definition: compat.h:752
#define GetProcAddress(x, y)
Definition: compat.h:753
#define FreeLibrary(x)
Definition: compat.h:748
#define MAX_PATH
Definition: compat.h:34
#define LoadLibraryW(x)
Definition: compat.h:747
#define ERROR_ACCESS_DENIED
Definition: compat.h:97
#define ERROR_INVALID_NAME
Definition: compat.h:103
#define lstrlenW
Definition: compat.h:750
static const WCHAR Cleanup[]
Definition: register.c:80
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
#define InsertTailList(ListHead, Entry)
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
FxAutoRegKey hKey
PLIST_ENTRY pEntry
Definition: fxioqueue.cpp:4484
GLuint res
Definition: glext.h:9613
GLenum GLsizei len
Definition: glext.h:6722
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
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define debugstr_w
Definition: kernel32.h:32
#define REG_SZ
Definition: layer.c:22
static LPMONITOR2 pm2
Definition: localmon.c:46
static LPSTR pName
Definition: security.c:75
@ SetValue
Definition: shader.c:1968
int DeleteValue()
Definition: movefile.cpp:60
#define KEY_READ
Definition: nt_native.h:1023
#define REG_OPTION_NON_VOLATILE
Definition: nt_native.h:1057
#define KEY_QUERY_VALUE
Definition: nt_native.h:1016
#define KEY_WRITE
Definition: nt_native.h:1031
#define DWORD
Definition: nt_native.h:44
#define REG_OPENED_EXISTING_KEY
Definition: nt_native.h:1085
#define MAXDWORD
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:455
#define L(x)
Definition: ntvdm.h:50
BYTE * PBYTE
Definition: pedump.c:66
DWORD * PDWORD
Definition: pedump.c:68
long LONG
Definition: pedump.c:60
static LONG WINAPI CloseKey(HANDLE hcKey, HANDLE hSpooler)
Definition: monitors.c:61
BOOL WINAPI LocalEnumMonitors(PWSTR pName, DWORD Level, PBYTE pMonitors, DWORD cbBuf, PDWORD pcbNeeded, PDWORD pcReturned)
Definition: monitors.c:396
PLOCAL_PRINT_MONITOR FindPrintMonitor(PCWSTR pwszName)
Definition: monitors.c:28
BOOL InitializePrintMonitorList(void)
Definition: monitors.c:126
BOOL WINAPI LocalDeleteMonitor(PWSTR pName, PWSTR pEnvironment, PWSTR pMonitorName)
Definition: monitors.c:724
static void _LocalGetMonitorLevel2(PLOCAL_PRINT_MONITOR pPrintMonitor, PMONITOR_INFO_2W *ppMonitorInfo, PBYTE *ppMonitorInfoEnd, PDWORD pcbNeeded)
Definition: monitors.c:365
static LONG WINAPI CreateKey(HANDLE hcKey, LPCWSTR pszSubKey, DWORD dwOptions, REGSAM samDesired, PSECURITY_ATTRIBUTES pSecurityAttributes, PHANDLE phckResult, PDWORD pdwDisposition, HANDLE hSpooler)
Definition: monitors.c:49
LIST_ENTRY PrintMonitorList
Definition: monitors.c:11
static MONITORREG MonReg
Definition: monitors.c:110
BOOL WINAPI LocalAddMonitor(PWSTR pName, DWORD Level, PBYTE pMonitors)
Definition: monitors.c:636
static LONG WINAPI QueryValue(HANDLE hcKey, LPCWSTR pszValue, PDWORD pType, PBYTE pData, PDWORD pcbData, HANDLE hSpooler)
Definition: monitors.c:104
static LONG WINAPI OpenKey(HANDLE hcKey, LPCWSTR pszSubKey, REGSAM samDesired, PHANDLE phkResult, HANDLE hSpooler)
Definition: monitors.c:55
static LONG WINAPI QueryInfoKey(HANDLE hcKey, PDWORD pcSubKeys, PDWORD pcbKey, PDWORD pcValues, PDWORD pcbValue, PDWORD pcbData, PDWORD pcbSecurityDescriptor, PFILETIME pftLastWriteTime, HANDLE hSpooler)
Definition: monitors.c:79
static LONG WINAPI EnumValue(HANDLE hcKey, DWORD dwIndex, LPWSTR pszValue, PDWORD pcbValue, PDWORD pType, PBYTE pData, PDWORD pcbData, HANDLE hSpooler)
Definition: monitors.c:98
static LONG WINAPI EnumKey(HANDLE hcKey, DWORD dwIndex, LPWSTR pszName, PDWORD pcchName, PFILETIME pftLastWriteTime, HANDLE hSpooler)
Definition: monitors.c:73
static LONG WINAPI DeleteKey(HANDLE hcKey, LPCWSTR pszSubKey, HANDLE hSpooler)
Definition: monitors.c:67
BOOL AddPrintMonitorList(LPCWSTR pName, LPWSTR DllName)
Definition: monitors.c:457
static DWORD dwMonitorInfo1Offsets[]
Definition: monitors.c:14
static DWORD dwMonitorInfo2Offsets[]
Definition: monitors.c:19
static void _LocalGetMonitorLevel1(PLOCAL_PRINT_MONITOR pPrintMonitor, PMONITOR_INFO_1W *ppMonitorInfo, PBYTE *ppMonitorInfoEnd, PDWORD pcbNeeded)
Definition: monitors.c:342
struct _MONITORINIT MONITORINIT
struct _MONITOR2 * PMONITOR2
struct _MONITORREG MONITORREG
struct _MONITOREX * LPMONITOREX
_Check_return_ _CRTIMP int __cdecl _wcsicmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
#define memset(x, y, z)
Definition: compat.h:39
#define _countof(array)
Definition: sndvol32.h:68
#define TRACE(s)
Definition: solgame.cpp:4
DWORD dwOptions
Definition: solitaire.cpp:25
STRSAFEAPI StringCbCopyW(STRSAFE_LPWSTR pszDest, size_t cbDest, STRSAFE_LPCWSTR pszSrc)
Definition: strsafe.h:166
STRSAFEAPI StringCbCatW(STRSAFE_LPWSTR pszDest, size_t cbDest, STRSAFE_LPCWSTR pszSrc)
Definition: strsafe.h:342
base of all file and directory entries
Definition: entries.h:83
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
LIST_ENTRY Entry
Definition: precomp.h:73
BOOL bLocal
Definition: winsplp.h:750
DWORD cbSize
Definition: winsplp.h:746
HKEYMONITOR hckRegistryRoot
Definition: winsplp.h:748
PMONITORREG pMonitorReg
Definition: winsplp.h:749
LPWSTR pEnvironment
Definition: winspool.h:834
LPWSTR pDLLName
Definition: winspool.h:835
TW_UINT32 TW_UINT16 TW_UINT16 TW_MEMREF pData
Definition: twain.h:1830
uint16_t * PWSTR
Definition: typedefs.h:56
const uint16_t * PCWSTR
Definition: typedefs.h:57
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
unsigned char * LPBYTE
Definition: typedefs.h:53
int32_t INT
Definition: typedefs.h:58
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
BOOL WINAPI DllFreeSplMem(PVOID pMem)
Definition: memory.c:112
PVOID WINAPI DllAllocSplMem(DWORD dwBytes)
Definition: memory.c:95
BOOL WINAPI DllFreeSplStr(PWSTR pwszString)
Definition: memory.c:130
PWSTR WINAPI AllocSplStr(PCWSTR pwszInput)
Definition: memory.c:56
LONG copy_servername_from_name(LPCWSTR name, LPWSTR target)
Definition: tools.c:89
LPMONITOR2(WINAPI * PInitializePrintMonitor2)(PMONITORINIT, PHANDLE)
Definition: precomp.h:52
const DWORD cbCurrentEnvironment
LPMONITOREX(WINAPI * PInitializePrintMonitor)(PWSTR)
Definition: precomp.h:51
PWSTR AllocAndRegQueryWSZ(HKEY hKey, PCWSTR pwszValueName)
Definition: tools.c:26
PPRINTENV_T validate_envW(LPCWSTR env)
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define CopyMemory
Definition: winbase.h:1710
_In_ DWORD _Out_writes_bytes_to_opt_ pcbData void _Inout_ DWORD * pcbData
Definition: wincrypt.h:4950
_In_ DWORD _Out_ PDWORD pcbNeeded
Definition: winddi.h:3828
#define WINAPI
Definition: msvc.h:6
#define ERROR_INVALID_LEVEL
Definition: winerror.h:196
#define ERROR_UNKNOWN_PRINT_MONITOR
Definition: winerror.h:1205
#define ERROR_PROC_NOT_FOUND
Definition: winerror.h:199
#define ERROR_PRINT_MONITOR_ALREADY_INSTALLED
Definition: winerror.h:1211
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
ACCESS_MASK REGSAM
Definition: winreg.h:69
struct _MONITOR_INFO_1W MONITOR_INFO_1W
struct _MONITOR_INFO_2W MONITOR_INFO_2W
struct _MONITOR_INFO_2W * LPMONITOR_INFO_2W
_IRQL_requires_same_ typedef _In_ ULONG _In_ UCHAR Level
Definition: wmitypes.h:56
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
unsigned char BYTE
Definition: xxhash.c:193