[FASTFAT_NEW]

- Implement opening an existing DCB.
- Add a bunch of useful macros and helper functions and use them throughout the code.
- Implement in-memory setendoffile set information class. On-disk to be done.
- Implement user fs ctrl wrapper with stubs.
- Fill up QueryVolumeInfo with classes it should handle. Silence up a warning about classes it should reject.

svn path=/trunk/; revision=48498
This commit is contained in:
Aleksey Bragin 2010-08-09 21:33:17 +00:00
parent e787f57ee7
commit 03d3e84856
7 changed files with 714 additions and 24 deletions

View file

@ -188,9 +188,98 @@ FatiOpenExistingDcb(IN PFAT_IRP_CONTEXT IrpContext,
IN BOOLEAN DeleteOnClose)
{
IO_STATUS_BLOCK Iosb = {{0}};
PCCB Ccb;
Iosb.Status = STATUS_NOT_IMPLEMENTED;
UNIMPLEMENTED;
/* Exclusively lock this FCB */
FatAcquireExclusiveFcb(IrpContext, Dcb);
/* Check if it's a delete-on-close of a root DCB */
if (FatNodeType(Dcb) == FAT_NTC_ROOT_DCB && DeleteOnClose)
{
Iosb.Status = STATUS_CANNOT_DELETE;
/* Release the lock and return */
FatReleaseFcb(IrpContext, Dcb);
return Iosb;
}
/*if (NoEaKnowledge && NodeType(Dcb) != FAT_NTC_ROOT_DCB &&
!FatIsFat32(Vcb))
{
UNIMPLEMENTED;
}*/
/* Check the create disposition and desired access */
if ((CreateDisposition != FILE_OPEN) &&
(CreateDisposition != FILE_OPEN_IF))
{
Iosb.Status = STATUS_OBJECT_NAME_COLLISION;
/* Release the lock and return */
FatReleaseFcb(IrpContext, Dcb);
return Iosb;
}
#if 0
if (!FatCheckFileAccess(IrpContext,
Dcb->DirentFatFlags,
DesiredAccess))
{
Iosb.Status = STATUS_ACCESS_DENIED;
try_return( Iosb );
}
#endif
/* If it's already opened - check share access */
if (Dcb->OpenCount > 0)
{
Iosb.Status = IoCheckShareAccess(*DesiredAccess,
ShareAccess,
FileObject,
&Dcb->ShareAccess,
TRUE);
if (!NT_SUCCESS(Iosb.Status))
{
/* Release the lock and return */
FatReleaseFcb(IrpContext, Dcb);
return Iosb;
}
}
else
{
IoSetShareAccess(*DesiredAccess,
ShareAccess,
FileObject,
&Dcb->ShareAccess);
}
/* Set the file object */
Ccb = FatCreateCcb(IrpContext);
FatSetFileObject(FileObject,
UserDirectoryOpen,
Dcb,
Ccb);
/* Increase counters */
Dcb->UncleanCount++;
Dcb->OpenCount++;
Vcb->OpenFileCount++;
if (IsFileObjectReadOnly(FileObject)) Vcb->ReadOnlyCount++;
/* Set delete on close */
if (DeleteOnClose)
SetFlag(Ccb->Flags, CCB_DELETE_ON_CLOSE);
/* Clear delay close flag */
ClearFlag(Dcb->State, FCB_STATE_DELAY_CLOSE);
/* That's it */
Iosb.Status = STATUS_SUCCESS;
Iosb.Information = FILE_OPENED;
/* Release the lock */
FatReleaseFcb(IrpContext, Dcb);
return Iosb;
}

View file

