Пример #1
0
        public static void ChangeDeviceEnabledState(
            DeviceInfoListHandle deviceInfoList, ref SP_DEVINFO_DATA deviceInfoData,
            DiClassInstallState state, DiClassInstallScope scope,
            DiClassInstallFunction installFunction
            )
        {
            var pcp = new SP_PROPCHANGE_PARAMS();

            pcp.Header.cbSize          = (uint)Marshal.SizeOf(pcp.Header.GetType());
            pcp.Header.InstallFunction = installFunction;
            pcp.StateChange            = state;
            pcp.Scope     = scope;
            pcp.HwProfile = 0;

            SetupDiSetClassInstallParams(deviceInfoList, ref deviceInfoData, pcp);

            if (!SetupDiCallClassInstaller(
                    installFunction, deviceInfoList.DangerousGetHandle(), ref deviceInfoData
                    ))
            {
                var error = Marshal.GetLastWin32Error();
                if (error != 0)
                {
                    throw new Win32Exception(error);
                }
                else
                {
                    throw new Exception("Failed to change device enabled state");
                }
            }
        }
Пример #2
0
        public static unsafe void SetupDiSetClassInstallParams <TParams>
            (DeviceInfoListHandle deviceList, ref SP_DEVINFO_DATA deviceInfoData, TParams parms)
            where TParams : class
        {
            var pinned = GCHandle.Alloc(parms, GCHandleType.Pinned);

            try {
                if (!_SetupDiSetClassInstallParams(
                        deviceList.DangerousGetHandle(), ref deviceInfoData,
                        pinned.AddrOfPinnedObject(), (UInt32)Marshal.SizeOf(parms)
                        ))
                {
                    var error = Marshal.GetLastWin32Error();
                    if (error != 0)
                    {
                        throw new Win32Exception(error);
                    }
                }
            } finally {
                pinned.Free();
            }
        }
Пример #3
0
        public static unsafe void EnumerateDevices <TContext> (
            string machine, DiGetClassFlags flags,
            string[] deviceClassNames, EnumerateDevicesFunc <TContext> callback,
            TContext context
            ) where TContext : class
        {
            DeviceInfoListHandle devs = null;
            var devInfo           = new SP_DEVINFO_DATA();
            var devInfoListDetail = new SP_DEVINFO_LIST_DETAIL_DATA();

            Guid[] deviceClassGuids;

            try {
                int numClasses = 0;

                if (deviceClassNames != null)
                {
                    deviceClassGuids = new Guid[deviceClassNames.Length];

                    foreach (var className in deviceClassNames)
                    {
                        UInt32 numResults;

                        if (
                            !SetupDiClassGuidsFromNameEx(
                                className, out deviceClassGuids[numClasses],
                                1, out numResults,
                                machine, IntPtr.Zero
                                ) && (Marshal.GetLastWin32Error() != ERROR_INSUFFICIENT_BUFFER)
                            )
                        {
                            throw new Exception("Unable to resolve class name '" + className + "'");
                        }

                        numClasses += 1;
                    }

                    var newClassGuids = new Guid[numClasses];
                    Array.Copy(deviceClassGuids, newClassGuids, numClasses);
                    deviceClassGuids = newClassGuids;
                }
                else
                {
                    deviceClassGuids = new Guid[0];
                }

                if (deviceClassGuids.Length > 0)
                {
                    for (int i = 0; i < deviceClassGuids.Length; i++)
                    {
                        fixed(Guid *pGuid = &(deviceClassGuids[i]))
                        {
                            var existingPtr = IntPtr.Zero;

                            if (devs != null)
                            {
                                existingPtr = devs.DangerousGetHandle();
                            }

                            var result = SetupDiGetClassDevsEx(
                                new IntPtr(pGuid), null, IntPtr.Zero, flags,
                                existingPtr, machine, IntPtr.Zero
                                );

                            var lastError = Marshal.GetLastWin32Error();

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

                            if (devs == null)
                            {
                                devs = new DeviceInfoListHandle(result, true);
                            }
                        }
                    }
                }
                else
                {
                    devs = new DeviceInfoListHandle(
                        SetupDiGetClassDevsEx(
                            IntPtr.Zero, null, IntPtr.Zero,
                            flags | DiGetClassFlags.DIGCF_ALLCLASSES,
                            IntPtr.Zero, machine, IntPtr.Zero
                            ), true
                        );

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

                if (devs.IsInvalid)
                {
                    throw new Exception("Failed to create device info list");
                }

                devInfoListDetail.cbSize = (UInt32)Marshal.SizeOf(devInfoListDetail.GetType());
                if (!SetupDiGetDeviceInfoListDetail(devs.DangerousGetHandle(), ref devInfoListDetail))
                {
                    var lastError = Marshal.GetLastWin32Error();
                    if (lastError != 0)
                    {
                        throw new Win32Exception(lastError);
                    }

                    return;
                }

                devInfo.cbSize = (UInt32)Marshal.SizeOf(devInfo.GetType());
                for (UInt32 devIndex = 0; SetupDiEnumDeviceInfo(devs.DangerousGetHandle(), devIndex, ref devInfo); devIndex++)
                {
                    callback(devs, ref devInfo, GetDeviceId(ref devInfo), context);
                }

                {
                    var lastError = Marshal.GetLastWin32Error();
                    if ((lastError != 0) && (lastError != ERROR_NO_MORE_ITEMS))
                    {
                        throw new Win32Exception(lastError);
                    }
                }
            } finally {
                if (devs != null && !devs.IsClosed)
                {
                    devs.Close();
                }
            }
        }
Пример #4
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 {
            }
        }