executifs
executifs

Reputation: 1178

How to use the "__ProviderArchitecture" flag of IWbemContext in c?

I've been trying to follow the following MSDN tutorial to query the 64 bit registry provider from a 32 bit application.

Sadly, the examples are all written in VB, and I'm stuck with something.

For C++ developers, the article mentions that...

C++ applications can use the IWbemContext interface with IWbemServices::ExecMethod to communicate the use of a nondefault provider to WMI.

...although, when you look at the sample VB code, the context object is also used in the ConnectServer method:

Set objCtx = CreateObject("WbemScripting.SWbemNamedValueSet")
objCtx.Add "__ProviderArchitecture", 32
Set objLocator = CreateObject("Wbemscripting.SWbemLocator")
Set objServices = objLocator.ConnectServer("","root\default","","",,,,objCtx)
Set objStdRegProv = objServices.Get("StdRegProv") 

I've tried reproducing this in VC++:

HRESULT res;
CComPtr<IWbemContext> ctx;
if (!create_registry_redirection_context_(hive, ctx)) {
    return false;
}

res = locator_->ConnectServer(CComBSTR(namespace_.c_str()),     // Namespace to use
                              0,                                // Current security context (username)
                              0,                                // Current security context (password)
                              0,                                // Use current locale
                              WBEM_FLAG_CONNECT_USE_MAX_WAIT,   // Return if connexion is unsuccessful after 2 minutes
                              0,                                // Name of the domain  of the user to authenticate
                              ctx,                              // Optional context
                              &service_);                       // Fill this pointer

The create_registry_redirection_context_ method uses CoCreateInstance to instantiate my context, and I use the following lines to set the architecture:

CComVariant value_arch(64, VT_I4);
ctx->SetValue(L"__ProviderArchitecture", 0, &value_arch);

Now the problem is, the ConnectServer method returns an error (0x80041008 - WMI Invalid Parameter). If I comment out the ctx->SetValue(L"__ProviderArchitecture", 0, &value_arch); line, everything works properly, but of course, I end up querying the 32 bit registry provider.

I've also tried not setting any context during the ConnectServer call, but only during the ExecMethod call (as specified in the MSDN article), but although I don't get any error, I'm still querying the 32 bit provider, and not seeing my 64bit registry keys.

What am I doing wrong? Thanks in advance for your time.

Upvotes: 3

Views: 1369

Answers (2)

max_payne
max_payne

Reputation: 1

I know, it's a little bit late, but for archive (and because MS is unable to provide such a sample):

  HRESULT hres;
  IWbemLocator *pLoc = NULL;
  hres = CoCreateInstance(CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID *) &pLoc); 
  if (FAILED(hres))
  {
    m_nExitCode = TCP1;
    return FALSE;
  }

  IWbemContext *pContext = NULL;
  hres = CoCreateInstance(CLSID_WbemContext, 0, CLSCTX_INPROC_SERVER, IID_IWbemContext, (LPVOID *) &pContext); 
  if (FAILED(hres))
  {
    m_nExitCode = TCP1_2;
    return FALSE;
  }

  VARIANT vArchitecture;
  VariantInit(&vArchitecture);
  V_VT(&vArchitecture) = VT_I4;
  V_INT(&vArchitecture) = 64;
  hres = pContext->SetValue(_bstr_t(L"__ProviderArchitecture"), 0, &vArchitecture);
  VariantClear(&vArchitecture);

  //VARIANT vRequiredArchicture;
  //VariantInit(&vRequiredArchicture);
  //V_VT(&vRequiredArchicture) = VT_BOOL;
  //V_BOOL(&vRequiredArchicture) = VARIANT_TRUE;
  //hres = pContext->SetValue(_bstr_t(L"__RequiredArchitecture"), 0, &vRequiredArchicture);
  //VariantClear(&vRequiredArchicture);

  IWbemServices *pSvc = NULL;

  hres = pLoc->ConnectServer(
     _bstr_t(L"root\\Microsoft\\SqlServer\\ComputerManagement10"), // Object path of WMI namespace
     NULL,                    // User name. NULL = current user
     NULL,                    // User password. NULL = current
     0,                       // Locale. NULL indicates current
     NULL,                    // Security flags.
     0,                       // Authority (for example, Kerberos)
     pContext,               // Context object 
     &pSvc                    // pointer to IWbemServices proxy
     );

The block with RequiredArchitecture is untested and seems to be unnecessary. PS: Error-handling needs to be improved!

Upvotes: 0

Dan
Dan

Reputation: 2109

have you looked at http://msdn.microsoft.com/en-us/library/windows/desktop/aa393067(v=vs.85).aspx and tried setting "__RequiredArchitecture" = TRUE as well?

Also have to tried to get it to work in the way that the same code shows ( ie 64 bit to 32 bit) first?

Upvotes: 0

Related Questions