From: Mark Jansen learn0more+wine@gmail.com
Signed-off-by: Alistair Leslie-Hughes leslie_alistair@hotmail.com --- dlls/shell32/shlexec.c | 47 +++++++++++++++++++++++++++++++++++++++++++- dlls/shell32/tests/shlexec.c | 6 +++--- 2 files changed, 49 insertions(+), 4 deletions(-)
diff --git a/dlls/shell32/shlexec.c b/dlls/shell32/shlexec.c index 40306d6..0b794b0 100644 --- a/dlls/shell32/shlexec.c +++ b/dlls/shell32/shlexec.c @@ -1557,6 +1557,26 @@ static void do_error_dialog( UINT_PTR retval, HWND hwnd ) MessageBoxW(hwnd, msg, NULL, MB_ICONERROR); }
+static WCHAR *expand_environment( const WCHAR *str ) +{ + WCHAR *buf; + DWORD len; + + len = ExpandEnvironmentStringsW(str, NULL, 0); + if (!len) return NULL; + + buf = heap_alloc(len * sizeof(WCHAR)); + if (!buf) return NULL; + + len = ExpandEnvironmentStringsW(str, buf, len); + if (!len) + { + heap_free(buf); + return NULL; + } + return buf; +} + /************************************************************************* * SHELL_execute [Internal] */ @@ -1570,7 +1590,7 @@ static BOOL SHELL_execute( LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc ) SEE_MASK_UNICODE | SEE_MASK_ASYNCOK | SEE_MASK_HMONITOR;
WCHAR parametersBuffer[1024], dirBuffer[MAX_PATH], wcmdBuffer[1024]; - WCHAR *wszApplicationName, *wszParameters, *wszDir, *wcmd; + WCHAR *wszApplicationName, *wszParameters, *wszDir, *wcmd = NULL; DWORD dwApplicationNameLen = MAX_PATH+2; DWORD parametersLen = ARRAY_SIZE(parametersBuffer); DWORD wcmdLen = ARRAY_SIZE(wcmdBuffer); @@ -1676,6 +1696,30 @@ static BOOL SHELL_execute( LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc ) TRACE("-- idlist=%p (%s)\n", sei_tmp.lpIDList, debugstr_w(wszApplicationName)); }
+ if (sei_tmp.fMask & SEE_MASK_DOENVSUBST) + { + WCHAR *tmp; + + tmp = expand_environment(sei_tmp.lpFile); + if (!tmp) + { + retval = SE_ERR_OOM; + goto end; + } + heap_free(wszApplicationName); + sei_tmp.lpFile = wszApplicationName = tmp; + + tmp = expand_environment(sei_tmp.lpDirectory); + if (!tmp) + { + retval = SE_ERR_OOM; + goto end; + } + if (wszDir != dirBuffer) + heap_free(wszDir); + sei_tmp.lpDirectory = wszDir = tmp; + } + if ( ERROR_SUCCESS == ShellExecute_FromContextMenu( &sei_tmp ) ) { sei->hInstApp = (HINSTANCE) 33; @@ -1846,6 +1890,7 @@ static BOOL SHELL_execute( LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc ) retval = (UINT_PTR)ShellExecuteW(sei_tmp.hwnd, sei_tmp.lpVerb, lpstrTmpFile, NULL, NULL, 0); }
+end: TRACE("retval %lu\n", retval);
heap_free(wszApplicationName); diff --git a/dlls/shell32/tests/shlexec.c b/dlls/shell32/tests/shlexec.c index ab77fa1..bb2b842 100644 --- a/dlls/shell32/tests/shlexec.c +++ b/dlls/shell32/tests/shlexec.c @@ -2133,13 +2133,13 @@ static void test_lnks(void) get_long_path_name(params, filename, sizeof(filename)); okChildPath("argvA4", filename);
- todo_wait rc=shell_execute_ex(SEE_MASK_NOZONECHECKS|SEE_MASK_DOENVSUBST, NULL, "%TMPDIR%\test_shortcut_shlexec.lnk", NULL, NULL, NULL); + rc=shell_execute_ex(SEE_MASK_NOZONECHECKS|SEE_MASK_DOENVSUBST, NULL, "%TMPDIR%\test_shortcut_shlexec.lnk", NULL, NULL, NULL); okShell(rc > 32, "failed: rc=%lu err=%u\n", rc, GetLastError()); okChildInt("argcA", 5); - todo_wine okChildString("argvA3", "Open"); + okChildString("argvA3", "Open"); sprintf(params, "%s\test file.shlexec", tmpdir); get_long_path_name(params, filename, sizeof(filename)); - todo_wine okChildPath("argvA4", filename); + okChildPath("argvA4", filename); }
/* Should just run our executable */