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
31 #include <wine/debug.h>
33 WINE_DEFAULT_DEBUG_CHANNEL(winspool
);
35 /******************************************************************************
36 * GetDefaultPrinterA (WINSPOOL.@)
38 BOOL WINAPI
GetDefaultPrinterA(LPSTR name
, LPDWORD namesize
)
44 SetLastError (ERROR_INSUFFICIENT_BUFFER
);
48 if (!GetProfileStringA ("windows", "device", "", name
, *namesize
))
50 SetLastError (ERROR_FILE_NOT_FOUND
);
54 if ((ptr
= strchr (name
, ',')) == NULL
)
56 SetLastError (ERROR_FILE_NOT_FOUND
);
61 *namesize
= strlen (name
) + 1;
66 /******************************************************************************
67 * GetDefaultPrinterW (WINSPOOL.@)
69 BOOL WINAPI
GetDefaultPrinterW(LPWSTR name
, LPDWORD namesize
)
76 SetLastError (ERROR_INSUFFICIENT_BUFFER
);
80 buf
= HeapAlloc (GetProcessHeap (), 0, *namesize
);
81 ret
= GetDefaultPrinterA (buf
, namesize
);
84 DWORD len
= MultiByteToWideChar (CP_ACP
, 0, buf
, -1, name
, *namesize
);
87 SetLastError (ERROR_INSUFFICIENT_BUFFER
);
93 HeapFree (GetProcessHeap (), 0, buf
);
97 /******************************************************************************
98 * AddPrintProvidorA (WINSPOOL.@)
102 AddPrintProvidorA(LPSTR Name
, DWORD Level
, PBYTE Buffer
)
104 if (Name
|| Level
> 2 || Buffer
== NULL
)
106 SetLastError(ERROR_INVALID_PARAMETER
);
113 PROVIDOR_INFO_1W Provider
;
114 PROVIDOR_INFO_1A
*Prov
= (PROVIDOR_INFO_1A
*)Buffer
;
116 if (Prov
->pName
== NULL
|| Prov
->pDLLName
== NULL
|| Prov
->pEnvironment
== NULL
)
121 Provider
.pDLLName
= HeapAlloc(GetProcessHeap(), 0, (strlen(Prov
->pDLLName
)+1) * sizeof(WCHAR
));
122 if (Provider
.pDLLName
)
124 MultiByteToWideChar(CP_ACP
, 0, Prov
->pDLLName
, -1, Provider
.pDLLName
, strlen(Prov
->pDLLName
)+1);
125 Provider
.pDLLName
[strlen(Prov
->pDLLName
)] = L
'\0';
128 Provider
.pEnvironment
= HeapAlloc(GetProcessHeap(), 0, (strlen(Prov
->pEnvironment
)+1) * sizeof(WCHAR
));
129 if (Provider
.pEnvironment
)
131 MultiByteToWideChar(CP_ACP
, 0, Prov
->pEnvironment
, -1, Provider
.pEnvironment
, strlen(Prov
->pEnvironment
)+1);
132 Provider
.pEnvironment
[strlen(Prov
->pEnvironment
)] = L
'\0';
135 Provider
.pName
= HeapAlloc(GetProcessHeap(), 0, (strlen(Prov
->pName
)+1) * sizeof(WCHAR
));
138 MultiByteToWideChar(CP_ACP
, 0, Prov
->pName
, -1, Provider
.pName
, strlen(Prov
->pName
)+1);
139 Provider
.pName
[strlen(Prov
->pName
)] = L
'\0';
142 bRet
= AddPrintProvidorW(NULL
, Level
, (LPBYTE
)&Provider
);
144 if (Provider
.pDLLName
)
145 HeapFree(GetProcessHeap(), 0, Provider
.pDLLName
);
147 if (Provider
.pEnvironment
)
148 HeapFree(GetProcessHeap(), 0, Provider
.pEnvironment
);
151 HeapFree(GetProcessHeap(), 0, Provider
.pName
);
157 PROVIDOR_INFO_2W Provider
;
158 PROVIDOR_INFO_2A
*Prov
= (PROVIDOR_INFO_2A
*)Buffer
;
160 Provider
.pOrder
= HeapAlloc(GetProcessHeap(), 0, (strlen(Prov
->pOrder
)+1) * sizeof(WCHAR
));
164 MultiByteToWideChar(CP_ACP
, 0, Prov
->pOrder
, -1, Provider
.pOrder
, strlen(Prov
->pOrder
)+1);
165 Provider
.pOrder
[strlen(Prov
->pOrder
)] = L
'\0';
167 bRet
= AddPrintProvidorW(NULL
, Level
, (LPBYTE
)&Provider
);
168 HeapFree(GetProcessHeap(), 0, Provider
.pOrder
);
177 /******************************************************************************
178 * AddPrintProvidorW (WINSPOOL.@)
182 AddPrintProvidorW(LPWSTR Name
, DWORD Level
, PBYTE Buffer
)
186 DWORD dwSize
, dwType
;
189 if (Name
|| Level
> 2 || Buffer
== NULL
)
191 SetLastError(ERROR_INVALID_PARAMETER
);
196 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
, L
"SYSTEM\\CurrentControlSet\\Control\\Print\\Providers", 0, KEY_READ
| KEY_WRITE
, &hKey
) != ERROR_SUCCESS
)
201 if (RegQueryValueExW(hKey
, L
"Order", NULL
, &dwType
, NULL
, &dwSize
) != ERROR_SUCCESS
|| dwType
!= REG_MULTI_SZ
)
207 pOrder
= HeapAlloc(GetProcessHeap(), 0, dwSize
);
214 if (RegQueryValueExW(hKey
, L
"Order", NULL
, &dwType
, (LPBYTE
)pOrder
, &dwSize
) != ERROR_SUCCESS
|| dwType
!= REG_MULTI_SZ
)
224 PROVIDOR_INFO_1W
* Prov
= (PROVIDOR_INFO_1W
*)Buffer
;
226 if (Prov
->pName
== NULL
|| Prov
->pDLLName
== NULL
|| Prov
->pEnvironment
== NULL
)
228 SetLastError(ERROR_INVALID_PARAMETER
);
237 if (!wcsicmp(pBuffer
, Prov
->pName
))
242 pBuffer
+= wcslen(pBuffer
) + 1;
248 DWORD dwFullSize
= dwSize
+ (wcslen(Prov
->pName
)+1) * sizeof(WCHAR
);
250 if (RegCreateKeyExW(hKey
, Prov
->pName
, 0, NULL
, 0, KEY_WRITE
, NULL
, &hSubKey
, NULL
) == ERROR_SUCCESS
)
252 RegSetValueExW(hSubKey
, L
"Name", 0, REG_SZ
, (LPBYTE
)Prov
->pDLLName
, (wcslen(Prov
->pDLLName
)+1) * sizeof(WCHAR
));
253 RegCloseKey(hSubKey
);
256 pBuffer
= HeapAlloc(GetProcessHeap(), 0, dwFullSize
);
259 CopyMemory(pBuffer
, pOrder
, dwSize
);
260 wcscpy(&pBuffer
[(dwSize
/sizeof(WCHAR
))-1], Prov
->pName
);
261 pBuffer
[(dwSize
/sizeof(WCHAR
)) + wcslen(Prov
->pName
)] = L
'\0';
262 RegSetValueExW(hKey
, L
"Order", 0, REG_MULTI_SZ
, (LPBYTE
)pBuffer
, dwFullSize
);
263 HeapFree(GetProcessHeap(), 0, pBuffer
);
271 HeapFree(GetProcessHeap(), 0, pOrder
);
276 /******************************************************************************
277 * DeletePrintProvidorA (WINSPOOL.@)
281 DeletePrintProvidorA(LPSTR Name
, LPSTR Environment
, LPSTR PrintProvidor
)
286 if (Name
|| !Environment
|| !PrintProvidor
)
288 SetLastError(ERROR_INVALID_PARAMETER
);
292 Env
= HeapAlloc(GetProcessHeap(), 0, (strlen(Environment
)+1) * sizeof(WCHAR
));
298 MultiByteToWideChar(CP_ACP
, 0, Environment
, -1, Env
, strlen(Environment
)+1);
299 Env
[strlen(Environment
)] = L
'\0';
301 Prov
= HeapAlloc(GetProcessHeap(), 0, (strlen(PrintProvidor
)+1) * sizeof(WCHAR
));
304 HeapFree(GetProcessHeap(), 0, Env
);
308 MultiByteToWideChar(CP_ACP
, 0, PrintProvidor
, -1, Prov
, strlen(PrintProvidor
)+1);
309 Prov
[strlen(PrintProvidor
)] = L
'\0';
311 bRet
= DeletePrintProvidorW(NULL
, Env
, Prov
);
312 HeapFree(GetProcessHeap(), 0, Env
);
313 HeapFree(GetProcessHeap(), 0, Prov
);
323 DeletePrintProvidorW(LPWSTR Name
, LPWSTR Environment
, LPWSTR PrintProvidor
)
327 DWORD dwType
, dwSize
, dwOffset
, dwLength
;
328 LPWSTR pOrder
, pBuffer
, pNew
;
330 if (Name
|| !Environment
|| !PrintProvidor
)
332 SetLastError(ERROR_INVALID_PARAMETER
);
336 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
, L
"SYSTEM\\CurrentControlSet\\Control\\Print\\Providers", 0, KEY_READ
| KEY_WRITE
, &hKey
) != ERROR_SUCCESS
)
341 if (RegQueryValueExW(hKey
, L
"Order", NULL
, &dwType
, NULL
, &dwSize
) != ERROR_SUCCESS
|| dwType
!= REG_MULTI_SZ
)
347 pOrder
= HeapAlloc(GetProcessHeap(), 0, dwSize
);
354 if (RegQueryValueExW(hKey
, L
"Order", NULL
, &dwType
, (LPBYTE
)pOrder
, &dwSize
) != ERROR_SUCCESS
|| dwType
!= REG_MULTI_SZ
)
365 if (!wcsicmp(pBuffer
, PrintProvidor
))
370 pBuffer
+= wcslen(pBuffer
) + 1;
376 HeapFree(GetProcessHeap(), 0, pOrder
);
380 pNew
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, dwSize
);
384 HeapFree(GetProcessHeap(), 0, pOrder
);
388 dwOffset
= pBuffer
- pOrder
;
389 dwLength
= (dwSize
/ sizeof(WCHAR
)) - (dwOffset
+ wcslen(pBuffer
) + 1);
390 CopyMemory(pNew
, pOrder
, dwOffset
* sizeof(WCHAR
));
391 CopyMemory(&pNew
[dwOffset
], pBuffer
+ wcslen(pBuffer
) + 1, dwLength
);
393 RegSetValueExW(hKey
, L
"Order", 0, REG_MULTI_SZ
, (LPBYTE
)pNew
, (dwOffset
+ dwLength
) * sizeof(WCHAR
));
394 RegDeleteKey(hKey
, PrintProvidor
);
396 HeapFree(GetProcessHeap(), 0, pOrder
);
397 HeapFree(GetProcessHeap(), 0, pNew
);
408 AddMonitorA(LPSTR Name
, DWORD Level
, PBYTE Monitors
)
410 LPWSTR szName
= NULL
;
411 MONITOR_INFO_2W Monitor
;
412 MONITOR_INFO_2A
*pMonitor
;
415 if (Level
!= 2 || !Monitors
)
417 SetLastError(ERROR_INVALID_PARAMETER
);
421 pMonitor
= (MONITOR_INFO_2A
*)Monitors
;
422 if (pMonitor
->pDLLName
== NULL
|| pMonitor
->pName
== NULL
)
424 SetLastError(ERROR_INVALID_PARAMETER
);
428 ZeroMemory(&Monitor
, sizeof(Monitor
));
432 szName
= HeapAlloc(GetProcessHeap(), 0, (strlen(Name
) + 1) * sizeof(WCHAR
));
437 MultiByteToWideChar(CP_ACP
, 0, Name
, -1, szName
, strlen(Name
)+1);
438 szName
[strlen(Name
)] = L
'\0';
441 Monitor
.pDLLName
= HeapAlloc(GetProcessHeap(), 0, (strlen(pMonitor
->pDLLName
)+1) * sizeof(WCHAR
));
442 if (!Monitor
.pDLLName
)
446 MultiByteToWideChar(CP_ACP
, 0, pMonitor
->pDLLName
, -1, Monitor
.pDLLName
, strlen(pMonitor
->pDLLName
)+1);
447 pMonitor
->pDLLName
[strlen(pMonitor
->pDLLName
)] = L
'\0';
449 Monitor
.pName
= HeapAlloc(GetProcessHeap(), 0, (strlen(pMonitor
->pName
)+1) * sizeof(WCHAR
));
454 MultiByteToWideChar(CP_ACP
, 0, pMonitor
->pName
, -1, Monitor
.pName
, strlen(pMonitor
->pName
)+1);
455 pMonitor
->pName
[strlen(pMonitor
->pName
)] = L
'\0';
458 if (pMonitor
->pEnvironment
)
460 Monitor
.pEnvironment
= HeapAlloc(GetProcessHeap(), 0, (strlen(pMonitor
->pEnvironment
)+1) * sizeof(WCHAR
));
461 if (!Monitor
.pEnvironment
)
465 MultiByteToWideChar(CP_ACP
, 0, pMonitor
->pEnvironment
, -1, Monitor
.pEnvironment
, strlen(pMonitor
->pEnvironment
)+1);
466 pMonitor
->pEnvironment
[strlen(pMonitor
->pEnvironment
)] = L
'\0';
469 bRet
= AddMonitorW(szName
, Level
, (LPBYTE
)&Monitor
);
474 HeapFree(GetProcessHeap(), 0, szName
);
476 if (Monitor
.pDLLName
)
477 HeapFree(GetProcessHeap(), 0, Monitor
.pDLLName
);
479 if (Monitor
.pEnvironment
)
480 HeapFree(GetProcessHeap(), 0, Monitor
.pEnvironment
);
483 HeapFree(GetProcessHeap(), 0, Monitor
.pName
);
494 AddMonitorW(LPWSTR Name
, DWORD Level
, PBYTE Monitors
)
496 WCHAR szPath
[MAX_PATH
];
497 HMODULE hLibrary
= NULL
;
500 MONITOR_INFO_2W
* pMonitor
;
503 if (Level
!= 2 || !Monitors
)
505 SetLastError(ERROR_INVALID_PARAMETER
);
509 pMonitor
= (MONITOR_INFO_2W
*)Monitors
;
511 if (pMonitor
->pDLLName
== NULL
|| pMonitor
->pName
== NULL
)
513 SetLastError(ERROR_INVALID_PARAMETER
);
517 if (wcschr(pMonitor
->pDLLName
, L
'\\'))
519 hLibrary
= LoadLibraryExW(pMonitor
->pDLLName
, NULL
, 0);
521 else if (GetSystemDirectoryW(szPath
, MAX_PATH
) && PathAddBackslashW(szPath
))
523 wcscat(szPath
, pMonitor
->pDLLName
);
524 hLibrary
= LoadLibraryExW(szPath
, NULL
, 0);
532 InitProc
= GetProcAddress(hLibrary
, "InitializePrintMonitor");
535 InitProc
= GetProcAddress(hLibrary
, "InitializePrintMonitor2");
538 FreeLibrary(hLibrary
);
539 SetLastError(ERROR_PROC_NOT_FOUND
);
545 // Initialize monitor
546 FreeLibrary(hLibrary
);
548 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
, L
"SYSTEM\\CurrentControlSet\\Control\\Print\\Monitors", 0, KEY_WRITE
, &hKey
) == ERROR_SUCCESS
)
550 if (RegCreateKeyExW(hKey
, pMonitor
->pName
, 0, NULL
, 0, KEY_WRITE
, NULL
, &hSubKey
, NULL
) == ERROR_SUCCESS
)
552 RegSetValueExW(hSubKey
, L
"Driver", 0, REG_SZ
, (LPBYTE
)pMonitor
->pDLLName
, (wcslen(pMonitor
->pDLLName
)+1)*sizeof(WCHAR
));
553 RegCloseKey(hSubKey
);