Reimplemented FindFirstFileEx and removed some overhead. Modified: trunk/reactos/lib/kernel32/file/find.c _____
Modified: trunk/reactos/lib/kernel32/file/find.c --- trunk/reactos/lib/kernel32/file/find.c 2005-08-11 18:49:40 UTC (rev 17290) +++ trunk/reactos/lib/kernel32/file/find.c 2005-08-11 19:02:31 UTC (rev 17291) @@ -28,20 +28,98 @@
typedef struct _KERNEL32_FIND_FILE_DATA { HANDLE DirectoryHandle; + BOOLEAN DirectoryOnly; PFILE_BOTH_DIR_INFORMATION pFileInfo; } KERNEL32_FIND_FILE_DATA, *PKERNEL32_FIND_FILE_DATA;
/* FUNCTIONS ****************************************************************/
+VOID +InternalCopyFindDataW(LPWIN32_FIND_DATAW lpFindFileData, + PFILE_BOTH_DIR_INFORMATION lpFileInfo) +{ + lpFindFileData->dwFileAttributes = lpFileInfo->FileAttributes;
+ lpFindFileData->ftCreationTime.dwHighDateTime = lpFileInfo->CreationTime.u.HighPart; + lpFindFileData->ftCreationTime.dwLowDateTime = lpFileInfo->CreationTime.u.LowPart; + + lpFindFileData->ftLastAccessTime.dwHighDateTime = lpFileInfo->LastAccessTime.u.HighPart; + lpFindFileData->ftLastAccessTime.dwLowDateTime = lpFileInfo->LastAccessTime.u.LowPart; + + lpFindFileData->ftLastWriteTime.dwHighDateTime = lpFileInfo->LastWriteTime.u.HighPart; + lpFindFileData->ftLastWriteTime.dwLowDateTime = lpFileInfo->LastWriteTime.u.LowPart; + + lpFindFileData->nFileSizeHigh = lpFileInfo->EndOfFile.u.HighPart; + lpFindFileData->nFileSizeLow = lpFileInfo->EndOfFile.u.LowPart; + + memcpy (lpFindFileData->cFileName, lpFileInfo->FileName, lpFileInfo->FileNameLength); + lpFindFileData->cFileName[lpFileInfo->FileNameLength / sizeof(WCHAR)] = 0; + + memcpy (lpFindFileData->cAlternateFileName, lpFileInfo->ShortName, lpFileInfo->ShortNameLength); + lpFindFileData->cAlternateFileName[lpFileInfo->ShortNameLength / sizeof(WCHAR)] = 0; +} + +VOID +InternalCopyFindDataA(LPWIN32_FIND_DATAA lpFindFileData, + PFILE_BOTH_DIR_INFORMATION lpFileInfo) +{ + UNICODE_STRING FileNameU; + ANSI_STRING FileNameA; + + lpFindFileData->dwFileAttributes = lpFileInfo->FileAttributes; + + lpFindFileData->ftCreationTime.dwHighDateTime = lpFileInfo->CreationTime.u.HighPart; + lpFindFileData->ftCreationTime.dwLowDateTime = lpFileInfo->CreationTime.u.LowPart; + + lpFindFileData->ftLastAccessTime.dwHighDateTime = lpFileInfo->LastAccessTime.u.HighPart; + lpFindFileData->ftLastAccessTime.dwLowDateTime = lpFileInfo->LastAccessTime.u.LowPart; + + lpFindFileData->ftLastWriteTime.dwHighDateTime = lpFileInfo->LastWriteTime.u.HighPart; + lpFindFileData->ftLastWriteTime.dwLowDateTime = lpFileInfo->LastWriteTime.u.LowPart; + + lpFindFileData->nFileSizeHigh = lpFileInfo->EndOfFile.u.HighPart; + lpFindFileData->nFileSizeLow = lpFileInfo->EndOfFile.u.LowPart; + + FileNameU.Length = FileNameU.MaximumLength = lpFileInfo->FileNameLength; + FileNameU.Buffer = lpFileInfo->FileName; + + FileNameA.MaximumLength = sizeof(lpFindFileData->cFileName) - sizeof(CHAR); + FileNameA.Buffer = lpFindFileData->cFileName; + + /* convert unicode string to ansi (or oem) */ + if (bIsFileApiAnsi) + RtlUnicodeStringToAnsiString (&FileNameA, &FileNameU, FALSE); + else + RtlUnicodeStringToOemString (&FileNameA, &FileNameU, FALSE); + + FileNameA.Buffer[FileNameA.Length] = 0; + + DPRINT("lpFileInfo->ShortNameLength %d\n", lpFileInfo->ShortNameLength); + + FileNameU.Length = FileNameU.MaximumLength = lpFileInfo->ShortNameLength; + FileNameU.Buffer = lpFileInfo->ShortName; + + FileNameA.MaximumLength = sizeof(lpFindFileData->cAlternateFileName) - sizeof(CHAR); + FileNameA.Buffer = lpFindFileData->cAlternateFileName; + + /* convert unicode string to ansi (or oem) */ + if (bIsFileApiAnsi) + RtlUnicodeStringToAnsiString (&FileNameA, &FileNameU, FALSE); + else + RtlUnicodeStringToOemString (&FileNameA, &FileNameU, FALSE); + + FileNameA.Buffer[FileNameA.Length] = 0; +} + /* * @implemented */ BOOL STDCALL InternalFindNextFile ( - HANDLE hFindFile + HANDLE hFindFile, + PUNICODE_STRING SearchPattern ) { PKERNEL32_FIND_FILE_DATA IData; @@ -52,32 +130,40 @@
IData = (PKERNEL32_FIND_FILE_DATA)hFindFile;
- if (IData->pFileInfo->NextEntryOffset != 0) - { - IData->pFileInfo = (PVOID)((ULONG_PTR)IData->pFileInfo + IData->pFileInfo->NextEntryOffset); - DPRINT("Found %.*S\n",IData->pFileInfo->FileNameLength/sizeof(WCHAR), IData->pFileInfo->FileName); - return TRUE; - } - IData->pFileInfo = (PVOID)((ULONG_PTR)IData + sizeof(KERNEL32_FIND_FILE_DATA)); - IData->pFileInfo->FileIndex = 0; - Status = NtQueryDirectoryFile (IData->DirectoryHandle, - NULL, - NULL, - NULL, - &IoStatusBlock, - (PVOID)IData->pFileInfo, - FIND_DATA_SIZE, - FileBothDirectoryInformation, - FALSE, - NULL, - FALSE); - if (!NT_SUCCESS(Status)) - { - SetLastErrorByStatus (Status); - return FALSE; - } - DPRINT("Found %.*S\n",IData->pFileInfo->FileNameLength/sizeof(WCHAR), IData->pFileInfo->FileName); - return TRUE; + while (1) + { + if (IData->pFileInfo->NextEntryOffset != 0) + { + IData->pFileInfo = (PVOID)((ULONG_PTR)IData->pFileInfo + IData->pFileInfo->NextEntryOffset); + } + else + { + IData->pFileInfo = (PVOID)((ULONG_PTR)IData + sizeof(KERNEL32_FIND_FILE_DATA)); + IData->pFileInfo->FileIndex = 0; + Status = NtQueryDirectoryFile (IData->DirectoryHandle, + NULL, + NULL, + NULL, + &IoStatusBlock, + (PVOID)IData->pFileInfo, + FIND_DATA_SIZE, + FileBothDirectoryInformation, + SearchPattern ? TRUE : FALSE, + SearchPattern, + SearchPattern ? TRUE : FALSE); + SearchPattern = NULL; + if (!NT_SUCCESS(Status)) + { + SetLastErrorByStatus (Status); + return FALSE; + } + } + if (!IData->DirectoryOnly || IData->pFileInfo->FileAttributes & FILE_ATTRIBUTE_DIRECTORY) + { + DPRINT("Found %.*S\n",IData->pFileInfo->FileNameLength/sizeof(WCHAR), IData->pFileInfo->FileName); + return TRUE; + } + } }
@@ -87,7 +173,8 @@ HANDLE STDCALL InternalFindFirstFile ( - LPCWSTR lpFileName + LPCWSTR lpFileName, + BOOLEAN DirectoryOnly ) { OBJECT_ATTRIBUTES ObjectAttributes; @@ -273,34 +360,22 @@ } IData->pFileInfo = (PVOID)((ULONG_PTR)IData + sizeof(KERNEL32_FIND_FILE_DATA)); IData->pFileInfo->FileIndex = 0; + IData->DirectoryOnly = DirectoryOnly;
- Status = NtQueryDirectoryFile (IData->DirectoryHandle, - NULL, - NULL, - NULL, - &IoStatusBlock, - (PVOID)IData->pFileInfo, - FIND_DATA_SIZE, - FileBothDirectoryInformation, - TRUE, - &PatternStr, - TRUE); + bResult = InternalFindNextFile((HANDLE)IData, &PatternStr); if (NULL != SlashlessFileName) { RtlFreeHeap(hProcessHeap, 0, SlashlessFileName); } - if (!NT_SUCCESS(Status)) - { - DPRINT("Status %lx\n", Status); - CloseHandle (IData->DirectoryHandle); - RtlFreeHeap (hProcessHeap, 0, IData); - SetLastErrorByStatus (Status); - return NULL; - } - DPRINT("Found %.*S\n",IData->pFileInfo->FileNameLength/sizeof(WCHAR), IData->pFileInfo->FileName);
+ if (!bResult) + { + FindClose((HANDLE)IData); + return NULL; + } + return IData; }
@@ -332,7 +407,7 @@ &FileName, TRUE);
- IData = InternalFindFirstFile (FileNameU.Buffer); + IData = InternalFindFirstFile (FileNameU.Buffer, FALSE);
RtlFreeUnicodeString (&FileNameU);
@@ -346,59 +421,9 @@ IData->pFileInfo->FileNameLength);
/* copy data into WIN32_FIND_DATA structure */ - lpFindFileData->dwFileAttributes = IData->pFileInfo->FileAttributes; + InternalCopyFindDataA(lpFindFileData, IData->pFileInfo);
- lpFindFileData->ftCreationTime.dwHighDateTime = IData->pFileInfo->CreationTime.u.HighPart; - lpFindFileData->ftCreationTime.dwLowDateTime = IData->pFileInfo->CreationTime.u.LowPart;
- lpFindFileData->ftLastAccessTime.dwHighDateTime = IData->pFileInfo->LastAccessTime.u.HighPart; - lpFindFileData->ftLastAccessTime.dwLowDateTime = IData->pFileInfo->LastAccessTime.u.LowPart; - - lpFindFileData->ftLastWriteTime.dwHighDateTime = IData->pFileInfo->LastWriteTime.u.HighPart; - lpFindFileData->ftLastWriteTime.dwLowDateTime = IData->pFileInfo->LastWriteTime.u.LowPart; - - lpFindFileData->nFileSizeHigh = IData->pFileInfo->EndOfFile.u.HighPart; - lpFindFileData->nFileSizeLow = IData->pFileInfo->EndOfFile.u.LowPart; - - FileNameU.Length = IData->pFileInfo->FileNameLength; - FileNameU.MaximumLength = FileNameU.Length + sizeof(WCHAR); - FileNameU.Buffer = IData->pFileInfo->FileName; - - FileName.Length = 0; - FileName.MaximumLength = MAX_PATH; - FileName.Buffer = lpFindFileData->cFileName; - - /* convert unicode string to ansi (or oem) */ - if (bIsFileApiAnsi) - RtlUnicodeStringToAnsiString (&FileName, - &FileNameU, - FALSE); - else - RtlUnicodeStringToOemString (&FileName, - &FileNameU, - FALSE); - - DPRINT("IData->pFileInfo->ShortNameLength %d\n", - IData->pFileInfo->ShortNameLength); - - FileNameU.Length = IData->pFileInfo->ShortNameLength; - FileNameU.MaximumLength = FileNameU.Length + sizeof(WCHAR); - FileNameU.Buffer = IData->pFileInfo->ShortName; - - FileName.Length = 0; - FileName.MaximumLength = 14; - FileName.Buffer = lpFindFileData->cAlternateFileName; - - /* convert unicode string to ansi (or oem) */ - if (bIsFileApiAnsi) - RtlUnicodeStringToAnsiString (&FileName, - &FileNameU, - FALSE); - else - RtlUnicodeStringToOemString (&FileName, - &FileNameU, - FALSE); - return (HANDLE)IData; }
@@ -413,8 +438,6 @@ LPWIN32_FIND_DATAA lpFindFileData) { PKERNEL32_FIND_FILE_DATA IData; - UNICODE_STRING FileNameU; - ANSI_STRING FileName;
if (hFindFile == INVALID_HANDLE_VALUE) { @@ -424,7 +447,7 @@ }
IData = (PKERNEL32_FIND_FILE_DATA)hFindFile; - if (!InternalFindNextFile (hFindFile)) + if (!InternalFindNextFile (hFindFile, NULL)) { DPRINT("InternalFindNextFile() failed\n"); return FALSE; @@ -434,59 +457,8 @@ IData->pFileInfo->FileNameLength);
/* copy data into WIN32_FIND_DATA structure */ - lpFindFileData->dwFileAttributes = IData->pFileInfo->FileAttributes; + InternalCopyFindDataA(lpFindFileData, IData->pFileInfo);
- lpFindFileData->ftCreationTime.dwHighDateTime = IData->pFileInfo->CreationTime.u.HighPart; - lpFindFileData->ftCreationTime.dwLowDateTime = IData->pFileInfo->CreationTime.u.LowPart; - - lpFindFileData->ftLastAccessTime.dwHighDateTime = IData->pFileInfo->LastAccessTime.u.HighPart; - lpFindFileData->ftLastAccessTime.dwLowDateTime = IData->pFileInfo->LastAccessTime.u.LowPart; - - lpFindFileData->ftLastWriteTime.dwHighDateTime = IData->pFileInfo->LastWriteTime.u.HighPart; - lpFindFileData->ftLastWriteTime.dwLowDateTime = IData->pFileInfo->LastWriteTime.u.LowPart; - - lpFindFileData->nFileSizeHigh = IData->pFileInfo->EndOfFile.u.HighPart; - lpFindFileData->nFileSizeLow = IData->pFileInfo->EndOfFile.u.LowPart; - - FileNameU.Length = IData->pFileInfo->FileNameLength; - FileNameU.MaximumLength = FileNameU.Length + sizeof(WCHAR); - FileNameU.Buffer = IData->pFileInfo->FileName; - - FileName.Length = 0; - FileName.MaximumLength = MAX_PATH; - FileName.Buffer = lpFindFileData->cFileName; - - /* convert unicode string to ansi (or oem) */ - if (bIsFileApiAnsi) - RtlUnicodeStringToAnsiString (&FileName, - &FileNameU, - FALSE); - else - RtlUnicodeStringToOemString (&FileName, - &FileNameU, - FALSE); - - DPRINT("IData->pFileInfo->ShortNameLength %d\n", - IData->pFileInfo->ShortNameLength); - - FileNameU.Length = IData->pFileInfo->ShortNameLength; - FileNameU.MaximumLength = FileNameU.Length + sizeof(WCHAR); - FileNameU.Buffer = IData->pFileInfo->ShortName; - - FileName.Length = 0; - FileName.MaximumLength = 14; - FileName.Buffer = lpFindFileData->cAlternateFileName; - - /* convert unicode string to ansi (or oem) */ - if (bIsFileApiAnsi) - RtlUnicodeStringToAnsiString (&FileName, - &FileNameU, - FALSE); - else - RtlUnicodeStringToOemString (&FileName, - &FileNameU, - FALSE); - return TRUE; }
@@ -529,42 +501,15 @@ LPWIN32_FIND_DATAW lpFindFileData ) { - PKERNEL32_FIND_FILE_DATA IData;
- IData = InternalFindFirstFile (lpFileName); - if (IData == NULL) - { - DPRINT("Failing request\n"); - return INVALID_HANDLE_VALUE; - } - - /* copy data into WIN32_FIND_DATA structure */ - lpFindFileData->dwFileAttributes = IData->pFileInfo->FileAttributes; - - lpFindFileData->ftCreationTime.dwHighDateTime = IData->pFileInfo->CreationTime.u.HighPart; - lpFindFileData->ftCreationTime.dwLowDateTime = IData->pFileInfo->CreationTime.u.LowPart; - - lpFindFileData->ftLastAccessTime.dwHighDateTime = IData->pFileInfo->LastAccessTime.u.HighPart; - lpFindFileData->ftLastAccessTime.dwLowDateTime = IData->pFileInfo->LastAccessTime.u.LowPart; - - lpFindFileData->ftLastWriteTime.dwHighDateTime = IData->pFileInfo->LastWriteTime.u.HighPart; - lpFindFileData->ftLastWriteTime.dwLowDateTime = IData->pFileInfo->LastWriteTime.u.LowPart; - - lpFindFileData->nFileSizeHigh = IData->pFileInfo->EndOfFile.u.HighPart; - lpFindFileData->nFileSizeLow = IData->pFileInfo->EndOfFile.u.LowPart; - - memcpy (lpFindFileData->cFileName, - IData->pFileInfo->FileName, - IData->pFileInfo->FileNameLength); - lpFindFileData->cFileName[IData->pFileInfo->FileNameLength / sizeof(WCHAR)] = 0; - memcpy (lpFindFileData->cAlternateFileName, - IData->pFileInfo->ShortName, - IData->pFileInfo->ShortNameLength); - lpFindFileData->cAlternateFileName[IData->pFileInfo->ShortNameLength / sizeof(WCHAR)] = 0; - return IData; + return FindFirstFileExW (lpFileName, + FindExInfoStandard, + (LPVOID)lpFindFileData, + FindExSearchNameMatch, + NULL, + 0); }
- /* * @implemented */ @@ -585,38 +530,15 @@ }
IData = (PKERNEL32_FIND_FILE_DATA)hFindFile; - if (!InternalFindNextFile(hFindFile)) + if (!InternalFindNextFile(hFindFile, NULL)) { DPRINT("Failing request\n"); return FALSE; }
/* copy data into WIN32_FIND_DATA structure */ - lpFindFileData->dwFileAttributes = IData->pFileInfo->FileAttributes; + InternalCopyFindDataW(lpFindFileData, IData->pFileInfo);
- lpFindFileData->ftCreationTime.dwHighDateTime = IData->pFileInfo->CreationTime.u.HighPart; - lpFindFileData->ftCreationTime.dwLowDateTime = IData->pFileInfo->CreationTime.u.LowPart; - - lpFindFileData->ftLastAccessTime.dwHighDateTime = IData->pFileInfo->LastAccessTime.u.HighPart; - lpFindFileData->ftLastAccessTime.dwLowDateTime = IData->pFileInfo->LastAccessTime.u.LowPart; - - lpFindFileData->ftLastWriteTime.dwHighDateTime = IData->pFileInfo->LastWriteTime.u.HighPart; - lpFindFileData->ftLastWriteTime.dwLowDateTime = IData->pFileInfo->LastWriteTime.u.LowPart; - - lpFindFileData->nFileSizeHigh = IData->pFileInfo->EndOfFile.u.HighPart; - lpFindFileData->nFileSizeLow = IData->pFileInfo->EndOfFile.u.LowPart; - - lpFindFileData->nFileSizeHigh = IData->pFileInfo->EndOfFile.u.HighPart; - lpFindFileData->nFileSizeLow = IData->pFileInfo->EndOfFile.u.LowPart; - - memcpy (lpFindFileData->cFileName, - IData->pFileInfo->FileName, - IData->pFileInfo->FileNameLength); - lpFindFileData->cFileName[IData->pFileInfo->FileNameLength / sizeof(WCHAR)] = 0; - memcpy (lpFindFileData->cAlternateFileName, - IData->pFileInfo->ShortName, - IData->pFileInfo->ShortNameLength); - lpFindFileData->cAlternateFileName[IData->pFileInfo->ShortNameLength / sizeof(WCHAR)] = 0; return TRUE; }
@@ -626,20 +548,44 @@ */ HANDLE STDCALL -FindFirstFileExW ( - LPCWSTR lpFileName, - FINDEX_INFO_LEVELS fInfoLevelId, - LPVOID lpFindFileData, - FINDEX_SEARCH_OPS fSearchOp, - LPVOID lpSearchFilter, - DWORD dwAdditionalFlags - ) +FindFirstFileExW (LPCWSTR lpFileName, + FINDEX_INFO_LEVELS fInfoLevelId, + LPVOID lpFindFileData, + FINDEX_SEARCH_OPS fSearchOp, + LPVOID lpSearchFilter, + DWORD dwAdditionalFlags) { - /* FIXME */ - return (HANDLE) 0; -} + PKERNEL32_FIND_FILE_DATA IData;
+ if (fInfoLevelId != FindExInfoStandard) + { + SetLastError(ERROR_INVALID_PARAMETER); + return INVALID_HANDLE_VALUE; + } + if (fSearchOp == FindExSearchNameMatch || fSearchOp == FindExSearchLimitToDirectories) + { + if (lpSearchFilter) + { + SetLastError(ERROR_INVALID_PARAMETER); + return INVALID_HANDLE_VALUE; + }
+ IData = InternalFindFirstFile (lpFileName, fSearchOp == FindExSearchLimitToDirectories ? TRUE : FALSE); + if (IData == NULL) + { + DPRINT("Failing request\n"); + return INVALID_HANDLE_VALUE; + } + + /* copy data into WIN32_FIND_DATA structure */ + InternalCopyFindDataW((LPWIN32_FIND_DATAW)lpFindFileData, IData->pFileInfo); + + return (HANDLE)IData; + } + SetLastError(ERROR_INVALID_PARAMETER); + return INVALID_HANDLE_VALUE; +} + /* * @unimplemented */ @@ -654,8 +600,46 @@ DWORD dwAdditionalFlags ) { - /* FIXME */ - return (HANDLE) 0; + PKERNEL32_FIND_FILE_DATA IData; + UNICODE_STRING FileNameU; + ANSI_STRING FileNameA; + + if (fInfoLevelId != FindExInfoStandard) + { + SetLastError(ERROR_INVALID_PARAMETER); + return INVALID_HANDLE_VALUE; + } + if (fSearchOp == FindExSearchNameMatch || fSearchOp == FindExSearchLimitToDirectories) + { + if (lpSearchFilter) + { + SetLastError(ERROR_INVALID_PARAMETER); + return INVALID_HANDLE_VALUE; + } + + RtlInitAnsiString (&FileNameA, (LPSTR)lpFileName); + + /* convert ansi (or oem) string to unicode */ + if (bIsFileApiAnsi) + RtlAnsiStringToUnicodeString (&FileNameU, &FileNameA, TRUE); + else + RtlOemStringToUnicodeString (&FileNameU, &FileNameA, TRUE); + + IData = InternalFindFirstFile (FileNameU.Buffer, FALSE); + + RtlFreeUnicodeString (&FileNameU); + + if (IData == NULL) + { + DPRINT("Failing request\n"); + return INVALID_HANDLE_VALUE; + } + + /* copy data into WIN32_FIND_DATA structure */ + InternalCopyFindDataA(lpFindFileData, IData->pFileInfo); + } + SetLastError(ERROR_INVALID_PARAMETER); + return INVALID_HANDLE_VALUE; }