3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS system libraries
5 * FILE: lib/kernel32/file/find.c
6 * PURPOSE: Find functions
7 * PROGRAMMER: Ariadne ( ariadne@xs4all.nl)
12 /* INCLUDES *****************************************************************/
17 #include <kernel32/kernel32.h>
20 /* TYPES ********************************************************************/
23 #define offsetof(TYPE, MEMBER) ((size_t) &( ((TYPE *) 0)->MEMBER ))
26 #define FIND_DATA_SIZE (16*1024)
28 typedef struct _KERNEL32_FIND_FILE_DATA
30 HANDLE DirectoryHandle;
31 PFILE_BOTH_DIRECTORY_INFORMATION pFileInfo;
32 } KERNEL32_FIND_FILE_DATA, *PKERNEL32_FIND_FILE_DATA;
35 /* FUNCTIONS ****************************************************************/
43 InternalFindNextFile (
47 PKERNEL32_FIND_FILE_DATA IData;
48 IO_STATUS_BLOCK IoStatusBlock;
51 IData = (PKERNEL32_FIND_FILE_DATA)hFindFile;
53 if (IData->pFileInfo->NextEntryOffset != 0)
55 IData->pFileInfo = (PVOID)IData->pFileInfo + IData->pFileInfo->NextEntryOffset;
56 DPRINT("Found %.*S\n",IData->pFileInfo->FileNameLength, IData->pFileInfo->FileName);
59 IData->pFileInfo = (PVOID)IData + sizeof(KERNEL32_FIND_FILE_DATA);
60 IData->pFileInfo->FileIndex = 0;
61 Status = NtQueryDirectoryFile (IData->DirectoryHandle,
66 (PVOID)IData->pFileInfo,
68 FileBothDirectoryInformation,
72 if (!NT_SUCCESS(Status))
74 SetLastErrorByStatus (Status);
77 DPRINT("Found %.*S\n",IData->pFileInfo->FileNameLength, IData->pFileInfo->FileName);
87 InternalFindFirstFile (
91 OBJECT_ATTRIBUTES ObjectAttributes;
92 PKERNEL32_FIND_FILE_DATA IData;
93 IO_STATUS_BLOCK IoStatusBlock;
94 UNICODE_STRING NtPathU;
95 UNICODE_STRING PatternStr;
98 WCHAR CurrentDir[256];
100 PWCHAR SearchPattern;
104 DPRINT("FindFirstFileW(lpFileName %S)\n",
107 e1 = wcsrchr(lpFileName, L'/');
108 e2 = wcsrchr(lpFileName, L'\\');
109 SearchPattern = max(e1, e2);
110 SearchPath = CurrentDir;
112 if (NULL == SearchPattern)
115 SearchPattern = (PWCHAR)lpFileName;
116 Length = GetCurrentDirectoryW(sizeof(CurrentDir) / sizeof(WCHAR), SearchPath);
121 if (Length > sizeof(CurrentDir) / sizeof(WCHAR))
123 SearchPath = RtlAllocateHeap(hProcessHeap,
125 Length * sizeof(WCHAR));
126 if (NULL == SearchPath)
128 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
131 GetCurrentDirectoryW(Length, SearchPath);
138 Length = SearchPattern - lpFileName;
139 if (Length + 1 > sizeof(CurrentDir) / sizeof(WCHAR))
141 SearchPath = RtlAllocateHeap(hProcessHeap,
143 (Length + 1) * sizeof(WCHAR));
144 if (NULL == SearchPath)
146 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
150 memcpy(SearchPath, lpFileName, Length * sizeof(WCHAR));
151 SearchPath[Length] = 0;
154 bResult = RtlDosPathNameToNtPathName_U ((LPWSTR)SearchPath,
158 if (SearchPath != CurrentDir)
160 RtlFreeHeap(hProcessHeap,
164 if (FALSE == bResult)
169 DPRINT("NtPathU \'%S\'\n", NtPathU.Buffer);
171 IData = RtlAllocateHeap (hProcessHeap,
173 sizeof(KERNEL32_FIND_FILE_DATA) + FIND_DATA_SIZE);
176 RtlFreeHeap (hProcessHeap,
179 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
183 /* change pattern: "*.*" --> "*" */
184 if (!wcscmp (SearchPattern, L"*.*"))
186 RtlInitUnicodeStringFromLiteral(&PatternStr, L"*");
190 RtlInitUnicodeString(&PatternStr, SearchPattern);
193 DPRINT("NtPathU \'%S\' Pattern \'%S\'\n",
194 NtPathU.Buffer, PatternStr.Buffer);
196 InitializeObjectAttributes (&ObjectAttributes,
202 Status = NtOpenFile (&IData->DirectoryHandle,
209 RtlFreeHeap (hProcessHeap,
213 if (!NT_SUCCESS(Status))
215 RtlFreeHeap (hProcessHeap, 0, IData);
216 SetLastErrorByStatus (Status);
219 IData->pFileInfo = (PVOID)IData + sizeof(KERNEL32_FIND_FILE_DATA);
220 IData->pFileInfo->FileIndex = 0;
222 Status = NtQueryDirectoryFile (IData->DirectoryHandle,
227 (PVOID)IData->pFileInfo,
229 FileBothDirectoryInformation,
233 if (!NT_SUCCESS(Status))
235 DPRINT("Status %lx\n", Status);
236 RtlFreeHeap (hProcessHeap, 0, IData);
237 SetLastErrorByStatus (Status);
240 DPRINT("Found %.*S\n",IData->pFileInfo->FileNameLength, IData->pFileInfo->FileName);
253 LPWIN32_FIND_DATAA lpFindFileData
256 PKERNEL32_FIND_FILE_DATA IData;
257 UNICODE_STRING FileNameU;
258 ANSI_STRING FileName;
260 RtlInitAnsiString (&FileName,
263 /* convert ansi (or oem) string to unicode */
265 RtlAnsiStringToUnicodeString (&FileNameU,
269 RtlOemStringToUnicodeString (&FileNameU,
273 IData = InternalFindFirstFile (FileNameU.Buffer);
275 RtlFreeUnicodeString (&FileNameU);
279 DPRINT("Failing request\n");
280 return INVALID_HANDLE_VALUE;
283 DPRINT("IData->pFileInfo->FileNameLength %d\n",
284 IData->pFileInfo->FileNameLength);
286 /* copy data into WIN32_FIND_DATA structure */
287 lpFindFileData->dwFileAttributes = IData->pFileInfo->FileAttributes;
288 memcpy (&lpFindFileData->ftCreationTime,
289 &IData->pFileInfo->CreationTime,
291 memcpy (&lpFindFileData->ftLastAccessTime,
292 &IData->pFileInfo->LastAccessTime,
294 memcpy (&lpFindFileData->ftLastWriteTime,
295 &IData->pFileInfo->LastWriteTime,
297 lpFindFileData->nFileSizeHigh = IData->pFileInfo->EndOfFile.u.HighPart;
298 lpFindFileData->nFileSizeLow = IData->pFileInfo->EndOfFile.u.LowPart;
300 FileNameU.Length = IData->pFileInfo->FileNameLength;
301 FileNameU.MaximumLength = FileNameU.Length + sizeof(WCHAR);
302 FileNameU.Buffer = IData->pFileInfo->FileName;
305 FileName.MaximumLength = MAX_PATH;
306 FileName.Buffer = lpFindFileData->cFileName;
308 /* convert unicode string to ansi (or oem) */
310 RtlUnicodeStringToAnsiString (&FileName,
314 RtlUnicodeStringToOemString (&FileName,
318 DPRINT("IData->pFileInfo->ShortNameLength %d\n",
319 IData->pFileInfo->ShortNameLength);
321 FileNameU.Length = IData->pFileInfo->ShortNameLength;
322 FileNameU.MaximumLength = FileNameU.Length + sizeof(WCHAR);
323 FileNameU.Buffer = IData->pFileInfo->ShortName;
326 FileName.MaximumLength = 14;
327 FileName.Buffer = lpFindFileData->cAlternateFileName;
329 /* convert unicode string to ansi (or oem) */
331 RtlUnicodeStringToAnsiString (&FileName,
335 RtlUnicodeStringToOemString (&FileName,
339 return (HANDLE)IData;
350 LPWIN32_FIND_DATAA lpFindFileData)
352 PKERNEL32_FIND_FILE_DATA IData;
353 UNICODE_STRING FileNameU;
354 ANSI_STRING FileName;
356 IData = (PKERNEL32_FIND_FILE_DATA)hFindFile;
362 if (!InternalFindNextFile (hFindFile))
364 DPRINT("InternalFindNextFile() failed\n");
368 DPRINT("IData->pFileInfo->FileNameLength %d\n",
369 IData->pFileInfo->FileNameLength);
371 /* copy data into WIN32_FIND_DATA structure */
372 lpFindFileData->dwFileAttributes = IData->pFileInfo->FileAttributes;
373 memcpy (&lpFindFileData->ftCreationTime,
374 &IData->pFileInfo->CreationTime,
376 memcpy (&lpFindFileData->ftLastAccessTime,
377 &IData->pFileInfo->LastAccessTime,
379 memcpy (&lpFindFileData->ftLastWriteTime,
380 &IData->pFileInfo->LastWriteTime,
382 lpFindFileData->nFileSizeHigh = IData->pFileInfo->EndOfFile.u.HighPart;
383 lpFindFileData->nFileSizeLow = IData->pFileInfo->EndOfFile.u.LowPart;
385 FileNameU.Length = IData->pFileInfo->FileNameLength;
386 FileNameU.MaximumLength = FileNameU.Length + sizeof(WCHAR);
387 FileNameU.Buffer = IData->pFileInfo->FileName;
390 FileName.MaximumLength = MAX_PATH;
391 FileName.Buffer = lpFindFileData->cFileName;
393 /* convert unicode string to ansi (or oem) */
395 RtlUnicodeStringToAnsiString (&FileName,
399 RtlUnicodeStringToOemString (&FileName,
403 DPRINT("IData->pFileInfo->ShortNameLength %d\n",
404 IData->pFileInfo->ShortNameLength);
406 FileNameU.Length = IData->pFileInfo->ShortNameLength;
407 FileNameU.MaximumLength = FileNameU.Length + sizeof(WCHAR);
408 FileNameU.Buffer = IData->pFileInfo->ShortName;
411 FileName.MaximumLength = 14;
412 FileName.Buffer = lpFindFileData->cAlternateFileName;
414 /* convert unicode string to ansi (or oem) */
416 RtlUnicodeStringToAnsiString (&FileName,
420 RtlUnicodeStringToOemString (&FileName,
437 PKERNEL32_FIND_FILE_DATA IData;
439 DPRINT("FindClose(hFindFile %x)\n",hFindFile);
441 if (!hFindFile || hFindFile == INVALID_HANDLE_VALUE)
443 SetLastError (ERROR_INVALID_HANDLE);
447 IData = (PKERNEL32_FIND_FILE_DATA)hFindFile;
449 CloseHandle (IData->DirectoryHandle);
450 RtlFreeHeap (hProcessHeap, 0, IData);
463 LPWIN32_FIND_DATAW lpFindFileData
466 PKERNEL32_FIND_FILE_DATA IData;
468 IData = InternalFindFirstFile (lpFileName);
471 DPRINT("Failing request\n");
472 return INVALID_HANDLE_VALUE;
475 /* copy data into WIN32_FIND_DATA structure */
476 lpFindFileData->dwFileAttributes = IData->pFileInfo->FileAttributes;
477 memcpy (&lpFindFileData->ftCreationTime,
478 &IData->pFileInfo->CreationTime,
480 memcpy (&lpFindFileData->ftLastAccessTime,
481 &IData->pFileInfo->LastAccessTime,
483 memcpy (&lpFindFileData->ftLastWriteTime,
484 &IData->pFileInfo->LastWriteTime,
486 lpFindFileData->nFileSizeHigh = IData->pFileInfo->EndOfFile.u.HighPart;
487 lpFindFileData->nFileSizeLow = IData->pFileInfo->EndOfFile.u.LowPart;
488 memcpy (lpFindFileData->cFileName,
489 IData->pFileInfo->FileName,
490 IData->pFileInfo->FileNameLength);
491 lpFindFileData->cFileName[IData->pFileInfo->FileNameLength / sizeof(WCHAR)] = 0;
492 memcpy (lpFindFileData->cAlternateFileName,
493 IData->pFileInfo->ShortName,
494 IData->pFileInfo->ShortNameLength);
495 lpFindFileData->cAlternateFileName[IData->pFileInfo->ShortNameLength / sizeof(WCHAR)] = 0;
507 LPWIN32_FIND_DATAW lpFindFileData
510 PKERNEL32_FIND_FILE_DATA IData;
512 IData = (PKERNEL32_FIND_FILE_DATA)hFindFile;
513 if (!InternalFindNextFile(hFindFile))
515 DPRINT("Failing request\n");
519 /* copy data into WIN32_FIND_DATA structure */
520 lpFindFileData->dwFileAttributes = IData->pFileInfo->FileAttributes;
521 memcpy (&lpFindFileData->ftCreationTime,
522 &IData->pFileInfo->CreationTime,
524 memcpy (&lpFindFileData->ftLastAccessTime,
525 &IData->pFileInfo->LastAccessTime,
527 memcpy (&lpFindFileData->ftLastWriteTime,
528 &IData->pFileInfo->LastWriteTime,
530 lpFindFileData->nFileSizeHigh = IData->pFileInfo->EndOfFile.u.HighPart;
531 lpFindFileData->nFileSizeLow = IData->pFileInfo->EndOfFile.u.LowPart;
532 memcpy (lpFindFileData->cFileName,
533 IData->pFileInfo->FileName,
534 IData->pFileInfo->FileNameLength);
535 lpFindFileData->cFileName[IData->pFileInfo->FileNameLength / sizeof(WCHAR)] = 0;
536 memcpy (lpFindFileData->cAlternateFileName,
537 IData->pFileInfo->ShortName,
538 IData->pFileInfo->ShortNameLength);
539 lpFindFileData->cAlternateFileName[IData->pFileInfo->ShortNameLength / sizeof(WCHAR)] = 0;
551 FINDEX_INFO_LEVELS fInfoLevelId,
552 LPVOID lpFindFileData,
553 FINDEX_SEARCH_OPS fSearchOp,
554 LPVOID lpSearchFilter,
555 DWORD dwAdditionalFlags
570 FINDEX_INFO_LEVELS fInfoLevelId,
571 LPVOID lpFindFileData,
572 FINDEX_SEARCH_OPS fSearchOp,
573 LPVOID lpSearchFilter,
574 DWORD dwAdditionalFlags