mirror of
				https://github.com/winfsp/winfsp.git
				synced 2025-10-29 19:18:39 -05:00 
			
		
		
		
	sys: IRP_MJ_CREATE refactoring
This commit is contained in:
		| @@ -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; | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user