2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS system libraries
4 * FILE: lib/kernel32/file/find.c
5 * PURPOSE: Find functions
6 * PROGRAMMER: Ariadne ( ariadne@xs4all.nl)
11 /* INCLUDES *****************************************************************/
15 #include <ddk/ntddk.h>
19 #include <kernel32/kernel32.h>
21 /* TYPES ********************************************************************/
23 typedef struct _KERNEL32_FIND_FILE_DATA
25 HANDLE DirectoryHandle
;
26 FILE_BOTH_DIRECTORY_INFORMATION FileInfo
;
27 WCHAR FileNameExtra
[MAX_PATH
];
28 UNICODE_STRING PatternStr
;
29 } KERNEL32_FIND_FILE_DATA
, *PKERNEL32_FIND_FILE_DATA
;
31 typedef struct _WIN32_FIND_DATA_UNICODE
{
32 DWORD dwFileAttributes
;
33 FILETIME ftCreationTime
;
34 FILETIME ftLastAccessTime
;
35 FILETIME ftLastWriteTime
;
40 WCHAR cFileName
[ MAX_PATH
];
41 WCHAR cAlternateFileName
[ 14 ];
42 } WIN32_FIND_DATA_UNICODE
, *PWIN32_FIND_DATA_UNICODE
;
44 typedef struct _WIN32_FIND_DATA_ASCII
{
45 DWORD dwFileAttributes
;
46 FILETIME ftCreationTime
;
47 FILETIME ftLastAccessTime
;
48 FILETIME ftLastWriteTime
;
53 CHAR cFileName
[ MAX_PATH
];
54 CHAR cAlternateFileName
[ 14 ];
55 } WIN32_FIND_DATA_ASCII
, *PWIN32_FIND_DATA_ASCII
;
57 /* FUNCTIONS *****************************************************************/
60 static void FileDataToWin32Data(LPWIN32_FIND_DATA lpFindFileData
, PKERNEL32_FIND_FILE_DATA IData
)
62 lpFindFileData
->dwFileAttributes
= IData
->FileInfo
.FileAttributes
;
63 memcpy(&lpFindFileData
->ftCreationTime
,&IData
->FileInfo
.CreationTime
,sizeof(FILETIME
));
64 memcpy(&lpFindFileData
->ftLastAccessTime
,&IData
->FileInfo
.LastAccessTime
,sizeof(FILETIME
));
65 memcpy(&lpFindFileData
->ftLastWriteTime
,&IData
->FileInfo
.LastWriteTime
,sizeof(FILETIME
));
66 lpFindFileData
->nFileSizeHigh
= IData
->FileInfo
.EndOfFile
.u
.HighPart
;
67 lpFindFileData
->nFileSizeLow
= IData
->FileInfo
.EndOfFile
.u
.LowPart
;
70 WINBOOL STDCALL
InternalFindNextFile(HANDLE hFindFile
,
71 LPWIN32_FIND_DATA lpFindFileData
)
73 IO_STATUS_BLOCK IoStatusBlock
;
75 PKERNEL32_FIND_FILE_DATA IData
;
77 IData
= (PKERNEL32_FIND_FILE_DATA
)hFindFile
;
79 Status
= NtQueryDirectoryFile(IData
->DirectoryHandle
,
84 (PVOID
)&IData
->FileInfo
,
85 sizeof(IData
->FileInfo
) +
86 sizeof(IData
->FileNameExtra
),
87 FileBothDirectoryInformation
,
91 DPRINT("Found %w\n",IData
->FileInfo
.FileName
);
92 if (Status
!= STATUS_SUCCESS
)
97 FileDataToWin32Data(lpFindFileData
, IData
);
102 HANDLE STDCALL
InternalFindFirstFile(LPCWSTR lpFileName
,
103 LPWIN32_FIND_DATA lpFindFileData
)
105 WCHAR CurrentDirectory
[MAX_PATH
];
106 WCHAR Pattern
[MAX_PATH
];
107 WCHAR Directory
[MAX_PATH
];
109 PKERNEL32_FIND_FILE_DATA IData
;
110 OBJECT_ATTRIBUTES ObjectAttributes
;
111 UNICODE_STRING DirectoryNameStr
;
112 IO_STATUS_BLOCK IoStatusBlock
;
114 DPRINT("FindFirstFileW(lpFileName %w, lpFindFileData %x)\n",
115 lpFileName
, lpFindFileData
);
117 GetFullPathNameW(lpFileName
, MAX_PATH
, CurrentDirectory
, NULL
);
123 DPRINT("Directory %w\n",Directory
);
124 wcscat(Directory
, CurrentDirectory
);
125 DPRINT("Directory %w\n",Directory
);
126 End
= wcsrchr(Directory
, '\\');
129 wcscpy(Pattern
, End
+1);
133 /* change pattern: "*.*" --> "*" */
134 if (!wcscmp(Pattern
, L
"*.*"))
137 DPRINT("Directory %w Pattern %w\n",Directory
,Pattern
);
139 IData
= HeapAlloc(GetProcessHeap(),
141 sizeof(KERNEL32_FIND_FILE_DATA
));
143 RtlInitUnicodeString(&DirectoryNameStr
, Directory
);
144 InitializeObjectAttributes(&ObjectAttributes
,
150 if (ZwOpenFile(&IData
->DirectoryHandle
,
155 OPEN_EXISTING
)!=STATUS_SUCCESS
)
160 RtlInitUnicodeString(&(IData
->PatternStr
), Pattern
);
162 NtQueryDirectoryFile(IData
->DirectoryHandle
,
167 (PVOID
)&IData
->FileInfo
,
168 sizeof(IData
->FileInfo
) +
169 sizeof(IData
->FileNameExtra
),
170 FileBothDirectoryInformation
,
172 &(IData
->PatternStr
),
174 DPRINT("Found %w\n",IData
->FileInfo
.FileName
);
176 FileDataToWin32Data(lpFindFileData
, IData
);
181 HANDLE
FindFirstFileA(LPCTSTR lpFileName
, LPWIN32_FIND_DATA lpFindFileData
)
183 WCHAR lpFileNameW
[MAX_PATH
];
185 PKERNEL32_FIND_FILE_DATA IData
;
186 PWIN32_FIND_DATA_ASCII Ret
;
189 while (lpFileName
[i
]!=0)
191 lpFileNameW
[i
] = lpFileName
[i
];
196 IData
= InternalFindFirstFile(lpFileNameW
,lpFindFileData
);
199 DPRINT("Failing request\n");
200 return(INVALID_HANDLE_VALUE
);
204 Ret
= (PWIN32_FIND_DATA_ASCII
)lpFindFileData
;
206 DPRINT("IData->FileInfo.FileNameLength %d\n",
207 IData
->FileInfo
.FileNameLength
);
208 for (i
=0; i
<IData
->FileInfo
.FileNameLength
; i
++)
210 Ret
->cFileName
[i
] = IData
->FileInfo
.FileName
[i
];
212 Ret
->cFileName
[i
] = 0;
214 DPRINT("IData->FileInfo.ShortNameLength %d\n",
215 IData
->FileInfo
.ShortNameLength
);
216 if (IData
->FileInfo
.ShortNameLength
> 13)
218 IData
->FileInfo
.ShortNameLength
= 13;
220 for (i
=0; i
<IData
->FileInfo
.ShortNameLength
; i
++)
222 Ret
->cAlternateFileName
[i
] = IData
->FileInfo
.ShortName
[i
];
224 Ret
->cAlternateFileName
[i
] = 0;
230 WINBOOL
FindNextFileA(HANDLE hFindFile
, LPWIN32_FIND_DATA lpFindFileData
)
232 PWIN32_FIND_DATA_ASCII Ret
;
233 PKERNEL32_FIND_FILE_DATA IData
;
236 IData
= (PKERNEL32_FIND_FILE_DATA
)hFindFile
;
241 if (!InternalFindNextFile(hFindFile
, lpFindFileData
))
243 DPRINT("InternalFindNextFile() failed\n");
247 Ret
= (PWIN32_FIND_DATA_ASCII
)lpFindFileData
;
249 DPRINT("IData->FileInfo.FileNameLength %d\n",
250 IData
->FileInfo
.FileNameLength
);
251 for (i
=0; i
<IData
->FileInfo
.FileNameLength
; i
++)
253 Ret
->cFileName
[i
] = IData
->FileInfo
.FileName
[i
];
255 Ret
->cFileName
[i
] = 0;
257 DPRINT("IData->FileInfo.ShortNameLength %d\n",
258 IData
->FileInfo
.ShortNameLength
);
259 for (i
=0; i
<IData
->FileInfo
.ShortNameLength
; i
++)
261 Ret
->cAlternateFileName
[i
] = IData
->FileInfo
.ShortName
[i
];
263 Ret
->cAlternateFileName
[i
] = 0;
268 BOOL
FindClose(HANDLE hFindFile
)
270 PKERNEL32_FIND_FILE_DATA IData
;
272 DPRINT("FindClose(hFindFile %x)\n",hFindFile
);
274 if (hFindFile
|| hFindFile
== INVALID_HANDLE_VALUE
)
276 SetLastError (ERROR_INVALID_HANDLE
);
279 IData
= (PKERNEL32_FIND_FILE_DATA
)hFindFile
;
280 CloseHandle(IData
->DirectoryHandle
);
281 HeapFree(GetProcessHeap(), 0, IData
);
285 HANDLE STDCALL
FindFirstFileW(LPCWSTR lpFileName
,
286 LPWIN32_FIND_DATA lpFindFileData
)
288 PWIN32_FIND_DATA_UNICODE Ret
;
289 PKERNEL32_FIND_FILE_DATA IData
;
291 IData
= InternalFindFirstFile(lpFileName
,lpFindFileData
);
292 Ret
= (PWIN32_FIND_DATA_UNICODE
)lpFindFileData
;
294 memcpy(Ret
->cFileName
, IData
->FileInfo
.FileName
,
295 IData
->FileInfo
.FileNameLength
);
296 memcpy(Ret
->cAlternateFileName
, IData
->FileInfo
.ShortName
,
297 IData
->FileInfo
.ShortNameLength
);
302 WINBOOL STDCALL
FindNextFileW(HANDLE hFindFile
,
303 LPWIN32_FIND_DATA lpFindFileData
)
305 PWIN32_FIND_DATA_UNICODE Ret
;
306 PKERNEL32_FIND_FILE_DATA IData
;
308 IData
= (PKERNEL32_FIND_FILE_DATA
)hFindFile
;
309 if (!InternalFindNextFile(hFindFile
, lpFindFileData
))
314 Ret
= (PWIN32_FIND_DATA_UNICODE
)lpFindFileData
;
316 memcpy(Ret
->cFileName
, IData
->FileInfo
.FileName
,
317 IData
->FileInfo
.FileNameLength
);
318 memcpy(Ret
->cAlternateFileName
, IData
->FileInfo
.ShortName
,
319 IData
->FileInfo
.ShortNameLength
);