#define _WIN32_DCOM
#include <iostream>
#include <clocale>
using namespace std;
#define _WIN32_WINNT 0x600
#include <comdef.h>
#include <Wbemidl.h>
# pragma comment(lib, "wbemuuid.lib")
#ifdef NDEBUG
# pragma comment(lib,"comsuppw.lib")
#else
# pragma comment(lib,"comsuppwd.lib")
#endif
//CREDENTIAL structure
//http://msdn.microsoft.com/en-us/library/windows/desktop/aa374788%28v=vs.85%29.aspx
#define CRED_MAX_USERNAME_LENGTH 513
#define CRED_MAX_CREDENTIAL_BLOB_SIZE 512
#define CREDUI_MAX_USERNAME_LENGTH CRED_MAX_USERNAME_LENGTH
#define CREDUI_MAX_PASSWORD_LENGTH (CRED_MAX_CREDENTIAL_BLOB_SIZE / 2)
_COM_SMARTPTR_TYPEDEF(IWbemLocator, __uuidof(IWbemLocator));
_COM_SMARTPTR_TYPEDEF(IWbemServices, __uuidof(IWbemServices));
_COM_SMARTPTR_TYPEDEF(IEnumWbemClassObject, __uuidof(IEnumWbemClassObject));
_COM_SMARTPTR_TYPEDEF(IWbemClassObject, __uuidof(IWbemClassObject));
struct CComError
{
HRESULT hr;
const char *msg;
};
struct CCoInitializeEx
{
HRESULT hr;
CCoInitializeEx(DWORD dwCoInit)
{
hr = CoInitializeEx(nullptr, dwCoInit);
}
~CCoInitializeEx()
{
if (SUCCEEDED(hr))
CoUninitialize();
}
};
#define HRCHECK(what, msg) { HRESULT hr = what; if FAILED(hr) throw CComError { hr, msg }; }
int main(int argc, char* argv[])
{
setlocale(LC_CTYPE, ".ACP");
wchar_t pszName[CREDUI_MAX_USERNAME_LENGTH + 1] = L"user";
wchar_t pszPwd[CREDUI_MAX_PASSWORD_LENGTH + 1] = L"password";
BSTR strNetworkResource;
//To use a WMI remote connection set localconn to false and configure the values of the pszName, pszPwd and the name of the remote machine in strNetworkResource
bool localconn = true;
strNetworkResource = localconn ? L"\\\\.\\root\\CIMV2" : L"\\\\remote--machine\\root\\CIMV2";
COAUTHIDENTITY *userAcct = NULL;
COAUTHIDENTITY authIdent;
HRESULT hres;
try
{
// Initialize COM. ------------------------------------------
CCoInitializeEx coinit(COINIT_MULTITHREADED);
HRCHECK(coinit.hr, "Failed to initialize COM library.");
// Set general COM security levels --------------------------
DWORD impLevel = localconn ? RPC_C_IMP_LEVEL_IMPERSONATE : RPC_C_IMP_LEVEL_IDENTIFY;
hres = CoInitializeSecurity(
NULL,
-1, // COM authentication
NULL, // Authentication services
NULL, // Reserved
RPC_C_AUTHN_LEVEL_DEFAULT, // Default authentication
impLevel, // Default Impersonation
NULL, // Authentication info
EOAC_NONE, // Additional capabilities
NULL // Reserved
);
HRCHECK(hres, "Failed to initialize security.");
// Obtain the initial locator to WMI -------------------------
IWbemLocatorPtr pLoc;
hres = pLoc.CreateInstance(CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER);
HRCHECK(hres, "Failed to create IWbemLocator object.");
// Connect to WMI through the IWbemLocator::ConnectServer method
IWbemServicesPtr pSvc;
if (localconn)
hres = pLoc->ConnectServer(
_bstr_t(strNetworkResource), // 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 (e.g. Kerberos)
0, // Context object
&pSvc // pointer to IWbemServices proxy
);
else
hres = pLoc->ConnectServer(
_bstr_t(strNetworkResource), // Object path of WMI namespace
_bstr_t(pszName), // User name
_bstr_t(pszPwd), // User password
NULL, // Locale
NULL, // Security flags
NULL, // Authority
NULL, // Context object
&pSvc // IWbemServices proxy
);
HRCHECK(hres, "Could not connect.");
cout << "Connected to root\\CIMV2 WMI namespace" << endl;
// Set security levels on the proxy -------------------------
if (localconn)
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
);
else
{
// Create COAUTHIDENTITY that can be used for setting security on proxy
memset(&authIdent, 0, sizeof(COAUTHIDENTITY));
authIdent.PasswordLength = wcslen(pszPwd);
authIdent.Password = (USHORT*)pszPwd;
authIdent.User = (USHORT*)pszName;
authIdent.UserLength = wcslen(pszName);
authIdent.Domain = 0;
authIdent.DomainLength = 0;
authIdent.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;
userAcct = &authIdent;
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
);
}
HRCHECK(hres, "Could not set proxy blanket.");
// Use the IWbemServices pointer to make requests of WMI ----
IEnumWbemClassObjectPtr pEnumerator;
hres = pSvc->ExecQuery(L"WQL", L"SELECT * FROM Win32_NetworkAdapterConfiguration",
WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, NULL, &pEnumerator);
HRCHECK(hres, "ExecQuery failed");
// Secure the enumerator proxy
if (!localconn)
{
hres = 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
);
HRCHECK(hres, "Could not set proxy blanket on enumerator.");
}
while (pEnumerator)
{
// Get the data from the WQL sentence
IWbemClassObjectPtr pclsObj;
ULONG uReturn = 0;
HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, &pclsObj, &uReturn);
if (0 == uReturn || FAILED(hr))
break;
_variant_t vtProp;
hr = pclsObj->Get(L"IPAddress", 0, &vtProp, 0, 0);// String
if (SUCCEEDED(hr))
{
if (vtProp.vt == VT_NULL)
wcout << "IPAddress : NULL" << endl;
else if (vtProp.vt == VT_EMPTY)
wcout << "IPAddress : EMPTY" << endl;
else if ((vtProp.vt & VT_ARRAY))
{
SAFEARRAY *psa = vtProp.parray;
if (psa)
{
LONG uBound = -1, lBound = 0;
SafeArrayGetUBound(psa, 1, &uBound);
SafeArrayGetLBound(psa, 1, &lBound);
int nCount = uBound - lBound + 1;
for (long i = 0; i < nCount; ++i)
{
BSTR element;
SafeArrayGetElement(psa, &i, &element);
wcout << element << endl;
}
}
}
else
wcout << "IPAddress : " << vtProp.bstrVal << endl;
}
}
// Cleanup
return 0; // Program successfully completed.
}
catch (CComError err)
{
cout << err.msg << " Error code = 0x" << hex << err.hr << endl;
wcout << _com_error(err.hr).ErrorMessage() << endl;
cout << "press enter to exit" << endl;
cin.get();
return 1; // Program has failed.
}
}