ENTERPRISE

Windows 7 : Programming Multiple I/O Queues and Programming I/O - Reading and Writing the Registry

7/17/2014 4:41:50 AM

KMDF includes numerous methods with which a driver can read and write the registry. These methods enable the driver to create, open, and close a registry key, and to query, change, and delete the values of keys and individual data items within them.

To read the value of a registry key, a driver opens the registry key and then calls a method that queries the registry for data. A driver can read the registry either before or after creating its device object.

To read the registry before creating the device object, a driver calls the WdfFdoInitOpenRegistryKey method with the following parameters:

  • A handle to the WDFDEVICE_INIT structure that was passed to its EvtDriverDeviceAdd function.

  • A ULONG value that identifies the key to open.

  • A bit mask that indicates the type of required access.

  • An optional attribute structure.

  • A location to receive a handle to a WDFKEY object.

The WDFDEVICE_INIT structure contains settings that the framework requires before the device object has been created. WdfFdoInitOpenRegisterKey requires some of this information so that it can find the requested key.

To read the registry after creating the device object, a driver calls WdfDeviceOpenRegistryKey with a handle to the device object instead of the WDFDEVICE_INIT structure.

To get the value of a single setting within the key, the driver must query the key. KMDF provides several query methods, each of which returns a different type of value. For example, if the information is stored as a ULONG, the driver calls WdfRegisteryQueryUlong with the handle to the keys, a pointer to the name of the value, and a pointer to a ULONG variable to receive the value. After completing its query, the driver closes the registry key by calling WdfRegistryClose.

1. Code to Read and Write the Registry

The PCIDRV sample provides functions that

  • Read a REG_DWORD registry value that was written by another user mode or kernel mode component.

  • Read a REG_DWORD registry value that was stored under the device key.

  • Write a REG_DWORD registry value that was stored under the device key.

These functions are in the pcidrv.c source file.

The PCIDRV sample driver’s PciDrvReadFdoRegistryKeyValue function is called from the EvtDriverDeviceAdd callback, before the driver creates the device object. It reads a key that the driver’s INF wrote at installation, which indicates whether the driver was installed as an NDIS upper-edge miniport driver. This information is important because it determines whether the driver registers certain power policy and I/O event callbacks. If the driver was installed as an upper-edge miniport driver, it is not the power policy manager for its device; NDIS manages power policy.

The following is the source code for this function:

BOOLEAN
PciDrvReadFdoRegistryKeyValue (
__in PWDFDEVICE_INIT DeviceInit,
__in PWCHAR Name,
__out PULONG Value
)
{
WDFKEY hKey = NULL;
NTSTATUS status;
BOOLEAN retValue = FALSE;
UNICODE_STRING valueName;

PAGED_CODE();

*Value = 0;
status = WdfFdoInitOpenRegistryKey (DeviceInit,
PLUGPLAY_REGKEY_DEVICE,
STANDARD_RIGHTS_ALL,
WDF_NO_OBJECT_ATTRIBUTES,
&hKey
);

if (NT_SUCCESS (status))
{
RtlInitUnicodeString (&valueName, Name);
status = WdfRegistryQueryULong (hKey,
&valueName,
Value
);
if (NT_SUCCESS (status))
{
retValue = TRUE;
}
WdfRegistryClose (hKey);
}
return retValue;
}


First, the driver initializes the Value parameter that will receive the requested key value. Next, it opens the registry key by calling WdfFdoInitOpenRegistryKey. The WDF_DEVICEINIT object provides information that is required to identify the driver-specific key. The next parameter is a ULONG that contains flags that identify the key to open; the constant PLUGPLAY_REGKEY_DEVICE indicates the device’s hardware key. Although the sample requests all access rights to the registry (STANDARD_RIGHTS_ALL), the driver only reads the key and does not write it, so STANDARD_RIGHTS_READ would also work. Finally, the driver specifies WDF_NO_OBJECT_ATTRIBUTES to indicate that it is not passing an attribute structure for the key object. The output parameter hKey receives a handle to the returned WDFKEY object.

If the driver successfully opens the hardware key, it can query the key for the requested value. The name of the value is passed into the current function as a pointer to a string. However, the KMDF query method requires the name in a counted Unicode string. Therefore, before querying for the value, the driver calls RtInitUnicodeString to copy the input string into a string of the correct format.

The driver then queries for the value by calling WdfRegistryQueryUlong, which returns the ULONG value of the key in the Value parameter. The driver then closes the key by calling WdfRegisterClose and the function returns.

The driver’s other function to read the registry is similar. The only difference is that PciDrvReadRegistryValue is always called after the WDFDEVICE object has been created and therefore uses a handle to the WDFDEVICE object instead of a handle to the WDFDEVICE_INIT object.

The following is the code for this function:

BOOLEAN
PciDrvReadRegistryValue (
__in PFDO_DATA FdoData,
__in PWCHAR Name,
__out PULONG Value
)
{
WDFKEY hKey = NULL;
NTSTATUS status;
BOOLEAN retValue = FALSE;
UNICODE_STRING valueName;

PAGED_CODE ();

*Value = 0;
status = WdfDeviceOpenRegistryKey (FdoData->WdfDevice,
PLUGPLAY_REGKEY_DEVICE,
STANDARD_RIGHTS_ALL,
WDF_NO_OBJECT_ATTRIBUTES,
&hKey
);
if (NT_SUCCESS (status))
{
RtlInitUnicodeString (&valueName, Name);
status = WdfRegistryQueryULong (hKey,
&valueName, Value
);
if (NT_SUCCESS (status))
{
retValue = TRUE;
}
WdfRegistryClost (hKey);
}
return retValue;
}


