I'd just like to say Merry Christmas...and...setupapi.h

Merry Christmas and man are microsoft some real jerks....

I'm playing around in the setupapi.h .... they sure don't make life easy that's for sure. You can usually tell where they don't want newbs playing around bc of how ungodly difficult to deal with some of these lower level libraries are. That and the documentation gets more vague and the examples point you in the right general direction but many times they contain variables that they don't show where they are declared, what type they are or where some of the necessary values come from.

Figured i'd share this bc of what a pita it has been.

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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194

#include <Windows.h>
#include <iostream>
#include <vector>
#include <Setupapi.h>
#pragma comment(lib, "setupapi.lib")
using namespace std;

HANDLE GetDeviceInfoSet() {
 
  HANDLE DeviceInfoSet = SetupDiGetClassDevs(NULL, NULL, NULL, DIGCF_ALLCLASSES | DIGCF_PRESENT);

    if (DeviceInfoSet == INVALID_HANDLE_VALUE) {
        cout << "invalid handle";
    }

    return DeviceInfoSet;
}

vector<SP_DEVINFO_DATA> GetDeviceInfoData(HANDLE DeviceInfoSet) {
    SP_DEVINFO_DATA DeviceInfoData;

    ZeroMemory(&DeviceInfoData, sizeof(SP_DEVINFO_DATA));
    DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
    size_t DeviceIndex = 0;

    vector<SP_DEVINFO_DATA> v_Device_Info_Data{};

    while (SetupDiEnumDeviceInfo(DeviceInfoSet, DeviceIndex, &DeviceInfoData)) {
        v_Device_Info_Data.push_back(DeviceInfoData);
        DeviceIndex++;
    }
    return v_Device_Info_Data;

}

vector<vector<DEVPROPKEY>> GetDevicePropertyKeys(HANDLE DeviceInfoSet, vector<SP_DEVINFO_DATA> v_Device_Info_Data) {

    vector<vector<DEVPROPKEY>> v_key{};

    for (int x = 0; x < v_Device_Info_Data.size(); x++) {
        vector<DEVPROPKEY> k{};
        DWORD size = 0;

        SetupDiGetDevicePropertyKeys(DeviceInfoSet, &v_Device_Info_Data[x], NULL, 0, &size, 0);

        BYTE* lp = new BYTE[size * sizeof(DEVPROPKEY)];
        DEVPROPKEY* key = (DEVPROPKEY*)lp;

        SetupDiGetDevicePropertyKeys(DeviceInfoSet, &v_Device_Info_Data[x], key, size, &size, 0);

        for (int y = 0; y < size; y++) {
            k.push_back(key[y]);
        }

        v_key.push_back(k);
        delete[] lp;

    }
    return v_key;

}

vector<string> GetDeviceInstanceIDs(HANDLE DeviceInfoSet, vector<SP_DEVINFO_DATA> v_Device_Info_Data) {
    vector<string> v_InstanceID{};
    for (int y = 0; y < v_Device_Info_Data.size(); y++) {
        DWORD size{};

        SetupDiGetDeviceInstanceIdW(DeviceInfoSet, &v_Device_Info_Data[y], NULL, NULL, &size);

        WCHAR* ID = new WCHAR[size];

        SetupDiGetDeviceInstanceIdW(DeviceInfoSet, &v_Device_Info_Data[y], ID, size, &size);
        string s{};
        for (int x = 0; x < size; x++) {
            s.push_back(ID[x]);
        }

        v_InstanceID.push_back(s);

        delete[] ID;

    }
    return v_InstanceID;

}

vector<string> GetDeviceLocation(HANDLE DeviceInfoSet, vector<SP_DEVINFO_DATA> v_Device_Info_Data) {  //SetupDiGetDeviceRegistryProperty example  <~~~~~~~~~~~~~~~~~

    vector<string> v_Device_Location{};

    for (int x = 0; x < v_Device_Info_Data.size(); x++) {
        DWORD size{};

        SetupDiGetDeviceRegistryPropertyA(DeviceInfoSet, &v_Device_Info_Data[x], SPDRP_LOCATION_PATHS, NULL, NULL, NULL, &size);

        char* pb = new char[size];
        SetupDiGetDeviceRegistryPropertyA(DeviceInfoSet, &v_Device_Info_Data[x], SPDRP_LOCATION_PATHS, NULL, (PBYTE)pb, size, &size);

        string s{};

        for (int y = 0; y < size; y++) {
            s.push_back(pb[y]);
        }

        v_Device_Location.push_back(s);

        delete[] pb;

    }

    return v_Device_Location;
}

