/*
* ReactOS kernel
- * Copyright (C) 2002 ReactOS Team
+ * Copyright (C) 2002, 2014 ReactOS Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* PROJECT: ReactOS kernel
* FILE: drivers/filesystem/ntfs/volume.c
* PURPOSE: NTFS filesystem driver
- * PROGRAMMER: Eric Kohl
+ * PROGRAMMERS: Eric Kohl
+ * Pierre Schweitzer (pierre@reactos.org)
*/
/* INCLUDES *****************************************************************/
/* FUNCTIONS ****************************************************************/
-static NTSTATUS
+ULONGLONG
+NtfsGetFreeClusters(PDEVICE_EXTENSION DeviceExt)
+{
+ NTSTATUS Status;
+ PFILE_RECORD_HEADER BitmapRecord;
+ PNTFS_ATTR_CONTEXT DataContext;
+ ULONGLONG BitmapDataSize;
+ PCHAR BitmapData;
+ ULONGLONG FreeClusters = 0;
+ ULONG Read = 0;
+ RTL_BITMAP Bitmap;
+
+ DPRINT1("NtfsGetFreeClusters(%p)\n", DeviceExt);
+
+ BitmapRecord = ExAllocatePoolWithTag(NonPagedPool,
+ DeviceExt->NtfsInfo.BytesPerFileRecord,
+ TAG_NTFS);
+ if (BitmapRecord == NULL)
+ {
+ return 0;
+ }
+
+ Status = ReadFileRecord(DeviceExt, NTFS_FILE_BITMAP, BitmapRecord);
+ if (!NT_SUCCESS(Status))
+ {
+ ExFreePoolWithTag(BitmapRecord, TAG_NTFS);
+ return 0;
+ }
+
+ Status = FindAttribute(DeviceExt, BitmapRecord, AttributeData, L"", 0, &DataContext, NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ ExFreePoolWithTag(BitmapRecord, TAG_NTFS);
+ return 0;
+ }
+
+ BitmapDataSize = AttributeDataLength(&DataContext->Record);
+ ASSERT((BitmapDataSize * 8) >= DeviceExt->NtfsInfo.ClusterCount);
+ BitmapData = ExAllocatePoolWithTag(NonPagedPool, ROUND_UP(BitmapDataSize, DeviceExt->NtfsInfo.BytesPerSector), TAG_NTFS);
+ if (BitmapData == NULL)
+ {
+ ReleaseAttributeContext(DataContext);
+ ExFreePoolWithTag(BitmapRecord, TAG_NTFS);
+ return 0;
+ }
+
+ /* FIXME: Totally underoptimized! */
+ for (; Read < BitmapDataSize; Read += DeviceExt->NtfsInfo.BytesPerSector)
+ {
+ ReadAttribute(DeviceExt, DataContext, Read, (PCHAR)((ULONG_PTR)BitmapData + Read), DeviceExt->NtfsInfo.BytesPerSector);
+ }
+ ReleaseAttributeContext(DataContext);
+
+ DPRINT1("Total clusters: %I64x\n", DeviceExt->NtfsInfo.ClusterCount);
+ DPRINT1("Total clusters in bitmap: %I64x\n", BitmapDataSize * 8);
+ DPRINT1("Diff in size: %I64d B\n", ((BitmapDataSize * 8) - DeviceExt->NtfsInfo.ClusterCount) * DeviceExt->NtfsInfo.SectorsPerCluster * DeviceExt->NtfsInfo.BytesPerSector);
+
+ RtlInitializeBitMap(&Bitmap, (PULONG)BitmapData, DeviceExt->NtfsInfo.ClusterCount);
+ FreeClusters = RtlNumberOfClearBits(&Bitmap);
+
+ ExFreePoolWithTag(BitmapData, TAG_NTFS);
+ ExFreePoolWithTag(BitmapRecord, TAG_NTFS);
+
+ return FreeClusters;
+}
+
+/**
+* NtfsAllocateClusters
+* Allocates a run of clusters. The run allocated might be smaller than DesiredClusters.
+*/
+NTSTATUS
+NtfsAllocateClusters(PDEVICE_EXTENSION DeviceExt,
+ ULONG FirstDesiredCluster,
+ ULONG DesiredClusters,
+ PULONG FirstAssignedCluster,
+ PULONG AssignedClusters)
+{
+ NTSTATUS Status;
+ PFILE_RECORD_HEADER BitmapRecord;
+ PNTFS_ATTR_CONTEXT DataContext;
+ ULONGLONG BitmapDataSize;
+ PCHAR BitmapData;
+ ULONGLONG FreeClusters = 0;
+ RTL_BITMAP Bitmap;
+
+ DPRINT1("NtfsAllocateClusters(%p, %lu, %lu, %p, %p)\n", DeviceExt, FirstDesiredCluster, DesiredClusters, FirstAssignedCluster, AssignedClusters);
+
+ BitmapRecord = ExAllocatePoolWithTag(NonPagedPool,
+ DeviceExt->NtfsInfo.BytesPerFileRecord,
+ TAG_NTFS);
+ if (BitmapRecord == NULL)
+ {
+ return 0;
+ }
+
+ Status = ReadFileRecord(DeviceExt, NTFS_FILE_BITMAP, BitmapRecord);
+ if (!NT_SUCCESS(Status))
+ {
+ ExFreePoolWithTag(BitmapRecord, TAG_NTFS);
+ return 0;
+ }
+
+ Status = FindAttribute(DeviceExt, BitmapRecord, AttributeData, L"", 0, &DataContext, NULL);
+ if (!NT_SUCCESS(Status))
+ {
+ ExFreePoolWithTag(BitmapRecord, TAG_NTFS);
+ return 0;
+ }
+
+ BitmapDataSize = AttributeDataLength(&DataContext->Record);
+ BitmapDataSize = min(BitmapDataSize, 0xffffffff);
+ ASSERT((BitmapDataSize * 8) >= DeviceExt->NtfsInfo.ClusterCount);
+ BitmapData = ExAllocatePoolWithTag(NonPagedPool, ROUND_UP(BitmapDataSize, DeviceExt->NtfsInfo.BytesPerSector), TAG_NTFS);
+ if (BitmapData == NULL)
+ {
+ ReleaseAttributeContext(DataContext);
+ ExFreePoolWithTag(BitmapRecord, TAG_NTFS);
+ return 0;
+ }
+
+ DPRINT1("Total clusters: %I64x\n", DeviceExt->NtfsInfo.ClusterCount);
+ DPRINT1("Total clusters in bitmap: %I64x\n", BitmapDataSize * 8);
+ DPRINT1("Diff in size: %I64d B\n", ((BitmapDataSize * 8) - DeviceExt->NtfsInfo.ClusterCount) * DeviceExt->NtfsInfo.SectorsPerCluster * DeviceExt->NtfsInfo.BytesPerSector);
+
+ ReadAttribute(DeviceExt, DataContext, 0, (PCHAR)BitmapData, (ULONG)BitmapDataSize);
+
+ RtlInitializeBitMap(&Bitmap, (PULONG)BitmapData, DeviceExt->NtfsInfo.ClusterCount);
+ FreeClusters = RtlNumberOfClearBits(&Bitmap);
+
+ if (FreeClusters >= DesiredClusters)
+ {
+ // TODO: Observe MFT reservation zone
+
+ // Can we get one contiguous run?
+ ULONG AssignedRun = RtlFindClearBitsAndSet(&Bitmap, DesiredClusters, FirstDesiredCluster);
+ ULONG LengthWritten;
+
+ if (AssignedRun != 0xFFFFFFFF)
+ {
+ *FirstAssignedCluster = AssignedRun;
+ *AssignedClusters = DesiredClusters;
+ }
+ else
+ {
+ // we can't get one contiguous run
+ *AssignedClusters = RtlFindNextForwardRunClear(&Bitmap, FirstDesiredCluster, FirstAssignedCluster);
+
+ if (*AssignedClusters == 0)
+ {
+ // we couldn't find any runs starting at DesiredFirstCluster
+ *AssignedClusters = RtlFindLongestRunClear(&Bitmap, FirstAssignedCluster);
+ }
+
+ }
+
+ Status = WriteAttribute(DeviceExt, DataContext, 0, BitmapData, (ULONG)BitmapDataSize, &LengthWritten);
+ }
+ else
+ Status = STATUS_DISK_FULL;
+
+
+ ReleaseAttributeContext(DataContext);
+
+ ExFreePoolWithTag(BitmapData, TAG_NTFS);
+ ExFreePoolWithTag(BitmapRecord, TAG_NTFS);
+
+ return Status;
+}
+
+static
+NTSTATUS
NtfsGetFsVolumeInformation(PDEVICE_OBJECT DeviceObject,
PFILE_FS_VOLUME_INFORMATION FsVolumeInfo,
PULONG BufferLength)
{
- DPRINT("NtfsGetFsVolumeInformation() called\n");
- DPRINT("FsVolumeInfo = %p\n", FsVolumeInfo);
- DPRINT("BufferLength %lu\n", *BufferLength);
+ DPRINT("NtfsGetFsVolumeInformation() called\n");
+ DPRINT("FsVolumeInfo = %p\n", FsVolumeInfo);
+ DPRINT("BufferLength %lu\n", *BufferLength);
- DPRINT("Vpb %p\n", DeviceObject->Vpb);
+ DPRINT("Vpb %p\n", DeviceObject->Vpb);
- DPRINT("Required length %lu\n",
- sizeof(FILE_FS_VOLUME_INFORMATION) + DeviceObject->Vpb->VolumeLabelLength);
- DPRINT("LabelLength %hu\n",
- DeviceObject->Vpb->VolumeLabelLength);
- DPRINT("Label %*.S\n",
- DeviceObject->Vpb->VolumeLabelLength / sizeof(WCHAR),
- DeviceObject->Vpb->VolumeLabel);
+ DPRINT("Required length %lu\n",
+ sizeof(FILE_FS_VOLUME_INFORMATION) + DeviceObject->Vpb->VolumeLabelLength);
+ DPRINT("LabelLength %hu\n",
+ DeviceObject->Vpb->VolumeLabelLength);
+ DPRINT("Label %.*S\n",
+ DeviceObject->Vpb->VolumeLabelLength / sizeof(WCHAR),
+ DeviceObject->Vpb->VolumeLabel);
- if (*BufferLength < sizeof(FILE_FS_VOLUME_INFORMATION))
- return STATUS_INFO_LENGTH_MISMATCH;
+ if (*BufferLength < sizeof(FILE_FS_VOLUME_INFORMATION))
+ return STATUS_INFO_LENGTH_MISMATCH;
- if (*BufferLength < (sizeof(FILE_FS_VOLUME_INFORMATION) + DeviceObject->Vpb->VolumeLabelLength))
- return STATUS_BUFFER_OVERFLOW;
+ if (*BufferLength < (sizeof(FILE_FS_VOLUME_INFORMATION) + DeviceObject->Vpb->VolumeLabelLength))
+ return STATUS_BUFFER_OVERFLOW;
- /* valid entries */
- FsVolumeInfo->VolumeSerialNumber = DeviceObject->Vpb->SerialNumber;
- FsVolumeInfo->VolumeLabelLength = DeviceObject->Vpb->VolumeLabelLength;
- memcpy(FsVolumeInfo->VolumeLabel,
- DeviceObject->Vpb->VolumeLabel,
- DeviceObject->Vpb->VolumeLabelLength);
+ /* valid entries */
+ FsVolumeInfo->VolumeSerialNumber = DeviceObject->Vpb->SerialNumber;
+ FsVolumeInfo->VolumeLabelLength = DeviceObject->Vpb->VolumeLabelLength;
+ memcpy(FsVolumeInfo->VolumeLabel,
+ DeviceObject->Vpb->VolumeLabel,
+ DeviceObject->Vpb->VolumeLabelLength);
- /* dummy entries */
- FsVolumeInfo->VolumeCreationTime.QuadPart = 0;
- FsVolumeInfo->SupportsObjects = FALSE;
+ /* dummy entries */
+ FsVolumeInfo->VolumeCreationTime.QuadPart = 0;
+ FsVolumeInfo->SupportsObjects = FALSE;
- *BufferLength -= (sizeof(FILE_FS_VOLUME_INFORMATION) + DeviceObject->Vpb->VolumeLabelLength);
+ *BufferLength -= (sizeof(FILE_FS_VOLUME_INFORMATION) + DeviceObject->Vpb->VolumeLabelLength);
- DPRINT("BufferLength %lu\n", *BufferLength);
- DPRINT("NtfsGetFsVolumeInformation() done\n");
+ DPRINT("BufferLength %lu\n", *BufferLength);
+ DPRINT("NtfsGetFsVolumeInformation() done\n");
- return STATUS_SUCCESS;
+ return STATUS_SUCCESS;
}
-static NTSTATUS
+static
+NTSTATUS
NtfsGetFsAttributeInformation(PDEVICE_EXTENSION DeviceExt,
PFILE_FS_ATTRIBUTE_INFORMATION FsAttributeInfo,
PULONG BufferLength)
{
- DPRINT("NtfsGetFsAttributeInformation()\n");
- DPRINT("FsAttributeInfo = %p\n", FsAttributeInfo);
- DPRINT("BufferLength %lu\n", *BufferLength);
- DPRINT("Required length %lu\n", (sizeof(FILE_FS_ATTRIBUTE_INFORMATION) + 8));
+ UNREFERENCED_PARAMETER(DeviceExt);
- if (*BufferLength < sizeof (FILE_FS_ATTRIBUTE_INFORMATION))
- return(STATUS_INFO_LENGTH_MISMATCH);
+ DPRINT("NtfsGetFsAttributeInformation()\n");
+ DPRINT("FsAttributeInfo = %p\n", FsAttributeInfo);
+ DPRINT("BufferLength %lu\n", *BufferLength);
+ DPRINT("Required length %lu\n", (sizeof(FILE_FS_ATTRIBUTE_INFORMATION) + 8));
- if (*BufferLength < (sizeof(FILE_FS_ATTRIBUTE_INFORMATION) + 8))
- return(STATUS_BUFFER_OVERFLOW);
+ if (*BufferLength < sizeof (FILE_FS_ATTRIBUTE_INFORMATION))
+ return STATUS_INFO_LENGTH_MISMATCH;
- FsAttributeInfo->FileSystemAttributes =
- FILE_CASE_PRESERVED_NAMES | FILE_UNICODE_ON_DISK;
- FsAttributeInfo->MaximumComponentNameLength = 255;
- FsAttributeInfo->FileSystemNameLength = 8;
+ if (*BufferLength < (sizeof(FILE_FS_ATTRIBUTE_INFORMATION) + 8))
+ return STATUS_BUFFER_OVERFLOW;
- memcpy(FsAttributeInfo->FileSystemName, L"NTFS", 8);
+ FsAttributeInfo->FileSystemAttributes =
+ FILE_CASE_PRESERVED_NAMES | FILE_UNICODE_ON_DISK | FILE_READ_ONLY_VOLUME;
+ FsAttributeInfo->MaximumComponentNameLength = 255;
+ FsAttributeInfo->FileSystemNameLength = 8;
- DPRINT("Finished NtfsGetFsAttributeInformation()\n");
+ memcpy(FsAttributeInfo->FileSystemName, L"NTFS", 8);
- *BufferLength -= (sizeof(FILE_FS_ATTRIBUTE_INFORMATION) + 8);
- DPRINT("BufferLength %lu\n", *BufferLength);
+ DPRINT("Finished NtfsGetFsAttributeInformation()\n");
- return(STATUS_SUCCESS);
+ *BufferLength -= (sizeof(FILE_FS_ATTRIBUTE_INFORMATION) + 8);
+ DPRINT("BufferLength %lu\n", *BufferLength);
+
+ return STATUS_SUCCESS;
}
-static NTSTATUS
+static
+NTSTATUS
NtfsGetFsSizeInformation(PDEVICE_OBJECT DeviceObject,
PFILE_FS_SIZE_INFORMATION FsSizeInfo,
PULONG BufferLength)
{
- PDEVICE_EXTENSION DeviceExt;
- NTSTATUS Status = STATUS_SUCCESS;
+ PDEVICE_EXTENSION DeviceExt;
+ NTSTATUS Status = STATUS_SUCCESS;
- DPRINT("NtfsGetFsSizeInformation()\n");
- DPRINT("FsSizeInfo = %p\n", FsSizeInfo);
+ DPRINT("NtfsGetFsSizeInformation()\n");
+ DPRINT("FsSizeInfo = %p\n", FsSizeInfo);
- if (*BufferLength < sizeof(FILE_FS_SIZE_INFORMATION))
- return(STATUS_BUFFER_OVERFLOW);
+ if (*BufferLength < sizeof(FILE_FS_SIZE_INFORMATION))
+ return STATUS_BUFFER_OVERFLOW;
- DeviceExt = DeviceObject->DeviceExtension;
+ DeviceExt = DeviceObject->DeviceExtension;
- FsSizeInfo->AvailableAllocationUnits.QuadPart = 0;
- FsSizeInfo->TotalAllocationUnits.QuadPart = DeviceExt->NtfsInfo.SectorCount; /* ?? */
- FsSizeInfo->SectorsPerAllocationUnit = DeviceExt->NtfsInfo.SectorsPerCluster;
- FsSizeInfo->BytesPerSector = DeviceExt->NtfsInfo.BytesPerSector;
+ FsSizeInfo->AvailableAllocationUnits.QuadPart = NtfsGetFreeClusters(DeviceExt);
+ FsSizeInfo->TotalAllocationUnits.QuadPart = DeviceExt->NtfsInfo.ClusterCount;
+ FsSizeInfo->SectorsPerAllocationUnit = DeviceExt->NtfsInfo.SectorsPerCluster;
+ FsSizeInfo->BytesPerSector = DeviceExt->NtfsInfo.BytesPerSector;
- DPRINT("Finished NtfsGetFsSizeInformation()\n");
- if (NT_SUCCESS(Status))
- *BufferLength -= sizeof(FILE_FS_SIZE_INFORMATION);
+ DPRINT("Finished NtfsGetFsSizeInformation()\n");
+ if (NT_SUCCESS(Status))
+ *BufferLength -= sizeof(FILE_FS_SIZE_INFORMATION);
- return(Status);
+ return Status;
}
-static NTSTATUS
-NtfsGetFsDeviceInformation(PFILE_FS_DEVICE_INFORMATION FsDeviceInfo,
+static
+NTSTATUS
+NtfsGetFsDeviceInformation(PDEVICE_OBJECT DeviceObject,
+ PFILE_FS_DEVICE_INFORMATION FsDeviceInfo,
PULONG BufferLength)
{
- DPRINT("NtfsGetFsDeviceInformation()\n");
- DPRINT("FsDeviceInfo = %p\n", FsDeviceInfo);
- DPRINT("BufferLength %lu\n", *BufferLength);
- DPRINT("Required length %lu\n", sizeof(FILE_FS_DEVICE_INFORMATION));
+ DPRINT("NtfsGetFsDeviceInformation()\n");
+ DPRINT("FsDeviceInfo = %p\n", FsDeviceInfo);
+ DPRINT("BufferLength %lu\n", *BufferLength);
+ DPRINT("Required length %lu\n", sizeof(FILE_FS_DEVICE_INFORMATION));
- if (*BufferLength < sizeof(FILE_FS_DEVICE_INFORMATION))
- return(STATUS_BUFFER_OVERFLOW);
+ if (*BufferLength < sizeof(FILE_FS_DEVICE_INFORMATION))
+ return STATUS_BUFFER_OVERFLOW;
- FsDeviceInfo->DeviceType = FILE_DEVICE_DISK;
- FsDeviceInfo->Characteristics = 0; /* FIXME: fix this !! */
+ FsDeviceInfo->DeviceType = FILE_DEVICE_DISK;
+ FsDeviceInfo->Characteristics = DeviceObject->Characteristics;
- DPRINT("NtfsGetFsDeviceInformation() finished.\n");
+ DPRINT("NtfsGetFsDeviceInformation() finished.\n");
- *BufferLength -= sizeof(FILE_FS_DEVICE_INFORMATION);
- DPRINT("BufferLength %lu\n", *BufferLength);
+ *BufferLength -= sizeof(FILE_FS_DEVICE_INFORMATION);
+ DPRINT("BufferLength %lu\n", *BufferLength);
- return(STATUS_SUCCESS);
+ return STATUS_SUCCESS;
}
-
NTSTATUS
NtfsQueryVolumeInformation(PNTFS_IRP_CONTEXT IrpContext)
{
- PIRP Irp;
- PDEVICE_OBJECT DeviceObject;
- FS_INFORMATION_CLASS FsInformationClass;
- PIO_STACK_LOCATION Stack;
- NTSTATUS Status = STATUS_SUCCESS;
- PVOID SystemBuffer;
- ULONG BufferLength;
-
- DPRINT("NtfsQueryVolumeInformation() called\n");
-
- ASSERT(IrpContext);
-
- Irp = IrpContext->Irp;
- DeviceObject = IrpContext->DeviceObject;
- Stack = IoGetCurrentIrpStackLocation(Irp);
- FsInformationClass = Stack->Parameters.QueryVolume.FsInformationClass;
- BufferLength = Stack->Parameters.QueryVolume.Length;
- SystemBuffer = Irp->AssociatedIrp.SystemBuffer;
- RtlZeroMemory(SystemBuffer, BufferLength);
-
- DPRINT("FsInformationClass %d\n", FsInformationClass);
- DPRINT("SystemBuffer %p\n", SystemBuffer);
-
- switch (FsInformationClass)
- {
- case FileFsVolumeInformation:
- Status = NtfsGetFsVolumeInformation(DeviceObject,
- SystemBuffer,
- &BufferLength);
- break;
-
- case FileFsAttributeInformation:
- Status = NtfsGetFsAttributeInformation(DeviceObject->DeviceExtension,
- SystemBuffer,
- &BufferLength);
- break;
-
- case FileFsSizeInformation:
- Status = NtfsGetFsSizeInformation(DeviceObject,
- SystemBuffer,
- &BufferLength);
- break;
-
- case FileFsDeviceInformation:
- Status = NtfsGetFsDeviceInformation(SystemBuffer,
- &BufferLength);
- break;
-
- default:
- Status = STATUS_NOT_SUPPORTED;
- }
-
- if (NT_SUCCESS(Status))
- Irp->IoStatus.Information =
- Stack->Parameters.QueryVolume.Length - BufferLength;
- else
- Irp->IoStatus.Information = 0;
-
- return Status;
+ PIRP Irp;
+ PDEVICE_OBJECT DeviceObject;
+ FS_INFORMATION_CLASS FsInformationClass;
+ PIO_STACK_LOCATION Stack;
+ NTSTATUS Status = STATUS_SUCCESS;
+ PVOID SystemBuffer;
+ ULONG BufferLength;
+ PDEVICE_EXTENSION DeviceExt;
+
+ DPRINT("NtfsQueryVolumeInformation() called\n");
+
+ ASSERT(IrpContext);
+
+ Irp = IrpContext->Irp;
+ DeviceObject = IrpContext->DeviceObject;
+ DeviceExt = DeviceObject->DeviceExtension;
+ Stack = IrpContext->Stack;
+
+ if (!ExAcquireResourceSharedLite(&DeviceExt->DirResource,
+ BooleanFlagOn(IrpContext->Flags, IRPCONTEXT_CANWAIT)))
+ {
+ return NtfsMarkIrpContextForQueue(IrpContext);
+ }
+
+ FsInformationClass = Stack->Parameters.QueryVolume.FsInformationClass;
+ BufferLength = Stack->Parameters.QueryVolume.Length;
+ SystemBuffer = Irp->AssociatedIrp.SystemBuffer;
+ RtlZeroMemory(SystemBuffer, BufferLength);
+
+ DPRINT("FsInformationClass %d\n", FsInformationClass);
+ DPRINT("SystemBuffer %p\n", SystemBuffer);
+
+ switch (FsInformationClass)
+ {
+ case FileFsVolumeInformation:
+ Status = NtfsGetFsVolumeInformation(DeviceObject,
+ SystemBuffer,
+ &BufferLength);
+ break;
+
+ case FileFsAttributeInformation:
+ Status = NtfsGetFsAttributeInformation(DeviceObject->DeviceExtension,
+ SystemBuffer,
+ &BufferLength);
+ break;
+
+ case FileFsSizeInformation:
+ Status = NtfsGetFsSizeInformation(DeviceObject,
+ SystemBuffer,
+ &BufferLength);
+ break;
+
+ case FileFsDeviceInformation:
+ Status = NtfsGetFsDeviceInformation(DeviceObject,
+ SystemBuffer,
+ &BufferLength);
+ break;
+
+ default:
+ Status = STATUS_NOT_SUPPORTED;
+ }
+
+ ExReleaseResourceLite(&DeviceExt->DirResource);
+
+ if (NT_SUCCESS(Status))
+ Irp->IoStatus.Information =
+ Stack->Parameters.QueryVolume.Length - BufferLength;
+ else
+ Irp->IoStatus.Information = 0;
+
+ return Status;
}
NTSTATUS
NtfsSetVolumeInformation(PNTFS_IRP_CONTEXT IrpContext)
{
- PIRP Irp;
-
- DPRINT("NtfsSetVolumeInformation() called\n");
+ PIRP Irp;
- ASSERT(IrpContext);
+ DPRINT("NtfsSetVolumeInformation() called\n");
- Irp = IrpContext->Irp;
- Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
- Irp->IoStatus.Information = 0;
+ ASSERT(IrpContext);
+
+ Irp = IrpContext->Irp;
+ Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
+ Irp->IoStatus.Information = 0;
- return STATUS_NOT_SUPPORTED;
+ return STATUS_NOT_SUPPORTED;
}
/* EOF */