[fastfat_new]

- Implement overwrite/supersede operations on an existing FCB, no on-disk writing yet.

svn path=/trunk/; revision=43809
This commit is contained in:
Aleksey Bragin 2009-10-28 11:29:34 +00:00
parent d3b074aa2c
commit 41b71cf811
4 changed files with 146 additions and 7 deletions

View file

@ -117,6 +117,113 @@ FatiTryToOpen(IN PFILE_OBJECT FileObject,
return Error;
}
IO_STATUS_BLOCK
NTAPI
FatiOverwriteFile(PFAT_IRP_CONTEXT IrpContext,
PFILE_OBJECT FileObject,
PFCB Fcb,
ULONG AllocationSize,
PFILE_FULL_EA_INFORMATION EaBuffer,
ULONG EaLength,
UCHAR FileAttributes,
ULONG CreateDisposition,
BOOLEAN NoEaKnowledge)
{
IO_STATUS_BLOCK Iosb = {{0}};
PCCB Ccb;
LARGE_INTEGER Zero;
ULONG NotifyFilter;
Zero.QuadPart = 0;
/* Check Ea mismatch first */
if (NoEaKnowledge && EaLength > 0)
{
Iosb.Status = STATUS_ACCESS_DENIED;
return Iosb;
}
do
{
/* Check if it's not still mapped */
if (!MmCanFileBeTruncated(&Fcb->SectionObjectPointers,
&Zero))
{
/* Fail */
Iosb.Status = STATUS_USER_MAPPED_FILE;
break;
}
/* Set file object pointers */
Ccb = FatCreateCcb();
FatSetFileObject(FileObject,
UserFileOpen,
Fcb,
Ccb);
FileObject->SectionObjectPointer = &Fcb->SectionObjectPointers;
/* Indicate that create is in progress */
Fcb->Vcb->State |= VCB_STATE_CREATE_IN_PROGRESS;
/* Purge the cache section */
CcPurgeCacheSection(&Fcb->SectionObjectPointers, NULL, 0, FALSE);
/* Add Eas */
if (EaLength > 0)
{
ASSERT(FALSE);
}
/* Acquire the paging resource */
(VOID)ExAcquireResourceExclusiveLite(Fcb->Header.PagingIoResource, TRUE);
/* Initialize FCB header */
Fcb->Header.FileSize.QuadPart = 0;
Fcb->Header.ValidDataLength.QuadPart = 0;
/* Let CC know about changed file size */
CcSetFileSizes(FileObject, (PCC_FILE_SIZES)&Fcb->Header.AllocationSize);
// TODO: Actually truncate the file
DPRINT1("TODO: Actually truncate the file with a fullfat handle %x\n", Fcb->FatHandle);
/* Release the paging resource */
ExReleaseResourceLite(Fcb->Header.PagingIoResource);
/* Specify truncate on close */
Fcb->State |= FCB_STATE_TRUNCATE_ON_CLOSE;
// TODO: Delete previous EA if needed
/* Send notification about changes */
NotifyFilter = FILE_NOTIFY_CHANGE_LAST_WRITE |
FILE_NOTIFY_CHANGE_ATTRIBUTES |
FILE_NOTIFY_CHANGE_SIZE;
FsRtlNotifyFullReportChange(Fcb->Vcb->NotifySync,
&Fcb->Vcb->NotifyList,
(PSTRING)&Fcb->FullFileName,
Fcb->FullFileName.Length - Fcb->FileNameLength,
NULL,
NULL,
NotifyFilter,
FILE_ACTION_MODIFIED,
NULL);
/* Set success status */
Iosb.Status = STATUS_SUCCESS;
/* Set correct information code */
Iosb.Information = (CreateDisposition == FILE_SUPERSEDE) ? FILE_SUPERSEDED : FILE_OVERWRITTEN;
} while (0);
/* Remove the create in progress flag */
ClearFlag(Fcb->Vcb->State, VCB_STATE_CREATE_IN_PROGRESS);
return Iosb;
}
IO_STATUS_BLOCK
NTAPI
FatiOpenExistingDir(IN PFAT_IRP_CONTEXT IrpContext,

View file

@ -95,6 +95,18 @@ FatiOpenExistingDcb(IN PFAT_IRP_CONTEXT IrpContext,
/* -------------------------------------------------------- create.c */
IO_STATUS_BLOCK
NTAPI
FatiOverwriteFile(PFAT_IRP_CONTEXT IrpContext,
PFILE_OBJECT FileObject,
PFCB Fcb,
ULONG AllocationSize,
PFILE_FULL_EA_INFORMATION EaBuffer,
ULONG EaLength,
UCHAR FileAttributes,
ULONG CreateDisposition,
BOOLEAN NoEaKnowledge);
NTSTATUS NTAPI
FatCreate(PDEVICE_OBJECT DeviceObject, PIRP Irp);

View file

@ -248,10 +248,11 @@ typedef enum _FCB_CONDITION
FcbNeedsToBeVerified
} FCB_CONDITION;
#define FCB_STATE_HAS_NAMES 0x01
#define FCB_STATE_HAS_UNICODE_NAME 0x02
#define FCB_STATE_PAGEFILE 0x04
#define FCB_STATE_DELAY_CLOSE 0x08
#define FCB_STATE_HAS_NAMES 0x01
#define FCB_STATE_HAS_UNICODE_NAME 0x02
#define FCB_STATE_PAGEFILE 0x04
#define FCB_STATE_DELAY_CLOSE 0x08
#define FCB_STATE_TRUNCATE_ON_CLOSE 0x10
typedef struct _FCB
{

View file

@ -195,7 +195,7 @@ FatiOpenExistingFcb(IN PFAT_IRP_CONTEXT IrpContext,
BOOLEAN Hidden;
BOOLEAN System;
PCCB Ccb = NULL;
NTSTATUS Status;
NTSTATUS Status, StatusPrev;
/* Acquire exclusive FCB lock */
(VOID)FatAcquireExclusiveFcb(IrpContext, Fcb);
@ -383,8 +383,27 @@ FatiOpenExistingFcb(IN PFAT_IRP_CONTEXT IrpContext,
(CreateDisposition == FILE_OVERWRITE) ||
(CreateDisposition == FILE_OVERWRITE_IF))
{
UNIMPLEMENTED;
ASSERT(FALSE);
/* Remember previous status */
StatusPrev = Iosb.Status;
// TODO: Check system security access
/* Perform overwrite operation */
Iosb = FatiOverwriteFile(IrpContext,
FileObject,
Fcb,
AllocationSize,
EaBuffer,
EaLength,
FileAttributes,
CreateDisposition,
NoEaKnowledge);
/* Restore previous status in case of success */
if (Iosb.Status == STATUS_SUCCESS)
Iosb.Status = StatusPrev;
/* Fall down to completion */
}
else
{