@ -524,4 +524,32 @@ FatIsTopLevelIrp(IN PIRP Irp)
return FALSE;
}
VOID
NTAPI
FatNotifyReportChange(IN PFAT_IRP_CONTEXT IrpContext,
IN PVCB Vcb,
IN PFCB Fcb,
IN ULONG Filter,
IN ULONG Action)
{
if (Fcb->FullFileName.Buffer == NULL)
FatSetFullFileNameInFcb(IrpContext, Fcb);
ASSERT(Fcb->FullFileName.Length != 0 );
ASSERT(Fcb->FileNameLength != 0 );
ASSERT(Fcb->FullFileName.Length > Fcb->FileNameLength );
ASSERT(Fcb->FullFileName.Buffer[(Fcb->FullFileName.Length - Fcb->FileNameLength)/sizeof(WCHAR) - 1] == L'\\' );
FsRtlNotifyFullReportChange(Vcb->NotifySync,
&Vcb->NotifyList,
(PSTRING)&Fcb->FullFileName,
(USHORT)(Fcb->FullFileName.Length -
Fcb->FileNameLength),
NULL,
NULL,
Filter,
Action,
NULL);
}
/* EOF */

View file

@ -51,6 +51,18 @@
)
#define IsFileObjectReadOnly(FO) (!((FO)->WriteAccess | (FO)->DeleteAccess))
#define IsFileDeleted(FCB) (FlagOn((FCB)->State, FCB_STATE_DELETE_ON_CLOSE) && ((FCB)->UncleanCount == 0))
BOOLEAN
FORCEINLINE
FatIsIoRangeValid(IN LARGE_INTEGER Start, IN ULONG Length)
{
/* Check if it's more than 32bits, or if the length causes 32bit overflow.
FAT-specific! */
return !(Start.HighPart || Start.LowPart + Length < Start.LowPart);
}
NTSYSAPI
NTSTATUS
@ -230,6 +242,13 @@ FatMapUserBuffer(PIRP Irp);
BOOLEAN NTAPI
FatIsTopLevelIrp(IN PIRP Irp);
VOID NTAPI
FatNotifyReportChange(IN PFAT_IRP_CONTEXT IrpContext,
IN PVCB Vcb,
IN PFCB Fcb,
IN ULONG Filter,
IN ULONG Action);
/* --------------------------------------------------------- fullfat.c */
FF_T_SINT32

View file

