Implementation of EnumPrintersA, info level 4 and 5.
[wine/gsoc_dplay.git] / misc / printdrv.c
blob0d3f7a0208ece4e0e285e28bf67622a3bb1b52bf
1 /*
2 * Implementation of some printer driver bits
3 *
4 * Copyright 1996 John Harvey
5 * Copyright 1998 Andreas Mohr
6 */
8 #include <stdlib.h>
9 #include <string.h>
10 #include <ctype.h>
11 #include "winspool.h"
12 #include "ldt.h"
13 #include "winerror.h"
14 #include "winreg.h"
15 #include "debug.h"
17 static char PrinterModel[] = "Printer Model";
18 static char DefaultDevMode[] = "Default DevMode";
19 static char PrinterDriverData[] = "PrinterDriverData";
20 static char Printers[] = "System\\CurrentControlSet\\Control\\Print\\Printers\\";
22 /******************************************************************
23 * StartDoc16 [GDI.377]
26 INT16 WINAPI StartDoc16( HDC16 hdc, const DOCINFO16 *lpdoc )
28 INT16 retVal;
29 TRACE(print,"(%p)\n", lpdoc );
30 TRACE(print,"%d 0x%lx:0x%p 0x%lx:0x%p\n",lpdoc->cbSize,
31 lpdoc->lpszDocName,PTR_SEG_TO_LIN(lpdoc->lpszDocName),
32 lpdoc->lpszOutput,PTR_SEG_TO_LIN(lpdoc->lpszOutput));
33 TRACE(print, "%d %s %s\n",lpdoc->cbSize,
34 (LPSTR)PTR_SEG_TO_LIN(lpdoc->lpszDocName),
35 (LPSTR)PTR_SEG_TO_LIN(lpdoc->lpszOutput));
36 retVal = Escape16(hdc, STARTDOC,
37 strlen((LPSTR)PTR_SEG_TO_LIN(lpdoc->lpszDocName)), lpdoc->lpszDocName, 0);
38 TRACE(print,"Escape16 returned %d\n",retVal);
39 return retVal;
42 /******************************************************************
43 * EndPage16 [GDI.380]
46 INT16 WINAPI EndPage16( HDC16 hdc )
48 INT16 retVal;
49 retVal = Escape16(hdc, NEWFRAME, 0, 0, 0);
50 TRACE(print,"Escape16 returned %d\n",retVal);
51 return retVal;
54 /******************************************************************
55 * StartDoc32A [GDI32.347]
58 INT WINAPI StartDocA(HDC hdc ,const DOCINFOA* doc)
60 FIXME(gdi,"stub\n");
61 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
62 return 0; /* failure*/
65 /*************************************************************************
66 * StartDoc32W [GDI32.348]
69 INT WINAPI StartDocW(HDC hdc, const DOCINFOW* doc) {
70 FIXME(gdi,"stub\n");
71 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
72 return 0; /* failure*/
75 /******************************************************************
76 * StartPage32 [GDI32.349]
79 INT WINAPI StartPage(HDC hdc)
81 FIXME(gdi,"stub\n");
82 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
83 return 0; /* failure*/
86 /******************************************************************
87 * EndPage32 [GDI32.77]
90 INT WINAPI EndPage(HDC hdc)
92 FIXME(gdi,"stub\n");
93 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
94 return 0; /* failure*/
97 /******************************************************************
98 * EndDoc16 [GDI.378]
101 INT16 WINAPI EndDoc16(HDC16 hdc)
103 return Escape16(hdc, ENDDOC, 0, 0, 0);
106 /******************************************************************
107 * EndDoc32 [GDI32.76]
110 INT WINAPI EndDoc(HDC hdc)
112 FIXME(gdi,"stub\n");
113 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
114 return 0; /* failure*/
117 /******************************************************************************
118 * AbortDoc16 [GDI.382]
120 INT16 WINAPI AbortDoc16(HDC16 hdc)
122 return Escape16(hdc, ABORTDOC, 0, 0, 0);
125 /******************************************************************************
126 * AbortDoc32 [GDI32.0]
128 INT WINAPI AbortDoc(HDC hdc)
130 FIXME(gdi, "(%d): stub\n", hdc);
131 return 1;
134 /******************************************************************
135 * DrvGetPrinterDataInternal
137 * Helper for DrvGetPrinterData
139 static DWORD DrvGetPrinterDataInternal(LPSTR RegStr_Printer,
140 LPBYTE lpPrinterData, int cbData, int what)
142 DWORD res = -1;
143 HKEY hkey;
144 DWORD dwType, cbQueryData;
146 if (!(RegOpenKeyA(HKEY_LOCAL_MACHINE, RegStr_Printer, &hkey))) {
147 if (what == INT_PD_DEFAULT_DEVMODE) { /* "Default DevMode" */
148 if (!(RegQueryValueExA(hkey, DefaultDevMode, 0, &dwType, 0, &cbQueryData))) {
149 if (!lpPrinterData)
150 res = cbQueryData;
151 else if ((cbQueryData) && (cbQueryData <= cbData)) {
152 cbQueryData = cbData;
153 if (RegQueryValueExA(hkey, DefaultDevMode, 0,
154 &dwType, lpPrinterData, &cbQueryData))
155 res = cbQueryData;
158 } else { /* "Printer Driver" */
159 cbQueryData = 32;
160 RegQueryValueExA(hkey, "Printer Driver", 0,
161 &dwType, lpPrinterData, &cbQueryData);
162 res = cbQueryData;
165 if (hkey) RegCloseKey(hkey);
166 return res;
169 /******************************************************************
170 * DrvGetPrinterData [GDI.282]
173 DWORD WINAPI DrvGetPrinterData16(LPSTR lpPrinter, LPSTR lpProfile,
174 LPDWORD lpType, LPBYTE lpPrinterData,
175 int cbData, LPDWORD lpNeeded)
177 LPSTR RegStr_Printer;
178 HKEY hkey = 0, hkey2 = 0;
179 DWORD res = 0;
180 DWORD dwType, PrinterAttr, cbPrinterAttr, SetData, size;
182 if (HIWORD(lpPrinter))
183 TRACE(print,"printer %s\n",lpPrinter);
184 else
185 TRACE(print,"printer %p\n",lpPrinter);
186 if (HIWORD(lpProfile))
187 TRACE(print,"profile %s\n",lpProfile);
188 else
189 TRACE(print,"profile %p\n",lpProfile);
190 TRACE(print,"lpType %p\n",lpType);
192 if ((!lpPrinter) || (!lpProfile) || (!lpNeeded))
193 return ERROR_INVALID_PARAMETER;
195 RegStr_Printer = HeapAlloc(GetProcessHeap(), 0,
196 strlen(Printers) + strlen(lpPrinter) + 2);
197 strcpy(RegStr_Printer, Printers);
198 strcat(RegStr_Printer, lpPrinter);
200 if (((DWORD)lpProfile == INT_PD_DEFAULT_DEVMODE) || (HIWORD(lpProfile) &&
201 (!strcmp(lpProfile, DefaultDevMode)))) {
202 size = DrvGetPrinterDataInternal(RegStr_Printer, lpPrinterData, cbData,
203 INT_PD_DEFAULT_DEVMODE);
204 if (size+1) {
205 *lpNeeded = size;
206 if ((lpPrinterData) && (*lpNeeded > cbData))
207 res = ERROR_MORE_DATA;
209 else res = ERROR_INVALID_PRINTER_NAME;
211 else
212 if (((DWORD)lpProfile == INT_PD_DEFAULT_MODEL) || (HIWORD(lpProfile) &&
213 (!strcmp(lpProfile, PrinterModel)))) {
214 *lpNeeded = 32;
215 if (!lpPrinterData) goto failed;
216 if (cbData < 32) {
217 res = ERROR_MORE_DATA;
218 goto failed;
220 size = DrvGetPrinterDataInternal(RegStr_Printer, lpPrinterData, cbData,
221 INT_PD_DEFAULT_MODEL);
222 if ((size+1) && (lpType))
223 *lpType = REG_SZ;
224 else
225 res = ERROR_INVALID_PRINTER_NAME;
227 else
229 if ((res = RegOpenKeyA(HKEY_LOCAL_MACHINE, RegStr_Printer, &hkey)))
230 goto failed;
231 cbPrinterAttr = 4;
232 if ((res = RegQueryValueExA(hkey, "Attributes", 0,
233 &dwType, (LPBYTE)&PrinterAttr, &cbPrinterAttr)))
234 goto failed;
235 if ((res = RegOpenKeyA(hkey, PrinterDriverData, &hkey2)))
236 goto failed;
237 *lpNeeded = cbData;
238 res = RegQueryValueExA(hkey2, lpProfile, 0,
239 lpType, lpPrinterData, lpNeeded);
240 if ((res != ERROR_CANTREAD) &&
241 ((PrinterAttr &
242 (PRINTER_ATTRIBUTE_ENABLE_BIDI|PRINTER_ATTRIBUTE_NETWORK))
243 == PRINTER_ATTRIBUTE_NETWORK))
245 if (!(res) && (*lpType == REG_DWORD) && (*(LPDWORD)lpPrinterData == -1))
246 res = ERROR_INVALID_DATA;
248 else
250 SetData = -1;
251 RegSetValueExA(hkey2, lpProfile, 0, REG_DWORD, (LPBYTE)&SetData, 4); /* no result returned */
255 failed:
256 if (hkey2) RegCloseKey(hkey2);
257 if (hkey) RegCloseKey(hkey);
258 HeapFree(GetProcessHeap(), 0, RegStr_Printer);
259 return res;
263 /******************************************************************
264 * DrvSetPrinterData [GDI.281]
267 DWORD WINAPI DrvSetPrinterData16(LPSTR lpPrinter, LPSTR lpProfile,
268 DWORD lpType, LPBYTE lpPrinterData,
269 DWORD dwSize)
271 LPSTR RegStr_Printer;
272 HKEY hkey = 0;
273 DWORD res = 0;
275 if (HIWORD(lpPrinter))
276 TRACE(print,"printer %s\n",lpPrinter);
277 else
278 TRACE(print,"printer %p\n",lpPrinter);
279 if (HIWORD(lpProfile))
280 TRACE(print,"profile %s\n",lpProfile);
281 else
282 TRACE(print,"profile %p\n",lpProfile);
283 TRACE(print,"lpType %08lx\n",lpType);
285 if ((!lpPrinter) || (!lpProfile) ||
286 ((DWORD)lpProfile == INT_PD_DEFAULT_MODEL) || (HIWORD(lpProfile) &&
287 (!strcmp(lpProfile, PrinterModel))))
288 return ERROR_INVALID_PARAMETER;
290 RegStr_Printer = HeapAlloc(GetProcessHeap(), 0,
291 strlen(Printers) + strlen(lpPrinter) + 2);
292 strcpy(RegStr_Printer, Printers);
293 strcat(RegStr_Printer, lpPrinter);
295 if (((DWORD)lpProfile == INT_PD_DEFAULT_DEVMODE) || (HIWORD(lpProfile) &&
296 (!strcmp(lpProfile, DefaultDevMode)))) {
297 if ( RegOpenKeyA(HKEY_LOCAL_MACHINE, RegStr_Printer, &hkey)
298 != ERROR_SUCCESS ||
299 RegSetValueExA(hkey, DefaultDevMode, 0, REG_BINARY,
300 lpPrinterData, dwSize) != ERROR_SUCCESS )
301 res = ERROR_INVALID_PRINTER_NAME;
303 else
305 strcat(RegStr_Printer, "\\");
307 if( (res = RegOpenKeyA(HKEY_LOCAL_MACHINE, RegStr_Printer, &hkey)) ==
308 ERROR_SUCCESS ) {
310 if (!lpPrinterData)
311 res = RegDeleteValueA(hkey, lpProfile);
312 else
313 res = RegSetValueExA(hkey, lpProfile, 0, lpType,
314 lpPrinterData, dwSize);
318 if (hkey) RegCloseKey(hkey);
319 HeapFree(GetProcessHeap(), 0, RegStr_Printer);
320 return res;
324 /******************************************************************
325 * DeviceCapabilities32A [WINSPOOL.151]
328 INT WINAPI DeviceCapabilitiesA(LPCSTR printer,LPCSTR target,WORD z,
329 LPSTR a,LPDEVMODEA b)
331 FIXME(print,"(%s,%s,%d,%p,%p):stub.\n",printer,target,z,a,b);
332 return 1;
336 /*****************************************************************************
337 * DeviceCapabilities32W
339 INT WINAPI DeviceCapabilitiesW(LPCWSTR pDevice, LPCWSTR pPort,
340 WORD fwCapability, LPWSTR pOutput,
341 const DEVMODEW *pDevMode)
343 FIXME(print,"(%p,%p,%d,%p,%p): stub\n",
344 pDevice, pPort, fwCapability, pOutput, pDevMode);
345 return -1;
348 /******************************************************************
349 * DocumentProperties32A [WINSPOOL.155]
352 LONG WINAPI DocumentPropertiesA(HWND hWnd,HANDLE hPrinter,
353 LPSTR pDeviceName, LPDEVMODEA pDevModeOutput,
354 LPDEVMODEA pDevModeInput,DWORD fMode )
356 FIXME(print,"(%d,%d,%s,%p,%p,%ld):stub.\n",
357 hWnd,hPrinter,pDeviceName,pDevModeOutput,pDevModeInput,fMode
359 return 1;
363 /*****************************************************************************
364 * DocumentProperties32W
366 LONG WINAPI DocumentPropertiesW(HWND hWnd, HANDLE hPrinter,
367 LPWSTR pDeviceName,
368 LPDEVMODEW pDevModeOutput,
369 LPDEVMODEW pDevModeInput, DWORD fMode)
371 FIXME(print,"(%d,%d,%s,%p,%p,%ld): stub\n",
372 hWnd,hPrinter,debugstr_w(pDeviceName),pDevModeOutput,pDevModeInput,
373 fMode);
374 return -1;
378 /******************************************************************
379 * OpenPrinter32A [WINSPOOL.196]
382 BOOL WINAPI OpenPrinterA(LPSTR lpPrinterName,HANDLE *phPrinter,
383 LPPRINTER_DEFAULTSA pDefault)
385 FIXME(print,"(%s,%p,%p):stub\n",debugstr_a(lpPrinterName), phPrinter,
386 pDefault);
387 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
388 return FALSE;
391 /******************************************************************
392 * OpenPrinter32W [WINSPOOL.197]
395 BOOL WINAPI OpenPrinterW(LPWSTR lpPrinterName,HANDLE *phPrinter,
396 LPPRINTER_DEFAULTSW pDefault)
398 FIXME(print,"(%s,%p,%p):stub\n",debugstr_w(lpPrinterName), phPrinter,
399 pDefault);
400 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
401 return FALSE;
405 /******************************************************************
406 * ENUMPRINTERS_AddInfo4A internal
408 * Creates a PRINTER_INFO_4A structure at: lpbPrinters[dwNextStructPos]
409 * for printer PrinterNameKey.
410 * Note that there is no check whether the information really fits!
412 * RETURNS
413 * FALSE if there is still space left in the buffer.
415 * BUGS:
416 * This function should not exist in Win95 mode, but does anyway.
418 BOOL ENUMPRINTERS_AddInfo4A(
419 LPSTR lpszPrinterName,/* name of printer to fill struct for*/
420 LPBYTE lpbPrinters, /* buffer which receives info*/
421 DWORD dwNextStructPos, /* pos in buffer for struct */
422 LPDWORD dwNextStringPos, /* pos in buffer for next string */
423 DWORD dwBufSize, /* max size of buffer in bytes */
424 BOOL bCalcSpaceOnly /* TRUE if out-of-space in buffer */
426 HKEY hPrinterSettings;
427 DWORD DataType;
428 DWORD DataSize=8;
429 char Data[8];
430 DWORD* DataPointer= (DWORD*) Data;
431 LPSTR lpszPrinterSettings = (LPSTR) malloc(strlen(Printers)+
432 strlen(lpszPrinterName)+2);
433 LPPRINTER_INFO_4A lpPInfo4 = (LPPRINTER_INFO_4A) &lpbPrinters[dwNextStructPos];
435 lpPInfo4->pPrinterName = &lpbPrinters[*dwNextStringPos];
436 *dwNextStringPos += strlen(lpszPrinterName)+1;
437 if (*dwNextStringPos > dwBufSize)
438 bCalcSpaceOnly=TRUE;
439 if (bCalcSpaceOnly==FALSE)
440 strcpy(lpPInfo4->pPrinterName, lpszPrinterName);
441 lpPInfo4->pServerName = NULL;
443 /* open the registry to find the attributes of the printer */
444 if (lpszPrinterSettings!=NULL)
446 strcpy(lpszPrinterSettings,Printers);
447 strcat(lpszPrinterSettings,lpszPrinterName);
449 if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, lpszPrinterSettings, 0,
450 KEY_READ, &hPrinterSettings) != ERROR_SUCCESS)
452 FIXME(print, "The registry did not contain my printer anymore?\n");
453 lpPInfo4->Attributes = 0;
455 else
457 RegQueryValueExA(hPrinterSettings, "Attributes", NULL, &DataType,
458 Data, &DataSize);
459 if (DataType==REG_DWORD)
460 lpPInfo4->Attributes = PRINTER_ATTRIBUTE_LOCAL + *DataPointer;
462 if (lpszPrinterSettings)
463 free(lpszPrinterSettings);
465 return(bCalcSpaceOnly);
468 /******************************************************************
469 * ENUMPRINTERS_AddInfo5A internal
471 * Creates a PRINTER_INFO_5A structure at: lpbPrinters[dwNextStructPos]
472 * for printer PrinterNameKey.
473 * Settings are read from the registry.
474 * Note that there is no check whether the information really fits!
475 * RETURNS
476 * FALSE if there is still space left in the buffer.
478 BOOL ENUMPRINTERS_AddInfo5A(
479 LPSTR lpszPrinterName,/* name of printer to fill struct for*/
480 LPBYTE lpbPrinters, /* buffer which receives info*/
481 DWORD dwNextStructPos, /* pos in buffer for struct */
482 LPDWORD dwNextStringPos, /* pos in buffer for next string */
483 DWORD dwBufSize, /* max size of buffer in bytes */
484 BOOL bCalcSpaceOnly /* TRUE if out-of-space in buffer */
486 HKEY hPrinterSettings;
487 DWORD DataType;
488 DWORD DataSize=255;
489 char Data[255];
490 DWORD* DataPointer= (DWORD*) Data;
491 LPSTR lpszPrinterSettings = (LPSTR) malloc(strlen(Printers)+
492 strlen(lpszPrinterName)+2);
493 LPPRINTER_INFO_5A lpPInfo5 = (LPPRINTER_INFO_5A) &lpbPrinters[dwNextStructPos];
495 /* copy the PrinterName into the structure */
496 lpPInfo5->pPrinterName = &lpbPrinters[*dwNextStringPos];
497 *dwNextStringPos += strlen(lpszPrinterName)+1;
498 if (*dwNextStringPos > dwBufSize)
499 bCalcSpaceOnly=TRUE;
500 if (bCalcSpaceOnly==FALSE)
501 strcpy(lpPInfo5->pPrinterName, lpszPrinterName);
503 /* open the registry to find the attributes, etc of the printer */
504 if (lpszPrinterSettings!=NULL)
506 strcpy(lpszPrinterSettings,Printers);
507 strcat(lpszPrinterSettings,lpszPrinterName);
509 if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, lpszPrinterSettings, 0,
510 KEY_READ, &hPrinterSettings) != ERROR_SUCCESS)
512 FIXME(print, "The registry did not contain my printer anymore?\n");
513 lpPInfo5->Attributes = 0;
514 lpPInfo5->pPortName = NULL;
515 lpPInfo5->Attributes = 0;
516 lpPInfo5->DeviceNotSelectedTimeOut =0;
517 lpPInfo5->TransmissionRetryTimeout = 0;
519 else
521 RegQueryValueExA(hPrinterSettings, "Attributes", NULL, &DataType,
522 Data, &DataSize);
523 if (DataType==REG_DWORD)
524 lpPInfo5->Attributes = PRINTER_ATTRIBUTE_LOCAL + *DataPointer;
526 DataSize=255;
527 RegQueryValueExA(hPrinterSettings, "txTimeout", NULL, &DataType,
528 Data, &DataSize);
529 if (DataType==REG_DWORD)
530 lpPInfo5->DeviceNotSelectedTimeOut = *DataPointer;
532 DataSize=255;
533 RegQueryValueExA(hPrinterSettings, "dnsTimeout", NULL, &DataType,
534 Data, &DataSize);
535 if (DataType==REG_DWORD)
536 lpPInfo5->TransmissionRetryTimeout = *DataPointer;
538 DataSize=255;
539 RegQueryValueExA(hPrinterSettings, "Port", NULL, &DataType,
540 Data, &DataSize);
541 lpPInfo5->pPortName = &lpbPrinters[*dwNextStringPos];
542 *dwNextStringPos += DataSize+1;
543 if (*dwNextStringPos > dwBufSize)
544 bCalcSpaceOnly=TRUE;
545 if (bCalcSpaceOnly==FALSE)
546 strcpy(lpPInfo5->pPortName, Data);
549 if (lpszPrinterSettings)
550 free(lpszPrinterSettings);
552 return(bCalcSpaceOnly);
556 /******************************************************************
557 * EnumPrintersA [WINSPOOL.174]
559 * Enumerates the available printers, print servers and print
560 * providers, depending on the specified flags, name and level.
562 * RETURNS:
564 * If level is set to 1:
565 * If level is set to 2:
566 * Not implemented yet!
567 * Returns TRUE with an empty list.
569 * If level is set to 4 (officially WinNT only):
570 * Possible flags: PRINTER_ENUM_CONNECTIONS, PRINTER_ENUM_LOCAL).
571 * Fast: Only the registry is queried to retrieve printer names,
572 * no connection to the driver is made.
573 * Returns an array of PRINTER_INFO_4 data structures in the
574 * lpbPrinters buffer.
576 * If level is set to 5 (officially WinNT4/Win9x only):
577 * Fast: Only the registry is queried to retrieve printer names,
578 * no connection to the driver is made.
579 * Returns an array of PRINTER_INFO_5 data structures in the
580 * lpbPrinters buffer.
582 * If level set to 3 or 6+:
583 * returns zero (faillure!)
585 * Returns nonzero (TRUE) on succes, or zero on faillure, use GetLastError
586 * for information.
588 * BUGS:
589 * - Only PRINTER_ENUM_LOCAL and PRINTER_ENUM_NAME are implemented.
590 * - Only level 4 and 5 are implemented at the moment.
591 * - 16-bit printer drivers are not enumerated.
592 * - returned bytes used/needed do not match the real Windoze implementation
594 * NOTE:
595 * - In a regular Wine installation, no registry settings for printers
596 * exist, which makes this function return an empty list.
598 BOOL WINAPI EnumPrintersA(
599 DWORD dwType, /* Types of print objects to enumerate */
600 LPSTR lpszName, /* name of objects to enumerate */
601 DWORD dwLevel, /* type of printer info structure */
602 LPBYTE lpbPrinters,/* buffer which receives info*/
603 DWORD cbBuf, /* max size of buffer in bytes */
604 LPDWORD lpdwNeeded,/* pointer to var: # bytes used/needed */
605 LPDWORD lpdwReturned/* number of entries returned */
608 HKEY hPrinterListKey;
609 DWORD dwIndex=0;
610 char PrinterName[255];
611 DWORD PrinterNameLength=255;
612 FILETIME FileTime;
613 DWORD dwNextStringPos; /* position of next space for a string in the buffer*/
614 DWORD dwStructPrinterInfoSize; /* size of a Printer_Info_X structure */
615 BOOL bCalcSpaceOnly=FALSE;/* if TRUE: don't store data, just calculate space*/
617 TRACE(print, "EnumPrintersA\n");
619 /* check for valid Flags */
620 if (dwType != PRINTER_ENUM_LOCAL && dwType != PRINTER_ENUM_NAME)
622 SetLastError(ERROR_INVALID_FLAGS);
623 return(0);
625 if (dwLevel == 1 || dwLevel == 2)
626 return(TRUE);
627 if (dwLevel != 4 && dwLevel != 5)
629 SetLastError(ERROR_INVALID_PARAMETER);
630 return(0);
633 /* zero out the data area, and initialise some returns to zero,
634 * to prevent problems
637 int i;
638 for (i=0; i<cbBuf; i++)
639 lpbPrinters[i]=0;
641 *lpdwReturned=0;
642 *lpdwNeeded = 0;
644 /* get a pointer to a list of all printer names in the registry */
645 if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, Printers, 0, KEY_READ,
646 &hPrinterListKey) !=ERROR_SUCCESS)
648 /* Oh no! An empty list of printers!
649 * (which is a valid configuration anyway)
651 TRACE(print, "No entries in the Printers part of the registry\n");
652 return(TRUE);
655 /* count the number of entries and check if it fits in the buffer
657 while(RegEnumKeyExA(hPrinterListKey, dwIndex, PrinterName, &PrinterNameLength,
658 NULL, NULL, NULL, &FileTime)==ERROR_SUCCESS)
660 PrinterNameLength=255;
661 dwIndex++;
663 *lpdwReturned = dwIndex;
664 switch(dwLevel)
666 case 1:
667 dwStructPrinterInfoSize = sizeof(PRINTER_INFO_1A);
668 break;
669 case 2:
670 dwStructPrinterInfoSize = sizeof(PRINTER_INFO_2A);
671 break;
672 case 4:
673 dwStructPrinterInfoSize = sizeof(PRINTER_INFO_4A);
674 break;
675 case 5:
676 dwStructPrinterInfoSize = sizeof(PRINTER_INFO_5A);
677 break;
678 default:
679 dwStructPrinterInfoSize = 0;
680 break;
682 if (dwIndex*dwStructPrinterInfoSize+1 > cbBuf)
683 bCalcSpaceOnly = TRUE;
685 /* the strings which contain e.g. PrinterName, PortName, etc,
686 * are also stored in lpbPrinters, but after the regular structs.
687 * dwNextStringPos will always point to the next free place for a
688 * string.
690 dwNextStringPos=(dwIndex+1)*dwStructPrinterInfoSize;
692 /* check each entry: if OK, add to list in corresponding INFO .
694 for(dwIndex=0; dwIndex < *lpdwReturned; dwIndex++)
696 PrinterNameLength=255;
697 if (RegEnumKeyExA(hPrinterListKey, dwIndex, PrinterName, &PrinterNameLength,
698 NULL, NULL, NULL, &FileTime)!=ERROR_SUCCESS)
699 break; /* exit for loop*/
701 /* check whether this printer is allowed in the list
702 * by comparing name to lpszName
704 if (dwType == PRINTER_ENUM_NAME)
705 if (strcmp(PrinterName,lpszName)!=0)
706 continue;
708 switch(dwLevel)
710 case 1:
711 /* FIXME: unimplemented */
712 break;
713 case 2:
714 /* FIXME: unimplemented */
715 break;
716 case 4:
717 bCalcSpaceOnly = ENUMPRINTERS_AddInfo4A(PrinterName, lpbPrinters,
718 dwIndex*dwStructPrinterInfoSize,
719 &dwNextStringPos, cbBuf, bCalcSpaceOnly);
720 break;
721 case 5:
722 bCalcSpaceOnly = ENUMPRINTERS_AddInfo5A(PrinterName, lpbPrinters,
723 dwIndex*dwStructPrinterInfoSize,
724 &dwNextStringPos, cbBuf, bCalcSpaceOnly);
725 break;
728 RegCloseKey(hPrinterListKey);
729 *lpdwNeeded = dwNextStringPos;
731 if (bCalcSpaceOnly==TRUE)
733 int i;
734 for (i=0; i<cbBuf; i++)
735 lpbPrinters[i]=0;
736 *lpdwReturned=0;
739 return(TRUE);
742 /******************************************************************
743 * EnumPrinters32W [WINSPOOL.175]
746 BOOL WINAPI EnumPrintersW(DWORD dwType, LPWSTR lpszName,
747 DWORD dwLevel, LPBYTE lpbPrinters,
748 DWORD cbBuf, LPDWORD lpdwNeeded,
749 LPDWORD lpdwReturned)
751 FIXME(print,"Nearly empty stub\n");
752 *lpdwReturned=0;
753 *lpdwNeeded = 0;
754 return TRUE;
757 /******************************************************************
758 * AddMonitor32A [WINSPOOL.107]
761 BOOL WINAPI AddMonitorA(LPCSTR pName, DWORD Level, LPBYTE pMonitors)
763 FIXME(print, "(%s,%lx,%p):stub!\n", pName, Level, pMonitors);
764 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
765 return FALSE;
768 /******************************************************************
769 * DeletePrinterDriver32A [WINSPOOL.146]
772 BOOL WINAPI
773 DeletePrinterDriverA (LPSTR pName, LPSTR pEnvironment, LPSTR pDriverName)
775 FIXME(print,"(%s,%s,%s):stub\n",debugstr_a(pName),debugstr_a(pEnvironment),
776 debugstr_a(pDriverName));
777 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
778 return FALSE;
782 /******************************************************************
783 * DeleteMonitor32A [WINSPOOL.135]
786 BOOL WINAPI
787 DeleteMonitorA (LPSTR pName, LPSTR pEnvironment, LPSTR pMonitorName)
789 FIXME(print,"(%s,%s,%s):stub\n",debugstr_a(pName),debugstr_a(pEnvironment),
790 debugstr_a(pMonitorName));
791 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
792 return FALSE;
796 /******************************************************************
797 * DeletePort32A [WINSPOOL.137]
800 BOOL WINAPI
801 DeletePortA (LPSTR pName, HWND hWnd, LPSTR pPortName)
803 FIXME(print,"(%s,0x%08x,%s):stub\n",debugstr_a(pName),hWnd,
804 debugstr_a(pPortName));
805 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
806 return FALSE;
809 /******************************************************************************
810 * SetPrinter32W [WINSPOOL.214]
812 BOOL WINAPI
813 SetPrinterW(
814 HANDLE hPrinter,
815 DWORD Level,
816 LPBYTE pPrinter,
817 DWORD Command) {
819 FIXME(print,"():stub\n");
820 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
821 return FALSE;
824 /******************************************************************************
825 * WritePrinter32 [WINSPOOL.223]
827 BOOL WINAPI
828 WritePrinter(
829 HANDLE hPrinter,
830 LPVOID pBuf,
831 DWORD cbBuf,
832 LPDWORD pcWritten) {
834 FIXME(print,"():stub\n");
835 SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
836 return FALSE;
839 /*****************************************************************************
840 * AddForm32A [WINSPOOL.103]
842 BOOL WINAPI AddFormA(HANDLE hPrinter, DWORD Level, LPBYTE pForm)
844 FIXME(print, "(%d,%ld,%p): stub\n", hPrinter, Level, pForm);
845 return 1;
848 /*****************************************************************************
849 * AddForm32W [WINSPOOL.104]
851 BOOL WINAPI AddFormW(HANDLE hPrinter, DWORD Level, LPBYTE pForm)
853 FIXME(print, "(%d,%ld,%p): stub\n", hPrinter, Level, pForm);
854 return 1;
857 /*****************************************************************************
858 * AddJob32A [WINSPOOL.105]
860 BOOL WINAPI AddJobA(HANDLE hPrinter, DWORD Level, LPBYTE pData,
861 DWORD cbBuf, LPDWORD pcbNeeded)
863 FIXME(print, "(%d,%ld,%p,%ld,%p): stub\n", hPrinter, Level, pData, cbBuf,
864 pcbNeeded);
865 return 1;
868 /*****************************************************************************
869 * AddJob32W [WINSPOOL.106]
871 BOOL WINAPI AddJobW(HANDLE hPrinter, DWORD Level, LPBYTE pData, DWORD cbBuf,
872 LPDWORD pcbNeeded)
874 FIXME(print, "(%d,%ld,%p,%ld,%p): stub\n", hPrinter, Level, pData, cbBuf,
875 pcbNeeded);
876 return 1;
879 /*****************************************************************************
880 * AddPrinter32A [WINSPOOL.117]
882 HANDLE WINAPI AddPrinterA(LPSTR pName, DWORD Level, LPBYTE pPrinter)
884 FIXME(print, "(%s,%ld,%p): stub\n", pName, Level, pPrinter);
885 return 0;
888 /*****************************************************************************
889 * AddPrinter32W [WINSPOOL.122]
891 HANDLE WINAPI AddPrinterW(LPWSTR pName, DWORD Level, LPBYTE pPrinter)
893 FIXME(print, "(%p,%ld,%p): stub\n", pName, Level, pPrinter);
894 return 0;
898 /*****************************************************************************
899 * ClosePrinter32 [WINSPOOL.126]
901 BOOL WINAPI ClosePrinter(HANDLE hPrinter)
903 FIXME(print, "(%d): stub\n", hPrinter);
904 return 1;
907 /*****************************************************************************
908 * DeleteForm32A [WINSPOOL.133]
910 BOOL WINAPI DeleteFormA(HANDLE hPrinter, LPSTR pFormName)
912 FIXME(print, "(%d,%s): stub\n", hPrinter, pFormName);
913 return 1;
916 /*****************************************************************************
917 * DeleteForm32W [WINSPOOL.134]
919 BOOL WINAPI DeleteFormW(HANDLE hPrinter, LPWSTR pFormName)
921 FIXME(print, "(%d,%s): stub\n", hPrinter, debugstr_w(pFormName));
922 return 1;
925 /*****************************************************************************
926 * DeletePrinter32 [WINSPOOL.143]
928 BOOL WINAPI DeletePrinter(HANDLE hPrinter)
930 FIXME(print, "(%d): stub\n", hPrinter);
931 return 1;
934 /*****************************************************************************
935 * SetPrinter32A [WINSPOOL.211]
937 BOOL WINAPI SetPrinterA(HANDLE hPrinter, DWORD Level, LPBYTE pPrinter,
938 DWORD Command)
940 FIXME(print, "(%d,%ld,%p,%ld): stub\n",hPrinter,Level,pPrinter,Command);
941 return FALSE;
944 /*****************************************************************************
945 * SetJob32A [WINSPOOL.209]
947 BOOL WINAPI SetJobA(HANDLE hPrinter, DWORD JobId, DWORD Level,
948 LPBYTE pJob, DWORD Command)
950 FIXME(print, "(%d,%ld,%ld,%p,%ld): stub\n",hPrinter,JobId,Level,pJob,
951 Command);
952 return FALSE;
955 /*****************************************************************************
956 * SetJob32W [WINSPOOL.210]
958 BOOL WINAPI SetJobW(HANDLE hPrinter, DWORD JobId, DWORD Level,
959 LPBYTE pJob, DWORD Command)
961 FIXME(print, "(%d,%ld,%ld,%p,%ld): stub\n",hPrinter,JobId,Level,pJob,
962 Command);
963 return FALSE;
966 /*****************************************************************************
967 * GetForm32A [WINSPOOL.181]
969 BOOL WINAPI GetFormA(HANDLE hPrinter, LPSTR pFormName, DWORD Level,
970 LPBYTE pForm, DWORD cbBuf, LPDWORD pcbNeeded)
972 FIXME(print, "(%d,%s,%ld,%p,%ld,%p): stub\n",hPrinter,pFormName,
973 Level,pForm,cbBuf,pcbNeeded);
974 return FALSE;
977 /*****************************************************************************
978 * GetForm32W [WINSPOOL.182]
980 BOOL WINAPI GetFormW(HANDLE hPrinter, LPWSTR pFormName, DWORD Level,
981 LPBYTE pForm, DWORD cbBuf, LPDWORD pcbNeeded)
983 FIXME(print, "(%d,%s,%ld,%p,%ld,%p): stub\n",hPrinter,
984 debugstr_w(pFormName),Level,pForm,cbBuf,pcbNeeded);
985 return FALSE;
988 /*****************************************************************************
989 * SetForm32A [WINSPOOL.207]
991 BOOL WINAPI SetFormA(HANDLE hPrinter, LPSTR pFormName, DWORD Level,
992 LPBYTE pForm)
994 FIXME(print, "(%d,%s,%ld,%p): stub\n",hPrinter,pFormName,Level,pForm);
995 return FALSE;
998 /*****************************************************************************
999 * SetForm32W [WINSPOOL.208]
1001 BOOL WINAPI SetFormW(HANDLE hPrinter, LPWSTR pFormName, DWORD Level,
1002 LPBYTE pForm)
1004 FIXME(print, "(%d,%p,%ld,%p): stub\n",hPrinter,pFormName,Level,pForm);
1005 return FALSE;
1008 /*****************************************************************************
1009 * ReadPrinter32 [WINSPOOL.202]
1011 BOOL WINAPI ReadPrinter(HANDLE hPrinter, LPVOID pBuf, DWORD cbBuf,
1012 LPDWORD pNoBytesRead)
1014 FIXME(print, "(%d,%p,%ld,%p): stub\n",hPrinter,pBuf,cbBuf,pNoBytesRead);
1015 return FALSE;
1018 /*****************************************************************************
1019 * ResetPrinter32A [WINSPOOL.203]
1021 BOOL WINAPI ResetPrinterA(HANDLE hPrinter, LPPRINTER_DEFAULTSA pDefault)
1023 FIXME(print, "(%d, %p): stub\n", hPrinter, pDefault);
1024 return FALSE;
1027 /*****************************************************************************
1028 * ResetPrinter32W [WINSPOOL.204]
1030 BOOL WINAPI ResetPrinterW(HANDLE hPrinter, LPPRINTER_DEFAULTSW pDefault)
1032 FIXME(print, "(%d, %p): stub\n", hPrinter, pDefault);
1033 return FALSE;
1036 /*****************************************************************************
1037 * GetPrinter32A [WINSPOOL.187]
1039 BOOL WINAPI GetPrinterA(HANDLE hPrinter, DWORD Level, LPBYTE pPrinter,
1040 DWORD cbBuf, LPDWORD pcbNeeded)
1042 FIXME(print, "(%d,%ld,%p,%ld,%p): stub\n", hPrinter, Level, pPrinter,
1043 cbBuf, pcbNeeded);
1044 return FALSE;
1047 /*****************************************************************************
1048 * GetPrinter32W [WINSPOOL.194]
1050 BOOL WINAPI GetPrinterW(HANDLE hPrinter, DWORD Level, LPBYTE pPrinter,
1051 DWORD cbBuf, LPDWORD pcbNeeded)
1053 FIXME(print, "(%d,%ld,%p,%ld,%p): stub\n", hPrinter, Level, pPrinter,
1054 cbBuf, pcbNeeded);
1055 return FALSE;
1058 /*****************************************************************************
1059 * GetPrinterDriver32A [WINSPOOL.190]
1061 BOOL WINAPI GetPrinterDriverA(HANDLE hPrinter, LPSTR pEnvironment,
1062 DWORD Level, LPBYTE pDriverInfo,
1063 DWORD cbBuf, LPDWORD pcbNeeded)
1065 FIXME(print, "(%d,%s,%ld,%p,%ld,%p): stub\n",hPrinter,pEnvironment,
1066 Level,pDriverInfo,cbBuf, pcbNeeded);
1067 return FALSE;
1070 /*****************************************************************************
1071 * GetPrinterDriver32W [WINSPOOL.193]
1073 BOOL WINAPI GetPrinterDriverW(HANDLE hPrinter, LPWSTR pEnvironment,
1074 DWORD Level, LPBYTE pDriverInfo,
1075 DWORD cbBuf, LPDWORD pcbNeeded)
1077 FIXME(print, "(%d,%p,%ld,%p,%ld,%p): stub\n",hPrinter,pEnvironment,
1078 Level,pDriverInfo,cbBuf, pcbNeeded);
1079 return FALSE;
1081 /*****************************************************************************
1082 * AddPrinterDriver32A [WINSPOOL.120]
1084 BOOL WINAPI AddPrinterDriverA(LPSTR printerName,DWORD level,
1085 LPBYTE pDriverInfo)
1087 FIXME(print, "(%s,%ld,%p): stub\n",printerName,level,pDriverInfo);
1088 return FALSE;
1090 /*****************************************************************************
1091 * AddPrinterDriver32W [WINSPOOL.121]
1093 BOOL WINAPI AddPrinterDriverW(LPWSTR printerName,DWORD level,
1094 LPBYTE pDriverInfo)
1096 FIXME(print, "(%s,%ld,%p): stub\n",debugstr_w(printerName),
1097 level,pDriverInfo);
1098 return FALSE;