1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
#[cfg(not(target_os = "windows"))]
pub fn is_missing() -> bool {
    false
}

#[cfg(target_os = "windows")]
pub fn is_missing() -> bool {
    use std::{
        ffi::OsStr,
        iter::once,
        mem::size_of,
        os::windows::ffi::OsStrExt,
        ptr::{null, null_mut},
    };

    use winapi::um::setupapi::*;

    let flags = DIGCF_ALLCLASSES;
    let wide: Vec<u16> = OsStr::new("USB").encode_wide().chain(once(0)).collect();

    let dev_info = unsafe { SetupDiGetClassDevsW(null(), wide.as_ptr(), null_mut(), flags) };

    let mut dev_info_data = SP_DEVINFO_DATA {
        cbSize: size_of::<SP_DEVINFO_DATA>() as u32,
        ..Default::default()
    };

    let mut i = 0;
    while unsafe { SetupDiEnumDeviceInfo(dev_info, i, &mut dev_info_data) } > 0 {
        if unsafe { SetupDiBuildDriverInfoList(dev_info, &mut dev_info_data, SPDIT_COMPATDRIVER) }
            > 0
        {
            let mut j = 0;
            loop {
                let mut drv_info_data = SP_DRVINFO_DATA_V2_W {
                    cbSize: std::mem::size_of::<SP_DRVINFO_DATA_V2_W>() as u32,
                    ..Default::default()
                };

                if unsafe {
                    SetupDiEnumDriverInfoW(
                        dev_info,
                        &mut dev_info_data,
                        SPDIT_COMPATDRIVER,
                        j,
                        &mut drv_info_data,
                    )
                } == 0
                {
                    break;
                }

                let mfg = drv_info_data.MfgName;
                if String::from_utf16_lossy(&mfg)
                    .trim_matches(char::from(0))
                    .contains("Pico Technology Ltd")
                {
                    return false;
                }

                j += 1;
            }
        }

        i += 1;
    }

    true
}