.NET

A WDM IEEE 1394 Configuration ROM Decoder

Source Code Accompanies This Article. Download It Now.

Bill updates his DUMPROM utility by presenting a WDM version that runs on Windows 98 and Windows 2000. DUMPROM lets you examine the configuration ROM of any 1394 device.

Dec99: A WDM IEEE 1394 Configuration ROM Decoder

Bill is a senior software engineer at LSI Logic (formerly Symbios Logic). His current responsibilities include developing 1394 device drivers, software, and utilities. He can be contacted at http://www .geocities.com/SiliconValley/Haven/4824.

In the August, 1999, issue of DDJ, I wrote the article "An IEEE 1394 Configuration ROM Decoder." That article discussed how to read and decode the configuration ROM of 1394 peripherals on Windows 95 using the Texas Instruments TSBKPCI 1394 controller and the TI LynxSoft drivers. In this article, I'll present a new version of the DumpRom utility that runs on Windows 98 and Windows 2000. (The complete source code to this version of DumpRom is available electronically; see "Resource Center," page 5.)

On Windows 98 and Windows 2000, Microsoft's 1394 architecture is much more complicated than that of TI's LynxSoft on Windows 95. Microsoft's architecture is based on the Windows Driver Model (WDM) and is a multilayered design. The most important layer in this design is 1394BUS.SYS, which is also known as the 1394 bus class driver. 1394BUS.SYS is responsible for presenting a unified, low-level interface to 1394. Underneath 1394BUS.SYS are the 1394 port drivers. These drivers are responsible for communicating directly to the various 1394 controllers. The port drivers shipped with Windows 98 include:

These high-level drivers, in turn, connect with various other subsystems. For example, SONYDCAM.SYS registers with the streaming drivers as a source of video. SBP2.SYS, on the other hand, registers with the SCSI subsystem to provide a source of file storage; see Figure 1.

Windows 1394 API

As far as I know, Microsoft has not published a 1394 API for applications to use directly. Luckily, the Windows 98 DDK provides the source to an application/driver combination that can be used to test and debug 1394 devices. These files are named Win1394.EXE and 1394Diag.SYS. Win1394.EXE is a Win32 application that communicates with the driver. 1394Diag .SYS is a WDM driver that registers with the system as the handler of diagnostic 1394 peripherals. A diagnostic peripheral is one that is plugged into the system when the 1394 port driver is in diagnostic mode. This is a special mode of the port driver that allows you to circumvent the normal binding of a device to higher level drivers. The binding of the device is then rerouted to a custom driver that is used to test and debug the device. Using the DDK source as a base, I ported the source code from the previous article into the new DumpRom.EXE utility. DumpRom .EXE uses the WDM driver DumpRomD .SYS to communicate with diagnostic 1394 peripherals.

DumpRom Installation and Device Recognition

Along with the source code to the WDM version of DumpRom, I have included a setup program that will install the source and executables. To install DumpRom, unzip WDUMPROM.ZIP onto a floppy disk. Then run SETUP.EXE from the floppy. SETUP will copy the files onto your hard drive and create task bar links to the DumpRom utility and documents. The default installation directory is C:\98ddk\ src\1394\DumpRom\.

To install a diagnostic 1394 device, you must first launch DumpRom. From the task bar, select Start|Programs|Alexander|WDM Dump ROM|DumpRom. DumpRom will not automatically put the 1394 port driver into diagnostic mode. To do this, select 1394 Device|Find Device. The Find Device code puts the 1394 port driver into diagnostic mode. At this point, connecting a 1394 device will cause the bus class driver to detect a new diagnostic device and Windows will look for INF files that contain an entry for 1394\ 031887&040892 type devices. Windows will now prompt you for the location of the INF file. Inside of DumpRomD .INF, Windows will find the following entry under the Alexander manufacturer section:

[Alexander]

; Generic Diagnostic Device

%1394\031887&040892.DeviceDesc%=DumpRom,1394\031887&040892

This entry identifies DumpRomD.SYS as the handler of all 1394 diagnostic devices.

All diagnostic devices are listed in the Windows 98 and Windows 2000 registry under the key HKLM\SYSTEM\CurrentControlSet\Enum\1394\031887&040892. Under this key, each diagnostic peripheral will have a subkey that is the byte-wise reversal of the device's global unique ID (GUID) stripped of leading zeros. For instance, my LSI SYM13FW500 1394-to-ATA/ATAPI bridge has the GUID 0x00A0B80000005009. So the subkey in the registry is 950000000B8A000.

Next, Windows will locate the DumpRomD.SYS driver and copy it to the C:\Windows\System32\Drivers directory. DumpRomD.SYS is dynamically loadable and should now be servicing the device. If DumpRom cannot find the device, you'll need to bring up the Device Manager and try to delete and reinstall the device. If this does not work, try the Update Driver button and direct Windows to use DumpRomD.SYS.

Dumping and Decoding the Configuration ROM

Once the device has been found and DumpRomD.SYS has been loaded, you can now read the configuration ROM and display it by selecting 1394 Device|Dump Configuration ROM. As you can see in Listing One, the output is very much like that in the Windows 95 version of DumpRom.

Disconnecting the Device

After reading and decoding the configuration ROM, the only other option you have is to disconnect from the device. You can do this by selecting 1394 Device|Disconnect from Device. The disconnect code takes the 1394 port driver out of diagnostic mode and then prompts the user to physically disconnect the device from the 1394 bus. A word of caution here: A device will continue to look like a diagnostic device until the port driver is out of diagnostic mode and the device is disconnected from the bus. Just taking the port driver out of diagnostic mode is not good enough. Disconnecting the device forces the port driver to remove the device from its topology map. When the device is reconnected, it will be reenumerated as a normal device and will be bound to the driver that handles that device category.

