4 * Copyright 1996 John Harvey
5 * Copyright 1998 Andreas Mohr
6 * Copyright 1999 Klaas van Gend, Huw D M Davies
16 #include "debugtools.h"
20 DEFAULT_DEBUG_CHANNEL(winspool
)
22 CRITICAL_SECTION PRINT32_RegistryBlocker
;
24 typedef struct _OPENEDPRINTERA
28 LPPRINTER_DEFAULTSA lpDefault
;
29 } OPENEDPRINTERA
, *LPOPENEDPRINTERA
;
31 /* The OpenedPrinter Table dynamic array */
32 static HDPA pOpenedPrinterDPA
= NULL
;
34 extern HDPA (WINAPI
* WINSPOOL_DPA_CreateEx
) (INT
, HANDLE
);
35 extern LPVOID (WINAPI
* WINSPOOL_DPA_GetPtr
) (const HDPA
, INT
);
36 extern INT (WINAPI
* WINSPOOL_DPA_InsertPtr
) (const HDPA
, INT
, LPVOID
);
38 static char Printers
[] =
39 "System\\CurrentControlSet\\control\\Print\\Printers\\";
40 static char Drivers
[] =
41 "System\\CurrentControlSet\\control\\Print\\Environments\\Windows 4.0\\Drivers\\"; /* Hmm, well */
43 /******************************************************************
44 * WINSPOOL_GetOpenedPrinterEntryA
45 * Get the first place empty in the opened printer table
47 static LPOPENEDPRINTERA
WINSPOOL_GetOpenedPrinterEntryA()
50 LPOPENEDPRINTERA pOpenedPrinter
;
53 * Create the opened printers' handle dynamic array.
55 if (!pOpenedPrinterDPA
)
57 pOpenedPrinterDPA
= WINSPOOL_DPA_CreateEx(10, GetProcessHeap());
58 for (i
= 0; i
< 10; i
++)
60 pOpenedPrinter
= HeapAlloc(GetProcessHeap(),
62 sizeof(OPENEDPRINTERA
));
63 pOpenedPrinter
->hPrinter
= -1;
64 WINSPOOL_DPA_InsertPtr(pOpenedPrinterDPA
, i
, pOpenedPrinter
);
69 * Search for a handle not yet allocated.
71 for (i
= 0; i
< pOpenedPrinterDPA
->nItemCount
; i
++)
73 pOpenedPrinter
= WINSPOOL_DPA_GetPtr(pOpenedPrinterDPA
, i
);
75 if (pOpenedPrinter
->hPrinter
== -1)
77 pOpenedPrinter
->hPrinter
= i
+ 1;
78 return pOpenedPrinter
;
83 * Didn't find one, insert new element in the array.
85 if (i
== pOpenedPrinterDPA
->nItemCount
)
87 pOpenedPrinter
= HeapAlloc(GetProcessHeap(),
89 sizeof(OPENEDPRINTERA
));
90 pOpenedPrinter
->hPrinter
= i
+ 1;
91 WINSPOOL_DPA_InsertPtr(pOpenedPrinterDPA
, i
, pOpenedPrinter
);
92 return pOpenedPrinter
;
98 /******************************************************************
99 * WINSPOOL_GetOpenedPrinterA
100 * Get the pointer to the opened printer referred by the handle
102 static LPOPENEDPRINTERA
WINSPOOL_GetOpenedPrinterA(int printerHandle
)
104 LPOPENEDPRINTERA pOpenedPrinter
;
106 if(!pOpenedPrinterDPA
) return NULL
;
107 if((printerHandle
<=0) ||
108 (printerHandle
> (pOpenedPrinterDPA
->nItemCount
- 1)))
111 pOpenedPrinter
= WINSPOOL_DPA_GetPtr(pOpenedPrinterDPA
, printerHandle
-1);
113 return pOpenedPrinter
;
116 /******************************************************************
117 * DeviceCapabilities32A [WINSPOOL.151]
120 INT WINAPI
DeviceCapabilitiesA(LPCSTR pDeivce
,LPCSTR pPort
, WORD cap
,
121 LPSTR pOutput
, LPDEVMODEA lpdm
)
124 ret
= GDI_CallDeviceCapabilities16(pDeivce
, pPort
, cap
, pOutput
, lpdm
);
126 /* If DC_PAPERSIZE map POINT16s to POINTs */
127 if(ret
!= -1 && cap
== DC_PAPERSIZE
&& pOutput
) {
128 POINT16
*tmp
= HeapAlloc( GetProcessHeap(), 0, ret
* sizeof(POINT16
) );
130 memcpy(tmp
, pOutput
, ret
* sizeof(POINT16
));
131 for(i
= 0; i
< ret
; i
++)
132 CONV_POINT16TO32(tmp
+ i
, (POINT
*)pOutput
+ i
);
133 HeapFree( GetProcessHeap(), 0, tmp
);
139 /*****************************************************************************
140 * DeviceCapabilities32W
142 INT WINAPI
DeviceCapabilitiesW(LPCWSTR pDevice
, LPCWSTR pPort
,
143 WORD fwCapability
, LPWSTR pOutput
,
144 const DEVMODEW
*pDevMode
)
146 FIXME("(%p,%p,%d,%p,%p): stub\n",
147 pDevice
, pPort
, fwCapability
, pOutput
, pDevMode
);
151 /******************************************************************
152 * DocumentProperties32A [WINSPOOL.155]
155 LONG WINAPI
DocumentPropertiesA(HWND hWnd
,HANDLE hPrinter
,
156 LPSTR pDeviceName
, LPDEVMODEA pDevModeOutput
,
157 LPDEVMODEA pDevModeInput
,DWORD fMode
)
159 LPOPENEDPRINTERA lpOpenedPrinter
;
160 LPSTR lpName
= pDeviceName
;
162 TRACE("(%d,%d,%s,%p,%p,%ld)\n",
163 hWnd
,hPrinter
,pDeviceName
,pDevModeOutput
,pDevModeInput
,fMode
167 lpOpenedPrinter
= WINSPOOL_GetOpenedPrinterA(hPrinter
);
168 if(!lpOpenedPrinter
) {
169 SetLastError(ERROR_INVALID_HANDLE
);
172 lpName
= lpOpenedPrinter
->lpsPrinterName
;
175 return GDI_CallExtDeviceMode16(hWnd
, pDevModeOutput
, lpName
, "LPT1:",
176 pDevModeInput
, NULL
, fMode
);
181 /*****************************************************************************
182 * DocumentProperties32W
184 LONG WINAPI
DocumentPropertiesW(HWND hWnd
, HANDLE hPrinter
,
186 LPDEVMODEW pDevModeOutput
,
187 LPDEVMODEW pDevModeInput
, DWORD fMode
)
189 FIXME("(%d,%d,%s,%p,%p,%ld): stub\n",
190 hWnd
,hPrinter
,debugstr_w(pDeviceName
),pDevModeOutput
,pDevModeInput
,
196 /******************************************************************
197 * OpenPrinter32A [WINSPOOL.196]
200 BOOL WINAPI
OpenPrinterA(LPSTR lpPrinterName
,HANDLE
*phPrinter
,
201 LPPRINTER_DEFAULTSA pDefault
)
203 /* Not implemented: use the DesiredAccess of pDefault to set
204 the access rights to the printer */
206 LPOPENEDPRINTERA lpOpenedPrinter
;
207 HKEY hkeyPrinters
, hkeyPrinter
;
209 if (!lpPrinterName
) {
210 WARN("(printerName: NULL, pDefault %p Ret: False\n", pDefault
);
211 SetLastError(ERROR_INVALID_PARAMETER
);
215 TRACE("(printerName: %s, pDefault %p\n", lpPrinterName
, pDefault
);
217 /* Check Printer exists */
218 if(RegCreateKeyA(HKEY_LOCAL_MACHINE
, Printers
, &hkeyPrinters
) !=
220 ERR("Can't create Printers key\n");
221 SetLastError(ERROR_FILE_NOT_FOUND
); /* ?? */
225 if(RegOpenKeyA(hkeyPrinters
, lpPrinterName
, &hkeyPrinter
)
227 WARN("Can't find printer `%s' in registry\n", lpPrinterName
);
228 RegCloseKey(hkeyPrinters
);
229 SetLastError(ERROR_INVALID_PARAMETER
);
232 RegCloseKey(hkeyPrinter
);
233 RegCloseKey(hkeyPrinters
);
235 if(!phPrinter
) /* This seems to be what win95 does anyway */
238 /* Get a place in the opened printer buffer*/
239 lpOpenedPrinter
= WINSPOOL_GetOpenedPrinterEntryA();
240 if(!lpOpenedPrinter
) {
241 ERR("Can't allocate printer slot\n");
242 SetLastError(ERROR_OUTOFMEMORY
);
246 /* Get the name of the printer */
247 lpOpenedPrinter
->lpsPrinterName
=
248 HEAP_strdupA( GetProcessHeap(), 0, lpPrinterName
);
250 /* Get the unique handle of the printer*/
251 *phPrinter
= lpOpenedPrinter
->hPrinter
;
253 if (pDefault
!= NULL
) {
254 lpOpenedPrinter
->lpDefault
=
255 HeapAlloc(GetProcessHeap(), 0, sizeof(PRINTER_DEFAULTSA
));
256 lpOpenedPrinter
->lpDefault
->pDevMode
=
257 HeapAlloc(GetProcessHeap(), 0, sizeof(DEVMODEA
));
258 memcpy(lpOpenedPrinter
->lpDefault
->pDevMode
, pDefault
->pDevMode
,
260 lpOpenedPrinter
->lpDefault
->pDatatype
=
261 HEAP_strdupA( GetProcessHeap(), 0, pDefault
->pDatatype
);
262 lpOpenedPrinter
->lpDefault
->DesiredAccess
=
263 pDefault
->DesiredAccess
;
270 /******************************************************************
271 * OpenPrinter32W [WINSPOOL.197]
274 BOOL WINAPI
OpenPrinterW(LPWSTR lpPrinterName
,HANDLE
*phPrinter
,
275 LPPRINTER_DEFAULTSW pDefault
)
277 FIXME("(%s,%p,%p):stub\n",debugstr_w(lpPrinterName
), phPrinter
,
279 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
283 /******************************************************************
284 * AddMonitor32A [WINSPOOL.107]
287 BOOL WINAPI
AddMonitorA(LPSTR pName
, DWORD Level
, LPBYTE pMonitors
)
289 FIXME("(%s,%lx,%p):stub!\n", pName
, Level
, pMonitors
);
290 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
294 /******************************************************************
295 * DeletePrinterDriver32A [WINSPOOL.146]
299 DeletePrinterDriverA (LPSTR pName
, LPSTR pEnvironment
, LPSTR pDriverName
)
301 FIXME("(%s,%s,%s):stub\n",debugstr_a(pName
),debugstr_a(pEnvironment
),
302 debugstr_a(pDriverName
));
303 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
308 /******************************************************************
309 * DeleteMonitor32A [WINSPOOL.135]
313 DeleteMonitorA (LPSTR pName
, LPSTR pEnvironment
, LPSTR pMonitorName
)
315 FIXME("(%s,%s,%s):stub\n",debugstr_a(pName
),debugstr_a(pEnvironment
),
316 debugstr_a(pMonitorName
));
317 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
322 /******************************************************************
323 * DeletePort32A [WINSPOOL.137]
327 DeletePortA (LPSTR pName
, HWND hWnd
, LPSTR pPortName
)
329 FIXME("(%s,0x%08x,%s):stub\n",debugstr_a(pName
),hWnd
,
330 debugstr_a(pPortName
));
331 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
335 /******************************************************************************
336 * SetPrinter32W [WINSPOOL.214]
346 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
350 /******************************************************************************
351 * WritePrinter32 [WINSPOOL.223]
361 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
365 /*****************************************************************************
366 * AddForm32A [WINSPOOL.103]
368 BOOL WINAPI
AddFormA(HANDLE hPrinter
, DWORD Level
, LPBYTE pForm
)
370 FIXME("(%d,%ld,%p): stub\n", hPrinter
, Level
, pForm
);
374 /*****************************************************************************
375 * AddForm32W [WINSPOOL.104]
377 BOOL WINAPI
AddFormW(HANDLE hPrinter
, DWORD Level
, LPBYTE pForm
)
379 FIXME("(%d,%ld,%p): stub\n", hPrinter
, Level
, pForm
);
383 /*****************************************************************************
384 * AddJob32A [WINSPOOL.105]
386 BOOL WINAPI
AddJobA(HANDLE hPrinter
, DWORD Level
, LPBYTE pData
,
387 DWORD cbBuf
, LPDWORD pcbNeeded
)
389 FIXME("(%d,%ld,%p,%ld,%p): stub\n", hPrinter
, Level
, pData
, cbBuf
,
394 /*****************************************************************************
395 * AddJob32W [WINSPOOL.106]
397 BOOL WINAPI
AddJobW(HANDLE hPrinter
, DWORD Level
, LPBYTE pData
, DWORD cbBuf
,
400 FIXME("(%d,%ld,%p,%ld,%p): stub\n", hPrinter
, Level
, pData
, cbBuf
,
405 /*****************************************************************************
406 * AddPrinter32A [WINSPOOL.117]
408 HANDLE WINAPI
AddPrinterA(LPSTR pName
, DWORD Level
, LPBYTE pPrinter
)
410 PRINTER_INFO_2A
*pi
= (PRINTER_INFO_2A
*) pPrinter
;
413 HKEY hkeyPrinter
, hkeyPrinters
, hkeyDriver
, hkeyDrivers
;
415 TRACE("(%s,%ld,%p)\n", pName
, Level
, pPrinter
);
418 FIXME("pName = `%s' - unsupported\n", pName
);
419 SetLastError(ERROR_INVALID_PARAMETER
);
423 WARN("Level = %ld\n", Level
);
424 SetLastError(ERROR_INVALID_LEVEL
);
428 SetLastError(ERROR_INVALID_PARAMETER
);
431 if(RegCreateKeyA(HKEY_LOCAL_MACHINE
, Printers
, &hkeyPrinters
) !=
433 ERR("Can't create Printers key\n");
436 if(RegOpenKeyA(hkeyPrinters
, pi
->pPrinterName
, &hkeyPrinter
) ==
438 SetLastError(ERROR_PRINTER_ALREADY_EXISTS
);
439 RegCloseKey(hkeyPrinter
);
440 RegCloseKey(hkeyPrinters
);
443 if(RegCreateKeyA(HKEY_LOCAL_MACHINE
, Drivers
, &hkeyDrivers
) !=
445 ERR("Can't create Drivers key\n");
446 RegCloseKey(hkeyPrinters
);
449 if(RegOpenKeyA(hkeyDrivers
, pi
->pDriverName
, &hkeyDriver
) !=
451 WARN("Can't find driver `%s'\n", pi
->pDriverName
);
452 RegCloseKey(hkeyPrinters
);
453 RegCloseKey(hkeyDrivers
);
454 SetLastError(ERROR_UNKNOWN_PRINTER_DRIVER
);
457 RegCloseKey(hkeyDriver
);
458 RegCloseKey(hkeyDrivers
);
459 if(strcasecmp(pi
->pPrintProcessor
, "WinPrint")) { /* FIXME */
460 WARN("Can't find processor `%s'\n", pi
->pPrintProcessor
);
461 SetLastError(ERROR_UNKNOWN_PRINTPROCESSOR
);
462 RegCloseKey(hkeyPrinters
);
465 if(RegCreateKeyA(hkeyPrinters
, pi
->pPrinterName
, &hkeyPrinter
) !=
467 WARN("Can't create printer `%s'\n", pi
->pPrinterName
);
468 SetLastError(ERROR_INVALID_PRINTER_NAME
);
469 RegCloseKey(hkeyPrinters
);
472 RegSetValueExA(hkeyPrinter
, "Attributes", 0, REG_DWORD
,
473 (LPSTR
)&pi
->Attributes
, sizeof(DWORD
));
474 RegSetValueExA(hkeyPrinter
, "Default DevMode", 0, REG_BINARY
,
475 (LPSTR
)&pi
->pDevMode
,
476 pi
->pDevMode
? pi
->pDevMode
->dmSize
: 0);
477 RegSetValueExA(hkeyPrinter
, "Description", 0, REG_SZ
, pi
->pComment
, 0);
478 RegSetValueExA(hkeyPrinter
, "Location", 0, REG_SZ
, pi
->pLocation
, 0);
479 RegSetValueExA(hkeyPrinter
, "Name", 0, REG_SZ
, pi
->pPrinterName
, 0);
480 RegSetValueExA(hkeyPrinter
, "Parameters", 0, REG_SZ
, pi
->pParameters
, 0);
481 RegSetValueExA(hkeyPrinter
, "Port", 0, REG_SZ
, pi
->pPortName
, 0);
482 RegSetValueExA(hkeyPrinter
, "Print Processor", 0, REG_SZ
,
483 pi
->pPrintProcessor
, 0);
484 RegSetValueExA(hkeyPrinter
, "Printer Driver", 0, REG_SZ
, pi
->pDriverName
,
486 RegSetValueExA(hkeyPrinter
, "Priority", 0, REG_DWORD
,
487 (LPSTR
)&pi
->Priority
, sizeof(DWORD
));
488 RegSetValueExA(hkeyPrinter
, "Separator File", 0, REG_SZ
, pi
->pSepFile
, 0);
489 RegSetValueExA(hkeyPrinter
, "Share Name", 0, REG_SZ
, pi
->pShareName
, 0);
490 RegSetValueExA(hkeyPrinter
, "Start Time", 0, REG_DWORD
,
491 (LPSTR
)&pi
->StartTime
, sizeof(DWORD
));
492 RegSetValueExA(hkeyPrinter
, "Status", 0, REG_DWORD
,
493 (LPSTR
)&pi
->Status
, sizeof(DWORD
));
494 RegSetValueExA(hkeyPrinter
, "Until Time", 0, REG_DWORD
,
495 (LPSTR
)&pi
->UntilTime
, sizeof(DWORD
));
497 RegCloseKey(hkeyPrinter
);
498 RegCloseKey(hkeyPrinters
);
499 if(!OpenPrinterA(pi
->pPrinterName
, &retval
, NULL
)) {
500 ERR("OpenPrinter failing\n");
506 /*****************************************************************************
507 * AddPrinter32W [WINSPOOL.122]
509 HANDLE WINAPI
AddPrinterW(LPWSTR pName
, DWORD Level
, LPBYTE pPrinter
)
511 FIXME("(%p,%ld,%p): stub\n", pName
, Level
, pPrinter
);
516 /*****************************************************************************
517 * ClosePrinter32 [WINSPOOL.126]
519 BOOL WINAPI
ClosePrinter(HANDLE hPrinter
)
521 LPOPENEDPRINTERA lpOpenedPrinter
;
523 TRACE("Handle %d\n", hPrinter
);
525 if (!pOpenedPrinterDPA
)
528 if ((hPrinter
!= -1) && (hPrinter
< (pOpenedPrinterDPA
->nItemCount
- 1)))
530 lpOpenedPrinter
= WINSPOOL_GetOpenedPrinterA(hPrinter
);
531 HeapFree(GetProcessHeap(), 0, lpOpenedPrinter
->lpsPrinterName
);
532 lpOpenedPrinter
->lpsPrinterName
= NULL
;
534 /* Free the memory of lpDefault if it has been initialized*/
535 if(lpOpenedPrinter
->lpDefault
!= NULL
)
537 HeapFree(GetProcessHeap(), 0,
538 lpOpenedPrinter
->lpDefault
->pDevMode
);
539 HeapFree(GetProcessHeap(), 0,
540 lpOpenedPrinter
->lpDefault
->pDatatype
);
541 HeapFree(GetProcessHeap(), 0,
542 lpOpenedPrinter
->lpDefault
);
543 lpOpenedPrinter
->lpDefault
= NULL
;
546 lpOpenedPrinter
->hPrinter
= -1;
553 /*****************************************************************************
554 * DeleteForm32A [WINSPOOL.133]
556 BOOL WINAPI
DeleteFormA(HANDLE hPrinter
, LPSTR pFormName
)
558 FIXME("(%d,%s): stub\n", hPrinter
, pFormName
);
562 /*****************************************************************************
563 * DeleteForm32W [WINSPOOL.134]
565 BOOL WINAPI
DeleteFormW(HANDLE hPrinter
, LPWSTR pFormName
)
567 FIXME("(%d,%s): stub\n", hPrinter
, debugstr_w(pFormName
));
571 /*****************************************************************************
572 * DeletePrinter32 [WINSPOOL.143]
574 BOOL WINAPI
DeletePrinter(HANDLE hPrinter
)
576 FIXME("(%d): stub\n", hPrinter
);
580 /*****************************************************************************
581 * SetPrinter32A [WINSPOOL.211]
583 BOOL WINAPI
SetPrinterA(HANDLE hPrinter
, DWORD Level
, LPBYTE pPrinter
,
586 FIXME("(%d,%ld,%p,%ld): stub\n",hPrinter
,Level
,pPrinter
,Command
);
590 /*****************************************************************************
591 * SetJob32A [WINSPOOL.209]
593 BOOL WINAPI
SetJobA(HANDLE hPrinter
, DWORD JobId
, DWORD Level
,
594 LPBYTE pJob
, DWORD Command
)
596 FIXME("(%d,%ld,%ld,%p,%ld): stub\n",hPrinter
,JobId
,Level
,pJob
,
601 /*****************************************************************************
602 * SetJob32W [WINSPOOL.210]
604 BOOL WINAPI
SetJobW(HANDLE hPrinter
, DWORD JobId
, DWORD Level
,
605 LPBYTE pJob
, DWORD Command
)
607 FIXME("(%d,%ld,%ld,%p,%ld): stub\n",hPrinter
,JobId
,Level
,pJob
,
612 /*****************************************************************************
613 * GetForm32A [WINSPOOL.181]
615 BOOL WINAPI
GetFormA(HANDLE hPrinter
, LPSTR pFormName
, DWORD Level
,
616 LPBYTE pForm
, DWORD cbBuf
, LPDWORD pcbNeeded
)
618 FIXME("(%d,%s,%ld,%p,%ld,%p): stub\n",hPrinter
,pFormName
,
619 Level
,pForm
,cbBuf
,pcbNeeded
);
623 /*****************************************************************************
624 * GetForm32W [WINSPOOL.182]
626 BOOL WINAPI
GetFormW(HANDLE hPrinter
, LPWSTR pFormName
, DWORD Level
,
627 LPBYTE pForm
, DWORD cbBuf
, LPDWORD pcbNeeded
)
629 FIXME("(%d,%s,%ld,%p,%ld,%p): stub\n",hPrinter
,
630 debugstr_w(pFormName
),Level
,pForm
,cbBuf
,pcbNeeded
);
634 /*****************************************************************************
635 * SetForm32A [WINSPOOL.207]
637 BOOL WINAPI
SetFormA(HANDLE hPrinter
, LPSTR pFormName
, DWORD Level
,
640 FIXME("(%d,%s,%ld,%p): stub\n",hPrinter
,pFormName
,Level
,pForm
);
644 /*****************************************************************************
645 * SetForm32W [WINSPOOL.208]
647 BOOL WINAPI
SetFormW(HANDLE hPrinter
, LPWSTR pFormName
, DWORD Level
,
650 FIXME("(%d,%p,%ld,%p): stub\n",hPrinter
,pFormName
,Level
,pForm
);
654 /*****************************************************************************
655 * ReadPrinter32 [WINSPOOL.202]
657 BOOL WINAPI
ReadPrinter(HANDLE hPrinter
, LPVOID pBuf
, DWORD cbBuf
,
658 LPDWORD pNoBytesRead
)
660 FIXME("(%d,%p,%ld,%p): stub\n",hPrinter
,pBuf
,cbBuf
,pNoBytesRead
);
664 /*****************************************************************************
665 * ResetPrinter32A [WINSPOOL.203]
667 BOOL WINAPI
ResetPrinterA(HANDLE hPrinter
, LPPRINTER_DEFAULTSA pDefault
)
669 FIXME("(%d, %p): stub\n", hPrinter
, pDefault
);
673 /*****************************************************************************
674 * ResetPrinter32W [WINSPOOL.204]
676 BOOL WINAPI
ResetPrinterW(HANDLE hPrinter
, LPPRINTER_DEFAULTSW pDefault
)
678 FIXME("(%d, %p): stub\n", hPrinter
, pDefault
);
683 /*****************************************************************************
684 * WINSPOOL_GetStringFromRegA
686 * Get ValueName from hkey storing result in str. buflen is space left in str
688 static BOOL
WINSPOOL_GetStringFromRegA(HKEY hkey
, LPCSTR ValueName
, LPSTR ptr
,
689 DWORD buflen
, DWORD
*needed
)
691 DWORD sz
= buflen
, type
;
694 ret
= RegQueryValueExA(hkey
, ValueName
, 0, &type
, ptr
, &sz
);
696 if(ret
!= ERROR_SUCCESS
&& ret
!= ERROR_MORE_DATA
) {
697 ERR("Got ret = %ld\n", ret
);
704 /*********************************************************************
705 * WINSPOOL_GetPrinter_2A
707 * Fills out a PRINTER_INFO_2A struct storing the strings in buf.
709 static BOOL
WINSPOOL_GetPrinter_2A(HKEY hkeyPrinter
, PRINTER_INFO_2A
*pi2
,
710 LPBYTE buf
, DWORD cbBuf
, LPDWORD pcbNeeded
)
712 DWORD size
, left
= cbBuf
;
713 BOOL space
= (cbBuf
> 0);
718 WINSPOOL_GetStringFromRegA(hkeyPrinter
, "Name", ptr
, left
, &size
);
719 if(space
&& size
<= left
) {
720 pi2
->pPrinterName
= ptr
;
727 WINSPOOL_GetStringFromRegA(hkeyPrinter
, "Port", ptr
, left
, &size
);
728 if(space
&& size
<= left
) {
729 pi2
->pPortName
= ptr
;
736 WINSPOOL_GetStringFromRegA(hkeyPrinter
, "Printer Driver", ptr
, left
,
738 if(space
&& size
<= left
) {
739 pi2
->pDriverName
= ptr
;
746 WINSPOOL_GetStringFromRegA(hkeyPrinter
, "Default DevMode", ptr
, left
,
748 if(space
&& size
<= left
) {
749 pi2
->pDevMode
= (LPDEVMODEA
)ptr
;
756 WINSPOOL_GetStringFromRegA(hkeyPrinter
, "Print Processor", ptr
, left
,
758 if(space
&& size
<= left
) {
759 pi2
->pPrintProcessor
= ptr
;
766 if(!space
&& pi2
) /* zero out pi2 if we can't completely fill buf */
767 memset(pi2
, 0, sizeof(*pi2
));
772 /*********************************************************************
773 * WINSPOOL_GetPrinter_4A
775 * Fills out a PRINTER_INFO_4A struct storing the strings in buf.
777 static BOOL
WINSPOOL_GetPrinter_4A(HKEY hkeyPrinter
, PRINTER_INFO_4A
*pi4
,
778 LPBYTE buf
, DWORD cbBuf
, LPDWORD pcbNeeded
)
780 DWORD size
, left
= cbBuf
;
781 BOOL space
= (cbBuf
> 0);
786 WINSPOOL_GetStringFromRegA(hkeyPrinter
, "Name", ptr
, left
, &size
);
787 if(space
&& size
<= left
) {
788 pi4
->pPrinterName
= ptr
;
796 if(!space
&& pi4
) /* zero out pi4 if we can't completely fill buf */
797 memset(pi4
, 0, sizeof(*pi4
));
802 /*********************************************************************
803 * WINSPOOL_GetPrinter_5A
805 * Fills out a PRINTER_INFO_5A struct storing the strings in buf.
807 static BOOL
WINSPOOL_GetPrinter_5A(HKEY hkeyPrinter
, PRINTER_INFO_5A
*pi5
,
808 LPBYTE buf
, DWORD cbBuf
, LPDWORD pcbNeeded
)
810 DWORD size
, left
= cbBuf
;
811 BOOL space
= (cbBuf
> 0);
816 WINSPOOL_GetStringFromRegA(hkeyPrinter
, "Name", ptr
, left
, &size
);
817 if(space
&& size
<= left
) {
818 pi5
->pPrinterName
= ptr
;
825 WINSPOOL_GetStringFromRegA(hkeyPrinter
, "Port", ptr
, left
, &size
);
826 if(space
&& size
<= left
) {
827 pi5
->pPortName
= ptr
;
834 if(!space
&& pi5
) /* zero out pi5 if we can't completely fill buf */
835 memset(pi5
, 0, sizeof(*pi5
));
840 /*****************************************************************************
841 * GetPrinterA [WINSPOOL.187]
843 BOOL WINAPI
GetPrinterA(HANDLE hPrinter
, DWORD Level
, LPBYTE pPrinter
,
844 DWORD cbBuf
, LPDWORD pcbNeeded
)
846 OPENEDPRINTERA
*lpOpenedPrinter
;
847 DWORD size
, needed
= 0;
849 HKEY hkeyPrinter
, hkeyPrinters
;
852 TRACE("(%d,%ld,%p,%ld,%p)\n",hPrinter
,Level
,pPrinter
,cbBuf
, pcbNeeded
);
854 lpOpenedPrinter
= WINSPOOL_GetOpenedPrinterA(hPrinter
);
855 if(!lpOpenedPrinter
) {
856 SetLastError(ERROR_INVALID_HANDLE
);
859 if(RegCreateKeyA(HKEY_LOCAL_MACHINE
, Printers
, &hkeyPrinters
) !=
861 ERR("Can't create Printers key\n");
864 if(RegOpenKeyA(hkeyPrinters
, lpOpenedPrinter
->lpsPrinterName
, &hkeyPrinter
)
866 ERR("Can't find opened printer `%s' in registry\n",
867 lpOpenedPrinter
->lpsPrinterName
);
868 RegCloseKey(hkeyPrinters
);
869 SetLastError(ERROR_INVALID_PRINTER_NAME
); /* ? */
876 PRINTER_INFO_2A
*pi2
= (PRINTER_INFO_2A
*)pPrinter
;
878 size
= sizeof(PRINTER_INFO_2A
);
880 ptr
= pPrinter
+ size
;
882 memset(pPrinter
, 0, size
);
887 ret
= WINSPOOL_GetPrinter_2A(hkeyPrinter
, pi2
, ptr
, cbBuf
, &needed
);
894 PRINTER_INFO_4A
*pi4
= (PRINTER_INFO_4A
*)pPrinter
;
896 size
= sizeof(PRINTER_INFO_4A
);
898 ptr
= pPrinter
+ size
;
900 memset(pPrinter
, 0, size
);
905 ret
= WINSPOOL_GetPrinter_4A(hkeyPrinter
, pi4
, ptr
, cbBuf
, &needed
);
913 PRINTER_INFO_5A
*pi5
= (PRINTER_INFO_5A
*)pPrinter
;
915 size
= sizeof(PRINTER_INFO_5A
);
917 ptr
= pPrinter
+ size
;
919 memset(pPrinter
, 0, size
);
925 ret
= WINSPOOL_GetPrinter_5A(hkeyPrinter
, pi5
, ptr
, cbBuf
, &needed
);
931 FIXME("Unimplemented level %ld\n", Level
);
932 SetLastError(ERROR_INVALID_LEVEL
);
933 RegCloseKey(hkeyPrinters
);
934 RegCloseKey(hkeyPrinter
);
938 RegCloseKey(hkeyPrinter
);
939 RegCloseKey(hkeyPrinters
);
941 if(pcbNeeded
) *pcbNeeded
= needed
;
943 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
948 /*****************************************************************************
949 * GetPrinterW [WINSPOOL.194]
951 BOOL WINAPI
GetPrinterW(HANDLE hPrinter
, DWORD Level
, LPBYTE pPrinter
,
952 DWORD cbBuf
, LPDWORD pcbNeeded
)
954 FIXME("(%d,%ld,%p,%ld,%p): stub\n", hPrinter
, Level
, pPrinter
,
959 /******************************************************************
960 * EnumPrintersA [WINSPOOL.174]
962 * Enumerates the available printers, print servers and print
963 * providers, depending on the specified flags, name and level.
967 * If level is set to 1:
968 * Not implemented yet!
969 * Returns TRUE with an empty list.
971 * If level is set to 2:
972 * Possible flags: PRINTER_ENUM_CONNECTIONS, PRINTER_ENUM_LOCAL.
973 * Returns an array of PRINTER_INFO_2 data structures in the
974 * lpbPrinters buffer. Note that according to MSDN also an
975 * OpenPrinter should be performed on every remote printer.
977 * If level is set to 4 (officially WinNT only):
978 * Possible flags: PRINTER_ENUM_CONNECTIONS, PRINTER_ENUM_LOCAL.
979 * Fast: Only the registry is queried to retrieve printer names,
980 * no connection to the driver is made.
981 * Returns an array of PRINTER_INFO_4 data structures in the
982 * lpbPrinters buffer.
984 * If level is set to 5 (officially WinNT4/Win9x only):
985 * Fast: Only the registry is queried to retrieve printer names,
986 * no connection to the driver is made.
987 * Returns an array of PRINTER_INFO_5 data structures in the
988 * lpbPrinters buffer.
990 * If level set to 3 or 6+:
991 * returns zero (faillure!)
993 * Returns nonzero (TRUE) on succes, or zero on faillure, use GetLastError
997 * - Only PRINTER_ENUM_LOCAL and PRINTER_ENUM_NAME are implemented.
998 * - Only levels 2, 4 and 5 are implemented at the moment.
999 * - 16-bit printer drivers are not enumerated.
1000 * - Returned amount of bytes used/needed does not match the real Windoze
1001 * implementation (as in this implementation, all strings are part
1002 * of the buffer, whereas Win32 keeps them somewhere else)
1003 * - At level 2, EnumPrinters should also call OpenPrinter for remote printers.
1006 * - In a regular Wine installation, no registry settings for printers
1007 * exist, which makes this function return an empty list.
1009 BOOL WINAPI
EnumPrintersA(
1010 DWORD dwType
, /* Types of print objects to enumerate */
1011 LPSTR lpszName
, /* name of objects to enumerate */
1012 DWORD dwLevel
, /* type of printer info structure */
1013 LPBYTE lpbPrinters
, /* buffer which receives info */
1014 DWORD cbBuf
, /* max size of buffer in bytes */
1015 LPDWORD lpdwNeeded
, /* pointer to var: # bytes used/needed */
1016 LPDWORD lpdwReturned
/* number of entries returned */
1020 HKEY hkeyPrinters
, hkeyPrinter
;
1021 char PrinterName
[255];
1022 DWORD needed
= 0, number
= 0;
1023 DWORD used
, i
, left
;
1027 memset(lpbPrinters
, 0, cbBuf
);
1031 if (!((dwType
& PRINTER_ENUM_LOCAL
) || (dwType
& PRINTER_ENUM_NAME
))) {
1032 FIXME("dwType = %08lx\n", dwType
);
1033 SetLastError(ERROR_INVALID_FLAGS
);
1037 if(RegCreateKeyA(HKEY_LOCAL_MACHINE
, Printers
, &hkeyPrinters
) !=
1039 ERR("Can't create Printers key\n");
1043 if(RegQueryInfoKeyA(hkeyPrinters
, NULL
, NULL
, NULL
, &number
, NULL
, NULL
,
1044 NULL
, NULL
, NULL
, NULL
, NULL
) != ERROR_SUCCESS
) {
1045 RegCloseKey(hkeyPrinters
);
1046 ERR("Can't query Printers key\n");
1049 TRACE("Found %ld printers\n", number
);
1053 RegCloseKey(hkeyPrinters
);
1055 *lpdwReturned
= number
;
1059 used
= number
* sizeof(PRINTER_INFO_2A
);
1062 used
= number
* sizeof(PRINTER_INFO_4A
);
1065 used
= number
* sizeof(PRINTER_INFO_5A
);
1069 SetLastError(ERROR_INVALID_LEVEL
);
1070 RegCloseKey(hkeyPrinters
);
1073 pi
= (used
<= cbBuf
) ? lpbPrinters
: NULL
;
1075 for(i
= 0; i
< number
; i
++) {
1076 if(RegEnumKeyA(hkeyPrinters
, i
, PrinterName
, sizeof(PrinterName
)) !=
1078 ERR("Can't enum key number %ld\n", i
);
1079 RegCloseKey(hkeyPrinters
);
1082 if(RegOpenKeyA(hkeyPrinters
, PrinterName
, &hkeyPrinter
) !=
1084 ERR("Can't open key '%s'\n", PrinterName
);
1085 RegCloseKey(hkeyPrinters
);
1090 buf
= lpbPrinters
+ used
;
1091 left
= cbBuf
- used
;
1099 WINSPOOL_GetPrinter_2A(hkeyPrinter
, (PRINTER_INFO_2A
*)pi
, buf
,
1102 if(pi
) pi
+= sizeof(PRINTER_INFO_2A
);
1105 WINSPOOL_GetPrinter_4A(hkeyPrinter
, (PRINTER_INFO_4A
*)pi
, buf
,
1108 if(pi
) pi
+= sizeof(PRINTER_INFO_4A
);
1111 WINSPOOL_GetPrinter_5A(hkeyPrinter
, (PRINTER_INFO_5A
*)pi
, buf
,
1114 if(pi
) pi
+= sizeof(PRINTER_INFO_5A
);
1117 ERR("Shouldn't be here!\n");
1118 RegCloseKey(hkeyPrinter
);
1119 RegCloseKey(hkeyPrinters
);
1122 RegCloseKey(hkeyPrinter
);
1124 RegCloseKey(hkeyPrinters
);
1130 memset(lpbPrinters
, 0, cbBuf
);
1131 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
1135 *lpdwReturned
= number
;
1136 SetLastError(ERROR_SUCCESS
);
1140 /******************************************************************
1141 * EnumPrintersW [WINSPOOL.175]
1144 BOOL WINAPI
EnumPrintersW(DWORD dwType
, LPWSTR lpszName
,
1145 DWORD dwLevel
, LPBYTE lpbPrinters
,
1146 DWORD cbBuf
, LPDWORD lpdwNeeded
,
1147 LPDWORD lpdwReturned
)
1149 FIXME("Nearly empty stub\n");
1156 /*****************************************************************************
1157 * GetPrinterDriver32A [WINSPOOL.190]
1159 BOOL WINAPI
GetPrinterDriverA(HANDLE hPrinter
, LPSTR pEnvironment
,
1160 DWORD Level
, LPBYTE pDriverInfo
,
1161 DWORD cbBuf
, LPDWORD pcbNeeded
)
1163 OPENEDPRINTERA
*lpOpenedPrinter
;
1164 char DriverName
[100];
1165 DWORD ret
, type
, size
, dw
, needed
= 0;
1167 HKEY hkeyPrinter
, hkeyPrinters
, hkeyDriver
, hkeyDrivers
;
1169 TRACE("(%d,%s,%ld,%p,%ld,%p)\n",hPrinter
,pEnvironment
,
1170 Level
,pDriverInfo
,cbBuf
, pcbNeeded
);
1172 ZeroMemory(pDriverInfo
, cbBuf
);
1174 lpOpenedPrinter
= WINSPOOL_GetOpenedPrinterA(hPrinter
);
1175 if(!lpOpenedPrinter
) {
1176 SetLastError(ERROR_INVALID_HANDLE
);
1180 FIXME("pEnvironment = `%s'\n", pEnvironment
);
1181 SetLastError(ERROR_INVALID_ENVIRONMENT
);
1184 if(Level
< 1 || Level
> 3) {
1185 SetLastError(ERROR_INVALID_LEVEL
);
1188 if(RegCreateKeyA(HKEY_LOCAL_MACHINE
, Printers
, &hkeyPrinters
) !=
1190 ERR("Can't create Printers key\n");
1193 if(RegOpenKeyA(hkeyPrinters
, lpOpenedPrinter
->lpsPrinterName
, &hkeyPrinter
)
1195 ERR("Can't find opened printer `%s' in registry\n",
1196 lpOpenedPrinter
->lpsPrinterName
);
1197 RegCloseKey(hkeyPrinters
);
1198 SetLastError(ERROR_INVALID_PRINTER_NAME
); /* ? */
1201 size
= sizeof(DriverName
);
1202 ret
= RegQueryValueExA(hkeyPrinter
, "Printer Driver", 0, &type
, DriverName
,
1204 RegCloseKey(hkeyPrinter
);
1205 RegCloseKey(hkeyPrinters
);
1206 if(ret
!= ERROR_SUCCESS
) {
1207 ERR("Can't get DriverName for printer `%s'\n",
1208 lpOpenedPrinter
->lpsPrinterName
);
1211 if(RegCreateKeyA(HKEY_LOCAL_MACHINE
, Drivers
, &hkeyDrivers
) !=
1213 ERR("Can't create Drivers key\n");
1216 if(RegOpenKeyA(hkeyDrivers
, DriverName
, &hkeyDriver
)
1218 ERR("Can't find driver `%s' in registry\n", DriverName
);
1219 RegCloseKey(hkeyDrivers
);
1220 SetLastError(ERROR_UNKNOWN_PRINTER_DRIVER
); /* ? */
1226 size
= sizeof(DRIVER_INFO_1A
);
1229 size
= sizeof(DRIVER_INFO_2A
);
1232 size
= sizeof(DRIVER_INFO_3A
);
1235 ERR("Invalid level\n");
1240 ptr
= pDriverInfo
+ size
;
1246 size
= strlen(DriverName
) + 1;
1249 strcpy(ptr
, DriverName
);
1251 ((DRIVER_INFO_1A
*)pDriverInfo
)->pName
= ptr
;
1253 ((DRIVER_INFO_2A
*)pDriverInfo
)->pName
= ptr
;
1259 DRIVER_INFO_2A
*di2
= (DRIVER_INFO_2A
*)pDriverInfo
;
1262 if(RegQueryValueExA(hkeyDriver
, "Version", 0, &type
, (PBYTE
)&dw
,
1265 WARN("Can't get Version\n");
1269 size
= strlen("Wine") + 1; /* FIXME */
1272 strcpy(ptr
, "Wine");
1273 di2
->pEnvironment
= ptr
;
1279 WINSPOOL_GetStringFromRegA(hkeyDriver
, "Driver", ptr
, cbBuf
, &size
);
1280 if(cbBuf
&& size
<= cbBuf
) {
1281 di2
->pDriverPath
= ptr
;
1287 WINSPOOL_GetStringFromRegA(hkeyDriver
, "Data File", ptr
, cbBuf
, &size
);
1288 if(cbBuf
&& size
<= cbBuf
) {
1289 di2
->pDataFile
= ptr
;
1295 WINSPOOL_GetStringFromRegA(hkeyDriver
, "Configuration File", ptr
,
1297 if(cbBuf
&& size
<= cbBuf
) {
1298 di2
->pConfigFile
= ptr
;
1306 DRIVER_INFO_3A
*di3
= (DRIVER_INFO_3A
*)pDriverInfo
;
1308 WINSPOOL_GetStringFromRegA(hkeyDriver
, "Help File", ptr
, cbBuf
, &size
);
1309 if(cbBuf
&& size
<= cbBuf
) {
1310 di3
->pHelpFile
= ptr
;
1316 WINSPOOL_GetStringFromRegA(hkeyDriver
, "Dependent Files", ptr
, cbBuf
,
1318 if(cbBuf
&& size
<= cbBuf
) {
1319 di3
->pDependentFiles
= ptr
;
1325 WINSPOOL_GetStringFromRegA(hkeyDriver
, "Monitor", ptr
, cbBuf
, &size
);
1326 if(cbBuf
&& size
<= cbBuf
) {
1327 di3
->pMonitorName
= ptr
;
1333 WINSPOOL_GetStringFromRegA(hkeyDriver
, "DataType", ptr
, cbBuf
, &size
);
1334 if(cbBuf
&& size
<= cbBuf
) {
1335 di3
->pDefaultDataType
= ptr
;
1341 RegCloseKey(hkeyDriver
);
1342 RegCloseKey(hkeyDrivers
);
1344 if(pcbNeeded
) *pcbNeeded
= needed
;
1345 if(cbBuf
) return TRUE
;
1346 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
1350 /*****************************************************************************
1351 * GetPrinterDriver32W [WINSPOOL.193]
1353 BOOL WINAPI
GetPrinterDriverW(HANDLE hPrinter
, LPWSTR pEnvironment
,
1354 DWORD Level
, LPBYTE pDriverInfo
,
1355 DWORD cbBuf
, LPDWORD pcbNeeded
)
1357 FIXME("(%d,%p,%ld,%p,%ld,%p): stub\n",hPrinter
,pEnvironment
,
1358 Level
,pDriverInfo
,cbBuf
, pcbNeeded
);
1362 /*****************************************************************************
1363 * GetPrinterDriverDirectoryA [WINSPOOL.191]
1365 BOOL WINAPI
GetPrinterDriverDirectoryA(LPSTR pName
, LPSTR pEnvironment
,
1366 DWORD Level
, LPBYTE pDriverDirectory
,
1367 DWORD cbBuf
, LPDWORD pcbNeeded
)
1371 TRACE("(%s, %s, %ld, %p, %ld, %p)\n", pName
, pEnvironment
, Level
,
1372 pDriverDirectory
, cbBuf
, pcbNeeded
);
1374 FIXME("pName = `%s' - unsupported\n", pName
);
1375 SetLastError(ERROR_INVALID_PARAMETER
);
1378 if(pEnvironment
!= NULL
) {
1379 FIXME("pEnvironment = `%s' - unsupported\n", pEnvironment
);
1380 SetLastError(ERROR_INVALID_ENVIRONMENT
);
1383 if(Level
!= 1) /* win95 ignores this so we just carry on */
1384 WARN("Level = %ld - assuming 1\n", Level
);
1386 /* FIXME should read from registry */
1387 needed
= GetSystemDirectoryA(pDriverDirectory
, cbBuf
);
1390 *pcbNeeded
= needed
;
1391 if(needed
> cbBuf
) {
1392 SetLastError(ERROR_INSUFFICIENT_BUFFER
);
1399 /*****************************************************************************
1400 * GetPrinterDriverDirectoryW [WINSPOOL.192]
1402 BOOL WINAPI
GetPrinterDriverDirectoryW(LPWSTR pName
, LPWSTR pEnvironment
,
1403 DWORD Level
, LPBYTE pDriverDirectory
,
1404 DWORD cbBuf
, LPDWORD pcbNeeded
)
1406 LPSTR pNameA
= NULL
, pEnvironmentA
= NULL
;
1410 pNameA
= HEAP_strdupWtoA( GetProcessHeap(), 0, pName
);
1412 pEnvironmentA
= HEAP_strdupWtoA( GetProcessHeap(), 0, pEnvironment
);
1413 ret
= GetPrinterDriverDirectoryA( pNameA
, pEnvironmentA
, Level
,
1414 pDriverDirectory
, cbBuf
, pcbNeeded
);
1416 HeapFree( GetProcessHeap(), 0, pNameA
);
1418 HeapFree( GetProcessHeap(), 0, pEnvironment
);
1423 /*****************************************************************************
1424 * AddPrinterDriver32A [WINSPOOL.120]
1426 BOOL WINAPI
AddPrinterDriverA(LPSTR pName
, DWORD level
, LPBYTE pDriverInfo
)
1429 HKEY hkeyDrivers
, hkeyName
;
1431 TRACE("(%s,%ld,%p)\n",pName
,level
,pDriverInfo
);
1433 if(level
!= 2 && level
!= 3) {
1434 SetLastError(ERROR_INVALID_LEVEL
);
1438 FIXME("pName= `%s' - unsupported\n", pName
);
1439 SetLastError(ERROR_INVALID_PARAMETER
);
1443 WARN("pDriverInfo == NULL");
1444 SetLastError(ERROR_INVALID_PARAMETER
);
1449 di3
= *(DRIVER_INFO_3A
*)pDriverInfo
;
1451 memset(&di3
, 0, sizeof(di3
));
1452 *(DRIVER_INFO_2A
*)&di3
= *(DRIVER_INFO_2A
*)pDriverInfo
;
1455 if(!di3
.pName
|| !di3
.pDriverPath
|| !di3
.pConfigFile
||
1457 SetLastError(ERROR_INVALID_PARAMETER
);
1460 if(!di3
.pDefaultDataType
) di3
.pDefaultDataType
= "";
1461 if(!di3
.pDependentFiles
) di3
.pDependentFiles
= "\0";
1462 if(!di3
.pHelpFile
) di3
.pHelpFile
= "";
1463 if(!di3
.pMonitorName
) di3
.pMonitorName
= "";
1465 if(di3
.pEnvironment
) {
1466 FIXME("pEnvironment = `%s'\n", di3
.pEnvironment
);
1467 SetLastError(ERROR_INVALID_ENVIRONMENT
);
1470 if(RegCreateKeyA(HKEY_LOCAL_MACHINE
, Drivers
, &hkeyDrivers
) !=
1472 ERR("Can't create Drivers key\n");
1476 if(level
== 2) { /* apparently can't overwrite with level2 */
1477 if(RegOpenKeyA(hkeyDrivers
, di3
.pName
, &hkeyName
) == ERROR_SUCCESS
) {
1478 RegCloseKey(hkeyName
);
1479 RegCloseKey(hkeyDrivers
);
1480 WARN("Trying to create existing printer driver `%s'\n", di3
.pName
);
1481 SetLastError(ERROR_PRINTER_DRIVER_ALREADY_INSTALLED
);
1485 if(RegCreateKeyA(hkeyDrivers
, di3
.pName
, &hkeyName
) != ERROR_SUCCESS
) {
1486 RegCloseKey(hkeyDrivers
);
1487 ERR("Can't create Name key\n");
1490 RegSetValueExA(hkeyName
, "Configuration File", 0, REG_SZ
, di3
.pConfigFile
,
1492 RegSetValueExA(hkeyName
, "Data File", 0, REG_SZ
, di3
.pDataFile
, 0);
1493 RegSetValueExA(hkeyName
, "Driver", 0, REG_SZ
, di3
.pDriverPath
, 0);
1494 RegSetValueExA(hkeyName
, "Version", 0, REG_DWORD
, (LPSTR
)&di3
.cVersion
,
1496 RegSetValueExA(hkeyName
, "Datatype", 0, REG_SZ
, di3
.pDefaultDataType
, 0);
1497 RegSetValueExA(hkeyName
, "Dependent Files", 0, REG_MULTI_SZ
,
1498 di3
.pDependentFiles
, 0);
1499 RegSetValueExA(hkeyName
, "Help File", 0, REG_SZ
, di3
.pHelpFile
, 0);
1500 RegSetValueExA(hkeyName
, "Monitor", 0, REG_SZ
, di3
.pMonitorName
, 0);
1501 RegCloseKey(hkeyName
);
1502 RegCloseKey(hkeyDrivers
);
1506 /*****************************************************************************
1507 * AddPrinterDriver32W [WINSPOOL.121]
1509 BOOL WINAPI
AddPrinterDriverW(LPWSTR printerName
,DWORD level
,
1512 FIXME("(%s,%ld,%p): stub\n",debugstr_w(printerName
),
1518 /*****************************************************************************
1519 * PrinterProperties [WINSPOOL.201]
1521 * Displays a dialog to set the properties of the printer.
1524 * nonzero on succes or zero on faillure
1527 * implemented as stub only
1529 BOOL WINAPI
PrinterProperties(HWND hWnd
, /* handle to parent window */
1530 HANDLE hPrinter
/* handle to printer object */
1532 FIXME("(%d,%d): stub\n", hWnd
, hPrinter
);
1533 SetLastError(ERROR_CALL_NOT_IMPLEMENTED
);
1537 /*****************************************************************************
1538 * EnumJobsA [WINSPOOL.162]
1541 BOOL WINAPI
EnumJobsA(HANDLE hPrinter
, DWORD FirstJob
, DWORD NoJobs
,
1542 DWORD Level
, LPBYTE pJob
, DWORD cbBuf
, LPDWORD pcbNeeded
,
1546 if(pcbNeeded
) *pcbNeeded
= 0;
1547 if(pcReturned
) *pcReturned
= 0;
1552 /*****************************************************************************
1553 * EnumJobsW [WINSPOOL.163]
1556 BOOL WINAPI
EnumJobsW(HANDLE hPrinter
, DWORD FirstJob
, DWORD NoJobs
,
1557 DWORD Level
, LPBYTE pJob
, DWORD cbBuf
, LPDWORD pcbNeeded
,
1561 if(pcbNeeded
) *pcbNeeded
= 0;
1562 if(pcReturned
) *pcReturned
= 0;