[RUNAS] Pass the current directory to CreateProcessWithLogonW and handle errors
authorEric Kohl <eric.kohl@reactos.org>
Mon, 21 Feb 2022 10:12:50 +0000 (11:12 +0100)
committerEric Kohl <eric.kohl@reactos.org>
Mon, 21 Feb 2022 10:12:50 +0000 (11:12 +0100)
base/applications/runas/lang/de-DE.rc
base/applications/runas/lang/en-US.rc
base/applications/runas/resource.h
base/applications/runas/runas.c

index c9e3e15..7bba0d9 100644 (file)
@@ -13,11 +13,15 @@ BEGIN
     IDS_USAGE09 "   /profile        Legt fest, dass das Benutzerprofil geladen werden soll.\n"
     IDS_USAGE10 "                   Dies ist die Standardeinstellung.\n" 
     IDS_USAGE11 "   /env            Verwendet die aktuelle Umgebung statt der des Benutzers.\n"
-    IDS_USAGE12 "   /user           <Benutzername> muss in der Form Benutzer@Domäne oder\n                   Domäne\\Benutzer angegeben werden\n"
-    IDS_USAGE13 "   Programm        Befehlszeile einer ausführbaren Datei. Siehe unten\n                   aufgeführte Beispiele.\n\n"
+    IDS_USAGE12 "   /netonly        Noch nicht implementiert.\n"
+    IDS_USAGE13 "   /savecred       Noch nicht implementiert.\n"
+    IDS_USAGE14 "   /smartcard      Noch nicht implementiert.\n"
+    IDS_USAGE15 "   /user           <Benutzername> muss in der Form Benutzer@Domäne oder\n                   Domäne\\Benutzer angegeben werden\n"
+    IDS_USAGE16 "   Programm        Befehlszeile einer ausführbaren Datei. Siehe unten\n                   aufgeführte Beispiele.\n\n"
 
     IDS_START     "Es wird versucht, %s als Benutzer ""%s\\%s"" zu starten...\n"
     IDS_RUN_ERROR "RUNAS-FEHLER: %s kann nicht ausgeführt werden\n"
+    IDS_INTERNAL_ERROR "RUNAS-FEHLER: Interner Fehler %ld\n"
 
     IDS_PASSWORD "Geben Sie das Kennwort für ""%s\\%s"" ein: "
 END
index f3f478b..b067137 100644 (file)
@@ -13,11 +13,15 @@ BEGIN
     IDS_USAGE09 "   /profile        specifies that the user's profile should be loaded.\n"
     IDS_USAGE10 "                   This is the default.\n" 
     IDS_USAGE11 "   /env            to use current environment instead of user's.\n"
-    IDS_USAGE12 "   /user           <UserName> should be in form USER@DOMAIN or DOMAIN\\USER\n"
-    IDS_USAGE13 "   program         command line for EXE.  See below for examples\n\n"
+    IDS_USAGE12 "   /netonly        Not implemented yet.\n"
+    IDS_USAGE13 "   /savecred       Not implemented yet.\n"
+    IDS_USAGE14 "   /smartcard      Not implemented yet.\n"
+    IDS_USAGE15 "   /user           <UserName> should be in form USER@DOMAIN or DOMAIN\\USER\n"
+    IDS_USAGE16 "   program         command line for EXE.  See below for examples\n\n"
 
     IDS_START     "Attempting to start %s as user ""%s\\%s""...\n"
     IDS_RUN_ERROR "RUNAS ERROR: Unable to run %s\n"
+    IDS_INTERNAL_ERROR "RUNAS ERROR: Internal error %ld\n"
 
     IDS_PASSWORD  "Enter the password for ""%s\\%s"": "
 END
index a228846..e0f9205 100644 (file)
 #define IDS_USAGE11   7010
 #define IDS_USAGE12   7011
 #define IDS_USAGE13   7012
-#define IDS_USAGE_MAX IDS_USAGE13
+#define IDS_USAGE14   7013
+#define IDS_USAGE15   7014
+#define IDS_USAGE16   7015
+#define IDS_USAGE_MAX IDS_USAGE16
 
 #define IDS_START     7100
 #define IDS_RUN_ERROR 7101
