mirror of
				https://github.com/winfsp/winfsp.git
				synced 2025-10-30 19:48:38 -05:00 
			
		
		
		
	sys: FspFileNodeSetFileInfo: refactoring
This commit is contained in:
		| @@ -520,8 +520,6 @@ NTSTATUS FspFsvolCreateComplete( | ||||
|         } | ||||
|  | ||||
|         /* populate the FileNode/FileDesc fields from the Response */ | ||||
|         FileNode->Header.AllocationSize.QuadPart = Response->Rsp.Create.Opened.FileInfo.AllocationSize; | ||||
|         FileNode->Header.FileSize.QuadPart = Response->Rsp.Create.Opened.FileInfo.FileSize; | ||||
|         FileNode->UserContext = Response->Rsp.Create.Opened.UserContext; | ||||
|         FileNode->IndexNumber = Response->Rsp.Create.Opened.FileInfo.IndexNumber; | ||||
|         FileNode->IsDirectory = BooleanFlagOn(Response->Rsp.Create.Opened.FileInfo.FileAttributes, | ||||
| @@ -558,7 +556,8 @@ NTSTATUS FspFsvolCreateComplete( | ||||
|         FileObject->FsContext = FileNode; | ||||
|         FileObject->FsContext2 = FileDesc; | ||||
|  | ||||
|         if (FILE_OPENED == Response->IoStatus.Information) | ||||
|         if (FILE_SUPERSEDED != Response->IoStatus.Information && | ||||
|             FILE_OVERWRITTEN != Response->IoStatus.Information) | ||||
|         { | ||||
|             /* | ||||
|              * FastFat quote: | ||||
| @@ -577,8 +576,6 @@ NTSTATUS FspFsvolCreateComplete( | ||||
|             Result = FspFsvolCreateTryOpen(Irp, Response, FileNode, FileDesc, FileObject, FlushImage); | ||||
|         } | ||||
|         else | ||||
|         if (FILE_SUPERSEDED == Response->IoStatus.Information || | ||||
|             FILE_OVERWRITTEN == Response->IoStatus.Information) | ||||
|         { | ||||
|             /* | ||||
|              * Oh, noes! We have to go back to user mode to overwrite the file! | ||||
| @@ -623,14 +620,16 @@ NTSTATUS FspFsvolCreateComplete( | ||||
|              */ | ||||
|             FspIoqPostIrpBestEffort(FsvolDeviceExtension->Ioq, Irp, &Result); | ||||
|         } | ||||
|         else | ||||
|         { | ||||
|             /* SUCCESS! */ | ||||
|             FspFileNodeSetFileInfo(FileNode, &Response->Rsp.Create.Opened.FileInfo); | ||||
|             FspIopRequestContext(Request, RequestFileDesc) = 0; | ||||
|             Irp->IoStatus.Information = (ULONG_PTR)Response->IoStatus.Information; | ||||
|             Result = STATUS_SUCCESS; | ||||
|         } | ||||
|     } | ||||
|     else if (FspFsctlTransactReservedKind == Request->Kind) | ||||
|     { | ||||
|         /* | ||||
|          * A Reserved request is a special request used when retrying a file open. | ||||
|          */ | ||||
|  | ||||
|         BOOLEAN FlushImage = 0 != FspIopRequestContext(Request, RequestState); | ||||
|  | ||||
|         Result = FspFsvolCreateTryOpen(Irp, Response, FileNode, FileDesc, FileObject, FlushImage); | ||||
|     } | ||||
|     else if (FspFsctlTransactOverwriteKind == Request->Kind) | ||||
|     { | ||||
| @@ -648,28 +647,14 @@ NTSTATUS FspFsvolCreateComplete( | ||||
|         } | ||||
|  | ||||
|         /* file was successfully overwritten/superseded */ | ||||
|         FspFileObjectSetSizes(FileObject, | ||||
|             Response->Rsp.Overwrite.FileInfo.AllocationSize, | ||||
|             Response->Rsp.Overwrite.FileInfo.FileSize); | ||||
|  | ||||
|         FspFileNodeSetFileInfo(FileNode, FileObject, &Response->Rsp.Overwrite.FileInfo); | ||||
|         FspFileNodeRelease(FileNode, Full); | ||||
|  | ||||
|         /* SUCCESS! */ | ||||
|         FspFileNodeSetFileInfo(FileNode, &Response->Rsp.Overwrite.FileInfo); | ||||
|         FspIopRequestContext(Request, RequestFileDesc) = 0; | ||||
|         Irp->IoStatus.Information = Request->Req.Overwrite.Supersede ? FILE_SUPERSEDED : FILE_OVERWRITTEN; | ||||
|         Result = STATUS_SUCCESS; | ||||
|     } | ||||
|     else if (FspFsctlTransactReservedKind == Request->Kind) | ||||
|     { | ||||
|         /* | ||||
|          * A Reserved request is a special request used when retrying a file open. | ||||
|          */ | ||||
|  | ||||
|         BOOLEAN FlushImage = 0 != FspIopRequestContext(Request, RequestState); | ||||
|  | ||||
|         Result = FspFsvolCreateTryOpen(Irp, Response, FileNode, FileDesc, FileObject, FlushImage); | ||||
|     } | ||||
|     else | ||||
|         ASSERT(0); | ||||
|  | ||||
| @@ -712,9 +697,7 @@ static NTSTATUS FspFsvolCreateTryOpen(PIRP Irp, const FSP_FSCTL_TRANSACT_RSP *Re | ||||
|         return Result; | ||||
|     } | ||||
|  | ||||
|     FspFileObjectSetSizes(FileObject, | ||||
|         Response->Rsp.Create.Opened.FileInfo.AllocationSize, | ||||
|         Response->Rsp.Create.Opened.FileInfo.FileSize); | ||||
|     FspFileNodeSetFileInfo(FileNode, FileObject, &Response->Rsp.Create.Opened.FileInfo); | ||||
|  | ||||
|     if (FlushImage) | ||||
|     { | ||||
| @@ -739,9 +722,8 @@ static NTSTATUS FspFsvolCreateTryOpen(PIRP Irp, const FSP_FSCTL_TRANSACT_RSP *Re | ||||
|         FspFileNodeRelease(FileNode, Full); | ||||
|  | ||||
|     /* SUCCESS! */ | ||||
|     FspFileNodeSetFileInfo(FileNode, &Response->Rsp.Create.Opened.FileInfo); | ||||
|     FspIopRequestContext(Request, RequestFileDesc) = 0; | ||||
|     Irp->IoStatus.Information = FILE_OPENED; | ||||
|     Irp->IoStatus.Information = Response->IoStatus.Information; | ||||
|     return STATUS_SUCCESS; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -555,15 +555,6 @@ typedef struct | ||||
|     ERESOURCE PagingIoResource; | ||||
|     FAST_MUTEX HeaderFastMutex; | ||||
|     SECTION_OBJECT_POINTERS SectionObjectPointers; | ||||
|     /* FileInfo */ | ||||
|     KSPIN_LOCK InfoSpinLock; | ||||
|     UINT64 InfoExpirationTime; | ||||
|     UINT32 FileAttributes; | ||||
|     UINT32 ReparseTag; | ||||
|     UINT64 CreationTime; | ||||
|     UINT64 LastAccessTime; | ||||
|     UINT64 LastWriteTime; | ||||
|     UINT64 ChangeTime; | ||||
| } FSP_FILE_NODE_NONPAGED; | ||||
| typedef struct | ||||
| { | ||||
| @@ -579,7 +570,14 @@ typedef struct | ||||
|         UINT32 DeleteOnClose:1; | ||||
|         UINT32 DeletePending:1; | ||||
|     } Flags; | ||||
|     /* locked under same rules as Header.AllocationSize/FileSize */ | ||||
|     /* locked under Header.Resource */ | ||||
|     UINT64 InfoExpirationTime; | ||||
|     UINT32 FileAttributes; | ||||
|     UINT32 ReparseTag; | ||||
|     UINT64 CreationTime; | ||||
|     UINT64 LastAccessTime; | ||||
|     UINT64 LastWriteTime; | ||||
|     UINT64 ChangeTime; | ||||
|     NTSTATUS CcStatus; | ||||
|     /* read-only after creation (and insertion in the ContextTable) */ | ||||
|     PDEVICE_OBJECT FsvolDeviceObject; | ||||
| @@ -623,11 +621,10 @@ VOID FspFileNodeClose(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject, | ||||
|     PBOOLEAN PDeletePending); | ||||
| VOID FspFileNodeGetFileInfo(FSP_FILE_NODE *FileNode, FSP_FSCTL_FILE_INFO *FileInfo); | ||||
| BOOLEAN FspFileNodeTryGetFileInfo(FSP_FILE_NODE *FileNode, FSP_FSCTL_FILE_INFO *FileInfo); | ||||
| VOID FspFileNodeSetFileInfo(FSP_FILE_NODE *FileNode, const FSP_FSCTL_FILE_INFO *FileInfo); | ||||
| VOID FspFileNodeSetFileInfo(FSP_FILE_NODE *FileNode, PFILE_OBJECT CcFileObject, | ||||
|     const FSP_FSCTL_FILE_INFO *FileInfo); | ||||
| NTSTATUS FspFileDescCreate(FSP_FILE_DESC **PFileDesc); | ||||
| VOID FspFileDescDelete(FSP_FILE_DESC *FileDesc); | ||||
| VOID FspFileObjectSetSizes(PFILE_OBJECT FileObject, | ||||
|     UINT64 AllocationSize, UINT64 FileSize); | ||||
| #define FspFileNodeAcquireShared(N,F)   FspFileNodeAcquireSharedF(N, FspFileNodeAcquire ## F) | ||||
| #define FspFileNodeTryAcquireShared(N,F)    FspFileNodeTryAcquireSharedF(N, FspFileNodeAcquire ## F) | ||||
| #define FspFileNodeAcquireExclusive(N,F)    FspFileNodeAcquireExclusiveF(N, FspFileNodeAcquire ## F) | ||||
|   | ||||
							
								
								
									
										140
									
								
								src/sys/file.c
									
									
									
									
									
								
							
							
						
						
									
										140
									
								
								src/sys/file.c
									
									
									
									
									
								
							| @@ -22,11 +22,10 @@ VOID FspFileNodeClose(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject, | ||||
|     PBOOLEAN PDeletePending); | ||||
| VOID FspFileNodeGetFileInfo(FSP_FILE_NODE *FileNode, FSP_FSCTL_FILE_INFO *FileInfo); | ||||
| BOOLEAN FspFileNodeTryGetFileInfo(FSP_FILE_NODE *FileNode, FSP_FSCTL_FILE_INFO *FileInfo); | ||||
| VOID FspFileNodeSetFileInfo(FSP_FILE_NODE *FileNode, const FSP_FSCTL_FILE_INFO *FileInfo); | ||||
| VOID FspFileNodeSetFileInfo(FSP_FILE_NODE *FileNode, PFILE_OBJECT CcFileObject, | ||||
|     const FSP_FSCTL_FILE_INFO *FileInfo); | ||||
| NTSTATUS FspFileDescCreate(FSP_FILE_DESC **PFileDesc); | ||||
| VOID FspFileDescDelete(FSP_FILE_DESC *FileDesc); | ||||
| VOID FspFileObjectSetSizes(PFILE_OBJECT FileObject, | ||||
|     UINT64 AllocationSize, UINT64 FileSize); | ||||
|  | ||||
| #ifdef ALLOC_PRAGMA | ||||
| #pragma alloc_text(PAGE, FspFileNodeCreate) | ||||
| @@ -45,7 +44,6 @@ VOID FspFileObjectSetSizes(PFILE_OBJECT FileObject, | ||||
| #pragma alloc_text(PAGE, FspFileNodeSetFileInfo) | ||||
| #pragma alloc_text(PAGE, FspFileDescCreate) | ||||
| #pragma alloc_text(PAGE, FspFileDescDelete) | ||||
| #pragma alloc_text(PAGE, FspFileObjectSetSizes) | ||||
| #endif | ||||
|  | ||||
| NTSTATUS FspFileNodeCreate(PDEVICE_OBJECT DeviceObject, | ||||
| @@ -70,7 +68,6 @@ NTSTATUS FspFileNodeCreate(PDEVICE_OBJECT DeviceObject, | ||||
|     ExInitializeResourceLite(&NonPaged->Resource); | ||||
|     ExInitializeResourceLite(&NonPaged->PagingIoResource); | ||||
|     ExInitializeFastMutex(&NonPaged->HeaderFastMutex); | ||||
|     KeInitializeSpinLock(&NonPaged->InfoSpinLock); | ||||
|  | ||||
|     RtlZeroMemory(FileNode, sizeof *FileNode + ExtraSize); | ||||
|     FileNode->Header.NodeTypeCode = FspFileNodeFileKind; | ||||
| @@ -355,103 +352,69 @@ VOID FspFileNodeClose(FSP_FILE_NODE *FileNode, PFILE_OBJECT FileObject, | ||||
|         *PDeletePending = Deleted && DeletePending; | ||||
| } | ||||
|  | ||||
| static VOID FspFileNodeGetFileInfoNp(FSP_FILE_NODE_NONPAGED *FileNodeNp, FSP_FSCTL_FILE_INFO *FileInfoNp) | ||||
| { | ||||
|     // !PAGED_CODE(); | ||||
|  | ||||
|     KIRQL Irql; | ||||
|  | ||||
|     KeAcquireSpinLock(&FileNodeNp->InfoSpinLock, &Irql); | ||||
|     FileInfoNp->FileAttributes = FileNodeNp->FileAttributes; | ||||
|     FileInfoNp->ReparseTag = FileNodeNp->ReparseTag; | ||||
|     FileInfoNp->CreationTime = FileNodeNp->CreationTime; | ||||
|     FileInfoNp->LastAccessTime = FileNodeNp->LastAccessTime; | ||||
|     FileInfoNp->LastWriteTime = FileNodeNp->LastWriteTime; | ||||
|     FileInfoNp->ChangeTime = FileNodeNp->ChangeTime; | ||||
|     KeReleaseSpinLock(&FileNodeNp->InfoSpinLock, Irql); | ||||
| } | ||||
|  | ||||
| static BOOLEAN FspFileNodeTryGetFileInfoNp(FSP_FILE_NODE_NONPAGED *FileNodeNp, | ||||
|     FSP_FSCTL_FILE_INFO *FileInfoNp) | ||||
| { | ||||
|     // !PAGED_CODE(); | ||||
|  | ||||
|     KIRQL Irql; | ||||
|     BOOLEAN Result; | ||||
|  | ||||
|     KeAcquireSpinLock(&FileNodeNp->InfoSpinLock, &Irql); | ||||
|     if (0 < FileNodeNp->InfoExpirationTime && KeQueryInterruptTime() < FileNodeNp->InfoExpirationTime) | ||||
|     { | ||||
|         FileInfoNp->FileAttributes = FileNodeNp->FileAttributes; | ||||
|         FileInfoNp->ReparseTag = FileNodeNp->ReparseTag; | ||||
|         FileInfoNp->CreationTime = FileNodeNp->CreationTime; | ||||
|         FileInfoNp->LastAccessTime = FileNodeNp->LastAccessTime; | ||||
|         FileInfoNp->LastWriteTime = FileNodeNp->LastWriteTime; | ||||
|         FileInfoNp->ChangeTime = FileNodeNp->ChangeTime; | ||||
|         Result = TRUE; | ||||
|     } | ||||
|     else | ||||
|         Result = FALSE; | ||||
|     KeReleaseSpinLock(&FileNodeNp->InfoSpinLock, Irql); | ||||
|  | ||||
|     return Result; | ||||
| } | ||||
|  | ||||
| static VOID FspFileNodeSetFileInfoNp(FSP_FILE_NODE_NONPAGED *FileNodeNp, | ||||
|     const FSP_FSCTL_FILE_INFO *FileInfoNp, UINT64 FileInfoTimeout) | ||||
| { | ||||
|     // !PAGED_CODE(); | ||||
|  | ||||
|     KIRQL Irql; | ||||
|  | ||||
|     KeAcquireSpinLock(&FileNodeNp->InfoSpinLock, &Irql); | ||||
|     FileNodeNp->FileAttributes = FileInfoNp->FileAttributes; | ||||
|     FileNodeNp->ReparseTag = FileInfoNp->ReparseTag; | ||||
|     FileNodeNp->CreationTime = FileInfoNp->CreationTime; | ||||
|     FileNodeNp->LastAccessTime = FileInfoNp->LastAccessTime; | ||||
|     FileNodeNp->LastWriteTime = FileInfoNp->LastWriteTime; | ||||
|     FileNodeNp->ChangeTime = FileInfoNp->ChangeTime; | ||||
|     FileNodeNp->InfoExpirationTime = 0 != FileInfoTimeout ? | ||||
|         KeQueryInterruptTime() + FileInfoTimeout : 0; | ||||
|     KeReleaseSpinLock(&FileNodeNp->InfoSpinLock, Irql); | ||||
| } | ||||
|  | ||||
| VOID FspFileNodeGetFileInfo(FSP_FILE_NODE *FileNode, FSP_FSCTL_FILE_INFO *FileInfo) | ||||
| { | ||||
|     PAGED_CODE(); | ||||
|  | ||||
|     FSP_FILE_NODE_NONPAGED *FileNodeNp = FileNode->NonPaged; | ||||
|     FSP_FSCTL_FILE_INFO FileInfoNp; | ||||
|     FileInfo->AllocationSize = FileNode->Header.AllocationSize.QuadPart; | ||||
|     FileInfo->FileSize = FileNode->Header.FileSize.QuadPart; | ||||
|  | ||||
|     FspFileNodeGetFileInfoNp(FileNodeNp, &FileInfoNp); | ||||
|  | ||||
|     *FileInfo = FileInfoNp; | ||||
|     FileInfo->FileAttributes = FileNode->FileAttributes; | ||||
|     FileInfo->ReparseTag = FileNode->ReparseTag; | ||||
|     FileInfo->CreationTime = FileNode->CreationTime; | ||||
|     FileInfo->LastAccessTime = FileNode->LastAccessTime; | ||||
|     FileInfo->LastWriteTime = FileNode->LastWriteTime; | ||||
|     FileInfo->ChangeTime = FileNode->ChangeTime; | ||||
| } | ||||
|  | ||||
| BOOLEAN FspFileNodeTryGetFileInfo(FSP_FILE_NODE *FileNode, FSP_FSCTL_FILE_INFO *FileInfo) | ||||
| { | ||||
|     PAGED_CODE(); | ||||
|  | ||||
|     FSP_FILE_NODE_NONPAGED *FileNodeNp = FileNode->NonPaged; | ||||
|     FSP_FSCTL_FILE_INFO FileInfoNp; | ||||
|     BOOLEAN Result; | ||||
|  | ||||
|     if (!FspFileNodeTryGetFileInfoNp(FileNodeNp, &FileInfoNp)) | ||||
|         return FALSE; | ||||
|     if (0 < FileNode->InfoExpirationTime && KeQueryInterruptTime() < FileNode->InfoExpirationTime) | ||||
|     { | ||||
|         FileInfo->AllocationSize = FileNode->Header.AllocationSize.QuadPart; | ||||
|         FileInfo->FileSize = FileNode->Header.FileSize.QuadPart; | ||||
|  | ||||
|     *FileInfo = FileInfoNp; | ||||
|     return TRUE; | ||||
|         FileInfo->FileAttributes = FileNode->FileAttributes; | ||||
|         FileInfo->ReparseTag = FileNode->ReparseTag; | ||||
|         FileInfo->CreationTime = FileNode->CreationTime; | ||||
|         FileInfo->LastAccessTime = FileNode->LastAccessTime; | ||||
|         FileInfo->LastWriteTime = FileNode->LastWriteTime; | ||||
|         FileInfo->ChangeTime = FileNode->ChangeTime; | ||||
|         Result = TRUE; | ||||
|     } | ||||
|     else | ||||
|         Result = FALSE; | ||||
|  | ||||
|     return Result; | ||||
| } | ||||
|  | ||||
| VOID FspFileNodeSetFileInfo(FSP_FILE_NODE *FileNode, const FSP_FSCTL_FILE_INFO *FileInfo) | ||||
| VOID FspFileNodeSetFileInfo(FSP_FILE_NODE *FileNode, PFILE_OBJECT CcFileObject, | ||||
|     const FSP_FSCTL_FILE_INFO *FileInfo) | ||||
| { | ||||
|     PAGED_CODE(); | ||||
|  | ||||
|     UINT64 FileInfoTimeout = FspFsvolDeviceExtension(FileNode->FsvolDeviceObject)-> | ||||
|         VolumeParams.FileInfoTimeout * 10000ULL; | ||||
|     FSP_FILE_NODE_NONPAGED *FileNodeNp = FileNode->NonPaged; | ||||
|     FSP_FSCTL_FILE_INFO FileInfoNp = *FileInfo; | ||||
|  | ||||
|     FspFileNodeSetFileInfoNp(FileNodeNp, &FileInfoNp, FileInfoTimeout); | ||||
|     FileNode->Header.AllocationSize.QuadPart = FileInfo->AllocationSize; | ||||
|     FileNode->Header.FileSize.QuadPart = FileInfo->FileSize; | ||||
|  | ||||
|     FileNode->FileAttributes = FileInfo->FileAttributes; | ||||
|     FileNode->ReparseTag = FileInfo->ReparseTag; | ||||
|     FileNode->CreationTime = FileInfo->CreationTime; | ||||
|     FileNode->LastAccessTime = FileInfo->LastAccessTime; | ||||
|     FileNode->LastWriteTime = FileInfo->LastWriteTime; | ||||
|     FileNode->ChangeTime = FileInfo->ChangeTime; | ||||
|     FileNode->InfoExpirationTime = 0 != FileInfoTimeout ? | ||||
|         KeQueryInterruptTime() + FileInfoTimeout : 0; | ||||
|  | ||||
|     if (0 != CcFileObject) | ||||
|         FileNode->CcStatus = FspCcSetFileSizes( | ||||
|             CcFileObject, (PCC_FILE_SIZES)&FileNode->Header.AllocationSize); | ||||
| } | ||||
|  | ||||
| NTSTATUS FspFileDescCreate(FSP_FILE_DESC **PFileDesc) | ||||
| @@ -473,18 +436,3 @@ VOID FspFileDescDelete(FSP_FILE_DESC *FileDesc) | ||||
|  | ||||
|     FspFree(FileDesc); | ||||
| } | ||||
|  | ||||
| VOID FspFileObjectSetSizes(PFILE_OBJECT FileObject, | ||||
|     UINT64 AllocationSize, UINT64 FileSize) | ||||
| { | ||||
|     PAGED_CODE(); | ||||
|  | ||||
|     FSP_FILE_NODE *FileNode = FileObject->FsContext; | ||||
|  | ||||
|     ASSERT(ExIsResourceAcquiredExclusiveLite(FileNode->Header.PagingIoResource)); | ||||
|  | ||||
|     FileNode->Header.AllocationSize.QuadPart = AllocationSize; | ||||
|     FileNode->Header.FileSize.QuadPart = FileSize; | ||||
|     FileNode->CcStatus = FspCcSetFileSizes( | ||||
|         FileObject, (PCC_FILE_SIZES)&FileNode->Header.AllocationSize); | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user