From 3490cb81ed88492bae7694099e34de54b2401780 Mon Sep 17 00:00:00 2001 From: Aric Stewart Date: Fri, 3 Nov 2006 09:47:13 -0600 Subject: [PATCH] shell32: Create dynamic buffers for expanded enviroment strings to allow for parameters and such longer than MAX_PATH. With help from Michael Moss. --- dlls/shell32/shlexec.c | 48 +++++++++++++++++++++++++++++++----- dlls/shell32/tests/shlexec.c | 32 ++++++++++++++++++++++++ 2 files changed, 74 insertions(+), 6 deletions(-) diff --git a/dlls/shell32/shlexec.c b/dlls/shell32/shlexec.c index f57cb6ec8fa..ff1e314652f 100644 --- a/dlls/shell32/shlexec.c +++ b/dlls/shell32/shlexec.c @@ -1198,6 +1198,7 @@ BOOL SHELL_execute( LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc ) WCHAR *wszApplicationName, wszParameters[1024], wszDir[MAX_PATH]; DWORD dwApplicationNameLen = MAX_PATH+2; + DWORD len; SHELLEXECUTEINFOW sei_tmp; /* modifiable copy of SHELLEXECUTEINFO struct */ WCHAR wfileName[MAX_PATH]; WCHAR *env; @@ -1351,16 +1352,51 @@ BOOL SHELL_execute( LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc ) } /* expand environment strings */ - if (ExpandEnvironmentStringsW(sei_tmp.lpFile, buffer, MAX_PATH)) - lstrcpyW(wszApplicationName, buffer); + len = ExpandEnvironmentStringsW(sei_tmp.lpFile, NULL, 0); + if (len>0) + { + LPWSTR buf; + buf = HeapAlloc(GetProcessHeap(),0,(len+1)*sizeof(WCHAR)); + + ExpandEnvironmentStringsW(sei_tmp.lpFile, buf, len+1); + HeapFree(GetProcessHeap(), 0, wszApplicationName); + dwApplicationNameLen = len+1; + wszApplicationName = buf; + + sei_tmp.lpFile = wszApplicationName; + } if (*sei_tmp.lpParameters) - if (ExpandEnvironmentStringsW(sei_tmp.lpParameters, buffer, MAX_PATH)) - lstrcpyW(wszParameters, buffer); + { + len = ExpandEnvironmentStringsW(sei_tmp.lpParameters, NULL, 0); + if (len > 0) + { + LPWSTR buf; + len++; + buf = HeapAlloc(GetProcessHeap(),0,len*sizeof(WCHAR)); + ExpandEnvironmentStringsW(sei_tmp.lpParameters, buf, len); + if (len > 1024) + ERR("Parameters exceeds buffer size (%i > 1024)\n",len); + lstrcpynW(wszParameters, buf, min(1024,len)); + HeapFree(GetProcessHeap(),0,buf); + } + } if (*sei_tmp.lpDirectory) - if (ExpandEnvironmentStringsW(sei_tmp.lpDirectory, buffer, MAX_PATH)) - lstrcpyW(wszDir, buffer); + { + len = ExpandEnvironmentStringsW(sei_tmp.lpDirectory, NULL, 0); + if (len > 0) + { + LPWSTR buf; + len++; + buf = HeapAlloc(GetProcessHeap(),0,len*sizeof(WCHAR)); + ExpandEnvironmentStringsW(sei_tmp.lpDirectory, buf, len); + if (len > 1024) + ERR("Directory exceeds buffer size (%i > 1024)\n",len); + lstrcpynW(wszDir, buf, min(1024,len)); + HeapFree(GetProcessHeap(),0,buf); + } + } /* Else, try to execute the filename */ TRACE("execute:%s,%s,%s\n", debugstr_w(wszApplicationName), debugstr_w(wszParameters), debugstr_w(wszDir)); diff --git a/dlls/shell32/tests/shlexec.c b/dlls/shell32/tests/shlexec.c index b22bf2fd9fb..bed6fd8d0c7 100644 --- a/dlls/shell32/tests/shlexec.c +++ b/dlls/shell32/tests/shlexec.c @@ -813,6 +813,37 @@ static void test_exes(void) } } +static void test_exes_long(void) +{ + char filename[MAX_PATH]; + char params[2024]; + char longparam[MAX_PATH]; + int rc; + + for (rc = 0; rc < MAX_PATH; rc++) + longparam[rc]='a'+rc%26; + longparam[MAX_PATH-1]=0; + + + sprintf(params, "shlexec \"%s\" %s", child_file,longparam); + + /* We need NOZONECHECKS on Win2003 to block a dialog */ + rc=shell_execute_ex(SEE_MASK_NOZONECHECKS, NULL, argv0, params, + NULL); + ok(rc>=32, "%s returned %d\n", shell_call, rc); + okChildInt("argcA", 4); + okChildString("argvA3", longparam); + + sprintf(filename, "%s\\test file.noassoc", tmpdir); + if (CopyFile(argv0, filename, FALSE)) + { + rc=shell_execute(NULL, filename, params, NULL); + todo_wine { + ok(rc==SE_ERR_NOASSOC, "%s succeeded: rc=%d\n", shell_call, rc); + } + } +} + static void init_test(void) { @@ -954,6 +985,7 @@ START_TEST(shlexec) test_filename(); test_lnks(); test_exes(); + test_exes_long(); cleanup_test(); }