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/CMakeList... ============================================================================== --- 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?re... ============================================================================== --- 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?rev... ============================================================================== --- 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-B... ============================================================================== --- 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-C... ============================================================================== --- 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-D... ============================================================================== --- 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@gmail.com - * 2008 dark_shadow@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-U... ============================================================================== --- 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-E... ============================================================================== --- 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-F... ============================================================================== --- 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-H... ============================================================================== --- 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-I... ============================================================================== --- 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-I... ============================================================================== --- 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-J... ============================================================================== --- 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-N... ============================================================================== --- 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-P... ============================================================================== --- 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@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-B... ============================================================================== --- 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-R... ============================================================================== --- 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-R... ============================================================================== --- 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-S... ============================================================================== --- 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@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-T... ============================================================================== --- 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-U... ============================================================================== --- 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-C... ============================================================================== --- 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-T... ============================================================================== --- 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?r... ============================================================================== --- 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@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?r... ============================================================================== --- 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?r... ============================================================================== --- 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"