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 ****************************************************************/
40 InternalFindNextFile (
44 PKERNEL32_FIND_FILE_DATA IData;
45 IO_STATUS_BLOCK IoStatusBlock;
48 IData = (PKERNEL32_FIND_FILE_DATA)hFindFile;
50 if (IData->pFileInfo->NextEntryOffset != 0)
52 IData->pFileInfo = (PVOID)IData->pFileInfo + IData->pFileInfo->NextEntryOffset;
53 DPRINT("Found %.*S\n",IData->pFileInfo->FileNameLength, IData->pFileInfo->FileName);
56 IData->pFileInfo = (PVOID)IData + sizeof(KERNEL32_FIND_FILE_DATA);
57 IData->pFileInfo->FileIndex = 0;
58 Status = NtQueryDirectoryFile (IData->DirectoryHandle,
63 (PVOID)IData->pFileInfo,
65 FileBothDirectoryInformation,
69 if (!NT_SUCCESS(Status))
71 SetLastErrorByStatus (Status);
74 DPRINT("Found %.*S\n",IData->pFileInfo->FileNameLength, IData->pFileInfo->FileName);
81 InternalFindFirstFile (
85 OBJECT_ATTRIBUTES ObjectAttributes;
86 PKERNEL32_FIND_FILE_DATA IData;
87 IO_STATUS_BLOCK IoStatusBlock;
88 UNICODE_STRING NtPathU;
89 UNICODE_STRING PatternStr;
92 WCHAR CurrentDir[256];
98 DPRINT("FindFirstFileW(lpFileName %S)\n",
101 e1 = wcsrchr(lpFileName, L'/');
102 e2 = wcsrchr(lpFileName, L'\\');
103 SearchPattern = max(e1, e2);
104 SearchPath = CurrentDir;
106 if (NULL == SearchPattern)
109 SearchPattern = (PWCHAR)lpFileName;
110 Length = GetCurrentDirectoryW(sizeof(CurrentDir) / sizeof(WCHAR), SearchPath);
115 if (Length > sizeof(CurrentDir) / sizeof(WCHAR))
117 SearchPath = RtlAllocateHeap(hProcessHeap,
119 Length * sizeof(WCHAR));
120 if (NULL == SearchPath)
122 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
125 GetCurrentDirectoryW(Length, SearchPath);
132 Length = SearchPattern - lpFileName;
133 if (Length + 1 > sizeof(CurrentDir) / sizeof(WCHAR))
135 SearchPath = RtlAllocateHeap(hProcessHeap,
137 (Length + 1) * sizeof(WCHAR));
138 if (NULL == SearchPath)
140 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
144 memcpy(SearchPath, lpFileName, Length * sizeof(WCHAR));
145 SearchPath[Length] = 0;
148 bResult = RtlDosPathNameToNtPathName_U ((LPWSTR)SearchPath,
152 if (SearchPath != CurrentDir)
154 RtlFreeHeap(hProcessHeap,
158 if (FALSE == bResult)
163 DPRINT("NtPathU \'%S\'\n", NtPathU.Buffer);
165 IData = RtlAllocateHeap (hProcessHeap,
167 sizeof(KERNEL32_FIND_FILE_DATA) + FIND_DATA_SIZE);
170 RtlFreeHeap (hProcessHeap,
173 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
177 /* change pattern: "*.*" --> "*" */
178 if (!wcscmp (SearchPattern, L"*.*"))
180 RtlInitUnicodeStringFromLiteral(&PatternStr, L"*");
184 RtlInitUnicodeString(&PatternStr, SearchPattern);
187 DPRINT("NtPathU \'%S\' Pattern \'%S\'\n",
188 NtPathU.Buffer, PatternStr.Buffer);
190 InitializeObjectAttributes (&ObjectAttributes,
196 Status = NtOpenFile (&IData->DirectoryHandle,
203 RtlFreeHeap (hProcessHeap,
207 if (!NT_SUCCESS(Status))
209 RtlFreeHeap (hProcessHeap, 0, IData);
210 SetLastErrorByStatus (Status);
213 IData->pFileInfo = (PVOID)IData + sizeof(KERNEL32_FIND_FILE_DATA);
214 IData->pFileInfo->FileIndex = 0;
216 Status = NtQueryDirectoryFile (IData->DirectoryHandle,
221 (PVOID)IData->pFileInfo,
223 FileBothDirectoryInformation,
227 if (!NT_SUCCESS(Status))
229 DPRINT("Status %lx\n", Status);
230 RtlFreeHeap (hProcessHeap, 0, IData);
231 SetLastErrorByStatus (Status);
234 DPRINT("Found %.*S\n",IData->pFileInfo->FileNameLength, IData->pFileInfo->FileName);
244 LPWIN32_FIND_DATAA lpFindFileData
247 PKERNEL32_FIND_FILE_DATA IData;
248 UNICODE_STRING FileNameU;
249 ANSI_STRING FileName;
251 RtlInitAnsiString (&FileName,
254 /* convert ansi (or oem) string to unicode */
256 RtlAnsiStringToUnicodeString (&FileNameU,
260 RtlOemStringToUnicodeString (&FileNameU,
264 IData = InternalFindFirstFile (FileNameU.Buffer);
266 RtlFreeUnicodeString (&FileNameU);
270 DPRINT("Failing request\n");
271 return INVALID_HANDLE_VALUE;
274 DPRINT("IData->pFileInfo->FileNameLength %d\n",
275 IData->pFileInfo->FileNameLength);
277 /* copy data into WIN32_FIND_DATA structure */
278 lpFindFileData->dwFileAttributes = IData->pFileInfo->FileAttributes;
279 memcpy (&lpFindFileData->ftCreationTime,
280 &IData->pFileInfo->CreationTime,
282 memcpy (&lpFindFileData->ftLastAccessTime,
283 &IData->pFileInfo->LastAccessTime,
285 memcpy (&lpFindFileData->ftLastWriteTime,
286 &IData->pFileInfo->LastWriteTime,
288 lpFindFileData->nFileSizeHigh = IData->pFileInfo->EndOfFile.u.HighPart;
289 lpFindFileData->nFileSizeLow = IData->pFileInfo->EndOfFile.u.LowPart;
291 FileNameU.Length = IData->pFileInfo->FileNameLength;
292 FileNameU.MaximumLength = FileNameU.Length + sizeof(WCHAR);
293 FileNameU.Buffer = IData->pFileInfo->FileName;
296 FileName.MaximumLength = MAX_PATH;
297 FileName.Buffer = lpFindFileData->cFileName;
299 /* convert unicode string to ansi (or oem) */
301 RtlUnicodeStringToAnsiString (&FileName,
305 RtlUnicodeStringToOemString (&FileName,
309 DPRINT("IData->pFileInfo->ShortNameLength %d\n",
310 IData->pFileInfo->ShortNameLength);
312 FileNameU.Length = IData->pFileInfo->ShortNameLength;
313 FileNameU.MaximumLength = FileNameU.Length + sizeof(WCHAR);
314 FileNameU.Buffer = IData->pFileInfo->ShortName;
317 FileName.MaximumLength = 14;
318 FileName.Buffer = lpFindFileData->cAlternateFileName;
320 /* convert unicode string to ansi (or oem) */
322 RtlUnicodeStringToAnsiString (&FileName,
326 RtlUnicodeStringToOemString (&FileName,
330 return (HANDLE)IData;
338 LPWIN32_FIND_DATAA lpFindFileData)
340 PKERNEL32_FIND_FILE_DATA IData;
341 UNICODE_STRING FileNameU;
342 ANSI_STRING FileName;
344 IData = (PKERNEL32_FIND_FILE_DATA)hFindFile;
350 if (!InternalFindNextFile (hFindFile))
352 DPRINT("InternalFindNextFile() failed\n");
356 DPRINT("IData->pFileInfo->FileNameLength %d\n",
357 IData->pFileInfo->FileNameLength);
359 /* copy data into WIN32_FIND_DATA structure */
360 lpFindFileData->dwFileAttributes = IData->pFileInfo->FileAttributes;
361 memcpy (&lpFindFileData->ftCreationTime,
362 &IData->pFileInfo->CreationTime,
364 memcpy (&lpFindFileData->ftLastAccessTime,
365 &IData->pFileInfo->LastAccessTime,
367 memcpy (&lpFindFileData->ftLastWriteTime,
368 &IData->pFileInfo->LastWriteTime,
370 lpFindFileData->nFileSizeHigh = IData->pFileInfo->EndOfFile.u.HighPart;
371 lpFindFileData->nFileSizeLow = IData->pFileInfo->EndOfFile.u.LowPart;
373 FileNameU.Length = IData->pFileInfo->FileNameLength;
374 FileNameU.MaximumLength = FileNameU.Length + sizeof(WCHAR);
375 FileNameU.Buffer = IData->pFileInfo->FileName;
378 FileName.MaximumLength = MAX_PATH;
379 FileName.Buffer = lpFindFileData->cFileName;
381 /* convert unicode string to ansi (or oem) */
383 RtlUnicodeStringToAnsiString (&FileName,
387 RtlUnicodeStringToOemString (&FileName,
391 DPRINT("IData->pFileInfo->ShortNameLength %d\n",
392 IData->pFileInfo->ShortNameLength);
394 FileNameU.Length = IData->pFileInfo->ShortNameLength;
395 FileNameU.MaximumLength = FileNameU.Length + sizeof(WCHAR);
396 FileNameU.Buffer = IData->pFileInfo->ShortName;
399 FileName.MaximumLength = 14;
400 FileName.Buffer = lpFindFileData->cAlternateFileName;
402 /* convert unicode string to ansi (or oem) */
404 RtlUnicodeStringToAnsiString (&FileName,
408 RtlUnicodeStringToOemString (&FileName,
422 PKERNEL32_FIND_FILE_DATA IData;
424 DPRINT("FindClose(hFindFile %x)\n",hFindFile);
426 if (!hFindFile || hFindFile == INVALID_HANDLE_VALUE)
428 SetLastError (ERROR_INVALID_HANDLE);
432 IData = (PKERNEL32_FIND_FILE_DATA)hFindFile;
434 CloseHandle (IData->DirectoryHandle);
435 RtlFreeHeap (hProcessHeap, 0, IData);
445 LPWIN32_FIND_DATAW lpFindFileData
448 PKERNEL32_FIND_FILE_DATA IData;
450 IData = InternalFindFirstFile (lpFileName);
453 DPRINT("Failing request\n");
454 return INVALID_HANDLE_VALUE;
457 /* copy data into WIN32_FIND_DATA structure */
458 lpFindFileData->dwFileAttributes = IData->pFileInfo->FileAttributes;
459 memcpy (&lpFindFileData->ftCreationTime,
460 &IData->pFileInfo->CreationTime,
462 memcpy (&lpFindFileData->ftLastAccessTime,
463 &IData->pFileInfo->LastAccessTime,
465 memcpy (&lpFindFileData->ftLastWriteTime,
466 &IData->pFileInfo->LastWriteTime,
468 lpFindFileData->nFileSizeHigh = IData->pFileInfo->EndOfFile.u.HighPart;
469 lpFindFileData->nFileSizeLow = IData->pFileInfo->EndOfFile.u.LowPart;
470 memcpy (lpFindFileData->cFileName,
471 IData->pFileInfo->FileName,
472 IData->pFileInfo->FileNameLength);
473 lpFindFileData->cFileName[IData->pFileInfo->FileNameLength / sizeof(WCHAR)] = 0;
474 memcpy (lpFindFileData->cAlternateFileName,
475 IData->pFileInfo->ShortName,
476 IData->pFileInfo->ShortNameLength);
477 lpFindFileData->cAlternateFileName[IData->pFileInfo->ShortNameLength / sizeof(WCHAR)] = 0;
486 LPWIN32_FIND_DATAW lpFindFileData
489 PKERNEL32_FIND_FILE_DATA IData;
491 IData = (PKERNEL32_FIND_FILE_DATA)hFindFile;
492 if (!InternalFindNextFile(hFindFile))
494 DPRINT("Failing request\n");
498 /* copy data into WIN32_FIND_DATA structure */
499 lpFindFileData->dwFileAttributes = IData->pFileInfo->FileAttributes;
500 memcpy (&lpFindFileData->ftCreationTime,
501 &IData->pFileInfo->CreationTime,
503 memcpy (&lpFindFileData->ftLastAccessTime,
504 &IData->pFileInfo->LastAccessTime,
506 memcpy (&lpFindFileData->ftLastWriteTime,
507 &IData->pFileInfo->LastWriteTime,
509 lpFindFileData->nFileSizeHigh = IData->pFileInfo->EndOfFile.u.HighPart;
510 lpFindFileData->nFileSizeLow = IData->pFileInfo->EndOfFile.u.LowPart;
511 memcpy (lpFindFileData->cFileName,
512 IData->pFileInfo->FileName,
513 IData->pFileInfo->FileNameLength);
514 lpFindFileData->cFileName[IData->pFileInfo->FileNameLength / sizeof(WCHAR)] = 0;
515 memcpy (lpFindFileData->cAlternateFileName,
516 IData->pFileInfo->ShortName,
517 IData->pFileInfo->ShortNameLength);
518 lpFindFileData->cAlternateFileName[IData->pFileInfo->ShortNameLength / sizeof(WCHAR)] = 0;
527 FINDEX_INFO_LEVELS fInfoLevelId,
528 LPVOID lpFindFileData,
529 FINDEX_SEARCH_OPS fSearchOp,
530 LPVOID lpSearchFilter,
531 DWORD dwAdditionalFlags
543 FINDEX_INFO_LEVELS fInfoLevelId,
544 LPVOID lpFindFileData,
545 FINDEX_SEARCH_OPS fSearchOp,
546 LPVOID lpSearchFilter,
547 DWORD dwAdditionalFlags