#include "resource.h"
-/*
- * Activate this line if you want to run NTVDM in standalone mode with:
- * ntvdm.exe <program>
- */
-// #define STANDALONE
-
/* VARIABLES ******************************************************************/
static HANDLE ConsoleInput = INVALID_HANDLE_VALUE;
static INT VdmMenuPos = -1;
static BOOLEAN ShowPointer = FALSE;
+#ifndef STANDALONE
ULONG SessionId = 0;
+#endif
+
HANDLE VdmTaskEvent = NULL;
/*
static const VDM_MENUITEM VdmMenuItems[] =
{
- { IDS_VDM_QUIT, NULL, ID_VDM_QUIT },
+ { IDS_VDM_DUMPMEM, NULL, ID_VDM_DUMPMEM },
+ { IDS_VDM_QUIT , NULL, ID_VDM_QUIT },
{ 0, NULL, 0 } /* End of list */
};
} while (!(Items[i].uID == 0 && Items[i].SubMenu == NULL && Items[i].wCmdID == 0));
}
-static VOID
+/*static*/ VOID
CreateVdmMenu(HANDLE ConOutHandle)
{
- hConsoleMenu = ConsoleMenuControl(ConsoleOutput,
+ hConsoleMenu = ConsoleMenuControl(ConOutHandle,
ID_SHOWHIDE_MOUSE,
ID_VDM_QUIT);
if (hConsoleMenu == NULL) return;
DrawMenuBar(GetConsoleWindow());
}
-static VOID
+/*static*/ VOID
DestroyVdmMenu(VOID)
{
UINT i = 0;
/* PUBLIC FUNCTIONS ***********************************************************/
-VOID DisplayMessage(LPCWSTR Format, ...)
+VOID
+DisplayMessage(LPCWSTR Format, ...)
{
WCHAR Buffer[256];
va_list Parameters;
va_end(Parameters);
}
-BOOL WINAPI ConsoleCtrlHandler(DWORD ControlType)
+static BOOL
+WINAPI
+ConsoleCtrlHandler(DWORD ControlType)
{
switch (ControlType)
{
return TRUE;
}
-VOID ConsoleInitUI(VOID)
+static VOID
+ConsoleInitUI(VOID)
{
CreateVdmMenu(ConsoleOutput);
}
-VOID ConsoleCleanupUI(VOID)
+static VOID
+ConsoleCleanupUI(VOID)
{
/* Display again properly the mouse pointer */
if (ShowPointer) ShowHideMousePointer(ConsoleOutput, ShowPointer);
DestroyVdmMenu();
}
-DWORD WINAPI PumpConsoleInput(LPVOID Parameter)
+static BOOL
+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;
+ }
+
+ /* Initialize the UI */
+ ConsoleInitUI();
+
+ return TRUE;
+}
+
+static VOID
+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);
+}
+
+DWORD
+WINAPI
+PumpConsoleInput(LPVOID Parameter)
{
HANDLE ConsoleInput = (HANDLE)Parameter;
INPUT_RECORD InputRecord;
ShowPointer = !ShowPointer;
break;
+ case ID_VDM_DUMPMEM:
+ DumpMemory();
+ break;
+
case ID_VDM_QUIT:
/* Stop the VDM */
EmulatorTerminate();
return 0;
}
-BOOL ConsoleInit(VOID)
-{
- /* Set the handler routine */
- SetConsoleCtrlHandler(ConsoleCtrlHandler, TRUE);
-
- /* Enable the CTRL_LAST_CLOSE_EVENT */
- SetLastConsoleEventActive();
-
- /* 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;
- }
-
- /* 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;
- }
-
- /* Initialize the UI */
- ConsoleInitUI();
-
- return TRUE;
-}
-
-VOID ConsoleCleanup(VOID)
-{
- /* Restore the original input and output console modes */
- SetConsoleMode(ConsoleOutput, OrgConsoleOutputMode);
- SetConsoleMode(ConsoleInput , OrgConsoleInputMode );
-
- /* Cleanup the UI */
- ConsoleCleanupUI();
-
- /* Close the console handles */
- if (ConsoleOutput != INVALID_HANDLE_VALUE) CloseHandle(ConsoleOutput);
- if (ConsoleInput != INVALID_HANDLE_VALUE) CloseHandle(ConsoleInput);
-}
-
-DWORD WINAPI CommandThreadProc(LPVOID Parameter)
+#ifndef STANDALONE
+static DWORD
+WINAPI
+CommandThreadProc(LPVOID Parameter)
{
BOOLEAN First = TRUE;
DWORD Result;
CHAR PifFile[MAX_PATH];
CHAR Desktop[MAX_PATH];
CHAR Title[MAX_PATH];
- CHAR Env[MAX_PATH];
+ ULONG EnvSize = 256;
+ PVOID Env = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, EnvSize);
UNREFERENCED_PARAMETER(Parameter);
+ ASSERT(Env != NULL);
do
{
CommandInfo.Title = Title;
CommandInfo.TitleLen = sizeof(Title);
CommandInfo.Env = Env;
- CommandInfo.EnvLen = sizeof(Env);
+ CommandInfo.EnvLen = EnvSize;
if (First) CommandInfo.VDMState |= VDM_FLAG_FIRST_TASK;
- /* Wait for the next available VDM */
- if (!GetNextVDMCommand(&CommandInfo)) break;
+Command:
+ if (!GetNextVDMCommand(&CommandInfo))
+ {
+ if (CommandInfo.EnvLen > EnvSize)
+ {
+ /* Expand the environment size */
+ EnvSize = CommandInfo.EnvLen;
+ Env = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, Env, EnvSize);
- /* Start the process from the command line */
- DPRINT1("Starting '%s'...\n", AppName);
+ /* Repeat the request */
+ goto Command;
+ }
- Result = DosLoadExecutable(DOS_LOAD_AND_EXECUTE, AppName, CmdLine, Env, NULL, NULL);
+ break;
+ }
+
+ /* Start the process from the command line */
+ DPRINT1("Starting '%s' ('%s')...\n", AppName, CmdLine);
+ Result = DosStartProcess(AppName, CmdLine, Env);
if (Result != ERROR_SUCCESS)
{
DisplayMessage(L"Could not start '%S'. Error: %u", AppName, Result);
- break;
+ // break;
+ continue;
}
- /* Attach to the console */
- if (!First) VgaAttachToConsole();
-
- /* Perform a screen refresh */
- VgaRefreshDisplay();
-
- /* Start simulation */
- SetEvent(VdmTaskEvent);
- EmulatorSimulate();
-
- /* Perform another screen refresh */
- VgaRefreshDisplay();
-
- /* Detach from the console */
- VgaDetachFromConsole(FALSE);
-
First = FALSE;
}
while (AcceptCommands);
+ HeapFree(GetProcessHeap(), 0, Env);
return 0;
}
+#endif
-INT wmain(INT argc, WCHAR *argv[])
+INT
+wmain(INT argc, WCHAR *argv[])
{
#ifdef STANDALONE
}
#else
+
INT i;
WCHAR *endptr;
#else
/* Start the process from the command line */
- DPRINT1("Starting '%s'...\n", ApplicationName);
-
- Result = DosLoadExecutable(DOS_LOAD_AND_EXECUTE,
- ApplicationName,
- CommandLine,
- GetEnvironmentStrings(),
- NULL,
- NULL);
+ DPRINT1("Starting '%s' ('%s')...\n", ApplicationName, CommandLine);
+ Result = DosStartProcess(ApplicationName,
+ CommandLine,
+ GetEnvironmentStrings());
if (Result != ERROR_SUCCESS)
{
DisplayMessage(L"Could not start '%S'. Error: %u", ApplicationName, Result);
goto Cleanup;
}
- /* Start simulation */
- SetEvent(VdmTaskEvent);
- EmulatorSimulate();
-
- /* Perform another screen refresh */
- VgaRefreshDisplay();
-
#endif
Cleanup: