IoOpenDeviceRegistryKey returns STATUS_INVALID_DEVICE_REQUEST

Dear Friends,
I am trying to access the symbolic name assigned by Windows 2000 to my
Virtual Serial Port using the registry access function
“IoOpenDeviceRegistryKey”. But this function returns with error
STATUS_INVALID_DEVICE_REQUEST which, as per ddk documentation means that
the first parameter “DeviceObject is not a valid PDO”. I am not able to
figure out why the device object pointer passed by me to this function is
invalid. I am calling this function from my DriverEntry function after
successfully calling IoCreateDevice (I am using the same DeviceObject
poiter passed to IoCreateDevice). I am attaching a portion of the code for
examination. Any help will be greatly appreciated.
Regards,
Ganesh

////// Driver entry routine //////
NTSTATUS DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath )
{
// pointer to hold newly created Device Object - required for
// manipulating some of the DO’s parameters
PDEVICE_OBJECT DeviceObject = NULL;

// pointer to our device extension
SLXExtension *pSLXExtension;

// variable to hold result of function call
NTSTATUS status;

// unicode strings to hold the device’s NT name and the DOS (Win32) name
UNICODE_STRING NtNameString;

// Create counted unicode string of our device name
RtlInitUnicodeString( &NtNameString, NT_DEVICE_NAME);

// tell debugger your present status
KdPrint( (“SLXVirPort:Entered DriverEntry!\n”) );

// Create a new device object for the device
status = IoCreateDevice(
DriverObject, // passed by the higher level driver
sizeof(SLXExtension), // size of our global storage structure
&NtNameString, // Unicode string containing name of our
device
FILE_DEVICE_SERIAL_PORT, // Type of device
0, // additional info about device - we do not have any!
FALSE, // can have non-exclusive access
&DeviceObject // empty device object pointer which
IoCreateDevice will initialise
);

// if DO creation is successful proceed and manipulate certain parameters
in the DO
if (NT_SUCCESS(status))
{
// init our local pointer to the dev extension
pSLXExtension = (SLXExtension*)DeviceObject->DeviceExtension;

// Specify the way IO is done - Buffered IO always OR with existing value
DeviceObject->Flags |= DO_BUFFERED_IO;

// Set the DeviceType - for new unknown devices it must be between 32768
and 65535
DeviceObject->DeviceType = FILE_DEVICE_SERIAL_PORT;

// Create dispatch points for all driver all possible routines (create,
open, close, unload…)
DriverObject->DriverUnload = SLXVirPortUnload;
DriverObject->MajorFunction[IRP_MJ_WRITE] = SLXVirPortWrite;
DriverObject->MajorFunction[IRP_MJ_READ] = SLXVirPortRead;
DriverObject->MajorFunction[IRP_MJ_CREATE]= SLXVirPortOpen;
DriverObject->MajorFunction[IRP_MJ_CLOSE]= SLXVirPortClose;
DriverObject->MajorFunction[IRP_MJ_CLEANUP]= SLXVirPortCleanup;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] =
SLXVirPortIOCtlHandler;
DriverObject->MajorFunction[IRP_MJ_FLUSH_BUFFERS]= SLXVirPortFlush;
DriverObject->MajorFunction[IRP_MJ_PNP] = SLXVirPortPnpDispatch;
DriverObject->MajorFunction[IRP_MJ_POWER]=
SLXVirPortPowerDispatch;
DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] =
SLXVirPortQueryInformationFile;
DriverObject->MajorFunction[IRP_MJ_SET_INFORMATION]=
SLXVirPortSetInformationFile;
DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] =
SLXVirPortSystemControlDispatch;
DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] =
SLXVirPortInternalIoControl;

// just to say things are fine till here!
KdPrint( (“SLXVirPort: Completed Dispatch Functions mapping!\n”) );

/******************************************************************/
// create a handle to access our registry area
status = IoOpenDeviceRegistryKey(DeviceObject),
LUGPLAY_REGKEY_DEVICE, STANDARD_RIGHTS_READ, &keyHandle);

if (status != STATUS_SUCCESS)
{
KdPrint(("SlxVirPort:IoOpenDeviceRegistryKey failed: "));
if( status == STATUS_INVALID_PARAMETER )
{
KdPrint((“STATUS_INVALID_PARAMETER Error\n”)); }
else if( status == STATUS_INVALID_DEVICE_REQUEST )
{
KdPrint((“STATUS_INVALID_DEVICE_REQUEST Error\n”)); }
else
{
KdPrint((“Unknown Error\n”)); }
}
else
{
KdPrint((“SlxVirPort:IoOpenDeviceRegistryKey success\n”)); }
/******************************************************************/
if( !NT_SUCCESS (status) )
{
// if unable to create symbolic link object exit agter deleting the
DO
KdPrint( (“SLXVirPort:Couldn’t create the symbolic link!\n”) );
IoDeleteDevice( DriverObject->DeviceObject );
}
else
{
KdPrint( (“SLXVirPort:All initialized - Symbolic link object
created \n”) );
}
// do some variable initialisation
pSLXExtension->pSerialFileObject = NULL;
pSLXExtension->pSerialDeviceObject = NULL;
pSLXExtension->IsrWaitMask = 0;
pSLXExtension->PortOpened = FALSE;
}
else
{
// unable to create device - exit - no cleanup required
KdPrint( (“SLXVirPort:Couldn’t create the device\n”) );
}
return status;
}

