[NTVDM]
authorAleksandar Andrejevic <aandrejevic@reactos.org>
Fri, 3 Jan 2014 23:41:40 +0000 (23:41 +0000)
committerAleksandar Andrejevic <aandrejevic@reactos.org>
Fri, 3 Jan 2014 23:41:40 +0000 (23:41 +0000)
Implement DOS functions 0x4E (Find First File) and 0x4F (Find Next File). Not tested yet.

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

subsystems/ntvdm/dos.c
subsystems/ntvdm/dos.h

index f094fd4..affdded 100644 (file)
@@ -890,6 +890,69 @@ BOOLEAN DosCloseHandle(WORD DosHandle)
     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)
 {
     WCHAR DirectoryPath[DOS_CMDLINE_LENGTH];
@@ -2482,6 +2545,30 @@ VOID WINAPI DosInt21h(LPWORD Stack)
             break;
         }
 
+        /* Find First File */
+        case 0x4E:
+        {
+            WORD Result = DosFindFirstFile(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 = DosFindNextFile();
+
+            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:
         {
index d7108b8..2daa17a 100644 (file)
@@ -118,6 +118,22 @@ 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 ******************************************************************/