簡體   English   中英

如何在 C 中將 IOCTL 發送到 Windows 上的所有驅動程序

[英]How to Send IOCTL's to all drivers on windows in C

有人可以向我提供一個示例 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-

至少我有一個有效的句柄! 所以我想在系統上可用的所有設備上執行此操作,該怎么做?

恕我直言,我不認為,你可以在InstanceID上做一個CreateFile 要執行CreateFile ,您需要設備的符號名稱。 您可以使用以下 SetupAPI,

兩個 API 的備注部分指出,

SetupDiEnumDeviceInterfaces:: DeviceInterfaceData 指向標識請求的設備接口的結構。 要獲取有關接口的詳細信息,請調用 SetupDiGetDeviceInterfaceDetail。 詳細信息包括可以傳遞給 Win32 函數(如 CreateFile (在 Microsoft Windows SDK 文檔中描述)以獲取接口句柄)的設備接口的名稱。

SetupDiGetDeviceInterfaceDetail::此函數返回的接口詳細信息由一個設備路徑組成,該路徑可以傳遞給 CreateFile 等 Win32 函數。 不要嘗試解析設備路徑符號名稱。 設備路徑可以在系統啟動時重復使用。

這可能對您有用, 如何從 DeviceID 獲取 DevicePath

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM