Hardware and Driver Initialization
The DriverEntry function in sndblst.sys calls SoundEnumSubkeys, which in turn calls the SoundCardInstanceData function in sndblst.sys (defined in \src\mmedia\sndblst\driver\init.c) for each card described in the registry. For each card, SoundCardInstanceInit is responsible for:
·Saving the registry path
·Allocating device-specific memory
·Finding the bus number and type
·Obtaining configuration parameters
·Creating device objects
·Acquiring hardware resources
·Updating configuration information in the registry.
Saving the Registry Path
When SoundCardInstanceInit is called, it receives a pointer to a registry path. This path is the full path to a key representing a hardware device, such as HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\DriverName\Parameters\DeviceNumber. The driver saves this path in device-specific storage for later use with soundlib.lib functions requiring a registry path as input.
Note: Drivers that do not support multiple hardware devices do not call SoundEnumSubkeys. Instead, they call SoundSaveRegistryPath to store the registry path for later use with soundlib.lib functions requiring a registry path as input.
Allocating Device-Specific Memory
Waveform output and MIDI input drivers use interrupts and therefore provide interrupt service routines (ISRs) and deferred procedure calls (DPCs), as discussed in the Kernel-Mode Drivers Design Guide. All data that these routines access must be nonpaged. The driver allocates card-specific memory from nonpaged pool in a GLOBAL_DEVICE_INFO structure and adds the structure to a linked list.
Finding the Bus Number and Type
Calls to SoundGetBusNumber are used to determine which buses exist. Code in SoundCardInstanceData checks for ISA, EISA, and Microchannel buses, in that order. The code assumes that the Sound Blaster card is connected to the first of these buses that it finds.
This code can be modified to provide a more sophisticated bus search.
Different buses do not require different kernel-mode drivers. The Windows NT Hardware Abstraction Layer (HAL) insulates the kernel-mode driver from the bus.
Obtaining Configuration Parameters
Another task of SoundCardInstanceInit is copying device configuration information from the registry into the device's GLOBAL_DEVICE_INFO structure. Calling RtlQueryRegistryValues is an easy way to read registry values. The registry path to the card's subkeys are passed to SoundCardInstanceInit by SoundEnumSubKeys.
For the Sound Blaster card, configuration information stored in the registry includes the card I/O address, interrupt number, and DMA channel number. Usually, configuration values stored in the registry are values that can be set on the card. They can also be read-only values. Values that can be referenced only indirectly, such as those on the Sound Blaster Pro Card that can only be accessed through a device interrupt, can also be stored in the registry.
Creating Device Objects
SoundCreateDevice is used to create a new sound device object. SoundSaveDeviceName stores the device name under the registry path HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\DriverName\Parameters\DeviceNumber\Devices. Code in drvlib.lib finds the name there when the user-mode driver opens the device. The \Devices subkey is volatile and thus isn't written to disk.
Acquiring Hardware Resources
Before a kernel-mode driver can use hardware resources, such as DMA channels, I/O ports, and interrupts, the resources must be acquired for use. The SoundReportResourceUsage function determines if specified resources are already assigned to another piece of hardware and, if they are not, assigns them to the caller.
Updating Configuration Information in the Registry
The SoundWriteRegistryDWORD function is called if it is necessary to update hardware configuration information stored in the registry.