@ -263,11 +263,7 @@ FatQueryInformation(PDEVICE_OBJECT DeviceObject, PIRP Irp)
FsRtlEnterFileSystem();
/* Set Top Level IRP if not set */
if (IoGetTopLevelIrp() == NULL)
{
IoSetTopLevelIrp(Irp);
TopLevel = TRUE;
}
TopLevel = FatIsTopLevelIrp(Irp);
/* Build an irp context */
IrpContext = FatBuildIrpContext(Irp, CanWait);
@ -284,12 +280,394 @@ FatQueryInformation(PDEVICE_OBJECT DeviceObject, PIRP Irp)
return Status;
}
NTSTATUS
NTAPI
FatSetEndOfFileInfo(IN PFAT_IRP_CONTEXT IrpContext,
IN PIRP Irp,
IN PFILE_OBJECT FileObject,
IN PVCB Vcb,
IN PFCB Fcb)
{
PFILE_END_OF_FILE_INFORMATION Buffer;
ULONG NewFileSize;
ULONG InitialFileSize;
ULONG InitialValidDataLength;
//ULONG InitialValidDataToDisk;
BOOLEAN CacheMapInitialized = FALSE;
BOOLEAN ResourceAcquired = FALSE;
NTSTATUS Status;
Buffer = Irp->AssociatedIrp.SystemBuffer;
if (FatNodeType(Fcb) != FAT_NTC_FCB)
{
/* Trying to change size of a dir */
Status = STATUS_INVALID_DEVICE_REQUEST;
return Status;
}
/* Validate new size */
if (!FatIsIoRangeValid(Buffer->EndOfFile, 0))
{
Status = STATUS_DISK_FULL;
return Status;
}
NewFileSize = Buffer->EndOfFile.LowPart;
/* Lookup allocation size if needed */
if (Fcb->Header.AllocationSize.QuadPart == (LONGLONG)-1)
UNIMPLEMENTED;//FatLookupFileAllocationSize(IrpContext, Fcb);
/* Cache the file if there is a data section */
if (FileObject->SectionObjectPointer->DataSectionObject &&
(FileObject->SectionObjectPointer->SharedCacheMap == NULL) &&
!FlagOn(Irp->Flags, IRP_PAGING_IO))
{
if (FlagOn(FileObject->Flags, FO_CLEANUP_COMPLETE))
{
/* This is a really weird condition */
UNIMPLEMENTED;
//Raise(STATUS_FILE_CLOSED);
}
/* Initialize the cache map */
CcInitializeCacheMap(FileObject,
(PCC_FILE_SIZES)&Fcb->Header.AllocationSize,
FALSE,
&FatGlobalData.CacheMgrCallbacks,
Fcb);
CacheMapInitialized = TRUE;
}
/* Lazy write case */
if (IoGetCurrentIrpStackLocation(Irp)->Parameters.SetFile.AdvanceOnly)
{
if (!IsFileDeleted(Fcb) &&
(Fcb->Condition == FcbGood))
{
/* Clamp the new file size */
if (NewFileSize >= Fcb->Header.FileSize.LowPart)
NewFileSize = Fcb->Header.FileSize.LowPart;
ASSERT(NewFileSize <= Fcb->Header.AllocationSize.LowPart);
/* Never reduce the file size here! */
// TODO: Actually change file size
DPRINT1("Actually changing file size is missing\n");
/* Notify about file size change */
FatNotifyReportChange(IrpContext,
Vcb,
Fcb,
FILE_NOTIFY_CHANGE_SIZE,
FILE_ACTION_MODIFIED);
}
else
{
DPRINT1("Cannot set size on deleted file\n");
}
Status = STATUS_SUCCESS;
return Status;
}
if ( NewFileSize > Fcb->Header.AllocationSize.LowPart )
{
// TODO: Increase file size
DPRINT1("Actually changing file size is missing\n");
}
if (Fcb->Header.FileSize.LowPart != NewFileSize)
{
if (NewFileSize < Fcb->Header.FileSize.LowPart)
{
if (!MmCanFileBeTruncated(FileObject->SectionObjectPointer,
&Buffer->EndOfFile))
{
Status = STATUS_USER_MAPPED_FILE;
/* Free up resources if necessary */
if (CacheMapInitialized)
CcUninitializeCacheMap(FileObject, NULL, NULL);
return Status;
}
ResourceAcquired = ExAcquireResourceExclusiveLite(Fcb->Header.PagingIoResource, TRUE);
}
/* Set new file sizes */
InitialFileSize = Fcb->Header.FileSize.LowPart;
InitialValidDataLength = Fcb->Header.ValidDataLength.LowPart;
//InitialValidDataToDisk = Fcb->ValidDataToDisk;
Fcb->Header.FileSize.LowPart = NewFileSize;
/* Adjust valid data length if new size is less than that */
if (Fcb->Header.ValidDataLength.LowPart > NewFileSize)
Fcb->Header.ValidDataLength.LowPart = NewFileSize;
//if (Fcb->ValidDataToDisk > NewFileSize)
// Fcb->ValidDataToDisk = NewFileSize;
DPRINT1("New file size is 0x%08lx\n", NewFileSize);
/* Update cache mapping */
CcSetFileSizes(FileObject,
(PCC_FILE_SIZES)&Fcb->Header.AllocationSize);
/* Notify about size change */
FatNotifyReportChange(IrpContext,
Vcb,
Fcb,
FILE_NOTIFY_CHANGE_SIZE,
FILE_ACTION_MODIFIED);
/* Set truncate on close flag */
SetFlag(Fcb->State, FCB_STATE_TRUNCATE_ON_CLOSE);
}
/* Set modified flag */
FileObject->Flags |= FO_FILE_MODIFIED;
/* Free up resources if necessary */
if (CacheMapInitialized)
CcUninitializeCacheMap(FileObject, NULL, NULL);
if (ResourceAcquired)
ExReleaseResourceLite(Fcb->Header.PagingIoResource);
return STATUS_SUCCESS;
}
NTSTATUS
NTAPI
FatiSetInformation(IN PFAT_IRP_CONTEXT IrpContext,
IN PIRP Irp)
{
PFILE_OBJECT FileObject;
PIO_STACK_LOCATION IrpSp;
FILE_INFORMATION_CLASS InfoClass;
TYPE_OF_OPEN TypeOfOpen;
PVCB Vcb;
PFCB Fcb;
PCCB Ccb;
LONG Length;
PVOID Buffer;
NTSTATUS Status = STATUS_SUCCESS;
BOOLEAN VcbAcquired = FALSE, FcbAcquired = FALSE;
/* Get IRP stack location */
IrpSp = IoGetCurrentIrpStackLocation(Irp);
/* Get the file object */
FileObject = IrpSp->FileObject;
/* Copy variables to something with shorter names */
InfoClass = IrpSp->Parameters.SetFile.FileInformationClass;
Length = IrpSp->Parameters.SetFile.Length;
Buffer = Irp->AssociatedIrp.SystemBuffer;
DPRINT("FatiSetInformation\n", 0);
DPRINT("\tIrp = %08lx\n", Irp);
DPRINT("\tLength = %08lx\n", Length);
DPRINT("\tFileInformationClass = %08lx\n", InfoClass);
DPRINT("\tFileObject = %08lx\n", IrpSp->Parameters.SetFile.FileObject);
DPRINT("\tBuffer = %08lx\n", Buffer);
TypeOfOpen = FatDecodeFileObject(FileObject, &Vcb, &Fcb, &Ccb);
DPRINT("Vcb %p, Fcb %p, Ccb %p, open type %d\n", Vcb, Fcb, Ccb, TypeOfOpen);
switch (TypeOfOpen)
{
case UserVolumeOpen:
Status = STATUS_INVALID_PARAMETER;
/* Complete request and return status */
FatCompleteRequest(IrpContext, Irp, Status);
return Status;
case UserFileOpen:
/* Check oplocks */
if (!FlagOn(Fcb->State, FCB_STATE_PAGEFILE) &&
((InfoClass == FileEndOfFileInformation) ||
(InfoClass == FileAllocationInformation)))
{
Status = FsRtlCheckOplock(&Fcb->Fcb.Oplock,
Irp,
IrpContext,
NULL,
NULL);
if (Status != STATUS_SUCCESS)
{
/* Complete request and return status */
FatCompleteRequest(IrpContext, Irp, Status);
return Status;
}
/* Update Fast IO flag */
Fcb->Header.IsFastIoPossible = FatIsFastIoPossible(Fcb);
}
break;
case UserDirectoryOpen:
break;
default:
Status = STATUS_INVALID_PARAMETER;
/* Complete request and return status */
FatCompleteRequest(IrpContext, Irp, Status);
return Status;
}
/* If it's a root DCB - fail */
if (FatNodeType(Fcb) == FAT_NTC_ROOT_DCB)
{
if (InfoClass == FileDispositionInformation)
Status = STATUS_CANNOT_DELETE;
else
Status = STATUS_INVALID_PARAMETER;
/* Complete request and return status */
FatCompleteRequest(IrpContext, Irp, Status);
return Status;
}
/* Acquire the volume lock if needed */
if (InfoClass == FileDispositionInformation ||
InfoClass == FileRenameInformation)
{
if (!FatAcquireExclusiveVcb(IrpContext, Vcb))
{
UNIMPLEMENTED;
}
VcbAcquired = TRUE;
}
/* Acquire FCB lock */
if (!FlagOn(Fcb->State, FCB_STATE_PAGEFILE))
{
if (!FatAcquireExclusiveFcb(IrpContext, Fcb))
{
UNIMPLEMENTED;
}
FcbAcquired = TRUE;
}
// TODO: VerifyFcb
switch (InfoClass)
{
case FileBasicInformation:
//Status = FatSetBasicInfo(IrpContext, Irp, Fcb, Ccb);
DPRINT1("FileBasicInformation\n");
break;
case FileDispositionInformation:
if (FlagOn(Vcb->State, VCB_STATE_FLAG_DEFERRED_FLUSH) &&
!FlagOn(IrpContext->Flags, IRPCONTEXT_CANWAIT))
{
UNIMPLEMENTED;
}
else
{
//Status = FatSetDispositionInfo(IrpContext, Irp, FileObject, Fcb);
DPRINT1("FileDispositionInformation\n");
}
break;
case FileRenameInformation:
if (!FlagOn(IrpContext->Flags, IRPCONTEXT_CANWAIT))
{
UNIMPLEMENTED;
}
else
{
//Status = FatSetRenameInfo(IrpContext, Irp, Vcb, Fcb, Ccb);
DPRINT1("FileRenameInformation\n");
/* NOTE: Request must not be completed here!
That's why Irp/IrpContext are set to NULL */
if (Status == STATUS_PENDING)
{
Irp = NULL;
IrpContext = NULL;
}
}
break;
case FilePositionInformation:
//Status = FatSetPositionInfo(IrpContext, Irp, FileObject);
DPRINT1("FilePositionInformation\n");
break;
case FileLinkInformation:
Status = STATUS_INVALID_DEVICE_REQUEST;
break;
case FileAllocationInformation:
//Status = FatSetAllocationInfo(IrpContext, Irp, Fcb, FileObject);
DPRINT1("FileAllocationInformation\n");
break;
case FileEndOfFileInformation:
Status = FatSetEndOfFileInfo(IrpContext, Irp, FileObject, Vcb, Fcb);
break;
default:
Status = STATUS_INVALID_PARAMETER;
}
/* Release locks */
if (FcbAcquired) FatReleaseFcb(IrpContext, Fcb);
if (VcbAcquired) FatReleaseVcb(IrpContext, Vcb);
/* Complete request and return status */
FatCompleteRequest(IrpContext, Irp, Status);
return Status;
}
NTSTATUS
NTAPI
FatSetInformation(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
DPRINT1("FatSetInformation()\n");
return STATUS_NOT_IMPLEMENTED;
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);
/* Perform the actual read */
Status = FatiSetInformation(IrpContext, Irp);
/* Restore top level Irp */
if (TopLevel) IoSetTopLevelIrp(NULL);
/* Leave FsRtl critical region */
FsRtlExitFileSystem();
return Status;
}
/* EOF */

View file

@ -13,13 +13,181 @@
/* FUNCTIONS ****************************************************************/
NTSTATUS
NTAPI
FatOplockRequest(IN PFAT_IRP_CONTEXT IrpContext,
IN PIRP Irp)
{
NTSTATUS Status;
DPRINT1("Oplock request!\n");
Status = STATUS_INVALID_DEVICE_REQUEST;
FatCompleteRequest(IrpContext, Irp, Status);
return Status;
}
NTSTATUS
NTAPI
FatMarkVolumeDirty(IN PFAT_IRP_CONTEXT IrpContext,
IN PIRP Irp)
{
NTSTATUS Status;
DPRINT1("Marking volume as dirty\n");
Status = STATUS_SUCCESS;
FatCompleteRequest(IrpContext, Irp, Status);
return Status;
}
NTSTATUS
NTAPI
FatUserFsCtrl(PFAT_IRP_CONTEXT IrpContext, PIRP Irp)
{
DPRINT1("FatUserFsCtrl()\n");
FatCompleteRequest(IrpContext, Irp, STATUS_INVALID_DEVICE_REQUEST);
return STATUS_INVALID_DEVICE_REQUEST;
PIO_STACK_LOCATION IrpSp;
NTSTATUS Status;
ULONG Code;
/* Get current IRP stack location */
IrpSp = IoGetCurrentIrpStackLocation(Irp);
Code = IrpSp->Parameters.FileSystemControl.FsControlCode;
/* Set the wait flag */
if (Irp->RequestorMode != KernelMode &&
(Code & 3) == METHOD_NEITHER)
{
SetFlag(IrpContext->Flags, IRPCONTEXT_CANWAIT);
}
/* Branch according to the code */
switch (Code)
{
case FSCTL_REQUEST_OPLOCK_LEVEL_1:
case FSCTL_REQUEST_OPLOCK_LEVEL_2:
case FSCTL_REQUEST_BATCH_OPLOCK:
case FSCTL_OPLOCK_BREAK_ACKNOWLEDGE:
case FSCTL_OPBATCH_ACK_CLOSE_PENDING:
case FSCTL_OPLOCK_BREAK_NOTIFY:
case FSCTL_OPLOCK_BREAK_ACK_NO_2:
case FSCTL_REQUEST_FILTER_OPLOCK :
Status = FatOplockRequest(IrpContext, Irp);
break;
case FSCTL_LOCK_VOLUME:
//Status = FatLockVolume( IrpContext, Irp );
DPRINT1("FSCTL_LOCK_VOLUME\n");
Status = STATUS_INVALID_DEVICE_REQUEST;
FatCompleteRequest(IrpContext, Irp, Status);
break;
case FSCTL_UNLOCK_VOLUME:
//Status = FatUnlockVolume( IrpContext, Irp );
DPRINT1("FSCTL_UNLOCK_VOLUME\n");
Status = STATUS_INVALID_DEVICE_REQUEST;
FatCompleteRequest(IrpContext, Irp, Status);
break;
case FSCTL_DISMOUNT_VOLUME:
//Status = FatDismountVolume( IrpContext, Irp );
DPRINT1("FSCTL_DISMOUNT_VOLUME\n");
Status = STATUS_INVALID_DEVICE_REQUEST;
FatCompleteRequest(IrpContext, Irp, Status);
break;
case FSCTL_MARK_VOLUME_DIRTY:
Status = FatMarkVolumeDirty(IrpContext, Irp);
break;
case FSCTL_IS_VOLUME_DIRTY:
//Status = FatIsVolumeDirty( IrpContext, Irp );
DPRINT1("FSCTL_IS_VOLUME_DIRTY\n");
Status = STATUS_INVALID_DEVICE_REQUEST;
FatCompleteRequest(IrpContext, Irp, Status);
break;
case FSCTL_IS_VOLUME_MOUNTED:
//Status = FatIsVolumeMounted( IrpContext, Irp );
DPRINT1("FSCTL_IS_VOLUME_MOUNTED\n");
Status = STATUS_INVALID_DEVICE_REQUEST;
FatCompleteRequest(IrpContext, Irp, Status);
break;
case FSCTL_IS_PATHNAME_VALID:
//Status = FatIsPathnameValid( IrpContext, Irp );
DPRINT1("FSCTL_IS_PATHNAME_VALID\n");
Status = STATUS_INVALID_DEVICE_REQUEST;
FatCompleteRequest(IrpContext, Irp, Status);
break;
case FSCTL_QUERY_RETRIEVAL_POINTERS:
//Status = FatQueryRetrievalPointers( IrpContext, Irp );
DPRINT1("FSCTL_QUERY_RETRIEVAL_POINTERS\n");
Status = STATUS_INVALID_DEVICE_REQUEST;
FatCompleteRequest(IrpContext, Irp, Status);
break;
case FSCTL_QUERY_FAT_BPB:
//Status = FatQueryBpb( IrpContext, Irp );
DPRINT1("FSCTL_QUERY_FAT_BPB\n");
Status = STATUS_INVALID_DEVICE_REQUEST;
FatCompleteRequest(IrpContext, Irp, Status);
break;
case FSCTL_FILESYSTEM_GET_STATISTICS:
//Status = FatGetStatistics( IrpContext, Irp );
DPRINT1("FSCTL_FILESYSTEM_GET_STATISTICS\n");
Status = STATUS_INVALID_DEVICE_REQUEST;
FatCompleteRequest(IrpContext, Irp, Status);
break;
case FSCTL_GET_VOLUME_BITMAP:
//Status = FatGetVolumeBitmap( IrpContext, Irp );
DPRINT1("FSCTL_GET_VOLUME_BITMAP\n");
Status = STATUS_INVALID_DEVICE_REQUEST;
FatCompleteRequest(IrpContext, Irp, Status);
break;
case FSCTL_GET_RETRIEVAL_POINTERS:
//Status = FatGetRetrievalPointers( IrpContext, Irp );
DPRINT1("FSCTL_GET_RETRIEVAL_POINTERS\n");
Status = STATUS_INVALID_DEVICE_REQUEST;
FatCompleteRequest(IrpContext, Irp, Status);
break;
case FSCTL_MOVE_FILE:
//Status = FatMoveFile( IrpContext, Irp );
DPRINT1("FSCTL_MOVE_FILE\n");
Status = STATUS_INVALID_DEVICE_REQUEST;
FatCompleteRequest(IrpContext, Irp, Status);
break;
case FSCTL_ALLOW_EXTENDED_DASD_IO:
//Status = FatAllowExtendedDasdIo( IrpContext, Irp );
DPRINT1("FSCTL_ALLOW_EXTENDED_DASD_IO\n");
Status = STATUS_INVALID_DEVICE_REQUEST;
FatCompleteRequest(IrpContext, Irp, Status);
break;
default:
DPRINT1("FatUserFsCtrl(), unhandled fs control code 0x%x\n", Code);
Status = STATUS_INVALID_DEVICE_REQUEST;
FatCompleteRequest(IrpContext, Irp, Status);
}
//(((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method))
// 9c040
// 1 1 0 0 0
// 6 4 8 4 0
// 10011100000001000000
// DT = 1001 = 9
// Access = 11 = 3
// Function = 10000 = 16
// Method = 0
return Status;
}
NTSTATUS

