3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: subsys/ntvdm/ntvdm->c
6 * PURPOSE: Virtual DOS Machine
7 * PROGRAMMER: Robert Dickenson (robd@mok.lvcm.com)
12 /* INCLUDES *****************************************************************/
22 /* GLOBALS ******************************************************************/
25 /* FUNCTIONS *****************************************************************/
27 void PrintString(char* fmt,...)
33 vsprintf(buffer, fmt, ap);
36 OutputDebugStringA(buffer);
53 SetVDMCurrentDirectories
65 typedef struct tag_VDM_CONFIG {
71 //device=%SystemRoot%\system32\himem.sys
73 } VDM_CONFIG, *PVDM_CONFIG;
75 typedef struct tag_VDM_AUTOEXEC {
77 //lh %SystemRoot%\system32\mscdexnt.exe
78 //lh %SystemRoot%\system32\redir
79 //lh %SystemRoot%\system32\dosx
80 } VDM_AUTOEXEC, *PVDM_AUTOEXEC;
82 typedef struct tag_VDM_CONTROL_BLOCK {
86 VDM_AUTOEXEC vdmAutoexec;
87 PROCESS_INFORMATION ProcessInformation;
88 CHAR CommandLine[MAX_PATH];
89 CHAR CurrentDirectory[MAX_PATH];
91 } VDM_CONTROL_BLOCK, *PVDM_CONTROL_BLOCK;
95 StartVDM(PVDM_CONTROL_BLOCK vdm)
98 STARTUPINFOA StartupInfo;
100 StartupInfo.cb = sizeof(StartupInfo);
101 StartupInfo.lpReserved = NULL;
102 StartupInfo.lpDesktop = NULL;
103 StartupInfo.lpTitle = NULL;
104 StartupInfo.dwFlags = 0;
105 StartupInfo.cbReserved2 = 0;
106 StartupInfo.lpReserved2 = 0;
108 Result = CreateProcessA(vdm->CommandLine,
117 &vdm->ProcessInformation);
119 PrintString("VDM: Failed to execute target process\n");
122 WaitForSingleObject(vdm->ProcessInformation.hProcess, INFINITE);
123 CloseHandle(vdm->ProcessInformation.hProcess);
124 CloseHandle(vdm->ProcessInformation.hThread);
129 ShutdownVDM(PVDM_CONTROL_BLOCK vdm)
136 BOOL ReadConfigForVDM(PVDM_CONTROL_BLOCK vdm)
142 hFile = CreateFileW(L"\\system32\\config.nt",
146 OPEN_ALWAYS /*OPEN_EXISTING*/,
147 FILE_ATTRIBUTE_NORMAL,
149 dwError = GetLastError();
150 if (hFile == INVALID_HANDLE_VALUE) {
151 // error with file path or system problem?
154 // we just created a new file, perhaps we should set/write some defaults?
156 if (dwError == ERROR_ALREADY_EXISTS) {
157 // read the line entries and cache in some struct...
162 hFile = CreateFileW(L"\\system32\\autoexec.nt",
167 FILE_ATTRIBUTE_NORMAL,
169 dwError = GetLastError();
170 if (hFile == INVALID_HANDLE_VALUE) {
171 // error with file path or system problem?
174 // we just created a new file, perhaps we should set/write some defaults?
176 if (dwError == ERROR_ALREADY_EXISTS) {
177 // read the line entries and cache in some struct...
186 LoadConfigDriversForVDM(PVDM_CONFIG vdmConfig)
194 SetConfigOptionsForVDM(PVDM_AUTOEXEC vdmAutoexec)
202 CreateVDM(PVDM_CONTROL_BLOCK vdm)
204 // BOOL result = TRUE;
209 GlobalMemoryStatus(&stat);
210 if (stat.dwLength != sizeof(MEMORYSTATUS)) {
211 printf("WARNING: GlobalMemoryStatus() returned unknown structure version, size %ld, expected %d.\n", stat.dwLength, sizeof(stat));
213 printf("Memory Load: %ld percent in use.\n", stat.dwMemoryLoad);
214 printf("\t%ld total bytes physical memory.\n", stat.dwTotalPhys);
215 printf("\t%ld available physical memory.\n", stat.dwAvailPhys);
216 printf("\t%ld total bytes paging file.\n", stat.dwTotalPageFile);
217 printf("\t%ld available paging file.\n", stat.dwAvailPageFile);
218 printf("\t%lx total bytes virtual memory.\n", stat.dwTotalVirtual);
219 printf("\t%lx available bytes virtual memory.\n", stat.dwAvailVirtual);
221 #define OUT_OF_HEADROOM 90
222 if (stat.dwMemoryLoad > OUT_OF_HEADROOM) {
223 DPRINT("VDM: system resources deemed to low to start VDM.\n");
230 vdm->hHeap = HeapCreate(0, inf.dwAllocationGranularity, 0);
231 if (vdm->hHeap == NULL) {
232 DPRINT("VDM: failed to create heap.\n");
236 #define DEFAULT_VDM_IMAGE_SIZE 2000000
237 vdm->ImageMem = HeapAlloc(vdm->hHeap, 0, DEFAULT_VDM_IMAGE_SIZE);
238 if (vdm->ImageMem == NULL) {
239 DPRINT("VDM: failed to allocate image memory from heap %x.\n", vdm->hHeap);
240 HeapDestroy(vdm->hHeap);
248 DestroyVDM(PVDM_CONTROL_BLOCK vdm)
252 if (vdm->ImageMem != NULL) {
253 if (HeapFree(vdm->hHeap, 0, vdm->ImageMem) != FALSE) {
254 DPRINT("VDM: failed to free memory from heap %x.\n", vdm->hHeap);
257 vdm->ImageMem = NULL;
259 if (vdm->hHeap != NULL) {
260 if (!HeapDestroy(vdm->hHeap)) {
261 DPRINT("VDM: failed to destroy heap %x.\n", vdm->hHeap);
270 WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
272 VDM_CONTROL_BLOCK VdmCB;
277 BOOL vdmStarted = FALSE;
279 WCHAR WelcomeMsg[] = L"ReactOS Virtual DOS Machine support.\n";
280 WCHAR PromptMsg[] = L"Type r<cr> to run, s<cr> to shutdown or q<cr> to quit now.";
281 CHAR InputBuffer[255];
284 SetConsoleTitleW(L"ntvdm");
286 WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE),
287 WelcomeMsg, lstrlenW(WelcomeMsg), // wcslen(WelcomeMsg),
290 if (!CreateVDM(&VdmCB)) {
291 DPRINT("VDM: failed to create VDM.\n");
296 ReadConfigForVDM(&VdmCB);
298 if (!LoadConfigDriversForVDM(&(VdmCB.vdmConfig))) {
299 DPRINT("VDM: failed to load configuration drivers.\n");
303 if (!SetConfigOptionsForVDM(&(VdmCB.vdmAutoexec))) {
304 DPRINT("VDM: failed to set configuration options.\n");
309 GetSystemDirectoryA(VdmCB.CommandLine, MAX_PATH);
310 strcat(VdmCB.CommandLine, "\\hello.exe");
311 GetWindowsDirectoryA(VdmCB.CurrentDirectory, MAX_PATH);
314 WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE),
315 PromptMsg, lstrlenW(PromptMsg), // wcslen(PromptMsg),
319 ReadConsoleA(GetStdHandle(STD_INPUT_HANDLE),
322 if (++i >= (sizeof(InputBuffer) - 1)) {
325 } while (InputBuffer[i - 1] != '\n');
326 InputBuffer[i - 1] = '\0';
328 if (InputBuffer[0] == 'r' || InputBuffer[0] == 'R') {
330 if (StartVDM(&VdmCB)) {
333 DPRINT("VDM: failed to start.\n");
336 DPRINT("VDM: already started.\n");
339 if (InputBuffer[0] == 's' || InputBuffer[0] == 'S') {
341 if (ShutdownVDM(&VdmCB)) {
344 DPRINT("VDM: failed to shutdown.\n");
347 DPRINT("VDM: not started.\n");
350 if (InputBuffer[0] == 'q' || InputBuffer[0] == 'Q') {
355 if (!ShutdownVDM(&VdmCB)) {
356 DPRINT("VDM: failed to cleanly shutdown VDM.\n");
361 if (!DestroyVDM(&VdmCB)) {
362 DPRINT("VDM: failed to cleanly destroy VDM.\n");