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 /******************************************************************************
32 * GetDefaultPrinterA (WINSPOOL.@)
34 BOOL WINAPI
GetDefaultPrinterA(LPSTR name
, LPDWORD namesize
)
40 SetLastError (ERROR_INSUFFICIENT_BUFFER
);
44 if (!GetProfileStringA ("windows", "device", "", name
, *namesize
))
46 SetLastError (ERROR_FILE_NOT_FOUND
);
50 if ((ptr
= strchr (name
, ',')) == NULL
)
52 SetLastError (ERROR_FILE_NOT_FOUND
);
57 *namesize
= strlen (name
) + 1;
62 /******************************************************************************
63 * GetDefaultPrinterW (WINSPOOL.@)
65 BOOL WINAPI
GetDefaultPrinterW(LPWSTR name
, LPDWORD namesize
)
72 SetLastError (ERROR_INSUFFICIENT_BUFFER
);
76 buf
= HeapAlloc (GetProcessHeap (), 0, *namesize
);
77 ret
= GetDefaultPrinterA (buf
, namesize
);
80 DWORD len
= MultiByteToWideChar (CP_ACP
, 0, buf
, -1, name
, *namesize
);
83 SetLastError (ERROR_INSUFFICIENT_BUFFER
);
89 HeapFree (GetProcessHeap (), 0, buf
);
93 /******************************************************************************
94 * AddPrintProvidorA (WINSPOOL.@)
98 AddPrintProvidorA(LPSTR Name
, DWORD Level
, PBYTE Buffer
)
100 if (Name
|| Level
> 2 || Buffer
== NULL
)
102 SetLastError(ERROR_INVALID_PARAMETER
);
109 PROVIDOR_INFO_1W Provider
;
110 PROVIDOR_INFO_1A
*Prov
= (PROVIDOR_INFO_1A
*)Buffer
;
112 if (Prov
->pName
== NULL
|| Prov
->pDLLName
== NULL
|| Prov
->pEnvironment
== NULL
)
117 Provider
.pDLLName
= HeapAlloc(GetProcessHeap(), 0, (strlen(Prov
->pDLLName
)+1) * sizeof(WCHAR
));
118 if (Provider
.pDLLName
)
120 MultiByteToWideChar(CP_ACP
, 0, Prov
->pDLLName
, -1, Provider
.pDLLName
, strlen(Prov
->pDLLName
)+1);
121 Provider
.pDLLName
[strlen(Prov
->pDLLName
)] = L
'\0';
124 Provider
.pEnvironment
= HeapAlloc(GetProcessHeap(), 0, (strlen(Prov
->pEnvironment
)+1) * sizeof(WCHAR
));
125 if (Provider
.pEnvironment
)
127 MultiByteToWideChar(CP_ACP
, 0, Prov
->pEnvironment
, -1, Provider
.pEnvironment
, strlen(Prov
->pEnvironment
)+1);
128 Provider
.pEnvironment
[strlen(Prov
->pEnvironment
)] = L
'\0';
131 Provider
.pName
= HeapAlloc(GetProcessHeap(), 0, (strlen(Prov
->pName
)+1) * sizeof(WCHAR
));
134 MultiByteToWideChar(CP_ACP
, 0, Prov
->pName
, -1, Provider
.pName
, strlen(Prov
->pName
)+1);
135 Provider
.pName
[strlen(Prov
->pName
)] = L
'\0';
138 bRet
= AddPrintProvidorW(NULL
, Level
, (LPBYTE
)&Provider
);
140 if (Provider
.pDLLName
)
141 HeapFree(GetProcessHeap(), 0, Provider
.pDLLName
);
143 if (Provider
.pEnvironment
)
144 HeapFree(GetProcessHeap(), 0, Provider
.pEnvironment
);
147 HeapFree(GetProcessHeap(), 0, Provider
.pName
);
153 PROVIDOR_INFO_2W Provider
;
154 PROVIDOR_INFO_2A
*Prov
= (PROVIDOR_INFO_2A
*)Buffer
;
156 Provider
.pOrder
= HeapAlloc(GetProcessHeap(), 0, (strlen(Prov
->pOrder
)+1) * sizeof(WCHAR
));
160 MultiByteToWideChar(CP_ACP
, 0, Prov
->pOrder
, -1, Provider
.pOrder
, strlen(Prov
->pOrder
)+1);
161 Provider
.pOrder
[strlen(Prov
->pOrder
)] = L
'\0';
163 bRet
= AddPrintProvidorW(NULL
, Level
, (LPBYTE
)&Provider
);
164 HeapFree(GetProcessHeap(), 0, Provider
.pOrder
);
173 /******************************************************************************
174 * AddPrintProvidorW (WINSPOOL.@)
178 AddPrintProvidorW(LPWSTR Name
, DWORD Level
, PBYTE Buffer
)
182 DWORD dwSize
, dwType
;
185 if (Name
|| Level
> 2 || Buffer
== NULL
)
187 SetLastError(ERROR_INVALID_PARAMETER
);
192 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
, L
"SYSTEM\\CurrentControlSet\\Control\\Print\\Providers", 0, KEY_READ
| KEY_WRITE
, &hKey
) != ERROR_SUCCESS
)
197 if (RegQueryValueExW(hKey
, L
"Order", NULL
, &dwType
, NULL
, &dwSize
) != ERROR_SUCCESS
|| dwType
!= REG_MULTI_SZ
)
203 pOrder
= HeapAlloc(GetProcessHeap(), 0, dwSize
);
210 if (RegQueryValueExW(hKey
, L
"Order", NULL
, &dwType
, (LPBYTE
)pOrder
, &dwSize
) != ERROR_SUCCESS
|| dwType
!= REG_MULTI_SZ
)
220 PROVIDOR_INFO_1W
* Prov
= (PROVIDOR_INFO_1W
*)Buffer
;
222 if (Prov
->pName
== NULL
|| Prov
->pDLLName
== NULL
|| Prov
->pEnvironment
== NULL
)
224 SetLastError(ERROR_INVALID_PARAMETER
);
233 if (!wcsicmp(pBuffer
, Prov
->pName
))
238 pBuffer
+= wcslen(pBuffer
) + 1;
244 DWORD dwFullSize
= dwSize
+ (wcslen(Prov
->pName
)+1) * sizeof(WCHAR
);
246 if (RegCreateKeyExW(hKey
, Prov
->pName
, 0, NULL
, 0, KEY_WRITE
, NULL
, &hSubKey
, NULL
) == ERROR_SUCCESS
)
248 RegSetValueExW(hSubKey
, L
"Name", 0, REG_SZ
, (LPBYTE
)Prov
->pDLLName
, (wcslen(Prov
->pDLLName
)+1) * sizeof(WCHAR
));
249 RegCloseKey(hSubKey
);
252 pBuffer
= HeapAlloc(GetProcessHeap(), 0, dwFullSize
);
255 CopyMemory(pBuffer
, pOrder
, dwSize
);
256 wcscpy(&pBuffer
[(dwSize
/sizeof(WCHAR
))-1], Prov
->pName
);
257 pBuffer
[(dwSize
/sizeof(WCHAR
)) + wcslen(Prov
->pName
)] = L
'\0';
258 RegSetValueExW(hKey
, L
"Order", 0, REG_MULTI_SZ
, (LPBYTE
)pBuffer
, dwFullSize
);
259 HeapFree(GetProcessHeap(), 0, pBuffer
);
267 HeapFree(GetProcessHeap(), 0, pOrder
);
272 /******************************************************************************
273 * DeletePrintProvidorA (WINSPOOL.@)
277 DeletePrintProvidorA(LPSTR Name
, LPSTR Environment
, LPSTR PrintProvidor
)
282 if (Name
|| !Environment
|| !PrintProvidor
)
284 SetLastError(ERROR_INVALID_PARAMETER
);
288 Env
= HeapAlloc(GetProcessHeap(), 0, (strlen(Environment
)+1) * sizeof(WCHAR
));
294 MultiByteToWideChar(CP_ACP
, 0, Environment
, -1, Env
, strlen(Environment
)+1);
295 Env
[strlen(Environment
)] = L
'\0';
297 Prov
= HeapAlloc(GetProcessHeap(), 0, (strlen(PrintProvidor
)+1) * sizeof(WCHAR
));
300 HeapFree(GetProcessHeap(), 0, Env
);
304 MultiByteToWideChar(CP_ACP
, 0, PrintProvidor
, -1, Prov
, strlen(PrintProvidor
)+1);
305 Prov
[strlen(PrintProvidor
)] = L
'\0';
307 bRet
= DeletePrintProvidorW(NULL
, Env
, Prov
);
308 HeapFree(GetProcessHeap(), 0, Env
);
309 HeapFree(GetProcessHeap(), 0, Prov
);
319 DeletePrintProvidorW(LPWSTR Name
, LPWSTR Environment
, LPWSTR PrintProvidor
)
323 DWORD dwType
, dwSize
, dwOffset
, dwLength
;
324 LPWSTR pOrder
, pBuffer
, pNew
;
326 if (Name
|| !Environment
|| !PrintProvidor
)
328 SetLastError(ERROR_INVALID_PARAMETER
);
332 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
, L
"SYSTEM\\CurrentControlSet\\Control\\Print\\Providers", 0, KEY_READ
| KEY_WRITE
, &hKey
) != ERROR_SUCCESS
)
337 if (RegQueryValueExW(hKey
, L
"Order", NULL
, &dwType
, NULL
, &dwSize
) != ERROR_SUCCESS
|| dwType
!= REG_MULTI_SZ
)
343 pOrder
= HeapAlloc(GetProcessHeap(), 0, dwSize
);
350 if (RegQueryValueExW(hKey
, L
"Order", NULL
, &dwType
, (LPBYTE
)pOrder
, &dwSize
) != ERROR_SUCCESS
|| dwType
!= REG_MULTI_SZ
)
361 if (!wcsicmp(pBuffer
, PrintProvidor
))
366 pBuffer
+= wcslen(pBuffer
) + 1;
372 HeapFree(GetProcessHeap(), 0, pOrder
);
376 pNew
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, dwSize
);
380 HeapFree(GetProcessHeap(), 0, pOrder
);
384 dwOffset
= pBuffer
- pOrder
;
385 dwLength
= (dwSize
/ sizeof(WCHAR
)) - (dwOffset
+ wcslen(pBuffer
) + 1);
386 CopyMemory(pNew
, pOrder
, dwOffset
* sizeof(WCHAR
));
387 CopyMemory(&pNew
[dwOffset
], pBuffer
+ wcslen(pBuffer
) + 1, dwLength
);
389 RegSetValueExW(hKey
, L
"Order", 0, REG_MULTI_SZ
, (LPBYTE
)pNew
, (dwOffset
+ dwLength
) * sizeof(WCHAR
));
390 RegDeleteKey(hKey
, PrintProvidor
);
392 HeapFree(GetProcessHeap(), 0, pOrder
);
393 HeapFree(GetProcessHeap(), 0, pNew
);
404 AddMonitorA(LPSTR Name
, DWORD Level
, PBYTE Monitors
)
406 LPWSTR szName
= NULL
;
407 MONITOR_INFO_2W Monitor
;
408 MONITOR_INFO_2A
*pMonitor
;
411 if (Level
!= 2 || !Monitors
)
413 SetLastError(ERROR_INVALID_PARAMETER
);
417 pMonitor
= (MONITOR_INFO_2A
*)Monitors
;
418 if (pMonitor
->pDLLName
== NULL
|| pMonitor
->pName
== NULL
)
420 SetLastError(ERROR_INVALID_PARAMETER
);
424 ZeroMemory(&Monitor
, sizeof(Monitor
));
428 szName
= HeapAlloc(GetProcessHeap(), 0, (strlen(Name
) + 1) * sizeof(WCHAR
));
433 MultiByteToWideChar(CP_ACP
, 0, Name
, -1, szName
, strlen(Name
)+1);
434 szName
[strlen(Name
)] = L
'\0';
437 Monitor
.pDLLName
= HeapAlloc(GetProcessHeap(), 0, (strlen(pMonitor
->pDLLName
)+1) * sizeof(WCHAR
));
438 if (!Monitor
.pDLLName
)
442 MultiByteToWideChar(CP_ACP
, 0, pMonitor
->pDLLName
, -1, Monitor
.pDLLName
, strlen(pMonitor
->pDLLName
)+1);
443 pMonitor
->pDLLName
[strlen(pMonitor
->pDLLName
)] = L
'\0';
445 Monitor
.pName
= HeapAlloc(GetProcessHeap(), 0, (strlen(pMonitor
->pName
)+1) * sizeof(WCHAR
));
450 MultiByteToWideChar(CP_ACP
, 0, pMonitor
->pName
, -1, Monitor
.pName
, strlen(pMonitor
->pName
)+1);
451 pMonitor
->pName
[strlen(pMonitor
->pName
)] = L
'\0';
454 if (pMonitor
->pEnvironment
)
456 Monitor
.pEnvironment
= HeapAlloc(GetProcessHeap(), 0, (strlen(pMonitor
->pEnvironment
)+1) * sizeof(WCHAR
));
457 if (!Monitor
.pEnvironment
)
461 MultiByteToWideChar(CP_ACP
, 0, pMonitor
->pEnvironment
, -1, Monitor
.pEnvironment
, strlen(pMonitor
->pEnvironment
)+1);
462 pMonitor
->pEnvironment
[strlen(pMonitor
->pEnvironment
)] = L
'\0';
465 bRet
= AddMonitorW(szName
, Level
, (LPBYTE
)&Monitor
);
470 HeapFree(GetProcessHeap(), 0, szName
);
472 if (Monitor
.pDLLName
)
473 HeapFree(GetProcessHeap(), 0, Monitor
.pDLLName
);
475 if (Monitor
.pEnvironment
)
476 HeapFree(GetProcessHeap(), 0, Monitor
.pEnvironment
);
479 HeapFree(GetProcessHeap(), 0, Monitor
.pName
);
490 AddMonitorW(LPWSTR Name
, DWORD Level
, PBYTE Monitors
)
492 WCHAR szPath
[MAX_PATH
];
493 HMODULE hLibrary
= NULL
;
496 MONITOR_INFO_2W
* pMonitor
;
499 if (Level
!= 2 || !Monitors
)
501 SetLastError(ERROR_INVALID_PARAMETER
);
505 pMonitor
= (MONITOR_INFO_2W
*)Monitors
;
507 if (pMonitor
->pDLLName
== NULL
|| pMonitor
->pName
== NULL
)
509 SetLastError(ERROR_INVALID_PARAMETER
);
513 if (wcschr(pMonitor
->pDLLName
, L
'\\'))
515 hLibrary
= LoadLibraryExW(pMonitor
->pDLLName
, NULL
, 0);
517 else if (GetSystemDirectoryW(szPath
, MAX_PATH
) && PathAddBackslashW(szPath
))
519 wcscat(szPath
, pMonitor
->pDLLName
);
520 hLibrary
= LoadLibraryExW(szPath
, NULL
, 0);
528 InitProc
= GetProcAddress(hLibrary
, "InitializePrintMonitor");
531 InitProc
= GetProcAddress(hLibrary
, "InitializePrintMonitor2");
534 FreeLibrary(hLibrary
);
535 SetLastError(ERROR_PROC_NOT_FOUND
);
541 // Initialize monitor
542 FreeLibrary(hLibrary
);
544 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE
, L
"SYSTEM\\CurrentControlSet\\Control\\Print\\Monitors", 0, KEY_WRITE
, &hKey
) == ERROR_SUCCESS
)
546 if (RegCreateKeyExW(hKey
, pMonitor
->pName
, 0, NULL
, 0, KEY_WRITE
, NULL
, &hSubKey
, NULL
) == ERROR_SUCCESS
)
548 RegSetValueExW(hSubKey
, L
"Driver", 0, REG_SZ
, (LPBYTE
)pMonitor
->pDLLName
, (wcslen(pMonitor
->pDLLName
)+1)*sizeof(WCHAR
));
549 RegCloseKey(hSubKey
);