You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
516 lines
19 KiB
516 lines
19 KiB
#include <nt.h>
|
|
#include <ntrtl.h>
|
|
#include <nturtl.h>
|
|
#include <windows.h>
|
|
|
|
#include <netsh.h>
|
|
#include "objbase.h"
|
|
#include "Wbemidl.h"
|
|
#include "wincred.h"
|
|
|
|
extern "C"
|
|
{
|
|
UINT g_CIMOSType = 0;
|
|
UINT g_CIMOSProductSuite = 0;
|
|
UINT g_CIMProcessorArchitecture = 0;
|
|
WCHAR g_CIMOSVersion[MAX_PATH];
|
|
WCHAR g_CIMOSBuildNumber[MAX_PATH];
|
|
WCHAR g_CIMServicePackMajorVersion[MAX_PATH];
|
|
WCHAR g_CIMServicePackMinorVersion[MAX_PATH];
|
|
BOOL g_CIMAttempted = FALSE;
|
|
BOOL g_CIMSucceeded = FALSE;
|
|
|
|
HRESULT WINAPI UpdateVersionInfoGlobals(LPCWSTR pwszMachine, LPCWSTR pwszUserName, LPCWSTR pwszPassword);
|
|
}
|
|
|
|
//
|
|
// SetSecurity - set the Proxy Blanket on an IUnknown* interface so that it can be used by WMI
|
|
// cross-machine calls.
|
|
//
|
|
// Okay for any of pwszDomainName, pwszUserName or pwszPassword to be NULL.
|
|
//
|
|
// deonb 12/20/2001
|
|
//
|
|
HRESULT WINAPI SetSecurity(IN OUT IUnknown* pUnk, IN USHORT* pwszDomainName, IN USHORT* pwszUserName, IN USHORT* pwszPassword)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
COAUTHIDENTITY authident;
|
|
authident.Domain = pwszDomainName;
|
|
authident.DomainLength = pwszDomainName ? wcslen(pwszDomainName) : 0;
|
|
authident.Password = pwszPassword;
|
|
authident.PasswordLength = pwszPassword ? wcslen(pwszPassword) : 0;
|
|
authident.User = pwszUserName;
|
|
authident.UserLength = pwszUserName ? wcslen(pwszUserName) : 0;
|
|
authident.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;
|
|
|
|
hr = CoSetProxyBlanket(pUnk,
|
|
RPC_C_AUTHN_WINNT,
|
|
RPC_C_AUTHZ_NONE,
|
|
NULL,
|
|
RPC_C_AUTHN_LEVEL_PKT,
|
|
RPC_C_IMP_LEVEL_IMPERSONATE,
|
|
&authident,
|
|
EOAC_NONE);
|
|
|
|
return hr;
|
|
}
|
|
|
|
#define FImplies(a,b) (!(a) || (b))
|
|
|
|
HRESULT WINAPI
|
|
UpdateVersionInfoGlobalsFromWMI(LPCWSTR pwszMachine, LPCWSTR pwszUserName, LPCWSTR pwszPassword)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
g_CIMAttempted = TRUE;
|
|
g_CIMSucceeded = FALSE;
|
|
|
|
hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
|
|
if (FAILED(hr) && (RPC_E_CHANGED_MODE != hr))
|
|
{
|
|
return hr;
|
|
}
|
|
|
|
// Create an instance of the WbemLocator interface.
|
|
IWbemLocator *pIWbemLocator = NULL;
|
|
hr = CoCreateInstance(CLSID_WbemLocator,
|
|
NULL,
|
|
CLSCTX_INPROC_SERVER,
|
|
IID_IWbemLocator,
|
|
(LPVOID *) &pIWbemLocator);
|
|
|
|
if (FAILED(hr))
|
|
{
|
|
return hr;
|
|
}
|
|
|
|
IWbemServices *pIWbemServices;
|
|
// If already connected, release m_pIWbemServices.
|
|
// Using the locator, connect to CIMOM in the given namespace.
|
|
|
|
|
|
BSTR pNamespace = NULL;
|
|
BSTR pDomain = NULL;
|
|
BSTR pUserName = NULL;
|
|
BSTR pFQUserName= NULL;
|
|
BSTR pPassword = NULL;
|
|
|
|
do
|
|
{
|
|
WCHAR szPath[MAX_PATH];
|
|
wsprintf(szPath, L"\\\\%s\\root\\cimv2", !pwszMachine ? L"." : pwszMachine);
|
|
|
|
pNamespace = SysAllocString(szPath);
|
|
if ( (szPath) && (!pNamespace) )
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
break;
|
|
}
|
|
|
|
if (pwszUserName)
|
|
{
|
|
WCHAR szUserNameExtract[MAX_PATH];
|
|
WCHAR szDomainNameExtract[MAX_PATH];
|
|
|
|
// Break a domain\username type of username up into a seperate domain and username
|
|
// It doesn't do this for username@domain format, but it doesn't matter since
|
|
// the API using this (CoSetProxyBlanket) accepts names in username@domain format
|
|
DWORD dwErr = CredUIParseUserName(pwszUserName, szUserNameExtract, MAX_PATH, szDomainNameExtract, MAX_PATH);
|
|
hr = HRESULT_FROM_WIN32(dwErr);
|
|
if (FAILED(hr))
|
|
{
|
|
break;
|
|
}
|
|
|
|
pDomain = SysAllocString(szDomainNameExtract);
|
|
pUserName = SysAllocString(szUserNameExtract);
|
|
pFQUserName = SysAllocString(pwszUserName);
|
|
if ( (!FImplies(szDomainNameExtract, pDomain)) ||
|
|
(!FImplies(szUserNameExtract, pUserName)) ||
|
|
(!FImplies(pwszUserName, pFQUserName)) )
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
break;
|
|
}
|
|
}
|
|
|
|
pPassword = SysAllocString(pwszPassword);
|
|
if (!FImplies(pwszPassword, pPassword))
|
|
{
|
|
hr = E_OUTOFMEMORY;
|
|
break;
|
|
}
|
|
} while (FALSE);
|
|
|
|
if (FAILED(hr))
|
|
{
|
|
SysFreeString(pPassword);
|
|
SysFreeString(pUserName);
|
|
SysFreeString(pFQUserName);
|
|
SysFreeString(pDomain);
|
|
SysFreeString(pNamespace);
|
|
return hr;
|
|
}
|
|
|
|
hr = pIWbemLocator->ConnectServer(pNamespace,
|
|
pFQUserName, // username
|
|
pPassword, // password
|
|
0L, // locale
|
|
0L, // securityFlags
|
|
NULL, // authority (domain for NTLM)
|
|
NULL, // context
|
|
&pIWbemServices);
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = SetSecurity(pIWbemServices, pDomain, pUserName, pPassword);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
IEnumWbemClassObject *pEnum = NULL;
|
|
BSTR bstrWQL = SysAllocString(L"WQL");
|
|
BSTR bstrPath = SysAllocString(L"select * from Win32_OperatingSystem");
|
|
|
|
VARIANT varOSType;
|
|
VARIANT varOSVersion;
|
|
VARIANT varOSProductSuite;
|
|
VARIANT varOSBuildNumber;
|
|
VARIANT varServicePackMajorVersion;
|
|
VARIANT varServicePackMinorVersion;
|
|
VARIANT varArchitecture;
|
|
|
|
hr = pIWbemServices->ExecQuery(bstrWQL, bstrPath, WBEM_FLAG_FORWARD_ONLY, NULL, &pEnum);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = SetSecurity(pEnum, pDomain, pUserName, pPassword);
|
|
}
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
IWbemClassObject *pNSClass;
|
|
ULONG uReturned;
|
|
hr = pEnum->Next(WBEM_INFINITE, 1, &pNSClass, &uReturned );
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
if (uReturned)
|
|
{
|
|
do
|
|
{
|
|
g_CIMSucceeded = TRUE;
|
|
CIMTYPE ctpeType;
|
|
hr = pNSClass->Get(L"OSType", NULL, &varOSType, &ctpeType, NULL);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = VariantChangeType(&varOSType, &varOSType, 0, VT_UINT);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
g_CIMOSType = varOSType.uintVal;
|
|
}
|
|
}
|
|
if (FAILED(hr))
|
|
{
|
|
g_CIMSucceeded = FALSE;
|
|
break;
|
|
}
|
|
|
|
hr = pNSClass->Get(L"Version", NULL, &varOSVersion, &ctpeType, NULL);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = VariantChangeType(&varOSVersion, &varOSVersion, 0, VT_BSTR);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
wcscpy(g_CIMOSVersion, varOSVersion.bstrVal);
|
|
}
|
|
}
|
|
if (FAILED(hr))
|
|
{
|
|
g_CIMSucceeded = FALSE;
|
|
break;
|
|
}
|
|
|
|
hr = pNSClass->Get(L"OSProductSuite", NULL, &varOSProductSuite, &ctpeType, NULL);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
//
|
|
// if the return type is VT_NULL, leave g_CIMOSProductSuite value alone (0)
|
|
if (VT_NULL != varOSProductSuite.vt)
|
|
{
|
|
hr = VariantChangeType(&varOSProductSuite, &varOSProductSuite, 0, VT_UINT);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
g_CIMOSProductSuite = varOSProductSuite.uintVal;
|
|
}
|
|
}
|
|
}
|
|
if (FAILED(hr))
|
|
{
|
|
g_CIMSucceeded = FALSE;
|
|
break;
|
|
}
|
|
|
|
hr = pNSClass->Get(L"BuildNumber", NULL, &varOSBuildNumber, &ctpeType, NULL);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = VariantChangeType(&varOSBuildNumber, &varOSBuildNumber, 0, VT_BSTR);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
wcscpy(g_CIMOSBuildNumber, varOSBuildNumber.bstrVal);
|
|
}
|
|
}
|
|
if (FAILED(hr))
|
|
{
|
|
g_CIMSucceeded = FALSE;
|
|
break;
|
|
}
|
|
|
|
hr = pNSClass->Get(L"ServicePackMajorVersion", NULL, &varServicePackMajorVersion, &ctpeType, NULL);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = VariantChangeType(&varServicePackMajorVersion, &varServicePackMajorVersion, 0, VT_BSTR);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
wcscpy(g_CIMServicePackMajorVersion, varServicePackMajorVersion.bstrVal);
|
|
}
|
|
}
|
|
if (FAILED(hr))
|
|
{
|
|
g_CIMSucceeded = FALSE;
|
|
break;
|
|
}
|
|
|
|
hr = pNSClass->Get(L"ServicePackMinorVersion", NULL, &varServicePackMinorVersion, &ctpeType, NULL);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = VariantChangeType(&varServicePackMinorVersion, &varServicePackMinorVersion, 0, VT_BSTR);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
wcscpy(g_CIMServicePackMinorVersion, varServicePackMinorVersion.bstrVal);
|
|
}
|
|
}
|
|
if (FAILED(hr))
|
|
{
|
|
g_CIMSucceeded = FALSE;
|
|
break;
|
|
}
|
|
}
|
|
while (FALSE);
|
|
}
|
|
else
|
|
{
|
|
hr = E_UNEXPECTED;
|
|
}
|
|
pNSClass->Release();
|
|
}
|
|
pEnum->Release();
|
|
}
|
|
|
|
SysFreeString(bstrPath);
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
bstrPath = SysAllocString(L"select * from Win32_Processor");
|
|
|
|
hr = pIWbemServices->ExecQuery(bstrWQL, bstrPath, WBEM_FLAG_FORWARD_ONLY, NULL, &pEnum);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = SetSecurity(pEnum, pDomain, pUserName, pPassword);
|
|
}
|
|
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
IWbemClassObject *pNSClass;
|
|
ULONG uReturned;
|
|
hr = pEnum->Next(WBEM_INFINITE, 1, &pNSClass, &uReturned );
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
if (uReturned)
|
|
{
|
|
CIMTYPE ctpeType;
|
|
hr = pNSClass->Get(L"Architecture", NULL, &varArchitecture, &ctpeType, NULL);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
hr = VariantChangeType(&varArchitecture, &varArchitecture,
|
|
0, VT_UINT);
|
|
if (SUCCEEDED(hr))
|
|
{
|
|
g_CIMProcessorArchitecture = varArchitecture.uintVal;
|
|
}
|
|
else
|
|
{
|
|
g_CIMSucceeded = FALSE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
g_CIMSucceeded = FALSE;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
hr = E_UNEXPECTED;
|
|
}
|
|
pNSClass->Release();
|
|
}
|
|
pEnum->Release();
|
|
}
|
|
SysFreeString(bstrPath);
|
|
}
|
|
|
|
SysFreeString(bstrWQL);
|
|
pIWbemServices->Release();
|
|
} //hr = CoSetProxyBlanket(pIWbemServices.., if (SUCCEEDED(hr))
|
|
|
|
} //hr = pIWbemLocator->ConnectServer.., if (SUCCEEDED(hr))
|
|
SysFreeString(pPassword);
|
|
SysFreeString(pUserName);
|
|
SysFreeString(pFQUserName);
|
|
SysFreeString(pDomain);
|
|
SysFreeString(pNamespace);
|
|
|
|
CoUninitialize();
|
|
|
|
// Translate any WMI errors into Win32 errors:
|
|
switch (hr)
|
|
{
|
|
case WBEM_E_NOT_FOUND:
|
|
hr = HRESULT_FROM_WIN32(ERROR_HOST_UNREACHABLE);
|
|
break;
|
|
|
|
case WBEM_E_ACCESS_DENIED:
|
|
hr = E_ACCESSDENIED;
|
|
break;
|
|
|
|
case WBEM_E_PROVIDER_FAILURE:
|
|
hr = E_FAIL;
|
|
break;
|
|
|
|
case WBEM_E_TYPE_MISMATCH:
|
|
case WBEM_E_INVALID_CONTEXT:
|
|
case WBEM_E_INVALID_PARAMETER:
|
|
hr = E_INVALIDARG;
|
|
break;
|
|
|
|
case WBEM_E_OUT_OF_MEMORY:
|
|
hr = E_OUTOFMEMORY;
|
|
break;
|
|
|
|
}
|
|
|
|
if ( (hr == S_OK) && (!g_CIMSucceeded) )
|
|
{
|
|
return E_FAIL;
|
|
}
|
|
else
|
|
{
|
|
return hr;
|
|
}
|
|
}
|
|
|
|
HRESULT WINAPI
|
|
UpdateVersionInfoGlobalsFromLocalMachine()
|
|
{
|
|
HRESULT hr = S_OK;
|
|
BOOL fFailed = FALSE;
|
|
|
|
do
|
|
{
|
|
OSVERSIONINFOEX osv;
|
|
ZeroMemory(&osv, sizeof(OSVERSIONINFOEX));
|
|
osv.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
|
|
|
|
if (!GetVersionEx( reinterpret_cast<LPOSVERSIONINFO>(&osv)))
|
|
{
|
|
fFailed = TRUE;
|
|
break;
|
|
}
|
|
|
|
g_CIMOSType = 18; // WINNT
|
|
g_CIMOSProductSuite = osv.wSuiteMask;
|
|
|
|
#if defined(_X86_)
|
|
g_CIMProcessorArchitecture = 0;
|
|
#elif defined(_IA64_)
|
|
g_CIMProcessorArchitecture = 6;
|
|
#else
|
|
fFailed = TRUE;
|
|
break;
|
|
#endif
|
|
wsprintf(g_CIMOSVersion, L"%d.%d.%d", osv.dwMajorVersion, osv.dwMinorVersion, osv.dwBuildNumber);
|
|
wsprintf(g_CIMOSBuildNumber, L"%d", osv.dwBuildNumber);
|
|
wsprintf(g_CIMServicePackMajorVersion, L"%d", osv.wServicePackMajor);
|
|
wsprintf(g_CIMServicePackMinorVersion, L"%d", osv.wServicePackMinor);
|
|
|
|
g_CIMSucceeded = TRUE;
|
|
g_CIMAttempted = TRUE;
|
|
|
|
} while (FALSE);
|
|
|
|
if (fFailed)
|
|
{
|
|
return UpdateVersionInfoGlobalsFromWMI(NULL, NULL, NULL);
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
HRESULT WINAPI
|
|
UpdateVersionInfoGlobals(LPCWSTR pwszMachine, LPCWSTR pwszUserName, LPCWSTR pwszPassword)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
HRESULT hrWMI = S_OK;
|
|
if (pwszMachine)
|
|
{
|
|
return UpdateVersionInfoGlobalsFromWMI(pwszMachine, pwszUserName, pwszPassword);
|
|
}
|
|
else // Resolve locally
|
|
{
|
|
hr = UpdateVersionInfoGlobalsFromLocalMachine();
|
|
#ifdef DBG
|
|
UINT CIMOSType = g_CIMOSType;
|
|
UINT CIMOSProductSuite = g_CIMOSProductSuite;
|
|
UINT CIMProcessorArchitecture = g_CIMProcessorArchitecture;
|
|
|
|
WCHAR CIMOSVersion[MAX_PATH];
|
|
WCHAR CIMOSBuildNumber[MAX_PATH];
|
|
WCHAR CIMServicePackMajorVersion[MAX_PATH];
|
|
WCHAR CIMServicePackMinorVersion[MAX_PATH];
|
|
wcsncpy(CIMOSVersion, g_CIMOSVersion, MAX_PATH);
|
|
wcsncpy(CIMOSBuildNumber, g_CIMOSBuildNumber, MAX_PATH);
|
|
wcsncpy(CIMServicePackMajorVersion, g_CIMServicePackMajorVersion, MAX_PATH);
|
|
wcsncpy(CIMServicePackMinorVersion, g_CIMServicePackMinorVersion, MAX_PATH);
|
|
|
|
hrWMI = UpdateVersionInfoGlobalsFromWMI(pwszMachine, NULL, NULL);
|
|
if(SUCCEEDED(hr) && SUCCEEDED(hrWMI))
|
|
{
|
|
if ( (CIMOSType != g_CIMOSType) ||
|
|
( (CIMOSProductSuite & ~VER_SUITE_SINGLEUSERTS) != (g_CIMOSProductSuite & ~VER_SUITE_SINGLEUSERTS) ) ||
|
|
(CIMProcessorArchitecture != g_CIMProcessorArchitecture) ||
|
|
(0 != wcsncmp(CIMOSVersion, g_CIMOSVersion, MAX_PATH)) ||
|
|
(0 != wcsncmp(CIMOSBuildNumber, g_CIMOSBuildNumber, MAX_PATH)) ||
|
|
(0 != wcsncmp(CIMServicePackMajorVersion, g_CIMServicePackMajorVersion, MAX_PATH)) ||
|
|
(0 != wcsncmp(CIMServicePackMinorVersion, g_CIMServicePackMinorVersion, MAX_PATH)) )
|
|
{
|
|
WCHAR szAssertText[4096];
|
|
wsprintf(szAssertText, L"NETSH.EXE: ASSERT - mismatch between GetVersionInfoEx and WMI information:\r\n"
|
|
L"CIMOSType: %x vs. %x\r\n"
|
|
L"CIMOSProductSuite: %x vs. %x\r\n"
|
|
L"CIMProcessorArchitecture: %x vs %x\r\n"
|
|
L"CIMOSVersion: %s vs. %s\r\n"
|
|
L"CIMOSBuildNumber: %s vs. %s\r\n"
|
|
L"CIMServicePackMajorVersion: %s vs. %s\r\n"
|
|
L"CIMServicePackMinorVersion: %s vs. %s\r\n",
|
|
CIMOSType, g_CIMOSType,
|
|
CIMOSProductSuite, g_CIMOSProductSuite,
|
|
CIMProcessorArchitecture, g_CIMProcessorArchitecture,
|
|
CIMOSVersion, g_CIMOSVersion,
|
|
CIMOSBuildNumber, g_CIMOSBuildNumber,
|
|
CIMServicePackMajorVersion, g_CIMServicePackMajorVersion,
|
|
CIMServicePackMinorVersion, g_CIMServicePackMinorVersion);
|
|
|
|
ASSERTMSG((PCHAR)(szAssertText), FALSE);
|
|
}
|
|
}
|
|
#endif
|
|
return hr;
|
|
}
|
|
}
|