sys: IRP_MJ_CREATE refactoring

This commit is contained in:
Bill Zissimopoulos 2016-01-12 14:34:30 -08:00
parent cd28edf6a9
commit 8a77de8908
6 changed files with 65 additions and 38 deletions

View File

@ -131,12 +131,7 @@ typedef struct
{ {
UINT64 UserContext; UINT64 UserContext;
UINT64 UserContext2; UINT64 UserContext2;
UINT32 ReadAccess:1; /* file was open for read access */ UINT32 Delete:1; /* file must be deleted */
UINT32 WriteAccess:1; /* file was open for write access */
UINT32 DeleteAccess:1; /* file was open for delete access */
UINT32 SharedRead:1; /* file was open for shared read access */
UINT32 SharedWrite:1; /* file was open for shared write access */
UINT32 SharedDelete:1; /* file was open for shared delete access */
} Cleanup; } Cleanup;
struct struct
{ {

View File

@ -6,6 +6,7 @@
#include <dll/library.h> #include <dll/library.h>
#if 0
FSP_API VOID FspShareAccessRemove(FSP_FILE_SYSTEM *FileSystem, FSP_API VOID FspShareAccessRemove(FSP_FILE_SYSTEM *FileSystem,
FSP_FSCTL_TRANSACT_REQ *Request, FSP_FILE_NODE *FileNode) FSP_FSCTL_TRANSACT_REQ *Request, FSP_FILE_NODE *FileNode)
{ {
@ -65,3 +66,4 @@ FSP_API NTSTATUS FspFileSystemSendCleanupResponse(FSP_FILE_SYSTEM *FileSystem,
Response.IoStatus.Information = 0; Response.IoStatus.Information = 0;
return FspFileSystemSendResponse(FileSystem, &Response); return FspFileSystemSendResponse(FileSystem, &Response);
} }
#endif

View File

@ -60,8 +60,9 @@ static NTSTATUS FspFsvolCleanup(
UINT64 UserContext = FsContext->UserContext; UINT64 UserContext = FsContext->UserContext;
UINT64 UserContext2 = (UINT_PTR)FileObject->FsContext2; UINT64 UserContext2 = (UINT_PTR)FileObject->FsContext2;
FSP_FSCTL_TRANSACT_REQ *Request; FSP_FSCTL_TRANSACT_REQ *Request;
BOOLEAN DeletePending;
FspFileContextClose(FsContext, FileObject); FspFileContextClose(FsContext, FileObject, &DeletePending);
/* create the user-mode file system request; MustSucceed because IRP_MJ_CLEANUP cannot fail */ /* create the user-mode file system request; MustSucceed because IRP_MJ_CLEANUP cannot fail */
FspIopCreateRequestMustSucceed(Irp, FileNameRequired ? &FsContext->FileName : 0, 0, &Request); FspIopCreateRequestMustSucceed(Irp, FileNameRequired ? &FsContext->FileName : 0, 0, &Request);
@ -70,12 +71,7 @@ static NTSTATUS FspFsvolCleanup(
Request->Kind = FspFsctlTransactCleanupKind; Request->Kind = FspFsctlTransactCleanupKind;
Request->Req.Cleanup.UserContext = UserContext; Request->Req.Cleanup.UserContext = UserContext;
Request->Req.Cleanup.UserContext2 = UserContext2; Request->Req.Cleanup.UserContext2 = UserContext2;
Request->Req.Cleanup.ReadAccess = !!FileObject->ReadAccess; Request->Req.Cleanup.Delete = DeletePending;
Request->Req.Cleanup.WriteAccess = !!FileObject->WriteAccess;
Request->Req.Cleanup.DeleteAccess = !!FileObject->DeleteAccess;
Request->Req.Cleanup.SharedRead = !!FileObject->SharedRead;
Request->Req.Cleanup.SharedWrite = !!FileObject->SharedWrite;
Request->Req.Cleanup.SharedDelete = !!FileObject->SharedDelete;
/* /*
* Note that it is still possible for this request to not be delivered, * Note that it is still possible for this request to not be delivered,

View File

@ -359,7 +359,7 @@ NTSTATUS FspFsvolCreatePrepare(
FspFileContextPgioUnlock(FsContext); FspFileContextPgioUnlock(FsContext);
FspFsvolCreatePostClose(FsContext, (UINT_PTR)FileObject->FsContext2); FspFsvolCreatePostClose(FsContext, (UINT_PTR)FileObject->FsContext2);
FspFileContextClose(FsContext, FileObject); FspFileContextClose(FsContext, FileObject, 0);
return STATUS_USER_MAPPED_FILE; return STATUS_USER_MAPPED_FILE;
} }
@ -468,6 +468,7 @@ VOID FspFsvolCreateComplete(
/* open the FsContext */ /* open the FsContext */
OpenedFsContext = FspFileContextOpen(FsContext, FileObject, OpenedFsContext = FspFileContextOpen(FsContext, FileObject,
Response->Rsp.Create.Opened.GrantedAccess, IrpSp->Parameters.Create.ShareAccess, Response->Rsp.Create.Opened.GrantedAccess, IrpSp->Parameters.Create.ShareAccess,
DeleteOnClose,
&Result); &Result);
if (0 == OpenedFsContext) if (0 == OpenedFsContext)
{ {
@ -508,7 +509,7 @@ VOID FspFsvolCreateComplete(
{ {
FspFsvolCreatePostClose(FsContext, FspFsvolCreatePostClose(FsContext,
Response->Rsp.Create.Opened.UserContext2); Response->Rsp.Create.Opened.UserContext2);
FspFileContextClose(FsContext, FileObject); FspFileContextClose(FsContext, FileObject, 0);
Result = DeleteOnClose ? STATUS_CANNOT_DELETE : STATUS_SHARING_VIOLATION; Result = DeleteOnClose ? STATUS_CANNOT_DELETE : STATUS_SHARING_VIOLATION;
FSP_RETURN(); FSP_RETURN();
@ -576,7 +577,7 @@ VOID FspFsvolCreateComplete(
{ {
FspFileContextPgioUnlock(FsContext); FspFileContextPgioUnlock(FsContext);
FspFileContextClose(FsContext, FileObject); FspFileContextClose(FsContext, FileObject, 0);
Irp->IoStatus.Information = 0; Irp->IoStatus.Information = 0;
Result = Response->IoStatus.Status; Result = Response->IoStatus.Status;
@ -686,7 +687,7 @@ static VOID FspFsvolCreateOverwriteRequestFini(PVOID Context[3])
if (0 != FileObject) if (0 != FileObject)
{ {
FspFsvolCreatePostClose(FsContext, (UINT_PTR)FileObject->FsContext2); FspFsvolCreatePostClose(FsContext, (UINT_PTR)FileObject->FsContext2);
FspFileContextClose(FsContext, FileObject); FspFileContextClose(FsContext, FileObject, 0);
} }
FspFileContextRelease(FsContext); FspFileContextRelease(FsContext);

View File

@ -513,10 +513,15 @@ typedef struct
FSP_FILE_CONTEXT_NONPAGED *NonPaged; FSP_FILE_CONTEXT_NONPAGED *NonPaged;
/* interlocked access */ /* interlocked access */
LONG RefCount; LONG RefCount;
/* locked access */ /* locked access (ContextTable lock) */
LONG OpenCount; LONG OpenCount;
SHARE_ACCESS ShareAccess; SHARE_ACCESS ShareAccess;
/* read-only after creation (and insertion in the GenericTable) */ struct
{
UINT32 DeleteOnClose:1;
UINT32 DeletePending:1;
} Flags;
/* read-only after creation (and insertion in the ContextTable) */
PDEVICE_OBJECT FsvolDeviceObject; PDEVICE_OBJECT FsvolDeviceObject;
UINT64 UserContext; UINT64 UserContext;
FSP_DEVICE_GENERIC_TABLE_ELEMENT ElementStorage; FSP_DEVICE_GENERIC_TABLE_ELEMENT ElementStorage;
@ -527,8 +532,9 @@ NTSTATUS FspFileContextCreate(PDEVICE_OBJECT DeviceObject,
ULONG ExtraSize, FSP_FILE_CONTEXT **PFsContext); ULONG ExtraSize, FSP_FILE_CONTEXT **PFsContext);
VOID FspFileContextDelete(FSP_FILE_CONTEXT *FsContext); VOID FspFileContextDelete(FSP_FILE_CONTEXT *FsContext);
FSP_FILE_CONTEXT *FspFileContextOpen(FSP_FILE_CONTEXT *FsContext, PFILE_OBJECT FileObject, FSP_FILE_CONTEXT *FspFileContextOpen(FSP_FILE_CONTEXT *FsContext, PFILE_OBJECT FileObject,
DWORD GrantedAccess, DWORD ShareAccess, NTSTATUS *PResult); DWORD GrantedAccess, DWORD ShareAccess, BOOLEAN DeleteOnClose, NTSTATUS *PResult);
VOID FspFileContextClose(FSP_FILE_CONTEXT *FsContext, PFILE_OBJECT FileObject); VOID FspFileContextClose(FSP_FILE_CONTEXT *FsContext, PFILE_OBJECT FileObject,
PBOOLEAN PDeletePending);
static inline static inline
VOID FspFileContextRetain(FSP_FILE_CONTEXT *FsContext) VOID FspFileContextRetain(FSP_FILE_CONTEXT *FsContext)
{ {

View File

@ -9,10 +9,16 @@
NTSTATUS FspFileContextCreate(PDEVICE_OBJECT DeviceObject, NTSTATUS FspFileContextCreate(PDEVICE_OBJECT DeviceObject,
ULONG ExtraSize, FSP_FILE_CONTEXT **PFsContext); ULONG ExtraSize, FSP_FILE_CONTEXT **PFsContext);
VOID FspFileContextDelete(FSP_FILE_CONTEXT *Context); VOID FspFileContextDelete(FSP_FILE_CONTEXT *Context);
FSP_FILE_CONTEXT *FspFileContextOpen(FSP_FILE_CONTEXT *FsContext, PFILE_OBJECT FileObject,
DWORD GrantedAccess, DWORD ShareAccess, BOOLEAN DeleteOnClose, NTSTATUS *PResult);
VOID FspFileContextClose(FSP_FILE_CONTEXT *FsContext, PFILE_OBJECT FileObject,
PBOOLEAN PDeletePending);
#ifdef ALLOC_PRAGMA #ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGE, FspFileContextCreate) #pragma alloc_text(PAGE, FspFileContextCreate)
#pragma alloc_text(PAGE, FspFileContextDelete) #pragma alloc_text(PAGE, FspFileContextDelete)
#pragma alloc_text(PAGE, FspFileContextOpen)
#pragma alloc_text(PAGE, FspFileContextClose)
#endif #endif
NTSTATUS FspFileContextCreate(PDEVICE_OBJECT DeviceObject, NTSTATUS FspFileContextCreate(PDEVICE_OBJECT DeviceObject,
@ -74,7 +80,7 @@ VOID FspFileContextDelete(FSP_FILE_CONTEXT *FsContext)
} }
FSP_FILE_CONTEXT *FspFileContextOpen(FSP_FILE_CONTEXT *FsContext, PFILE_OBJECT FileObject, FSP_FILE_CONTEXT *FspFileContextOpen(FSP_FILE_CONTEXT *FsContext, PFILE_OBJECT FileObject,
DWORD GrantedAccess, DWORD ShareAccess, NTSTATUS *PResult) DWORD GrantedAccess, DWORD ShareAccess, BOOLEAN DeleteOnClose, NTSTATUS *PResult)
{ {
/* /*
* Attempt to insert our FsContext into the volume device's generic table. * Attempt to insert our FsContext into the volume device's generic table.
@ -82,9 +88,12 @@ FSP_FILE_CONTEXT *FspFileContextOpen(FSP_FILE_CONTEXT *FsContext, PFILE_OBJECT F
* FsContext instead. * FsContext instead.
*/ */
PAGED_CODE();
PDEVICE_OBJECT FsvolDeviceObject = FsContext->FsvolDeviceObject; PDEVICE_OBJECT FsvolDeviceObject = FsContext->FsvolDeviceObject;
FSP_FILE_CONTEXT *OpenedFsContext; FSP_FILE_CONTEXT *OpenedFsContext;
BOOLEAN Inserted; BOOLEAN Inserted;
NTSTATUS Result;
FspFsvolDeviceLockContextTable(FsvolDeviceObject); FspFsvolDeviceLockContextTable(FsvolDeviceObject);
@ -102,20 +111,21 @@ FSP_FILE_CONTEXT *FspFileContextOpen(FSP_FILE_CONTEXT *FsContext, PFILE_OBJECT F
ASSERT(OpenedFsContext == FsContext); ASSERT(OpenedFsContext == FsContext);
IoSetShareAccess(GrantedAccess, ShareAccess, FileObject, &FsContext->ShareAccess); IoSetShareAccess(GrantedAccess, ShareAccess, FileObject, &FsContext->ShareAccess);
FspFileContextRetain(OpenedFsContext);
OpenedFsContext->OpenCount++;
} }
else else
{ {
/* /*
* The new FsContext was NOT inserted into the Context table. Instead we are * The new FsContext was NOT inserted into the Context table. Instead we are
* opening a prior FsContext that we found in the table. * opening a prior FsContext that we found in the table.
*
* First check and update the share access. If successful then retain the
* opened FsContext for our caller.
*/ */
ASSERT(OpenedFsContext != FsContext); ASSERT(OpenedFsContext != FsContext);
if (OpenedFsContext->Flags.DeletePending)
{
Result = STATUS_DELETE_PENDING;
goto exit;
}
/* /*
* FastFat says to do the following on Vista and above. * FastFat says to do the following on Vista and above.
* *
@ -124,22 +134,20 @@ FSP_FILE_CONTEXT *FspFileContextOpen(FSP_FILE_CONTEXT *FsContext, PFILE_OBJECT F
* write sharing - this is neccessary since a section may exist with no handles * write sharing - this is neccessary since a section may exist with no handles
* open to the file its based against. * open to the file its based against.
*/ */
NTSTATUS Result = STATUS_SUCCESS;
if (!FlagOn(ShareAccess, FILE_SHARE_WRITE) && if (!FlagOn(ShareAccess, FILE_SHARE_WRITE) &&
FlagOn(GrantedAccess, FlagOn(GrantedAccess,
FILE_EXECUTE | FILE_READ_DATA | FILE_WRITE_DATA | FILE_APPEND_DATA | DELETE) && FILE_EXECUTE | FILE_READ_DATA | FILE_WRITE_DATA | FILE_APPEND_DATA | DELETE) &&
MmDoesFileHaveUserWritableReferences(&FsContext->NonPaged->SectionObjectPointers)) MmDoesFileHaveUserWritableReferences(&FsContext->NonPaged->SectionObjectPointers))
{
Result = STATUS_SHARING_VIOLATION; Result = STATUS_SHARING_VIOLATION;
goto exit;
}
/* share access check */ /* share access check */
if (NT_SUCCESS(Result))
Result = IoCheckShareAccess(GrantedAccess, ShareAccess, FileObject, &FsContext->ShareAccess, TRUE); Result = IoCheckShareAccess(GrantedAccess, ShareAccess, FileObject, &FsContext->ShareAccess, TRUE);
if (NT_SUCCESS(Result))
{ exit:
FspFileContextRetain(OpenedFsContext); if (!NT_SUCCESS(Result))
OpenedFsContext->OpenCount++;
}
else
{ {
if (0 != PResult) if (0 != PResult)
*PResult = Result; *PResult = Result;
@ -148,23 +156,39 @@ FSP_FILE_CONTEXT *FspFileContextOpen(FSP_FILE_CONTEXT *FsContext, PFILE_OBJECT F
} }
} }
if (0 != OpenedFsContext)
{
FspFileContextRetain(OpenedFsContext);
OpenedFsContext->OpenCount++;
if (DeleteOnClose)
OpenedFsContext->Flags.DeleteOnClose = TRUE;
}
FspFsvolDeviceUnlockContextTable(FsvolDeviceObject); FspFsvolDeviceUnlockContextTable(FsvolDeviceObject);
return OpenedFsContext; return OpenedFsContext;
} }
VOID FspFileContextClose(FSP_FILE_CONTEXT *FsContext, PFILE_OBJECT FileObject) VOID FspFileContextClose(FSP_FILE_CONTEXT *FsContext, PFILE_OBJECT FileObject,
PBOOLEAN PDeletePending)
{ {
/* /*
* Close the FsContext. If the OpenCount becomes zero remove it * Close the FsContext. If the OpenCount becomes zero remove it
* from the Context table. * from the Context table.
*/ */
PAGED_CODE();
PDEVICE_OBJECT FsvolDeviceObject = FsContext->FsvolDeviceObject; PDEVICE_OBJECT FsvolDeviceObject = FsContext->FsvolDeviceObject;
BOOLEAN Deleted = FALSE; BOOLEAN Deleted = FALSE, DeletePending;
FspFsvolDeviceLockContextTable(FsvolDeviceObject); FspFsvolDeviceLockContextTable(FsvolDeviceObject);
if (FsContext->Flags.DeleteOnClose)
FsContext->Flags.DeletePending = TRUE;
DeletePending = 0 != FsContext->Flags.DeletePending;
IoRemoveShareAccess(FileObject, &FsContext->ShareAccess); IoRemoveShareAccess(FileObject, &FsContext->ShareAccess);
if (0 == --FsContext->OpenCount) if (0 == --FsContext->OpenCount)
FspFsvolDeviceDeleteContext(FsvolDeviceObject, FsContext->UserContext, &Deleted); FspFsvolDeviceDeleteContext(FsvolDeviceObject, FsContext->UserContext, &Deleted);
@ -173,4 +197,7 @@ VOID FspFileContextClose(FSP_FILE_CONTEXT *FsContext, PFILE_OBJECT FileObject)
if (Deleted) if (Deleted)
FspFileContextRelease(FsContext); FspFileContextRelease(FsContext);
if (0 != PDeletePending)
*PDeletePending = Deleted && DeletePending;
} }