mirror of
https://github.com/reactos/reactos.git
synced 2024-10-15 21:56:40 +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)
|
IN BOOLEAN DeleteOnClose)
|
||||||
{
|
{
|
||||||
IO_STATUS_BLOCK Iosb = {{0}};
|
IO_STATUS_BLOCK Iosb = {{0}};
|
||||||
|
PCCB Ccb;
|
||||||
|
|
||||||
Iosb.Status = STATUS_NOT_IMPLEMENTED;
|
/* Exclusively lock this FCB */
|
||||||
UNIMPLEMENTED;
|
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;
|
return Iosb;
|
||||||
}
|
}
|
||||||
|
|
|
@ -524,4 +524,32 @@ FatIsTopLevelIrp(IN PIRP Irp)
|
||||||
return FALSE;
|
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 */
|
/* EOF */
|
||||||
|
|
|
@ -51,6 +51,18 @@
|
||||||
)
|
)
|
||||||
|
|
||||||
#define IsFileObjectReadOnly(FO) (!((FO)->WriteAccess | (FO)->DeleteAccess))
|
#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
|
NTSYSAPI
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
|
@ -230,6 +242,13 @@ FatMapUserBuffer(PIRP Irp);
|
||||||
BOOLEAN NTAPI
|
BOOLEAN NTAPI
|
||||||
FatIsTopLevelIrp(IN PIRP Irp);
|
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 */
|
/* --------------------------------------------------------- fullfat.c */
|
||||||
|
|
||||||
FF_T_SINT32
|
FF_T_SINT32
|
||||||
|
|
|
@ -263,11 +263,7 @@ FatQueryInformation(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||||
FsRtlEnterFileSystem();
|
FsRtlEnterFileSystem();
|
||||||
|
|
||||||
/* Set Top Level IRP if not set */
|
/* Set Top Level IRP if not set */
|
||||||
if (IoGetTopLevelIrp() == NULL)
|
TopLevel = FatIsTopLevelIrp(Irp);
|
||||||
{
|
|
||||||
IoSetTopLevelIrp(Irp);
|
|
||||||
TopLevel = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Build an irp context */
|
/* Build an irp context */
|
||||||
IrpContext = FatBuildIrpContext(Irp, CanWait);
|
IrpContext = FatBuildIrpContext(Irp, CanWait);
|
||||||
|
@ -284,12 +280,394 @@ FatQueryInformation(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||||
return Status;
|
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
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
FatSetInformation(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
FatSetInformation(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||||
{
|
{
|
||||||
DPRINT1("FatSetInformation()\n");
|
NTSTATUS Status;
|
||||||
return STATUS_NOT_IMPLEMENTED;
|
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 */
|
/* EOF */
|
||||||
|
|
|
@ -13,13 +13,181 @@
|
||||||
|
|
||||||
/* FUNCTIONS ****************************************************************/
|
/* 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
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
FatUserFsCtrl(PFAT_IRP_CONTEXT IrpContext, PIRP Irp)
|
FatUserFsCtrl(PFAT_IRP_CONTEXT IrpContext, PIRP Irp)
|
||||||
{
|
{
|
||||||
DPRINT1("FatUserFsCtrl()\n");
|
PIO_STACK_LOCATION IrpSp;
|
||||||
FatCompleteRequest(IrpContext, Irp, STATUS_INVALID_DEVICE_REQUEST);
|
NTSTATUS Status;
|
||||||
return STATUS_INVALID_DEVICE_REQUEST;
|
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
|
NTSTATUS
|
||||||
|
|
|
@ -91,11 +91,7 @@ FatRead(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||||
if (DeviceObject != FatGlobalData.DiskDeviceObject)
|
if (DeviceObject != FatGlobalData.DiskDeviceObject)
|
||||||
{
|
{
|
||||||
/* Set Top Level IRP if not set */
|
/* Set Top Level IRP if not set */
|
||||||
if (IoGetTopLevelIrp() == NULL)
|
TopLevel = FatIsTopLevelIrp(Irp);
|
||||||
{
|
|
||||||
IoSetTopLevelIrp(Irp);
|
|
||||||
TopLevel = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Build an irp context */
|
/* Build an irp context */
|
||||||
IrpContext = FatBuildIrpContext(Irp, CanWait);
|
IrpContext = FatBuildIrpContext(Irp, CanWait);
|
||||||
|
|
|
@ -135,13 +135,29 @@ FatiQueryVolumeInfo(PFAT_IRP_CONTEXT IrpContext, PIRP Irp)
|
||||||
/* Call FsVolumeInfo handler */
|
/* Call FsVolumeInfo handler */
|
||||||
Status = FatiQueryFsVolumeInfo(Vcb, Buffer, &Length);
|
Status = FatiQueryFsVolumeInfo(Vcb, Buffer, &Length);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FileFsSizeInformation:
|
case FileFsSizeInformation:
|
||||||
/* Call FsVolumeInfo handler */
|
/* Call FsVolumeInfo handler */
|
||||||
Status = FatiQueryFsSizeInfo(Vcb, Buffer, &Length);
|
Status = FatiQueryFsSizeInfo(Vcb, Buffer, &Length);
|
||||||
break;
|
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;
|
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 */
|
/* Set IoStatus.Information to amount of filled bytes */
|
||||||
|
@ -175,11 +191,7 @@ FatQueryVolumeInfo(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||||
FsRtlEnterFileSystem();
|
FsRtlEnterFileSystem();
|
||||||
|
|
||||||
/* Set Top Level IRP if not set */
|
/* Set Top Level IRP if not set */
|
||||||
if (IoGetTopLevelIrp() == NULL)
|
TopLevel = FatIsTopLevelIrp(Irp);
|
||||||
{
|
|
||||||
IoSetTopLevelIrp(Irp);
|
|
||||||
TopLevel = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Build an irp context */
|
/* Build an irp context */
|
||||||
IrpContext = FatBuildIrpContext(Irp, CanWait);
|
IrpContext = FatBuildIrpContext(Irp, CanWait);
|
||||||
|
|
Loading…
Reference in a new issue