Source code of Windows XP (NT5)
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.

554 lines
13 KiB

  1. //+--------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1994 - 1997.
  5. //
  6. // File: rsoputil.cpp
  7. //
  8. // Contents: helper functions for working with the RSOP databases
  9. //
  10. // History: 10-18-1999 stevebl Created
  11. //
  12. //---------------------------------------------------------------------------
  13. #include "precomp.hxx"
  14. #include "sddl.h"
  15. //+--------------------------------------------------------------------------
  16. //
  17. // Function: SetParameter
  18. //
  19. // Synopsis: sets a paramter's value in a WMI parameter list
  20. //
  21. // Arguments: [pInst] - instance on which to set the value
  22. // [szParam] - the name of the parameter
  23. // [xData] - the data
  24. //
  25. // History: 10-08-1999 stevebl Created
  26. //
  27. // Notes: There may be several flavors of this procedure, one for
  28. // each data type.
  29. //
  30. //---------------------------------------------------------------------------
  31. HRESULT SetParameter(IWbemClassObject * pInst, TCHAR * szParam, TCHAR * szData)
  32. {
  33. VARIANT var;
  34. HRESULT hr = S_OK;
  35. var.vt = VT_BSTR;
  36. var.bstrVal = SysAllocString(szData);
  37. hr = pInst->Put(szParam, 0, &var, 0);
  38. SysFreeString(var.bstrVal);
  39. return hr;
  40. }
  41. //+--------------------------------------------------------------------------
  42. //
  43. // Function: GetParameter
  44. //
  45. // Synopsis: retrieves a parameter value from a WMI paramter list
  46. //
  47. // Arguments: [pInst] - instance to get the paramter value from
  48. // [szParam] - the name of the paramter
  49. // [xData] - [out] data
  50. //
  51. // History: 10-08-1999 stevebl Created
  52. //
  53. // Notes: There are several flavors of this procedure, one for each
  54. // data type.
  55. //
  56. //---------------------------------------------------------------------------
  57. HRESULT GetParameter(IWbemClassObject * pInst, TCHAR * szParam, TCHAR * &szData)
  58. {
  59. VARIANT var;
  60. HRESULT hr = S_OK;
  61. VariantInit(&var);
  62. if (szData)
  63. {
  64. delete [] szData;
  65. szData = NULL;
  66. }
  67. hr = pInst->Get(szParam, 0, &var, 0, 0);
  68. if (SUCCEEDED(hr) && var.vt != VT_NULL)
  69. {
  70. if (var.bstrVal)
  71. {
  72. szData = (TCHAR *) OLEALLOC(sizeof(TCHAR) * (_tcslen(var.bstrVal) + 1));
  73. if (szData)
  74. {
  75. _tcscpy(szData, var.bstrVal);
  76. }
  77. else
  78. {
  79. hr = E_OUTOFMEMORY;
  80. }
  81. }
  82. }
  83. VariantClear(&var);
  84. return hr;
  85. }
  86. HRESULT GetParameter(IWbemClassObject * pInst, TCHAR * szParam, CString &szData)
  87. {
  88. VARIANT var;
  89. HRESULT hr = S_OK;
  90. VariantInit(&var);
  91. if (szData)
  92. {
  93. szData = "";
  94. }
  95. hr = pInst->Get(szParam, 0, &var, 0, 0);
  96. if (SUCCEEDED(hr) && var.vt != VT_NULL)
  97. {
  98. if (var.bstrVal)
  99. {
  100. szData = var.bstrVal;
  101. }
  102. }
  103. VariantClear(&var);
  104. return hr;
  105. }
  106. HRESULT GetParameterBSTR(IWbemClassObject * pInst, TCHAR * szParam, BSTR &bstrData)
  107. {
  108. VARIANT var;
  109. HRESULT hr = S_OK;
  110. VariantInit(&var);
  111. if (bstrData)
  112. {
  113. SysFreeString(bstrData);
  114. }
  115. hr = pInst->Get(szParam, 0, &var, 0, 0);
  116. if (SUCCEEDED(hr) && var.vt != VT_NULL)
  117. {
  118. bstrData = SysAllocStringLen(var.bstrVal, SysStringLen(var.bstrVal));
  119. if (NULL == bstrData)
  120. {
  121. hr = E_OUTOFMEMORY;
  122. }
  123. }
  124. VariantClear(&var);
  125. return hr;
  126. }
  127. HRESULT GetParameter(IWbemClassObject * pInst, TCHAR * szParam, BOOL &fData)
  128. {
  129. VARIANT var;
  130. HRESULT hr = S_OK;
  131. VariantInit(&var);
  132. hr = pInst->Get(szParam, 0, &var, 0, 0);
  133. if (SUCCEEDED(hr) && var.vt != VT_NULL)
  134. {
  135. fData = var.bVal;
  136. }
  137. VariantClear(&var);
  138. return hr;
  139. }
  140. HRESULT GetParameter(IWbemClassObject * pInst, TCHAR * szParam, HRESULT &hrData)
  141. {
  142. VARIANT var;
  143. HRESULT hr = S_OK;
  144. VariantInit(&var);
  145. hr = pInst->Get(szParam, 0, &var, 0, 0);
  146. if (SUCCEEDED(hr) && var.vt != VT_NULL)
  147. {
  148. hrData = (HRESULT) var.lVal;
  149. }
  150. VariantClear(&var);
  151. return hr;
  152. }
  153. HRESULT GetParameter(IWbemClassObject * pInst, TCHAR * szParam, ULONG &ulData)
  154. {
  155. VARIANT var;
  156. HRESULT hr = S_OK;
  157. VariantInit(&var);
  158. hr = pInst->Get(szParam, 0, &var, 0, 0);
  159. if (SUCCEEDED(hr) && var.vt != VT_NULL)
  160. {
  161. ulData = var.ulVal;
  162. }
  163. VariantClear(&var);
  164. return hr;
  165. }
  166. HRESULT GetParameter(IWbemClassObject * pInst, TCHAR * szParam, GUID &guid)
  167. {
  168. TCHAR * sz = NULL;
  169. memset(&guid, 0, sizeof(GUID));
  170. HRESULT hr = GetParameter(pInst, szParam, sz);
  171. if (SUCCEEDED(hr))
  172. {
  173. hr = CLSIDFromString(sz, &guid);
  174. }
  175. if (sz)
  176. {
  177. OLESAFE_DELETE(sz);
  178. }
  179. return hr;
  180. }
  181. HRESULT GetParameter(IWbemClassObject * pInst, TCHAR * szParam, unsigned int &ui)
  182. {
  183. VARIANT var;
  184. HRESULT hr = S_OK;
  185. VariantInit(&var);
  186. ui = 0;
  187. hr = pInst->Get(szParam, 0, &var, 0, 0);
  188. if (SUCCEEDED(hr) && var.vt != VT_NULL)
  189. {
  190. ui = (HRESULT) var.uiVal;
  191. }
  192. VariantClear(&var);
  193. return hr;
  194. }
  195. // array variation - gets an array of guids and a count
  196. HRESULT GetParameter(IWbemClassObject * pInst, TCHAR *szParam, UINT &uiCount, GUID * &rgGuid)
  197. {
  198. VARIANT var;
  199. HRESULT hr = S_OK;
  200. uiCount = 0;
  201. VariantInit(&var);
  202. hr = pInst->Get(szParam, 0, &var, 0, 0);
  203. if (SUCCEEDED(hr) && var.vt == (VT_ARRAY | VT_BSTR))
  204. {
  205. // build the array
  206. SAFEARRAY * parray = var.parray;
  207. uiCount = parray->rgsabound[0].cElements;
  208. if (uiCount > 0)
  209. {
  210. rgGuid = (GUID *)OLEALLOC(sizeof(GUID) * uiCount);
  211. if (rgGuid)
  212. {
  213. BSTR * rgData = (BSTR *)parray->pvData;
  214. UINT ui = uiCount;
  215. while (ui--)
  216. {
  217. hr = CLSIDFromString(rgData[ui], &rgGuid[ui]);
  218. if (FAILED(hr))
  219. {
  220. return hr;
  221. }
  222. }
  223. }
  224. else
  225. {
  226. uiCount = 0;
  227. hr = E_OUTOFMEMORY;
  228. }
  229. }
  230. }
  231. VariantClear(&var);
  232. return hr;
  233. }
  234. // array variation - gets an array of strings and a count
  235. HRESULT GetParameter(IWbemClassObject * pInst, TCHAR *szParam, UINT &uiCount, TCHAR ** &rgszData)
  236. {
  237. VARIANT var;
  238. HRESULT hr = S_OK;
  239. uiCount = 0;
  240. VariantInit(&var);
  241. hr = pInst->Get(szParam, 0, &var, 0, 0);
  242. if (SUCCEEDED(hr) && var.vt == (VT_ARRAY | VT_BSTR))
  243. {
  244. // build the array
  245. SAFEARRAY * parray = var.parray;
  246. uiCount = parray->rgsabound[0].cElements;
  247. if (uiCount > 0)
  248. {
  249. rgszData = (TCHAR **)OLEALLOC(sizeof(TCHAR *) * uiCount);
  250. if (rgszData)
  251. {
  252. BSTR * rgData = (BSTR *)parray->pvData;
  253. UINT ui = uiCount;
  254. while (ui--)
  255. {
  256. OLESAFE_COPYSTRING(rgszData[ui], rgData[ui]);
  257. }
  258. }
  259. else
  260. {
  261. uiCount = 0;
  262. hr = E_OUTOFMEMORY;
  263. }
  264. }
  265. }
  266. VariantClear(&var);
  267. return hr;
  268. }
  269. // array variation - gets an array of CSPLATFORM objects and a count
  270. HRESULT GetParameter(IWbemClassObject * pInst, TCHAR * szParam, UINT &uiCount, CSPLATFORM * &rgData)
  271. {
  272. VARIANT var;
  273. HRESULT hr = S_OK;
  274. uiCount = 0;
  275. VariantInit(&var);
  276. hr = pInst->Get(szParam, 0, &var, 0, 0);
  277. if (SUCCEEDED(hr) && var.vt == (VT_ARRAY | VT_I4))
  278. {
  279. // build the array
  280. SAFEARRAY * parray = var.parray;
  281. uiCount = parray->rgsabound[0].cElements;
  282. if (uiCount > 0)
  283. {
  284. rgData = (CSPLATFORM *)OLEALLOC(sizeof(CSPLATFORM) * uiCount);
  285. if (rgData)
  286. {
  287. ULONG * rgulData = (ULONG *)parray->pvData;
  288. UINT ui = uiCount;
  289. while (ui--)
  290. {
  291. rgData[ui].dwPlatformId = VER_PLATFORM_WIN32_NT;
  292. rgData[ui].dwVersionHi = 5;
  293. rgData[ui].dwVersionLo = 0;
  294. rgData[ui].dwProcessorArch = rgulData[ui];
  295. }
  296. }
  297. else
  298. {
  299. uiCount = 0;
  300. hr = E_OUTOFMEMORY;
  301. }
  302. }
  303. }
  304. VariantClear(&var);
  305. return hr;
  306. }
  307. HRESULT GetParameter(IWbemClassObject * pInst, TCHAR * szParam, PSECURITY_DESCRIPTOR &psd)
  308. {
  309. VARIANT var;
  310. HRESULT hr = S_OK;
  311. if (psd)
  312. {
  313. LocalFree(psd);
  314. psd = NULL;
  315. }
  316. VariantInit(&var);
  317. hr = pInst->Get(szParam, 0, &var, 0, 0);
  318. if (SUCCEEDED(hr) && var.vt != VT_NULL)
  319. {
  320. psd = (PSECURITY_DESCRIPTOR) LocalAlloc( LPTR, var.parray->rgsabound[0].cElements * sizeof( BYTE ) );
  321. if ( psd )
  322. {
  323. memcpy( psd, var.parray->pvData, var.parray->rgsabound[0].cElements * sizeof( BYTE ) );
  324. }
  325. else
  326. {
  327. hr = E_OUTOFMEMORY;
  328. }
  329. if (!IsValidSecurityDescriptor(psd))
  330. {
  331. LocalFree(psd);
  332. psd = NULL;
  333. }
  334. }
  335. VariantClear(&var);
  336. return hr;
  337. }
  338. HRESULT GetGPOFriendlyName(IWbemServices *pIWbemServices,
  339. LPTSTR lpGPOID, BSTR pLanguage,
  340. LPTSTR *pGPOName)
  341. {
  342. BSTR pQuery = NULL, pName = NULL;
  343. LPTSTR lpQuery = NULL;
  344. IEnumWbemClassObject * pEnum = NULL;
  345. IWbemClassObject *pObjects[2];
  346. HRESULT hr;
  347. ULONG ulRet;
  348. VARIANT varGPOName;
  349. //
  350. // Set the default
  351. //
  352. *pGPOName = NULL;
  353. //
  354. // Build the query
  355. //
  356. lpQuery = (LPTSTR) LocalAlloc (LPTR, ((lstrlen(lpGPOID) + 50) * sizeof(TCHAR)));
  357. if (!lpQuery)
  358. {
  359. DebugMsg((DM_WARNING, TEXT("GetGPOFriendlyName: Failed to allocate memory for unicode query")));
  360. hr = HRESULT_FROM_WIN32(ERROR_OUTOFMEMORY);
  361. goto Exit;
  362. }
  363. wsprintf (lpQuery, TEXT("SELECT name, id FROM RSOP_GPO where id=\"%s\""), lpGPOID);
  364. pQuery = SysAllocString (lpQuery);
  365. if (!pQuery)
  366. {
  367. DebugMsg((DM_WARNING, TEXT("GetGPOFriendlyName: Failed to allocate memory for query")));
  368. hr = HRESULT_FROM_WIN32(ERROR_OUTOFMEMORY);
  369. goto Exit;
  370. }
  371. //
  372. // Allocate BSTRs for the property names we want to retreive
  373. //
  374. pName = SysAllocString (TEXT("name"));
  375. if (!pName)
  376. {
  377. DebugMsg((DM_WARNING, TEXT("GetGPOFriendlyName: Failed to allocate memory for name")));
  378. hr = HRESULT_FROM_WIN32(ERROR_OUTOFMEMORY);
  379. goto Exit;
  380. }
  381. //
  382. // Execute the query
  383. //
  384. hr = pIWbemServices->ExecQuery (pLanguage, pQuery,
  385. WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,
  386. NULL, &pEnum);
  387. if (FAILED(hr))
  388. {
  389. DebugMsg((DM_WARNING, TEXT("GetGPOFriendlyName: Failed to query for %s with 0x%x"),
  390. pQuery, hr));
  391. goto Exit;
  392. }
  393. //
  394. // Loop through the results
  395. //
  396. hr = pEnum->Next(WBEM_INFINITE, 1, pObjects, &ulRet);
  397. if (FAILED(hr))
  398. {
  399. DebugMsg((DM_WARNING, TEXT("GetGPOFriendlyName: Failed to get first item in query results for %s with 0x%x"),
  400. pQuery, hr));
  401. goto Exit;
  402. }
  403. //
  404. // Check for the "data not available case"
  405. //
  406. if (ulRet == 0)
  407. {
  408. //
  409. // In this case, we cannot find the gpo -- it has most likely been deleted. To give the user some
  410. // useful information, we will fall back to the guid.
  411. //
  412. *pGPOName = (LPTSTR) LocalAlloc (LPTR, (lstrlen(lpGPOID) + 1) * sizeof(TCHAR));
  413. if ( *pGPOName )
  414. {
  415. DebugMsg((DM_WARNING, TEXT("GetGPOFriendlyName: Using GPO guid for friendly name because GPO can't be found")));
  416. lstrcpy( *pGPOName, lpGPOID );
  417. hr = S_OK;
  418. }
  419. else
  420. {
  421. DebugMsg((DM_WARNING, TEXT("GetGPOFriendlyName: Failed to allocate memory for GPO Name in GUID form")));
  422. hr = E_OUTOFMEMORY;
  423. }
  424. goto Exit;
  425. }
  426. //
  427. // Get the name
  428. //
  429. hr = pObjects[0]->Get (pName, 0, &varGPOName, NULL, NULL);
  430. if (FAILED(hr))
  431. {
  432. DebugMsg((DM_WARNING, TEXT("GetGPOFriendlyName: Failed to get gponame in query results for %s with 0x%x"),
  433. pQuery, hr));
  434. goto Exit;
  435. }
  436. //
  437. // Save the name
  438. //
  439. *pGPOName = (LPTSTR) LocalAlloc (LPTR, (lstrlen(varGPOName.bstrVal) + 1) * sizeof(TCHAR));
  440. if (!(*pGPOName))
  441. {
  442. DebugMsg((DM_WARNING, TEXT("GetGPOFriendlyName: Failed to allocate memory for GPO Name")));
  443. hr = HRESULT_FROM_WIN32(ERROR_OUTOFMEMORY);
  444. goto Exit;
  445. }
  446. lstrcpy (*pGPOName, varGPOName.bstrVal);
  447. VariantClear (&varGPOName);
  448. hr = S_OK;
  449. Exit:
  450. if (pEnum)
  451. {
  452. pEnum->Release();
  453. }
  454. if (pQuery)
  455. {
  456. SysFreeString (pQuery);
  457. }
  458. if (lpQuery)
  459. {
  460. LocalFree (lpQuery);
  461. }
  462. if (pName)
  463. {
  464. SysFreeString (pName);
  465. }
  466. return hr;
  467. }
  468. HRESULT CStringFromWBEMTime(CString &szOut, BSTR bstrIn, BOOL fShortFormat)
  469. {
  470. HRESULT hr = E_FAIL;
  471. WBEMTime wt(bstrIn);
  472. FILETIME ft;
  473. if (wt.GetFILETIME(&ft))
  474. {
  475. CTime t(ft);
  476. if (fShortFormat)
  477. {
  478. szOut = t.Format(TEXT("%x"));
  479. }
  480. else
  481. {
  482. szOut = t.Format(TEXT("%#c"));
  483. }
  484. hr = S_OK;
  485. }
  486. return hr;
  487. }