int main(int iArgCnt, char ** argv) { IWbemLocator *pLocator = NULL; IWbemServices *pNamespace = 0; IWbemClassObject * pClass = NULL; IWbemClassObject * pOutInst = NULL; IWbemClassObject * pInClass = NULL; IWbemClassObject * pInInst = NULL; BSTR Text = NULL; HRESULT hr = S_OK; BSTR path = SysAllocString(L"root\\default"); BSTR ClassPath = SysAllocString(L"MethProvSamp"); BSTR MethodName = SysAllocString(L"Echo"); BSTR ArgName = SysAllocString(L"sInArg"); if (!path || ! ClassPath || !MethodName || ! ArgName) { printf("SysAllocString failed. Out of memory.\n"); goto cleanup; } // Initialize COM and connect up to CIMOM hr = CoInitialize(0); if (FAILED(hr)) { printf("CoInitialize returned 0x%x:", hr); goto cleanup; } // NOTE: // When using asynchronous WMI API's remotely in an environment where the "Local System" account // has no network identity (such as non-Kerberos domains), the authentication level of // RPC_C_AUTHN_LEVEL_NONE is needed. However, lowering the authentication level to // RPC_C_AUTHN_LEVEL_NONE makes your application less secure. It is wise to // use semi-synchronous API's for accessing WMI data and events instead of the asynchronous ones. hr = CoInitializeSecurity ( NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_PKT_PRIVACY, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_SECURE_REFS, //change to EOAC_NONE if you change dwAuthnLevel to RPC_C_AUTHN_LEVEL_NONE NULL ); if (FAILED(hr)) { printf("CoInitializeSecurity returned 0x%x:", hr); goto cleanup; } hr = CoCreateInstance(CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID *) &pLocator); if (FAILED(hr)) { printf("CoCreateInstance returned 0x%x:", hr); goto cleanup; } hr = pLocator->ConnectServer(path, NULL, NULL, NULL, 0, NULL, NULL, &pNamespace); printf("\n\nConnectServer returned 0x%x:", hr); if(hr != WBEM_S_NO_ERROR) goto cleanup; // Get the class object hr = pNamespace->GetObject(ClassPath, 0, NULL, &pClass, NULL); printf("\nGetObject returned 0x%x:", hr); if(hr != WBEM_S_NO_ERROR) goto cleanup; // Get the input argument and set the property hr = pClass->GetMethod(MethodName, 0, &pInClass, NULL); printf("\nGetMethod returned 0x%x:", hr); if(hr != WBEM_S_NO_ERROR) goto cleanup; hr = pInClass->SpawnInstance(0, &pInInst); printf("\nSpawnInstance returned 0x%x:", hr); if(hr != WBEM_S_NO_ERROR) goto cleanup; VARIANT var; var.vt = VT_BSTR; var.bstrVal= SysAllocString(L"hello"); if (var.bstrVal == NULL) goto cleanup; hr = pInInst->Put(ArgName, 0, &var, 0); VariantClear(&var); // Call the method hr = pNamespace->ExecMethod(ClassPath, MethodName, 0, NULL, pInInst, &pOutInst, NULL); printf("\nExecMethod returned 0x%x:", hr); if(hr != WBEM_S_NO_ERROR) goto cleanup; // Display the results. hr = pOutInst->GetObjectText(0, &Text); if(hr != WBEM_S_NO_ERROR) goto cleanup; printf("\n\nThe object text of the output object is:\n%S", Text); printf("Terminating normally\n"); // Free up resources cleanup: SysFreeString(path); SysFreeString(ClassPath); SysFreeString(MethodName); SysFreeString(ArgName); SysFreeString(Text); if (pClass) pClass->Release(); if (pInInst) pInInst->Release(); if (pInClass) pInClass->Release(); if (pOutInst) pOutInst->Release(); if (pLocator) pLocator->Release(); if (pNamespace) pNamespace->Release(); CoUninitialize(); return 0; }
////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Description : // Sends WMI command to target after logging on. ////////////////////////////////////////////////////////////////////////////////////////////////////////////// DWORD startWMICommand(char* command, char* target, char* username, char* password) { HRESULT hres; IWbemLocator *pLoc = NULL; IWbemServices *pSvc = NULL; COAUTHIDENTITY *userAcct = NULL ; COAUTHIDENTITY authIdent; char* serverWMIA; PWCHAR serverWMIW; PWCHAR usernameW; PWCHAR commandW; PWCHAR passwordW; WCHAR pszDomain[CREDUI_MAX_USERNAME_LENGTH+1]; WCHAR pszUserName[CREDUI_MAX_USERNAME_LENGTH+1]; PWCHAR slash; int len = 0; // WCHAR len = strlen(target)+12; serverWMIA = (char*)malloc(sizeof(char)*(len)); strcpy_s(serverWMIA, len, target); strcat_s(serverWMIA, len, "\\ROOT\\CIMV2"); len = MultiByteToWideChar(CP_ACP,0,serverWMIA,-1,NULL,0); serverWMIW = (PWCHAR)malloc(sizeof(WCHAR)*len); MultiByteToWideChar(CP_ACP,0,serverWMIA,-1,serverWMIW,len); free(serverWMIA); len = MultiByteToWideChar(CP_ACP,0,username,-1,NULL,0); usernameW = (PWCHAR)malloc(sizeof(WCHAR)*len); MultiByteToWideChar(CP_ACP,0,username,-1,usernameW,len); len = MultiByteToWideChar(CP_ACP,0,password,-1,NULL,0); passwordW = (PWCHAR)malloc(sizeof(WCHAR)*len); MultiByteToWideChar(CP_ACP,0,password,-1,passwordW,len); len = MultiByteToWideChar(CP_ACP,0,command,-1,NULL,0); commandW = (PWCHAR)malloc(sizeof(WCHAR)*len); MultiByteToWideChar(CP_ACP,0,command,-1,commandW,len); hres = CoInitializeEx(0, COINIT_MULTITHREADED); if(hres<0) { free(usernameW); free(passwordW); free(commandW); free(serverWMIA); free(serverWMIW); return -1; } hres = CoInitializeSecurity(NULL,-1,NULL,NULL,RPC_C_AUTHN_LEVEL_DEFAULT,RPC_C_IMP_LEVEL_IDENTIFY,NULL,EOAC_NONE,NULL); if(hres<0) { free(usernameW); free(passwordW); free(commandW); free(serverWMIA); free(serverWMIW); CoUninitialize(); return -1; } hres = CoCreateInstance(CLSID_WbemLocator,0,CLSCTX_INPROC_SERVER,IID_IWbemLocator, (LPVOID *) &pLoc); if(hres<0) { free(usernameW); free(passwordW); free(commandW); free(serverWMIA); free(serverWMIW); CoUninitialize(); return -1; } //WMI connection hres = pLoc->ConnectServer(_bstr_t(serverWMIW),_bstr_t(usernameW),_bstr_t(passwordW),NULL,NULL,NULL,NULL,&pSvc); if(hres<0) { free(usernameW); free(passwordW); free(commandW); free(serverWMIA); free(serverWMIW); pLoc->Release(); CoUninitialize(); return -1; } //Set ProxyBlanket options memset(&authIdent, 0, sizeof(COAUTHIDENTITY)); authIdent.PasswordLength = wcslen (passwordW); authIdent.Password = (USHORT*)passwordW; slash = wcschr (usernameW, L'\\'); if(slash == NULL) { free(usernameW); free(passwordW); free(commandW); free(serverWMIA); free(serverWMIW); pSvc->Release(); pLoc->Release(); CoUninitialize(); return -1; } wcscpy_s(pszUserName,CREDUI_MAX_USERNAME_LENGTH+1, slash+1); authIdent.User = (USHORT*)pszUserName; authIdent.UserLength = wcslen(pszUserName); wcsncpy_s(pszDomain, CREDUI_MAX_USERNAME_LENGTH+1, usernameW, slash - usernameW); authIdent.Domain = (USHORT*)pszDomain; authIdent.DomainLength = slash - usernameW; authIdent.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE; userAcct = &authIdent; //Set the ProxyBlanket hres = CoSetProxyBlanket(pSvc,RPC_C_AUTHN_DEFAULT,RPC_C_AUTHZ_DEFAULT,COLE_DEFAULT_PRINCIPAL,RPC_C_AUTHN_LEVEL_PKT_PRIVACY,RPC_C_IMP_LEVEL_IMPERSONATE,userAcct,EOAC_NONE); if(hres<0) { free(usernameW); free(passwordW); free(commandW); free(serverWMIA); free(serverWMIW); pSvc->Release(); pLoc->Release(); CoUninitialize(); return -1; } BSTR MethodName = SysAllocString(L"Create"); BSTR ClassName = SysAllocString(L"Win32_Process"); IWbemClassObject* pClass = NULL; hres = pSvc->GetObject(ClassName, 0, NULL, &pClass, NULL); IWbemClassObject* pInParamsDefinition = NULL; hres = pClass->GetMethod(MethodName, 0, &pInParamsDefinition, NULL); IWbemClassObject* pClassInstance = NULL; hres = pInParamsDefinition->SpawnInstance(0, &pClassInstance); // Create the values for the "in" parameters VARIANT varCommand; varCommand.vt = VT_BSTR; varCommand.bstrVal = BSTR(commandW); // Store the value for the "in" parameters hres = pClassInstance->Put(L"CommandLine", 0, &varCommand, 0); // Execute Method IWbemClassObject* pOutParams = NULL; hres = pSvc->ExecMethod(ClassName, MethodName, 0, NULL, pClassInstance, &pOutParams, NULL); if (FAILED(hres)) { free(usernameW); free(passwordW); free(commandW); free(serverWMIA); free(serverWMIW); VariantClear(&varCommand); SysFreeString(ClassName); SysFreeString(MethodName); pClass->Release(); pInParamsDefinition->Release(); pOutParams->Release(); pSvc->Release(); pLoc->Release(); CoUninitialize(); return -1; } free(usernameW); free(passwordW); free(commandW); free(serverWMIA); free(serverWMIW); SecureZeroMemory(pszUserName, sizeof(pszUserName)); SecureZeroMemory(pszDomain, sizeof(pszDomain)); VariantClear(&varCommand); SysFreeString(ClassName); SysFreeString(MethodName); pClass->Release(); pInParamsDefinition->Release(); pOutParams->Release(); pSvc->Release(); pLoc->Release(); CoUninitialize(); return 0; }
bool WMI::call(const wstring& root, const wstring& query, const wstring& method) { HRESULT hres; // Step 1: -------------------------------------------------- // Initialize COM. ------------------------------------------ hres = CoInitializeEx(0, COINIT_MULTITHREADED); if (FAILED(hres)) { throw exception(); // Program has failed. } // Step 2: -------------------------------------------------- // Set general COM security levels -------------------------- if (!is_security_initialized_) { init_security(); } // Step 3: --------------------------------------------------- // Obtain the initial locator to WMI ------------------------- IWbemLocator *pLoc = NULL; hres = CoCreateInstance( CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID *)&pLoc); if (FAILED(hres)) { CoUninitialize(); throw exception(); // Program has failed. } // Step 4: --------------------------------------------------- // Connect to WMI through the IWbemLocator::ConnectServer method IWbemServices *pSvc = NULL; // Connect to the local root\cimv2 namespace // and obtain pointer pSvc to make IWbemServices calls. hres = pLoc->ConnectServer( _bstr_t(root.c_str()), NULL, NULL, 0, NULL, 0, 0, &pSvc ); if (FAILED(hres)) { pLoc->Release(); CoUninitialize(); throw exception(); // Program has failed. } // Step 5: -------------------------------------------------- // Set security levels for the proxy ------------------------ hres = CoSetProxyBlanket( pSvc, // Indicates the proxy to set RPC_C_AUTHN_WINNT, // RPC_C_AUTHN_xxx RPC_C_AUTHZ_NONE, // RPC_C_AUTHZ_xxx NULL, // Server principal name RPC_C_AUTHN_LEVEL_CALL, // RPC_C_AUTHN_LEVEL_xxx RPC_C_IMP_LEVEL_IMPERSONATE, // RPC_C_IMP_LEVEL_xxx NULL, // client identity EOAC_NONE // proxy capabilities ); if (FAILED(hres)) { pSvc->Release(); pLoc->Release(); CoUninitialize(); throw exception(); // Program has failed. } // Step 6: -------------------------------------------------- // Use the IWbemServices pointer to make requests of WMI ---- BSTR MethodName = SysAllocString(method.c_str()); IEnumWbemClassObject* pEnumerator = NULL; hres = pSvc->ExecQuery( bstr_t("WQL"), bstr_t(query.c_str()), WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, NULL, &pEnumerator); if (FAILED(hres)) { pSvc->Release(); pLoc->Release(); CoUninitialize(); throw exception(); // Program has failed. } // Step 7: ------------------------------------------------- // Get the data from the query in step 6 ------------------- IWbemClassObject *pClass = NULL; ULONG uReturn = 0; bool result; while (pEnumerator) { HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, &pClass, &uReturn); if (uReturn == 0) { break; } VARIANT vtPath; VariantInit(&vtPath); if (FAILED(pClass->Get(L"__Path", 0, &vtPath, NULL, NULL))) { pClass->Release(); } IWbemClassObject* pResult = NULL; if (FAILED(hres = pSvc->ExecMethod(vtPath.bstrVal, MethodName, 0, NULL, NULL, &pResult, NULL))) { SysFreeString(MethodName); pClass->Release(); pSvc->Release(); pLoc->Release(); CoUninitialize(); } else { VARIANT vtRet; VariantInit(&vtRet); if (FAILED(hres = pResult->Get(L"ReturnValue", 0, &vtRet, NULL, 0))) { VariantClear(&vtRet); SysFreeString(MethodName); pClass->Release(); pSvc->Release(); pLoc->Release(); CoUninitialize(); } else { result = vtRet.boolVal; VariantClear(&vtRet); pResult->Release(); break; } VariantClear(&vtRet); pResult->Release(); } if (FAILED(hres)) { SysFreeString(MethodName); pClass->Release(); pSvc->Release(); pLoc->Release(); CoUninitialize(); throw exception(); // Program has failed. } } // Clean up //-------------------------- SysFreeString(MethodName); pClass->Release(); pLoc->Release(); pSvc->Release(); CoUninitialize(); return result; }
// 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; }