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 #define WIN32_NO_STATUS
27 #define COM_NO_WINDOWS_H
29 #include <wine/config.h>
30 //#include "wine/port.h"
41 //#include "winerror.h"
46 //#include "wine/unicode.h"
47 #include <wine/debug.h>
50 WINE_DEFAULT_DEBUG_CHANNEL(winspool
);
52 /******************************************************************************
53 * GetDefaultPrinterA (WINSPOOL.@)
55 BOOL WINAPI
GetDefaultPrinterA(LPSTR name
, LPDWORD namesize
)
61 SetLastError (ERROR_INSUFFICIENT_BUFFER
);
65 if (!GetProfileStringA ("windows", "device", "", name
, *namesize
))
67 SetLastError (ERROR_FILE_NOT_FOUND
);
71 if ((ptr
= strchr (name
, ',')) == NULL
)
73 SetLastError (ERROR_FILE_NOT_FOUND
);
78 *namesize
= strlen (name
) + 1;
83 /******************************************************************************
84 * GetDefaultPrinterW (WINSPOOL.@)
86 BOOL WINAPI
GetDefaultPrinterW(LPWSTR name
, LPDWORD namesize
)
93 SetLastError (ERROR_INSUFFICIENT_BUFFER
);
97 buf
= HeapAlloc (GetProcessHeap (), 0, *namesize
);
98 ret
= GetDefaultPrinterA (buf
, namesize
);
101 DWORD len
= MultiByteToWideChar (CP_ACP
, 0, buf
, -1, name
, *namesize
);
104 SetLastError (ERROR_INSUFFICIENT_BUFFER
);
107 else *namesize
= len
;
110 HeapFree (GetProcessHeap (), 0, buf
);
114 /******************************************************************************
115 * AddPrintProvidorA (WINSPOOL.@)
119 AddPrintProvidorA(LPSTR Name
, DWORD Level
, PBYTE Buffer
)
121 if (Name
|| Level
> 2 || Buffer
== NULL
)
123 SetLastError(ERROR_INVALID_PARAMETER
);
130 PROVIDOR_INFO_1W Provider
;
131 PROVIDOR_INFO_1A
*Prov
= (PROVIDOR_INFO_1A
*)Buffer
;
133 if (Prov
->pName
== NULL
|| Prov
->pDLLName
== NULL
|| Prov
->pEnvironment
== NULL
)
138 Provider
.pDLLName
= HeapAlloc(GetProcessHeap(), 0, (strlen(Prov
->pDLLName
)+1) * sizeof(WCHAR
));
139 if (Provider
.pDLLName
)
141 MultiByteToWideChar(CP_ACP
, 0, Prov
->pDLLName
, -1, Provider
.pDLLName
, strlen(Prov
->pDLLName
)+1);
142 Provider
.pDLLName
[strlen(Prov
->pDLLName
)] = L
'\0';
145 Provider
.pEnvironment
= HeapAlloc(GetProcessHeap(), 0, (strlen(Prov
->pEnvironment
)+1) * sizeof(WCHAR
));
146 if (Provider
.pEnvironment
)
148 MultiByteToWideChar(CP_ACP
, 0, Prov
->pEnvironment
, -1, Provider
.pEnvironment
, strlen(Prov
->pEnvironment
)+1);
149 Provider
.pEnvironment
[strlen(Prov
->pEnvironment
)] = L
'\0';
152 Provider
.pName
= HeapAlloc(GetProcessHeap(), 0, (strlen(Prov
->pName
)+1) * sizeof(WCHAR
));
155 MultiByteToWideChar(CP_ACP
, 0, Prov
->pName
, -1, Provider
.pName
, strlen(Prov
->pName
)+1);
156 Provider
.pName
[strlen(Prov
->pName
)] = L
'\0';
159 bRet
= AddPrintProvidorW(NULL
, Level
, (LPBYTE
)&Provider
);
161 if (Provider
.pDLLName
)
162 HeapFree(GetProcessHeap(), 0, Provider
.pDLLName
);
164 if (Provider
.pEnvironment
)
165 HeapFree(GetProcessHeap(), 0, Provider
.pEnvironment
);
168 HeapFree(GetProcessHeap(), 0, Provider
.pName
);
174 PROVIDOR_INFO_2W Provider
;
175 PROVIDOR_INFO_2A
*Prov
= (PROVIDOR_INFO_2A
*)Buffer
;
177 Provider
.pOrder
= HeapAlloc(GetProcessHeap(), 0, (strlen(Prov
->pOrder
)+1) * sizeof(WCHAR
));
181 MultiByteToWideChar(CP_ACP
, 0, Prov
->pOrder
, -1, Provider
.pOrder
, strlen(Prov
->pOrder
)+1);
182 Provider
.pOrder
[strlen(Prov
->pOrder
)] = L
'\0';
184 bRet
= AddPrintProvidorW(NULL
, Level
, (LPBYTE
)&Provider
);
185 HeapFree(GetProcessHeap(), 0, Provider
.pOrder
);
194 /******************************************************************************
195 * AddPrintProvidorW (WINSPOOL.@)
199 AddPrintProvidorW(LPWSTR Name
, DWORD Level
, PBYTE Buffer
)
203 DWORD dwSize
, dwType
;
206 if (Name
|| Level
> 2 || Buffer
== NULL
)
208 SetLastError(ERROR_INVALID_PARAMETER
);
213 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
, L
"SYSTEM\\CurrentControlSet\\Control\\Print\\Providers", 0, KEY_READ
| KEY_WRITE
, &hKey
) != ERROR_SUCCESS
)
218 if (RegQueryValueExW(hKey
, L
"Order", NULL
, &dwType
, NULL
, &dwSize
) != ERROR_SUCCESS
|| dwType
!= REG_MULTI_SZ
)
224 pOrder
= HeapAlloc(GetProcessHeap(), 0, dwSize
);
231 if (RegQueryValueExW(hKey
, L
"Order", NULL
, &dwType
, (LPBYTE
)pOrder
, &dwSize
) != ERROR_SUCCESS
|| dwType
!= REG_MULTI_SZ
)
241 PROVIDOR_INFO_1W
* Prov
= (PROVIDOR_INFO_1W
*)Buffer
;
243 if (Prov
->pName
== NULL
|| Prov
->pDLLName
== NULL
|| Prov
->pEnvironment
== NULL
)
245 SetLastError(ERROR_INVALID_PARAMETER
);
254 if (!wcsicmp(pBuffer
, Prov
->pName
))
259 pBuffer
+= wcslen(pBuffer
) + 1;
265 DWORD dwFullSize
= dwSize
+ (wcslen(Prov
->pName
)+1) * sizeof(WCHAR
);
267 if (RegCreateKeyExW(hKey
, Prov
->pName
, 0, NULL
, 0, KEY_WRITE
, NULL
, &hSubKey
, NULL
) == ERROR_SUCCESS
)
269 RegSetValueExW(hSubKey
, L
"Name", 0, REG_SZ
, (LPBYTE
)Prov
->pDLLName
, (wcslen(Prov
->pDLLName
)+1) * sizeof(WCHAR
));
270 RegCloseKey(hSubKey
);
273 pBuffer
= HeapAlloc(GetProcessHeap(), 0, dwFullSize
);
276 CopyMemory(pBuffer
, pOrder
, dwSize
);
277 wcscpy(&pBuffer
[(dwSize
/sizeof(WCHAR
))-1], Prov
->pName
);
278 pBuffer
[(dwSize
/sizeof(WCHAR
)) + wcslen(Prov
->pName
)] = L
'\0';
279 RegSetValueExW(hKey
, L
"Order", 0, REG_MULTI_SZ
, (LPBYTE
)pBuffer
, dwFullSize
);
280 HeapFree(GetProcessHeap(), 0, pBuffer
);
288 HeapFree(GetProcessHeap(), 0, pOrder
);
293 /******************************************************************************
294 * DeletePrintProvidorA (WINSPOOL.@)
298 DeletePrintProvidorA(LPSTR Name
, LPSTR Environment
, LPSTR PrintProvidor
)
303 if (Name
|| !Environment
|| !PrintProvidor
)
305 SetLastError(ERROR_INVALID_PARAMETER
);
309 Env
= HeapAlloc(GetProcessHeap(), 0, (strlen(Environment
)+1) * sizeof(WCHAR
));
315 MultiByteToWideChar(CP_ACP
, 0, Environment
, -1, Env
, strlen(Environment
)+1);
316 Env
[strlen(Environment
)] = L
'\0';
318 Prov
= HeapAlloc(GetProcessHeap(), 0, (strlen(PrintProvidor
)+1) * sizeof(WCHAR
));
321 HeapFree(GetProcessHeap(), 0, Env
);
325 MultiByteToWideChar(CP_ACP
, 0, PrintProvidor
, -1, Prov
, strlen(PrintProvidor
)+1);
326 Prov
[strlen(PrintProvidor
)] = L
'\0';
328 bRet
= DeletePrintProvidorW(NULL
, Env
, Prov
);
329 HeapFree(GetProcessHeap(), 0, Env
);
330 HeapFree(GetProcessHeap(), 0, Prov
);
340 DeletePrintProvidorW(LPWSTR Name
, LPWSTR Environment
, LPWSTR PrintProvidor
)
344 DWORD dwType
, dwSize
, dwOffset
, dwLength
;
345 LPWSTR pOrder
, pBuffer
, pNew
;
347 if (Name
|| !Environment
|| !PrintProvidor
)
349 SetLastError(ERROR_INVALID_PARAMETER
);
353 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
, L
"SYSTEM\\CurrentControlSet\\Control\\Print\\Providers", 0, KEY_READ
| KEY_WRITE
, &hKey
) != ERROR_SUCCESS
)
358 if (RegQueryValueExW(hKey
, L
"Order", NULL
, &dwType
, NULL
, &dwSize
) != ERROR_SUCCESS
|| dwType
!= REG_MULTI_SZ
)
364 pOrder
= HeapAlloc(GetProcessHeap(), 0, dwSize
);
371 if (RegQueryValueExW(hKey
, L
"Order", NULL
, &dwType
, (LPBYTE
)pOrder
, &dwSize
) != ERROR_SUCCESS
|| dwType
!= REG_MULTI_SZ
)
382 if (!wcsicmp(pBuffer
, PrintProvidor
))
387 pBuffer
+= wcslen(pBuffer
) + 1;
393 HeapFree(GetProcessHeap(), 0, pOrder
);
397 pNew
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, dwSize
);
401 HeapFree(GetProcessHeap(), 0, pOrder
);
405 dwOffset
= pBuffer
- pOrder
;
406 dwLength
= (dwSize
/ sizeof(WCHAR
)) - (dwOffset
+ wcslen(pBuffer
) + 1);
407 CopyMemory(pNew
, pOrder
, dwOffset
* sizeof(WCHAR
));
408 CopyMemory(&pNew
[dwOffset
], pBuffer
+ wcslen(pBuffer
) + 1, dwLength
);
410 RegSetValueExW(hKey
, L
"Order", 0, REG_MULTI_SZ
, (LPBYTE
)pNew
, (dwOffset
+ dwLength
) * sizeof(WCHAR
));
411 RegDeleteKey(hKey
, PrintProvidor
);
413 HeapFree(GetProcessHeap(), 0, pOrder
);
414 HeapFree(GetProcessHeap(), 0, pNew
);
425 AddMonitorA(LPSTR Name
, DWORD Level
, PBYTE Monitors
)
427 LPWSTR szName
= NULL
;
428 MONITOR_INFO_2W Monitor
;
429 MONITOR_INFO_2A
*pMonitor
;
432 if (Level
!= 2 || !Monitors
)
434 SetLastError(ERROR_INVALID_PARAMETER
);
438 pMonitor
= (MONITOR_INFO_2A
*)Monitors
;
439 if (pMonitor
->pDLLName
== NULL
|| pMonitor
->pName
== NULL
)
441 SetLastError(ERROR_INVALID_PARAMETER
);
445 ZeroMemory(&Monitor
, sizeof(Monitor
));
449 szName
= HeapAlloc(GetProcessHeap(), 0, (strlen(Name
) + 1) * sizeof(WCHAR
));
454 MultiByteToWideChar(CP_ACP
, 0, Name
, -1, szName
, strlen(Name
)+1);
455 szName
[strlen(Name
)] = L
'\0';
458 Monitor
.pDLLName
= HeapAlloc(GetProcessHeap(), 0, (strlen(pMonitor
->pDLLName
)+1) * sizeof(WCHAR
));
459 if (!Monitor
.pDLLName
)
463 MultiByteToWideChar(CP_ACP
, 0, pMonitor
->pDLLName
, -1, Monitor
.pDLLName
, strlen(pMonitor
->pDLLName
)+1);
464 pMonitor
->pDLLName
[strlen(pMonitor
->pDLLName
)] = L
'\0';
466 Monitor
.pName
= HeapAlloc(GetProcessHeap(), 0, (strlen(pMonitor
->pName
)+1) * sizeof(WCHAR
));
471 MultiByteToWideChar(CP_ACP
, 0, pMonitor
->pName
, -1, Monitor
.pName
, strlen(pMonitor
->pName
)+1);
472 pMonitor
->pName
[strlen(pMonitor
->pName
)] = L
'\0';
475 if (pMonitor
->pEnvironment
)
477 Monitor
.pEnvironment
= HeapAlloc(GetProcessHeap(), 0, (strlen(pMonitor
->pEnvironment
)+1) * sizeof(WCHAR
));
478 if (!Monitor
.pEnvironment
)
482 MultiByteToWideChar(CP_ACP
, 0, pMonitor
->pEnvironment
, -1, Monitor
.pEnvironment
, strlen(pMonitor
->pEnvironment
)+1);
483 pMonitor
->pEnvironment
[strlen(pMonitor
->pEnvironment
)] = L
'\0';
486 bRet
= AddMonitorW(szName
, Level
, (LPBYTE
)&Monitor
);
491 HeapFree(GetProcessHeap(), 0, szName
);
493 if (Monitor
.pDLLName
)
494 HeapFree(GetProcessHeap(), 0, Monitor
.pDLLName
);
496 if (Monitor
.pEnvironment
)
497 HeapFree(GetProcessHeap(), 0, Monitor
.pEnvironment
);
500 HeapFree(GetProcessHeap(), 0, Monitor
.pName
);
511 AddMonitorW(LPWSTR Name
, DWORD Level
, PBYTE Monitors
)
513 WCHAR szPath
[MAX_PATH
];
514 HMODULE hLibrary
= NULL
;
517 MONITOR_INFO_2W
* pMonitor
;
520 if (Level
!= 2 || !Monitors
)
522 SetLastError(ERROR_INVALID_PARAMETER
);
526 pMonitor
= (MONITOR_INFO_2W
*)Monitors
;
528 if (pMonitor
->pDLLName
== NULL
|| pMonitor
->pName
== NULL
)
530 SetLastError(ERROR_INVALID_PARAMETER
);
534 if (wcschr(pMonitor
->pDLLName
, L
'\\'))
536 hLibrary
= LoadLibraryExW(pMonitor
->pDLLName
, NULL
, 0);
538 else if (GetSystemDirectoryW(szPath
, MAX_PATH
) && PathAddBackslashW(szPath
))
540 wcscat(szPath
, pMonitor
->pDLLName
);
541 hLibrary
= LoadLibraryExW(szPath
, NULL
, 0);
549 InitProc
= GetProcAddress(hLibrary
, "InitializePrintMonitor");
552 InitProc
= GetProcAddress(hLibrary
, "InitializePrintMonitor2");
555 FreeLibrary(hLibrary
);
556 SetLastError(ERROR_PROC_NOT_FOUND
);
562 // Initialize monitor
563 FreeLibrary(hLibrary
);
565 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
, L
"SYSTEM\\CurrentControlSet\\Control\\Print\\Monitors", 0, KEY_WRITE
, &hKey
) == ERROR_SUCCESS
)
567 if (RegCreateKeyExW(hKey
, pMonitor
->pName
, 0, NULL
, 0, KEY_WRITE
, NULL
, &hSubKey
, NULL
) == ERROR_SUCCESS
)
569 RegSetValueExW(hSubKey
, L
"Driver", 0, REG_SZ
, (LPBYTE
)pMonitor
->pDLLName
, (wcslen(pMonitor
->pDLLName
)+1)*sizeof(WCHAR
));
570 RegCloseKey(hSubKey
);