ReactOS  0.4.13-dev-235-g7373cb3
dem.c File Reference
#include "ntvdm.h"
#include <debug.h>
#include "emulator.h"
#include <isvbop.h>
#include "utils.h"
#include "dem.h"
#include "dos/dos32krnl/device.h"
#include "dos/dos32krnl/memory.h"
#include "dos/dos32krnl/process.h"
#include "cpu/bop.h"
#include "cpu/cpu.h"
#include "bios/bios.h"
#include "mouse32.h"
#include "vddsup.h"
#include "command_com.h"
Include dependency graph for dem.c:

Go to the source code of this file.

Classes

struct  _COMSPEC_INFO
 
struct  _NEXT_CMD
 
struct  _DOS_START_PROC32
 

Macros

#define NDEBUG
 

Typedefs

typedef struct _COMSPEC_INFO COMSPEC_INFO
 
typedef struct _COMSPEC_INFOPCOMSPEC_INFO
 
typedef struct _NEXT_CMD NEXT_CMD
 
typedef struct _NEXT_CMDPNEXT_CMD
 
typedef struct _DOS_START_PROC32 DOS_START_PROC32
 
typedef struct _DOS_START_PROC32PDOS_START_PROC32
 

Functions

VOID Dem_BiosCharPrint (CHAR Character)
 
VOID DosCharPrint (CHAR Character)
 
static VOID DemLoadNTDOSKernel (VOID)
 
static VOID WINAPI DosSystemBop (LPWORD Stack)
 
static PCOMSPEC_INFO FindComSpecInfoByPsp (WORD Psp)
 
static VOID InsertComSpecInfo (PCOMSPEC_INFO ComSpecInfo)
 
static VOID RemoveComSpecInfo (PCOMSPEC_INFO ComSpecInfo)
 
static VOID DosProcessConsoleAttach (VOID)
 
static VOID DosProcessConsoleDetach (VOID)
 
static VOID CmdStartProcess (VOID)
 
static VOID CmdStartExternalCommand (VOID)
 
static VOID CmdStartComSpec32 (VOID)
 
static VOID CmdSetExitCode (VOID)
 
static VOID WINAPI DosCmdInterpreterBop (LPWORD Stack)
 
static DWORD DosStartComSpec (IN BOOLEAN Permanent, IN LPCSTR Environment OPTIONAL, IN DWORD ReturnAddress OPTIONAL, OUT PWORD ComSpecPsp OPTIONAL)
 
static DWORD WINAPI CommandThreadProc (LPVOID Parameter)
 
DWORD DosStartProcess32 (IN LPCSTR ExecutablePath, IN LPCSTR CommandLine, IN LPCSTR Environment OPTIONAL, IN DWORD ReturnAddress OPTIONAL, IN BOOLEAN StartComSpec)
 
static VOID WINAPI DosInitialize (LPWORD Stack)
 
VOID DosBootsectorInitialize (VOID)
 
static VOID WINAPI DosStart (LPWORD Stack)
 
BOOLEAN DosShutdown (BOOLEAN Immediate)
 
DWORD WINAPI demClientErrorEx (IN HANDLE FileHandle, IN CHAR Unknown, IN BOOL Flag)
 
DWORD WINAPI demFileDelete (IN LPCSTR FileName)
 
DWORD WINAPI demFileFindFirst (OUT PVOID lpFindFileData, IN LPCSTR FileName, IN WORD AttribMask)
 
DWORD WINAPI demFileFindNext (OUT PVOID lpFindFileData)
 
UCHAR WINAPI demGetPhysicalDriveType (IN UCHAR DriveNumber)
 
BOOL WINAPI demIsShortPathName (IN LPCSTR Path, IN BOOL Unknown)
 
DWORD WINAPI demSetCurrentDirectoryGetDrive (IN LPCSTR CurrentDirectory, OUT PUCHAR DriveNumber)
 

Variables

static ULONG SessionId = 0
 
static COMSPEC_INFO RootCmd
 
static DWORD ReentrancyCount = 0
 
static LIST_ENTRY ComSpecInfoList = { &ComSpecInfoList, &ComSpecInfoList }
 
static VDM_COMMAND_INFO CommandInfo
 
static BOOLEAN Repeat = FALSE
 
static BOOLEAN Reentry = FALSE
 
static BOOLEAN First = TRUE
 
static CHAR CmdLine [MAX_PATH] = ""
 
static CHAR AppName [MAX_PATH] = ""
 
static CHAR PifFile [MAX_PATH] = ""
 
static CHAR CurDirectory [MAX_PATH] = ""
 
static CHAR Desktop [MAX_PATH] = ""
 
static CHAR Title [MAX_PATH] = ""
 
static ULONG EnvSize = 256
 
static PVOID Env = NULL
 
static BYTE Bootsector1 []
 
static BYTE Bootsector2 []
 
static BYTE Startup []
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 17 of file dem.c.

Typedef Documentation

◆ COMSPEC_INFO

◆ DOS_START_PROC32

◆ NEXT_CMD

◆ PCOMSPEC_INFO

◆ PDOS_START_PROC32

◆ PNEXT_CMD

Function Documentation

◆ CmdSetExitCode()

static VOID CmdSetExitCode ( VOID  )
static

Definition at line 505 of file dem.c.

506 {
507 #ifndef STANDALONE
508  BOOL Success;
509  PCOMSPEC_INFO ComSpecInfo;
511 #endif
512 
513  /* Pause the VM */
514  EmulatorPause();
515 
516 #ifndef STANDALONE
517  /*
518  * Check whether we need to shell out now in case we were started by a 32-bit app,
519  * or we were started alone along with the root 32-bit app.
520  */
521  ComSpecInfo = FindComSpecInfoByPsp(Sda->CurrentPsp);
522  if ((ComSpecInfo && ComSpecInfo->Terminated) ||
523  (ComSpecInfo == &RootCmd && SessionId != 0))
524  {
525  RemoveComSpecInfo(ComSpecInfo);
526 #endif
527  DPRINT1("Exit DOS from ExitCode (prologue)!\n");
528  setCF(0);
529  goto Quit;
530 #ifndef STANDALONE
531  }
532 
533  /* Clear the VDM structure */
535 
536 Retry:
537  /* Update the VDM state of the task */
538  // CommandInfo.TaskId = SessionId;
541  DPRINT1("Calling GetNextVDMCommand 32bit end of VDM task\n");
543  DPRINT1("GetNextVDMCommand 32bit end of VDM task success = %s, last error = %d\n", Success ? "true" : "false", GetLastError());
544 
545  /*
546  * Check whether we were awaited because the 32-bit process was stopped,
547  * or because it started a new DOS application.
548  */
549  if (CommandInfo.CmdLen != 0 || CommandInfo.AppLen != 0 || CommandInfo.PifLen != 0)
550  {
551  DPRINT1("GetNextVDMCommand end-of-app, this is for a new VDM task - CmdLen = %d, AppLen = %d, PifLen = %d\n",
553 
554  /* Repeat the request */
555  Repeat = TRUE;
556  setCF(1);
557  }
558  else
559  {
560  DPRINT1("GetNextVDMCommand end-of-app, the app stopped\n");
561 
562  /* Check whether we need to shell out now in case we were started by a 32-bit app */
563  ComSpecInfo = FindComSpecInfoByPsp(Sda->CurrentPsp);
564  if (!ComSpecInfo || !ComSpecInfo->Terminated)
565  {
566  DPRINT1("Not our 32-bit app, retrying...\n");
567  goto Retry;
568  }
569 
570  ASSERT(ComSpecInfo->Terminated == TRUE);
571 
572  /* Record found, remove it and exit now */
573  RemoveComSpecInfo(ComSpecInfo);
574 
575  DPRINT1("Exit DOS from ExitCode wait!\n");
576  setCF(0);
577  }
578 #endif
579 
580  // FIXME: Use the retrieved exit code as the value of our exit code
581  // when COMMAND.COM will shell-out ??
582 
583 Quit:
584  /* Resume the VM */
585  EmulatorResume();
586 }
static PCOMSPEC_INFO FindComSpecInfoByPsp(WORD Psp)
Definition: dem.c:199
WORD CurrentPsp
Definition: dos.h:156
#define TRUE
Definition: types.h:120
ULONG ExitCode
Definition: vdm.h:72
static VDM_COMMAND_INFO CommandInfo
Definition: dem.c:246
static VOID RemoveComSpecInfo(PCOMSPEC_INFO ComSpecInfo)
Definition: dem.c:220
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
static COMSPEC_INFO RootCmd
Definition: dem.c:192
USHORT PifLen
Definition: vdm.h:92
USHORT CmdLen
Definition: vdm.h:90
unsigned int BOOL
Definition: ntddk_ex.h:94
VOID WINAPI setCF(ULONG)
Definition: registers.c:573
IN PSCSI_REQUEST_BLOCK IN OUT NTSTATUS IN OUT BOOLEAN * Retry
Definition: class2.h:49
USHORT VDMState
Definition: vdm.h:94
BOOLEAN Terminated
Definition: dem.c:189
USHORT AppLen
Definition: vdm.h:91
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
VOID EmulatorPause(VOID)
Definition: emulator.c:487
USHORT WINAPI getDX(VOID)
Definition: registers.c:286
PDOS_SDA Sda
Definition: dos.c:48
static BOOLEAN Repeat
Definition: dem.c:247
static ULONG SessionId
Definition: dem.c:179
#define DPRINT1
Definition: precomp.h:8
VOID EmulatorResume(VOID)
Definition: emulator.c:495
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
BOOL WINAPI GetNextVDMCommand(PVDM_COMMAND_INFO CommandData)
Definition: vdm.c:1412
#define VDM_FLAG_DONT_WAIT
Definition: vdm.h:60

Referenced by DosCmdInterpreterBop().

◆ CmdStartComSpec32()

static VOID CmdStartComSpec32 ( VOID  )
static

Definition at line 465 of file dem.c.

466 {
467  DWORD Result;
468 
469  // TODO: improve: this code has strong similarities with the
470  // 'default' case of DosCreateProcess and with the 'case 0x08'.
471 
472  CHAR CmdLine[sizeof("cmd.exe") + 1] = "";
473 
474  /* Spawn a user-defined 32-bit command preprocessor */
475 
476  // FIXME: Use COMSPEC env var!!
477  strcpy(CmdLine, "cmd.exe");
478 
479  DPRINT1("CMD Run 32-bit Command Interpreter '%s'\n", CmdLine);
480 
481  /*
482  * No need to prepare the stack for DosStartComSpec since we won't start it.
483  */
485  SEG_OFF_TO_PTR(getES(), 0) /*Environment*/,
486  MAKELONG(getIP(), getCS()) /*ReturnAddress*/,
487  FALSE);
488  if (Result != ERROR_SUCCESS)
489  {
490  DosDisplayMessage("Failed to start 32-bit Command Interpreter '%s'. Error: %u\n", CmdLine, Result);
491  setCF(0);
492  setAL((UCHAR)Result);
493  }
494  else
495  {
496  DosDisplayMessage("32-bit Command Interpreter '%s' started successfully.\n", CmdLine);
497 #ifndef STANDALONE
498  setCF(Repeat); // Set CF if we need to start a 16-bit process
499 #else
500  setCF(0);
501 #endif
502  }
503 }
#define ERROR_SUCCESS
Definition: deptool.c:10
char CHAR
Definition: xmlstorage.h:175
static CHAR CmdLine[MAX_PATH]
Definition: dem.c:251
VOID WINAPI setAL(UCHAR)
Definition: registers.c:149
#define DosDisplayMessage(Format,...)
Definition: dem.h:37
#define SEG_OFF_TO_PTR(seg, off)
Definition: emulator.h:28
VOID WINAPI setCF(ULONG)
Definition: registers.c:573
#define MAKELONG(a, b)
Definition: typedefs.h:248
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:426
USHORT WINAPI getES(VOID)
Definition: registers.c:522
USHORT WINAPI getIP(VOID)
Definition: registers.c:464
unsigned long DWORD
Definition: ntddk_ex.h:95
unsigned char UCHAR
Definition: xmlstorage.h:181
DWORD DosStartProcess32(IN LPCSTR ExecutablePath, IN LPCSTR CommandLine, IN LPCSTR Environment OPTIONAL, IN DWORD ReturnAddress OPTIONAL, IN BOOLEAN StartComSpec)
Definition: dem.c:916
static BOOLEAN Repeat
Definition: dem.c:247
#define DPRINT1
Definition: precomp.h:8
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
USHORT WINAPI getCS(VOID)
Definition: registers.c:480