A device object is a PDO when you report to PNP via query bus relations
as one of your children and it has been started. Until that point in
time, the device object is not a PDO.

D

This posting is provided “AS IS” with no warranties, and confers no
rights.

-----Original Message-----
From: Ganesh Okade [mailto:xxxxx@sunlux-india.com]
Sent: Tuesday, July 16, 2002 9:31 PM
To: NT Developers Interest List
Subject: [ntdev] IoOpenDeviceRegistryKey returns
STATUS_INVALID_DEVICE_REQUEST

Dear Friends,
I am trying to access the symbolic name assigned by Windows 2000 to
my
Virtual Serial Port using the registry access function
“IoOpenDeviceRegistryKey”. But this function returns with error
STATUS_INVALID_DEVICE_REQUEST which, as per ddk documentation means that
the first parameter “DeviceObject is not a valid PDO”. I am not able to
figure out why the device object pointer passed by me to this function
is
invalid. I am calling this function from my DriverEntry function after
successfully calling IoCreateDevice (I am using the same DeviceObject
poiter passed to IoCreateDevice). I am attaching a portion of the code
for
examination. Any help will be greatly appreciated.
Regards,
Ganesh

////// Driver entry routine //////
NTSTATUS DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath )
{
// pointer to hold newly created Device Object - required for
// manipulating some of the DO’s parameters
PDEVICE_OBJECT DeviceObject = NULL;

// pointer to our device extension
SLXExtension *pSLXExtension;

// variable to hold result of function call
NTSTATUS status;

// unicode strings to hold the device’s NT name and the DOS
(Win32) name
UNICODE_STRING NtNameString;

// Create counted unicode string of our device name
RtlInitUnicodeString( &NtNameString, NT_DEVICE_NAME);

// tell debugger your present status
KdPrint( (“SLXVirPort:Entered DriverEntry!\n”) );

// Create a new device object for the device
status = IoCreateDevice(
DriverObject, // passed by the higher level driver
sizeof(SLXExtension), // size of our global storage
structure
&NtNameString, // Unicode string containing name of our
device
FILE_DEVICE_SERIAL_PORT, // Type of device
0, // additional info about device - we do not have any!
FALSE, // can have non-exclusive access
&DeviceObject // empty device object pointer which
IoCreateDevice will initialise
);

// if DO creation is successful proceed and manipulate certain
parameters
in the DO
if (NT_SUCCESS(status))
{
// init our local pointer to the dev extension
pSLXExtension = (SLXExtension*)DeviceObject->DeviceExtension;

// Specify the way IO is done - Buffered IO always OR with
existing value
DeviceObject->Flags |= DO_BUFFERED_IO;

// Set the DeviceType - for new unknown devices it must be
between 32768
and 65535
DeviceObject->DeviceType = FILE_DEVICE_SERIAL_PORT;

// Create dispatch points for all driver all possible routines
(create,
open, close, unload…)
DriverObject->DriverUnload = SLXVirPortUnload;
DriverObject->MajorFunction[IRP_MJ_WRITE] = SLXVirPortWrite;
DriverObject->MajorFunction[IRP_MJ_READ] = SLXVirPortRead;
DriverObject->MajorFunction[IRP_MJ_CREATE]= SLXVirPortOpen;
DriverObject->MajorFunction[IRP_MJ_CLOSE]= SLXVirPortClose;
DriverObject->MajorFunction[IRP_MJ_CLEANUP]= SLXVirPortCleanup;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] =
SLXVirPortIOCtlHandler;
DriverObject->MajorFunction[IRP_MJ_FLUSH_BUFFERS]=
SLXVirPortFlush;
DriverObject->MajorFunction[IRP_MJ_PNP] = SLXVirPortPnpDispatch;
DriverObject->MajorFunction[IRP_MJ_POWER]=
SLXVirPortPowerDispatch;
DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] =
SLXVirPortQueryInformationFile;
DriverObject->MajorFunction[IRP_MJ_SET_INFORMATION]=
SLXVirPortSetInformationFile;
DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] =
SLXVirPortSystemControlDispatch;
DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] =
SLXVirPortInternalIoControl;

// just to say things are fine till here!
KdPrint( (“SLXVirPort: Completed Dispatch Functions mapping!\n”) );

/******************************************************************/
// create a handle to access our registry area
status = IoOpenDeviceRegistryKey(DeviceObject),
LUGPLAY_REGKEY_DEVICE, STANDARD_RIGHTS_READ, &keyHandle);

