【发布时间】:2015-09-25 11:05:10
【问题描述】:
有人可以提供一个示例 C 代码,列出我可以使用 Createfile() 打开的所有设备名称吗?我总是得到错误代码 3:路径不存在
不起作用的示例代码:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <windows.h>
#include <regstr.h>
#include <devioctl.h>
#include <usb.h>
#include <usbiodef.h>
#include <usbioctl.h>
#include <usbprint.h>
#include <setupapi.h>
#include <devguid.h>
#include <wdmguid.h>
#pragma comment(lib, "Setupapi.lib")
int main(void){
HDEVINFO deviceInfoList;
deviceInfoList = SetupDiGetClassDevs(NULL, NULL, NULL, DIGCF_ALLCLASSES | DIGCF_PRESENT);
if (deviceInfoList != INVALID_HANDLE_VALUE)
{
SP_DEVINFO_DATA deviceInfoData;
deviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
for (DWORD i = 0; SetupDiEnumDeviceInfo(deviceInfoList, i, &deviceInfoData); i++)
{
LPTSTR buffer = NULL;
DWORD buffersize = 0;
while (!SetupDiGetDeviceInstanceIdA(deviceInfoList, &deviceInfoData, buffer, buffersize, &buffersize))
{
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
{
if (buffer) delete buffer;
buffer = new TCHAR[buffersize];
}
else
{
printf("%ls\n", "error");
break;
}
}
HANDLE hFile = CreateFileA(buffer,
GENERIC_READ,
0,
NULL,
OPEN_EXISTING,
0,
NULL);
if (hFile == INVALID_HANDLE_VALUE) {
printf("InvalidHandle, error code: %d\n", GetLastError());
}
CloseHandle(hFile);
printf("%s\n", buffer);
if (buffer) { delete buffer; buffer = NULL; }
}
}
getchar();
}
我的目标是打印所有有效的设备名称并尝试获取一个有效的句柄,以便以后用户发送 ioctl`s
谢谢
编辑: 好的 abhineet 所以这就是我现在得到的:
DWORD EnumerateDevices(){
DWORD dwResult = 0;
HDEVINFO hdev = SetupDiGetClassDevs(&GUID_DEVCLASS_BATTERY, 0, 0, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);// DIGCF_ALLCLASSES
/*HDEVINFO hdev =SetupDiGetClassDevs(NULL,
0, // Enumerator
0,
DIGCF_PRESENT | DIGCF_ALLCLASSES); */
if (INVALID_HANDLE_VALUE != hdev) {
for (int idev = 0; idev < 100; idev++)
{
SP_DEVICE_INTERFACE_DATA did = { 0 };
did.cbSize = sizeof(did);
if (SetupDiEnumDeviceInterfaces(hdev, NULL, &GUID_DEVCLASS_BATTERY, idev, &did))
{
DWORD cbRequired = 0;
SetupDiGetDeviceInterfaceDetail(hdev,
&did,
NULL,
0,
&cbRequired,
0);
if (ERROR_INSUFFICIENT_BUFFER == GetLastError())
{
PSP_DEVICE_INTERFACE_DETAIL_DATA pdidd = (PSP_DEVICE_INTERFACE_DETAIL_DATA)LocalAlloc(LPTR, cbRequired);
if (pdidd) {
pdidd->cbSize = sizeof(*pdidd);
if (SetupDiGetDeviceInterfaceDetail(hdev, &did, pdidd, cbRequired, &cbRequired, 0)) {
wprintf(L"%s\n", pdidd->DevicePath);
HANDLE hBattery = CreateFile(pdidd->DevicePath,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (INVALID_HANDLE_VALUE != hBattery)
{
printf("Successfully opened Handle\n");
CloseHandle(hBattery);
}
else{
wprintf(L"CreateFile(%s) failed %d\n", pdidd->DevicePath, GetLastError());
}
}
else{
printf("SetupDiGetDeviceInterfaceDetail() failed %d\n", GetLastError());
}
LocalFree(pdidd);
}
}
else{
printf("SetupDiGetDeviceInterfaceDetail() failed %d\n", GetLastError());
}
}
else if (ERROR_NO_MORE_ITEMS == GetLastError())
{
printf("-NoMoreItems-");
break; // Enumeration failed - perhaps we're out of items
}
}
SetupDiDestroyDeviceInfoList(hdev);
}
else{
printf("SetupDiGetClassDevs() failed %d\n", GetLastError());
}
return dwResult;
}
我从这里撕得最多:https://msdn.microsoft.com/en-us/library/windows/desktop/bb204769(v=vs.85).aspx
我的输出是:
\\?\acpi#pnp0c0a#1#{72631e54-78a4-11d0-bcf7-00aa00b7b32a}
Successfully opened Handle
-NoMoreItems-
至少我有一个有效的句柄! 所以我想在系统上所有可用的设备上执行此操作,该怎么做?
【问题讨论】:
-
好吧,您可以对每个设备类重复相同的过程。可能有更简单的方法;例如,尝试传递
NULL而不是类 GUID。但真的没有任何意义;如果您(至少)不知道设备类,您怎么知道哪些 IOCTL 是有效的? -
@harry johnston 1. 已经这样做了,但后来我得到了 -NoMoreItems- 2. 蛮力逆向工程。我的目标只是向当前正在运行的每个 .sys Driver-Service 发送一个 ioctl。
-
和顺便说一句:你不能将 NULL 作为 ClassGuid 传递给 SetupDiEnumDeviceInterfaces ,你会在 0x0 处获得 AV 读数
-
当您用完一个设备类中的项目时,您会从下一个设备类重新开始。
-
我尝试了很多 ClassGuid,除了电池类之外几乎所有的都只返回 -NoMoreItems-,所以我需要对每个 classguid 函数调用进行硬编码吗?有这么多...