2012-06-24 58 views
5

回到家中這個WE我遇到了一個有關蒸汽視頻遊戲的問題:我經常滯後,通過搜索網絡,我發現它來自一些控制設備,如我的WE鍵盤。試圖在Windows環境中禁用設備

解決方法是使用標準右鍵單擊=>禁用操作來禁用設備管理器(人機界面設備部分)中的某些HID設備。因此,我開始編寫一個小工具,在啓動遊戲時禁用這些設備,並在退出後重新啓用它們。

使用SetupDI API函數,我設法隔離了我想禁用的設備,但是當我通過應用DICS_DISABLE操作禁用它們,而不是像使用鼠標右鍵方法禁用它們時那樣,設備變成「未知設備「。我必須更新設備的驅動程序才能讓它們回到設備管理器。我也嘗試了DICS_STOP操作,但是使用這個操作,設備簡單地從DM中消失...

在這個操作中是否存在缺少的東西?

這是我的原型代碼: (控制檯應用程序,x64)=>系統是x64,如果我的應用程序是32位,則所有設備操作都會失敗。

#include <stdio.h> 
#include <Windows.h> 
#include <setupapi.h> 
#include <devguid.h> 
#include <regstr.h> 

#pragma comment (lib, "Newdev.lib") 
#pragma comment (lib, "Setupapi.lib") 

int main(int argc, void * argv[]) 
{ 
    HDEVINFO hDevInfo; 
    SP_DEVINFO_DATA DeviceInfoData; 
    DWORD i; 
    SP_PROPCHANGE_PARAMS params; // params to set in order to enable/disable the device 

    // Create a HDEVINFO with all present devices. 
    hDevInfo = SetupDiGetClassDevs(NULL, 
     0, // Enumerator 
     0, 
     DIGCF_PRESENT | DIGCF_ALLCLASSES); 

    if (hDevInfo == INVALID_HANDLE_VALUE) 
    { 
     // Insert error handling here. 
     return 1; 
    } 

    // Enumerate through all devices in Set. 

    DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA); 
    for (i=0;SetupDiEnumDeviceInfo(hDevInfo,i, 
     &DeviceInfoData);i++) 
    { 
     DWORD DataT; 
     LPTSTR buffer = NULL; 
     LPTSTR servBuffer = NULL; 
     DWORD buffersize = 0; 
     DWORD servBufferSize = 0; 

     // 
     // Call function with null to begin with, 
     // then use the returned buffer size (doubled) 
     // to Alloc the buffer. Keep calling until 
     // success or an unknown failure. 
     // 
     // Double the returned buffersize to correct 
     // for underlying legacy CM functions that 
     // return an incorrect buffersize value on 
     // DBCS/MBCS systems. 
     // 
     while (!SetupDiGetDeviceRegistryProperty(
      hDevInfo, 
      &DeviceInfoData, 
      SPDRP_DEVICEDESC, 
      &DataT, 
      (PBYTE)buffer, 
      buffersize, 
      &buffersize)) 
     { 
      if (GetLastError() == 
       ERROR_INSUFFICIENT_BUFFER) 
      { 
       // Change the buffer size. 
       if (buffer) LocalFree(buffer); 
       // Double the size to avoid problems on 
       // W2k MBCS systems per KB 888609. 
       buffer = (LPTSTR)LocalAlloc(LPTR,buffersize * 2); 
      } 
      else 
      { 
       // Insert error handling here. 
       break; 
      } 
     } 

     while (!SetupDiGetDeviceRegistryProperty(
      hDevInfo, 
      &DeviceInfoData, 
      SPDRP_SERVICE, 
      &DataT, 
      (PBYTE)servBuffer, 
      servBufferSize, 
      &servBufferSize)) 
     { 
      if (GetLastError() == 
       ERROR_INSUFFICIENT_BUFFER) 
      { 
       // Change the buffer size. 
       if (servBuffer) LocalFree(servBuffer); 
       // Double the size to avoid problems on 
       // W2k MBCS systems per KB 888609. 
       servBuffer = (LPTSTR)LocalAlloc(LPTR,servBufferSize * 2); 
      } 
      else 
      { 
       // Insert error handling here. 
       break; 
      } 
     } 

     if (strstr((char *)buffer, "(HID)") && NULL == servBuffer) 
     { 
      printf("New device found : %s\n", buffer); 
      printf("disabling...\n"); 
      // init the structure 
      params.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER); 
      params.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE; 
      params.HwProfile = 0; 
      params.Scope = DICS_FLAG_CONFIGSPECIFIC; 
      params.StateChange = DICS_DISABLE; 
      // prepare operation 
      if (!SetupDiSetClassInstallParams(hDevInfo, &DeviceInfoData, &params.ClassInstallHeader, sizeof(params))) 
      { 
       printf("Error while preparing params !\n"); 
       break; 
      } 
      // launch op 
      if (!SetupDiCallClassInstaller(DICS_DISABLE, hDevInfo, &DeviceInfoData)) 
      { 
       printf("Error while calling OP ! Return code is %x\n", GetLastError()); 
       continue; 
      } 
      printf("done.\n\n"); 
     } 

     if (buffer) LocalFree(buffer); 
    } 


    if (GetLastError()!=NO_ERROR && 
     GetLastError()!=ERROR_NO_MORE_ITEMS) 
    { 
     // Insert error handling here. 
     return 1; 
    } 

    // Cleanup 
    SetupDiDestroyDeviceInfoList(hDevInfo); 

    return 0; 
} 
+0

沒有ü需要重新啓動執行此代碼,因爲我implemeting的設備改變了這種相同的代碼狀況DM對我,但我需要重新啓動系統 – bhupinder

回答

8

你有錯誤的參數,你需要

SetupDiCallClassInstaller(DIF_PROPERTYCHANGE, hDevInfo, &DeviceInfoData) 

DeviceInfoData填充SP_PROPCHANGE_PARAMS

例如參見this。 (這是中文,剛看了代碼就夠了)

+0

這解決了問題:)感謝您的幫助後, 。我還設法在params.StateChange字段中使用相同的代碼和DICS_ENABLE啓用設備。 – axiagame

+0

執行此代碼後是否需要重新啓動,因爲我正在爲DM執行與DM相同的代碼狀態更改,但它要求我重新啓動系統 – bhupinder

+0

不,它沒有。但我認爲這可能取決於您的操作系統。我個人只在Windows 7上運行它。 – axiagame

0

已經使用devcon! 嘗試this:DEVCON禁用