diff --git a/src/sys/driver.h b/src/sys/driver.h index 0eb415f2..dfa31694 100644 --- a/src/sys/driver.h +++ b/src/sys/driver.h @@ -574,6 +574,7 @@ typedef struct UINT64 LastAccessTime; UINT64 LastWriteTime; UINT64 ChangeTime; + ULONG InfoChangeNumber; NTSTATUS CcStatus; /* read-only after creation (and insertion in the ContextTable) */ PDEVICE_OBJECT FsvolDeviceObject; @@ -620,6 +621,8 @@ VOID FspFileNodeGetFileInfo(FSP_FILE_NODE *FileNode, FSP_FSCTL_FILE_INFO *FileIn BOOLEAN FspFileNodeTryGetFileInfo(FSP_FILE_NODE *FileNode, FSP_FSCTL_FILE_INFO *FileInfo); VOID FspFileNodeSetFileInfo(FSP_FILE_NODE *FileNode, PFILE_OBJECT CcFileObject, const FSP_FSCTL_FILE_INFO *FileInfo); +BOOLEAN FspFileNodeTrySetFileInfo(FSP_FILE_NODE *FileNode, PFILE_OBJECT CcFileObject, + const FSP_FSCTL_FILE_INFO *FileInfo, ULONG InfoChangeNumber); NTSTATUS FspFileDescCreate(FSP_FILE_DESC **PFileDesc); VOID FspFileDescDelete(FSP_FILE_DESC *FileDesc); #define FspFileNodeAcquireShared(N,F) FspFileNodeAcquireSharedF(N, FspFileNodeAcquire ## F) diff --git a/src/sys/file.c b/src/sys/file.c index dc0e581a..2348dac6 100644 --- a/src/sys/file.c +++ b/src/sys/file.c @@ -24,6 +24,8 @@ VOID FspFileNodeGetFileInfo(FSP_FILE_NODE *FileNode, FSP_FSCTL_FILE_INFO *FileIn BOOLEAN FspFileNodeTryGetFileInfo(FSP_FILE_NODE *FileNode, FSP_FSCTL_FILE_INFO *FileInfo); VOID FspFileNodeSetFileInfo(FSP_FILE_NODE *FileNode, PFILE_OBJECT CcFileObject, const FSP_FSCTL_FILE_INFO *FileInfo); +BOOLEAN FspFileNodeTrySetFileInfo(FSP_FILE_NODE *FileNode, PFILE_OBJECT CcFileObject, + const FSP_FSCTL_FILE_INFO *FileInfo, ULONG InfoChangeNumber); NTSTATUS FspFileDescCreate(FSP_FILE_DESC **PFileDesc); VOID FspFileDescDelete(FSP_FILE_DESC *FileDesc); @@ -42,6 +44,7 @@ VOID FspFileDescDelete(FSP_FILE_DESC *FileDesc); #pragma alloc_text(PAGE, FspFileNodeGetFileInfo) #pragma alloc_text(PAGE, FspFileNodeTryGetFileInfo) #pragma alloc_text(PAGE, FspFileNodeSetFileInfo) +#pragma alloc_text(PAGE, FspFileNodeTrySetFileInfo) #pragma alloc_text(PAGE, FspFileDescCreate) #pragma alloc_text(PAGE, FspFileDescDelete) #endif @@ -412,12 +415,25 @@ VOID FspFileNodeSetFileInfo(FSP_FILE_NODE *FileNode, PFILE_OBJECT CcFileObject, FileNode->ChangeTime = FileInfo->ChangeTime; FileNode->InfoExpirationTime = 0 != FileInfoTimeout ? KeQueryInterruptTime() + FileInfoTimeout : 0; + FileNode->InfoChangeNumber++; if (0 != CcFileObject) FileNode->CcStatus = FspCcSetFileSizes( CcFileObject, (PCC_FILE_SIZES)&FileNode->Header.AllocationSize); } +BOOLEAN FspFileNodeTrySetFileInfo(FSP_FILE_NODE *FileNode, PFILE_OBJECT CcFileObject, + const FSP_FSCTL_FILE_INFO *FileInfo, ULONG InfoChangeNumber) +{ + PAGED_CODE(); + + if (FileNode->InfoChangeNumber != InfoChangeNumber) + return FALSE; + + FspFileNodeSetFileInfo(FileNode, CcFileObject, FileInfo); + return TRUE; +} + NTSTATUS FspFileDescCreate(FSP_FILE_DESC **PFileDesc) { PAGED_CODE(); diff --git a/src/sys/fileinfo.c b/src/sys/fileinfo.c index b0402077..84c65aa3 100644 --- a/src/sys/fileinfo.c +++ b/src/sys/fileinfo.c @@ -8,25 +8,25 @@ static NTSTATUS FspFsvolQueryAllInformation(PFILE_OBJECT FileObject, PVOID *PBuffer, PVOID BufferEnd, - FSP_FSCTL_TRANSACT_REQ *Request, const FSP_FSCTL_TRANSACT_RSP *Response); + const FSP_FSCTL_FILE_INFO *FileInfo); static NTSTATUS FspFsvolQueryAttributeTagInformation(PFILE_OBJECT FileObject, PVOID *PBuffer, PVOID BufferEnd, - FSP_FSCTL_TRANSACT_REQ *Request, const FSP_FSCTL_TRANSACT_RSP *Response); + const FSP_FSCTL_FILE_INFO *FileInfo); static NTSTATUS FspFsvolQueryBasicInformation(PFILE_OBJECT FileObject, PVOID *PBuffer, PVOID BufferEnd, - FSP_FSCTL_TRANSACT_REQ *Request, const FSP_FSCTL_TRANSACT_RSP *Response); + const FSP_FSCTL_FILE_INFO *FileInfo); static NTSTATUS FspFsvolQueryInternalInformation(PFILE_OBJECT FileObject, PVOID *PBuffer, PVOID BufferEnd); static NTSTATUS FspFsvolQueryNameInformation(PFILE_OBJECT FileObject, PVOID *PBuffer, PVOID BufferEnd); static NTSTATUS FspFsvolQueryNetworkOpenInformation(PFILE_OBJECT FileObject, PVOID *PBuffer, PVOID BufferEnd, - FSP_FSCTL_TRANSACT_REQ *Request, const FSP_FSCTL_TRANSACT_RSP *Response); + const FSP_FSCTL_FILE_INFO *FileInfo); static NTSTATUS FspFsvolQueryPositionInformation(PFILE_OBJECT FileObject, PVOID *PBuffer, PVOID BufferEnd); static NTSTATUS FspFsvolQueryStandardInformation(PFILE_OBJECT FileObject, PVOID *PBuffer, PVOID BufferEnd, - FSP_FSCTL_TRANSACT_REQ *Request, const FSP_FSCTL_TRANSACT_RSP *Response); + const FSP_FSCTL_FILE_INFO *FileInfo); static NTSTATUS FspFsvolQueryInformation( PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp); FSP_IOCMPL_DISPATCH FspFsvolQueryInformationComplete; @@ -82,58 +82,25 @@ FSP_DRIVER_DISPATCH FspSetInformation; enum { RequestFileNode = 0, - RequestAcquireFlags = 1, + RequestInfoChangeNumber = 1, }; static NTSTATUS FspFsvolQueryAllInformation(PFILE_OBJECT FileObject, PVOID *PBuffer, PVOID BufferEnd, - FSP_FSCTL_TRANSACT_REQ *Request, const FSP_FSCTL_TRANSACT_RSP *Response) + const FSP_FSCTL_FILE_INFO *FileInfo) { PAGED_CODE(); PFILE_ALL_INFORMATION Info = (PFILE_ALL_INFORMATION)*PBuffer; FSP_FILE_NODE *FileNode = FileObject->FsContext; - FSP_FSCTL_FILE_INFO FileInfoBuf; - const FSP_FSCTL_FILE_INFO *FileInfo; - if (0 == Request) + if (0 == FileInfo) { if ((PVOID)(Info + 1) > BufferEnd) return STATUS_BUFFER_TOO_SMALL; - if (!FspFileNodeTryGetFileInfo(FileNode, &FileInfoBuf)) - return FSP_STATUS_IOQ_POST; - FileInfo = &FileInfoBuf; - - FspFileNodeAcquireShared(FileNode, Full); + return STATUS_SUCCESS; } - else if (0 == Response) - { - FspFileNodeAcquireShared(FileNode, Full); - FspIopRequestContext(Request, RequestFileNode) = FileNode; - FspIopRequestContext(Request, RequestAcquireFlags) = (PVOID)FspFileNodeAcquireFull; - - return FSP_STATUS_IOQ_POST; - } - else - { - FspIopRequestContext(Request, RequestFileNode) = 0; - - FileInfo = &Response->Rsp.QueryInformation.FileInfo; - } - - Info->StandardInformation.AllocationSize = FileNode->Header.AllocationSize; - Info->StandardInformation.EndOfFile = FileNode->Header.FileSize; - - FspFileNodeRelease(FileNode, Pgio); - - Info->StandardInformation.NumberOfLinks = 1; - Info->StandardInformation.DeletePending = FileObject->DeletePending; - Info->StandardInformation.Directory = FileNode->IsDirectory; - - Info->PositionInformation.CurrentByteOffset = FileObject->CurrentByteOffset; - - FspFileNodeRelease(FileNode, Main); Info->BasicInformation.CreationTime.QuadPart = FileInfo->CreationTime; Info->BasicInformation.LastAccessTime.QuadPart = FileInfo->LastAccessTime; @@ -142,38 +109,37 @@ static NTSTATUS FspFsvolQueryAllInformation(PFILE_OBJECT FileObject, Info->BasicInformation.FileAttributes = 0 != FileInfo->FileAttributes ? FileInfo->FileAttributes : FILE_ATTRIBUTE_NORMAL; - Info->EaInformation.EaSize = 0; + Info->StandardInformation.AllocationSize.QuadPart = FileInfo->AllocationSize; + Info->StandardInformation.EndOfFile.QuadPart = FileInfo->FileSize; + Info->StandardInformation.NumberOfLinks = 1; + Info->StandardInformation.DeletePending = FileObject->DeletePending; + Info->StandardInformation.Directory = FileNode->IsDirectory; Info->InternalInformation.IndexNumber.QuadPart = FileNode->IndexNumber; + Info->EaInformation.EaSize = 0; + + Info->PositionInformation.CurrentByteOffset = FileObject->CurrentByteOffset; + *PBuffer = (PVOID)&Info->NameInformation; return FspFsvolQueryNameInformation(FileObject, PBuffer, BufferEnd); } static NTSTATUS FspFsvolQueryAttributeTagInformation(PFILE_OBJECT FileObject, PVOID *PBuffer, PVOID BufferEnd, - FSP_FSCTL_TRANSACT_REQ *Request, const FSP_FSCTL_TRANSACT_RSP *Response) + const FSP_FSCTL_FILE_INFO *FileInfo) { PAGED_CODE(); PFILE_ATTRIBUTE_TAG_INFORMATION Info = (PFILE_ATTRIBUTE_TAG_INFORMATION)*PBuffer; - FSP_FILE_NODE *FileNode = FileObject->FsContext; - FSP_FSCTL_FILE_INFO FileInfoBuf; - const FSP_FSCTL_FILE_INFO *FileInfo; - if (0 == Request) + if (0 == FileInfo) { - if ((PVOID)(Info + 1) > (PVOID)BufferEnd) + if ((PVOID)(Info + 1) > BufferEnd) return STATUS_BUFFER_TOO_SMALL; - if (!FspFileNodeTryGetFileInfo(FileNode, &FileInfoBuf)) - return FSP_STATUS_IOQ_POST; - FileInfo = &FileInfoBuf; + return STATUS_SUCCESS; } - else if (0 == Response) - return FSP_STATUS_IOQ_POST; - else - FileInfo = &Response->Rsp.QueryInformation.FileInfo; Info->FileAttributes = 0 != FileInfo->FileAttributes ? FileInfo->FileAttributes : FILE_ATTRIBUTE_NORMAL; @@ -186,28 +152,19 @@ static NTSTATUS FspFsvolQueryAttributeTagInformation(PFILE_OBJECT FileObject, static NTSTATUS FspFsvolQueryBasicInformation(PFILE_OBJECT FileObject, PVOID *PBuffer, PVOID BufferEnd, - FSP_FSCTL_TRANSACT_REQ *Request, const FSP_FSCTL_TRANSACT_RSP *Response) + const FSP_FSCTL_FILE_INFO *FileInfo) { PAGED_CODE(); PFILE_BASIC_INFORMATION Info = (PFILE_BASIC_INFORMATION)*PBuffer; - FSP_FILE_NODE *FileNode = FileObject->FsContext; - FSP_FSCTL_FILE_INFO FileInfoBuf; - const FSP_FSCTL_FILE_INFO *FileInfo; - if (0 == Request) + if (0 == FileInfo) { - if ((PVOID)(Info + 1) > (PVOID)BufferEnd) + if ((PVOID)(Info + 1) > BufferEnd) return STATUS_BUFFER_TOO_SMALL; - if (!FspFileNodeTryGetFileInfo(FileNode, &FileInfoBuf)) - return FSP_STATUS_IOQ_POST; - FileInfo = &FileInfoBuf; + return STATUS_SUCCESS; } - else if (0 == Response) - return FSP_STATUS_IOQ_POST; - else - FileInfo = &Response->Rsp.QueryInformation.FileInfo; Info->CreationTime.QuadPart = FileInfo->CreationTime; Info->LastAccessTime.QuadPart = FileInfo->LastAccessTime; @@ -229,7 +186,7 @@ static NTSTATUS FspFsvolQueryInternalInformation(PFILE_OBJECT FileObject, PFILE_INTERNAL_INFORMATION Info = (PFILE_INTERNAL_INFORMATION)*PBuffer; FSP_FILE_NODE *FileNode = FileObject->FsContext; - if ((PVOID)(Info + 1) > (PVOID)BufferEnd) + if ((PVOID)(Info + 1) > BufferEnd) return STATUS_BUFFER_TOO_SMALL; Info->IndexNumber.QuadPart = FileNode->IndexNumber; @@ -252,7 +209,7 @@ static NTSTATUS FspFsvolQueryNameInformation(PFILE_OBJECT FileObject, FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(FileNode->FsvolDeviceObject); - if ((PVOID)(Info + 1) > (PVOID)BufferEnd) + if ((PVOID)(Info + 1) > BufferEnd) return STATUS_BUFFER_TOO_SMALL; Info->FileNameLength = FsvolDeviceExtension->VolumePrefix.Length + FileNode->FileName.Length; @@ -282,46 +239,22 @@ static NTSTATUS FspFsvolQueryNameInformation(PFILE_OBJECT FileObject, static NTSTATUS FspFsvolQueryNetworkOpenInformation(PFILE_OBJECT FileObject, PVOID *PBuffer, PVOID BufferEnd, - FSP_FSCTL_TRANSACT_REQ *Request, const FSP_FSCTL_TRANSACT_RSP *Response) + const FSP_FSCTL_FILE_INFO *FileInfo) { PAGED_CODE(); PFILE_NETWORK_OPEN_INFORMATION Info = (PFILE_NETWORK_OPEN_INFORMATION)*PBuffer; - FSP_FILE_NODE *FileNode = FileObject->FsContext; - FSP_FSCTL_FILE_INFO FileInfoBuf; - const FSP_FSCTL_FILE_INFO *FileInfo; - if (0 == Request) + if (0 == FileInfo) { if ((PVOID)(Info + 1) > BufferEnd) return STATUS_BUFFER_TOO_SMALL; - if (!FspFileNodeTryGetFileInfo(FileNode, &FileInfoBuf)) - return FSP_STATUS_IOQ_POST; - FileInfo = &FileInfoBuf; - - FspFileNodeAcquireShared(FileNode, Full); - } - else if (0 == Response) - { - FspFileNodeAcquireShared(FileNode, Full); - FspIopRequestContext(Request, RequestFileNode) = FileNode; - FspIopRequestContext(Request, RequestAcquireFlags) = (PVOID)FspFileNodeAcquireFull; - - return FSP_STATUS_IOQ_POST; - } - else - { - FspIopRequestContext(Request, RequestFileNode) = 0; - - FileInfo = &Response->Rsp.QueryInformation.FileInfo; + return STATUS_SUCCESS; } - Info->AllocationSize = FileNode->Header.AllocationSize; - Info->EndOfFile = FileNode->Header.FileSize; - - FspFileNodeRelease(FileNode, Full); - + Info->AllocationSize.QuadPart = FileInfo->AllocationSize; + Info->EndOfFile.QuadPart = FileInfo->FileSize; Info->CreationTime.QuadPart = FileInfo->CreationTime; Info->LastAccessTime.QuadPart = FileInfo->LastAccessTime; Info->LastWriteTime.QuadPart = FileInfo->LastWriteTime; @@ -342,7 +275,7 @@ static NTSTATUS FspFsvolQueryPositionInformation(PFILE_OBJECT FileObject, PFILE_POSITION_INFORMATION Info = (PFILE_POSITION_INFORMATION)*PBuffer; FSP_FILE_NODE *FileNode = FileObject->FsContext; - if ((PVOID)(Info + 1) > (PVOID)BufferEnd) + if ((PVOID)(Info + 1) > BufferEnd) return STATUS_BUFFER_TOO_SMALL; FspFileNodeAcquireShared(FileNode, Main); @@ -358,52 +291,27 @@ static NTSTATUS FspFsvolQueryPositionInformation(PFILE_OBJECT FileObject, static NTSTATUS FspFsvolQueryStandardInformation(PFILE_OBJECT FileObject, PVOID *PBuffer, PVOID BufferEnd, - FSP_FSCTL_TRANSACT_REQ *Request, const FSP_FSCTL_TRANSACT_RSP *Response) + const FSP_FSCTL_FILE_INFO *FileInfo) { PAGED_CODE(); PFILE_STANDARD_INFORMATION Info = (PFILE_STANDARD_INFORMATION)*PBuffer; FSP_FILE_NODE *FileNode = FileObject->FsContext; - FSP_FSCTL_FILE_INFO FileInfoBuf; - const FSP_FSCTL_FILE_INFO *FileInfo; - if (0 == Request) + if (0 == FileInfo) { if ((PVOID)(Info + 1) > BufferEnd) return STATUS_BUFFER_TOO_SMALL; - if (!FspFileNodeTryGetFileInfo(FileNode, &FileInfoBuf)) - return FSP_STATUS_IOQ_POST; - FileInfo = &FileInfoBuf; - - FspFileNodeAcquireShared(FileNode, Full); - } - else if (0 == Response) - { - FspFileNodeAcquireShared(FileNode, Full); - FspIopRequestContext(Request, RequestFileNode) = FileNode; - FspIopRequestContext(Request, RequestAcquireFlags) = (PVOID)FspFileNodeAcquireFull; - - return FSP_STATUS_IOQ_POST; - } - else - { - FspIopRequestContext(Request, RequestFileNode) = 0; - - FileInfo = &Response->Rsp.QueryInformation.FileInfo; + return STATUS_SUCCESS; } - Info->AllocationSize = FileNode->Header.AllocationSize; - Info->EndOfFile = FileNode->Header.FileSize; - - FspFileNodeRelease(FileNode, Pgio); - + Info->AllocationSize.QuadPart = FileInfo->AllocationSize; + Info->EndOfFile.QuadPart = FileInfo->FileSize; Info->NumberOfLinks = 1; Info->DeletePending = FileObject->DeletePending; Info->Directory = FileNode->IsDirectory; - FspFileNodeRelease(FileNode, Main); - *PBuffer = (PVOID)(Info + 1); return STATUS_SUCCESS; @@ -421,99 +329,113 @@ static NTSTATUS FspFsvolQueryInformation( NTSTATUS Result; FILE_INFORMATION_CLASS FileInformationClass = IrpSp->Parameters.QueryFile.FileInformationClass; PFILE_OBJECT FileObject = IrpSp->FileObject; + FSP_FILE_NODE *FileNode = FileObject->FsContext; + FSP_FILE_DESC *FileDesc = FileObject->FsContext2; PVOID Buffer = Irp->AssociatedIrp.SystemBuffer; PVOID BufferEnd = (PUINT8)Buffer + IrpSp->Parameters.QueryFile.Length; + FSP_FSCTL_FILE_INFO FileInfoBuf; + + ASSERT(FileNode == FileDesc->FileNode); switch (FileInformationClass) { case FileAllInformation: - Result = FspFsvolQueryAllInformation(FileObject, &Buffer, BufferEnd, 0, 0); + Result = FspFsvolQueryAllInformation(FileObject, &Buffer, BufferEnd, 0); break; case FileAttributeTagInformation: - Result = FspFsvolQueryAttributeTagInformation(FileObject, &Buffer, BufferEnd, 0, 0); + Result = FspFsvolQueryAttributeTagInformation(FileObject, &Buffer, BufferEnd, 0); break; case FileBasicInformation: - Result = FspFsvolQueryBasicInformation(FileObject, &Buffer, BufferEnd, 0, 0); + Result = FspFsvolQueryBasicInformation(FileObject, &Buffer, BufferEnd, 0); break; case FileCompressionInformation: Result = STATUS_INVALID_PARAMETER; /* no compression support */ - break; + return Result; case FileEaInformation: Result = STATUS_INVALID_PARAMETER; /* no EA support currently */ - break; + return Result; case FileHardLinkInformation: Result = STATUS_INVALID_PARAMETER; /* no hard link support */ - break; + return Result; case FileInternalInformation: Result = FspFsvolQueryInternalInformation(FileObject, &Buffer, BufferEnd); - break; + return Result; case FileNameInformation: Result = FspFsvolQueryNameInformation(FileObject, &Buffer, BufferEnd); - break; + return Result; case FileNetworkOpenInformation: - Result = FspFsvolQueryNetworkOpenInformation(FileObject, &Buffer, BufferEnd, 0, 0); + Result = FspFsvolQueryNetworkOpenInformation(FileObject, &Buffer, BufferEnd, 0); break; case FilePositionInformation: Result = FspFsvolQueryPositionInformation(FileObject, &Buffer, BufferEnd); - break; + return Result; case FileStandardInformation: - Result = FspFsvolQueryStandardInformation(FileObject, &Buffer, BufferEnd, 0, 0); + Result = FspFsvolQueryStandardInformation(FileObject, &Buffer, BufferEnd, 0); break; case FileStreamInformation: Result = STATUS_INVALID_PARAMETER; /* !!!: no stream support yet! */ - break; + return Result; default: Result = STATUS_INVALID_PARAMETER; - break; + return Result; } - if (FSP_STATUS_IOQ_POST != Result) + if (!NT_SUCCESS(Result)) + return Result; + + FspFileNodeAcquireShared(FileNode, Main); + if (FspFileNodeTryGetFileInfo(FileNode, &FileInfoBuf)) { + FspFileNodeRelease(FileNode, Main); + switch (FileInformationClass) + { + case FileAllInformation: + Result = FspFsvolQueryAllInformation(FileObject, &Buffer, BufferEnd, &FileInfoBuf); + break; + case FileAttributeTagInformation: + Result = FspFsvolQueryAttributeTagInformation(FileObject, &Buffer, BufferEnd, &FileInfoBuf); + break; + case FileBasicInformation: + Result = FspFsvolQueryBasicInformation(FileObject, &Buffer, BufferEnd, &FileInfoBuf); + break; + case FileNetworkOpenInformation: + Result = FspFsvolQueryNetworkOpenInformation(FileObject, &Buffer, BufferEnd, &FileInfoBuf); + break; + case FileStandardInformation: + Result = FspFsvolQueryStandardInformation(FileObject, &Buffer, BufferEnd, &FileInfoBuf); + break; + default: + ASSERT(0); + Result = STATUS_INVALID_PARAMETER; + break; + } + Irp->IoStatus.Information = (UINT_PTR)((PUINT8)Buffer - (PUINT8)Irp->AssociatedIrp.SystemBuffer); return Result; } + FspFileNodeAcquireShared(FileNode, Pgio); + FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = FspFsvolDeviceExtension(FsvolDeviceObject); BOOLEAN FileNameRequired = 0 != FsvolDeviceExtension->VolumeParams.FileNameRequired; - FSP_FILE_NODE *FileNode = FileObject->FsContext; - FSP_FILE_DESC *FileDesc = FileObject->FsContext2; FSP_FSCTL_TRANSACT_REQ *Request; - ASSERT(FileNode == FileDesc->FileNode); - Result = FspIopCreateRequestEx(Irp, FileNameRequired ? &FileNode->FileName : 0, 0, FspFsvolInformationRequestFini, &Request); if (!NT_SUCCESS(Result)) + { + FspFileNodeRelease(FileNode, Full); return Result; + } Request->Kind = FspFsctlTransactQueryInformationKind; Request->Req.QueryInformation.UserContext = FileNode->UserContext; Request->Req.QueryInformation.UserContext2 = FileDesc->UserContext2; - switch (FileInformationClass) - { - case FileAllInformation: - Result = FspFsvolQueryAllInformation(FileObject, &Buffer, BufferEnd, Request, 0); - break; - case FileAttributeTagInformation: - Result = FspFsvolQueryAttributeTagInformation(FileObject, &Buffer, BufferEnd, Request, 0); - break; - case FileBasicInformation: - Result = FspFsvolQueryBasicInformation(FileObject, &Buffer, BufferEnd, Request, 0); - break; - case FileNetworkOpenInformation: - Result = FspFsvolQueryNetworkOpenInformation(FileObject, &Buffer, BufferEnd, Request, 0); - break; - case FileStandardInformation: - Result = FspFsvolQueryStandardInformation(FileObject, &Buffer, BufferEnd, Request, 0); - break; - default: - ASSERT(0); - Result = STATUS_INVALID_PARAMETER; - break; - } + FspFileNodeSetOwner(FileNode, Full, Request); + FspIopRequestContext(Request, RequestFileNode) = FileNode; - return Result; + return FSP_STATUS_IOQ_POST; } NTSTATUS FspFsvolQueryInformationComplete( @@ -523,7 +445,7 @@ NTSTATUS FspFsvolQueryInformationComplete( if (!NT_SUCCESS(Response->IoStatus.Status)) { - Irp->IoStatus.Information = Response->IoStatus.Information; + Irp->IoStatus.Information = 0; Result = Response->IoStatus.Status; FSP_RETURN(); } @@ -534,25 +456,47 @@ NTSTATUS FspFsvolQueryInformationComplete( PVOID Buffer = Irp->AssociatedIrp.SystemBuffer; PVOID BufferEnd = (PUINT8)Buffer + IrpSp->Parameters.QueryFile.Length; FSP_FSCTL_TRANSACT_REQ *Request = FspIrpRequest(Irp); + FSP_FSCTL_FILE_INFO FileInfoBuf; + const FSP_FSCTL_FILE_INFO *FileInfo; - FspFileNodeSetFileInfo(FileNode, &Response->Rsp.QueryInformation.FileInfo); + if (0 != FspIopRequestContext(Request, RequestFileNode)) + { + FspIopRequestContext(Request, RequestInfoChangeNumber) = (PVOID)FileNode->InfoChangeNumber; + FspIopRequestContext(Request, RequestFileNode) = 0; + + FspFileNodeReleaseOwner(FileNode, Full, Request); + } + + if (!FspFileNodeTryAcquireExclusive(FileNode, Main)) + FspIopRetryCompleteIrp(Irp, Response, &Result); + + if (!FspFileNodeTrySetFileInfo(FileNode, FileObject, &Response->Rsp.QueryInformation.FileInfo, + (ULONG)(UINT_PTR)FspIopRequestContext(Request, RequestInfoChangeNumber))) + { + FspFileNodeGetFileInfo(FileNode, &FileInfoBuf); + FileInfo = &FileInfoBuf; + } + else + FileInfo = &Response->Rsp.QueryInformation.FileInfo; + + FspFileNodeRelease(FileNode, Main); switch (FileInformationClass) { case FileAllInformation: - Result = FspFsvolQueryAllInformation(FileObject, &Buffer, BufferEnd, Request, Response); + Result = FspFsvolQueryAllInformation(FileObject, &Buffer, BufferEnd, FileInfo); break; case FileAttributeTagInformation: - Result = FspFsvolQueryAttributeTagInformation(FileObject, &Buffer, BufferEnd, Request, Response); + Result = FspFsvolQueryAttributeTagInformation(FileObject, &Buffer, BufferEnd, FileInfo); break; case FileBasicInformation: - Result = FspFsvolQueryBasicInformation(FileObject, &Buffer, BufferEnd, Request, Response); + Result = FspFsvolQueryBasicInformation(FileObject, &Buffer, BufferEnd, FileInfo); break; case FileNetworkOpenInformation: - Result = FspFsvolQueryNetworkOpenInformation(FileObject, &Buffer, BufferEnd, Request, Response); + Result = FspFsvolQueryNetworkOpenInformation(FileObject, &Buffer, BufferEnd, FileInfo); break; case FileStandardInformation: - Result = FspFsvolQueryStandardInformation(FileObject, &Buffer, BufferEnd, Request, Response); + Result = FspFsvolQueryStandardInformation(FileObject, &Buffer, BufferEnd, FileInfo); break; default: ASSERT(0); @@ -560,9 +504,6 @@ NTSTATUS FspFsvolQueryInformationComplete( break; } - ASSERT(FSP_STATUS_IOQ_POST != Result); - - if (STATUS_PENDING != Result) Irp->IoStatus.Information = (UINT_PTR)((PUINT8)Buffer - (PUINT8)Irp->AssociatedIrp.SystemBuffer); FSP_LEAVE_IOC("%s, FileObject=%p", @@ -570,6 +511,7 @@ NTSTATUS FspFsvolQueryInformationComplete( IrpSp->FileObject); } +#if 0 static NTSTATUS FspFsvolSetAllocationInformation(PFILE_OBJECT FileObject, PVOID Buffer, ULONG Length, FSP_FSCTL_TRANSACT_REQ *Request, const FSP_FSCTL_TRANSACT_RSP *Response) @@ -664,12 +606,14 @@ static NTSTATUS FspFsvolSetRenameInformation(PFILE_OBJECT FileObject, return STATUS_INVALID_DEVICE_REQUEST; } +#endif static NTSTATUS FspFsvolSetInformation( PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp) { PAGED_CODE(); +#if 0 /* is this a valid FileObject? */ if (!FspFileNodeIsValid(IrpSp->FileObject->FsContext)) return STATUS_INVALID_DEVICE_REQUEST; @@ -730,6 +674,9 @@ static NTSTATUS FspFsvolSetInformation( } return Result; +#else + return STATUS_INVALID_DEVICE_REQUEST; +#endif } NTSTATUS FspFsvolSetInformationComplete( @@ -737,6 +684,7 @@ NTSTATUS FspFsvolSetInformationComplete( { FSP_ENTER_IOC(PAGED_CODE()); +#if 0 if (!NT_SUCCESS(Response->IoStatus.Status)) { Irp->IoStatus.Information = Response->IoStatus.Information; @@ -788,23 +736,21 @@ NTSTATUS FspFsvolSetInformationComplete( ASSERT(FSP_STATUS_IOQ_POST != Result); Irp->IoStatus.Information = 0; +#endif FSP_LEAVE_IOC("%s, FileObject=%p", FileInformationClassSym(IrpSp->Parameters.SetFile.FileInformationClass), IrpSp->FileObject); } -static VOID FspFsvolInformationRequestFini(PVOID Context[3]) +static VOID FspFsvolInformationRequestFini(FSP_FSCTL_TRANSACT_REQ *Request, PVOID Context[3]) { PAGED_CODE(); FSP_FILE_NODE *FileNode = Context[RequestFileNode]; - ULONG AcquireFlags = (ULONG)(UINT_PTR)Context[RequestAcquireFlags]; if (0 != FileNode) - FspFileNodeReleaseF(FileNode, AcquireFlags); - - Context[RequestFileNode] = Context[RequestAcquireFlags] = 0; + FspFileNodeReleaseOwner(FileNode, Full, Request); } NTSTATUS FspQueryInformation(