enumdevicedrivers (psapi)
Last changed: -161.69.67.20

.
Summary
Retrieves the load address for each device driver in the system.

C# Signature:

[DllImport("psapi")]
private static extern bool EnumDeviceDrivers(
    [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.U4)] [In][Out] UInt32[] ddAddresses,
    UInt32 arraySizeBytes,
    [MarshalAs(UnmanagedType.U4)] out UInt32 bytesNeeded
);

VB Signature:

Declare Function EnumDeviceDrivers Lib "psapi.dll" (TODO) As TODO

User-Defined Types:

None.

Alternative Managed API:

The signature above only works on 32-bit machines. Here's a stab at something that works on x86 as well as x864.

[DllImport("psapi")]
private static extern bool EnumDeviceDrivers(
    [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.FunctionPtr)] [In][Out] UIntPtr[] ddAddresses,
    UInt32 arraySizeBytes,
    [MarshalAs(UnmanagedType.U4)] out UInt32 bytesNeeded
    );

Notes:

Remember, this ONLY enumerates device drivers that are currently loaded. If a plug-n-play device is not inserted, its driver probably won't be enumerated by EnumDeviceDrivers. With the 'load addresses' returned by this function, you can get the drivers' base names using the GetDeviceDriverBaseName function.

Tips & Tricks:

Please add some!

Sample Code:

using System;
using System.Runtime.InteropServices;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace EnumDriversTest
{
    class Program {
        [DllImport("psapi")]
        private static extern bool EnumDeviceDrivers(
            [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.U4)] [In][Out] UInt32[] ddAddresses,
            UInt32 arraySizeBytes,
            [MarshalAs(UnmanagedType.U4)] out UInt32 bytesNeeded
        );

        [DllImport("psapi")]
        private static extern int GetDeviceDriverBaseName(
            UInt32 ddAddress,
            StringBuilder ddBaseName,
            int baseNameStringSizeChars
        );

        static void Main(string[] args) {
            UInt32 arraySize;
            UInt32 arraySizeBytes;
            UInt32[] ddAddresses;
            UInt32 bytesNeeded;
            bool success;

            // Figure out how large an array we need to hold the device driver 'load addresses'
            success = EnumDeviceDrivers(null, 0, out bytesNeeded);

            Console.WriteLine("Success? " + success);
            Console.WriteLine("Array bytes needed? " + bytesNeeded);

            if (!success) {
                Console.WriteLine("Call to EnumDeviceDrivers failed!  To get extended error information, call GetLastError.");
                return;
            }
            if (bytesNeeded == 0) {
                Console.WriteLine("Apparently, there were NO device drivers to enumerate.  Strange.");
                return;
            }

            // Allocate the array; as each ID is a 4-byte int, it should be 1/4th the size of bytesNeeded
            arraySize = bytesNeeded / 4;
            arraySizeBytes = bytesNeeded;
            ddAddresses = new UInt32[arraySize];

            // Now fill it
            success = EnumDeviceDrivers(ddAddresses, arraySizeBytes, out bytesNeeded);

            if (!success) {
                Console.WriteLine("Call to EnumDeviceDrivers failed!  To get extended error information, call GetLastError.");
                return;
            }

            for (int i=0; i < arraySize; i++) {
                // If the length of the device driver base name is over 1000 characters, good luck to it.  :-)
                StringBuilder sb = new StringBuilder(1000);

                int result = GetDeviceDriverBaseName(ddAddresses[i], sb, sb.Capacity);

                Console.WriteLine("Device driver LoadAddress: " + ddAddresses[i] + ", BaseName: " + sb.ToString());
            }
        }
    }
}

Documentation