Author: hbelusca
Date: Mon Jun 17 00:00:36 2013
New Revision: 59249
URL:
http://svn.reactos.org/svn/reactos?rev=59249&view=rev
Log:
[NTVDM]
Start of an implementation of a software DOS emulator.
Brought to you by Aleksandar Andrejevic. Good luck ;)
Remove the old language files. They will be recreated when the time comes.
Added:
branches/ntvdm/subsystems/ntvdm/bios.c (with props)
branches/ntvdm/subsystems/ntvdm/dos.c (with props)
branches/ntvdm/subsystems/ntvdm/emulator.c (with props)
branches/ntvdm/subsystems/ntvdm/ntvdm.h (with props)
Removed:
branches/ntvdm/subsystems/ntvdm/lang/bg-BG.rc
branches/ntvdm/subsystems/ntvdm/lang/cs-CZ.rc
branches/ntvdm/subsystems/ntvdm/lang/de-DE.rc
branches/ntvdm/subsystems/ntvdm/lang/en-US.rc
branches/ntvdm/subsystems/ntvdm/lang/es-ES.rc
branches/ntvdm/subsystems/ntvdm/lang/fr-FR.rc
branches/ntvdm/subsystems/ntvdm/lang/hu-HU.rc
branches/ntvdm/subsystems/ntvdm/lang/id-ID.rc
branches/ntvdm/subsystems/ntvdm/lang/it-IT.rc
branches/ntvdm/subsystems/ntvdm/lang/ja-JP.rc
branches/ntvdm/subsystems/ntvdm/lang/no-NO.rc
branches/ntvdm/subsystems/ntvdm/lang/pl-PL.rc
branches/ntvdm/subsystems/ntvdm/lang/pt-BR.rc
branches/ntvdm/subsystems/ntvdm/lang/ro-RO.rc
branches/ntvdm/subsystems/ntvdm/lang/ru-RU.rc
branches/ntvdm/subsystems/ntvdm/lang/sk-SK.rc
branches/ntvdm/subsystems/ntvdm/lang/th-TH.rc
branches/ntvdm/subsystems/ntvdm/lang/uk-UA.rc
branches/ntvdm/subsystems/ntvdm/lang/zh-CN.rc
branches/ntvdm/subsystems/ntvdm/lang/zh-TW.rc
Modified:
branches/ntvdm/subsystems/ntvdm/CMakeLists.txt
branches/ntvdm/subsystems/ntvdm/ntvdm.c
branches/ntvdm/subsystems/ntvdm/ntvdm.rc
branches/ntvdm/subsystems/ntvdm/resource.h
branches/ntvdm/subsystems/ntvdm/rsrc.rc
Modified: branches/ntvdm/subsystems/ntvdm/CMakeLists.txt
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/CMakeLis…
==============================================================================
--- branches/ntvdm/subsystems/ntvdm/CMakeLists.txt [iso-8859-1] (original)
+++ branches/ntvdm/subsystems/ntvdm/CMakeLists.txt [iso-8859-1] Mon Jun 17 00:00:36 2013
@@ -1,11 +1,16 @@
-include_directories(.)
+include_directories(${REACTOS_SOURCE_DIR}/include/reactos/libs/softx86)
-add_executable(ntvdm
+list(APPEND SOURCE
+ bios.c
+ dos.c
+ emulator.c
ntvdm.c
ntvdm.rc)
-set_module_type(ntvdm win32cui)
-add_importlibs(ntvdm ntdll user32 gdi32 advapi32 msvcrt kernel32)
-add_dependencies(ntvdm ndk bugcodes)
+add_executable(ntvdm ${SOURCE})
+set_module_type(ntvdm win32cui UNICODE)
+target_link_libraries(ntvdm softx86 softx87)
+add_importlibs(ntvdm msvcrt user32 kernel32)
+add_dependencies(ntvdm softx86 softx87)
add_cd_file(TARGET ntvdm DESTINATION reactos/system32 FOR all)
Added: branches/ntvdm/subsystems/ntvdm/bios.c
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/bios.c?r…
==============================================================================
--- branches/ntvdm/subsystems/ntvdm/bios.c (added)
+++ branches/ntvdm/subsystems/ntvdm/bios.c [iso-8859-1] Mon Jun 17 00:00:36 2013
@@ -0,0 +1,225 @@
+/*
+ * COPYRIGHT: GPL - See COPYING in the top level directory
+ * PROJECT: ReactOS Virtual DOS Machine
+ * FILE: bios.c
+ * PURPOSE: VDM BIOS
+ * PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
+ */
+
+#include "ntvdm.h"
+
+BYTE CursorRow, CursorCol;
+WORD ConsoleWidth, ConsoleHeight;
+
+BOOLEAN BiosInitialize()
+{
+ INT i;
+ WORD Offset = 0;
+ HANDLE ConsoleOutput = GetStdHandle(STD_OUTPUT_HANDLE);
+ CONSOLE_SCREEN_BUFFER_INFO ConsoleInfo;
+ LPWORD IntVecTable = (LPWORD)((ULONG_PTR)BaseAddress);
+ LPBYTE BiosCode = (LPBYTE)((ULONG_PTR)BaseAddress + TO_LINEAR(BIOS_SEGMENT, 0));
+
+ /* Generate ISR stubs and fill the IVT */
+ for (i = 0; i < 256; i++)
+ {
+ IntVecTable[i * 2] = Offset;
+ IntVecTable[i * 2 + 1] = BIOS_SEGMENT;
+
+ if (i != SPECIAL_INT_NUM)
+ {
+ BiosCode[Offset++] = 0xFA; // cli
+
+ BiosCode[Offset++] = 0x6A; // push i
+ BiosCode[Offset++] = (BYTE)i;
+
+ BiosCode[Offset++] = 0xCD; // int SPECIAL_INT_NUM
+ BiosCode[Offset++] = SPECIAL_INT_NUM;
+
+ BiosCode[Offset++] = 0x83; // add sp, 2
+ BiosCode[Offset++] = 0xC4;
+ BiosCode[Offset++] = 0x02;
+ }
+
+ BiosCode[Offset++] = 0xCF; // iret
+ }
+
+ /* Get the console buffer info */
+ if (!GetConsoleScreenBufferInfo(ConsoleOutput, &ConsoleInfo))
+ {
+ return FALSE;
+ }
+
+ /* Set the initial cursor position and console size */
+ CursorCol = ConsoleInfo.dwCursorPosition.X;
+ CursorRow = ConsoleInfo.dwCursorPosition.Y;
+ ConsoleWidth = ConsoleInfo.dwSize.X;
+ ConsoleHeight = ConsoleInfo.dwSize.Y;
+
+ return TRUE;
+}
+
+static COORD BiosVideoAddressToCoord(ULONG Address)
+{
+ COORD Result = {0, 0};
+ CONSOLE_SCREEN_BUFFER_INFO ConsoleInfo;
+ HANDLE ConsoleOutput = GetStdHandle(STD_OUTPUT_HANDLE);
+
+ if (!GetConsoleScreenBufferInfo(ConsoleOutput, &ConsoleInfo))
+ {
+ assert(0);
+ return Result;
+ }
+
+ Result.X = ((Address - CONSOLE_VIDEO_MEM_START) >> 1) % ConsoleInfo.dwSize.X;
+ Result.Y = ((Address - CONSOLE_VIDEO_MEM_START) >> 1) / ConsoleInfo.dwSize.X;
+
+ return Result;
+}
+
+VOID BiosUpdateConsole(ULONG StartAddress, ULONG EndAddress)
+{
+ ULONG i;
+ COORD Coordinates;
+ DWORD CharsWritten;
+ HANDLE ConsoleOutput = GetStdHandle(STD_OUTPUT_HANDLE);
+
+ /* Loop through all the addresses */
+ for (i = StartAddress; i < EndAddress; i++)
+ {
+ /* Get the coordinates */
+ Coordinates = BiosVideoAddressToCoord(i);
+
+ /* Check if this is a character byte or an attribute byte */
+ if ((i - CONSOLE_VIDEO_MEM_START) % 2 == 0)
+ {
+ /* This is a regular character */
+ FillConsoleOutputCharacterA(ConsoleOutput,
+ *(PCHAR)((ULONG_PTR)BaseAddress + i),
+ sizeof(CHAR),
+ Coordinates,
+ &CharsWritten);
+ }
+ else
+ {
+ /* This is an attribute */
+ FillConsoleOutputAttribute(ConsoleOutput,
+ *(PCHAR)((ULONG_PTR)BaseAddress + i),
+ sizeof(CHAR),
+ Coordinates,
+ &CharsWritten);
+ }
+ }
+}
+
+VOID BiosUpdateVideoMemory(ULONG StartAddress, ULONG EndAddress)
+{
+ ULONG i;
+ COORD Coordinates;
+ WORD Attribute;
+ DWORD CharsWritten;
+ HANDLE ConsoleOutput = GetStdHandle(STD_OUTPUT_HANDLE);
+
+ /* Loop through all the addresses */
+ for (i = StartAddress; i < EndAddress; i++)
+ {
+ /* Get the coordinates */
+ Coordinates = BiosVideoAddressToCoord(i);
+
+ /* Check if this is a character byte or an attribute byte */
+ if ((i - CONSOLE_VIDEO_MEM_START) % 2 == 0)
+ {
+ /* This is a regular character */
+ ReadConsoleOutputCharacterA(ConsoleOutput,
+ (LPSTR)((ULONG_PTR)BaseAddress + i),
+ sizeof(CHAR),
+ Coordinates,
+ &CharsWritten);
+ }
+ else
+ {
+ /* This is an attribute */
+ ReadConsoleOutputAttribute(ConsoleOutput,
+ &Attribute,
+ sizeof(CHAR),
+ Coordinates,
+ &CharsWritten);
+
+ *(PCHAR)((ULONG_PTR)BaseAddress + i) = LOBYTE(Attribute);
+ }
+ }
+}
+
+VOID BiosVideoService()
+{
+ HANDLE ConsoleOutput = GetStdHandle(STD_OUTPUT_HANDLE);
+ INT CursorHeight;
+ BOOLEAN Invisible = FALSE;
+ COORD CursorPosition;
+ CONSOLE_CURSOR_INFO CursorInfo;
+ DWORD Eax = EmulatorGetRegister(EMULATOR_REG_AX);
+ DWORD Ecx = EmulatorGetRegister(EMULATOR_REG_CX);
+ DWORD Edx = EmulatorGetRegister(EMULATOR_REG_DX);
+
+ switch (LOBYTE(Eax))
+ {
+ /* Set Text-Mode Cursor Shape */
+ case 0x01:
+ {
+ /* Retrieve and validate the input */
+ Invisible = ((HIBYTE(Ecx) >> 5) & 0x03) ? TRUE : FALSE;
+ CursorHeight = (HIBYTE(Ecx) & 0x1F) - (LOBYTE(Ecx) & 0x1F);
+ if (CursorHeight < 1) CursorHeight = 1;
+ if (CursorHeight > 100) CursorHeight = 100;
+
+ /* Set the cursor */
+ CursorInfo.dwSize = (CursorHeight * 100) / CONSOLE_FONT_HEIGHT;
+ CursorInfo.bVisible = !Invisible;
+ SetConsoleCursorInfo(ConsoleOutput, &CursorInfo);
+
+ break;
+ }
+
+ /* Set Cursor Position */
+ case 0x02:
+ {
+ CursorPosition.X = LOBYTE(Edx);
+ CursorPosition.Y = HIBYTE(Edx);
+
+ SetConsoleCursorPosition(ConsoleOutput, CursorPosition);
+ break;
+ }
+
+ /* Scroll Up Window */
+ case 0x06:
+ {
+ break;
+ }
+
+ /* Scroll Down Window */
+ case 0x07:
+ {
+ break;
+ }
+
+ /* Read Character And Attribute At Cursor Position */
+ case 0x08:
+ {
+ break;
+ }
+
+ /* Write Character And Attribute At Cursor Position */
+ case 0x09:
+ {
+ break;
+ }
+
+ /* Write Character Only At Cursor Position */
+ case 0x0A:
+ {
+ break;
+ }
+ }
+}
+
+/* EOF */
Propchange: branches/ntvdm/subsystems/ntvdm/bios.c
------------------------------------------------------------------------------
svn:eol-style = native
Added: branches/ntvdm/subsystems/ntvdm/dos.c
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/dos.c?re…
==============================================================================
--- branches/ntvdm/subsystems/ntvdm/dos.c (added)
+++ branches/ntvdm/subsystems/ntvdm/dos.c [iso-8859-1] Mon Jun 17 00:00:36 2013
@@ -0,0 +1,707 @@
+/*
+ * COPYRIGHT: GPL - See COPYING in the top level directory
+ * PROJECT: ReactOS Virtual DOS Machine
+ * FILE: dos.c
+ * PURPOSE: VDM DOS Kernel
+ * PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
+ */
+
+#include "ntvdm.h"
+
+WORD CurrentPsp = SYSTEM_PSP, LastError = 0;
+
+static VOID DosCombineFreeBlocks()
+{
+ WORD Segment = FIRST_MCB_SEGMENT;
+ PDOS_MCB CurrentMcb, NextMcb;
+
+ /* Loop through all the blocks */
+ while (TRUE)
+ {
+ /* Get a pointer to the MCB */
+ CurrentMcb = SEGMENT_TO_MCB(Segment);
+
+ /* Ignore the last block */
+ if (CurrentMcb->BlockType == 'Z') break;
+
+ /* Get a pointer to the next MCB */
+ NextMcb = SEGMENT_TO_MCB(Segment + CurrentMcb->Size + 1);
+
+ /* If both this block and the next one are free, combine them */
+ if ((CurrentMcb->OwnerPsp == 0) && (NextMcb->OwnerPsp == 0))
+ {
+ CurrentMcb->Size += NextMcb->Size + 1;
+ CurrentMcb->BlockType = NextMcb->BlockType;
+
+ /* Invalidate the next MCB */
+ NextMcb->BlockType = 'I';
+
+ /* Try to combine the current block again with the next one */
+ continue;
+ }
+
+ /* Update the segment and continue */
+ Segment += CurrentMcb->Size + 1;
+ }
+}
+
+static WORD DosCopyEnvironmentBlock(WORD SourceSegment)
+{
+ PCHAR Ptr, SourceBuffer, DestBuffer = NULL;
+ ULONG TotalSize = 0;
+ WORD DestSegment;
+
+ Ptr = SourceBuffer = (PCHAR)((ULONG_PTR)BaseAddress + TO_LINEAR(SourceSegment, 0));
+
+ /* Calculate the size of the environment block */
+ while (*Ptr)
+ {
+ TotalSize += strlen(Ptr) + 1;
+ Ptr += strlen(Ptr) + 1;
+ }
+ TotalSize++;
+
+ /* Allocate the memory for the environment block */
+ DestSegment = DosAllocateMemory((TotalSize + 0x0F) >> 4);
+ if (!DestSegment) return 0;
+
+ Ptr = SourceBuffer;
+
+ DestBuffer = (PCHAR)((ULONG_PTR)BaseAddress + TO_LINEAR(DestSegment, 0));
+ while (*Ptr)
+ {
+ /* Copy the string */
+ strcpy(DestBuffer, Ptr);
+
+ /* Advance to the next string */
+ Ptr += strlen(Ptr) + 1;
+ DestBuffer += strlen(Ptr) + 1;
+ }
+
+ /* Set the final zero */
+ *DestBuffer = 0;
+
+ return DestSegment;
+}
+
+WORD DosAllocateMemory(WORD Size)
+{
+ WORD Result = 0, Segment = FIRST_MCB_SEGMENT;
+ PDOS_MCB CurrentMcb, NextMcb;
+
+ /* Find an unallocated block */
+ while (TRUE)
+ {
+ /* Get a pointer to the MCB */
+ CurrentMcb = SEGMENT_TO_MCB(Segment);
+
+ /* Make sure it's valid */
+ if (CurrentMcb->BlockType != 'M' && CurrentMcb->BlockType
!= 'Z')
+ {
+ return 0;
+ }
+
+ /* Only check free blocks */
+ if (CurrentMcb->OwnerPsp != 0) goto Next;
+
+ /* Check if the block is big enough */
+ if (CurrentMcb->Size < Size) goto Next;
+
+ /* It is, update the smallest found so far */
+ if ((Result == 0) || (CurrentMcb->Size < SEGMENT_TO_MCB(Result)->Size))
+ {
+ Result = Segment;
+ }
+
+Next:
+ /* If this was the last MCB in the chain, quit. */
+ if (CurrentMcb->BlockType == 'Z') break;
+
+ /* Otherwise, update the segment and continue */
+ Segment += CurrentMcb->Size + 1;
+ }
+
+ /* If we didn't find a free block, return zero */
+ if (Result == 0) return 0;
+
+ /* Get a pointer to the MCB */
+ CurrentMcb = SEGMENT_TO_MCB(Result);
+
+ /* Check if the block is larger than requested */
+ if (CurrentMcb->Size > Size)
+ {
+ /* It is, split it into two blocks */
+ NextMcb = SEGMENT_TO_MCB(Result + Size + 1);
+
+ /* Initialize the new MCB structure */
+ NextMcb->BlockType = CurrentMcb->BlockType;
+ NextMcb->Size = Size - CurrentMcb->Size - 1;
+ NextMcb->OwnerPsp = 0;
+
+ /* Update the current block */
+ CurrentMcb->BlockType = 'M';
+ CurrentMcb->Size = Size;
+
+ /* Combine consecutive free blocks into larger blocks */
+ DosCombineFreeBlocks();
+ }
+
+ /* Take ownership of the block */
+ CurrentMcb->OwnerPsp = CurrentPsp;
+
+ return Result;
+}
+
+WORD DosResizeMemory(WORD Segment, WORD NewSize)
+{
+ WORD ReturnSize = 0, CurrentSeg;
+ PDOS_MCB Mcb = SEGMENT_TO_MCB(Segment), CurrentMcb;
+ BOOLEAN FinalBlockUsed = FALSE;
+
+ /* We can't expand the last block */
+ if (Mcb->BlockType != 'M') return 0;
+
+ /* Check if need to expand or contract the block */
+ if (NewSize > Mcb->Size)
+ {
+ ReturnSize = Mcb->Size;
+
+ /* Get the segment of the next MCB */
+ CurrentSeg = Segment + Mcb->Size + 1;
+
+ /* Calculate the maximum amount of memory this block could expand to */
+ while (ReturnSize < NewSize)
+ {
+ /* Get the MCB */
+ CurrentMcb = SEGMENT_TO_MCB(CurrentSeg);
+
+ /* We can't expand the block over an allocated block */
+ if (CurrentMcb->OwnerPsp != 0) break;
+
+ ReturnSize += CurrentMcb->Size + 1;
+
+ /* Check if this is the last block */
+ if (CurrentMcb->BlockType == 'Z')
+ {
+ FinalBlockUsed = TRUE;
+ break;
+ }
+
+ /* Update the segment and continue */
+ CurrentSeg += CurrentMcb->Size + 1;
+ }
+
+ /* Check if we need to split the last block */
+ if (ReturnSize > NewSize)
+ {
+ /* Initialize the new MCB structure */
+ CurrentMcb = SEGMENT_TO_MCB(Segment + NewSize + 1);
+ CurrentMcb->BlockType = (FinalBlockUsed) ? 'Z' : 'M';
+ CurrentMcb->Size = ReturnSize - NewSize - 1;
+ CurrentMcb->OwnerPsp = 0;
+ }
+
+ /* Calculate the new size of the block */
+ ReturnSize = min(ReturnSize, NewSize);
+
+ /* Update the MCB */
+ if (FinalBlockUsed) Mcb->BlockType = 'Z';
+ Mcb->Size = ReturnSize;
+ }
+ else if (NewSize < Mcb->Size)
+ {
+ /* Just split the block */
+ CurrentMcb = SEGMENT_TO_MCB(Segment + NewSize + 1);
+ CurrentMcb->BlockType = Mcb->BlockType;
+ CurrentMcb->Size = Mcb->Size - NewSize - 1;
+ CurrentMcb->OwnerPsp = 0;
+
+ /* Update the MCB */
+ Mcb->BlockType = 'M';
+ Mcb->Size = NewSize;
+
+ ReturnSize = NewSize;
+ }
+
+ /* Combine consecutive free blocks into larger blocks */
+ DosCombineFreeBlocks();
+
+ return ReturnSize;
+}
+
+BOOLEAN DosFreeMemory(WORD Segment)
+{
+ PDOS_MCB Mcb = SEGMENT_TO_MCB(Segment);
+
+ /* Make sure the MCB is valid */
+ if (Mcb->BlockType != 'M' && Mcb->BlockType != 'Z')
return FALSE;
+
+ /* Mark the block as free */
+ Mcb->OwnerPsp = 0;
+
+ /* Combine consecutive free blocks into larger blocks */
+ DosCombineFreeBlocks();
+
+ return TRUE;
+}
+
+WORD DosCreateFile(LPCSTR FilePath)
+{
+ // TODO: NOT IMPLEMENTED
+ return 0;
+}
+
+WORD DosOpenFile(LPCSTR FilePath)
+{
+ // TODO: NOT IMPLEMENTED
+ return 0;
+}
+
+VOID DosInitializePsp(WORD PspSegment, LPCSTR CommandLine, WORD ProgramSize, WORD
Environment)
+{
+ INT i;
+ PDOS_PSP PspBlock = SEGMENT_TO_PSP(PspSegment);
+ LPDWORD IntVecTable = (LPDWORD)((ULONG_PTR)BaseAddress);
+
+ ZeroMemory(PspBlock, sizeof(DOS_PSP));
+
+ /* Set the exit interrupt */
+ PspBlock->Exit[0] = 0xCD; // int 0x20
+ PspBlock->Exit[1] = 0x20;
+
+ /* Set the program size */
+ PspBlock->MemSize = ProgramSize;
+
+ /* Save the interrupt vectors */
+ PspBlock->TerminateAddress = IntVecTable[0x22];
+ PspBlock->BreakAddress = IntVecTable[0x23];
+ PspBlock->CriticalAddress = IntVecTable[0x24];
+
+ /* Set the parent PSP */
+ PspBlock->ParentPsp = CurrentPsp;
+
+ /* Initialize the handle table */
+ for (i = 0; i < 20; i++) PspBlock->HandleTable[i] = 0xFF;
+
+ /* Did we get an environment segment? */
+ if (!Environment)
+ {
+ /* No, copy the one from the parent */
+ Environment = DosCopyEnvironmentBlock((CurrentPsp != SYSTEM_PSP)
+ ? SEGMENT_TO_PSP(CurrentPsp)->EnvBlock
+ : SYSTEM_ENV_BLOCK);
+ }
+
+ PspBlock->EnvBlock = Environment;
+
+ /* Set the handle table pointers to the internal handle table */
+ PspBlock->HandleTableSize = 20;
+ PspBlock->HandleTablePtr = MAKELONG(0x18, PspSegment);
+
+ /* Set the DOS version */
+ PspBlock->DosVersion = DOS_VERSION;
+
+ /* Set the far call opcodes */
+ PspBlock->FarCall[0] = 0xCD; // int 0x21
+ PspBlock->FarCall[1] = 0x21;
+ PspBlock->FarCall[2] = 0xCB; // retf
+
+ /* Set the command line */
+ PspBlock->CommandLineSize = strlen(CommandLine);
+ RtlCopyMemory(PspBlock->CommandLine, CommandLine, PspBlock->CommandLineSize);
+ PspBlock->CommandLine[PspBlock->CommandLineSize] = '\r';
+}
+
+BOOLEAN DosCreateProcess(LPCSTR CommandLine, WORD EnvBlock)
+{
+ BOOLEAN Success = FALSE;
+ HANDLE FileHandle = INVALID_HANDLE_VALUE, FileMapping = NULL;
+ LPBYTE Address = NULL;
+ LPSTR ProgramFilePath, Parameters[128];
+ CHAR CommandLineCopy[128];
+ INT ParamCount = 0;
+ WORD Segment, FileSize;
+
+ /* Save a copy of the command line */
+ strcpy(CommandLineCopy, CommandLine);
+
+ /* Get the file name of the executable */
+ ProgramFilePath = strtok(CommandLineCopy, " \t");
+
+ /* Load the parameters in the local array */
+ while ((ParamCount < 256)
+ && ((Parameters[ParamCount] = strtok(NULL, " \t")) !=
NULL))
+ {
+ ParamCount++;
+ }
+
+ /* Open a handle to the executable */
+ FileHandle = CreateFileA(ProgramFilePath,
+ GENERIC_READ,
+ 0,
+ NULL,
+ OPEN_EXISTING,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL);
+ if (FileHandle == INVALID_HANDLE_VALUE) goto Cleanup;
+
+ /* Get the file size */
+ FileSize = GetFileSize(FileHandle, NULL);
+
+ /* Create a mapping object for the file */
+ FileMapping = CreateFileMapping(FileHandle,
+ NULL,
+ PAGE_READONLY,
+ 0,
+ 0,
+ NULL);
+ if (FileMapping == NULL) goto Cleanup;
+
+ /* Map the file into memory */
+ Address = (LPBYTE)MapViewOfFile(FileMapping, FILE_MAP_READ, 0, 0, 0);
+ if (Address == NULL) goto Cleanup;
+
+ /* Check if this is an EXE file or a COM file */
+ if (Address[0] == 'M' && Address[1] == 'Z')
+ {
+ /* EXE file */
+
+ // TODO: NOT IMPLEMENTED
+ DisplayMessage(L"EXE files are not yet supported!");
+ }
+ else
+ {
+ /* COM file */
+
+ /* Allocate memory for the whole program and the PSP */
+ Segment = DosAllocateMemory((FileSize + sizeof(DOS_PSP)) >> 4);
+ if (Segment == 0) goto Cleanup;
+
+ /* Copy the program to Segment:0100 */
+ RtlCopyMemory((PVOID)((ULONG_PTR)BaseAddress
+ + TO_LINEAR(Segment, 0x100)),
+ Address,
+ FileSize);
+
+ /* Initialize the PSP */
+ DosInitializePsp(Segment,
+ CommandLine,
+ (FileSize + sizeof(DOS_PSP)) >> 4,
+ EnvBlock);
+
+ /* Set the initial segment registers */
+ EmulatorSetRegister(EMULATOR_REG_DS, Segment);
+ EmulatorSetRegister(EMULATOR_REG_ES, Segment);
+
+ /* Set the stack to the last word of the segment */
+ EmulatorSetStack(Segment, 0xFFFE);
+
+ /* Execute */
+ CurrentPsp = Segment;
+ EmulatorExecute(Segment, 0x100);
+
+ Success = TRUE;
+ }
+
+Cleanup:
+ /* Unmap the file*/
+ if (Address != NULL) UnmapViewOfFile(Address);
+
+ /* Close the file mapping object */
+ if (FileMapping != NULL) CloseHandle(FileMapping);
+
+ /* Close the file handle */
+ if (FileHandle != INVALID_HANDLE_VALUE) CloseHandle(FileHandle);
+
+ return Success;
+}
+
+VOID DosTerminateProcess(WORD Psp, BYTE ReturnCode)
+{
+ WORD McbSegment = FIRST_MCB_SEGMENT;
+ PDOS_MCB CurrentMcb;
+ LPDWORD IntVecTable = (LPDWORD)((ULONG_PTR)BaseAddress);
+ PDOS_PSP PspBlock = SEGMENT_TO_PSP(Psp);
+
+ /* Check if this PSP is it's own parent */
+ if (PspBlock->ParentPsp == Psp) goto Done;
+
+ // TODO: Close all handles opened by the process
+
+ /* Free the memory used by the process */
+ while (TRUE)
+ {
+ /* Get a pointer to the MCB */
+ CurrentMcb = SEGMENT_TO_MCB(McbSegment);
+
+ /* Make sure the MCB is valid */
+ if (CurrentMcb->BlockType != 'M' && CurrentMcb->BlockType
!='Z') break;
+
+ /* If this block was allocated by the process, free it */
+ if (CurrentMcb->OwnerPsp == Psp) DosFreeMemory(McbSegment);
+
+ /* If this was the last block, quit */
+ if (CurrentMcb->BlockType == 'Z') break;
+
+ /* Update the segment and continue */
+ McbSegment += CurrentMcb->Size + 1;
+ }
+
+Done:
+ /* Restore the interrupt vectors */
+ IntVecTable[0x22] = PspBlock->TerminateAddress;
+ IntVecTable[0x23] = PspBlock->BreakAddress;
+ IntVecTable[0x24] = PspBlock->CriticalAddress;
+
+ /* Update the current PSP */
+ if (Psp == CurrentPsp)
+ {
+ CurrentPsp = PspBlock->ParentPsp;
+ if (CurrentPsp == SYSTEM_PSP) VdmRunning = FALSE;
+ }
+
+ /* Return control to the parent process */
+ EmulatorExecute(HIWORD(PspBlock->TerminateAddress),
+ LOWORD(PspBlock->TerminateAddress));
+}
+
+CHAR DosReadCharacter()
+{
+ // TODO: STDIN can be redirected under DOS 2.0+
+ return _getch();
+}
+
+VOID DosPrintCharacter(CHAR Character)
+{
+ // TODO: STDOUT can be redirected under DOS 2.0+
+ if (Character == '\r') Character = '\n';
+ putchar(Character);
+}
+
+VOID DosInt20h(WORD CodeSegment)
+{
+ /* This is the exit interrupt */
+ DosTerminateProcess(CodeSegment, 0);
+}
+
+VOID DosInt21h(WORD CodeSegment)
+{
+ INT i;
+ CHAR Character;
+ PCHAR String;
+ PDOS_INPUT_BUFFER InputBuffer;
+ DWORD Eax = EmulatorGetRegister(EMULATOR_REG_AX);
+ DWORD Edx = EmulatorGetRegister(EMULATOR_REG_DX);
+ DWORD Ebx = EmulatorGetRegister(EMULATOR_REG_BX);
+ WORD DataSegment = EmulatorGetRegister(EMULATOR_REG_DS);
+ WORD ExtSegment = EmulatorGetRegister(EMULATOR_REG_ES);
+
+ /* Check the value in the AH register */
+ switch (HIBYTE(Eax))
+ {
+ /* Terminate Program */
+ case 0x00:
+ {
+ DosTerminateProcess(CodeSegment, 0);
+ break;
+ }
+
+ /* Read Character And Echo */
+ case 0x01:
+ {
+ Character = DosReadCharacter();
+ DosPrintCharacter(Character);
+ EmulatorSetRegister(EMULATOR_REG_AX, (Eax & 0xFFFFFF00) | Character);
+ break;
+ }
+
+ /* Print Character */
+ case 0x02:
+ {
+ DosPrintCharacter(LOBYTE(Edx));
+ break;
+ }
+
+ /* Read Character Without Echo */
+ case 0x08:
+ {
+ EmulatorSetRegister(EMULATOR_REG_AX,
+ (Eax & 0xFFFFFF00) | DosReadCharacter());
+ break;
+ }
+
+ /* Print String */
+ case 0x09:
+ {
+ String = (PCHAR)((ULONG_PTR)BaseAddress
+ + TO_LINEAR(DataSegment, LOWORD(Edx)));
+
+ while ((*String) != '$')
+ {
+ DosPrintCharacter(*String);
+ String++;
+ }
+
+ break;
+ }
+
+ /* Read Buffered Input */
+ case 0x0A:
+ {
+ InputBuffer = (PDOS_INPUT_BUFFER)((ULONG_PTR)BaseAddress
+ + TO_LINEAR(DataSegment,
+ LOWORD(Edx)));
+
+ InputBuffer->Length = 0;
+ for (i = 0; i < InputBuffer->MaxLength; i ++)
+ {
+ Character = DosReadCharacter();
+ DosPrintCharacter(Character);
+ InputBuffer->Buffer[InputBuffer->Length] = Character;
+ if (Character == '\r') break;
+ InputBuffer->Length++;
+ }
+
+ break;
+ }
+
+ /* Allocate Memory */
+ case 0x48:
+ {
+ WORD Segment = DosAllocateMemory(LOWORD(Ebx));
+ if (Segment != 0)
+ {
+ EmulatorSetRegister(EMULATOR_REG_AX, Segment);
+ EmulatorClearFlag(EMULATOR_FLAG_CF);
+ }
+ else EmulatorSetFlag(EMULATOR_FLAG_CF);
+
+ break;
+ }
+
+ /* Free Memory */
+ case 0x49:
+ {
+ if (DosFreeMemory(ExtSegment))
+ {
+ EmulatorClearFlag(EMULATOR_FLAG_CF);
+ }
+ else EmulatorSetFlag(EMULATOR_FLAG_CF);
+
+ break;
+ }
+
+ /* Resize Memory Block */
+ case 0x4A:
+ {
+ WORD Size = DosResizeMemory(ExtSegment, LOWORD(Ebx));
+
+ if (Size != 0)
+ {
+ EmulatorSetRegister(EMULATOR_REG_BX, Size);
+ EmulatorClearFlag(EMULATOR_FLAG_CF);
+ }
+ else EmulatorSetFlag(EMULATOR_FLAG_CF);
+
+ break;
+ }
+
+ /* Terminate With Return Code */
+ case 0x4C:
+ {
+ DosTerminateProcess(CurrentPsp, LOBYTE(Eax));
+ break;
+ }
+
+ /* Unsupported */
+ default:
+ {
+ EmulatorSetFlag(EMULATOR_FLAG_CF);
+ }
+ }
+}
+
+VOID DosBreakInterrupt()
+{
+ VdmRunning = FALSE;
+}
+
+BOOLEAN DosInitialize()
+{
+ PDOS_MCB Mcb = SEGMENT_TO_MCB(FIRST_MCB_SEGMENT);
+ FILE *Stream;
+ WCHAR Buffer[256];
+ LPWSTR SourcePtr, Environment;
+ LPSTR AsciiString;
+ LPSTR DestPtr = (LPSTR)((ULONG_PTR)BaseAddress + TO_LINEAR(SYSTEM_ENV_BLOCK, 0));
+ DWORD AsciiSize;
+
+ /* Initialize the MCB */
+ Mcb->BlockType = 'Z';
+ Mcb->Size = (WORD)USER_MEMORY_SIZE;
+ Mcb->OwnerPsp = 0;
+
+ /* Get the environment strings */
+ SourcePtr = Environment = GetEnvironmentStringsW();
+ if (Environment == NULL) return FALSE;
+
+ /* Fill the DOS system environment block */
+ while (*SourcePtr)
+ {
+ /* Get the size of the ASCII string */
+ AsciiSize = WideCharToMultiByte(CP_ACP,
+ 0,
+ SourcePtr,
+ -1,
+ NULL,
+ 0,
+ NULL,
+ NULL);
+
+ /* Allocate memory for the ASCII string */
+ AsciiString = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, AsciiSize);
+ if (AsciiString == NULL)
+ {
+ FreeEnvironmentStringsW(Environment);
+ return FALSE;
+ }
+
+ /* Convert to ASCII */
+ WideCharToMultiByte(CP_ACP,
+ 0,
+ SourcePtr,
+ -1,
+ AsciiString,
+ AsciiSize,
+ NULL,
+ NULL);
+
+ /* Copy the string into DOS memory */
+ strcpy(DestPtr, AsciiString);
+
+ /* Free the memory */
+ HeapFree(GetProcessHeap(), 0, AsciiString);
+
+ /* Move to the next string */
+ SourcePtr += wcslen(SourcePtr) + 1;
+ DestPtr += strlen(AsciiString) + 1;
+ }
+
+ /* Free the memory allocated for environment strings */
+ FreeEnvironmentStringsW(Environment);
+
+ /* Read CONFIG.SYS */
+ Stream = _wfopen(DOS_CONFIG_PATH, L"r");
+ if (Stream != NULL)
+ {
+ while (fgetws(Buffer, 256, Stream))
+ {
+ // TODO: Parse the line
+ }
+ fclose(Stream);
+ }
+
+ return TRUE;
+}
+
+/* EOF */
Propchange: branches/ntvdm/subsystems/ntvdm/dos.c
------------------------------------------------------------------------------
svn:eol-style = native
Added: branches/ntvdm/subsystems/ntvdm/emulator.c
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/emulator…
==============================================================================
--- branches/ntvdm/subsystems/ntvdm/emulator.c (added)
+++ branches/ntvdm/subsystems/ntvdm/emulator.c [iso-8859-1] Mon Jun 17 00:00:36 2013
@@ -0,0 +1,252 @@
+/*
+ * COPYRIGHT: GPL - See COPYING in the top level directory
+ * PROJECT: ReactOS Virtual DOS Machine
+ * FILE: emulator.c
+ * PURPOSE: Minimal x86 machine emulator for the VDM
+ * PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
+ */
+
+/* INCLUDES *******************************************************************/
+
+#include "ntvdm.h"
+#include <softx86/softx86.h>
+#include <softx86/softx87.h>
+
+softx86_ctx EmulatorContext;
+softx87_ctx FpuEmulatorContext;
+
+static VOID EmulatorReadMemory(PVOID Context, UINT Address, LPBYTE Buffer, INT Size)
+{
+ /* Make sure the requested address is valid */
+ if ((Address + Size) >= MAX_ADDRESS) return;
+
+ /* Are we reading some of the console video memory? */
+ if (((Address + Size) >= CONSOLE_VIDEO_MEM_START)
+ && (Address < CONSOLE_VIDEO_MEM_END))
+ {
+ /* Call the VDM BIOS to update the video memory */
+ BiosUpdateConsole(max(Address, CONSOLE_VIDEO_MEM_START),
+ min(Address + Size, CONSOLE_VIDEO_MEM_END));
+ }
+
+ /* Read the data from the virtual address space and store it in the buffer */
+ RtlCopyMemory(Buffer, (LPVOID)((ULONG_PTR)BaseAddress + Address), Size);
+}
+
+static VOID EmulatorWriteMemory(PVOID Context, UINT Address, LPBYTE Buffer, INT Size)
+{
+ /* Make sure the requested address is valid */
+ if ((Address + Size) >= MAX_ADDRESS) return;
+
+ /* Make sure we don't write to the ROM area */
+ if ((Address + Size) >= ROM_AREA_START && (Address < ROM_AREA_END))
return;
+
+ /* Read the data from the buffer and store it in the virtual address space */
+ RtlCopyMemory((LPVOID)((ULONG_PTR)BaseAddress + Address), Buffer, Size);
+
+ /* Check if we modified the console video memory */
+ if (((Address + Size) >= CONSOLE_VIDEO_MEM_START)
+ && (Address < CONSOLE_VIDEO_MEM_END))
+ {
+ /* Call the VDM BIOS to update the screen */
+ BiosUpdateConsole(max(Address, CONSOLE_VIDEO_MEM_START),
+ min(Address + Size, CONSOLE_VIDEO_MEM_END));
+ }
+}
+
+static VOID EmulatorReadIo(PVOID Context, UINT Address, LPBYTE Buffer, INT Size)
+{
+ // TODO: NOT IMPLEMENTED!
+}
+
+static VOID EmulatorWriteIo(PVOID Context, UINT Address, LPBYTE Buffer, INT Size)
+{
+ // TODO: NOT IMPLEMENTED!
+}
+
+static VOID EmulatorSoftwareInt(PVOID Context, BYTE Number)
+{
+ WORD StackSegment, StackPointer, CodeSegment, InstructionPointer;
+ BYTE IntNum;
+
+ /* Check if this is the special interrupt */
+ if (Number == SPECIAL_INT_NUM)
+ {
+ /* Get the SS:SP */
+ StackSegment = EmulatorContext.state->segment_reg[SX86_SREG_SS].val;
+ StackPointer = EmulatorContext.state->general_reg[SX86_REG_SP].val;
+
+ /* Get the interrupt number */
+ IntNum = *(LPBYTE)((ULONG_PTR)BaseAddress + TO_LINEAR(StackSegment,
StackPointer));
+
+ /* Move the stack pointer forward one word to skip the interrupt number */
+ StackPointer += sizeof(WORD);
+
+ /* Get the CS:IP */
+ InstructionPointer = *(LPWORD)((ULONG_PTR)BaseAddress
+ + TO_LINEAR(StackSegment, StackPointer));
+ CodeSegment = *(LPWORD)((ULONG_PTR)BaseAddress
+ + TO_LINEAR(StackSegment, StackPointer + sizeof(WORD)));
+
+ /* Check if this was an exception */
+ if (IntNum < 8)
+ {
+ /* Display a message to the user */
+ DisplayMessage(L"Exception: %s occured at %04X:%04X",
+ ExceptionName[IntNum],
+ CodeSegment,
+ InstructionPointer);
+
+ /* Stop the VDM */
+ VdmRunning = FALSE;
+ return;
+ }
+
+ switch (IntNum)
+ {
+ case VIDEO_BIOS_INTERRUPT:
+ {
+ /* This is the video BIOS interrupt, call the BIOS */
+ BiosVideoService();
+ break;
+ }
+ case 0x20:
+ {
+ DosInt20h(CodeSegment);
+ break;
+ }
+ case 0x21:
+ {
+ DosInt21h(CodeSegment);
+ break;
+ }
+ case 0x23:
+ {
+ DosBreakInterrupt();
+ break;
+ }
+ }
+ }
+}
+
+/* PUBLIC FUNCTIONS ***********************************************************/
+
+BOOLEAN EmulatorInitialize()
+{
+ /* Allocate memory for the 16-bit address space */
+ BaseAddress = HeapAlloc(GetProcessHeap(), 0, MAX_ADDRESS);
+ if (BaseAddress == NULL) return FALSE;
+
+ /* Initialize the softx86 CPU emulator */
+ if (!softx86_init(&EmulatorContext, SX86_CPULEVEL_80186))
+ {
+ HeapFree(GetProcessHeap(), 0, BaseAddress);
+ return FALSE;
+ }
+
+ /* Initialize the softx87 FPU emulator*/
+ if(!softx87_init(&FpuEmulatorContext, SX87_FPULEVEL_8087))
+ {
+ softx86_free(&EmulatorContext);
+ HeapFree(GetProcessHeap(), 0, BaseAddress);
+ return FALSE;
+ }
+
+ /* Set memory read/write callbacks */
+ EmulatorContext.callbacks->on_read_memory = EmulatorReadMemory;
+ EmulatorContext.callbacks->on_write_memory = EmulatorWriteMemory;
+
+ /* Set MMIO read/write callbacks */
+ EmulatorContext.callbacks->on_read_io = EmulatorReadIo;
+ EmulatorContext.callbacks->on_write_io = EmulatorWriteIo;
+
+ /* Set interrupt callbacks */
+ EmulatorContext.callbacks->on_sw_int = EmulatorSoftwareInt;
+
+ /* Connect the emulated FPU to the emulated CPU */
+ softx87_connect_to_CPU(&EmulatorContext, &FpuEmulatorContext);
+
+ return TRUE;
+}
+
+VOID EmulatorSetStack(WORD Segment, WORD Offset)
+{
+ /* Call the softx86 API */
+ softx86_set_stack_ptr(&EmulatorContext, Segment, Offset);
+}
+
+VOID EmulatorExecute(WORD Segment, WORD Offset)
+{
+ /* Call the softx86 API */
+ softx86_set_instruction_ptr(&EmulatorContext, Segment, Offset);
+}
+
+VOID EmulatorInterrupt(BYTE Number)
+{
+ LPWORD IntVecTable = (LPWORD)((ULONG_PTR)BaseAddress);
+ UINT Segment, Offset;
+
+ /* Get the segment and offset */
+ Segment = HIWORD(IntVecTable[Number]);
+ Offset = LOWORD(IntVecTable[Number]);
+
+ /* Call the softx86 API */
+ softx86_make_simple_interrupt_call(&EmulatorContext, &Segment, &Offset);
+}
+
+ULONG EmulatorGetRegister(ULONG Register)
+{
+ if (Register < EMULATOR_REG_CS)
+ {
+ return EmulatorContext.state->general_reg[Register].val;
+ }
+ else
+ {
+ return EmulatorContext.state->segment_reg[(Register >> 3) - 1].val;
+ }
+}
+
+VOID EmulatorSetRegister(ULONG Register, ULONG Value)
+{
+ if (Register < EMULATOR_REG_CS)
+ {
+ EmulatorContext.state->general_reg[Register].val = Value;
+ }
+ else
+ {
+ EmulatorContext.state->segment_reg[(Register >> 3) - 1].val = Value;
+ }
+}
+
+BOOLEAN EmulatorGetFlag(ULONG Flag)
+{
+ return (EmulatorContext.state->reg_flags.val & Flag);
+}
+
+VOID EmulatorSetFlag(ULONG Flag)
+{
+ EmulatorContext.state->reg_flags.val |= Flag;
+}
+
+VOID EmulatorClearFlag(ULONG Flag)
+{
+ EmulatorContext.state->reg_flags.val &= ~Flag;
+}
+
+VOID EmulatorStep()
+{
+ /* Call the softx86 API */
+ softx86_step(&EmulatorContext);
+}
+
+VOID EmulatorCleanup()
+{
+ /* Free the memory allocated for the 16-bit address space */
+ if (BaseAddress != NULL) HeapFree(GetProcessHeap(), 0, BaseAddress);
+
+ /* Free the softx86 CPU and FPU emulator */
+ softx86_free(&EmulatorContext);
+ softx87_free(&FpuEmulatorContext);
+}
+
+/* EOF */
Propchange: branches/ntvdm/subsystems/ntvdm/emulator.c
------------------------------------------------------------------------------
svn:eol-style = native
Removed: branches/ntvdm/subsystems/ntvdm/lang/bg-BG.rc
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/lang/bg-…
==============================================================================
--- branches/ntvdm/subsystems/ntvdm/lang/bg-BG.rc [iso-8859-1] (original)
+++ branches/ntvdm/subsystems/ntvdm/lang/bg-BG.rc (removed)
@@ -1,12 +0,0 @@
-/*
- * Moved all hardcoded strings to En.rc.
- * By Magnus Olsen 2005
- */
-
-LANGUAGE LANG_BULGARIAN, SUBLANG_DEFAULT
-STRINGTABLE DISCARDABLE
-BEGIN
-
-STRING_WelcomeMsg, "Ïîääðúæêà íà ÐåàêòÎÑ çà ïðèâèäíà ÄÎÑ ìàøèíà.\n"
-STRING_PromptMsg, "Íàïèøåòå r<cr> çà ïóñêàíå, s<cr> çà ñïèðàíå èëè
q<cr> çà èçõîä."
-END
Removed: branches/ntvdm/subsystems/ntvdm/lang/cs-CZ.rc
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/lang/cs-…
==============================================================================
--- branches/ntvdm/subsystems/ntvdm/lang/cs-CZ.rc [iso-8859-1] (original)
+++ branches/ntvdm/subsystems/ntvdm/lang/cs-CZ.rc (removed)
@@ -1,12 +0,0 @@
-/* FILE: subsystems/ntvdm/lang/cs-CZ.rc
- * TRANSLATOR: Radek Liska aka Black_Fox (radekliska at gmail dot com)
- * UPDATED: 2008-06-24
- */
-
-LANGUAGE LANG_CZECH, SUBLANG_DEFAULT
-STRINGTABLE DISCARDABLE
-BEGIN
-
-STRING_WelcomeMsg, "ReactOS podpora virtuálního DOS stroje.\n"
-STRING_PromptMsg, "Napite r<cr> pro sputìní, s<cr> pro vypnutí
nebo q<cr> pro ukonèení."
-END
Removed: branches/ntvdm/subsystems/ntvdm/lang/de-DE.rc
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/lang/de-…
==============================================================================
--- branches/ntvdm/subsystems/ntvdm/lang/de-DE.rc [iso-8859-1] (original)
+++ branches/ntvdm/subsystems/ntvdm/lang/de-DE.rc (removed)
@@ -1,13 +0,0 @@
-/*
- * Translate into German.
- * By Rouven Wessling 2005 pentiumforever(a)gmail.com
- * 2008 dark_shadow(a)gmx.at
- */
-
-LANGUAGE LANG_GERMAN, SUBLANG_NEUTRAL
-STRINGTABLE DISCARDABLE
-BEGIN
-
-STRING_WelcomeMsg, "ReactOS virtuelle DOS-Unterstützung.\n"
-STRING_PromptMsg, "Drücken Sie r<cr> zum Starten, s<cr> zum
Herunterfahren oder q<cr> zum Beenden."
-END
Removed: branches/ntvdm/subsystems/ntvdm/lang/en-US.rc
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/lang/en-…
==============================================================================
--- branches/ntvdm/subsystems/ntvdm/lang/en-US.rc [iso-8859-1] (original)
+++ branches/ntvdm/subsystems/ntvdm/lang/en-US.rc (removed)
@@ -1,12 +0,0 @@
-/*
- * Moved all hardcoded strings to En.rc.
- * By Magnus Olsen 2005
- */
-
-LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
-STRINGTABLE DISCARDABLE
-BEGIN
-
-STRING_WelcomeMsg, "ReactOS Virtual DOS Machine support.\n"
-STRING_PromptMsg, "Type r<cr> to run, s<cr> to shutdown or
q<cr> to quit now."
-END
Removed: branches/ntvdm/subsystems/ntvdm/lang/es-ES.rc
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/lang/es-…
==============================================================================
--- branches/ntvdm/subsystems/ntvdm/lang/es-ES.rc [iso-8859-1] (original)
+++ branches/ntvdm/subsystems/ntvdm/lang/es-ES.rc (removed)
@@ -1,12 +0,0 @@
-/*
- * Spanish Resource File
- * Reactos(c)2006 Samuel Serapion
- */
-
-LANGUAGE LANG_SPANISH, SUBLANG_NEUTRAL
-STRINGTABLE DISCARDABLE
-BEGIN
-
-STRING_WelcomeMsg, "Maquina virtual de DOS en ReactOS.\n"
-STRING_PromptMsg, "Escriba r<cr> para correr, s<cr> para
desactivar or q<cr> para salir ahora."
-END
Removed: branches/ntvdm/subsystems/ntvdm/lang/fr-FR.rc
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/lang/fr-…
==============================================================================
--- branches/ntvdm/subsystems/ntvdm/lang/fr-FR.rc [iso-8859-1] (original)
+++ branches/ntvdm/subsystems/ntvdm/lang/fr-FR.rc (removed)
@@ -1,12 +0,0 @@
-/*
- * Moved all hardcoded strings to En.rc.
- * By Magnus Olsen 2005
- */
-
-LANGUAGE LANG_FRENCH, SUBLANG_NEUTRAL
-STRINGTABLE DISCARDABLE
-BEGIN
-
-STRING_WelcomeMsg, "Aide de la Machine DOS Virtuel de ReactOS.\n"
-STRING_PromptMsg, "Taper r<cr> pour démarrer, s<cr> pour éteindre
ou q<cr> pour quitter maintenant."
-END
Removed: branches/ntvdm/subsystems/ntvdm/lang/hu-HU.rc
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/lang/hu-…
==============================================================================
--- branches/ntvdm/subsystems/ntvdm/lang/hu-HU.rc [iso-8859-1] (original)
+++ branches/ntvdm/subsystems/ntvdm/lang/hu-HU.rc (removed)
@@ -1,14 +0,0 @@
-/*
- * Hungarian resource file for ntvdm
- * Moved all hardcoded strings to En.rc.
- * By Magnus Olsen 2005
- * Translation by Robert Horvath 2005 - talley at cubeclub.hu
- */
-
-LANGUAGE LANG_HUNGARIAN, SUBLANG_DEFAULT
-STRINGTABLE DISCARDABLE
-BEGIN
-
-STRING_WelcomeMsg, "ReactOS Virtuális DOS Gép támogatás.\n"
-STRING_PromptMsg, "Futtatáshoz nyomd meg a r<cr>, leállításhoz a
s<cr> vagy kilépéshez a q<cr> gombot."
-END
Removed: branches/ntvdm/subsystems/ntvdm/lang/id-ID.rc
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/lang/id-…
==============================================================================
--- branches/ntvdm/subsystems/ntvdm/lang/id-ID.rc [iso-8859-1] (original)
+++ branches/ntvdm/subsystems/ntvdm/lang/id-ID.rc (removed)
@@ -1,8 +0,0 @@
-
-LANGUAGE LANG_INDONESIAN, SUBLANG_DEFAULT
-STRINGTABLE DISCARDABLE
-BEGIN
-
-STRING_WelcomeMsg, "Dukungan ReactOS Virtual DOS Machine.\n"
-STRING_PromptMsg, "Ketik r<cr> untuk menjalankan, s<cr> untuk
mematikan atau q<cr> untuk keluar sekarang."
-END
Removed: branches/ntvdm/subsystems/ntvdm/lang/it-IT.rc
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/lang/it-…
==============================================================================
--- branches/ntvdm/subsystems/ntvdm/lang/it-IT.rc [iso-8859-1] (original)
+++ branches/ntvdm/subsystems/ntvdm/lang/it-IT.rc (removed)
@@ -1,16 +0,0 @@
-/*
-* PROJECT: ReactOS Virtual DOS Machine
-* LICENSE: GPL - See COPYING in the top level directory
-* FILE: subsystems/ntvdm/it-IT.rc
-* PURPOSE: Italian Translation of subsystems/ntvdm/en-US.rc
-* PROGRAMMERS: Copyright (C) 2005 Magnus Olsen
-* Copyright (C) 2007 Daniele Forsi (dforsi at
gmail.com) Italian
Translation
-*/
-
-LANGUAGE LANG_ITALIAN, SUBLANG_NEUTRAL
-STRINGTABLE DISCARDABLE
-BEGIN
-
-STRING_WelcomeMsg, "Supporto di ReactOS per la macchina virtuale DOS.\n"
-STRING_PromptMsg, "Digitare r<invio> per avviare, s<invio> per
arrestare o q<invio> per abbandonare ora."
-END
Removed: branches/ntvdm/subsystems/ntvdm/lang/ja-JP.rc
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/lang/ja-…
==============================================================================
--- branches/ntvdm/subsystems/ntvdm/lang/ja-JP.rc [iso-8859-1] (original)
+++ branches/ntvdm/subsystems/ntvdm/lang/ja-JP.rc (removed)
@@ -1,12 +0,0 @@
-/*
- * Moved all hardcoded strings to En.rc.
- * By Magnus Olsen 2005
- */
-
-LANGUAGE LANG_JAPANESE, SUBLANG_DEFAULT
-STRINGTABLE DISCARDABLE
-BEGIN
-
-STRING_WelcomeMsg, "ReactOS Virtual DOS Machine support.\n"
-STRING_PromptMsg, "N®·éÉÍ r<cr> ðAVbg_E·éÉÍ
s<cr> ðA¡·®I¹³¹éÉÍ q<cr> ðü͵ľ³¢B"
-END
Removed: branches/ntvdm/subsystems/ntvdm/lang/no-NO.rc
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/lang/no-…
==============================================================================
--- branches/ntvdm/subsystems/ntvdm/lang/no-NO.rc [iso-8859-1] (original)
+++ branches/ntvdm/subsystems/ntvdm/lang/no-NO.rc (removed)
@@ -1,12 +0,0 @@
-/*
- * Moved all hardcoded strings to En.rc.
- * By Magnus Olsen 2005
- */
-
-LANGUAGE LANG_NORWEGIAN, SUBLANG_NEUTRAL
-STRINGTABLE DISCARDABLE
-BEGIN
-
-STRING_WelcomeMsg, "ReactOS Vituell DOS Maskin støtte.\n"
-STRING_PromptMsg, "Skriv r<cr> for å kjøre, s<cr> å avslutte eller
q<cr> for å slutte nå."
-END
Removed: branches/ntvdm/subsystems/ntvdm/lang/pl-PL.rc
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/lang/pl-…
==============================================================================
--- branches/ntvdm/subsystems/ntvdm/lang/pl-PL.rc [iso-8859-1] (original)
+++ branches/ntvdm/subsystems/ntvdm/lang/pl-PL.rc (removed)
@@ -1,14 +0,0 @@
-/*
- * translated by xrogers
- * xxrogers(a)users.sourceforge.net
- *
https://sourceforge.net/projects/reactospl
- * UTF-8 conversion by Caemyr (May, 2011)
- */
-
-LANGUAGE LANG_POLISH, SUBLANG_DEFAULT
-STRINGTABLE DISCARDABLE
-BEGIN
-
-STRING_WelcomeMsg, "Wirtualna maszyna DOS dla ReactOS.\n"
-STRING_PromptMsg, "WciÅnij r<cr> aby uruchomiÄ, s<cr> aby wyÅÄ
czyÄ lub q<cr>, aby zakoÅczyÄ."
-END
Removed: branches/ntvdm/subsystems/ntvdm/lang/pt-BR.rc
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/lang/pt-…
==============================================================================
--- branches/ntvdm/subsystems/ntvdm/lang/pt-BR.rc [iso-8859-1] (original)
+++ branches/ntvdm/subsystems/ntvdm/lang/pt-BR.rc (removed)
@@ -1,12 +0,0 @@
-/*
- * Moved all hardcoded strings to En.rc.
- * By Magnus Olsen 2005
- */
-
-LANGUAGE LANG_PORTUGUESE, SUBLANG_NEUTRAL
-STRINGTABLE DISCARDABLE
-BEGIN
-
-STRING_WelcomeMsg, "ReactOS subsistema para suporte DOS de 16 bits.\n"
-STRING_PromptMsg, "Digite r<cr> para executar, s<cr> para desligar
ou q<cr> para sair."
-END
Removed: branches/ntvdm/subsystems/ntvdm/lang/ro-RO.rc
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/lang/ro-…
==============================================================================
--- branches/ntvdm/subsystems/ntvdm/lang/ro-RO.rc [iso-8859-1] (original)
+++ branches/ntvdm/subsystems/ntvdm/lang/ro-RO.rc (removed)
@@ -1,14 +0,0 @@
-/*
- * FILE: subsystems/ntvdm/lang/ro-RO.rc
- * ReactOS Project (
http://www.reactos.org)
- * TRANSLATOR: Fulea Ètefan (PM on ReactOS Forum at fulea.stefan)
- * CHANGE LOG: 2011-10-16 initial translation
- */
-
-LANGUAGE LANG_ROMANIAN, SUBLANG_NEUTRAL
-STRINGTABLE DISCARDABLE
-BEGIN
-
-STRING_WelcomeMsg, "AsistenÈÄ pentru maÈina virtualÄ DOS.\n"
-STRING_PromptMsg, "TastaÈi r<cr> pentru a executa, s<cr> pentru a
închide sau q<cr> pentru a ieÈi imediat."
-END
Removed: branches/ntvdm/subsystems/ntvdm/lang/ru-RU.rc
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/lang/ru-…
==============================================================================
--- branches/ntvdm/subsystems/ntvdm/lang/ru-RU.rc [iso-8859-1] (original)
+++ branches/ntvdm/subsystems/ntvdm/lang/ru-RU.rc (removed)
@@ -1,12 +0,0 @@
-/*
- * Moved all hardcoded strings to En.rc.
- * By Magnus Olsen 2005
- */
-
-LANGUAGE LANG_RUSSIAN, SUBLANG_DEFAULT
-STRINGTABLE DISCARDABLE
-BEGIN
-
-STRING_WelcomeMsg, "ÐиÑÑÑалÑÐ½Ð°Ñ Ð¼Ð°Ñина поддеÑжки DOS
Ð´Ð»Ñ ReactOS.\n"
-STRING_PromptMsg, "ÐведиÑе r<cr> Ð´Ð»Ñ Ð·Ð°Ð¿ÑÑка,
s<cr> Ð´Ð»Ñ Ð²ÑклÑÑÐµÐ½Ð¸Ñ Ð¸Ð»Ð¸ q<cr> вÑÑ
ода."
-END
Removed: branches/ntvdm/subsystems/ntvdm/lang/sk-SK.rc
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/lang/sk-…
==============================================================================
--- branches/ntvdm/subsystems/ntvdm/lang/sk-SK.rc [iso-8859-1] (original)
+++ branches/ntvdm/subsystems/ntvdm/lang/sk-SK.rc (removed)
@@ -1,11 +0,0 @@
-/* TRANSLATOR: Mário Kaèmár /Mario Kacmar/ aka Kario (kario(a)szm.sk)
- * DATE OF TR: 12-02-2008
- */
-
-LANGUAGE LANG_SLOVAK, SUBLANG_DEFAULT
-STRINGTABLE DISCARDABLE
-BEGIN
-
-STRING_WelcomeMsg, "Podpora virtuálneho DOSového stroja v systéme
ReactOS.\n"
-STRING_PromptMsg, "Napíte r<cr> pre spustenie, s<cr> pre vypnutie
alebo q<cr> pre okamité skonèenie."
-END
Removed: branches/ntvdm/subsystems/ntvdm/lang/th-TH.rc
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/lang/th-…
==============================================================================
--- branches/ntvdm/subsystems/ntvdm/lang/th-TH.rc [iso-8859-1] (original)
+++ branches/ntvdm/subsystems/ntvdm/lang/th-TH.rc (removed)
@@ -1,8 +0,0 @@
-
-LANGUAGE LANG_THAI, SUBLANG_DEFAULT
-STRINGTABLE DISCARDABLE
-BEGIN
-
-STRING_WelcomeMsg, "ÃͧÃѺ¡Ò÷ӧҹÃкº´ÍÊàÊÁ×͹¢Í§ ReactOS\n"
-STRING_PromptMsg, "Ẻ r<cr> à¾×èÍ·Ó§Ò¹, s<cr> à¾×èͻԴÃкºËÃ×Í
q<cr> à¾×èÍÍÍ¡·Ñ¹·Õ"
-END
Removed: branches/ntvdm/subsystems/ntvdm/lang/uk-UA.rc
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/lang/uk-…
==============================================================================
--- branches/ntvdm/subsystems/ntvdm/lang/uk-UA.rc [iso-8859-1] (original)
+++ branches/ntvdm/subsystems/ntvdm/lang/uk-UA.rc (removed)
@@ -1,16 +0,0 @@
-/*
- * PROJECT: Virtual DOS Machine
- * LICENSE: GPL - See COPYING in the top level directory
- * FILE: subsystems/ntvdm/Uk.rc
- * PURPOSE: Ukraianian Language File for Virtual DOS Machine
- * TRANSLATOR: Artem Reznikov
- */
-
-LANGUAGE LANG_UKRAINIAN, SUBLANG_DEFAULT
-
-STRINGTABLE DISCARDABLE
-BEGIN
-
-STRING_WelcomeMsg, "ÐÑдÑÑимка вÑÑÑÑалÑÐ½Ð¾Ñ Ð¼Ð°Ñини DOS
Ñ ReactOS.\n"
-STRING_PromptMsg, "ÐведÑÑÑ r<cr> Ð´Ð»Ñ Ð·Ð°Ð¿ÑÑкÑ,
s<cr> Ð´Ð»Ñ Ð·Ð°ÐºÑиÑÑÑ Ð°Ð±Ð¾ q<cr>, Ñоб вийÑи
заÑаз."
-END
Removed: branches/ntvdm/subsystems/ntvdm/lang/zh-CN.rc
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/lang/zh-…
==============================================================================
--- branches/ntvdm/subsystems/ntvdm/lang/zh-CN.rc [iso-8859-1] (original)
+++ branches/ntvdm/subsystems/ntvdm/lang/zh-CN.rc (removed)
@@ -1,8 +0,0 @@
-
-LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED
-STRINGTABLE DISCARDABLE
-BEGIN
-
-STRING_WelcomeMsg, "ReactOS ÐéÄâ DOS »úÖ§³Ö¡£\n"
-STRING_PromptMsg, "ÊäÈë r<cr> ÒÔ±ãÔËÐУ¬s<cr> ÒÔ±ã¹Ø±Õ»òÕß
q<cr> ÒÔ±ãÁ¢¼´Í˳ö¡£"
-END
Removed: branches/ntvdm/subsystems/ntvdm/lang/zh-TW.rc
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/lang/zh-…
==============================================================================
--- branches/ntvdm/subsystems/ntvdm/lang/zh-TW.rc [iso-8859-1] (original)
+++ branches/ntvdm/subsystems/ntvdm/lang/zh-TW.rc (removed)
@@ -1,8 +0,0 @@
-
-LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL
-STRINGTABLE DISCARDABLE
-BEGIN
-
-STRING_WelcomeMsg, "ReactOS µêÀÀ DOS ¾÷¤ä´©¡C\n"
-STRING_PromptMsg, "Áä¤J r<cr> ¥H«K¹B¦æ¡A s<cr> ¥H«KÃö³¬©ÎªÌ
q<cr> ¥H«K¥ß§Y°h¥X¡C"
-END
Modified: branches/ntvdm/subsystems/ntvdm/ntvdm.c
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/ntvdm.c?…
==============================================================================
--- branches/ntvdm/subsystems/ntvdm/ntvdm.c [iso-8859-1] (original)
+++ branches/ntvdm/subsystems/ntvdm/ntvdm.c [iso-8859-1] Mon Jun 17 00:00:36 2013
@@ -1,375 +1,130 @@
/*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS kernel
- * FILE: subsys/ntvdm/ntvdm->c
+ * COPYRIGHT: GPL - See COPYING in the top level directory
+ * PROJECT: ReactOS Virtual DOS Machine
+ * FILE: ntvdm.c
* PURPOSE: Virtual DOS Machine
- * PROGRAMMER: Robert Dickenson (robd(a)mok.lvcm.com)
- * UPDATE HISTORY:
- * Created 23/10/2002
+ * PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
*/
-/* INCLUDES *****************************************************************/
+#include "ntvdm.h"
-#include <stdarg.h>
-#define WIN32_NO_STATUS
-#include <windef.h>
-#include <winbase.h>
-#include <wincon.h>
-#include <winuser.h>
-#include <stdio.h>
+BOOLEAN VdmRunning = TRUE;
+LPVOID BaseAddress = NULL;
+LPCWSTR ExceptionName[] =
+{
+ L"Division By Zero",
+ L"Debug",
+ L"Unexpected Error",
+ L"Breakpoint",
+ L"Integer Overflow",
+ L"Bound Range Exceeded",
+ L"Invalid Opcode",
+ L"FPU Not Available"
+};
-#include "resource.h"
+VOID DisplayMessage(LPCWSTR Format, ...)
+{
+ WCHAR Buffer[256];
+ va_list Parameters;
-#define NDEBUG
-#include <debug.h>
-
-/* GLOBALS ******************************************************************/
-
-
-/* FUNCTIONS *****************************************************************/
-
-void PrintString(char* fmt,...)
-{
- char buffer[512];
- va_list ap;
-
- va_start(ap, fmt);
- vsprintf(buffer, fmt, ap);
- va_end(ap);
-
- OutputDebugStringA(buffer);
+ va_start(Parameters, Format);
+ _vsnwprintf(Buffer, 256, Format, Parameters);
+ MessageBox(NULL, Buffer, L"NTVDM Subsystem", MB_OK);
+ va_end(Parameters);
}
-/*
-GetVersion
-GetVolumeInformationW
-GetWindowsDirectoryA
-GlobalMemoryStatus
-HeapAlloc
-HeapCreate
-HeapDestroy
-HeapFree
-HeapReAlloc
-
-GetNextVDMCommand
-ExitVDM
-RegisterConsoleVDM
-SetVDMCurrentDirectories
-VDMConsoleOperation
-WriteConsoleInputVDMW
-
-NtSetLdtEntries
-NtTerminateProcess
-
-NtMapViewOfSection
-NtUnmapViewOfSection
-
-NtVdmControl
- */
-typedef struct tag_VDM_CONFIG {
- int dos_options;
- int files;
- int buffers;
- WCHAR** device_list;
-//dos=high, umb
-//device=%SystemRoot%\system32\himem.sys
-//files=40
-} VDM_CONFIG, *PVDM_CONFIG;
-
-typedef struct tag_VDM_AUTOEXEC {
- WCHAR** load_list;
-//lh %SystemRoot%\system32\mscdexnt.exe
-//lh %SystemRoot%\system32\redir
-//lh %SystemRoot%\system32\dosx
-} VDM_AUTOEXEC, *PVDM_AUTOEXEC;
-
-typedef struct tag_VDM_CONTROL_BLOCK {
- HANDLE hHeap;
- PVOID ImageMem;
- VDM_CONFIG vdmConfig;
- VDM_AUTOEXEC vdmAutoexec;
- PROCESS_INFORMATION ProcessInformation;
- CHAR CommandLine[MAX_PATH];
- CHAR CurrentDirectory[MAX_PATH];
-
-} VDM_CONTROL_BLOCK, *PVDM_CONTROL_BLOCK;
-
-
-BOOL
-StartVDM(PVDM_CONTROL_BLOCK vdm)
+BOOL WINAPI ConsoleCtrlHandler(DWORD ControlType)
{
- BOOL Result;
- STARTUPINFOA StartupInfo;
-
- StartupInfo.cb = sizeof(StartupInfo);
- StartupInfo.lpReserved = NULL;
- StartupInfo.lpDesktop = NULL;
- StartupInfo.lpTitle = NULL;
- StartupInfo.dwFlags = 0;
- StartupInfo.cbReserved2 = 0;
- StartupInfo.lpReserved2 = 0;
-
- Result = CreateProcessA(vdm->CommandLine,
- NULL,
- NULL,
- NULL,
- FALSE,
- DETACHED_PROCESS,
- NULL,
- NULL,
- &StartupInfo,
- &vdm->ProcessInformation);
- if (!Result) {
- PrintString("VDM: Failed to execute target process\n");
- return FALSE;
- }
- WaitForSingleObject(vdm->ProcessInformation.hProcess, INFINITE);
- CloseHandle(vdm->ProcessInformation.hProcess);
- CloseHandle(vdm->ProcessInformation.hThread);
- return TRUE;
-}
-
-BOOL
-ShutdownVDM(PVDM_CONTROL_BLOCK vdm)
-{
- BOOL result = TRUE;
-
- return result;
-}
-
-BOOL ReadConfigForVDM(PVDM_CONTROL_BLOCK vdm)
-{
- BOOL result = TRUE;
- DWORD dwError;
- HANDLE hFile;
-
- hFile = CreateFileW(L"\\system32\\config.nt",
- GENERIC_READ,
- FILE_SHARE_READ,
- NULL,
- OPEN_ALWAYS /*OPEN_EXISTING*/,
- FILE_ATTRIBUTE_NORMAL,
- 0);
- dwError = GetLastError();
- if (hFile == INVALID_HANDLE_VALUE) {
- // error with file path or system problem?
- } else {
- if (dwError == 0L) {
- // we just created a new file, perhaps we should set/write some defaults?
+ switch (ControlType)
+ {
+ case CTRL_C_EVENT:
+ case CTRL_BREAK_EVENT:
+ {
+ /* Perform interrupt 0x23 */
+ EmulatorInterrupt(0x23);
}
- if (dwError == ERROR_ALREADY_EXISTS) {
- // read the line entries and cache in some struct...
+ default:
+ {
+ /* Stop the VDM if the user logs out or closes the console */
+ VdmRunning = FALSE;
}
- CloseHandle(hFile);
- }
-
- hFile = CreateFileW(L"\\system32\\autoexec.nt",
- GENERIC_READ,
- FILE_SHARE_READ,
- NULL,
- OPEN_ALWAYS,
- FILE_ATTRIBUTE_NORMAL,
- 0);
- dwError = GetLastError();
- if (hFile == INVALID_HANDLE_VALUE) {
- // error with file path or system problem?
- } else {
- if (dwError == 0L) {
- // we just created a new file, perhaps we should set/write some defaults?
- }
- if (dwError == ERROR_ALREADY_EXISTS) {
- // read the line entries and cache in some struct...
- }
- CloseHandle(hFile);
- }
-
- return result;
-}
-
-BOOL
-LoadConfigDriversForVDM(PVDM_CONFIG vdmConfig)
-{
- BOOL result = TRUE;
-
- return result;
-}
-
-BOOL
-SetConfigOptionsForVDM(PVDM_AUTOEXEC vdmAutoexec)
-{
- BOOL result = TRUE;
-
- return result;
-}
-
-BOOL
-CreateVDM(PVDM_CONTROL_BLOCK vdm)
-{
-// BOOL result = TRUE;
- SYSTEM_INFO inf;
- MEMORYSTATUS stat;
-
-
- GlobalMemoryStatus(&stat);
- if (stat.dwLength != sizeof(MEMORYSTATUS)) {
- printf("WARNING: GlobalMemoryStatus() returned unknown structure version,
size %ld, expected %d.\n", stat.dwLength, sizeof(stat));
- } else {
- printf("Memory Load: %ld percent in use.\n", stat.dwMemoryLoad);
- printf("\t%ld total bytes physical memory.\n", stat.dwTotalPhys);
- printf("\t%ld available physical memory.\n", stat.dwAvailPhys);
- printf("\t%ld total bytes paging file.\n", stat.dwTotalPageFile);
- printf("\t%ld available paging file.\n", stat.dwAvailPageFile);
- printf("\t%lx total bytes virtual memory.\n", stat.dwTotalVirtual);
- printf("\t%lx available bytes virtual memory.\n",
stat.dwAvailVirtual);
-
-#define OUT_OF_HEADROOM 90
- if (stat.dwMemoryLoad > OUT_OF_HEADROOM) {
- DPRINT("VDM: system resources deemed to low to start VDM.\n");
- //SetLastError();
- return FALSE;
- }
-
- }
-
- GetSystemInfo(&inf);
- vdm->hHeap = HeapCreate(0, inf.dwAllocationGranularity, 0);
- if (vdm->hHeap == NULL) {
- DPRINT("VDM: failed to create heap.\n");
- return FALSE;
- }
-
-#define DEFAULT_VDM_IMAGE_SIZE 2000000
- vdm->ImageMem = HeapAlloc(vdm->hHeap, 0, DEFAULT_VDM_IMAGE_SIZE);
- if (vdm->ImageMem == NULL) {
- DPRINT("VDM: failed to allocate image memory from heap %x.\n",
vdm->hHeap);
- HeapDestroy(vdm->hHeap);
- vdm->hHeap = NULL;
- return FALSE;
}
return TRUE;
}
-BOOL
-DestroyVDM(PVDM_CONTROL_BLOCK vdm)
+INT wmain(INT argc, WCHAR *argv[])
{
- BOOL result = TRUE;
+ INT i;
+ BOOLEAN PrintUsage = TRUE;
+ CHAR CommandLine[128];
- if (vdm->ImageMem != NULL) {
- if (HeapFree(vdm->hHeap, 0, vdm->ImageMem) != FALSE) {
- DPRINT("VDM: failed to free memory from heap %x.\n",
vdm->hHeap);
- result = FALSE;
- }
- vdm->ImageMem = NULL;
- }
- if (vdm->hHeap != NULL) {
- if (!HeapDestroy(vdm->hHeap)) {
- DPRINT("VDM: failed to destroy heap %x.\n", vdm->hHeap);
- result = FALSE;
- }
- vdm->hHeap = NULL;
- }
- return result;
-}
+ /* Set the handler routine */
+ SetConsoleCtrlHandler(ConsoleCtrlHandler, TRUE);
-int WINAPI
-WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
-{
- VDM_CONTROL_BLOCK VdmCB;
- DWORD Result;
- ULONG i;
- BOOL vdmStarted = FALSE;
+ /* Parse the command line arguments */
+ for (i = 1; i < argc; i++)
+ {
+ if (argv[i][0] != L'-' && argv[i][0] != L'/') continue;
- WCHAR WelcomeMsg[RC_STRING_MAX_SIZE];
- WCHAR PromptMsg[RC_STRING_MAX_SIZE];
- CHAR InputBuffer[255];
+ switch (argv[i][1])
+ {
+ case L'f':
+ case L'F':
+ {
+ if (argv[i+1] != NULL)
+ {
+ /* The DOS command line must be ASCII */
+ WideCharToMultiByte(CP_ACP, 0, argv[i+1], -1, CommandLine, 128, NULL,
NULL);
- LoadStringW( GetModuleHandle(NULL), STRING_WelcomeMsg, WelcomeMsg,sizeof(WelcomeMsg)
/ sizeof(WelcomeMsg[0]));
- LoadStringW( GetModuleHandle(NULL), STRING_PromptMsg, PromptMsg ,sizeof(PromptMsg) /
sizeof(PromptMsg[0]));
-
- AllocConsole();
- SetConsoleTitleW(L"ntvdm");
-
- WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE),
- WelcomeMsg, lstrlenW(WelcomeMsg), // wcslen(WelcomeMsg),
- &Result, NULL);
-
- if (!CreateVDM(&VdmCB)) {
- DPRINT("VDM: failed to create VDM.\n");
- //SetLastError();
- return 2;
- }
-
- ReadConfigForVDM(&VdmCB);
-
- if (!LoadConfigDriversForVDM(&(VdmCB.vdmConfig))) {
- DPRINT("VDM: failed to load configuration drivers.\n");
- //SetLastError();
- return 2;
- }
- if (!SetConfigOptionsForVDM(&(VdmCB.vdmAutoexec))) {
- DPRINT("VDM: failed to set configuration options.\n");
- //SetLastError();
- return 3;
- }
-
- GetSystemDirectoryA(VdmCB.CommandLine, MAX_PATH);
- strcat(VdmCB.CommandLine, "\\hello.exe");
- GetWindowsDirectoryA(VdmCB.CurrentDirectory, MAX_PATH);
-
- for (;;) {
- WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE),
- PromptMsg, lstrlenW(PromptMsg), // wcslen(PromptMsg),
- &Result, NULL);
- i = 0;
- do {
- ReadConsoleA(GetStdHandle(STD_INPUT_HANDLE),
- &InputBuffer[i], 1,
- &Result, NULL);
- if (++i >= (sizeof(InputBuffer) - 1)) {
+ /* This is the only mandatory parameter */
+ PrintUsage = FALSE;
+ }
break;
}
- } while (InputBuffer[i - 1] != '\n');
- InputBuffer[i - 1] = '\0';
-
- if (InputBuffer[0] == 'r' || InputBuffer[0] == 'R') {
- if (!vdmStarted) {
- if (StartVDM(&VdmCB)) {
- vdmStarted = TRUE;
- } else {
- DPRINT("VDM: failed to start.\n");
- }
- } else {
- DPRINT("VDM: already started.\n");
+ default:
+ {
+ wprintf(L"Unknown option: %s", argv[i]);
}
- }
- if (InputBuffer[0] == 's' || InputBuffer[0] == 'S') {
- if (vdmStarted) {
- if (ShutdownVDM(&VdmCB)) {
- vdmStarted = FALSE;
- } else {
- DPRINT("VDM: failed to shutdown.\n");
- }
- } else {
- DPRINT("VDM: not started.\n");
- }
- }
- if (InputBuffer[0] == 'q' || InputBuffer[0] == 'Q') {
- break;
}
}
- if (!ShutdownVDM(&VdmCB)) {
- DPRINT("VDM: failed to cleanly shutdown VDM.\n");
- //SetLastError();
- return 5;
+ if (PrintUsage)
+ {
+ wprintf(L"ReactOS Virtual DOS Machine\n\n");
+ wprintf(L"Usage: NTVDM /F <PROGRAM>\n");
+ return 0;
}
- if (!DestroyVDM(&VdmCB)) {
- DPRINT("VDM: failed to cleanly destroy VDM.\n");
- //SetLastError();
- return 6;
+ if (!EmulatorInitialize()) return 1;
+
+ /* Initialize the system BIOS */
+ if (!BiosInitialize())
+ {
+ wprintf(L"FATAL: Failed to initialize the VDM BIOS.\n");
+ goto Cleanup;
}
- ExitProcess(0);
+ /* Initialize the VDM DOS kernel */
+ if (!DosInitialize())
+ {
+ wprintf(L"FATAL: Failed to initialize the VDM DOS kernel.\n");
+ goto Cleanup;
+ }
+
+ /* Start the process from the command line */
+ if (!DosCreateProcess(CommandLine, 0))
+ {
+ DisplayMessage(L"Could not start program: %S", CommandLine);
+ return -1;
+ }
+
+ /* Main loop */
+ while (VdmRunning) EmulatorStep();
+
+Cleanup:
+ EmulatorCleanup();
+
return 0;
}
+
+/* EOF */
Added: branches/ntvdm/subsystems/ntvdm/ntvdm.h
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/ntvdm.h?…
==============================================================================
--- branches/ntvdm/subsystems/ntvdm/ntvdm.h (added)
+++ branches/ntvdm/subsystems/ntvdm/ntvdm.h [iso-8859-1] Mon Jun 17 00:00:36 2013
@@ -0,0 +1,199 @@
+/*
+ * COPYRIGHT: GPL - See COPYING in the top level directory
+ * PROJECT: ReactOS Virtual DOS Machine
+ * FILE: ntvdm.h
+ * PURPOSE: Header file to define commonly used stuff
+ * PROGRAMMERS: Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
+ */
+
+/* INCLUDES *******************************************************************/
+
+#include <windows.h>
+#include <tchar.h>
+#include <stdio.h>
+#include <conio.h>
+#include <assert.h>
+#include <stdarg.h>
+
+/* DEFINES ********************************************************************/
+
+#define TO_LINEAR(seg, off) (((seg) << 4) + (off))
+#define MAX_SEGMENT 0xFFFF
+#define MAX_OFFSET 0xFFFF
+#define MAX_ADDRESS TO_LINEAR(MAX_SEGMENT, MAX_OFFSET)
+#define ROM_AREA_START 0xC0000
+#define ROM_AREA_END 0xFFFFF
+#define BIOS_SEGMENT 0xF000
+#define VIDEO_BIOS_INTERRUPT 0x10
+#define SPECIAL_INT_NUM 0xFF
+#define SEGMENT_TO_MCB(seg) ((PDOS_MCB)((ULONG_PTR)BaseAddress + TO_LINEAR((seg), 0)))
+#define SEGMENT_TO_PSP(seg) ((PDOS_PSP)((ULONG_PTR)BaseAddress + TO_LINEAR((seg), 0)))
+
+/* DOS constants */
+#define DOS_VERSION 0x0600
+#define DOS_CONFIG_PATH L"%SystemRoot%\\system32\\CONFIG.NT"
+#define DOS_COMMAND_INTERPRETER
L"%SystemRoot%\\system32\\COMMAND.COM /k
%SystemRoot%\\system32\\AUTOEXEC.NT"
+#define FIRST_MCB_SEGMENT 0x1000
+#define USER_MEMORY_SIZE 0x8FFFF
+#define SYSTEM_PSP 0x08
+#define SYSTEM_ENV_BLOCK 0x800
+
+/* System console constants */
+#define CONSOLE_FONT_HEIGHT 8
+#define CONSOLE_VIDEO_MEM_START 0xB8000
+#define CONSOLE_VIDEO_MEM_END 0xBFFFF
+
+#define EMULATOR_FLAG_CF (1 << 0)
+#define EMULATOR_FLAG_PF (1 << 2)
+#define EMULATOR_FLAG_AF (1 << 4)
+#define EMULATOR_FLAG_ZF (1 << 6)
+#define EMULATOR_FLAG_SF (1 << 7)
+#define EMULATOR_FLAG_TF (1 << 8)
+#define EMULATOR_FLAG_IF (1 << 9)
+#define EMULATOR_FLAG_DF (1 << 10)
+#define EMULATOR_FLAG_OF (1 << 11)
+#define EMULATOR_FLAG_NT (1 << 14)
+#define EMULATOR_FLAG_RF (1 << 16)
+#define EMULATOR_FLAG_VM (1 << 17)
+#define EMULATOR_FLAG_AC (1 << 18)
+#define EMULATOR_FLAG_VIF (1 << 19)
+#define EMULATOR_FLAG_VIP (1 << 20)
+#define EMULATOR_FLAG_ID (1 << 21)
+
+typedef enum
+{
+ EMULATOR_REG_AX,
+ EMULATOR_REG_CX,
+ EMULATOR_REG_DX,
+ EMULATOR_REG_BX,
+ EMULATOR_REG_SI,
+ EMULATOR_REG_DI,
+ EMULATOR_REG_SP,
+ EMULATOR_REG_BP,
+ EMULATOR_REG_CS,
+ EMULATOR_REG_SS,
+ EMULATOR_REG_DS,
+ EMULATOR_REG_ES,
+ EMULATOR_REG_FS,
+ EMULATOR_REG_GS
+} EMULATOR_REGISTER;
+
+#pragma pack(push, 1)
+
+typedef struct _DOS_MCB
+{
+ CHAR BlockType;
+ WORD OwnerPsp;
+ WORD Size;
+ BYTE Unused[3];
+ CHAR Name[8];
+} DOS_MCB, *PDOS_MCB;
+
+typedef struct _DOS_FCB
+{
+ BYTE DriveNumber;
+ CHAR FileName[8];
+ CHAR FileExt[3];
+ WORD BlockNumber;
+ WORD RecordSize;
+ DWORD FileSize;
+ WORD LastWriteDate;
+ WORD LastWriteTime;
+ BYTE Reserved[8];
+ BYTE BlockRecord;
+ BYTE RecordNumber[3];
+} DOS_FCB, *PDOS_FCB;
+
+typedef struct _DOS_PSP
+{
+ BYTE Exit[2];
+ WORD MemSize;
+ BYTE Reserved0[6];
+ DWORD TerminateAddress;
+ DWORD BreakAddress;
+ DWORD CriticalAddress;
+ WORD ParentPsp;
+ BYTE HandleTable[20];
+ WORD EnvBlock;
+ DWORD LastStack;
+ WORD HandleTableSize;
+ DWORD HandleTablePtr;
+ DWORD PreviousPsp;
+ DWORD Reserved1;
+ WORD DosVersion;
+ BYTE Reserved2[14];
+ BYTE FarCall[3];
+ BYTE Reserved3[9];
+ DOS_FCB Fcb;
+ BYTE CommandLineSize;
+ CHAR CommandLine[127];
+} DOS_PSP, *PDOS_PSP;
+
+typedef struct _DOS_SFT_ENTRY
+{
+ WORD ReferenceCount;
+ WORD Mode;
+ BYTE Attribute;
+ WORD DeviceInfo;
+ DWORD DriveParamBlock;
+ WORD FirstCluster;
+ WORD FileTime;
+ WORD FileDate;
+ DWORD FileSize;
+ DWORD CurrentOffset;
+ WORD LastClusterAccessed;
+ DWORD DirEntSector;
+ BYTE DirEntryIndex;
+ CHAR FileName[11];
+ BYTE Reserved0[6];
+ WORD OwnerPsp;
+ BYTE Reserved1[8];
+} DOS_SFT_ENTRY, *PDOS_SFT_ENTRY;
+
+typedef struct _DOS_SFT
+{
+ DWORD NextTablePtr;
+ WORD FileCount;
+ DOS_SFT_ENTRY Entry[ANYSIZE_ARRAY];
+} DOS_SFT, *PDOS_SFT;
+
+typedef struct _DOS_INPUT_BUFFER
+{
+ BYTE MaxLength, Length;
+ CHAR Buffer[ANYSIZE_ARRAY];
+} DOS_INPUT_BUFFER, *PDOS_INPUT_BUFFER;
+
+#pragma pack(pop)
+
+/* FUNCTIONS ******************************************************************/
+
+extern LPVOID BaseAddress;
+extern BOOLEAN VdmRunning;
+extern LPCWSTR ExceptionName[];
+
+VOID DisplayMessage(LPCWSTR Format, ...);
+BOOLEAN BiosInitialize();
+VOID BiosUpdateConsole(ULONG StartAddress, ULONG EndAddress);
+VOID BiosPrintCharacter(CHAR Character, BYTE Attribute);
+BOOLEAN DosInitialize();
+WORD DosAllocateMemory(WORD Size);
+BOOLEAN DosFreeMemory(WORD Segment);
+WORD DosResizeMemory(WORD Segment, WORD NewSize);
+BOOLEAN DosCreateProcess(LPCSTR CommandLine, WORD EnvBlock);
+VOID DosInt20h(WORD CodeSegment);
+VOID DosInt21h(WORD CodeSegment);
+VOID DosBreakInterrupt();
+VOID BiosVideoService();
+VOID EmulatorSetStack(WORD Segment, WORD Offset);
+VOID EmulatorExecute(WORD Segment, WORD Offset);
+VOID EmulatorInterrupt(BYTE Number);
+ULONG EmulatorGetRegister(ULONG Register);
+VOID EmulatorSetRegister(ULONG Register, ULONG Value);
+VOID EmulatorSetFlag(ULONG Flag);
+VOID EmulatorClearFlag(ULONG Flag);
+BOOLEAN EmulatorGetFlag(ULONG Flag);
+BOOLEAN EmulatorInitialize();
+VOID EmulatorStep();
+VOID EmulatorCleanup();
+
+/* EOF */
Propchange: branches/ntvdm/subsystems/ntvdm/ntvdm.h
------------------------------------------------------------------------------
svn:eol-style = native
Modified: branches/ntvdm/subsystems/ntvdm/ntvdm.rc
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/ntvdm.rc…
==============================================================================
--- branches/ntvdm/subsystems/ntvdm/ntvdm.rc [iso-8859-1] (original)
+++ branches/ntvdm/subsystems/ntvdm/ntvdm.rc [iso-8859-1] Mon Jun 17 00:00:36 2013
@@ -1,8 +1,12 @@
+#include <windef.h>
+#include <winuser.h>
+#include "resource.h"
-#include <windows.h>
-#define REACTOS_STR_FILE_DESCRIPTION "ReactOS Virtual DOS Machine\0"
-#define REACTOS_STR_INTERNAL_NAME "ntvdm\0"
-#define REACTOS_STR_ORIGINAL_FILENAME "ntvdm.exe\0"
+LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
+
+#define REACTOS_STR_FILE_DESCRIPTION "ReactOS Virtual DOS Machine"
+#define REACTOS_STR_INTERNAL_NAME "ntvdm"
+#define REACTOS_STR_ORIGINAL_FILENAME "ntvdm.exe"
#include <reactos/version.rc>
#include "rsrc.rc"
Modified: branches/ntvdm/subsystems/ntvdm/resource.h
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/resource…
==============================================================================
--- branches/ntvdm/subsystems/ntvdm/resource.h [iso-8859-1] (original)
+++ branches/ntvdm/subsystems/ntvdm/resource.h [iso-8859-1] Mon Jun 17 00:00:36 2013
@@ -1,6 +1,2 @@
-#define RC_STRING_MAX_SIZE 2048
-#define STRING_WelcomeMsg 100
-#define STRING_PromptMsg 101
-
/* EOF */
Modified: branches/ntvdm/subsystems/ntvdm/rsrc.rc
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/rsrc.rc?…
==============================================================================
--- branches/ntvdm/subsystems/ntvdm/rsrc.rc [iso-8859-1] (original)
+++ branches/ntvdm/subsystems/ntvdm/rsrc.rc [iso-8859-1] Mon Jun 17 00:00:36 2013
@@ -1,27 +1,4 @@
-#include <windows.h>
-#include "resource.h"
-
-/* Language-specific resources */
-#include "lang/bg-BG.rc"
-#include "lang/cs-CZ.rc"
-#include "lang/de-DE.rc"
-#include "lang/en-US.rc"
-#include "lang/es-ES.rc"
-#include "lang/fr-FR.rc"
-#include "lang/hu-HU.rc"
-#include "lang/id-ID.rc"
-#include "lang/it-IT.rc"
-#include "lang/ja-JP.rc"
-#include "lang/no-NO.rc"
-#include "lang/th-TH.rc"
-#include "lang/pt-BR.rc"
-#include "lang/sk-SK.rc"
-#include "lang/zh-CN.rc"
-#include "lang/zh-TW.rc"
+LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
// UTF-8
#pragma code_page(65001)
-#include "lang/pl-PL.rc"
-#include "lang/ro-RO.rc"
-#include "lang/ru-RU.rc"
-#include "lang/uk-UA.rc"