#include "emulator.h"
#include "dos.h"
+#include "dos/dem.h"
#include "bios/bios.h"
#include "bop.h"
static WORD CurrentPsp = SYSTEM_PSP;
static WORD DosLastError = 0;
static DWORD DiskTransferArea;
-static BYTE CurrentDrive;
+/*static*/ BYTE CurrentDrive;
static CHAR LastDrive = 'E';
static CHAR CurrentDirectories[NUM_DRIVES][DOS_DIR_LENGTH];
static HANDLE DosSystemFileTable[DOS_SFT_SIZE];
/* PRIVATE FUNCTIONS **********************************************************/
-/* 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 VOID DosCombineFreeBlocks(WORD StartBlock)
{
PDOS_MCB CurrentMcb = SEGMENT_TO_MCB(StartBlock), NextMcb;
}
}
-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]]++;
- }
-}
-
-/* PUBLIC FUNCTIONS ***********************************************************/
-
-WORD DosAllocateMemory(WORD Size, WORD *MaxAvailable)
+static WORD DosAllocateMemory(WORD Size, WORD *MaxAvailable)
{
WORD Result = 0, Segment = FIRST_MCB_SEGMENT, MaxSize = 0;
PDOS_MCB CurrentMcb, NextMcb;
return Result + 1;
}
-BOOLEAN DosResizeMemory(WORD BlockData, WORD NewSize, WORD *MaxAvailable)
+static BOOLEAN DosResizeMemory(WORD BlockData, WORD NewSize, WORD *MaxAvailable)
{
BOOLEAN Success = TRUE;
WORD Segment = BlockData - 1, ReturnSize = 0, NextSegment;
goto Done;
}
- ReturnSize = Mcb->Size;
+ 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 we need to expand or contract the block */
- if (NewSize > Mcb->Size)
+ /* Check if this is the initial process */
+ if (CurrentPsp == SYSTEM_PSP)
{
- /* We can't expand the last block */
- if (Mcb->BlockType != 'M')
+ /* Set up the standard I/O devices */
+ for (i = 0; i <= 2; i++)
{
- Success = FALSE;
- goto Done;
- }
-
- /* Get the pointer and segment of the next MCB */
- NextSegment = Segment + Mcb->Size + 1;
- NextMcb = SEGMENT_TO_MCB(NextSegment);
+ /* Set the index in the SFT */
+ DestinationTable[i] = (BYTE)i;
- /* 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;
+ /* Increase the reference count */
+ DosSftRefCount[i]++;
}
- /* Combine this free block with adjoining free blocks */
- DosCombineFreeBlocks(NextSegment);
+ /* Done */
+ return;
+ }
- /* Set the maximum possible size of the block */
- ReturnSize += NextMcb->Size + 1;
+ /* Get the parent PSP block and handle table */
+ PspBlock = SEGMENT_TO_PSP(CurrentPsp);
+ SourceTable = (LPBYTE)FAR_POINTER(PspBlock->HandleTablePtr);
- /* Maximize the current block */
- Mcb->Size = ReturnSize;
- Mcb->BlockType = NextMcb->BlockType;
+ /* Copy the first 20 handles into the new table */
+ for (i = 0; i < 20; i++)
+ {
+ DestinationTable[i] = SourceTable[i];
- /* Invalidate the next block */
- NextMcb->BlockType = 'I';
+ /* Increase the reference count */
+ DosSftRefCount[SourceTable[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);
+static BOOLEAN DosCloseHandle(WORD DosHandle)
+{
+ BYTE SftIndex;
+ PDOS_PSP PspBlock;
+ LPBYTE HandleTable;
- /* 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;
+ DPRINT("DosCloseHandle: DosHandle 0x%04X\n", DosHandle);
- /* 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);
+ /* The system PSP has no handle table */
+ if (CurrentPsp == SYSTEM_PSP) return FALSE;
- /* Just split the block */
- NextMcb = SEGMENT_TO_MCB(Segment + NewSize + 1);
- NextMcb->BlockType = Mcb->BlockType;
- NextMcb->Size = Mcb->Size - NewSize - 1;
- NextMcb->OwnerPsp = 0;
+ /* Get a pointer to the handle table */
+ PspBlock = SEGMENT_TO_PSP(CurrentPsp);
+ HandleTable = (LPBYTE)FAR_POINTER(PspBlock->HandleTablePtr);
- /* Update the MCB */
- Mcb->BlockType = 'M';
- Mcb->Size = NewSize;
- }
+ /* Make sure the handle is open */
+ if (HandleTable[DosHandle] == 0xFF) return FALSE;
-Done:
- /* Check if the operation failed */
- if (!Success)
+ /* Decrement the reference count of the SFT entry */
+ SftIndex = HandleTable[DosHandle];
+ DosSftRefCount[SftIndex]--;
+
+ /* Check if the reference count fell to zero */
+ if (!DosSftRefCount[SftIndex])
{
- DPRINT("DosResizeMemory FAILED. Maximum available: 0x%04X\n",
- ReturnSize);
+ /* Close the file, it's no longer needed */
+ CloseHandle(DosSystemFileTable[SftIndex]);
- /* Return the maximum possible size */
- if (MaxAvailable) *MaxAvailable = ReturnSize;
+ /* Clear the handle */
+ DosSystemFileTable[SftIndex] = INVALID_HANDLE_VALUE;
}
-
- return Success;
+
+ /* Clear the entry in the JFT */
+ HandleTable[DosHandle] = 0xFF;
+
+ return TRUE;
}
-BOOLEAN DosFreeMemory(WORD BlockData)
+static BOOLEAN DosDuplicateHandle(WORD OldHandle, WORD NewHandle)
{
- PDOS_MCB Mcb = SEGMENT_TO_MCB(BlockData - 1);
+ BYTE SftIndex;
+ PDOS_PSP PspBlock;
+ LPBYTE HandleTable;
- DPRINT("DosFreeMemory: BlockData 0x%04X\n", BlockData);
+ DPRINT("DosDuplicateHandle: OldHandle 0x%04X, NewHandle 0x%04X\n",
+ OldHandle,
+ NewHandle);
- /* Make sure the MCB is valid */
- if (Mcb->BlockType != 'M' && Mcb->BlockType != 'Z')
+ /* 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)
{
- DPRINT("MCB block type '%c' not valid!\n", Mcb->BlockType);
- return FALSE;
+ /* Close it */
+ DosCloseHandle(NewHandle);
}
- /* Mark the block as free */
- Mcb->OwnerPsp = 0;
+ /* 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;
}
-BOOLEAN DosLinkUmb(VOID)
+static BOOLEAN DosLinkUmb(VOID)
{
DWORD Segment = FIRST_MCB_SEGMENT;
PDOS_MCB Mcb = SEGMENT_TO_MCB(Segment);
return TRUE;
}
-BOOLEAN DosUnlinkUmb(VOID)
+static BOOLEAN DosUnlinkUmb(VOID)
{
DWORD Segment = FIRST_MCB_SEGMENT;
PDOS_MCB Mcb = SEGMENT_TO_MCB(Segment);
return TRUE;
}
-WORD DosCreateFile(LPWORD Handle, LPCSTR FilePath, WORD Attributes)
+static WORD DosCreateFile(LPWORD Handle, LPCSTR FilePath, WORD Attributes)
{
HANDLE FileHandle;
WORD DosHandle;
return ERROR_SUCCESS;
}
-WORD DosOpenFile(LPWORD Handle, LPCSTR FilePath, BYTE AccessMode)
+static WORD DosOpenFile(LPWORD Handle, LPCSTR FilePath, BYTE AccessMode)
{
HANDLE FileHandle;
ACCESS_MASK Access = 0;
return ERROR_SUCCESS;
}
-WORD DosReadFile(WORD FileHandle, LPVOID Buffer, WORD Count, LPWORD BytesRead)
+static WORD DosReadFile(WORD FileHandle, LPVOID Buffer, WORD Count, LPWORD BytesRead)
{
WORD Result = ERROR_SUCCESS;
DWORD BytesRead32 = 0;
return Result;
}
-WORD DosWriteFile(WORD FileHandle, LPVOID Buffer, WORD Count, LPWORD BytesWritten)
+static WORD DosWriteFile(WORD FileHandle, LPVOID Buffer, WORD Count, LPWORD BytesWritten)
{
WORD Result = ERROR_SUCCESS;
DWORD BytesWritten32 = 0;
return Result;
}
-WORD DosSeekFile(WORD FileHandle, LONG Offset, BYTE Origin, LPDWORD NewOffset)
+static WORD DosSeekFile(WORD FileHandle, LONG Offset, BYTE Origin, LPDWORD NewOffset)
{
WORD Result = ERROR_SUCCESS;
DWORD FilePointer;
return ERROR_SUCCESS;
}
-BOOLEAN DosFlushFileBuffers(WORD FileHandle)
+static BOOLEAN DosFlushFileBuffers(WORD FileHandle)
{
HANDLE Handle = DosGetRealHandle(FileHandle);
return (BOOLEAN)FlushFileBuffers(Handle);
}
-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;
-}
-
-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;
-}
-
-WORD DosFindFirstFile(LPSTR FileSpec, WORD AttribMask)
-{
- BOOLEAN Success = TRUE;
- WIN32_FIND_DATAA FindData;
- PVDM_FIND_FILE_BLOCK FindFileBlock = (PVDM_FIND_FILE_BLOCK)FAR_POINTER(DiskTransferArea);
-
- /* Fill the block */
- FindFileBlock->DriveLetter = CurrentDrive + 'A';
- FindFileBlock->AttribMask = AttribMask;
- FindFileBlock->SearchHandle = FindFirstFileA(FileSpec, &FindData);
- if (FindFileBlock->SearchHandle == INVALID_HANDLE_VALUE) return GetLastError();
-
- do
- {
- /* Check the attributes */
- if (!((FindData.dwFileAttributes
- & (FILE_ATTRIBUTE_HIDDEN
- | FILE_ATTRIBUTE_SYSTEM
- | FILE_ATTRIBUTE_DIRECTORY))
- & ~AttribMask)) break;
- }
- while ((Success = FindNextFileA(FindFileBlock->SearchHandle, &FindData)));
-
- if (!Success) return GetLastError();
-
- FindFileBlock->Attributes = LOBYTE(FindData.dwFileAttributes);
- FileTimeToDosDateTime(&FindData.ftLastWriteTime,
- &FindFileBlock->FileDate,
- &FindFileBlock->FileTime);
- FindFileBlock->FileSize = FindData.nFileSizeHigh ? 0xFFFFFFFF
- : FindData.nFileSizeLow;
- strcpy(FindFileBlock->FileName, FindData.cAlternateFileName);
-
- return ERROR_SUCCESS;
-}
-
-WORD DosFindNextFile(VOID)
-{
- WIN32_FIND_DATAA FindData;
- PVDM_FIND_FILE_BLOCK FindFileBlock = (PVDM_FIND_FILE_BLOCK)FAR_POINTER(DiskTransferArea);
-
- do
- {
- if (!FindNextFileA(FindFileBlock->SearchHandle, &FindData)) return GetLastError();
-
- /* Update the block */
- FindFileBlock->Attributes = LOBYTE(FindData.dwFileAttributes);
- FileTimeToDosDateTime(&FindData.ftLastWriteTime,
- &FindFileBlock->FileDate,
- &FindFileBlock->FileTime);
- FindFileBlock->FileSize = FindData.nFileSizeHigh ? 0xFFFFFFFF
- : FindData.nFileSizeLow;
- strcpy(FindFileBlock->FileName, FindData.cAlternateFileName);
- }
- while((FindData.dwFileAttributes
- & (FILE_ATTRIBUTE_HIDDEN
- | FILE_ATTRIBUTE_SYSTEM
- | FILE_ATTRIBUTE_DIRECTORY))
- & ~FindFileBlock->AttribMask);
-
- return ERROR_SUCCESS;
-}
-
-BOOLEAN DosChangeDrive(BYTE Drive)
+static BOOLEAN DosChangeDrive(BYTE Drive)
{
WCHAR DirectoryPath[DOS_CMDLINE_LENGTH];
return TRUE;
}
-BOOLEAN DosChangeDirectory(LPSTR Directory)
+static BOOLEAN DosChangeDirectory(LPSTR Directory)
{
BYTE DriveNumber;
DWORD Attributes;
return TRUE;
}
+/* PUBLIC FUNCTIONS ***********************************************************/
+
VOID DosInitializePsp(WORD PspSegment, LPCSTR CommandLine, WORD ProgramSize, WORD Environment)
{
PDOS_PSP PspBlock = SEGMENT_TO_PSP(PspSegment);
{
LPSTR FileName = (LPSTR)SEG_OFF_TO_PTR(getDS(), getDX());
- /* Call the API function */
- if (DeleteFileA(FileName))
+ if (demFileDelete(FileName) == ERROR_SUCCESS)
{
Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;
/*
/* Find First File */
case 0x4E:
{
- WORD Result = DosFindFirstFile(SEG_OFF_TO_PTR(getDS(), getDX()), getCX());
+ 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;
/* Find Next File */
case 0x4F:
{
- WORD Result = DosFindNextFile();
+ WORD Result = (WORD)demFileFindNext(FAR_POINTER(DiskTransferArea));
setAX(Result);
if (Result == ERROR_SUCCESS) Stack[STACK_FLAGS] &= ~EMULATOR_FLAG_CF;