2015-09-25 84 views
2

有人可以給我提供一個示例C代碼,列出可以用Createfile()打開的所有設備名稱嗎?我總是得到錯誤代碼3:路徑不存在,這並不作品如何發送IOCTL到Windows上的所有驅動程序C

示例代碼:

#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

THX

編輯: OK 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- 

至少我得到了一個有效的句柄! 所以我想要做到這一點在系統上可用的所有設備,如何做到這一點?

+0

嗯,你可以重複同樣的過程對每個設備類。可能有一個更簡單的方法;例如,嘗試傳遞'NULL'而不是類GUID。但真的沒有任何意義;如果你(至少)不知道設備類,你怎麼知道IOCTLs是有效的? –

+0

@harry johnston 1.已經完成了,但是我剛剛獲得-NoMoreItems- 2.蠻力,反向工程。我的目標是將ioctl發送到當前正在運行的每個.sys Driver-Service。 – test123423

+0

和btw:你不能將NULL作爲ClassGuid傳遞給SetupDiEnumDeviceInterfaces,你可以在0x0處讀取AV – test123423

回答

1

恕我直言,我不認爲,你可以做一個CreateFileInstanceID。要做CreateFile,您需要設備的符號名稱。您可以使用以下SetupAPIs,

兩個API的備註部分指出,

SetupDiEnumDeviceInterfaces :: DeviceInterfaceData指向結構,標識請求的 設備接口。要獲得有關接口的詳細信息,請致電 SetupDiGetDeviceInterfaceDetail。 的詳細信息,包括可傳遞到Win32函數 如的CreateFile(微軟的Windows SDK文檔中描述) 得到一個句柄接口設備接口的 名稱。

SetupDiGetDeviceInterfaceDetail ::由該函數返回的接口的細節由可以被傳遞到的Win32作爲這樣的CreateFile 功能的設備路徑的。不要試圖解析設備路徑 符號名稱。設備路徑可以在系統啓動時重複使用。

這可能是你的使用,how to get DevicePath from DeviceID

相關問題