-
Notifications
You must be signed in to change notification settings - Fork 1
/
DevicesHandler.cpp
executable file
·138 lines (108 loc) · 4.3 KB
/
DevicesHandler.cpp
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
#include "DevicesHandler.h"
#include "WinUtils.h"
#include <iostream>
#include <windows.h>
#include <initguid.h>
#include <devguid.h>
#include <cfgmgr32.h>
#include <setupapi.h>
DevicesHandler::DevicesHandler()
{
handle = SetupDiGetClassDevs(&GUID_DEVCLASS_NET, nullptr, nullptr, DIGCF_PRESENT);
if (handle == INVALID_HANDLE_VALUE) {
std::cout << "DevicesHandler::DevicesHandler(): SetupDiGetClassDevs() failed with error: " << GetLastError() << std::endl;
}
}
DevicesHandler::~DevicesHandler()
{
if (handle == INVALID_HANDLE_VALUE) {
return;
}
if (!SetupDiDestroyDeviceInfoList(handle)) {
std::cout << "DevicesHandler::~DevicesHandler(): SetupDiDestroyDeviceInfoList() failed with error: " << GetLastError() << std::endl;
}
}
bool DevicesHandler::enumerateNics()
{
if (handle == INVALID_HANDLE_VALUE) {
return false;
}
SP_DEVINFO_DATA deviceInfoData;
deviceInfoData.cbSize = sizeof(deviceInfoData);
for (DWORD i = 0; SetupDiEnumDeviceInfo(handle, i, &deviceInfoData); ++i) {
DWORD requiredSize;
if (!SetupDiGetDeviceRegistryProperty(handle, &deviceInfoData, SPDRP_FRIENDLYNAME, nullptr, nullptr, 0, &requiredSize)) {
const DWORD err = GetLastError();
if (err != ERROR_INSUFFICIENT_BUFFER) {
std::cout << "DevicesHandler::enumerateNics(): SetupDiGetDeviceRegistryProperty() failed with error: " << err << std::endl;
return false;
}
}
std::wstring name(requiredSize, 0);
if (!SetupDiGetDeviceRegistryProperty(handle, &deviceInfoData, SPDRP_FRIENDLYNAME, nullptr, reinterpret_cast<PBYTE>(&name[0]), static_cast<DWORD>(name.size()), nullptr)) {
std::cout << "DevicesHandler::enumerateNics(): SetupDiGetDeviceRegistryProperty() failed with error: " << GetLastError() << std::endl;
return false;
}
std::cout << "Index: " << i << std::endl;
std::wcout << "Name: " << name << std::endl << std::endl;
}
const DWORD err = GetLastError();
if (err != ERROR_NO_MORE_ITEMS) {
std::cout << "DevicesHandler::enumerateNics(): SetupDiEnumDeviceInfo() failed with error: " << err << std::endl;
return false;
}
return true;
}
bool DevicesHandler::toggleNic(const unsigned long &index, const Action &action)
{
if (!WinUtils::isRunningAsAdmin()) {
std::cout << "DevicesHandler::toggleNic(): Administrator privileges are required in order to change a device's state.";
return false;
}
if (handle == INVALID_HANDLE_VALUE) {
return false;
}
SP_DEVINFO_DATA deviceInfoData;
deviceInfoData.cbSize = sizeof(deviceInfoData);
if (!SetupDiEnumDeviceInfo(handle, index, &deviceInfoData)) {
std::cout << "DevicesHandler::toggleNic(): SetupDiEnumDeviceInfo() failed with error: " << GetLastError() << std::endl;
return false;
}
SP_PROPCHANGE_PARAMS propChangeParams;
switch (action) {
case Disable:
propChangeParams.StateChange = DICS_DISABLE;
break;
case Enable:
propChangeParams.StateChange = DICS_ENABLE;
break;
case Toggle: {
ULONG status, problem;
const CONFIGRET ret = CM_Get_DevNode_Status(&status, &problem, deviceInfoData.DevInst, 0);
if (ret != CR_SUCCESS) {
std::cout << "DevicesHandler::toggleNic(): CM_Get_DevNode_Status() failed with error: " << ret << std::endl;
return false;
}
propChangeParams.StateChange = problem == CM_PROB_DISABLED ? DICS_ENABLE : DICS_DISABLE;
break;
}
default:
std::cout << "DevicesHandler::toggleNic(): Unrecognized action: " << action << std::endl;
return false;
}
propChangeParams.HwProfile = 0;
propChangeParams.Scope = DICS_FLAG_CONFIGSPECIFIC;
propChangeParams.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE;
propChangeParams.ClassInstallHeader.cbSize = sizeof(propChangeParams.ClassInstallHeader);
if (!SetupDiSetClassInstallParams(handle, &deviceInfoData, &propChangeParams.ClassInstallHeader, sizeof(propChangeParams))) {
std::cout << "DevicesHandler::toggleNic(): SetupDiSetClassInstallParams() failed with error: " << GetLastError() << std::endl;
return false;
}
if (!SetupDiCallClassInstaller(DIF_PROPERTYCHANGE, handle, &deviceInfoData)) {
std::cout << "DevicesHandler::toggleNic(): SetupDiCallClassInstaller() failed with error: " << GetLastError() << std::endl;
// Clear parameters, otherwise the device remains in an inconsistent state (e.g. with the enabled icon even if disabled).
SetupDiSetClassInstallParams(handle, &deviceInfoData, nullptr, 0);
return false;
}
return true;
}