mirror of
https://github.com/winfsp/winfsp.git
synced 2025-04-23 00:43:00 -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 UserContext2;
|
||||
UINT32 ReadAccess:1; /* file was open for read access */
|
||||
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 */
|
||||
UINT32 Delete:1; /* file must be deleted */
|
||||
} Cleanup;
|
||||
struct
|
||||
{
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
#include <dll/library.h>
|
||||
|
||||
#if 0
|
||||
FSP_API VOID FspShareAccessRemove(FSP_FILE_SYSTEM *FileSystem,
|
||||
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;
|
||||
return FspFileSystemSendResponse(FileSystem, &Response);
|
||||
}
|
||||
#endif
|
||||
|
@ -60,8 +60,9 @@ static NTSTATUS FspFsvolCleanup(
|
||||
UINT64 UserContext = FsContext->UserContext;
|
||||
UINT64 UserContext2 = (UINT_PTR)FileObject->FsContext2;
|
||||
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 */
|
||||
FspIopCreateRequestMustSucceed(Irp, FileNameRequired ? &FsContext->FileName : 0, 0, &Request);
|
||||
@ -70,12 +71,7 @@ static NTSTATUS FspFsvolCleanup(
|
||||
Request->Kind = FspFsctlTransactCleanupKind;
|
||||
Request->Req.Cleanup.UserContext = UserContext;
|
||||
Request->Req.Cleanup.UserContext2 = UserContext2;
|
||||
Request->Req.Cleanup.ReadAccess = !!FileObject->ReadAccess;
|
||||
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;
|
||||
Request->Req.Cleanup.Delete = DeletePending;
|
||||
|
||||
/*
|
||||
* Note that it is still possible for this request to not be delivered,
|
||||
|
@ -359,7 +359,7 @@ NTSTATUS FspFsvolCreatePrepare(
|
||||
FspFileContextPgioUnlock(FsContext);
|
||||
|
||||
FspFsvolCreatePostClose(FsContext, (UINT_PTR)FileObject->FsContext2);
|
||||
FspFileContextClose(FsContext, FileObject);
|
||||
FspFileContextClose(FsContext, FileObject, 0);
|
||||
|
||||
return STATUS_USER_MAPPED_FILE;
|
||||
}
|
||||
@ -468,6 +468,7 @@ VOID FspFsvolCreateComplete(
|
||||
/* open the FsContext */
|
||||
OpenedFsContext = FspFileContextOpen(FsContext, FileObject,
|
||||
Response->Rsp.Create.Opened.GrantedAccess, IrpSp->Parameters.Create.ShareAccess,
|
||||
DeleteOnClose,
|
||||
&Result);
|
||||
if (0 == OpenedFsContext)
|
||||
{
|
||||
@ -508,7 +509,7 @@ VOID FspFsvolCreateComplete(
|
||||
{
|
||||
FspFsvolCreatePostClose(FsContext,
|
||||
Response->Rsp.Create.Opened.UserContext2);
|
||||
FspFileContextClose(FsContext, FileObject);
|
||||
FspFileContextClose(FsContext, FileObject, 0);
|
||||
|
||||
Result = DeleteOnClose ? STATUS_CANNOT_DELETE : STATUS_SHARING_VIOLATION;
|
||||
FSP_RETURN();
|
||||
@ -576,7 +577,7 @@ VOID FspFsvolCreateComplete(
|
||||
{
|
||||
FspFileContextPgioUnlock(FsContext);
|
||||
|
||||
FspFileContextClose(FsContext, FileObject);
|
||||
FspFileContextClose(FsContext, FileObject, 0);
|
||||
|
||||
Irp->IoStatus.Information = 0;
|
||||
Result = Response->IoStatus.Status;
|
||||
@ -686,7 +687,7 @@ static VOID FspFsvolCreateOverwriteRequestFini(PVOID Context[3])
|
||||
if (0 != FileObject)
|
||||
{
|
||||
FspFsvolCreatePostClose(FsContext, (UINT_PTR)FileObject->FsContext2);
|
||||
FspFileContextClose(FsContext, FileObject);
|
||||
FspFileContextClose(FsContext, FileObject, 0);
|
||||
}
|
||||
|
||||
FspFileContextRelease(FsContext);
|
||||
|
@ -513,10 +513,15 @@ typedef struct
|
||||
FSP_FILE_CONTEXT_NONPAGED *NonPaged;
|
||||
/* interlocked access */
|
||||
LONG RefCount;
|
||||
/* locked access */
|
||||
/* locked access (ContextTable lock) */
|
||||
LONG OpenCount;
|
||||
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;
|
||||
UINT64 UserContext;
|
||||
FSP_DEVICE_GENERIC_TABLE_ELEMENT ElementStorage;
|
||||
@ -527,8 +532,9 @@ NTSTATUS FspFileContextCreate(PDEVICE_OBJECT DeviceObject,
|
||||
ULONG ExtraSize, FSP_FILE_CONTEXT **PFsContext);
|
||||
VOID FspFileContextDelete(FSP_FILE_CONTEXT *FsContext);
|
||||
FSP_FILE_CONTEXT *FspFileContextOpen(FSP_FILE_CONTEXT *FsContext, PFILE_OBJECT FileObject,
|
||||
DWORD GrantedAccess, DWORD ShareAccess, NTSTATUS *PResult);
|
||||
VOID FspFileContextClose(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);
|
||||
static inline
|
||||
VOID FspFileContextRetain(FSP_FILE_CONTEXT *FsContext)
|
||||
{
|
||||
|
@ -9,10 +9,16 @@
|
||||
NTSTATUS FspFileContextCreate(PDEVICE_OBJECT DeviceObject,
|
||||
ULONG ExtraSize, FSP_FILE_CONTEXT **PFsContext);
|
||||
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
|
||||
#pragma alloc_text(PAGE, FspFileContextCreate)
|
||||
#pragma alloc_text(PAGE, FspFileContextDelete)
|
||||
#pragma alloc_text(PAGE, FspFileContextOpen)
|
||||
#pragma alloc_text(PAGE, FspFileContextClose)
|
||||
#endif
|
||||
|
||||
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,
|
||||
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.
|
||||
@ -82,9 +88,12 @@ FSP_FILE_CONTEXT *FspFileContextOpen(FSP_FILE_CONTEXT *FsContext, PFILE_OBJECT F
|
||||
* FsContext instead.
|
||||
*/
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
PDEVICE_OBJECT FsvolDeviceObject = FsContext->FsvolDeviceObject;
|
||||
FSP_FILE_CONTEXT *OpenedFsContext;
|
||||
BOOLEAN Inserted;
|
||||
NTSTATUS Result;
|
||||
|
||||
FspFsvolDeviceLockContextTable(FsvolDeviceObject);
|
||||
|
||||
@ -102,20 +111,21 @@ FSP_FILE_CONTEXT *FspFileContextOpen(FSP_FILE_CONTEXT *FsContext, PFILE_OBJECT F
|
||||
ASSERT(OpenedFsContext == FsContext);
|
||||
|
||||
IoSetShareAccess(GrantedAccess, ShareAccess, FileObject, &FsContext->ShareAccess);
|
||||
FspFileContextRetain(OpenedFsContext);
|
||||
OpenedFsContext->OpenCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* The new FsContext was NOT inserted into the Context table. Instead we are
|
||||
* 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);
|
||||
|
||||
if (OpenedFsContext->Flags.DeletePending)
|
||||
{
|
||||
Result = STATUS_DELETE_PENDING;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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
|
||||
* open to the file its based against.
|
||||
*/
|
||||
NTSTATUS Result = STATUS_SUCCESS;
|
||||
if (!FlagOn(ShareAccess, FILE_SHARE_WRITE) &&
|
||||
FlagOn(GrantedAccess,
|
||||
FILE_EXECUTE | FILE_READ_DATA | FILE_WRITE_DATA | FILE_APPEND_DATA | DELETE) &&
|
||||
MmDoesFileHaveUserWritableReferences(&FsContext->NonPaged->SectionObjectPointers))
|
||||
{
|
||||
Result = STATUS_SHARING_VIOLATION;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* share access check */
|
||||
if (NT_SUCCESS(Result))
|
||||
Result = IoCheckShareAccess(GrantedAccess, ShareAccess, FileObject, &FsContext->ShareAccess, TRUE);
|
||||
if (NT_SUCCESS(Result))
|
||||
{
|
||||
FspFileContextRetain(OpenedFsContext);
|
||||
OpenedFsContext->OpenCount++;
|
||||
}
|
||||
else
|
||||
Result = IoCheckShareAccess(GrantedAccess, ShareAccess, FileObject, &FsContext->ShareAccess, TRUE);
|
||||
|
||||
exit:
|
||||
if (!NT_SUCCESS(Result))
|
||||
{
|
||||
if (0 != PResult)
|
||||
*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);
|
||||
|
||||
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
|
||||
* from the Context table.
|
||||
*/
|
||||
|
||||
PAGED_CODE();
|
||||
|
||||
PDEVICE_OBJECT FsvolDeviceObject = FsContext->FsvolDeviceObject;
|
||||
BOOLEAN Deleted = FALSE;
|
||||
BOOLEAN Deleted = FALSE, DeletePending;
|
||||
|
||||
FspFsvolDeviceLockContextTable(FsvolDeviceObject);
|
||||
|
||||
if (FsContext->Flags.DeleteOnClose)
|
||||
FsContext->Flags.DeletePending = TRUE;
|
||||
DeletePending = 0 != FsContext->Flags.DeletePending;
|
||||
|
||||
IoRemoveShareAccess(FileObject, &FsContext->ShareAccess);
|
||||
if (0 == --FsContext->OpenCount)
|
||||
FspFsvolDeviceDeleteContext(FsvolDeviceObject, FsContext->UserContext, &Deleted);
|
||||
@ -173,4 +197,7 @@ VOID FspFileContextClose(FSP_FILE_CONTEXT *FsContext, PFILE_OBJECT FileObject)
|
||||
|
||||
if (Deleted)
|
||||
FspFileContextRelease(FsContext);
|
||||
|
||||
if (0 != PDeletePending)
|
||||
*PDeletePending = Deleted && DeletePending;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user