Hello,
I want to make the Ramdisk sample a first class Windows citizen and make it
mountable and supporting arbitrary FS on it. No, this is not done for
performance reasons, I know the Cache Manager does a much better job then a
Ramdisk.
Right now the Ramdisk formats itself and creates a drive letter via a
symbolic link. The Ramdisk can’t be seen by the diskmgmt.msc tools and can’t
be formatted or remounted.
I have added support for multiple Ramdisk devices loaded simultaneously.
I have implemented support for IOCTL_MOUNTDEV_QUERY_UNIQUE_ID and
IOCTL_MOUNTDEV_QUERY_DEVICE_NAME ioctls. From what I understand, this are
the only mandatory ioctls required by the mount manager.
case IOCTL_MOUNTDEV_QUERY_DEVICE_NAME:
{
PMOUNTDEV_NAME OutputBuffer;
//
// Return the NT Device Name to the Mount Manager
//
Status = WdfRequestRetrieveOutputBuffer(
Request,
sizeof(MOUNTDEV_NAME),
&OutputBuffer,
&bufSize
);
if (NT_SUCCESS(Status))
{
WCHAR DeviceName = NT_DEVICE_NAME;
USHORT CbDeviceNameLen = sizeof(DeviceName);
ULONG_PTR MinimumBufferLength =
OutputBuffer->NameLength + sizeof(USHORT);
//
// If the buffer retrieved is big enough, just copy the
// Device Name to it.
//
if (bufSize >= MinimumBufferLength)
{
OutputBuffer->NameLength = CbDeviceNameLen;
RtlCopyMemory(OutputBuffer->Name, DeviceName,
CbDeviceNameLen);
information = MinimumBufferLength;
Status = STATUS_SUCCESS;
break;
}
//
// If the buffer is not big enough we must return to the
mount
// manager the actual size we need.
//
else
{
OutputBuffer->NameLength = CbDeviceNameLen;
information = sizeof(MOUNTDEV_NAME);
Status = STATUS_BUFFER_OVERFLOW;
break;
}
}
break;
}
case IOCTL_MOUNTDEV_QUERY_UNIQUE_ID:
{
PMOUNTDEV_UNIQUE_ID OutputBuffer;
//
// Return a unique ID to the Mount Manager.
//
Status = WdfRequestRetrieveOutputBuffer(
Request,
sizeof(MOUNTDEV_UNIQUE_ID),
&OutputBuffer,
&bufSize
);
if (NT_SUCCESS(Status))
{
UCHAR UniqueIdName = “test only”; // hardcoded name sa far
UCHAR CbUniqueIdNameLen = sizeof(UniqueIdName);
RtlCopyMemory(
OutputBuffer->UniqueId,
UniqueIdName,
CbUniqueIdNameLen
);
OutputBuffer->UniqueIdLength = CbUniqueIdNameLen;
information = CbUniqueIdNameLen + sizeof(USHORT);
break;
}
break;
}
I have created the MOUNTDEV_MOUNTED_DEVICE_GUID device interface to register
with the mount manager like this:
NTSTATUS
RamDiskRegisterDeviceWithMountManager(
WDFDEVICE device
)
{
NTSTATUS Status;
PDEVICE_OBJECT Pdo;
UNICODE_STRING SymbolicLinkName;
KdPrint((
MGKRAMDISK
"trying to register with the mount manager… "
));
Pdo = WdfDeviceWdmGetPhysicalDevice(device);
Status = IoRegisterDeviceInterface(
Pdo,
&MOUNTDEV_MOUNTED_DEVICE_GUID,
NULL,
&SymbolicLinkName
);
KdPrint((
MGKRAMDISK
“symbolic link name is %S\n”,
SymbolicLinkName.Buffer
));
RtlFreeUnicodeString(&SymbolicLinkName);
return Status;
}
The function returns success, however, my device does not appear in
diskmgmt.msc. Is there anything else I should do? Any more ioctls I need to
support?
Thanks,
–
Aram Hăvărneanu