This function is passed a pointer to the device context area (FdoData), where the driver keeps a handle to the device object. It passes the device object handle to the WdfDeviceOpenRegistryKey method. The driver then proceeds in exactly the same way as the previously discussed PciDrvReadFdoRegisterKeyValue function: It calls RtlUnicode-StringCopyString to build a Unicode string that holds the requested value name, calls WdfRegistryQueryUlong to get the ULONG value of the key, and calls WdfRegistryClose when it is finished.

The third registry function in the driver is PciDrvWriteRegistry-Value, which writes a ULONG value to the registry. This function differs from PciDrvReadRegistryValue in only two aspects:

  • The value of the key is an input parameter to PciDrvWriteRegistryValue but an output parameter to PciDrvReadRegistryValue.

  • PciDrvWriteRegistryValue calls WdfRegistryAssignULong to write a new value for the key, whereas PciDrvReadRegistryValue calls WdfRegistryQueryULong to read the current value of the key.

Otherwise, the functions are identical. The following statement shows how the driver writes the new value for the key:

status = WdfREgistryAssignULong (hKey, &valueName, Value);

Currently, the PCIDRV sample driver does not call PciDrvWriteRegistryValue; this function is included only for demonstration.

Other  
  •  Windows 7 : Programming Multiple I/O Queues and Programming I/O - Retrieving Requests from a Manual Queue
  •  Windows 7 : Programming Multiple I/O Queues and Programming I/O - Handling Requests from a Parallel Queue
  •  Windows 7 : Programming Multiple I/O Queues and Programming I/O - Creating and Configuring the Queues (part 2)
  •  Windows 7 : Programming Multiple I/O Queues and Programming I/O - Creating and Configuring the Queues (part 1)
  •  Microsoft Exchange Server 2010 : Managing Mailbox and public Folder Databases (part 2) - Moving Databases
  •  Microsoft Exchange Server 2010 : Managing Mailbox and public Folder Databases (part 1) - Mounting and Dismounting Databases
  •  Microsoft Exchange Server 2010 : Using Public Folder Databases (part 4) - Configuring Public Folder Referrals, Recovering Deleted Items from Public Folder Databases
  •  Microsoft Exchange Server 2010 : Using Public Folder Databases (part 3) - Configuring Public Folder Replication
  •  Microsoft Exchange Server 2010 : Using Public Folder Databases (part 2) - Setting Public Folder Database Limits
  •  Microsoft Exchange Server 2010 : Using Public Folder Databases (part 1) - Creating Public Folder Databases
  •  
    Top 10
    Extending LINQ to Objects : Writing a Single Element Operator (part 2) - Building the RandomElement Operator
    Extending LINQ to Objects : Writing a Single Element Operator (part 1) - Building Our Own Last Operator
    3 Tips for Maintaining Your Cell Phone Battery (part 2) - Discharge Smart, Use Smart
    3 Tips for Maintaining Your Cell Phone Battery (part 1) - Charge Smart
    OPEL MERIVA : Making a grand entrance
    FORD MONDEO 2.0 ECOBOOST : Modern Mondeo
    BMW 650i COUPE : Sexy retooling of BMW's 6-series
    BMW 120d; M135i - Finely tuned
    PHP Tutorials : Storing Images in MySQL with PHP (part 2) - Creating the HTML, Inserting the Image into MySQL
    PHP Tutorials : Storing Images in MySQL with PHP (part 1) - Why store binary files in MySQL using PHP?
    REVIEW
    - First look: Apple Watch

    - 3 Tips for Maintaining Your Cell Phone Battery (part 1)

    - 3 Tips for Maintaining Your Cell Phone Battery (part 2)
    VIDEO TUTORIAL
    - How to create your first Swimlane Diagram or Cross-Functional Flowchart Diagram by using Microsoft Visio 2010 (Part 1)

    - How to create your first Swimlane Diagram or Cross-Functional Flowchart Diagram by using Microsoft Visio 2010 (Part 2)

    - How to create your first Swimlane Diagram or Cross-Functional Flowchart Diagram by using Microsoft Visio 2010 (Part 3)
    Popular Tags
    Microsoft Access Microsoft Excel Microsoft OneNote Microsoft PowerPoint Microsoft Project Microsoft Visio Microsoft Word Active Directory Biztalk Exchange Server Microsoft LynC Server Microsoft Dynamic Sharepoint Sql Server Windows Server 2008 Windows Server 2012 Windows 7 Windows 8 Adobe Indesign Adobe Flash Professional Dreamweaver Adobe Illustrator Adobe After Effects Adobe Photoshop Adobe Fireworks Adobe Flash Catalyst Corel Painter X CorelDRAW X5 CorelDraw 10 QuarkXPress 8 windows Phone 7 windows Phone 8 BlackBerry Android Ipad Iphone iOS