if (status != STATUS_SUCCESS)
{
KdPrint(("SlxVirPort:IoOpenDeviceRegistryKey failed:
"));
if( status == STATUS_INVALID_PARAMETER )
{
KdPrint((“STATUS_INVALID_PARAMETER Error\n”));
}
else if( status == STATUS_INVALID_DEVICE_REQUEST )
{
KdPrint((“STATUS_INVALID_DEVICE_REQUEST
Error\n”)); }
else
{
KdPrint((“Unknown Error\n”));
}
}
else
{
KdPrint((“SlxVirPort:IoOpenDeviceRegistryKey
success\n”)); }
/******************************************************************/
if( !NT_SUCCESS (status) )
{
// if unable to create symbolic link object exit agter
deleting the
DO
KdPrint( (“SLXVirPort:Couldn’t create the symbolic link!\n”)
);
IoDeleteDevice( DriverObject->DeviceObject );
}
else
{
KdPrint( (“SLXVirPort:All initialized - Symbolic link object
created \n”) );
}
// do some variable initialisation
pSLXExtension->pSerialFileObject = NULL;
pSLXExtension->pSerialDeviceObject = NULL;
pSLXExtension->IsrWaitMask = 0;
pSLXExtension->PortOpened = FALSE;
}
else
{
// unable to create device - exit - no cleanup required
KdPrint( (“SLXVirPort:Couldn’t create the device\n”) );
}
return status;
}


You are currently subscribed to ntdev as: xxxxx@windows.microsoft.com
To unsubscribe send a blank email to %%email.unsub%%

Hello Doron,
Thanks for the reply. If you take the simple case of my driver which is
not plug and play, how do I access my registry area? Is it mandatory that
all drivers register themselves with the PnP manager? If yes can you brief
me the steps?
Regards,
Ganesh

If you are being loaded because you are a part of a pnp device node
(which sounds like your device would be root enumerated because no pnp
bus would find it), you get the PDO in your AddDevice routine. If you
are not a PNP aware device driver and your AddDevice routine is not
being called, you cannot use the PNP APIs that expect a PDO

D

This posting is provided “AS IS” with no warranties, and confers no
rights.

-----Original Message-----
From: Ganesh Okade [mailto:xxxxx@sunlux-india.com]
Sent: Wednesday, July 17, 2002 4:23 AM
To: NT Developers Interest List
Subject: [ntdev] RE: IoOpenDeviceRegistryKey returns
STATUS_INVALID_DEVICE_REQUEST

Hello Doron,
Thanks for the reply. If you take the simple case of my driver which
is
not plug and play, how do I access my registry area? Is it mandatory
that
all drivers register themselves with the PnP manager? If yes can you
brief
me the steps?
Regards,
Ganesh


You are currently subscribed to ntdev as: xxxxx@windows.microsoft.com
To unsubscribe send a blank email to %%email.unsub%%

Hello Doron,
I have now changed my logic to access the registry directly to get the
friendly portname assigned to my port. I now directly access the
\Enum\Ports\0000 section using functions like zwquery… etc.
I am facing a problem. My code for getting the portname is in the
DriverEntry function after successfully creating the device object. Now
when I install my port using “Add Remove Hardware” in Win 2K, the driver
entry gets called and the driver is able to access the registry path. But
after a system restart when my DriverEntry is being called again the
access to the above said registry path is failing. I am not able to
figureout why? Is it so that \Enum\Ports\0000 gets recreated after every
system reset and my driver is accessing the location before it is being
created?
Regards,
Ganesh

You should never ever open the Enum branch directly and look for your
device; this is why there is an API to manage this. Also, our hardcoded
path may be different from machine to machine, so it is completely non
portable.

If you are searching for other com ports to open other then your own,
look at the toastmon example on how to listen for device interface
notifications. Otherwise, if you are trying to open your own PDO, you
need to be a pnp driver, plain and simple.

D

This posting is provided “AS IS” with no warranties, and confers no
rights.

-----Original Message-----
From: Ganesh Okade [mailto:xxxxx@sunlux-india.com]
Sent: Friday, July 19, 2002 1:13 AM
To: NT Developers Interest List
Subject: [ntdev] RE: IoOpenDeviceRegistryKey returns
STATUS_INVALID_DEVICE_REQUEST

Hello Doron,
I have now changed my logic to access the registry directly to get
the friendly portname assigned to my port. I now directly access the
\Enum\Ports\0000 section using functions like zwquery… etc.
I am facing a problem. My code for getting the portname is in the
DriverEntry function after successfully creating the device object. Now
when I install my port using “Add Remove Hardware” in Win 2K, the driver
entry gets called and the driver is able to access the registry path.
But after a system restart when my DriverEntry is being called again the
access to the above said registry path is failing. I am not able to
figureout why? Is it so that \Enum\Ports\0000 gets recreated after
every system reset and my driver is accessing the location before it is
being created? Regards, Ganesh


You are currently subscribed to ntdev as: xxxxx@windows.microsoft.com
To unsubscribe send a blank email to %%email.unsub%%