Beispiel #1
0
        public static unsafe void EnumerateDeviceInterfaces <TContext> (
            DeviceInfoListHandle devs, ref SP_DEVINFO_DATA devInfo,
            ref Guid interfaceGuid, EnumerateDeviceInterfacesFunc <TContext> callback,
            TContext context
            ) where TContext : class
        {
            try {
                var deviceInterfaceData = new SP_DEVICE_INTERFACE_DATA();
                deviceInterfaceData.cbSize = (uint)Marshal.SizeOf(deviceInterfaceData.GetType());

                for (
                    UInt32 memberIndex = 0;
                    SetupDiEnumDeviceInterfaces(
                        devs.DangerousGetHandle(), ref devInfo,
                        ref interfaceGuid, memberIndex,
                        ref deviceInterfaceData
                        );
                    memberIndex++
                    )
                {
                    uint requiredSize;

                    // We can't use a struct for this because the CLR's interpretation of
                    //  alignment is different from Win32's on x64 :(
                    var buffer = new byte[1024 + 4];
                    fixed(byte *pBuffer = buffer)
                    {
                        // Account for differences in alignment strategy
                        if (Environment.Is64BitProcess)
                        {
                            *(UInt32 *)pBuffer = 8;
                        }
                        else
                        {
                            *(UInt32 *)pBuffer = (uint)(4 + Marshal.SystemDefaultCharSize);
                        }

                        SetupDiGetDeviceInterfaceDetail(
                            devs.DangerousGetHandle(), ref deviceInterfaceData,
                            new IntPtr(pBuffer), (UInt32)buffer.Length,
                            out requiredSize, ref devInfo
                            );
                        var lastError = Marshal.GetLastWin32Error();

                        if (lastError != 0)
                        {
                            throw new Win32Exception(lastError);
                        }

                        var devicePath = new String(
                            (char *)(pBuffer + 4)
                            );

                        callback(
                            devs, ref devInfo,
                            ref deviceInterfaceData, devicePath,
                            context
                            );
                    }
                }

                {
                    var lastError = Marshal.GetLastWin32Error();
                    if ((lastError != 0) && (lastError != ERROR_NO_MORE_ITEMS))
                    {
                        throw new Win32Exception(lastError);
                    }
                }
            } finally {
            }
        }