+#define IDS_INTERNAL_ERROR 7102
 #define IDS_PASSWORD  7500
index 8adbe8d..316b547 100644 (file)
@@ -85,10 +85,13 @@ wmain(
     PWSTR pszDomain = NULL;
     PWSTR pszCommandLine = NULL;
     PWSTR pszPassword = NULL;
+    PWSTR pszCurrentDirectory = NULL;
+    PWSTR pszEnvironment = NULL;
     PWSTR ptr;
     STARTUPINFOW StartupInfo;
     PROCESS_INFORMATION ProcessInfo;
     DWORD dwLogonFlags = 0;
+    DWORD dwCreateFlags = 0;
     BOOL rc;
 
     /* Initialize the Console Standard Streams */
@@ -112,6 +115,8 @@ wmain(
             if (wcscmp(pszArg, L"?") == 0)
             {
                 Usage();
+                result = 0;
+                goto done;
             }
             else if (wcsicmp(pszArg, L"profile") == 0)
             {
@@ -133,13 +138,25 @@ wmain(
                 {
                     /* User@Domain */
                     pszUserName = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, ((ptr - pszArg) + 1) * sizeof(WCHAR));
-                    if (pszUserName)
-                        wcsncpy(pszUserName, pszArg, (ptr - pszArg));
+                    if (pszUserName == NULL)
+                    {
+                        ConResPrintf(StdOut, IDS_INTERNAL_ERROR, ERROR_OUTOFMEMORY);
+                        result = -1;
+                        goto done;
+                    }
+
+                    wcsncpy(pszUserName, pszArg, (ptr - pszArg));
 
                     ptr++;
                     pszDomain = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (wcslen(ptr) + 1) * sizeof(WCHAR));
-                    if (pszDomain)
-                        wcscpy(pszDomain, ptr);
+                    if (pszDomain == NULL)
+                    {
+                        ConResPrintf(StdOut, IDS_INTERNAL_ERROR, ERROR_OUTOFMEMORY);
+                        result = -1;
+                        goto done;
+                    }
+
+                    wcscpy(pszDomain, ptr);
                 }
                 else
                 {
@@ -148,19 +165,37 @@ wmain(
                     {
                         /* Domain\User */
                         pszUserName = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (wcslen(ptr + 1) + 1)* sizeof(WCHAR));
-                        if (pszUserName)
-                            wcscpy(pszUserName, (ptr + 1));
+                        if (pszUserName == NULL)
+                        {
+                            ConResPrintf(StdOut, IDS_INTERNAL_ERROR, ERROR_OUTOFMEMORY);
+                            result = -1;
+                            goto done;
+                        }
+
+                        wcscpy(pszUserName, (ptr + 1));
 
                         pszDomain = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, ((ptr - pszArg) + 1) * sizeof(WCHAR));
-                        if (pszDomain)
-                            wcsncpy(pszDomain, pszArg, (ptr - pszArg));
+                        if (pszDomain == NULL)
+                        {
+                            ConResPrintf(StdOut, IDS_INTERNAL_ERROR, ERROR_OUTOFMEMORY);
+                            result = -1;
+                            goto done;
+                        }
+
+                        wcsncpy(pszDomain, pszArg, (ptr - pszArg));
                     }
                     else
                     {
                         /* User */
                         pszUserName = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (wcslen(pszArg) + 1) * sizeof(WCHAR));
-                        if (pszUserName)
-                            wcscpy(pszUserName, pszArg);
+                        if (pszUserName == NULL)
+                        {
+                            ConResPrintf(StdOut, IDS_INTERNAL_ERROR, ERROR_OUTOFMEMORY);
+                            result = -1;
+                            goto done;
+                        }
+
+                        wcscpy(pszUserName, pszArg);
                     }
                 }
             }
@@ -168,6 +203,7 @@ wmain(
             {
                 Usage();
                 result = -1;
+                goto done;
             }
         }
         else
