mirror of
https://github.com/reactos/reactos.git
synced 2024-12-27 09:34:43 +00:00
[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.
This commit is contained in:
parent
e0a272c95b
commit
2693a26e3e
2 changed files with 93 additions and 33 deletions
|
@ -22,6 +22,8 @@
|
||||||
|
|
||||||
/* PRIVATE VARIABLES **********************************************************/
|
/* PRIVATE VARIABLES **********************************************************/
|
||||||
|
|
||||||
|
#define CMOS_RAM_FILE "cmos.ram"
|
||||||
|
|
||||||
static HANDLE hCmosRam = INVALID_HANDLE_VALUE;
|
static HANDLE hCmosRam = INVALID_HANDLE_VALUE;
|
||||||
static CMOS_MEMORY CmosMemory;
|
static CMOS_MEMORY CmosMemory;
|
||||||
|
|
||||||
|
@ -438,41 +440,88 @@ BOOLEAN IsNmiEnabled(VOID)
|
||||||
return NmiEnabled;
|
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)
|
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);
|
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 */
|
/* Clear the CMOS memory */
|
||||||
RtlZeroMemory(&CmosMemory, sizeof(CmosMemory));
|
RtlZeroMemory(&CmosMemory, sizeof(CmosMemory));
|
||||||
|
|
||||||
/* Always open (and if needed, create) a RAM file with shared access */
|
/* Load the file only if it already existed and was opened, not newly created */
|
||||||
SetLastError(0); // For debugging purposes
|
if (Success)
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
BOOL Success;
|
if ((GetLastError() == ERROR_ALREADY_EXISTS) /* || (GetLastError() == ERROR_FILE_EXISTS) */)
|
||||||
|
|
||||||
/* 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))
|
|
||||||
{
|
{
|
||||||
/* Bad CMOS RAM file. Reinitialize the CMOS memory. */
|
/* Attempt to load the CMOS memory from the RAM file */
|
||||||
DPRINT1("Invalid CMOS file, read bytes %u, expected bytes %u\n", CmosSize, sizeof(CmosMemory));
|
DWORD CmosSize = sizeof(CmosMemory);
|
||||||
RtlZeroMemory(&CmosMemory, 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
|
||||||
|
{
|
||||||
|
/* 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);
|
SetFilePointer(hCmosRam, 0, NULL, FILE_BEGIN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -518,19 +567,25 @@ VOID CmosInitialize(VOID)
|
||||||
|
|
||||||
VOID CmosCleanup(VOID)
|
VOID CmosCleanup(VOID)
|
||||||
{
|
{
|
||||||
DWORD CmosSize = sizeof(CmosMemory);
|
|
||||||
|
|
||||||
if (hCmosRam == INVALID_HANDLE_VALUE) return;
|
|
||||||
|
|
||||||
DestroyHardwareTimer(PeriodicTimer);
|
DestroyHardwareTimer(PeriodicTimer);
|
||||||
DestroyHardwareTimer(ClockTimer);
|
DestroyHardwareTimer(ClockTimer);
|
||||||
|
|
||||||
/* Flush the CMOS memory back to the RAM file and close it */
|
if (hCmosRam != INVALID_HANDLE_VALUE)
|
||||||
SetFilePointer(hCmosRam, 0, NULL, FILE_BEGIN);
|
{
|
||||||
WriteFile(hCmosRam, &CmosMemory, CmosSize, &CmosSize, NULL);
|
/* Flush the CMOS memory back to the RAM file and close it */
|
||||||
|
BOOL Success;
|
||||||
|
DWORD CmosSize = sizeof(CmosMemory);
|
||||||
|
|
||||||
CloseHandle(hCmosRam);
|
Success = CmosWriteFile(hCmosRam, &CmosMemory, CmosSize, &CmosSize);
|
||||||
hCmosRam = INVALID_HANDLE_VALUE;
|
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 */
|
/* EOF */
|
||||||
|
|
|
@ -44,6 +44,11 @@
|
||||||
#define _countof(_Array) (sizeof(_Array) / sizeof(_Array[0]))
|
#define _countof(_Array) (sizeof(_Array) / sizeof(_Array[0]))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* String widening macro */
|
||||||
|
#define __L(x) L ## x
|
||||||
|
#define _L(x) __L(x)
|
||||||
|
#define L(x) _L(x)
|
||||||
|
|
||||||
/* PSDK/NDK Headers */
|
/* PSDK/NDK Headers */
|
||||||
#define WIN32_NO_STATUS
|
#define WIN32_NO_STATUS
|
||||||
#include <windef.h>
|
#include <windef.h>
|
||||||
|
|
Loading…
Reference in a new issue