mirror of
https://github.com/reactos/reactos.git
synced 2024-10-07 01:44:21 +00:00
- Fix caching of directory queries, FindFirstFile(Ex) should no longer return garbage occasionally
- These changes re-introduce the problem with searches for fake DOS devices that I claimed to have fixed in r27634 svn path=/trunk/; revision=27667
This commit is contained in:
parent
8cd2e2a887
commit
bd6665924c
|
@ -19,15 +19,19 @@
|
||||||
|
|
||||||
/* TYPES ********************************************************************/
|
/* TYPES ********************************************************************/
|
||||||
|
|
||||||
#define FIND_DATA_SIZE (16*1024)
|
#define FIND_DATA_SIZE 0x4000
|
||||||
|
|
||||||
#define FIND_DEVICE_HANDLE ((HANDLE)0x1)
|
#define FIND_DEVICE_HANDLE ((HANDLE)0x1)
|
||||||
|
|
||||||
typedef struct _KERNEL32_FIND_FILE_DATA
|
typedef struct _KERNEL32_FIND_FILE_DATA
|
||||||
{
|
{
|
||||||
HANDLE DirectoryHandle;
|
HANDLE DirectoryHandle;
|
||||||
BOOLEAN DirectoryOnly;
|
RTL_CRITICAL_SECTION Lock;
|
||||||
PFILE_BOTH_DIR_INFORMATION pFileInfo;
|
PFILE_BOTH_DIR_INFORMATION pFileInfo;
|
||||||
|
BOOLEAN DirectoryOnly;
|
||||||
|
BOOLEAN HasMoreData;
|
||||||
|
BOOLEAN HasData;
|
||||||
|
BOOLEAN LockInitialized;
|
||||||
} KERNEL32_FIND_FILE_DATA, *PKERNEL32_FIND_FILE_DATA;
|
} KERNEL32_FIND_FILE_DATA, *PKERNEL32_FIND_FILE_DATA;
|
||||||
|
|
||||||
typedef struct _KERNEL32_FIND_STREAM_DATA
|
typedef struct _KERNEL32_FIND_STREAM_DATA
|
||||||
|
@ -51,7 +55,7 @@ typedef struct _KERNEL32_FIND_DATA_HEADER
|
||||||
|
|
||||||
/* FUNCTIONS ****************************************************************/
|
/* FUNCTIONS ****************************************************************/
|
||||||
|
|
||||||
HANDLE
|
static HANDLE
|
||||||
InternalCopyDeviceFindDataW(LPWIN32_FIND_DATAW lpFindFileData,
|
InternalCopyDeviceFindDataW(LPWIN32_FIND_DATAW lpFindFileData,
|
||||||
LPCWSTR lpFileName,
|
LPCWSTR lpFileName,
|
||||||
ULONG DeviceNameInfo)
|
ULONG DeviceNameInfo)
|
||||||
|
@ -72,7 +76,7 @@ InternalCopyDeviceFindDataW(LPWIN32_FIND_DATAW lpFindFileData,
|
||||||
return FIND_DEVICE_HANDLE;
|
return FIND_DEVICE_HANDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
HANDLE
|
static HANDLE
|
||||||
InternalCopyDeviceFindDataA(LPWIN32_FIND_DATAA lpFindFileData,
|
InternalCopyDeviceFindDataA(LPWIN32_FIND_DATAA lpFindFileData,
|
||||||
PUNICODE_STRING FileName,
|
PUNICODE_STRING FileName,
|
||||||
ULONG DeviceNameInfo)
|
ULONG DeviceNameInfo)
|
||||||
|
@ -91,10 +95,6 @@ InternalCopyDeviceFindDataA(LPWIN32_FIND_DATAA lpFindFileData,
|
||||||
else
|
else
|
||||||
RtlUnicodeStringToOemString (&BufferA, &DeviceName, FALSE);
|
RtlUnicodeStringToOemString (&BufferA, &DeviceName, FALSE);
|
||||||
|
|
||||||
/* NOTE: Free the string before we try to write the results to the caller,
|
|
||||||
this way we prevent a memory leak in case of a fault... */
|
|
||||||
RtlFreeUnicodeString(FileName);
|
|
||||||
|
|
||||||
/* Return the data */
|
/* Return the data */
|
||||||
RtlZeroMemory(lpFindFileData,
|
RtlZeroMemory(lpFindFileData,
|
||||||
sizeof(*lpFindFileData));
|
sizeof(*lpFindFileData));
|
||||||
|
@ -106,7 +106,7 @@ InternalCopyDeviceFindDataA(LPWIN32_FIND_DATAA lpFindFileData,
|
||||||
return FIND_DEVICE_HANDLE;
|
return FIND_DEVICE_HANDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
static VOID
|
||||||
InternalCopyFindDataW(LPWIN32_FIND_DATAW lpFindFileData,
|
InternalCopyFindDataW(LPWIN32_FIND_DATAW lpFindFileData,
|
||||||
PFILE_BOTH_DIR_INFORMATION lpFileInfo)
|
PFILE_BOTH_DIR_INFORMATION lpFileInfo)
|
||||||
{
|
{
|
||||||
|
@ -131,7 +131,7 @@ InternalCopyFindDataW(LPWIN32_FIND_DATAW lpFindFileData,
|
||||||
lpFindFileData->cAlternateFileName[lpFileInfo->ShortNameLength / sizeof(WCHAR)] = 0;
|
lpFindFileData->cAlternateFileName[lpFileInfo->ShortNameLength / sizeof(WCHAR)] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
static VOID
|
||||||
InternalCopyFindDataA(LPWIN32_FIND_DATAA lpFindFileData,
|
InternalCopyFindDataA(LPWIN32_FIND_DATAA lpFindFileData,
|
||||||
PFILE_BOTH_DIR_INFORMATION lpFileInfo)
|
PFILE_BOTH_DIR_INFORMATION lpFileInfo)
|
||||||
{
|
{
|
||||||
|
@ -189,23 +189,23 @@ InternalCopyFindDataA(LPWIN32_FIND_DATAA lpFindFileData,
|
||||||
BOOL
|
BOOL
|
||||||
STDCALL
|
STDCALL
|
||||||
InternalFindNextFile (
|
InternalFindNextFile (
|
||||||
HANDLE hFindFile,
|
HANDLE hFindFile,
|
||||||
PUNICODE_STRING SearchPattern
|
PUNICODE_STRING SearchPattern,
|
||||||
)
|
PVOID lpFindFileData,
|
||||||
|
BOOL bUnicode
|
||||||
|
)
|
||||||
{
|
{
|
||||||
PKERNEL32_FIND_DATA_HEADER IHeader;
|
PKERNEL32_FIND_DATA_HEADER IHeader;
|
||||||
PKERNEL32_FIND_FILE_DATA IData;
|
PKERNEL32_FIND_FILE_DATA IData;
|
||||||
IO_STATUS_BLOCK IoStatusBlock;
|
IO_STATUS_BLOCK IoStatusBlock;
|
||||||
NTSTATUS Status;
|
BOOLEAN Locked = FALSE;
|
||||||
|
PFILE_BOTH_DIR_INFORMATION Buffer, FoundFile = NULL;
|
||||||
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
|
|
||||||
DPRINT("InternalFindNextFile(%lx)\n", hFindFile);
|
DPRINT("InternalFindNextFile(%lx, %wZ)\n", hFindFile, SearchPattern);
|
||||||
|
|
||||||
if (hFindFile == FIND_DEVICE_HANDLE)
|
if (hFindFile != FIND_DEVICE_HANDLE)
|
||||||
{
|
{
|
||||||
SetLastError (ERROR_NO_MORE_FILES);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
IHeader = (PKERNEL32_FIND_DATA_HEADER)hFindFile;
|
IHeader = (PKERNEL32_FIND_DATA_HEADER)hFindFile;
|
||||||
if (hFindFile == NULL || hFindFile == INVALID_HANDLE_VALUE ||
|
if (hFindFile == NULL || hFindFile == INVALID_HANDLE_VALUE ||
|
||||||
IHeader->Type != FileFind)
|
IHeader->Type != FileFind)
|
||||||
|
@ -215,41 +215,119 @@ InternalFindNextFile (
|
||||||
}
|
}
|
||||||
|
|
||||||
IData = (PKERNEL32_FIND_FILE_DATA)(IHeader + 1);
|
IData = (PKERNEL32_FIND_FILE_DATA)(IHeader + 1);
|
||||||
|
Buffer = (PFILE_BOTH_DIR_INFORMATION)((ULONG_PTR)IData + sizeof(KERNEL32_FIND_FILE_DATA));
|
||||||
|
|
||||||
while (1)
|
if (SearchPattern == NULL)
|
||||||
{
|
{
|
||||||
if (IData->pFileInfo->NextEntryOffset != 0)
|
RtlEnterCriticalSection(&IData->Lock);
|
||||||
{
|
Locked = TRUE;
|
||||||
IData->pFileInfo = (PVOID)((ULONG_PTR)IData->pFileInfo + IData->pFileInfo->NextEntryOffset);
|
}
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if (IData->HasData)
|
||||||
|
{
|
||||||
|
if (!IData->DirectoryOnly || (IData->pFileInfo->FileAttributes & FILE_ATTRIBUTE_DIRECTORY))
|
||||||
|
{
|
||||||
|
FoundFile = IData->pFileInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IData->pFileInfo->NextEntryOffset != 0)
|
||||||
|
{
|
||||||
|
ULONG_PTR BufferEnd;
|
||||||
|
|
||||||
|
IData->pFileInfo = (PFILE_BOTH_DIR_INFORMATION)((ULONG_PTR)IData->pFileInfo + IData->pFileInfo->NextEntryOffset);
|
||||||
|
|
||||||
|
/* Be paranoid and make sure that the next entry is completely there */
|
||||||
|
BufferEnd = (ULONG_PTR)Buffer + FIND_DATA_SIZE;
|
||||||
|
if (BufferEnd < (ULONG_PTR)IData->pFileInfo ||
|
||||||
|
BufferEnd < (ULONG_PTR)&IData->pFileInfo->FileNameLength + sizeof(IData->pFileInfo->FileNameLength) ||
|
||||||
|
BufferEnd <= (ULONG_PTR)&IData->pFileInfo->FileName[IData->pFileInfo->FileNameLength])
|
||||||
|
{
|
||||||
|
goto NeedMoreData;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
NeedMoreData:
|
||||||
|
IData->HasData = FALSE;
|
||||||
|
|
||||||
|
if (!IData->HasMoreData)
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
IData->pFileInfo = (PVOID)((ULONG_PTR)IData + sizeof(KERNEL32_FIND_FILE_DATA));
|
IData->pFileInfo = Buffer;
|
||||||
IData->pFileInfo->FileIndex = 0;
|
IData->pFileInfo->NextEntryOffset = 0;
|
||||||
Status = NtQueryDirectoryFile (IData->DirectoryHandle,
|
Status = NtQueryDirectoryFile (IData->DirectoryHandle,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
&IoStatusBlock,
|
&IoStatusBlock,
|
||||||
(PVOID)IData->pFileInfo,
|
(PVOID)IData->pFileInfo,
|
||||||
FIND_DATA_SIZE,
|
FIND_DATA_SIZE,
|
||||||
FileBothDirectoryInformation,
|
FileBothDirectoryInformation,
|
||||||
SearchPattern ? TRUE : FALSE,
|
FALSE,
|
||||||
SearchPattern,
|
SearchPattern,
|
||||||
SearchPattern ? TRUE : FALSE);
|
SearchPattern != NULL);
|
||||||
SearchPattern = NULL;
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (Status == STATUS_BUFFER_OVERFLOW)
|
||||||
{
|
{
|
||||||
SetLastErrorByStatus (Status);
|
IData->HasMoreData = TRUE;
|
||||||
return FALSE;
|
Status = STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
break;
|
||||||
|
|
||||||
|
IData->HasMoreData = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
IData->HasData = TRUE;
|
||||||
|
SearchPattern = NULL;
|
||||||
}
|
}
|
||||||
if (!IData->DirectoryOnly || IData->pFileInfo->FileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
|
||||||
|
} while (FoundFile == NULL);
|
||||||
|
|
||||||
|
if (FoundFile != NULL)
|
||||||
|
{
|
||||||
|
_SEH_TRY
|
||||||
{
|
{
|
||||||
DPRINT("Found %.*S\n",IData->pFileInfo->FileNameLength/sizeof(WCHAR), IData->pFileInfo->FileName);
|
if (bUnicode)
|
||||||
return TRUE;
|
{
|
||||||
|
InternalCopyFindDataW(lpFindFileData,
|
||||||
|
FoundFile);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
InternalCopyFindDataA(lpFindFileData,
|
||||||
|
FoundFile);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
_SEH_HANDLE
|
||||||
|
{
|
||||||
|
}
|
||||||
|
_SEH_END;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Locked)
|
||||||
|
RtlLeaveCriticalSection(&IData->Lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
SetLastErrorByStatus (Status);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
else if (FoundFile == NULL)
|
||||||
|
{
|
||||||
|
SetLastError (ERROR_NO_MORE_FILES);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -261,7 +339,8 @@ STDCALL
|
||||||
InternalFindFirstFile (
|
InternalFindFirstFile (
|
||||||
LPCWSTR lpFileName,
|
LPCWSTR lpFileName,
|
||||||
BOOLEAN DirectoryOnly,
|
BOOLEAN DirectoryOnly,
|
||||||
PULONG DeviceNameInfo
|
PVOID lpFindFileData,
|
||||||
|
BOOL bUnicode
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||||
|
@ -274,12 +353,12 @@ InternalFindFirstFile (
|
||||||
BOOLEAN RemovedSlash = FALSE;
|
BOOLEAN RemovedSlash = FALSE;
|
||||||
BOOL bResult;
|
BOOL bResult;
|
||||||
CURDIR DirInfo;
|
CURDIR DirInfo;
|
||||||
HANDLE hDirectory = NULL;
|
ULONG DeviceNameInfo;
|
||||||
|
HANDLE hDirectory = NULL;
|
||||||
|
|
||||||
DPRINT("FindFirstFileW(lpFileName %S)\n",
|
DPRINT("FindFirstFileW(lpFileName %S)\n",
|
||||||
lpFileName);
|
lpFileName);
|
||||||
|
|
||||||
*DeviceNameInfo = 0;
|
|
||||||
RtlZeroMemory(&PathFileName,
|
RtlZeroMemory(&PathFileName,
|
||||||
sizeof(PathFileName));
|
sizeof(PathFileName));
|
||||||
RtlInitUnicodeString(&FileName,
|
RtlInitUnicodeString(&FileName,
|
||||||
|
@ -329,8 +408,8 @@ InternalFindFirstFile (
|
||||||
|
|
||||||
/* Remove a trailing backslash from the path, unless it's a DOS drive directly */
|
/* Remove a trailing backslash from the path, unless it's a DOS drive directly */
|
||||||
if (NtPathU.Length > 3 * sizeof(WCHAR) &&
|
if (NtPathU.Length > 3 * sizeof(WCHAR) &&
|
||||||
NtPathU.Buffer[(NtPathU.Length / sizeof(WCHAR)) - 2] != L':' &&
|
NtPathU.Buffer[(NtPathU.Length / sizeof(WCHAR)) - 1] == L'\\' &&
|
||||||
NtPathU.Buffer[(NtPathU.Length / sizeof(WCHAR)) - 1] != L'\\')
|
NtPathU.Buffer[(NtPathU.Length / sizeof(WCHAR)) - 2] != L':')
|
||||||
{
|
{
|
||||||
NtPathU.Length -= sizeof(WCHAR);
|
NtPathU.Length -= sizeof(WCHAR);
|
||||||
RemovedSlash = TRUE;
|
RemovedSlash = TRUE;
|
||||||
|
@ -348,11 +427,11 @@ InternalFindFirstFile (
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
Status = NtOpenFile (&hDirectory,
|
Status = NtOpenFile (&hDirectory,
|
||||||
FILE_LIST_DIRECTORY,
|
FILE_LIST_DIRECTORY | SYNCHRONIZE,
|
||||||
&ObjectAttributes,
|
&ObjectAttributes,
|
||||||
&IoStatusBlock,
|
&IoStatusBlock,
|
||||||
FILE_SHARE_READ|FILE_SHARE_WRITE,
|
FILE_SHARE_READ|FILE_SHARE_WRITE,
|
||||||
FILE_DIRECTORY_FILE);
|
FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT);
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status) && RemovedSlash)
|
if (!NT_SUCCESS(Status) && RemovedSlash)
|
||||||
{
|
{
|
||||||
|
@ -360,25 +439,38 @@ InternalFindFirstFile (
|
||||||
NtPathU.Length -= sizeof(WCHAR);
|
NtPathU.Length -= sizeof(WCHAR);
|
||||||
|
|
||||||
Status = NtOpenFile (&hDirectory,
|
Status = NtOpenFile (&hDirectory,
|
||||||
FILE_LIST_DIRECTORY,
|
FILE_LIST_DIRECTORY | SYNCHRONIZE,
|
||||||
&ObjectAttributes,
|
&ObjectAttributes,
|
||||||
&IoStatusBlock,
|
&IoStatusBlock,
|
||||||
FILE_SHARE_READ|FILE_SHARE_WRITE,
|
FILE_SHARE_READ|FILE_SHARE_WRITE,
|
||||||
FILE_DIRECTORY_FILE);
|
FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT);
|
||||||
|
|
||||||
NtPathU.Length -= sizeof(WCHAR);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
if (!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
RtlFreeHeap (hProcessHeap,
|
RtlFreeHeap (hProcessHeap,
|
||||||
0,
|
0,
|
||||||
NtPathBuffer);
|
NtPathBuffer);
|
||||||
|
|
||||||
/* See if the application tries to look for a DOS device */
|
/* See if the application tries to look for a DOS device */
|
||||||
*DeviceNameInfo = RtlIsDosDeviceName_U((PWSTR)((ULONG_PTR)lpFileName));
|
DeviceNameInfo = RtlIsDosDeviceName_U((PWSTR)((ULONG_PTR)lpFileName));
|
||||||
if (*DeviceNameInfo != 0)
|
if (DeviceNameInfo != 0)
|
||||||
|
{
|
||||||
|
if (bUnicode)
|
||||||
|
{
|
||||||
|
InternalCopyDeviceFindDataW(lpFindFileData,
|
||||||
|
lpFileName,
|
||||||
|
DeviceNameInfo);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
InternalCopyDeviceFindDataA(lpFindFileData,
|
||||||
|
&FileName,
|
||||||
|
DeviceNameInfo);
|
||||||
|
}
|
||||||
|
|
||||||
return FIND_DEVICE_HANDLE;
|
return FIND_DEVICE_HANDLE;
|
||||||
|
}
|
||||||
|
|
||||||
SetLastErrorByStatus (Status);
|
SetLastErrorByStatus (Status);
|
||||||
return(NULL);
|
return(NULL);
|
||||||
|
@ -413,6 +505,7 @@ InternalFindFirstFile (
|
||||||
IHeader->Type = FileFind;
|
IHeader->Type = FileFind;
|
||||||
IData = (PKERNEL32_FIND_FILE_DATA)(IHeader + 1);
|
IData = (PKERNEL32_FIND_FILE_DATA)(IHeader + 1);
|
||||||
IData->DirectoryHandle = hDirectory;
|
IData->DirectoryHandle = hDirectory;
|
||||||
|
IData->HasMoreData = TRUE;
|
||||||
|
|
||||||
/* change pattern: "*.*" --> "*" */
|
/* change pattern: "*.*" --> "*" */
|
||||||
if (PathFileName.Length == 6 &&
|
if (PathFileName.Length == 6 &&
|
||||||
|
@ -427,7 +520,10 @@ InternalFindFirstFile (
|
||||||
IData->pFileInfo->FileIndex = 0;
|
IData->pFileInfo->FileIndex = 0;
|
||||||
IData->DirectoryOnly = DirectoryOnly;
|
IData->DirectoryOnly = DirectoryOnly;
|
||||||
|
|
||||||
bResult = InternalFindNextFile((HANDLE)IHeader, &PathFileName);
|
bResult = InternalFindNextFile((HANDLE)IHeader,
|
||||||
|
&PathFileName,
|
||||||
|
lpFindFileData,
|
||||||
|
bUnicode);
|
||||||
|
|
||||||
RtlFreeHeap (hProcessHeap,
|
RtlFreeHeap (hProcessHeap,
|
||||||
0,
|
0,
|
||||||
|
@ -439,6 +535,9 @@ InternalFindFirstFile (
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RtlInitializeCriticalSection(&IData->Lock);
|
||||||
|
IData->LockInitialized = TRUE;
|
||||||
|
|
||||||
return (HANDLE)IHeader;
|
return (HANDLE)IHeader;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -453,52 +552,12 @@ FindFirstFileA (
|
||||||
LPWIN32_FIND_DATAA lpFindFileData
|
LPWIN32_FIND_DATAA lpFindFileData
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
PKERNEL32_FIND_DATA_HEADER IHeader;
|
return FindFirstFileExA (lpFileName,
|
||||||
PKERNEL32_FIND_FILE_DATA IData;
|
FindExInfoStandard,
|
||||||
UNICODE_STRING FileNameU;
|
(LPVOID)lpFindFileData,
|
||||||
ANSI_STRING FileName;
|
FindExSearchNameMatch,
|
||||||
ULONG DeviceNameInfo;
|
NULL,
|
||||||
|
0);
|
||||||
RtlInitAnsiString (&FileName,
|
|
||||||
(LPSTR)lpFileName);
|
|
||||||
|
|
||||||
/* convert ansi (or oem) string to unicode */
|
|
||||||
if (bIsFileApiAnsi)
|
|
||||||
RtlAnsiStringToUnicodeString (&FileNameU,
|
|
||||||
&FileName,
|
|
||||||
TRUE);
|
|
||||||
else
|
|
||||||
RtlOemStringToUnicodeString (&FileNameU,
|
|
||||||
&FileName,
|
|
||||||
TRUE);
|
|
||||||
|
|
||||||
IHeader = InternalFindFirstFile (FileNameU.Buffer, FALSE, &DeviceNameInfo);
|
|
||||||
|
|
||||||
if (IHeader == NULL)
|
|
||||||
{
|
|
||||||
RtlFreeUnicodeString (&FileNameU);
|
|
||||||
DPRINT("Failing request\n");
|
|
||||||
return INVALID_HANDLE_VALUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((HANDLE)IHeader == FIND_DEVICE_HANDLE)
|
|
||||||
{
|
|
||||||
/* NOTE: FileNameU will be freed in InternalCopyDeviceFindDataA */
|
|
||||||
return InternalCopyDeviceFindDataA(lpFindFileData, &FileNameU, DeviceNameInfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
RtlFreeUnicodeString (&FileNameU);
|
|
||||||
|
|
||||||
IData = (PKERNEL32_FIND_FILE_DATA)(IHeader + 1);
|
|
||||||
|
|
||||||
DPRINT("IData->pFileInfo->FileNameLength %d\n",
|
|
||||||
IData->pFileInfo->FileNameLength);
|
|
||||||
|
|
||||||
/* copy data into WIN32_FIND_DATA structure */
|
|
||||||
InternalCopyFindDataA(lpFindFileData, IData->pFileInfo);
|
|
||||||
|
|
||||||
|
|
||||||
return (HANDLE)IHeader;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -511,23 +570,10 @@ FindNextFileA (
|
||||||
HANDLE hFindFile,
|
HANDLE hFindFile,
|
||||||
LPWIN32_FIND_DATAA lpFindFileData)
|
LPWIN32_FIND_DATAA lpFindFileData)
|
||||||
{
|
{
|
||||||
PKERNEL32_FIND_FILE_DATA IData;
|
return InternalFindNextFile (hFindFile,
|
||||||
|
NULL,
|
||||||
if (!InternalFindNextFile (hFindFile, NULL))
|
lpFindFileData,
|
||||||
{
|
FALSE);
|
||||||
DPRINT("InternalFindNextFile() failed\n");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
IData = (PKERNEL32_FIND_FILE_DATA)((PKERNEL32_FIND_DATA_HEADER)hFindFile + 1);
|
|
||||||
|
|
||||||
DPRINT("IData->pFileInfo->FileNameLength %d\n",
|
|
||||||
IData->pFileInfo->FileNameLength);
|
|
||||||
|
|
||||||
/* copy data into WIN32_FIND_DATA structure */
|
|
||||||
InternalCopyFindDataA(lpFindFileData, IData->pFileInfo);
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -561,6 +607,8 @@ FindClose (
|
||||||
{
|
{
|
||||||
PKERNEL32_FIND_FILE_DATA IData = (PKERNEL32_FIND_FILE_DATA)(IHeader + 1);
|
PKERNEL32_FIND_FILE_DATA IData = (PKERNEL32_FIND_FILE_DATA)(IHeader + 1);
|
||||||
CloseHandle (IData->DirectoryHandle);
|
CloseHandle (IData->DirectoryHandle);
|
||||||
|
if (IData->LockInitialized)
|
||||||
|
RtlDeleteCriticalSection(&IData->Lock);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -595,13 +643,12 @@ FindFirstFileW (
|
||||||
LPWIN32_FIND_DATAW lpFindFileData
|
LPWIN32_FIND_DATAW lpFindFileData
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
return FindFirstFileExW (lpFileName,
|
||||||
return FindFirstFileExW (lpFileName,
|
FindExInfoStandard,
|
||||||
FindExInfoStandard,
|
(LPVOID)lpFindFileData,
|
||||||
(LPVOID)lpFindFileData,
|
FindExSearchNameMatch,
|
||||||
FindExSearchNameMatch,
|
NULL,
|
||||||
NULL,
|
0);
|
||||||
0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -614,20 +661,10 @@ FindNextFileW (
|
||||||
LPWIN32_FIND_DATAW lpFindFileData
|
LPWIN32_FIND_DATAW lpFindFileData
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
PKERNEL32_FIND_FILE_DATA IData;
|
return InternalFindNextFile (hFindFile,
|
||||||
|
NULL,
|
||||||
if (!InternalFindNextFile(hFindFile, NULL))
|
lpFindFileData,
|
||||||
{
|
TRUE);
|
||||||
DPRINT("Failing request\n");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
IData = (PKERNEL32_FIND_FILE_DATA)((PKERNEL32_FIND_DATA_HEADER)hFindFile + 1);
|
|
||||||
|
|
||||||
/* copy data into WIN32_FIND_DATA structure */
|
|
||||||
InternalCopyFindDataW(lpFindFileData, IData->pFileInfo);
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -643,15 +680,14 @@ FindFirstFileExW (LPCWSTR lpFileName,
|
||||||
LPVOID lpSearchFilter,
|
LPVOID lpSearchFilter,
|
||||||
DWORD dwAdditionalFlags)
|
DWORD dwAdditionalFlags)
|
||||||
{
|
{
|
||||||
PKERNEL32_FIND_DATA_HEADER IHeader;
|
HANDLE Handle;
|
||||||
PKERNEL32_FIND_FILE_DATA IData;
|
|
||||||
ULONG DeviceNameInfo;
|
|
||||||
|
|
||||||
if (fInfoLevelId != FindExInfoStandard)
|
if (fInfoLevelId != FindExInfoStandard)
|
||||||
{
|
{
|
||||||
SetLastError(ERROR_INVALID_PARAMETER);
|
SetLastError(ERROR_INVALID_PARAMETER);
|
||||||
return INVALID_HANDLE_VALUE;
|
return INVALID_HANDLE_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fSearchOp == FindExSearchNameMatch || fSearchOp == FindExSearchLimitToDirectories)
|
if (fSearchOp == FindExSearchNameMatch || fSearchOp == FindExSearchLimitToDirectories)
|
||||||
{
|
{
|
||||||
if (lpSearchFilter)
|
if (lpSearchFilter)
|
||||||
|
@ -660,23 +696,19 @@ FindFirstFileExW (LPCWSTR lpFileName,
|
||||||
return INVALID_HANDLE_VALUE;
|
return INVALID_HANDLE_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
IHeader = InternalFindFirstFile (lpFileName, fSearchOp == FindExSearchLimitToDirectories ? TRUE : FALSE, &DeviceNameInfo);
|
Handle = InternalFindFirstFile (lpFileName,
|
||||||
if (IHeader == NULL)
|
fSearchOp == FindExSearchLimitToDirectories,
|
||||||
|
lpFindFileData,
|
||||||
|
TRUE);
|
||||||
|
if (Handle == NULL)
|
||||||
{
|
{
|
||||||
DPRINT("Failing request\n");
|
DPRINT("Failing request\n");
|
||||||
return INVALID_HANDLE_VALUE;
|
return INVALID_HANDLE_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((HANDLE)IHeader == FIND_DEVICE_HANDLE)
|
return Handle;
|
||||||
return InternalCopyDeviceFindDataW((LPWIN32_FIND_DATAW)lpFindFileData, lpFileName, DeviceNameInfo);
|
|
||||||
|
|
||||||
IData = (PKERNEL32_FIND_FILE_DATA)(IHeader + 1);
|
|
||||||
|
|
||||||
/* copy data into WIN32_FIND_DATA structure */
|
|
||||||
InternalCopyFindDataW((LPWIN32_FIND_DATAW)lpFindFileData, IData->pFileInfo);
|
|
||||||
|
|
||||||
return (HANDLE)IHeader;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SetLastError(ERROR_INVALID_PARAMETER);
|
SetLastError(ERROR_INVALID_PARAMETER);
|
||||||
return INVALID_HANDLE_VALUE;
|
return INVALID_HANDLE_VALUE;
|
||||||
}
|
}
|
||||||
|
@ -695,11 +727,9 @@ FindFirstFileExA (
|
||||||
DWORD dwAdditionalFlags
|
DWORD dwAdditionalFlags
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
PKERNEL32_FIND_DATA_HEADER IHeader;
|
|
||||||
PKERNEL32_FIND_FILE_DATA IData;
|
|
||||||
UNICODE_STRING FileNameU;
|
UNICODE_STRING FileNameU;
|
||||||
ANSI_STRING FileNameA;
|
ANSI_STRING FileNameA;
|
||||||
ULONG DeviceNameInfo;
|
HANDLE Handle;
|
||||||
|
|
||||||
if (fInfoLevelId != FindExInfoStandard)
|
if (fInfoLevelId != FindExInfoStandard)
|
||||||
{
|
{
|
||||||
|
@ -713,39 +743,31 @@ FindFirstFileExA (
|
||||||
SetLastError(ERROR_INVALID_PARAMETER);
|
SetLastError(ERROR_INVALID_PARAMETER);
|
||||||
return INVALID_HANDLE_VALUE;
|
return INVALID_HANDLE_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
RtlInitAnsiString (&FileNameA, (LPSTR)lpFileName);
|
RtlInitAnsiString (&FileNameA, (LPSTR)lpFileName);
|
||||||
|
|
||||||
/* convert ansi (or oem) string to unicode */
|
/* convert ansi (or oem) string to unicode */
|
||||||
if (bIsFileApiAnsi)
|
if (bIsFileApiAnsi)
|
||||||
RtlAnsiStringToUnicodeString (&FileNameU, &FileNameA, TRUE);
|
RtlAnsiStringToUnicodeString (&FileNameU, &FileNameA, TRUE);
|
||||||
else
|
else
|
||||||
RtlOemStringToUnicodeString (&FileNameU, &FileNameA, TRUE);
|
RtlOemStringToUnicodeString (&FileNameU, &FileNameA, TRUE);
|
||||||
|
|
||||||
IHeader = InternalFindFirstFile (FileNameU.Buffer, FALSE, &DeviceNameInfo);
|
Handle = InternalFindFirstFile (FileNameU.Buffer,
|
||||||
|
fSearchOp == FindExSearchLimitToDirectories,
|
||||||
|
lpFindFileData,
|
||||||
|
FALSE);
|
||||||
|
|
||||||
if (IHeader == NULL)
|
RtlFreeUnicodeString (&FileNameU);
|
||||||
{
|
|
||||||
RtlFreeUnicodeString (&FileNameU);
|
|
||||||
DPRINT("Failing request\n");
|
|
||||||
return INVALID_HANDLE_VALUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((HANDLE)IHeader == FIND_DEVICE_HANDLE)
|
if (Handle == NULL)
|
||||||
{
|
{
|
||||||
/* NOTE: FileNameU will be freed in InternalCopyDeviceFindDataA */
|
DPRINT("Failing request\n");
|
||||||
return InternalCopyDeviceFindDataA(lpFindFileData, &FileNameU, DeviceNameInfo);
|
return INVALID_HANDLE_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
RtlFreeUnicodeString (&FileNameU);
|
return Handle;
|
||||||
|
|
||||||
IData = (PKERNEL32_FIND_FILE_DATA)(IHeader + 1);
|
|
||||||
|
|
||||||
/* copy data into WIN32_FIND_DATA structure */
|
|
||||||
InternalCopyFindDataA(lpFindFileData, IData->pFileInfo);
|
|
||||||
|
|
||||||
return (HANDLE)IHeader;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SetLastError(ERROR_INVALID_PARAMETER);
|
SetLastError(ERROR_INVALID_PARAMETER);
|
||||||
return INVALID_HANDLE_VALUE;
|
return INVALID_HANDLE_VALUE;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue