Accessing the registry with DriverWorks.

0 Likes

Problem:

Does DriverWorks offer any help in accessing the registry.

Resolution:

How to read the registry using DriverWorks

Access to the system registry from a kernel mode driver can be difficult using the raw DDK calls. The DDK provides a diverse set of entry points that operate on the registry, some of which have the 'Zw' prefix, and others of which have the 'Rtl' prefix.

DriverWorks class KRegistryKey simplifies access to the registry by unifying all operations under a single class, and by providing member functions that make common operations simple. The class exposes the natural object orientation that underlies the registry implementation in NT, which, like many aspects of the system, is obscured by the DDK interface.

Here is a summary of the member functions of KRegistry::Key:

KRegistryKey Constructors

~KRegistryKey Destructor

Reconstruct Maps an instance to a different registry key

LastError Retrieves the status of the last operation

QueryValue Get information about one of the key's values

InitializeSubkeyEnumeration Initialize an enumeration of the key's subkeys

EnumerateSubkey Get information about the next subkey

InitializeValueEnumeration Initialize an enumeration of the key's values

EnumerateValue Get information about the next value

WriteValue Add a new value or replace data of an existing value

Delete Delete the key from the registry

I. Creating an instance of KRegistryKey

The class has several constructors, the most commonly used being:

KRegistryKey(PUNICODE_STRING RootDir,

PCWSTR path=NULL,

BOOLEAN bCreateSubkey=FALSE,

ULONG CreateOptions=0,

ACCESS_MASK access=KEY_DEFAULT_ACCESS,

ULONG Flags=KEY_DEFAULT_ATTRIBUTES);

Parameter RootDir is typically the path of the driver key, which is passed to DriverEntry, and can always be retrieved with the following line of code:

PUNICODE_STRING DriverKeyPath =

KDriver::DriverInstance()->RegistryPath();

The second parameter, path, is the name of a subkey below the key specified by the root path. This is often a constant. For example, here is the invocation of a constructor that opens the subkey named "Parameters" under the driver key:

KRegistryKey ParamKey(DriverKeyPath,

L"Parameters");

When reading the registry, the first two parameters to the constructor are usually sufficient.

Check the success of the constructor by calling member function LastErrror.

if ( NT_SUCCESS(ParamKey.LastError()) )

{

// the key was opened successfully

}

II. Using KRegistryKey to access values

Usually the reason to access the registry is to get a particular value associated with some key. Suppose, there is a value of type ULONG named "BUFFER_SIZE" attached to the subkey opened above. To read the value, use a form of member function QueryValue.

ULONG BufferSize=DEFAULT_BUFFER_SIZE;

status = ParamKey.QueryValue(L"BUFFER_SIZE",

&BufferSize);

If a value named BUFFER_SIZE is found on the parameters key, the above call reads its value into variable BufferSize. If the value is not present, the query does not change BufferSize, so it may be preset to a default. The status return indicates whether or not a value was found.

To read a string value from the registry, use a different form of QueryValue. Suppose there is a string value named "MODEL NAME" attached to the subkey opened above. Here is how to access it:

PWSTR Model = DEFAULT_MODEL_NAME;

ULONG ModelLength = 0; // request storage allocation

status = ParamKey.QueryValue(L"MODEL NAME",

Model,

ModelLength,

PagedPool);

If QueryValue locates the specified value, it retrieves the value data from the registry. The buffer to which QueryValue copies the value data may be provided by the caller, or QueryValue may allocate it dynamically. In this example, because "ModelLength" was set to zero, QueryValue allocates storage for the value data. QueryValue allocates a block of memory, reads the string into the allocated storage, sets the pointer, Model, to point to the newly allocated block, and sets "ModelLength" to the size of the data area allocated. The caller must delete the data area when it is no longer needed.

The caller may provide storage for the string instead of having QueryValue allocate it. If "ModelLength" were not zero, QueryValue would use the provided pointer, Model. In this case, the input length parameter indicates the length of the storage provided by the caller.

If the value is not found, neither the pointer nor the length variable is modified.

III. Using KRegistryKey to enumerate subkeys

Enumerating subkeys is very easy using KRegistryKey. Here is a fragment that illustrates how to enumerate all the subkeys under a driver's 'Parameters' key:

REGKEYPROPERTIES Props;

// First open the key

KRegistryKey Rk (DriverPath, L"\\Parameters");

// Create a string object to hold each subkey name

KUstring KeyName(MAX_KEY_LENGTH, PagedPool);

// Initialize subkey enumeration for the key

Rk.InitializeSubkeyEnumeration();

// Enumerate each key, emit names to the monitor

while ( NT_SUCCESS(Rk.EnumerateSubkey( KeyName,

NULL,

&Props) ))

{

Tracer << "Subkey: " <<

KeyName << "

";

Old KB# 11294
Comment List
Anonymous
Related Discussions
Recommended