help with IOCTL_MOUNTMGR_VOLUME_ARRIVAL_NOTIFICATION

I have the following situation:

Our FSD creates a named device-object of type
FILE_DEVICE_DISK (our PDO), and another of type
FILE_DEVICE_DISK_FILE_SYSTEM for a logical volume
(our VDO), upon the discovery of our logical
disks. These 2 are in addition to the control CDO
(ie the FSD itself).

We link our VDO and the PDO thru the PDO’s VPB in
response to the IRP_MN_MOUNT_VOLUME call.

Somewhere down the line, we are trying to notify
the Windows Mount-Manager about the creation of
our volume. Our aim here is to get a persistent
drive letter via the Mount-Mgr. We are NOT using
Pnp, hence cannot use IoRegisterDeviceInterface()
with the MOUNTDEV_MOUNTED_DEVICE_GUID class. So,
per the DDK doc, we have tried both the
IOCTL_MOUNTMGR_VOLUME_ARRIVAL_NOTIFICATION
and IOCTL_MOUNTMGR_CREATE_POINT ioctls, but
always get the STATUS_INVALID_DEVICE_REQUEST
error.

Code for IOCTL_MOUNTMGR_VOLUME_ARRIVAL_NOTIFICATION:

//… start_of_code …

NTSTATUS status;
UNICODE_STRING devName, ntName;
PIRP Irp;
KEVENT Event;
IO_STATUS_BLOCK Iosb;
PFILE_OBJECT fileObject;
PDEVICE_OBJECT deviceObject;
ULONG mountPointSize;
MOUNTMGR_TARGET_NAME *mountPoint=NULL;

// this is the name of the PDO
// this named-PDO was successfully created and ascertained
// via “Winobj.exe”.
// Also did the InitializeObjectAttributes() and
// ZwCreateDirectoryObject() on “\Device\MyDevice”

RtlInitUnicodeString(&ntName, L"\Device\MyDevice\Foo");
mountPointSize = sizeof(MOUNTMGR_TARGET_NAME) +

  • ntName.Length - 1;

mountPoint = (PMOUNTMGR_TARGET_NAME)
ExAllocatePool(PagedPool, mountPointSize);
mountPoint->DeviceNameLength = ntName.Length;
RtlCopyMemory((PCHAR)mountPoint->DeviceName,
ntName.Buffer, ntName.Length);

#if 0 // see comments at end
// force ourselves to be mounted
status = IoGetDeviceObjectPointer( &ntName,
FILE_READ_DATA,
&fileObject,
&deviceObject );
if(NT_SUCCESS(status))
{
ObDereferenceObject( fileObject );
ObDereferenceObject( deviceObject );
}
#endif

// Use the name of the Mount Manager device object
// defined in mountmgr.h (MOUNTMGR_DEVICE_NAME) to
// obtain a pointer to the Mount Manager.
RtlInitUnicodeString(&devName, MOUNTMGR_DEVICE_NAME);
status = IoGetDeviceObjectPointer( &devName,
FILE_READ_ATTRIBUTES,
&fileObject,
&deviceObject );
if(NT_SUCCESS(status))
{
// announce the volume’s arrival to Mount-manager
KeInitializeEvent( &Event, NotificationEvent, FALSE );
Irp = IoBuildDeviceIoControlRequest(
IOCTL_MOUNTMGR_VOLUME_ARRIVAL_NOTIFICATION,
deviceObject,
mountPoint,
mountPointSize,
NULL,
0,
FALSE,
&Event,
&Iosb );
if ( Irp == NULL )
{
status = STATUS_INSUFFICIENT_RESOURCES;
THROW( status );
}

status = IoCallDriver( deviceObject, Irp );

// the above call to IoCallDriver always fails with
// STATUS_INVALID_DEVICE_REQUEST

if ( status == STATUS_PENDING )
{
(VOID) KeWaitForSingleObject( &Event,
Executive,
KernelMode,
FALSE,
NULL );
}
status = Iosb.Status;
}

//… end_of_code …

Notice the disabled code for forcing the mount by passing
FILE_READ_DATA to IoGetDeviceObjectPointer (on the PDO).
Even then, the failure was the same.

Does anyone have any clues on what could be going wrong?
I have also tried to populate the MOUNTMGR_CREATE_POINT_INPUT
& do a IOCTL_MOUNTMGR_CREATE_POINT, but same error.
I have tried doing the IOCTL_MOUNTMGR_CREATE_POINT against
something like “\Device\HarddiskVolume1” and that succeeds.

Can someone point us to a working sample of these Mount-Mgr
ioctls.
Thanks a lot.