How the New Code Works

Because this is a follow-up from a previous article, I will not discuss the decode algorithm. The issues that are of interest are as follows:

Placing the 1394 bus class driver into diagnostic mode.

Binding DumpRomD.SYS to a device.

Interfacing to DumpRomD.SYS.

Interfacing to 1394BUS.SYS.

Before any device can be recognized as a diagnostic device, you must first select 1394 Device|Find Device to place the 1394 port driver, 1394BUS.SYS, into diagnostic mode. When this menu item is selected, DumpRom calls the Find1394Device() routine. Find1394Device() is a fairly simple routine that will prompt users to disconnect the target 1394 device, place the bus into diagnostic mode, prompt users to reconnect the device, and then confirm that there is a diagnostic device attached.

To place the bus in diagnostic mode, Find1394Device() calls the DiagnoseAllAdapters() routine. Before discussing DiagnoseAllAdapters(), I must explain a little about 1394BUS.SYS. Because 1394BUS.SYS is a class driver, it can have multiple port drivers underneath it. As a result, the class driver actually looks like a collection of 1394 buses to the system and you must place each bus or port into diagnostic mode. Port is an unfortunate naming with 1394. In Windows, port means the 1394 port driver that is controlling a 1394 adapter. Do not confuse this with the physical 1394 ports on the adapter to which you connect peripherals. There are generally three physical ports on a 1394 adapter, but to Windows, all three of these physical ports are handled by only one port driver. To avoid confusion, I called my function DiagnoseAllAdapters() instead of DiagnoseAllPorts().

When DiagnoseAllAdapters() is called, it enters a loop that will open all 1394 buses and put them into diagnostic mode. To open the first 1394 bus, the loop uses the standard Win32 CreateFile() function with the symbolic device link name "\\\\.\\1394BUS0." For each iteration through the loop, this symbolic link name is incremented to open the next device. For example, the second 1394 bus has the name "\\\\.\\1394BUS1." Once a bus device is open, DiagoseAllAdapters() calls the Win32 DeviceIoControl() function with IO Control Code IOCTL_1394_TOGGLE_ ENUM_TEST_ON, which places the bus into diagnostic mode (see Listing Two).

You will notice that DiagnoseAllAdapters() is also used to leave diagnostic mode. The bMode parameter indicates whether to enter or leave diagnostic mode. A value of True means to enter diagnostic mode, and False leaves diagnostic mode. In the case of False, the IO Control Code passed to DeviceIoControl() is IOCTL_1394_TOGGLE_ENUM_TEST_OFF.

Once all 1394 buses are in diagnostic mode, any device plugged in at this point will appear as a diagnostic device. Initially, the system will not know about the new device because it has not been registered previously. The system will run the setup process that prompts users for the location of the INF and driver files and loads DumpRomD.SYS.

To confirm that there is a device bound to DumpRomD.SYS, Find1394Device() next calls the ConfirmDeviceAttached() routine. ConfirmDeviceAttached() opens device "\\\\.\\DUMPROMD" and issues a GET_NODE_INFO IOCTL, which retrieves a list of devices that are bound to DumpRomD.SYS. The device list is built by a routine called DumpRomDGetDeviceInfo(), which lists all of the devices on every 1394 bus associated with DumpRomD. On return from DumpRomD, ConfirmDeviceAttached() selects one device from the list and returns to Find1394Devices() (see Listing Three).

Once a device is found and selected, DumpRom calls DecodeConfigRom(), which reads the entire configuration ROM on the device one QUADLET at a time and places the image into a buffer. The old DumpRom program used a routine called ReadQuadlet() to read the configuration ROM image. This version of DumpRom employs the Win32 ReadFile() function with a buffer of four bytes to accomplish the same task. The ReadFile() call is translated to an IRP_MJ_READ IOCTL by the system, which then calls DumpRomDRead() inside of DumpRomD .SYS. In a nutshell (that is, excluding all of the IRP details), DumpRomDRead() builds an IRB (IO Request Block) structure with a function code of REQUEST_ ASYNC_READ and calls 1394BUS.SYS. 1394BUS transmits the 1394 QUADLET Read Request packet on the bus and receives a Read Response packet back from the device. The quadlet value is conveyed to DumpRomDRead(), which returns the value back to ReadConfigRom(); see Figure 2.

The last thing that DumpRom does is decode the configuration ROM, which is achieved via the DecodeConfigRom() function. The source to DecodeConfigRom() did not change significantly from the old version of DumpRom. You can find a detailed description of DecodeConfigRom() in my August 1999 article.

Conclusion

The WDM version of DumpRom is much more complicated than its Windows 95 predecessor. The overall functionality is the same, but the additional driver module, DumpRomD.SYS, greatly increased the development time of the code. Also, hooking the device driver into the system by placing the bus class driver into diagnostic mode added to this level of complexity. Complexity aside, once the driver is installed properly, DumpRom works quite well. It also serves as a convenient tool to debug your configuration ROM under Windows 98 and Windows 2000. Because DumpRom can be dynamically hooked and unhooked from the system, you can decode the configuration ROM of your device and then reconnect the device to continue normal operation without rebooting the system.

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task.
However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

Video

This month's Dr. Dobb's Journal

This month,
Dr. Dobb's Journal is devoted to mobile programming. We introduce you to Apple's new Swift programming language, discuss the perils of being the third-most-popular mobile platform, revisit SQLite on Android
, and much more!