https://git.reactos.org/?p=reactos.git;a=commitdiff;h=5811da1ec5c7fe377e28d…
commit 5811da1ec5c7fe377e28dc207b250d771fade5e3
Author: Eric Kohl <eric.kohl(a)reactos.org>
AuthorDate: Sun Feb 13 21:45:10 2022 +0100
Commit: Eric Kohl <eric.kohl(a)reactos.org>
CommitDate: Sun Feb 13 21:45:10 2022 +0100
[RUNAS] Initial version of the runas utility
- Work in progress
- Please do not translate it yet because the resources will change significantly
---
base/applications/CMakeLists.txt | 1 +
base/applications/runas/CMakeLists.txt | 8 ++
base/applications/runas/lang/de-DE.rc | 12 ++
base/applications/runas/lang/en-US.rc | 12 ++
base/applications/runas/resource.h | 7 ++
base/applications/runas/runas.c | 210 +++++++++++++++++++++++++++++++++
base/applications/runas/runas.rc | 24 ++++
7 files changed, 274 insertions(+)
diff --git a/base/applications/CMakeLists.txt b/base/applications/CMakeLists.txt
index 7c18212ed4f..c363430f0cb 100644
--- a/base/applications/CMakeLists.txt
+++ b/base/applications/CMakeLists.txt
@@ -33,6 +33,7 @@ add_subdirectory(rapps)
add_subdirectory(rapps_com)
add_subdirectory(regedit)
add_subdirectory(regedt32)
+add_subdirectory(runas)
add_subdirectory(sc)
add_subdirectory(screensavers)
add_subdirectory(sdbinst)
diff --git a/base/applications/runas/CMakeLists.txt
b/base/applications/runas/CMakeLists.txt
new file mode 100644
index 00000000000..0bc636230f3
--- /dev/null
+++ b/base/applications/runas/CMakeLists.txt
@@ -0,0 +1,8 @@
+
+include_directories(${REACTOS_SOURCE_DIR}/sdk/lib/conutils)
+
+add_executable(runas runas.c runas.rc)
+set_module_type(runas win32cui UNICODE)
+target_link_libraries(runas conutils ${PSEH_LIB})
+add_importlibs(runas advapi32 msvcrt kernel32 ntdll)
+add_cd_file(TARGET runas DESTINATION reactos/system32 FOR all)
diff --git a/base/applications/runas/lang/de-DE.rc
b/base/applications/runas/lang/de-DE.rc
new file mode 100644
index 00000000000..53f50974495
--- /dev/null
+++ b/base/applications/runas/lang/de-DE.rc
@@ -0,0 +1,12 @@
+LANGUAGE LANG_GERMAN, SUBLANG_NEUTRAL
+
+STRINGTABLE
+BEGIN
+ IDS_USAGE01 "Syntax für RUNAS:\n\n"
+ IDS_USAGE02 "RUNAS [ [/noprofile | /profile] [/env] [/savecred | /netonly]
]\n"
+ IDS_USAGE03 " /user:<Benutzername> Programm\n\n"
+ IDS_USAGE04 "RUNAS [ [/noprofile | /profile] [/env] [/savecred | /netonly]
]\n"
+ IDS_USAGE05 " /smartcard [/user:<Benutzername>] Programm\n\n"
+ IDS_USAGE06 "/noprofile"
+ IDS_USAGE07 "/profile"
+END
diff --git a/base/applications/runas/lang/en-US.rc
b/base/applications/runas/lang/en-US.rc
new file mode 100644
index 00000000000..815319ea936
--- /dev/null
+++ b/base/applications/runas/lang/en-US.rc
@@ -0,0 +1,12 @@
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+
+STRINGTABLE
+BEGIN
+ IDS_USAGE01 "RUNAS USAGE\n\n"
+ IDS_USAGE02 "RUNAS [ [/noprofile | /profile] [/env] [/savecred | /netonly]
]\n"
+ IDS_USAGE03 " /user:<UserName> program\n\n"
+ IDS_USAGE04 "RUNAS [ [/noprofile | /profile] [/env] [/savecred | /netonly]
]\n"
+ IDS_USAGE05 " /smartcard [/user:<UserName>] program\n\n"
+ IDS_USAGE06 "/noprofile"
+ IDS_USAGE07 "/profile"
+END
diff --git a/base/applications/runas/resource.h b/base/applications/runas/resource.h
new file mode 100644
index 00000000000..11ad5ad8fa3
--- /dev/null
+++ b/base/applications/runas/resource.h
@@ -0,0 +1,7 @@
+#define IDS_USAGE01 7000
+#define IDS_USAGE02 7001
+#define IDS_USAGE03 7002
+#define IDS_USAGE04 7003
+#define IDS_USAGE05 7004
+#define IDS_USAGE06 7005
+#define IDS_USAGE07 7006
diff --git a/base/applications/runas/runas.c b/base/applications/runas/runas.c
new file mode 100644
index 00000000000..581f24e2d00
--- /dev/null
+++ b/base/applications/runas/runas.c
@@ -0,0 +1,210 @@
+/*
+ * PROJECT: ReactOS runas utility
+ * LICENSE: GPL - See COPYING in the top level directory
+ * FILE: base/applications/runas/runas.c
+ * COPYRIGHT: Copyright 2022 Eric Kohl <eric.kohl(a)reactos.org>
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <stdarg.h>
+
+#define WIN32_NO_STATUS
+#include <windef.h>
+#include <winbase.h>
+#include <winnls.h>
+#include <wincon.h>
+#include <winsvc.h>
+#include <conutils.h>
+
+#include "resource.h"
+
+#define NDEBUG
+#include <debug.h>
+
+static
+void
+Usage(void)
+{
+ ConResPuts(StdOut, IDS_USAGE01);
+ ConResPuts(StdOut, IDS_USAGE02);
+ ConResPuts(StdOut, IDS_USAGE03);
+ ConResPuts(StdOut, IDS_USAGE04);
+ ConResPuts(StdOut, IDS_USAGE05);
+ ConResPuts(StdOut, IDS_USAGE06);
+ ConResPuts(StdOut, IDS_USAGE07);
+}
+
+
+int
+wmain(
+ int argc,
+ LPCWSTR argv[])
+{
+ LPCWSTR pszArg;
+ int i, result = 0;
+ BOOL bProfile = FALSE, bNoProfile = FALSE;
+ BOOL bEnv = FALSE;
+ PWSTR pszUserName = NULL;
+ PWSTR pszDomain = NULL;
+ PWSTR pszCommandLine = NULL;
+ PWSTR pszPassword = NULL;
+ PWSTR ptr;
+ STARTUPINFOW StartupInfo;
+ PROCESS_INFORMATION ProcessInfo;
+ DWORD dwLogonFlags = 0;
+ BOOL rc;
+
+ /* Initialize the Console Standard Streams */
+ ConInitStdStreams();
+
+ if (argc == 1)
+ {
+ Usage();
+ return 0;
+ }
+
+ ZeroMemory(&StartupInfo, sizeof(StartupInfo));
+ ZeroMemory(&ProcessInfo, sizeof(ProcessInfo));
+
+ for (i = 1; i < argc; i++)
+ {
+ pszArg = argv[i];
+ if (*pszArg == L'-' || *pszArg == L'/')
+ {
+ pszArg++;
+ if (wcscmp(pszArg, L"?") == 0)
+ {
+ Usage();
+ }
+ else if (wcsicmp(pszArg, L"profile") == 0)
+ {
+ bProfile = TRUE;
+ }
+ else if (wcsicmp(pszArg, L"noprofile") == 0)
+ {
+ bNoProfile = TRUE;
+ }
+ else if (wcsicmp(pszArg, L"env") == 0)
+ {
+ bEnv = TRUE;
+ }
+ else if (_wcsnicmp(pszArg, L"user:", 5) == 0)
+ {
+ pszArg += 5;
+ ptr = wcschr(pszArg, L'@');
+ if (ptr != NULL)
+ {
+ /* User@Domain */
+ pszUserName = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, ((ptr -
pszArg) + 1) * sizeof(WCHAR));
+ if (pszUserName)
+ wcsncpy(pszUserName, pszArg, (ptr - pszArg));
+
+ ptr++;
+ pszDomain = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
(wcslen(ptr) + 1) * sizeof(WCHAR));
+ if (pszDomain)
+ wcscpy(pszDomain, ptr);
+ }
+ else
+ {
+ ptr = wcschr(pszArg, L'\\');
+ if (ptr != NULL)
+ {
+ /* Domain\User */
+ pszUserName = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
(wcslen(ptr + 1) + 1)* sizeof(WCHAR));
+ if (pszUserName)
+ wcscpy(pszUserName, (ptr + 1));
+
+ pszDomain = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, ((ptr -
pszArg) + 1) * sizeof(WCHAR));
+ if (pszDomain)
+ wcsncpy(pszDomain, pszArg, (ptr - pszArg));
+ }
+ else
+ {
+ /* User */
+ pszUserName = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
(wcslen(pszArg) + 1) * sizeof(WCHAR));
+ if (pszUserName)
+ wcscpy(pszUserName, pszArg);
+ }
+ }
+ }
+ else
+ {
+ Usage();
+ result = -1;
+ }
+ }
+ else
+ {
+ if (pszCommandLine == NULL)
+ {
+ pszCommandLine = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
(wcslen(pszArg) + 1) * sizeof(WCHAR));
+ if (pszCommandLine != NULL)
+ wcscpy(pszCommandLine, pszArg);
+ break;
+ }
+ }
+ }
+
+ if (bProfile && bNoProfile)
+ {
+ Usage();
+ result = -1;
+ goto done;
+ }
+
+ if (bProfile)
+ dwLogonFlags |= LOGON_WITH_PROFILE;
+
+ 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);
+
+ /* FIXME: Query the password: */
+
+ rc = CreateProcessWithLogonW(pszUserName,
+ pszDomain,
+ pszPassword,
+ dwLogonFlags,
+ NULL, //[in, optional] LPCWSTR
lpApplicationName,
+ pszCommandLine,
+ 0, //[in] DWORD
dwCreationFlags,
+ bEnv ? GetEnvironmentStringsW() : NULL,
+ NULL, //[in, optional] LPCWSTR
lpCurrentDirectory,
+ &StartupInfo,
+ &ProcessInfo);
+ if (rc == FALSE)
+ {
+ DPRINT("Error: %lu\n", GetLastError());
+ }
+
+done:
+ if (ProcessInfo.hThread)
+ CloseHandle(ProcessInfo.hThread);
+
+ if (ProcessInfo.hProcess)
+ CloseHandle(ProcessInfo.hProcess);
+
+ if (pszPassword)
+ HeapFree(GetProcessHeap(), 0, pszPassword);
+
+ if (pszCommandLine)
+ HeapFree(GetProcessHeap(), 0, pszCommandLine);
+
+ if (pszUserName)
+ HeapFree(GetProcessHeap(), 0, pszUserName);
+
+ if (pszDomain)
+ HeapFree(GetProcessHeap(), 0, pszDomain);
+
+ return result;
+}
diff --git a/base/applications/runas/runas.rc b/base/applications/runas/runas.rc
new file mode 100644
index 00000000000..ebf9f255cd9
--- /dev/null
+++ b/base/applications/runas/runas.rc
@@ -0,0 +1,24 @@
+#include <windef.h>
+#include <winuser.h>
+
+#include "resource.h"
+
+/* Define language neutral resources */
+LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
+
+#define REACTOS_STR_FILE_DESCRIPTION "Run As Utility"
+#define REACTOS_STR_INTERNAL_NAME "runas"
+#define REACTOS_STR_ORIGINAL_FILENAME "runas.exe"
+#include <reactos/version.rc>
+
+#include <reactos/manifest_exe.rc>
+
+/* UTF-8 */
+#pragma code_page(65001)
+
+#ifdef LANGUAGE_DE_DE
+ #include "lang/de-DE.rc"
+#endif
+#ifdef LANGUAGE_EN_US
+ #include "lang/en-US.rc"
+#endif