title: How to get a instance of Win32_SecurityDescriptor in WMI?
body: <p>i'm writting a C++ WMI utility class which wraps the WMI stuff to help my further WMI query. i encountered a problem when accessing a Win32_SecurityDescriptor instance.</p>
  
  <p>i used the WQL query "Select * from Win32_LogicalShareSecuritySetting" to get all the Win32_LogicalShareSecuritySetting instances. then called the GetSecurityDescriptor method of Win32_LogicalShareSecuritySetting instance to get a Win32_SecurityDescriptor instance. But when i attempted to retrieve some property like "__PATH" from the Win32_SecurityDescriptor instance, i got a 0xC0000005 Access Violation messagebox.</p>
  
  <p>i wrote my code in C++, but i think the problem should be common.
  I also used the wbemtest tool by Microsoft for test but didn't find a way to display a Win32_SecurityDescriptor instance. Why is Win32_SecurityDescriptor so special?</p>
  
  <p>here's all my code, you can try it in your VC, mine is 6. Windows SDK maybe needed.
  Access Violation found in the caller code:
  CString strSDInstancePath = wmiSearcher->getStringFromObject(pSDInstance, "__PATH");</p>
  
  <p>ADWMISearch.cpp</p>
  
  <pre><code>#include "StdAfx.h"
  #include "ADWMISearch.h"
  
  #include &lt;comdef.h&gt;
  # pragma comment(lib, "wbemuuid.lib")
  # pragma comment(lib, "credui.lib")
  # pragma comment(lib, "comsupp.lib")
  #include &lt;wincred.h&gt;
  #include &lt;strsafe.h&gt;
  #include &lt;iostream&gt;
  using namespace std;
  
  DWORD ADWMISearch::WIN32_FROM_HRESULT_alternate(HRESULT hr)
  {
      DWORD dwResult;
      if (hr &lt; 0)
      {
          dwResult = (DWORD) hr;
          return dwResult;
      }
      else
      {
          MyMessageBox_Error(_T("WIN32_FROM_HRESULT_alternate Error."), _T("Error"));
          return -1;
      }
  }
  
  IWbemServices* ADWMISearch::connect(CString strServerName, CString strServerIP, CString strDomainName, CString strUsername,
                           CString strPassword)
  {
      CString strComputerName = strServerName;
      CString strFullUsername; //_T("adtest\\Administrator")
      if (strDomainName == _T(""))
      {
          strUsername = _T("");
          strFullUsername = _T("");
          strPassword = _T("");
      }
      else
      {
          strFullUsername = strDomainName + _T("\\") + strUsername;
      }
  
  
      HRESULT hres;
  
      // Step 1: --------------------------------------------------
      // Initialize COM. ------------------------------------------
  
      hres =  CoInitializeEx(0, COINIT_MULTITHREADED); 
      if (FAILED(hres))
      {
          //cout &lt;&lt; "Failed to initialize COM library. Error code = 0x" 
          //    &lt;&lt; hex &lt;&lt; hres &lt;&lt; endl;
          MyMessageBox_Error(_T("connect"));
          return NULL;                  // Program has failed.
      }
  
      // Step 2: --------------------------------------------------
      // Set general COM security levels --------------------------
  
      hres =  CoInitializeSecurity(
          NULL, 
          -1,                          // COM authentication
          NULL,                        // Authentication services
          NULL,                        // Reserved
          RPC_C_AUTHN_LEVEL_DEFAULT,   // Default authentication 
          RPC_C_IMP_LEVEL_IDENTIFY,    // Default Impersonation  
          NULL,                        // Authentication info
          EOAC_NONE,                   // Additional capabilities 
          NULL                         // Reserved
          );
  
      //char aaa[100];
      //sprintf(aaa, "%x", hres);
  
      if (FAILED(hres) &amp;&amp; hres != RPC_E_TOO_LATE)
          {
              //cout &lt;&lt; "Failed to initialize security. Error code = 0x" 
              //    &lt;&lt; hex &lt;&lt; hres &lt;&lt; endl;
              CoUninitialize();
              MyMessageBox_Error(_T("connect"));
              return NULL;                    // Program has failed.
          }
  
      // Step 3: ---------------------------------------------------
      // Obtain the initial locator to WMI -------------------------
  
      IWbemLocator *pLoc = NULL;
  
      hres = CoCreateInstance(
          CLSID_WbemLocator,             
          0, 
          CLSCTX_INPROC_SERVER, 
          IID_IWbemLocator, (LPVOID *) &amp;pLoc);
  
      if (FAILED(hres))
      {
          CoUninitialize();
          MyMessageBox_Error(_T("connect"));
          return NULL;                 // Program has failed.
      }
  
      // Step 4: -----------------------------------------------------
      // Connect to WMI through the IWbemLocator::ConnectServer method
  
      IWbemServices *pSvc = NULL;
  
      bool useToken = TRUE;
      bool useNTLM = FALSE;
      // Get the user name and password for the remote computer
      /*
      CREDUI_INFO cui;
      bool useToken = TRUE;
      bool useNTLM = FALSE;
      TCHAR pszName[CREDUI_MAX_USERNAME_LENGTH+1] = {0};
      TCHAR pszPwd[CREDUI_MAX_PASSWORD_LENGTH+1] = {0};
      TCHAR pszDomain[CREDUI_MAX_USERNAME_LENGTH+1];
      TCHAR pszUserName[CREDUI_MAX_USERNAME_LENGTH+1];
      TCHAR pszAuthority[CREDUI_MAX_USERNAME_LENGTH+1];
      BOOL fSave;
      DWORD dwErr;
  
      memset(&amp;cui,0,sizeof(CREDUI_INFO));
      cui.cbSize = sizeof(CREDUI_INFO);
      cui.hwndParent = NULL;
      // Ensure that MessageText and CaptionText identify
      // what credentials to use and which application requires them.
      cui.pszMessageText = _T("Press cancel to use process token");
      cui.pszCaptionText = _T("Enter Account Information");
      cui.hbmBanner = NULL;
      fSave = FALSE;
  
      dwErr = CredUIPromptForCredentials( 
          &amp;cui,                             // CREDUI_INFO structure
          _T(""),                         // Target for credentials
          NULL,                             // Reserved
          0,                                // Reason
          pszName,                          // User name
          CREDUI_MAX_USERNAME_LENGTH+1,     // Max number for user name
          pszPwd,                           // Password
          CREDUI_MAX_PASSWORD_LENGTH+1,     // Max number for password
          &amp;fSave,                           // State of save check box
          CREDUI_FLAGS_GENERIC_CREDENTIALS |// flags
          CREDUI_FLAGS_ALWAYS_SHOW_UI |
          CREDUI_FLAGS_DO_NOT_PERSIST);  
  
      if(dwErr == ERROR_CANCELLED)
      {
          useToken = true;
      }
      else if (dwErr)
      {
          cout &lt;&lt; "Did not get credentials " &lt;&lt; dwErr &lt;&lt; endl;
          pLoc-&gt;Release();     
          CoUninitialize();
          return 1;      
      }
      */
  
      // change the computerName strings below to the full computer name
      // of the remote computer
      CString strAuthority;
      if(!useNTLM)
      {
          //StringCchPrintf(pszAuthority, CREDUI_MAX_USERNAME_LENGTH+1, _T("kERBEROS:%s"), strComputerName);
          strAuthority = _T("kERBEROS:") + strComputerName;
  
      }
  
      // Connect to the remote root\cimv2 namespace
      // and obtain pointer pSvc to make IWbemServices calls.
      //---------------------------------------------------------
      CString strNetworkResource = _T("\\\\") + strComputerName + _T("\\root\\cimv2");
      if (strFullUsername == _T(""))
      {
          hres = pLoc-&gt;ConnectServer(
              _bstr_t(strNetworkResource),
              NULL,                                   // User name
              NULL,                                   // User password
              NULL,                                   // Locale             
              WBEM_FLAG_CONNECT_USE_MAX_WAIT,         // Security flags
              _bstr_t(strAuthority),                  // Authority        
              NULL,                                   // Context object 
              &amp;pSvc                                   // IWbemServices proxy
              );
      }
      else
      {
          hres = pLoc-&gt;ConnectServer(
              _bstr_t(strNetworkResource),
              _bstr_t(strFullUsername),                   // User name
              _bstr_t(strPassword),                   // User password
              NULL,                                   // Locale             
              WBEM_FLAG_CONNECT_USE_MAX_WAIT,         // Security flags
              _bstr_t(strAuthority),                  // Authority        
              NULL,                                   // Context object 
              &amp;pSvc                                   // IWbemServices proxy
              );
      }
  
      if (FAILED(hres))
      {
          DWORD aaa = WIN32_FROM_HRESULT_alternate(hres);
          //cout &lt;&lt; "Could not connect. Error code = 0x" 
          //     &lt;&lt; hex &lt;&lt; hres &lt;&lt; endl;
  
          pLoc-&gt;Release();
          CoUninitialize();
          MyMessageBox_Error(_T("connect"));
          return NULL;                // Program has failed.
      }
  
      //cout &lt;&lt; "Connected to ROOT\\CIMV2 WMI namespace" &lt;&lt; endl;
  
  
      // step 5: --------------------------------------------------
      // Create COAUTHIDENTITY that can be used for setting security on proxy
  
      COAUTHIDENTITY *userAcct = NULL;
      COAUTHIDENTITY authIdent;
  
      if(!useToken)
      {
          memset(&amp;authIdent, 0, sizeof(COAUTHIDENTITY));
          authIdent.PasswordLength = strPassword.GetLength();
          authIdent.Password = (USHORT*) _bstr_t(strPassword);
  
  
          authIdent.Domain = (USHORT*) _bstr_t(strDomainName);
          authIdent.DomainLength = strDomainName.GetLength();
          authIdent.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;
  
          userAcct = &amp;authIdent;
  
      }
  
      // Step 6: --------------------------------------------------
      // Set security levels on a WMI connection ------------------
  
      hres = CoSetProxyBlanket(
         pSvc,                           // Indicates the proxy to set
         RPC_C_AUTHN_DEFAULT,            // RPC_C_AUTHN_xxx
         RPC_C_AUTHZ_DEFAULT,            // RPC_C_AUTHZ_xxx
         COLE_DEFAULT_PRINCIPAL,         // Server principal name 
         RPC_C_AUTHN_LEVEL_PKT_PRIVACY,  // RPC_C_AUTHN_LEVEL_xxx 
         RPC_C_IMP_LEVEL_IMPERSONATE,    // RPC_C_IMP_LEVEL_xxx
         userAcct,                       // client identity
         EOAC_NONE                       // proxy capabilities 
      );
  
      if (FAILED(hres))
      {
          //cout &lt;&lt; "Could not set proxy blanket. Error code = 0x" 
          //    &lt;&lt; hex &lt;&lt; hres &lt;&lt; endl;
          pSvc-&gt;Release();
          pLoc-&gt;Release();     
          CoUninitialize();
          MyMessageBox_Error(_T("connect"));
          return NULL;               // Program has failed.
      }
  
      // Cleanup
      // ========
      pLoc-&gt;Release();
  
      return pSvc;
  }
  
  vector&lt;IWbemClassObject*&gt; ADWMISearch::query(IWbemServices *pSvc, CString strDomainName, CString strPassword, CString strWQL)
  {
      vector&lt;IWbemClassObject*&gt; npResultObjects;
      BOOL useToken = TRUE;
      // step 5: --------------------------------------------------
      // Create COAUTHIDENTITY that can be used for setting security on proxy
  
      COAUTHIDENTITY *userAcct = NULL;
      COAUTHIDENTITY authIdent;
  
      if(!useToken)
      {
          memset(&amp;authIdent, 0, sizeof(COAUTHIDENTITY));
          authIdent.PasswordLength = strPassword.GetLength();
          authIdent.Password = (USHORT*) _bstr_t(strPassword);
  
          /*
          LPTSTR slash = _tcschr(pszName, _T('\\'));
          if( slash == NULL )
          {
              //cout &lt;&lt; _T("Could not create Auth identity. No domain specified\n") ;
              pSvc-&gt;Release();
              pLoc-&gt;Release();     
              CoUninitialize();
              return 1;               // Program has failed.
          }
  
          StringCchCopy(pszUserName, CREDUI_MAX_USERNAME_LENGTH+1, slash+1);
          authIdent.User = (USHORT*)pszUserName;
          authIdent.UserLength = _tcslen(pszUserName);
          StringCchCopyN(pszDomain, CREDUI_MAX_USERNAME_LENGTH+1, pszName, slash - pszName);
          */
  
          authIdent.Domain = (USHORT*) _bstr_t(strDomainName);
          authIdent.DomainLength = strDomainName.GetLength();
          authIdent.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;
  
          userAcct = &amp;authIdent;
  
      }
  
      // Step 7: --------------------------------------------------
      // Use the IWbemServices pointer to make requests of WMI ----
  
      // For example, get the name of the operating system
      IEnumWbemClassObject* pEnumerator = NULL;
      HRESULT hResult;
      hResult = pSvc-&gt;ExecQuery(
          _bstr_t(_T("WQL")), 
          _bstr_t(strWQL), //_T("Select * from Win32_Share")
          WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, 
          NULL,
          &amp;pEnumerator);
  
      if (FAILED(hResult))
      {
          //cout &lt;&lt; "Query for operating system name failed."
          //    &lt;&lt; " Error code = 0x" 
          //    &lt;&lt; hex &lt;&lt; hres &lt;&lt; endl;
          MyMessageBox_Error(_T("query"));
          return npResultObjects;               // Program has failed.
      }
  
      // Step 8: -------------------------------------------------
      // Secure the enumerator proxy
      hResult = CoSetProxyBlanket(
          pEnumerator,                    // Indicates the proxy to set
          RPC_C_AUTHN_DEFAULT,            // RPC_C_AUTHN_xxx
          RPC_C_AUTHZ_DEFAULT,            // RPC_C_AUTHZ_xxx
          COLE_DEFAULT_PRINCIPAL,         // Server principal name 
          RPC_C_AUTHN_LEVEL_PKT_PRIVACY,  // RPC_C_AUTHN_LEVEL_xxx 
          RPC_C_IMP_LEVEL_IMPERSONATE,    // RPC_C_IMP_LEVEL_xxx
          userAcct,                       // client identity
          EOAC_NONE                       // proxy capabilities 
          );
  
      if (FAILED(hResult))
      {
          //cout &lt;&lt; "Could not set proxy blanket on enumerator. Error code = 0x" 
          //     &lt;&lt; hex &lt;&lt; hres &lt;&lt; endl;
          pEnumerator-&gt;Release();
          MyMessageBox_Error(_T("query"));
          return npResultObjects;               // Program has failed.
      }
  
      // When you have finished using the credentials,
      // erase them from memory.
  
  
  
      // Step 9: -------------------------------------------------
      // Get the data from the query in step 7 -------------------
  
      IWbemClassObject *pclsObj = NULL;
      ULONG uReturn = 0;
  
      while (pEnumerator)
      {
          HRESULT hr = pEnumerator-&gt;Next(WBEM_INFINITE, 1, 
              &amp;pclsObj, &amp;uReturn);
  
          if(0 == uReturn)
          {
              break;
          }
  
          npResultObjects.push_back(pclsObj);
          /*
          VARIANT vtProp;
  
          // Get the value of the Name property
          hr = pclsObj-&gt;Get(L"Name", 0, &amp;vtProp, 0, 0);
          cout &lt;&lt; _T("OS Name: ") &lt;&lt; vtProp.bstrVal &lt;&lt; endl;
  
          // Get the value of the FreePhysicalMemory property
          hr = pclsObj-&gt;Get(L"FreePhysicalMemory", 0, &amp;vtProp, 0, 0);
          cout &lt;&lt; "Free physical memory(in kilobytes): " &lt;&lt; vtProp.uintVal &lt;&lt; endl;
          VariantClear(&amp;vtProp);
  
          pclsObj-&gt;Release();
          pclsObj = NULL;
          */
      }
  
      // Cleanup
      // ========
  
      pEnumerator-&gt;Release();
  
      return npResultObjects;
  }
  
  CString ADWMISearch::getStringFromObject(IWbemClassObject* pObject, CString strPropertyName)
  {
      _bstr_t bstrPropertyName = strPropertyName;
  
      VARIANT vtProperty;
      CString strProperty;
      // Get the value of the property
      VariantInit(&amp;vtProperty);
      HRESULT hResult = pObject-&gt;Get(bstrPropertyName, 0, &amp;vtProperty, 0, 0);
      if (SUCCEEDED(hResult) &amp;&amp; V_VT(&amp;vtProperty) == VT_BSTR)
      {
          strProperty = vtProperty.bstrVal;
          VariantClear(&amp;vtProperty);
          return strProperty;
      }
      else
      {
          VariantClear(&amp;vtProperty);
          MyMessageBox_Error(_T("getStringsFromObjects"));
          return _T("");
      }
  }
  
  vector&lt;CString&gt; ADWMISearch::getStringsFromObjects(vector&lt;IWbemClassObject*&gt; npObjects, CString strPropertyName)
  {
      _bstr_t bstrPropertyName = strPropertyName;
      vector&lt;CString&gt; nstrProperties;
  
      for (int i = 0; i &lt; npObjects.size(); i ++)
      {
          VARIANT vtProperty;
          CString strProperty;
          // Get the value of the property
          VariantInit(&amp;vtProperty);
          HRESULT hResult = npObjects[i]-&gt;Get(bstrPropertyName, 0, &amp;vtProperty, 0, 0);
          if (SUCCEEDED(hResult) &amp;&amp; V_VT(&amp;vtProperty) == VT_BSTR)
          {
              CString strProperty = vtProperty.bstrVal;
              nstrProperties.push_back(strProperty);
              VariantClear(&amp;vtProperty);
          }
          else
          {
              VariantClear(&amp;vtProperty);
              MyMessageBox_Error(_T("getStringsFromObjects"));
              return nstrProperties;
          }
      }
      return nstrProperties;
  }
  
  void ADWMISearch::clearObjects(vector&lt;IWbemClassObject*&gt; npObjects)
  {
      for (int i = 0; i &lt; npObjects.size(); i ++)
      {
          npObjects[i]-&gt;Release();
          npObjects[i] = NULL;
      }
      npObjects.clear();
  }
  
  IWbemClassObject* ADWMISearch::getWMIClass(IWbemServices *pSvc, CString strClassName)
  {
      HRESULT hResult;
      IWbemClassObject* pClass = NULL;
      hResult = pSvc-&gt;GetObject(_bstr_t(strClassName), 0, NULL, &amp;pClass, NULL); //_T("Win32_Share")
      if (!SUCCEEDED(hResult))
      {
          MyMessageBox_Error(_T("getWMIClass"));
          return NULL;
      }
      else
      {
          return pClass;
      }
  }
  
  IWbemClassObject* ADWMISearch::getObjectFromObject(IWbemClassObject *pObject, CString strArgumentName)
  {
      if (!pObject)
      {
          MyMessageBox_Error(_T("getObjectFromObject"));
          return NULL;
      }
  
      HRESULT hResult;
      VARIANT varArgument;
  
      hResult = pObject-&gt;Get(_bstr_t(strArgumentName), 0, &amp;varArgument, NULL, 0);
      if (!SUCCEEDED(hResult))
      {
          VariantClear(&amp;varArgument);
          MyMessageBox_Error(_T("getObjectFromObject"));
          return NULL;
      }
  
      //IWbemClassObject **ppResultObject;
      IWbemClassObject *pResultObject2;
      if (V_VT(&amp;varArgument) == VT_UNKNOWN)
      {
          //ppResultObject = (IWbemClassObject **)varArgument.ppunkVal;
          pResultObject2 = (IWbemClassObject *)varArgument.punkVal;
      }
      else if (V_VT(&amp;varArgument) == VT_DISPATCH)
      {
          //ppResultObject = (IWbemClassObject **)varArgument.ppdispVal;
          pResultObject2 = (IWbemClassObject *)varArgument.pdispVal;
      }
      else
      {
          VariantClear(&amp;varArgument);
          MyMessageBox_Error(_T("getObjectFromObject"));
          return NULL;
      }
  
      VariantClear(&amp;varArgument);
  
      //IWbemClassObject *pResultObject = *ppResultObject;
      //return pResultObject;
      return pResultObject2;
  }
  
  IWbemClassObject* ADWMISearch::getObjectFromObjectWithCheck(IWbemClassObject *pOutParams, CString strArgumentName)
  {
      if (!pOutParams)
      {
          MyMessageBox_Error(_T("getObjectFromObjectWithCheck"));
          return NULL;
      }
  
      HRESULT hResult;
      VARIANT varReturnValue;
      VARIANT varArgument;
      hResult = pOutParams-&gt;Get(_bstr_t(L"ReturnValue"), 0, &amp;varReturnValue, NULL, 0);
      if (!SUCCEEDED(hResult))
      {
          VariantClear(&amp;varReturnValue);
          VariantClear(&amp;varArgument);
          MyMessageBox_Error(_T("getObjectFromObjectWithCheck"));
          return NULL;
      }
      DWORD dwResult = varReturnValue.lVal;
  
      hResult = pOutParams-&gt;Get(_bstr_t(strArgumentName), 0, &amp;varArgument, NULL, 0);
      if (!SUCCEEDED(hResult))
      {
          VariantClear(&amp;varReturnValue);
          VariantClear(&amp;varArgument);
          MyMessageBox_Error(_T("getObjectFromObjectWithCheck"));
          return NULL;
      }
  
      //IWbemClassObject **ppResultObject;
      IWbemClassObject *pResultObject2;
      if (V_VT(&amp;varArgument) == VT_UNKNOWN)
      {
          //ppResultObject = (IWbemClassObject **)varArgument.ppunkVal;
          pResultObject2 = (IWbemClassObject *)varArgument.punkVal;
      }
      else if (V_VT(&amp;varArgument) == VT_DISPATCH)
      {
          //ppResultObject = (IWbemClassObject **)varArgument.ppdispVal;
          pResultObject2 = (IWbemClassObject *)varArgument.pdispVal;
      }
      else
      {
          VariantClear(&amp;varReturnValue);
          VariantClear(&amp;varArgument);
          MyMessageBox_Error(_T("getObjectFromObjectWithCheck"));
          return NULL;
      }
  
      VariantClear(&amp;varReturnValue);
      VariantClear(&amp;varArgument);
  
      //IWbemClassObject *pResultObject = *ppResultObject;
      //return pResultObject;
      return pResultObject2;
  }
  
  vector&lt;ADWMIParam&gt; ADWMISearch::genObjectArguments(CString strArgName, IWbemClassObject *pObject)
  {
      vector&lt;ADWMIParam&gt; resultArgs;
      resultArgs.push_back(ADWMIParam(strArgName, pObject));
      return resultArgs;
  }
  
  IWbemClassObject* ADWMISearch::callStaticMethod(IWbemServices *pSvc, IWbemClassObject *pClass, CString strClassName,
                                                  CString strMethodName)
  {
      return callStaticMethod(pSvc, pClass, strClassName, strMethodName, vector&lt;ADWMIParam&gt;());
  }
  
  IWbemClassObject* ADWMISearch::callStaticMethod(IWbemServices *pSvc, IWbemClassObject *pClass, CString strClassName,
                                                  CString strMethodName, vector&lt;ADWMIParam&gt; &amp;arguments)
  {
      _bstr_t bstrClassName = _bstr_t(strClassName);
      _bstr_t bstrMethodName = _bstr_t(strMethodName);
      BOOL bInParams;
      BOOL bOutParams;
  
      HRESULT hResult;
      IWbemClassObject* pClass2 = getWMIClass(pSvc, strClassName);
  
      IWbemClassObject* pInParamsDefinition = NULL;
      IWbemClassObject* pOutParamsDefinition = NULL;
      hResult = pClass2-&gt;GetMethod(bstrMethodName, 0, &amp;pInParamsDefinition, &amp;pOutParamsDefinition);
      if (hResult != WBEM_S_NO_ERROR)
      {
          //pClass-&gt;Release();
          MyMessageBox_Error(_T("callStaticMethod"));
          return NULL;
      }
      if (pInParamsDefinition == NULL)
      {
          bInParams = FALSE;
      }
      else
      {
          bInParams = TRUE;
      }
      if (pOutParamsDefinition == NULL)
      {
          bOutParams = FALSE;
      }
      else
      {
          bOutParams = TRUE;
      }
  
      IWbemClassObject* pInParamsInstance = NULL;
      if (bInParams)
      {
          hResult = pInParamsDefinition-&gt;SpawnInstance(0, &amp;pInParamsInstance);
  
          for (int i = 0; i &lt; arguments.size(); i ++)
          {
              _variant_t varArg;
              VariantCopy(&amp;varArg, &amp;(arguments[i].value));
              hResult = pInParamsInstance-&gt;Put(_bstr_t(arguments[i].key), 0, &amp;varArg, 0);
              //hResult = pInParamsInstance-&gt;Put(_bstr_t(arguments[i].key), 0, &amp;(arguments[i].value), 0);
          }
      }
  
      IWbemClassObject* pOutParams = NULL;
      hResult = pSvc-&gt;ExecMethod(bstrClassName, bstrMethodName, 0, NULL, pInParamsInstance, &amp;pOutParams, NULL);
      if (hResult != WBEM_S_NO_ERROR)
      {
          //pClass-&gt;Release();
          if (pInParamsDefinition != NULL)
          {
              pInParamsDefinition-&gt;Release();
          }
          if (pOutParamsDefinition != NULL)
          {
              pOutParamsDefinition-&gt;Release();
          }
          if (pInParamsInstance != NULL)
          {
              pInParamsInstance-&gt;Release();
          }
          MyMessageBox_Error(_T("callStaticMethod"));
          return NULL;
      }
  
      if (pInParamsDefinition != NULL)
      {
          pInParamsDefinition-&gt;Release();
      }
      if (pOutParamsDefinition != NULL)
      {
          pOutParamsDefinition-&gt;Release();
      }
      if (pInParamsInstance != NULL)
      {
          pInParamsInstance-&gt;Release();
      }
  
      if (bOutParams)
      {
          return pOutParams;
      }
      else
      {
          return NULL;
      }
  }
  
  IWbemClassObject* ADWMISearch::callMethod(IWbemServices *pSvc, IWbemClassObject *pClass, CString strClassName,
                                            CString strInstancePath, CString strMethodName)
  {
      return callMethod(pSvc, pClass, strClassName, strInstancePath, strMethodName, vector&lt;ADWMIParam&gt;());
  }
  
  IWbemClassObject* ADWMISearch::callMethod(IWbemServices *pSvc, IWbemClassObject *pClass, CString strClassName,
                                            CString strInstancePath, CString strMethodName,  vector&lt;ADWMIParam&gt; &amp;arguments)
  {
      _bstr_t bstrClassName = _bstr_t(strClassName);
      _bstr_t bstrMethodName = _bstr_t(strMethodName);
      BOOL bInParams;
      BOOL bOutParams;
  
      HRESULT hResult;
      //IWbemClassObject* pClass = getWMIClass(pSvc, strClassName);
  
      IWbemClassObject* pInParamsDefinition = NULL;
      IWbemClassObject* pOutParamsDefinition = NULL;
      hResult = pClass-&gt;GetMethod(bstrMethodName, 0, &amp;pInParamsDefinition, &amp;pOutParamsDefinition);
      if (hResult != WBEM_S_NO_ERROR)
      {
          //pClass-&gt;Release();
          MyMessageBox_Error(_T("callMethod"));
          return NULL;
      }
      if (pInParamsDefinition == NULL)
      {
          bInParams = FALSE;
      }
      else
      {
          bInParams = TRUE;
      }
      if (pOutParamsDefinition == NULL)
      {
          bOutParams = FALSE;
      }
      else
      {
          bOutParams = TRUE;
      }
  
      IWbemClassObject* pInParamsInstance = NULL;
      if (bInParams)
      {
          hResult = pInParamsDefinition-&gt;SpawnInstance(0, &amp;pInParamsInstance);
  
          for (int i = 0; i &lt; arguments.size(); i ++)
          {
              _variant_t varArg;
              VariantCopy(&amp;varArg, &amp;(arguments[i].value));
              hResult = pInParamsInstance-&gt;Put(_bstr_t(arguments[i].key), 0, &amp;varArg, 0);
              //hResult = pInParamsInstance-&gt;Put(_bstr_t(arguments[i].key), 0, &amp;(arguments[i].value), 0);
          }
      }
  
      IWbemClassObject* pOutParams = NULL;
      hResult = pSvc-&gt;ExecMethod(_bstr_t(strInstancePath), bstrMethodName, 0, NULL, pInParamsInstance, &amp;pOutParams, NULL);
      if (hResult != WBEM_S_NO_ERROR)
      {
          //pClass-&gt;Release();
          if (pInParamsDefinition != NULL)
          {
              pInParamsDefinition-&gt;Release();
          }
          if (pOutParamsDefinition != NULL)
          {
              pOutParamsDefinition-&gt;Release();
          }
          if (pInParamsInstance != NULL)
          {
              pInParamsInstance-&gt;Release();
          }
          MyMessageBox_Error(_T("callMethod"));
          return NULL;
      }
  
      if (pInParamsDefinition != NULL)
      {
          pInParamsDefinition-&gt;Release();
      }
      if (pOutParamsDefinition != NULL)
      {
          pOutParamsDefinition-&gt;Release();
      }
      if (pInParamsInstance != NULL)
      {
          pInParamsInstance-&gt;Release();
      }
  
      if (bOutParams)
      {
          return pOutParams;
      }
      else
      {
          return NULL;
      }
  }
  
  void ADWMISearch::disconnect(IWbemServices *pSvc)
  {
      pSvc-&gt;Release();
      CoUninitialize();
  }
  </code></pre>
  
  <p>ADWMISearch.h</p>
  
  <pre><code>#include &lt;Wbemidl.h&gt;
  
  #include &lt;vector&gt;
  #include &lt;map&gt;
  using namespace std;
  
  class ADWMIParam
  {
  public:
      CString key;
      _variant_t value;
  public:
      ADWMIParam(CString strKey, CString strValue)
      {
          key = strKey;
          VariantInit(&amp;value);
          value.vt = VT_BSTR;
          value.bstrVal = _bstr_t(strValue);
      }
      ADWMIParam(CString strKey, IWbemClassObject *pValue)
      {
          key = strKey;
          VariantInit(&amp;value);
          value.vt = VT_UNKNOWN;
          value.punkVal = pValue;
      }
  };
  
  class ADWMISearch
  {
  public:
      DWORD WIN32_FROM_HRESULT_alternate(HRESULT hr);
      IWbemServices* connect(CString strServerName, CString strServerIP, CString strDomainName,
          CString strUsername, CString strPassword);
      vector&lt;IWbemClassObject*&gt; query(IWbemServices *pSvc, CString strDomainName, CString strPassword, CString strWQL);
      CString getStringFromObject(IWbemClassObject* pObject, CString strPropertyName);
      vector&lt;CString&gt; getStringsFromObjects(vector&lt;IWbemClassObject*&gt; npObjects, CString strPropertyName);
      void clearObjects(vector&lt;IWbemClassObject*&gt; npObjects);
      IWbemClassObject* getWMIClass(IWbemServices *pSvc, CString strClassName);
      IWbemClassObject* getObjectFromObject(IWbemClassObject *pObject, CString strArgumentName);
      IWbemClassObject* getObjectFromObjectWithCheck(IWbemClassObject *pOutParams, CString strArgumentName);
      vector&lt;ADWMIParam&gt; genObjectArguments(CString strArgName, IWbemClassObject *pObject);
      IWbemClassObject* callStaticMethod(IWbemServices *pSvc, IWbemClassObject *pClass, CString strClassName,
          CString strMethodName);
      IWbemClassObject* callStaticMethod(IWbemServices *pSvc, IWbemClassObject *pClass, CString strClassName,
          CString strMethodName, vector&lt;ADWMIParam&gt; &amp;arguments);
      IWbemClassObject* callMethod(IWbemServices *pSvc, IWbemClassObject *pClass, CString strClassName,
          CString strInstancePath, CString strMethodName);
      IWbemClassObject* callMethod(IWbemServices *pSvc, IWbemClassObject *pClass, CString strClassName,
          CString strInstancePath, CString strMethodName, vector&lt;ADWMIParam&gt; &amp;arguments);
      void disconnect(IWbemServices *pSvc);
  };
  </code></pre>
  
  <p>the call code(a place like main is ok)</p>
  
  <pre><code>ADWMISearch *wmiSearcher = new ADWMISearch();
  IWbemServices *pSvc = wmiSearcher-&gt;connect("luo-pc", "127.0.0.1", "", "", "");
  IWbemClassObject *pLSSSClass = wmiSearcher-&gt;getWMIClass(pSvc, "Win32_LogicalShareSecuritySetting");
  
  vector&lt;IWbemClassObject*&gt; npObjects = wmiSearcher-&gt;query(pSvc, "", "", "Select * from Win32_Log
  </code></pre>