vector<vector<BYTE>> GetDeviceRegistryProperty(HANDLE DeviceInfoSet, vector<SP_DEVINFO_DATA> v_Device_Info_Data, DWORD Property) {

    vector<vector<BYTE>> v_Registry_Property{};

    for (int x = 0; x < v_Device_Info_Data.size(); x++) {
        DWORD size{};

        SetupDiGetDeviceRegistryPropertyA(DeviceInfoSet, &v_Device_Info_Data[x], Property, NULL, NULL, NULL, &size);

        BYTE* pb = new BYTE[size];

        SetupDiGetDeviceRegistryPropertyA(DeviceInfoSet, &v_Device_Info_Data[x], Property, NULL, pb, size, &size);

        vector<BYTE> v_Byte{};

        for (int y = 0; y < size; y++) {
            v_Byte.push_back(pb[y]);
        }

        v_Registry_Property.push_back(v_Byte);

        delete[] pb;
    }
    return v_Registry_Property;
}

vector<SP_DRVINFO_DATA> GetDeviceDriverInfoData(HANDLE DeviceInfoSet, vector<SP_DEVINFO_DATA> v_Device_Info_Data) {

    vector<SP_DRVINFO_DATA> v_Driver_Info_Data{};

    SP_DRVINFO_DATA DriverInfoData{};

    if (!SetupDiBuildDriverInfoList(DeviceInfoSet, NULL, SPDIT_CLASSDRIVER)) {
        cout << "failed to build list\n";
    }
        
    for (int x = 0; x < v_Device_Info_Data.size(); x++) {

        ZeroMemory(&DriverInfoData, sizeof(SP_DRVINFO_DATA));
        DriverInfoData.cbSize = sizeof(SP_DRVINFO_DATA);

        if (!SetupDiEnumDriverInfoW(DeviceInfoSet, NULL, SPDIT_CLASSDRIVER, x, &DriverInfoData)) {
            cout << "failed";
        }
        auto error = GetLastError();
        v_Driver_Info_Data.push_back(DriverInfoData);

    }

    return v_Driver_Info_Data;

}

vector<SP_DRVINFO_DETAIL_DATA> GetDeviceDriverDetail(HANDLE DeviceInfoSet, vector<SP_DRVINFO_DATA> v_Driver_Info_Data) {
    vector<SP_DRVINFO_DETAIL_DATA> v_Driver_Info_Detail_Data{};

    for (int x = 0; x < v_Driver_Info_Data.size(); x++) {

        DWORD size{};

        SetupDiGetDriverInfoDetailW(DeviceInfoSet, NULL, &v_Driver_Info_Data[x], NULL, 0, &size);

        void* lp = malloc(size);

        PSP_DRVINFO_DETAIL_DATA DriverInfoDetailData = (PSP_DRVINFO_DETAIL_DATA)lp;

        ZeroMemory(DriverInfoDetailData, size);

        DriverInfoDetailData->cbSize = sizeof(SP_DRVINFO_DETAIL_DATA);

        SetupDiGetDriverInfoDetailW(DeviceInfoSet, NULL, &v_Driver_Info_Data[x], DriverInfoDetailData, size, &size);

        v_Driver_Info_Detail_Data.push_back(*DriverInfoDetailData);

        VirtualFree(lp, size, MEM_RELEASE);
        delete lp;
    }
    return v_Driver_Info_Detail_Data;

}

I'd also like to point out a weird problem that i'm having which is kinda an example of the bs that i was describing above....

So I am actually attempting to suck out Class Interface GUID's and it isn't very clear where they come from so i'm trying a variety of things to see if i just stumble upon them. So I saw that that can get a "list" of the guid's that belong to a class by the class name....

So I extract the class names via the SetupDiGetClassNameFromGuid function...(I KNOW!!)

So so so ... Then I notice that i'm getting duplicate class names so i filter out the duplicates and end up with a unique list of class names. I wrote a utility function that converts a vector of strings to a vector of wstrings... so that I can easily utilize PWSTR variable requirements in the SetupGetClassGuidsFromName()...

