Module: wine Branch: refs/heads/master Commit: 23ead2b174129297f4b4e5e9738fc9b3fac603cc URL: http://source.winehq.org/git/?p=wine.git;a=commit;h=23ead2b174129297f4b4e5e9...
Author: Detlef Riekenberg wine.dev@web.de Date: Wed Jan 18 12:26:32 2006 +0100
winspool: Printing environment support for GetPrinterDriverDirectory.
---
dlls/winspool/info.c | 127 +++++++++++++++++++++++++++++++++++++------- dlls/winspool/tests/info.c | 11 +--- 2 files changed, 111 insertions(+), 27 deletions(-)
diff --git a/dlls/winspool/info.c b/dlls/winspool/info.c index 9b1771d..d0f51aa 100644 --- a/dlls/winspool/info.c +++ b/dlls/winspool/info.c @@ -96,6 +96,14 @@ typedef struct { WCHAR *document_title; } job_t;
+ +typedef struct { + LPCWSTR envname; + LPCWSTR subdir; +} printenv_t; + +/* ############################### */ + static opened_printer_t **printer_handles; static int nb_printer_handles; static LONG next_job_id = 1; @@ -131,6 +139,12 @@ static const WCHAR user_printers_reg_key 'D','e','v','i','c','e','s',0};
static const WCHAR DefaultEnvironmentW[] = {'W','i','n','e',0}; +static const WCHAR envname_win40W[] = {'W','i','n','d','o','w','s',' ','4','.','0',0}; +static const WCHAR envname_x86W[] = {'W','i','n','d','o','w','s',' ','N','T',' ','x','8','6',0}; +static const WCHAR subdir_win40W[] = {'w','i','n','4','0',0}; +static const WCHAR subdir_x86W[] = {'w','3','2','x','8','6',0}; + +static const WCHAR spooldriversW[] = {'\','s','p','o','o','l','\','d','r','i','v','e','r','s','\',0};
static const WCHAR Configuration_FileW[] = {'C','o','n','f','i','g','u','r','a','t', 'i','o','n',' ','F','i','l','e',0}; @@ -179,6 +193,58 @@ static BOOL WINSPOOL_GetPrinterDriver(HA BOOL unicode); static DWORD WINSPOOL_GetOpenedPrinterRegKey(HANDLE hPrinter, HKEY *phkey);
+/****************************************************************** + * validate the user-supplied printing-environment [internal] + * + * PARAMS + * env [I] PTR to Environment-String or NULL + * + * RETURNS + * Failure: NULL + * Success: PTR to printenv_t + * + * NOTES + * SetLastEror(ERROR_INVALID_ENVIRONMENT) is called on Failure + * + */ + +static const printenv_t * validate_envW(LPCWSTR env) +{ + static const printenv_t env_x86 = {envname_x86W, subdir_x86W}; + static const printenv_t env_win40 = {envname_win40W, subdir_win40W}; + static const printenv_t * const all_printenv[]={&env_x86, &env_win40}; + + const printenv_t *result = NULL; + unsigned int i; + + TRACE("testing %s\n", debugstr_w(env)); + if (env) + { + for (i = 0; i < sizeof(all_printenv)/sizeof(all_printenv[0]); i++) + { + if (lstrcmpiW(env, all_printenv[i]->envname) == 0) + { + result = all_printenv[i]; + break; + } + } + + if (result == NULL) { + FIXME("unsupported Environment: %s\n", debugstr_w(env)); + SetLastError(ERROR_INVALID_ENVIRONMENT); + } + /* on win9x, only "Windows 4.0" is allowed, but we ignore this */ + } + else + { + result = (GetVersion() & 0x80000000) ? &env_win40 : &env_x86; + } + TRACE("using %p: %s\n", result, debugstr_w(result ? result->envname : NULL)); + + return result; +} + + /* RtlCreateUnicodeStringFromAsciiz will return an empty string in the buffer if passed a NULL string. This returns NULLs to the result. */ @@ -3343,37 +3409,55 @@ BOOL WINAPI GetPrinterDriverDirectoryW(L DWORD cbBuf, LPDWORD pcbNeeded) { DWORD needed; + const printenv_t * env;
TRACE("(%s, %s, %ld, %p, %ld, %p)\n", debugstr_w(pName), debugstr_w(pEnvironment), Level, pDriverDirectory, cbBuf, pcbNeeded); if(pName != NULL) { - FIXME("pName = `%s' - unsupported\n", debugstr_w(pName)); - SetLastError(ERROR_INVALID_PARAMETER); - return FALSE; + FIXME("pName unsupported: %s\n", debugstr_w(pName)); + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; } - if(pEnvironment != NULL) { - FIXME("pEnvironment = `%s' - unsupported\n", debugstr_w(pEnvironment)); - SetLastError(ERROR_INVALID_ENVIRONMENT); - return FALSE; + + env = validate_envW(pEnvironment); + if(!env) return FALSE; /* pEnvironment invalid or unsupported */ + + if(Level != 1) { + WARN("(Level: %ld) is ignored in win9x\n", Level); + SetLastError(ERROR_INVALID_LEVEL); + return FALSE; } - if(Level != 1) /* win95 ignores this so we just carry on */ - WARN("Level = %ld - assuming 1\n", Level);
- /* FIXME should read from registry */ - needed = GetSystemDirectoryW( (LPWSTR)pDriverDirectory, cbBuf/sizeof(WCHAR)); - /* GetSystemDirectoryW returns number of TCHAR without '\0' - * adjust this now - */ - needed++; - needed*=sizeof(WCHAR); + /* GetSystemDirectoryW returns number of WCHAR including the '\0' */ + needed = GetSystemDirectoryW(NULL, 0); + /* add the Size for the Subdirectories */ + needed += lstrlenW(spooldriversW); + needed += lstrlenW(env->subdir); + needed *= sizeof(WCHAR); /* return-value is size in Bytes */
if(pcbNeeded) *pcbNeeded = needed; - TRACE("required <%08lx>\n", *pcbNeeded); + TRACE("required: 0x%lx/%ld\n", needed, needed); if(needed > cbBuf) { SetLastError(ERROR_INSUFFICIENT_BUFFER); - return FALSE; + return FALSE; + } + if(pcbNeeded == NULL) { + WARN("(pcbNeeded == NULL) is ignored in win9x\n"); + SetLastError(RPC_X_NULL_REF_POINTER); + return FALSE; } + if(pDriverDirectory == NULL) { + /* ERROR_INVALID_USER_BUFFER is NT, ERROR_INVALID_PARAMETER is win9x */ + SetLastError(ERROR_INVALID_USER_BUFFER); + return FALSE; + } + + GetSystemDirectoryW((LPWSTR) pDriverDirectory, cbBuf/sizeof(WCHAR)); + /* add the Subdirectories */ + lstrcatW((LPWSTR) pDriverDirectory, spooldriversW); + lstrcatW((LPWSTR) pDriverDirectory, env->subdir); + TRACE(" => %s\n", debugstr_w((LPWSTR) pDriverDirectory)); return TRUE; }
@@ -3399,6 +3483,9 @@ BOOL WINAPI GetPrinterDriverDirectoryA(L INT len = cbBuf * sizeof(WCHAR)/sizeof(CHAR); WCHAR *driverDirectoryW = NULL;
+ TRACE("(%s, %s, %ld, %p, %ld, %p)\n", debugstr_a(pName), + debugstr_a(pEnvironment), Level, pDriverDirectory, cbBuf, pcbNeeded); + if (len) driverDirectoryW = HeapAlloc( GetProcessHeap(), 0, len );
if(pName) RtlCreateUnicodeStringFromAsciiz(&nameW, pName); @@ -3410,7 +3497,7 @@ BOOL WINAPI GetPrinterDriverDirectoryA(L (LPBYTE)driverDirectoryW, len, &pcbNeededW ); if (ret) { DWORD needed; - needed = 1 + WideCharToMultiByte( CP_ACP, 0, driverDirectoryW, -1, + needed = WideCharToMultiByte( CP_ACP, 0, driverDirectoryW, -1, (LPSTR)pDriverDirectory, cbBuf, NULL, NULL); if(pcbNeeded) *pcbNeeded = needed; @@ -3418,7 +3505,7 @@ BOOL WINAPI GetPrinterDriverDirectoryA(L } else if(pcbNeeded) *pcbNeeded = pcbNeededW * sizeof(CHAR)/sizeof(WCHAR);
- TRACE("provided<%ld> required <%ld>\n", cbBuf, *pcbNeeded); + TRACE("required: 0x%lx/%ld\n", pcbNeeded ? *pcbNeeded : 0, pcbNeeded ? *pcbNeeded : 0);
HeapFree( GetProcessHeap(), 0, driverDirectoryW ); RtlFreeUnicodeString(&environmentW); diff --git a/dlls/winspool/tests/info.c b/dlls/winspool/tests/info.c index 2218ef4..4b11829 100644 --- a/dlls/winspool/tests/info.c +++ b/dlls/winspool/tests/info.c @@ -213,12 +213,11 @@ static void test_printer_directory(void) ok( !res , "expected result == 0, got %d\n", res); ok( cbBuf == pcbNeeded, "pcbNeeded set to %ld instead of %ld\n", pcbNeeded, cbBuf); - todo_wine { + ok( ERROR_INSUFFICIENT_BUFFER == GetLastError(), "last error set to %ld instead of ERROR_INSUFFICIENT_BUFFER\n", GetLastError()); - } - + SetLastError(0x00dead00); res = GetPrinterDriverDirectoryA( NULL, NULL, 1, NULL, cbBuf, &pcbNeeded); ok( (!res && ERROR_INVALID_USER_BUFFER == GetLastError()) || @@ -278,12 +277,10 @@ static void test_printer_directory(void) res = GetPrinterDriverDirectoryA(NULL, env_win9x_case, 1, buffer, cbBuf*2, &pcbNeeded); } - - todo_wine{ + ok(res && buffer[0], "returned %d with " \ - "lasterror=%ld and len=%d (expected '0' with 'len > 0')\n", + "lasterror=%ld and len=%d (expected '1' with 'len > 0')\n", res, GetLastError(), lstrlenA((char *)buffer)); - }
buffer[0] = '\0'; SetLastError(0x00dead00);