How do I connect to NT Mount Manager to schedule?

I'm trying to replace some user space code DefineDosDevice

(which doesn't work on Vista with admin users due to the elevated and normal session being represented by different DosDevice stores, so a rather strange scenario is generated that the disk is visible if created from non-elevated processes but invisible if created from a promoted process).

A replacement for this, as I found out by looking at the Truecrypt source and this WDM Sample should output messages IOCTL_MOUNTMGR_VOLUME_ARRIVAL_NOTIFICATION

to mountmgr.sys followed by IOCTL_MOUNTMGR_CREATE_POINT

/ IOCTL_MOUNTMGR_DELETE_POINT

.

So this is what I am doing - my code looks like this:

First, the different locales:

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;

      

Then I create and make my two requests. The first fails with the above status code. The second fails with a different status code (but is not expected to work if the first fails).

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

      

Then I create a symlink \ 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);
}

      

However, the answer is ntStatus

from the mount manager 0xC0000010

STATUS_INVALID_DEVICE_REQUEST

; my device string is shaped \Device\DevName

and responds to each of:

  • IOCTL_VOLUME_ONLINE
  • IOCTL_MOUNTDEV_QUERY_SUGGESTED_LINK_NAME
  • IOCTL_MOUNTDEV_QUERY_UNIQUE_ID
  • IOCTL_MOUNTDEV_QUERY_DEVICE_NAME

and a list of other IOCTLs expected for the storage device. However, I have breakpoints set in all of these routines and none of them are reached.

My device is built with this little snippet:

// 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.
);

      

So, up to some questions:

  • Am I generating messages for the mount manager correctly? The MakeDeviceIoRequest call basically wraps around IoCallDriver

    , and I'm pretty sure that's not a problem.
  • Am I doing something with the problem CreateDevice

    ? I ask because I am reading this blog post which implies something about device names, FDO and PDO, which I honestly don't quite understand.
  • If I seem to be too deep, is there a chance to figure out how I understand how it all works?

Notes: I have some limitations. The code I'm building from above is pretty inherited, so I include ntddk.h and wdmsec.h

; I cannot change them to wdm.h

or ntifs.h

at this stage.

+3


source to share


1 answer


Before diving into this, can you translate your calls to DefineDosDevice into a service? The call from the service puts the link in the global catalog, which will completely get rid of the problem with the alias you have.



If you cannot do this, I am assuming you are not handling any other required IOCTL mount manager. I know you have breakpoints on all specific IOCTLs, but do you have a breakpoint in your default handler? This usually comes from STATUS_INVALID_DEVICE_REQUEST.

+2


source







All Articles