https://git.reactos.org/?p=reactos.git;a=commitdiff;h=1bd0e3f9f96e255a56e1c…
commit 1bd0e3f9f96e255a56e1c1d9f5c6e57c22878759
Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
AuthorDate: Sat Nov 27 21:03:55 2021 +0100
Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
CommitDate: Sun Nov 28 00:26:45 2021 +0100
[NTVDM] Retrieve the full directory of the current running NTVDM instance, to be used
as a base path for opening other NTVDM system files.
---
subsystems/mvdm/ntvdm/ntvdm.c | 52 +++++++++++++++++++++++++++++++++++++++++--
subsystems/mvdm/ntvdm/ntvdm.h | 10 +++++++++
2 files changed, 60 insertions(+), 2 deletions(-)
diff --git a/subsystems/mvdm/ntvdm/ntvdm.c b/subsystems/mvdm/ntvdm/ntvdm.c
index bedc20ea7ea..5214d81e7c8 100644
--- a/subsystems/mvdm/ntvdm/ntvdm.c
+++ b/subsystems/mvdm/ntvdm/ntvdm.c
@@ -31,6 +31,10 @@ NTVDM_SETTINGS GlobalSettings;
INT NtVdmArgc;
WCHAR** NtVdmArgv;
+/* Full directory where NTVDM resides, or the SystemRoot\System32 path */
+WCHAR NtVdmPath[MAX_PATH];
+ULONG NtVdmPathSize; // Length without NULL terminator.
+
/* PRIVATE FUNCTIONS **********************************************************/
static NTSTATUS
@@ -476,6 +480,8 @@ PrintMessageAnsi(IN CHAR_PRINT CharPrint,
INT
wmain(INT argc, WCHAR *argv[])
{
+ BOOL Success;
+
#ifdef STANDALONE
if (argc < 2)
@@ -531,20 +537,62 @@ wmain(INT argc, WCHAR *argv[])
"\n\n",
GetCommandLineA());
+ /*
+ * Retrieve the full directory of the current running NTVDM instance.
+ * In case of failure, use the default SystemRoot\System32 path.
+ */
+ NtVdmPathSize = GetModuleFileNameW(NULL, NtVdmPath, _countof(NtVdmPath));
+ NtVdmPath[_countof(NtVdmPath) - 1] = UNICODE_NULL; // Ensure NULL-termination (see
WinXP bug)
+
+ Success = ((NtVdmPathSize != 0) && (NtVdmPathSize < _countof(NtVdmPath))
&&
+ (GetLastError() != ERROR_INSUFFICIENT_BUFFER));
+ if (Success)
+ {
+ /* Find the last path separator, remove it as well as the file name */
+ PWCHAR pch = wcsrchr(NtVdmPath, L'\\');
+ if (pch)
+ *pch = UNICODE_NULL;
+ }
+ else
+ {
+ /* We failed, use the default SystemRoot\System32 path */
+ NtVdmPathSize = GetSystemDirectoryW(NtVdmPath, _countof(NtVdmPath));
+ Success = ((NtVdmPathSize != 0) && (NtVdmPathSize <
_countof(NtVdmPath)));
+ if (!Success)
+ {
+ /* We failed again, try to do it ourselves */
+ NtVdmPathSize = (ULONG)wcslen(SharedUserData->NtSystemRoot) +
_countof("\\System32") - 1;
+ Success = (NtVdmPathSize < _countof(NtVdmPath));
+ if (Success)
+ {
+ Success = NT_SUCCESS(RtlStringCchPrintfW(NtVdmPath,
+ _countof(NtVdmPath),
+ L"%s\\System32",
+
SharedUserData->NtSystemRoot));
+ }
+ if (!Success)
+ {
+ wprintf(L"FATAL: Could not retrieve NTVDM path.\n");
+ goto Cleanup;
+ }
+ }
+ }
+ NtVdmPathSize = (ULONG)wcslen(NtVdmPath);
+
/* Load the global VDM settings */
LoadGlobalSettings(&GlobalSettings);
/* Initialize the console */
if (!ConsoleInit())
{
- wprintf(L"FATAL: A problem occurred when trying to initialize the
console\n");
+ wprintf(L"FATAL: A problem occurred when trying to initialize the
console.\n");
goto Cleanup;
}
/* Initialize the emulator */
if (!EmulatorInitialize(ConsoleInput, ConsoleOutput))
{
- wprintf(L"FATAL: Failed to initialize the emulator\n");
+ wprintf(L"FATAL: Failed to initialize the emulator.\n");
goto Cleanup;
}
diff --git a/subsystems/mvdm/ntvdm/ntvdm.h b/subsystems/mvdm/ntvdm/ntvdm.h
index 2b006c06c39..b3876fb9a98 100644
--- a/subsystems/mvdm/ntvdm/ntvdm.h
+++ b/subsystems/mvdm/ntvdm/ntvdm.h
@@ -40,6 +40,10 @@
#include <stdarg.h>
#include <wchar.h>
+#ifndef _countof
+#define _countof(_Array) (sizeof(_Array) / sizeof(_Array[0]))
+#endif
+
/* PSDK/NDK Headers */
#define WIN32_NO_STATUS
#include <windef.h>
@@ -67,6 +71,8 @@ DWORD WINAPI SetLastConsoleEventActive(VOID);
/* PSEH for SEH Support */
#include <pseh/pseh2.h>
+#include <ntstrsafe.h>
+
/* VARIABLES ******************************************************************/
@@ -84,6 +90,10 @@ extern NTVDM_SETTINGS GlobalSettings;
extern INT NtVdmArgc;
extern WCHAR** NtVdmArgv;
+/* Full directory where NTVDM resides, or the SystemRoot\System32 path */
+extern WCHAR NtVdmPath[MAX_PATH];
+extern ULONG NtVdmPathSize; // Length without NULL terminator.
+
extern HWND hConsoleWnd;