@@ -175,8 +211,14 @@ wmain(
             if (pszCommandLine == NULL)
             {
                 pszCommandLine = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (wcslen(pszArg) + 1) * sizeof(WCHAR));
-                if (pszCommandLine != NULL)
-                    wcscpy(pszCommandLine, pszArg);
+                if (pszCommandLine == NULL)
+                {
+                    ConResPrintf(StdOut, IDS_INTERNAL_ERROR, ERROR_OUTOFMEMORY);
+                    result = -1;
+                    goto done;
+                }
+
+                wcscpy(pszCommandLine, pszArg);
                 break;
             }
         }
@@ -195,11 +237,6 @@ wmain(
     if (bNoProfile)
         dwLogonFlags &= ~LOGON_WITH_PROFILE;
 
-    if (bEnv)
-    {
-        DPRINT("env\n");
-    }
-
     DPRINT("User: %S\n", pszUserName);
     DPRINT("Domain: %S\n", pszDomain);
     DPRINT("CommandLine: %S\n", pszCommandLine);
@@ -208,11 +245,38 @@ wmain(
     {
         DWORD dwLength = MAX_COMPUTERNAME_LENGTH + 1;
         pszDomain = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwLength * sizeof(WCHAR));
-        if (pszDomain)
-            GetComputerNameW(pszDomain, &dwLength);
+        if (pszDomain == NULL)
+        {
+            ConResPrintf(StdOut, IDS_INTERNAL_ERROR, ERROR_OUTOFMEMORY);
+            result = -1;
+            goto done;
+        }
+
+        GetComputerNameW(pszDomain, &dwLength);
+    }
+
+    if (bEnv)
+    {
+        pszEnvironment = GetEnvironmentStringsW();
+        pszCurrentDirectory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (MAX_PATH + 1) * sizeof(WCHAR));
+        if (pszCurrentDirectory == NULL)
+        {
+            ConResPrintf(StdOut, IDS_INTERNAL_ERROR, ERROR_OUTOFMEMORY);
+            result = -1;
+            goto done;
+        }
+
+        GetCurrentDirectory(MAX_PATH + 1, pszCurrentDirectory);
+        dwCreateFlags |= CREATE_UNICODE_ENVIRONMENT;
     }
 
     pszPassword = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (MAX_PASSWORD_LENGTH + 1) * sizeof(WCHAR));
+    if (pszPassword == NULL)
+    {
+        ConResPrintf(StdOut, IDS_INTERNAL_ERROR, ERROR_OUTOFMEMORY);
+        result = -1;
+        goto done;
+    }
 
     /* Query the password */
     ConResPrintf(StdOut, IDS_PASSWORD, pszDomain, pszUserName);
@@ -225,17 +289,17 @@ wmain(
                                  pszDomain,
                                  pszPassword,
                                  dwLogonFlags,
-                                 NULL,      //[in, optional]      LPCWSTR               lpApplicationName,
+                                 NULL,
                                  pszCommandLine,
-                                 0,         //[in]                DWORD                 dwCreationFlags,
-                                 bEnv ? GetEnvironmentStringsW() : NULL,
-                                 NULL,      //[in, optional]      LPCWSTR               lpCurrentDirectory,
+                                 dwCreateFlags,
+                                 pszEnvironment,
+                                 pszCurrentDirectory,
                                  &StartupInfo,
                                  &ProcessInfo);
     if (rc == FALSE)
     {
         ConResPrintf(StdOut, IDS_RUN_ERROR, pszCommandLine);
-        ConPrintf(StdOut, L"Error: %lu\n", GetLastError());
+        ConPrintf(StdOut, L"%lu\n", GetLastError());
     }
 
 done:
@@ -248,6 +312,11 @@ done:
     if (pszPassword)
         HeapFree(GetProcessHeap(), 0, pszPassword);
 
+    /* NOTE: Do NOT free pszEnvironment */
+
+    if (pszCurrentDirectory)
+        HeapFree(GetProcessHeap(), 0, pszCurrentDirectory);
+
     if (pszCommandLine)
         HeapFree(GetProcessHeap(), 0, pszCommandLine);