Fix for SetAbortProc16, stub for SetAbortProc32 and tidy up some other
[wine] / misc / printdrv.c
1 /* 
2  * Implementation of some printer driver bits
3  * 
4  * Copyright 1996 John Harvey
5  * Copyright 1998 Andreas Mohr
6  */
7
8 #include <stdlib.h>
9 #include <string.h>
10 #include <ctype.h>
11 #include "windows.h"
12 #include "win.h"
13 #include "winerror.h"
14 #include "winreg.h"
15 #include "debug.h"
16 #include "print.h"
17
18 static char PrinterModel[]      = "Printer Model";
19 static char DefaultDevMode[]    = "Default DevMode";
20 static char PrinterDriverData[] = "PrinterDriverData";
21 static char Printers[]          = "System\\CurrentControlSet\\Control\\Print\\Printers\\";
22
23 /******************************************************************
24  *                  StartDoc16  [GDI.377]
25  *
26  */
27 INT16 WINAPI StartDoc16( HDC16 hdc, const DOCINFO16 *lpdoc )
28 {
29   INT16 retVal;
30   TRACE(print,"(%p)\n", lpdoc );
31   TRACE(print,"%d 0x%lx:0x%p 0x%lx:0x%p\n",lpdoc->cbSize,
32         lpdoc->lpszDocName,PTR_SEG_TO_LIN(lpdoc->lpszDocName),
33         lpdoc->lpszOutput,PTR_SEG_TO_LIN(lpdoc->lpszOutput));
34   TRACE(print, "%d %s %s\n",lpdoc->cbSize,
35         (LPSTR)PTR_SEG_TO_LIN(lpdoc->lpszDocName),
36         (LPSTR)PTR_SEG_TO_LIN(lpdoc->lpszOutput));
37   retVal =  Escape16(hdc, STARTDOC,
38     strlen((LPSTR)PTR_SEG_TO_LIN(lpdoc->lpszDocName)), lpdoc->lpszDocName, 0);
39   TRACE(print,"Escape16 returned %d\n",retVal);
40   return retVal;
41 }
42
43 /******************************************************************
44  *                  StartDoc32A  [GDI32.347]
45  *
46  */
47 INT32 WINAPI StartDoc32A(HDC32 hdc ,const DOCINFO32A* doc)
48 {
49   FIXME(gdi,"stub\n");
50   SetLastError(ERROR_CALL_NOT_IMPLEMENTED); 
51   return 0; /* failure*/
52 }
53
54 /******************************************************************
55  *                  StartPage32  [GDI32.349]
56  *
57  */
58 INT32 WINAPI StartPage32(HDC32 hdc)
59 {
60   FIXME(gdi,"stub\n");
61   SetLastError(ERROR_CALL_NOT_IMPLEMENTED); 
62   return 0; /* failure*/
63 }
64
65 /******************************************************************
66  *                  EndPage32  [GDI32.77]
67  *
68  */
69 INT32 WINAPI EndPage32(HDC32 hdc)
70 {
71   FIXME(gdi,"stub\n");
72   SetLastError(ERROR_CALL_NOT_IMPLEMENTED); 
73   return 0; /* failure*/
74 }
75
76 /******************************************************************
77  *                  EndDoc16  [GDI.378]
78  *
79  */
80 INT16 WINAPI EndDoc16(HDC16 hdc)
81 {
82   return  Escape16(hdc, ENDDOC, 0, 0, 0);
83 }
84
85 /******************************************************************
86  *                  EndDoc32  [GDI32.76]
87  *
88  */
89 INT32 WINAPI EndDoc32(HDC32 hdc)
90 {
91   FIXME(gdi,"stub\n");
92   SetLastError(ERROR_CALL_NOT_IMPLEMENTED); 
93   return 0; /* failure*/
94 }
95
96 /******************************************************************
97  *                  DrvGetPrinterDataInternal
98  *
99  * Helper for DrvGetPrinterData
100  */
101 static DWORD DrvGetPrinterDataInternal(LPSTR RegStr_Printer,
102 LPBYTE lpPrinterData, int cbData)
103 {
104     DWORD res = -1;
105     HKEY hkey;
106     DWORD dwType, cbQueryData;
107
108     if (!(RegOpenKey32A(HKEY_LOCAL_MACHINE, RegStr_Printer, &hkey))) {
109         if (cbData > 1) { /* "Default DevMode" */
110             if (!(RegQueryValueEx32A(hkey, DefaultDevMode, 0, &dwType, 0, &cbQueryData))) {
111                 if (!lpPrinterData)
112                     res = cbQueryData;
113                 else if ((cbQueryData) && (cbQueryData <= cbData)) {
114                     cbQueryData = cbData;
115                     if (RegQueryValueEx32A(hkey, DefaultDevMode, 0,
116                                 &dwType, lpPrinterData, &cbQueryData))
117                         res = cbQueryData;
118                 }
119             }
120         } else { /* "Printer Driver" */
121             cbQueryData = 32;
122             RegQueryValueEx32A(hkey, "Printer Driver", 0,
123                         &dwType, lpPrinterData, &cbQueryData);
124             res = cbQueryData;
125         }
126     }
127     if (hkey) RegCloseKey(hkey);
128     return res;
129 }
130
131 /******************************************************************
132  *                DrvGetPrinterData     [GDI.282]
133  *
134  */
135 DWORD WINAPI DrvGetPrinterData(LPSTR lpPrinter, LPSTR lpProfile,
136                                LPDWORD lpType, LPBYTE lpPrinterData,
137                                int cbData, LPDWORD lpNeeded)
138 {
139     LPSTR RegStr_Printer;
140     HKEY hkey = 0, hkey2 = 0;
141     DWORD res = 0;
142     DWORD dwType, PrinterAttr, cbPrinterAttr, SetData, size;
143
144     if (HIWORD(lpPrinter))
145             TRACE(print,"printer %s\n",lpPrinter);
146     else
147             TRACE(print,"printer %p\n",lpPrinter);
148     if (HIWORD(lpProfile))
149             TRACE(print,"profile %s\n",lpProfile);
150     else
151             TRACE(print,"profile %p\n",lpProfile);
152     TRACE(print,"lpType %p\n",lpType);
153
154     if ((!lpPrinter) || (!lpProfile) || (!lpNeeded))
155         return ERROR_INVALID_PARAMETER;
156
157     RegStr_Printer = HeapAlloc(GetProcessHeap(), 0,
158                                strlen(Printers) + strlen(lpPrinter) + 2);
159     strcpy(RegStr_Printer, Printers);
160     strcat(RegStr_Printer, lpPrinter);
161
162     if (((DWORD)lpProfile == INT_PD_DEFAULT_DEVMODE) || (HIWORD(lpProfile) &&
163     (!strcmp(lpProfile, DefaultDevMode)))) {
164         size = DrvGetPrinterDataInternal(RegStr_Printer, lpPrinterData, cbData);
165         if (size+1) {
166             *lpNeeded = size;
167             if ((lpPrinterData) && (*lpNeeded > cbData))
168                 res = ERROR_MORE_DATA;
169         }
170         else res = ERROR_INVALID_PRINTER_NAME;
171     }
172     else
173     if (((DWORD)lpProfile == INT_PD_DEFAULT_MODEL) || (HIWORD(lpProfile) &&
174     (!strcmp(lpProfile, PrinterModel)))) {
175         *lpNeeded = 32;
176         if (!lpPrinterData) goto failed;
177         if (cbData < 32) {
178             res = ERROR_MORE_DATA;
179             goto failed;
180         }
181         size = DrvGetPrinterDataInternal(RegStr_Printer, lpPrinterData, 1);
182         if ((size+1) && (lpType))
183             *lpType = REG_SZ;
184         else
185             res = ERROR_INVALID_PRINTER_NAME;
186     }
187     else
188     {
189         if ((res = RegOpenKey32A(HKEY_LOCAL_MACHINE, RegStr_Printer, &hkey)))
190             goto failed;
191         cbPrinterAttr = 4;
192         if ((res = RegQueryValueEx32A(hkey, "Attributes", 0,
193                         &dwType, (LPBYTE)&PrinterAttr, &cbPrinterAttr)))
194             goto failed;
195         if ((res = RegOpenKey32A(hkey, PrinterDriverData, &hkey2)))
196             goto failed;
197         *lpNeeded = cbData;
198         res = RegQueryValueEx32A(hkey2, lpProfile, 0,
199                 lpType, lpPrinterData, lpNeeded);
200         if ((res != ERROR_CANTREAD) &&
201          ((PrinterAttr &
202         (PRINTER_ATTRIBUTE_ENABLE_BIDI|PRINTER_ATTRIBUTE_NETWORK))
203         == PRINTER_ATTRIBUTE_NETWORK))
204         {
205             if (!(res) && (*lpType == REG_DWORD) && (*(LPDWORD)lpPrinterData == -1))
206                 res = ERROR_INVALID_DATA;
207         }
208         else
209         {
210             SetData = -1;
211             RegSetValueEx32A(hkey2, lpProfile, 0, REG_DWORD, (LPBYTE)&SetData, 4); /* no result returned */
212         }
213     }
214         
215 failed:
216     if (hkey2) RegCloseKey(hkey2);
217     if (hkey) RegCloseKey(hkey);
218     HeapFree(GetProcessHeap(), 0, RegStr_Printer);
219     return res;
220 }
221
222
223 /******************************************************************
224  *                 DrvSetPrinterData     [GDI.281]
225  *
226  */
227 DWORD WINAPI DrvSetPrinterData(LPSTR lpPrinter, LPSTR lpProfile,
228                                DWORD lpType, LPBYTE lpPrinterData,
229                                DWORD dwSize)
230 {
231     LPSTR RegStr_Printer;
232     HKEY hkey = 0;
233     DWORD res = 0;
234
235     if (HIWORD(lpPrinter))
236             TRACE(print,"printer %s\n",lpPrinter);
237     else
238             TRACE(print,"printer %p\n",lpPrinter);
239     if (HIWORD(lpProfile))
240             TRACE(print,"profile %s\n",lpProfile);
241     else
242             TRACE(print,"profile %p\n",lpProfile);
243     TRACE(print,"lpType %08lx\n",lpType);
244
245     if ((!lpPrinter) || (!lpProfile) ||
246     ((DWORD)lpProfile == INT_PD_DEFAULT_MODEL) || (HIWORD(lpProfile) &&
247     (!strcmp(lpProfile, PrinterModel))))
248         return ERROR_INVALID_PARAMETER;
249
250     RegStr_Printer = HeapAlloc(GetProcessHeap(), 0,
251                         strlen(Printers) + strlen(lpPrinter) + 2);
252     strcpy(RegStr_Printer, Printers);
253     strcat(RegStr_Printer, lpPrinter);
254
255     if (((DWORD)lpProfile == INT_PD_DEFAULT_DEVMODE) || (HIWORD(lpProfile) &&
256     (!strcmp(lpProfile, DefaultDevMode)))) {
257         if ( RegOpenKey32A(HKEY_LOCAL_MACHINE, RegStr_Printer, &hkey) 
258              != ERROR_SUCCESS ||
259              RegSetValueEx32A(hkey, DefaultDevMode, 0, REG_BINARY, 
260                               lpPrinterData, dwSize) != ERROR_SUCCESS )
261                 res = ERROR_INVALID_PRINTER_NAME;
262     }
263     else
264     {
265         strcat(RegStr_Printer, "\\");
266
267         if( (res = RegOpenKey32A(HKEY_LOCAL_MACHINE, RegStr_Printer, &hkey)) ==
268             ERROR_SUCCESS ) {
269
270             if (!lpPrinterData) 
271                 res = RegDeleteValue32A(hkey, lpProfile);
272             else
273                 res = RegSetValueEx32A(hkey, lpProfile, 0, lpType,
274                                        lpPrinterData, dwSize);
275         }
276     }
277
278     if (hkey) RegCloseKey(hkey);
279     HeapFree(GetProcessHeap(), 0, RegStr_Printer);
280     return res;
281 }
282
283
284 /******************************************************************
285  *              DeviceCapabilities32A    [WINSPOOL.151]
286  *
287  */
288 INT32 WINAPI DeviceCapabilities32A(LPCSTR printer,LPCSTR target,WORD z,
289                                    LPSTR a,LPDEVMODE32A b)
290 {
291     FIXME(print,"(%s,%s,%d,%p,%p):stub.\n",printer,target,z,a,b);
292     return 1;           
293 }
294
295
296 /******************************************************************
297  *              DocumentProperties32A   [WINSPOOL.155]
298  *
299  */
300 LONG WINAPI DocumentProperties32A(HWND32 hWnd,HANDLE32 hPrinter,
301                                 LPSTR pDeviceName, LPDEVMODE32A pDevModeOutput,
302                                   LPDEVMODE32A pDevModeInput,DWORD fMode )
303 {
304     FIXME(print,"(%d,%d,%s,%p,%p,%ld):stub.\n",
305         hWnd,hPrinter,pDeviceName,pDevModeOutput,pDevModeInput,fMode
306     );
307     return 1;
308 }
309
310
311 /******************************************************************
312  *              OpenPrinter32A        [WINSPOOL.196]
313  *
314  */
315 BOOL32 WINAPI OpenPrinter32A(LPSTR lpPrinterName,HANDLE32 *phPrinter,
316                              LPPRINTER_DEFAULTS32A pDefault)
317 {
318     FIXME(print,"(%s,%p,%p):stub\n",debugstr_a(lpPrinterName), phPrinter,
319           pDefault);
320     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
321     return FALSE;
322 }
323
324 /******************************************************************
325  *              OpenPrinter32W        [WINSPOOL.197]
326  *
327  */
328 BOOL32 WINAPI OpenPrinter32W(LPWSTR lpPrinterName,HANDLE32 *phPrinter,
329                              LPPRINTER_DEFAULTS32W pDefault)
330 {
331     FIXME(print,"(%s,%p,%p):stub\n",debugstr_w(lpPrinterName), phPrinter,
332           pDefault);
333     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
334     return FALSE;
335 }
336
337 /******************************************************************
338  *              EnumPrinters32A        [WINSPOOL.174]
339  *
340  */
341 BOOL32  WINAPI EnumPrinters32A(DWORD dwType, LPSTR lpszName,
342                                DWORD dwLevel, LPBYTE lpbPrinters,
343                                DWORD cbBuf, LPDWORD lpdwNeeded,
344                                LPDWORD lpdwReturned)
345 {
346     FIXME(print,"Nearly empty stub\n");
347     *lpdwReturned=0;
348     return TRUE;
349 }
350
351 /******************************************************************
352  *              EnumPrinters32W        [WINSPOOL.175]
353  *
354  */
355 BOOL32  WINAPI EnumPrinters32W(DWORD dwType, LPWSTR lpszName,
356                                DWORD dwLevel, LPBYTE lpbPrinters,
357                                DWORD cbBuf, LPDWORD lpdwNeeded,
358                                LPDWORD lpdwReturned)
359 {
360     FIXME(print,"Nearly empty stub\n");
361     *lpdwReturned=0;
362     return TRUE;
363 }
364
365 /******************************************************************
366  *              AddMonitor32A        [WINSPOOL.107]
367  *
368  */
369 BOOL32 WINAPI AddMonitor32A(LPCSTR pName, DWORD Level, LPBYTE pMonitors)
370 {
371     FIXME(print, "(%s,%lx,%p):stub!\n", pName, Level, pMonitors);
372     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
373     return FALSE;
374 }
375
376 /******************************************************************
377  *              DeletePrinterDriver32A        [WINSPOOL.146]
378  *
379  */
380 BOOL32 WINAPI
381 DeletePrinterDriver32A (LPSTR pName, LPSTR pEnvironment, LPSTR pDriverName)
382 {
383     FIXME(print,"(%s,%s,%s):stub\n",debugstr_a(pName),debugstr_a(pEnvironment),
384           debugstr_a(pDriverName));
385     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
386     return FALSE;
387 }
388
389
390 /******************************************************************
391  *              DeleteMonitor32A        [WINSPOOL.135]
392  *
393  */
394 BOOL32 WINAPI
395 DeleteMonitor32A (LPSTR pName, LPSTR pEnvironment, LPSTR pMonitorName)
396 {
397     FIXME(print,"(%s,%s,%s):stub\n",debugstr_a(pName),debugstr_a(pEnvironment),
398           debugstr_a(pMonitorName));
399     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
400     return FALSE;
401 }
402
403
404 /******************************************************************
405  *              DeletePort32A        [WINSPOOL.137]
406  *
407  */
408 BOOL32 WINAPI
409 DeletePort32A (LPSTR pName, HWND32 hWnd, LPSTR pPortName)
410 {
411     FIXME(print,"(%s,0x%08x,%s):stub\n",debugstr_a(pName),hWnd,
412           debugstr_a(pPortName));
413     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
414     return FALSE;
415 }
416