Skip to content

Commit

Permalink
Merge pull request #11 from ng75063/Add-Find-Command
Browse files Browse the repository at this point in the history
Add find command
  • Loading branch information
nefarius authored Jun 13, 2023
2 parents 5231517 + 980a84b commit 2c8a2cf
Show file tree
Hide file tree
Showing 3 changed files with 181 additions and 1 deletion.
160 changes: 160 additions & 0 deletions src/Devcon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
// STL
//
#include <vector>
#include <iomanip>


//
// Logging
Expand Down Expand Up @@ -1135,6 +1137,164 @@ bool devcon::inf_default_uninstall(const std::wstring& fullInfPath, bool* reboot
return errCode == ERROR_SUCCESS;
}

bool devcon::find_hwid(const std::wstring& matchstring)
{
el::Logger* logger = el::Loggers::getLogger("default");
bool found = FALSE;
DWORD devIndex, err, total = 0;
HDEVINFO hDevInfo;
SP_DEVINFO_DATA spDevInfoData;

DWORD DataT;
LPTSTR buffer = nullptr;
DWORD buffersize = 0;

hDevInfo = SetupDiGetClassDevs(
nullptr,
nullptr,
nullptr,
DIGCF_ALLCLASSES | DIGCF_PRESENT
);
if (hDevInfo == INVALID_HANDLE_VALUE)
{
return found;
}

spDevInfoData.cbSize = sizeof(spDevInfoData);
for (devIndex = 0; SetupDiEnumDeviceInfo(hDevInfo, devIndex, &spDevInfoData); devIndex++) {
// get all devices info
while (!SetupDiGetDeviceRegistryProperty(hDevInfo,
&spDevInfoData,
SPDRP_HARDWAREID,
&DataT,
(PBYTE)buffer,
buffersize,
&buffersize))
{
if (GetLastError() == ERROR_INVALID_DATA)
{
break;
}
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
{
if (buffer)
LocalFree(buffer);
buffer = static_cast<wchar_t*>(LocalAlloc(LPTR, buffersize));
}
else
{
goto cleanup_DeviceInfo;
}
}
if (GetLastError() == ERROR_INVALID_DATA)
continue;

std::vector<std::wstring> arraybuf;
const TCHAR* p = buffer;
while (*p)
{
arraybuf.push_back(p);
p += _tcslen(p) + 1;
}
bool found_match = FALSE;
for (int i = 0; i < arraybuf.size(); i++) {
if (arraybuf[i].find(matchstring) != std::wstring::npos) {
found_match = TRUE;
break;
}
}
// If we have a match, print out the whole array
if (found_match) {
found = TRUE;
total++;
logger->verbose(1, "Hardware IDs: ");
for (int i = 0; i < arraybuf.size(); i++) {
logger->verbose(1, "%v", arraybuf[i]);
}
while (!SetupDiGetDeviceRegistryProperty(hDevInfo,
&spDevInfoData,
SPDRP_DEVICEDESC,
&DataT,
(PBYTE)buffer,
buffersize,
&buffersize))
{
if (GetLastError() == ERROR_INVALID_DATA)
{
break;
}
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
{
if (buffer)
LocalFree(buffer);
buffer = static_cast<wchar_t*>(LocalAlloc(LPTR, buffersize));
}
else
{
goto cleanup_DeviceInfo;
}
}
if (GetLastError() == ERROR_INVALID_DATA)
{
// Lets try SPDRP_DEVICEDESC
while (!SetupDiGetDeviceRegistryProperty(hDevInfo,
&spDevInfoData,
SPDRP_FRIENDLYNAME,
&DataT,
(PBYTE)buffer,
buffersize,
&buffersize))
{
if (GetLastError() == ERROR_INVALID_DATA)
{
break;
}
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
{
if (buffer)
LocalFree(buffer);
buffer = static_cast<wchar_t*>(LocalAlloc(LPTR, buffersize));
}
else
{
goto cleanup_DeviceInfo;
}
}
if (GetLastError() != ERROR_INVALID_DATA)
{
logger->verbose(1, "Name: %v", std::wstring(buffer));
}
}
else
{
logger->verbose(1, "Name: %v", std::wstring(buffer));
}
// Build a list of driver info items that we will retrieve below
if (!SetupDiBuildDriverInfoList(hDevInfo, &spDevInfoData, SPDIT_COMPATDRIVER))
goto cleanup_DeviceInfo;

// Get the first info item for this driver
SP_DRVINFO_DATA drvInfo;
drvInfo.cbSize = sizeof(SP_DRVINFO_DATA);
if (!SetupDiEnumDriverInfo(hDevInfo, &spDevInfoData, SPDIT_COMPATDRIVER, 0, &drvInfo))
goto cleanup_DeviceInfo; // Still fails with "no more items"

logger->verbose(1, "Version: %v.%v.%v.%v", std::to_wstring((drvInfo.DriverVersion >> 48) & 0xFFFF),
std::to_wstring((drvInfo.DriverVersion >> 32) & 0xFFFF),
std::to_wstring((drvInfo.DriverVersion >> 16) & 0xFFFF),
std::to_wstring(drvInfo.DriverVersion & 0x0000FFFF));
}
}

cleanup_DeviceInfo:
err = GetLastError();
SetupDiDestroyDeviceInfoList(hDevInfo);
SetLastError(err);
logger->verbose(1, "Total Found:: %v", std::to_wstring(total));
return found;
}


//
// Hooks MessageBoxW which is called if an error occurred, even when instructed to suppress any UI interaction
//
Expand Down
2 changes: 2 additions & 0 deletions src/Devcon.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,6 @@ namespace devcon
bool inf_default_install(const std::wstring& fullInfPath, bool* rebootRequired);

bool inf_default_uninstall(const std::wstring& fullInfPath, bool* rebootRequired);

bool find_hwid(const std::wstring& matchstring);
};
20 changes: 19 additions & 1 deletion src/NefConUtil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -730,6 +730,22 @@ int main(int argc, char* argv[])
return EXIT_SUCCESS;
}

if (cmdl[{ "--find-hwid" }])
{
hwId = cmdl({ "--hardware-id" }).str();

if (hwId.empty()) {
logger->error("Hardware ID missing");
std::cout << color(red) << "Hardware ID missing" << std::endl;
return EXIT_FAILURE;
}
if (!devcon::find_hwid(ConvertAnsiToWide(hwId)))
{
return ERROR_NOT_FOUND;
}
return EXIT_SUCCESS;
}

#pragma endregion

if (cmdl[{ "-v", "--version" }])
Expand Down Expand Up @@ -783,7 +799,9 @@ int main(int argc, char* argv[])
std::cout << " --inf-default-uninstall Uninstalls an INF file with a [DefaultUninstall] section" << std::endl;
std::cout << " --inf-path Absolute path to the INF file to uninstall (required)" << std::endl;
std::cout << " --delete-file-on-reboot Marks a given file to get deleted on next reboot" << std::endl;
std::cout << " --file-path The absolute path of the file to remove (required)" << std::endl;
std::cout << " --file-path The absolute path of the file to remove (required)" << std::endl;
std::cout << " --find-hwid Shows the devices matching the wildcard hwid" << std::endl;
std::cout << " ---hardware-id Hardware ID (or partial) of the device for matching (required)" << std::endl;
std::cout << " -v, --version Display version of this utility" << std::endl;
std::cout << std::endl;
std::cout << " logging:" << std::endl;
Expand Down

0 comments on commit 2c8a2cf

Please sign in to comment.