https://git.reactos.org/?p=reactos.git;a=commitdiff;h=2693a26e3e9ae7cf22b96…
commit 2693a26e3e9ae7cf22b96da7391612df80b14be7
Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
AuthorDate: Fri Nov 26 20:13:58 2021 +0100
Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
CommitDate: Sun Nov 28 00:26:46 2021 +0100
[NTVDM] Create the CMOS ram file in NTVDM's own directory, instead of in whatever
current directory we are running.
This fixes the age-long annoyance that wherever you ran a DOS program
with NTVDM, its cmos.ram file would be created in the same current
directory the DOS program was being started.
This created at least two problems:
- useless pollution of directories with cmos.ram files;
- for installers, e.g. of Turbo C 1.x that enumerate the install files
from their directories to be copied/extracted somewhere, the cmos.ram
file could then be enumerated along and cause the installation to
interrupt and/or fail.
Now the cmos.ram file is created in the same directory NTVDM resides
(usually in System32...).
Also, debug-print out only loading errors instead of successes as well.
---
subsystems/mvdm/ntvdm/hardware/cmos.c | 121 ++++++++++++++++++++++++----------
subsystems/mvdm/ntvdm/ntvdm.h | 5 ++
2 files changed, 93 insertions(+), 33 deletions(-)
diff --git a/subsystems/mvdm/ntvdm/hardware/cmos.c
b/subsystems/mvdm/ntvdm/hardware/cmos.c
index 8482553c08e..60abb6ffef9 100644
--- a/subsystems/mvdm/ntvdm/hardware/cmos.c
+++ b/subsystems/mvdm/ntvdm/hardware/cmos.c
@@ -22,6 +22,8 @@
/* PRIVATE VARIABLES **********************************************************/
+#define CMOS_RAM_FILE "cmos.ram"
+
static HANDLE hCmosRam = INVALID_HANDLE_VALUE;
static CMOS_MEMORY CmosMemory;
@@ -438,41 +440,88 @@ BOOLEAN IsNmiEnabled(VOID)
return NmiEnabled;
}
+static inline BOOL
+CmosWriteFile(
+ _In_ HANDLE FileHandle,
+ _In_ PVOID Buffer,
+ _In_ ULONG BufferSize,
+ _Out_opt_ PULONG BytesWritten)
+{
+ BOOL Success;
+ ULONG Written;
+
+ SetFilePointer(FileHandle, 0, NULL, FILE_BEGIN);
+ Success = WriteFile(FileHandle, Buffer, BufferSize, &Written, NULL);
+ if (BytesWritten)
+ *BytesWritten = (Success ? Written : 0);
+ return Success;
+}
+
VOID CmosInitialize(VOID)
{
- DWORD CmosSize = sizeof(CmosMemory);
+ BOOL Success;
+ WCHAR CmosPath[_countof(NtVdmPath) + _countof("\\" CMOS_RAM_FILE)];
- /* File must not be opened before */
+ /* CMOS file must not be opened before */
ASSERT(hCmosRam == INVALID_HANDLE_VALUE);
+ /* Always open (and if needed, create) a RAM file with shared access */
+ Success = NT_SUCCESS(RtlStringCbPrintfW(CmosPath,
+ sizeof(CmosPath),
+ L"%s\\" L(CMOS_RAM_FILE),
+ NtVdmPath));
+ if (!Success)
+ DPRINT1("Could not create CMOS file path!\n");
+
+ if (Success)
+ {
+ SetLastError(ERROR_SUCCESS);
+ hCmosRam = CreateFileW(CmosPath,
+ GENERIC_READ | GENERIC_WRITE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL,
+ OPEN_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+ Success = (hCmosRam != INVALID_HANDLE_VALUE);
+ if (!Success)
+ DPRINT1("CMOS opening failed (Error: %u)\n", GetLastError());
+ }
+
/* Clear the CMOS memory */
RtlZeroMemory(&CmosMemory, sizeof(CmosMemory));
- /* Always open (and if needed, create) a RAM file with shared access */
- SetLastError(0); // For debugging purposes
- hCmosRam = CreateFileW(L"cmos.ram",
- GENERIC_READ | GENERIC_WRITE,
- FILE_SHARE_READ | FILE_SHARE_WRITE,
- NULL,
- OPEN_ALWAYS,
- FILE_ATTRIBUTE_NORMAL,
- NULL);
- DPRINT1("CMOS opening %s (Error: %u)\n", hCmosRam != INVALID_HANDLE_VALUE ?
"succeeded" : "failed", GetLastError());
-
- if (hCmosRam != INVALID_HANDLE_VALUE)
+ /* Load the file only if it already existed and was opened, not newly created */
+ if (Success)
{
- BOOL Success;
-
- /* Attempt to fill the CMOS memory with the RAM file */
- SetLastError(0); // For debugging purposes
- Success = ReadFile(hCmosRam, &CmosMemory, CmosSize, &CmosSize, NULL);
- if (CmosSize != sizeof(CmosMemory))
+ if ((GetLastError() == ERROR_ALREADY_EXISTS) /* || (GetLastError() ==
ERROR_FILE_EXISTS) */)
+ {
+ /* Attempt to load the CMOS memory from the RAM file */
+ DWORD CmosSize = sizeof(CmosMemory);
+ Success = ReadFile(hCmosRam, &CmosMemory, CmosSize, &CmosSize,
NULL);
+ if (!Success)
+ {
+ DPRINT1("CMOS loading failed (Error: %u)\n", GetLastError());
+ }
+ else if (CmosSize != sizeof(CmosMemory))
+ {
+ /* Invalid CMOS RAM file; reinitialize the CMOS memory */
+ DPRINT1("Invalid CMOS file, read %u bytes, expected %u
bytes\n",
+ CmosSize, sizeof(CmosMemory));
+ Success = FALSE;
+ }
+ if (!Success)
+ {
+ /* Reset the CMOS memory and its RAM file */
+ RtlZeroMemory(&CmosMemory, sizeof(CmosMemory));
+ CmosWriteFile(hCmosRam, &CmosMemory, sizeof(CmosMemory), NULL);
+ }
+ }
+ else
{
- /* Bad CMOS RAM file. Reinitialize the CMOS memory. */
- DPRINT1("Invalid CMOS file, read bytes %u, expected bytes %u\n",
CmosSize, sizeof(CmosMemory));
- RtlZeroMemory(&CmosMemory, sizeof(CmosMemory));
+ /* Reset the CMOS RAM file */
+ CmosWriteFile(hCmosRam, &CmosMemory, sizeof(CmosMemory), NULL);
}
- DPRINT1("CMOS loading %s (Error: %u)\n", Success ?
"succeeded" : "failed", GetLastError());
SetFilePointer(hCmosRam, 0, NULL, FILE_BEGIN);
}
@@ -518,19 +567,25 @@ VOID CmosInitialize(VOID)
VOID CmosCleanup(VOID)
{
- DWORD CmosSize = sizeof(CmosMemory);
-
- if (hCmosRam == INVALID_HANDLE_VALUE) return;
-
DestroyHardwareTimer(PeriodicTimer);
DestroyHardwareTimer(ClockTimer);
- /* Flush the CMOS memory back to the RAM file and close it */
- SetFilePointer(hCmosRam, 0, NULL, FILE_BEGIN);
- WriteFile(hCmosRam, &CmosMemory, CmosSize, &CmosSize, NULL);
+ if (hCmosRam != INVALID_HANDLE_VALUE)
+ {
+ /* Flush the CMOS memory back to the RAM file and close it */
+ BOOL Success;
+ DWORD CmosSize = sizeof(CmosMemory);
- CloseHandle(hCmosRam);
- hCmosRam = INVALID_HANDLE_VALUE;
+ Success = CmosWriteFile(hCmosRam, &CmosMemory, CmosSize, &CmosSize);
+ if (!Success || (CmosSize != sizeof(CmosMemory)))
+ {
+ DPRINT1("CMOS saving failed (Error: %u), written %u bytes, expected %u
bytes\n",
+ GetLastError(), CmosSize, sizeof(CmosMemory));
+ }
+
+ CloseHandle(hCmosRam);
+ hCmosRam = INVALID_HANDLE_VALUE;
+ }
}
/* EOF */
diff --git a/subsystems/mvdm/ntvdm/ntvdm.h b/subsystems/mvdm/ntvdm/ntvdm.h
index b3876fb9a98..1c99f2a0011 100644
--- a/subsystems/mvdm/ntvdm/ntvdm.h
+++ b/subsystems/mvdm/ntvdm/ntvdm.h
@@ -44,6 +44,11 @@
#define _countof(_Array) (sizeof(_Array) / sizeof(_Array[0]))
#endif
+/* String widening macro */
+#define __L(x) L ## x
+#define _L(x) __L(x)
+#define L(x) _L(x)
+
/* PSDK/NDK Headers */
#define WIN32_NO_STATUS
#include <windef.h>