Registry, WDM and WinDK

We developed a driver using WinDK under Windows NT and ported this to
Windows 2000. It has worked fine for us but we are definitely
overdue to move to Windows XP. The driver itself works fine but we
are having trouble storing information in the registry. If anyone
can point me in some direction I would sincerely appreciate it. The
original driver uses the path provided by IoGetDriverObjectExtension
to get to the service key
(HKLM\System\CurrentControlSet\Services\TapPci\Parameters\ProgramAtStart)
where TapPci is our driver, Parameters\ProgramAtStart our desired
registry entry. I confess that I am an old Unix programmer and am
having difficulty wading through the DDK. We were very happy with
WinDK and were sorry to see it go. At any rate, from reading the
documentation, it appears that WDM drivers should not use this
registry key, but instead should use one obtained using status =
IoOpenDeviceRegistryKey(m_pDeviceObject, DevInstKeyType,
m_AccessMask, &m_hBaseHandle). However, when doing this the return
from status = ZwQueryValueKey(m_hCurrentHandle, Name,
KeyValueFullInformation, NULL, 0, pLength); fails. Writing to the
registry also fails.

I realize all this might not make sense. If anyone wants any more
information I would be so happy to provide it. But in a nutshell if
someone knows what we are doing wrong please please shine the light.

Otherwise perhaps some other questions might help us. We need to
store some parameters in the registry for the driver. Where should
they be stored? They are needed only at bootup or when the user uses
the device manager. Is it proper to store them in the services key
under “Parameters\MyKey”? Should we instead be using
IoOpenDeviceRegistryKey? If so, how is the key initialized? I have
tried Oney’s book and I got confused between the Hardware (Instance)
Key, the Class Key, the Driver Key and the Services Key. I still
don’t understand where the driver should store information it needs
from boot to boot.

Below is some code that may or may not be useful. If anyone is
familiar with WinDK and would like some consulting money please contact me.

Thanks,
Michael

First, our driver seems to work fine under Windows 2000. It works
fine under Windows XP also except for the registry. The problem
appears to result from the original driver referencing the registry
using the pRegistryPath passed in the constructor. From reading
documentation/sample code of WinDK, I assumed that this is not
correct for WDM and may be the problem with our registry
reading. The current driver (which does not work under XP) does this:

CString RegistryPathString = pRegistryPath;
CRegistry *pRegistry = new CRegistry( RegistryPathString, (ULONG) 0 );

pRegistry->SetRelativePath( ( L"\Parameters" ) );

CString ExistStr( TAPPCI_CHIPEXISTS_KEY );
ExistStr += CString( i );

if ( !NT_SUCCESS( pRegistry->GetKey(
ExistStr, &ChipExists[i] ) ) )
{
KdPrint( ( “ReadRegistry. GetKey( ChipExists ) failed for
chip %d\n”, i ) );
KdPrintCStringnl( Concatenate( RegistryPathString,
L"\Parameters" ) );
KdPrintCStringnl( ExistStr );
return;
}

As I said, this does not work under XP as it doesn’t remember the
parameters from boot to boot. So I made the following change:

Under PnpSetupDevice Resources:

CRegistry registry( m_pPhysicalDeviceObject, KEY_ALL_ACCESS );

// we need to initialize the handle now
status = registry.InitializeHandle();
if (!NT_SUCCESS( status ) )
{
KdPrint((“TAPPCI: CTappci::TappciReadRegistry - unable to
initialize handle (0x%X)\n”, status));
return status;
}

// Normally, registry keys are stored under the Parameters subkey under
// our device key.
status = registry.SetRelativePath(L"Parameters");
if ( !NT_SUCCESS( status ) )
{
KdPrint((“TAPPCI: CTappci::TappciReadRegistry - unable to
change path (0x%X)\n”, status));
return status;
}

CString ExistStr( TAPPCI_CHIPEXISTS_KEY );
ExistStr += CString( i );

if ( !registry.IsKeyPresent( ExistStr ) )
{
// missing registry information log the event
m_EventLog.LogError( MISSING_REGISTRY_INFORMATION, 2,
(PWCHAR) m_DeviceName, ExistStr );
KdPrint( ( “TAPPCI: CTappci::TappciReadRegistry - Missing
key ChipExists%d\n”, i ) );
// return STATUS_INSUFFICIENT_RESOURCES;
}

status = registry.GetKey( ExistStr, &ChipExists[i], FALSE );
if ( !NT_SUCCESS( status ) )
{
KdPrint( ( “TAPPCI: CTappci::TappciReadRegistry - Failed to
get ChipExists%d (0x%X)\n”, i, status ) );
// return status;
}

I get KdPrints saying that the key is missing and failed to get. I
also tried just writing the key and then reading it but the write fails.

IoGetDriverObjectExtension does not provide a registry path (unless you
are in some type of port/miniport model where the port driver stored the
registry path for you).

Your examples use 2 different reg variables, M_hCurrentHandle and
m_hBaseHandle

status = IoOpenDeviceRegistryKey(m_pDeviceObject, DevInstKeyType,
m_AccessMask, &m_hBaseHandle).

status = ZwQueryValueKey(m_hCurrentHandle, Name,
KeyValueFullInformation, NULL, 0, pLength);

Don’t know if that is a problem or not. Furthermore,
IoOpenDeviceRegistryKey requires a PDO (m_pPhysicalDeviceObject based on
the snippet), not your device object. Have you tried using the raw WDM
APIs to open the key instead of the WinDK wrapper classes?