View file

@ -91,11 +91,7 @@ FatRead(PDEVICE_OBJECT DeviceObject, PIRP Irp)
if (DeviceObject != FatGlobalData.DiskDeviceObject)
{
/* Set Top Level IRP if not set */
if (IoGetTopLevelIrp() == NULL)
{
IoSetTopLevelIrp(Irp);
TopLevel = TRUE;
}
TopLevel = FatIsTopLevelIrp(Irp);
/* Build an irp context */
IrpContext = FatBuildIrpContext(Irp, CanWait);

View file

@ -135,13 +135,29 @@ FatiQueryVolumeInfo(PFAT_IRP_CONTEXT IrpContext, PIRP Irp)
/* Call FsVolumeInfo handler */
Status = FatiQueryFsVolumeInfo(Vcb, Buffer, &Length);
break;
case FileFsSizeInformation:
/* Call FsVolumeInfo handler */
Status = FatiQueryFsSizeInfo(Vcb, Buffer, &Length);
break;
default:
DPRINT1("Volume information class %d is not supported!\n", InfoClass);
case FileFsDeviceInformation:
UNIMPLEMENTED
//Status = FatiQueryFsDeviceInfo(IrpContext, 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 */
@ -175,11 +191,7 @@ FatQueryVolumeInfo(PDEVICE_OBJECT DeviceObject, PIRP Irp)
FsRtlEnterFileSystem();
/* Set Top Level IRP if not set */
if (IoGetTopLevelIrp() == NULL)
{
IoSetTopLevelIrp(Irp);
TopLevel = TRUE;
}
TopLevel = FatIsTopLevelIrp(Irp);
/* Build an irp context */
IrpContext = FatBuildIrpContext(Irp, CanWait);