utils.cpp 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. #include "utils.h"
  2. #ifndef _XBOX
  3. #ifndef SAFE_RELEASE
  4. #define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p)=NULL; } }
  5. #endif
  6. #include <objbase.h>
  7. #include <wbemidl.h>
  8. #pragma warning (disable : 4996)
  9. #include <stdio.h>
  10. //-----------------------------------------------------------------------------
  11. // Enum each PNP device using WMI and check each device ID to see if it contains
  12. // "IG_" (ex. "VID_045E&PID_028E&IG_00"). If it does, then it's an XInput device
  13. // Unfortunately this information can not be found by just using DirectInput
  14. //-----------------------------------------------------------------------------
  15. bool IsXInputDevice( const GUID* pGuidProductFromDirectInput )
  16. {
  17. IWbemLocator* pIWbemLocator = NULL;
  18. IEnumWbemClassObject* pEnumDevices = NULL;
  19. IWbemClassObject* pDevices[20] = {0};
  20. IWbemServices* pIWbemServices = NULL;
  21. BSTR bstrNamespace = NULL;
  22. BSTR bstrDeviceID = NULL;
  23. BSTR bstrClassName = NULL;
  24. DWORD uReturned = 0;
  25. bool bIsXinputDevice= false;
  26. UINT iDevice = 0;
  27. VARIANT var;
  28. HRESULT hr;
  29. // CoInit if needed
  30. hr = CoInitialize(NULL);
  31. bool bCleanupCOM = SUCCEEDED(hr);
  32. // Create WMI
  33. hr = CoCreateInstance( __uuidof(WbemLocator),
  34. NULL,
  35. CLSCTX_INPROC_SERVER,
  36. __uuidof(IWbemLocator),
  37. (LPVOID*) &pIWbemLocator);
  38. if( FAILED(hr) || pIWbemLocator == NULL )
  39. goto LCleanup;
  40. bstrNamespace = SysAllocString( L"\\\\.\\root\\cimv2" );if( bstrNamespace == NULL ) goto LCleanup;
  41. bstrClassName = SysAllocString( L"Win32_PNPEntity" ); if( bstrClassName == NULL ) goto LCleanup;
  42. bstrDeviceID = SysAllocString( L"DeviceID" ); if( bstrDeviceID == NULL ) goto LCleanup;
  43. // Connect to WMI
  44. hr = pIWbemLocator->ConnectServer( bstrNamespace, NULL, NULL, 0L,
  45. 0L, NULL, NULL, &pIWbemServices );
  46. if( FAILED(hr) || pIWbemServices == NULL )
  47. goto LCleanup;
  48. // Switch security level to IMPERSONATE.
  49. CoSetProxyBlanket( pIWbemServices, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL,
  50. RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE );
  51. hr = pIWbemServices->CreateInstanceEnum( bstrClassName, 0, NULL, &pEnumDevices );
  52. if( FAILED(hr) || pEnumDevices == NULL )
  53. goto LCleanup;
  54. // Loop over all devices
  55. for( ;; )
  56. {
  57. // Get 20 at a time
  58. hr = pEnumDevices->Next( 10000, 20, pDevices, &uReturned );
  59. if( FAILED(hr) )
  60. goto LCleanup;
  61. if( uReturned == 0 )
  62. break;
  63. for( iDevice=0; iDevice<uReturned; iDevice++ )
  64. {
  65. // For each device, get its device ID
  66. hr = pDevices[iDevice]->Get( bstrDeviceID, 0L, &var, NULL, NULL );
  67. if( SUCCEEDED( hr ) && var.vt == VT_BSTR && var.bstrVal != NULL )
  68. {
  69. // Check if the device ID contains "IG_". If it does, then it's an XInput device
  70. // This information can not be found from DirectInput
  71. if( wcsstr( var.bstrVal, L"IG_" ) )
  72. {
  73. // If it does, then get the VID/PID from var.bstrVal
  74. DWORD dwPid = 0, dwVid = 0;
  75. WCHAR* strVid = wcsstr( var.bstrVal, L"VID_" );
  76. if( strVid && swscanf( strVid, L"VID_%4X", &dwVid ) != 1 )
  77. dwVid = 0;
  78. WCHAR* strPid = wcsstr( var.bstrVal, L"PID_" );
  79. if( strPid && swscanf( strPid, L"PID_%4X", &dwPid ) != 1 )
  80. dwPid = 0;
  81. // Compare the VID/PID to the DInput device
  82. DWORD dwVidPid = MAKELONG( dwVid, dwPid );
  83. if( dwVidPid == pGuidProductFromDirectInput->Data1 )
  84. {
  85. bIsXinputDevice = true;
  86. goto LCleanup;
  87. }
  88. }
  89. }
  90. SAFE_RELEASE( pDevices[iDevice] );
  91. }
  92. }
  93. LCleanup:
  94. if(bstrNamespace)
  95. SysFreeString(bstrNamespace);
  96. if(bstrDeviceID)
  97. SysFreeString(bstrDeviceID);
  98. if(bstrClassName)
  99. SysFreeString(bstrClassName);
  100. for( iDevice=0; iDevice<20; iDevice++ )
  101. SAFE_RELEASE( pDevices[iDevice] );
  102. SAFE_RELEASE( pEnumDevices );
  103. SAFE_RELEASE( pIWbemLocator );
  104. SAFE_RELEASE( pIWbemServices );
  105. if( bCleanupCOM )
  106. CoUninitialize();
  107. return bIsXinputDevice;
  108. }
  109. #pragma warning (default : 4996)
  110. #endif