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

  1. #include <nt.h>
  2. #include <ntrtl.h>
  3. #include <nturtl.h>
  4. #include <windows.h>
  5. #include <netsh.h>
  6. #include "objbase.h"
  7. #include "Wbemidl.h"
  8. #include "wincred.h"
  9. extern "C"
  10. {
  11. UINT g_CIMOSType = 0;
  12. UINT g_CIMOSProductSuite = 0;
  13. UINT g_CIMProcessorArchitecture = 0;
  14. WCHAR g_CIMOSVersion[MAX_PATH];
  15. WCHAR g_CIMOSBuildNumber[MAX_PATH];
  16. WCHAR g_CIMServicePackMajorVersion[MAX_PATH];
  17. WCHAR g_CIMServicePackMinorVersion[MAX_PATH];
  18. BOOL g_CIMAttempted = FALSE;
  19. BOOL g_CIMSucceeded = FALSE;
  20. HRESULT WINAPI UpdateVersionInfoGlobals(LPCWSTR pwszMachine, LPCWSTR pwszUserName, LPCWSTR pwszPassword);
  21. }
  22. //
  23. // SetSecurity - set the Proxy Blanket on an IUnknown* interface so that it can be used by WMI
  24. // cross-machine calls.
  25. //
  26. // Okay for any of pwszDomainName, pwszUserName or pwszPassword to be NULL.
  27. //
  28. // deonb 12/20/2001
  29. //
  30. HRESULT WINAPI SetSecurity(IN OUT IUnknown* pUnk, IN USHORT* pwszDomainName, IN USHORT* pwszUserName, IN USHORT* pwszPassword)
  31. {
  32. HRESULT hr = S_OK;
  33. COAUTHIDENTITY authident;
  34. authident.Domain = pwszDomainName;
  35. authident.DomainLength = pwszDomainName ? wcslen(pwszDomainName) : 0;
  36. authident.Password = pwszPassword;
  37. authident.PasswordLength = pwszPassword ? wcslen(pwszPassword) : 0;
  38. authident.User = pwszUserName;
  39. authident.UserLength = pwszUserName ? wcslen(pwszUserName) : 0;
  40. authident.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;
  41. hr = CoSetProxyBlanket(pUnk,
  42. RPC_C_AUTHN_WINNT,
  43. RPC_C_AUTHZ_NONE,
  44. NULL,
  45. RPC_C_AUTHN_LEVEL_PKT,
  46. RPC_C_IMP_LEVEL_IMPERSONATE,
  47. &authident,
  48. EOAC_NONE);
  49. return hr;
  50. }
  51. #define FImplies(a,b) (!(a) || (b))
  52. HRESULT WINAPI
  53. UpdateVersionInfoGlobalsFromWMI(LPCWSTR pwszMachine, LPCWSTR pwszUserName, LPCWSTR pwszPassword)
  54. {
  55. HRESULT hr = S_OK;
  56. g_CIMAttempted = TRUE;
  57. g_CIMSucceeded = FALSE;
  58. hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
  59. if (FAILED(hr) && (RPC_E_CHANGED_MODE != hr))
  60. {
  61. return hr;
  62. }
  63. // Create an instance of the WbemLocator interface.
  64. IWbemLocator *pIWbemLocator = NULL;
  65. hr = CoCreateInstance(CLSID_WbemLocator,
  66. NULL,
  67. CLSCTX_INPROC_SERVER,
  68. IID_IWbemLocator,
  69. (LPVOID *) &pIWbemLocator);
  70. if (FAILED(hr))
  71. {
  72. return hr;
  73. }
  74. IWbemServices *pIWbemServices;
  75. // If already connected, release m_pIWbemServices.
  76. // Using the locator, connect to CIMOM in the given namespace.
  77. BSTR pNamespace = NULL;
  78. BSTR pDomain = NULL;
  79. BSTR pUserName = NULL;
  80. BSTR pFQUserName= NULL;
  81. BSTR pPassword = NULL;
  82. do
  83. {
  84. WCHAR szPath[MAX_PATH];
  85. wsprintf(szPath, L"\\\\%s\\root\\cimv2", !pwszMachine ? L"." : pwszMachine);
  86. pNamespace = SysAllocString(szPath);
  87. if ( (szPath) && (!pNamespace) )
  88. {
  89. hr = E_OUTOFMEMORY;
  90. break;
  91. }
  92. if (pwszUserName)
  93. {
  94. WCHAR szUserNameExtract[MAX_PATH];
  95. WCHAR szDomainNameExtract[MAX_PATH];
  96. // Break a domain\username type of username up into a seperate domain and username
  97. // It doesn't do this for username@domain format, but it doesn't matter since
  98. // the API using this (CoSetProxyBlanket) accepts names in username@domain format
  99. DWORD dwErr = CredUIParseUserName(pwszUserName, szUserNameExtract, MAX_PATH, szDomainNameExtract, MAX_PATH);
  100. hr = HRESULT_FROM_WIN32(dwErr);
  101. if (FAILED(hr))
  102. {
  103. break;
  104. }
  105. pDomain = SysAllocString(szDomainNameExtract);
  106. pUserName = SysAllocString(szUserNameExtract);
  107. pFQUserName = SysAllocString(pwszUserName);
  108. if ( (!FImplies(szDomainNameExtract, pDomain)) ||
  109. (!FImplies(szUserNameExtract, pUserName)) ||
  110. (!FImplies(pwszUserName, pFQUserName)) )
  111. {
  112. hr = E_OUTOFMEMORY;
  113. break;
  114. }
  115. }
  116. pPassword = SysAllocString(pwszPassword);
  117. if (!FImplies(pwszPassword, pPassword))
  118. {
  119. hr = E_OUTOFMEMORY;
  120. break;
  121. }
  122. } while (FALSE);
  123. if (FAILED(hr))
  124. {
  125. SysFreeString(pPassword);
  126. SysFreeString(pUserName);
  127. SysFreeString(pFQUserName);
  128. SysFreeString(pDomain);
  129. SysFreeString(pNamespace);
  130. return hr;
  131. }
  132. hr = pIWbemLocator->ConnectServer(pNamespace,
  133. pFQUserName, // username
  134. pPassword, // password
  135. 0L, // locale
  136. 0L, // securityFlags
  137. NULL, // authority (domain for NTLM)
  138. NULL, // context
  139. &pIWbemServices);
  140. if (SUCCEEDED(hr))
  141. {
  142. hr = SetSecurity(pIWbemServices, pDomain, pUserName, pPassword);
  143. if (SUCCEEDED(hr))
  144. {
  145. IEnumWbemClassObject *pEnum = NULL;
  146. BSTR bstrWQL = SysAllocString(L"WQL");
  147. BSTR bstrPath = SysAllocString(L"select * from Win32_OperatingSystem");
  148. VARIANT varOSType;
  149. VARIANT varOSVersion;
  150. VARIANT varOSProductSuite;
  151. VARIANT varOSBuildNumber;
  152. VARIANT varServicePackMajorVersion;
  153. VARIANT varServicePackMinorVersion;
  154. VARIANT varArchitecture;
  155. hr = pIWbemServices->ExecQuery(bstrWQL, bstrPath, WBEM_FLAG_FORWARD_ONLY, NULL, &pEnum);
  156. if (SUCCEEDED(hr))
  157. {
  158. hr = SetSecurity(pEnum, pDomain, pUserName, pPassword);
  159. }
  160. if (SUCCEEDED(hr))
  161. {
  162. IWbemClassObject *pNSClass;
  163. ULONG uReturned;
  164. hr = pEnum->Next(WBEM_INFINITE, 1, &pNSClass, &uReturned );
  165. if (SUCCEEDED(hr))
  166. {
  167. if (uReturned)
  168. {
  169. do
  170. {
  171. g_CIMSucceeded = TRUE;
  172. CIMTYPE ctpeType;
  173. hr = pNSClass->Get(L"OSType", NULL, &varOSType, &ctpeType, NULL);
  174. if (SUCCEEDED(hr))
  175. {
  176. hr = VariantChangeType(&varOSType, &varOSType, 0, VT_UINT);
  177. if (SUCCEEDED(hr))
  178. {
  179. g_CIMOSType = varOSType.uintVal;
  180. }
  181. }
  182. if (FAILED(hr))
  183. {
  184. g_CIMSucceeded = FALSE;
  185. break;
  186. }
  187. hr = pNSClass->Get(L"Version", NULL, &varOSVersion, &ctpeType, NULL);
  188. if (SUCCEEDED(hr))
  189. {
  190. hr = VariantChangeType(&varOSVersion, &varOSVersion, 0, VT_BSTR);
  191. if (SUCCEEDED(hr))
  192. {
  193. wcscpy(g_CIMOSVersion, varOSVersion.bstrVal);
  194. }
  195. }
  196. if (FAILED(hr))
  197. {
  198. g_CIMSucceeded = FALSE;
  199. break;
  200. }
  201. hr = pNSClass->Get(L"OSProductSuite", NULL, &varOSProductSuite, &ctpeType, NULL);
  202. if (SUCCEEDED(hr))
  203. {
  204. //
  205. // if the return type is VT_NULL, leave g_CIMOSProductSuite value alone (0)
  206. if (VT_NULL != varOSProductSuite.vt)
  207. {
  208. hr = VariantChangeType(&varOSProductSuite, &varOSProductSuite, 0, VT_UINT);
  209. if (SUCCEEDED(hr))
  210. {
  211. g_CIMOSProductSuite = varOSProductSuite.uintVal;
  212. }
  213. }
  214. }
  215. if (FAILED(hr))
  216. {
  217. g_CIMSucceeded = FALSE;
  218. break;
  219. }
  220. hr = pNSClass->Get(L"BuildNumber", NULL, &varOSBuildNumber, &ctpeType, NULL);
  221. if (SUCCEEDED(hr))
  222. {
  223. hr = VariantChangeType(&varOSBuildNumber, &varOSBuildNumber, 0, VT_BSTR);
  224. if (SUCCEEDED(hr))
  225. {
  226. wcscpy(g_CIMOSBuildNumber, varOSBuildNumber.bstrVal);
  227. }
  228. }
  229. if (FAILED(hr))
  230. {
  231. g_CIMSucceeded = FALSE;
  232. break;
  233. }
  234. hr = pNSClass->Get(L"ServicePackMajorVersion", NULL, &varServicePackMajorVersion, &ctpeType, NULL);
  235. if (SUCCEEDED(hr))
  236. {
  237. hr = VariantChangeType(&varServicePackMajorVersion, &varServicePackMajorVersion, 0, VT_BSTR);
  238. if (SUCCEEDED(hr))
  239. {
  240. wcscpy(g_CIMServicePackMajorVersion, varServicePackMajorVersion.bstrVal);
  241. }
  242. }
  243. if (FAILED(hr))
  244. {
  245. g_CIMSucceeded = FALSE;
  246. break;
  247. }
  248. hr = pNSClass->Get(L"ServicePackMinorVersion", NULL, &varServicePackMinorVersion, &ctpeType, NULL);
  249. if (SUCCEEDED(hr))
  250. {
  251. hr = VariantChangeType(&varServicePackMinorVersion, &varServicePackMinorVersion, 0, VT_BSTR);
  252. if (SUCCEEDED(hr))
  253. {
  254. wcscpy(g_CIMServicePackMinorVersion, varServicePackMinorVersion.bstrVal);
  255. }
  256. }
  257. if (FAILED(hr))
  258. {
  259. g_CIMSucceeded = FALSE;
  260. break;
  261. }
  262. }
  263. while (FALSE);
  264. }
  265. else
  266. {
  267. hr = E_UNEXPECTED;
  268. }
  269. pNSClass->Release();
  270. }
  271. pEnum->Release();
  272. }
  273. SysFreeString(bstrPath);
  274. if (SUCCEEDED(hr))
  275. {
  276. bstrPath = SysAllocString(L"select * from Win32_Processor");
  277. hr = pIWbemServices->ExecQuery(bstrWQL, bstrPath, WBEM_FLAG_FORWARD_ONLY, NULL, &pEnum);
  278. if (SUCCEEDED(hr))
  279. {
  280. hr = SetSecurity(pEnum, pDomain, pUserName, pPassword);
  281. }
  282. if (SUCCEEDED(hr))
  283. {
  284. IWbemClassObject *pNSClass;
  285. ULONG uReturned;
  286. hr = pEnum->Next(WBEM_INFINITE, 1, &pNSClass, &uReturned );
  287. if (SUCCEEDED(hr))
  288. {
  289. if (uReturned)
  290. {
  291. CIMTYPE ctpeType;
  292. hr = pNSClass->Get(L"Architecture", NULL, &varArchitecture, &ctpeType, NULL);
  293. if (SUCCEEDED(hr))
  294. {
  295. hr = VariantChangeType(&varArchitecture, &varArchitecture,
  296. 0, VT_UINT);
  297. if (SUCCEEDED(hr))
  298. {
  299. g_CIMProcessorArchitecture = varArchitecture.uintVal;
  300. }
  301. else
  302. {
  303. g_CIMSucceeded = FALSE;
  304. }
  305. }
  306. else
  307. {
  308. g_CIMSucceeded = FALSE;
  309. }
  310. }
  311. else
  312. {
  313. hr = E_UNEXPECTED;
  314. }
  315. pNSClass->Release();
  316. }
  317. pEnum->Release();
  318. }
  319. SysFreeString(bstrPath);
  320. }
  321. SysFreeString(bstrWQL);
  322. pIWbemServices->Release();
  323. } //hr = CoSetProxyBlanket(pIWbemServices.., if (SUCCEEDED(hr))
  324. } //hr = pIWbemLocator->ConnectServer.., if (SUCCEEDED(hr))
  325. SysFreeString(pPassword);
  326. SysFreeString(pUserName);
  327. SysFreeString(pFQUserName);
  328. SysFreeString(pDomain);
  329. SysFreeString(pNamespace);
  330. CoUninitialize();
  331. // Translate any WMI errors into Win32 errors:
  332. switch (hr)
  333. {
  334. case WBEM_E_NOT_FOUND:
  335. hr = HRESULT_FROM_WIN32(ERROR_HOST_UNREACHABLE);
  336. break;
  337. case WBEM_E_ACCESS_DENIED:
  338. hr = E_ACCESSDENIED;
  339. break;
  340. case WBEM_E_PROVIDER_FAILURE:
  341. hr = E_FAIL;
  342. break;
  343. case WBEM_E_TYPE_MISMATCH:
  344. case WBEM_E_INVALID_CONTEXT:
  345. case WBEM_E_INVALID_PARAMETER:
  346. hr = E_INVALIDARG;
  347. break;
  348. case WBEM_E_OUT_OF_MEMORY:
  349. hr = E_OUTOFMEMORY;
  350. break;
  351. }
  352. if ( (hr == S_OK) && (!g_CIMSucceeded) )
  353. {
  354. return E_FAIL;
  355. }
  356. else
  357. {
  358. return hr;
  359. }
  360. }
  361. HRESULT WINAPI
  362. UpdateVersionInfoGlobalsFromLocalMachine()
  363. {
  364. HRESULT hr = S_OK;
  365. BOOL fFailed = FALSE;
  366. do
  367. {
  368. OSVERSIONINFOEX osv;
  369. ZeroMemory(&osv, sizeof(OSVERSIONINFOEX));
  370. osv.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
  371. if (!GetVersionEx( reinterpret_cast<LPOSVERSIONINFO>(&osv)))
  372. {
  373. fFailed = TRUE;
  374. break;
  375. }
  376. g_CIMOSType = 18; // WINNT
  377. g_CIMOSProductSuite = osv.wSuiteMask;
  378. #if defined(_X86_)
  379. g_CIMProcessorArchitecture = 0;
  380. #elif defined(_IA64_)
  381. g_CIMProcessorArchitecture = 6;
  382. #else
  383. fFailed = TRUE;
  384. break;
  385. #endif
  386. wsprintf(g_CIMOSVersion, L"%d.%d.%d", osv.dwMajorVersion, osv.dwMinorVersion, osv.dwBuildNumber);
  387. wsprintf(g_CIMOSBuildNumber, L"%d", osv.dwBuildNumber);
  388. wsprintf(g_CIMServicePackMajorVersion, L"%d", osv.wServicePackMajor);
  389. wsprintf(g_CIMServicePackMinorVersion, L"%d", osv.wServicePackMinor);
  390. g_CIMSucceeded = TRUE;
  391. g_CIMAttempted = TRUE;
  392. } while (FALSE);
  393. if (fFailed)
  394. {
  395. return UpdateVersionInfoGlobalsFromWMI(NULL, NULL, NULL);
  396. }
  397. return hr;
  398. }
  399. HRESULT WINAPI
  400. UpdateVersionInfoGlobals(LPCWSTR pwszMachine, LPCWSTR pwszUserName, LPCWSTR pwszPassword)
  401. {
  402. HRESULT hr = S_OK;
  403. HRESULT hrWMI = S_OK;
  404. if (pwszMachine)
  405. {
  406. return UpdateVersionInfoGlobalsFromWMI(pwszMachine, pwszUserName, pwszPassword);
  407. }
  408. else // Resolve locally
  409. {
  410. hr = UpdateVersionInfoGlobalsFromLocalMachine();
  411. #ifdef DBG
  412. UINT CIMOSType = g_CIMOSType;
  413. UINT CIMOSProductSuite = g_CIMOSProductSuite;
  414. UINT CIMProcessorArchitecture = g_CIMProcessorArchitecture;
  415. WCHAR CIMOSVersion[MAX_PATH];
  416. WCHAR CIMOSBuildNumber[MAX_PATH];
  417. WCHAR CIMServicePackMajorVersion[MAX_PATH];
  418. WCHAR CIMServicePackMinorVersion[MAX_PATH];
  419. wcsncpy(CIMOSVersion, g_CIMOSVersion, MAX_PATH);
  420. wcsncpy(CIMOSBuildNumber, g_CIMOSBuildNumber, MAX_PATH);
  421. wcsncpy(CIMServicePackMajorVersion, g_CIMServicePackMajorVersion, MAX_PATH);
  422. wcsncpy(CIMServicePackMinorVersion, g_CIMServicePackMinorVersion, MAX_PATH);
  423. hrWMI = UpdateVersionInfoGlobalsFromWMI(pwszMachine, NULL, NULL);
  424. if(SUCCEEDED(hr) && SUCCEEDED(hrWMI))
  425. {
  426. if ( (CIMOSType != g_CIMOSType) ||
  427. ( (CIMOSProductSuite & ~VER_SUITE_SINGLEUSERTS) != (g_CIMOSProductSuite & ~VER_SUITE_SINGLEUSERTS) ) ||
  428. (CIMProcessorArchitecture != g_CIMProcessorArchitecture) ||
  429. (0 != wcsncmp(CIMOSVersion, g_CIMOSVersion, MAX_PATH)) ||
  430. (0 != wcsncmp(CIMOSBuildNumber, g_CIMOSBuildNumber, MAX_PATH)) ||
  431. (0 != wcsncmp(CIMServicePackMajorVersion, g_CIMServicePackMajorVersion, MAX_PATH)) ||
  432. (0 != wcsncmp(CIMServicePackMinorVersion, g_CIMServicePackMinorVersion, MAX_PATH)) )
  433. {
  434. WCHAR szAssertText[4096];
  435. wsprintf(szAssertText, L"NETSH.EXE: ASSERT - mismatch between GetVersionInfoEx and WMI information:\r\n"
  436. L"CIMOSType: %x vs. %x\r\n"
  437. L"CIMOSProductSuite: %x vs. %x\r\n"
  438. L"CIMProcessorArchitecture: %x vs %x\r\n"
  439. L"CIMOSVersion: %s vs. %s\r\n"
  440. L"CIMOSBuildNumber: %s vs. %s\r\n"
  441. L"CIMServicePackMajorVersion: %s vs. %s\r\n"
  442. L"CIMServicePackMinorVersion: %s vs. %s\r\n",
  443. CIMOSType, g_CIMOSType,
  444. CIMOSProductSuite, g_CIMOSProductSuite,
  445. CIMProcessorArchitecture, g_CIMProcessorArchitecture,
  446. CIMOSVersion, g_CIMOSVersion,
  447. CIMOSBuildNumber, g_CIMOSBuildNumber,
  448. CIMServicePackMajorVersion, g_CIMServicePackMajorVersion,
  449. CIMServicePackMinorVersion, g_CIMServicePackMinorVersion);
  450. ASSERTMSG((PCHAR)(szAssertText), FALSE);
  451. }
  452. }
  453. #endif
  454. return hr;
  455. }
  456. }