mirror of
https://github.com/reactos/reactos.git
synced 2025-01-01 03:54:02 +00:00
[NTVDM]
Implement file creation, opening, reading and writing. svn path=/branches/ntvdm/; revision=59406
This commit is contained in:
parent
ed9f26ccca
commit
40e7d3a9fb
3 changed files with 469 additions and 39 deletions
|
@ -16,6 +16,8 @@
|
|||
|
||||
static WORD CurrentPsp = SYSTEM_PSP;
|
||||
static DWORD DiskTransferArea;
|
||||
static HANDLE DosSystemFileTable[DOS_SFT_SIZE];
|
||||
static WORD DosSftRefCount[DOS_SFT_SIZE];
|
||||
|
||||
/* PRIVATE FUNCTIONS **********************************************************/
|
||||
|
||||
|
@ -94,6 +96,125 @@ static VOID DosChangeMemoryOwner(WORD Segment, WORD NewOwner)
|
|||
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] = 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)
|
||||
|
@ -273,21 +394,193 @@ BOOLEAN DosFreeMemory(WORD BlockData)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
WORD DosCreateFile(LPCSTR FilePath)
|
||||
WORD DosCreateFile(LPWORD Handle, LPCSTR FilePath, WORD Attributes)
|
||||
{
|
||||
// TODO: NOT IMPLEMENTED
|
||||
return 0;
|
||||
HANDLE FileHandle;
|
||||
WORD DosHandle;
|
||||
|
||||
/* 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 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;
|
||||
}
|
||||
|
||||
WORD DosOpenFile(LPCSTR FilePath)
|
||||
WORD DosOpenFile(LPWORD Handle, LPCSTR FilePath, BYTE AccessMode)
|
||||
{
|
||||
// TODO: NOT IMPLEMENTED
|
||||
return 0;
|
||||
HANDLE FileHandle;
|
||||
ACCESS_MASK Access = 0;
|
||||
WORD DosHandle;
|
||||
|
||||
/* 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 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;
|
||||
}
|
||||
|
||||
WORD DosReadFile(WORD FileHandle, LPVOID Buffer, WORD Count, LPWORD BytesRead)
|
||||
{
|
||||
WORD Result = ERROR_SUCCESS;
|
||||
DWORD BytesRead32 = 0;
|
||||
HANDLE Handle = DosGetRealHandle(FileHandle);
|
||||
|
||||
/* Make sure the handle is valid */
|
||||
if (Handle == INVALID_HANDLE_VALUE) return ERROR_INVALID_PARAMETER;
|
||||
|
||||
/* Read the file */
|
||||
if (!ReadFile(Handle, Buffer, Count, &BytesRead32, NULL))
|
||||
{
|
||||
/* Store the error code */
|
||||
Result = GetLastError();
|
||||
}
|
||||
|
||||
/* The number of bytes read is always 16-bit */
|
||||
*BytesRead = LOWORD(BytesRead32);
|
||||
|
||||
/* Return the error code */
|
||||
return Result;
|
||||
}
|
||||
|
||||
WORD DosWriteFile(WORD FileHandle, LPVOID Buffer, WORD Count, LPWORD BytesWritten)
|
||||
{
|
||||
WORD Result = ERROR_SUCCESS;
|
||||
DWORD BytesWritten32 = 0;
|
||||
HANDLE Handle = DosGetRealHandle(FileHandle);
|
||||
|
||||
/* Make sure the handle is valid */
|
||||
if (Handle == INVALID_HANDLE_VALUE) return ERROR_INVALID_PARAMETER;
|
||||
|
||||
/* Write the file */
|
||||
if (!WriteFile(Handle, Buffer, Count, &BytesWritten32, NULL))
|
||||
{
|
||||
/* Store the error code */
|
||||
Result = GetLastError();
|
||||
}
|
||||
|
||||
/* The number of bytes written is always 16-bit */
|
||||
*BytesWritten = LOWORD(BytesWritten32);
|
||||
|
||||
/* Return the error code */
|
||||
return Result;
|
||||
}
|
||||
|
||||
BOOLEAN DosCloseHandle(WORD DosHandle)
|
||||
{
|
||||
BYTE SftIndex;
|
||||
PDOS_PSP PspBlock;
|
||||
LPBYTE HandleTable;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
VOID DosInitializePsp(WORD PspSegment, LPCSTR CommandLine, WORD ProgramSize, WORD Environment)
|
||||
{
|
||||
INT i;
|
||||
PDOS_PSP PspBlock = SEGMENT_TO_PSP(PspSegment);
|
||||
LPDWORD IntVecTable = (LPDWORD)((ULONG_PTR)BaseAddress);
|
||||
|
||||
|
@ -308,11 +601,10 @@ VOID DosInitializePsp(WORD PspSegment, LPCSTR CommandLine, WORD ProgramSize, WOR
|
|||
/* Set the parent PSP */
|
||||
PspBlock->ParentPsp = CurrentPsp;
|
||||
|
||||
/* Initialize the handle table */
|
||||
for (i = 0; i < 20; i++) PspBlock->HandleTable[i] = 0xFF;
|
||||
|
||||
|
||||
/* 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 */
|
||||
|
@ -863,6 +1155,152 @@ VOID DosInt21h(WORD CodeSegment)
|
|||
break;
|
||||
}
|
||||
|
||||
/* Create File */
|
||||
case 0x3C:
|
||||
{
|
||||
WORD FileHandle;
|
||||
WORD ErrorCode = DosCreateFile(&FileHandle,
|
||||
(LPCSTR)(ULONG_PTR)BaseAddress
|
||||
+ TO_LINEAR(DataSegment, LOWORD(Edx)),
|
||||
LOWORD(Ecx));
|
||||
|
||||
if (ErrorCode == 0)
|
||||
{
|
||||
/* Clear CF */
|
||||
EmulatorClearFlag(EMULATOR_FLAG_CF);
|
||||
|
||||
/* Return the handle in AX */
|
||||
EmulatorSetRegister(EMULATOR_REG_AX,
|
||||
(Eax & 0xFFFF0000) | FileHandle);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Set CF */
|
||||
EmulatorSetFlag(EMULATOR_FLAG_CF);
|
||||
|
||||
/* Return the error code in AX */
|
||||
EmulatorSetRegister(EMULATOR_REG_AX,
|
||||
(Eax & 0xFFFF0000) | ErrorCode);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
/* Open File */
|
||||
case 0x3D:
|
||||
{
|
||||
WORD FileHandle;
|
||||
WORD ErrorCode = DosCreateFile(&FileHandle,
|
||||
(LPCSTR)(ULONG_PTR)BaseAddress
|
||||
+ TO_LINEAR(DataSegment, LOWORD(Edx)),
|
||||
LOBYTE(Eax));
|
||||
|
||||
if (ErrorCode == 0)
|
||||
{
|
||||
/* Clear CF */
|
||||
EmulatorClearFlag(EMULATOR_FLAG_CF);
|
||||
|
||||
/* Return the handle in AX */
|
||||
EmulatorSetRegister(EMULATOR_REG_AX,
|
||||
(Eax & 0xFFFF0000) | FileHandle);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Set CF */
|
||||
EmulatorSetFlag(EMULATOR_FLAG_CF);
|
||||
|
||||
/* Return the error code in AX */
|
||||
EmulatorSetRegister(EMULATOR_REG_AX,
|
||||
(Eax & 0xFFFF0000) | ErrorCode);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
/* Close File */
|
||||
case 0x3E:
|
||||
{
|
||||
if (DosCloseHandle(LOWORD(Ebx)))
|
||||
{
|
||||
/* Clear CF */
|
||||
EmulatorClearFlag(EMULATOR_FLAG_CF);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Set CF */
|
||||
EmulatorSetFlag(EMULATOR_FLAG_CF);
|
||||
|
||||
/* Return the error code in AX */
|
||||
EmulatorSetRegister(EMULATOR_REG_AX,
|
||||
(Eax & 0xFFFF0000) | ERROR_INVALID_PARAMETER);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
/* Read File */
|
||||
case 0x3F:
|
||||
{
|
||||
WORD BytesRead = 0;
|
||||
WORD ErrorCode = DosReadFile(LOWORD(Ebx),
|
||||
(LPVOID)((ULONG_PTR)BaseAddress
|
||||
+ TO_LINEAR(DataSegment, LOWORD(Edx))),
|
||||
LOWORD(Ecx),
|
||||
&BytesRead);
|
||||
|
||||
if (ErrorCode == 0)
|
||||
{
|
||||
/* Clear CF */
|
||||
EmulatorClearFlag(EMULATOR_FLAG_CF);
|
||||
|
||||
/* Return the number of bytes read in AX */
|
||||
EmulatorSetRegister(EMULATOR_REG_AX,
|
||||
(Eax & 0xFFFF0000) | BytesRead);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Set CF */
|
||||
EmulatorSetFlag(EMULATOR_FLAG_CF);
|
||||
|
||||
/* Return the error code in AX */
|
||||
EmulatorSetRegister(EMULATOR_REG_AX,
|
||||
(Eax & 0xFFFF0000) | ErrorCode);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* Write File */
|
||||
case 0x40:
|
||||
{
|
||||
WORD BytesWritten = 0;
|
||||
WORD ErrorCode = DosWriteFile(LOWORD(Ebx),
|
||||
(LPVOID)((ULONG_PTR)BaseAddress
|
||||
+ TO_LINEAR(DataSegment, LOWORD(Edx))),
|
||||
LOWORD(Ecx),
|
||||
&BytesWritten);
|
||||
|
||||
if (ErrorCode == 0)
|
||||
{
|
||||
/* Clear CF */
|
||||
EmulatorClearFlag(EMULATOR_FLAG_CF);
|
||||
|
||||
/* Return the number of bytes written in AX */
|
||||
EmulatorSetRegister(EMULATOR_REG_AX,
|
||||
(Eax & 0xFFFF0000) | BytesWritten);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Set CF */
|
||||
EmulatorSetFlag(EMULATOR_FLAG_CF);
|
||||
|
||||
/* Return the error code in AX */
|
||||
EmulatorSetRegister(EMULATOR_REG_AX,
|
||||
(Eax & 0xFFFF0000) | ErrorCode);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
/* Allocate Memory */
|
||||
case 0x48:
|
||||
{
|
||||
|
@ -933,6 +1371,7 @@ VOID DosBreakInterrupt()
|
|||
|
||||
BOOLEAN DosInitialize()
|
||||
{
|
||||
BYTE i;
|
||||
PDOS_MCB Mcb = SEGMENT_TO_MCB(FIRST_MCB_SEGMENT);
|
||||
FILE *Stream;
|
||||
WCHAR Buffer[256];
|
||||
|
@ -1006,6 +1445,18 @@ BOOLEAN DosInitialize()
|
|||
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);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
|
|
@ -22,6 +22,8 @@
|
|||
#define USER_MEMORY_SIZE 0x8FFFF
|
||||
#define SYSTEM_PSP 0x08
|
||||
#define SYSTEM_ENV_BLOCK 0x800
|
||||
#define INVALID_DOS_HANDLE 0xFFFF
|
||||
#define DOS_SFT_SIZE 255
|
||||
#define SEGMENT_TO_MCB(seg) ((PDOS_MCB)((ULONG_PTR)BaseAddress + TO_LINEAR((seg), 0)))
|
||||
#define SEGMENT_TO_PSP(seg) ((PDOS_PSP)((ULONG_PTR)BaseAddress + TO_LINEAR((seg), 0)))
|
||||
|
||||
|
@ -76,34 +78,6 @@ typedef struct _DOS_PSP
|
|||
CHAR CommandLine[127];
|
||||
} DOS_PSP, *PDOS_PSP;
|
||||
|
||||
typedef struct _DOS_SFT_ENTRY
|
||||
{
|
||||
WORD ReferenceCount;
|
||||
WORD Mode;
|
||||
BYTE Attribute;
|
||||
WORD DeviceInfo;
|
||||
DWORD DriveParamBlock;
|
||||
WORD FirstCluster;
|
||||
WORD FileTime;
|
||||
WORD FileDate;
|
||||
DWORD FileSize;
|
||||
DWORD CurrentOffset;
|
||||
WORD LastClusterAccessed;
|
||||
DWORD DirEntSector;
|
||||
BYTE DirEntryIndex;
|
||||
CHAR FileName[11];
|
||||
BYTE Reserved0[6];
|
||||
WORD OwnerPsp;
|
||||
BYTE Reserved1[8];
|
||||
} DOS_SFT_ENTRY, *PDOS_SFT_ENTRY;
|
||||
|
||||
typedef struct _DOS_SFT
|
||||
{
|
||||
DWORD NextTablePtr;
|
||||
WORD FileCount;
|
||||
DOS_SFT_ENTRY Entry[ANYSIZE_ARRAY];
|
||||
} DOS_SFT, *PDOS_SFT;
|
||||
|
||||
typedef struct _DOS_INPUT_BUFFER
|
||||
{
|
||||
BYTE MaxLength, Length;
|
||||
|
@ -117,6 +91,10 @@ typedef struct _DOS_INPUT_BUFFER
|
|||
WORD DosAllocateMemory(WORD Size, WORD *MaxAvailable);
|
||||
BOOLEAN DosResizeMemory(WORD BlockData, WORD NewSize, WORD *MaxAvailable);
|
||||
BOOLEAN DosFreeMemory(WORD BlockData);
|
||||
WORD DosCreateFile(LPWORD Handle, LPCSTR FilePath, WORD Attributes);
|
||||
WORD DosOpenFile(LPWORD Handle, LPCSTR FilePath, BYTE AccessMode);
|
||||
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);
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#define MAX_SEGMENT 0xFFFF
|
||||
#define MAX_OFFSET 0xFFFF
|
||||
#define MAX_ADDRESS TO_LINEAR(MAX_SEGMENT, MAX_OFFSET)
|
||||
#define FAR_POINTER(x) ((ULONG_PTR)BaseAddress + TO_LINEAR(HIWORD(x), LOWORD(x)))
|
||||
#define STEPS_PER_CYCLE 256
|
||||
|
||||
/* FUNCTIONS ******************************************************************/
|
||||
|
|
Loading…
Reference in a new issue