The description of the function says that since the names arent unique that it should return mulitple guid's per name (hence the duplicate names from above...). I'm finding that for whatever reason that it doesn't do that.....I'm only getting one guid per name. I swear sometimes i'm in crazy town. I very well could be doing something wrong but the function is being called sucessfully;

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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88

vector<string> GetDeviceClassNames(HANDLE DeviceInfoSet, vector<SP_DEVINFO_DATA> v_Device_Info_Data) {
    vector<string> v_Class_Names{};

    for (int y = 0; y < v_Device_Info_Data.size(); y++) {

        DWORD size{};

        SetupDiClassNameFromGuidA(&v_Device_Info_Data[y].ClassGuid, NULL, NULL, &size);

        char* ClassName = new char[size];

        SetupDiClassNameFromGuidA(&v_Device_Info_Data[y].ClassGuid, ClassName, size, &size);

        string s{};

        for (int x = 0; x < size; x++) {
            s.push_back(ClassName[x]);
        }

        bool a = true;

        for (int i = 0; i < v_Class_Names.size(); i++) {

            if (s == v_Class_Names[i]) {
                a = false;
            }
        }
        if (a) {
            v_Class_Names.push_back(s);
        }

        delete[] ClassName;
    }
    return v_Class_Names;
}

vector<wstring> ClassNamesTo_ClassNames_W(vector<string> v_Class_Names) {
    vector<wstring> v_Class_Names_W{};

    for (int x = 0; x < v_Class_Names.size(); x++) {
        wstring wstr{};

        for (int i = 0; i < v_Class_Names[x].size(); i++) {
         wstr.push_back(v_Class_Names[x][i]);
        }
        v_Class_Names_W.push_back(wstr);

    }
    return v_Class_Names_W;
}


int main() {

    HANDLE DeviceInfoSet = GetDeviceInfoSet();

    vector<SP_DEVINFO_DATA> v_Device_Info_Data = GetDeviceInfoData(DeviceInfoSet);

    //vector<vector<DEVPROPKEY>> v_key=GetDevicePropertyKeys(DeviceInfoSet,v_Device_Info_Data);

    //vector<SP_DRVINFO_DATA> v_Driver_Info_Data = GetDeviceDriverInfoData(DeviceInfoSet, v_Device_Info_Data);

    vector<vector<GUID>> v_Class_Guids{};

    vector<wstring> v_Class_Names_W = ClassNamesTo_ClassNames_W(GetDeviceClassNames(DeviceInfoSet, v_Device_Info_Data));

    for (int x = 0; x < v_Class_Names_W.size(); x++) {

        DWORD size{};

        SetupDiClassGuidsFromName(&v_Class_Names_W[x][0], nullptr, NULL, &size);

        GUID* guid = new GUID[size];

        if (!SetupDiClassGuidsFromName(&v_Class_Names_W[x][0], guid, size, &size)) { cout << "failed"; }

        vector<GUID> g{};

        for (int y = 0; y < size; y++) {
            g.push_back(guid[y]);
        }
        v_Class_Guids.push_back(g);

        delete[] guid;

    }
> I am actually attempting to suck out Class Interface GUID's and it isn't very clear where they come from

AFAIK, for standard device classes, they are pre-defined. Microsoft has provided a list:
https://docs.microsoft.com/en-us/windows-hardware/drivers/install/system-defined-device-setup-classes-available-to-vendors

For non-standard devices, it can be picked up from the .inf file in [Version] ... ClassGuid = ...
SP_DRVINFO_DETAIL_DATA should have the fully qualified name of the .inf file

Caveat: AFAIK. My knowledge it is nowhere near current.
I did actually figure that out. Its just so ridiculous how this is all setup. I realize what I have posted is a little sloppy, just trying to pump out as much as quickly as possible and go back later and reorganize.

Thats parts of what has been so frustrating with this is that I did manage to get alot of things working. Just everything revolving around the interfaces has been a nightmare up until this point.

What im trying to do is talk directly with the port that my keyboard and mouse are connected to with the intent of mimicking physical device inputs. Im just kinda trying to get as much data easily accessible b4 I really start getting into making connections, sending packets etc. Just bc im not exactly sure what im going to need when I get to that point.

Again nothing nefarious just for my own use.

Actually I'm thinking with the right information I can just register my application as a new instance of a device and just have my own access? Not sure if either scenario is possible but I guess I'll find out soon enough.
Last edited on
Topic archived. No new replies allowed.