mirror of
https://github.com/reactos/reactos.git
synced 2024-09-28 13:34:53 +00:00
implemented FindFirstStreamW() and FindNextStreamW() (untested!)
svn path=/trunk/; revision=20882
This commit is contained in:
parent
e592a21cc6
commit
ba9679e15b
|
@ -320,6 +320,15 @@ typedef struct _FILE_STANDARD_INFORMATION
|
|||
BOOLEAN Directory;
|
||||
} FILE_STANDARD_INFORMATION, *PFILE_STANDARD_INFORMATION;
|
||||
|
||||
typedef struct _FILE_STREAM_INFORMATION
|
||||
{
|
||||
ULONG NextEntryOffset;
|
||||
ULONG StreamNameLength;
|
||||
LARGE_INTEGER StreamSize;
|
||||
LARGE_INTEGER StreamAllocationSize;
|
||||
WCHAR StreamName[1];
|
||||
} FILE_STREAM_INFORMATION, *PFILE_STREAM_INFORMATION;
|
||||
|
||||
typedef struct _FILE_NETWORK_OPEN_INFORMATION
|
||||
{
|
||||
LARGE_INTEGER CreationTime;
|
||||
|
|
|
@ -19,10 +19,6 @@
|
|||
|
||||
/* TYPES ********************************************************************/
|
||||
|
||||
#ifndef offsetof
|
||||
#define offsetof(TYPE, MEMBER) ((size_t) &( ((TYPE *) 0)->MEMBER ))
|
||||
#endif
|
||||
|
||||
#define FIND_DATA_SIZE (16*1024)
|
||||
|
||||
typedef struct _KERNEL32_FIND_FILE_DATA
|
||||
|
@ -32,9 +28,41 @@ typedef struct _KERNEL32_FIND_FILE_DATA
|
|||
PFILE_BOTH_DIR_INFORMATION pFileInfo;
|
||||
} KERNEL32_FIND_FILE_DATA, *PKERNEL32_FIND_FILE_DATA;
|
||||
|
||||
typedef struct _KERNEL32_FIND_STREAM_DATA
|
||||
{
|
||||
STREAM_INFO_LEVELS InfoLevel;
|
||||
PFILE_STREAM_INFORMATION pFileStreamInfo;
|
||||
PFILE_STREAM_INFORMATION pCurrent;
|
||||
} KERNEL32_FIND_STREAM_DATA, *PKERNEL32_FIND_STREAM_DATA;
|
||||
|
||||
typedef enum _KERNEL32_FIND_DATA_TYPE
|
||||
{
|
||||
FileFind,
|
||||
StreamFind
|
||||
} KERNEL32_FIND_DATA_TYPE;
|
||||
|
||||
typedef struct _KERNEL32_FIND_DATA_HEADER
|
||||
{
|
||||
KERNEL32_FIND_DATA_TYPE Type;
|
||||
} KERNEL32_FIND_DATA_HEADER, *PKERNEL32_FIND_DATA_HEADER;
|
||||
|
||||
|
||||
/* FUNCTIONS ****************************************************************/
|
||||
|
||||
static __inline PKERNEL32_FIND_FILE_DATA
|
||||
HandleToFindData(IN HANDLE Handle)
|
||||
{
|
||||
PKERNEL32_FIND_DATA_HEADER FindData = (PKERNEL32_FIND_DATA_HEADER)Handle;
|
||||
|
||||
if (Handle != NULL && Handle != INVALID_HANDLE_VALUE &&
|
||||
FindData->Type == FileFind)
|
||||
{
|
||||
return (PKERNEL32_FIND_FILE_DATA)(FindData + 1);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
VOID
|
||||
InternalCopyFindDataW(LPWIN32_FIND_DATAW lpFindFileData,
|
||||
PFILE_BOTH_DIR_INFORMATION lpFileInfo)
|
||||
|
@ -122,13 +150,22 @@ InternalFindNextFile (
|
|||
PUNICODE_STRING SearchPattern
|
||||
)
|
||||
{
|
||||
PKERNEL32_FIND_DATA_HEADER IHeader;
|
||||
PKERNEL32_FIND_FILE_DATA IData;
|
||||
IO_STATUS_BLOCK IoStatusBlock;
|
||||
NTSTATUS Status;
|
||||
|
||||
DPRINT("InternalFindNextFile(%lx)\n", hFindFile);
|
||||
|
||||
IData = (PKERNEL32_FIND_FILE_DATA)hFindFile;
|
||||
IHeader = (PKERNEL32_FIND_DATA_HEADER)hFindFile;
|
||||
if (hFindFile == NULL || hFindFile == INVALID_HANDLE_VALUE ||
|
||||
IHeader->Type != FileFind)
|
||||
{
|
||||
SetLastError (ERROR_INVALID_HANDLE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
IData = (PKERNEL32_FIND_FILE_DATA)(IHeader + 1);
|
||||
|
||||
while (1)
|
||||
{
|
||||
|
@ -178,6 +215,7 @@ InternalFindFirstFile (
|
|||
)
|
||||
{
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
PKERNEL32_FIND_DATA_HEADER IHeader;
|
||||
PKERNEL32_FIND_FILE_DATA IData;
|
||||
IO_STATUS_BLOCK IoStatusBlock;
|
||||
UNICODE_STRING NtPathU;
|
||||
|
@ -302,10 +340,11 @@ InternalFindFirstFile (
|
|||
|
||||
DPRINT("NtPathU \'%S\'\n", NtPathU.Buffer);
|
||||
|
||||
IData = RtlAllocateHeap (hProcessHeap,
|
||||
HEAP_ZERO_MEMORY,
|
||||
sizeof(KERNEL32_FIND_FILE_DATA) + FIND_DATA_SIZE);
|
||||
if (NULL == IData)
|
||||
IHeader = RtlAllocateHeap (hProcessHeap,
|
||||
HEAP_ZERO_MEMORY,
|
||||
sizeof(KERNEL32_FIND_DATA_HEADER) +
|
||||
sizeof(KERNEL32_FIND_FILE_DATA) + FIND_DATA_SIZE);
|
||||
if (NULL == IHeader)
|
||||
{
|
||||
RtlFreeHeap (hProcessHeap,
|
||||
0,
|
||||
|
@ -320,6 +359,9 @@ InternalFindFirstFile (
|
|||
return NULL;
|
||||
}
|
||||
|
||||
IHeader->Type = FileFind;
|
||||
IData = (PKERNEL32_FIND_FILE_DATA)(IHeader + 1);
|
||||
|
||||
/* change pattern: "*.*" --> "*" */
|
||||
if (wcscmp (SearchPattern, L"*.*"))
|
||||
{
|
||||
|
@ -348,7 +390,7 @@ InternalFindFirstFile (
|
|||
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
RtlFreeHeap (hProcessHeap, 0, IData);
|
||||
RtlFreeHeap (hProcessHeap, 0, IHeader);
|
||||
if (NULL != SlashlessFileName)
|
||||
{
|
||||
RtlFreeHeap(hProcessHeap,
|
||||
|
@ -362,7 +404,7 @@ InternalFindFirstFile (
|
|||
IData->pFileInfo->FileIndex = 0;
|
||||
IData->DirectoryOnly = DirectoryOnly;
|
||||
|
||||
bResult = InternalFindNextFile((HANDLE)IData, &PatternStr);
|
||||
bResult = InternalFindNextFile((HANDLE)IHeader, &PatternStr);
|
||||
if (NULL != SlashlessFileName)
|
||||
{
|
||||
RtlFreeHeap(hProcessHeap,
|
||||
|
@ -372,11 +414,11 @@ InternalFindFirstFile (
|
|||
|
||||
if (!bResult)
|
||||
{
|
||||
FindClose((HANDLE)IData);
|
||||
FindClose((HANDLE)IHeader);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return IData;
|
||||
return (HANDLE)IHeader;
|
||||
}
|
||||
|
||||
|
||||
|
@ -390,6 +432,7 @@ FindFirstFileA (
|
|||
LPWIN32_FIND_DATAA lpFindFileData
|
||||
)
|
||||
{
|
||||
PKERNEL32_FIND_DATA_HEADER IHeader;
|
||||
PKERNEL32_FIND_FILE_DATA IData;
|
||||
UNICODE_STRING FileNameU;
|
||||
ANSI_STRING FileName;
|
||||
|
@ -407,16 +450,18 @@ FindFirstFileA (
|
|||
&FileName,
|
||||
TRUE);
|
||||
|
||||
IData = InternalFindFirstFile (FileNameU.Buffer, FALSE);
|
||||
IHeader = InternalFindFirstFile (FileNameU.Buffer, FALSE);
|
||||
|
||||
RtlFreeUnicodeString (&FileNameU);
|
||||
|
||||
if (IData == NULL)
|
||||
if (IHeader == NULL)
|
||||
{
|
||||
DPRINT("Failing request\n");
|
||||
return INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
IData = (PKERNEL32_FIND_FILE_DATA)(IHeader + 1);
|
||||
|
||||
DPRINT("IData->pFileInfo->FileNameLength %d\n",
|
||||
IData->pFileInfo->FileNameLength);
|
||||
|
||||
|
@ -424,7 +469,7 @@ FindFirstFileA (
|
|||
InternalCopyFindDataA(lpFindFileData, IData->pFileInfo);
|
||||
|
||||
|
||||
return (HANDLE)IData;
|
||||
return (HANDLE)IHeader;
|
||||
}
|
||||
|
||||
|
||||
|
@ -439,20 +484,14 @@ FindNextFileA (
|
|||
{
|
||||
PKERNEL32_FIND_FILE_DATA IData;
|
||||
|
||||
if (hFindFile == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
SetLastError (ERROR_INVALID_HANDLE);
|
||||
DPRINT("Failing request\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
IData = (PKERNEL32_FIND_FILE_DATA)hFindFile;
|
||||
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);
|
||||
|
||||
|
@ -472,7 +511,7 @@ FindClose (
|
|||
HANDLE hFindFile
|
||||
)
|
||||
{
|
||||
PKERNEL32_FIND_FILE_DATA IData;
|
||||
PKERNEL32_FIND_DATA_HEADER IHeader;
|
||||
|
||||
DPRINT("FindClose(hFindFile %x)\n",hFindFile);
|
||||
|
||||
|
@ -482,10 +521,33 @@ FindClose (
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
IData = (PKERNEL32_FIND_FILE_DATA)hFindFile;
|
||||
IHeader = (PKERNEL32_FIND_DATA_HEADER)hFindFile;
|
||||
|
||||
CloseHandle (IData->DirectoryHandle);
|
||||
RtlFreeHeap (hProcessHeap, 0, IData);
|
||||
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;
|
||||
}
|
||||
|
@ -522,20 +584,14 @@ FindNextFileW (
|
|||
{
|
||||
PKERNEL32_FIND_FILE_DATA IData;
|
||||
|
||||
if (hFindFile == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
SetLastError (ERROR_INVALID_HANDLE);
|
||||
DPRINT("Failing request\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
IData = (PKERNEL32_FIND_FILE_DATA)hFindFile;
|
||||
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);
|
||||
|
||||
|
@ -555,6 +611,7 @@ FindFirstFileExW (LPCWSTR lpFileName,
|
|||
LPVOID lpSearchFilter,
|
||||
DWORD dwAdditionalFlags)
|
||||
{
|
||||
PKERNEL32_FIND_DATA_HEADER IHeader;
|
||||
PKERNEL32_FIND_FILE_DATA IData;
|
||||
|
||||
if (fInfoLevelId != FindExInfoStandard)
|
||||
|
@ -570,17 +627,19 @@ FindFirstFileExW (LPCWSTR lpFileName,
|
|||
return INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
IData = InternalFindFirstFile (lpFileName, fSearchOp == FindExSearchLimitToDirectories ? TRUE : FALSE);
|
||||
if (IData == NULL)
|
||||
IHeader = InternalFindFirstFile (lpFileName, fSearchOp == FindExSearchLimitToDirectories ? TRUE : FALSE);
|
||||
if (IHeader == NULL)
|
||||
{
|
||||
DPRINT("Failing request\n");
|
||||
return INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
/* copy data into WIN32_FIND_DATA structure */
|
||||
IData = (PKERNEL32_FIND_FILE_DATA)(IHeader + 1);
|
||||
|
||||
/* copy data into WIN32_FIND_DATA structure */
|
||||
InternalCopyFindDataW((LPWIN32_FIND_DATAW)lpFindFileData, IData->pFileInfo);
|
||||
|
||||
return (HANDLE)IData;
|
||||
return (HANDLE)IHeader;
|
||||
}
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return INVALID_HANDLE_VALUE;
|
||||
|
@ -600,6 +659,7 @@ FindFirstFileExA (
|
|||
DWORD dwAdditionalFlags
|
||||
)
|
||||
{
|
||||
PKERNEL32_FIND_DATA_HEADER IHeader;
|
||||
PKERNEL32_FIND_FILE_DATA IData;
|
||||
UNICODE_STRING FileNameU;
|
||||
ANSI_STRING FileNameA;
|
||||
|
@ -625,22 +685,263 @@ FindFirstFileExA (
|
|||
else
|
||||
RtlOemStringToUnicodeString (&FileNameU, &FileNameA, TRUE);
|
||||
|
||||
IData = InternalFindFirstFile (FileNameU.Buffer, FALSE);
|
||||
IHeader = InternalFindFirstFile (FileNameU.Buffer, FALSE);
|
||||
|
||||
RtlFreeUnicodeString (&FileNameU);
|
||||
|
||||
if (IData == NULL)
|
||||
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_DATAW *StreamData = (WIN32_FIND_STREAM_DATAW*)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);
|
||||
}
|
||||
|
||||
RtlFreeUnicodeString(&NtPathU);
|
||||
|
||||
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 */
|
||||
|
|
|
@ -243,9 +243,11 @@ FindFirstFileA@8
|
|||
FindFirstFileExA@24
|
||||
FindFirstFileExW@24
|
||||
FindFirstFileW@8
|
||||
FindFirstStreamW@16
|
||||
FindNextChangeNotification@4
|
||||
FindNextFileA@8
|
||||
FindNextFileW@8
|
||||
FindNextStreamW@8
|
||||
FindFirstVolumeA@8
|
||||
FindFirstVolumeMountPointA@12
|
||||
FindFirstVolumeMountPointW@12
|
||||
|
|
|
@ -809,6 +809,15 @@ typedef struct _WIN32_FIND_DATAW {
|
|||
WCHAR cFileName[MAX_PATH];
|
||||
WCHAR cAlternateFileName[14];
|
||||
} WIN32_FIND_DATAW,*PWIN32_FIND_DATAW,*LPWIN32_FIND_DATAW;
|
||||
#if (_WIN32_WINNT >= 0x0501)
|
||||
typedef enum _STREAM_INFO_LEVELS {
|
||||
FindStreamInfoStandard
|
||||
} STREAM_INFO_LEVELS;
|
||||
typedef struct _WIN32_FIND_STREAM_DATAW {
|
||||
LARGE_INTEGER StreamSize;
|
||||
WCHAR cStreamName[MAX_PATH + 36];
|
||||
} WIN32_FIND_STREAM_DATAW, *PWIN32_FIND_STREAM_DATAW, *LPWIN32_FIND_STREAM_DATAW;
|
||||
#endif
|
||||
typedef struct _WIN32_STREAM_ID {
|
||||
DWORD dwStreamId;
|
||||
DWORD dwStreamAttributes;
|
||||
|
@ -1288,6 +1297,9 @@ HANDLE WINAPI FindFirstFileA(LPCSTR,LPWIN32_FIND_DATAA);
|
|||
HANDLE WINAPI FindFirstFileW(LPCWSTR,LPWIN32_FIND_DATAW);
|
||||
HANDLE WINAPI FindFirstFileExA(LPCSTR,FINDEX_INFO_LEVELS,PVOID,FINDEX_SEARCH_OPS,PVOID,DWORD);
|
||||
HANDLE WINAPI FindFirstFileExW(LPCWSTR,FINDEX_INFO_LEVELS,PVOID,FINDEX_SEARCH_OPS,PVOID,DWORD);
|
||||
#if (_WIN32_WINNT >= 0x0501)
|
||||
HANDLE WINAPI FindFirstStreamW(LPCWSTR,STREAM_INFO_LEVELS,LPVOID,DWORD);
|
||||
#endif
|
||||
BOOL WINAPI FindFirstFreeAce(PACL,PVOID*);
|
||||
#if (_WIN32_WINNT >= 0x0500)
|
||||
HANDLE WINAPI FindFirstVolumeA(LPCSTR,DWORD);
|
||||
|
@ -1298,6 +1310,9 @@ HANDLE WINAPI FindFirstVolumeMountPointW(LPWSTR,LPWSTR,DWORD);
|
|||
BOOL WINAPI FindNextChangeNotification(HANDLE);
|
||||
BOOL WINAPI FindNextFileA(HANDLE,LPWIN32_FIND_DATAA);
|
||||
BOOL WINAPI FindNextFileW(HANDLE,LPWIN32_FIND_DATAW);
|
||||
#if (_WIN32_WINNT >= 0x0501)
|
||||
BOOL WINAPI FindNextStreamW(HANDLE,LPVOID);
|
||||
#endif
|
||||
#if (_WIN32_WINNT >= 0x0500)
|
||||
BOOL WINAPI FindNextVolumeA(HANDLE,LPCSTR,DWORD);
|
||||
BOOL WINAPI FindNextVolumeW(HANDLE,LPWSTR,DWORD);
|
||||
|
@ -1988,6 +2003,9 @@ BOOL WINAPI MapUserPhysicalPagesScatter(PVOID*,ULONG_PTR,PULONG_PTR);
|
|||
#ifdef UNICODE
|
||||
typedef STARTUPINFOW STARTUPINFO,*LPSTARTUPINFO;
|
||||
typedef WIN32_FIND_DATAW WIN32_FIND_DATA,*LPWIN32_FIND_DATA;
|
||||
#if (_WIN32_WINNT >= 0x0501)
|
||||
typedef WIN32_FIND_STREAM_DATAW WIN32_FIND_STREAM_DATA,*LPWIN32_FIND_STREAM_DATA;
|
||||
#endif
|
||||
typedef HW_PROFILE_INFOW HW_PROFILE_INFO,*LPHW_PROFILE_INFO;
|
||||
typedef ENUMRESLANGPROCW ENUMRESLANGPROC;
|
||||
typedef ENUMRESNAMEPROCW ENUMRESNAMEPROC;
|
||||
|
|
Loading…
Reference in a new issue