RtlEqualUnicodeString Returns TRUE if the two Unicode strings are equal, optionally case-insensitive.
RtlFreeUnicodeString Frees the Unicode string buffer memory from the pool.
RtlInitUnicodeString Sets the Unicode string buffer to point to the given wide string, and sets the length fields to match.
RtlIntegerToUnicodeString Converts a ULONG value to a Unicode string in the specified base. The string buffer must have been initialized beforehand.
RtlPrefixUnicodeString† Sees if one Unicode string is a prefix of another, optionally case-insensitive.
RtlUnicodeStringToAnsiString Converts a Unicode string into ANSI. If you ask for the destination ANSI buffer to be allocated, free it eventually with RtlFreeAnsiString.
RtlUnicodeStringToInteger Converts a Unicode string to an integer.
RtlUpcaseUnicodeString† Converts a Unicode string into uppercase, optionally allocating a buffer.

†NT/W2000 only

ReadReg declares the variables that will receive the values from the registry. For a UNICODE_STRING, its Buffer, Length, and MaximumLength fields have to be initialized. In this case, these fields are initialized to NULL and zero. The call to RtlQueryRegistryValues will allocate a Buffer and set the length fields.

In most cases, a UNICODE_STRING's buffer needs to be set up correctly. If you want to store an unchanging wide string value in a Unicode string, use the RtlInitUnicodeString function. The Unicode string Buffer is set to point to the passed string and the Length and Maximum-Length strings are set to the length of the string[10].

RtlInitUnicodeString(&UnicodeString, L'\Device\Wdm1');

If you wish to work with the contents of a Unicode string, you need to provide the wide string buffer. Use code like this.

const int MAX_CHARS = 30;

UNICODE_STRING UnicodeString;

WCHAR UnicodeStringBuffer[MAX_CHARS];

UnicodeString.Buffer = UnicodeStringBuffer;

UnicodeString.MaximumLength = MAX_CHARS*2;

UnicodeString.Length = 0;

In this case, the buffer is on the stack. If you want to use the Unicode string after this routine has completed, you must allocate the buffer from pool memory. Do not forget to free this memory once you have finished using the string.

Calling RtlQueryRegistryValues

You must send a query table array to RtlQueryRegistryValues. This array details the actions that you want to do. The last entry in the query table must be zeroed to indicate the end of the list. This is achieved when the entire query table is zeroed using RtlZeroMemory in ReadReg.

There is a wide range of options available when querying the registry. The Flags field in each query table element indicates the action you want to do. The first query listed previously uses RTL_QUERY_REGISTRY_SUBKEY, which means that the Name field contains the subkey for subsequent queries.

The following queries both set the Flags field to RTL_QUERY_REGISTRY_DI RECT. In this case, the Name field contains the registry value name, and the EntryContext field contains a pointer to the variable to receive the value. You have to trust that no one has fiddled with the value types so that a string is returned when you were expecting a ULONG.

A safer approach (not used here) is to pass the name of a callback routine in the QueryRoutine field and set the Flags field to zero. Your routine is called for each value found, and indicates the type of the found value.

The remaining parameters to RtlQueryRegistryValues give even more flexibility. RTL_REGISTRY_ABSOLUTE indicates that the Path parameter is an absolute registry path. Various other useful options can be given (e.g., if the Path is relative to the HKLMSystcmCurrentControlSet Services key).

RtlQueryRegistryValues only returns STATUS_SUCCESS if all the queries were processed correctly and all the registry values were found. The code in ReadReg simply displays the return status and the values retrieved. If using this routine for real, you will probably want to store the values in global variables.

Operating system version

You can use a registry setting to determine at run time whether you are running in W98 or not. In NT and W2000 the following registry value is available, HKLMSystemCurrentControlSet ControlProductOptionsProductType. The value is 'WinNT' for the Workstation/Professional Windows version and either 'LanmanNT' or 'ServerNT' for the Server/Enterprise version. In W98 this registry value should not be available.

Installing Wdm1

That's enough on the Wdm1 code so far. The compiled driver, Wdm1.sys, is provided on the CD in free and checked build versions. However, you can recompile it if you wish.

Normally, Windows detects when a device is installed and prompts for the necessary drivers if they cannot be found already in the system. Full details of the driver selection process are given later.

For the virtual Wdm1 device, use the Control Panel 'Add New Hardware' applet wizard. The process is basically the same for Windows 98 and Windows 2000.

Click Next two times, select 'No, I want to select hardware from a list' and click Next. Select 'Other devices' and click Next. Click 'Have Disk…' and browse to the path of the Wdm1 driver (e.g., C:WDMBookWdm1Sys) and click 'OK'.

Two models are listed from the found installation INF files, one for the Wdm1 checked build and one for the free build. Select the model you want to install and select Next. Select 'Finish' to complete installation.

The installation process does whatever the INF file specifies. The Wdm1 INF files copy the relevant driver to the Windows system32drivers directory, adds registry settings, etc.

Windows should now have created a Wdm1 device for you. Check that it appears in the Device Manager 'Other devices' category (e.g., named 'WDM Book: WDM1 Example, free build'). The next chapter describes a Win32 user mode program that you can use to test that the driver is working.

In the Wdm1 code, the DriverEntry routine has been called along with various other Plug and Play callback routines, as described later.

Installation Details

You may be interested to know precisely what happens as a result of installing the Wdm1 driver and one Wdm1 device.

INF Files

Windows 98

Windows 98 copies the INF file to the Windows INFOTHER directory. The INF file is renamed, after the manufacturer name, to 'WDM BookWDM1.INF'.

Windows 98 remembers that the INF file has been installed in the registry. The HKLM SoftwareMicrosoftWindowsCurrentVersionSetupSetupXINFOFM Name key has a value C:W98INFOTHERWDM BookWDM1.INF set to 'WDM BookWDM1.INF'. This entry is not deleted if you remove the Wdm1 device.

Windows 98 also keeps a note of the most recently used install locations in the registry.

Добавить отзыв
ВСЕ ОТЗЫВЫ О КНИГЕ В ИЗБРАННОЕ

0

Вы можете отметить интересные вам фрагменты текста, которые будут доступны по уникальной ссылке в адресной строке браузера.

Отметить Добавить цитату