/* ================ XInputChecker::XInputChecker ================ */ XInputChecker::XInputChecker() { // CoInit if needed HRESULT hr = CoInitialize( OG_NULL ); bool bCleanupCOM = SUCCEEDED( hr ); // Create WMI IWbemLocator* pIWbemLocator = OG_NULL; hr = CoCreateInstance( __uuidof( WbemLocator ), OG_NULL, CLSCTX_INPROC_SERVER, __uuidof( IWbemLocator ), ( LPVOID* )&pIWbemLocator ); if( FAILED( hr ) || pIWbemLocator == OG_NULL ) { if( bCleanupCOM ) CoUninitialize(); return; } IEnumWbemClassObject* pEnumDevices = OG_NULL; IWbemServices* pIWbemServices = OG_NULL; IWbemClassObject* pDevices[20] = {0}; BSTR bstrDeviceID = OG_NULL; BSTR bstrClassName = OG_NULL; BSTR bstrNamespace = OG_NULL; // Do just once do { bstrNamespace = SysAllocString( L"\\\\.\\root\\cimv2" ); if( bstrNamespace == OG_NULL ) break; bstrDeviceID = SysAllocString( L"DeviceID" ); if( bstrDeviceID == OG_NULL ) break; bstrClassName = SysAllocString( L"Win32_PNPEntity" ); if( bstrClassName == OG_NULL ) break; // Connect to WMI hr = pIWbemLocator->ConnectServer( bstrNamespace, OG_NULL, OG_NULL, 0L, 0L, OG_NULL, OG_NULL, &pIWbemServices ); if( FAILED( hr ) || pIWbemServices == OG_NULL ) break; // Switch security level to IMPERSONATE CoSetProxyBlanket( pIWbemServices, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, OG_NULL, RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, OG_NULL, 0 ); // Get list of Win32_PNPEntity devices hr = pIWbemServices->CreateInstanceEnum( bstrClassName, 0, OG_NULL, &pEnumDevices ); if( FAILED( hr ) || pEnumDevices == OG_NULL ) break; // Loop over all devices DWORD uReturned = 0; VARIANT var; for( ; ; ) { // Get 20 at a time hr = pEnumDevices->Next( 10000, 20, pDevices, &uReturned ); if( FAILED( hr ) || uReturned == 0 ) break; for( int i = 0; i < uReturned; i++ ) { // For each device, get its device ID hr = pDevices[i]->Get( bstrDeviceID, 0L, &var, OG_NULL, OG_NULL ); if( SUCCEEDED( hr ) && var.vt == VT_BSTR && var.bstrVal != OG_NULL ) { // Check if the device ID contains "IG_". If it does, then it’s an XInput device // Unfortunately this information can not be found by just using DirectInput if( wcsstr( var.bstrVal, L"IG_" ) ) { // If it does, then get the VID/PID from var.bstrVal DWORD dwPid = 0, dwVid = 0; WCHAR* strVid = wcsstr( var.bstrVal, L"VID_" ); if( strVid && swscanf( strVid, L"VID_%4X", &dwVid ) != 1 ) dwVid = 0; WCHAR* strPid = wcsstr( var.bstrVal, L"PID_" ); if( strPid && swscanf( strPid, L"PID_%4X", &dwPid ) != 1 ) dwPid = 0; listIds.Alloc() = MAKELONG( dwVid, dwPid ); } } SAFE_RELEASE( pDevices[i] ); } } } while( 0 ); // Do just once if( bstrNamespace ) SysFreeString( bstrNamespace ); if( bstrDeviceID ) SysFreeString( bstrDeviceID ); if( bstrClassName ) SysFreeString( bstrClassName ); for( int i=0; i<20; i++ ) SAFE_RELEASE( pDevices[i] ); SAFE_RELEASE( pEnumDevices ); SAFE_RELEASE( pIWbemLocator ); SAFE_RELEASE( pIWbemServices ); if( bCleanupCOM ) CoUninitialize(); }
//This is copy pasted from Microsoft. pretty poorly written code, //----------------------------------------------------------------------------- // Enum each PNP device using WMI and check each device ID to see if it contains // "IG_" (ex. "VID_045E&PID_028E&IG_00"). If it does, then it's an XInput device // Unfortunately this information can not be found by just using DirectInput //----------------------------------------------------------------------------- bool IsXInputDevice( const GUID* pGuidProductFromDirectInput ) { IWbemLocator* pIWbemLocator = NULL; IEnumWbemClassObject* pEnumDevices = NULL; IWbemClassObject* pDevices[20] = {0}; IWbemServices* pIWbemServices = NULL; BSTR bstrNamespace = NULL; BSTR bstrDeviceID = NULL; BSTR bstrClassName = NULL; DWORD uReturned = 0; bool bIsXinputDevice= false; UINT iDevice = 0; VARIANT var; HRESULT hr; // CoInit if needed hr = CoInitialize(NULL); bool bCleanupCOM = SUCCEEDED(hr); // Create WMI hr = CoCreateInstance( __uuidof(WbemLocator), NULL, CLSCTX_INPROC_SERVER, __uuidof(IWbemLocator), (LPVOID*) &pIWbemLocator); if( FAILED(hr) || pIWbemLocator == NULL ) goto LCleanup; bstrNamespace = SysAllocString( L"\\\\.\\root\\cimv2" );if( bstrNamespace == NULL ) goto LCleanup; bstrClassName = SysAllocString( L"Win32_PNPEntity" ); if( bstrClassName == NULL ) goto LCleanup; bstrDeviceID = SysAllocString( L"DeviceID" ); if( bstrDeviceID == NULL ) goto LCleanup; // Connect to WMI hr = pIWbemLocator->ConnectServer( bstrNamespace, NULL, NULL, 0L, 0L, NULL, NULL, &pIWbemServices ); if( FAILED(hr) || pIWbemServices == NULL ) goto LCleanup; // Switch security level to IMPERSONATE. CoSetProxyBlanket( pIWbemServices, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL, RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE ); hr = pIWbemServices->CreateInstanceEnum( bstrClassName, 0, NULL, &pEnumDevices ); if( FAILED(hr) || pEnumDevices == NULL ) goto LCleanup; // Loop over all devices for( ;; ) { // Get 20 at a time hr = pEnumDevices->Next( 10000, 20, pDevices, &uReturned ); if( FAILED(hr) ) goto LCleanup; if( uReturned == 0 ) break; for( iDevice=0; iDevice<uReturned; iDevice++ ) { // For each device, get its device ID hr = pDevices[iDevice]->Get( bstrDeviceID, 0L, &var, NULL, NULL ); if( SUCCEEDED( hr ) && var.vt == VT_BSTR && var.bstrVal != NULL ) { // Check if the device ID contains "IG_". If it does, then it's an XInput device // This information can not be found from DirectInput if( wcsstr( var.bstrVal, L"IG_" ) ) { // If it does, then get the VID/PID from var.bstrVal DWORD dwPid = 0, dwVid = 0; WCHAR* strVid = wcsstr( var.bstrVal, L"VID_" ); if( strVid && swscanf_s( strVid, L"VID_%4X", &dwVid ) != 1 ) dwVid = 0; WCHAR* strPid = wcsstr( var.bstrVal, L"PID_" ); if( strPid && swscanf_s( strPid, L"PID_%4X", &dwPid ) != 1 ) dwPid = 0; // Compare the VID/PID to the DInput device DWORD dwVidPid = MAKELONG( dwVid, dwPid ); if( dwVidPid == pGuidProductFromDirectInput->Data1 ) { bIsXinputDevice = true; goto LCleanup; } } } SAFE_RELEASE( pDevices[iDevice] ); } } LCleanup: if(bstrNamespace) SysFreeString(bstrNamespace); if(bstrDeviceID) SysFreeString(bstrDeviceID); if(bstrClassName) SysFreeString(bstrClassName); for( iDevice=0; iDevice<20; iDevice++ ) SAFE_RELEASE( pDevices[iDevice] ); SAFE_RELEASE( pEnumDevices ); SAFE_RELEASE( pIWbemLocator ); SAFE_RELEASE( pIWbemServices ); if( bCleanupCOM ) CoUninitialize(); return bIsXinputDevice; }
bool CSMBiosTable::FetchSMBiosDataByCom( unsigned char ** p ) { BOOL bRet = FALSE; HRESULT hres; // Initialize COM. hres = CoInitializeEx( 0, COINIT_MULTITHREADED ); if( FAILED(hres) ) { return FALSE; // Program has failed. } // Obtain the initial locator to Windows Management // on a particular host computer. IWbemLocator *pLoc = 0; hres = CoCreateInstance( CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID *) &pLoc ); if( FAILED(hres) ) { CoUninitialize(); return FALSE; // Program has failed. } IWbemServices *pSvc = 0; // Connect to the root\cimv2 namespace with the z // current user and obtain pointer pSvc // to make IWbemServices calls. hres = pLoc->ConnectServer( _bstr_t(L"ROOT\\WMI"), // WMI namespace NULL, // User name NULL, // User password 0, // Locale NULL, // Security flags 0, // Authority 0, // Context object &pSvc // IWbemServices proxy ); if( FAILED(hres) ) { pLoc->Release(); CoUninitialize(); return FALSE; // Program has failed. } // Set the IWbemServices proxy so that impersonation // of the user (client) occurs. hres = CoSetProxyBlanket( pSvc, // the proxy to set RPC_C_AUTHN_WINNT, // authentication service RPC_C_AUTHZ_NONE, // authorization service NULL, // Server principal name RPC_C_AUTHN_LEVEL_CALL, // authentication level RPC_C_IMP_LEVEL_IMPERSONATE, // impersonation level NULL, // client identity EOAC_NONE // proxy capabilities ); if( FAILED(hres) ) { pSvc->Release(); pLoc->Release(); CoUninitialize(); return FALSE; // Program has failed. } IEnumWbemClassObject* pEnumerator = NULL; hres = pSvc->CreateInstanceEnum( L"MSSMBios_RawSMBiosTables", 0, NULL, &pEnumerator); if( FAILED(hres) ) { pSvc->Release(); pLoc->Release(); CoUninitialize(); return FALSE; // Program has failed. } else { do { IWbemClassObject* pInstance = NULL; ULONG dwCount = NULL; hres = pEnumerator->Next( WBEM_INFINITE, 1, &pInstance, &dwCount); if( SUCCEEDED(hres) ) { VARIANT varBIOSData; VariantInit(&varBIOSData); CIMTYPE type; hres = pInstance->Get(bstr_t("SmbiosMajorVersion"),0,&varBIOSData,&type,NULL); if( FAILED(hres) ) { VariantClear(&varBIOSData); } else { m_smbiosbuffer.nSMBIOSMajorVersion = varBIOSData.iVal; VariantInit(&varBIOSData); hres = pInstance->Get( bstr_t("SmbiosMinorVersion"), 0, &varBIOSData, &type, NULL ); if( FAILED(hres) ) { VariantClear( &varBIOSData ); } else { m_smbiosbuffer.nSMBIOSMinorVersion = varBIOSData.iVal; VariantInit(&varBIOSData); hres = pInstance->Get( bstr_t("SMBiosData"), 0, &varBIOSData, &type, NULL ); if( SUCCEEDED(hres) ) { if( ( VT_UI1 | VT_ARRAY ) != varBIOSData.vt ) { } else { SAFEARRAY *parray = NULL; parray = V_ARRAY(&varBIOSData); BYTE* pbData = (BYTE*)parray->pvData; m_smbiosbuffer.nLength = parray->rgsabound[0].cElements; (*p) = new unsigned char[m_smbiosbuffer.nLength]; memcpy_s( (*p), m_smbiosbuffer.nLength, pbData, m_smbiosbuffer.nLength ); bRet = TRUE; } } VariantClear( &varBIOSData ); } } break; } }while( hres == WBEM_S_NO_ERROR ); } // Cleanup // ======== pSvc->Release(); pLoc->Release(); CoUninitialize(); return bRet; }
//----------------------------------------------------------------------------- // Enum each PNP device using WMI and check each device ID to see if it contains // "IG_" (ex. "VID_045E&PID_028E&IG_00"). If it does, then itӳ an XInput device // Unfortunately this information can not be found by just using DirectInput. // Checking against a VID/PID of 0x028E/0x045E won't find 3rd party or future // XInput devices. // // This function stores the list of xinput devices in a linked list // at g_pXInputDeviceList, and IsXInputDevice() searchs that linked list //----------------------------------------------------------------------------- HRESULT SetupForIsXInputDevice() { IWbemServices* pIWbemServices = NULL; IEnumWbemClassObject* pEnumDevices = NULL; IWbemLocator* pIWbemLocator = NULL; IWbemClassObject* pDevices[20] = {0}; BSTR bstrDeviceID = NULL; BSTR bstrClassName = NULL; BSTR bstrNamespace = NULL; DWORD uReturned = 0; bool bCleanupCOM = false; UINT iDevice = 0; VARIANT var; HRESULT hr; // CoInit if needed hr = CoInitialize( NULL ); bCleanupCOM = SUCCEEDED( hr ); // Create WMI hr = CoCreateInstance( __uuidof( WbemLocator ), NULL, CLSCTX_INPROC_SERVER, __uuidof( IWbemLocator ), ( LPVOID* )&pIWbemLocator ); if( VP_FAILED( hr ) || pIWbemLocator == NULL ) goto LCleanup; // Create BSTRs for WMI bstrNamespace = SysAllocString( L"\\\\.\\root\\cimv2" ); if( bstrNamespace == NULL ) goto LCleanup; bstrDeviceID = SysAllocString( L"DeviceID" ); if( bstrDeviceID == NULL ) goto LCleanup; bstrClassName = SysAllocString( L"Win32_PNPEntity" ); if( bstrClassName == NULL ) goto LCleanup; // Connect to WMI hr = pIWbemLocator->ConnectServer( bstrNamespace, NULL, NULL, 0L, 0L, NULL, NULL, &pIWbemServices ); if( VP_FAILED( hr ) || pIWbemServices == NULL ) goto LCleanup; // Switch security level to IMPERSONATE CoSetProxyBlanket( pIWbemServices, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL, RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, 0 ); // Get list of Win32_PNPEntity devices hr = pIWbemServices->CreateInstanceEnum( bstrClassName, 0, NULL, &pEnumDevices ); if( VP_FAILED( hr ) || pEnumDevices == NULL ) goto LCleanup; // Loop over all devices for(; ; ) { // Get 20 at a time hr = pEnumDevices->Next( 10000, 20, pDevices, &uReturned ); if( VP_FAILED( hr ) ) goto LCleanup; if( uReturned == 0 ) break; for( iDevice = 0; iDevice < uReturned; iDevice++ ) { // For each device, get its device ID hr = pDevices[iDevice]->Get( bstrDeviceID, 0L, &var, NULL, NULL ); if( SUCCEEDED( hr ) && var.vt == VT_BSTR && var.bstrVal != NULL ) { // Check if the device ID contains "IG_". If it does, then itӳ an XInput device // Unfortunately this information can not be found by just using DirectInput if( wcsstr( var.bstrVal, L"IG_" ) ) { // If it does, then get the VID/PID from var.bstrVal DWORD dwPid = 0, dwVid = 0; WCHAR* strVid = wcsstr( var.bstrVal, L"VID_" ); if( strVid && swscanf( strVid, L"VID_%4X", &dwVid ) != 1 ) dwVid = 0; WCHAR* strPid = wcsstr( var.bstrVal, L"PID_" ); if( strPid && swscanf( strPid, L"PID_%4X", &dwPid ) != 1 ) dwPid = 0; DWORD dwVidPid = MAKELONG( dwVid, dwPid ); // Add the VID/PID to a linked list XINPUT_DEVICE_NODE* pNewNode = new XINPUT_DEVICE_NODE; if( pNewNode ) { pNewNode->dwVidPid = dwVidPid; pNewNode->pNext = g_pXInputDeviceList; g_pXInputDeviceList = pNewNode; } } } SAFE_RELEASE( pDevices[iDevice] ); } } LCleanup: if( bstrNamespace ) SysFreeString( bstrNamespace ); if( bstrDeviceID ) SysFreeString( bstrDeviceID ); if( bstrClassName ) SysFreeString( bstrClassName ); for( iDevice = 0; iDevice < 20; iDevice++ ) SAFE_RELEASE( pDevices[iDevice] ); SAFE_RELEASE( pEnumDevices ); SAFE_RELEASE( pIWbemLocator ); SAFE_RELEASE( pIWbemServices ); return hr; }
HRESULT GetVideoMemoryViaWMI( WCHAR* strInputDeviceID, DWORD* pdwAdapterRam ) { HRESULT hr; bool bGotMemory = false; HRESULT hrCoInitialize = S_OK; IWbemLocator* pIWbemLocator = nullptr; IWbemServices* pIWbemServices = nullptr; BSTR pNamespace = nullptr; *pdwAdapterRam = 0; hrCoInitialize = CoInitialize( 0 ); hr = CoCreateInstance( CLSID_WbemLocator, nullptr, CLSCTX_INPROC_SERVER, IID_IWbemLocator, ( LPVOID* )&pIWbemLocator ); #ifdef PRINTF_DEBUGGING if( FAILED( hr ) ) wprintf( L"WMI: CoCreateInstance failed: 0x%0.8x\n", hr ); #endif if( SUCCEEDED( hr ) && pIWbemLocator ) { // Using the locator, connect to WMI in the given namespace. pNamespace = SysAllocString( L"\\\\.\\root\\cimv2" ); hr = pIWbemLocator->ConnectServer( pNamespace, nullptr, nullptr, 0L, 0L, nullptr, nullptr, &pIWbemServices ); #ifdef PRINTF_DEBUGGING if( FAILED( hr ) ) wprintf( L"WMI: pIWbemLocator->ConnectServer failed: 0x%0.8x\n", hr ); #endif if( SUCCEEDED( hr ) && pIWbemServices != 0 ) { HINSTANCE hinstOle32 = nullptr; hinstOle32 = LoadLibraryW( L"ole32.dll" ); if( hinstOle32 ) { PfnCoSetProxyBlanket pfnCoSetProxyBlanket = nullptr; pfnCoSetProxyBlanket = ( PfnCoSetProxyBlanket )GetProcAddress( hinstOle32, "CoSetProxyBlanket" ); if( pfnCoSetProxyBlanket != 0 ) { // Switch security level to IMPERSONATE. pfnCoSetProxyBlanket( pIWbemServices, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, nullptr, RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, nullptr, 0 ); } FreeLibrary( hinstOle32 ); } IEnumWbemClassObject* pEnumVideoControllers = nullptr; BSTR pClassName = nullptr; pClassName = SysAllocString( L"Win32_VideoController" ); hr = pIWbemServices->CreateInstanceEnum( pClassName, 0, nullptr, &pEnumVideoControllers ); #ifdef PRINTF_DEBUGGING if( FAILED( hr ) ) wprintf( L"WMI: pIWbemServices->CreateInstanceEnum failed: 0x%0.8x\n", hr ); #endif if( SUCCEEDED( hr ) && pEnumVideoControllers ) { IWbemClassObject* pVideoControllers[10] = {0}; DWORD uReturned = 0; BSTR pPropName = nullptr; // Get the first one in the list pEnumVideoControllers->Reset(); hr = pEnumVideoControllers->Next( 5000, // timeout in 5 seconds 10, // return the first 10 pVideoControllers, &uReturned ); #ifdef PRINTF_DEBUGGING if( FAILED( hr ) ) wprintf( L"WMI: pEnumVideoControllers->Next failed: 0x%0.8x\n", hr ); if( uReturned == 0 ) wprintf( L"WMI: pEnumVideoControllers uReturned == 0\n" ); #endif VARIANT var; if( SUCCEEDED( hr ) ) { bool bFound = false; for( UINT iController = 0; iController < uReturned; iController++ ) { if ( !pVideoControllers[iController] ) continue; pPropName = SysAllocString( L"PNPDeviceID" ); hr = pVideoControllers[iController]->Get( pPropName, 0L, &var, nullptr, nullptr ); #ifdef PRINTF_DEBUGGING if( FAILED( hr ) ) wprintf( L"WMI: pVideoControllers[iController]->Get PNPDeviceID failed: 0x%0.8x\n", hr ); #endif if( SUCCEEDED( hr ) ) { if( wcsstr( var.bstrVal, strInputDeviceID ) != 0 ) bFound = true; } VariantClear( &var ); if( pPropName ) SysFreeString( pPropName ); if( bFound ) { pPropName = SysAllocString( L"AdapterRAM" ); hr = pVideoControllers[iController]->Get( pPropName, 0L, &var, nullptr, nullptr ); #ifdef PRINTF_DEBUGGING if( FAILED( hr ) ) wprintf( L"WMI: pVideoControllers[iController]->Get AdapterRAM failed: 0x%0.8x\n", hr ); #endif if( SUCCEEDED( hr ) ) { bGotMemory = true; *pdwAdapterRam = var.ulVal; } VariantClear( &var ); if( pPropName ) SysFreeString( pPropName ); break; } SAFE_RELEASE( pVideoControllers[iController] ); } } SAFE_RELEASE(pEnumVideoControllers); } if( pClassName ) SysFreeString( pClassName ); } if( pNamespace ) SysFreeString( pNamespace ); SAFE_RELEASE( pIWbemServices ); } SAFE_RELEASE( pIWbemLocator ); if( SUCCEEDED( hrCoInitialize ) ) CoUninitialize(); if( bGotMemory ) return S_OK; else return E_FAIL; }
//=============================================== //XInputの設定 //=============================================== //[input] // //[return] // hr //=============================================== HRESULT CInput::SetupXInputDevice() { IWbemServices *pIWbemServices = NULL; IEnumWbemClassObject *pEnumDevices = NULL; IWbemLocator *pIWbemLocator = NULL; IWbemClassObject *pDevice[20] = {0}; BSTR bstrDeviceID = NULL; BSTR bstrClassName = NULL; BSTR bstrNamespace = NULL; DWORD Returned = 0; bool IsCleanupCOM = false; UINT Device = 0; VARIANT var; HRESULT hr; hr = CoInitialize(NULL); IsCleanupCOM = SUCCEEDED(hr); /*WMIの生成*/ hr = CoCreateInstance(__uuidof(WbemLocator), NULL, CLSCTX_INPROC_SERVER, __uuidof(IWbemLocator), (LPVOID*)&pIWbemLocator); if(FAILED(hr) || pIWbemLocator == NULL) { goto LCleanUp; } /*BSTRの生成*/ bstrNamespace = SysAllocString(L"\\\\.\\root\\cimv2"); bstrDeviceID = SysAllocString(L"DeviceID"); bstrClassName = SysAllocString(L"Win32_PNPEntity"); if(bstrNamespace == NULL) { goto LCleanUp; } if(bstrDeviceID == NULL) { goto LCleanUp; } if(bstrClassName == NULL) { goto LCleanUp; } /*WMIへの接続*/ hr = pIWbemLocator->ConnectServer(bstrNamespace, NULL, NULL, 0L, 0L, NULL, NULL, &pIWbemServices); if(FAILED(hr) || pIWbemServices == NULL) { goto LCleanUp; } /*セキュリティーレベルの切替*/ //CoSetProxyBlanket(pIWbemServices, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL, // RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, 0); /*リストを得る*/ hr = pIWbemServices->CreateInstanceEnum(bstrClassName, 0, NULL, &pEnumDevices); if(FAILED(hr) ) { goto LCleanUp; } for(;;) { hr = pEnumDevices->Next(10000, 20, pDevice, &Returned); if(FAILED(hr) ) { goto LCleanUp; } if(Returned == 0) { break; } for(Device = 0;Device < Returned;Device++) { hr = pDevice[Device]->Get(bstrDeviceID, 0L, &var, NULL, NULL); if(SUCCEEDED(hr) ) { if(wcsstr(var.bstrVal, L"IG_") ) { DWORD dwPid = 0; DWORD dwVid = 0; WCHAR *pstrVid = wcsstr(var.bstrVal, L"VID_" ); if(pstrVid && swscanf_s(pstrVid, L"VID_%4X", &dwVid) != 1) { dwVid = 0; } WCHAR *pstrPid = wcsstr(var.bstrVal, L"PID_"); if(pstrPid && swscanf_s(pstrPid, L"PID_%4L", &dwPid) != 1) { dwPid = 0; } DWORD dwVidPid = MAKELONG(dwVid, dwPid); XINPUT_DEVICE_NODE *pNewNode = new XINPUT_DEVICE_NODE; if(pNewNode) { pNewNode->dwVidPid = dwVidPid; } } } RELEASE(pDevice[Device] ); } } LCleanUp: if(bstrNamespace) { SysFreeString(bstrNamespace); } if(bstrDeviceID) { SysFreeString(bstrDeviceID); } if(bstrClassName) { SysFreeString(bstrClassName); } for(Device = 0;Device < 20;Device++) { RELEASE(pDevice[Device]); } RELEASE(pEnumDevices); RELEASE(pIWbemLocator); RELEASE(pIWbemServices); return hr; }
BOOL CEnumerateSerial::UsingWMI(CSimpleArray<UINT>& ports, CSimpleArray<CString>& friendlyNames) #endif { //Make sure we clear out any elements which may already be in the array(s) #if defined CENUMERATESERIAL_USE_STL ports.clear(); friendlyNames.clear(); #else ports.RemoveAll(); friendlyNames.RemoveAll(); #endif //What will be the return value BOOL bSuccess = FALSE; //Create the WBEM locator IWbemLocator* pLocator = NULL; HRESULT hr = CoCreateInstance(CLSID_WbemLocator, NULL, CLSCTX_INPROC_SERVER, IID_IWbemLocator, reinterpret_cast<void**>(&pLocator)); if (SUCCEEDED(hr)) { IWbemServices* pServices = NULL; hr = pLocator->ConnectServer(_bstr_t("\\\\.\\root\\cimv2"), NULL, NULL, NULL, 0, NULL, NULL, &pServices); if (SUCCEEDED(hr)) { //Execute the query IEnumWbemClassObject* pClassObject = NULL; hr = pServices->CreateInstanceEnum(_bstr_t("Win32_SerialPort"), WBEM_FLAG_RETURN_WBEM_COMPLETE, NULL, &pClassObject); if (SUCCEEDED(hr)) { bSuccess = TRUE; //Now enumerate all the ports hr = WBEM_S_NO_ERROR; //Final Next will return WBEM_S_FALSE while (hr == WBEM_S_NO_ERROR) { ULONG uReturned = 0; IWbemClassObject* apObj[10]; memset(apObj, 0, sizeof(apObj)); hr = pClassObject->Next(WBEM_INFINITE, 10, reinterpret_cast<IWbemClassObject**>(apObj), &uReturned); if (SUCCEEDED(hr)) { for (ULONG n=0; n<uReturned; n++) { VARIANT varProperty1; VariantInit(&varProperty1); HRESULT hrGet = apObj[n]->Get(L"DeviceID", 0, &varProperty1, NULL, NULL); if (SUCCEEDED(hrGet) && (varProperty1.vt == VT_BSTR) && (wcslen(varProperty1.bstrVal) > 3)) { //If it looks like "COMX" then add it to the array which will be returned if ((_wcsnicmp(varProperty1.bstrVal, L"COM", 3) == 0) && IsNumeric(&(varProperty1.bstrVal[3]), TRUE)) { //Work out the port number int nPort = _wtoi(&(varProperty1.bstrVal[3])); #if defined CENUMERATESERIAL_USE_STL ports.push_back(nPort); #else ports.Add(nPort); #endif //Also get the friendly name of the port VARIANT varProperty2; VariantInit(&varProperty2); if (SUCCEEDED(apObj[n]->Get(L"Name", 0, &varProperty2, NULL, NULL)) && (varProperty2.vt == VT_BSTR)) { #if defined CENUMERATESERIAL_USE_STL #if defined _UNICODE std::wstring szName(varProperty2.bstrVal); #else CAutoHeapAlloc szAsciiValue; int nLengthA = WideCharToMultiByte(CP_ACP, 0, varProperty2.bstrVal, -1, NULL, 0, NULL, NULL); if (nLengthA) { if (szAsciiValue.Allocate(nLengthA)) WideCharToMultiByte(CP_ACP, 0, varProperty2.bstrVal, -1, static_cast<LPSTR>(szAsciiValue.m_pData), nLengthA, NULL, NULL); } std::string szName(static_cast<LPSTR>(szAsciiValue.m_pData)); #endif friendlyNames.push_back(szName); #else friendlyNames.Add(CString(varProperty2.bstrVal)); #endif } else { #if defined CENUMERATESERIAL_USE_STL friendlyNames.push_back(_T("")); #else friendlyNames.Add(_T("")); #endif } //Free up the variant; VariantClear(&varProperty2); } } //Free up the variant; VariantClear(&varProperty1); //Free up each COM interface apObj[n]->Release(); } } } //Free up the COM interface pClassObject->Release(); } //Free up the COM interface pServices->Release(); } //Free up the COM interface pLocator->Release(); } return bSuccess; }
int readSystemUUID(u_char *uuidbuf){ int gotData = NO; BSTR path = SysAllocString(L"root\\wmi"); BSTR className = SysAllocString(L"MSSmBios_RawSMBiosTables"); BSTR propName = SysAllocString(L"SMBiosData"); ULONG uReturned = 1; HRESULT hr = S_FALSE; IWbemLocator *pLocator = NULL; IWbemServices *pNamespace = NULL; IEnumWbemClassObject *pEnumSMBIOS = NULL; IWbemClassObject *pSmbios = NULL; CIMTYPE type; VARIANT pVal; SAFEARRAY *pArray = NULL; smbiosHeader *smbiosData; u_char *uuidPtr; DWORD smbufSize; hr = CoInitializeEx(0, COINIT_MULTITHREADED); if (! SUCCEEDED( hr ) ){ myLog(LOG_ERR,"readSystemUUID: failed to initialize COM"); gotData = NO; goto Cleanup; } hr = CoInitializeSecurity(NULL,-1,NULL,NULL,RPC_C_AUTHN_LEVEL_DEFAULT,RPC_C_IMP_LEVEL_IMPERSONATE,NULL,EOAC_NONE,NULL); hr = CoCreateInstance( CLSID_WbemLocator, NULL, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID *) &pLocator ); if(! SUCCEEDED( hr ) ){ myLog(LOG_ERR,"readSystemUUID: failed to create WMI instance"); gotData = NO; goto Cleanup; } hr = pLocator->ConnectServer(path, NULL, NULL, NULL, 0, NULL, NULL, &pNamespace ); pLocator->Release(); if( WBEM_S_NO_ERROR != hr ){ myLog(LOG_ERR,"getSystemUUID: ConnectServer() failed for namespace"); gotData = NO; goto Cleanup; } hr = pNamespace->CreateInstanceEnum(className, 0, NULL, &pEnumSMBIOS ); pNamespace->Release(); if (! SUCCEEDED( hr ) ){ myLog(LOG_ERR,"getSystemUUID: CreateInstanceEnum() failed for MSSmBios_RawSMBiosTables"); gotData = NO; goto Cleanup; } hr = pEnumSMBIOS->Next(4000, 1, &pSmbios, &uReturned ); pEnumSMBIOS->Release(); if ( 1 != uReturned ){ myLog(LOG_ERR,"getSystemUUID: Next() failed for pEnumSMBIOS"); gotData = NO; goto Cleanup; } pSmbios->Get(propName,0L,&pVal,&type,NULL); if ( ( VT_UI1 | VT_ARRAY) != pVal.vt){ myLog(LOG_ERR,"getSystemUUID: Get() failed for pSmbios"); gotData = NO; goto Cleanup; } pArray = V_ARRAY(&pVal); smbufSize = pArray->rgsabound[0].cElements; smbiosData = (smbiosHeader*)my_calloc(smbufSize); if(!smbiosData){ myLog(LOG_ERR,"getSystemUUID: failed to allocate buffer for smbiosData"); gotData = NO; goto Cleanup; } memcpy((void*)smbiosData,pArray->pvData,smbufSize); uuidPtr = (u_char*)getUUIDPtr(smbufSize,smbiosData); if(!uuidPtr){ myLog(LOG_ERR,"getSystemUUID: failed to find UUID in SMBIOS"); gotData = NO; goto Cleanup; } memcpy((void*)uuidbuf,uuidPtr,16); gotData = YES; Cleanup: SysFreeString(propName); SysFreeString(className); SysFreeString(path); if(smbiosData) my_free(smbiosData); return gotData; }
RTDECL(int) RTSystemQueryDmiString(RTSYSDMISTR enmString, char *pszBuf, size_t cbBuf) { AssertPtrReturn(pszBuf, VERR_INVALID_POINTER); AssertReturn(cbBuf > 0, VERR_INVALID_PARAMETER); *pszBuf = '\0'; AssertReturn(enmString > RTSYSDMISTR_INVALID && enmString < RTSYSDMISTR_END, VERR_INVALID_PARAMETER); /* * Figure the property name before we start. */ const char *pszPropName; switch (enmString) { case RTSYSDMISTR_PRODUCT_NAME: pszPropName = "Name"; break; case RTSYSDMISTR_PRODUCT_VERSION: pszPropName = "Version"; break; case RTSYSDMISTR_PRODUCT_UUID: pszPropName = "UUID"; break; case RTSYSDMISTR_PRODUCT_SERIAL: pszPropName = "IdentifyingNumber"; break; case RTSYSDMISTR_MANUFACTURER: pszPropName = "Vendor"; break; default: return VERR_NOT_SUPPORTED; } /* * Before we do anything with COM, we have to initialize it. */ HRESULT hrc = rtSystemDmiWinInitialize(); if (FAILED(hrc)) return VERR_NOT_SUPPORTED; int rc = VERR_NOT_SUPPORTED; BSTR pBstrPropName = rtSystemWinBstrFromUtf8(pszPropName); if (pBstrPropName) { /* * Instantiate the IWbemLocator, whatever that is and connect to the * DMI serve. */ IWbemLocator *pLoc; hrc = CoCreateInstance(CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID *)&pLoc); if (SUCCEEDED(hrc)) { IWbemServices *pServices; hrc = rtSystemDmiWinConnectToServer(pLoc, "ROOT\\CIMV2", &pServices); if (SUCCEEDED(hrc)) { /* * Enumerate whatever it is we're looking at and try get * the desired property. */ BSTR pBstrFilter = rtSystemWinBstrFromUtf8("Win32_ComputerSystemProduct"); if (pBstrFilter) { IEnumWbemClassObject *pEnum; hrc = pServices->CreateInstanceEnum(pBstrFilter, 0, NULL, &pEnum); if (SUCCEEDED(hrc)) { do { IWbemClassObject *pObj; ULONG cObjRet; hrc = pEnum->Next(WBEM_INFINITE, 1, &pObj, &cObjRet); if ( SUCCEEDED(hrc) && cObjRet >= 1) { VARIANT Var; VariantInit(&Var); hrc = pObj->Get(pBstrPropName, 0, &Var, 0, 0); if ( SUCCEEDED(hrc) && V_VT(&Var) == VT_BSTR) { /* * Convert the BSTR to UTF-8 and copy it * into the return buffer. */ char *pszValue; rc = RTUtf16ToUtf8(Var.bstrVal, &pszValue); if (RT_SUCCESS(rc)) { rc = RTStrCopy(pszBuf, cbBuf, pszValue); RTStrFree(pszValue); hrc = WBEM_S_FALSE; } } VariantClear(&Var); pObj->Release(); } } while (hrc != WBEM_S_FALSE); pEnum->Release(); } SysFreeString(pBstrFilter); } else hrc = E_OUTOFMEMORY; pServices->Release(); } pLoc->Release(); } SysFreeString(pBstrPropName); } else hrc = E_OUTOFMEMORY; rtSystemDmiWinTerminate(); if (FAILED(hrc) && rc == VERR_NOT_SUPPORTED) rc = VERR_NOT_SUPPORTED; return rc; }
/* ================ Sys_GetVideoRam returns in megabytes ================ */ int Sys_GetVideoRam( void ) { #ifdef ID_DEDICATED return 0; #else unsigned int retSize = 64; #if 0 IWbemLocator* spLoc = NULL; HRESULT hr = CoCreateInstance( CLSID_WbemLocator, 0, CLSCTX_SERVER, IID_IWbemLocator, ( LPVOID * ) &spLoc ); if ( hr != S_OK || spLoc == NULL ) { return retSize; } IWbemServices *spServices = NULL; // Connect to CIM hr = spLoc->ConnectServer( L"\\\\.\\root\\CIMV2", NULL, NULL, 0, NULL, 0, 0, &spServices ); if ( hr != WBEM_S_NO_ERROR ) { spLoc->Release(); return retSize; } // Switch the security level to IMPERSONATE so that provider will grant access to system-level objects. hr = CoSetProxyBlanket( spServices, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL, RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE ); if ( hr != S_OK ) { spServices->Release(); spLoc->Release(); return retSize; } // Get the vid controller IEnumWbemClassObject *spEnumInst = NULL; hr = spServices->CreateInstanceEnum( L"Win32_VideoController", WBEM_FLAG_SHALLOW, NULL, &spEnumInst ); if ( hr != WBEM_S_NO_ERROR || spEnumInst == NULL ) { spServices->Release(); spLoc->Release(); return retSize; } ULONG uNumOfInstances = 0; IWbemClassObject *spInstance = NULL; hr = spEnumInst->Next( 10000, 1, &spInstance, &uNumOfInstances ); if ( hr == S_OK && spInstance ) { // Get properties from the object VARIANT varSize; hr = spInstance->Get( L"AdapterRAM", 0, &varSize, 0, 0 ); if ( hr == S_OK ) { retSize = varSize.intVal / ( 1024 * 1024 ); if ( retSize == 0 ) { retSize = 64; } } spInstance->Release(); } spEnumInst->Release(); spServices->Release(); spLoc->Release(); #endif // 0 return retSize; #endif }
// target_network_adaptorで指定しているアダプター名にnetwork_addressを追加する。 long FirstFindAdaptorAddStaticIPAddress(const std::wstring &target_network_adaptor, const std::vector<NetworkAddress> &network_addres) { IWbemLocator *locator = nullptr; HRESULT hr = ::CoCreateInstance(CLSID_WbemLocator, nullptr, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&locator)); /* CIMV2名前空間 */ IWbemServices *targetNamespace = nullptr; if(SUCCEEDED(hr)) { BSTR namespacePath = ::SysAllocString(L"root\\cimv2"); hr = locator->ConnectServer(namespacePath, nullptr, nullptr, nullptr, 0, nullptr, nullptr, &targetNamespace); ::SysFreeString(namespacePath); } /* セキュリティ設定 */ if(SUCCEEDED(hr)) { hr = ::CoSetProxyBlanket(targetNamespace, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, nullptr, RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, nullptr, EOAC_NONE); } /* クラスオブジェクト */ IWbemClassObject *wmi_class = nullptr; BSTR wmi_class_name = ::SysAllocString(L"Win32_NetworkAdapterConfiguration"); if(SUCCEEDED(hr)) { hr = targetNamespace->GetObjectW(wmi_class_name, 0, nullptr, &wmi_class, nullptr); } /* メソッド */ IWbemClassObject *wmi_method = nullptr; BSTR method_name = ::SysAllocString(L"EnableStatic"); if(SUCCEEDED(hr)) { hr = wmi_class->GetMethod(method_name, 0, &wmi_method, nullptr); } /* ネットワークアドレスのパラメーター */ IWbemClassObject *network_address_param = nullptr; if(SUCCEEDED(hr)) { hr = wmi_method->SpawnInstance(0, &network_address_param); } /* パラメーターにIPアドレス設定 */ if(SUCCEEDED(hr)) { VARIANT address_var; VARIANT subnet_mask_var; { SAFEARRAYBOUND sab[1] = {0}; sab[0].cElements = network_addres.size(); // IPアドレス address_var.vt = VT_ARRAY | VT_BSTR; address_var.parray = ::SafeArrayCreate(VT_BSTR, 1, sab); // サブネットマスク subnet_mask_var.vt = VT_ARRAY | VT_BSTR; subnet_mask_var.parray = ::SafeArrayCreate(VT_BSTR, 1, sab); // 配列に設定 LONG index = 0; for(auto iter = std::begin(network_addres); iter != std::end(network_addres); ++iter) { if(SUCCEEDED(hr)) { BSTR ip_address = ::SysAllocString(iter->GetIPAddress().c_str()); hr = ::SafeArrayPutElement(address_var.parray, &index, ip_address); ::SysFreeString(ip_address); } if(SUCCEEDED(hr)) { BSTR subnet_mask = ::SysAllocString(iter->GetSubnetMask().c_str()); hr = ::SafeArrayPutElement(subnet_mask_var.parray, &index, subnet_mask); ::SysFreeString(subnet_mask); } ++index; } } if(SUCCEEDED(hr)) { BSTR param_ip_address = ::SysAllocString(L"IPAddress"); hr = network_address_param->Put(param_ip_address, 0, &address_var, 0); ::SysFreeString(param_ip_address); } if(SUCCEEDED(hr)) { BSTR param_subnet_mask = ::SysAllocString(L"SubnetMask"); network_address_param->Put(param_subnet_mask, 0, &subnet_mask_var, 0); ::SysFreeString(param_subnet_mask); } ::VariantClear(&subnet_mask_var); ::VariantClear(&address_var); } /* ネットワークアダプターを探す */ IEnumWbemClassObject *adapter_enumerator = nullptr; if(SUCCEEDED(hr)) { hr = targetNamespace->CreateInstanceEnum(wmi_class_name, WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, nullptr, &adapter_enumerator); } /* ネットワークアダプター インスタンスへのパスを取得 */ BSTR network_adaptr_instance; if(SUCCEEDED(hr)) { // 対象のネットワークアダプターのインスタンス取得 IWbemClassObject *instance = nullptr; do { ULONG ret = 0u; hr = adapter_enumerator->Next(WBEM_INFINITE, (ULONG)1, &instance, &ret); if(SUCCEEDED(hr) && (ret != 0)) { BSTR desc_property = ::SysAllocString(L"Description"); VARIANT desc; hr = instance->Get(desc_property, 0, &desc, nullptr, nullptr); ::SysFreeString(desc_property); if(SUCCEEDED(hr)) { const std::wstring &adaptor_name = desc.bstrVal; ::VariantClear(&desc); auto b_find = adaptor_name.find(target_network_adaptor); if(b_find != std::wstring::npos) { break; // do_whileをぬける } } } else { break; // do_whileをぬける } } while(hr != WBEM_S_FALSE); // インスタンスへのパス取得 if(SUCCEEDED(hr)) { BSTR path_property = ::SysAllocString(L"__PATH"); VARIANT path_var; hr = instance->Get(path_property, 0, &path_var, nullptr, nullptr); ::SysFreeString(path_property); if(SUCCEEDED(hr)) { network_adaptr_instance = path_var.bstrVal; } ::VariantClear(&path_var); } SAFE_RELEASE(instance); } /* IPアドレスの設定 */ IWbemClassObject *result_class = nullptr; if(SUCCEEDED(hr)) { hr = targetNamespace->ExecMethod(network_adaptr_instance, method_name, 0, nullptr, network_address_param, &result_class, nullptr); } long result = -1; if(FAILED(hr)) { result = 1; } else { BSTR return_value = SysAllocString(L"ReturnValue"); VARIANT res_var; hr = result_class->Get(return_value, 0, &res_var, 0, 0); result = V_I4(&res_var); ::SysFreeString(return_value); ::VariantClear(&res_var); } SAFE_RELEASE(result_class); ::SysFreeString(network_adaptr_instance); SAFE_RELEASE(adapter_enumerator); SAFE_RELEASE(network_address_param); SAFE_RELEASE(wmi_method); ::SysFreeString(method_name); SAFE_RELEASE(wmi_class); ::SysFreeString(wmi_class_name); SAFE_RELEASE(targetNamespace); SAFE_RELEASE(locator); return result; }