https://git.reactos.org/?p=reactos.git;a=commitdiff;h=1cb7e0852260735df364abb1d993d5d67f22eab6

commit 1cb7e0852260735df364abb1d993d5d67f22eab6
Author:     Hermès Bélusca-Maïto <[email protected]>
AuthorDate: Sat Jul 18 23:35:56 2020 +0200
Commit:     Hermès Bélusca-Maïto <[email protected]>
CommitDate: Wed Aug 19 20:36:13 2020 +0200

    [CMD] SETLOCAL / ENDLOCAL: Save / Restore as well the current drive and 
current directory.
    
    That's an actual fact, done on original MS-DOS COMMAND.COM, FreeCOM,
    Windows' CMD.EXE, etc., but is strangely undocumented on MSDN documentation.
    
    See https://www.dostips.com/forum/viewtopic.php?t=4436
    
    Fixes some cmd_winetests.
---
 base/shell/cmd/setlocal.c | 35 +++++++++++++++++++++++++++++++++--
 1 file changed, 33 insertions(+), 2 deletions(-)

diff --git a/base/shell/cmd/setlocal.c b/base/shell/cmd/setlocal.c
index daf86099050..18cec04b6f0 100644
--- a/base/shell/cmd/setlocal.c
+++ b/base/shell/cmd/setlocal.c
@@ -9,10 +9,13 @@
 
 #include "precomp.h"
 
+#include <direct.h> // For _getdrive().
+
 typedef struct _SETLOCAL
 {
     struct _SETLOCAL *Prev;
     LPTSTR Environment;
+    INT CurDrive;
     BOOL EnableExtensions;
     BOOL DelayedExpansion;
 } SETLOCAL, *PSETLOCAL;
@@ -42,6 +45,13 @@ INT cmd_setlocal(LPTSTR param)
     LPTSTR* arg;
     INT argc, i;
 
+    if (!_tcscmp(param, _T("/?")))
+    {
+        // FIXME
+        ConOutPuts(_T("SETLOCAL help not implemented yet!\n"));
+        return 0;
+    }
+
     /* SETLOCAL only works inside a batch context */
     if (!bc)
         return 0;
@@ -53,6 +63,7 @@ INT cmd_setlocal(LPTSTR param)
         error_out_of_memory();
         return 1;
     }
+
     Saved->Environment = DuplicateEnvironment();
     if (!Saved->Environment)
     {
@@ -60,6 +71,12 @@ INT cmd_setlocal(LPTSTR param)
         cmd_free(Saved);
         return 1;
     }
+    /*
+     * Save the current drive; the duplicated environment
+     * contains the corresponding current directory.
+     */
+    Saved->CurDrive = _getdrive();
+
     Saved->EnableExtensions = bEnableExtensions;
     Saved->DelayedExpansion = bDelayedExpansion;
 
@@ -94,9 +111,15 @@ INT cmd_endlocal(LPTSTR param)
 {
     LPTSTR Environ, Name, Value;
     PSETLOCAL Saved;
+    TCHAR drvEnvVar[] = _T("=?:");
+    TCHAR szCurrent[MAX_PATH];
 
-    /* ENDLOCAL doesn't take any params */
-    UNREFERENCED_PARAMETER(param);
+    if (!_tcscmp(param, _T("/?")))
+    {
+        // FIXME
+        ConOutPuts(_T("ENDLOCAL help not implemented yet!\n"));
+        return 0;
+    }
 
     /* Pop a SETLOCAL struct off of this batch context's stack */
     if (!bc || !(Saved = bc->setlocal))
@@ -133,6 +156,14 @@ INT cmd_endlocal(LPTSTR param)
         Name = Value;
     }
 
+    /* Restore the current drive and its current directory from the 
environment */
+    drvEnvVar[1] = _T('A') + Saved->CurDrive - 1;
+    if (!GetEnvironmentVariable(drvEnvVar, szCurrent, ARRAYSIZE(szCurrent)))
+    {
+        _stprintf(szCurrent, _T("%C:\\"), _T('A') + Saved->CurDrive - 1);
+    }
+    _tchdir(szCurrent); // SetRootPath(NULL, szCurrent);
+
     cmd_free(Saved->Environment);
     cmd_free(Saved);
     return 0;

Reply via email to