sys: IRP_MJ_SET_INFORMATION

This commit is contained in:
Bill Zissimopoulos 2016-02-05 18:30:34 -08:00
parent dc77a1109f
commit 66f54294a2
6 changed files with 253 additions and 16 deletions

View File

@ -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);

View File

@ -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);
}

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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))