Dmitry Philippov <shedon@mail.ru>:

- Implemented FindFirstFileExW() and have removed InternalFindFirstFile() in /lib/kernel32/file/find.c, now FindFirstFileA (), FindFirstFileExA () and FindFirstFileW called FindFirstFileExW ()

NOTE: Filip has asked revision "16661" (the next one) to be done by him... sorry if this sounds silly, but please respect his wish :)

svn path=/trunk/; revision=16660
This commit is contained in:
Alex Ionescu 2005-07-20 04:43:12 +00:00
parent e8ebef770f
commit 692af5f653

View file

@ -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,329 +82,6 @@ InternalFindNextFile (
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
*/
@ -518,6 +197,64 @@ FindClose (
return TRUE;
}
/*
* @implemented
*/
HANDLE
STDCALL
FindFirstFileA (
LPCSTR lpFileName,
LPWIN32_FIND_DATAA lpFindFileData
)
{
PKERNEL32_FIND_FILE_DATA IData;
UNICODE_STRING FileNameU;
ANSI_STRING FileName;
WIN32_FIND_DATAW FindFileData;
RtlInitAnsiString (&FileName,
(LPSTR)lpFileName);
/* convert ansi (or oem) string to unicode */
if (bIsFileApiAnsi)
RtlAnsiStringToUnicodeString (&FileNameU,
&FileName,
TRUE);
else
RtlOemStringToUnicodeString (&FileNameU,
&FileName,
TRUE);
IData = FindFirstFileExW(FileNameU.Buffer,
FindExInfoStandard,
&FindFileData,
FindExSearchNameMatch,
NULL,
0);
RtlFreeUnicodeString(&FileNameU);
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);
}
}
return (HANDLE)IData;
}
/*
* @implemented
@ -529,39 +266,14 @@ FindFirstFileW (
LPWIN32_FIND_DATAW lpFindFileData
)
{
PKERNEL32_FIND_FILE_DATA IData;
IData = InternalFindFirstFile (lpFileName);
if (IData == NULL)
{
DPRINT("Failing request\n");
return INVALID_HANDLE_VALUE;
}
/* 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;
return FindFirstFileExW(
lpFileName,
FindExInfoStandard,
lpFindFileData,
FindExSearchNameMatch,
NULL,
0
);
}
@ -609,7 +321,7 @@ FindNextFileW (
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 @@ FindNextFileW (
/*
* @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;
}