[NTVDM]
authorHermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
Sun, 26 Jan 2014 18:25:59 +0000 (18:25 +0000)
committerHermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
Sun, 26 Jan 2014 18:25:59 +0000 (18:25 +0000)
- Start to refactor the DOS sources:
  Introduce the DEM (DOS Emulation) support library that is used by our built-in DOS, and that is used (via BOPs) by windows NT DOS (files: ntio.sys and ntdos.sys).
- Export some of DEM functions; stub most of them and implement the remaining ones (with existing code that we had in dos.c before).

svn path=/branches/ntvdm/; revision=61838

subsystems/ntvdm/CMakeLists.txt
subsystems/ntvdm/bios/bios.c
subsystems/ntvdm/dos/dem.c [new file with mode: 0644]
subsystems/ntvdm/dos/dem.h [new file with mode: 0644]
subsystems/ntvdm/dos/dos32/dos.c [moved from subsystems/ntvdm/dos/dos.c with 95% similarity]
subsystems/ntvdm/dos/dos32/dos.h [moved from subsystems/ntvdm/dos/dos.h with 78% similarity]
subsystems/ntvdm/ntvdm.c
subsystems/ntvdm/ntvdm.spec

index 933d4c1..95cc920 100644 (file)
@@ -15,7 +15,8 @@ list(APPEND SOURCE
     hardware/speaker.c
     hardware/timer.c
     hardware/vga.c
-    dos/dos.c
+    dos/dos32/dos.c
+    dos/dem.c
     bop.c
     emulator.c
     int32.c
index 8eca3d8..8c827ee 100644 (file)
@@ -53,7 +53,7 @@ static VOID WINAPI BiosMiscService(LPWORD Stack)
         case 0x86:
         {
             /*
-             * Interval in microseconds CX:DX
+             * Interval in microseconds in CX:DX
              * See Ralf Brown: http://www.ctyme.com/intr/rb-1525.htm
              * for more information.
              */
diff --git a/subsystems/ntvdm/dos/dem.c b/subsystems/ntvdm/dos/dem.c
new file mode 100644 (file)
index 0000000..9ff801a
--- /dev/null
@@ -0,0 +1,178 @@
+/*
+ * COPYRIGHT:       GPL - See COPYING in the top level directory
+ * PROJECT:         ReactOS Virtual DOS Machine
+ * FILE:            dem.c
+ * PURPOSE:         DOS 32-bit Emulation Support Library -
+ *                  This library is used by the built-in NTVDM DOS32 and by
+ *                  the NT 16-bit DOS in Windows (via BOPs). It also exposes
+ *                  exported functions that can be used by VDDs.
+ * PROGRAMMERS:     Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
+ *                  Hermes Belusca-Maito (hermes.belusca@sfr.fr)
+ */
+
+/* INCLUDES *******************************************************************/
+
+#define NDEBUG
+
+#include "dem.h"
+
+/* 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 **********************************************************/
+
+/* PUBLIC FUNCTIONS ***********************************************************/
+
+/* PUBLIC EXPORTED APIS *******************************************************/
+
+// demLFNCleanup
+// demLFNGetCurrentDirectory
+
+// demGetFileTimeByHandle_WOW
+// demWOWLFNAllocateSearchHandle
+// demWOWLFNCloseSearchHandle
+// demWOWLFNEntry
+// demWOWLFNGetSearchHandle
+// demWOWLFNInit
+
+DWORD
+WINAPI
+demClientErrorEx(IN HANDLE FileHandle,
+                 IN CHAR   Unknown,
+                 IN BOOL   Flag)
+{
+    UNIMPLEMENTED;
+    return GetLastError();
+}
+
+DWORD
+WINAPI
+demFileDelete(IN LPCSTR FileName)
+{
+    if (DeleteFileA(FileName)) SetLastError(ERROR_SUCCESS);
+
+    return GetLastError();
+}
+
+DWORD
+WINAPI
+demFileFindFirst(OUT PVOID  lpFindFileData,
+                 IN  LPCSTR FileName,
+                 IN  WORD   AttribMask)
+{
+    BOOLEAN Success = TRUE;
+    WIN32_FIND_DATAA FindData;
+    PVDM_FIND_FILE_BLOCK FindFileBlock = (PVDM_FIND_FILE_BLOCK)lpFindFileData;
+
+    /* Fill the block */
+    FindFileBlock->DriveLetter  = CurrentDrive + 'A';
+    FindFileBlock->AttribMask   = AttribMask;
+    FindFileBlock->SearchHandle = FindFirstFileA(FileName, &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;
+}
+
+DWORD
+WINAPI
+demFileFindNext(OUT PVOID lpFindFileData)
+{
+    WIN32_FIND_DATAA FindData;
+    PVDM_FIND_FILE_BLOCK FindFileBlock = (PVDM_FIND_FILE_BLOCK)lpFindFileData;
+
+    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;
+}
+
+UCHAR
+WINAPI
+demGetPhysicalDriveType(IN UCHAR DriveNumber)
+{
+    UNIMPLEMENTED;
+    return DOSDEVICE_DRIVE_UNKNOWN;
+}
+
+BOOL
+WINAPI
+demIsShortPathName(IN LPCSTR Path,
+                   IN BOOL Unknown)
+{
+    UNIMPLEMENTED;
+    return FALSE;
+}
+
+DWORD
+WINAPI
+demSetCurrentDirectoryGetDrive(IN  LPCSTR CurrentDirectory,
+                               OUT PUCHAR DriveNumber)
+{
+    UNIMPLEMENTED;
+    return ERROR_SUCCESS;
+}
+
+/* EOF */
diff --git a/subsystems/ntvdm/dos/dem.h b/subsystems/ntvdm/dos/dem.h
new file mode 100644 (file)
index 0000000..907d913
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * COPYRIGHT:       GPL - See COPYING in the top level directory
+ * PROJECT:         ReactOS Virtual DOS Machine
+ * FILE:            dem.h
+ * PURPOSE:         DOS 32-bit Emulation Support Library -
+ *                  This library is used by the built-in NTVDM DOS32 and by
+ *                  the NT 16-bit DOS in Windows (via BOPs). It also exposes
+ *                  exported functions that can be used by VDDs.
+ * PROGRAMMERS:     Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
+ *                  Hermes Belusca-Maito (hermes.belusca@sfr.fr)
+ */
+
+#ifndef _DEM_H_
+#define _DEM_H_
+
+/* INCLUDES *******************************************************************/
+
+#include "ntvdm.h"
+
+/* FUNCTIONS ******************************************************************/
+
+DWORD
+WINAPI
+demClientErrorEx
+(
+    IN HANDLE FileHandle,
+    IN CHAR   Unknown,
+    IN BOOL   Flag
+);
+
+DWORD
+WINAPI
+demFileDelete
+(
+    IN LPCSTR FileName
+);
+
+DWORD
+WINAPI
+demFileFindFirst
+(
+    OUT PVOID  lpFindFileData,
+    IN  LPCSTR FileName,
+    IN  WORD   AttribMask
+);
+
+DWORD
+WINAPI
+demFileFindNext
+(
+    OUT PVOID lpFindFileData
+);
+
+UCHAR
+WINAPI
+demGetPhysicalDriveType
+(
+    IN UCHAR DriveNumber
+);
+
+BOOL
+WINAPI
+demIsShortPathName
+(
+    IN LPCSTR Path,
+    IN BOOL Unknown
+);
+
+DWORD
+WINAPI
+demSetCurrentDirectoryGetDrive
+(
+    IN  LPCSTR CurrentDirectory,
+    OUT PUCHAR DriveNumber
+);
+
+#endif // _DEM_H_
+
+/* EOF */
similarity index 95%
rename from subsystems/ntvdm/dos/dos.c
rename to subsystems/ntvdm/dos/dos32/dos.c
index 53223c9..c761d7f 100644 (file)
@@ -12,6 +12,7 @@
 
 #include "emulator.h"
 #include "dos.h"
+#include "dos/dem.h"
 
 #include "bios/bios.h"
 #include "bop.h"
@@ -23,7 +24,7 @@
 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];
@@ -38,30 +39,6 @@ static WORD DosErrorLevel = 0x0000;
 
 /* 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;
@@ -90,184 +67,7 @@ static VOID DosCombineFreeBlocks(WORD StartBlock)
     }
 }
 
-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;
@@ -390,7 +190,7 @@ Done:
     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;
@@ -408,115 +208,390 @@ BOOLEAN DosResizeMemory(WORD BlockData, WORD NewSize, WORD *MaxAvailable)
         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);
@@ -543,7 +618,7 @@ BOOLEAN DosLinkUmb(VOID)
     return TRUE;
 }
 
-BOOLEAN DosUnlinkUmb(VOID)
+static BOOLEAN DosUnlinkUmb(VOID)
 {
     DWORD Segment = FIRST_MCB_SEGMENT;
     PDOS_MCB Mcb = SEGMENT_TO_MCB(Segment);
@@ -574,7 +649,7 @@ BOOLEAN DosUnlinkUmb(VOID)
     return TRUE;
 }
 
-WORD DosCreateFile(LPWORD Handle, LPCSTR FilePath, WORD Attributes)
+static WORD DosCreateFile(LPWORD Handle, LPCSTR FilePath, WORD Attributes)
 {
     HANDLE FileHandle;
     WORD DosHandle;
@@ -615,7 +690,7 @@ WORD DosCreateFile(LPWORD Handle, LPCSTR FilePath, WORD Attributes)
     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;
@@ -688,7 +763,7 @@ WORD DosOpenFile(LPWORD Handle, LPCSTR FilePath, BYTE AccessMode)
     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;
@@ -713,7 +788,7 @@ WORD DosReadFile(WORD FileHandle, LPVOID Buffer, WORD Count, LPWORD BytesRead)
     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;
@@ -753,7 +828,7 @@ WORD DosWriteFile(WORD FileHandle, LPVOID Buffer, WORD Count, LPWORD BytesWritte
     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;
@@ -796,7 +871,7 @@ WORD DosSeekFile(WORD FileHandle, LONG Offset, BYTE Origin, LPDWORD NewOffset)
     return ERROR_SUCCESS;
 }
 
-BOOLEAN DosFlushFileBuffers(WORD FileHandle)
+static BOOLEAN DosFlushFileBuffers(WORD FileHandle)
 {
     HANDLE Handle = DosGetRealHandle(FileHandle);
 
@@ -814,146 +889,7 @@ BOOLEAN DosFlushFileBuffers(WORD 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];
 
@@ -973,7 +909,7 @@ BOOLEAN DosChangeDrive(BYTE Drive)
     return TRUE;
 }
 
-BOOLEAN DosChangeDirectory(LPSTR Directory)
+static BOOLEAN DosChangeDirectory(LPSTR Directory)
 {
     BYTE DriveNumber;
     DWORD Attributes;
@@ -1040,6 +976,8 @@ BOOLEAN DosChangeDirectory(LPSTR Directory)
     return TRUE;
 }
 
+/* PUBLIC FUNCTIONS ***********************************************************/
+
 VOID DosInitializePsp(WORD PspSegment, LPCSTR CommandLine, WORD ProgramSize, WORD Environment)
 {
     PDOS_PSP PspBlock = SEGMENT_TO_PSP(PspSegment);
@@ -2279,8 +2217,7 @@ VOID WINAPI DosInt21h(LPWORD Stack)
         {
             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;
                 /*
@@ -2548,7 +2485,9 @@ VOID WINAPI DosInt21h(LPWORD Stack)
         /* 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;
@@ -2560,7 +2499,7 @@ VOID WINAPI DosInt21h(LPWORD Stack)
         /* 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;
similarity index 78%
rename from subsystems/ntvdm/dos/dos.h
rename to subsystems/ntvdm/dos/dos32/dos.h
index 2daa17a..500bdfd 100644 (file)
@@ -118,36 +118,10 @@ typedef struct _DOS_DRIVER_HEADER
     CHAR DeviceName[8];
 } DOS_DRIVER_HEADER, *PDOS_DRIVER_HEADER;
 
-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)
 
 /* FUNCTIONS ******************************************************************/
 
-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);
-WORD DosSeekFile(WORD FileHandle, LONG Offset, BYTE Origin, LPDWORD NewOffset);
-BOOLEAN DosDuplicateHandle(WORD OldHandle, WORD NewHandle);
-BOOLEAN DosCloseHandle(WORD DosHandle);
 VOID DosInitializePsp(WORD PspSegment, LPCSTR CommandLine, WORD ProgramSize, WORD Environment);
 BOOLEAN DosCreateProcess(LPCSTR CommandLine, WORD EnvBlock);
 VOID DosTerminateProcess(WORD Psp, BYTE ReturnCode);
index 91bbe55..e6a33d6 100644 (file)
@@ -18,7 +18,7 @@
 #include "hardware/ps2.h"
 #include "hardware/timer.h"
 #include "hardware/vga.h"
-#include "dos/dos.h"
+#include "dos/dos32/dos.h"
 
 /*
  * Activate this line if you want to be able to test NTVDM with:
index ceca023..8a9d7b3 100644 (file)
 
 
 
+@ stdcall demClientErrorEx(long long long)
+@ stdcall demFileDelete(ptr)
+@ stdcall demFileFindFirst(ptr ptr long)
+@ stdcall demFileFindNext(ptr)
+;@ stdcall demGetFileTimeByHandle_WOW
+@ stdcall demGetPhysicalDriveType(long)
+@ stdcall demIsShortPathName(ptr long)
+;@ stdcall demLFNCleanup
+;@ stdcall demLFNGetCurrentDirectory
+@ stdcall demSetCurrentDirectoryGetDrive(ptr ptr)
+;@ stdcall demWOWLFNAllocateSearchHandle
+;@ stdcall demWOWLFNCloseSearchHandle
+;@ stdcall demWOWLFNEntry
+;@ stdcall demWOWLFNGetSearchHandle
+;@ stdcall demWOWLFNInit
+
+
+
 @ stdcall MGetVdmPointer(long long long)
 @ stdcall Sim32pGetVDMPointer(long long)