Fix parameters for MDI_RestoreFrameMenu in WM_DESTROY msg.
[wine.git] / dlls / winspool / info.c
blobf55e84f03d60a466bbe19a5fc0f1cbebc20dc84f
1 /*
2 * WINSPOOL functions
3 *
4 * Copyright 1996 John Harvey
5 * Copyright 1998 Andreas Mohr
6 * Copyright 1999 Klaas van Gend, Huw D M Davies
7 */
9 #include <stdlib.h>
10 #include <string.h>
11 #include <ctype.h>
12 #include "winspool.h"
13 #include "winbase.h"
14 #include "winerror.h"
15 #include "winreg.h"
16 #include "debugtools.h"
17 #include "heap.h"
18 #include "commctrl.h"
20 DEFAULT_DEBUG_CHANNEL(winspool)
22 CRITICAL_SECTION PRINT32_RegistryBlocker;
24 typedef struct _OPENEDPRINTERA
26 LPSTR lpsPrinterName;
27 HANDLE hPrinter;
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()
49 int i;
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(),
61 HEAP_ZERO_MEMORY,
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(),
88 HEAP_ZERO_MEMORY,
89 sizeof(OPENEDPRINTERA));
90 pOpenedPrinter->hPrinter = i + 1;
91 WINSPOOL_DPA_InsertPtr(pOpenedPrinterDPA, i, pOpenedPrinter);
92 return pOpenedPrinter;
95 return NULL;
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)))
109 return NULL;
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)
123 INT ret;
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) );
129 INT i;
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 );
135 return ret;
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);
148 return -1;
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
166 if(!pDeviceName) {
167 lpOpenedPrinter = WINSPOOL_GetOpenedPrinterA(hPrinter);
168 if(!lpOpenedPrinter) {
169 SetLastError(ERROR_INVALID_HANDLE);
170 return -1;
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,
185 LPWSTR pDeviceName,
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,
191 fMode);
192 return -1;
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 TRACE("(printerName: %s, pDefault %p\n", lpPrinterName, pDefault);
211 /* Check Printer exists */
212 if(RegCreateKeyA(HKEY_LOCAL_MACHINE, Printers, &hkeyPrinters) !=
213 ERROR_SUCCESS) {
214 ERR("Can't create Printers key\n");
215 SetLastError(ERROR_FILE_NOT_FOUND); /* ?? */
216 return FALSE;
219 if(RegOpenKeyA(hkeyPrinters, lpPrinterName, &hkeyPrinter)
220 != ERROR_SUCCESS) {
221 WARN("Can't find printer `%s' in registry\n", lpPrinterName);
222 RegCloseKey(hkeyPrinters);
223 SetLastError(ERROR_INVALID_PARAMETER);
224 return FALSE;
226 RegCloseKey(hkeyPrinter);
227 RegCloseKey(hkeyPrinters);
229 if(!phPrinter) /* This seems to be what win95 does anyway */
230 return TRUE;
232 /* Get a place in the opened printer buffer*/
233 lpOpenedPrinter = WINSPOOL_GetOpenedPrinterEntryA();
234 if(!lpOpenedPrinter) {
235 ERR("Can't allocate printer slot\n");
236 SetLastError(ERROR_OUTOFMEMORY);
237 return FALSE;
240 /* Get the name of the printer */
241 lpOpenedPrinter->lpsPrinterName =
242 HEAP_strdupA( GetProcessHeap(), 0, lpPrinterName );
244 /* Get the unique handle of the printer*/
245 *phPrinter = lpOpenedPrinter->hPrinter;
247 if (pDefault != NULL) {
248 lpOpenedPrinter->lpDefault =
249 HeapAlloc(GetProcessHeap(), 0, sizeof(PRINTER_DEFAULTSA));
250 lpOpenedPrinter->lpDefault->pDevMode =
251 HeapAlloc(GetProcessHeap(), 0, sizeof(DEVMODEA));
252 memcpy(lpOpenedPrinter->lpDefault->pDevMode, pDefault->pDevMode,
253 sizeof(DEVMODEA));
254 lpOpenedPrinter->lpDefault->pDatatype =
255 HEAP_strdupA( GetProcessHeap(), 0, pDefault->pDatatype );
256 lpOpenedPrinter->lpDefault->DesiredAccess =
257 pDefault->DesiredAccess;
260 return TRUE;
264 /******************************************************************
265 * OpenPrinter32W [WINSPOOL.197]
268 BOOL WINAPI OpenPrinterW(LPWSTR lpPrinterName,HANDLE *phPrinter,
269 LPPRINTER_DEFAULTSW pDefault)
271 FIXME("(%s,%p,%p):stub\n",debugstr_w(lpPrinterName), phPrinter,
272 pDefault);
273 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
274 return FALSE;
277 /******************************************************************
278 * AddMonitor32A [WINSPOOL.107]
281 BOOL WINAPI AddMonitorA(LPSTR pName, DWORD Level, LPBYTE pMonitors)
283 FIXME("(%s,%lx,%p):stub!\n", pName, Level, pMonitors);
284 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
285 return FALSE;
288 /******************************************************************
289 * DeletePrinterDriver32A [WINSPOOL.146]
292 BOOL WINAPI
293 DeletePrinterDriverA (LPSTR pName, LPSTR pEnvironment, LPSTR pDriverName)
295 FIXME("(%s,%s,%s):stub\n",debugstr_a(pName),debugstr_a(pEnvironment),
296 debugstr_a(pDriverName));
297 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
298 return FALSE;
302 /******************************************************************
303 * DeleteMonitor32A [WINSPOOL.135]
306 BOOL WINAPI
307 DeleteMonitorA (LPSTR pName, LPSTR pEnvironment, LPSTR pMonitorName)
309 FIXME("(%s,%s,%s):stub\n",debugstr_a(pName),debugstr_a(pEnvironment),
310 debugstr_a(pMonitorName));
311 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
312 return FALSE;
316 /******************************************************************
317 * DeletePort32A [WINSPOOL.137]
320 BOOL WINAPI
321 DeletePortA (LPSTR pName, HWND hWnd, LPSTR pPortName)
323 FIXME("(%s,0x%08x,%s):stub\n",debugstr_a(pName),hWnd,
324 debugstr_a(pPortName));
325 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
326 return FALSE;
329 /******************************************************************************
330 * SetPrinter32W [WINSPOOL.214]
332 BOOL WINAPI
333 SetPrinterW(
334 HANDLE hPrinter,
335 DWORD Level,
336 LPBYTE pPrinter,
337 DWORD Command) {
339 FIXME("():stub\n");
340 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
341 return FALSE;
344 /******************************************************************************
345 * WritePrinter32 [WINSPOOL.223]
347 BOOL WINAPI
348 WritePrinter(
349 HANDLE hPrinter,
350 LPVOID pBuf,
351 DWORD cbBuf,
352 LPDWORD pcWritten) {
354 FIXME("():stub\n");
355 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
356 return FALSE;
359 /*****************************************************************************
360 * AddForm32A [WINSPOOL.103]
362 BOOL WINAPI AddFormA(HANDLE hPrinter, DWORD Level, LPBYTE pForm)
364 FIXME("(%d,%ld,%p): stub\n", hPrinter, Level, pForm);
365 return 1;
368 /*****************************************************************************
369 * AddForm32W [WINSPOOL.104]
371 BOOL WINAPI AddFormW(HANDLE hPrinter, DWORD Level, LPBYTE pForm)
373 FIXME("(%d,%ld,%p): stub\n", hPrinter, Level, pForm);
374 return 1;
377 /*****************************************************************************
378 * AddJob32A [WINSPOOL.105]
380 BOOL WINAPI AddJobA(HANDLE hPrinter, DWORD Level, LPBYTE pData,
381 DWORD cbBuf, LPDWORD pcbNeeded)
383 FIXME("(%d,%ld,%p,%ld,%p): stub\n", hPrinter, Level, pData, cbBuf,
384 pcbNeeded);
385 return 1;
388 /*****************************************************************************
389 * AddJob32W [WINSPOOL.106]
391 BOOL WINAPI AddJobW(HANDLE hPrinter, DWORD Level, LPBYTE pData, DWORD cbBuf,
392 LPDWORD pcbNeeded)
394 FIXME("(%d,%ld,%p,%ld,%p): stub\n", hPrinter, Level, pData, cbBuf,
395 pcbNeeded);
396 return 1;
399 /*****************************************************************************
400 * AddPrinter32A [WINSPOOL.117]
402 HANDLE WINAPI AddPrinterA(LPSTR pName, DWORD Level, LPBYTE pPrinter)
404 PRINTER_INFO_2A *pi = (PRINTER_INFO_2A *) pPrinter;
406 HANDLE retval;
407 HKEY hkeyPrinter, hkeyPrinters, hkeyDriver, hkeyDrivers;
409 TRACE("(%s,%ld,%p)\n", pName, Level, pPrinter);
411 if(pName != NULL) {
412 FIXME("pName = `%s' - unsupported\n", pName);
413 SetLastError(ERROR_INVALID_PARAMETER);
414 return 0;
416 if(Level != 2) {
417 WARN("Level = %ld\n", Level);
418 SetLastError(ERROR_INVALID_LEVEL);
419 return 0;
421 if(!pPrinter) {
422 SetLastError(ERROR_INVALID_PARAMETER);
423 return 0;
425 if(RegCreateKeyA(HKEY_LOCAL_MACHINE, Printers, &hkeyPrinters) !=
426 ERROR_SUCCESS) {
427 ERR("Can't create Printers key\n");
428 return 0;
430 if(RegOpenKeyA(hkeyPrinters, pi->pPrinterName, &hkeyPrinter) ==
431 ERROR_SUCCESS) {
432 SetLastError(ERROR_PRINTER_ALREADY_EXISTS);
433 RegCloseKey(hkeyPrinter);
434 RegCloseKey(hkeyPrinters);
435 return 0;
437 if(RegCreateKeyA(HKEY_LOCAL_MACHINE, Drivers, &hkeyDrivers) !=
438 ERROR_SUCCESS) {
439 ERR("Can't create Drivers key\n");
440 RegCloseKey(hkeyPrinters);
441 return 0;
443 if(RegOpenKeyA(hkeyDrivers, pi->pDriverName, &hkeyDriver) !=
444 ERROR_SUCCESS) {
445 WARN("Can't find driver `%s'\n", pi->pDriverName);
446 RegCloseKey(hkeyPrinters);
447 RegCloseKey(hkeyDrivers);
448 SetLastError(ERROR_UNKNOWN_PRINTER_DRIVER);
449 return 0;
451 RegCloseKey(hkeyDriver);
452 RegCloseKey(hkeyDrivers);
453 if(strcasecmp(pi->pPrintProcessor, "WinPrint")) { /* FIXME */
454 WARN("Can't find processor `%s'\n", pi->pPrintProcessor);
455 SetLastError(ERROR_UNKNOWN_PRINTPROCESSOR);
456 RegCloseKey(hkeyPrinters);
457 return 0;
459 if(RegCreateKeyA(hkeyPrinters, pi->pPrinterName, &hkeyPrinter) !=
460 ERROR_SUCCESS) {
461 WARN("Can't create printer `%s'\n", pi->pPrinterName);
462 SetLastError(ERROR_INVALID_PRINTER_NAME);
463 RegCloseKey(hkeyPrinters);
464 return 0;
466 RegSetValueExA(hkeyPrinter, "Attributes", 0, REG_DWORD,
467 (LPSTR)&pi->Attributes, sizeof(DWORD));
468 RegSetValueExA(hkeyPrinter, "Default DevMode", 0, REG_BINARY,
469 (LPSTR)&pi->pDevMode,
470 pi->pDevMode ? pi->pDevMode->dmSize : 0);
471 RegSetValueExA(hkeyPrinter, "Description", 0, REG_SZ, pi->pComment, 0);
472 RegSetValueExA(hkeyPrinter, "Location", 0, REG_SZ, pi->pLocation, 0);
473 RegSetValueExA(hkeyPrinter, "Name", 0, REG_SZ, pi->pPrinterName, 0);
474 RegSetValueExA(hkeyPrinter, "Parameters", 0, REG_SZ, pi->pParameters, 0);
475 RegSetValueExA(hkeyPrinter, "Port", 0, REG_SZ, pi->pPortName, 0);
476 RegSetValueExA(hkeyPrinter, "Print Processor", 0, REG_SZ,
477 pi->pPrintProcessor, 0);
478 RegSetValueExA(hkeyPrinter, "Printer Driver", 0, REG_SZ, pi->pDriverName,
480 RegSetValueExA(hkeyPrinter, "Priority", 0, REG_DWORD,
481 (LPSTR)&pi->Priority, sizeof(DWORD));
482 RegSetValueExA(hkeyPrinter, "Separator File", 0, REG_SZ, pi->pSepFile, 0);
483 RegSetValueExA(hkeyPrinter, "Share Name", 0, REG_SZ, pi->pShareName, 0);
484 RegSetValueExA(hkeyPrinter, "Start Time", 0, REG_DWORD,
485 (LPSTR)&pi->StartTime, sizeof(DWORD));
486 RegSetValueExA(hkeyPrinter, "Status", 0, REG_DWORD,
487 (LPSTR)&pi->Status, sizeof(DWORD));
488 RegSetValueExA(hkeyPrinter, "Until Time", 0, REG_DWORD,
489 (LPSTR)&pi->UntilTime, sizeof(DWORD));
491 RegCloseKey(hkeyPrinter);
492 RegCloseKey(hkeyPrinters);
493 if(!OpenPrinterA(pi->pPrinterName, &retval, NULL)) {
494 ERR("OpenPrinter failing\n");
495 return 0;
497 return retval;
500 /*****************************************************************************
501 * AddPrinter32W [WINSPOOL.122]
503 HANDLE WINAPI AddPrinterW(LPWSTR pName, DWORD Level, LPBYTE pPrinter)
505 FIXME("(%p,%ld,%p): stub\n", pName, Level, pPrinter);
506 return 0;
510 /*****************************************************************************
511 * ClosePrinter32 [WINSPOOL.126]
513 BOOL WINAPI ClosePrinter(HANDLE hPrinter)
515 LPOPENEDPRINTERA lpOpenedPrinter;
517 TRACE("Handle %d\n", hPrinter);
519 if (!pOpenedPrinterDPA)
520 return FALSE;
522 if ((hPrinter != -1) && (hPrinter < (pOpenedPrinterDPA->nItemCount - 1)))
524 lpOpenedPrinter = WINSPOOL_GetOpenedPrinterA(hPrinter);
525 HeapFree(GetProcessHeap(), 0, lpOpenedPrinter->lpsPrinterName);
526 lpOpenedPrinter->lpsPrinterName = NULL;
528 /* Free the memory of lpDefault if it has been initialized*/
529 if(lpOpenedPrinter->lpDefault != NULL)
531 HeapFree(GetProcessHeap(), 0,
532 lpOpenedPrinter->lpDefault->pDevMode);
533 HeapFree(GetProcessHeap(), 0,
534 lpOpenedPrinter->lpDefault->pDatatype);
535 HeapFree(GetProcessHeap(), 0,
536 lpOpenedPrinter->lpDefault);
537 lpOpenedPrinter->lpDefault = NULL;
540 lpOpenedPrinter->hPrinter = -1;
542 return TRUE;
544 return FALSE;
547 /*****************************************************************************
548 * DeleteForm32A [WINSPOOL.133]
550 BOOL WINAPI DeleteFormA(HANDLE hPrinter, LPSTR pFormName)
552 FIXME("(%d,%s): stub\n", hPrinter, pFormName);
553 return 1;
556 /*****************************************************************************
557 * DeleteForm32W [WINSPOOL.134]
559 BOOL WINAPI DeleteFormW(HANDLE hPrinter, LPWSTR pFormName)
561 FIXME("(%d,%s): stub\n", hPrinter, debugstr_w(pFormName));
562 return 1;
565 /*****************************************************************************
566 * DeletePrinter32 [WINSPOOL.143]
568 BOOL WINAPI DeletePrinter(HANDLE hPrinter)
570 FIXME("(%d): stub\n", hPrinter);
571 return 1;
574 /*****************************************************************************
575 * SetPrinter32A [WINSPOOL.211]
577 BOOL WINAPI SetPrinterA(HANDLE hPrinter, DWORD Level, LPBYTE pPrinter,
578 DWORD Command)
580 FIXME("(%d,%ld,%p,%ld): stub\n",hPrinter,Level,pPrinter,Command);
581 return FALSE;
584 /*****************************************************************************
585 * SetJob32A [WINSPOOL.209]
587 BOOL WINAPI SetJobA(HANDLE hPrinter, DWORD JobId, DWORD Level,
588 LPBYTE pJob, DWORD Command)
590 FIXME("(%d,%ld,%ld,%p,%ld): stub\n",hPrinter,JobId,Level,pJob,
591 Command);
592 return FALSE;
595 /*****************************************************************************
596 * SetJob32W [WINSPOOL.210]
598 BOOL WINAPI SetJobW(HANDLE hPrinter, DWORD JobId, DWORD Level,
599 LPBYTE pJob, DWORD Command)
601 FIXME("(%d,%ld,%ld,%p,%ld): stub\n",hPrinter,JobId,Level,pJob,
602 Command);
603 return FALSE;
606 /*****************************************************************************
607 * GetForm32A [WINSPOOL.181]
609 BOOL WINAPI GetFormA(HANDLE hPrinter, LPSTR pFormName, DWORD Level,
610 LPBYTE pForm, DWORD cbBuf, LPDWORD pcbNeeded)
612 FIXME("(%d,%s,%ld,%p,%ld,%p): stub\n",hPrinter,pFormName,
613 Level,pForm,cbBuf,pcbNeeded);
614 return FALSE;
617 /*****************************************************************************
618 * GetForm32W [WINSPOOL.182]
620 BOOL WINAPI GetFormW(HANDLE hPrinter, LPWSTR pFormName, DWORD Level,
621 LPBYTE pForm, DWORD cbBuf, LPDWORD pcbNeeded)
623 FIXME("(%d,%s,%ld,%p,%ld,%p): stub\n",hPrinter,
624 debugstr_w(pFormName),Level,pForm,cbBuf,pcbNeeded);
625 return FALSE;
628 /*****************************************************************************
629 * SetForm32A [WINSPOOL.207]
631 BOOL WINAPI SetFormA(HANDLE hPrinter, LPSTR pFormName, DWORD Level,
632 LPBYTE pForm)
634 FIXME("(%d,%s,%ld,%p): stub\n",hPrinter,pFormName,Level,pForm);
635 return FALSE;
638 /*****************************************************************************
639 * SetForm32W [WINSPOOL.208]
641 BOOL WINAPI SetFormW(HANDLE hPrinter, LPWSTR pFormName, DWORD Level,
642 LPBYTE pForm)
644 FIXME("(%d,%p,%ld,%p): stub\n",hPrinter,pFormName,Level,pForm);
645 return FALSE;
648 /*****************************************************************************
649 * ReadPrinter32 [WINSPOOL.202]
651 BOOL WINAPI ReadPrinter(HANDLE hPrinter, LPVOID pBuf, DWORD cbBuf,
652 LPDWORD pNoBytesRead)
654 FIXME("(%d,%p,%ld,%p): stub\n",hPrinter,pBuf,cbBuf,pNoBytesRead);
655 return FALSE;
658 /*****************************************************************************
659 * ResetPrinter32A [WINSPOOL.203]
661 BOOL WINAPI ResetPrinterA(HANDLE hPrinter, LPPRINTER_DEFAULTSA pDefault)
663 FIXME("(%d, %p): stub\n", hPrinter, pDefault);
664 return FALSE;
667 /*****************************************************************************
668 * ResetPrinter32W [WINSPOOL.204]
670 BOOL WINAPI ResetPrinterW(HANDLE hPrinter, LPPRINTER_DEFAULTSW pDefault)
672 FIXME("(%d, %p): stub\n", hPrinter, pDefault);
673 return FALSE;
677 /*****************************************************************************
678 * WINSPOOL_GetStringFromRegA
680 * Get ValueName from hkey storing result in str. buflen is space left in str
682 static BOOL WINSPOOL_GetStringFromRegA(HKEY hkey, LPCSTR ValueName, LPSTR ptr,
683 DWORD buflen, DWORD *needed)
685 DWORD sz = buflen, type;
686 LONG ret;
688 ret = RegQueryValueExA(hkey, ValueName, 0, &type, ptr, &sz);
690 if(ret != ERROR_SUCCESS && ret != ERROR_MORE_DATA) {
691 ERR("Got ret = %ld\n", ret);
692 return FALSE;
694 *needed = sz;
695 return TRUE;
698 /*********************************************************************
699 * WINSPOOL_GetPrinter_2A
701 * Fills out a PRINTER_INFO_2A struct storing the strings in buf.
703 static BOOL WINSPOOL_GetPrinter_2A(HKEY hkeyPrinter, PRINTER_INFO_2A *pi2,
704 LPBYTE buf, DWORD cbBuf, LPDWORD pcbNeeded)
706 DWORD size, left = cbBuf;
707 BOOL space = (cbBuf > 0);
708 LPBYTE ptr = buf;
710 *pcbNeeded = 0;
712 WINSPOOL_GetStringFromRegA(hkeyPrinter, "Name", ptr, left, &size);
713 if(space && size <= left) {
714 pi2->pPrinterName = ptr;
715 ptr += size;
716 left -= size;
717 } else
718 space = FALSE;
719 *pcbNeeded += size;
721 WINSPOOL_GetStringFromRegA(hkeyPrinter, "Port", ptr, left, &size);
722 if(space && size <= left) {
723 pi2->pPortName = ptr;
724 ptr += size;
725 left -= size;
726 } else
727 space = FALSE;
728 *pcbNeeded += size;
730 WINSPOOL_GetStringFromRegA(hkeyPrinter, "Printer Driver", ptr, left,
731 &size);
732 if(space && size <= left) {
733 pi2->pDriverName = ptr;
734 ptr += size;
735 left -= size;
736 } else
737 space = FALSE;
738 *pcbNeeded += size;
740 WINSPOOL_GetStringFromRegA(hkeyPrinter, "Default DevMode", ptr, left,
741 &size);
742 if(space && size <= left) {
743 pi2->pDevMode = (LPDEVMODEA)ptr;
744 ptr += size;
745 left -= size;
746 } else
747 space = FALSE;
748 *pcbNeeded += size;
750 WINSPOOL_GetStringFromRegA(hkeyPrinter, "Print Processor", ptr, left,
751 &size);
752 if(space && size <= left) {
753 pi2->pPrintProcessor = ptr;
754 ptr += size;
755 left -= size;
756 } else
757 space = FALSE;
758 *pcbNeeded += size;
760 if(!space && pi2) /* zero out pi2 if we can't completely fill buf */
761 memset(pi2, 0, sizeof(*pi2));
763 return space;
766 /*********************************************************************
767 * WINSPOOL_GetPrinter_4A
769 * Fills out a PRINTER_INFO_4A struct storing the strings in buf.
771 static BOOL WINSPOOL_GetPrinter_4A(HKEY hkeyPrinter, PRINTER_INFO_4A *pi4,
772 LPBYTE buf, DWORD cbBuf, LPDWORD pcbNeeded)
774 DWORD size, left = cbBuf;
775 BOOL space = (cbBuf > 0);
776 LPBYTE ptr = buf;
778 *pcbNeeded = 0;
780 WINSPOOL_GetStringFromRegA(hkeyPrinter, "Name", ptr, left, &size);
781 if(space && size <= left) {
782 pi4->pPrinterName = ptr;
783 ptr += size;
784 left -= size;
785 } else
786 space = FALSE;
788 *pcbNeeded += size;
790 if(!space && pi4) /* zero out pi4 if we can't completely fill buf */
791 memset(pi4, 0, sizeof(*pi4));
793 return space;
796 /*********************************************************************
797 * WINSPOOL_GetPrinter_5A
799 * Fills out a PRINTER_INFO_5A struct storing the strings in buf.
801 static BOOL WINSPOOL_GetPrinter_5A(HKEY hkeyPrinter, PRINTER_INFO_5A *pi5,
802 LPBYTE buf, DWORD cbBuf, LPDWORD pcbNeeded)
804 DWORD size, left = cbBuf;
805 BOOL space = (cbBuf > 0);
806 LPBYTE ptr = buf;
808 *pcbNeeded = 0;
810 WINSPOOL_GetStringFromRegA(hkeyPrinter, "Name", ptr, left, &size);
811 if(space && size <= left) {
812 pi5->pPrinterName = ptr;
813 ptr += size;
814 left -= size;
815 } else
816 space = FALSE;
817 *pcbNeeded += size;
819 WINSPOOL_GetStringFromRegA(hkeyPrinter, "Port", ptr, left, &size);
820 if(space && size <= left) {
821 pi5->pPortName = ptr;
822 ptr += size;
823 left -= size;
824 } else
825 space = FALSE;
826 *pcbNeeded += size;
828 if(!space && pi5) /* zero out pi5 if we can't completely fill buf */
829 memset(pi5, 0, sizeof(*pi5));
831 return space;
834 /*****************************************************************************
835 * GetPrinterA [WINSPOOL.187]
837 BOOL WINAPI GetPrinterA(HANDLE hPrinter, DWORD Level, LPBYTE pPrinter,
838 DWORD cbBuf, LPDWORD pcbNeeded)
840 OPENEDPRINTERA *lpOpenedPrinter;
841 DWORD size, needed = 0;
842 LPBYTE ptr = NULL;
843 HKEY hkeyPrinter, hkeyPrinters;
844 BOOL ret;
846 TRACE("(%d,%ld,%p,%ld,%p)\n",hPrinter,Level,pPrinter,cbBuf, pcbNeeded);
848 lpOpenedPrinter = WINSPOOL_GetOpenedPrinterA(hPrinter);
849 if(!lpOpenedPrinter) {
850 SetLastError(ERROR_INVALID_HANDLE);
851 return FALSE;
853 if(RegCreateKeyA(HKEY_LOCAL_MACHINE, Printers, &hkeyPrinters) !=
854 ERROR_SUCCESS) {
855 ERR("Can't create Printers key\n");
856 return FALSE;
858 if(RegOpenKeyA(hkeyPrinters, lpOpenedPrinter->lpsPrinterName, &hkeyPrinter)
859 != ERROR_SUCCESS) {
860 ERR("Can't find opened printer `%s' in registry\n",
861 lpOpenedPrinter->lpsPrinterName);
862 RegCloseKey(hkeyPrinters);
863 SetLastError(ERROR_INVALID_PRINTER_NAME); /* ? */
864 return FALSE;
867 switch(Level) {
868 case 2:
870 PRINTER_INFO_2A *pi2 = (PRINTER_INFO_2A *)pPrinter;
872 size = sizeof(PRINTER_INFO_2A);
873 if(size <= cbBuf) {
874 ptr = pPrinter + size;
875 cbBuf -= size;
876 memset(pPrinter, 0, size);
877 } else {
878 pi2 = NULL;
879 cbBuf = 0;
881 ret = WINSPOOL_GetPrinter_2A(hkeyPrinter, pi2, ptr, cbBuf, &needed);
882 needed += size;
883 break;
886 case 4:
888 PRINTER_INFO_4A *pi4 = (PRINTER_INFO_4A *)pPrinter;
890 size = sizeof(PRINTER_INFO_4A);
891 if(size <= cbBuf) {
892 ptr = pPrinter + size;
893 cbBuf -= size;
894 memset(pPrinter, 0, size);
895 } else {
896 pi4 = NULL;
897 cbBuf = 0;
899 ret = WINSPOOL_GetPrinter_4A(hkeyPrinter, pi4, ptr, cbBuf, &needed);
900 needed += size;
901 break;
905 case 5:
907 PRINTER_INFO_5A *pi5 = (PRINTER_INFO_5A *)pPrinter;
909 size = sizeof(PRINTER_INFO_5A);
910 if(size <= cbBuf) {
911 ptr = pPrinter + size;
912 cbBuf -= size;
913 memset(pPrinter, 0, size);
914 } else {
915 pi5 = NULL;
916 cbBuf = 0;
919 ret = WINSPOOL_GetPrinter_5A(hkeyPrinter, pi5, ptr, cbBuf, &needed);
920 needed += size;
921 break;
924 default:
925 FIXME("Unimplemented level %ld\n", Level);
926 SetLastError(ERROR_INVALID_LEVEL);
927 RegCloseKey(hkeyPrinters);
928 RegCloseKey(hkeyPrinter);
929 return FALSE;
932 RegCloseKey(hkeyPrinter);
933 RegCloseKey(hkeyPrinters);
935 if(pcbNeeded) *pcbNeeded = needed;
936 if(!ret)
937 SetLastError(ERROR_INSUFFICIENT_BUFFER);
938 return ret;
942 /*****************************************************************************
943 * GetPrinterW [WINSPOOL.194]
945 BOOL WINAPI GetPrinterW(HANDLE hPrinter, DWORD Level, LPBYTE pPrinter,
946 DWORD cbBuf, LPDWORD pcbNeeded)
948 FIXME("(%d,%ld,%p,%ld,%p): stub\n", hPrinter, Level, pPrinter,
949 cbBuf, pcbNeeded);
950 return FALSE;
953 /******************************************************************
954 * EnumPrintersA [WINSPOOL.174]
956 * Enumerates the available printers, print servers and print
957 * providers, depending on the specified flags, name and level.
959 * RETURNS:
961 * If level is set to 1:
962 * Not implemented yet!
963 * Returns TRUE with an empty list.
965 * If level is set to 2:
966 * Possible flags: PRINTER_ENUM_CONNECTIONS, PRINTER_ENUM_LOCAL.
967 * Returns an array of PRINTER_INFO_2 data structures in the
968 * lpbPrinters buffer. Note that according to MSDN also an
969 * OpenPrinter should be performed on every remote printer.
971 * If level is set to 4 (officially WinNT only):
972 * Possible flags: PRINTER_ENUM_CONNECTIONS, PRINTER_ENUM_LOCAL.
973 * Fast: Only the registry is queried to retrieve printer names,
974 * no connection to the driver is made.
975 * Returns an array of PRINTER_INFO_4 data structures in the
976 * lpbPrinters buffer.
978 * If level is set to 5 (officially WinNT4/Win9x only):
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_5 data structures in the
982 * lpbPrinters buffer.
984 * If level set to 3 or 6+:
985 * returns zero (faillure!)
987 * Returns nonzero (TRUE) on succes, or zero on faillure, use GetLastError
988 * for information.
990 * BUGS:
991 * - Only PRINTER_ENUM_LOCAL and PRINTER_ENUM_NAME are implemented.
992 * - Only levels 2, 4 and 5 are implemented at the moment.
993 * - 16-bit printer drivers are not enumerated.
994 * - Returned amount of bytes used/needed does not match the real Windoze
995 * implementation (as in this implementation, all strings are part
996 * of the buffer, whereas Win32 keeps them somewhere else)
997 * - At level 2, EnumPrinters should also call OpenPrinter for remote printers.
999 * NOTE:
1000 * - In a regular Wine installation, no registry settings for printers
1001 * exist, which makes this function return an empty list.
1003 BOOL WINAPI EnumPrintersA(
1004 DWORD dwType, /* Types of print objects to enumerate */
1005 LPSTR lpszName, /* name of objects to enumerate */
1006 DWORD dwLevel, /* type of printer info structure */
1007 LPBYTE lpbPrinters, /* buffer which receives info */
1008 DWORD cbBuf, /* max size of buffer in bytes */
1009 LPDWORD lpdwNeeded, /* pointer to var: # bytes used/needed */
1010 LPDWORD lpdwReturned /* number of entries returned */
1014 HKEY hkeyPrinters, hkeyPrinter;
1015 char PrinterName[255];
1016 DWORD needed = 0, number = 0;
1017 DWORD used, i, left;
1018 PBYTE pi, buf;
1020 if(lpbPrinters)
1021 memset(lpbPrinters, 0, cbBuf);
1022 if(lpdwReturned)
1023 *lpdwReturned = 0;
1025 if (!((dwType & PRINTER_ENUM_LOCAL) || (dwType & PRINTER_ENUM_NAME))) {
1026 FIXME("dwType = %08lx\n", dwType);
1027 SetLastError(ERROR_INVALID_FLAGS);
1028 return FALSE;
1031 if(RegCreateKeyA(HKEY_LOCAL_MACHINE, Printers, &hkeyPrinters) !=
1032 ERROR_SUCCESS) {
1033 ERR("Can't create Printers key\n");
1034 return FALSE;
1037 if(RegQueryInfoKeyA(hkeyPrinters, NULL, NULL, NULL, &number, NULL, NULL,
1038 NULL, NULL, NULL, NULL, NULL) != ERROR_SUCCESS) {
1039 RegCloseKey(hkeyPrinters);
1040 ERR("Can't query Printers key\n");
1041 return FALSE;
1043 TRACE("Found %ld printers\n", number);
1045 switch(dwLevel) {
1046 case 1:
1047 RegCloseKey(hkeyPrinters);
1048 return TRUE;
1050 case 2:
1051 used = number * sizeof(PRINTER_INFO_2A);
1052 break;
1053 case 4:
1054 used = number * sizeof(PRINTER_INFO_4A);
1055 break;
1056 case 5:
1057 used = number * sizeof(PRINTER_INFO_5A);
1058 break;
1060 default:
1061 SetLastError(ERROR_INVALID_LEVEL);
1062 RegCloseKey(hkeyPrinters);
1063 return FALSE;
1065 pi = (used <= cbBuf) ? lpbPrinters : NULL;
1067 for(i = 0; i < number; i++) {
1068 if(RegEnumKeyA(hkeyPrinters, i, PrinterName, sizeof(PrinterName)) !=
1069 ERROR_SUCCESS) {
1070 ERR("Can't enum key number %ld\n", i);
1071 RegCloseKey(hkeyPrinters);
1072 return FALSE;
1074 if(RegOpenKeyA(hkeyPrinters, PrinterName, &hkeyPrinter) !=
1075 ERROR_SUCCESS) {
1076 ERR("Can't open key '%s'\n", PrinterName);
1077 RegCloseKey(hkeyPrinters);
1078 return FALSE;
1081 if(cbBuf > used) {
1082 buf = lpbPrinters + used;
1083 left = cbBuf - used;
1084 } else {
1085 buf = NULL;
1086 left = 0;
1089 switch(dwLevel) {
1090 case 2:
1091 WINSPOOL_GetPrinter_2A(hkeyPrinter, (PRINTER_INFO_2A *)pi, buf,
1092 left, &needed);
1093 used += needed;
1094 if(pi) pi += sizeof(PRINTER_INFO_2A);
1095 break;
1096 case 4:
1097 WINSPOOL_GetPrinter_4A(hkeyPrinter, (PRINTER_INFO_4A *)pi, buf,
1098 left, &needed);
1099 used += needed;
1100 if(pi) pi += sizeof(PRINTER_INFO_4A);
1101 break;
1102 case 5:
1103 WINSPOOL_GetPrinter_5A(hkeyPrinter, (PRINTER_INFO_5A *)pi, buf,
1104 left, &needed);
1105 used += needed;
1106 if(pi) pi += sizeof(PRINTER_INFO_5A);
1107 break;
1108 default:
1109 ERR("Shouldn't be here!\n");
1110 RegCloseKey(hkeyPrinter);
1111 RegCloseKey(hkeyPrinters);
1112 return FALSE;
1114 RegCloseKey(hkeyPrinter);
1116 RegCloseKey(hkeyPrinters);
1118 if(lpdwNeeded)
1119 *lpdwNeeded = used;
1120 if(used > cbBuf) {
1121 if(lpbPrinters)
1122 memset(lpbPrinters, 0, cbBuf);
1123 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1124 return FALSE;
1126 if(lpdwReturned)
1127 *lpdwReturned = number;
1128 SetLastError(ERROR_SUCCESS);
1129 return TRUE;
1132 /******************************************************************
1133 * EnumPrintersW [WINSPOOL.175]
1136 BOOL WINAPI EnumPrintersW(DWORD dwType, LPWSTR lpszName,
1137 DWORD dwLevel, LPBYTE lpbPrinters,
1138 DWORD cbBuf, LPDWORD lpdwNeeded,
1139 LPDWORD lpdwReturned)
1141 FIXME("Nearly empty stub\n");
1142 *lpdwReturned=0;
1143 *lpdwNeeded = 0;
1144 return TRUE;
1148 /*****************************************************************************
1149 * GetPrinterDriver32A [WINSPOOL.190]
1151 BOOL WINAPI GetPrinterDriverA(HANDLE hPrinter, LPSTR pEnvironment,
1152 DWORD Level, LPBYTE pDriverInfo,
1153 DWORD cbBuf, LPDWORD pcbNeeded)
1155 OPENEDPRINTERA *lpOpenedPrinter;
1156 char DriverName[100];
1157 DWORD ret, type, size, dw, needed = 0;
1158 LPBYTE ptr = NULL;
1159 HKEY hkeyPrinter, hkeyPrinters, hkeyDriver, hkeyDrivers;
1161 TRACE("(%d,%s,%ld,%p,%ld,%p)\n",hPrinter,pEnvironment,
1162 Level,pDriverInfo,cbBuf, pcbNeeded);
1164 lpOpenedPrinter = WINSPOOL_GetOpenedPrinterA(hPrinter);
1165 if(!lpOpenedPrinter) {
1166 SetLastError(ERROR_INVALID_HANDLE);
1167 return FALSE;
1169 if(pEnvironment) {
1170 FIXME("pEnvironment = `%s'\n", pEnvironment);
1171 SetLastError(ERROR_INVALID_ENVIRONMENT);
1172 return FALSE;
1174 if(Level < 1 || Level > 3) {
1175 SetLastError(ERROR_INVALID_LEVEL);
1176 return FALSE;
1178 if(RegCreateKeyA(HKEY_LOCAL_MACHINE, Printers, &hkeyPrinters) !=
1179 ERROR_SUCCESS) {
1180 ERR("Can't create Printers key\n");
1181 return FALSE;
1183 if(RegOpenKeyA(hkeyPrinters, lpOpenedPrinter->lpsPrinterName, &hkeyPrinter)
1184 != ERROR_SUCCESS) {
1185 ERR("Can't find opened printer `%s' in registry\n",
1186 lpOpenedPrinter->lpsPrinterName);
1187 RegCloseKey(hkeyPrinters);
1188 SetLastError(ERROR_INVALID_PRINTER_NAME); /* ? */
1189 return FALSE;
1191 size = sizeof(DriverName);
1192 ret = RegQueryValueExA(hkeyPrinter, "Printer Driver", 0, &type, DriverName,
1193 &size);
1194 RegCloseKey(hkeyPrinter);
1195 RegCloseKey(hkeyPrinters);
1196 if(ret != ERROR_SUCCESS) {
1197 ERR("Can't get DriverName for printer `%s'\n",
1198 lpOpenedPrinter->lpsPrinterName);
1199 return FALSE;
1201 if(RegCreateKeyA(HKEY_LOCAL_MACHINE, Drivers, &hkeyDrivers) !=
1202 ERROR_SUCCESS) {
1203 ERR("Can't create Drivers key\n");
1204 return FALSE;
1206 if(RegOpenKeyA(hkeyDrivers, DriverName, &hkeyDriver)
1207 != ERROR_SUCCESS) {
1208 ERR("Can't find driver `%s' in registry\n", DriverName);
1209 RegCloseKey(hkeyDrivers);
1210 SetLastError(ERROR_UNKNOWN_PRINTER_DRIVER); /* ? */
1211 return FALSE;
1214 switch(Level) {
1215 case 1:
1216 size = sizeof(DRIVER_INFO_1A);
1217 break;
1218 case 2:
1219 size = sizeof(DRIVER_INFO_2A);
1220 break;
1221 case 3:
1222 size = sizeof(DRIVER_INFO_3A);
1223 break;
1224 default:
1225 ERR("Invalid level\n");
1226 return FALSE;
1229 if(size <= cbBuf) {
1230 ptr = pDriverInfo + size;
1231 cbBuf -= size;
1232 } else
1233 cbBuf = 0;
1234 needed = size;
1236 size = strlen(DriverName) + 1;
1237 if(size <= cbBuf) {
1238 cbBuf -= size;
1239 strcpy(ptr, DriverName);
1240 if(Level == 1)
1241 ((DRIVER_INFO_1A *)pDriverInfo)->pName = ptr;
1242 else
1243 ((DRIVER_INFO_2A *)pDriverInfo)->pName = ptr;
1244 ptr += size;
1246 needed += size;
1248 if(Level > 1) {
1249 DRIVER_INFO_2A *di2 = (DRIVER_INFO_2A *)pDriverInfo;
1251 size = sizeof(dw);
1252 if(RegQueryValueExA(hkeyDriver, "Version", 0, &type, (PBYTE)&dw,
1253 &size) !=
1254 ERROR_SUCCESS)
1255 WARN("Can't get Version\n");
1256 else if(cbBuf)
1257 di2->cVersion = dw;
1259 size = strlen("Wine") + 1; /* FIXME */
1260 if(size <= cbBuf) {
1261 cbBuf -= size;
1262 strcpy(ptr, "Wine");
1263 di2->pEnvironment = ptr;
1264 ptr += size;
1265 } else
1266 cbBuf = 0;
1267 needed += size;
1269 WINSPOOL_GetStringFromRegA(hkeyDriver, "Driver", ptr, cbBuf, &size);
1270 if(cbBuf && size <= cbBuf) {
1271 di2->pDriverPath = ptr;
1272 ptr += size;
1273 } else
1274 cbBuf = 0;
1275 needed += size;
1277 WINSPOOL_GetStringFromRegA(hkeyDriver, "Data File", ptr, cbBuf, &size);
1278 if(cbBuf && size <= cbBuf) {
1279 di2->pDataFile = ptr;
1280 ptr += size;
1281 } else
1282 cbBuf = 0;
1283 needed += size;
1285 WINSPOOL_GetStringFromRegA(hkeyDriver, "Configuration File", ptr,
1286 cbBuf, &size);
1287 if(cbBuf && size <= cbBuf) {
1288 di2->pConfigFile = ptr;
1289 ptr += size;
1290 } else
1291 cbBuf = 0;
1292 needed += size;
1295 if(Level > 2) {
1296 DRIVER_INFO_3A *di3 = (DRIVER_INFO_3A *)pDriverInfo;
1298 WINSPOOL_GetStringFromRegA(hkeyDriver, "Help File", ptr, cbBuf, &size);
1299 if(cbBuf && size <= cbBuf) {
1300 di3->pHelpFile = ptr;
1301 ptr += size;
1302 } else
1303 cbBuf = 0;
1304 needed += size;
1306 WINSPOOL_GetStringFromRegA(hkeyDriver, "Dependent Files", ptr, cbBuf,
1307 &size);
1308 if(cbBuf && size <= cbBuf) {
1309 di3->pDependentFiles = ptr;
1310 ptr += size;
1311 } else
1312 cbBuf = 0;
1313 needed += size;
1315 WINSPOOL_GetStringFromRegA(hkeyDriver, "Monitor", ptr, cbBuf, &size);
1316 if(cbBuf && size <= cbBuf) {
1317 di3->pMonitorName = ptr;
1318 ptr += size;
1319 } else
1320 cbBuf = 0;
1321 needed += size;
1323 WINSPOOL_GetStringFromRegA(hkeyDriver, "DataType", ptr, cbBuf, &size);
1324 if(cbBuf && size <= cbBuf) {
1325 di3->pDefaultDataType = ptr;
1326 ptr += size;
1327 } else
1328 cbBuf = 0;
1329 needed += size;
1331 RegCloseKey(hkeyDriver);
1332 RegCloseKey(hkeyDrivers);
1334 if(pcbNeeded) *pcbNeeded = needed;
1335 if(cbBuf) return TRUE;
1336 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1337 return FALSE;
1340 /*****************************************************************************
1341 * GetPrinterDriver32W [WINSPOOL.193]
1343 BOOL WINAPI GetPrinterDriverW(HANDLE hPrinter, LPWSTR pEnvironment,
1344 DWORD Level, LPBYTE pDriverInfo,
1345 DWORD cbBuf, LPDWORD pcbNeeded)
1347 FIXME("(%d,%p,%ld,%p,%ld,%p): stub\n",hPrinter,pEnvironment,
1348 Level,pDriverInfo,cbBuf, pcbNeeded);
1349 return FALSE;
1352 /*****************************************************************************
1353 * GetPrinterDriverDirectoryA [WINSPOOL.191]
1355 BOOL WINAPI GetPrinterDriverDirectoryA(LPSTR pName, LPSTR pEnvironment,
1356 DWORD Level, LPBYTE pDriverDirectory,
1357 DWORD cbBuf, LPDWORD pcbNeeded)
1359 DWORD needed;
1361 TRACE("(%s, %s, %ld, %p, %ld, %p)\n", pName, pEnvironment, Level,
1362 pDriverDirectory, cbBuf, pcbNeeded);
1363 if(pName != NULL) {
1364 FIXME("pName = `%s' - unsupported\n", pName);
1365 SetLastError(ERROR_INVALID_PARAMETER);
1366 return FALSE;
1368 if(pEnvironment != NULL) {
1369 FIXME("pEnvironment = `%s' - unsupported\n", pEnvironment);
1370 SetLastError(ERROR_INVALID_ENVIRONMENT);
1371 return FALSE;
1373 if(Level != 1) /* win95 ignores this so we just carry on */
1374 WARN("Level = %ld - assuming 1\n", Level);
1376 /* FIXME should read from registry */
1377 needed = GetSystemDirectoryA(pDriverDirectory, cbBuf);
1378 needed++;
1379 if(pcbNeeded)
1380 *pcbNeeded = needed;
1381 if(needed > cbBuf) {
1382 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1383 return FALSE;
1385 return TRUE;
1389 /*****************************************************************************
1390 * GetPrinterDriverDirectoryW [WINSPOOL.192]
1392 BOOL WINAPI GetPrinterDriverDirectoryW(LPWSTR pName, LPWSTR pEnvironment,
1393 DWORD Level, LPBYTE pDriverDirectory,
1394 DWORD cbBuf, LPDWORD pcbNeeded)
1396 LPSTR pNameA = NULL, pEnvironmentA = NULL;
1397 BOOL ret;
1399 if(pName)
1400 pNameA = HEAP_strdupWtoA( GetProcessHeap(), 0, pName );
1401 if(pEnvironment)
1402 pEnvironmentA = HEAP_strdupWtoA( GetProcessHeap(), 0, pEnvironment );
1403 ret = GetPrinterDriverDirectoryA( pNameA, pEnvironmentA, Level,
1404 pDriverDirectory, cbBuf, pcbNeeded );
1405 if(pNameA)
1406 HeapFree( GetProcessHeap(), 0, pNameA );
1407 if(pEnvironmentA)
1408 HeapFree( GetProcessHeap(), 0, pEnvironment );
1410 return ret;
1413 /*****************************************************************************
1414 * AddPrinterDriver32A [WINSPOOL.120]
1416 BOOL WINAPI AddPrinterDriverA(LPSTR pName, DWORD level, LPBYTE pDriverInfo)
1418 DRIVER_INFO_3A di3;
1419 HKEY hkeyDrivers, hkeyName;
1421 TRACE("(%s,%ld,%p)\n",pName,level,pDriverInfo);
1423 if(level != 2 && level != 3) {
1424 SetLastError(ERROR_INVALID_LEVEL);
1425 return FALSE;
1427 if(pName != NULL) {
1428 FIXME("pName= `%s' - unsupported\n", pName);
1429 SetLastError(ERROR_INVALID_PARAMETER);
1430 return FALSE;
1432 if(!pDriverInfo) {
1433 WARN("pDriverInfo == NULL");
1434 SetLastError(ERROR_INVALID_PARAMETER);
1435 return FALSE;
1438 if(level == 3)
1439 di3 = *(DRIVER_INFO_3A *)pDriverInfo;
1440 else {
1441 memset(&di3, 0, sizeof(di3));
1442 *(DRIVER_INFO_2A *)&di3 = *(DRIVER_INFO_2A *)pDriverInfo;
1445 if(!di3.pName || !di3.pDriverPath || !di3.pConfigFile ||
1446 !di3.pDataFile) {
1447 SetLastError(ERROR_INVALID_PARAMETER);
1448 return FALSE;
1450 if(!di3.pDefaultDataType) di3.pDefaultDataType = "";
1451 if(!di3.pDependentFiles) di3.pDependentFiles = "\0";
1452 if(!di3.pHelpFile) di3.pHelpFile = "";
1453 if(!di3.pMonitorName) di3.pMonitorName = "";
1455 if(di3.pEnvironment) {
1456 FIXME("pEnvironment = `%s'\n", di3.pEnvironment);
1457 SetLastError(ERROR_INVALID_ENVIRONMENT);
1458 return FALSE;
1460 if(RegCreateKeyA(HKEY_LOCAL_MACHINE, Drivers, &hkeyDrivers) !=
1461 ERROR_SUCCESS) {
1462 ERR("Can't create Drivers key\n");
1463 return FALSE;
1466 if(level == 2) { /* apparently can't overwrite with level2 */
1467 if(RegOpenKeyA(hkeyDrivers, di3.pName, &hkeyName) == ERROR_SUCCESS) {
1468 RegCloseKey(hkeyName);
1469 RegCloseKey(hkeyDrivers);
1470 WARN("Trying to create existing printer driver `%s'\n", di3.pName);
1471 SetLastError(ERROR_PRINTER_DRIVER_ALREADY_INSTALLED);
1472 return FALSE;
1475 if(RegCreateKeyA(hkeyDrivers, di3.pName, &hkeyName) != ERROR_SUCCESS) {
1476 RegCloseKey(hkeyDrivers);
1477 ERR("Can't create Name key\n");
1478 return FALSE;
1480 RegSetValueExA(hkeyName, "Configuration File", 0, REG_SZ, di3.pConfigFile,
1482 RegSetValueExA(hkeyName, "Data File", 0, REG_SZ, di3.pDataFile, 0);
1483 RegSetValueExA(hkeyName, "Driver", 0, REG_SZ, di3.pDriverPath, 0);
1484 RegSetValueExA(hkeyName, "Version", 0, REG_DWORD, (LPSTR)&di3.cVersion,
1485 sizeof(DWORD));
1486 RegSetValueExA(hkeyName, "Datatype", 0, REG_SZ, di3.pDefaultDataType, 0);
1487 RegSetValueExA(hkeyName, "Dependent Files", 0, REG_MULTI_SZ,
1488 di3.pDependentFiles, 0);
1489 RegSetValueExA(hkeyName, "Help File", 0, REG_SZ, di3.pHelpFile, 0);
1490 RegSetValueExA(hkeyName, "Monitor", 0, REG_SZ, di3.pMonitorName, 0);
1491 RegCloseKey(hkeyName);
1492 RegCloseKey(hkeyDrivers);
1494 return TRUE;
1496 /*****************************************************************************
1497 * AddPrinterDriver32W [WINSPOOL.121]
1499 BOOL WINAPI AddPrinterDriverW(LPWSTR printerName,DWORD level,
1500 LPBYTE pDriverInfo)
1502 FIXME("(%s,%ld,%p): stub\n",debugstr_w(printerName),
1503 level,pDriverInfo);
1504 return FALSE;
1508 /*****************************************************************************
1509 * PrinterProperties [WINSPOOL.201]
1511 * Displays a dialog to set the properties of the printer.
1513 * RETURNS
1514 * nonzero on succes or zero on faillure
1516 * BUGS
1517 * implemented as stub only
1519 BOOL WINAPI PrinterProperties(HWND hWnd, /* handle to parent window */
1520 HANDLE hPrinter /* handle to printer object */
1522 FIXME("(%d,%d): stub\n", hWnd, hPrinter);
1523 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
1524 return FALSE;
1527 /*****************************************************************************
1528 * EnumJobsA [WINSPOOL.162]
1531 BOOL WINAPI EnumJobsA(HANDLE hPrinter, DWORD FirstJob, DWORD NoJobs,
1532 DWORD Level, LPBYTE pJob, DWORD cbBuf, LPDWORD pcbNeeded,
1533 LPDWORD pcReturned)
1535 FIXME("stub\n");
1536 if(pcbNeeded) *pcbNeeded = 0;
1537 if(pcReturned) *pcReturned = 0;
1538 return TRUE;
1542 /*****************************************************************************
1543 * EnumJobsW [WINSPOOL.163]
1546 BOOL WINAPI EnumJobsW(HANDLE hPrinter, DWORD FirstJob, DWORD NoJobs,
1547 DWORD Level, LPBYTE pJob, DWORD cbBuf, LPDWORD pcbNeeded,
1548 LPDWORD pcReturned)
1550 FIXME("stub\n");
1551 if(pcbNeeded) *pcbNeeded = 0;
1552 if(pcReturned) *pcReturned = 0;
1553 return TRUE;