mirror of
https://github.com/winfsp/winfsp.git
synced 2025-04-23 17:03:12 -05:00
sys: IRP_MJ_CREATE refactoring
This commit is contained in:
parent
cd28edf6a9
commit
8a77de8908
@ -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
|
||||||
{
|
{
|
||||||
|
@ -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
|
||||||
|
@ -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,
|
||||||
|
@ -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);
|
||||||
|
@ -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)
|
||||||
{
|
{
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user