mirror of
https://github.com/reactos/reactos.git
synced 2024-07-22 20:28:08 +00:00
[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:
parent
e787f57ee7
commit
03d3e84856
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue