4 * Copyright 1996 John Harvey
5 * Copyright 1998 Andreas Mohr
6 * Copyright 1999 Klaas van Gend
7 * Copyright 1999, 2000 Huw D M Davies
8 * Copyright 2001 Marcus Meissner
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2.1 of the License, or (at your option) any later version.
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with this library; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
25 #include "wine/config.h"
26 #include "wine/port.h"
42 #include "wine/unicode.h"
43 #include "wine/debug.h"
46 WINE_DEFAULT_DEBUG_CHANNEL(winspool
);
48 /******************************************************************************
49 * GetDefaultPrinterA (WINSPOOL.@)
51 BOOL WINAPI
GetDefaultPrinterA(LPSTR name
, LPDWORD namesize
)
57 SetLastError (ERROR_INSUFFICIENT_BUFFER
);
61 if (!GetProfileStringA ("windows", "device", "", name
, *namesize
))
63 SetLastError (ERROR_FILE_NOT_FOUND
);
67 if ((ptr
= strchr (name
, ',')) == NULL
)
69 SetLastError (ERROR_FILE_NOT_FOUND
);
74 *namesize
= strlen (name
) + 1;
79 /******************************************************************************
80 * GetDefaultPrinterW (WINSPOOL.@)
82 BOOL WINAPI
GetDefaultPrinterW(LPWSTR name
, LPDWORD namesize
)
89 SetLastError (ERROR_INSUFFICIENT_BUFFER
);
93 buf
= HeapAlloc (GetProcessHeap (), 0, *namesize
);
94 ret
= GetDefaultPrinterA (buf
, namesize
);
97 DWORD len
= MultiByteToWideChar (CP_ACP
, 0, buf
, -1, name
, *namesize
);
100 SetLastError (ERROR_INSUFFICIENT_BUFFER
);
103 else *namesize
= len
;
106 HeapFree (GetProcessHeap (), 0, buf
);
110 /******************************************************************************
111 * AddPrintProvidorA (WINSPOOL.@)
115 AddPrintProvidorA(LPSTR Name
, DWORD Level
, PBYTE Buffer
)
117 if (Name
|| Level
> 2 || Buffer
== NULL
)
119 SetLastError(ERROR_INVALID_PARAMETER
);
126 PROVIDOR_INFO_1W Provider
;
127 PROVIDOR_INFO_1A
*Prov
= (PROVIDOR_INFO_1A
*)Buffer
;
129 if (Prov
->pName
== NULL
|| Prov
->pDLLName
== NULL
|| Prov
->pEnvironment
== NULL
)
134 Provider
.pDLLName
= HeapAlloc(GetProcessHeap(), 0, (strlen(Prov
->pDLLName
)+1) * sizeof(WCHAR
));
135 if (Provider
.pDLLName
)
137 MultiByteToWideChar(CP_ACP
, 0, Prov
->pDLLName
, -1, Provider
.pDLLName
, strlen(Prov
->pDLLName
)+1);
138 Provider
.pDLLName
[strlen(Prov
->pDLLName
)] = L
'\0';
141 Provider
.pEnvironment
= HeapAlloc(GetProcessHeap(), 0, (strlen(Prov
->pEnvironment
)+1) * sizeof(WCHAR
));
142 if (Provider
.pEnvironment
)
144 MultiByteToWideChar(CP_ACP
, 0, Prov
->pEnvironment
, -1, Provider
.pEnvironment
, strlen(Prov
->pEnvironment
)+1);
145 Provider
.pEnvironment
[strlen(Prov
->pEnvironment
)] = L
'\0';
148 Provider
.pName
= HeapAlloc(GetProcessHeap(), 0, (strlen(Prov
->pName
)+1) * sizeof(WCHAR
));
151 MultiByteToWideChar(CP_ACP
, 0, Prov
->pName
, -1, Provider
.pName
, strlen(Prov
->pName
)+1);
152 Provider
.pName
[strlen(Prov
->pName
)] = L
'\0';
155 bRet
= AddPrintProvidorW(NULL
, Level
, (LPBYTE
)&Provider
);
157 if (Provider
.pDLLName
)
158 HeapFree(GetProcessHeap(), 0, Provider
.pDLLName
);
160 if (Provider
.pEnvironment
)
161 HeapFree(GetProcessHeap(), 0, Provider
.pEnvironment
);
164 HeapFree(GetProcessHeap(), 0, Provider
.pName
);
170 PROVIDOR_INFO_2W Provider
;
171 PROVIDOR_INFO_2A
*Prov
= (PROVIDOR_INFO_2A
*)Buffer
;
173 Provider
.pOrder
= HeapAlloc(GetProcessHeap(), 0, (strlen(Prov
->pOrder
)+1) * sizeof(WCHAR
));
177 MultiByteToWideChar(CP_ACP
, 0, Prov
->pOrder
, -1, Provider
.pOrder
, strlen(Prov
->pOrder
)+1);
178 Provider
.pOrder
[strlen(Prov
->pOrder
)] = L
'\0';
180 bRet
= AddPrintProvidorW(NULL
, Level
, (LPBYTE
)&Provider
);
181 HeapFree(GetProcessHeap(), 0, Provider
.pOrder
);
190 /******************************************************************************
191 * AddPrintProvidorW (WINSPOOL.@)
195 AddPrintProvidorW(LPWSTR Name
, DWORD Level
, PBYTE Buffer
)
199 DWORD dwSize
, dwType
;
202 if (Name
|| Level
> 2 || Buffer
== NULL
)
204 SetLastError(ERROR_INVALID_PARAMETER
);
209 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
, L
"SYSTEM\\CurrentControlSet\\Control\\Print\\Providers", 0, KEY_READ
| KEY_WRITE
, &hKey
) != ERROR_SUCCESS
)
214 if (RegQueryValueExW(hKey
, L
"Order", NULL
, &dwType
, NULL
, &dwSize
) != ERROR_SUCCESS
|| dwType
!= REG_MULTI_SZ
)
220 pOrder
= HeapAlloc(GetProcessHeap(), 0, dwSize
);
227 if (RegQueryValueExW(hKey
, L
"Order", NULL
, &dwType
, (LPBYTE
)pOrder
, &dwSize
) != ERROR_SUCCESS
|| dwType
!= REG_MULTI_SZ
)
237 PROVIDOR_INFO_1W
* Prov
= (PROVIDOR_INFO_1W
*)Buffer
;
239 if (Prov
->pName
== NULL
|| Prov
->pDLLName
== NULL
|| Prov
->pEnvironment
== NULL
)
241 SetLastError(ERROR_INVALID_PARAMETER
);
250 if (!wcsicmp(pBuffer
, Prov
->pName
))
255 pBuffer
+= wcslen(pBuffer
) + 1;
261 DWORD dwFullSize
= dwSize
+ (wcslen(Prov
->pName
)+1) * sizeof(WCHAR
);
263 if (RegCreateKeyExW(hKey
, Prov
->pName
, 0, NULL
, 0, KEY_WRITE
, NULL
, &hSubKey
, NULL
) == ERROR_SUCCESS
)
265 RegSetValueExW(hSubKey
, L
"Name", 0, REG_SZ
, (LPBYTE
)Prov
->pDLLName
, (wcslen(Prov
->pDLLName
)+1) * sizeof(WCHAR
));
266 RegCloseKey(hSubKey
);
269 pBuffer
= HeapAlloc(GetProcessHeap(), 0, dwFullSize
);
272 CopyMemory(pBuffer
, pOrder
, dwSize
);
273 wcscpy(&pBuffer
[(dwSize
/sizeof(WCHAR
))-1], Prov
->pName
);
274 pBuffer
[(dwSize
/sizeof(WCHAR
)) + wcslen(Prov
->pName
)] = L
'\0';
275 RegSetValueExW(hKey
, L
"Order", 0, REG_MULTI_SZ
, (LPBYTE
)pBuffer
, dwFullSize
);
276 HeapFree(GetProcessHeap(), 0, pBuffer
);
284 HeapFree(GetProcessHeap(), 0, pOrder
);
289 /******************************************************************************
290 * DeletePrintProvidorA (WINSPOOL.@)
294 DeletePrintProvidorA(LPSTR Name
, LPSTR Environment
, LPSTR PrintProvidor
)
299 if (Name
|| !Environment
|| !PrintProvidor
)
301 SetLastError(ERROR_INVALID_PARAMETER
);
305 Env
= HeapAlloc(GetProcessHeap(), 0, (strlen(Environment
)+1) * sizeof(WCHAR
));
311 MultiByteToWideChar(CP_ACP
, 0, Environment
, -1, Env
, strlen(Environment
)+1);
312 Env
[strlen(Environment
)] = L
'\0';
314 Prov
= HeapAlloc(GetProcessHeap(), 0, (strlen(PrintProvidor
)+1) * sizeof(WCHAR
));
317 HeapFree(GetProcessHeap(), 0, Env
);
321 MultiByteToWideChar(CP_ACP
, 0, PrintProvidor
, -1, Prov
, strlen(PrintProvidor
)+1);
322 Prov
[strlen(PrintProvidor
)] = L
'\0';
324 bRet
= DeletePrintProvidorW(NULL
, Env
, Prov
);
325 HeapFree(GetProcessHeap(), 0, Env
);
326 HeapFree(GetProcessHeap(), 0, Prov
);
336 DeletePrintProvidorW(LPWSTR Name
, LPWSTR Environment
, LPWSTR PrintProvidor
)
340 DWORD dwType
, dwSize
, dwOffset
, dwLength
;
341 LPWSTR pOrder
, pBuffer
, pNew
;
343 if (Name
|| !Environment
|| !PrintProvidor
)
345 SetLastError(ERROR_INVALID_PARAMETER
);
349 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
, L
"SYSTEM\\CurrentControlSet\\Control\\Print\\Providers", 0, KEY_READ
| KEY_WRITE
, &hKey
) != ERROR_SUCCESS
)
354 if (RegQueryValueExW(hKey
, L
"Order", NULL
, &dwType
, NULL
, &dwSize
) != ERROR_SUCCESS
|| dwType
!= REG_MULTI_SZ
)
360 pOrder
= HeapAlloc(GetProcessHeap(), 0, dwSize
);
367 if (RegQueryValueExW(hKey
, L
"Order", NULL
, &dwType
, (LPBYTE
)pOrder
, &dwSize
) != ERROR_SUCCESS
|| dwType
!= REG_MULTI_SZ
)
378 if (!wcsicmp(pBuffer
, PrintProvidor
))
383 pBuffer
+= wcslen(pBuffer
) + 1;
389 HeapFree(GetProcessHeap(), 0, pOrder
);
393 pNew
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, dwSize
);
397 HeapFree(GetProcessHeap(), 0, pOrder
);
401 dwOffset
= pBuffer
- pOrder
;
402 dwLength
= (dwSize
/ sizeof(WCHAR
)) - (dwOffset
+ wcslen(pBuffer
) + 1);
403 CopyMemory(pNew
, pOrder
, dwOffset
* sizeof(WCHAR
));
404 CopyMemory(&pNew
[dwOffset
], pBuffer
+ wcslen(pBuffer
) + 1, dwLength
);
406 RegSetValueExW(hKey
, L
"Order", 0, REG_MULTI_SZ
, (LPBYTE
)pNew
, (dwOffset
+ dwLength
) * sizeof(WCHAR
));
407 RegDeleteKey(hKey
, PrintProvidor
);
409 HeapFree(GetProcessHeap(), 0, pOrder
);
410 HeapFree(GetProcessHeap(), 0, pNew
);
421 AddMonitorA(LPSTR Name
, DWORD Level
, PBYTE Monitors
)
423 LPWSTR szName
= NULL
;
424 MONITOR_INFO_2W Monitor
;
425 MONITOR_INFO_2A
*pMonitor
;
428 if (Level
!= 2 || !Monitors
)
430 SetLastError(ERROR_INVALID_PARAMETER
);
434 pMonitor
= (MONITOR_INFO_2A
*)Monitors
;
435 if (pMonitor
->pDLLName
== NULL
|| pMonitor
->pName
== NULL
)
437 SetLastError(ERROR_INVALID_PARAMETER
);
441 ZeroMemory(&Monitor
, sizeof(Monitor
));
445 szName
= HeapAlloc(GetProcessHeap(), 0, (strlen(Name
) + 1) * sizeof(WCHAR
));
450 MultiByteToWideChar(CP_ACP
, 0, Name
, -1, szName
, strlen(Name
)+1);
451 szName
[strlen(Name
)] = L
'\0';
454 Monitor
.pDLLName
= HeapAlloc(GetProcessHeap(), 0, (strlen(pMonitor
->pDLLName
)+1) * sizeof(WCHAR
));
455 if (!Monitor
.pDLLName
)
459 MultiByteToWideChar(CP_ACP
, 0, pMonitor
->pDLLName
, -1, Monitor
.pDLLName
, strlen(pMonitor
->pDLLName
)+1);
460 pMonitor
->pDLLName
[strlen(pMonitor
->pDLLName
)] = L
'\0';
462 Monitor
.pName
= HeapAlloc(GetProcessHeap(), 0, (strlen(pMonitor
->pName
)+1) * sizeof(WCHAR
));
467 MultiByteToWideChar(CP_ACP
, 0, pMonitor
->pName
, -1, Monitor
.pName
, strlen(pMonitor
->pName
)+1);
468 pMonitor
->pName
[strlen(pMonitor
->pName
)] = L
'\0';
471 if (pMonitor
->pEnvironment
)
473 Monitor
.pEnvironment
= HeapAlloc(GetProcessHeap(), 0, (strlen(pMonitor
->pEnvironment
)+1) * sizeof(WCHAR
));
474 if (!Monitor
.pEnvironment
)
478 MultiByteToWideChar(CP_ACP
, 0, pMonitor
->pEnvironment
, -1, Monitor
.pEnvironment
, strlen(pMonitor
->pEnvironment
)+1);
479 pMonitor
->pEnvironment
[strlen(pMonitor
->pEnvironment
)] = L
'\0';
482 bRet
= AddMonitorW(szName
, Level
, (LPBYTE
)&Monitor
);
487 HeapFree(GetProcessHeap(), 0, szName
);
489 if (Monitor
.pDLLName
)
490 HeapFree(GetProcessHeap(), 0, Monitor
.pDLLName
);
492 if (Monitor
.pEnvironment
)
493 HeapFree(GetProcessHeap(), 0, Monitor
.pEnvironment
);
496 HeapFree(GetProcessHeap(), 0, Monitor
.pName
);
507 AddMonitorW(LPWSTR Name
, DWORD Level
, PBYTE Monitors
)
509 WCHAR szPath
[MAX_PATH
];
510 HMODULE hLibrary
= NULL
;
513 MONITOR_INFO_2W
* pMonitor
;
516 if (Level
!= 2 || !Monitors
)
518 SetLastError(ERROR_INVALID_PARAMETER
);
522 pMonitor
= (MONITOR_INFO_2W
*)Monitors
;
524 if (pMonitor
->pDLLName
== NULL
|| pMonitor
->pName
== NULL
)
526 SetLastError(ERROR_INVALID_PARAMETER
);
530 if (wcschr(pMonitor
->pDLLName
, L
'\\'))
532 hLibrary
= LoadLibraryExW(pMonitor
->pDLLName
, NULL
, 0);
534 else if (GetSystemDirectoryW(szPath
, MAX_PATH
) && PathAddBackslashW(szPath
))
536 wcscat(szPath
, pMonitor
->pDLLName
);
537 hLibrary
= LoadLibraryExW(szPath
, NULL
, 0);
545 InitProc
= GetProcAddress(hLibrary
, "InitializePrintMonitor");
548 InitProc
= GetProcAddress(hLibrary
, "InitializePrintMonitor2");
551 FreeLibrary(hLibrary
);
552 SetLastError(ERROR_PROC_NOT_FOUND
);
558 // Initialize monitor
559 FreeLibrary(hLibrary
);
561 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
, L
"SYSTEM\\CurrentControlSet\\Control\\Print\\Monitors", 0, KEY_WRITE
, &hKey
) == ERROR_SUCCESS
)
563 if (RegCreateKeyExW(hKey
, pMonitor
->pName
, 0, NULL
, 0, KEY_WRITE
, NULL
, &hSubKey
, NULL
) == ERROR_SUCCESS
)
565 RegSetValueExW(hSubKey
, L
"Driver", 0, REG_SZ
, (LPBYTE
)pMonitor
->pDLLName
, (wcslen(pMonitor
->pDLLName
)+1)*sizeof(WCHAR
));
566 RegCloseKey(hSubKey
);