The bigger question is, do you have driver global data or per device
data? If you have driver global data, the old location under
hklm.…\services\Parameters\ProgramAtStart is a fine place to store
them. If you have device specific data, use the device specific
devnode. If you don’t know where to store the data, open up
PLUGPLAY_REGKEY_DEVICE and store it there.

Even bigger picture, consider droping WinDK and port to KMDF. KMDF is
current and is supported.

d

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Michael Wade
Sent: Tuesday, April 10, 2007 5:18 PM
To: Windows System Software Devs Interest List
Subject: [ntdev] Registry, WDM and WinDK

We developed a driver using WinDK under Windows NT and ported this to
Windows 2000. It has worked fine for us but we are definitely
overdue to move to Windows XP. The driver itself works fine but we
are having trouble storing information in the registry. If anyone
can point me in some direction I would sincerely appreciate it. The
original driver uses the path provided by IoGetDriverObjectExtension
to get to the service key
(HKLM\System\CurrentControlSet\Services\TapPci\Parameters\ProgramAtStart
)
where TapPci is our driver, Parameters\ProgramAtStart our desired
registry entry. I confess that I am an old Unix programmer and am
having difficulty wading through the DDK. We were very happy with
WinDK and were sorry to see it go. At any rate, from reading the
documentation, it appears that WDM drivers should not use this
registry key, but instead should use one obtained using status =
IoOpenDeviceRegistryKey(m_pDeviceObject, DevInstKeyType,
m_AccessMask, &m_hBaseHandle). However, when doing this the return
from status = ZwQueryValueKey(m_hCurrentHandle, Name,
KeyValueFullInformation, NULL, 0, pLength); fails. Writing to the
registry also fails.

I realize all this might not make sense. If anyone wants any more
information I would be so happy to provide it. But in a nutshell if
someone knows what we are doing wrong please please shine the light.

Otherwise perhaps some other questions might help us. We need to
store some parameters in the registry for the driver. Where should
they be stored? They are needed only at bootup or when the user uses
the device manager. Is it proper to store them in the services key
under “Parameters\MyKey”? Should we instead be using
IoOpenDeviceRegistryKey? If so, how is the key initialized? I have
tried Oney’s book and I got confused between the Hardware (Instance)
Key, the Class Key, the Driver Key and the Services Key. I still
don’t understand where the driver should store information it needs
from boot to boot.

Below is some code that may or may not be useful. If anyone is
familiar with WinDK and would like some consulting money please contact
me.

Thanks,
Michael

First, our driver seems to work fine under Windows 2000. It works
fine under Windows XP also except for the registry. The problem
appears to result from the original driver referencing the registry
using the pRegistryPath passed in the constructor. From reading
documentation/sample code of WinDK, I assumed that this is not
correct for WDM and may be the problem with our registry
reading. The current driver (which does not work under XP) does this:

CString RegistryPathString = pRegistryPath;
CRegistry *pRegistry = new CRegistry( RegistryPathString, (ULONG)
0 );

pRegistry->SetRelativePath( ( L"\Parameters" ) );

CString ExistStr( TAPPCI_CHIPEXISTS_KEY );
ExistStr += CString( i );

if ( !NT_SUCCESS( pRegistry->GetKey(
ExistStr, &ChipExists[i] ) ) )
{
KdPrint( ( “ReadRegistry. GetKey( ChipExists ) failed for
chip %d\n”, i ) );
KdPrintCStringnl( Concatenate( RegistryPathString,
L"\Parameters" ) );
KdPrintCStringnl( ExistStr );
return;
}

As I said, this does not work under XP as it doesn’t remember the
parameters from boot to boot. So I made the following change:

Under PnpSetupDevice Resources:

CRegistry registry( m_pPhysicalDeviceObject, KEY_ALL_ACCESS );

// we need to initialize the handle now
status = registry.InitializeHandle();
if (!NT_SUCCESS( status ) )
{
KdPrint((“TAPPCI: CTappci::TappciReadRegistry - unable to
initialize handle (0x%X)\n”, status));
return status;
}

// Normally, registry keys are stored under the Parameters subkey
under
// our device key.
status = registry.SetRelativePath(L"Parameters");
if ( !NT_SUCCESS( status ) )
{
KdPrint((“TAPPCI: CTappci::TappciReadRegistry - unable to
change path (0x%X)\n”, status));
return status;
}

CString ExistStr( TAPPCI_CHIPEXISTS_KEY );
ExistStr += CString( i );

if ( !registry.IsKeyPresent( ExistStr ) )
{
// missing registry information log the event
m_EventLog.LogError( MISSING_REGISTRY_INFORMATION, 2,
(PWCHAR) m_DeviceName, ExistStr );
KdPrint( ( “TAPPCI: CTappci::TappciReadRegistry - Missing
key ChipExists%d\n”, i ) );
// return STATUS_INSUFFICIENT_RESOURCES;
}

status = registry.GetKey( ExistStr, &ChipExists[i], FALSE );
if ( !NT_SUCCESS( status ) )
{
KdPrint( ( “TAPPCI: CTappci::TappciReadRegistry - Failed to
get ChipExists%d (0x%X)\n”, i, status ) );
// return status;
}

I get KdPrints saying that the key is missing and failed to get. I
also tried just writing the key and then reading it but the write fails.


Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256

To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer