Why is IEnumWbemClassObject->Next returning E_ACCESSDENIED

I am trying to query the WMI information on other computers on the local network.  All of the computers are running Windows XP (with SP) and are on the same local workgroup.  All of the computers have the same administrator password which has been verified by successfully connecting to each computer and mapping to the C$ share using the administrator username/password.  However, the following code works correctly on 3 out of the 4 computers.  On one of the computers the code works up until the call to enumerator->Next which failes with an HRESULT of E_ACCESSDENIED.  First of all, how could the administrator get an access denied result.  Second, why does it only get an access denied on the next and not on any of the prior calls to connect to the computer or to setup the WMI query.  Thirdly, why would this work on 3 other extremely similar computers and not the 4th?

int main(int argc,char** argv)
      HRESULT hres;
      char username[]="administrator";
      char password[]="adminPassword";
      char domain[]="";
      char wmiNamespace[]="\\\\ServerName\\ROOT\\CIMV2";

      hres =  CoInitializeEx(0, COINIT_MULTITHREADED);
      if (FAILED(hres))
            cout << "Failed to initialize COM library. Error code = 0x" << hex << hres << endl;
            return 1;                  // Program has failed.

      hres =  CoInitializeSecurity(
            -1,                          // COM authentication
            NULL,                        // Authentication services
            NULL,                        // Reserved
            RPC_C_AUTHN_LEVEL_DEFAULT,   // Default authentication
            RPC_C_IMP_LEVEL_IMPERSONATE, // Default Impersonation  
            NULL,                        // Authentication info
            EOAC_NONE,                   // Additional capabilities
            NULL                         // Reserved
    if (FAILED(hres)) {
        cout << "Failed to initialize security. Error code = 0x" << hex << hres << endl;
        return 1;                    // Program has failed.

      IWbemLocator *pLoc = NULL;
      hres = CoCreateInstance( CLSID_WbemLocator,0, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID *) &pLoc);
      if (FAILED(hres))
            cout << "Failed to create IWbemLocator object." << " Err code = 0x" << hex << hres << endl;
            return 1;                 // Program has failed.

      IWbemServices *pSvc = NULL;
      hres = pLoc->ConnectServer(
            T2W(wmiNamespace),                              // Object path of WMI namespace
            T2W(username),                    // User name. NULL = current user
            T2W(password),                    // User password. NULL = current
            0,                       // Locale. NULL indicates current              
            WBEM_FLAG_CONNECT_USE_MAX_WAIT,                    // Security flags.
            0,                       // Authority (e.g. Kerberos)        
            0,                       // Context object
            &pSvc                    // pointer to IWbemServices proxy

      if (FAILED(hres))
            cout << "Could not connect. Error code = 0x" << hex << hres << endl;
            return 1;                // Program has failed.

      cout << "Connected to ROOT\\CIMV2 WMI namespace" << endl;

      SEC_WINNT_AUTH_IDENTITY        authidentity;
      SecureZeroMemory( &authidentity, sizeof(authidentity) );
      authidentity.User = (LPUSTR)T2W( (LPTSTR)(LPCTSTR)username);
      authidentity.UserLength = strlen(username);
      authidentity.Domain = (LPUSTR)T2W( (LPTSTR)(LPCTSTR)domain);
      authidentity.DomainLength = strlen(domain );
      authidentity.Password = (LPUSTR)T2W( (LPTSTR)(LPCTSTR)password);
      authidentity.PasswordLength = strlen(password );
      authidentity.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;

      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
            &authidentity,                        // client identity
            EOAC_NONE                    // proxy capabilities

      if (FAILED(hres))
            cout << "Could not set proxy blanket. Error code = 0x" << hex << hres << endl;
            return 1;               // Program has failed.

      IEnumWbemClassObject* pEnumerator = NULL;
      hres = pSvc->ExecQuery( bstr_t("WQL"),
            bstr_t("SELECT * FROM Win32_Desktop"),
      if (FAILED(hres))
            cout << "Query for operating system name failed."
                  << " Error code = 0x"
                  << hex << hres << endl;
            return 1;               // Program has failed.

      IWbemClassObject *pclsObj=NULL;
      ULONG uReturn = 0;
      while (pEnumerator)
            HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);
            if(0 == uReturn) break;
            VARIANT vtProp;
            hr = pclsObj->Get(L"ScreenSaverExecutable", 0, &vtProp, 0, 0);    
            cout << "Executable: ";
            char* executableName = W2T(vtProp.bstrVal);
            cout << executableName;
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

>> First of all, how could the administrator get an access denied result.
Administrator accounts do not have access rights to everything on Windows just because they are administrators. It's possible to remove access rights even for adminstrators from files, directories (i.e. by default no access to /System Volume Information) or registry subtrees (i.e. cannot write to HKLM\SYSTEM\CurrentControlSet\Enum\Root by default). Although Administrators can modify all access rights they want and as a consequence of this gain access to everything. Revoking administrators (i.e. your own) access rights is sometimes actually quite usefull, i.e. to prevent programs (or malwale) from modifying certain files or registry entries.
gmainAuthor Commented:
Just as added info, the following VBScript works on all of the machines:

Set objSWbemLocator = CreateObject("WbemScripting.SWbemLocator")
Set objWMIService = objSWbemLocator.ConnectServer("computerName", _
    "root\CIMV2", "Administrator", "AdminPassword",NULL,NULL)
Set colItems = objWMIService.ExecQuery("SELECT * FROM Win32_Desktop",,48)

For Each objItem in colItems
    Wscript.Echo "ScreenSaverExecutable: " & objItem.ScreenSaverExecutable

The key now is to get this same functionality to work in C++ code
gmainAuthor Commented:
In an effort to discover the reason for the E_ACCESSDENIED, I have done the following on the computer where the Next operation fails:
   - Ran WmiMgmt.msc and verified that the administrators group has full access to the CIMV2 namespace
   - Enabled WMI verbose logging (in WmiMgmt.msc) and ran the C++ code again and no errors appeared in the generated logs
Cloud Class® Course: MCSA MCSE Windows Server 2012

This course teaches how to install and configure Windows Server 2012 R2.  It is the first step on your path to becoming a Microsoft Certified Solutions Expert (MCSE).

gmainAuthor Commented:
Figured out the problem.... per a Microsoft website, you MUST call CoSetProxyBlanket on EVERY interface you retrieve.  This would include the enumerator class.  Once I successfully called that on the enumerator object I no longer got the E_ACCESSDENIED return from the next function.
I'm happy that gmain found a solution to his problem and refunding the points is perfectly o.k. for me.
PAQ-ing the question and refunding 500 points

Thanks x4u !

The Experts Exchange
Community Support Moderator of all Ages

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.