2012-06-24 24 views
5

Wracając do domu to WE poszedłem do problemu związanego z parową grą wideo: Miałem regularne opóźnienia, a przeszukując sieć odkryłem, że pochodzi to z urządzeń sterujących, ponieważ moja klawiatura WE.Próba wyłączenia urządzenia w środowisku Windows

Rozwiązaniem jest dezaktywacja niektórych urządzeń HID w menedżerze urządzeń (sekcja urządzeń interfejsu ludzkiego) za pomocą standardowego kliknięcia prawym przyciskiem myszy =>. Zacząłem więc kodować małe narzędzie, aby wyłączyć te urządzenia podczas uruchamiania gry i ponownie je włączyć po wyjściu.

Dzięki funkcjom API SetupDI udało mi się wyodrębnić urządzenia, które chciałem wyłączyć, ale gdy je wyłączę przez zastosowanie operacji DICS_DISABLE, zamiast działać tak, jakbym je wyłączył za pomocą metody prawym przyciskiem myszy, urządzenia stają się " unkown devices "w menedżerze urządzeń. Muszę zaktualizować sterowniki urządzeń, aby przywrócić je do menedżera urządzeń. Próbowałem również operacji DICS_STOP, ale tym razem urządzenia po prostu znikają z DM ...

Czy jest coś, czego mi brakuje w tej operacji?

Oto mój prototypowy kod: (aplikacja konsolowa, x64) => system to x64, a jeśli moja aplikacja ma 32 bity, wszystkie operacje na urządzeniach po prostu się nie udają.

#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

zrobił u wymagany restart po wykonaniu tego kodu, ponieważ jestem implemeting ten sam status kodu urządzeń zmian w DM dla mnie, ale to wymaga mnie do systemu – bhupinder

Odpowiedz

8

Masz parametr źle, trzeba

SetupDiCallClassInstaller(DIF_PROPERTYCHANGE, hDevInfo, &DeviceInfoData) 

z wypełnionym SP_PROPCHANGE_PARAMS w DeviceInfoData.

Zobacz na przykład this. (jest w języku chińskim, wystarczy przeczytać kod)

+0

które rozwiązały problem :) Dzięki za pomoc restart . Udało mi się również przywrócić urządzenie z tym samym kodem i DICS_ENABLE w polu params.StateChange. – axiagame

+0

czy konieczne było ponowne uruchomienie po wykonaniu tego kodu, ponieważ wdrażam ten sam kod stanu zmian urządzeń w DM dla mnie, ale wymaga on ponownego uruchomienia systemu – bhupinder

+0

Nie, nie zrobił tego. Ale myślę, że to może zależeć od twojego systemu operacyjnego. Osobiście uruchomiłem go tylko w systemie Windows 7. – axiagame

0

Użyłem devcon! Spróbuj this: devcon wyłączyć

Powiązane problemy