Some fixes to Wine startup/termination sequence with native USER.
[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 INT16 WINAPI StartDoc16( HDC16 hdc, const DOCINFO16 *lpdoc )
24 {
25   INT16 retVal;
26   TRACE(print,"(%p)\n", lpdoc );
27   TRACE(print,"%d 0x%lx:0x%p 0x%lx:0x%p\n",lpdoc->cbSize,
28         lpdoc->lpszDocName,PTR_SEG_TO_LIN(lpdoc->lpszDocName),
29         lpdoc->lpszOutput,PTR_SEG_TO_LIN(lpdoc->lpszOutput));
30   TRACE(print, "%d %s %s\n",lpdoc->cbSize,
31         (LPSTR)PTR_SEG_TO_LIN(lpdoc->lpszDocName),
32         (LPSTR)PTR_SEG_TO_LIN(lpdoc->lpszOutput));
33   retVal =  Escape16(hdc, STARTDOC,
34     strlen((LPSTR)PTR_SEG_TO_LIN(lpdoc->lpszDocName)), lpdoc->lpszDocName, 0);
35   TRACE(print,"Escape16 returned %d\n",retVal);
36   return retVal;
37 }
38
39 INT16 WINAPI EndDoc16(HDC16 hdc)
40 {
41   return  Escape16(hdc, ENDDOC, 0, 0, 0);
42 }
43
44 DWORD DrvGetPrinterDataInternal(LPSTR RegStr_Printer, LPBYTE lpPrinterData, int cbData)
45 {
46     DWORD res = -1;
47     HKEY hkey;
48     DWORD dwType, cbQueryData;
49
50     if (!(RegOpenKey32A(HKEY_LOCAL_MACHINE, RegStr_Printer, &hkey))) {
51         if (cbData > 1) { /* "Default DevMode" */
52             if (!(RegQueryValueEx32A(hkey, DefaultDevMode, 0, &dwType, 0, &cbQueryData))) {
53                 if (!lpPrinterData)
54                     res = cbQueryData;
55                 else if ((cbQueryData) && (cbQueryData <= cbData)) {
56                     cbQueryData = cbData;
57                     if (RegQueryValueEx32A(hkey, DefaultDevMode, 0,
58                                 &dwType, lpPrinterData, &cbQueryData))
59                         res = cbQueryData;
60                 }
61             }
62         } else { /* "Printer Driver" */
63             cbQueryData = 32;
64             RegQueryValueEx32A(hkey, "Printer Driver", 0,
65                         &dwType, lpPrinterData, &cbQueryData);
66             res = cbQueryData;
67         }
68     }
69     if (hkey) RegCloseKey(hkey);
70     return res;
71 }
72
73
74 DWORD WINAPI DrvGetPrinterData(LPSTR lpPrinter, LPSTR lpProfile,
75                                LPDWORD lpType, LPBYTE lpPrinterData,
76                                int cbData, LPDWORD lpNeeded)
77 {
78     LPSTR RegStr_Printer;
79     HKEY hkey = 0, hkey2 = 0;
80     DWORD res = 0;
81     DWORD dwType, PrinterAttr, cbPrinterAttr, SetData, size;
82
83     if (HIWORD(lpPrinter))
84             TRACE(print,"printer %s\n",lpPrinter);
85     else
86             TRACE(print,"printer %p\n",lpPrinter);
87     if (HIWORD(lpProfile))
88             TRACE(print,"profile %s\n",lpProfile);
89     else
90             TRACE(print,"profile %p\n",lpProfile);
91     TRACE(print,"lpType %p\n",lpType);
92
93     if ((!lpPrinter) || (!lpProfile) || (!lpNeeded))
94         return ERROR_INVALID_PARAMETER;
95
96     RegStr_Printer = HeapAlloc(GetProcessHeap(), 0,
97                                strlen(Printers) + strlen(lpPrinter) + 2);
98     strcpy(RegStr_Printer, Printers);
99     strcat(RegStr_Printer, lpPrinter);
100
101     if (((DWORD)lpProfile == INT_PD_DEFAULT_DEVMODE) || (HIWORD(lpProfile) &&
102     (!strcmp(lpProfile, DefaultDevMode)))) {
103         size = DrvGetPrinterDataInternal(RegStr_Printer, lpPrinterData, cbData);
104         if (size+1) {
105             *lpNeeded = size;
106             if ((lpPrinterData) && (*lpNeeded > cbData))
107                 res = ERROR_MORE_DATA;
108         }
109         else res = ERROR_INVALID_PRINTER_NAME;
110     }
111     else
112     if (((DWORD)lpProfile == INT_PD_DEFAULT_MODEL) || (HIWORD(lpProfile) &&
113     (!strcmp(lpProfile, PrinterModel)))) {
114         *lpNeeded = 32;
115         if (!lpPrinterData) goto failed;
116         if (cbData < 32) {
117             res = ERROR_MORE_DATA;
118             goto failed;
119         }
120         size = DrvGetPrinterDataInternal(RegStr_Printer, lpPrinterData, 1);
121         if ((size+1) && (lpType))
122             *lpType = REG_SZ;
123         else
124             res = ERROR_INVALID_PRINTER_NAME;
125     }
126     else
127     {
128         if ((res = RegOpenKey32A(HKEY_LOCAL_MACHINE, RegStr_Printer, &hkey)))
129             goto failed;
130         cbPrinterAttr = 4;
131         if ((res = RegQueryValueEx32A(hkey, "Attributes", 0,
132                         &dwType, (LPBYTE)&PrinterAttr, &cbPrinterAttr)))
133             goto failed;
134         if ((res = RegOpenKey32A(hkey, PrinterDriverData, &hkey2)))
135             goto failed;
136         *lpNeeded = cbData;
137         res = RegQueryValueEx32A(hkey2, lpProfile, 0,
138                 lpType, lpPrinterData, lpNeeded);
139         if ((res != ERROR_CANTREAD) &&
140          ((PrinterAttr &
141         (PRINTER_ATTRIBUTE_ENABLE_BIDI|PRINTER_ATTRIBUTE_NETWORK))
142         == PRINTER_ATTRIBUTE_NETWORK))
143         {
144             if (!(res) && (*lpType == REG_DWORD) && (*(LPDWORD)lpPrinterData == -1))
145                 res = ERROR_INVALID_DATA;
146         }
147         else
148         {
149             SetData = -1;
150             RegSetValueEx32A(hkey2, lpProfile, 0, REG_DWORD, (LPBYTE)&SetData, 4); /* no result returned */
151         }
152     }
153         
154 failed:
155     if (hkey2) RegCloseKey(hkey2);
156     if (hkey) RegCloseKey(hkey);
157     HeapFree(GetProcessHeap(), 0, RegStr_Printer);
158     return res;
159 }
160
161
162
163 DWORD WINAPI DrvSetPrinterData(LPSTR lpPrinter, LPSTR lpProfile,
164                                DWORD lpType, LPBYTE lpPrinterData,
165                                DWORD dwSize)
166 {
167     LPSTR RegStr_Printer;
168     HKEY hkey = 0;
169     DWORD res = 0;
170
171     if (HIWORD(lpPrinter))
172             TRACE(print,"printer %s\n",lpPrinter);
173     else
174             TRACE(print,"printer %p\n",lpPrinter);
175     if (HIWORD(lpProfile))
176             TRACE(print,"profile %s\n",lpProfile);
177     else
178             TRACE(print,"profile %p\n",lpProfile);
179     TRACE(print,"lpType %08lx\n",lpType);
180
181     if ((!lpPrinter) || (!lpProfile) ||
182     ((DWORD)lpProfile == INT_PD_DEFAULT_MODEL) || (HIWORD(lpProfile) &&
183     (!strcmp(lpProfile, PrinterModel))))
184         return ERROR_INVALID_PARAMETER;
185
186     RegStr_Printer = HeapAlloc(GetProcessHeap(), 0,
187                         strlen(Printers) + strlen(lpPrinter) + 2);
188     strcpy(RegStr_Printer, Printers);
189     strcat(RegStr_Printer, lpPrinter);
190
191     if (((DWORD)lpProfile == INT_PD_DEFAULT_DEVMODE) || (HIWORD(lpProfile) &&
192     (!strcmp(lpProfile, DefaultDevMode)))) {
193         if ( RegOpenKey32A(HKEY_LOCAL_MACHINE, RegStr_Printer, &hkey) 
194              != ERROR_SUCCESS ||
195              RegSetValueEx32A(hkey, DefaultDevMode, 0, REG_BINARY, 
196                               lpPrinterData, dwSize) != ERROR_SUCCESS )
197                 res = ERROR_INVALID_PRINTER_NAME;
198     }
199     else
200     {
201         strcat(RegStr_Printer, "\\");
202
203         if( (res = RegOpenKey32A(HKEY_LOCAL_MACHINE, RegStr_Printer, &hkey)) ==
204             ERROR_SUCCESS ) {
205
206             if (!lpPrinterData) 
207                 res = RegDeleteValue32A(hkey, lpProfile);
208             else
209                 res = RegSetValueEx32A(hkey, lpProfile, 0, lpType,
210                                        lpPrinterData, dwSize);
211         }
212     }
213
214     if (hkey) RegCloseKey(hkey);
215     HeapFree(GetProcessHeap(), 0, RegStr_Printer);
216     return res;
217 }
218
219
220 INT32 WINAPI DeviceCapabilities32A(LPCSTR printer,LPCSTR target,WORD z,
221                                    LPSTR a,LPDEVMODE32A b)
222 {
223     FIXME(print,"(%s,%s,%d,%p,%p):stub.\n",printer,target,z,a,b);
224     return 1;           
225 }
226
227 LONG WINAPI DocumentProperties32A(HWND32 hWnd,HANDLE32 hPrinter,
228                                 LPSTR pDeviceName, LPDEVMODE32A pDevModeOutput,
229                                   LPDEVMODE32A pDevModeInput,DWORD fMode )
230 {
231     FIXME(print,"(%d,%d,%s,%p,%p,%ld):stub.\n",
232         hWnd,hPrinter,pDeviceName,pDevModeOutput,pDevModeInput,fMode
233     );
234     return 1;
235 }
236
237 BOOL32 WINAPI OpenPrinter32A(LPSTR lpPrinterName,HANDLE32 *phPrinter,
238                              LPPRINTER_DEFAULTS32A pDefault)
239 {
240     FIXME(print,"(%s,%p,%p):stub\n",debugstr_a(lpPrinterName), phPrinter,
241           pDefault);
242     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
243     return FALSE;
244 }
245
246 BOOL32 WINAPI OpenPrinter32W(LPWSTR lpPrinterName,HANDLE32 *phPrinter,
247                              LPPRINTER_DEFAULTS32W pDefault)
248 {
249     FIXME(print,"(%s,%p,%p):stub\n",debugstr_w(lpPrinterName), phPrinter,
250           pDefault);
251     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
252     return FALSE;
253 }
254
255 BOOL32  WINAPI EnumPrinters32A(DWORD dwType, LPSTR lpszName,
256                                DWORD dwLevel, LPBYTE lpbPrinters,
257                                DWORD cbBuf, LPDWORD lpdwNeeded,
258                                LPDWORD lpdwReturned)
259 {
260     FIXME(print,"Nearly empty stub\n");
261     *lpdwReturned=0;
262     return TRUE;
263 }
264
265 BOOL32  WINAPI EnumPrinters32W(DWORD dwType, LPWSTR lpszName,
266                                DWORD dwLevel, LPBYTE lpbPrinters,
267                                DWORD cbBuf, LPDWORD lpdwNeeded,
268                                LPDWORD lpdwReturned)
269 {
270     FIXME(print,"Nearly empty stub\n");
271     *lpdwReturned=0;
272     return TRUE;
273 }
274
275
276 BOOL32 WINAPI AddMonitor32A(LPCSTR pName, DWORD Level, LPBYTE pMonitors)
277 {
278     FIXME(print, "(%s,%lx,%p):stub!\n", pName, Level, pMonitors);
279     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
280     return FALSE;
281 }
282
283
284 BOOL32 WINAPI
285 DeletePrinterDriver32A (LPSTR pName, LPSTR pEnvironment, LPSTR pDriverName)
286 {
287     FIXME(print,"(%s,%s,%s):stub\n",debugstr_a(pName),debugstr_a(pEnvironment),
288           debugstr_a(pDriverName));
289     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
290     return FALSE;
291 }
292
293
294 BOOL32 WINAPI
295 DeleteMonitor32A (LPSTR pName, LPSTR pEnvironment, LPSTR pMonitorName)
296 {
297     FIXME(print,"(%s,%s,%s):stub\n",debugstr_a(pName),debugstr_a(pEnvironment),
298           debugstr_a(pMonitorName));
299     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
300     return FALSE;
301 }
302
303
304 BOOL32 WINAPI
305 DeletePort32A (LPSTR pName, HWND32 hWnd, LPSTR pPortName)
306 {
307     FIXME(print,"(%s,0x%08x,%s):stub\n",debugstr_a(pName),hWnd,
308           debugstr_a(pPortName));
309     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
310     return FALSE;
311 }
312