Implement DOS functions 0x4E (Find First File) and 0x4F (Find Next File). Not tested yet.


svn path=/branches/ntvdm/; revision=61507
This commit is contained in:
Aleksandar Andrejevic 2014-01-03 23:41:40 +00:00
parent 2b13376ad5
commit 4d933b0747
2 changed files with 103 additions and 0 deletions

View 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:
{

View 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 ******************************************************************/