mirror of
				https://github.com/winfsp/winfsp.git
				synced 2025-10-31 12:08:41 -05:00 
			
		
		
		
	sys: IRP_MJ_SET_INFORMATION
This commit is contained in:
		| @@ -62,6 +62,26 @@ typedef struct _FSP_FILE_SYSTEM_INTERFACE | |||||||
|         FSP_FSCTL_TRANSACT_REQ *Request, |         FSP_FSCTL_TRANSACT_REQ *Request, | ||||||
|         PVOID FileNode, |         PVOID FileNode, | ||||||
|         FSP_FSCTL_FILE_INFO *FileInfo); |         FSP_FSCTL_FILE_INFO *FileInfo); | ||||||
|  |     NTSTATUS (*SetBasicInfo)(FSP_FILE_SYSTEM *FileSystem, | ||||||
|  |         FSP_FSCTL_TRANSACT_REQ *Request, | ||||||
|  |         PVOID FileNode, UINT32 FileAttributes, | ||||||
|  |         UINT64 CreationTime, UINT64 LastAccessTime, UINT64 LastWriteTime, | ||||||
|  |         FSP_FSCTL_FILE_INFO *FileInfo); | ||||||
|  |     NTSTATUS (*SetAllocationSize)(FSP_FILE_SYSTEM *FileSystem, | ||||||
|  |         FSP_FSCTL_TRANSACT_REQ *Request, | ||||||
|  |         PVOID FileNode, UINT64 AllocationSize, | ||||||
|  |         FSP_FSCTL_FILE_INFO *FileInfo); | ||||||
|  |     NTSTATUS (*SetFileSize)(FSP_FILE_SYSTEM *FileSystem, | ||||||
|  |         FSP_FSCTL_TRANSACT_REQ *Request, | ||||||
|  |         PVOID FileNode, UINT64 FileSize, BOOLEAN AdvanceOnly, | ||||||
|  |         FSP_FSCTL_FILE_INFO *FileInfo); | ||||||
|  |     NTSTATUS (*CanDelete)(FSP_FILE_SYSTEM *FileSystem, | ||||||
|  |         FSP_FSCTL_TRANSACT_REQ *Request, | ||||||
|  |         PVOID FileNode); | ||||||
|  |     NTSTATUS (*Rename)(FSP_FILE_SYSTEM *FileSystem, | ||||||
|  |         FSP_FSCTL_TRANSACT_REQ *Request, | ||||||
|  |         PVOID FileNode, | ||||||
|  |         PWSTR ExistingFileName, PWSTR NewFileName, BOOLEAN ReplaceIfExists); | ||||||
| } FSP_FILE_SYSTEM_INTERFACE; | } FSP_FILE_SYSTEM_INTERFACE; | ||||||
| typedef struct _FSP_FILE_SYSTEM | typedef struct _FSP_FILE_SYSTEM | ||||||
| { | { | ||||||
| @@ -167,6 +187,8 @@ FSP_API NTSTATUS FspFileSystemOpClose(FSP_FILE_SYSTEM *FileSystem, | |||||||
|     FSP_FSCTL_TRANSACT_REQ *Request); |     FSP_FSCTL_TRANSACT_REQ *Request); | ||||||
| FSP_API NTSTATUS FspFileSystemOpQueryInformation(FSP_FILE_SYSTEM *FileSystem, | FSP_API NTSTATUS FspFileSystemOpQueryInformation(FSP_FILE_SYSTEM *FileSystem, | ||||||
|     FSP_FSCTL_TRANSACT_REQ *Request); |     FSP_FSCTL_TRANSACT_REQ *Request); | ||||||
|  | FSP_API NTSTATUS FspFileSystemOpSetInformation(FSP_FILE_SYSTEM *FileSystem, | ||||||
|  |     FSP_FSCTL_TRANSACT_REQ *Request); | ||||||
| FSP_API NTSTATUS FspFileSystemOpQueryVolumeInformation(FSP_FILE_SYSTEM *FileSystem, | FSP_API NTSTATUS FspFileSystemOpQueryVolumeInformation(FSP_FILE_SYSTEM *FileSystem, | ||||||
|     FSP_FSCTL_TRANSACT_REQ *Request); |     FSP_FSCTL_TRANSACT_REQ *Request); | ||||||
| FSP_API NTSTATUS FspFileSystemSendCreateResponse(FSP_FILE_SYSTEM *FileSystem, | FSP_API NTSTATUS FspFileSystemSendCreateResponse(FSP_FILE_SYSTEM *FileSystem, | ||||||
| @@ -181,6 +203,8 @@ FSP_API NTSTATUS FspFileSystemSendCloseResponse(FSP_FILE_SYSTEM *FileSystem, | |||||||
|     FSP_FSCTL_TRANSACT_REQ *Request); |     FSP_FSCTL_TRANSACT_REQ *Request); | ||||||
| FSP_API NTSTATUS FspFileSystemSendQueryInformationResponse(FSP_FILE_SYSTEM *FileSystem, | FSP_API NTSTATUS FspFileSystemSendQueryInformationResponse(FSP_FILE_SYSTEM *FileSystem, | ||||||
|     FSP_FSCTL_TRANSACT_REQ *Request, const FSP_FSCTL_FILE_INFO *FileInfo); |     FSP_FSCTL_TRANSACT_REQ *Request, const FSP_FSCTL_FILE_INFO *FileInfo); | ||||||
|  | FSP_API NTSTATUS FspFileSystemSendSetInformationResponse(FSP_FILE_SYSTEM *FileSystem, | ||||||
|  |     FSP_FSCTL_TRANSACT_REQ *Request, const FSP_FSCTL_FILE_INFO *FileInfo); | ||||||
| FSP_API NTSTATUS FspFileSystemSendQueryVolumeInformationResponse(FSP_FILE_SYSTEM *FileSystem, | FSP_API NTSTATUS FspFileSystemSendQueryVolumeInformationResponse(FSP_FILE_SYSTEM *FileSystem, | ||||||
|     FSP_FSCTL_TRANSACT_REQ *Request, const FSP_FSCTL_VOLUME_INFO *VolumeInfo); |     FSP_FSCTL_TRANSACT_REQ *Request, const FSP_FSCTL_VOLUME_INFO *VolumeInfo); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -17,13 +17,88 @@ FSP_API NTSTATUS FspFileSystemOpQueryInformation(FSP_FILE_SYSTEM *FileSystem, | |||||||
|  |  | ||||||
|     memset(&FileInfo, 0, sizeof FileInfo); |     memset(&FileInfo, 0, sizeof FileInfo); | ||||||
|     Result = FileSystem->Interface->GetFileInfo(FileSystem, Request, |     Result = FileSystem->Interface->GetFileInfo(FileSystem, Request, | ||||||
|         (PVOID)Request->Req.Close.UserContext, &FileInfo); |         (PVOID)Request->Req.QueryInformation.UserContext, &FileInfo); | ||||||
|     if (!NT_SUCCESS(Result)) |     if (!NT_SUCCESS(Result)) | ||||||
|         return FspFileSystemSendResponseWithStatus(FileSystem, Request, Result); |         return FspFileSystemSendResponseWithStatus(FileSystem, Request, Result); | ||||||
|  |  | ||||||
|     return FspFileSystemSendQueryInformationResponse(FileSystem, Request, &FileInfo); |     return FspFileSystemSendQueryInformationResponse(FileSystem, Request, &FileInfo); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | FSP_API NTSTATUS FspFileSystemOpSetInformation(FSP_FILE_SYSTEM *FileSystem, | ||||||
|  |     FSP_FSCTL_TRANSACT_REQ *Request) | ||||||
|  | { | ||||||
|  |     NTSTATUS Result; | ||||||
|  |     FSP_FSCTL_FILE_INFO FileInfo; | ||||||
|  |  | ||||||
|  |     Result = STATUS_INVALID_DEVICE_REQUEST; | ||||||
|  |     memset(&FileInfo, 0, sizeof FileInfo); | ||||||
|  |     switch (Request->Req.SetInformation.FileInformationClass) | ||||||
|  |     { | ||||||
|  |     case 4/*FileBasicInformation*/: | ||||||
|  |         if (0 != FileSystem->Interface->SetBasicInfo) | ||||||
|  |             Result = FileSystem->Interface->SetBasicInfo(FileSystem, Request, | ||||||
|  |                 (PVOID)Request->Req.SetInformation.UserContext, | ||||||
|  |                 Request->Req.SetInformation.Info.Basic.FileAttributes, | ||||||
|  |                 Request->Req.SetInformation.Info.Basic.CreationTime, | ||||||
|  |                 Request->Req.SetInformation.Info.Basic.LastAccessTime, | ||||||
|  |                 Request->Req.SetInformation.Info.Basic.LastWriteTime, | ||||||
|  |                 &FileInfo); | ||||||
|  |         break; | ||||||
|  |     case 19/*FileAllocationInformation*/: | ||||||
|  |         if (0 != FileSystem->Interface->SetAllocationSize) | ||||||
|  |             Result = FileSystem->Interface->SetAllocationSize(FileSystem, Request, | ||||||
|  |                 (PVOID)Request->Req.SetInformation.UserContext, | ||||||
|  |                 Request->Req.SetInformation.Info.Allocation.AllocationSize, | ||||||
|  |                 &FileInfo); | ||||||
|  |         else | ||||||
|  |         if (0 != FileSystem->Interface->GetFileInfo && | ||||||
|  |             0 != FileSystem->Interface->SetFileSize) | ||||||
|  |         { | ||||||
|  |             Result = FileSystem->Interface->GetFileInfo(FileSystem, Request, | ||||||
|  |                 (PVOID)Request->Req.SetInformation.UserContext, &FileInfo); | ||||||
|  |             if (NT_SUCCESS(Result) && | ||||||
|  |                 Request->Req.SetInformation.Info.Allocation.AllocationSize < FileInfo.FileSize) | ||||||
|  |             { | ||||||
|  |                 Result = FileSystem->Interface->SetFileSize(FileSystem, Request, | ||||||
|  |                     (PVOID)Request->Req.SetInformation.UserContext, | ||||||
|  |                     Request->Req.SetInformation.Info.Allocation.AllocationSize, | ||||||
|  |                     FALSE, | ||||||
|  |                     &FileInfo); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         break; | ||||||
|  |     case 20/*FileEndOfFileInformation*/: | ||||||
|  |         if (0 != FileSystem->Interface->SetFileSize) | ||||||
|  |             Result = FileSystem->Interface->SetFileSize(FileSystem, Request, | ||||||
|  |                 (PVOID)Request->Req.SetInformation.UserContext, | ||||||
|  |                 Request->Req.SetInformation.Info.EndOfFile.FileSize, | ||||||
|  |                 Request->Req.SetInformation.Info.EndOfFile.AdvanceOnly, | ||||||
|  |                 &FileInfo); | ||||||
|  |         break; | ||||||
|  |     case 13/*FileDispositionInformation*/: | ||||||
|  |         if (0 != FileSystem->Interface->CanDelete) | ||||||
|  |             if (Request->Req.SetInformation.Info.Disposition.Delete) | ||||||
|  |                 Result = FileSystem->Interface->CanDelete(FileSystem, Request, | ||||||
|  |                     (PVOID)Request->Req.Close.UserContext); | ||||||
|  |             else | ||||||
|  |                 Result = STATUS_SUCCESS; | ||||||
|  |         break; | ||||||
|  |     case 10/*FileRenameInformation*/: | ||||||
|  |         if (0 != FileSystem->Interface->Rename) | ||||||
|  |             Result = FileSystem->Interface->Rename(FileSystem, Request, | ||||||
|  |                 (PVOID)Request->Req.SetInformation.UserContext, | ||||||
|  |                 (PWSTR)Request->Buffer, | ||||||
|  |                 (PWSTR)(Request->Buffer + Request->Req.SetInformation.Info.Rename.NewFileName.Offset), | ||||||
|  |                 Request->Req.SetInformation.Info.Rename.ReplaceIfExists); | ||||||
|  |         break; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     if (!NT_SUCCESS(Result)) | ||||||
|  |         return FspFileSystemSendResponseWithStatus(FileSystem, Request, Result); | ||||||
|  |  | ||||||
|  |     return FspFileSystemSendSetInformationResponse(FileSystem, Request, &FileInfo); | ||||||
|  | } | ||||||
|  |  | ||||||
| FSP_API NTSTATUS FspFileSystemSendQueryInformationResponse(FSP_FILE_SYSTEM *FileSystem, | FSP_API NTSTATUS FspFileSystemSendQueryInformationResponse(FSP_FILE_SYSTEM *FileSystem, | ||||||
|     FSP_FSCTL_TRANSACT_REQ *Request, const FSP_FSCTL_FILE_INFO *FileInfo) |     FSP_FSCTL_TRANSACT_REQ *Request, const FSP_FSCTL_FILE_INFO *FileInfo) | ||||||
| { | { | ||||||
| @@ -38,3 +113,18 @@ FSP_API NTSTATUS FspFileSystemSendQueryInformationResponse(FSP_FILE_SYSTEM *File | |||||||
|     Response.Rsp.QueryInformation.FileInfo = *FileInfo; |     Response.Rsp.QueryInformation.FileInfo = *FileInfo; | ||||||
|     return FspFileSystemSendResponse(FileSystem, &Response); |     return FspFileSystemSendResponse(FileSystem, &Response); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | FSP_API NTSTATUS FspFileSystemSendSetInformationResponse(FSP_FILE_SYSTEM *FileSystem, | ||||||
|  |     FSP_FSCTL_TRANSACT_REQ *Request, const FSP_FSCTL_FILE_INFO *FileInfo) | ||||||
|  | { | ||||||
|  |     FSP_FSCTL_TRANSACT_RSP Response; | ||||||
|  |  | ||||||
|  |     memset(&Response, 0, sizeof Response); | ||||||
|  |     Response.Size = sizeof Response; | ||||||
|  |     Response.Kind = FspFsctlTransactSetInformationKind; | ||||||
|  |     Response.Hint = Request->Hint; | ||||||
|  |     Response.IoStatus.Status = STATUS_SUCCESS; | ||||||
|  |     Response.IoStatus.Information = 0; | ||||||
|  |     Response.Rsp.SetInformation.FileInfo = *FileInfo; | ||||||
|  |     return FspFileSystemSendResponse(FileSystem, &Response); | ||||||
|  | } | ||||||
|   | |||||||
| @@ -116,7 +116,8 @@ static NTSTATUS FspFsvolCreate( | |||||||
|     USHORT FileAttributes = IrpSp->Parameters.Create.FileAttributes; |     USHORT FileAttributes = IrpSp->Parameters.Create.FileAttributes; | ||||||
|     PSECURITY_DESCRIPTOR SecurityDescriptor = AccessState->SecurityDescriptor; |     PSECURITY_DESCRIPTOR SecurityDescriptor = AccessState->SecurityDescriptor; | ||||||
|     ULONG SecurityDescriptorSize = 0; |     ULONG SecurityDescriptorSize = 0; | ||||||
|     LARGE_INTEGER AllocationSize = Irp->Overlay.AllocationSize; |     UINT64 AllocationSize = Irp->Overlay.AllocationSize.QuadPart; | ||||||
|  |     UINT64 AllocationUnit; | ||||||
|     ACCESS_MASK DesiredAccess = IrpSp->Parameters.Create.SecurityContext->DesiredAccess; |     ACCESS_MASK DesiredAccess = IrpSp->Parameters.Create.SecurityContext->DesiredAccess; | ||||||
|     USHORT ShareAccess = IrpSp->Parameters.Create.ShareAccess; |     USHORT ShareAccess = IrpSp->Parameters.Create.ShareAccess; | ||||||
|     PFILE_FULL_EA_INFORMATION EaBuffer = Irp->AssociatedIrp.SystemBuffer; |     PFILE_FULL_EA_INFORMATION EaBuffer = Irp->AssociatedIrp.SystemBuffer; | ||||||
| @@ -156,6 +157,11 @@ static NTSTATUS FspFsvolCreate( | |||||||
|         SecurityDescriptorSize = RtlLengthSecurityDescriptor(SecurityDescriptor); |         SecurityDescriptorSize = RtlLengthSecurityDescriptor(SecurityDescriptor); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /* align allocation size */ | ||||||
|  |     AllocationUnit = FsvolDeviceExtension->VolumeParams.SectorSize * | ||||||
|  |         FsvolDeviceExtension->VolumeParams.SectorsPerAllocationUnit; | ||||||
|  |     AllocationSize = (AllocationSize + AllocationUnit - 1) / AllocationUnit * AllocationUnit; | ||||||
|  |  | ||||||
|     /* according to fastfat, filenames that begin with two backslashes are ok */ |     /* according to fastfat, filenames that begin with two backslashes are ok */ | ||||||
|     if (sizeof(WCHAR) * 2 <= FileName.Length && |     if (sizeof(WCHAR) * 2 <= FileName.Length && | ||||||
|         L'\\' == FileName.Buffer[1] && L'\\' == FileName.Buffer[0]) |         L'\\' == FileName.Buffer[1] && L'\\' == FileName.Buffer[0]) | ||||||
| @@ -323,7 +329,7 @@ static NTSTATUS FspFsvolCreate( | |||||||
|     Request->Req.Create.SecurityDescriptor.Offset = 0 == SecurityDescriptorSize ? 0 : |     Request->Req.Create.SecurityDescriptor.Offset = 0 == SecurityDescriptorSize ? 0 : | ||||||
|         FSP_FSCTL_DEFAULT_ALIGN_UP(Request->FileName.Size); |         FSP_FSCTL_DEFAULT_ALIGN_UP(Request->FileName.Size); | ||||||
|     Request->Req.Create.SecurityDescriptor.Size = (UINT16)SecurityDescriptorSize; |     Request->Req.Create.SecurityDescriptor.Size = (UINT16)SecurityDescriptorSize; | ||||||
|     Request->Req.Create.AllocationSize = AllocationSize.QuadPart; |     Request->Req.Create.AllocationSize = AllocationSize; | ||||||
|     Request->Req.Create.AccessToken = 0; |     Request->Req.Create.AccessToken = 0; | ||||||
|     Request->Req.Create.DesiredAccess = DesiredAccess; |     Request->Req.Create.DesiredAccess = DesiredAccess; | ||||||
|     Request->Req.Create.ShareAccess = ShareAccess; |     Request->Req.Create.ShareAccess = ShareAccess; | ||||||
|   | |||||||
| @@ -401,10 +401,18 @@ VOID FspFileNodeSetFileInfo(FSP_FILE_NODE *FileNode, PFILE_OBJECT CcFileObject, | |||||||
| { | { | ||||||
|     PAGED_CODE(); |     PAGED_CODE(); | ||||||
|  |  | ||||||
|     UINT64 FileInfoTimeout = FspFsvolDeviceExtension(FileNode->FsvolDeviceObject)-> |     FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = | ||||||
|         VolumeParams.FileInfoTimeout * 10000ULL; |         FspFsvolDeviceExtension(FileNode->FsvolDeviceObject); | ||||||
|  |     UINT64 FileInfoTimeout = FsvolDeviceExtension->VolumeParams.FileInfoTimeout * 10000ULL; | ||||||
|  |     UINT64 AllocationSize = FileInfo->AllocationSize > FileInfo->FileSize ? | ||||||
|  |         FileInfo->AllocationSize : FileInfo->FileSize; | ||||||
|  |     UINT64 AllocationUnit; | ||||||
|  |  | ||||||
|     FileNode->Header.AllocationSize.QuadPart = FileInfo->AllocationSize; |     AllocationUnit = FsvolDeviceExtension->VolumeParams.SectorSize * | ||||||
|  |         FsvolDeviceExtension->VolumeParams.SectorsPerAllocationUnit; | ||||||
|  |     AllocationSize = (AllocationSize + AllocationUnit - 1) / AllocationUnit * AllocationUnit; | ||||||
|  |  | ||||||
|  |     FileNode->Header.AllocationSize.QuadPart = AllocationSize; | ||||||
|     FileNode->Header.FileSize.QuadPart = FileInfo->FileSize; |     FileNode->Header.FileSize.QuadPart = FileInfo->FileSize; | ||||||
|  |  | ||||||
|     FileNode->FileAttributes = FileInfo->FileAttributes; |     FileNode->FileAttributes = FileInfo->FileAttributes; | ||||||
|   | |||||||
| @@ -531,9 +531,17 @@ static NTSTATUS FspFsvolSetAllocationInformation(PFILE_OBJECT FileObject, | |||||||
|         return STATUS_SUCCESS; |         return STATUS_SUCCESS; | ||||||
|  |  | ||||||
|     PFILE_ALLOCATION_INFORMATION Info = (PFILE_ALLOCATION_INFORMATION)Buffer; |     PFILE_ALLOCATION_INFORMATION Info = (PFILE_ALLOCATION_INFORMATION)Buffer; | ||||||
|  |  | ||||||
|  |     FSP_FSVOL_DEVICE_EXTENSION *FsvolDeviceExtension = | ||||||
|  |         FspFsvolDeviceExtension(FileObject->DeviceObject); | ||||||
|  |     UINT64 AllocationSize = Info->AllocationSize.QuadPart; | ||||||
|  |     UINT64 AllocationUnit; | ||||||
|     BOOLEAN Success; |     BOOLEAN Success; | ||||||
|  |  | ||||||
|     Request->Req.SetInformation.Info.Allocation.AllocationSize = Info->AllocationSize.QuadPart; |     AllocationUnit = FsvolDeviceExtension->VolumeParams.SectorSize * | ||||||
|  |         FsvolDeviceExtension->VolumeParams.SectorsPerAllocationUnit; | ||||||
|  |     AllocationSize = (AllocationSize + AllocationUnit - 1) / AllocationUnit * AllocationUnit; | ||||||
|  |     Request->Req.SetInformation.Info.Allocation.AllocationSize = AllocationSize; | ||||||
|  |  | ||||||
|     Success = MmCanFileBeTruncated(FileObject->SectionObjectPointer, &Info->AllocationSize); |     Success = MmCanFileBeTruncated(FileObject->SectionObjectPointer, &Info->AllocationSize); | ||||||
|     if (!Success) |     if (!Success) | ||||||
| @@ -599,11 +607,14 @@ static NTSTATUS FspFsvolSetDispositionInformation(PFILE_OBJECT FileObject, | |||||||
|         PFILE_DISPOSITION_INFORMATION Info = (PFILE_DISPOSITION_INFORMATION)Buffer; |         PFILE_DISPOSITION_INFORMATION Info = (PFILE_DISPOSITION_INFORMATION)Buffer; | ||||||
|         BOOLEAN Success; |         BOOLEAN Success; | ||||||
|  |  | ||||||
|         /* make sure no process is mapping the file as an image */ |         if (Info->DeleteFile) | ||||||
|         Success = MmFlushImageSection(FileObject->SectionObjectPointer, |         { | ||||||
|             MmFlushForDelete); |             /* make sure no process is mapping the file as an image */ | ||||||
|         if (!Success) |             Success = MmFlushImageSection(FileObject->SectionObjectPointer, | ||||||
|             return STATUS_CANNOT_DELETE; |                 MmFlushForDelete); | ||||||
|  |             if (!Success) | ||||||
|  |                 return STATUS_CANNOT_DELETE; | ||||||
|  |         } | ||||||
|  |  | ||||||
|         Request->Req.SetInformation.Info.Disposition.Delete = Info->DeleteFile; |         Request->Req.SetInformation.Info.Disposition.Delete = Info->DeleteFile; | ||||||
|  |  | ||||||
| @@ -802,20 +813,21 @@ NTSTATUS FspFsvolSetInformationComplete( | |||||||
|     ULONG Length = IrpSp->Parameters.SetFile.Length; |     ULONG Length = IrpSp->Parameters.SetFile.Length; | ||||||
|     FSP_FSCTL_TRANSACT_REQ *Request = FspIrpRequest(Irp); |     FSP_FSCTL_TRANSACT_REQ *Request = FspIrpRequest(Irp); | ||||||
|  |  | ||||||
|     FspFileNodeSetFileInfo(FileNode, FileObject, &Response->Rsp.SetInformation.FileInfo); |  | ||||||
|  |  | ||||||
|     switch (FileInformationClass) |     switch (FileInformationClass) | ||||||
|     { |     { | ||||||
|     case FileAllocationInformation: |     case FileAllocationInformation: | ||||||
|  |         FspFileNodeSetFileInfo(FileNode, FileObject, &Response->Rsp.SetInformation.FileInfo); | ||||||
|         Result = FspFsvolSetAllocationInformation(FileObject, Buffer, Length, Request, Response); |         Result = FspFsvolSetAllocationInformation(FileObject, Buffer, Length, Request, Response); | ||||||
|         break; |         break; | ||||||
|     case FileBasicInformation: |     case FileBasicInformation: | ||||||
|  |         FspFileNodeSetFileInfo(FileNode, FileObject, &Response->Rsp.SetInformation.FileInfo); | ||||||
|         Result = FspFsvolSetBasicInformation(FileObject, Buffer, Length, Request, Response); |         Result = FspFsvolSetBasicInformation(FileObject, Buffer, Length, Request, Response); | ||||||
|         break; |         break; | ||||||
|     case FileDispositionInformation: |     case FileDispositionInformation: | ||||||
|         Result = FspFsvolSetDispositionInformation(FileObject, Buffer, Length, Request, Response); |         Result = FspFsvolSetDispositionInformation(FileObject, Buffer, Length, Request, Response); | ||||||
|         break; |         break; | ||||||
|     case FileEndOfFileInformation: |     case FileEndOfFileInformation: | ||||||
|  |         FspFileNodeSetFileInfo(FileNode, FileObject, &Response->Rsp.SetInformation.FileInfo); | ||||||
|         Result = FspFsvolSetEndOfFileInformation(FileObject, Buffer, Length, |         Result = FspFsvolSetEndOfFileInformation(FileObject, Buffer, Length, | ||||||
|             IrpSp->Parameters.SetFile.AdvanceOnly, Request, Response); |             IrpSp->Parameters.SetFile.AdvanceOnly, Request, Response); | ||||||
|         break; |         break; | ||||||
|   | |||||||
| @@ -295,7 +295,7 @@ static NTSTATUS Create(FSP_FILE_SYSTEM *FileSystem, | |||||||
|         memcpy(FileNode->FileSecurity, SecurityDescriptor, FileNode->FileSecuritySize); |         memcpy(FileNode->FileSecurity, SecurityDescriptor, FileNode->FileSecuritySize); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     FileNode->FileInfo.AllocationSize = FSP_FSCTL_ALIGN_UP((ULONG)AllocationSize, MEMFS_SECTOR_SIZE); |     FileNode->FileInfo.AllocationSize = AllocationSize; | ||||||
|     if (0 != FileNode->FileInfo.AllocationSize) |     if (0 != FileNode->FileInfo.AllocationSize) | ||||||
|     { |     { | ||||||
|         FileNode->FileData = malloc(FileNode->FileInfo.AllocationSize); |         FileNode->FileData = malloc(FileNode->FileInfo.AllocationSize); | ||||||
| @@ -407,6 +407,96 @@ static NTSTATUS GetFileInfo(FSP_FILE_SYSTEM *FileSystem, | |||||||
|     return STATUS_SUCCESS; |     return STATUS_SUCCESS; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | NTSTATUS SetBasicInfo(FSP_FILE_SYSTEM *FileSystem, | ||||||
|  |     FSP_FSCTL_TRANSACT_REQ *Request, | ||||||
|  |     PVOID FileNode0, UINT32 FileAttributes, | ||||||
|  |     UINT64 CreationTime, UINT64 LastAccessTime, UINT64 LastWriteTime, | ||||||
|  |     FSP_FSCTL_FILE_INFO *FileInfo) | ||||||
|  | { | ||||||
|  |     MEMFS_FILE_NODE *FileNode = (MEMFS_FILE_NODE *)FileNode0; | ||||||
|  |  | ||||||
|  |     if (INVALID_FILE_ATTRIBUTES != FileAttributes) | ||||||
|  |         FileNode->FileInfo.FileAttributes = FileAttributes; | ||||||
|  |     if (0 != CreationTime) | ||||||
|  |         FileNode->FileInfo.CreationTime = CreationTime; | ||||||
|  |     if (0 != LastAccessTime) | ||||||
|  |         FileNode->FileInfo.CreationTime = LastAccessTime; | ||||||
|  |     if (0 != LastWriteTime) | ||||||
|  |         FileNode->FileInfo.CreationTime = LastWriteTime; | ||||||
|  |  | ||||||
|  |     *FileInfo = FileNode->FileInfo; | ||||||
|  |  | ||||||
|  |     return STATUS_SUCCESS; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | NTSTATUS SetAllocationSize(FSP_FILE_SYSTEM *FileSystem, | ||||||
|  |     FSP_FSCTL_TRANSACT_REQ *Request, | ||||||
|  |     PVOID FileNode0, UINT64 AllocationSize, | ||||||
|  |     FSP_FSCTL_FILE_INFO *FileInfo) | ||||||
|  | { | ||||||
|  |     MEMFS_FILE_NODE *FileNode = (MEMFS_FILE_NODE *)FileNode0; | ||||||
|  |     PVOID FileData; | ||||||
|  |  | ||||||
|  |     FileData = realloc(FileNode->FileData, AllocationSize); | ||||||
|  |     if (0 == FileData) | ||||||
|  |         return STATUS_INSUFFICIENT_RESOURCES; | ||||||
|  |  | ||||||
|  |     FileNode->FileData = FileData; | ||||||
|  |  | ||||||
|  |     FileNode->FileInfo.AllocationSize = AllocationSize; | ||||||
|  |     if (FileNode->FileInfo.FileSize > AllocationSize) | ||||||
|  |         FileNode->FileInfo.FileSize = AllocationSize; | ||||||
|  |  | ||||||
|  |     *FileInfo = FileNode->FileInfo; | ||||||
|  |  | ||||||
|  |     return STATUS_SUCCESS; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | NTSTATUS SetFileSize(FSP_FILE_SYSTEM *FileSystem, | ||||||
|  |     FSP_FSCTL_TRANSACT_REQ *Request, | ||||||
|  |     PVOID FileNode0, UINT64 FileSize, BOOLEAN AdvanceOnly, | ||||||
|  |     FSP_FSCTL_FILE_INFO *FileInfo) | ||||||
|  | { | ||||||
|  |     MEMFS_FILE_NODE *FileNode = (MEMFS_FILE_NODE *)FileNode0; | ||||||
|  |  | ||||||
|  |     if (FileNode->FileInfo.AllocationSize < FileSize) | ||||||
|  |     { | ||||||
|  |         UINT64 AllocationUnit = MEMFS_SECTOR_SIZE * MEMFS_SECTORS_PER_ALLOCATION_UNIT; | ||||||
|  |         UINT64 AllocationSize = (FileSize + AllocationUnit - 1) / AllocationUnit * AllocationUnit; | ||||||
|  |  | ||||||
|  |         NTSTATUS Result = SetAllocationSize(FileSystem, Request, FileNode, AllocationSize, FileInfo); | ||||||
|  |         if (!NT_SUCCESS(Result)) | ||||||
|  |             return Result; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     FileNode->FileInfo.FileSize = FileSize; | ||||||
|  |  | ||||||
|  |     *FileInfo = FileNode->FileInfo; | ||||||
|  |  | ||||||
|  |     return STATUS_SUCCESS; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | NTSTATUS CanDelete(FSP_FILE_SYSTEM *FileSystem, | ||||||
|  |     FSP_FSCTL_TRANSACT_REQ *Request, | ||||||
|  |     PVOID FileNode0) | ||||||
|  | { | ||||||
|  |     MEMFS *Memfs = (MEMFS *)FileSystem->UserContext; | ||||||
|  |     MEMFS_FILE_NODE *FileNode = (MEMFS_FILE_NODE *)FileNode0; | ||||||
|  |  | ||||||
|  |     if (MemfsFileNodeMapHasChild(Memfs->FileNodeMap, FileNode)) | ||||||
|  |         return STATUS_DIRECTORY_NOT_EMPTY; | ||||||
|  |  | ||||||
|  |     return STATUS_SUCCESS; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | NTSTATUS Rename(FSP_FILE_SYSTEM *FileSystem, | ||||||
|  |     FSP_FSCTL_TRANSACT_REQ *Request, | ||||||
|  |     PVOID FileNode, | ||||||
|  |     PWSTR ExistingFileName, PWSTR NewFileName, BOOLEAN ReplaceIfExists) | ||||||
|  | { | ||||||
|  |     return STATUS_INVALID_DEVICE_REQUEST; | ||||||
|  | } | ||||||
|  |  | ||||||
| static FSP_FILE_SYSTEM_INTERFACE MemfsInterface = | static FSP_FILE_SYSTEM_INTERFACE MemfsInterface = | ||||||
| { | { | ||||||
|     GetVolumeInfo, |     GetVolumeInfo, | ||||||
| @@ -417,6 +507,11 @@ static FSP_FILE_SYSTEM_INTERFACE MemfsInterface = | |||||||
|     Cleanup, |     Cleanup, | ||||||
|     Close, |     Close, | ||||||
|     GetFileInfo, |     GetFileInfo, | ||||||
|  |     SetBasicInfo, | ||||||
|  |     SetAllocationSize, | ||||||
|  |     SetFileSize, | ||||||
|  |     CanDelete, | ||||||
|  |     Rename, | ||||||
| }; | }; | ||||||
|  |  | ||||||
| static VOID MemfsEnterOperation(FSP_FILE_SYSTEM *FileSystem, FSP_FSCTL_TRANSACT_REQ *Request) | static VOID MemfsEnterOperation(FSP_FILE_SYSTEM *FileSystem, FSP_FSCTL_TRANSACT_REQ *Request) | ||||||
| @@ -439,6 +534,7 @@ NTSTATUS MemfsCreate(ULONG Flags, ULONG FileInfoTimeout, | |||||||
|     FSP_FSCTL_VOLUME_PARAMS VolumeParams; |     FSP_FSCTL_VOLUME_PARAMS VolumeParams; | ||||||
|     PWSTR DevicePath = (Flags & MemfsNet) ? |     PWSTR DevicePath = (Flags & MemfsNet) ? | ||||||
|         L"" FSP_FSCTL_NET_DEVICE_NAME : L"" FSP_FSCTL_DISK_DEVICE_NAME; |         L"" FSP_FSCTL_NET_DEVICE_NAME : L"" FSP_FSCTL_DISK_DEVICE_NAME; | ||||||
|  |     UINT64 AllocationUnit; | ||||||
|     MEMFS *Memfs; |     MEMFS *Memfs; | ||||||
|     MEMFS_FILE_NODE *RootNode; |     MEMFS_FILE_NODE *RootNode; | ||||||
|     BOOLEAN Inserted; |     BOOLEAN Inserted; | ||||||
| @@ -451,7 +547,8 @@ NTSTATUS MemfsCreate(ULONG Flags, ULONG FileInfoTimeout, | |||||||
|  |  | ||||||
|     memset(Memfs, 0, sizeof *Memfs); |     memset(Memfs, 0, sizeof *Memfs); | ||||||
|     Memfs->MaxFileNodes = MaxFileNodes; |     Memfs->MaxFileNodes = MaxFileNodes; | ||||||
|     Memfs->MaxFileSize = FSP_FSCTL_ALIGN_UP(MaxFileSize, MEMFS_SECTOR_SIZE); |     AllocationUnit = MEMFS_SECTOR_SIZE * MEMFS_SECTORS_PER_ALLOCATION_UNIT; | ||||||
|  |     Memfs->MaxFileSize = (ULONG)((MaxFileSize + AllocationUnit - 1) / AllocationUnit * AllocationUnit); | ||||||
|  |  | ||||||
|     Result = MemfsFileNodeMapCreate(&Memfs->FileNodeMap); |     Result = MemfsFileNodeMapCreate(&Memfs->FileNodeMap); | ||||||
|     if (!NT_SUCCESS(Result)) |     if (!NT_SUCCESS(Result)) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user