mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 18:15:11 +00:00
[NTFS]
Implement FileStreamInformation class for IRP_MJ_QUERY_INFORMATION. It allows enumerating streams for a given file svn path=/trunk/; revision=68808
This commit is contained in:
parent
57c8922ec2
commit
6f4dfe4e09
1 changed files with 75 additions and 0 deletions
|
@ -218,6 +218,74 @@ NtfsGetNetworkOpenInformation(PNTFS_FCB Fcb,
|
|||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static
|
||||
NTSTATUS
|
||||
NtfsGetSteamInformation(PNTFS_FCB Fcb,
|
||||
PDEVICE_EXTENSION DeviceExt,
|
||||
PFILE_STREAM_INFORMATION StreamInfo,
|
||||
PULONG BufferLength)
|
||||
{
|
||||
NTSTATUS Status;
|
||||
ULONG CurrentSize;
|
||||
PNTFS_ATTR_RECORD Attribute;
|
||||
PFILE_RECORD_HEADER FileRecord;
|
||||
PFILE_STREAM_INFORMATION CurrentInfo = StreamInfo, Previous = NULL;
|
||||
|
||||
if (*BufferLength < sizeof(FILE_STREAM_INFORMATION))
|
||||
return STATUS_BUFFER_OVERFLOW;
|
||||
|
||||
FileRecord = ExAllocatePoolWithTag(NonPagedPool, DeviceExt->NtfsInfo.BytesPerFileRecord, TAG_NTFS);
|
||||
if (FileRecord == NULL)
|
||||
{
|
||||
DPRINT1("Not enough memory!\n");
|
||||
return STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
Status = ReadFileRecord(DeviceExt, Fcb->MFTIndex, FileRecord);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
DPRINT1("Can't find record!\n");
|
||||
ExFreePoolWithTag(FileRecord, TAG_NTFS);
|
||||
return Status;
|
||||
}
|
||||
|
||||
Status = STATUS_SUCCESS;
|
||||
Attribute = (PNTFS_ATTR_RECORD)((ULONG_PTR)FileRecord + FileRecord->AttributeOffset);
|
||||
while (Attribute < (PNTFS_ATTR_RECORD)((ULONG_PTR)FileRecord + FileRecord->BytesInUse) &&
|
||||
Attribute->Type != AttributeEnd)
|
||||
{
|
||||
if (Attribute->Type == AttributeData)
|
||||
{
|
||||
CurrentSize = FIELD_OFFSET(FILE_STREAM_INFORMATION, StreamName) + Attribute->NameLength * sizeof(WCHAR);
|
||||
|
||||
if (CurrentSize > *BufferLength)
|
||||
{
|
||||
Status = STATUS_BUFFER_OVERFLOW;
|
||||
break;
|
||||
}
|
||||
|
||||
CurrentInfo->NextEntryOffset = 0;
|
||||
CurrentInfo->StreamNameLength = Attribute->NameLength * sizeof(WCHAR);
|
||||
CurrentInfo->StreamSize.QuadPart = AttributeDataLength(Attribute);
|
||||
CurrentInfo->StreamAllocationSize.QuadPart = AttributeAllocatedLength(Attribute);
|
||||
RtlMoveMemory(CurrentInfo->StreamName, (PWCHAR)((ULONG_PTR)Attribute + Attribute->NameOffset), CurrentInfo->StreamNameLength);
|
||||
|
||||
if (Previous != NULL)
|
||||
{
|
||||
Previous->NextEntryOffset = (ULONG_PTR)CurrentInfo - (ULONG_PTR)Previous;
|
||||
}
|
||||
Previous = CurrentInfo;
|
||||
CurrentInfo = (PFILE_STREAM_INFORMATION)((ULONG_PTR)CurrentInfo + CurrentSize);
|
||||
*BufferLength -= CurrentSize;
|
||||
}
|
||||
|
||||
Attribute = (PNTFS_ATTR_RECORD)((ULONG_PTR)Attribute + Attribute->Length);
|
||||
}
|
||||
|
||||
ExFreePoolWithTag(FileRecord, TAG_NTFS);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/*
|
||||
* FUNCTION: Retrieve the specified file information
|
||||
*/
|
||||
|
@ -296,6 +364,13 @@ NtfsQueryInformation(PNTFS_IRP_CONTEXT IrpContext)
|
|||
&BufferLength);
|
||||
break;
|
||||
|
||||
case FileStreamInformation:
|
||||
Status = NtfsGetSteamInformation(Fcb,
|
||||
DeviceObject->DeviceExtension,
|
||||
SystemBuffer,
|
||||
&BufferLength);
|
||||
break;
|
||||
|
||||
case FileAlternateNameInformation:
|
||||
case FileAllInformation:
|
||||
DPRINT1("Unimplemented information class %u\n", FileInformationClass);
|
||||
|
|
Loading…
Reference in a new issue