mirror of
https://github.com/winfsp/winfsp.git
synced 2025-04-23 08:53:01 -05:00
sys: IRP_MJ_SET_VOLUME_INFORMATION/FileFsLabelInformation
This commit is contained in:
parent
003e9a6d91
commit
49cf687de3
@ -219,6 +219,17 @@ typedef struct
|
|||||||
} Rename;
|
} Rename;
|
||||||
} Info;
|
} Info;
|
||||||
} SetInformation;
|
} SetInformation;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
UINT32 FsInformationClass;
|
||||||
|
union
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
FSP_FSCTL_TRANSACT_BUF VolumeLabel;
|
||||||
|
} Label;
|
||||||
|
} Info;
|
||||||
|
} SetVolumeInformation;
|
||||||
} Req;
|
} Req;
|
||||||
FSP_FSCTL_TRANSACT_BUF FileName; /* {Create,Cleanup,SetInformation/{Disposition,Rename}} */
|
FSP_FSCTL_TRANSACT_BUF FileName; /* {Create,Cleanup,SetInformation/{Disposition,Rename}} */
|
||||||
FSP_FSCTL_DECLSPEC_ALIGN UINT8 Buffer[];
|
FSP_FSCTL_DECLSPEC_ALIGN UINT8 Buffer[];
|
||||||
@ -268,6 +279,10 @@ typedef struct
|
|||||||
{
|
{
|
||||||
FSP_FSCTL_VOLUME_INFO VolumeInfo;
|
FSP_FSCTL_VOLUME_INFO VolumeInfo;
|
||||||
} QueryVolumeInformation;
|
} QueryVolumeInformation;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
FSP_FSCTL_VOLUME_INFO VolumeInfo;
|
||||||
|
} SetVolumeInformation;
|
||||||
} Rsp;
|
} Rsp;
|
||||||
FSP_FSCTL_DECLSPEC_ALIGN UINT8 Buffer[];
|
FSP_FSCTL_DECLSPEC_ALIGN UINT8 Buffer[];
|
||||||
} FSP_FSCTL_TRANSACT_RSP;
|
} FSP_FSCTL_TRANSACT_RSP;
|
||||||
|
@ -38,6 +38,10 @@ typedef struct _FSP_FILE_SYSTEM_INTERFACE
|
|||||||
NTSTATUS (*GetVolumeInfo)(FSP_FILE_SYSTEM *FileSystem,
|
NTSTATUS (*GetVolumeInfo)(FSP_FILE_SYSTEM *FileSystem,
|
||||||
FSP_FSCTL_TRANSACT_REQ *Request,
|
FSP_FSCTL_TRANSACT_REQ *Request,
|
||||||
FSP_FSCTL_VOLUME_INFO *VolumeInfo);
|
FSP_FSCTL_VOLUME_INFO *VolumeInfo);
|
||||||
|
NTSTATUS (*SetVolumeLabel)(FSP_FILE_SYSTEM *FileSystem,
|
||||||
|
FSP_FSCTL_TRANSACT_REQ *Request,
|
||||||
|
PWSTR VolumeLabel,
|
||||||
|
FSP_FSCTL_VOLUME_INFO *VolumeInfo);
|
||||||
NTSTATUS (*GetSecurity)(FSP_FILE_SYSTEM *FileSystem,
|
NTSTATUS (*GetSecurity)(FSP_FILE_SYSTEM *FileSystem,
|
||||||
PWSTR FileName, PUINT32 PFileAttributes,
|
PWSTR FileName, PUINT32 PFileAttributes,
|
||||||
PSECURITY_DESCRIPTOR SecurityDescriptor, SIZE_T *PSecurityDescriptorSize);
|
PSECURITY_DESCRIPTOR SecurityDescriptor, SIZE_T *PSecurityDescriptorSize);
|
||||||
@ -180,6 +184,8 @@ FSP_API NTSTATUS FspFileSystemOpSetInformation(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response);
|
FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response);
|
||||||
FSP_API NTSTATUS FspFileSystemOpQueryVolumeInformation(FSP_FILE_SYSTEM *FileSystem,
|
FSP_API NTSTATUS FspFileSystemOpQueryVolumeInformation(FSP_FILE_SYSTEM *FileSystem,
|
||||||
FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response);
|
FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response);
|
||||||
|
FSP_API NTSTATUS FspFileSystemOpSetVolumeInformation(FSP_FILE_SYSTEM *FileSystem,
|
||||||
|
FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response);
|
||||||
static inline
|
static inline
|
||||||
NTSTATUS FspAccessCheck(FSP_FILE_SYSTEM *FileSystem,
|
NTSTATUS FspAccessCheck(FSP_FILE_SYSTEM *FileSystem,
|
||||||
FSP_FSCTL_TRANSACT_REQ *Request,
|
FSP_FSCTL_TRANSACT_REQ *Request,
|
||||||
|
@ -47,6 +47,7 @@ FSP_API NTSTATUS FspFileSystemCreate(PWSTR DevicePath,
|
|||||||
FileSystem->Operations[FspFsctlTransactQueryInformationKind] = FspFileSystemOpQueryInformation;
|
FileSystem->Operations[FspFsctlTransactQueryInformationKind] = FspFileSystemOpQueryInformation;
|
||||||
FileSystem->Operations[FspFsctlTransactSetInformationKind] = FspFileSystemOpSetInformation;
|
FileSystem->Operations[FspFsctlTransactSetInformationKind] = FspFileSystemOpSetInformation;
|
||||||
FileSystem->Operations[FspFsctlTransactQueryVolumeInformationKind] = FspFileSystemOpQueryVolumeInformation;
|
FileSystem->Operations[FspFsctlTransactQueryVolumeInformationKind] = FspFileSystemOpQueryVolumeInformation;
|
||||||
|
FileSystem->Operations[FspFsctlTransactSetVolumeInformationKind] = FspFileSystemOpSetVolumeInformation;
|
||||||
// !!!: ...
|
// !!!: ...
|
||||||
FileSystem->Interface = Interface;
|
FileSystem->Interface = Interface;
|
||||||
|
|
||||||
|
@ -23,3 +23,27 @@ FSP_API NTSTATUS FspFileSystemOpQueryVolumeInformation(FSP_FILE_SYSTEM *FileSyst
|
|||||||
memcpy(&Response->Rsp.QueryVolumeInformation.VolumeInfo, &VolumeInfo, sizeof VolumeInfo);
|
memcpy(&Response->Rsp.QueryVolumeInformation.VolumeInfo, &VolumeInfo, sizeof VolumeInfo);
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FSP_API NTSTATUS FspFileSystemOpSetVolumeInformation(FSP_FILE_SYSTEM *FileSystem,
|
||||||
|
FSP_FSCTL_TRANSACT_REQ *Request, FSP_FSCTL_TRANSACT_RSP *Response)
|
||||||
|
{
|
||||||
|
NTSTATUS Result;
|
||||||
|
FSP_FSCTL_VOLUME_INFO VolumeInfo;
|
||||||
|
|
||||||
|
Result = STATUS_INVALID_DEVICE_REQUEST;
|
||||||
|
memset(&VolumeInfo, 0, sizeof VolumeInfo);
|
||||||
|
switch (Request->Req.SetVolumeInformation.FsInformationClass)
|
||||||
|
{
|
||||||
|
case 2/*FileFsLabelInformation*/:
|
||||||
|
if (0 != FileSystem->Interface->SetVolumeLabel)
|
||||||
|
Result = FileSystem->Interface->SetVolumeLabel(FileSystem, Request,
|
||||||
|
(PWSTR)Request->Buffer,
|
||||||
|
&VolumeInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
return Result;
|
||||||
|
|
||||||
|
memcpy(&Response->Rsp.SetVolumeInformation.VolumeInfo, &VolumeInfo, sizeof VolumeInfo);
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
@ -22,6 +22,9 @@ static NTSTATUS FspFsvolQueryFsVolumeInformation(
|
|||||||
static NTSTATUS FspFsvolQueryVolumeInformation(
|
static NTSTATUS FspFsvolQueryVolumeInformation(
|
||||||
PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
||||||
FSP_IOCMPL_DISPATCH FspFsvolQueryVolumeInformationComplete;
|
FSP_IOCMPL_DISPATCH FspFsvolQueryVolumeInformationComplete;
|
||||||
|
static NTSTATUS FspFsvolSetFsLabelInformation(
|
||||||
|
PDEVICE_OBJECT FsvolDeviceObject, PVOID Buffer, ULONG Length, PULONG PRequestExtraSize,
|
||||||
|
FSP_FSCTL_TRANSACT_REQ *Request, const FSP_FSCTL_TRANSACT_RSP *Response);
|
||||||
static NTSTATUS FspFsvolSetVolumeInformation(
|
static NTSTATUS FspFsvolSetVolumeInformation(
|
||||||
PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp);
|
||||||
FSP_IOCMPL_DISPATCH FspFsvolSetVolumeInformationComplete;
|
FSP_IOCMPL_DISPATCH FspFsvolSetVolumeInformationComplete;
|
||||||
@ -36,6 +39,7 @@ FSP_DRIVER_DISPATCH FspSetVolumeInformation;
|
|||||||
#pragma alloc_text(PAGE, FspFsvolQueryFsVolumeInformation)
|
#pragma alloc_text(PAGE, FspFsvolQueryFsVolumeInformation)
|
||||||
#pragma alloc_text(PAGE, FspFsvolQueryVolumeInformation)
|
#pragma alloc_text(PAGE, FspFsvolQueryVolumeInformation)
|
||||||
#pragma alloc_text(PAGE, FspFsvolQueryVolumeInformationComplete)
|
#pragma alloc_text(PAGE, FspFsvolQueryVolumeInformationComplete)
|
||||||
|
#pragma alloc_text(PAGE, FspFsvolSetFsLabelInformation)
|
||||||
#pragma alloc_text(PAGE, FspFsvolSetVolumeInformation)
|
#pragma alloc_text(PAGE, FspFsvolSetVolumeInformation)
|
||||||
#pragma alloc_text(PAGE, FspFsvolSetVolumeInformationComplete)
|
#pragma alloc_text(PAGE, FspFsvolSetVolumeInformationComplete)
|
||||||
#pragma alloc_text(PAGE, FspQueryVolumeInformation)
|
#pragma alloc_text(PAGE, FspQueryVolumeInformation)
|
||||||
@ -293,12 +297,83 @@ NTSTATUS FspFsvolQueryVolumeInformationComplete(
|
|||||||
FsInformationClassSym(IrpSp->Parameters.QueryVolume.FsInformationClass));
|
FsInformationClassSym(IrpSp->Parameters.QueryVolume.FsInformationClass));
|
||||||
}
|
}
|
||||||
|
|
||||||
static NTSTATUS FspFsvolSetVolumeInformation(
|
static NTSTATUS FspFsvolSetFsLabelInformation(
|
||||||
PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
|
PDEVICE_OBJECT FsvolDeviceObject, PVOID Buffer, ULONG Length, PULONG PRequestExtraSize,
|
||||||
|
FSP_FSCTL_TRANSACT_REQ *Request, const FSP_FSCTL_TRANSACT_RSP *Response)
|
||||||
{
|
{
|
||||||
PAGED_CODE();
|
PAGED_CODE();
|
||||||
|
|
||||||
return STATUS_INVALID_DEVICE_REQUEST;
|
if (0 == Request)
|
||||||
|
{
|
||||||
|
if (sizeof(FILE_FS_LABEL_INFORMATION) > Length)
|
||||||
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
|
||||||
|
PFILE_FS_LABEL_INFORMATION Info = (PFILE_FS_LABEL_INFORMATION)Buffer;
|
||||||
|
|
||||||
|
*PRequestExtraSize = Info->VolumeLabelLength + sizeof(WCHAR);
|
||||||
|
}
|
||||||
|
else if (0 == Response)
|
||||||
|
{
|
||||||
|
PFILE_FS_LABEL_INFORMATION Info = (PFILE_FS_LABEL_INFORMATION)Buffer;
|
||||||
|
|
||||||
|
Request->Req.SetVolumeInformation.Info.Label.VolumeLabel.Offset = 0;
|
||||||
|
Request->Req.SetVolumeInformation.Info.Label.VolumeLabel.Size =
|
||||||
|
(UINT16)(Info->VolumeLabelLength + sizeof(WCHAR));
|
||||||
|
RtlCopyMemory(Request->Buffer, Info->VolumeLabel, Info->VolumeLabelLength);
|
||||||
|
((PWSTR)Request->Buffer)[Info->VolumeLabelLength / sizeof(WCHAR)] = L'\0';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
FspFsvolSetVolumeInfo(FsvolDeviceObject, &Response->Rsp.SetVolumeInformation.VolumeInfo);
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static NTSTATUS FspFsvolSetVolumeInformation(
|
||||||
|
PDEVICE_OBJECT FsvolDeviceObject, PIRP Irp, PIO_STACK_LOCATION IrpSp)
|
||||||
|
{
|
||||||
|
NTSTATUS Result;
|
||||||
|
FS_INFORMATION_CLASS FsInformationClass = IrpSp->Parameters.SetVolume.FsInformationClass;
|
||||||
|
PVOID Buffer = Irp->AssociatedIrp.SystemBuffer;
|
||||||
|
ULONG Length = IrpSp->Parameters.SetVolume.Length;
|
||||||
|
ULONG RequestExtraSize = 0;
|
||||||
|
|
||||||
|
switch (FsInformationClass)
|
||||||
|
{
|
||||||
|
case FileFsLabelInformation:
|
||||||
|
Result = FspFsvolSetFsLabelInformation(FsvolDeviceObject, Buffer, Length, &RequestExtraSize, 0, 0);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
Result = STATUS_INVALID_PARAMETER;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
return Result;
|
||||||
|
|
||||||
|
FSP_FSCTL_TRANSACT_REQ *Request;
|
||||||
|
|
||||||
|
Result = FspIopCreateRequest(Irp, 0, RequestExtraSize, &Request);
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
return Result;
|
||||||
|
|
||||||
|
Request->Kind = FspFsctlTransactSetVolumeInformationKind;
|
||||||
|
Request->Req.SetVolumeInformation.FsInformationClass = FsInformationClass;
|
||||||
|
|
||||||
|
switch (FsInformationClass)
|
||||||
|
{
|
||||||
|
case FileFsLabelInformation:
|
||||||
|
Result = FspFsvolSetFsLabelInformation(FsvolDeviceObject, Buffer, Length, 0, Request, 0);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ASSERT(0);
|
||||||
|
Result = STATUS_INVALID_PARAMETER;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(Result))
|
||||||
|
return Result;
|
||||||
|
|
||||||
|
return FSP_STATUS_IOQ_POST;
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS FspFsvolSetVolumeInformationComplete(
|
NTSTATUS FspFsvolSetVolumeInformationComplete(
|
||||||
@ -306,6 +381,32 @@ NTSTATUS FspFsvolSetVolumeInformationComplete(
|
|||||||
{
|
{
|
||||||
FSP_ENTER_IOC(PAGED_CODE());
|
FSP_ENTER_IOC(PAGED_CODE());
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(Response->IoStatus.Status))
|
||||||
|
{
|
||||||
|
Irp->IoStatus.Information = 0;
|
||||||
|
Result = Response->IoStatus.Status;
|
||||||
|
FSP_RETURN();
|
||||||
|
}
|
||||||
|
|
||||||
|
FS_INFORMATION_CLASS FsInformationClass = IrpSp->Parameters.SetVolume.FsInformationClass;
|
||||||
|
PDEVICE_OBJECT FsvolDeviceObject = IrpSp->DeviceObject;
|
||||||
|
PVOID Buffer = Irp->AssociatedIrp.SystemBuffer;
|
||||||
|
ULONG Length = IrpSp->Parameters.SetFile.Length;
|
||||||
|
FSP_FSCTL_TRANSACT_REQ *Request = FspIrpRequest(Irp);
|
||||||
|
|
||||||
|
switch (FsInformationClass)
|
||||||
|
{
|
||||||
|
case FileFsLabelInformation:
|
||||||
|
Result = FspFsvolSetFsLabelInformation(FsvolDeviceObject, Buffer, Length, 0, Request, Response);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ASSERT(0);
|
||||||
|
Result = STATUS_INVALID_PARAMETER;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
Irp->IoStatus.Information = 0;
|
||||||
|
|
||||||
FSP_LEAVE_IOC("%s",
|
FSP_LEAVE_IOC("%s",
|
||||||
FsInformationClassSym(IrpSp->Parameters.SetVolume.FsInformationClass));
|
FsInformationClassSym(IrpSp->Parameters.SetVolume.FsInformationClass));
|
||||||
}
|
}
|
||||||
|
@ -459,6 +459,98 @@ void getvolinfo_test(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void setvolinfo_dotest(ULONG Flags, PWSTR Prefix, ULONG FileInfoTimeout)
|
||||||
|
{
|
||||||
|
if (-1 == Flags)
|
||||||
|
return;/* avoid accidentally changing the volume label on our NTFS disk */
|
||||||
|
if (0 != Prefix)
|
||||||
|
return;/* cannot do SetVolumeLabel on a network share! */
|
||||||
|
|
||||||
|
void *memfs = memfs_start_ex(Flags, FileInfoTimeout);
|
||||||
|
|
||||||
|
BOOL Success;
|
||||||
|
WCHAR FilePath[MAX_PATH];
|
||||||
|
WCHAR VolumeLabelBuf[MAX_PATH];
|
||||||
|
DWORD VolumeSerialNumber;
|
||||||
|
DWORD MaxComponentLength;
|
||||||
|
DWORD FileSystemFlags;
|
||||||
|
WCHAR FileSystemNameBuf[MAX_PATH];
|
||||||
|
|
||||||
|
StringCbPrintfW(FilePath, sizeof FilePath, L"%s%s\\",
|
||||||
|
Prefix ? L"" : L"\\\\?\\GLOBALROOT", Prefix ? Prefix : memfs_volumename(memfs));
|
||||||
|
|
||||||
|
Success = SetVolumeLabelW(FilePath, L"12345678901234567890123456789012");
|
||||||
|
ASSERT(Success);
|
||||||
|
|
||||||
|
Success = GetVolumeInformationW(FilePath,
|
||||||
|
VolumeLabelBuf, sizeof VolumeLabelBuf,
|
||||||
|
&VolumeSerialNumber, &MaxComponentLength, &FileSystemFlags,
|
||||||
|
FileSystemNameBuf, sizeof FileSystemNameBuf);
|
||||||
|
ASSERT(Success);
|
||||||
|
if (-1 != Flags)
|
||||||
|
{
|
||||||
|
ASSERT(0 == wcscmp(VolumeLabelBuf, L"12345678901234567890123456789012"));
|
||||||
|
ASSERT(255 == MaxComponentLength);
|
||||||
|
ASSERT(0 != (FileSystemFlags &
|
||||||
|
(FILE_CASE_SENSITIVE_SEARCH | FILE_CASE_PRESERVED_NAMES | FILE_UNICODE_ON_DISK | FILE_PERSISTENT_ACLS)));
|
||||||
|
ASSERT(0 == wcscmp(FileSystemNameBuf, L"WinFsp"));
|
||||||
|
}
|
||||||
|
|
||||||
|
Success = SetVolumeLabelW(FilePath, L"TestLabel");
|
||||||
|
ASSERT(Success);
|
||||||
|
|
||||||
|
Success = GetVolumeInformationW(FilePath,
|
||||||
|
VolumeLabelBuf, sizeof VolumeLabelBuf,
|
||||||
|
&VolumeSerialNumber, &MaxComponentLength, &FileSystemFlags,
|
||||||
|
FileSystemNameBuf, sizeof FileSystemNameBuf);
|
||||||
|
ASSERT(Success);
|
||||||
|
if (-1 != Flags)
|
||||||
|
{
|
||||||
|
ASSERT(0 == wcscmp(VolumeLabelBuf, L"TestLabel"));
|
||||||
|
ASSERT(255 == MaxComponentLength);
|
||||||
|
ASSERT(0 != (FileSystemFlags &
|
||||||
|
(FILE_CASE_SENSITIVE_SEARCH | FILE_CASE_PRESERVED_NAMES | FILE_UNICODE_ON_DISK | FILE_PERSISTENT_ACLS)));
|
||||||
|
ASSERT(0 == wcscmp(FileSystemNameBuf, L"WinFsp"));
|
||||||
|
}
|
||||||
|
|
||||||
|
Success = SetVolumeLabelW(FilePath, L"123456789012345678901234567890123");
|
||||||
|
ASSERT(Success);
|
||||||
|
|
||||||
|
Success = GetVolumeInformationW(FilePath,
|
||||||
|
VolumeLabelBuf, sizeof VolumeLabelBuf,
|
||||||
|
&VolumeSerialNumber, &MaxComponentLength, &FileSystemFlags,
|
||||||
|
FileSystemNameBuf, sizeof FileSystemNameBuf);
|
||||||
|
ASSERT(Success);
|
||||||
|
if (-1 != Flags)
|
||||||
|
{
|
||||||
|
ASSERT(0 == wcscmp(VolumeLabelBuf, L"12345678901234567890123456789012"));
|
||||||
|
ASSERT(255 == MaxComponentLength);
|
||||||
|
ASSERT(0 != (FileSystemFlags &
|
||||||
|
(FILE_CASE_SENSITIVE_SEARCH | FILE_CASE_PRESERVED_NAMES | FILE_UNICODE_ON_DISK | FILE_PERSISTENT_ACLS)));
|
||||||
|
ASSERT(0 == wcscmp(FileSystemNameBuf, L"WinFsp"));
|
||||||
|
}
|
||||||
|
|
||||||
|
memfs_stop(memfs);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setvolinfo_test(void)
|
||||||
|
{
|
||||||
|
#if 0
|
||||||
|
if (NtfsTests)
|
||||||
|
setvolinfo_dotest(-1, L"C:", 0);
|
||||||
|
#endif
|
||||||
|
if (WinFspDiskTests)
|
||||||
|
{
|
||||||
|
setvolinfo_dotest(MemfsDisk, 0, 0);
|
||||||
|
setvolinfo_dotest(MemfsDisk, 0, 1000);
|
||||||
|
}
|
||||||
|
if (WinFspNetTests)
|
||||||
|
{
|
||||||
|
setvolinfo_dotest(MemfsNet, L"\\\\memfs\\share", 0);
|
||||||
|
setvolinfo_dotest(MemfsNet, L"\\\\memfs\\share", 1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void info_tests(void)
|
void info_tests(void)
|
||||||
{
|
{
|
||||||
TEST(getfileinfo_test);
|
TEST(getfileinfo_test);
|
||||||
@ -466,4 +558,5 @@ void info_tests(void)
|
|||||||
TEST(delete_test);
|
TEST(delete_test);
|
||||||
TEST(rename_test);
|
TEST(rename_test);
|
||||||
TEST(getvolinfo_test);
|
TEST(getvolinfo_test);
|
||||||
|
TEST(setvolinfo_test);
|
||||||
}
|
}
|
||||||
|
@ -51,6 +51,8 @@ typedef struct _MEMFS
|
|||||||
MEMFS_FILE_NODE_MAP *FileNodeMap;
|
MEMFS_FILE_NODE_MAP *FileNodeMap;
|
||||||
ULONG MaxFileNodes;
|
ULONG MaxFileNodes;
|
||||||
ULONG MaxFileSize;
|
ULONG MaxFileSize;
|
||||||
|
UINT16 VolumeLabelLength;
|
||||||
|
WCHAR VolumeLabel[32];
|
||||||
CRITICAL_SECTION Lock;
|
CRITICAL_SECTION Lock;
|
||||||
} MEMFS;
|
} MEMFS;
|
||||||
|
|
||||||
@ -196,17 +198,33 @@ static NTSTATUS GetVolumeInfo(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
FSP_FSCTL_VOLUME_INFO *VolumeInfo)
|
FSP_FSCTL_VOLUME_INFO *VolumeInfo)
|
||||||
{
|
{
|
||||||
MEMFS *Memfs = (MEMFS *)FileSystem->UserContext;
|
MEMFS *Memfs = (MEMFS *)FileSystem->UserContext;
|
||||||
MEMFS_FILE_NODE *RootNode;
|
|
||||||
|
|
||||||
RootNode = MemfsFileNodeMapGet(Memfs->FileNodeMap, L"\\");
|
|
||||||
if (0 == RootNode)
|
|
||||||
return STATUS_DISK_CORRUPT_ERROR;
|
|
||||||
|
|
||||||
VolumeInfo->TotalSize = Memfs->MaxFileNodes * Memfs->MaxFileSize;
|
VolumeInfo->TotalSize = Memfs->MaxFileNodes * Memfs->MaxFileSize;
|
||||||
VolumeInfo->FreeSize =
|
VolumeInfo->FreeSize =
|
||||||
(Memfs->MaxFileNodes - MemfsFileNodeMapCount(Memfs->FileNodeMap)) * Memfs->MaxFileSize;
|
(Memfs->MaxFileNodes - MemfsFileNodeMapCount(Memfs->FileNodeMap)) * Memfs->MaxFileSize;
|
||||||
VolumeInfo->VolumeLabelLength = sizeof L"MEMFS" - sizeof(WCHAR);
|
VolumeInfo->VolumeLabelLength = Memfs->VolumeLabelLength;
|
||||||
memcpy(VolumeInfo->VolumeLabel, L"MEMFS", VolumeInfo->VolumeLabelLength);
|
memcpy(VolumeInfo->VolumeLabel, Memfs->VolumeLabel, Memfs->VolumeLabelLength);
|
||||||
|
|
||||||
|
return STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static NTSTATUS SetVolumeLabel(FSP_FILE_SYSTEM *FileSystem,
|
||||||
|
FSP_FSCTL_TRANSACT_REQ *Request,
|
||||||
|
PWSTR VolumeLabel,
|
||||||
|
FSP_FSCTL_VOLUME_INFO *VolumeInfo)
|
||||||
|
{
|
||||||
|
MEMFS *Memfs = (MEMFS *)FileSystem->UserContext;
|
||||||
|
|
||||||
|
Memfs->VolumeLabelLength = (UINT16)(wcslen(VolumeLabel) * sizeof(WCHAR));
|
||||||
|
if (Memfs->VolumeLabelLength > sizeof Memfs->VolumeLabel)
|
||||||
|
Memfs->VolumeLabelLength = sizeof Memfs->VolumeLabel;
|
||||||
|
memcpy(Memfs->VolumeLabel, VolumeLabel, Memfs->VolumeLabelLength);
|
||||||
|
|
||||||
|
VolumeInfo->TotalSize = Memfs->MaxFileNodes * Memfs->MaxFileSize;
|
||||||
|
VolumeInfo->FreeSize =
|
||||||
|
(Memfs->MaxFileNodes - MemfsFileNodeMapCount(Memfs->FileNodeMap)) * Memfs->MaxFileSize;
|
||||||
|
VolumeInfo->VolumeLabelLength = Memfs->VolumeLabelLength;
|
||||||
|
memcpy(VolumeInfo->VolumeLabel, Memfs->VolumeLabel, Memfs->VolumeLabelLength);
|
||||||
|
|
||||||
return STATUS_SUCCESS;
|
return STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
@ -538,6 +556,7 @@ NTSTATUS Rename(FSP_FILE_SYSTEM *FileSystem,
|
|||||||
static FSP_FILE_SYSTEM_INTERFACE MemfsInterface =
|
static FSP_FILE_SYSTEM_INTERFACE MemfsInterface =
|
||||||
{
|
{
|
||||||
GetVolumeInfo,
|
GetVolumeInfo,
|
||||||
|
SetVolumeLabel,
|
||||||
GetSecurity,
|
GetSecurity,
|
||||||
Create,
|
Create,
|
||||||
Open,
|
Open,
|
||||||
@ -616,7 +635,10 @@ NTSTATUS MemfsCreate(ULONG Flags, ULONG FileInfoTimeout,
|
|||||||
free(Memfs);
|
free(Memfs);
|
||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
Memfs->FileSystem->UserContext = Memfs;
|
Memfs->FileSystem->UserContext = Memfs;
|
||||||
|
Memfs->VolumeLabelLength = sizeof L"MEMFS" - sizeof(WCHAR);
|
||||||
|
memcpy(Memfs->VolumeLabel, L"MEMFS", Memfs->VolumeLabelLength);
|
||||||
|
|
||||||
InitializeCriticalSection(&Memfs->Lock);
|
InitializeCriticalSection(&Memfs->Lock);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user