2013-03-14 21:04:13 +00:00
|
|
|
/*
|
2013-06-17 00:00:36 +00:00
|
|
|
* COPYRIGHT: GPL - See COPYING in the top level directory
|
|
|
|
* PROJECT: ReactOS Virtual DOS Machine
|
|
|
|
* FILE: ntvdm.c
|
2002-10-28 13:59:59 +00:00
|
|
|
* PURPOSE: Virtual DOS Machine
|
2013-06-17 00:00:36 +00:00
|
|
|
* PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
|
2002-10-28 13:59:59 +00:00
|
|
|
*/
|
|
|
|
|
2013-06-26 22:58:41 +00:00
|
|
|
/* INCLUDES *******************************************************************/
|
|
|
|
|
2013-07-22 13:51:26 +00:00
|
|
|
#define NDEBUG
|
|
|
|
|
2013-06-17 00:00:36 +00:00
|
|
|
#include "ntvdm.h"
|
2013-06-26 22:58:41 +00:00
|
|
|
#include "emulator.h"
|
2014-10-04 13:36:17 +00:00
|
|
|
#include "cpu/cpu.h"
|
2014-01-11 15:27:18 +00:00
|
|
|
|
2014-02-01 16:32:20 +00:00
|
|
|
#include "bios/bios.h"
|
|
|
|
|
|
|
|
#include "resource.h"
|
2013-06-26 22:58:41 +00:00
|
|
|
|
2014-02-01 16:32:20 +00:00
|
|
|
/* VARIABLES ******************************************************************/
|
2013-01-24 23:00:42 +00:00
|
|
|
|
2014-01-11 20:59:27 +00:00
|
|
|
static HANDLE ConsoleInput = INVALID_HANDLE_VALUE;
|
|
|
|
static HANDLE ConsoleOutput = INVALID_HANDLE_VALUE;
|
|
|
|
static DWORD OrgConsoleInputMode, OrgConsoleOutputMode;
|
2014-02-01 16:32:20 +00:00
|
|
|
|
2014-10-04 13:36:17 +00:00
|
|
|
// For DOS
|
2014-05-11 19:25:09 +00:00
|
|
|
#ifndef STANDALONE
|
2014-10-04 13:36:17 +00:00
|
|
|
BOOLEAN AcceptCommands = TRUE;
|
|
|
|
HANDLE CommandThread = NULL;
|
2014-05-02 22:23:34 +00:00
|
|
|
ULONG SessionId = 0;
|
2014-05-11 19:25:09 +00:00
|
|
|
#endif
|
|
|
|
|
2014-05-02 18:24:40 +00:00
|
|
|
HANDLE VdmTaskEvent = NULL;
|
|
|
|
|
2014-10-04 13:36:17 +00:00
|
|
|
// Command line of NTVDM
|
|
|
|
INT NtVdmArgc;
|
|
|
|
WCHAR** NtVdmArgv;
|
|
|
|
|
|
|
|
|
|
|
|
static HMENU hConsoleMenu = NULL;
|
|
|
|
static INT VdmMenuPos = -1;
|
|
|
|
static BOOLEAN ShowPointer = FALSE;
|
|
|
|
|
2014-02-01 16:32:20 +00:00
|
|
|
/*
|
|
|
|
* Those menu helpers were taken from the GUI frontend in winsrv.dll
|
|
|
|
*/
|
|
|
|
typedef struct _VDM_MENUITEM
|
|
|
|
{
|
|
|
|
UINT uID;
|
|
|
|
const struct _VDM_MENUITEM *SubMenu;
|
|
|
|
WORD wCmdID;
|
|
|
|
} VDM_MENUITEM, *PVDM_MENUITEM;
|
|
|
|
|
|
|
|
static const VDM_MENUITEM VdmMenuItems[] =
|
|
|
|
{
|
2014-09-28 16:27:30 +00:00
|
|
|
{ IDS_VDM_DUMPMEM_TXT, NULL, ID_VDM_DUMPMEM_TXT },
|
|
|
|
{ IDS_VDM_DUMPMEM_BIN, NULL, ID_VDM_DUMPMEM_BIN },
|
|
|
|
{ IDS_VDM_QUIT , NULL, ID_VDM_QUIT },
|
2014-02-01 16:32:20 +00:00
|
|
|
|
|
|
|
{ 0, NULL, 0 } /* End of list */
|
|
|
|
};
|
|
|
|
|
|
|
|
static const VDM_MENUITEM VdmMainMenuItems[] =
|
|
|
|
{
|
|
|
|
{ -1, NULL, 0 }, /* Separator */
|
|
|
|
{ IDS_HIDE_MOUSE, NULL, ID_SHOWHIDE_MOUSE }, /* Hide mouse; can be renamed to Show mouse */
|
|
|
|
{ IDS_VDM_MENU , VdmMenuItems, 0 }, /* ReactOS VDM Menu */
|
|
|
|
|
|
|
|
{ 0, NULL, 0 } /* End of list */
|
|
|
|
};
|
|
|
|
|
|
|
|
static VOID
|
|
|
|
AppendMenuItems(HMENU hMenu,
|
|
|
|
const VDM_MENUITEM *Items)
|
|
|
|
{
|
|
|
|
UINT i = 0;
|
|
|
|
WCHAR szMenuString[255];
|
|
|
|
HMENU hSubMenu;
|
|
|
|
|
|
|
|
do
|
|
|
|
{
|
|
|
|
if (Items[i].uID != (UINT)-1)
|
|
|
|
{
|
|
|
|
if (LoadStringW(GetModuleHandle(NULL),
|
|
|
|
Items[i].uID,
|
|
|
|
szMenuString,
|
|
|
|
sizeof(szMenuString) / sizeof(szMenuString[0])) > 0)
|
|
|
|
{
|
|
|
|
if (Items[i].SubMenu != NULL)
|
|
|
|
{
|
|
|
|
hSubMenu = CreatePopupMenu();
|
|
|
|
if (hSubMenu != NULL)
|
|
|
|
{
|
|
|
|
AppendMenuItems(hSubMenu, Items[i].SubMenu);
|
|
|
|
|
|
|
|
if (!AppendMenuW(hMenu,
|
|
|
|
MF_STRING | MF_POPUP,
|
|
|
|
(UINT_PTR)hSubMenu,
|
|
|
|
szMenuString))
|
|
|
|
{
|
|
|
|
DestroyMenu(hSubMenu);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
AppendMenuW(hMenu,
|
|
|
|
MF_STRING,
|
|
|
|
Items[i].wCmdID,
|
|
|
|
szMenuString);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
AppendMenuW(hMenu,
|
|
|
|
MF_SEPARATOR,
|
|
|
|
0,
|
|
|
|
NULL);
|
|
|
|
}
|
|
|
|
i++;
|
|
|
|
} while (!(Items[i].uID == 0 && Items[i].SubMenu == NULL && Items[i].wCmdID == 0));
|
|
|
|
}
|
|
|
|
|
2014-09-14 00:43:43 +00:00
|
|
|
/*static*/ VOID
|
2014-02-01 16:32:20 +00:00
|
|
|
CreateVdmMenu(HANDLE ConOutHandle)
|
|
|
|
{
|
2014-05-11 19:25:09 +00:00
|
|
|
hConsoleMenu = ConsoleMenuControl(ConOutHandle,
|
2014-02-01 16:32:20 +00:00
|
|
|
ID_SHOWHIDE_MOUSE,
|
|
|
|
ID_VDM_QUIT);
|
2014-03-02 14:37:51 +00:00
|
|
|
if (hConsoleMenu == NULL) return;
|
|
|
|
|
|
|
|
VdmMenuPos = GetMenuItemCount(hConsoleMenu);
|
|
|
|
AppendMenuItems(hConsoleMenu, VdmMainMenuItems);
|
|
|
|
DrawMenuBar(GetConsoleWindow());
|
2014-02-01 16:32:20 +00:00
|
|
|
}
|
|
|
|
|
2014-09-14 00:43:43 +00:00
|
|
|
/*static*/ VOID
|
2014-02-01 16:32:20 +00:00
|
|
|
DestroyVdmMenu(VOID)
|
|
|
|
{
|
|
|
|
UINT i = 0;
|
|
|
|
const VDM_MENUITEM *Items = VdmMainMenuItems;
|
|
|
|
|
|
|
|
do
|
|
|
|
{
|
|
|
|
DeleteMenu(hConsoleMenu, VdmMenuPos, MF_BYPOSITION);
|
|
|
|
i++;
|
|
|
|
} while (!(Items[i].uID == 0 && Items[i].SubMenu == NULL && Items[i].wCmdID == 0));
|
|
|
|
|
|
|
|
DrawMenuBar(GetConsoleWindow());
|
|
|
|
}
|
|
|
|
|
|
|
|
static VOID ShowHideMousePointer(HANDLE ConOutHandle, BOOLEAN ShowPtr)
|
|
|
|
{
|
|
|
|
WCHAR szMenuString[255] = L"";
|
|
|
|
|
2014-03-02 01:45:57 +00:00
|
|
|
if (ShowPtr)
|
|
|
|
{
|
|
|
|
/* Be sure the cursor will be shown */
|
|
|
|
while (ShowConsoleCursor(ConOutHandle, TRUE) < 0) ;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Be sure the cursor will be hidden */
|
|
|
|
while (ShowConsoleCursor(ConOutHandle, FALSE) >= 0) ;
|
|
|
|
}
|
2014-02-01 16:32:20 +00:00
|
|
|
|
|
|
|
if (LoadStringW(GetModuleHandle(NULL),
|
|
|
|
(!ShowPtr ? IDS_SHOW_MOUSE : IDS_HIDE_MOUSE),
|
|
|
|
szMenuString,
|
|
|
|
sizeof(szMenuString) / sizeof(szMenuString[0])) > 0)
|
|
|
|
{
|
|
|
|
ModifyMenu(hConsoleMenu, ID_SHOWHIDE_MOUSE,
|
|
|
|
MF_BYCOMMAND, ID_SHOWHIDE_MOUSE, szMenuString);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-03-31 21:28:40 +00:00
|
|
|
static VOID EnableExtraHardware(HANDLE ConsoleInput)
|
|
|
|
{
|
|
|
|
DWORD ConInMode;
|
|
|
|
|
|
|
|
if (GetConsoleMode(ConsoleInput, &ConInMode))
|
|
|
|
{
|
|
|
|
#if 0
|
|
|
|
// GetNumberOfConsoleMouseButtons();
|
|
|
|
// GetSystemMetrics(SM_CMOUSEBUTTONS);
|
|
|
|
// GetSystemMetrics(SM_MOUSEPRESENT);
|
|
|
|
if (MousePresent)
|
|
|
|
{
|
|
|
|
#endif
|
|
|
|
/* Support mouse input events if there is a mouse on the system */
|
|
|
|
ConInMode |= ENABLE_MOUSE_INPUT;
|
|
|
|
#if 0
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Do not support mouse input events if there is no mouse on the system */
|
|
|
|
ConInMode &= ~ENABLE_MOUSE_INPUT;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
SetConsoleMode(ConsoleInput, ConInMode);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-06-26 22:58:41 +00:00
|
|
|
/* PUBLIC FUNCTIONS ***********************************************************/
|
|
|
|
|
2014-05-11 19:25:09 +00:00
|
|
|
VOID
|
|
|
|
DisplayMessage(LPCWSTR Format, ...)
|
2003-01-12 01:54:40 +00:00
|
|
|
{
|
2014-11-09 01:46:31 +00:00
|
|
|
#ifndef WIN2K_COMPLIANT
|
|
|
|
WCHAR StaticBuffer[256];
|
|
|
|
LPWSTR Buffer = StaticBuffer; // Use the static buffer by default.
|
|
|
|
#else
|
|
|
|
WCHAR Buffer[2048]; // Large enough. If not, increase it by hand.
|
|
|
|
#endif
|
|
|
|
size_t MsgLen;
|
2013-06-17 00:00:36 +00:00
|
|
|
va_list Parameters;
|
2003-01-12 01:54:40 +00:00
|
|
|
|
2013-06-17 00:00:36 +00:00
|
|
|
va_start(Parameters, Format);
|
2014-11-09 01:46:31 +00:00
|
|
|
|
|
|
|
#ifndef WIN2K_COMPLIANT
|
|
|
|
/*
|
|
|
|
* Retrieve the message length and if it is too long, allocate
|
|
|
|
* an auxiliary buffer; otherwise use the static buffer.
|
|
|
|
*/
|
|
|
|
MsgLen = _vscwprintf(Format, Parameters) + 1; // NULL-terminated
|
|
|
|
if (MsgLen > sizeof(StaticBuffer)/sizeof(StaticBuffer[0]))
|
|
|
|
{
|
|
|
|
Buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, MsgLen * sizeof(WCHAR));
|
|
|
|
if (Buffer == NULL)
|
|
|
|
{
|
|
|
|
/* Allocation failed, use the static buffer and display a suitable error message */
|
|
|
|
Buffer = StaticBuffer;
|
|
|
|
Format = L"DisplayMessage()\nOriginal message is too long and allocating an auxiliary buffer failed.";
|
|
|
|
MsgLen = wcslen(Format);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#else
|
|
|
|
MsgLen = sizeof(Buffer)/sizeof(Buffer[0]);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* Display the message */
|
|
|
|
_vsnwprintf(Buffer, MsgLen, Format, Parameters);
|
2013-11-09 15:53:52 +00:00
|
|
|
DPRINT1("\n\nNTVDM Subsystem\n%S\n\n", Buffer);
|
2013-08-06 20:01:05 +00:00
|
|
|
MessageBoxW(NULL, Buffer, L"NTVDM Subsystem", MB_OK);
|
2014-11-09 01:46:31 +00:00
|
|
|
|
|
|
|
#ifndef WIN2K_COMPLIANT
|
|
|
|
/* Free the buffer if needed */
|
|
|
|
if (Buffer != StaticBuffer) HeapFree(GetProcessHeap(), 0, Buffer);
|
|
|
|
#endif
|
|
|
|
|
2013-06-17 00:00:36 +00:00
|
|
|
va_end(Parameters);
|
2003-01-12 01:54:40 +00:00
|
|
|
}
|
|
|
|
|
2014-05-11 19:25:09 +00:00
|
|
|
static BOOL
|
|
|
|
WINAPI
|
|
|
|
ConsoleCtrlHandler(DWORD ControlType)
|
2003-01-12 01:54:40 +00:00
|
|
|
{
|
2013-06-17 00:00:36 +00:00
|
|
|
switch (ControlType)
|
|
|
|
{
|
2014-04-22 20:46:50 +00:00
|
|
|
case CTRL_LAST_CLOSE_EVENT:
|
|
|
|
{
|
2014-05-02 18:24:40 +00:00
|
|
|
if (WaitForSingleObject(VdmTaskEvent, 0) == WAIT_TIMEOUT)
|
2014-04-27 22:38:54 +00:00
|
|
|
{
|
|
|
|
/* Exit immediately */
|
2014-10-04 13:36:17 +00:00
|
|
|
#ifndef STANDALONE
|
2014-04-27 22:38:54 +00:00
|
|
|
if (CommandThread) TerminateThread(CommandThread, 0);
|
2014-10-04 13:36:17 +00:00
|
|
|
#endif
|
2014-05-02 18:24:40 +00:00
|
|
|
EmulatorTerminate();
|
2014-04-27 22:38:54 +00:00
|
|
|
}
|
2014-10-04 13:36:17 +00:00
|
|
|
#ifndef STANDALONE
|
2014-04-27 22:38:54 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
/* Stop accepting new commands */
|
|
|
|
AcceptCommands = FALSE;
|
|
|
|
}
|
2014-10-04 13:36:17 +00:00
|
|
|
#endif
|
2014-04-27 22:38:54 +00:00
|
|
|
|
2014-04-22 20:46:50 +00:00
|
|
|
break;
|
|
|
|
}
|
2015-03-31 21:28:40 +00:00
|
|
|
|
2013-06-17 00:00:36 +00:00
|
|
|
default:
|
|
|
|
{
|
|
|
|
/* Stop the VDM if the user logs out or closes the console */
|
2014-03-02 14:37:51 +00:00
|
|
|
EmulatorTerminate();
|
2003-01-12 01:54:40 +00:00
|
|
|
}
|
2002-10-28 13:59:59 +00:00
|
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2014-05-11 19:25:09 +00:00
|
|
|
static VOID
|
|
|
|
ConsoleInitUI(VOID)
|
2014-02-01 16:32:20 +00:00
|
|
|
{
|
|
|
|
CreateVdmMenu(ConsoleOutput);
|
|
|
|
}
|
|
|
|
|
2014-05-11 19:25:09 +00:00
|
|
|
static VOID
|
|
|
|
ConsoleCleanupUI(VOID)
|
2014-02-01 16:32:20 +00:00
|
|
|
{
|
|
|
|
/* Display again properly the mouse pointer */
|
|
|
|
if (ShowPointer) ShowHideMousePointer(ConsoleOutput, ShowPointer);
|
|
|
|
|
|
|
|
DestroyVdmMenu();
|
|
|
|
}
|
|
|
|
|
2015-03-31 21:28:40 +00:00
|
|
|
BOOL
|
2014-05-11 19:25:09 +00:00
|
|
|
ConsoleAttach(VOID)
|
|
|
|
{
|
|
|
|
/* Save the original input and output console modes */
|
|
|
|
if (!GetConsoleMode(ConsoleInput , &OrgConsoleInputMode ) ||
|
|
|
|
!GetConsoleMode(ConsoleOutput, &OrgConsoleOutputMode))
|
|
|
|
{
|
|
|
|
CloseHandle(ConsoleOutput);
|
|
|
|
CloseHandle(ConsoleInput);
|
|
|
|
wprintf(L"FATAL: Cannot save console in/out modes\n");
|
|
|
|
// return FALSE;
|
|
|
|
}
|
|
|
|
|
2015-03-31 21:28:40 +00:00
|
|
|
/* Set the console input mode */
|
|
|
|
// FIXME: Activate ENABLE_WINDOW_INPUT when we will want to perform actions
|
|
|
|
// upon console window events (screen buffer resize, ...).
|
|
|
|
SetConsoleMode(ConsoleInput, 0 /* | ENABLE_WINDOW_INPUT */);
|
|
|
|
EnableExtraHardware(ConsoleInput);
|
|
|
|
|
|
|
|
/* Set the console output mode */
|
|
|
|
// SetConsoleMode(ConsoleOutput, ENABLE_PROCESSED_OUTPUT | ENABLE_WRAP_AT_EOL_OUTPUT);
|
|
|
|
|
2014-05-11 19:25:09 +00:00
|
|
|
/* Initialize the UI */
|
|
|
|
ConsoleInitUI();
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2015-03-31 21:28:40 +00:00
|
|
|
VOID
|
2014-05-11 19:25:09 +00:00
|
|
|
ConsoleDetach(VOID)
|
|
|
|
{
|
|
|
|
/* Restore the original input and output console modes */
|
|
|
|
SetConsoleMode(ConsoleOutput, OrgConsoleOutputMode);
|
|
|
|
SetConsoleMode(ConsoleInput , OrgConsoleInputMode );
|
|
|
|
|
|
|
|
/* Cleanup the UI */
|
|
|
|
ConsoleCleanupUI();
|
|
|
|
}
|
|
|
|
|
|
|
|
static BOOL
|
|
|
|
ConsoleInit(VOID)
|
|
|
|
{
|
|
|
|
/* Set the handler routine */
|
|
|
|
SetConsoleCtrlHandler(ConsoleCtrlHandler, TRUE);
|
|
|
|
|
|
|
|
/* Enable the CTRL_LAST_CLOSE_EVENT */
|
|
|
|
SetLastConsoleEventActive();
|
|
|
|
|
|
|
|
/*
|
|
|
|
* NOTE: The CONIN$ and CONOUT$ "virtual" files
|
|
|
|
* always point to non-redirected console handles.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* Get the input handle to the real console, and check for success */
|
|
|
|
ConsoleInput = CreateFileW(L"CONIN$",
|
|
|
|
GENERIC_READ | GENERIC_WRITE,
|
|
|
|
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
|
|
|
NULL,
|
|
|
|
OPEN_EXISTING,
|
|
|
|
0,
|
|
|
|
NULL);
|
|
|
|
if (ConsoleInput == INVALID_HANDLE_VALUE)
|
|
|
|
{
|
|
|
|
wprintf(L"FATAL: Cannot retrieve a handle to the console input\n");
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Get the output handle to the real console, and check for success */
|
|
|
|
ConsoleOutput = CreateFileW(L"CONOUT$",
|
|
|
|
GENERIC_READ | GENERIC_WRITE,
|
|
|
|
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
|
|
|
NULL,
|
|
|
|
OPEN_EXISTING,
|
|
|
|
0,
|
|
|
|
NULL);
|
|
|
|
if (ConsoleOutput == INVALID_HANDLE_VALUE)
|
|
|
|
{
|
|
|
|
CloseHandle(ConsoleInput);
|
|
|
|
wprintf(L"FATAL: Cannot retrieve a handle to the console output\n");
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Effectively attach to the console */
|
|
|
|
return ConsoleAttach();
|
|
|
|
}
|
|
|
|
|
|
|
|
static VOID
|
|
|
|
ConsoleCleanup(VOID)
|
|
|
|
{
|
|
|
|
/* Detach from the console */
|
|
|
|
ConsoleDetach();
|
|
|
|
|
|
|
|
/* Close the console handles */
|
|
|
|
if (ConsoleOutput != INVALID_HANDLE_VALUE) CloseHandle(ConsoleOutput);
|
|
|
|
if (ConsoleInput != INVALID_HANDLE_VALUE) CloseHandle(ConsoleInput);
|
|
|
|
}
|
|
|
|
|
2014-09-16 00:51:15 +00:00
|
|
|
VOID MenuEventHandler(PMENU_EVENT_RECORD MenuEvent)
|
2014-02-01 16:32:20 +00:00
|
|
|
{
|
2014-09-16 00:51:15 +00:00
|
|
|
switch (MenuEvent->dwCommandId)
|
2014-02-01 16:32:20 +00:00
|
|
|
{
|
2014-09-16 00:51:15 +00:00
|
|
|
case ID_SHOWHIDE_MOUSE:
|
|
|
|
ShowHideMousePointer(ConsoleOutput, ShowPointer);
|
|
|
|
ShowPointer = !ShowPointer;
|
|
|
|
break;
|
2014-02-01 16:32:20 +00:00
|
|
|
|
2014-09-28 16:27:30 +00:00
|
|
|
case ID_VDM_DUMPMEM_TXT:
|
|
|
|
DumpMemory(TRUE);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case ID_VDM_DUMPMEM_BIN:
|
|
|
|
DumpMemory(FALSE);
|
2014-09-16 00:51:15 +00:00
|
|
|
break;
|
2014-02-01 16:32:20 +00:00
|
|
|
|
2014-09-16 00:51:15 +00:00
|
|
|
case ID_VDM_QUIT:
|
|
|
|
/* Stop the VDM */
|
|
|
|
EmulatorTerminate();
|
|
|
|
break;
|
2014-02-01 16:32:20 +00:00
|
|
|
|
2014-09-16 00:51:15 +00:00
|
|
|
default:
|
|
|
|
break;
|
2014-02-01 16:32:20 +00:00
|
|
|
}
|
2014-09-16 00:51:15 +00:00
|
|
|
}
|
2014-02-01 16:32:20 +00:00
|
|
|
|
2014-09-16 00:51:15 +00:00
|
|
|
VOID FocusEventHandler(PFOCUS_EVENT_RECORD FocusEvent)
|
|
|
|
{
|
|
|
|
DPRINT1("Focus events not handled\n");
|
2014-02-01 16:32:20 +00:00
|
|
|
}
|
|
|
|
|
2014-05-11 19:25:09 +00:00
|
|
|
INT
|
|
|
|
wmain(INT argc, WCHAR *argv[])
|
2014-04-22 20:46:50 +00:00
|
|
|
{
|
|
|
|
#ifdef STANDALONE
|
2014-04-27 22:38:54 +00:00
|
|
|
|
2014-10-04 13:36:17 +00:00
|
|
|
if (argc < 2)
|
2013-07-18 00:17:04 +00:00
|
|
|
{
|
|
|
|
wprintf(L"\nReactOS Virtual DOS Machine\n\n"
|
2014-04-26 08:57:17 +00:00
|
|
|
L"Usage: NTVDM <executable> [<parameters>]\n");
|
2013-07-18 00:17:04 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2005-05-08 04:07:56 +00:00
|
|
|
|
2014-05-02 22:23:34 +00:00
|
|
|
#else
|
2014-05-11 19:25:09 +00:00
|
|
|
|
2014-05-02 22:23:34 +00:00
|
|
|
INT i;
|
|
|
|
WCHAR *endptr;
|
|
|
|
|
|
|
|
/* Parse the command line arguments */
|
|
|
|
for (i = 1; i < argc; i++)
|
|
|
|
{
|
|
|
|
if (wcsncmp(argv[i], L"-i", 2) == 0)
|
|
|
|
{
|
|
|
|
/* This is the session ID */
|
|
|
|
SessionId = wcstoul(argv[i] + 2, &endptr, 10);
|
2014-05-03 02:13:51 +00:00
|
|
|
|
|
|
|
/* The VDM hasn't been started from a console, so quit when the task is done */
|
|
|
|
AcceptCommands = FALSE;
|
2014-05-02 22:23:34 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-04-08 00:28:49 +00:00
|
|
|
#endif
|
|
|
|
|
2014-10-04 13:36:17 +00:00
|
|
|
NtVdmArgc = argc;
|
|
|
|
NtVdmArgv = argv;
|
|
|
|
|
2014-04-08 14:57:24 +00:00
|
|
|
DPRINT1("\n\n\nNTVDM - Starting...\n\n\n");
|
|
|
|
|
2014-05-02 18:24:40 +00:00
|
|
|
/* Create the task event */
|
|
|
|
VdmTaskEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
|
|
|
ASSERT(VdmTaskEvent != NULL);
|
|
|
|
|
2014-01-11 20:59:27 +00:00
|
|
|
/* Initialize the console */
|
|
|
|
if (!ConsoleInit())
|
|
|
|
{
|
|
|
|
wprintf(L"FATAL: A problem occurred when trying to initialize the console\n");
|
|
|
|
goto Cleanup;
|
|
|
|
}
|
|
|
|
|
2013-11-26 20:20:51 +00:00
|
|
|
/* Initialize the emulator */
|
2014-01-25 00:21:51 +00:00
|
|
|
if (!EmulatorInitialize(ConsoleInput, ConsoleOutput))
|
2013-07-02 21:40:11 +00:00
|
|
|
{
|
2014-01-11 20:59:27 +00:00
|
|
|
wprintf(L"FATAL: Failed to initialize the emulator\n");
|
2013-07-05 00:08:18 +00:00
|
|
|
goto Cleanup;
|
2013-07-02 21:40:11 +00:00
|
|
|
}
|
2013-11-17 20:44:23 +00:00
|
|
|
|
2013-06-17 00:00:36 +00:00
|
|
|
/* Initialize the system BIOS */
|
2014-03-02 01:45:57 +00:00
|
|
|
if (!BiosInitialize(NULL))
|
2013-06-17 00:00:36 +00:00
|
|
|
{
|
|
|
|
wprintf(L"FATAL: Failed to initialize the VDM BIOS.\n");
|
|
|
|
goto Cleanup;
|
2003-01-12 01:54:40 +00:00
|
|
|
}
|
2002-10-28 13:59:59 +00:00
|
|
|
|
2014-10-04 13:36:17 +00:00
|
|
|
/* Let's go! Start simulation */
|
|
|
|
CpuSimulate();
|
2014-04-08 14:57:24 +00:00
|
|
|
|
2013-06-17 00:00:36 +00:00
|
|
|
Cleanup:
|
2013-07-05 01:31:50 +00:00
|
|
|
BiosCleanup();
|
2013-06-17 00:00:36 +00:00
|
|
|
EmulatorCleanup();
|
2014-01-11 20:59:27 +00:00
|
|
|
ConsoleCleanup();
|
2003-01-12 01:54:40 +00:00
|
|
|
|
2014-04-08 14:57:24 +00:00
|
|
|
#ifndef STANDALONE
|
|
|
|
ExitVDM(FALSE, 0);
|
|
|
|
#endif
|
|
|
|
|
2014-04-08 00:28:49 +00:00
|
|
|
/* Quit the VDM */
|
2013-11-04 00:22:29 +00:00
|
|
|
DPRINT1("\n\n\nNTVDM - Exiting...\n\n\n");
|
|
|
|
|
2002-10-28 13:59:59 +00:00
|
|
|
return 0;
|
|
|
|
}
|
2013-06-17 00:00:36 +00:00
|
|
|
|
|
|
|
/* EOF */
|