Я пытаюсь заменить какой-то устаревший код DefineDosDevice
пользовательского пространства (который не работает в Vista с пользователями Администратора из-за того, что повышенный и обычный сеанс представлен различными хранилищами DosDevice, поэтому создается довольно странный сценарий что диск виден, если он создан из неуровневых процессов, но невидим, если он создан из процесса с повышенными правами).
Замена этого, как я выяснил из проверки источника Truecrypt и этого примера WDM , заключается в выдаче IOCTL_MOUNTMGR_VOLUME_ARRIVAL_NOTIFICATION
сообщений на mountmgr.sys, а затем IOCTL_MOUNTMGR_CREATE_POINT
/ IOCTL_MOUNTMGR_DELETE_POINT
.
Так вот, что я делаю - мой код выглядит так:
Во-первых, различные местные жители:
NTSTATUS ntStatus;
PDEVICE_EXTENSION device_extension;
UNICODE_STRING uVolumeName;
ULONG mntNameLen = 0;
ULONG mntPointLen = 0;
PMOUNTMGR_TARGET_NAME mntName = NULL;
PMOUNTMGR_CREATE_POINT_INPUT mntPoint = NULL;
Затем я строю и делаю два моих запроса. Первый сбой с указанным кодом состояния. Второй сбой с другим кодом состояния (но он не будет работать, если первый сбой).
mntNameLen = sizeof(MOUNTMGR_TARGET_NAME) + device_extension->sDevName.Length;
mntName = ExAllocatePool(PagedPool, mntNameLen);
mntName->DeviceNameLength = device_extension->sDevName.Length;
RtlCopyMemory(mntName->DeviceName, device_extension->sDevName.Buffer,
mntName->DeviceNameLength);
ntStatus = MakeDeviceIoRequest (MOUNTMGR_DEVICE_NAME,
IOCTL_MOUNTMGR_VOLUME_ARRIVAL_NOTIFICATION,
mntName, mntNameLen, 0, 0);
mntPointLen = sizeof(PMOUNTMGR_CREATE_POINT_INPUT) +
device_extension->sDevName.Length + uVolumeName.Length;
mntPoint = ExAllocatePool(PagedPool, mntPointLen);
mntPoint->SymbolicLinkNameOffset = sizeof (MOUNTMGR_CREATE_POINT_INPUT);
RtlCopyMemory(&mntPoint+mntPoint->SymbolicLinkNameOffset,
uVolumeName.Buffer, uVolumeName.Length * sizeof(WCHAR));
mntPoint->SymbolicLinkNameLength = uVolumeName.Length;
mntPoint->DeviceNameOffset = mntPoint->SymbolicLinkNameOffset +
mntPoint->SymbolicLinkNameLength;
RtlCopyMemory(&mntPoint+mntPoint->DeviceNameOffset,
device_extension->sDevName.Buffer, device_extension->sDevName.Length);
mntPoint->DeviceNameLength = device_extension->sDevName.Length;
ntStatus = MakeDeviceIoRequest(MOUNTMGR_DEVICE_NAME,
IOCTL_MOUNTMGR_CREATE_POINT, mntPoint,
mntPointLen, 0, 0);
Затем я создаю символическую ссылку \ GLOBAL ?? \ L: -> \ Device \ DeviceName
ntStatus = IoCreateSymbolicLink(&uVolumeName, &(device_extension->sDevName));
DbgPrint("Mapped %wZ -> %wZ\n", &uVolumeName, &(device_extension->sDevName));
RtlFreeUnicodeString(&uVolumeName);
if ( mntName != NULL )
{
ExFreePool(mntName);
}
if ( mntPoint != NULL)
{
ExFreePool(mntPoint);
}
Тем не менее, ntStatus
ответ от менеджера монтирования - 0xC0000010
STATUS_INVALID_DEVICE_REQUEST
; строка моего устройства имеет вид \Device\DevName
и отвечает каждому из:
- IOCTL_VOLUME_ONLINE
- IOCTL_MOUNTDEV_QUERY_SUGGESTED_LINK_NAME
- IOCTL_MOUNTDEV_QUERY_UNIQUE_ID
- IOCTL_MOUNTDEV_QUERY_DEVICE_NAME
и список других IOCTL, ожидаемых для устройства хранения. Однако на всех этих подпрограммах установлены точки останова, и ни одна из них не достигнута.
Мое устройство создано с помощью этого небольшого фрагмента:
// Security descriptor
RtlInitUnicodeString(&sddl,
_T("D:P(A;;GA;;;SY)(A;;GA;;;BA)(A;;GA;;;BU)(A;;GA;;;WD)"));
// named device
status = IoCreateDeviceSecure(
DriverObject,
sizeof(DEVICE_EXTENSION),
&device_name, // \Device\DeviceName
DeviceType, // valid devicetype.
0,
FALSE,
&sddl, // security descriptor
NULL, // no idea what this does.
&device_object // output device object.
);
Итак, перейдем к некоторым вопросам:
- Правильно ли я создаю сообщения для менеджера монтирования? Вызов MakeDeviceIoRequest в основном охватывает
IoCallDriver
, и я достаточно уверен, что это не проблема.
- Что-то, что я делаю с
CreateDevice
, является проблемой? Я спрашиваю, потому что я прочитал эту запись в блоге , которая подразумевает что-то об именах устройств, FDO и PDO, что я, честно говоря, не совсем понимаю.
- Если мне кажется, что я слишком глубоко, есть ли шанс уточнить мое понимание того, как все это работает?
Примечания : У меня есть некоторые ограничения. Код, над которым я работаю, довольно унаследован, поэтому я включаю ntddk.h and wdmsec.h
; На данном этапе я не могу изменить их на wdm.h
или ntifs.h
.