Leaked source code of windows server 2003
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

#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;
}
}