Referenced by DosCmdInterpreterBop().

◆ CmdStartExternalCommand()

static VOID CmdStartExternalCommand ( VOID  )
static

Definition at line 411 of file dem.c.

412 {
413  DWORD Result;
414 
415  // TODO: improve: this code has strong similarities
416  // with the 'default' case of DosCreateProcess.
417 
419  CHAR CmdLine[sizeof("cmd.exe /c ") + DOS_CMDLINE_LENGTH + 1] = "";
420  LPSTR CmdLinePtr;
421  SIZE_T CmdLineLen;
422 
423  /* Spawn a user-defined 32-bit command preprocessor */
424 
425  // FIXME: Use COMSPEC env var!!
426  CmdLinePtr = CmdLine;
427  strcpy(CmdLinePtr, "cmd.exe /c ");
428  CmdLinePtr += strlen(CmdLinePtr);
429 
430  /* Build a Win32-compatible command-line */
431  CmdLineLen = min(strlen(Command), sizeof(CmdLine) - strlen(CmdLinePtr) - 1);
432  RtlCopyMemory(CmdLinePtr, Command, CmdLineLen);
433  CmdLinePtr[CmdLineLen] = '\0';
434 
435  /* Remove any trailing return carriage character and NULL-terminate the command line */
436  while (*CmdLinePtr && *CmdLinePtr != '\r' && *CmdLinePtr != '\n') CmdLinePtr++;
437  *CmdLinePtr = '\0';
438 
439  DPRINT1("CMD Run Command '%s' ('%s')\n", Command, CmdLine);
440 
441  /*
442  * No need to prepare the stack for DosStartComSpec since we won't start it.
443  */
445  SEG_OFF_TO_PTR(getES(), 0) /*Environment*/,
446  MAKELONG(getIP(), getCS()) /*ReturnAddress*/,
447  FALSE);
448  if (Result != ERROR_SUCCESS)
449  {
450  DosDisplayMessage("Failed to start command '%s' ('%s'). Error: %u\n", Command, CmdLine, Result);
451  setCF(0);
452  setAL((UCHAR)Result);
453  }
454  else
455  {
456  DosDisplayMessage("Command '%s' ('%s') started successfully.\n", Command, CmdLine);
457 #ifndef STANDALONE
458  setCF(Repeat); // Set CF if we need to start a 16-bit process
459 #else
460  setCF(0);
461 #endif
462  }
463 }
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define ERROR_SUCCESS
Definition: deptool.c:10
USHORT WINAPI getSI(VOID)
Definition: registers.c:404
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
char CHAR
Definition: xmlstorage.h:175
static CHAR CmdLine[MAX_PATH]
Definition: dem.c:251
#define DOS_CMDLINE_LENGTH
Definition: process.h:13
VOID WINAPI setAL(UCHAR)
Definition: registers.c:149
Definition: shell.h:41
char * LPSTR
Definition: xmlstorage.h:182
#define DosDisplayMessage(Format,...)
Definition: dem.h:37
#define SEG_OFF_TO_PTR(seg, off)
Definition: emulator.h:28
VOID WINAPI setCF(ULONG)
Definition: registers.c:573
#define MAKELONG(a, b)
Definition: typedefs.h:248
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:426
USHORT WINAPI getES(VOID)
Definition: registers.c:522
USHORT WINAPI getIP(VOID)
Definition: registers.c:464
unsigned long DWORD
Definition: ntddk_ex.h:95
unsigned char UCHAR
Definition: xmlstorage.h:181
DWORD DosStartProcess32(IN LPCSTR ExecutablePath, IN LPCSTR CommandLine, IN LPCSTR Environment OPTIONAL, IN DWORD ReturnAddress OPTIONAL, IN BOOLEAN StartComSpec)
Definition: dem.c:916
static BOOLEAN Repeat
Definition: dem.c:247
ULONG_PTR SIZE_T
Definition: typedefs.h:78
#define min(a, b)
Definition: monoChain.cc:55
#define DPRINT1
Definition: precomp.h:8
USHORT WINAPI getDS(VOID)
Definition: registers.c:508
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
USHORT WINAPI getCS(VOID)
Definition: registers.c:480

Referenced by DosCmdInterpreterBop().

◆ CmdStartProcess()

static VOID CmdStartProcess ( VOID  )
static

Definition at line 290 of file dem.c.

291 {
292 #ifndef STANDALONE
293  PCOMSPEC_INFO ComSpecInfo;
294 #endif
295  SIZE_T CmdLen;
296  PNEXT_CMD DataStruct = (PNEXT_CMD)SEG_OFF_TO_PTR(getDS(), getDX());
297 
298  DPRINT1("CmdStartProcess -- DS:DX = %04X:%04X (DataStruct = 0x%p)\n",
299  getDS(), getDX(), DataStruct);
300 
301  /* Pause the VM */
302  EmulatorPause();
303 
304 #ifndef STANDALONE
305  /* Check whether we need to shell out now in case we were started by a 32-bit app */
306  ComSpecInfo = FindComSpecInfoByPsp(Sda->CurrentPsp);
307  if (ComSpecInfo && ComSpecInfo->Terminated)
308  {
309  RemoveComSpecInfo(ComSpecInfo);
310 
311  DPRINT1("Exit DOS from start-app BOP\n");
312  setCF(1);
313  goto Quit;
314  }
315 
316  /* Clear the structure */
318 
319  /* Initialize the structure members */
323  CommandInfo.CmdLen = sizeof(CmdLine);
325  CommandInfo.AppLen = sizeof(AppName);
327  CommandInfo.PifLen = sizeof(PifFile);
331  CommandInfo.DesktopLen = sizeof(Desktop);
333  CommandInfo.TitleLen = sizeof(Title);
334  CommandInfo.Env = Env;
336 
338 
339 Command:
340 
342  Repeat = FALSE;
343 
344  /* Get the VDM command information */
345  DPRINT1("Calling GetNextVDMCommand in CmdStartProcess: wait for new VDM task...\n");
347  {
348  DPRINT1("CmdStartProcess - GetNextVDMCommand failed, retrying... last error = %d\n", GetLastError());
349  if (CommandInfo.EnvLen > EnvSize)
350  {
351  /* Expand the environment size */
353  CommandInfo.Env = Env = RtlReAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, Env, EnvSize);
354 
355  /* Repeat the request */
356  Repeat = TRUE;
357  goto Command;
358  }
359 
360  /* Shouldn't happen */
361  DisplayMessage(L"An unrecoverable failure happened from start-app BOP; exiting DOS.");
362  setCF(1);
363  goto Quit;
364  }
365 
366  // FIXME: What happens if some other 32-bit app is killed while we are waiting there??
367 
368  DPRINT1("CmdStartProcess - GetNextVDMCommand succeeded, start app...\n");
369 
370 #else
371 
372  if (!First)
373  {
374  DPRINT1("Exit DOS from start-app BOP\n");
375  setCF(1);
376  goto Quit;
377  }
378 
379 #endif
380 
381  /* Compute the command line length, not counting the terminating "\r\n" */
382  CmdLen = strlen(CmdLine);
383  if (CmdLen >= 2 && CmdLine[CmdLen - 2] == '\r')
384  CmdLen -= 2;
385 
386  DPRINT1("Starting '%s' ('%.*s')...\n", AppName, CmdLen, CmdLine);
387 
388  /* Start the process */
389  // FIXME: Merge 'Env' with the master environment SEG_OFF_TO_PTR(SYSTEM_ENV_BLOCK, 0)
390  // FIXME: Environment
391  RtlCopyMemory(SEG_OFF_TO_PTR(DataStruct->AppNameSeg, DataStruct->AppNameOff), AppName, MAX_PATH);
392  *(PBYTE)(SEG_OFF_TO_PTR(DataStruct->CmdLineSeg, DataStruct->CmdLineOff)) = (BYTE)CmdLen;
394 
395 #ifndef STANDALONE
396  /* Update console title if we run in a separate console */
397  if (SessionId != 0)
399 #endif
400 
401  First = FALSE;
402  setCF(0);
403 
404  DPRINT1("App started!\n");
405 
406 Quit:
407  /* Resume the VM */
408  EmulatorResume();
409 }
LPSTR Desktop
Definition: vdm.h:84
static PCOMSPEC_INFO FindComSpecInfoByPsp(WORD Psp)
Definition: dem.c:199
WORD CurrentPsp
Definition: dos.h:156
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
ULONG DesktopLen
Definition: vdm.h:85
LPSTR CmdLine
Definition: vdm.h:77
static VDM_COMMAND_INFO CommandInfo
Definition: dem.c:246
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
Definition: dem.c:267
static VOID RemoveComSpecInfo(PCOMSPEC_INFO ComSpecInfo)
Definition: dem.c:220
static CHAR CmdLine[MAX_PATH]
Definition: dem.c:251
static CHAR AppName[MAX_PATH]
Definition: dem.c:252
#define DOS_CMDLINE_LENGTH
Definition: process.h:13
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
USHORT PifLen
Definition: vdm.h:92
USHORT CmdLen
Definition: vdm.h:90
NTSYSAPI PVOID WINAPI RtlReAllocateHeap(HANDLE, ULONG, PVOID, SIZE_T)
Definition: heap.c:2561
#define SEG_OFF_TO_PTR(seg, off)
Definition: emulator.h:28
USHORT CurDirectoryLen
Definition: vdm.h:93
static ULONG EnvSize
Definition: dem.c:258
VOID WINAPI setCF(ULONG)
Definition: registers.c:573
#define VDM_FLAG_RETRY
Definition: vdm.h:56
#define VDM_FLAG_DOS
Definition: vdm.h:55
USHORT VDMState
Definition: vdm.h:94
static CHAR Desktop[MAX_PATH]
Definition: dem.c:256
LPSTR CurDirectory
Definition: vdm.h:80
struct Command Command
USHORT CmdLineSeg
Definition: dem.c:273
LPSTR PifFile
Definition: vdm.h:79
BOOLEAN Terminated
Definition: dem.c:189
#define MAX_PATH
Definition: compat.h:26
USHORT AppLen
Definition: vdm.h:91
static PVOID Env
Definition: dem.c:259
LPSTR Env
Definition: vdm.h:81
VOID EmulatorPause(VOID)
Definition: emulator.c:487
static const WCHAR L[]
Definition: oid.c:1250
USHORT WINAPI getDX(VOID)
Definition: registers.c:286
unsigned char BYTE
Definition: mem.h:68
PDOS_SDA Sda
Definition: dos.c:48
static BOOLEAN Repeat
Definition: dem.c:247
static CHAR PifFile[MAX_PATH]
Definition: dem.c:254
ULONG EnvLen
Definition: vdm.h:82
static CHAR Title[MAX_PATH]
Definition: dem.c:257
ULONG_PTR SIZE_T
Definition: typedefs.h:78
static ULONG SessionId
Definition: dem.c:179
static BOOLEAN First
Definition: dem.c:250
LPSTR AppName
Definition: vdm.h:78
static CHAR CurDirectory[MAX_PATH]
Definition: dem.c:255
#define HEAP_ZERO_MEMORY
Definition: compat.h:123
USHORT AppNameOff
Definition: dem.c:283
BOOL WINAPI DECLSPEC_HOTPATCH SetConsoleTitleA(LPCSTR lpConsoleTitle)
Definition: console.c:2304
#define DPRINT1
Definition: precomp.h:8
LPSTR Title
Definition: vdm.h:86
VOID EmulatorResume(VOID)
Definition: emulator.c:495
USHORT WINAPI getDS(VOID)
Definition: registers.c:508
USHORT CmdLineOff
Definition: dem.c:274
#define VDM_FLAG_FIRST_TASK
Definition: vdm.h:53
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
BOOL WINAPI GetNextVDMCommand(PVDM_COMMAND_INFO CommandData)
Definition: vdm.c:1412
ULONG TitleLen
Definition: vdm.h:87
void DisplayMessage(BOOL bConsole, BOOL bSilent, LPCTSTR lpMessage, LPCTSTR lpTitle, UINT uType)
Definition: regsvr32.c:239
USHORT AppNameSeg
Definition: dem.c:282
BYTE * PBYTE
Definition: pedump.c:66
struct _NEXT_CMD * PNEXT_CMD
ULONG TaskId
Definition: vdm.h:70

