-/* $Id: ntvdm.c,v 1.1 2002/10/28 13:59:59 robd Exp $
- *
+/* $Id$
+ *
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
- * FILE: subsys/ntvdm/ntvdm.c
+ * FILE: subsys/ntvdm/ntvdm->c
* PURPOSE: Virtual DOS Machine
* PROGRAMMER: Robert Dickenson (robd@mok.lvcm.com)
* UPDATE HISTORY:
*/
/* INCLUDES *****************************************************************/
-
-#include <ntos.h>
+#define WIN32_NO_STATUS
#include <windows.h>
#include <stdio.h>
#include <wchar.h>
+#include "resource.h"
+
+#define NTOS_MODE_USER
+#include <ndk/ntndk.h>
#define NDEBUG
#include <debug.h>
vsprintf(buffer, fmt, ap);
va_end(ap);
- OutputDebugString(buffer);
+ OutputDebugStringA(buffer);
}
/*
NtVdmControl
*/
+typedef struct tag_VDM_CONFIG {
+ int dos_options;
+ int files;
+ int buffers;
+ WCHAR** device_list;
+//dos=high, umb
+//device=%SystemRoot%\system32\himem.sys
+//files=40
+} VDM_CONFIG, *PVDM_CONFIG;
-BOOLEAN
-StartVirtualMachine(VOID)
-{
- BOOLEAN Result;
- STARTUPINFO StartupInfo;
- PROCESS_INFORMATION ProcessInformation;
- CHAR CommandLine[MAX_PATH];
- CHAR CurrentDirectory[MAX_PATH];
+typedef struct tag_VDM_AUTOEXEC {
+ WCHAR** load_list;
+//lh %SystemRoot%\system32\mscdexnt.exe
+//lh %SystemRoot%\system32\redir
+//lh %SystemRoot%\system32\dosx
+} VDM_AUTOEXEC, *PVDM_AUTOEXEC;
+
+typedef struct tag_VDM_CONTROL_BLOCK {
+ HANDLE hHeap;
+ PVOID ImageMem;
+ VDM_CONFIG vdmConfig;
+ VDM_AUTOEXEC vdmAutoexec;
+ PROCESS_INFORMATION ProcessInformation;
+ CHAR CommandLine[MAX_PATH];
+ CHAR CurrentDirectory[MAX_PATH];
+
+} VDM_CONTROL_BLOCK, *PVDM_CONTROL_BLOCK;
- GetSystemDirectory(CommandLine, MAX_PATH);
- strcat(CommandLine, "\\hello.exe");
- GetWindowsDirectory(CurrentDirectory, MAX_PATH);
+
+BOOL
+StartVDM(PVDM_CONTROL_BLOCK vdm)
+{
+ BOOL Result;
+ STARTUPINFOA StartupInfo;
StartupInfo.cb = sizeof(StartupInfo);
StartupInfo.lpReserved = NULL;
StartupInfo.cbReserved2 = 0;
StartupInfo.lpReserved2 = 0;
- Result = CreateProcess(CommandLine,
+ Result = CreateProcessA(vdm->CommandLine,
NULL,
NULL,
NULL,
NULL,
NULL,
&StartupInfo,
- &ProcessInformation);
+ &vdm->ProcessInformation);
if (!Result) {
- PrintString("WL: Failed to execute target process\n");
+ PrintString("VDM: Failed to execute target process\n");
+ return FALSE;
+ }
+ WaitForSingleObject(vdm->ProcessInformation.hProcess, INFINITE);
+ CloseHandle(vdm->ProcessInformation.hProcess);
+ CloseHandle(vdm->ProcessInformation.hThread);
+ return TRUE;
+}
+
+BOOL
+ShutdownVDM(PVDM_CONTROL_BLOCK vdm)
+{
+ BOOL result = TRUE;
+
+ return result;
+}
+
+BOOL ReadConfigForVDM(PVDM_CONTROL_BLOCK vdm)
+{
+ BOOL result = TRUE;
+ DWORD dwError;
+ HANDLE hFile;
+
+ hFile = CreateFileW(L"\\system32\\config.nt",
+ GENERIC_READ,
+ FILE_SHARE_READ,
+ NULL,
+ OPEN_ALWAYS /*OPEN_EXISTING*/,
+ FILE_ATTRIBUTE_NORMAL,
+ 0);
+ dwError = GetLastError();
+ if (hFile == INVALID_HANDLE_VALUE) {
+ // error with file path or system problem?
+ } else {
+ if (dwError == 0L) {
+ // we just created a new file, perhaps we should set/write some defaults?
+ }
+ if (dwError == ERROR_ALREADY_EXISTS) {
+ // read the line entries and cache in some struct...
+ }
+ CloseHandle(hFile);
+ }
+
+ hFile = CreateFileW(L"\\system32\\autoexec.nt",
+ GENERIC_READ,
+ FILE_SHARE_READ,
+ NULL,
+ OPEN_ALWAYS,
+ FILE_ATTRIBUTE_NORMAL,
+ 0);
+ dwError = GetLastError();
+ if (hFile == INVALID_HANDLE_VALUE) {
+ // error with file path or system problem?
+ } else {
+ if (dwError == 0L) {
+ // we just created a new file, perhaps we should set/write some defaults?
+ }
+ if (dwError == ERROR_ALREADY_EXISTS) {
+ // read the line entries and cache in some struct...
+ }
+ CloseHandle(hFile);
+ }
+
+ return result;
+}
+
+BOOL
+LoadConfigDriversForVDM(PVDM_CONFIG vdmConfig)
+{
+ BOOL result = TRUE;
+
+ return result;
+}
+
+BOOL
+SetConfigOptionsForVDM(PVDM_AUTOEXEC vdmAutoexec)
+{
+ BOOL result = TRUE;
+
+ return result;
+}
+
+BOOL
+CreateVDM(PVDM_CONTROL_BLOCK vdm)
+{
+// BOOL result = TRUE;
+ SYSTEM_INFO inf;
+ MEMORYSTATUS stat;
+
+
+ GlobalMemoryStatus(&stat);
+ if (stat.dwLength != sizeof(MEMORYSTATUS)) {
+ printf("WARNING: GlobalMemoryStatus() returned unknown structure version, size %ld, expected %d.\n", stat.dwLength, sizeof(stat));
+ } else {
+ printf("Memory Load: %ld percent in use.\n", stat.dwMemoryLoad);
+ printf("\t%ld total bytes physical memory.\n", stat.dwTotalPhys);
+ printf("\t%ld available physical memory.\n", stat.dwAvailPhys);
+ printf("\t%ld total bytes paging file.\n", stat.dwTotalPageFile);
+ printf("\t%ld available paging file.\n", stat.dwAvailPageFile);
+ printf("\t%lx total bytes virtual memory.\n", stat.dwTotalVirtual);
+ printf("\t%lx available bytes virtual memory.\n", stat.dwAvailVirtual);
+
+#define OUT_OF_HEADROOM 90
+ if (stat.dwMemoryLoad > OUT_OF_HEADROOM) {
+ DPRINT("VDM: system resources deemed to low to start VDM.\n");
+ //SetLastError();
+ return FALSE;
+ }
+
+ }
+
+ GetSystemInfo(&inf);
+ vdm->hHeap = HeapCreate(0, inf.dwAllocationGranularity, 0);
+ if (vdm->hHeap == NULL) {
+ DPRINT("VDM: failed to create heap.\n");
+ return FALSE;
+ }
+
+#define DEFAULT_VDM_IMAGE_SIZE 2000000
+ vdm->ImageMem = HeapAlloc(vdm->hHeap, 0, DEFAULT_VDM_IMAGE_SIZE);
+ if (vdm->ImageMem == NULL) {
+ DPRINT("VDM: failed to allocate image memory from heap %x.\n", vdm->hHeap);
+ HeapDestroy(vdm->hHeap);
+ vdm->hHeap = NULL;
return FALSE;
}
- WaitForSingleObject(ProcessInformation.hProcess, INFINITE);
- CloseHandle(ProcessInformation.hProcess);
- CloseHandle(ProcessInformation.hThread);
return TRUE;
}
+BOOL
+DestroyVDM(PVDM_CONTROL_BLOCK vdm)
+{
+ BOOL result = TRUE;
+
+ if (vdm->ImageMem != NULL) {
+ if (HeapFree(vdm->hHeap, 0, vdm->ImageMem) != FALSE) {
+ DPRINT("VDM: failed to free memory from heap %x.\n", vdm->hHeap);
+ result = FALSE;
+ }
+ vdm->ImageMem = NULL;
+ }
+ if (vdm->hHeap != NULL) {
+ if (!HeapDestroy(vdm->hHeap)) {
+ DPRINT("VDM: failed to destroy heap %x.\n", vdm->hHeap);
+ result = FALSE;
+ }
+ vdm->hHeap = NULL;
+ }
+ return result;
+}
+
int STDCALL
WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
+ VDM_CONTROL_BLOCK VdmCB;
DWORD Result;
- BOOL Success;
ULONG i;
- NTSTATUS Status;
+ BOOL vdmStarted = FALSE;
- CHAR WelcomeMsg[] = "ReactOS Virtual DOS Machine support.\nType q<cr> to quit.";
+ WCHAR WelcomeMsg[RC_STRING_MAX_SIZE];
+ WCHAR PromptMsg[RC_STRING_MAX_SIZE];
CHAR InputBuffer[255];
-
+
+ LoadString( GetModuleHandle(NULL), STRING_WelcomeMsg, (LPTSTR) WelcomeMsg,sizeof(WelcomeMsg) / sizeof(WelcomeMsg[0]));
+ LoadString( GetModuleHandle(NULL), STRING_PromptMsg, (LPTSTR) PromptMsg ,sizeof(PromptMsg) / sizeof(PromptMsg[0]));
+
AllocConsole();
- SetConsoleTitle("ntvdm");
- StartVirtualMachine();
-
+ SetConsoleTitleW(L"ntvdm");
+
+ WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE),
+ WelcomeMsg, lstrlenW(WelcomeMsg), // wcslen(WelcomeMsg),
+ &Result, NULL);
+
+ if (!CreateVDM(&VdmCB)) {
+ DPRINT("VDM: failed to create VDM.\n");
+ //SetLastError();
+ return 2;
+ }
+
+ ReadConfigForVDM(&VdmCB);
+
+ if (!LoadConfigDriversForVDM(&(VdmCB.vdmConfig))) {
+ DPRINT("VDM: failed to load configuration drivers.\n");
+ //SetLastError();
+ return 2;
+ }
+ if (!SetConfigOptionsForVDM(&(VdmCB.vdmAutoexec))) {
+ DPRINT("VDM: failed to set configuration options.\n");
+ //SetLastError();
+ return 3;
+ }
+
+ GetSystemDirectoryA(VdmCB.CommandLine, MAX_PATH);
+ strcat(VdmCB.CommandLine, "\\hello.exe");
+ GetWindowsDirectoryA(VdmCB.CurrentDirectory, MAX_PATH);
+
for (;;) {
- WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE),
- WelcomeMsg, strlen(WelcomeMsg), // wcslen(WelcomeMsg),
+ WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE),
+ PromptMsg, lstrlenW(PromptMsg), // wcslen(PromptMsg),
&Result, NULL);
i = 0;
do {
- ReadConsole(GetStdHandle(STD_INPUT_HANDLE),
+ ReadConsoleA(GetStdHandle(STD_INPUT_HANDLE),
&InputBuffer[i], 1,
&Result, NULL);
if (++i >= (sizeof(InputBuffer) - 1)) {
} while (InputBuffer[i - 1] != '\n');
InputBuffer[i - 1] = '\0';
+ if (InputBuffer[0] == 'r' || InputBuffer[0] == 'R') {
+ if (!vdmStarted) {
+ if (StartVDM(&VdmCB)) {
+ vdmStarted = TRUE;
+ } else {
+ DPRINT("VDM: failed to start.\n");
+ }
+ } else {
+ DPRINT("VDM: already started.\n");
+ }
+ }
+ if (InputBuffer[0] == 's' || InputBuffer[0] == 'S') {
+ if (vdmStarted) {
+ if (ShutdownVDM(&VdmCB)) {
+ vdmStarted = FALSE;
+ } else {
+ DPRINT("VDM: failed to shutdown.\n");
+ }
+ } else {
+ DPRINT("VDM: not started.\n");
+ }
+ }
if (InputBuffer[0] == 'q' || InputBuffer[0] == 'Q') {
break;
}
}
+ if (!ShutdownVDM(&VdmCB)) {
+ DPRINT("VDM: failed to cleanly shutdown VDM.\n");
+ //SetLastError();
+ return 5;
+ }
+
+ if (!DestroyVDM(&VdmCB)) {
+ DPRINT("VDM: failed to cleanly destroy VDM.\n");
+ //SetLastError();
+ return 6;
+ }
+
ExitProcess(0);
return 0;
}