--- trunk/reactos/lib/kernel32/file/find.c 2005-07-20 03:50:50 UTC (rev 16659)
+++ trunk/reactos/lib/kernel32/file/find.c 2005-07-20 04:43:12 UTC (rev 16660)
@@ -4,9 +4,11 @@
* PROJECT: ReactOS system libraries
* FILE: lib/kernel32/file/find.c
* PURPOSE: Find functions
- * PROGRAMMER: Ariadne ( ariadne@xs4all.nl)
+ * PROGRAMMERS: Ariadne ( ariadne@xs4all.nl)
+ Dmitry Philippov ( shedon@mail.ru )
* UPDATE HISTORY:
* Created 01/11/98
+ * DP (18/06/2005) remove InternalFindFirstFile, implemented FindFirstFileExW
*/
/* INCLUDES *****************************************************************/
@@ -80,332 +82,9 @@
return TRUE;
}
-
/*
* @implemented
*/
-HANDLE
-STDCALL
-InternalFindFirstFile (
- LPCWSTR lpFileName
- )
-{
- OBJECT_ATTRIBUTES ObjectAttributes;
- PKERNEL32_FIND_FILE_DATA IData;
- IO_STATUS_BLOCK IoStatusBlock;
- UNICODE_STRING NtPathU;
- UNICODE_STRING PatternStr = RTL_CONSTANT_STRING(L"*");
- NTSTATUS Status;
- PWSTR e1, e2;
- WCHAR CurrentDir[256];
- PWCHAR SlashlessFileName;
- PWSTR SearchPath;
- PWCHAR SearchPattern;
- ULONG Length;
- BOOLEAN bResult;
-
- DPRINT("FindFirstFileW(lpFileName %S)\n",
- lpFileName);
-
- Length = wcslen(lpFileName);
- if (L'\\' == lpFileName[Length - 1])
- {
- SlashlessFileName = RtlAllocateHeap(hProcessHeap,
- 0,
- Length * sizeof(WCHAR));
- if (NULL == SlashlessFileName)
- {
- SetLastError(ERROR_NOT_ENOUGH_MEMORY);
- return NULL;
- }
- memcpy(SlashlessFileName, lpFileName, (Length - 1) * sizeof(WCHAR));
- SlashlessFileName[Length - 1] = L'\0';
- lpFileName = SlashlessFileName;
- }
- else
- {
- SlashlessFileName = NULL;
- }
-
- e1 = wcsrchr(lpFileName, L'/');
- e2 = wcsrchr(lpFileName, L'\\');
- SearchPattern = max(e1, e2);
- SearchPath = CurrentDir;
-
- if (NULL == SearchPattern)
- {
- CHECKPOINT;
- SearchPattern = (PWCHAR)lpFileName;
- Length = GetCurrentDirectoryW(sizeof(CurrentDir) / sizeof(WCHAR), SearchPath);
- if (0 == Length)
- {
- if (NULL != SlashlessFileName)
- {
- RtlFreeHeap(hProcessHeap,
- 0,
- SlashlessFileName);
- }
- return NULL;
- }
- if (Length > sizeof(CurrentDir) / sizeof(WCHAR))
- {
- SearchPath = RtlAllocateHeap(hProcessHeap,
- HEAP_ZERO_MEMORY,
- Length * sizeof(WCHAR));
- if (NULL == SearchPath)
- {
- if (NULL != SlashlessFileName)
- {
- RtlFreeHeap(hProcessHeap,
- 0,
- SlashlessFileName);
- }
- SetLastError(ERROR_NOT_ENOUGH_MEMORY);
- return NULL;
- }
- GetCurrentDirectoryW(Length, SearchPath);
- }
- }
- else
- {
- CHECKPOINT;
- SearchPattern++;
- Length = SearchPattern - lpFileName;
- if (Length + 1 > sizeof(CurrentDir) / sizeof(WCHAR))
- {
- SearchPath = RtlAllocateHeap(hProcessHeap,
- HEAP_ZERO_MEMORY,
- (Length + 1) * sizeof(WCHAR));
- if (NULL == SearchPath)
- {
- if (NULL != SlashlessFileName)
- {
- RtlFreeHeap(hProcessHeap,
- 0,
- SlashlessFileName);
- }
- SetLastError(ERROR_NOT_ENOUGH_MEMORY);
- return NULL;
- }
- }
- memcpy(SearchPath, lpFileName, Length * sizeof(WCHAR));
- SearchPath[Length] = 0;
- }
-
- bResult = RtlDosPathNameToNtPathName_U ((LPWSTR)SearchPath,
- &NtPathU,
- NULL,
- NULL);
- if (SearchPath != CurrentDir)
- {
- RtlFreeHeap(hProcessHeap,
- 0,
- SearchPath);
- }
- if (FALSE == bResult)
- {
- if (NULL != SlashlessFileName)
- {
- RtlFreeHeap(hProcessHeap,
- 0,
- SlashlessFileName);
- }
- return NULL;
- }
-
- DPRINT("NtPathU \'%S\'\n", NtPathU.Buffer);
-
- IData = RtlAllocateHeap (hProcessHeap,
- HEAP_ZERO_MEMORY,
- sizeof(KERNEL32_FIND_FILE_DATA) + FIND_DATA_SIZE);
- if (NULL == IData)
- {
- RtlFreeHeap (hProcessHeap,
- 0,
- NtPathU.Buffer);
- if (NULL != SlashlessFileName)
- {
- RtlFreeHeap(hProcessHeap,
- 0,
- SlashlessFileName);
- }
- SetLastError(ERROR_NOT_ENOUGH_MEMORY);
- return NULL;
- }
-
- /* change pattern: "*.*" --> "*" */
- if (wcscmp (SearchPattern, L"*.*"))
- {
- RtlInitUnicodeString(&PatternStr, SearchPattern);
- }
-
- DPRINT("NtPathU \'%S\' Pattern \'%S\'\n",
- NtPathU.Buffer, PatternStr.Buffer);
-
- InitializeObjectAttributes (&ObjectAttributes,
- &NtPathU,
- 0,
- NULL,
- NULL);
-
- Status = NtOpenFile (&IData->DirectoryHandle,
- FILE_LIST_DIRECTORY,
- &ObjectAttributes,
- &IoStatusBlock,
- FILE_SHARE_READ|FILE_SHARE_WRITE,
- FILE_DIRECTORY_FILE);
-
- RtlFreeHeap (hProcessHeap,
- 0,
- NtPathU.Buffer);
-
- if (!NT_SUCCESS(Status))
- {
- RtlFreeHeap (hProcessHeap, 0, IData);
- if (NULL != SlashlessFileName)
- {
- RtlFreeHeap(hProcessHeap,
- 0,
- SlashlessFileName);
- }
- SetLastErrorByStatus (Status);
- return(NULL);
- }
- 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,
- TRUE,
- &PatternStr,
- TRUE);
- 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);
-
- return IData;
-}
-
-
-/*
- * @implemented
- */
-HANDLE
-STDCALL
-FindFirstFileA (
- LPCSTR lpFileName,
- LPWIN32_FIND_DATAA lpFindFileData
- )
-{
- PKERNEL32_FIND_FILE_DATA IData;
- UNICODE_STRING FileNameU;
- ANSI_STRING FileName;
-
- RtlInitAnsiString (&FileName,
- (LPSTR)lpFileName);
-
- /* convert ansi (or oem) string to unicode */
- if (bIsFileApiAnsi)
- RtlAnsiStringToUnicodeString (&FileNameU,
- &FileName,
- TRUE);
- else
- RtlOemStringToUnicodeString (&FileNameU,
- &FileName,
- TRUE);
-
- IData = InternalFindFirstFile (FileNameU.Buffer);
-
- RtlFreeUnicodeString (&FileNameU);
-
- if (IData == NULL)
- {
- DPRINT("Failing request\n");
- return INVALID_HANDLE_VALUE;
- }
-
- DPRINT("IData->pFileInfo->FileNameLength %d\n",
- IData->pFileInfo->FileNameLength);
-
- /* 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;
-
- 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;
-}
-
-
-/*
- * @implemented
- */
BOOL
STDCALL
FindNextFileA (
@@ -518,53 +197,86 @@
return TRUE;
}
-
/*
* @implemented
*/
HANDLE
STDCALL
-FindFirstFileW (
- LPCWSTR lpFileName,
- LPWIN32_FIND_DATAW lpFindFileData
+FindFirstFileA (
+ LPCSTR lpFileName,
+ LPWIN32_FIND_DATAA lpFindFileData
)
{
PKERNEL32_FIND_FILE_DATA IData;
+ UNICODE_STRING FileNameU;
+ ANSI_STRING FileName;
+ WIN32_FIND_DATAW FindFileData;
- IData = InternalFindFirstFile (lpFileName);
- if (IData == NULL)
- {
- DPRINT("Failing request\n");
- return INVALID_HANDLE_VALUE;
- }
+ RtlInitAnsiString (&FileName,
+ (LPSTR)lpFileName);
- /* copy data into WIN32_FIND_DATA structure */
- lpFindFileData->dwFileAttributes = IData->pFileInfo->FileAttributes;
+ /* convert ansi (or oem) string to unicode */
+ if (bIsFileApiAnsi)
+ RtlAnsiStringToUnicodeString (&FileNameU,
+ &FileName,
+ TRUE);
+ else
+ RtlOemStringToUnicodeString (&FileNameU,
+ &FileName,
+ TRUE);
- lpFindFileData->ftCreationTime.dwHighDateTime = IData->pFileInfo->CreationTime.u.HighPart;
- lpFindFileData->ftCreationTime.dwLowDateTime = IData->pFileInfo->CreationTime.u.LowPart;
+ IData = FindFirstFileExW(FileNameU.Buffer,
+ FindExInfoStandard,
+ &FindFileData,
+ FindExSearchNameMatch,
+ NULL,
+ 0);
- lpFindFileData->ftLastAccessTime.dwHighDateTime = IData->pFileInfo->LastAccessTime.u.HighPart;
- lpFindFileData->ftLastAccessTime.dwLowDateTime = IData->pFileInfo->LastAccessTime.u.LowPart;
+ RtlFreeUnicodeString(&FileNameU);
- lpFindFileData->ftLastWriteTime.dwHighDateTime = IData->pFileInfo->LastWriteTime.u.HighPart;
- lpFindFileData->ftLastWriteTime.dwLowDateTime = IData->pFileInfo->LastWriteTime.u.LowPart;
+ if(INVALID_HANDLE_VALUE != IData)
+ {
+ RtlInitUnicodeString(&FileNameU, (PWSTR)FindFileData.cFileName);
+ FileName.Buffer = lpFindFileData->cFileName;
+ FileName.MaximumLength = MAX_PATH;
+ if (bIsFileApiAnsi) {
+ RtlUnicodeStringToAnsiString (&FileName,
+ &FileNameU,
+ FALSE);
+ }
+ else
+ {
+ RtlUnicodeStringToOemString (&FileName,
+ &FileNameU,
+ FALSE);
+ }
+ }
- 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 (HANDLE)IData;
}
+/*
+ * @implemented
+ */
+HANDLE
+STDCALL
+FindFirstFileW (
+ LPCWSTR lpFileName,
+ LPWIN32_FIND_DATAW lpFindFileData
+ )
+{
+ return FindFirstFileExW(
+ lpFileName,
+ FindExInfoStandard,
+ lpFindFileData,
+ FindExSearchNameMatch,
+ NULL,
+ 0
+ );
+}
+
/*
* @implemented
*/
@@ -609,7 +321,7 @@
lpFindFileData->nFileSizeHigh = IData->pFileInfo->EndOfFile.u.HighPart;
lpFindFileData->nFileSizeLow = IData->pFileInfo->EndOfFile.u.LowPart;
- memcpy (lpFindFileData->cFileName,
+ memcpy (lpFindFileData->cFileName,
IData->pFileInfo->FileName,
IData->pFileInfo->FileNameLength);
lpFindFileData->cFileName[IData->pFileInfo->FileNameLength / sizeof(WCHAR)] = 0;
@@ -622,40 +334,326 @@
/*
- * @unimplemented
+ * @implemented
*/
HANDLE
STDCALL
FindFirstFileExW (
- LPCWSTR lpFileName,
- FINDEX_INFO_LEVELS fInfoLevelId,
- LPVOID lpFindFileData,
- FINDEX_SEARCH_OPS fSearchOp,
- LPVOID lpSearchFilter,
- DWORD dwAdditionalFlags
+ 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;
+ IO_STATUS_BLOCK IoStatusBlock;
+ NTSTATUS Status;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ UNICODE_STRING DosFilePath;
+ UNICODE_STRING NtName;
+ UNICODE_STRING FileNameU;
+ UNICODE_STRING NtFilePath;
+ PWSTR e1, e2;
+ WCHAR CurrentDir[256];
+ PWCHAR SlashlessFileName;
+ PWSTR SearchPath;
+ PWCHAR SearchPattern;
+ ULONG Length;
+
+/*
+.....
+.....
+.....
+*/
+ DPRINT("FindFirstFileExW(%S, %p, %p, %X, %p %d)\n",
+ lpFileName,
+ fInfoLevelId,
+ lpFindFileData,
+ fSearchOp,
+ lpSearchFilter,
+ dwAdditionalFlags);
+
+ RtlInitUnicodeString(&FileNameU, lpFileName);
+
+ Length = wcslen(lpFileName);
+ if (L'\\' == lpFileName[Length - 1])
+ {
+ SlashlessFileName = RtlAllocateHeap(hProcessHeap, 0, Length * sizeof(WCHAR));
+ if (NULL == SlashlessFileName)
+ {
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ return (INVALID_HANDLE_VALUE);
+ }
+ memcpy(SlashlessFileName, lpFileName, (Length - 1) * sizeof(WCHAR));
+ SlashlessFileName[Length - 1] = L'\0';
+ lpFileName = SlashlessFileName;
+ }
+ else
+ {
+ SlashlessFileName = NULL;
+ }
+
+ e1 = wcsrchr(lpFileName, L'/');
+ e2 = wcsrchr(lpFileName, L'\\');
+ SearchPattern = max(e1, e2);
+ SearchPath = CurrentDir;
+
+ if (NULL == SearchPattern)
+ {
+ CHECKPOINT;
+ SearchPattern = (PWCHAR)lpFileName;
+ Length = GetCurrentDirectoryW(sizeof(CurrentDir) / sizeof(WCHAR), SearchPath);
+ if (0 == Length)
+ {
+ if (NULL != SlashlessFileName) {
+ RtlFreeHeap(hProcessHeap, 0, SlashlessFileName);
+ }
+ return (INVALID_HANDLE_VALUE);
+ }
+ if (Length > sizeof(CurrentDir) / sizeof(WCHAR))
+ {
+ SearchPath = RtlAllocateHeap(hProcessHeap, HEAP_ZERO_MEMORY, Length * sizeof(WCHAR));
+ if (NULL == SearchPath)
+ {
+ if (NULL != SlashlessFileName) {
+ RtlFreeHeap(hProcessHeap, 0, SlashlessFileName);
+ }
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ return (INVALID_HANDLE_VALUE);
+ }
+ GetCurrentDirectoryW(Length, SearchPath);
+ }
+ }
+ else
+ {
+ CHECKPOINT;
+ SearchPattern++;
+ Length = SearchPattern - lpFileName;
+ if (Length + 1 > sizeof(CurrentDir) / sizeof(WCHAR))
+ {
+ SearchPath = RtlAllocateHeap(hProcessHeap, HEAP_ZERO_MEMORY, (Length + 1) * sizeof(WCHAR));
+ if (NULL == SearchPath) {
+ if (NULL != SlashlessFileName) {
+ RtlFreeHeap(hProcessHeap, 0, SlashlessFileName);
+ }
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ return (INVALID_HANDLE_VALUE);
+ }
+ }
+ memcpy(SearchPath, lpFileName, Length * sizeof(WCHAR));
+ SearchPath[Length] = 0;
+ }
+
+ if( FALSE == RtlDosPathNameToNtPathName_U(
+ (PWSTR)SearchPath,
+ &NtName,
+ &DosFilePath.Buffer,
+ (PCURDIR)&NtFilePath
+ ) )
+ {
+ RtlFreeHeap(hProcessHeap, 0, SearchPath);
+ if (NULL != SlashlessFileName) {
+ RtlFreeHeap(hProcessHeap, 0, SlashlessFileName);
+ }
+ SetLastError(ERROR_PATH_NOT_FOUND);
+ return (INVALID_HANDLE_VALUE);
+ }
+
+
+ if (SearchPath != CurrentDir) {
+ RtlFreeHeap(hProcessHeap, 0, SearchPath);
+ }
+
+ DPRINT("NtName \'%S\'\n", NtName.Buffer);
+
+ IData = RtlAllocateHeap (hProcessHeap,
+ HEAP_ZERO_MEMORY,
+ sizeof(KERNEL32_FIND_FILE_DATA) + FIND_DATA_SIZE);
+ if (NULL == IData)
+ {
+ RtlFreeHeap (hProcessHeap, 0, NtName.Buffer);
+ if (NULL != SlashlessFileName) {
+ RtlFreeHeap(hProcessHeap, 0, SlashlessFileName);
+ }
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ return (INVALID_HANDLE_VALUE);
+ }
+
+ /* change pattern: "*.*" --> "*" */
+ if (!wcscmp (SearchPattern, L"*.*")) {
+ RtlInitUnicodeString(&DosFilePath, L"*");
+ } else {
+ RtlInitUnicodeString(&DosFilePath, SearchPattern);
+ }
+
+ DPRINT("NtName \'%S\' DosFilePath \'%S\'\n",
+ NtName.Buffer, DosFilePath.Buffer);
+
+ InitializeObjectAttributes( &ObjectAttributes,
+ &NtName,
+ dwAdditionalFlags,
+ NtFilePath.Buffer,
+ NULL );
+
+ Status =
+ NtOpenFile(
+ &IData->DirectoryHandle,
+ SYNCHRONIZE | FILE_LIST_DIRECTORY,
+ &ObjectAttributes,
+ &IoStatusBlock,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ FILE_DIRECTORY_FILE | FILE_OPEN_FOR_BACKUP_INTENT | FILE_SYNCHRONOUS_IO_NONALERT
+ );
+
+ if( !NT_SUCCESS(Status) )
+ {
+ DPRINT1("NtOpenFile() - failed (Status %lx)\n", Status);
+ SetLastError( Status );
+ return (INVALID_HANDLE_VALUE);
+ }
+
+ RtlFreeHeap(hProcessHeap, 0, NtName.Buffer);
+
+ if (!NT_SUCCESS(Status))
+ {
+ RtlFreeHeap (hProcessHeap, 0, IData);
+ if (NULL != SlashlessFileName) {
+ RtlFreeHeap(hProcessHeap, 0, SlashlessFileName);
+ }
+ SetLastErrorByStatus (Status);
+ return (INVALID_HANDLE_VALUE);
+ }
+
+ if ( 0 == DosFilePath.Length ) {
+ DPRINT1("0 == DosFilePath.Length\n");
+ NtClose(IData->DirectoryHandle);
+ SetLastError(ERROR_FILE_NOT_FOUND);
+ return INVALID_HANDLE_VALUE;
+ }
+
+ 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,
+ TRUE,
+ &DosFilePath,
+ FALSE
+ );
+
+ if (NULL != SlashlessFileName) {
+ RtlFreeHeap(hProcessHeap, 0, SlashlessFileName);
+ }
+
+ if( !NT_SUCCESS(Status) ) {
+ DPRINT1("NtQueryDirectoryFile() - failed (Status %lx)\n", Status);
+ RtlFreeHeap(hProcessHeap, 0, IData);
+ NtClose(IData->DirectoryHandle);
+ SetLastError(Status);
+ return (INVALID_HANDLE_VALUE);
+ }
+
+ DPRINT("Found %.*S\n",IData->pFileInfo->FileNameLength/sizeof(WCHAR), IData->pFileInfo->FileName);
+
+ /* copy data into WIN32_FIND_DATA structure */
+ ((LPWIN32_FIND_DATAW)lpFindFileData)->dwFileAttributes = IData->pFileInfo->FileAttributes;
+
+ ((LPWIN32_FIND_DATAW)lpFindFileData)->ftCreationTime.dwHighDateTime = IData->pFileInfo->CreationTime.u.HighPart;
+ ((LPWIN32_FIND_DATAW)lpFindFileData)->ftCreationTime.dwLowDateTime = IData->pFileInfo->CreationTime.u.LowPart;
+
+ ((LPWIN32_FIND_DATAW)lpFindFileData)->ftLastAccessTime.dwHighDateTime = IData->pFileInfo->LastAccessTime.u.HighPart;
+ ((LPWIN32_FIND_DATAW)lpFindFileData)->ftLastAccessTime.dwLowDateTime = IData->pFileInfo->LastAccessTime.u.LowPart;
+
+ ((LPWIN32_FIND_DATAW)lpFindFileData)->ftLastWriteTime.dwHighDateTime = IData->pFileInfo->LastWriteTime.u.HighPart;
+ ((LPWIN32_FIND_DATAW)lpFindFileData)->ftLastWriteTime.dwLowDateTime = IData->pFileInfo->LastWriteTime.u.LowPart;
+
+ ((LPWIN32_FIND_DATAW)lpFindFileData)->nFileSizeHigh = IData->pFileInfo->EndOfFile.u.HighPart;
+ ((LPWIN32_FIND_DATAW)lpFindFileData)->nFileSizeLow = IData->pFileInfo->EndOfFile.u.LowPart;
+
+ memcpy (((LPWIN32_FIND_DATAW)lpFindFileData)->cFileName,
+ IData->pFileInfo->FileName,
+ IData->pFileInfo->FileNameLength);
+ ((LPWIN32_FIND_DATAW)lpFindFileData)->cFileName[IData->pFileInfo->FileNameLength / sizeof(WCHAR)] = 0;
+ memcpy (((LPWIN32_FIND_DATAW)lpFindFileData)->cAlternateFileName,
+ IData->pFileInfo->ShortName,
+ IData->pFileInfo->ShortNameLength);
+ ((LPWIN32_FIND_DATAW)lpFindFileData)->cAlternateFileName[IData->pFileInfo->ShortNameLength / sizeof(WCHAR)] = 0;
+
+
+ return (HANDLE)IData;
}
/*
- * @unimplemented
+ * @implemented
*/
HANDLE
STDCALL
FindFirstFileExA (
- LPCSTR lpFileName,
- FINDEX_INFO_LEVELS fInfoLevelId,
- LPVOID lpFindFileData,
- FINDEX_SEARCH_OPS fSearchOp,
- LPVOID lpSearchFilter,
- DWORD dwAdditionalFlags
+ LPCSTR lpFileName,
+ FINDEX_INFO_LEVELS fInfoLevelId,
+ LPVOID lpFindFileData,
+ FINDEX_SEARCH_OPS fSearchOp,
+ LPVOID lpSearchFilter,
+ DWORD dwAdditionalFlags
)
{
- /* FIXME */
- return (HANDLE) 0;
+ PKERNEL32_FIND_FILE_DATA IData;
+ UNICODE_STRING FileNameU;
+ ANSI_STRING FileNameA;
+
+ RtlInitAnsiString (&FileNameA,
+ (LPSTR)lpFileName);
+
+ /* convert ansi (or oem) string to unicode */
+ if (bIsFileApiAnsi)
+ RtlAnsiStringToUnicodeString (&FileNameU,
+ &FileNameA,
+ TRUE);
+ else
+ RtlOemStringToUnicodeString (&FileNameU,
+ &FileNameA,
+ TRUE);
+
+ IData = FindFirstFileExW(
+ (LPCWSTR)FileNameU.Buffer,
+ fInfoLevelId,
+ lpFindFileData,
+ fSearchOp,
+ lpSearchFilter,
+ dwAdditionalFlags
+ );
+
+ RtlFreeUnicodeString(&FileNameU);
+
+ if(INVALID_HANDLE_VALUE != IData)
+ {
+ RtlInitUnicodeString(&FileNameU, (PWSTR)((LPWIN32_FIND_DATAW)lpFindFileData)->cFileName);
+ FileNameU.Buffer = ((LPWIN32_FIND_DATAW)lpFindFileData)->cFileName;
+ FileNameU.MaximumLength = MAX_PATH;
+
+ /* convert unicode string to ansi (or oem) */
+ if (bIsFileApiAnsi)
+ RtlUnicodeStringToAnsiString (&FileNameA,
+ &FileNameU,
+ FALSE);
+ else
+ RtlUnicodeStringToOemString (&FileNameA,
+ &FileNameU,
+ FALSE);
+ }
+
+ return (HANDLE)IData;
}