From 160f13b108c326a99d0fd34669da7c1116b32acb Mon Sep 17 00:00:00 2001 From: Vincent Povirk Date: Tue, 21 Oct 2008 16:07:47 -0500 Subject: [PATCH] shell32: try to guess the working directory in the run dialog The Run dialog on Windows, when invoked from the start menu or by passing NULL as a working directory to RunFileDlg, sets the working directory to the parent of the file being run. Programs often rely on the working directory so we should copy this behavior. --- dlls/shell32/dialogs.c | 63 ++++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 61 insertions(+), 2 deletions(-) diff --git a/dlls/shell32/dialogs.c b/dlls/shell32/dialogs.c index 77eea18..19ef014 100644 --- a/dlls/shell32/dialogs.c +++ b/dlls/shell32/dialogs.c @@ -113,6 +113,58 @@ void WINAPI RunFileDlgW( } +/* find the directory that contains the file being run */ +static LPWSTR RunDlg_GetParentDir(LPCWSTR cmdline) +{ + const WCHAR *src; + WCHAR *dest, *result, *result_end=NULL; + static WCHAR dotexeW[] = {'.','e','x','e',0}; + + result = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*(strlenW(cmdline)+5)); + + src = cmdline; + dest = result; + + if (*src == '"') + { + src++; + while (*src && *src != '"') + { + if (*src == '\\') + result_end = dest; + *dest++ = *src++; + } + } + else { + while (*src) + { + if (isspace(*src)) + { + *dest = 0; + if (INVALID_FILE_ATTRIBUTES != GetFileAttributesW(result)) + break; + strcatW(dest, dotexeW); + if (INVALID_FILE_ATTRIBUTES != GetFileAttributesW(result)) + break; + } + else if (*src == '\\') + result_end = dest; + *dest++ = *src++; + } + } + + if (result_end) + { + *result_end = 0; + return result; + } + else + { + HeapFree(GetProcessHeap(), 0, result); + return NULL; + } +} + /* Dialog procedure for RunFileDlg */ static INT_PTR CALLBACK RunDlgProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { @@ -158,14 +210,20 @@ static INT_PTR CALLBACK RunDlgProc (HWND hwnd, UINT message, WPARAM wParam, LPAR HWND htxt = GetDlgItem (hwnd, IDC_RUNDLG_EDITPATH); if ((ic = GetWindowTextLengthW (htxt))) { - WCHAR *psz ; + WCHAR *psz, *parent=NULL ; + LPCWSTR working_dir ; psz = HeapAlloc( GetProcessHeap(), 0, (ic + 1)*sizeof(WCHAR) ); GetWindowTextW (htxt, psz, ic + 1) ; /* according to http://www.codeproject.com/KB/shell/runfiledlg.aspx we should send a * WM_NOTIFY before execution */ - if (ShellExecuteW(hwnd, NULL, psz, NULL, prfdp->lpstrDirectory, SW_SHOWNORMAL) < (HINSTANCE)33) + if (prfdp->lpstrDirectory) + working_dir = prfdp->lpstrDirectory; + else + working_dir = parent = RunDlg_GetParentDir(psz); + + if (ShellExecuteW(hwnd, NULL, psz, NULL, working_dir, SW_SHOWNORMAL) < (HINSTANCE)33) { char *pszSysMsg = NULL ; char szMsg[256]; @@ -191,6 +249,7 @@ static INT_PTR CALLBACK RunDlgProc (HWND hwnd, UINT message, WPARAM wParam, LPAR FillList (htxt, (LPSTR)psz, FALSE) ; HeapFree(GetProcessHeap(), 0, psz); + HeapFree(GetProcessHeap(), 0, parent); EndDialog (hwnd, 0) ; } } -- 1.5.6.3