Referenced by DosCmdInterpreterBop().

◆ CommandThreadProc()

static DWORD WINAPI CommandThreadProc ( LPVOID  Parameter)
static

Definition at line 828 of file dem.c.

829 {
830  BOOL Success;
831  PROCESS_INFORMATION ProcessInfo;
832  STARTUPINFOA StartupInfo;
833  DWORD dwExitCode;
835 #ifndef STANDALONE
837  PCOMSPEC_INFO ComSpecInfo = DosStartProc32->ComSpecInfo;
838 #endif
839 
840  /* Set up the VDM, startup and process info structures */
841 #ifndef STANDALONE
843 #endif
844  RtlZeroMemory(&ProcessInfo, sizeof(ProcessInfo));
845  RtlZeroMemory(&StartupInfo, sizeof(StartupInfo));
846  StartupInfo.cb = sizeof(StartupInfo);
847 
848  // FIXME: Build suitable 32-bit environment!!
849 
850 #ifndef STANDALONE
851  /*
852  * Wait for signaling a new VDM task and increment the VDM re-entry count so
853  * that we can handle 16-bit apps that may be possibly started by the 32-bit app.
854  */
856  DPRINT1("Calling GetNextVDMCommand reenter++\n");
858  DPRINT1("GetNextVDMCommand reenter++ success = %s, last error = %d\n", Success ? "true" : "false", GetLastError());
859  ++ReentrancyCount;
860 #endif
861 
862  /* Start the process */
863  Success = CreateProcessA(NULL, // ProgramName,
864  DosStartProc32->CommandLine,
865  NULL,
866  NULL,
867  TRUE, // Inherit handles
869  DosStartProc32->Environment,
870  NULL, // lpCurrentDirectory, see "START" command in cmd.exe
871  &StartupInfo,
872  &ProcessInfo);
873 
874 #ifndef STANDALONE
875  /* Signal our caller the process was started */
876  SetEvent(DosStartProc32->hEvent);
877  // After this point, 'DosStartProc32' is not valid anymore.
878 #endif
879 
880  if (Success)
881  {
882  /* Resume the process */
883  ResumeThread(ProcessInfo.hThread);
884 
885  /* Wait for the process to finish running and retrieve its exit code */
886  WaitForSingleObject(ProcessInfo.hProcess, INFINITE);
887  GetExitCodeProcess(ProcessInfo.hProcess, &dwExitCode);
888 
889  /* Close the handles */
890  CloseHandle(ProcessInfo.hThread);
891  CloseHandle(ProcessInfo.hProcess);
892  }
893  else
894  {
895  dwExitCode = GetLastError();
896  }
897 
898 #ifndef STANDALONE
899  ASSERT(ComSpecInfo);
900  ComSpecInfo->Terminated = TRUE;
901  ComSpecInfo->dwExitCode = dwExitCode;
902 
903  /* Decrement the VDM re-entry count */
905  DPRINT1("Calling GetNextVDMCommand reenter--\n");
907  DPRINT1("GetNextVDMCommand reenter-- success = %s, last error = %d\n", Success ? "true" : "false", GetLastError());
908  --ReentrancyCount;
909 
910  return 0;
911 #else
912  return dwExitCode;
913 #endif
914 }
HANDLE hEvent
Definition: dem.c:822
#define TRUE
Definition: types.h:120
#define CloseHandle
Definition: compat.h:398
static VDM_COMMAND_INFO CommandInfo
Definition: dem.c:246
BOOL WINAPI GetExitCodeProcess(IN HANDLE hProcess, IN LPDWORD lpExitCode)
Definition: proc.c:1198
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:679
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
DWORD dwExitCode
Definition: dem.c:187
#define CREATE_DEFAULT_ERROR_MODE
Definition: winbase.h:194
_In_ PVOID Parameter
Definition: ldrtypes.h:240
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
#define CREATE_SUSPENDED
Definition: winbase.h:178
unsigned int BOOL
Definition: ntddk_ex.h:94
PCOMSPEC_INFO ComSpecInfo
Definition: dem.c:821
smooth NULL
Definition: ftsmooth.c:416
USHORT VDMState
Definition: vdm.h:94
#define VDM_DEC_REENTER_COUNT
Definition: vdm.h:58
struct _DOS_START_PROC32 * PDOS_START_PROC32
DWORD cb
Definition: winbase.h:796
BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessA(LPCSTR lpApplicationName, LPSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCSTR lpCurrentDirectory, LPSTARTUPINFOA lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation)
Definition: proc.c:4772
BOOLEAN Terminated
Definition: dem.c:189
unsigned long DWORD
Definition: ntddk_ex.h:95
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
LPSTR CommandLine
Definition: dem.c:818
#define DPRINT1
Definition: precomp.h:8
#define VDM_INC_REENTER_COUNT
Definition: vdm.h:57
static DWORD ReentrancyCount
Definition: dem.c:193
DWORD WINAPI ResumeThread(IN HANDLE hThread)
Definition: thread.c:528
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
BOOL WINAPI GetNextVDMCommand(PVDM_COMMAND_INFO CommandData)
Definition: vdm.c:1412
#define INFINITE
Definition: serial.h:102

Referenced by DosStartProcess32().

◆ Dem_BiosCharPrint()

VOID Dem_BiosCharPrint ( CHAR  Character)

Definition at line 57 of file dem.c.

58 {
59  /* Save AX and BX */
60  USHORT AX = getAX();
61  USHORT BX = getBX();
62 
63  /*
64  * Set the parameters:
65  * AL contains the character to print,
66  * BL contains the character attribute,
67  * BH contains the video page to use.
68  */
69  setAL(Character);
72 
73  /* Call the BIOS INT 10h, AH=0Eh "Teletype Output" */
74  setAH(0x0E);
76 
77  /* Restore AX and BX */
78  setBX(BX);
79  setAX(AX);
80 }
USHORT WINAPI getBX(VOID)
Definition: registers.c:170
BYTE VideoPage
Definition: bios.h:66
VOID WINAPI setBL(UCHAR)
Definition: registers.c:205
VOID WINAPI setAH(UCHAR)
Definition: registers.c:135
VOID WINAPI setAX(USHORT)
Definition: registers.c:121
VOID Int32Call(IN PCALLBACK16 Context, IN BYTE IntNumber)
Definition: int32.c:151
VOID WINAPI setAL(UCHAR)
Definition: registers.c:149
PBIOS_DATA_AREA Bda
Definition: bios.c:42
#define AX
Definition: i386-dis.c:415
#define DEFAULT_ATTRIBUTE
Definition: vidbios.h:21
#define BIOS_VIDEO_INTERRUPT
Definition: vidbios.h:15
CALLBACK16 DosContext
Definition: dos.c:40
USHORT WINAPI getAX(VOID)
Definition: registers.c:114
VOID WINAPI setBX(USHORT)
Definition: registers.c:177
VOID WINAPI setBH(UCHAR)
Definition: registers.c:191
unsigned short USHORT
Definition: pedump.c:61

◆ demClientErrorEx()

DWORD WINAPI demClientErrorEx ( IN HANDLE  FileHandle,
IN CHAR  Unknown,
IN BOOL  Flag 
)

Definition at line 1392 of file dem.c.

1395 {
1396  UNIMPLEMENTED;
1397  return GetLastError();
1398 }
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
#define UNIMPLEMENTED
Definition: debug.h:114

◆ demFileDelete()

DWORD WINAPI demFileDelete ( IN LPCSTR  FileName)

Definition at line 1402 of file dem.c.

1403 {
1405 
1406  return GetLastError();
1407 }
#define ERROR_SUCCESS
Definition: deptool.c:10
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
BOOL WINAPI DeleteFileA(IN LPCSTR lpFileName)
Definition: delete.c:24
#define SetLastError(x)
Definition: compat.h:409

Referenced by DosInt21h().

◆ demFileFindFirst()

DWORD WINAPI demFileFindFirst ( OUT PVOID  lpFindFileData,
IN LPCSTR  FileName,
IN WORD  AttribMask 
)

Definition at line 1411 of file dem.c.

