Module: wine Branch: master Commit: 3490cb81ed88492bae7694099e34de54b2401780 URL: http://source.winehq.org/git/wine.git/?a=commit;h=3490cb81ed88492bae7694099e...
Author: Aric Stewart aric@codeweavers.com Date: Fri Nov 3 09:47:13 2006 -0600
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 f57cb6e..ff1e314 100644 --- a/dlls/shell32/shlexec.c +++ b/dlls/shell32/shlexec.c @@ -1198,6 +1198,7 @@ BOOL SHELL_execute( LPSHELLEXECUTEINFOW
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 }
/* 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 b22bf2f..bed6fd8 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(); }