mirror of
				https://github.com/winfsp/winfsp.git
				synced 2025-10-30 19:48:38 -05:00 
			
		
		
		
	Major refactoring: IRP_MJ_CREATE
This commit is contained in:
		| @@ -123,7 +123,6 @@ typedef struct | |||||||
|         { |         { | ||||||
|             UINT64 UserContext; |             UINT64 UserContext; | ||||||
|             UINT64 UserContext2; |             UINT64 UserContext2; | ||||||
|             UINT32 Delete:1;            /* if set, the file or directory must be deleted */ |  | ||||||
|         } Cleanup; |         } Cleanup; | ||||||
|         struct |         struct | ||||||
|         { |         { | ||||||
| @@ -154,6 +153,7 @@ typedef struct | |||||||
|             { |             { | ||||||
|                 UINT64 UserContext;     /* open file user context (unique file id) */ |                 UINT64 UserContext;     /* open file user context (unique file id) */ | ||||||
|                 UINT64 UserContext2;    /* kernel file object user context (only low 32 bits valid) */ |                 UINT64 UserContext2;    /* kernel file object user context (only low 32 bits valid) */ | ||||||
|  |                 UINT32 GrantedAccess;   /* FILE_{READ_DATA,WRITE_DATA,etc.} */ | ||||||
|             } Opened; |             } Opened; | ||||||
|             /* IoStatus.Status == STATUS_REPARSE */ |             /* IoStatus.Status == STATUS_REPARSE */ | ||||||
|             struct |             struct | ||||||
|   | |||||||
							
								
								
									
										106
									
								
								src/sys/create.c
									
									
									
									
									
								
							
							
						
						
									
										106
									
								
								src/sys/create.c
									
									
									
									
									
								
							| @@ -105,7 +105,7 @@ static NTSTATUS FspFsvolCreate( | |||||||
|     BOOLEAN IsAbsoluteSecurityDescriptor = FALSE; |     BOOLEAN IsAbsoluteSecurityDescriptor = FALSE; | ||||||
|     BOOLEAN IsSelfRelativeSecurityDescriptor = FALSE; |     BOOLEAN IsSelfRelativeSecurityDescriptor = FALSE; | ||||||
|     BOOLEAN HasTrailingBackslash = FALSE; |     BOOLEAN HasTrailingBackslash = FALSE; | ||||||
|     FSP_FILE_CONTEXT *FsContext = 0, *RelatedFsContext; |     FSP_FILE_CONTEXT *FsContext, *RelatedFsContext; | ||||||
|     FSP_FSCTL_TRANSACT_REQ *Request; |     FSP_FSCTL_TRANSACT_REQ *Request; | ||||||
|  |  | ||||||
|     /* cannot open files by fileid */ |     /* cannot open files by fileid */ | ||||||
| @@ -313,6 +313,110 @@ VOID FspFsvolCreateComplete( | |||||||
| { | { | ||||||
|     FSP_ENTER_IOC(PAGED_CODE()); |     FSP_ENTER_IOC(PAGED_CODE()); | ||||||
|  |  | ||||||
|  |     PDEVICE_OBJECT FsvolDeviceObject = IrpSp->DeviceObject; | ||||||
|  |     FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(FsvolDeviceObject); | ||||||
|  |     PFILE_OBJECT FileObject = IrpSp->FileObject; | ||||||
|  |     SHARE_ACCESS TemporaryShareAccess; | ||||||
|  |     UNICODE_STRING ReparseFileName; | ||||||
|  |     FSP_FSCTL_TRANSACT_REQ *Request; | ||||||
|  |     FSP_FILE_CONTEXT *FsContext; | ||||||
|  |     BOOLEAN Inserted; | ||||||
|  |  | ||||||
|  |     /* did the user-mode file system sent us a failure code? */ | ||||||
|  |     if (!NT_SUCCESS(Response->IoStatus.Status)) | ||||||
|  |     { | ||||||
|  |         Irp->IoStatus.Information = Response->IoStatus.Information; | ||||||
|  |         Result = Response->IoStatus.Status; | ||||||
|  |         FSP_RETURN(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /* special case STATUS_REPARSE */ | ||||||
|  |     if (STATUS_REPARSE == Result) | ||||||
|  |     { | ||||||
|  |         ReparseFileName.Buffer = | ||||||
|  |             (PVOID)(Response->Buffer + Response->Rsp.Create.Reparse.FileName.Offset); | ||||||
|  |         ReparseFileName.Length = ReparseFileName.MaximumLength = | ||||||
|  |             Response->Rsp.Create.Reparse.FileName.Size; | ||||||
|  |  | ||||||
|  |         Result = STATUS_ACCESS_DENIED; | ||||||
|  |         if (IO_REPARSE == Response->IoStatus.Information) | ||||||
|  |         { | ||||||
|  |             if (0 == ReparseFileName.Length || | ||||||
|  |                 (PUINT8)ReparseFileName.Buffer + ReparseFileName.Length > | ||||||
|  |                 (PUINT8)Response + Response->Size) | ||||||
|  |                 FSP_RETURN(); | ||||||
|  |  | ||||||
|  |             if (ReparseFileName.Length > FileObject->FileName.MaximumLength) | ||||||
|  |             { | ||||||
|  |                 PVOID Buffer = FspAllocExternal(ReparseFileName.Length); | ||||||
|  |                 if (0 == Buffer) | ||||||
|  |                     FSP_RETURN(Result = STATUS_INSUFFICIENT_RESOURCES); | ||||||
|  |                 FspFreeExternal(FileObject->FileName.Buffer); | ||||||
|  |                 FileObject->FileName.MaximumLength = ReparseFileName.Length; | ||||||
|  |                 FileObject->FileName.Buffer = Buffer; | ||||||
|  |             } | ||||||
|  |             FileObject->FileName.Length = 0; | ||||||
|  |             RtlCopyUnicodeString(&FileObject->FileName, &ReparseFileName); | ||||||
|  |         } | ||||||
|  |         else | ||||||
|  |         if (IO_REMOUNT == Response->IoStatus.Information) | ||||||
|  |         { | ||||||
|  |             if (0 != ReparseFileName.Length) | ||||||
|  |                 FSP_RETURN(); | ||||||
|  |         } | ||||||
|  |         else | ||||||
|  |             FSP_RETURN(); | ||||||
|  |  | ||||||
|  |         Irp->IoStatus.Information = Response->IoStatus.Information; | ||||||
|  |         Result = Response->IoStatus.Status; | ||||||
|  |         FSP_RETURN(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /* get the FsContext from our Request and associate it with the Response UserContext */ | ||||||
|  |     Request = FspIrpRequest(Irp); | ||||||
|  |     FsContext = FspIopRequestContext(Request, RequestFsContext); | ||||||
|  |     FsContext->UserContext = Response->Rsp.Create.Opened.UserContext; | ||||||
|  |  | ||||||
|  |     /* | ||||||
|  |      * Attempt to insert our FsContext into the volume device's generic table. | ||||||
|  |      * If an FsContext with the same UserContext already exists, then use that | ||||||
|  |      * FsContext instead. | ||||||
|  |      */ | ||||||
|  |     FspFsvolDeviceLockContext(FsvolDeviceObject); | ||||||
|  |     FsContext = FspFsvolDeviceInsertContext(FsvolDeviceObject, | ||||||
|  |         FsContext->UserContext, FsContext, &FsContext->ElementStorage, &Inserted); | ||||||
|  |     ASSERT(0 != FsContext); | ||||||
|  |     if (Inserted) | ||||||
|  |         /* Our FsContext was inserted into the volume device's generic table. | ||||||
|  |          * Disassociate it from the Request. | ||||||
|  |          */ | ||||||
|  |         FspIopRequestContext(Request, RequestFsContext) = 0; | ||||||
|  |     else | ||||||
|  |         /* | ||||||
|  |          * We are using a previously inserted FsContext. We must retain it. | ||||||
|  |          * Our own FsContext is still associated with the Request and will be | ||||||
|  |          * deleted during IRP completion. | ||||||
|  |          */ | ||||||
|  |         FspFileContextRetain(FsContext); | ||||||
|  |     FspFileContextOpen(FsContext); | ||||||
|  |     FspFsvolDeviceUnlockContext(FsvolDeviceObject); | ||||||
|  |  | ||||||
|  |     /* set up share access on FileObject; user-mode file system assumed to have done share check */ | ||||||
|  |     IoSetShareAccess(Response->Rsp.Create.Opened.GrantedAccess, IrpSp->Parameters.Create.ShareAccess, | ||||||
|  |         FileObject, &TemporaryShareAccess); | ||||||
|  |  | ||||||
|  |     /* finish seting up the FileObject */ | ||||||
|  |     if (0 != FsvolDeviceExtension->FsvrtDeviceObject) | ||||||
|  |         FileObject->Vpb = FsvolDeviceExtension->FsvrtDeviceObject->Vpb; | ||||||
|  |     FileObject->SectionObjectPointer = &FsContext->NonPaged->SectionObjectPointers; | ||||||
|  |     FileObject->PrivateCacheMap = 0; | ||||||
|  |     FileObject->FsContext = FsContext; | ||||||
|  |     FileObject->FsContext2 = (PVOID)(UINT_PTR)Response->Rsp.Create.Opened.UserContext2; | ||||||
|  |  | ||||||
|  |     /* SUCCESS! */ | ||||||
|  |     Irp->IoStatus.Information = Response->IoStatus.Information; | ||||||
|  |     Result = Response->IoStatus.Status; | ||||||
|  |  | ||||||
|     FSP_LEAVE_IOC( |     FSP_LEAVE_IOC( | ||||||
|         "FileObject=%p[%p:\"%wZ\"]", |         "FileObject=%p[%p:\"%wZ\"]", | ||||||
|         IrpSp->FileObject, IrpSp->FileObject->RelatedFileObject, IrpSp->FileObject->FileName); |         IrpSp->FileObject, IrpSp->FileObject->RelatedFileObject, IrpSp->FileObject->FileName); | ||||||
|   | |||||||
| @@ -456,6 +456,7 @@ typedef struct | |||||||
|     ERESOURCE Resource; |     ERESOURCE Resource; | ||||||
|     ERESOURCE PagingIoResource; |     ERESOURCE PagingIoResource; | ||||||
|     FAST_MUTEX HeaderFastMutex; |     FAST_MUTEX HeaderFastMutex; | ||||||
|  |     SECTION_OBJECT_POINTERS SectionObjectPointers; | ||||||
| } FSP_FILE_CONTEXT_NONPAGED; | } FSP_FILE_CONTEXT_NONPAGED; | ||||||
| typedef struct | typedef struct | ||||||
| { | { | ||||||
| @@ -463,34 +464,38 @@ typedef struct | |||||||
|     FSP_FILE_CONTEXT_NONPAGED *NonPaged; |     FSP_FILE_CONTEXT_NONPAGED *NonPaged; | ||||||
|     /* interlocked access */ |     /* interlocked access */ | ||||||
|     LONG RefCount; |     LONG RefCount; | ||||||
| #if 0 |  | ||||||
|     /* protected by Header.Resource */ |  | ||||||
|     LONG OpenCount; |     LONG OpenCount; | ||||||
|     SHARE_ACCESS ShareAccess; |     /* read-only after creation (and insertion in the GenericTable) */ | ||||||
|     BOOLEAN DeletePending;              /* FileDispositionInformation */ |  | ||||||
|     BOOLEAN DeleteOnClose;              /* FILE_DELETE_ON_CLOSE */ |  | ||||||
|     FSP_DEVICE_GENERIC_TABLE_ELEMENT ElementStorage; |  | ||||||
|     UINT64 UserContext; |  | ||||||
| #endif |  | ||||||
|     /* read-only after creation */ |  | ||||||
|     PDEVICE_OBJECT FsvolDeviceObject; |     PDEVICE_OBJECT FsvolDeviceObject; | ||||||
|  |     UINT64 UserContext; | ||||||
|  |     FSP_DEVICE_GENERIC_TABLE_ELEMENT ElementStorage; | ||||||
|     UNICODE_STRING FileName; |     UNICODE_STRING FileName; | ||||||
|     WCHAR FileNameBuf[]; |     WCHAR FileNameBuf[]; | ||||||
| } FSP_FILE_CONTEXT; | } FSP_FILE_CONTEXT; | ||||||
| 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 *FsContext); | ||||||
| static inline | static inline | ||||||
| VOID FspFileContextRetain(FSP_FILE_CONTEXT *Context) | VOID FspFileContextRetain(FSP_FILE_CONTEXT *FsContext) | ||||||
| { | { | ||||||
|     InterlockedIncrement(&Context->RefCount); |     InterlockedIncrement(&FsContext->RefCount); | ||||||
| } | } | ||||||
| static inline | static inline | ||||||
| VOID FspFileContextRelease(FSP_FILE_CONTEXT *Context) | VOID FspFileContextRelease(FSP_FILE_CONTEXT *FsContext) | ||||||
| { | { | ||||||
|     LONG RefCount = InterlockedDecrement(&Context->RefCount); |     LONG RefCount = InterlockedDecrement(&FsContext->RefCount); | ||||||
|     if (0 == RefCount) |     if (0 == RefCount) | ||||||
|         FspFileContextDelete(Context); |         FspFileContextDelete(FsContext); | ||||||
|  | } | ||||||
|  | static inline | ||||||
|  | VOID FspFileContextOpen(FSP_FILE_CONTEXT *FsContext) | ||||||
|  | { | ||||||
|  |     InterlockedIncrement(&FsContext->OpenCount); | ||||||
|  | } | ||||||
|  | static inline | ||||||
|  | LONG FspFileContextClose(FSP_FILE_CONTEXT *FsContext) | ||||||
|  | { | ||||||
|  |     return InterlockedDecrement(&FsContext->OpenCount); | ||||||
| } | } | ||||||
|  |  | ||||||
| /* debug */ | /* debug */ | ||||||
| @@ -508,42 +513,4 @@ extern PDEVICE_OBJECT FspFsctlNetDeviceObject; | |||||||
| extern FSP_IOPREP_DISPATCH *FspIopPrepareFunction[]; | extern FSP_IOPREP_DISPATCH *FspIopPrepareFunction[]; | ||||||
| extern FSP_IOCMPL_DISPATCH *FspIopCompleteFunction[]; | extern FSP_IOCMPL_DISPATCH *FspIopCompleteFunction[]; | ||||||
|  |  | ||||||
| #if 0 |  | ||||||
| typedef struct |  | ||||||
| { |  | ||||||
|     FSRTL_ADVANCED_FCB_HEADER Header; |  | ||||||
|     FSP_FILE_CONTEXT_NONPAGED *NonPaged; |  | ||||||
|     /* interlocked access */ |  | ||||||
|     LONG RefCount; |  | ||||||
|     /* protected by Header.Resource */ |  | ||||||
|     LONG OpenCount; |  | ||||||
|     SHARE_ACCESS ShareAccess; |  | ||||||
|     BOOLEAN DeletePending;              /* FileDispositionInformation */ |  | ||||||
|     BOOLEAN DeleteOnClose;              /* FILE_DELETE_ON_CLOSE */ |  | ||||||
|     /* read-only after creation */ |  | ||||||
|     FSP_DEVICE_GENERIC_TABLE_ELEMENT ElementStorage; |  | ||||||
|     PDEVICE_OBJECT FsvolDeviceObject; |  | ||||||
|     UINT64 UserContext; |  | ||||||
|     UNICODE_STRING FileName; |  | ||||||
|     WCHAR FileNameBuf[]; |  | ||||||
| } FSP_FILE_CONTEXT; |  | ||||||
| NTSTATUS FspFileContextCreate(PDEVICE_OBJECT DeviceObject, |  | ||||||
|     ULONG ExtraSize, FSP_FILE_CONTEXT **PFsContext); |  | ||||||
| VOID FspFileContextDelete(FSP_FILE_CONTEXT *Context); |  | ||||||
| static inline |  | ||||||
| VOID FspFileContextOpen(FSP_FILE_CONTEXT *Context) |  | ||||||
| { |  | ||||||
|     ASSERT(0 == Context->OpenCount || ExIsResourceAcquiredExclusiveLite(Context->Header.Resource)); |  | ||||||
|     Context->OpenCount++; |  | ||||||
| } |  | ||||||
| static inline |  | ||||||
| LONG FspFileContextClose(FSP_FILE_CONTEXT *Context) |  | ||||||
| { |  | ||||||
|     ASSERT(ExIsResourceAcquiredExclusiveLite(Context->Header.Resource)); |  | ||||||
|     ASSERT(0 < Context->OpenCount); |  | ||||||
|     return --Context->OpenCount; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| #endif | #endif | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user