winspool: Support special environment value "all" in EnumPrinterDrivers.
A custom action in the sp1 installer passes this value.
This commit is contained in:
parent
86af876987
commit
a01ba78546
@ -267,6 +267,12 @@ static const DWORD pi_sizeof[] = {0, sizeof(PRINTER_INFO_1W), sizeof(PRINTER_INF
|
|||||||
sizeof(PRINTER_INFO_7W), sizeof(PRINTER_INFO_8W),
|
sizeof(PRINTER_INFO_7W), sizeof(PRINTER_INFO_8W),
|
||||||
sizeof(PRINTER_INFO_9W)};
|
sizeof(PRINTER_INFO_9W)};
|
||||||
|
|
||||||
|
static const printenv_t env_x64 = {envname_x64W, subdir_x64W, 3, Version3_RegPathW, Version3_SubdirW};
|
||||||
|
static const printenv_t env_x86 = {envname_x86W, subdir_x86W, 3, Version3_RegPathW, Version3_SubdirW};
|
||||||
|
static const printenv_t env_win40 = {envname_win40W, subdir_win40W, 0, Version0_RegPathW, Version0_SubdirW};
|
||||||
|
|
||||||
|
static const printenv_t * const all_printenv[] = {&env_x86, &env_x64, &env_win40};
|
||||||
|
|
||||||
/******************************************************************
|
/******************************************************************
|
||||||
* validate the user-supplied printing-environment [internal]
|
* validate the user-supplied printing-environment [internal]
|
||||||
*
|
*
|
||||||
@ -285,15 +291,6 @@ static const DWORD pi_sizeof[] = {0, sizeof(PRINTER_INFO_1W), sizeof(PRINTER_INF
|
|||||||
|
|
||||||
static const printenv_t * validate_envW(LPCWSTR env)
|
static const printenv_t * validate_envW(LPCWSTR env)
|
||||||
{
|
{
|
||||||
static const printenv_t env_x64 = {envname_x64W, subdir_x64W,
|
|
||||||
3, Version3_RegPathW, Version3_SubdirW};
|
|
||||||
static const printenv_t env_x86 = {envname_x86W, subdir_x86W,
|
|
||||||
3, Version3_RegPathW, Version3_SubdirW};
|
|
||||||
static const printenv_t env_win40 = {envname_win40W, subdir_win40W,
|
|
||||||
0, Version0_RegPathW, Version0_SubdirW};
|
|
||||||
|
|
||||||
static const printenv_t * const all_printenv[]={&env_x86, &env_x64, &env_win40};
|
|
||||||
|
|
||||||
const printenv_t *result = NULL;
|
const printenv_t *result = NULL;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
@ -5169,7 +5166,7 @@ static BOOL WINSPOOL_EnumPrinterDrivers(LPWSTR pName, LPCWSTR pEnvironment,
|
|||||||
RegCloseKey(hkeyDrivers);
|
RegCloseKey(hkeyDrivers);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
(*pcbNeeded) += needed;
|
*pcbNeeded += needed;
|
||||||
}
|
}
|
||||||
|
|
||||||
RegCloseKey(hkeyDrivers);
|
RegCloseKey(hkeyDrivers);
|
||||||
@ -5192,6 +5189,29 @@ BOOL WINAPI EnumPrinterDriversW(LPWSTR pName, LPWSTR pEnvironment, DWORD Level,
|
|||||||
LPBYTE pDriverInfo, DWORD cbBuf,
|
LPBYTE pDriverInfo, DWORD cbBuf,
|
||||||
LPDWORD pcbNeeded, LPDWORD pcReturned)
|
LPDWORD pcbNeeded, LPDWORD pcReturned)
|
||||||
{
|
{
|
||||||
|
static const WCHAR allW[] = {'a','l','l',0};
|
||||||
|
|
||||||
|
if (pEnvironment && !strcmpW(pEnvironment, allW))
|
||||||
|
{
|
||||||
|
BOOL ret;
|
||||||
|
DWORD i, needed, returned, bufsize = cbBuf;
|
||||||
|
|
||||||
|
for (i = 0; i < sizeof(all_printenv)/sizeof(all_printenv[0]); i++)
|
||||||
|
{
|
||||||
|
needed = returned = 0;
|
||||||
|
ret = WINSPOOL_EnumPrinterDrivers(pName, all_printenv[i]->envname, Level,
|
||||||
|
pDriverInfo, bufsize, &needed, &returned, TRUE);
|
||||||
|
if (!ret && GetLastError() != ERROR_INSUFFICIENT_BUFFER) return FALSE;
|
||||||
|
else if (ret)
|
||||||
|
{
|
||||||
|
bufsize -= needed;
|
||||||
|
if (pDriverInfo) pDriverInfo += needed;
|
||||||
|
if (pcReturned) *pcReturned += returned;
|
||||||
|
}
|
||||||
|
if (pcbNeeded) *pcbNeeded += needed;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
return WINSPOOL_EnumPrinterDrivers(pName, pEnvironment, Level, pDriverInfo,
|
return WINSPOOL_EnumPrinterDrivers(pName, pEnvironment, Level, pDriverInfo,
|
||||||
cbBuf, pcbNeeded, pcReturned, TRUE);
|
cbBuf, pcbNeeded, pcReturned, TRUE);
|
||||||
}
|
}
|
||||||
@ -5204,14 +5224,34 @@ BOOL WINAPI EnumPrinterDriversW(LPWSTR pName, LPWSTR pEnvironment, DWORD Level,
|
|||||||
BOOL WINAPI EnumPrinterDriversA(LPSTR pName, LPSTR pEnvironment, DWORD Level,
|
BOOL WINAPI EnumPrinterDriversA(LPSTR pName, LPSTR pEnvironment, DWORD Level,
|
||||||
LPBYTE pDriverInfo, DWORD cbBuf,
|
LPBYTE pDriverInfo, DWORD cbBuf,
|
||||||
LPDWORD pcbNeeded, LPDWORD pcReturned)
|
LPDWORD pcbNeeded, LPDWORD pcReturned)
|
||||||
{ BOOL ret;
|
{
|
||||||
|
BOOL ret;
|
||||||
UNICODE_STRING pNameW, pEnvironmentW;
|
UNICODE_STRING pNameW, pEnvironmentW;
|
||||||
PWSTR pwstrNameW, pwstrEnvironmentW;
|
PWSTR pwstrNameW, pwstrEnvironmentW;
|
||||||
|
|
||||||
pwstrNameW = asciitounicode(&pNameW, pName);
|
pwstrNameW = asciitounicode(&pNameW, pName);
|
||||||
pwstrEnvironmentW = asciitounicode(&pEnvironmentW, pEnvironment);
|
pwstrEnvironmentW = asciitounicode(&pEnvironmentW, pEnvironment);
|
||||||
|
|
||||||
ret = WINSPOOL_EnumPrinterDrivers(pwstrNameW, pwstrEnvironmentW,
|
if (pEnvironment && !strcmp(pEnvironment, "all"))
|
||||||
|
{
|
||||||
|
DWORD i, needed, returned, bufsize = cbBuf;
|
||||||
|
|
||||||
|
for (i = 0; i < sizeof(all_printenv)/sizeof(all_printenv[0]); i++)
|
||||||
|
{
|
||||||
|
needed = returned = 0;
|
||||||
|
ret = WINSPOOL_EnumPrinterDrivers(pwstrNameW, all_printenv[i]->envname, Level,
|
||||||
|
pDriverInfo, bufsize, &needed, &returned, FALSE);
|
||||||
|
if (!ret && GetLastError() != ERROR_INSUFFICIENT_BUFFER) break;
|
||||||
|
else if (ret)
|
||||||
|
{
|
||||||
|
bufsize -= needed;
|
||||||
|
if (pDriverInfo) pDriverInfo += needed;
|
||||||
|
if (pcReturned) *pcReturned += returned;
|
||||||
|
}
|
||||||
|
if (pcbNeeded) *pcbNeeded += needed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else ret = WINSPOOL_EnumPrinterDrivers(pwstrNameW, pwstrEnvironmentW,
|
||||||
Level, pDriverInfo, cbBuf, pcbNeeded,
|
Level, pDriverInfo, cbBuf, pcbNeeded,
|
||||||
pcReturned, FALSE);
|
pcReturned, FALSE);
|
||||||
RtlFreeUnicodeString(&pNameW);
|
RtlFreeUnicodeString(&pNameW);
|
||||||
|
@ -1107,6 +1107,8 @@ static void test_EnumPorts(void)
|
|||||||
|
|
||||||
static void test_EnumPrinterDrivers(void)
|
static void test_EnumPrinterDrivers(void)
|
||||||
{
|
{
|
||||||
|
static char env_all[] = "all";
|
||||||
|
|
||||||
DWORD res;
|
DWORD res;
|
||||||
LPBYTE buffer;
|
LPBYTE buffer;
|
||||||
DWORD cbBuf;
|
DWORD cbBuf;
|
||||||
@ -1210,6 +1212,23 @@ static void test_EnumPrinterDrivers(void)
|
|||||||
|
|
||||||
HeapFree(GetProcessHeap(), 0, buffer);
|
HeapFree(GetProcessHeap(), 0, buffer);
|
||||||
} /* for(level ... */
|
} /* for(level ... */
|
||||||
|
|
||||||
|
pcbNeeded = 0;
|
||||||
|
pcReturned = 0;
|
||||||
|
SetLastError(0xdeadbeef);
|
||||||
|
res = EnumPrinterDriversA(NULL, env_all, 1, NULL, 0, &pcbNeeded, &pcReturned);
|
||||||
|
if (res)
|
||||||
|
{
|
||||||
|
skip("no printer drivers found\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "unexpected error %u\n", GetLastError());
|
||||||
|
|
||||||
|
buffer = HeapAlloc(GetProcessHeap(), 0, pcbNeeded);
|
||||||
|
res = EnumPrinterDriversA(NULL, env_all, 1, buffer, pcbNeeded, &pcbNeeded, &pcReturned);
|
||||||
|
ok(res, "EnumPrinterDriversA failed %u\n", GetLastError());
|
||||||
|
|
||||||
|
HeapFree(GetProcessHeap(), 0, buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ########################### */
|
/* ########################### */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user