Author: hbelusca
Date: Sun Jan 26 21:51:27 2014
New Revision: 61846
URL:
http://svn.reactos.org/svn/reactos?rev=61846&view=rev
Log:
[NTVDM]
- Break the DOS source file into the "DOS BIOS" (also known in other places as
ibmbio or io or...), which is in fact some kind of hardware abstraction layer, and the
"DOS BDOS" kernel (also known in other places as
ibmdos.com or msdos.sys
or...).
- Add in DEM the possibility of loading the DOS from another files (WIP).
Added:
branches/ntvdm/subsystems/ntvdm/dos/dos32krnl/
- copied from r61838, branches/ntvdm/subsystems/ntvdm/dos/dos32/
branches/ntvdm/subsystems/ntvdm/dos/dos32krnl/bios.c
- copied, changed from r61838, branches/ntvdm/subsystems/ntvdm/dos/dos32/dos.c
Removed:
branches/ntvdm/subsystems/ntvdm/dos/dos32/
Modified:
branches/ntvdm/subsystems/ntvdm/CMakeLists.txt
branches/ntvdm/subsystems/ntvdm/dos/dem.c
branches/ntvdm/subsystems/ntvdm/dos/dem.h
branches/ntvdm/subsystems/ntvdm/dos/dos32krnl/dos.c
branches/ntvdm/subsystems/ntvdm/dos/dos32krnl/dos.h
branches/ntvdm/subsystems/ntvdm/ntvdm.c
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] Sun Jan 26 21:51:27 2014
@@ -15,7 +15,8 @@
hardware/speaker.c
hardware/timer.c
hardware/vga.c
- dos/dos32/dos.c
+ dos/dos32krnl/bios.c
+ dos/dos32krnl/dos.c
dos/dem.c
bop.c
emulator.c
Modified: branches/ntvdm/subsystems/ntvdm/dos/dem.c
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/dos/dem.…
==============================================================================
--- branches/ntvdm/subsystems/ntvdm/dos/dem.c [iso-8859-1] (original)
+++ branches/ntvdm/subsystems/ntvdm/dos/dem.c [iso-8859-1] Sun Jan 26 21:51:27 2014
@@ -19,33 +19,27 @@
/* Extra PSDK/NDK Headers */
#include <ndk/obtypes.h>
-/* PRIVATE VARIABLES **********************************************************/
-
-#pragma pack(push, 1)
-
-typedef struct _VDM_FIND_FILE_BLOCK
-{
- CHAR DriveLetter;
- CHAR Pattern[11];
- UCHAR AttribMask;
- DWORD Unused;
- HANDLE SearchHandle;
-
- /* The following part of the structure is documented */
- UCHAR Attributes;
- WORD FileTime;
- WORD FileDate;
- DWORD FileSize;
- CHAR FileName[13];
-} VDM_FIND_FILE_BLOCK, *PVDM_FIND_FILE_BLOCK;
-
-#pragma pack(pop)
-
-extern BYTE CurrentDrive;
-
-/* PRIVATE FUNCTIONS **********************************************************/
+/**/extern BYTE CurrentDrive;/**/
/* PUBLIC FUNCTIONS ***********************************************************/
+
+BOOLEAN DosInitialize(IN LPCSTR DosKernelFileNames)
+{
+ if (DosKernelFileNames)
+ {
+ DisplayMessage(L"NTVDM: Loading DOS kernel from external files is currently
unsupported");
+ return FALSE;
+ }
+ else
+ {
+ BOOLEAN Result;
+
+ Result = DosBIOSInitialize();
+ Result &= DosKRNLInitialize();
+
+ return Result;
+ }
+}
/* PUBLIC EXPORTED APIS *******************************************************/
@@ -86,7 +80,7 @@
{
BOOLEAN Success = TRUE;
WIN32_FIND_DATAA FindData;
- PVDM_FIND_FILE_BLOCK FindFileBlock = (PVDM_FIND_FILE_BLOCK)lpFindFileData;
+ PDOS_FIND_FILE_BLOCK FindFileBlock = (PDOS_FIND_FILE_BLOCK)lpFindFileData;
/* Fill the block */
FindFileBlock->DriveLetter = CurrentDrive + 'A';
@@ -125,7 +119,7 @@
demFileFindNext(OUT PVOID lpFindFileData)
{
WIN32_FIND_DATAA FindData;
- PVDM_FIND_FILE_BLOCK FindFileBlock = (PVDM_FIND_FILE_BLOCK)lpFindFileData;
+ PDOS_FIND_FILE_BLOCK FindFileBlock = (PDOS_FIND_FILE_BLOCK)lpFindFileData;
do
{
Modified: branches/ntvdm/subsystems/ntvdm/dos/dem.h
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/dos/dem.…
==============================================================================
--- branches/ntvdm/subsystems/ntvdm/dos/dem.h [iso-8859-1] (original)
+++ branches/ntvdm/subsystems/ntvdm/dos/dem.h [iso-8859-1] Sun Jan 26 21:51:27 2014
@@ -16,8 +16,11 @@
/* INCLUDES *******************************************************************/
#include "ntvdm.h"
+#include "dos32krnl/dos.h"
/* FUNCTIONS ******************************************************************/
+
+BOOLEAN DosInitialize(IN LPCSTR DosKernelFileNames);
DWORD
WINAPI
Copied: branches/ntvdm/subsystems/ntvdm/dos/dos32krnl/bios.c (from r61838,
branches/ntvdm/subsystems/ntvdm/dos/dos32/dos.c)
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/dos/dos3…
==============================================================================
--- branches/ntvdm/subsystems/ntvdm/dos/dos32/dos.c [iso-8859-1] (original)
+++ branches/ntvdm/subsystems/ntvdm/dos/dos32krnl/bios.c [iso-8859-1] Sun Jan 26 21:51:27
2014
@@ -12,26 +12,15 @@
#include "emulator.h"
#include "dos.h"
-#include "dos/dem.h"
#include "bios/bios.h"
#include "bop.h"
-#include "int32.h"
-#include "registers.h"
+// #include "int32.h"
/* PRIVATE VARIABLES **********************************************************/
-static WORD CurrentPsp = SYSTEM_PSP;
-static WORD DosLastError = 0;
-static DWORD DiskTransferArea;
-/*static*/ BYTE CurrentDrive;
-static CHAR LastDrive = 'E';
-static CHAR CurrentDirectories[NUM_DRIVES][DOS_DIR_LENGTH];
-static HANDLE DosSystemFileTable[DOS_SFT_SIZE];
-static WORD DosSftRefCount[DOS_SFT_SIZE];
-static BYTE DosAllocStrategy = DOS_ALLOC_BEST_FIT;
-static BOOLEAN DosUmbLinked = FALSE;
-static WORD DosErrorLevel = 0x0000;
+// static BYTE CurrentDrive;
+// static CHAR CurrentDirectories[NUM_DRIVES][DOS_DIR_LENGTH];
/* BOP Identifiers */
#define BOP_DOS 0x50 // DOS System BOP (for NTIO.SYS and NTDOS.SYS)
@@ -39,755 +28,7 @@
/* PRIVATE FUNCTIONS **********************************************************/
-static VOID DosCombineFreeBlocks(WORD StartBlock)
-{
- PDOS_MCB CurrentMcb = SEGMENT_TO_MCB(StartBlock), NextMcb;
-
- /* If this is the last block or it's not free, quit */
- if (CurrentMcb->BlockType == 'Z' || CurrentMcb->OwnerPsp != 0) return;
-
- while (TRUE)
- {
- /* Get a pointer to the next MCB */
- NextMcb = SEGMENT_TO_MCB(StartBlock + CurrentMcb->Size + 1);
-
- /* Check if the next MCB is free */
- if (NextMcb->OwnerPsp == 0)
- {
- /* Combine them */
- CurrentMcb->Size += NextMcb->Size + 1;
- CurrentMcb->BlockType = NextMcb->BlockType;
- NextMcb->BlockType = 'I';
- }
- else
- {
- /* No more adjoining free blocks */
- break;
- }
- }
-}
-
-static WORD DosAllocateMemory(WORD Size, WORD *MaxAvailable)
-{
- WORD Result = 0, Segment = FIRST_MCB_SEGMENT, MaxSize = 0;
- PDOS_MCB CurrentMcb, NextMcb;
- BOOLEAN SearchUmb = FALSE;
-
- DPRINT("DosAllocateMemory: Size 0x%04X\n", Size);
-
- if (DosUmbLinked && (DosAllocStrategy & (DOS_ALLOC_HIGH |
DOS_ALLOC_HIGH_LOW)))
- {
- /* Search UMB first */
- Segment = UMB_START_SEGMENT;
- SearchUmb = TRUE;
- }
-
- 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')
- {
- DPRINT("The DOS memory arena is corrupted!\n");
- DosLastError = ERROR_ARENA_TRASHED;
- return 0;
- }
-
- /* Only check free blocks */
- if (CurrentMcb->OwnerPsp != 0) goto Next;
-
- /* Combine this free block with adjoining free blocks */
- DosCombineFreeBlocks(Segment);
-
- /* Update the maximum block size */
- if (CurrentMcb->Size > MaxSize) MaxSize = CurrentMcb->Size;
-
- /* Check if this block is big enough */
- if (CurrentMcb->Size < Size) goto Next;
-
- switch (DosAllocStrategy & 0x3F)
- {
- case DOS_ALLOC_FIRST_FIT:
- {
- /* For first fit, stop immediately */
- Result = Segment;
- goto Done;
- }
-
- case DOS_ALLOC_BEST_FIT:
- {
- /* For best fit, update the smallest block found so far */
- if ((Result == 0) || (CurrentMcb->Size <
SEGMENT_TO_MCB(Result)->Size))
- {
- Result = Segment;
- }
-
- break;
- }
-
- case DOS_ALLOC_LAST_FIT:
- {
- /* For last fit, make the current block the result, but keep searching
*/
- Result = Segment;
- break;
- }
- }
-
-Next:
- /* If this was the last MCB in the chain, quit */
- if (CurrentMcb->BlockType == 'Z')
- {
- /* Check if nothing was found while searching through UMBs */
- if ((Result == 0) && SearchUmb && (DosAllocStrategy &
DOS_ALLOC_HIGH_LOW))
- {
- /* Search low memory */
- Segment = FIRST_MCB_SEGMENT;
- continue;
- }
-
- break;
- }
-
- /* Otherwise, update the segment and continue */
- Segment += CurrentMcb->Size + 1;
- }
-
-Done:
-
- /* If we didn't find a free block, return 0 */
- if (Result == 0)
- {
- DosLastError = ERROR_NOT_ENOUGH_MEMORY;
- if (MaxAvailable) *MaxAvailable = MaxSize;
- 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 = CurrentMcb->Size - Size - 1;
- NextMcb->OwnerPsp = 0;
-
- /* Update the current block */
- CurrentMcb->BlockType = 'M';
- CurrentMcb->Size = Size;
- }
-
- /* Take ownership of the block */
- CurrentMcb->OwnerPsp = CurrentPsp;
-
- /* Return the segment of the data portion of the block */
- return Result + 1;
-}
-
-static BOOLEAN DosResizeMemory(WORD BlockData, WORD NewSize, WORD *MaxAvailable)
-{
- BOOLEAN Success = TRUE;
- WORD Segment = BlockData - 1, ReturnSize = 0, NextSegment;
- PDOS_MCB Mcb = SEGMENT_TO_MCB(Segment), NextMcb;
-
- DPRINT("DosResizeMemory: BlockData 0x%04X, NewSize 0x%04X\n",
- BlockData,
- NewSize);
-
- /* Make sure this is a valid, allocated block */
- if ((Mcb->BlockType != 'M' && Mcb->BlockType != 'Z') ||
Mcb->OwnerPsp == 0)
- {
- Success = FALSE;
- DosLastError = ERROR_INVALID_HANDLE;
- goto Done;
- }
-
- ReturnSize = Mcb->Size;
-
- /* Check if we need to expand or contract the block */
- if (NewSize > Mcb->Size)
- {
- /* We can't expand the last block */
- if (Mcb->BlockType != 'M')
- {
- Success = FALSE;
- goto Done;
- }
-
- /* Get the pointer and segment of the next MCB */
- NextSegment = Segment + Mcb->Size + 1;
- NextMcb = SEGMENT_TO_MCB(NextSegment);
-
- /* Make sure the next segment is free */
- if (NextMcb->OwnerPsp != 0)
- {
- DPRINT("Cannot expand memory block: next segment is not free!\n");
- DosLastError = ERROR_NOT_ENOUGH_MEMORY;
- Success = FALSE;
- goto Done;
- }
-
- /* Combine this free block with adjoining free blocks */
- DosCombineFreeBlocks(NextSegment);
-
- /* Set the maximum possible size of the block */
- ReturnSize += NextMcb->Size + 1;
-
- /* Maximize the current block */
- Mcb->Size = ReturnSize;
- Mcb->BlockType = NextMcb->BlockType;
-
- /* Invalidate the next block */
- NextMcb->BlockType = 'I';
-
- /* Check if the block is larger than requested */
- if (Mcb->Size > NewSize)
- {
- DPRINT("Block too large, reducing size from 0x%04X to 0x%04X\n",
- Mcb->Size,
- NewSize);
-
- /* It is, split it into two blocks */
- NextMcb = SEGMENT_TO_MCB(Segment + NewSize + 1);
-
- /* Initialize the new MCB structure */
- NextMcb->BlockType = Mcb->BlockType;
- NextMcb->Size = Mcb->Size - NewSize - 1;
- NextMcb->OwnerPsp = 0;
-
- /* Update the current block */
- Mcb->BlockType = 'M';
- Mcb->Size = NewSize;
- }
- }
- else if (NewSize < Mcb->Size)
- {
- DPRINT("Shrinking block from 0x%04X to 0x%04X\n",
- Mcb->Size,
- NewSize);
-
- /* Just split the block */
- NextMcb = SEGMENT_TO_MCB(Segment + NewSize + 1);
- NextMcb->BlockType = Mcb->BlockType;
- NextMcb->Size = Mcb->Size - NewSize - 1;
- NextMcb->OwnerPsp = 0;
-
- /* Update the MCB */
- Mcb->BlockType = 'M';
- Mcb->Size = NewSize;
- }
-
-Done:
- /* Check if the operation failed */
- if (!Success)
- {
- DPRINT("DosResizeMemory FAILED. Maximum available: 0x%04X\n",
- ReturnSize);
-
- /* Return the maximum possible size */
- if (MaxAvailable) *MaxAvailable = ReturnSize;
- }
-
- return Success;
-}
-
-static BOOLEAN DosFreeMemory(WORD BlockData)
-{
- PDOS_MCB Mcb = SEGMENT_TO_MCB(BlockData - 1);
-
- DPRINT("DosFreeMemory: BlockData 0x%04X\n", BlockData);
-
- /* Make sure the MCB is valid */
- if (Mcb->BlockType != 'M' && Mcb->BlockType != 'Z')
- {
- DPRINT("MCB block type '%c' not valid!\n", Mcb->BlockType);
- return FALSE;
- }
-
- /* Mark the block as free */
- Mcb->OwnerPsp = 0;
-
- return TRUE;
-}
-
-/* Taken from base/shell/cmd/console.c */
-static BOOL IsConsoleHandle(HANDLE hHandle)
-{
- DWORD dwMode;
-
- /* Check whether the handle may be that of a console... */
- if ((GetFileType(hHandle) & FILE_TYPE_CHAR) == 0) return FALSE;
-
- /*
- * It may be. Perform another test... The idea comes from the
- * MSDN description of the WriteConsole API:
- *
- * "WriteConsole fails if it is used with a standard handle
- * that is redirected to a file. If an application processes
- * multilingual output that can be redirected, determine whether
- * the output handle is a console handle (one method is to call
- * the GetConsoleMode function and check whether it succeeds).
- * If the handle is a console handle, call WriteConsole. If the
- * handle is not a console handle, the output is redirected and
- * you should call WriteFile to perform the I/O."
- */
- return GetConsoleMode(hHandle, &dwMode);
-}
-
-static WORD DosCopyEnvironmentBlock(WORD SourceSegment, LPCSTR ProgramName)
-{
- PCHAR Ptr, SourceBuffer, DestBuffer = NULL;
- ULONG TotalSize = 0;
- WORD DestSegment;
-
- Ptr = SourceBuffer = (PCHAR)SEG_OFF_TO_PTR(SourceSegment, 0);
-
- /* Calculate the size of the environment block */
- while (*Ptr)
- {
- TotalSize += strlen(Ptr) + 1;
- Ptr += strlen(Ptr) + 1;
- }
- TotalSize++;
-
- /* Add the string buffer size */
- TotalSize += strlen(ProgramName) + 1;
-
- /* Allocate the memory for the environment block */
- DestSegment = DosAllocateMemory((WORD)((TotalSize + 0x0F) >> 4), NULL);
- if (!DestSegment) return 0;
-
- Ptr = SourceBuffer;
-
- DestBuffer = (PCHAR)SEG_OFF_TO_PTR(DestSegment, 0);
- while (*Ptr)
- {
- /* Copy the string */
- strcpy(DestBuffer, Ptr);
-
- /* Advance to the next string */
- DestBuffer += strlen(Ptr);
- Ptr += strlen(Ptr) + 1;
-
- /* Put a zero after the string */
- *(DestBuffer++) = 0;
- }
-
- /* Set the final zero */
- *(DestBuffer++) = 0;
-
- /* Copy the program name after the environment block */
- strcpy(DestBuffer, ProgramName);
-
- return DestSegment;
-}
-
-static VOID DosChangeMemoryOwner(WORD Segment, WORD NewOwner)
-{
- PDOS_MCB Mcb = SEGMENT_TO_MCB(Segment - 1);
-
- /* Just set the owner */
- Mcb->OwnerPsp = NewOwner;
-}
-
-static WORD DosOpenHandle(HANDLE Handle)
-{
- BYTE i;
- WORD DosHandle;
- PDOS_PSP PspBlock;
- LPBYTE HandleTable;
-
- /* The system PSP has no handle table */
- if (CurrentPsp == SYSTEM_PSP) return INVALID_DOS_HANDLE;
-
- /* Get a pointer to the handle table */
- PspBlock = SEGMENT_TO_PSP(CurrentPsp);
- HandleTable = (LPBYTE)FAR_POINTER(PspBlock->HandleTablePtr);
-
- /* Find a free entry in the JFT */
- for (DosHandle = 0; DosHandle < PspBlock->HandleTableSize; DosHandle++)
- {
- if (HandleTable[DosHandle] == 0xFF) break;
- }
-
- /* If there are no free entries, fail */
- if (DosHandle == PspBlock->HandleTableSize) return INVALID_DOS_HANDLE;
-
- /* Check if the handle is already in the SFT */
- for (i = 0; i < DOS_SFT_SIZE; i++)
- {
- /* Check if this is the same handle */
- if (DosSystemFileTable[i] != Handle) continue;
-
- /* Already in the table, reference it */
- DosSftRefCount[i]++;
-
- /* Set the JFT entry to that SFT index */
- HandleTable[DosHandle] = i;
-
- /* Return the new handle */
- return DosHandle;
- }
-
- /* Add the handle to the SFT */
- for (i = 0; i < DOS_SFT_SIZE; i++)
- {
- /* Make sure this is an empty table entry */
- if (DosSystemFileTable[i] != INVALID_HANDLE_VALUE) continue;
-
- /* Initialize the empty table entry */
- DosSystemFileTable[i] = Handle;
- DosSftRefCount[i] = 1;
-
- /* Set the JFT entry to that SFT index */
- HandleTable[DosHandle] = i;
-
- /* Return the new handle */
- return DosHandle;
- }
-
- /* The SFT is full */
- return INVALID_DOS_HANDLE;
-}
-
-static HANDLE DosGetRealHandle(WORD DosHandle)
-{
- PDOS_PSP PspBlock;
- LPBYTE HandleTable;
-
- /* The system PSP has no handle table */
- if (CurrentPsp == SYSTEM_PSP) return INVALID_HANDLE_VALUE;
-
- /* Get a pointer to the handle table */
- PspBlock = SEGMENT_TO_PSP(CurrentPsp);
- HandleTable = (LPBYTE)FAR_POINTER(PspBlock->HandleTablePtr);
-
- /* Make sure the handle is open */
- if (HandleTable[DosHandle] == 0xFF) return INVALID_HANDLE_VALUE;
-
- /* Return the Win32 handle */
- return DosSystemFileTable[HandleTable[DosHandle]];
-}
-
-static VOID DosCopyHandleTable(LPBYTE DestinationTable)
-{
- INT i;
- PDOS_PSP PspBlock;
- LPBYTE SourceTable;
-
- /* Clear the table first */
- for (i = 0; i < 20; i++) DestinationTable[i] = 0xFF;
-
- /* Check if this is the initial process */
- if (CurrentPsp == SYSTEM_PSP)
- {
- /* Set up the standard I/O devices */
- for (i = 0; i <= 2; i++)
- {
- /* Set the index in the SFT */
- DestinationTable[i] = (BYTE)i;
-
- /* Increase the reference count */
- DosSftRefCount[i]++;
- }
-
- /* Done */
- return;
- }
-
- /* Get the parent PSP block and handle table */
- PspBlock = SEGMENT_TO_PSP(CurrentPsp);
- SourceTable = (LPBYTE)FAR_POINTER(PspBlock->HandleTablePtr);
-
- /* Copy the first 20 handles into the new table */
- for (i = 0; i < 20; i++)
- {
- DestinationTable[i] = SourceTable[i];
-
- /* Increase the reference count */
- DosSftRefCount[SourceTable[i]]++;
- }
-}
-
-static BOOLEAN DosCloseHandle(WORD DosHandle)
-{
- BYTE SftIndex;
- PDOS_PSP PspBlock;
- LPBYTE HandleTable;
-
- DPRINT("DosCloseHandle: DosHandle 0x%04X\n", DosHandle);
-
- /* The system PSP has no handle table */
- if (CurrentPsp == SYSTEM_PSP) return FALSE;
-
- /* Get a pointer to the handle table */
- PspBlock = SEGMENT_TO_PSP(CurrentPsp);
- HandleTable = (LPBYTE)FAR_POINTER(PspBlock->HandleTablePtr);
-
- /* Make sure the handle is open */
- if (HandleTable[DosHandle] == 0xFF) return FALSE;
-
- /* Decrement the reference count of the SFT entry */
- SftIndex = HandleTable[DosHandle];
- DosSftRefCount[SftIndex]--;
-
- /* Check if the reference count fell to zero */
- if (!DosSftRefCount[SftIndex])
- {
- /* Close the file, it's no longer needed */
- CloseHandle(DosSystemFileTable[SftIndex]);
-
- /* Clear the handle */
- DosSystemFileTable[SftIndex] = INVALID_HANDLE_VALUE;
- }
-
- /* Clear the entry in the JFT */
- HandleTable[DosHandle] = 0xFF;
-
- return TRUE;
-}
-
-static BOOLEAN DosDuplicateHandle(WORD OldHandle, WORD NewHandle)
-{
- BYTE SftIndex;
- PDOS_PSP PspBlock;
- LPBYTE HandleTable;
-
- DPRINT("DosDuplicateHandle: OldHandle 0x%04X, NewHandle 0x%04X\n",
- OldHandle,
- NewHandle);
-
- /* The system PSP has no handle table */
- if (CurrentPsp == SYSTEM_PSP) return FALSE;
-
- /* Get a pointer to the handle table */
- PspBlock = SEGMENT_TO_PSP(CurrentPsp);
- HandleTable = (LPBYTE)FAR_POINTER(PspBlock->HandleTablePtr);
-
- /* Make sure the old handle is open */
- if (HandleTable[OldHandle] == 0xFF) return FALSE;
-
- /* Check if the new handle is open */
- if (HandleTable[NewHandle] != 0xFF)
- {
- /* Close it */
- DosCloseHandle(NewHandle);
- }
-
- /* Increment the reference count of the SFT entry */
- SftIndex = HandleTable[OldHandle];
- DosSftRefCount[SftIndex]++;
-
- /* Make the new handle point to that SFT entry */
- HandleTable[NewHandle] = SftIndex;
-
- /* Return success */
- return TRUE;
-}
-
-static BOOLEAN DosLinkUmb(VOID)
-{
- DWORD Segment = FIRST_MCB_SEGMENT;
- PDOS_MCB Mcb = SEGMENT_TO_MCB(Segment);
-
- DPRINT("Linking UMB\n");
-
- /* Check if UMBs are already linked */
- if (DosUmbLinked) return FALSE;
-
- /* Find the last block */
- while ((Mcb->BlockType == 'M') && (Segment <= 0xFFFF))
- {
- Segment += Mcb->Size + 1;
- Mcb = SEGMENT_TO_MCB(Segment);
- }
-
- /* Make sure it's valid */
- if (Mcb->BlockType != 'Z') return FALSE;
-
- /* Connect the MCB with the UMB chain */
- Mcb->BlockType = 'M';
-
- DosUmbLinked = TRUE;
- return TRUE;
-}
-
-static BOOLEAN DosUnlinkUmb(VOID)
-{
- DWORD Segment = FIRST_MCB_SEGMENT;
- PDOS_MCB Mcb = SEGMENT_TO_MCB(Segment);
-
- DPRINT("Unlinking UMB\n");
-
- /* Check if UMBs are already unlinked */
- if (!DosUmbLinked) return FALSE;
-
- /* Find the block preceding the MCB that links it with the UMB chain */
- while (Segment <= 0xFFFF)
- {
- if ((Segment + Mcb->Size) == (FIRST_MCB_SEGMENT + USER_MEMORY_SIZE))
- {
- /* This is the last non-UMB segment */
- break;
- }
-
- /* Advance to the next MCB */
- Segment += Mcb->Size + 1;
- Mcb = SEGMENT_TO_MCB(Segment);
- }
-
- /* Mark the MCB as the last MCB */
- Mcb->BlockType = 'Z';
-
- DosUmbLinked = FALSE;
- return TRUE;
-}
-
-static WORD DosCreateFile(LPWORD Handle, LPCSTR FilePath, WORD Attributes)
-{
- HANDLE FileHandle;
- WORD DosHandle;
-
- DPRINT("DosCreateFile: FilePath \"%s\", Attributes 0x%04X\n",
- FilePath,
- Attributes);
-
- /* Create the file */
- FileHandle = CreateFileA(FilePath,
- GENERIC_READ | GENERIC_WRITE,
- FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
- NULL,
- CREATE_ALWAYS,
- Attributes,
- NULL);
-
- if (FileHandle == INVALID_HANDLE_VALUE)
- {
- /* Return the error code */
- return (WORD)GetLastError();
- }
-
- /* Open the DOS handle */
- DosHandle = DosOpenHandle(FileHandle);
-
- if (DosHandle == INVALID_DOS_HANDLE)
- {
- /* Close the handle */
- CloseHandle(FileHandle);
-
- /* Return the error code */
- return ERROR_TOO_MANY_OPEN_FILES;
- }
-
- /* It was successful */
- *Handle = DosHandle;
- return ERROR_SUCCESS;
-}
-
-static WORD DosOpenFile(LPWORD Handle, LPCSTR FilePath, BYTE AccessMode)
-{
- HANDLE FileHandle;
- ACCESS_MASK Access = 0;
- WORD DosHandle;
-
- DPRINT("DosOpenFile: FilePath \"%s\", AccessMode 0x%04X\n",
- FilePath,
- AccessMode);
-
- /* Parse the access mode */
- switch (AccessMode & 3)
- {
- case 0:
- {
- /* Read-only */
- Access = GENERIC_READ;
- break;
- }
-
- case 1:
- {
- /* Write only */
- Access = GENERIC_WRITE;
- break;
- }
-
- case 2:
- {
- /* Read and write */
- Access = GENERIC_READ | GENERIC_WRITE;
- break;
- }
-
- default:
- {
- /* Invalid */
- return ERROR_INVALID_PARAMETER;
- }
- }
-
- /* Open the file */
- FileHandle = CreateFileA(FilePath,
- Access,
- FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
- NULL,
- OPEN_EXISTING,
- FILE_ATTRIBUTE_NORMAL,
- NULL);
-
- if (FileHandle == INVALID_HANDLE_VALUE)
- {
- /* Return the error code */
- return (WORD)GetLastError();
- }
-
- /* Open the DOS handle */
- DosHandle = DosOpenHandle(FileHandle);
-
- if (DosHandle == INVALID_DOS_HANDLE)
- {
- /* Close the handle */
- CloseHandle(FileHandle);
-
- /* Return the error code */
- return ERROR_TOO_MANY_OPEN_FILES;
- }
-
- /* It was successful */
- *Handle = DosHandle;
- return ERROR_SUCCESS;
-}
-
-static WORD DosReadFile(WORD FileHandle, LPVOID Buffer, WORD Count, LPWORD BytesRead)
-{
- WORD Result = ERROR_SUCCESS;
- DWORD BytesRead32 = 0;
- HANDLE Handle = DosGetRealHandle(FileHandle);
-
- DPRINT("DosReadFile: FileHandle 0x%04X, Count 0x%04X\n", FileHandle,
Count);
-
- /* Make sure the handle is valid */
- if (Handle == INVALID_HANDLE_VALUE) return ERROR_INVALID_HANDLE;
-
- /* Read the file */
- if (!ReadFile(Handle, Buffer, Count, &BytesRead32, NULL))
- {
- /* Store the error code */
- Result = (WORD)GetLastError();
- }
-
- /* The number of bytes read is always 16-bit */
- *BytesRead = LOWORD(BytesRead32);
-
- /* Return the error code */
- return Result;
-}
-
+#if 0
static WORD DosWriteFile(WORD FileHandle, LPVOID Buffer, WORD Count, LPWORD
BytesWritten)
{
WORD Result = ERROR_SUCCESS;
@@ -827,491 +68,9 @@
/* Return the error code */
return Result;
}
-
-static WORD DosSeekFile(WORD FileHandle, LONG Offset, BYTE Origin, LPDWORD NewOffset)
-{
- WORD Result = ERROR_SUCCESS;
- DWORD FilePointer;
- HANDLE Handle = DosGetRealHandle(FileHandle);
-
- DPRINT("DosSeekFile: FileHandle 0x%04X, Offset 0x%08X, Origin 0x%02X\n",
- FileHandle,
- Offset,
- Origin);
-
- /* Make sure the handle is valid */
- if (Handle == INVALID_HANDLE_VALUE) return ERROR_INVALID_HANDLE;
-
- /* Check if the origin is valid */
- if (Origin != FILE_BEGIN && Origin != FILE_CURRENT && Origin !=
FILE_END)
- {
- return ERROR_INVALID_FUNCTION;
- }
-
- /* Move the file pointer */
- FilePointer = SetFilePointer(Handle, Offset, NULL, Origin);
-
- /* Check if there's a possibility the operation failed */
- if (FilePointer == INVALID_SET_FILE_POINTER)
- {
- /* Get the real error code */
- Result = (WORD)GetLastError();
- }
-
- if (Result != ERROR_SUCCESS)
- {
- /* The operation did fail */
- return Result;
- }
-
- /* Return the file pointer, if requested */
- if (NewOffset) *NewOffset = FilePointer;
-
- /* Return success */
- return ERROR_SUCCESS;
-}
-
-static BOOLEAN DosFlushFileBuffers(WORD FileHandle)
-{
- HANDLE Handle = DosGetRealHandle(FileHandle);
-
- /* Make sure the handle is valid */
- if (Handle == INVALID_HANDLE_VALUE) return FALSE;
-
- /*
- * No need to check whether the handle is a console handle since
- * FlushFileBuffers() automatically does this check and calls
- * FlushConsoleInputBuffer() for us.
- */
- // if (IsConsoleHandle(Handle))
- // return (BOOLEAN)FlushConsoleInputBuffer(Handle);
- // else
- return (BOOLEAN)FlushFileBuffers(Handle);
-}
-
-static BOOLEAN DosChangeDrive(BYTE Drive)
-{
- WCHAR DirectoryPath[DOS_CMDLINE_LENGTH];
-
- /* Make sure the drive exists */
- if (Drive > (LastDrive - 'A')) return FALSE;
-
- /* Find the path to the new current directory */
- swprintf(DirectoryPath, L"%c\\%S", Drive + 'A',
CurrentDirectories[Drive]);
-
- /* Change the current directory of the process */
- if (!SetCurrentDirectory(DirectoryPath)) return FALSE;
-
- /* Set the current drive */
- CurrentDrive = Drive;
-
- /* Return success */
- return TRUE;
-}
-
-static BOOLEAN DosChangeDirectory(LPSTR Directory)
-{
- BYTE DriveNumber;
- DWORD Attributes;
- LPSTR Path;
-
- /* Make sure the directory path is not too long */
- if (strlen(Directory) >= DOS_DIR_LENGTH)
- {
- DosLastError = ERROR_PATH_NOT_FOUND;
- return FALSE;
- }
-
- /* Get the drive number */
- DriveNumber = Directory[0] - 'A';
-
- /* Make sure the drive exists */
- if (DriveNumber > (LastDrive - 'A'))
- {
- DosLastError = ERROR_PATH_NOT_FOUND;
- return FALSE;
- }
-
- /* Get the file attributes */
- Attributes = GetFileAttributesA(Directory);
-
- /* Make sure the path exists and is a directory */
- if ((Attributes == INVALID_FILE_ATTRIBUTES)
- || !(Attributes & FILE_ATTRIBUTE_DIRECTORY))
- {
- DosLastError = ERROR_PATH_NOT_FOUND;
- return FALSE;
- }
-
- /* Check if this is the current drive */
- if (DriveNumber == CurrentDrive)
- {
- /* Change the directory */
- if (!SetCurrentDirectoryA(Directory))
- {
- DosLastError = LOWORD(GetLastError());
- return FALSE;
- }
- }
-
- /* Get the directory part of the path */
- Path = strchr(Directory, '\\');
- if (Path != NULL)
- {
- /* Skip the backslash */
- Path++;
- }
-
- /* Set the directory for the drive */
- if (Path != NULL)
- {
- strncpy(CurrentDirectories[DriveNumber], Path, DOS_DIR_LENGTH);
- }
- else
- {
- CurrentDirectories[DriveNumber][0] = '\0';
- }
-
- /* Return success */
- return TRUE;
-}
+#endif
/* PUBLIC FUNCTIONS ***********************************************************/
-
-VOID DosInitializePsp(WORD PspSegment, LPCSTR CommandLine, WORD ProgramSize, WORD
Environment)
-{
- 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 number of the last paragraph */
- PspBlock->LastParagraph = PspSegment + ProgramSize - 1;
-
- /* Save the interrupt vectors */
- PspBlock->TerminateAddress = IntVecTable[0x22];
- PspBlock->BreakAddress = IntVecTable[0x23];
- PspBlock->CriticalAddress = IntVecTable[0x24];
-
- /* Set the parent PSP */
- PspBlock->ParentPsp = CurrentPsp;
-
- /* Copy the parent handle table */
- DosCopyHandleTable(PspBlock->HandleTable);
-
- /* Set the environment 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 = (BYTE)min(strlen(CommandLine), DOS_CMDLINE_LENGTH -
1);
- RtlCopyMemory(PspBlock->CommandLine, CommandLine, PspBlock->CommandLineSize);
- PspBlock->CommandLine[PspBlock->CommandLineSize] = '\r';
-}
-
-BOOLEAN DosCreateProcess(LPCSTR CommandLine, WORD EnvBlock)
-{
- BOOLEAN Success = FALSE, AllocatedEnvBlock = FALSE;
- HANDLE FileHandle = INVALID_HANDLE_VALUE, FileMapping = NULL;
- LPBYTE Address = NULL;
- LPSTR ProgramFilePath, Parameters[256];
- CHAR CommandLineCopy[DOS_CMDLINE_LENGTH];
- CHAR ParamString[DOS_CMDLINE_LENGTH];
- INT ParamCount = 0;
- WORD Segment = 0;
- WORD MaxAllocSize;
- DWORD i, FileSize, ExeSize;
- PIMAGE_DOS_HEADER Header;
- PDWORD RelocationTable;
- PWORD RelocWord;
-
- DPRINT("DosCreateProcess: CommandLine \"%s\", EnvBlock
0x%04X\n",
- CommandLine,
- EnvBlock);
-
- /* 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 < sizeof(Parameters)/sizeof(Parameters[0]))
- && ((Parameters[ParamCount] = strtok(NULL, " \t")) !=
NULL))
- {
- ParamCount++;
- }
-
- ZeroMemory(ParamString, sizeof(ParamString));
-
- /* Store the parameters in a string */
- for (i = 0; i < ParamCount; i++)
- {
- strncat(ParamString, Parameters[i], DOS_CMDLINE_LENGTH - strlen(ParamString) -
1);
- strncat(ParamString, " ", DOS_CMDLINE_LENGTH - strlen(ParamString) -
1);
- }
-
- /* 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;
-
- /* Did we get an environment segment? */
- if (!EnvBlock)
- {
- /* Set a flag to know if the environment block was allocated here */
- AllocatedEnvBlock = TRUE;
-
- /* No, copy the one from the parent */
- EnvBlock = DosCopyEnvironmentBlock((CurrentPsp != SYSTEM_PSP)
- ? SEGMENT_TO_PSP(CurrentPsp)->EnvBlock
- : SYSTEM_ENV_BLOCK,
- ProgramFilePath);
- }
-
- /* Check if this is an EXE file or a COM file */
- if (Address[0] == 'M' && Address[1] == 'Z')
- {
- /* EXE file */
-
- /* Get the MZ header */
- Header = (PIMAGE_DOS_HEADER)Address;
-
- /* Get the base size of the file, in paragraphs (rounded up) */
- ExeSize = (((Header->e_cp - 1) * 512) + Header->e_cblp + 0x0F) >> 4;
-
- /* Add the PSP size, in paragraphs */
- ExeSize += sizeof(DOS_PSP) >> 4;
-
- /* Add the maximum size that should be allocated */
- ExeSize += Header->e_maxalloc;
-
- /* Make sure it does not pass 0xFFFF */
- if (ExeSize > 0xFFFF) ExeSize = 0xFFFF;
-
- /* Reduce the size one by one until the allocation is successful */
- for (i = Header->e_maxalloc; i >= Header->e_minalloc; i--, ExeSize--)
- {
- /* Try to allocate that much memory */
- Segment = DosAllocateMemory((WORD)ExeSize, NULL);
- if (Segment != 0) break;
- }
-
- /* Check if at least the lowest allocation was successful */
- if (Segment == 0) goto Cleanup;
-
- /* Initialize the PSP */
- DosInitializePsp(Segment,
- ParamString,
- (WORD)ExeSize,
- EnvBlock);
-
- /* The process owns its own memory */
- DosChangeMemoryOwner(Segment, Segment);
- DosChangeMemoryOwner(EnvBlock, Segment);
-
- /* Copy the program to Segment:0100 */
- RtlCopyMemory(SEG_OFF_TO_PTR(Segment, 0x100),
- Address + (Header->e_cparhdr << 4),
- min(FileSize - (Header->e_cparhdr << 4),
- (ExeSize << 4) - sizeof(DOS_PSP)));
-
- /* Get the relocation table */
- RelocationTable = (PDWORD)(Address + Header->e_lfarlc);
-
- /* Perform relocations */
- for (i = 0; i < Header->e_crlc; i++)
- {
- /* Get a pointer to the word that needs to be patched */
- RelocWord = (PWORD)SEG_OFF_TO_PTR(Segment + HIWORD(RelocationTable[i]),
- 0x100 + LOWORD(RelocationTable[i]));
-
- /* Add the number of the EXE segment to it */
- *RelocWord += Segment + (sizeof(DOS_PSP) >> 4);
- }
-
- /* Set the initial segment registers */
- setDS(Segment);
- setES(Segment);
-
- /* Set the stack to the location from the header */
- EmulatorSetStack(Segment + (sizeof(DOS_PSP) >> 4) + Header->e_ss,
- Header->e_sp);
-
- /* Execute */
- CurrentPsp = Segment;
- DiskTransferArea = MAKELONG(0x80, Segment);
- EmulatorExecute(Segment + Header->e_cs + (sizeof(DOS_PSP) >> 4),
- Header->e_ip);
-
- Success = TRUE;
- }
- else
- {
- /* COM file */
-
- /* Find the maximum amount of memory that can be allocated */
- DosAllocateMemory(0xFFFF, &MaxAllocSize);
-
- /* Make sure it's enough for the whole program and the PSP */
- if (((DWORD)MaxAllocSize << 4) < (FileSize + sizeof(DOS_PSP))) goto
Cleanup;
-
- /* Allocate all of it */
- Segment = DosAllocateMemory(MaxAllocSize, NULL);
- if (Segment == 0) goto Cleanup;
-
- /* The process owns its own memory */
- DosChangeMemoryOwner(Segment, Segment);
- DosChangeMemoryOwner(EnvBlock, Segment);
-
- /* Copy the program to Segment:0100 */
- RtlCopyMemory(SEG_OFF_TO_PTR(Segment, 0x100),
- Address,
- FileSize);
-
- /* Initialize the PSP */
- DosInitializePsp(Segment,
- ParamString,
- MaxAllocSize,
- EnvBlock);
-
- /* Set the initial segment registers */
- setDS(Segment);
- setES(Segment);
-
- /* Set the stack to the last word of the segment */
- EmulatorSetStack(Segment, 0xFFFE);
-
- /*
- * Set the value on the stack to 0, so that a near return
- * jumps to PSP:0000 which has the exit code.
- */
- *((LPWORD)SEG_OFF_TO_PTR(Segment, 0xFFFE)) = 0;
-
- /* Execute */
- CurrentPsp = Segment;
- DiskTransferArea = MAKELONG(0x80, Segment);
- EmulatorExecute(Segment, 0x100);
-
- Success = TRUE;
- }
-
-Cleanup:
- if (!Success)
- {
- /* It was not successful, cleanup the DOS memory */
- if (AllocatedEnvBlock) DosFreeMemory(EnvBlock);
- if (Segment) DosFreeMemory(Segment);
- }
-
- /* 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 i;
- WORD McbSegment = FIRST_MCB_SEGMENT;
- PDOS_MCB CurrentMcb;
- LPDWORD IntVecTable = (LPDWORD)((ULONG_PTR)BaseAddress);
- PDOS_PSP PspBlock = SEGMENT_TO_PSP(Psp);
-
- DPRINT("DosTerminateProcess: Psp 0x%04X, ReturnCode 0x%02X\n",
- Psp,
- ReturnCode);
-
- /* Check if this PSP is it's own parent */
- if (PspBlock->ParentPsp == Psp) goto Done;
-
- for (i = 0; i < PspBlock->HandleTableSize; i++)
- {
- /* Close the handle */
- DosCloseHandle(i);
- }
-
- /* 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 + 1);
-
- /* 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;
- }
-
- /* Save the return code - Normal termination */
- DosErrorLevel = MAKEWORD(ReturnCode, 0x00);
-
- /* Return control to the parent process */
- EmulatorExecute(HIWORD(PspBlock->TerminateAddress),
- LOWORD(PspBlock->TerminateAddress));
-}
CHAR DosReadCharacter(VOID)
{
@@ -1358,59 +117,6 @@
/* Use the file writing function */
DosWriteFile(DOS_OUTPUT_HANDLE, &Character, sizeof(CHAR), &BytesWritten);
-}
-
-BOOLEAN DosHandleIoctl(BYTE ControlCode, WORD FileHandle)
-{
- HANDLE Handle = DosGetRealHandle(FileHandle);
-
- if (Handle == INVALID_HANDLE_VALUE)
- {
- /* Doesn't exist */
- DosLastError = ERROR_FILE_NOT_FOUND;
- return FALSE;
- }
-
- switch (ControlCode)
- {
- /* Get Device Information */
- case 0x00:
- {
- WORD InfoWord = 0;
-
- /*
- * See Ralf Brown:
http://www.ctyme.com/intr/rb-2820.htm
- * for a list of possible flags.
- */
-
- if (Handle == DosSystemFileTable[0])
- {
- /* Console input */
- InfoWord |= 1 << 0;
- }
- else if (Handle == DosSystemFileTable[1])
- {
- /* Console output */
- InfoWord |= 1 << 1;
- }
-
- /* It is a device */
- InfoWord |= 1 << 7;
-
- /* Return the device information word */
- setDX(InfoWord);
- return TRUE;
- }
-
- /* Unsupported control code */
- default:
- {
- DPRINT1("Unsupported IOCTL: 0x%02X\n", ControlCode);
-
- DosLastError = ERROR_INVALID_PARAMETER;
- return FALSE;
- }
- }
}
VOID WINAPI DosSystemBop(LPWORD Stack)
@@ -1501,1166 +207,24 @@
}
}
-VOID WINAPI DosInt20h(LPWORD Stack)
-{
- /* This is the exit interrupt */
- DosTerminateProcess(Stack[STACK_CS], 0);
-}
-
-VOID WINAPI DosInt21h(LPWORD Stack)
-{
- BYTE Character;
- SYSTEMTIME SystemTime;
- PCHAR String;
- PDOS_INPUT_BUFFER InputBuffer;
-
- /* Check the value in the AH register */
- switch (getAH())
- {
- /* Terminate Program */
- case 0x00:
- {
- DosTerminateProcess(Stack[STACK_CS], 0);
- break;
- }
-
- /* Read Character from STDIN with Echo */
- case 0x01:
- {
- Character = DosReadCharacter();
- DosPrintCharacter(Character);
-
- /* Let the BOP repeat if needed */
- if (getCF()) break;
-
- setAL(Character);
- break;
- }
-
- /* Write Character to STDOUT */
- case 0x02:
- {
- Character = getDL();
- DosPrintCharacter(Character);
-
- /*
- * We return the output character (DOS 2.1+).
- * Also, if we're going to output a TAB, then
- * don't return a TAB but a SPACE instead.
- * See Ralf Brown:
http://www.ctyme.com/intr/rb-2554.htm
- * for more information.
- */
- setAL(Character == '\t' ? ' ' : Character);
- break;
- }
-
- /* Read Character from STDAUX */
- case 0x03:
- {
- // FIXME: Really read it from STDAUX!
- DPRINT1("INT 16h, 03h: Read character from STDAUX is
HALFPLEMENTED\n");
- setAL(DosReadCharacter());
- break;
- }
-
- /* Write Character to STDAUX */
- case 0x04:
- {
- // FIXME: Really write it to STDAUX!
- DPRINT1("INT 16h, 04h: Write character to STDAUX is
HALFPLEMENTED\n");
- DosPrintCharacter(getDL());
- break;
- }
-
- /* Write Character to Printer */
- case 0x05:
- {
- // FIXME: Really write it to printer!
- DPRINT1("INT 16h, 05h: Write character to printer is HALFPLEMENTED
-\n\n");
- DPRINT1("0x%p\n", getDL());
- DPRINT1("\n\n-----------\n\n");
- break;
- }
-
- /* Direct Console I/O */
- case 0x06:
- {
- Character = getDL();
-
- if (Character != 0xFF)
- {
- /* Output */
- DosPrintCharacter(Character);
-
- /*
- * We return the output character (DOS 2.1+).
- * See Ralf Brown:
http://www.ctyme.com/intr/rb-2558.htm
- * for more information.
- */
- setAL(Character);
- }
- else
- {
- /* Input */
- if (DosCheckInput())
- {
- Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_ZF;
- setAL(DosReadCharacter());
- }
- else
- {
- /* No character available */
- Stack[STACK_FLAGS] |= EMULATOR_FLAG_ZF;
- setAL(0x00);
- }
- }
-
- break;
- }
-
- /* Character Input without Echo */
- case 0x07:
- case 0x08:
- {
- Character = DosReadCharacter();
-
- /* Let the BOP repeat if needed */
- if (getCF()) break;
-
- setAL(Character);
- break;
- }
-
- /* Write string to STDOUT */
- case 0x09:
- {
- String = (PCHAR)SEG_OFF_TO_PTR(getDS(), getDX());
-
- while (*String != '$')
- {
- DosPrintCharacter(*String);
- String++;
- }
-
- /*
- * We return the terminating character (DOS 2.1+).
- * See Ralf Brown:
http://www.ctyme.com/intr/rb-2562.htm
- * for more information.
- */
- setAL('$');
- break;
- }
-
- /* Read Buffered Input */
- case 0x0A:
- {
- InputBuffer = (PDOS_INPUT_BUFFER)SEG_OFF_TO_PTR(getDS(), getDX());
-
- while (Stack[STACK_COUNTER] < InputBuffer->MaxLength)
- {
- /* Try to read a character */
- Character = DosReadCharacter();
-
- /* If it's not ready yet, let the BOP repeat */
- if (getCF()) break;
-
- /* Echo the character and append it to the buffer */
- DosPrintCharacter(Character);
- InputBuffer->Buffer[Stack[STACK_COUNTER]] = Character;
-
- if (Character == '\r') break;
- Stack[STACK_COUNTER]++;
- }
-
- /* Update the length */
- InputBuffer->Length = Stack[STACK_COUNTER];
- break;
- }
-
- /* Get STDIN Status */
- case 0x0B:
- {
- setAL(DosCheckInput() ? 0xFF : 0x00);
- break;
- }
-
- /* Flush Buffer and Read STDIN */
- case 0x0C:
- {
- BYTE InputFunction = getAL();
-
- /* Flush STDIN buffer */
- DosFlushFileBuffers(DOS_INPUT_HANDLE); // Maybe just create a
DosFlushInputBuffer...
-
- /*
- * If the input function number contained in AL is valid, i.e.
- * AL == 0x01 or 0x06 or 0x07 or 0x08 or 0x0A, call ourselves
- * recursively with AL == AH.
- */
- if (InputFunction == 0x01 || InputFunction == 0x06 ||
- InputFunction == 0x07 || InputFunction == 0x08 ||
- InputFunction == 0x0A)
- {
- setAH(InputFunction);
- /*
- * Instead of calling ourselves really recursively as in:
- * DosInt21h(Stack);
- * prefer resetting the CF flag to let the BOP repeat.
- */
- setCF(1);
- }
- break;
- }
-
- /* Disk Reset */
- case 0x0D:
- {
- PDOS_PSP PspBlock = SEGMENT_TO_PSP(CurrentPsp);
-
- // TODO: Flush what's needed.
- DPRINT1("INT 21h, 0Dh is UNIMPLEMENTED\n");
-
- /* Clear CF in DOS 6 only */
- if (PspBlock->DosVersion == 0x0006)
- Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
-
- break;
- }
-
- /* Set Default Drive */
- case 0x0E:
- {
- DosChangeDrive(getDL());
- setAL(LastDrive - 'A' + 1);
- break;
- }
-
- /* NULL Function for CP/M Compatibility */
- case 0x18:
- {
- /*
- * This function corresponds to the CP/M BDOS function
- * "get bit map of logged drives", which is meaningless
- * under MS-DOS.
- *
- * For: PTS-DOS 6.51 & S/DOS 1.0 - EXTENDED RENAME FILE USING FCB
- * See Ralf Brown:
http://www.ctyme.com/intr/rb-2584.htm
- * for more information.
- */
- setAL(0x00);
- break;
- }
-
- /* Get Default Drive */
- case 0x19:
- {
- setAL(CurrentDrive);
- break;
- }
-
- /* Set Disk Transfer Area */
- case 0x1A:
- {
- DiskTransferArea = MAKELONG(getDX(), getDS());
- break;
- }
-
- /* NULL Function for CP/M Compatibility */
- case 0x1D:
- case 0x1E:
- {
- /*
- * Function 0x1D corresponds to the CP/M BDOS function
- * "get bit map of read-only drives", which is meaningless
- * under MS-DOS.
- * See Ralf Brown:
http://www.ctyme.com/intr/rb-2592.htm
- * for more information.
- *
- * Function 0x1E corresponds to the CP/M BDOS function
- * "set file attributes", which was meaningless under MS-DOS 1.x.
- * See Ralf Brown:
http://www.ctyme.com/intr/rb-2593.htm
- * for more information.
- */
- setAL(0x00);
- break;
- }
-
- /* NULL Function for CP/M Compatibility */
- case 0x20:
- {
- /*
- * This function corresponds to the CP/M BDOS function
- * "get/set default user (sublibrary) number", which is
meaningless
- * under MS-DOS.
- *
- * For: S/DOS 1.0+ & PTS-DOS 6.51+ - GET OEM REVISION
- * See Ralf Brown:
http://www.ctyme.com/intr/rb-2596.htm
- * for more information.
- */
- setAL(0x00);
- break;
- }
-
- /* Set Interrupt Vector */
- case 0x25:
- {
- DWORD FarPointer = MAKELONG(getDX(), getDS());
- DPRINT1("Setting interrupt 0x%x ...\n", getAL());
-
- /* Write the new far pointer to the IDT */
- ((PDWORD)BaseAddress)[getAL()] = FarPointer;
- break;
- }
-
- /* Create New PSP */
- case 0x26:
- {
- DPRINT1("INT 21h, 26h - Create New PSP is UNIMPLEMENTED\n");
- break;
- }
-
- /* Get System Date */
- case 0x2A:
- {
- GetLocalTime(&SystemTime);
- setCX(SystemTime.wYear);
- setDX(MAKEWORD(SystemTime.wDay, SystemTime.wMonth));
- setAL(SystemTime.wDayOfWeek);
- break;
- }
-
- /* Set System Date */
- case 0x2B:
- {
- GetLocalTime(&SystemTime);
- SystemTime.wYear = getCX();
- SystemTime.wMonth = getDH();
- SystemTime.wDay = getDL();
-
- /* Return success or failure */
- setAL(SetLocalTime(&SystemTime) ? 0x00 : 0xFF);
- break;
- }
-
- /* Get System Time */
- case 0x2C:
- {
- GetLocalTime(&SystemTime);
- setCX(MAKEWORD(SystemTime.wMinute, SystemTime.wHour));
- setDX(MAKEWORD(SystemTime.wMilliseconds / 10, SystemTime.wSecond));
- break;
- }
-
- /* Set System Time */
- case 0x2D:
- {
- GetLocalTime(&SystemTime);
- SystemTime.wHour = getCH();
- SystemTime.wMinute = getCL();
- SystemTime.wSecond = getDH();
- SystemTime.wMilliseconds = getDL() * 10; // In hundredths of seconds
-
- /* Return success or failure */
- setAL(SetLocalTime(&SystemTime) ? 0x00 : 0xFF);
- break;
- }
-
- /* Get Disk Transfer Area */
- case 0x2F:
- {
- setES(HIWORD(DiskTransferArea));
- setBX(LOWORD(DiskTransferArea));
- break;
- }
-
- /* Get DOS Version */
- case 0x30:
- {
- PDOS_PSP PspBlock = SEGMENT_TO_PSP(CurrentPsp);
-
- /*
- * DOS 2+ - GET DOS VERSION
- * See Ralf Brown:
http://www.ctyme.com/intr/rb-2711.htm
- * for more information.
- */
-
- if (LOBYTE(PspBlock->DosVersion) < 5 || getAL() == 0x00)
- {
- /*
- * Return DOS OEM number:
- * 0x00 for IBM PC-DOS
- * 0x02 for packaged MS-DOS
- */
- setBH(0x02);
- }
-
- if (LOBYTE(PspBlock->DosVersion) >= 5 && getAL() == 0x01)
- {
- /*
- * Return version flag:
- * 1 << 3 if DOS is in ROM,
- * 0 (reserved) if not.
- */
- setBH(0x00);
- }
-
- /* Return DOS 24-bit user serial number in BL:CX */
- setBL(0x00);
- setCX(0x0000);
-
- /*
- * Return DOS version: Minor:Major in AH:AL
- * The Windows NT DOS box returns version 5.00, subject to SETVER.
- */
- setAX(PspBlock->DosVersion);
-
- break;
- }
-
- /* Extended functionalities */
- case 0x33:
- {
- if (getAL() == 0x06)
- {
- /*
- * DOS 5+ - GET TRUE VERSION NUMBER
- * This function always returns the true version number, unlike
- * AH=30h, whose return value may be changed with SETVER.
- * See Ralf Brown:
http://www.ctyme.com/intr/rb-2730.htm
- * for more information.
- */
-
- /*
- * Return the true DOS version: Minor:Major in BH:BL
- * The Windows NT DOS box returns BX=3205h (version 5.50).
- */
- setBX(NTDOS_VERSION);
-
- /* DOS revision 0 */
- setDL(0x00);
-
- /* Unpatched DOS */
- setDH(0x00);
- }
- // else
- // {
- // /* Invalid subfunction */
- // setAL(0xFF);
- // }
-
- break;
- }
-
- /* Get Interrupt Vector */
- case 0x35:
- {
- DWORD FarPointer = ((PDWORD)BaseAddress)[getAL()];
-
- /* Read the address from the IDT into ES:BX */
- setES(HIWORD(FarPointer));
- setBX(LOWORD(FarPointer));
- break;
- }
-
- /* SWITCH character - AVAILDEV */
- case 0x37:
- {
- if (getAL() == 0x00)
- {
- /*
- * DOS 2+ - "SWITCHAR" - GET SWITCH CHARACTER
- * This setting is ignored by MS-DOS 4.0+.
- * MS-DOS 5+ always return AL=00h/DL=2Fh.
- * See Ralf Brown:
http://www.ctyme.com/intr/rb-2752.htm
- * for more information.
- */
- setDL('/');
- setAL(0x00);
- }
- else if (getAL() == 0x01)
- {
- /*
- * DOS 2+ - "SWITCHAR" - SET SWITCH CHARACTER
- * This setting is ignored by MS-DOS 5+.
- * See Ralf Brown:
http://www.ctyme.com/intr/rb-2753.htm
- * for more information.
- */
- // getDL();
- setAL(0xFF);
- }
- else if (getAL() == 0x02)
- {
- /*
- * DOS 2.x and 3.3+ only - "AVAILDEV" - SPECIFY \DEV\ PREFIX
USE
- * See Ralf Brown:
http://www.ctyme.com/intr/rb-2754.htm
- * for more information.
- */
- // setDL();
- setAL(0xFF);
- }
- else if (getAL() == 0x03)
- {
- /*
- * DOS 2.x and 3.3+ only - "AVAILDEV" - SPECIFY \DEV\ PREFIX
USE
- * See Ralf Brown:
http://www.ctyme.com/intr/rb-2754.htm
- * for more information.
- */
- // getDL();
- setAL(0xFF);
- }
- else
- {
- /* Invalid subfunction */
- setAL(0xFF);
- }
-
- break;
- }
-
- /* Create Directory */
- case 0x39:
- {
- String = (PCHAR)SEG_OFF_TO_PTR(getDS(), getDX());
-
- if (CreateDirectoryA(String, NULL))
- {
- Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
- }
- else
- {
- Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
- setAX(LOWORD(GetLastError()));
- }
-
- break;
- }
-
- /* Remove Directory */
- case 0x3A:
- {
- String = (PCHAR)SEG_OFF_TO_PTR(getDS(), getDX());
-
- if (RemoveDirectoryA(String))
- {
- Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
- }
- else
- {
- Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
- setAX(LOWORD(GetLastError()));
- }
-
- break;
- }
-
- /* Set Current Directory */
- case 0x3B:
- {
- String = (PCHAR)SEG_OFF_TO_PTR(getDS(), getDX());
-
- if (DosChangeDirectory(String))
- {
- Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
- }
- else
- {
- Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
- setAX(DosLastError);
- }
-
- break;
- }
-
- /* Create File */
- case 0x3C:
- {
- WORD FileHandle;
- WORD ErrorCode = DosCreateFile(&FileHandle,
- (LPCSTR)SEG_OFF_TO_PTR(getDS(), getDX()),
- getCX());
-
- if (ErrorCode == 0)
- {
- Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
- setAX(FileHandle);
- }
- else
- {
- Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
- setAX(ErrorCode);
- }
-
- break;
- }
-
- /* Open File */
- case 0x3D:
- {
- WORD FileHandle;
- WORD ErrorCode = DosOpenFile(&FileHandle,
- (LPCSTR)SEG_OFF_TO_PTR(getDS(), getDX()),
- getAL());
-
- if (ErrorCode == 0)
- {
- Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
- setAX(FileHandle);
- }
- else
- {
- Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
- setAX(ErrorCode);
- }
-
- break;
- }
-
- /* Close File */
- case 0x3E:
- {
- if (DosCloseHandle(getBX()))
- {
- Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
- }
- else
- {
- Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
- setAX(ERROR_INVALID_HANDLE);
- }
-
- break;
- }
-
- /* Read from File or Device */
- case 0x3F:
- {
- WORD Handle = getBX();
- LPBYTE Buffer = (LPBYTE)SEG_OFF_TO_PTR(getDS(), getDX());
- WORD Count = getCX();
- WORD BytesRead = 0;
- WORD ErrorCode = ERROR_SUCCESS;
- CHAR Character;
-
- if (IsConsoleHandle(DosGetRealHandle(Handle)))
- {
- while (Stack[STACK_COUNTER] < Count)
- {
- /* Read a character from the BIOS */
- Character = LOBYTE(BiosGetCharacter());
-
- /* Stop if the BOP needs to be repeated */
- if (getCF()) break;
-
- // FIXME: Security checks!
- DosPrintCharacter(Character);
- Buffer[Stack[STACK_COUNTER]++] = Character;
-
- if (Character == '\r')
- {
- /* Stop on first carriage return */
- DosPrintCharacter('\n');
- break;
- }
- }
-
- if (Character != '\r')
- {
- if (Stack[STACK_COUNTER] < Count) ErrorCode = ERROR_NOT_READY;
- else BytesRead = Count;
- }
- else BytesRead = Stack[STACK_COUNTER];
- }
- else
- {
- /* Use the file reading function */
- ErrorCode = DosReadFile(Handle, Buffer, Count, &BytesRead);
- }
-
- if (ErrorCode == ERROR_SUCCESS)
- {
- Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
- setAX(BytesRead);
- }
- else if (ErrorCode != ERROR_NOT_READY)
- {
- Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
- setAX(ErrorCode);
- }
- break;
- }
-
- /* Write to File or Device */
- case 0x40:
- {
- WORD BytesWritten = 0;
- WORD ErrorCode = DosWriteFile(getBX(),
- SEG_OFF_TO_PTR(getDS(), getDX()),
- getCX(),
- &BytesWritten);
-
- if (ErrorCode == ERROR_SUCCESS)
- {
- Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
- setAX(BytesWritten);
- }
- else
- {
- Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
- setAX(ErrorCode);
- }
-
- break;
- }
-
- /* Delete File */
- case 0x41:
- {
- LPSTR FileName = (LPSTR)SEG_OFF_TO_PTR(getDS(), getDX());
-
- if (demFileDelete(FileName) == ERROR_SUCCESS)
- {
- Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
- /*
- * See Ralf Brown:
http://www.ctyme.com/intr/rb-2797.htm
- * "AX destroyed (DOS 3.3) AL seems to be drive of deleted
file."
- */
- setAL(FileName[0] - 'A');
- }
- else
- {
- Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
- setAX(GetLastError());
- }
-
- break;
- }
-
- /* Seek File */
- case 0x42:
- {
- DWORD NewLocation;
- WORD ErrorCode = DosSeekFile(getBX(),
- MAKELONG(getDX(), getCX()),
- getAL(),
- &NewLocation);
-
- if (ErrorCode == ERROR_SUCCESS)
- {
- Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
-
- /* Return the new offset in DX:AX */
- setDX(HIWORD(NewLocation));
- setAX(LOWORD(NewLocation));
- }
- else
- {
- Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
- setAX(ErrorCode);
- }
-
- break;
- }
-
- /* Get/Set File Attributes */
- case 0x43:
- {
- DWORD Attributes;
- LPSTR FileName = (LPSTR)SEG_OFF_TO_PTR(getDS(), getDX());
-
- if (getAL() == 0x00)
- {
- /* Get the attributes */
- Attributes = GetFileAttributesA(FileName);
-
- /* Check if it failed */
- if (Attributes == INVALID_FILE_ATTRIBUTES)
- {
- Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
- setAX(GetLastError());
- }
- else
- {
- /* Return the attributes that DOS can understand */
- Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
- setCX(Attributes & 0x00FF);
- }
- }
- else if (getAL() == 0x01)
- {
- /* Try to set the attributes */
- if (SetFileAttributesA(FileName, getCL()))
- {
- Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
- }
- else
- {
- Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
- setAX(GetLastError());
- }
- }
- else
- {
- Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
- setAX(ERROR_INVALID_FUNCTION);
- }
-
- break;
- }
-
- /* IOCTL */
- case 0x44:
- {
- if (DosHandleIoctl(getAL(), getBX()))
- {
- Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
- }
- else
- {
- Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
- setAX(DosLastError);
- }
-
- break;
- }
-
- /* Duplicate Handle */
- case 0x45:
- {
- WORD NewHandle;
- HANDLE Handle = DosGetRealHandle(getBX());
-
- if (Handle != INVALID_HANDLE_VALUE)
- {
- /* The handle is invalid */
- Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
- setAX(ERROR_INVALID_HANDLE);
- break;
- }
-
- /* Open a new handle to the same entry */
- NewHandle = DosOpenHandle(Handle);
-
- if (NewHandle == INVALID_DOS_HANDLE)
- {
- /* Too many files open */
- Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
- setAX(ERROR_TOO_MANY_OPEN_FILES);
- break;
- }
-
- /* Return the result */
- Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
- setAX(NewHandle);
- break;
- }
-
- /* Force Duplicate Handle */
- case 0x46:
- {
- if (DosDuplicateHandle(getBX(), getCX()))
- {
- Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
- }
- else
- {
- Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
- setAX(ERROR_INVALID_HANDLE);
- }
-
- break;
- }
-
- /* Get Current Directory */
- case 0x47:
- {
- BYTE DriveNumber = getDL();
- String = (PCHAR)SEG_OFF_TO_PTR(getDS(), getSI());
-
- /* Get the real drive number */
- if (DriveNumber == 0)
- {
- DriveNumber = CurrentDrive;
- }
- else
- {
- /* Decrement DriveNumber since it was 1-based */
- DriveNumber--;
- }
-
- if (DriveNumber <= LastDrive - 'A')
- {
- /*
- * Copy the current directory into the target buffer.
- * It doesn't contain the drive letter and the backslash.
- */
- strncpy(String, CurrentDirectories[DriveNumber], DOS_DIR_LENGTH);
- Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
- setAX(0x0100); // Undocumented, see Ralf Brown:
http://www.ctyme.com/intr/rb-2933.htm
- }
- else
- {
- Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
- setAX(ERROR_INVALID_DRIVE);
- }
-
- break;
- }
-
- /* Allocate Memory */
- case 0x48:
- {
- WORD MaxAvailable = 0;
- WORD Segment = DosAllocateMemory(getBX(), &MaxAvailable);
-
- if (Segment != 0)
- {
- Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
- setAX(Segment);
- }
- else
- {
- Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
- setAX(DosLastError);
- setBX(MaxAvailable);
- }
-
- break;
- }
-
- /* Free Memory */
- case 0x49:
- {
- if (DosFreeMemory(getES()))
- {
- Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
- }
- else
- {
- Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
- setAX(ERROR_ARENA_TRASHED);
- }
-
- break;
- }
-
- /* Resize Memory Block */
- case 0x4A:
- {
- WORD Size;
-
- if (DosResizeMemory(getES(), getBX(), &Size))
- {
- Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
- }
- else
- {
- Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
- setAX(DosLastError);
- setBX(Size);
- }
-
- break;
- }
-
- /* Terminate With Return Code */
- case 0x4C:
- {
- DosTerminateProcess(CurrentPsp, getAL());
- break;
- }
-
- /* Get Return Code (ERRORLEVEL) */
- case 0x4D:
- {
- /*
- * According to Ralf Brown:
http://www.ctyme.com/intr/rb-2976.htm
- * DosErrorLevel is cleared after being read by this function.
- */
- Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
- setAX(DosErrorLevel);
- DosErrorLevel = 0x0000; // Clear it
- break;
- }
-
- /* Find First File */
- case 0x4E:
- {
- WORD Result = (WORD)demFileFindFirst(FAR_POINTER(DiskTransferArea),
- SEG_OFF_TO_PTR(getDS(), getDX()),
- getCX());
-
- setAX(Result);
- if (Result == ERROR_SUCCESS) Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
- else Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
-
- break;
- }
-
- /* Find Next File */
- case 0x4F:
- {
- WORD Result = (WORD)demFileFindNext(FAR_POINTER(DiskTransferArea));
-
- setAX(Result);
- if (Result == ERROR_SUCCESS) Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
- else Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
-
- break;
- }
-
- /* Internal - Set Current Process ID (Set PSP Address) */
- case 0x50:
- {
- // FIXME: Is it really what it's done ??
- CurrentPsp = getBX();
- break;
- }
-
- /* Internal - Get Current Process ID (Get PSP Address) */
- case 0x51:
- /* Get Current PSP Address */
- case 0x62:
- {
- /*
- * Undocumented AH=51h is identical to the documented AH=62h.
- * See Ralf Brown:
http://www.ctyme.com/intr/rb-2982.htm
- * and
http://www.ctyme.com/intr/rb-3140.htm
- * for more information.
- */
- setBX(CurrentPsp);
- break;
- }
-
- /* Get/Set Memory Management Options */
- case 0x58:
- {
- if (getAL() == 0x00)
- {
- /* Get allocation strategy */
- Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
- setAX(DosAllocStrategy);
- }
- else if (getAL() == 0x01)
- {
- /* Set allocation strategy */
-
- if ((getBL() & (DOS_ALLOC_HIGH | DOS_ALLOC_HIGH_LOW))
- == (DOS_ALLOC_HIGH | DOS_ALLOC_HIGH_LOW))
- {
- /* Can't set both */
- Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
- setAX(ERROR_INVALID_PARAMETER);
- break;
- }
-
- if ((getBL() & 0x3F) > DOS_ALLOC_LAST_FIT)
- {
- /* Invalid allocation strategy */
- Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
- setAX(ERROR_INVALID_PARAMETER);
- break;
- }
-
- DosAllocStrategy = getBL();
- Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
- }
- else if (getAL() == 0x02)
- {
- /* Get UMB link state */
- Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
- setAL(DosUmbLinked ? 0x01 : 0x00);
- }
- else if (getAL() == 0x03)
- {
- /* Set UMB link state */
- if (getBX()) DosLinkUmb();
- else DosUnlinkUmb();
- Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
- }
- else
- {
- /* Invalid or unsupported function */
- Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
- setAX(ERROR_INVALID_FUNCTION);
- }
-
- break;
- }
-
- /* Unsupported */
- default:
- {
- DPRINT1("DOS Function INT 0x21, AH = %xh, AL = %xh NOT
IMPLEMENTED!\n",
- getAH(), getAL());
-
- setAL(0); // Some functions expect AL to be 0 when it's not supported.
- Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
- }
- }
-}
-
-VOID WINAPI DosBreakInterrupt(LPWORD Stack)
-{
- UNREFERENCED_PARAMETER(Stack);
-
- /* Stop the VDM */
- VdmRunning = FALSE;
-}
-
-VOID WINAPI DosFastConOut(LPWORD Stack)
-{
- /*
- * This is the DOS 2+ Fast Console Output Interrupt.
- * See Ralf Brown:
http://www.ctyme.com/intr/rb-4124.htm
- * for more information.
- */
-
- if (Stack[STACK_COUNTER] == 0)
- {
- Stack[STACK_COUNTER]++;
-
- /* Save AX and BX */
- Stack[STACK_VAR_A] = getAX();
- Stack[STACK_VAR_B] = getBX();
-
- /* Rewind the BOP manually, we can't use CF because the interrupt could
modify it */
- EmulatorExecute(getCS(), getIP() - 4);
-
- /* Call INT 0x10, AH = 0x0E */
- setAH(0x0E);
- setBL(DOS_CHAR_ATTRIBUTE);
- setBH(Bda->VideoPage);
-
- EmulatorInterrupt(0x10);
- }
- else
- {
- /* Restore AX and BX */
- setAX(Stack[STACK_VAR_A]);
- setBX(Stack[STACK_VAR_B]);
- }
-}
-
-VOID WINAPI DosInt2Fh(LPWORD Stack)
-{
- DPRINT1("DOS System Function INT 0x2F, AH = %xh, AL = %xh NOT
IMPLEMENTED!\n",
- getAH(), getAL());
- Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
-}
-
-BOOLEAN DosInitialize(VOID)
-{
- BYTE i;
+BOOLEAN DosBIOSInitialize(VOID)
+{
PDOS_MCB Mcb = SEGMENT_TO_MCB(FIRST_MCB_SEGMENT);
- FILE *Stream;
- WCHAR Buffer[256];
+
LPWSTR SourcePtr, Environment;
LPSTR AsciiString;
+ DWORD AsciiSize;
LPSTR DestPtr = (LPSTR)SEG_OFF_TO_PTR(SYSTEM_ENV_BLOCK, 0);
- DWORD AsciiSize;
+
+#if 0
+ UCHAR i;
CHAR CurrentDirectory[MAX_PATH];
CHAR DosDirectory[DOS_DIR_LENGTH];
LPSTR Path;
+
+ FILE *Stream;
+ WCHAR Buffer[256];
+#endif
/* Initialize the MCB */
Mcb->BlockType = 'Z';
@@ -2730,6 +294,9 @@
/* Free the memory allocated for environment strings */
FreeEnvironmentStringsW(Environment);
+
+#if 0
+
/* Clear the current directory buffer */
ZeroMemory(CurrentDirectories, sizeof(CurrentDirectories));
@@ -2768,37 +335,24 @@
Stream = _wfopen(DOS_CONFIG_PATH, L"r");
if (Stream != NULL)
{
- while (fgetws(Buffer, 256, Stream))
+ while (fgetws(Buffer, sizeof(Buffer)/sizeof(Buffer[0]), Stream))
{
// TODO: Parse the line
}
fclose(Stream);
}
- /* Initialize the SFT */
- for (i = 0; i < DOS_SFT_SIZE; i++)
- {
- DosSystemFileTable[i] = INVALID_HANDLE_VALUE;
- DosSftRefCount[i] = 0;
- }
-
- /* Get handles to standard I/O devices */
- DosSystemFileTable[0] = GetStdHandle(STD_INPUT_HANDLE);
- DosSystemFileTable[1] = GetStdHandle(STD_OUTPUT_HANDLE);
- DosSystemFileTable[2] = GetStdHandle(STD_ERROR_HANDLE);
+#endif
+
/* Register the DOS BOPs */
RegisterBop(BOP_DOS, DosSystemBop );
RegisterBop(BOP_CMD, DosCmdInterpreterBop);
/* Register the DOS 32-bit Interrupts */
- RegisterInt32(0x20, DosInt20h );
- RegisterInt32(0x21, DosInt21h );
-// RegisterInt32(0x22, DosInt22h ); // Termination
- RegisterInt32(0x23, DosBreakInterrupt); // Ctrl-C / Ctrl-Break
-// RegisterInt32(0x24, DosInt24h ); // Critical Error
- RegisterInt32(0x29, DosFastConOut ); // DOS 2+ Fast Console Output
- RegisterInt32(0x2F, DosInt2Fh );
+ // RegisterInt32(0x20, DosInt20h);
+
+ /* TODO: Initialize the DOS kernel */
return TRUE;
}
Modified: branches/ntvdm/subsystems/ntvdm/dos/dos32krnl/dos.c
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/dos/dos3…
==============================================================================
--- branches/ntvdm/subsystems/ntvdm/dos/dos32krnl/dos.c [iso-8859-1] (original)
+++ branches/ntvdm/subsystems/ntvdm/dos/dos32krnl/dos.c [iso-8859-1] Sun Jan 26 21:51:27
2014
@@ -15,7 +15,6 @@
#include "dos/dem.h"
#include "bios/bios.h"
-#include "bop.h"
#include "int32.h"
#include "registers.h"
@@ -33,12 +32,11 @@
static BOOLEAN DosUmbLinked = FALSE;
static WORD DosErrorLevel = 0x0000;
-/* BOP Identifiers */
-#define BOP_DOS 0x50 // DOS System BOP (for NTIO.SYS and NTDOS.SYS)
-#define BOP_CMD 0x54 // DOS Command Interpreter BOP (for
COMMAND.COM)
-
/* PRIVATE FUNCTIONS **********************************************************/
+/*
+ * Memory management functions
+ */
static VOID DosCombineFreeBlocks(WORD StartBlock)
{
PDOS_MCB CurrentMcb = SEGMENT_TO_MCB(StartBlock), NextMcb;
@@ -316,8 +314,124 @@
return TRUE;
}
+static BOOLEAN DosLinkUmb(VOID)
+{
+ DWORD Segment = FIRST_MCB_SEGMENT;
+ PDOS_MCB Mcb = SEGMENT_TO_MCB(Segment);
+
+ DPRINT("Linking UMB\n");
+
+ /* Check if UMBs are already linked */
+ if (DosUmbLinked) return FALSE;
+
+ /* Find the last block */
+ while ((Mcb->BlockType == 'M') && (Segment <= 0xFFFF))
+ {
+ Segment += Mcb->Size + 1;
+ Mcb = SEGMENT_TO_MCB(Segment);
+ }
+
+ /* Make sure it's valid */
+ if (Mcb->BlockType != 'Z') return FALSE;
+
+ /* Connect the MCB with the UMB chain */
+ Mcb->BlockType = 'M';
+
+ DosUmbLinked = TRUE;
+ return TRUE;
+}
+
+static BOOLEAN DosUnlinkUmb(VOID)
+{
+ DWORD Segment = FIRST_MCB_SEGMENT;
+ PDOS_MCB Mcb = SEGMENT_TO_MCB(Segment);
+
+ DPRINT("Unlinking UMB\n");
+
+ /* Check if UMBs are already unlinked */
+ if (!DosUmbLinked) return FALSE;
+
+ /* Find the block preceding the MCB that links it with the UMB chain */
+ while (Segment <= 0xFFFF)
+ {
+ if ((Segment + Mcb->Size) == (FIRST_MCB_SEGMENT + USER_MEMORY_SIZE))
+ {
+ /* This is the last non-UMB segment */
+ break;
+ }
+
+ /* Advance to the next MCB */
+ Segment += Mcb->Size + 1;
+ Mcb = SEGMENT_TO_MCB(Segment);
+ }
+
+ /* Mark the MCB as the last MCB */
+ Mcb->BlockType = 'Z';
+
+ DosUmbLinked = FALSE;
+ return TRUE;
+}
+
+static VOID DosChangeMemoryOwner(WORD Segment, WORD NewOwner)
+{
+ PDOS_MCB Mcb = SEGMENT_TO_MCB(Segment - 1);
+
+ /* Just set the owner */
+ Mcb->OwnerPsp = NewOwner;
+}
+
+
+
+static WORD DosCopyEnvironmentBlock(WORD SourceSegment, LPCSTR ProgramName)
+{
+ PCHAR Ptr, SourceBuffer, DestBuffer = NULL;
+ ULONG TotalSize = 0;
+ WORD DestSegment;
+
+ Ptr = SourceBuffer = (PCHAR)SEG_OFF_TO_PTR(SourceSegment, 0);
+
+ /* Calculate the size of the environment block */
+ while (*Ptr)
+ {
+ TotalSize += strlen(Ptr) + 1;
+ Ptr += strlen(Ptr) + 1;
+ }
+ TotalSize++;
+
+ /* Add the string buffer size */
+ TotalSize += strlen(ProgramName) + 1;
+
+ /* Allocate the memory for the environment block */
+ DestSegment = DosAllocateMemory((WORD)((TotalSize + 0x0F) >> 4), NULL);
+ if (!DestSegment) return 0;
+
+ Ptr = SourceBuffer;
+
+ DestBuffer = (PCHAR)SEG_OFF_TO_PTR(DestSegment, 0);
+ while (*Ptr)
+ {
+ /* Copy the string */
+ strcpy(DestBuffer, Ptr);
+
+ /* Advance to the next string */
+ DestBuffer += strlen(Ptr);
+ Ptr += strlen(Ptr) + 1;
+
+ /* Put a zero after the string */
+ *(DestBuffer++) = 0;
+ }
+
+ /* Set the final zero */
+ *(DestBuffer++) = 0;
+
+ /* Copy the program name after the environment block */
+ strcpy(DestBuffer, ProgramName);
+
+ return DestSegment;
+}
+
/* Taken from base/shell/cmd/console.c */
-static BOOL IsConsoleHandle(HANDLE hHandle)
+BOOL IsConsoleHandle(HANDLE hHandle)
{
DWORD dwMode;
@@ -340,62 +454,6 @@
return GetConsoleMode(hHandle, &dwMode);
}
-static WORD DosCopyEnvironmentBlock(WORD SourceSegment, LPCSTR ProgramName)
-{
- PCHAR Ptr, SourceBuffer, DestBuffer = NULL;
- ULONG TotalSize = 0;
- WORD DestSegment;
-
- Ptr = SourceBuffer = (PCHAR)SEG_OFF_TO_PTR(SourceSegment, 0);
-
- /* Calculate the size of the environment block */
- while (*Ptr)
- {
- TotalSize += strlen(Ptr) + 1;
- Ptr += strlen(Ptr) + 1;
- }
- TotalSize++;
-
- /* Add the string buffer size */
- TotalSize += strlen(ProgramName) + 1;
-
- /* Allocate the memory for the environment block */
- DestSegment = DosAllocateMemory((WORD)((TotalSize + 0x0F) >> 4), NULL);
- if (!DestSegment) return 0;
-
- Ptr = SourceBuffer;
-
- DestBuffer = (PCHAR)SEG_OFF_TO_PTR(DestSegment, 0);
- while (*Ptr)
- {
- /* Copy the string */
- strcpy(DestBuffer, Ptr);
-
- /* Advance to the next string */
- DestBuffer += strlen(Ptr);
- Ptr += strlen(Ptr) + 1;
-
- /* Put a zero after the string */
- *(DestBuffer++) = 0;
- }
-
- /* Set the final zero */
- *(DestBuffer++) = 0;
-
- /* Copy the program name after the environment block */
- strcpy(DestBuffer, ProgramName);
-
- return DestSegment;
-}
-
-static VOID DosChangeMemoryOwner(WORD Segment, WORD NewOwner)
-{
- PDOS_MCB Mcb = SEGMENT_TO_MCB(Segment - 1);
-
- /* Just set the owner */
- Mcb->OwnerPsp = NewOwner;
-}
-
static WORD DosOpenHandle(HANDLE Handle)
{
BYTE i;
@@ -456,7 +514,7 @@
return INVALID_DOS_HANDLE;
}
-static HANDLE DosGetRealHandle(WORD DosHandle)
+HANDLE DosGetRealHandle(WORD DosHandle)
{
PDOS_PSP PspBlock;
LPBYTE HandleTable;
@@ -588,64 +646,6 @@
HandleTable[NewHandle] = SftIndex;
/* Return success */
- return TRUE;
-}
-
-static BOOLEAN DosLinkUmb(VOID)
-{
- DWORD Segment = FIRST_MCB_SEGMENT;
- PDOS_MCB Mcb = SEGMENT_TO_MCB(Segment);
-
- DPRINT("Linking UMB\n");
-
- /* Check if UMBs are already linked */
- if (DosUmbLinked) return FALSE;
-
- /* Find the last block */
- while ((Mcb->BlockType == 'M') && (Segment <= 0xFFFF))
- {
- Segment += Mcb->Size + 1;
- Mcb = SEGMENT_TO_MCB(Segment);
- }
-
- /* Make sure it's valid */
- if (Mcb->BlockType != 'Z') return FALSE;
-
- /* Connect the MCB with the UMB chain */
- Mcb->BlockType = 'M';
-
- DosUmbLinked = TRUE;
- return TRUE;
-}
-
-static BOOLEAN DosUnlinkUmb(VOID)
-{
- DWORD Segment = FIRST_MCB_SEGMENT;
- PDOS_MCB Mcb = SEGMENT_TO_MCB(Segment);
-
- DPRINT("Unlinking UMB\n");
-
- /* Check if UMBs are already unlinked */
- if (!DosUmbLinked) return FALSE;
-
- /* Find the block preceding the MCB that links it with the UMB chain */
- while (Segment <= 0xFFFF)
- {
- if ((Segment + Mcb->Size) == (FIRST_MCB_SEGMENT + USER_MEMORY_SIZE))
- {
- /* This is the last non-UMB segment */
- break;
- }
-
- /* Advance to the next MCB */
- Segment += Mcb->Size + 1;
- Mcb = SEGMENT_TO_MCB(Segment);
- }
-
- /* Mark the MCB as the last MCB */
- Mcb->BlockType = 'Z';
-
- DosUmbLinked = FALSE;
return TRUE;
}
@@ -763,7 +763,7 @@
return ERROR_SUCCESS;
}
-static WORD DosReadFile(WORD FileHandle, LPVOID Buffer, WORD Count, LPWORD BytesRead)
+WORD DosReadFile(WORD FileHandle, LPVOID Buffer, WORD Count, LPWORD BytesRead)
{
WORD Result = ERROR_SUCCESS;
DWORD BytesRead32 = 0;
@@ -788,7 +788,7 @@
return Result;
}
-static WORD DosWriteFile(WORD FileHandle, LPVOID Buffer, WORD Count, LPWORD
BytesWritten)
+WORD DosWriteFile(WORD FileHandle, LPVOID Buffer, WORD Count, LPWORD BytesWritten)
{
WORD Result = ERROR_SUCCESS;
DWORD BytesWritten32 = 0;
@@ -1032,7 +1032,7 @@
LPSTR ProgramFilePath, Parameters[256];
CHAR CommandLineCopy[DOS_CMDLINE_LENGTH];
CHAR ParamString[DOS_CMDLINE_LENGTH];
- INT ParamCount = 0;
+ DWORD ParamCount = 0;
WORD Segment = 0;
WORD MaxAllocSize;
DWORD i, FileSize, ExeSize;
@@ -1313,53 +1313,6 @@
LOWORD(PspBlock->TerminateAddress));
}
-CHAR DosReadCharacter(VOID)
-{
- CHAR Character = '\0';
- WORD BytesRead;
-
- if (IsConsoleHandle(DosGetRealHandle(DOS_INPUT_HANDLE)))
- {
- /* Call the BIOS */
- Character = LOBYTE(BiosGetCharacter());
- }
- else
- {
- /* Use the file reading function */
- DosReadFile(DOS_INPUT_HANDLE, &Character, sizeof(CHAR), &BytesRead);
- }
-
- return Character;
-}
-
-BOOLEAN DosCheckInput(VOID)
-{
- HANDLE Handle = DosGetRealHandle(DOS_INPUT_HANDLE);
-
- if (IsConsoleHandle(Handle))
- {
- /* Call the BIOS */
- return (BiosPeekCharacter() != 0xFFFF);
- }
- else
- {
- DWORD FileSizeHigh;
- DWORD FileSize = GetFileSize(Handle, &FileSizeHigh);
- LONG LocationHigh = 0;
- DWORD Location = SetFilePointer(Handle, 0, &LocationHigh, FILE_CURRENT);
-
- return ((Location != FileSize) || (LocationHigh != FileSizeHigh));
- }
-}
-
-VOID DosPrintCharacter(CHAR Character)
-{
- WORD BytesWritten;
-
- /* Use the file writing function */
- DosWriteFile(DOS_OUTPUT_HANDLE, &Character, sizeof(CHAR), &BytesWritten);
-}
-
BOOLEAN DosHandleIoctl(BYTE ControlCode, WORD FileHandle)
{
HANDLE Handle = DosGetRealHandle(FileHandle);
@@ -1409,94 +1362,6 @@
DosLastError = ERROR_INVALID_PARAMETER;
return FALSE;
- }
- }
-}
-
-VOID WINAPI DosSystemBop(LPWORD Stack)
-{
- /* Get the Function Number and skip it */
- BYTE FuncNum = *(PBYTE)SEG_OFF_TO_PTR(getCS(), getIP());
- setIP(getIP() + 1);
-
- DPRINT1("Unknown DOS System BOP Function: 0x%02X\n", FuncNum);
-}
-
-VOID WINAPI DosCmdInterpreterBop(LPWORD Stack)
-{
- /* Get the Function Number and skip it */
- BYTE FuncNum = *(PBYTE)SEG_OFF_TO_PTR(getCS(), getIP());
- setIP(getIP() + 1);
-
- switch (FuncNum)
- {
- case 0x08: // Launch external command
- {
-#define CMDLINE_LENGTH 1024
-
- BOOL Result;
- DWORD dwExitCode;
-
- LPSTR Command = (LPSTR)SEG_OFF_TO_PTR(getDS(), getSI());
- CHAR CommandLine[CMDLINE_LENGTH] = "";
- STARTUPINFOA StartupInfo;
- PROCESS_INFORMATION ProcessInformation;
- DPRINT1("CMD Run Command '%s'\n", Command);
-
- Command[strlen(Command)-1] = 0;
-
- strcpy(CommandLine, "cmd.exe /c ");
- strcat(CommandLine, Command);
-
- ZeroMemory(&StartupInfo, sizeof(StartupInfo));
- ZeroMemory(&ProcessInformation, sizeof(ProcessInformation));
-
- StartupInfo.cb = sizeof(StartupInfo);
-
- DosPrintCharacter('\n');
-
- Result = CreateProcessA(NULL,
- CommandLine,
- NULL,
- NULL,
- TRUE,
- 0,
- NULL,
- NULL,
- &StartupInfo,
- &ProcessInformation);
- if (Result)
- {
- DPRINT1("Command '%s' launched successfully\n");
-
- /* Wait for process termination */
- WaitForSingleObject(ProcessInformation.hProcess, INFINITE);
-
- /* Get the exit code */
- GetExitCodeProcess(ProcessInformation.hProcess, &dwExitCode);
-
- /* Close handles */
- CloseHandle(ProcessInformation.hThread);
- CloseHandle(ProcessInformation.hProcess);
- }
- else
- {
- DPRINT1("Failed when launched command '%s'\n");
- dwExitCode = GetLastError();
- }
-
- DosPrintCharacter('\n');
-
- setAL((UCHAR)dwExitCode);
-
- break;
- }
-
- default:
- {
- DPRINT1("Unknown DOS CMD Interpreter BOP Function: 0x%02X\n",
FuncNum);
- // setCF(1); // Disable, otherwise we enter an infinite loop
- break;
}
}
}
@@ -2648,87 +2513,18 @@
Stack[STACK_FLAGS] |= EMULATOR_FLAG_CF;
}
-BOOLEAN DosInitialize(VOID)
-{
- BYTE i;
- PDOS_MCB Mcb = SEGMENT_TO_MCB(FIRST_MCB_SEGMENT);
- FILE *Stream;
- WCHAR Buffer[256];
- LPWSTR SourcePtr, Environment;
- LPSTR AsciiString;
- LPSTR DestPtr = (LPSTR)SEG_OFF_TO_PTR(SYSTEM_ENV_BLOCK, 0);
- DWORD AsciiSize;
+BOOLEAN DosKRNLInitialize(VOID)
+{
+
+#if 1
+
+ UCHAR i;
CHAR CurrentDirectory[MAX_PATH];
CHAR DosDirectory[DOS_DIR_LENGTH];
LPSTR Path;
- /* Initialize the MCB */
- Mcb->BlockType = 'Z';
- Mcb->Size = USER_MEMORY_SIZE;
- Mcb->OwnerPsp = 0;
-
- /* Initialize the link MCB to the UMB area */
- Mcb = SEGMENT_TO_MCB(FIRST_MCB_SEGMENT + USER_MEMORY_SIZE + 1);
- Mcb->BlockType = 'M';
- Mcb->Size = UMB_START_SEGMENT - FIRST_MCB_SEGMENT - USER_MEMORY_SIZE - 2;
- Mcb->OwnerPsp = SYSTEM_PSP;
-
- /* Initialize the UMB area */
- Mcb = SEGMENT_TO_MCB(UMB_START_SEGMENT);
- Mcb->BlockType = 'Z';
- Mcb->Size = UMB_END_SEGMENT - UMB_START_SEGMENT;
- 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);
-
- /* Move to the next string */
- SourcePtr += wcslen(SourcePtr) + 1;
- DestPtr += strlen(AsciiString);
- *(DestPtr++) = 0;
-
- /* Free the memory */
- HeapFree(GetProcessHeap(), 0, AsciiString);
- }
- *DestPtr = 0;
-
- /* Free the memory allocated for environment strings */
- FreeEnvironmentStringsW(Environment);
+ FILE *Stream;
+ WCHAR Buffer[256];
/* Clear the current directory buffer */
ZeroMemory(CurrentDirectories, sizeof(CurrentDirectories));
@@ -2787,9 +2583,8 @@
DosSystemFileTable[1] = GetStdHandle(STD_OUTPUT_HANDLE);
DosSystemFileTable[2] = GetStdHandle(STD_ERROR_HANDLE);
- /* Register the DOS BOPs */
- RegisterBop(BOP_DOS, DosSystemBop );
- RegisterBop(BOP_CMD, DosCmdInterpreterBop);
+#endif
+
/* Register the DOS 32-bit Interrupts */
RegisterInt32(0x20, DosInt20h );
Modified: branches/ntvdm/subsystems/ntvdm/dos/dos32krnl/dos.h
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/ntvdm/dos/dos3…
==============================================================================
--- branches/ntvdm/subsystems/ntvdm/dos/dos32krnl/dos.h [iso-8859-1] (original)
+++ branches/ntvdm/subsystems/ntvdm/dos/dos32krnl/dos.h [iso-8859-1] Sun Jan 26 21:51:27
2014
@@ -118,15 +118,49 @@
CHAR DeviceName[8];
} DOS_DRIVER_HEADER, *PDOS_DRIVER_HEADER;
+typedef struct _DOS_FIND_FILE_BLOCK
+{
+ CHAR DriveLetter;
+ CHAR Pattern[11];
+ UCHAR AttribMask;
+ DWORD Unused;
+ HANDLE SearchHandle;
+
+ /* The following part of the structure is documented */
+ UCHAR Attributes;
+ WORD FileTime;
+ WORD FileDate;
+ DWORD FileSize;
+ CHAR FileName[13];
+} DOS_FIND_FILE_BLOCK, *PDOS_FIND_FILE_BLOCK;
+
#pragma pack(pop)
/* FUNCTIONS ******************************************************************/
+/*
+ * DOS BIOS Functions
+ * See bios.c
+ */
+CHAR DosReadCharacter(VOID);
+BOOLEAN DosCheckInput(VOID);
+VOID DosPrintCharacter(CHAR Character);
+
+BOOLEAN DosBIOSInitialize(VOID);
+
+
+/*
+ * DOS Kernel Functions
+ * See dos.c
+ */
+BOOL IsConsoleHandle(HANDLE hHandle);
+HANDLE DosGetRealHandle(WORD DosHandle);
+WORD DosReadFile(WORD FileHandle, LPVOID Buffer, WORD Count, LPWORD BytesRead);
+WORD DosWriteFile(WORD FileHandle, LPVOID Buffer, WORD Count, LPWORD BytesWritten);
+
VOID DosInitializePsp(WORD PspSegment, LPCSTR CommandLine, WORD ProgramSize, WORD
Environment);
BOOLEAN DosCreateProcess(LPCSTR CommandLine, WORD EnvBlock);
VOID DosTerminateProcess(WORD Psp, BYTE ReturnCode);
-CHAR DosReadCharacter(VOID);
-VOID DosPrintCharacter(CHAR Character);
BOOLEAN DosHandleIoctl(BYTE ControlCode, WORD FileHandle);
VOID WINAPI DosInt20h(LPWORD Stack);
@@ -134,7 +168,7 @@
VOID WINAPI DosBreakInterrupt(LPWORD Stack);
VOID WINAPI DosInt2Fh(LPWORD Stack);
-BOOLEAN DosInitialize(VOID);
+BOOLEAN DosKRNLInitialize(VOID);
#endif // _DOS_H_
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] Sun Jan 26 21:51:27 2014
@@ -14,11 +14,11 @@
#include "emulator.h"
#include "bios/bios.h"
+#include "dos/dem.h"
#include "hardware/cmos.h"
#include "hardware/ps2.h"
#include "hardware/timer.h"
#include "hardware/vga.h"
-#include "dos/dos32/dos.h"
/*
* Activate this line if you want to be able to test NTVDM with:
@@ -225,7 +225,7 @@
}
/* Initialize the VDM DOS kernel */
- if (!DosInitialize())
+ if (!DosInitialize(NULL))
{
wprintf(L"FATAL: Failed to initialize the VDM DOS kernel.\n");
goto Cleanup;