Revert, thx Thomas, wasnt sure.
[reactos.git] / reactos / subsys / ntvdm / ntvdm.c
index 2fb0169..97accab 100644 (file)
@@ -1,8 +1,8 @@
-/* $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>
@@ -33,7 +36,7 @@ void PrintString(char* fmt,...)
    vsprintf(buffer, fmt, ap);
    va_end(ap);
 
-   OutputDebugString(buffer);
+   OutputDebugStringA(buffer);
 }
 
 /*
@@ -62,19 +65,40 @@ NtUnmapViewOfSection
 
 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;
@@ -84,7 +108,7 @@ StartVirtualMachine(VOID)
    StartupInfo.cbReserved2 = 0;
    StartupInfo.lpReserved2 = 0;
 
-   Result = CreateProcess(CommandLine,
+   Result = CreateProcessA(vdm->CommandLine,
                           NULL,
                           NULL,
                           NULL,
@@ -93,39 +117,211 @@ StartVirtualMachine(VOID)
                           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)) {
@@ -134,11 +330,45 @@ WinMain(HINSTANCE hInstance,  HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nSho
         } 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;
 }