[FASTFAT]

- Set the correct length in FsdGetFsVolumeInformation/FsdGetFsAttributeInformation, and write back partial data when returning STATUS_BUFFER_OVERFLOW
- Replace unnecessary checks with ASSERTs
CORE-9820 #resolve

svn path=/trunk/; revision=68175
This commit is contained in:
Thomas Faber 2015-06-17 19:19:39 +00:00
parent dc03297c13
commit 2abff2a105

View file

@ -23,28 +23,41 @@ FsdGetFsVolumeInformation(
PFILE_FS_VOLUME_INFORMATION FsVolumeInfo, PFILE_FS_VOLUME_INFORMATION FsVolumeInfo,
PULONG BufferLength) PULONG BufferLength)
{ {
NTSTATUS Status;
PDEVICE_EXTENSION DeviceExt; PDEVICE_EXTENSION DeviceExt;
DPRINT("FsdGetFsVolumeInformation()\n"); DPRINT("FsdGetFsVolumeInformation()\n");
DPRINT("FsVolumeInfo = %p\n", FsVolumeInfo); DPRINT("FsVolumeInfo = %p\n", FsVolumeInfo);
DPRINT("BufferLength %lu\n", *BufferLength); DPRINT("BufferLength %lu\n", *BufferLength);
DPRINT("Required length %lu\n", (sizeof(FILE_FS_VOLUME_INFORMATION) + DeviceObject->Vpb->VolumeLabelLength)); DPRINT("Required length %lu\n", FIELD_OFFSET(FILE_FS_VOLUME_INFORMATION, VolumeLabel) + DeviceObject->Vpb->VolumeLabelLength);
DPRINT("LabelLength %hu\n", DeviceObject->Vpb->VolumeLabelLength); DPRINT("LabelLength %hu\n", DeviceObject->Vpb->VolumeLabelLength);
DPRINT("Label %*.S\n", DeviceObject->Vpb->VolumeLabelLength / sizeof(WCHAR), DeviceObject->Vpb->VolumeLabel); DPRINT("Label %*.S\n", DeviceObject->Vpb->VolumeLabelLength / sizeof(WCHAR), DeviceObject->Vpb->VolumeLabel);
if (*BufferLength < sizeof(FILE_FS_VOLUME_INFORMATION)) ASSERT(*BufferLength >= sizeof(FILE_FS_VOLUME_INFORMATION));
return STATUS_INFO_LENGTH_MISMATCH; *BufferLength -= FIELD_OFFSET(FILE_FS_VOLUME_INFORMATION, VolumeLabel);
if (*BufferLength < (sizeof(FILE_FS_VOLUME_INFORMATION) + DeviceObject->Vpb->VolumeLabelLength))
return STATUS_BUFFER_OVERFLOW;
DeviceExt = DeviceObject->DeviceExtension; DeviceExt = DeviceObject->DeviceExtension;
/* valid entries */ /* valid entries */
FsVolumeInfo->VolumeSerialNumber = DeviceObject->Vpb->SerialNumber; FsVolumeInfo->VolumeSerialNumber = DeviceObject->Vpb->SerialNumber;
FsVolumeInfo->VolumeLabelLength = DeviceObject->Vpb->VolumeLabelLength; FsVolumeInfo->VolumeLabelLength = DeviceObject->Vpb->VolumeLabelLength;
RtlCopyMemory(FsVolumeInfo->VolumeLabel, DeviceObject->Vpb->VolumeLabel, FsVolumeInfo->VolumeLabelLength); if (*BufferLength < DeviceObject->Vpb->VolumeLabelLength)
{
Status = STATUS_BUFFER_OVERFLOW;
RtlCopyMemory(FsVolumeInfo->VolumeLabel,
DeviceObject->Vpb->VolumeLabel,
*BufferLength);
*BufferLength = 0;
}
else
{
Status = STATUS_SUCCESS;
RtlCopyMemory(FsVolumeInfo->VolumeLabel,
DeviceObject->Vpb->VolumeLabel,
FsVolumeInfo->VolumeLabelLength);
*BufferLength -= DeviceObject->Vpb->VolumeLabelLength;
}
if (DeviceExt->VolumeFcb->Flags & FCB_IS_FATX_ENTRY) if (DeviceExt->VolumeFcb->Flags & FCB_IS_FATX_ENTRY)
{ {
@ -64,12 +77,9 @@ FsdGetFsVolumeInformation(
FsVolumeInfo->SupportsObjects = FALSE; FsVolumeInfo->SupportsObjects = FALSE;
DPRINT("Finished FsdGetFsVolumeInformation()\n"); DPRINT("Finished FsdGetFsVolumeInformation()\n");
*BufferLength -= (sizeof(FILE_FS_VOLUME_INFORMATION) + DeviceObject->Vpb->VolumeLabelLength);
DPRINT("BufferLength %lu\n", *BufferLength); DPRINT("BufferLength %lu\n", *BufferLength);
return STATUS_SUCCESS; return Status;
} }
@ -80,29 +90,38 @@ FsdGetFsAttributeInformation(
PFILE_FS_ATTRIBUTE_INFORMATION FsAttributeInfo, PFILE_FS_ATTRIBUTE_INFORMATION FsAttributeInfo,
PULONG BufferLength) PULONG BufferLength)
{ {
PCWSTR pName; ULONG Length; NTSTATUS Status;
PCWSTR pName;
ULONG Length;
DPRINT("FsdGetFsAttributeInformation()\n"); DPRINT("FsdGetFsAttributeInformation()\n");
DPRINT("FsAttributeInfo = %p\n", FsAttributeInfo); DPRINT("FsAttributeInfo = %p\n", FsAttributeInfo);
DPRINT("BufferLength %lu\n", *BufferLength); DPRINT("BufferLength %lu\n", *BufferLength);
if (*BufferLength < sizeof (FILE_FS_ATTRIBUTE_INFORMATION)) ASSERT(*BufferLength >= sizeof(FILE_FS_ATTRIBUTE_INFORMATION));
return STATUS_INFO_LENGTH_MISMATCH; *BufferLength -= FIELD_OFFSET(FILE_FS_ATTRIBUTE_INFORMATION, FileSystemName);
if (DeviceExt->FatInfo.FatType == FAT32) if (DeviceExt->FatInfo.FatType == FAT32)
{ {
Length = 10;
pName = L"FAT32"; pName = L"FAT32";
} }
else else
{ {
Length = 6;
pName = L"FAT"; pName = L"FAT";
} }
DPRINT("Required length %lu\n", (sizeof(FILE_FS_ATTRIBUTE_INFORMATION) + Length)); Length = wcslen(pName) * sizeof(WCHAR);
DPRINT("Required length %lu\n", (FIELD_OFFSET(FILE_FS_ATTRIBUTE_INFORMATION, FileSystemName) + Length));
if (*BufferLength < (sizeof(FILE_FS_ATTRIBUTE_INFORMATION) + Length)) if (*BufferLength < Length)
return STATUS_BUFFER_OVERFLOW; {
Status = STATUS_BUFFER_OVERFLOW;
Length = *BufferLength;
}
else
{
Status = STATUS_SUCCESS;
}
FsAttributeInfo->FileSystemAttributes = FsAttributeInfo->FileSystemAttributes =
FILE_CASE_PRESERVED_NAMES | FILE_UNICODE_ON_DISK; FILE_CASE_PRESERVED_NAMES | FILE_UNICODE_ON_DISK;
@ -115,10 +134,10 @@ FsdGetFsAttributeInformation(
DPRINT("Finished FsdGetFsAttributeInformation()\n"); DPRINT("Finished FsdGetFsAttributeInformation()\n");
*BufferLength -= (sizeof(FILE_FS_ATTRIBUTE_INFORMATION) + Length); *BufferLength -= Length;
DPRINT("BufferLength %lu\n", *BufferLength); DPRINT("BufferLength %lu\n", *BufferLength);
return STATUS_SUCCESS; return Status;
} }
@ -135,8 +154,7 @@ FsdGetFsSizeInformation(
DPRINT("FsdGetFsSizeInformation()\n"); DPRINT("FsdGetFsSizeInformation()\n");
DPRINT("FsSizeInfo = %p\n", FsSizeInfo); DPRINT("FsSizeInfo = %p\n", FsSizeInfo);
if (*BufferLength < sizeof(FILE_FS_SIZE_INFORMATION)) ASSERT(*BufferLength >= sizeof(FILE_FS_SIZE_INFORMATION));
return STATUS_BUFFER_OVERFLOW;
DeviceExt = DeviceObject->DeviceExtension; DeviceExt = DeviceObject->DeviceExtension;
Status = CountAvailableClusters(DeviceExt, &FsSizeInfo->AvailableAllocationUnits); Status = CountAvailableClusters(DeviceExt, &FsSizeInfo->AvailableAllocationUnits);
@ -165,8 +183,7 @@ FsdGetFsDeviceInformation(
DPRINT("BufferLength %lu\n", *BufferLength); DPRINT("BufferLength %lu\n", *BufferLength);
DPRINT("Required length %lu\n", sizeof(FILE_FS_DEVICE_INFORMATION)); DPRINT("Required length %lu\n", sizeof(FILE_FS_DEVICE_INFORMATION));
if (*BufferLength < sizeof(FILE_FS_DEVICE_INFORMATION)) ASSERT(*BufferLength >= sizeof(FILE_FS_DEVICE_INFORMATION));
return STATUS_BUFFER_OVERFLOW;
FsDeviceInfo->DeviceType = FILE_DEVICE_DISK; FsDeviceInfo->DeviceType = FILE_DEVICE_DISK;
FsDeviceInfo->Characteristics = DeviceObject->Characteristics; FsDeviceInfo->Characteristics = DeviceObject->Characteristics;
@ -193,8 +210,7 @@ FsdGetFsFullSizeInformation(
DPRINT("FsdGetFsFullSizeInformation()\n"); DPRINT("FsdGetFsFullSizeInformation()\n");
DPRINT("FsSizeInfo = %p\n", FsSizeInfo); DPRINT("FsSizeInfo = %p\n", FsSizeInfo);
if (*BufferLength < sizeof(FILE_FS_FULL_SIZE_INFORMATION)) ASSERT(*BufferLength >= sizeof(FILE_FS_FULL_SIZE_INFORMATION));
return STATUS_BUFFER_OVERFLOW;
DeviceExt = DeviceObject->DeviceExtension; DeviceExt = DeviceObject->DeviceExtension;
Status = CountAvailableClusters(DeviceExt, &FsSizeInfo->CallerAvailableAllocationUnits); Status = CountAvailableClusters(DeviceExt, &FsSizeInfo->CallerAvailableAllocationUnits);
@ -445,11 +461,8 @@ VfatQueryVolumeInformation(
ExReleaseResourceLite(&((PDEVICE_EXTENSION)IrpContext->DeviceObject->DeviceExtension)->DirResource); ExReleaseResourceLite(&((PDEVICE_EXTENSION)IrpContext->DeviceObject->DeviceExtension)->DirResource);
if (NT_SUCCESS(RC))
IrpContext->Irp->IoStatus.Information = IrpContext->Irp->IoStatus.Information =
IrpContext->Stack->Parameters.QueryVolume.Length - BufferLength; IrpContext->Stack->Parameters.QueryVolume.Length - BufferLength;
else
IrpContext->Irp->IoStatus.Information = 0;
return RC; return RC;
} }