📄 find.c
字号:
LPWIN32_FIND_DATAA lpFindFileData)
{
PKERNEL32_FIND_FILE_DATA IData;
if (!InternalFindNextFile (hFindFile, NULL))
{
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;
}
/*
* @implemented
*/
BOOL
STDCALL
FindClose (
HANDLE hFindFile
)
{
PKERNEL32_FIND_DATA_HEADER IHeader;
DPRINT("FindClose(hFindFile %x)\n",hFindFile);
if (!hFindFile || hFindFile == INVALID_HANDLE_VALUE)
{
SetLastError (ERROR_INVALID_HANDLE);
return FALSE;
}
IHeader = (PKERNEL32_FIND_DATA_HEADER)hFindFile;
switch (IHeader->Type)
{
case FileFind:
{
PKERNEL32_FIND_FILE_DATA IData = (PKERNEL32_FIND_FILE_DATA)(IHeader + 1);
CloseHandle (IData->DirectoryHandle);
break;
}
case StreamFind:
{
PKERNEL32_FIND_STREAM_DATA IData = (PKERNEL32_FIND_STREAM_DATA)(IHeader + 1);
if (IData->pFileStreamInfo != NULL)
{
RtlFreeHeap (hProcessHeap, 0, IData->pFileStreamInfo);
}
break;
}
default:
SetLastError (ERROR_INVALID_HANDLE);
return FALSE;
}
RtlFreeHeap (hProcessHeap, 0, IHeader);
return TRUE;
}
/*
* @implemented
*/
HANDLE
STDCALL
FindFirstFileW (
LPCWSTR lpFileName,
LPWIN32_FIND_DATAW lpFindFileData
)
{
return FindFirstFileExW (lpFileName,
FindExInfoStandard,
(LPVOID)lpFindFileData,
FindExSearchNameMatch,
NULL,
0);
}
/*
* @implemented
*/
BOOL
STDCALL
FindNextFileW (
HANDLE hFindFile,
LPWIN32_FIND_DATAW lpFindFileData
)
{
PKERNEL32_FIND_FILE_DATA IData;
if (!InternalFindNextFile(hFindFile, NULL))
{
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;
}
/*
* @unimplemented
*/
HANDLE
STDCALL
FindFirstFileExW (LPCWSTR lpFileName,
FINDEX_INFO_LEVELS fInfoLevelId,
LPVOID lpFindFileData,
FINDEX_SEARCH_OPS fSearchOp,
LPVOID lpSearchFilter,
DWORD dwAdditionalFlags)
{
PKERNEL32_FIND_DATA_HEADER IHeader;
PKERNEL32_FIND_FILE_DATA IData;
if (fInfoLevelId != FindExInfoStandard)
{
SetLastError(ERROR_INVALID_PARAMETER);
return INVALID_HANDLE_VALUE;
}
if (fSearchOp == FindExSearchNameMatch || fSearchOp == FindExSearchLimitToDirectories)
{
if (lpSearchFilter)
{
SetLastError(ERROR_INVALID_PARAMETER);
return INVALID_HANDLE_VALUE;
}
IHeader = InternalFindFirstFile (lpFileName, fSearchOp == FindExSearchLimitToDirectories ? TRUE : FALSE);
if (IHeader == NULL)
{
DPRINT("Failing request\n");
return INVALID_HANDLE_VALUE;
}
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);
return INVALID_HANDLE_VALUE;
}
/*
* @unimplemented
*/
HANDLE
STDCALL
FindFirstFileExA (
LPCSTR lpFileName,
FINDEX_INFO_LEVELS fInfoLevelId,
LPVOID lpFindFileData,
FINDEX_SEARCH_OPS fSearchOp,
LPVOID lpSearchFilter,
DWORD dwAdditionalFlags
)
{
PKERNEL32_FIND_DATA_HEADER IHeader;
PKERNEL32_FIND_FILE_DATA IData;
UNICODE_STRING FileNameU;
ANSI_STRING FileNameA;
if (fInfoLevelId != FindExInfoStandard)
{
SetLastError(ERROR_INVALID_PARAMETER);
return INVALID_HANDLE_VALUE;
}
if (fSearchOp == FindExSearchNameMatch || fSearchOp == FindExSearchLimitToDirectories)
{
if (lpSearchFilter)
{
SetLastError(ERROR_INVALID_PARAMETER);
return INVALID_HANDLE_VALUE;
}
RtlInitAnsiString (&FileNameA, (LPSTR)lpFileName);
/* convert ansi (or oem) string to unicode */
if (bIsFileApiAnsi)
RtlAnsiStringToUnicodeString (&FileNameU, &FileNameA, TRUE);
else
RtlOemStringToUnicodeString (&FileNameU, &FileNameA, TRUE);
IHeader = InternalFindFirstFile (FileNameU.Buffer, FALSE);
RtlFreeUnicodeString (&FileNameU);
if (IHeader == NULL)
{
DPRINT("Failing request\n");
return INVALID_HANDLE_VALUE;
}
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);
return INVALID_HANDLE_VALUE;
}
static VOID
InternalCopyStreamInfo(IN OUT PKERNEL32_FIND_STREAM_DATA IData,
OUT LPVOID lpFindStreamData)
{
ASSERT(IData->pCurrent != NULL);
switch (IData->InfoLevel)
{
case FindStreamInfoStandard:
{
ULONG StreamNameLen;
WIN32_FIND_STREAM_DATA *StreamData = (WIN32_FIND_STREAM_DATA*)lpFindStreamData;
StreamNameLen = IData->pCurrent->StreamNameLength;
if (StreamNameLen > sizeof(StreamData->cStreamName) - sizeof(WCHAR))
StreamNameLen = sizeof(StreamData->cStreamName) - sizeof(WCHAR);
StreamData->StreamSize.QuadPart = IData->pCurrent->StreamSize.QuadPart;
RtlCopyMemory(StreamData->cStreamName,
IData->pCurrent->StreamName,
StreamNameLen);
StreamData->cStreamName[StreamNameLen / sizeof(WCHAR)] = L'\0';
break;
}
default:
ASSERT(FALSE);
break;
}
}
/*
* @implemented
*/
HANDLE
WINAPI
FindFirstStreamW(IN LPCWSTR lpFileName,
IN STREAM_INFO_LEVELS InfoLevel,
OUT LPVOID lpFindStreamData,
IN DWORD dwFlags)
{
PKERNEL32_FIND_DATA_HEADER IHeader = NULL;
PKERNEL32_FIND_STREAM_DATA IData = NULL;
OBJECT_ATTRIBUTES ObjectAttributes;
IO_STATUS_BLOCK IoStatusBlock;
UNICODE_STRING NtPathU;
HANDLE FileHandle = NULL;
NTSTATUS Status;
ULONG BufferSize = 0;
if (dwFlags != 0 || InfoLevel != FindStreamInfoStandard ||
lpFindStreamData == NULL)
{
SetLastError(ERROR_INVALID_PARAMETER);
return INVALID_HANDLE_VALUE;
}
/* validate & translate the filename */
if (!RtlDosPathNameToNtPathName_U(lpFileName,
&NtPathU,
NULL,
NULL))
{
SetLastError(ERROR_PATH_NOT_FOUND);
return INVALID_HANDLE_VALUE;
}
/* open the file */
InitializeObjectAttributes(&ObjectAttributes,
&NtPathU,
OBJ_CASE_INSENSITIVE,
NULL,
NULL);
Status = NtCreateFile(&FileHandle,
0,
&ObjectAttributes,
&IoStatusBlock,
NULL,
0,
FILE_SHARE_DELETE | FILE_SHARE_READ | FILE_SHARE_WRITE,
FILE_OPEN,
0,
NULL,
0);
if (!NT_SUCCESS(Status))
{
goto Cleanup;
}
/* create the search context */
IHeader = RtlAllocateHeap(hProcessHeap,
0,
sizeof(KERNEL32_FIND_DATA_HEADER) +
sizeof(KERNEL32_FIND_STREAM_DATA));
if (IHeader == NULL)
{
Status = STATUS_NO_MEMORY;
goto Cleanup;
}
IHeader->Type = StreamFind;
IData = (PKERNEL32_FIND_STREAM_DATA)(IHeader + 1);
/* capture all information about the streams */
IData->InfoLevel = InfoLevel;
IData->pCurrent = NULL;
IData->pFileStreamInfo = NULL;
do
{
BufferSize += 0x1000;
if (IData->pFileStreamInfo == NULL)
{
IData->pFileStreamInfo = RtlAllocateHeap(hProcessHeap,
0,
BufferSize);
if (IData->pFileStreamInfo == NULL)
{
Status = STATUS_NO_MEMORY;
break;
}
}
else
{
PFILE_STREAM_INFORMATION pfsi;
pfsi = RtlReAllocateHeap(hProcessHeap,
0,
IData->pFileStreamInfo,
BufferSize);
if (pfsi == NULL)
{
Status = STATUS_NO_MEMORY;
break;
}
IData->pFileStreamInfo = pfsi;
}
Status = NtQueryInformationFile(FileHandle,
&IoStatusBlock,
IData->pFileStreamInfo,
BufferSize,
FileStreamInformation);
} while (Status == STATUS_BUFFER_TOO_SMALL);
if (NT_SUCCESS(Status))
{
NtClose(FileHandle);
FileHandle = NULL;
/* select the first stream and return the information */
IData->pCurrent = IData->pFileStreamInfo;
InternalCopyStreamInfo(IData,
lpFindStreamData);
/* all done */
Status = STATUS_SUCCESS;
}
Cleanup:
if (FileHandle != NULL)
{
NtClose(FileHandle);
}
RtlFreeHeap(RtlGetProcessHeap(),
0,
NtPathU.Buffer);
if (!NT_SUCCESS(Status))
{
if (IHeader != NULL)
{
if (IData->pFileStreamInfo != NULL)
{
RtlFreeHeap(hProcessHeap,
0,
IData->pFileStreamInfo);
}
RtlFreeHeap(hProcessHeap,
0,
IHeader);
}
SetLastErrorByStatus(Status);
return INVALID_HANDLE_VALUE;
}
return (HANDLE)IHeader;
}
/*
* @implemented
*/
BOOL
WINAPI
FindNextStreamW(IN HANDLE hFindStream,
OUT LPVOID lpFindStreamData)
{
PKERNEL32_FIND_DATA_HEADER IHeader;
PKERNEL32_FIND_STREAM_DATA IData;
IHeader = (PKERNEL32_FIND_DATA_HEADER)hFindStream;
if (hFindStream == NULL || hFindStream == INVALID_HANDLE_VALUE ||
IHeader->Type != StreamFind)
{
SetLastError (ERROR_INVALID_HANDLE);
return FALSE;
}
IData = (PKERNEL32_FIND_STREAM_DATA)(IHeader + 1);
/* select next stream if possible */
if (IData->pCurrent->NextEntryOffset != 0)
{
IData->pCurrent = (PFILE_STREAM_INFORMATION)((ULONG_PTR)IData->pFileStreamInfo +
IData->pCurrent->NextEntryOffset);
}
else
{
SetLastError(ERROR_HANDLE_EOF);
return FALSE;
}
/* return the information */
InternalCopyStreamInfo(IData,
lpFindStreamData);
return TRUE;
}
/* EOF */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -