Reimplemented FindFirstFileEx and removed some overhead.

svn path=/trunk/; revision=17291
This commit is contained in:
Hartmut Birr 2005-08-11 19:02:31 +00:00
parent 9bfc144257
commit 77b9c0a70d

View file

@ -28,12 +28,89 @@
typedef struct _KERNEL32_FIND_FILE_DATA typedef struct _KERNEL32_FIND_FILE_DATA
{ {
HANDLE DirectoryHandle; HANDLE DirectoryHandle;
BOOLEAN DirectoryOnly;
PFILE_BOTH_DIR_INFORMATION pFileInfo; PFILE_BOTH_DIR_INFORMATION pFileInfo;
} KERNEL32_FIND_FILE_DATA, *PKERNEL32_FIND_FILE_DATA; } KERNEL32_FIND_FILE_DATA, *PKERNEL32_FIND_FILE_DATA;
/* FUNCTIONS ****************************************************************/ /* 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 * @implemented
@ -41,7 +118,8 @@ typedef struct _KERNEL32_FIND_FILE_DATA
BOOL BOOL
STDCALL STDCALL
InternalFindNextFile ( InternalFindNextFile (
HANDLE hFindFile HANDLE hFindFile,
PUNICODE_STRING SearchPattern
) )
{ {
PKERNEL32_FIND_FILE_DATA IData; PKERNEL32_FIND_FILE_DATA IData;
@ -52,32 +130,40 @@ InternalFindNextFile (
IData = (PKERNEL32_FIND_FILE_DATA)hFindFile; IData = (PKERNEL32_FIND_FILE_DATA)hFindFile;
if (IData->pFileInfo->NextEntryOffset != 0) while (1)
{ {
IData->pFileInfo = (PVOID)((ULONG_PTR)IData->pFileInfo + IData->pFileInfo->NextEntryOffset); if (IData->pFileInfo->NextEntryOffset != 0)
DPRINT("Found %.*S\n",IData->pFileInfo->FileNameLength/sizeof(WCHAR), IData->pFileInfo->FileName); {
return TRUE; IData->pFileInfo = (PVOID)((ULONG_PTR)IData->pFileInfo + IData->pFileInfo->NextEntryOffset);
} }
IData->pFileInfo = (PVOID)((ULONG_PTR)IData + sizeof(KERNEL32_FIND_FILE_DATA)); else
IData->pFileInfo->FileIndex = 0; {
Status = NtQueryDirectoryFile (IData->DirectoryHandle, IData->pFileInfo = (PVOID)((ULONG_PTR)IData + sizeof(KERNEL32_FIND_FILE_DATA));
NULL, IData->pFileInfo->FileIndex = 0;
NULL, Status = NtQueryDirectoryFile (IData->DirectoryHandle,
NULL, NULL,
&IoStatusBlock, NULL,
(PVOID)IData->pFileInfo, NULL,
FIND_DATA_SIZE, &IoStatusBlock,
FileBothDirectoryInformation, (PVOID)IData->pFileInfo,
FALSE, FIND_DATA_SIZE,
NULL, FileBothDirectoryInformation,
FALSE); SearchPattern ? TRUE : FALSE,
if (!NT_SUCCESS(Status)) SearchPattern,
{ SearchPattern ? TRUE : FALSE);
SetLastErrorByStatus (Status); SearchPattern = NULL;
return FALSE; if (!NT_SUCCESS(Status))
} {
DPRINT("Found %.*S\n",IData->pFileInfo->FileNameLength/sizeof(WCHAR), IData->pFileInfo->FileName); SetLastErrorByStatus (Status);
return TRUE; 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 @@ InternalFindNextFile (
HANDLE HANDLE
STDCALL STDCALL
InternalFindFirstFile ( InternalFindFirstFile (
LPCWSTR lpFileName LPCWSTR lpFileName,
BOOLEAN DirectoryOnly
) )
{ {
OBJECT_ATTRIBUTES ObjectAttributes; OBJECT_ATTRIBUTES ObjectAttributes;
@ -273,33 +360,21 @@ InternalFindFirstFile (
} }
IData->pFileInfo = (PVOID)((ULONG_PTR)IData + sizeof(KERNEL32_FIND_FILE_DATA)); IData->pFileInfo = (PVOID)((ULONG_PTR)IData + sizeof(KERNEL32_FIND_FILE_DATA));
IData->pFileInfo->FileIndex = 0; IData->pFileInfo->FileIndex = 0;
IData->DirectoryOnly = DirectoryOnly;
Status = NtQueryDirectoryFile (IData->DirectoryHandle, bResult = InternalFindNextFile((HANDLE)IData, &PatternStr);
NULL,
NULL,
NULL,
&IoStatusBlock,
(PVOID)IData->pFileInfo,
FIND_DATA_SIZE,
FileBothDirectoryInformation,
TRUE,
&PatternStr,
TRUE);
if (NULL != SlashlessFileName) if (NULL != SlashlessFileName)
{ {
RtlFreeHeap(hProcessHeap, RtlFreeHeap(hProcessHeap,
0, 0,
SlashlessFileName); SlashlessFileName);
} }
if (!NT_SUCCESS(Status))
{ if (!bResult)
DPRINT("Status %lx\n", Status); {
CloseHandle (IData->DirectoryHandle); FindClose((HANDLE)IData);
RtlFreeHeap (hProcessHeap, 0, IData); return NULL;
SetLastErrorByStatus (Status); }
return NULL;
}
DPRINT("Found %.*S\n",IData->pFileInfo->FileNameLength/sizeof(WCHAR), IData->pFileInfo->FileName);
return IData; return IData;
} }
@ -332,7 +407,7 @@ FindFirstFileA (
&FileName, &FileName,
TRUE); TRUE);
IData = InternalFindFirstFile (FileNameU.Buffer); IData = InternalFindFirstFile (FileNameU.Buffer, FALSE);
RtlFreeUnicodeString (&FileNameU); RtlFreeUnicodeString (&FileNameU);
@ -346,58 +421,8 @@ FindFirstFileA (
IData->pFileInfo->FileNameLength); IData->pFileInfo->FileNameLength);
/* copy data into WIN32_FIND_DATA structure */ /* 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; return (HANDLE)IData;
} }
@ -413,8 +438,6 @@ FindNextFileA (
LPWIN32_FIND_DATAA lpFindFileData) LPWIN32_FIND_DATAA lpFindFileData)
{ {
PKERNEL32_FIND_FILE_DATA IData; PKERNEL32_FIND_FILE_DATA IData;
UNICODE_STRING FileNameU;
ANSI_STRING FileName;
if (hFindFile == INVALID_HANDLE_VALUE) if (hFindFile == INVALID_HANDLE_VALUE)
{ {
@ -424,7 +447,7 @@ FindNextFileA (
} }
IData = (PKERNEL32_FIND_FILE_DATA)hFindFile; IData = (PKERNEL32_FIND_FILE_DATA)hFindFile;
if (!InternalFindNextFile (hFindFile)) if (!InternalFindNextFile (hFindFile, NULL))
{ {
DPRINT("InternalFindNextFile() failed\n"); DPRINT("InternalFindNextFile() failed\n");
return FALSE; return FALSE;
@ -434,58 +457,7 @@ FindNextFileA (
IData->pFileInfo->FileNameLength); IData->pFileInfo->FileNameLength);
/* copy data into WIN32_FIND_DATA structure */ /* 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; return TRUE;
} }
@ -529,42 +501,15 @@ FindFirstFileW (
LPWIN32_FIND_DATAW lpFindFileData LPWIN32_FIND_DATAW lpFindFileData
) )
{ {
PKERNEL32_FIND_FILE_DATA IData;
IData = InternalFindFirstFile (lpFileName); return FindFirstFileExW (lpFileName,
if (IData == NULL) FindExInfoStandard,
{ (LPVOID)lpFindFileData,
DPRINT("Failing request\n"); FindExSearchNameMatch,
return INVALID_HANDLE_VALUE; NULL,
} 0);
/* 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;
} }
/* /*
* @implemented * @implemented
*/ */
@ -585,38 +530,15 @@ FindNextFileW (
} }
IData = (PKERNEL32_FIND_FILE_DATA)hFindFile; IData = (PKERNEL32_FIND_FILE_DATA)hFindFile;
if (!InternalFindNextFile(hFindFile)) if (!InternalFindNextFile(hFindFile, NULL))
{ {
DPRINT("Failing request\n"); DPRINT("Failing request\n");
return FALSE; return FALSE;
} }
/* copy data into WIN32_FIND_DATA structure */ /* 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; return TRUE;
} }
@ -626,19 +548,43 @@ FindNextFileW (
*/ */
HANDLE HANDLE
STDCALL STDCALL
FindFirstFileExW ( FindFirstFileExW (LPCWSTR lpFileName,
LPCWSTR lpFileName, FINDEX_INFO_LEVELS fInfoLevelId,
FINDEX_INFO_LEVELS fInfoLevelId, LPVOID lpFindFileData,
LPVOID lpFindFileData, FINDEX_SEARCH_OPS fSearchOp,
FINDEX_SEARCH_OPS fSearchOp, LPVOID lpSearchFilter,
LPVOID lpSearchFilter, DWORD dwAdditionalFlags)
DWORD dwAdditionalFlags
)
{ {
/* FIXME */ PKERNEL32_FIND_FILE_DATA IData;
return (HANDLE) 0;
}
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 * @unimplemented
@ -654,8 +600,46 @@ FindFirstFileExA (
DWORD dwAdditionalFlags DWORD dwAdditionalFlags
) )
{ {
/* FIXME */ PKERNEL32_FIND_FILE_DATA IData;
return (HANDLE) 0; 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;
} }