From: huangqinjin huangqinjin@gmail.com
Set =C: environment variable only when CD succeeds. --- programs/cmd/builtins.c | 142 +++++++++++++++++++++++++--------------- 1 file changed, 90 insertions(+), 52 deletions(-)
diff --git a/programs/cmd/builtins.c b/programs/cmd/builtins.c index d7c5090d17f..a748ff64d29 100644 --- a/programs/cmd/builtins.c +++ b/programs/cmd/builtins.c @@ -1750,6 +1750,15 @@ RETURN_CODE WCMD_goto(void) return ERROR_INVALID_FUNCTION; }
+/***************************************************************************** + * WCMD_cd_set_env + * + * Change current directory and set special environment variable =C:. + * Restore to cwd after cd if supplied. + */ + +static RETURN_CODE WCMD_cd_set_env(const WCHAR *args, const WCHAR *cwd); + /***************************************************************************** * WCMD_pushd * @@ -2307,12 +2316,7 @@ RETURN_CODE WCMD_endlocal(void) RETURN_CODE WCMD_setshow_default(const WCHAR *args) { RETURN_CODE return_code; - BOOL status; - WCHAR string[1024]; WCHAR cwd[1024]; - WCHAR *pos; - WIN32_FIND_DATAW fd; - HANDLE hff;
WINE_TRACE("Request change to directory '%s'\n", wine_dbgstr_w(args));
@@ -2334,61 +2338,96 @@ RETURN_CODE WCMD_setshow_default(const WCHAR *args) WCMD_output_asis (cwd); } else { - /* Remove any double quotes, which may be in the - middle, eg. cd "C:\Program Files"\Microsoft is ok */ - pos = string; - while (*args) { - if (*args != '"') *pos++ = *args; - args++; + /* Restore old directory if drive letter would change, and + CD x:\directory /D (or pushd c:\directory) not supplied */ + if ((wcsstr(quals, L"/D") == NULL) && + (param1[1] == ':') && (towupper(param1[0]) != towupper(cwd[0]))) { + return_code = WCMD_cd_set_env(args, cwd); + } + else { + return_code = WCMD_cd_set_env(args, NULL); } - while (pos > string && (*(pos-1) == ' ' || *(pos-1) == '\t')) - pos--; - *pos = 0x00; + }
- /* Search for appropriate directory */ - WINE_TRACE("Looking for directory '%s'\n", wine_dbgstr_w(string)); - hff = FindFirstFileW(string, &fd); - if (hff != INVALID_HANDLE_VALUE) { - do { - if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { - WCHAR fpath[MAX_PATH]; - WCHAR drive[10]; - WCHAR dir[MAX_PATH]; - WCHAR fname[MAX_PATH]; - WCHAR ext[MAX_PATH]; + if (return_code == ERROR_PATH_NOT_FOUND) { + WCMD_print_error(); + }
- /* Convert path into actual directory spec */ - if (!WCMD_get_fullpath(string, ARRAY_SIZE(fpath), fpath, NULL)) - return errorlevel = ERROR_INVALID_FUNCTION; + return return_code == NO_ERROR ? + (errorlevel = NO_ERROR) : (errorlevel = ERROR_INVALID_FUNCTION); +}
- _wsplitpath(fpath, drive, dir, fname, ext); +/***************************************************************************** + * WCMD_cd_set_env + * + * Change current directory and set special environment variable =C:. + * Restore to cwd after cd if supplied. + */
- /* Rebuild path */ - wsprintfW(string, L"%s%s%s", drive, dir, fd.cFileName); - break; - } - } while (FindNextFileW(hff, &fd) != 0); - FindClose(hff); - } +static RETURN_CODE WCMD_cd_set_env(const WCHAR *args, const WCHAR *cwd) +{ + RETURN_CODE return_code; + BOOL status; + WCHAR string[1024]; + WCHAR *pos; + WIN32_FIND_DATAW fd; + HANDLE hff;
- /* Change to that directory */ - WINE_TRACE("Really changing to directory '%s'\n", wine_dbgstr_w(string)); + return_code = NO_ERROR;
- status = SetCurrentDirectoryW(string); - if (!status) { - WCMD_print_error (); - return_code = ERROR_INVALID_FUNCTION; - } else { + /* Remove any double quotes, which may be in the + middle, eg. cd "C:\Program Files"\Microsoft is ok */ + pos = string; + while (*args) { + if (*args != '"') *pos++ = *args; + args++; + } + while (pos > string && (*(pos-1) == ' ' || *(pos-1) == '\t')) + pos--; + *pos = 0x00; + + /* Search for appropriate directory */ + WINE_TRACE("Looking for directory '%s'\n", wine_dbgstr_w(string)); + hff = FindFirstFileW(string, &fd); + if (hff != INVALID_HANDLE_VALUE) { + do { + if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { + WCHAR fpath[MAX_PATH]; + WCHAR drive[10]; + WCHAR dir[MAX_PATH]; + WCHAR fname[MAX_PATH]; + WCHAR ext[MAX_PATH];
- /* Save away the actual new directory, to store as current location */ - GetCurrentDirectoryW(ARRAY_SIZE(string), string); + /* Convert path into actual directory spec */ + if (!WCMD_get_fullpath(string, ARRAY_SIZE(fpath), fpath, NULL)) { + FindClose(hff); + return ERROR_INVALID_FUNCTION; + } + _wsplitpath(fpath, drive, dir, fname, ext);
- /* Restore old directory if drive letter would change, and - CD x:\directory /D (or pushd c:\directory) not supplied */ - if ((wcsstr(quals, L"/D") == NULL) && - (param1[1] == ':') && (towupper(param1[0]) != towupper(cwd[0]))) { - SetCurrentDirectoryW(cwd); + /* Rebuild path */ + wsprintfW(string, L"%s%s%s", drive, dir, fd.cFileName); + break; } + } while (FindNextFileW(hff, &fd) != 0); + FindClose(hff); + } + + /* Change to that directory */ + WINE_TRACE("Really changing to directory '%s'\n", wine_dbgstr_w(string)); + + status = SetCurrentDirectoryW(string); + if (!status) { + return_code = ERROR_PATH_NOT_FOUND; + } else { + + /* Save away the actual new directory, to store as current location */ + GetCurrentDirectoryW(ARRAY_SIZE(string), string); + + /* Restore old directory if drive letter would change, and + CD x:\directory /D (or pushd c:\directory) not supplied */ + if (cwd != NULL) { + SetCurrentDirectoryW(cwd); }
/* Set special =C: type environment variable, for drive letter of @@ -2403,9 +2442,8 @@ RETURN_CODE WCMD_setshow_default(const WCHAR *args) WINE_TRACE("Setting '%s' to '%s'\n", wine_dbgstr_w(env), wine_dbgstr_w(string)); SetEnvironmentVariableW(env, string); } - } - return errorlevel = return_code; + return return_code; }
/****************************************************************************