reactos/drivers/filesystems/fastfat_new/volume.c
Timo Kreuzer 912ce51ae6 [CMAKE]
Sync with trunk head (r48826)

svn path=/branches/cmake-bringup/; revision=48831
2010-09-20 17:27:52 +00:00

272 lines
7.1 KiB
C

/*
* PROJECT: ReactOS FAT file system driver
* LICENSE: GNU GPLv3 as published by the Free Software Foundation
* FILE: drivers/filesystems/fastfat/volume.c
* PURPOSE: Volume information
* PROGRAMMERS: Aleksey Bragin (aleksey@reactos.org)
*/
/* INCLUDES *****************************************************************/
#define NDEBUG
#include "fastfat.h"
/* FUNCTIONS ****************************************************************/
NTSTATUS
NTAPI
FatiQueryFsVolumeInfo(PVCB Vcb,
PFILE_FS_VOLUME_INFORMATION Buffer,
PLONG Length)
{
ULONG ByteSize;
NTSTATUS Status = STATUS_SUCCESS;
/* Deduct the minimum written length */
*Length -= FIELD_OFFSET(FILE_FS_VOLUME_INFORMATION, VolumeLabel[0]);
/* Zero it */
RtlZeroMemory(Buffer, sizeof(FILE_FS_VOLUME_INFORMATION));
DPRINT("Serial number 0x%x, label length %d\n",
Vcb->Vpb->SerialNumber, Vcb->Vpb->VolumeLabelLength);
/* Save serial number */
Buffer->VolumeSerialNumber = Vcb->Vpb->SerialNumber;
/* Set max byte size */
ByteSize = Vcb->Vpb->VolumeLabelLength;
/* Check buffer length and reduce byte size if needed */
if (*Length < Vcb->Vpb->VolumeLabelLength)
{
/* Copy only up to what buffer size was provided */
ByteSize = *Length;
Status = STATUS_BUFFER_OVERFLOW;
}
/* Copy volume label */
Buffer->VolumeLabelLength = Vcb->Vpb->VolumeLabelLength;
RtlCopyMemory(Buffer->VolumeLabel, Vcb->Vpb->VolumeLabel, ByteSize);
*Length -= ByteSize;
return Status;
}
NTSTATUS
NTAPI
FatiQueryFsSizeInfo(PVCB Vcb,
PFILE_FS_SIZE_INFORMATION Buffer,
PLONG Length)
{
FF_PARTITION *Partition;
NTSTATUS Status = STATUS_SUCCESS;
/* Deduct the minimum written length */
*Length -= sizeof(FILE_FS_SIZE_INFORMATION);
/* Zero it */
RtlZeroMemory(Buffer, sizeof(FILE_FS_SIZE_INFORMATION));
/* Reference FullFAT's partition */
Partition = Vcb->Ioman->pPartition;
/* Set values */
Buffer->AvailableAllocationUnits.LowPart = Partition->FreeClusterCount;
Buffer->TotalAllocationUnits.LowPart = Partition->NumClusters;
Buffer->SectorsPerAllocationUnit = Vcb->Bpb.SectorsPerCluster;
Buffer->BytesPerSector = Vcb->Bpb.BytesPerSector;
DPRINT1("Total %d, free %d, SPC %d, BPS %d\n", Partition->NumClusters,
Partition->FreeClusterCount, Vcb->Bpb.SectorsPerCluster, Vcb->Bpb.BytesPerSector);
return Status;
}
NTSTATUS
NTAPI
FatiQueryFsDeviceInfo(PVCB Vcb,
PFILE_FS_DEVICE_INFORMATION Buffer,
PLONG Length)
{
/* Deduct the minimum written length */
*Length -= sizeof(FILE_FS_DEVICE_INFORMATION);
/* Zero it */
RtlZeroMemory(Buffer, sizeof(FILE_FS_DEVICE_INFORMATION));
/* Set values */
Buffer->DeviceType = FILE_DEVICE_DISK;
Buffer->Characteristics = Vcb->TargetDeviceObject->Characteristics;
return STATUS_SUCCESS;
}
NTSTATUS
NTAPI
FatiQueryVolumeInfo(PFAT_IRP_CONTEXT IrpContext, PIRP Irp)
{
PFILE_OBJECT FileObject;
PIO_STACK_LOCATION IrpSp;
FILE_INFORMATION_CLASS InfoClass;
TYPE_OF_OPEN FileType;
PVCB Vcb;
PFCB Fcb;
PCCB Ccb;
LONG Length;
PVOID Buffer;
BOOLEAN VcbLocked = FALSE;
NTSTATUS Status = STATUS_SUCCESS;
/* Get IRP stack location */
IrpSp = IoGetCurrentIrpStackLocation(Irp);
/* Get the file object */
FileObject = IrpSp->FileObject;
/* Copy variables to something with shorter names */
InfoClass = IrpSp->Parameters.QueryVolume.FsInformationClass;
Length = IrpSp->Parameters.QueryVolume.Length;
Buffer = Irp->AssociatedIrp.SystemBuffer;
DPRINT("FatiQueryVolumeInfo\n", 0);
DPRINT("\tIrp = %08lx\n", Irp);
DPRINT("\tLength = %08lx\n", Length);
DPRINT("\tFsInformationClass = %08lx\n", InfoClass);
DPRINT("\tBuffer = %08lx\n", Buffer);
FileType = FatDecodeFileObject(FileObject, &Vcb, &Fcb, &Ccb);
DPRINT("Vcb %p, Fcb %p, Ccb %p, open type %d\n", Vcb, Fcb, Ccb, FileType);
switch (InfoClass)
{
case FileFsVolumeInformation:
/* Acquired the shared VCB lock */
if (!FatAcquireSharedVcb(IrpContext, Vcb))
{
ASSERT(FALSE);
}
/* Remember we locked it */
VcbLocked = TRUE;
/* Call FsVolumeInfo handler */
Status = FatiQueryFsVolumeInfo(Vcb, Buffer, &Length);
break;
case FileFsSizeInformation:
/* Call FsVolumeInfo handler */
Status = FatiQueryFsSizeInfo(Vcb, Buffer, &Length);
break;
case FileFsDeviceInformation:
Status = FatiQueryFsDeviceInfo(Vcb, Buffer, &Length);
break;
case FileFsAttributeInformation:
UNIMPLEMENTED;
//Status = FatiQueryFsAttributeInfo(IrpContext, Vcb, Buffer, &Length);
break;
case FileFsFullSizeInformation:
UNIMPLEMENTED;
//Status = FatiQueryFsFullSizeInfo(IrpContext, Vcb, Buffer, &Length);
break;
default:
Status = STATUS_INVALID_PARAMETER;
}
/* Set IoStatus.Information to amount of filled bytes */
Irp->IoStatus.Information = IrpSp->Parameters.QueryVolume.Length - Length;
/* Release VCB lock */
if (VcbLocked) FatReleaseVcb(IrpContext, Vcb);
/* Complete request and return status */
FatCompleteRequest(IrpContext, Irp, Status);
return Status;
}
NTSTATUS
NTAPI
FatQueryVolumeInfo(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
NTSTATUS Status;
BOOLEAN TopLevel, CanWait;
PFAT_IRP_CONTEXT IrpContext;
CanWait = TRUE;
TopLevel = FALSE;
Status = STATUS_INVALID_DEVICE_REQUEST;
/* Get CanWait flag */
if (IoGetCurrentIrpStackLocation(Irp)->FileObject != NULL)
CanWait = IoIsOperationSynchronous(Irp);
/* Enter FsRtl critical region */
FsRtlEnterFileSystem();
/* Set Top Level IRP if not set */
TopLevel = FatIsTopLevelIrp(Irp);
/* Build an irp context */
IrpContext = FatBuildIrpContext(Irp, CanWait);
/* Call the request handler */
Status = FatiQueryVolumeInfo(IrpContext, Irp);
/* Restore top level Irp */
if (TopLevel)
IoSetTopLevelIrp(NULL);
/* Leave FsRtl critical region */
FsRtlExitFileSystem();
return Status;
}
NTSTATUS
NTAPI
FatSetVolumeInfo(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
DPRINT1("FatSetVolumeInfo()\n");
return STATUS_NOT_IMPLEMENTED;
}
VOID
NTAPI
FatReadStreamFile(PVCB Vcb,
ULONGLONG ByteOffset,
ULONG ByteSize,
PBCB *Bcb,
PVOID *Buffer)
{
LARGE_INTEGER Offset;
Offset.QuadPart = ByteOffset;
if (!CcMapData(Vcb->StreamFileObject,
&Offset,
ByteSize,
TRUE, // FIXME: CanWait
Bcb,
Buffer))
{
ASSERT(FALSE);
}
}
BOOLEAN
NTAPI
FatCheckForDismount(IN PFAT_IRP_CONTEXT IrpContext,
PVCB Vcb,
IN BOOLEAN Force)
{
/* We never allow deletion of a volume for now */
return FALSE;
}
/* EOF */