EnumPrinterDrivers (winspool)
Last changed: -87.175.208.64

.
Summary
The EnumPrinterDrivers function enumerates the printer drivers installed on a specified printer server

C# Signature:

[DllImport("winspool.drv", CharSet = CharSet.Auto, SetLastError = true)]
    static extern bool EnumPrinterDrivers(String pName, String pEnvironment, uint level, IntPtr pDriverInfo, uint cdBuf, ref uint pcbNeeded, ref uint pcRetruned);

VB Signature:

Declare Function EnumPrinterDrivers Lib "winspool.dll" (TODO) As TODO

User-Defined Types:

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]

    public struct DRIVER_INFO_2
    {
        public uint cVersion;
        [MarshalAs(UnmanagedType.LPTStr)]
        public string pName;
        [MarshalAs(UnmanagedType.LPTStr)]
        public string pEnvironment;
        [MarshalAs(UnmanagedType.LPTStr)]
        public string pDriverPath;
        [MarshalAs(UnmanagedType.LPTStr)]
        public string pDataFile;
        [MarshalAs(UnmanagedType.LPTStr)]
        public string pConfigFile;
    }

Alternative Managed API:

Do you know one? Please contribute it!

Notes:

None.

Tips & Tricks:

pName is the machine name. If null, it will target the local computer. If a remote machine is specified, it must be preceded by @"\\".

Sample Code:

private DRIVER_INFO_2[] GetInstalledPrinterDrivers()

    {
        /*
        'To determine the required buffer size,
        'call EnumPrinterDrivers with cbBuffer set
        'to zero. The call will fails specifying
        'ERROR_INSUFFICIENT_BUFFER and filling in
        'cbRequired with the required size, in bytes,
        'of the buffer required to hold the array
        'of structures and data.
*/

        uint cbNeeded = 0;
        uint cReturned = 0;
        if (EnumPrinterDrivers(null, null, 2, IntPtr.Zero, 0, ref cbNeeded, ref cReturned))
        {
        //succeeds, but shouldn't, because buffer is zero (too small)!
        throw new Exception("EnumPrinters should fail!");
        }

        int lastWin32Error = Marshal.GetLastWin32Error();
        //ERROR_INSUFFICIENT_BUFFER = 122 expected, if not -> Exception
        if (lastWin32Error != 122)
        {
        throw new Win32Exception(lastWin32Error);
        }

        IntPtr pAddr = Marshal.AllocHGlobal((int)cbNeeded);
        if (EnumPrinterDrivers(null, null, 2, pAddr, cbNeeded, ref cbNeeded, ref cReturned))
        {
        DRIVER_INFO_2[] printerInfo2 = new DRIVER_INFO_2[cReturned];
        int offset = pAddr.ToInt32();
        Type type = typeof(DRIVER_INFO_2);
        int increment = Marshal.SizeOf(type);
        for (int i = 0; i < cReturned; i++)
        {
            printerInfo2[i] = (DRIVER_INFO_2)Marshal.PtrToStructure(new IntPtr(offset), type);
            offset += increment;
        }
        Marshal.FreeHGlobal(pAddr);

        return printerInfo2;
        }

        throw new Win32Exception(Marshal.GetLastWin32Error());
    }

Documentation