1414 {
1415  BOOLEAN Success = TRUE;
1416  WIN32_FIND_DATAA FindData;
1417  HANDLE SearchHandle;
1418  PDOS_FIND_FILE_BLOCK FindFileBlock = (PDOS_FIND_FILE_BLOCK)lpFindFileData;
1419 
1420  /* Start a search */
1421  SearchHandle = FindFirstFileA(FileName, &FindData);
1422  if (SearchHandle == INVALID_HANDLE_VALUE) return GetLastError();
1423 
1424  do
1425  {
1426  /* Check the attributes and retry as long as we haven't found a matching file */
1427  if (!((FindData.dwFileAttributes & (FILE_ATTRIBUTE_HIDDEN |
1430  & ~AttribMask))
1431  {
1432  break;
1433  }
1434  }
1435  while ((Success = FindNextFileA(SearchHandle, &FindData)));
1436 
1437  /* If we failed at some point, close the search and return an error */
1438  if (!Success)
1439  {
1440  FindClose(SearchHandle);
1441  return GetLastError();
1442  }
1443 
1444  /* Fill the block */
1445  FindFileBlock->DriveLetter = DosData->Sda.CurrentDrive + 'A';
1446  FindFileBlock->AttribMask = AttribMask;
1447  FindFileBlock->SearchHandle = SearchHandle;
1448  FindFileBlock->Attributes = LOBYTE(FindData.dwFileAttributes);
1449  FileTimeToDosDateTime(&FindData.ftLastWriteTime,
1450  &FindFileBlock->FileDate,
1451  &FindFileBlock->FileTime);
1452  FindFileBlock->FileSize = FindData.nFileSizeHigh ? 0xFFFFFFFF
1453  : FindData.nFileSizeLow;
1454  /* Build a short path name */
1455  if (*FindData.cAlternateFileName)
1456  strncpy(FindFileBlock->FileName, FindData.cAlternateFileName, sizeof(FindFileBlock->FileName));
1457  else
1458  GetShortPathNameA(FindData.cFileName, FindFileBlock->FileName, sizeof(FindFileBlock->FileName));
1459 
1460  return ERROR_SUCCESS;
1461 }
#define TRUE
Definition: types.h:120
#define ERROR_SUCCESS
Definition: deptool.c:10
#define LOBYTE(W)
Definition: jmemdos.c:487
HANDLE SearchHandle
Definition: dos.h:128
#define FILE_ATTRIBUTE_SYSTEM
Definition: nt_native.h:704
char * strncpy(char *DstString, const char *SrcString, ACPI_SIZE Count)
Definition: utclib.c:427
#define INVALID_HANDLE_VALUE
Definition: compat.h:391
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
BOOL WINAPI FindNextFileA(IN HANDLE hFindFile, OUT LPWIN32_FIND_DATAA lpFindFileData)
Definition: find.c:336
DOS_SDA Sda
Definition: dos.h:247
PDOS_DATA DosData
Definition: dos.c:45
UCHAR Attributes
Definition: dos.h:131
BYTE CurrentDrive
Definition: dos.h:159
unsigned char BOOLEAN
DWORD FileSize
Definition: dos.h:134
#define FILE_ATTRIBUTE_DIRECTORY
Definition: nt_native.h:705
struct _DOS_FIND_FILE_BLOCK * PDOS_FIND_FILE_BLOCK
UCHAR AttribMask
Definition: dos.h:126
DWORD WINAPI GetShortPathNameA(IN LPCSTR lpszLongPath, OUT LPSTR lpszShortPath, IN DWORD cchBuffer)
Definition: path.c:1751
BOOL WINAPI FileTimeToDosDateTime(IN CONST FILETIME *lpFileTime, OUT LPWORD lpFatDate, OUT LPWORD lpFatTime)
Definition: time.c:37
#define FILE_ATTRIBUTE_HIDDEN
Definition: nt_native.h:703
CHAR FileName[13]
Definition: dos.h:135
HANDLE WINAPI FindFirstFileA(IN LPCSTR lpFileName, OUT LPWIN32_FIND_DATAA lpFindFileData)
Definition: find.c:263
CHAR DriveLetter
Definition: dos.h:124
BOOL WINAPI FindClose(HANDLE hFindFile)
Definition: find.c:502

Referenced by DosInt21h().

◆ demFileFindNext()

DWORD WINAPI demFileFindNext ( OUT PVOID  lpFindFileData)

Definition at line 1465 of file dem.c.

1466 {
1467  WIN32_FIND_DATAA FindData;
1468  PDOS_FIND_FILE_BLOCK FindFileBlock = (PDOS_FIND_FILE_BLOCK)lpFindFileData;
1469 
1470  do
1471  {
1472  /* Continue searching as long as we haven't found a matching file */
1473 
1474  /* If we failed at some point, close the search and return an error */
1475  if (!FindNextFileA(FindFileBlock->SearchHandle, &FindData))
1476  {
1477  FindClose(FindFileBlock->SearchHandle);
1478  return GetLastError();
1479  }
1480  }
1481  while ((FindData.dwFileAttributes & (FILE_ATTRIBUTE_HIDDEN |
1484  & ~FindFileBlock->AttribMask);
1485 
1486  /* Update the block */
1487  FindFileBlock->Attributes = LOBYTE(FindData.dwFileAttributes);
1488  FileTimeToDosDateTime(&FindData.ftLastWriteTime,
1489  &FindFileBlock->FileDate,
1490  &FindFileBlock->FileTime);
1491  FindFileBlock->FileSize = FindData.nFileSizeHigh ? 0xFFFFFFFF
1492  : FindData.nFileSizeLow;
1493  /* Build a short path name */
1494  if (*FindData.cAlternateFileName)
1495  strncpy(FindFileBlock->FileName, FindData.cAlternateFileName, sizeof(FindFileBlock->FileName));
1496  else
1497  GetShortPathNameA(FindData.cFileName, FindFileBlock->FileName, sizeof(FindFileBlock->FileName));
1498 
1499  return ERROR_SUCCESS;
1500 }
#define ERROR_SUCCESS
Definition: deptool.c:10
#define LOBYTE(W)
Definition: jmemdos.c:487
HANDLE SearchHandle
Definition: dos.h:128
#define FILE_ATTRIBUTE_SYSTEM
Definition: nt_native.h:704
char * strncpy(char *DstString, const char *SrcString, ACPI_SIZE Count)
Definition: utclib.c:427
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
BOOL WINAPI FindNextFileA(IN HANDLE hFindFile, OUT LPWIN32_FIND_DATAA lpFindFileData)
Definition: find.c:336
UCHAR Attributes
Definition: dos.h:131
DWORD FileSize
Definition: dos.h:134
#define FILE_ATTRIBUTE_DIRECTORY
Definition: nt_native.h:705
struct _DOS_FIND_FILE_BLOCK * PDOS_FIND_FILE_BLOCK
UCHAR AttribMask
Definition: dos.h:126
DWORD WINAPI GetShortPathNameA(IN LPCSTR lpszLongPath, OUT LPSTR lpszShortPath, IN DWORD cchBuffer)
Definition: path.c:1751
BOOL WINAPI FileTimeToDosDateTime(IN CONST FILETIME *lpFileTime, OUT LPWORD lpFatDate, OUT LPWORD lpFatTime)
Definition: time.c:37
#define FILE_ATTRIBUTE_HIDDEN
Definition: nt_native.h:703
CHAR FileName[13]
Definition: dos.h:135
BOOL WINAPI FindClose(HANDLE hFindFile)
Definition: find.c:502

Referenced by DosInt21h().

◆ demGetPhysicalDriveType()

UCHAR WINAPI demGetPhysicalDriveType ( IN UCHAR  DriveNumber)

Definition at line 1504 of file dem.c.

1505 {
1506  UNIMPLEMENTED;
1507  return DOSDEVICE_DRIVE_UNKNOWN;
1508 }
#define DOSDEVICE_DRIVE_UNKNOWN
Definition: obtypes.h:163
#define UNIMPLEMENTED
Definition: debug.h:114

◆ demIsShortPathName()

BOOL WINAPI demIsShortPathName ( IN LPCSTR  Path,
IN BOOL  Unknown 
)

Definition at line 1512 of file dem.c.

1514 {
1515  UNIMPLEMENTED;
1516  return FALSE;
1517 }
#define UNIMPLEMENTED
Definition: debug.h:114

◆ DemLoadNTDOSKernel()

static VOID DemLoadNTDOSKernel ( VOID  )
static

Definition at line 88 of file dem.c.

89 {
91  LPCSTR DosKernelFileName = "ntdos.sys";
92  HANDLE hDosKernel;
93  ULONG ulDosKernelSize = 0;
94 
95  DPRINT1("You are loading Windows NT DOS!\n");
96 
97  /* Open the DOS kernel file */
98  hDosKernel = FileOpen(DosKernelFileName, &ulDosKernelSize);
99  if (hDosKernel == NULL) goto Quit;
100 
101  /*
102  * Attempt to load the DOS kernel into memory.
103  * The segment where to load the DOS kernel is defined
104  * by the DOS BIOS and is found in DI:0000 .
105  */
106  Success = FileLoadByHandle(hDosKernel,
107  REAL_TO_PHYS(TO_LINEAR(getDI(), 0x0000)),
108  ulDosKernelSize,
109  &ulDosKernelSize);
110 
111  DPRINT1("Windows NT DOS file '%s' loading %s at %04X:%04X, size 0x%X (Error: %u).\n",
112  DosKernelFileName,
113  (Success ? "succeeded" : "failed"),
114  getDI(), 0x0000,
115  ulDosKernelSize,
116  GetLastError());
117 
118  /* Close the DOS kernel file */
119  FileClose(hDosKernel);
120 
121 Quit:
122  if (!Success)
123  {
124  /* We failed everything, stop the VDM */
125  BiosDisplayMessage("Windows NT DOS kernel file '%s' loading failed (Error: %u). The VDM will shut down.\n",
126  DosKernelFileName, GetLastError());
128  return;
129  }
130 }
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
VOID FileClose(IN HANDLE FileHandle)
Definition: utils.c:21
#define REAL_TO_PHYS(ptr)
Definition: emulator.h:33
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
const char * LPCSTR
Definition: xmlstorage.h:183
#define TO_LINEAR(seg, off)
Definition: emulator.h:22
VOID EmulatorTerminate(VOID)
Definition: emulator.c:503
HANDLE FileOpen(IN PCSTR FileName, OUT PULONG FileSize OPTIONAL)
Definition: utils.c:27
USHORT WINAPI getDI(VOID)
Definition: registers.c:434
#define DPRINT1
Definition: precomp.h:8
unsigned int ULONG
Definition: retypes.h:1
BOOLEAN FileLoadByHandle(IN HANDLE FileHandle, IN PVOID Location, IN ULONG FileSize, OUT PULONG BytesRead)
Definition: utils.c:69
#define BiosDisplayMessage(Format,...)
Definition: dem.h:33

Referenced by DosSystemBop().

◆ demSetCurrentDirectoryGetDrive()

DWORD WINAPI demSetCurrentDirectoryGetDrive ( IN LPCSTR  CurrentDirectory,
OUT PUCHAR  DriveNumber 
)

Definition at line 1521 of file dem.c.

1523 {
1524  UNIMPLEMENTED;
1525  return ERROR_SUCCESS;
1526 }
#define ERROR_SUCCESS
Definition: deptool.c:10
#define UNIMPLEMENTED
Definition: debug.h:114

◆ DosBootsectorInitialize()

VOID DosBootsectorInitialize ( VOID  )

Definition at line 1089 of file dem.c.

1090 {
1091  /* We write the bootsector at 0000:7C00 */
1092  ULONG_PTR StartAddress = (ULONG_PTR)SEG_OFF_TO_PTR(0x0000, 0x7C00);
1093  ULONG_PTR Address = StartAddress;
1094  CHAR DosKernelFileName[] = ""; // No DOS BIOS file name, therefore we will load DOS32
1095 
1096  DPRINT("DosBootsectorInitialize\n");
1097 
1098  /* Write the "bootsector" */
1100  Address += sizeof(Bootsector1);
1101  RtlCopyMemory((PVOID)Address, DosKernelFileName, sizeof(DosKernelFileName));
1102  Address += sizeof(DosKernelFileName);
1104  Address += sizeof(Bootsector2);
1105 
1106  /* Initialize the callback context */
1107  InitializeContext(&DosContext, 0x0000,
1108  (ULONG_PTR)MEM_ALIGN_UP(0x7C00 + Address - StartAddress, sizeof(WORD)));
1109 
1110  /* Register the DOS Loading BOP */
1112 }
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
VOID RegisterBop(BYTE BopCode, EMULATOR_BOP_PROC BopHandler)
Definition: bop.c:29
VOID InitializeContext(IN PCALLBACK16 Context, IN USHORT Segment, IN USHORT Offset)
Definition: callback.c:60
char CHAR
Definition: xmlstorage.h:175
#define SEG_OFF_TO_PTR(seg, off)
Definition: emulator.h:28
static VOID WINAPI DosInitialize(LPWORD Stack)
Definition: dem.c:1129
uint32_t ULONG_PTR
Definition: typedefs.h:63
CALLBACK16 DosContext
Definition: dos.c:40
static WCHAR Address[46]
Definition: ping.c:68
void DPRINT(...)
Definition: polytest.cpp:61
#define BOP_LOAD_DOS
Definition: dem.h:23
static BYTE Bootsector2[]
Definition: dem.c:1082
unsigned short WORD
Definition: ntddk_ex.h:93
#define MEM_ALIGN_UP(ptr, align)
Definition: emulator.h:20
#define ULONG_PTR
Definition: config.h:101
static BYTE Bootsector1[]
Definition: dem.c:1076

Referenced by BiosBootstrapLoader().

◆ DosCharPrint()

VOID DosCharPrint ( CHAR  Character)

Definition at line 82 of file dem.c.

83 {
85 }
#define DOS_OUTPUT_HANDLE
Definition: dos.h:43
VOID DosPrintCharacter(WORD FileHandle, CHAR Character)
Definition: bios.c:152

◆ DosCmdInterpreterBop()

static VOID WINAPI DosCmdInterpreterBop ( LPWORD  Stack)
static

Definition at line 588 of file dem.c.

589 {
590  /* Get the Function Number and skip it */
591  BYTE FuncNum = *(PBYTE)SEG_OFF_TO_PTR(getCS(), getIP());
592  setIP(getIP() + 1);
593 
594  switch (FuncNum)
595  {
596  /* Kill the VDM */
597  case 0x00:
598  {
599  /* Stop the VDM */
601  return;
602  }
603 
604  /*
605  * Get a new app to start
606  *
607  * Input
608  * DS:DX : Data block.
609  *
610  * Output
611  * CF : 0: Success; 1: Failure.
612  */
613  case 0x01:
614  {
615  CmdStartProcess();
616  break;
617  }
618 
619  /*
620  * Check binary format
621  *
622  * Input
623  * DS:DX : Program to check.
624  *
625  * Output
626  * CF : 0: Success; 1: Failure.
627  * AX : Error code.
628  */
629  case 0x07:
630  {
631  DWORD BinaryType;
632  LPSTR ProgramName = (LPSTR)SEG_OFF_TO_PTR(getDS(), getDX());
633 
634  if (!GetBinaryTypeA(ProgramName, &BinaryType))
635  {
636  /* An error happened, bail out */
637  setCF(1);
639  break;
640  }
641 
642  // FIXME: We only support DOS binaries for now...
643  ASSERT(BinaryType == SCS_DOS_BINARY);
644  if (BinaryType != SCS_DOS_BINARY)
645  {
646  /* An error happened, bail out */
647  setCF(1);
649  break;
650  }
651 
652  /* Return success: DOS application */
653  setCF(0);
654  break;
655  }
656 
657  /*
658  * Start an external command
659  *
660  * Input
661  * DS:SI : Command to start.
662  * ES : Environment block segment.
663  * AL : Current drive number.
664  * AH : 0: Directly start the command;
665  * 1: Use "cmd.exe /c" to start the command.
666  *
667  * Output
668  * CF : 0: Shell-out; 1: Continue.
669  * AL : Error/Exit code.
670  */
671  case 0x08:
672  {
674  break;
675  }
676 
677  /*
678  * Start the default 32-bit command interpreter (COMSPEC)
679  *
680  * Input
681  * ES : Environment block segment.
682  * AL : Current drive number.
683  *
684  * Output
685  * CF : 0: Shell-out; 1: Continue.
686  * AL : Error/Exit code.
687  */
688  case 0x0A:
689  {
691  break;
692  }
693 
694  /*
695  * Set exit code
696  *
697  * Input
698  * DX : Exit code
699  *
700  * Output
701  * CF : 0: Shell-out; 1: Continue.
702  */
703  case 0x0B:
704  {
705  CmdSetExitCode();
706  break;
707  }
708 
709  /*
710  * Get start information
711  *
712  * Output
713  * AL : 0 (resp. 1): Started from (resp. without) an existing console.
714  */
715  case 0x10:
716  {
717 #ifndef STANDALONE
718  /*
719  * When a new instance of our (internal) COMMAND.COM is started,
720  * we check whether we need to run a 32-bit COMSPEC. This goes by
721  * checking whether we were started in a new console (no parent
722  * console process) or from an existing one.
723  *
724  * However COMMAND.COM can also be started in the case where a
725  * 32-bit process (started by a 16-bit parent) wants to start a new
726  * 16-bit process: to ensure DOS reentry we need to start a new
727  * instance of COMMAND.COM. On Windows the COMMAND.COM is started
728  * just before the 32-bit process (in fact, it is this COMMAND.COM
729  * which starts the 32-bit process via an undocumented command-line
730  * switch '/z', which syntax is:
731  * COMMAND.COM /z\bAPPNAME.EXE
732  * notice the '\b' character inserted in-between. Then COMMAND.COM
733  * issues a BOP_CMD 08h with AH=00h to start the process).
734  *
735  * Instead, we do the reverse, i.e. we start the 32-bit process,
736  * and *only* if needed, i.e. if this process wants to start a
737  * new 16-bit process, we start our COMMAND.COM.
738  *
739  * The problem we then face is that our COMMAND.COM will possibly
740  * want to start a new COMSPEC, however we do not want this.
741  * The chosen solution is to flag this case -- done with the 'Reentry'
742  * boolean -- so that COMMAND.COM will not attempt to start COMSPEC
743  * but instead will directly try to start the 16-bit process.
744  */
745  // setAL(SessionId != 0);
746  setAL((SessionId != 0) && !Reentry);
747  /* Reset 'Reentry' */
748  Reentry = FALSE;
749 #else
750  setAL(0);
751 #endif
752  break;
753  }
754 
755  default:
756  {
757  DPRINT1("Unknown DOS CMD Interpreter BOP Function: 0x%02X\n", FuncNum);
758  // setCF(1); // Disable, otherwise we enter an infinite loop
759  break;
760  }
761  }
762 }
VOID WINAPI setIP(USHORT)
Definition: registers.c:471
VOID WINAPI setAX(USHORT)
Definition: registers.c:121
VOID WINAPI setAL(UCHAR)
Definition: registers.c:149
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
char * LPSTR
Definition: xmlstorage.h:182
#define SEG_OFF_TO_PTR(seg, off)
Definition: emulator.h:28
#define SCS_DOS_BINARY
Definition: winbase.h:235
VOID WINAPI setCF(ULONG)
Definition: registers.c:573
#define ERROR_BAD_EXE_FORMAT
Definition: winerror.h:251
USHORT WINAPI getIP(VOID)
Definition: registers.c:464
unsigned long DWORD
Definition: ntddk_ex.h:95
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
BOOL WINAPI GetBinaryTypeA(IN LPCSTR lpApplicationName, OUT LPDWORD lpBinaryType)
Definition: vdm.c:1327
static VOID CmdStartExternalCommand(VOID)
Definition: dem.c:411
static VOID CmdSetExitCode(VOID)
Definition: dem.c:505
USHORT WINAPI getDX(VOID)
Definition: registers.c:286
unsigned char BYTE
Definition: mem.h:68
VOID EmulatorTerminate(VOID)
Definition: emulator.c:503
static BOOLEAN Reentry
Definition: dem.c:248
static ULONG SessionId
Definition: dem.c:179
static VOID CmdStartComSpec32(VOID)
Definition: dem.c:465
#define DPRINT1
Definition: precomp.h:8
static VOID CmdStartProcess(VOID)
Definition: dem.c:290
USHORT WINAPI getDS(VOID)
Definition: registers.c:508
USHORT WINAPI getCS(VOID)
Definition: registers.c:480
BYTE * PBYTE
Definition: pedump.c:66
#define LOWORD(l)
Definition: pedump.c:82

Referenced by DosInitialize().

◆ DosInitialize()

static VOID WINAPI DosInitialize ( LPWORD  Stack)
static

Definition at line 1129 of file dem.c.

1130 {
1131  /* Get the DOS BIOS file name (NULL-terminated) */
1132  // FIXME: Isn't it possible to use some DS:SI instead??
1133  LPCSTR DosBiosFileName = (LPCSTR)SEG_OFF_TO_PTR(getCS(), getIP());
1134  setIP(getIP() + strlen(DosBiosFileName) + 1); // Skip it
1135 
1136  DPRINT("DosInitialize('%s')\n", DosBiosFileName);
1137 
1138  /*
1139  * We succeeded, deregister the DOS Loading BOP
1140  * so that no app will be able to call us back.
1141  */
1143 
1144  /* Register the DOS BOPs */
1147 
1148  if (DosBiosFileName[0] != '\0')
1149  {
1150  BOOLEAN Success = FALSE;
1151  HANDLE hDosBios;
1152  ULONG ulDosBiosSize = 0;
1153 
1154  /* Open the DOS BIOS file */
1155  hDosBios = FileOpen(DosBiosFileName, &ulDosBiosSize);
1156  if (hDosBios == NULL) goto Quit;
1157 
1158  /* Attempt to load the DOS BIOS into memory */
1159  Success = FileLoadByHandle(hDosBios,
1160  REAL_TO_PHYS(TO_LINEAR(0x0070, 0x0000)),
1161  ulDosBiosSize,
1162  &ulDosBiosSize);
1163 
1164  DPRINT1("DOS BIOS file '%s' loading %s at %04X:%04X, size 0x%X (Error: %u).\n",
1165  DosBiosFileName,
1166  (Success ? "succeeded" : "failed"),
1167  0x0070, 0x0000,
1168  ulDosBiosSize,
1169  GetLastError());
1170 
1171  /* Close the DOS BIOS file */
1172  FileClose(hDosBios);
1173 
1174 Quit:
1175  if (!Success)
1176  {
1177  BiosDisplayMessage("DOS BIOS file '%s' loading failed (Error: %u). The VDM will shut down.\n",
1178  DosBiosFileName, GetLastError());
1179  return;
1180  }
1181  }
1182  else
1183  {
1184  /* Load the 16-bit startup code for DOS32 and register its Starting BOP */
1185  RtlCopyMemory(SEG_OFF_TO_PTR(0x0070, 0x0000), Startup, sizeof(Startup));
1186 
1187  // This is the equivalent of BOP_LOAD_DOS, function 0x11 "Load the DOS kernel"
1188  // for the Windows NT DOS.
1190  }
1191 
1192  /* Position execution pointers for DOS startup and return */
1193  setCS(0x0070);
1194  setIP(0x0000);
1195 }
static BYTE Startup[]
Definition: dem.c:1121
VOID WINAPI setIP(USHORT)
Definition: registers.c:471
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define BOP_START_DOS
Definition: dem.h:24
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
VOID RegisterBop(BYTE BopCode, EMULATOR_BOP_PROC BopHandler)
Definition: bop.c:29
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
VOID FileClose(IN HANDLE FileHandle)
Definition: utils.c:21
#define SEG_OFF_TO_PTR(seg, off)
Definition: emulator.h:28
#define BOP_DOS
Definition: dem.h:25
#define REAL_TO_PHYS(ptr)
Definition: emulator.h:33
unsigned char BOOLEAN
#define BOP_CMD
Definition: dem.h:26
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
const char * LPCSTR
Definition: xmlstorage.h:183
#define BOP_LOAD_DOS
Definition: dem.h:23
static VOID WINAPI DosCmdInterpreterBop(LPWORD Stack)
Definition: dem.c:588
USHORT WINAPI getIP(VOID)
Definition: registers.c:464
#define TO_LINEAR(seg, off)
Definition: emulator.h:22
static VOID WINAPI DosStart(LPWORD Stack)
Definition: dem.c:1197
HANDLE FileOpen(IN PCSTR FileName, OUT PULONG FileSize OPTIONAL)
Definition: utils.c:27
static VOID WINAPI DosSystemBop(LPWORD Stack)
Definition: dem.c:132
VOID WINAPI setCS(USHORT)
Definition: registers.c:487
#define DPRINT1
Definition: precomp.h:8
unsigned int ULONG
Definition: retypes.h:1
BOOLEAN FileLoadByHandle(IN HANDLE FileHandle, IN PVOID Location, IN ULONG FileSize, OUT PULONG BytesRead)
Definition: utils.c:69
USHORT WINAPI getCS(VOID)
Definition: registers.c:480
#define BiosDisplayMessage(Format,...)
Definition: dem.h:33

Referenced by DosBootsectorInitialize().

◆ DosProcessConsoleAttach()

static VOID DosProcessConsoleAttach ( VOID  )
static

Definition at line 228 of file dem.c.

229 {
230  /* Attach to the console */
231  ConsoleAttach();
233 }
VOID VidBiosAttachToConsole(VOID)
Definition: vidbios.c:3907
BOOL ConsoleAttach(VOID)
Definition: console.c:398

Referenced by DosStart(), and DosStartProcess32().

◆ DosProcessConsoleDetach()

static VOID DosProcessConsoleDetach ( VOID  )
static

Definition at line 235 of file dem.c.

236 {
237  /* Detach from the console */
239  ConsoleDetach();
240 }
VOID VidBiosDetachFromConsole(VOID)
Definition: vidbios.c:3920
VOID ConsoleDetach(VOID)
Definition: console.c:424

Referenced by DosStartProcess32().

◆ DosShutdown()

BOOLEAN DosShutdown ( BOOLEAN  Immediate)

Definition at line 1331 of file dem.c.

1332 {
1333  /*
1334  * Immediate = TRUE: Immediate shutdown;
1335  * FALSE: Delayed shutdown (notification).
1336  */
1337 
1338 #ifndef STANDALONE
1339  if (Immediate)
1340  {
1341  ExitVDM(FALSE, 0);
1342  return TRUE;
1343  }
1344  else
1345  {
1346 // HACK!
1347 extern HANDLE VdmTaskEvent; // see emulator.c
1348 
1349  /*
1350  * Signal the root COMMAND.COM that it should terminate
1351  * when it checks for a new command.
1352  */
1354 
1355  /* If the list is already empty, or just contains only one element, bail out */
1356  // FIXME: Question: if the list has only one element, is it ALWAYS RootCmd ??
1357  // FIXME: The following is hackish.
1358  if ((IsListEmpty(&ComSpecInfoList) ||
1361  ReentrancyCount == 0 &&
1363  {
1364  /* Nothing runs, so exit immediately */
1365  ExitVDM(FALSE, 0);
1366  return TRUE;
1367  }
1368 
1369  return FALSE;
1370  }
1371 #else
1372  UNREFERENCED_PARAMETER(Immediate);
1373  return TRUE;
1374 #endif
1375 }
#define TRUE
Definition: types.h:120
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:323
struct _LIST_ENTRY * Blink
Definition: typedefs.h:120
static COMSPEC_INFO RootCmd
Definition: dem.c:192
HANDLE VdmTaskEvent
Definition: emulator.c:51
VOID WINAPI ExitVDM(BOOL IsWow, ULONG iWowTask)
Definition: vdm.c:1384
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
LIST_ENTRY Entry
Definition: dem.c:186
static LIST_ENTRY ComSpecInfoList
Definition: dem.c:196
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
BOOLEAN Terminated
Definition: dem.c:189
#define WAIT_TIMEOUT
Definition: dderror.h:14
static DWORD ReentrancyCount
Definition: dem.c:193

Referenced by VdmShutdown().

◆ DosStart()

static VOID WINAPI DosStart ( LPWORD  Stack)
static

Definition at line 1197 of file dem.c.

1198 {
1199  BOOLEAN Success;
1200  DWORD Result;
1201 #ifndef STANDALONE
1202  INT i;
1203 #endif
1204 
1205  DPRINT("DosStart\n");
1206 
1207  /*
1208  * We succeeded, deregister the DOS Starting BOP
1209  * so that no app will be able to call us back.
1210  */
1212 
1213  /* Initialize the callback context */
1215 
1217 // Success &= DosKRNLInitialize();
1218  if (!Success)
1219  {
1220  BiosDisplayMessage("DOS32 loading failed (Error: %u). The VDM will shut down.\n", GetLastError());
1222  return;
1223  }
1224 
1225  /* Load the mouse driver */
1227 
1228 #ifndef STANDALONE
1229 
1230  /* Parse the command line arguments */
1231  for (i = 1; i < NtVdmArgc; i++)
1232  {
1233  if (wcsncmp(NtVdmArgv[i], L"-i", 2) == 0)
1234  {
1235  /* This is the session ID (hex format) */
1236  SessionId = wcstoul(NtVdmArgv[i] + 2, NULL, 16);
1237  }
1238  }
1239 
1240  /* Initialize Win32-VDM environment */
1241  Env = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, EnvSize);
1242  if (Env == NULL)
1243  {
1244  DosDisplayMessage("Failed to initialize the global environment (Error: %u). The VDM will shut down.\n", GetLastError());
1246  return;
1247  }
1248 
1249  /* Clear the structure */
1251 
1252  /* Get the initial information */
1256 
1257 #else
1258 
1259  /* Retrieve the command to start */
1260  if (NtVdmArgc >= 2)
1261  {
1262  WideCharToMultiByte(CP_ACP, 0, NtVdmArgv[1], -1, AppName, sizeof(AppName), NULL, NULL);
1263 
1264  if (NtVdmArgc >= 3)
1265  WideCharToMultiByte(CP_ACP, 0, NtVdmArgv[2], -1, CmdLine, sizeof(CmdLine), NULL, NULL);
1266  else
1267  strcpy(CmdLine, "");
1268  }
1269  else
1270  {
1271  DosDisplayMessage("Invalid DOS command line\n");
1273  return;
1274  }
1275 
1276 #endif
1277 
1278  /*
1279  * At this point, CS:IP points to the DOS BIOS exit code. If the
1280  * root command interpreter fails to start (or if it exits), DOS
1281  * exits and the VDM terminates.
1282  */
1283 
1284  /* Start the root command interpreter */
1285  // TODO: Really interpret the 'SHELL=' line of CONFIG.NT, and use it!
1286 
1287  /*
1288  * Prepare the stack for DosStartComSpec:
1289  * push Flags, CS and IP, and an extra WORD.
1290  */
1291  setSP(getSP() - sizeof(WORD));
1292  *((LPWORD)SEG_OFF_TO_PTR(getSS(), getSP())) = (WORD)getEFLAGS();
1293  setSP(getSP() - sizeof(WORD));
1294  *((LPWORD)SEG_OFF_TO_PTR(getSS(), getSP())) = getCS();
1295  setSP(getSP() - sizeof(WORD));
1296  *((LPWORD)SEG_OFF_TO_PTR(getSS(), getSP())) = getIP();
1297  setSP(getSP() - sizeof(WORD));
1298 
1300  MAKELONG(getIP(), getCS()),
1301 #ifndef STANDALONE
1303 #else
1304  NULL
1305 #endif
1306  );
1307  if (Result != ERROR_SUCCESS)
1308  {
1309  /* Unprepare the stack for DosStartComSpec */
1310  setSP(getSP() + 4*sizeof(WORD));
1311 
1312  DosDisplayMessage("Failed to start the Command Interpreter (Error: %u). The VDM will shut down.\n", Result);
1314  return;
1315  }
1316 
1317 #ifndef STANDALONE
1320 #endif
1321 
1322 
1323  /* Attach to the console and resume the VM */
1325  EmulatorResume();
1326 
1327 
1328  return;
1329 }
INT NtVdmArgc
Definition: ntvdm.c:28
#define TRUE
Definition: types.h:120
#define BOP_START_DOS
Definition: dem.h:24
#define ERROR_SUCCESS
Definition: deptool.c:10
#define WideCharToMultiByte
Definition: compat.h:101
WORD ComSpecPsp
Definition: dem.c:188
static VDM_COMMAND_INFO CommandInfo
Definition: dem.c:246
static VOID InsertComSpecInfo(PCOMSPEC_INFO ComSpecInfo)
Definition: dem.c:214
#define BIOS_CODE_SEGMENT
Definition: dos.h:30
#define SYSTEM_ENV_BLOCK
Definition: dos.h:37
VOID RegisterBop(BYTE BopCode, EMULATOR_BOP_PROC BopHandler)
Definition: bop.c:29
#define CP_ACP
Definition: compat.h:99
VOID InitializeContext(IN PCALLBACK16 Context, IN USHORT Segment, IN USHORT Offset)
Definition: callback.c:60
static CHAR CmdLine[MAX_PATH]
Definition: dem.c:251
static CHAR AppName[MAX_PATH]
Definition: dem.c:252
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
static COMSPEC_INFO RootCmd
Definition: dem.c:192
USHORT WINAPI getSS(VOID)
Definition: registers.c:494
_Check_return_ unsigned long __cdecl wcstoul(_In_z_ const wchar_t *_Str, _Out_opt_ _Deref_post_z_ wchar_t **_EndPtr, _In_ int _Radix)
#define DosDisplayMessage(Format,...)
Definition: dem.h:37
#define SEG_OFF_TO_PTR(seg, off)
Definition: emulator.h:28
int32_t INT
Definition: typedefs.h:56
#define STANDALONE
Definition: testlist.c:3
static VOID DosProcessConsoleAttach(VOID)
Definition: dem.c:228
static ULONG EnvSize
Definition: dem.c:258
VOID WINAPI setSP(USHORT)
Definition: registers.c:351
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
ULONG WINAPI getEFLAGS(VOID)
Definition: registers.c:680
CALLBACK16 DosContext
Definition: dos.c:40
#define VDM_GET_FIRST_COMMAND
Definition: vdm.h:61
#define MAKELONG(a, b)
Definition: typedefs.h:248
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:426
WCHAR ** NtVdmArgv
Definition: ntvdm.c:29
#define VDM_FLAG_DOS
Definition: vdm.h:55
void DPRINT(...)
Definition: polytest.cpp:61
USHORT VDMState
Definition: vdm.h:94
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:585
BOOLEAN DosBIOSInitialize(VOID)
Definition: bios.c:221
USHORT WINAPI getIP(VOID)
Definition: registers.c:464
BOOLEAN Terminated
Definition: dem.c:189
unsigned short WORD
Definition: ntddk_ex.h:93
static PVOID Env
Definition: dem.c:259
unsigned long DWORD
Definition: ntddk_ex.h:95
_Check_return_ _CRTIMP int __cdecl wcsncmp(_In_reads_or_z_(_MaxCount) const wchar_t *_Str1, _In_reads_or_z_(_MaxCount) const wchar_t *_Str2, _In_ size_t _MaxCount)
static DWORD DosStartComSpec(IN BOOLEAN Permanent, IN LPCSTR Environment OPTIONAL, IN DWORD ReturnAddress OPTIONAL, OUT PWORD ComSpecPsp OPTIONAL)
Definition: dem.c:772
static const WCHAR L[]
Definition: oid.c:1250
BOOLEAN DosMouseInitialize(VOID)
Definition: mouse32.c:1260
VOID EmulatorTerminate(VOID)
Definition: emulator.c:503
uint16_t * LPWORD
Definition: typedefs.h:54
static ULONG SessionId
Definition: dem.c:179
#define HEAP_ZERO_MEMORY
Definition: compat.h:123
VOID EmulatorResume(VOID)
Definition: emulator.c:495
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
USHORT WINAPI getSP(VOID)
Definition: registers.c:344
BOOL WINAPI GetNextVDMCommand(PVDM_COMMAND_INFO CommandData)
Definition: vdm.c:1412
USHORT WINAPI getCS(VOID)
Definition: registers.c:480
ULONG TaskId
Definition: vdm.h:70
#define BiosDisplayMessage(Format,...)
Definition: dem.h:33

Referenced by DosInitialize().

◆ DosStartComSpec()

static DWORD DosStartComSpec ( IN BOOLEAN  Permanent,
IN LPCSTR Environment  OPTIONAL,
IN DWORD ReturnAddress  OPTIONAL,
OUT PWORD ComSpecPsp  OPTIONAL 
)
static

Definition at line 772 of file dem.c.

776 {
777  /*
778  * BOOLEAN Permanent
779  * TRUE to simulate the /P switch of command.com: starts AUTOEXEC.BAT/NT
780  * and makes the interpreter permanent (cannot exit).
781  */
782 
783  DWORD Result;
784 
785  if (ComSpecPsp) *ComSpecPsp = 0;
786 
787  Result =
788 #ifndef COMSPEC_FULLY_EXTERNAL
790  CommandCom,
791  sizeof(CommandCom),
792  "COMMAND.COM",
793 #else
795 #ifndef STANDALONE // FIXME: Those values are hardcoded paths on my local test machines!!
796  "C:\\CMDCMD.COM",
797 #else
798  "H:\\DOS_tests\\CMDCMD.COM",
799 #endif // STANDALONE
800 #endif // COMSPEC_FULLY_EXTERNAL
801  NULL,
802  Permanent ? "/P" : "",
803  Environment ? Environment : "", // FIXME: Default environment!
804  ReturnAddress);
805  if (Result != ERROR_SUCCESS) return Result;
806 
807  /* TODO: Read AUTOEXEC.NT/BAT */
808 
809  /* Retrieve the PSP of the COMSPEC (current PSP set by DosLoadExecutable) */
810  if (ComSpecPsp) *ComSpecPsp = Sda->CurrentPsp;
811 
812  return Result;
813 }
PVOID PVOID PWCHAR PVOID Environment
Definition: env.c:45
WORD CurrentPsp
Definition: dos.h:156
#define ERROR_SUCCESS
Definition: deptool.c:10
#define STANDALONE
Definition: testlist.c:3
smooth NULL
Definition: ftsmooth.c:416
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:426
unsigned long DWORD
Definition: ntddk_ex.h:95
PDOS_SDA Sda
Definition: dos.c:48
DWORD DosLoadExecutableInternal(IN DOS_EXEC_TYPE LoadType, IN LPBYTE ExeBuffer, IN DWORD ExeBufferSize, IN LPCSTR ExePath, IN PDOS_EXEC_PARAM_BLOCK Parameters, IN LPCSTR CommandLine OPTIONAL, IN LPCSTR Environment OPTIONAL, IN DWORD ReturnAddress OPTIONAL)
Definition: process.c:327
DWORD DosLoadExecutable(IN DOS_EXEC_TYPE LoadType, IN LPCSTR ExecutablePath, IN PDOS_EXEC_PARAM_BLOCK Parameters, IN LPCSTR CommandLine OPTIONAL, IN LPCSTR Environment OPTIONAL, IN DWORD ReturnAddress OPTIONAL)
Definition: process.c:695

Referenced by DosStart(), and DosStartProcess32().

◆ DosStartProcess32()

DWORD DosStartProcess32 ( IN LPCSTR  ExecutablePath,
IN LPCSTR  CommandLine,
IN LPCSTR Environment  OPTIONAL,
IN DWORD ReturnAddress  OPTIONAL,
IN BOOLEAN  StartComSpec 
)

Definition at line 916 of file dem.c.

921 {
923  HANDLE CommandThread;
924  DOS_START_PROC32 DosStartProc32;
925 #ifndef STANDALONE
926  BOOL Success;
928 #endif
929 
930  DosStartProc32.ExecutablePath = (LPSTR)ExecutablePath;
931  DosStartProc32.CommandLine = (LPSTR)CommandLine;
932  DosStartProc32.Environment = (LPSTR)Environment;
933 
934 #ifndef STANDALONE
935  DosStartProc32.ComSpecInfo =
936  RtlAllocateHeap(RtlGetProcessHeap(),
938  sizeof(*DosStartProc32.ComSpecInfo));
939  ASSERT(DosStartProc32.ComSpecInfo);
940 
941  DosStartProc32.hEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
942  ASSERT(DosStartProc32.hEvent);
943 #endif
944 
945  /* Pause the VM and detach from the console */
946  EmulatorPause();
948 
949  /* Start the 32-bit process via another thread */
950  CommandThread = CreateThread(NULL, 0, &CommandThreadProc, &DosStartProc32, 0, NULL);
951  if (CommandThread == NULL)
952  {
953  DisplayMessage(L"FATAL: Failed to create the command processing thread: %d", GetLastError());
954  Result = GetLastError();
955  goto Quit;
956  }
957 
958 #ifndef STANDALONE
959  /* Close the thread handle */
960  CloseHandle(CommandThread);
961 
962  /* Wait for the process to be ready to start */
963  WaitForSingleObject(DosStartProc32.hEvent, INFINITE);
964 
965  /* Wait for any potential new DOS app started by the 32-bit process */
967 
968 Retry:
970  DPRINT1("Calling GetNextVDMCommand 32bit for possible new VDM task...\n");
972  DPRINT1("GetNextVDMCommand 32bit awaited, success = %s, last error = %d\n", Success ? "true" : "false", GetLastError());
973 
974  /*
975  * Check whether we were awaited because the 32-bit process was stopped,
976  * or because it started a new DOS application.
977  */
978  if (CommandInfo.CmdLen != 0 || CommandInfo.AppLen != 0 || CommandInfo.PifLen != 0)
979  {
980  DPRINT1("GetNextVDMCommand 32bit, this is for a new VDM task - CmdLen = %d, AppLen = %d, PifLen = %d\n",
982 
983  /* Repeat the request */
984  Repeat = TRUE;
985 
986  /*
987  * Set 'Reentry' to TRUE or FALSE depending on whether we are going
988  * to reenter with a new COMMAND.COM. See the comment for:
989  * BOP_CMD 0x10 'Get start information'
990  * (dem.c!DosCmdInterpreterBop) for more details.
991  */
992  Reentry = StartComSpec;
993 
994  /* If needed, start a new command interpreter to handle the possible incoming DOS commands */
995  if (StartComSpec)
996  {
997  //
998  // DosStartProcess32 was only called by DosCreateProcess, called from INT 21h,
999  // so the caller stack is already prepared for running a new DOS program
1000  // (Flags, CS and IP, and the extra interrupt number, are already pushed).
1001  //
1002  Result = DosStartComSpec(FALSE, Environment, ReturnAddress,
1003  &DosStartProc32.ComSpecInfo->ComSpecPsp);
1004  if (Result != ERROR_SUCCESS)
1005  {
1006  DosDisplayMessage("Failed to start a new Command Interpreter (Error: %u).\n", Result);
1007  goto Quit;
1008  }
1009  }
1010  else
1011  {
1012  /* Retrieve the PSP of the COMSPEC (current PSP set by DosLoadExecutable) */
1013  DosStartProc32.ComSpecInfo->ComSpecPsp = Sda->CurrentPsp;
1015  }
1016 
1017  /* Insert the new entry in the list; it will be freed when needed by COMMAND.COM */
1018  InsertComSpecInfo(DosStartProc32.ComSpecInfo);
1019  }
1020  else
1021  {
1022  DPRINT1("GetNextVDMCommand 32bit, 32-bit app stopped\n");
1023 
1024  /* Check whether this was our 32-bit app which was killed */
1025  if (!DosStartProc32.ComSpecInfo->Terminated)
1026  {
1027  DPRINT1("Not our 32-bit app, retrying...\n");
1028  goto Retry;
1029  }
1030 
1031  Result = DosStartProc32.ComSpecInfo->dwExitCode;
1032 
1033  /* Delete the entry */
1034  RtlFreeHeap(RtlGetProcessHeap(), 0, DosStartProc32.ComSpecInfo);
1035  }
1036 #else
1037  /* Wait for the thread to finish */
1038  WaitForSingleObject(CommandThread, INFINITE);
1039  GetExitCodeThread(CommandThread, &Result);
1040 
1041  /* Close the thread handle */
1042  CloseHandle(CommandThread);
1043 
1044  DPRINT1("32-bit app stopped\n");
1045 #endif
1046 
1047 Quit:
1048 #ifndef STANDALONE
1049  CloseHandle(DosStartProc32.hEvent);
1050 #endif
1051 
1052  /* Attach to the console and resume the VM */
1054  EmulatorResume();
1055 
1056  return Result;
1057 }
HANDLE hEvent
Definition: dem.c:822
PVOID PVOID PWCHAR PVOID Environment
Definition: env.c:45
WORD CurrentPsp
Definition: dos.h:156
#define TRUE
Definition: types.h:120
#define CloseHandle
Definition: compat.h:398
#define ERROR_SUCCESS
Definition: deptool.c:10
WORD ComSpecPsp
Definition: dem.c:188
static VDM_COMMAND_INFO CommandInfo
Definition: dem.c:246
static VOID InsertComSpecInfo(PCOMSPEC_INFO ComSpecInfo)
Definition: dem.c:214
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:603
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
USHORT PifLen
Definition: vdm.h:92
DWORD dwExitCode
Definition: dem.c:187
USHORT CmdLen
Definition: vdm.h:90
char * LPSTR
Definition: xmlstorage.h:182
#define DosDisplayMessage(Format,...)
Definition: dem.h:37
static VOID DosProcessConsoleAttach(VOID)
Definition: dem.c:228
HANDLE WINAPI DECLSPEC_HOTPATCH CreateEventW(IN LPSECURITY_ATTRIBUTES lpEventAttributes OPTIONAL, IN BOOL bManualReset, IN BOOL bInitialState, IN LPCWSTR lpName OPTIONAL)
Definition: synch.c:597
BOOL WINAPI GetExitCodeThread(IN HANDLE hThread, OUT LPDWORD lpExitCode)
Definition: thread.c:502
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
unsigned int BOOL
Definition: ntddk_ex.h:94
PCOMSPEC_INFO ComSpecInfo
Definition: dem.c:821
HANDLE WINAPI DECLSPEC_HOTPATCH CreateThread(IN LPSECURITY_ATTRIBUTES lpThreadAttributes, IN DWORD dwStackSize, IN LPTHREAD_START_ROUTINE lpStartAddress, IN LPVOID lpParameter, IN DWORD dwCreationFlags, OUT LPDWORD lpThreadId)
Definition: thread.c:111
smooth NULL
Definition: ftsmooth.c:416
LPSTR ExecutablePath
Definition: dem.c:817
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:426
IN PSCSI_REQUEST_BLOCK IN OUT NTSTATUS IN OUT BOOLEAN * Retry
Definition: class2.h:49
USHORT VDMState
Definition: vdm.h:94
#define VDM_FLAG_NESTED_TASK
Definition: vdm.h:59
static DWORD WINAPI CommandThreadProc(LPVOID Parameter)
Definition: dem.c:828
static VOID DosProcessConsoleDetach(VOID)
Definition: dem.c:235
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:585
BOOLEAN Terminated
Definition: dem.c:189
USHORT AppLen
Definition: vdm.h:91
unsigned long DWORD
Definition: ntddk_ex.h:95
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
static DWORD DosStartComSpec(IN BOOLEAN Permanent, IN LPCSTR Environment OPTIONAL, IN DWORD ReturnAddress OPTIONAL, OUT PWORD ComSpecPsp OPTIONAL)
Definition: dem.c:772
VOID EmulatorPause(VOID)
Definition: emulator.c:487
static const WCHAR L[]
Definition: oid.c:1250
PDOS_SDA Sda
Definition: dos.c:48
static BOOLEAN Repeat
Definition: dem.c:247
static BOOLEAN Reentry
Definition: dem.c:248
LPSTR CommandLine
Definition: dem.c:818
#define HEAP_ZERO_MEMORY
Definition: compat.h:123
#define DPRINT1
Definition: precomp.h:8
VOID EmulatorResume(VOID)
Definition: emulator.c:495
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
BOOL WINAPI GetNextVDMCommand(PVDM_COMMAND_INFO CommandData)
Definition: vdm.c:1412
void DisplayMessage(BOOL bConsole, BOOL bSilent, LPCTSTR lpMessage, LPCTSTR lpTitle, UINT uType)
Definition: regsvr32.c:239
#define INFINITE
Definition: serial.h:102
#define VDM_FLAG_DONT_WAIT
Definition: vdm.h:60

Referenced by CmdStartComSpec32(), CmdStartExternalCommand(), and DosCreateProcess().

◆ DosSystemBop()

static VOID WINAPI DosSystemBop ( LPWORD  Stack)
static

Definition at line 132 of file dem.c.

133 {
134  /* Get the Function Number and skip it */
135  BYTE FuncNum = *(PBYTE)SEG_OFF_TO_PTR(getCS(), getIP());
136  setIP(getIP() + 1);
137 
138  switch (FuncNum)
139  {
140  /* Load the DOS kernel */
141  case 0x11:
142  {
144  break;
145  }
146 
147  /* Call 32-bit Driver Strategy Routine */
148  case BOP_DRV_STRATEGY:
149  {
151  break;
152  }
153 
154  /* Call 32-bit Driver Interrupt Routine */
155  case BOP_DRV_INTERRUPT:
156  {
158  break;
159  }
160 
161  default:
162  {
163  DPRINT1("Unknown DOS System BOP Function: 0x%02X\n", FuncNum);
164  // setCF(1); // Disable, otherwise we enter an infinite loop
165  break;
166  }
167  }
168 }
VOID WINAPI setIP(USHORT)
Definition: registers.c:471
#define BOP_DRV_STRATEGY
Definition: device.h:18
static VOID DemLoadNTDOSKernel(VOID)
Definition: dem.c:88
#define SEG_OFF_TO_PTR(seg, off)
Definition: emulator.h:28
#define BOP_DRV_INTERRUPT
Definition: device.h:19
VOID DeviceStrategyBop(VOID)
Definition: device.c:430
USHORT WINAPI getIP(VOID)
Definition: registers.c:464
VOID DeviceInterruptBop(VOID)
Definition: device.c:436
unsigned char BYTE
Definition: mem.h:68
#define DPRINT1
Definition: precomp.h:8
USHORT WINAPI getCS(VOID)
Definition: registers.c:480
BYTE * PBYTE
Definition: pedump.c:66

Referenced by DosInitialize().

◆ FindComSpecInfoByPsp()

static PCOMSPEC_INFO FindComSpecInfoByPsp ( WORD  Psp)
static

Definition at line 199 of file dem.c.

200 {
201  PLIST_ENTRY Pointer;
202  PCOMSPEC_INFO ComSpecInfo;
203 
204  for (Pointer = ComSpecInfoList.Flink; Pointer != &ComSpecInfoList; Pointer = Pointer->Flink)
205  {
206  ComSpecInfo = CONTAINING_RECORD(Pointer, COMSPEC_INFO, Entry);
207  if (ComSpecInfo->ComSpecPsp == Psp) return ComSpecInfo;
208  }
209 
210  return NULL;
211 }
WORD ComSpecPsp
Definition: dem.c:188
static LIST_ENTRY ComSpecInfoList
Definition: dem.c:196
smooth NULL
Definition: ftsmooth.c:416
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
Definition: typedefs.h:117
base of all file and directory entries
Definition: entries.h:82

Referenced by CmdSetExitCode(), and CmdStartProcess().

◆ InsertComSpecInfo()

static VOID InsertComSpecInfo ( PCOMSPEC_INFO  ComSpecInfo)
static

Definition at line 214 of file dem.c.

215 {
216  InsertHeadList(&ComSpecInfoList, &ComSpecInfo->Entry);
217 }
FORCEINLINE VOID InsertHeadList(_Inout_ PLIST_ENTRY ListHead, _Inout_ __drv_aliasesMem PLIST_ENTRY Entry)
Definition: rtlfuncs.h:201
LIST_ENTRY Entry
Definition: dem.c:186
static LIST_ENTRY ComSpecInfoList
Definition: dem.c:196

Referenced by DosStart(), and DosStartProcess32().

◆ RemoveComSpecInfo()

static VOID RemoveComSpecInfo ( PCOMSPEC_INFO  ComSpecInfo)
static

Definition at line 220 of file dem.c.

221 {
222  RemoveEntryList(&ComSpecInfo->Entry);
223  if (ComSpecInfo != &RootCmd)
224  RtlFreeHeap(RtlGetProcessHeap(), 0, ComSpecInfo);
225 }
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:603
static COMSPEC_INFO RootCmd
Definition: dem.c:192
LIST_ENTRY Entry
Definition: dem.c:186
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105

Referenced by CmdSetExitCode(), and CmdStartProcess().

Variable Documentation

◆ AppName

◆ Bootsector1

BYTE Bootsector1[]
static
Initial value:
=
{
}
#define LOBYTE(W)
Definition: jmemdos.c:487
#define HIBYTE(W)
Definition: jmemdos.c:486
#define BOP_LOAD_DOS
Definition: dem.h:23
#define EMULATOR_BOP
Definition: bop.h:16

Definition at line 1076 of file dem.c.

Referenced by DosBootsectorInitialize().

◆ Bootsector2

BYTE Bootsector2[]
static
Initial value:
=
{
}
#define LOBYTE(W)
Definition: jmemdos.c:487
#define HIBYTE(W)
Definition: jmemdos.c:486
#define BOP_UNSIMULATE
Definition: isvbop.h:31
#define EMULATOR_BOP
Definition: bop.h:16

Definition at line 1082 of file dem.c.

Referenced by DosBootsectorInitialize().

◆ CmdLine

CHAR CmdLine[MAX_PATH] = ""
static

Definition at line 251 of file dem.c.

Referenced by CmdStartComSpec32(), CmdStartExternalCommand(), CmdStartProcess(), and DosStart().

◆ CommandInfo

◆ ComSpecInfoList

LIST_ENTRY ComSpecInfoList = { &ComSpecInfoList, &ComSpecInfoList }
static

Definition at line 196 of file dem.c.

Referenced by DosShutdown(), FindComSpecInfoByPsp(), and InsertComSpecInfo().

◆ CurDirectory

CHAR CurDirectory[MAX_PATH] = ""
static

Definition at line 255 of file dem.c.

Referenced by CmdStartProcess().

◆ Desktop

◆ Env

PVOID Env = NULL
static

Definition at line 259 of file dem.c.

Referenced by CmdStartProcess(), DosStart(), and test_Predefined().

◆ EnvSize

ULONG EnvSize = 256
static

Definition at line 258 of file dem.c.

Referenced by CmdStartProcess(), DosStart(), and test_Predefined().

◆ First

BOOLEAN First = TRUE
static

Definition at line 250 of file dem.c.

Referenced by CmdStartProcess().

◆ PifFile

CHAR PifFile[MAX_PATH] = ""
static

Definition at line 254 of file dem.c.

Referenced by CmdStartProcess().

◆ ReentrancyCount

DWORD ReentrancyCount = 0
static

Definition at line 193 of file dem.c.

Referenced by CommandThreadProc(), and DosShutdown().

◆ Reentry

BOOLEAN Reentry = FALSE
static

Definition at line 248 of file dem.c.

Referenced by DosCmdInterpreterBop(), and DosStartProcess32().

◆ Repeat

◆ RootCmd

COMSPEC_INFO RootCmd
static

Definition at line 192 of file dem.c.

Referenced by CmdSetExitCode(), DosShutdown(), DosStart(), and RemoveComSpecInfo().

◆ SessionId

ULONG SessionId = 0
static

Definition at line 179 of file dem.c.

Referenced by CmdSetExitCode(), CmdStartProcess(), DosCmdInterpreterBop(), and DosStart().

◆ Startup

BYTE Startup[]
static
Initial value:
=
{
}
#define BOP_START_DOS
Definition: dem.h:24
#define LOBYTE(W)
Definition: jmemdos.c:487
#define HIBYTE(W)
Definition: jmemdos.c:486
#define BOP_UNSIMULATE
Definition: isvbop.h:31
#define EMULATOR_BOP
Definition: bop.h:16

Definition at line 1121 of file dem.c.

Referenced by DosInitialize().

◆ Title

CHAR Title[MAX_PATH] = ""
static

Definition at line 257 of file dem.c.

Referenced by CmdStartProcess().