Module: wine Branch: master Commit: 86140e3fbb0ac108314f4db6d504c62a4a7cf3bb URL: http://source.winehq.org/git/wine.git/?a=commit;h=86140e3fbb0ac108314f4db6d5...
Author: Jason Edmeades us@edmeades.me.uk Date: Thu Mar 8 00:48:49 2007 +0000
cmd.exe: setlocal and endlocal should preserve drive and directory.
---
programs/cmd/builtins.c | 24 ++++++++++++++++++++++-- programs/cmd/wcmd.h | 5 ++++- 2 files changed, 26 insertions(+), 3 deletions(-)
diff --git a/programs/cmd/builtins.c b/programs/cmd/builtins.c index 5149159..6a1a3a6 100644 --- a/programs/cmd/builtins.c +++ b/programs/cmd/builtins.c @@ -893,6 +893,7 @@ static WCHAR *WCMD_dupenv( const WCHAR *env ) void WCMD_setlocal (const char *s) { WCHAR *env; struct env_stack *env_copy; + char cwd[MAX_PATH];
/* DISABLEEXTENSIONS ignored */
@@ -910,11 +911,16 @@ void WCMD_setlocal (const char *s) { { env_copy->next = saved_environment; saved_environment = env_copy; + + /* Save the current drive letter */ + GetCurrentDirectory (MAX_PATH, cwd); + env_copy->cwd = cwd[0]; } else LocalFree (env_copy);
FreeEnvironmentStringsW (env); + }
/***************************************************************************** @@ -935,6 +941,8 @@ static inline WCHAR *WCMD_strchrW(WCHAR *str, WCHAR ch) * WCMD_endlocal * * endlocal pops the environment off a stack + * Note: When searching for '=', search from char position 1, to handle + * special internal environment variables =C:, =D: etc */ void WCMD_endlocal (void) { WCHAR *env, *old, *p; @@ -954,7 +962,7 @@ void WCMD_endlocal (void) { len = 0; while (old[len]) { n = lstrlenW(&old[len]) + 1; - p = WCMD_strchrW(&old[len], '='); + p = WCMD_strchrW(&old[len] + 1, '='); if (p) { *p++ = 0; @@ -970,7 +978,7 @@ void WCMD_endlocal (void) { len = 0; while (env[len]) { n = lstrlenW(&env[len]) + 1; - p = WCMD_strchrW(&env[len], '='); + p = WCMD_strchrW(&env[len] + 1, '='); if (p) { *p++ = 0; @@ -978,6 +986,18 @@ void WCMD_endlocal (void) { } len += n; } + + /* Restore current drive letter */ + if (IsCharAlpha(temp->cwd)) { + char envvar[4]; + char cwd[MAX_PATH]; + sprintf(envvar, "=%c:", temp->cwd); + if (GetEnvironmentVariable(envvar, cwd, MAX_PATH)) { + WINE_TRACE("Resetting cwd to %s\n", cwd); + SetCurrentDirectory(cwd); + } + } + LocalFree (env); LocalFree (temp); } diff --git a/programs/cmd/wcmd.h b/programs/cmd/wcmd.h index 53f163c..e7ffa94 100644 --- a/programs/cmd/wcmd.h +++ b/programs/cmd/wcmd.h @@ -101,7 +101,10 @@ typedef struct { struct env_stack { struct env_stack *next; - int stackdepth; /* Only used for pushd and popd */ + union { + int stackdepth; /* Only used for pushd and popd */ + char cwd; /* Only used for set/endlocal */ + }; WCHAR *strings; };