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.

749 lines
17 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 "main.h"
  14. #include "rsoputil.h"
  15. #pragma warning(4:4535) // set_se_translator used w/o /EHa from sdkinc\provexce.h
  16. #include "wbemtime.h"
  17. //+--------------------------------------------------------------------------
  18. //
  19. // Function: SetParameter
  20. //
  21. // Synopsis: sets a paramter's value in a WMI parameter list
  22. //
  23. // Arguments: [pInst] - instance on which to set the value
  24. // [szParam] - the name of the parameter
  25. // [xData] - the data
  26. //
  27. // History: 10-08-1999 stevebl Created
  28. //
  29. // Notes: There may be several flavors of this procedure, one for
  30. // each data type.
  31. //
  32. //---------------------------------------------------------------------------
  33. HRESULT SetParameter(IWbemClassObject * pInst, TCHAR * szParam, TCHAR * szData)
  34. {
  35. VARIANT var;
  36. HRESULT hr = S_OK;
  37. var.vt = VT_BSTR;
  38. var.bstrVal = SysAllocString(szData);
  39. hr = pInst->Put(szParam, 0, &var, 0);
  40. SysFreeString(var.bstrVal);
  41. return hr;
  42. }
  43. HRESULT SetParameter(IWbemClassObject * pInst, TCHAR * szParam, SAFEARRAY * psa)
  44. {
  45. VARIANT var;
  46. HRESULT hr = S_OK;
  47. var.vt = VT_BSTR | VT_ARRAY;
  48. var.parray = psa;
  49. hr = pInst->Put(szParam, 0, &var, 0);
  50. return hr;
  51. }
  52. HRESULT SetParameter(IWbemClassObject * pInst, TCHAR * szParam, UINT uiData)
  53. {
  54. VARIANT var;
  55. HRESULT hr = S_OK;
  56. var.vt = VT_I4;
  57. var.lVal = uiData;
  58. hr = pInst->Put(szParam, 0, &var, 0);
  59. return hr;
  60. }
  61. //+--------------------------------------------------------------------------
  62. //
  63. // Function: SetParameterToNull
  64. //
  65. // Synopsis: sets a paramter's value in a WMI parameter list to null
  66. //
  67. // Arguments: [pInst] - instance on which to set the value
  68. // [szParam] - the name of the parameter
  69. //
  70. // History: 03-01-2000 ericflo Created
  71. //
  72. // Notes:
  73. //
  74. //---------------------------------------------------------------------------
  75. HRESULT SetParameterToNull(IWbemClassObject * pInst, TCHAR * szParam)
  76. {
  77. VARIANT var;
  78. var.vt = VT_NULL;
  79. return (pInst->Put(szParam, 0, &var, 0));
  80. }
  81. //+--------------------------------------------------------------------------
  82. //
  83. // Function: GetParameter
  84. //
  85. // Synopsis: retrieves a parameter value from a WMI paramter list
  86. //
  87. // Arguments: [pInst] - instance to get the paramter value from
  88. // [szParam] - the name of the paramter
  89. // [xData] - [out] data
  90. //
  91. // History: 10-08-1999 stevebl Created
  92. //
  93. // Notes: There are several flavors of this procedure, one for each
  94. // data type.
  95. //
  96. //---------------------------------------------------------------------------
  97. HRESULT GetParameter(IWbemClassObject * pInst, TCHAR * szParam, TCHAR * &szData)
  98. {
  99. VARIANT var;
  100. HRESULT hr = S_OK;
  101. if (!pInst)
  102. return E_INVALIDARG;
  103. VariantInit(&var);
  104. hr = pInst->Get(szParam, 0, &var, 0, 0);
  105. if (SUCCEEDED(hr))
  106. {
  107. if (var.vt == VT_BSTR)
  108. {
  109. if (szData)
  110. {
  111. delete [] szData;
  112. szData = NULL;
  113. }
  114. szData = new TCHAR[_tcslen(var.bstrVal) + 1];
  115. if (szData)
  116. {
  117. _tcscpy(szData, var.bstrVal);
  118. }
  119. else
  120. {
  121. hr = E_OUTOFMEMORY;
  122. }
  123. }
  124. else
  125. {
  126. hr = E_UNEXPECTED;
  127. }
  128. }
  129. VariantClear(&var);
  130. return hr;
  131. }
  132. HRESULT GetParameterBSTR(IWbemClassObject * pInst, TCHAR * szParam, BSTR &bstrData)
  133. {
  134. VARIANT var;
  135. HRESULT hr = S_OK;
  136. if (!pInst)
  137. return E_INVALIDARG;
  138. VariantInit(&var);
  139. hr = pInst->Get(szParam, 0, &var, 0, 0);
  140. if (SUCCEEDED(hr))
  141. {
  142. if (var.vt == VT_BSTR)
  143. {
  144. if (bstrData)
  145. {
  146. SysFreeString(bstrData);
  147. }
  148. bstrData = SysAllocStringLen(var.bstrVal, SysStringLen(var.bstrVal));
  149. if (NULL == bstrData)
  150. {
  151. hr = E_OUTOFMEMORY;
  152. }
  153. }
  154. else
  155. {
  156. hr = E_UNEXPECTED;
  157. }
  158. }
  159. VariantClear(&var);
  160. return hr;
  161. }
  162. HRESULT GetParameter(IWbemClassObject * pInst, TCHAR * szParam, BOOL &fData)
  163. {
  164. VARIANT var;
  165. HRESULT hr = S_OK;
  166. if (!pInst)
  167. return E_INVALIDARG;
  168. VariantInit(&var);
  169. hr = pInst->Get(szParam, 0, &var, 0, 0);
  170. if (SUCCEEDED(hr))
  171. {
  172. if (var.vt == VT_BOOL)
  173. {
  174. fData = var.bVal;
  175. }
  176. else
  177. {
  178. hr = E_UNEXPECTED;
  179. }
  180. }
  181. VariantClear(&var);
  182. return hr;
  183. }
  184. HRESULT GetParameter(IWbemClassObject * pInst, TCHAR * szParam, HRESULT &hrData)
  185. {
  186. VARIANT var;
  187. HRESULT hr = S_OK;
  188. if (!pInst)
  189. return E_INVALIDARG;
  190. VariantInit(&var);
  191. hr = pInst->Get(szParam, 0, &var, 0, 0);
  192. if (SUCCEEDED(hr))
  193. {
  194. if (var.vt == VT_I4)
  195. {
  196. hrData = (HRESULT) var.lVal;
  197. }
  198. else
  199. {
  200. hr = E_UNEXPECTED;
  201. }
  202. }
  203. VariantClear(&var);
  204. return hr;
  205. }
  206. HRESULT GetParameter(IWbemClassObject * pInst, TCHAR * szParam, ULONG &ulData)
  207. {
  208. VARIANT var;
  209. HRESULT hr = S_OK;
  210. if (!pInst)
  211. return E_INVALIDARG;
  212. VariantInit(&var);
  213. hr = pInst->Get(szParam, 0, &var, 0, 0);
  214. if (SUCCEEDED(hr))
  215. {
  216. if ((var.vt == VT_UI4) || (var.vt == VT_I4))
  217. {
  218. ulData = var.ulVal;
  219. }
  220. else
  221. {
  222. hr = E_UNEXPECTED;
  223. }
  224. }
  225. VariantClear(&var);
  226. return hr;
  227. }
  228. HRESULT GetParameterBytes(IWbemClassObject * pInst, TCHAR * szParam, LPBYTE * lpData, DWORD *dwDataSize)
  229. {
  230. VARIANT var;
  231. HRESULT hr = S_OK;
  232. SAFEARRAY * pSafeArray;
  233. DWORD dwSrcDataSize;
  234. LPBYTE lpSrcData;
  235. if (!pInst)
  236. return E_INVALIDARG;
  237. VariantInit(&var);
  238. hr = pInst->Get(szParam, 0, &var, 0, 0);
  239. if (SUCCEEDED(hr))
  240. {
  241. if (var.vt != VT_NULL)
  242. {
  243. pSafeArray = var.parray;
  244. dwSrcDataSize = pSafeArray->rgsabound[0].cElements;
  245. lpSrcData = (LPBYTE) pSafeArray->pvData;
  246. *lpData = (LPBYTE)LocalAlloc (LPTR, dwSrcDataSize);
  247. if (!(*lpData))
  248. {
  249. return HRESULT_FROM_WIN32(GetLastError());
  250. }
  251. CopyMemory (*lpData, lpSrcData, dwSrcDataSize);
  252. *dwDataSize = dwSrcDataSize;
  253. }
  254. else
  255. {
  256. hr = E_UNEXPECTED;
  257. }
  258. }
  259. VariantClear(&var);
  260. return hr;
  261. }
  262. HRESULT WINAPI ImportRSoPData (LPOLESTR lpNameSpace, LPOLESTR lpFileName)
  263. {
  264. IMofCompiler * pIMofCompiler;
  265. HRESULT hr;
  266. WBEM_COMPILE_STATUS_INFO info;
  267. //
  268. // Check args
  269. //
  270. if (!lpNameSpace)
  271. {
  272. DebugMsg((DM_WARNING, TEXT("LoadNameSpaceFromFile: Null namespace arg")));
  273. return E_INVALIDARG;
  274. }
  275. if (!lpFileName)
  276. {
  277. DebugMsg((DM_WARNING, TEXT("LoadNameSpaceFromFile: Null filename arg")));
  278. return E_INVALIDARG;
  279. }
  280. //
  281. // Create an instance of the mof compiler
  282. //
  283. hr = CoCreateInstance(CLSID_MofCompiler, NULL, CLSCTX_INPROC_SERVER,
  284. IID_IMofCompiler, (LPVOID *) &pIMofCompiler);
  285. if (FAILED(hr))
  286. {
  287. DebugMsg((DM_WARNING, TEXT("LoadNameSpaceFromFile: CoCreateInstance failed with 0x%x"), hr));
  288. return hr;
  289. }
  290. //
  291. // Compile the file
  292. //
  293. ZeroMemory (&info, sizeof(info));
  294. hr = pIMofCompiler->CompileFile (lpFileName, lpNameSpace, NULL, NULL, NULL,
  295. 0, 0, 0, &info);
  296. if (FAILED(hr))
  297. {
  298. DebugMsg((DM_WARNING, TEXT("LoadNameSpaceFromFile: CompileFile failed with 0x%x"), hr));
  299. }
  300. pIMofCompiler->Release();
  301. return hr;
  302. }
  303. BOOL WriteMofFile (HANDLE hFile, LPTSTR lpData)
  304. {
  305. DWORD dwBytesWritten, dwAnsiDataSize, dwByteCount, dwLFCount = 0;
  306. LPSTR lpAnsiData;
  307. LPTSTR lpTemp, lpRealData, lpDest;
  308. //
  309. // The lpData argument contains linefeed characters only. We need to convert
  310. // these to CR LF characters. Loop through the data to determine how many LFs
  311. // need to be converted.
  312. //
  313. lpTemp = lpData;
  314. while (*lpTemp)
  315. {
  316. if (*lpTemp == 0x0A)
  317. {
  318. dwLFCount++;
  319. }
  320. lpTemp++;
  321. }
  322. //
  323. // Allocate a new buffer to hold the string plus CR characters
  324. //
  325. lpRealData = (LPTSTR) LocalAlloc (LPTR, (lstrlen(lpData) + dwLFCount + 1) * sizeof(TCHAR));
  326. if (!lpRealData)
  327. {
  328. DebugMsg((DM_WARNING, TEXT("WriteMofFile: LocalAlloc failed with %d"), GetLastError()));
  329. return FALSE;
  330. }
  331. //
  332. // Copy the string replacing LF with CRLF as we find them
  333. //
  334. lpDest = lpRealData;
  335. lpTemp = lpData;
  336. while (*lpTemp)
  337. {
  338. if (*lpTemp == 0x0A)
  339. {
  340. *lpDest = 0x0D;
  341. lpDest++;
  342. }
  343. *lpDest = *lpTemp;
  344. lpDest++;
  345. lpTemp++;
  346. }
  347. //
  348. // Allocate a buffer to hold the ANSI data
  349. //
  350. dwAnsiDataSize = lstrlen (lpRealData) * 2;
  351. lpAnsiData = (LPSTR) LocalAlloc (LPTR, dwAnsiDataSize);
  352. if (!lpAnsiData)
  353. {
  354. DebugMsg((DM_WARNING, TEXT("WriteMofFile: LocalAlloc failed with %d"), GetLastError()));
  355. LocalFree (lpRealData);
  356. return FALSE;
  357. }
  358. //
  359. // Convert the buffer
  360. //
  361. dwByteCount = (DWORD) WideCharToMultiByte (CP_ACP, 0, lpRealData, lstrlen(lpRealData), lpAnsiData, dwAnsiDataSize, NULL, NULL);
  362. LocalFree (lpRealData);
  363. if (!dwByteCount)
  364. {
  365. DebugMsg((DM_WARNING, TEXT("WriteMofFile: WriteFile failed with %d"), GetLastError()));
  366. LocalFree (lpAnsiData);
  367. return FALSE;
  368. }
  369. //
  370. // Write the mof description to the file
  371. //
  372. if (!WriteFile (hFile, lpAnsiData, dwByteCount, &dwBytesWritten, NULL))
  373. {
  374. DebugMsg((DM_WARNING, TEXT("WriteMofFile: WriteFile failed with %d"), GetLastError()));
  375. LocalFree (lpAnsiData);
  376. return FALSE;
  377. }
  378. LocalFree (lpAnsiData);
  379. //
  380. // Make sure it was all written to the file
  381. //
  382. if (dwByteCount != dwBytesWritten)
  383. {
  384. DebugMsg((DM_WARNING, TEXT("WriteMofFile: Failed to write the correct amount of data.")));
  385. SetLastError(ERROR_INVALID_DATA);
  386. return FALSE;
  387. }
  388. return TRUE;
  389. }
  390. HRESULT EnumInstances (IWbemServices * pIWbemServices, BSTR pClassName, HANDLE hFile)
  391. {
  392. IWbemClassObject *pObjects[2], *pObject;
  393. IEnumWbemClassObject *pEnum = NULL;
  394. ULONG ulCount;
  395. HRESULT hr;
  396. BSTR bstrClass;
  397. DWORD dwError;
  398. //
  399. // Create the instance enumerator
  400. //
  401. hr = pIWbemServices->CreateInstanceEnum (pClassName, WBEM_FLAG_DEEP | WBEM_FLAG_RETURN_IMMEDIATELY, NULL, &pEnum);
  402. if (FAILED(hr))
  403. {
  404. DebugMsg((DM_WARNING, TEXT("EnumInstances: CreateInstanceEnum failed with 0x%x"), hr));
  405. return hr;
  406. }
  407. //
  408. // Walk through the list
  409. //
  410. while (pEnum->Next(WBEM_INFINITE, 1, pObjects, &ulCount) == S_OK)
  411. {
  412. pObject = pObjects[0];
  413. //
  414. // Get the mof description of this class
  415. //
  416. hr = pObject->GetObjectText (0, &bstrClass);
  417. pObject->Release();
  418. if (FAILED(hr))
  419. {
  420. DebugMsg((DM_WARNING, TEXT("EnumInstances: GetObjectText failed with 0x%x"), hr));
  421. pEnum->Release();
  422. return hr;
  423. }
  424. //
  425. // Write the mof description to the file
  426. //
  427. if (!WriteMofFile (hFile, bstrClass))
  428. {
  429. dwError = GetLastError();
  430. DebugMsg((DM_WARNING, TEXT("EnumInstances: WriteMofFile failed with %d"), dwError));
  431. SysFreeString (bstrClass);
  432. pEnum->Release();
  433. return HRESULT_FROM_WIN32(dwError);
  434. }
  435. SysFreeString (bstrClass);
  436. }
  437. pEnum->Release();
  438. return hr;
  439. }
  440. HRESULT EnumNameSpace (IWbemServices * pIWbemServices, HANDLE hFile)
  441. {
  442. IWbemClassObject *pObjects[2], *pObject;
  443. IEnumWbemClassObject *pEnum = NULL;
  444. ULONG ulCount;
  445. HRESULT hr;
  446. VARIANT var;
  447. BSTR bstrClass;
  448. DWORD dwError;
  449. //
  450. // Create the class enumerator
  451. //
  452. hr = pIWbemServices->CreateClassEnum (NULL, WBEM_FLAG_DEEP | WBEM_FLAG_RETURN_IMMEDIATELY, NULL, &pEnum);
  453. if (FAILED(hr))
  454. {
  455. DebugMsg((DM_WARNING, TEXT("EnumNameSpace: CreateClassEnum failed with 0x%x"), hr));
  456. return hr;
  457. }
  458. //
  459. // Walk through the list
  460. //
  461. while (pEnum->Next(WBEM_INFINITE, 1, pObjects, &ulCount) == S_OK)
  462. {
  463. pObject = pObjects[0];
  464. //
  465. // Get the class name
  466. //
  467. hr = pObject->Get (TEXT("__CLASS"), 0, &var, NULL, NULL);
  468. if (FAILED(hr))
  469. {
  470. DebugMsg((DM_WARNING, TEXT("EnumNameSpace: Failed to get class name with 0x%x"), hr));
  471. pEnum->Release();
  472. return hr;
  473. }
  474. //
  475. // Check if this is a system class. System classes start with "_"
  476. //
  477. if (var.bstrVal[0] != TEXT('_'))
  478. {
  479. //
  480. // Get the mof description of this class
  481. //
  482. hr = pObject->GetObjectText (0, &bstrClass);
  483. if (FAILED(hr))
  484. {
  485. DebugMsg((DM_WARNING, TEXT("EnumNameSpace: GetObjectText failed with 0x%x"), hr));
  486. VariantClear (&var);
  487. pEnum->Release();
  488. return hr;
  489. }
  490. //
  491. // Write the mof description to the file
  492. //
  493. if (!WriteMofFile (hFile, bstrClass))
  494. {
  495. dwError = GetLastError();
  496. DebugMsg((DM_WARNING, TEXT("EnumNameSpace: WriteMofFile failed with %d"), dwError));
  497. SysFreeString (bstrClass);
  498. VariantClear (&var);
  499. pEnum->Release();
  500. return HRESULT_FROM_WIN32(dwError);
  501. }
  502. SysFreeString (bstrClass);
  503. //
  504. // Now enumerate the instances of this class
  505. //
  506. hr = EnumInstances (pIWbemServices, var.bstrVal, hFile);
  507. if (FAILED(hr))
  508. {
  509. DebugMsg((DM_WARNING, TEXT("EnumNameSpace: EnumInstances failed with 0x%x"), hr));
  510. VariantClear (&var);
  511. pEnum->Release();
  512. return hr;
  513. }
  514. }
  515. VariantClear (&var);
  516. }
  517. pEnum->Release();
  518. return hr;
  519. }
  520. HRESULT WINAPI ExportRSoPData (LPTSTR lpNameSpace, LPTSTR lpFileName)
  521. {
  522. IWbemLocator *pIWbemLocator;
  523. IWbemServices *pIWbemServices;
  524. HANDLE hFile;
  525. HRESULT hr;
  526. DWORD dwError;
  527. //
  528. // Open the data file
  529. //
  530. hFile = CreateFile (lpFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
  531. FILE_ATTRIBUTE_NORMAL, NULL);
  532. if (hFile == INVALID_HANDLE_VALUE)
  533. {
  534. dwError = GetLastError();
  535. DebugMsg((DM_WARNING, TEXT("ExportRSoPData: CreateFile for %s failed with %d"), lpFileName, dwError));
  536. return HRESULT_FROM_WIN32(dwError);
  537. }
  538. //
  539. // Create a locater instance
  540. //
  541. hr = CoCreateInstance(CLSID_WbemLocator, NULL, CLSCTX_INPROC_SERVER,
  542. IID_IWbemLocator, (LPVOID *) &pIWbemLocator);
  543. if (FAILED(hr))
  544. {
  545. DebugMsg((DM_WARNING, TEXT("ExportRSoPData: CoCreateInstance failed with 0x%x"), hr));
  546. CloseHandle (hFile);
  547. return hr;
  548. }
  549. //
  550. // Connect to the server
  551. //
  552. hr = pIWbemLocator->ConnectServer(lpNameSpace, NULL, NULL, 0, 0, NULL, NULL, &pIWbemServices);
  553. if (FAILED(hr))
  554. {
  555. DebugMsg((DM_WARNING, TEXT("ExportRSoPData: ConnectServer to %s failed with 0x%x"), lpNameSpace, hr));
  556. pIWbemLocator->Release();
  557. CloseHandle (hFile);
  558. return hr;
  559. }
  560. //
  561. // Enumerate the classes and instances
  562. //
  563. hr = EnumNameSpace (pIWbemServices, hFile);
  564. if (FAILED(hr))
  565. {
  566. DebugMsg((DM_WARNING, TEXT("ExportRSoPData: EnumNameSpace failed with 0x%x"), hr));
  567. }
  568. CloseHandle (hFile);
  569. pIWbemServices->Release();
  570. pIWbemLocator->Release();
  571. return hr;
  572. }
  573. //******************************************************************************
  574. //
  575. // Function: WbemTimeToSystemTime
  576. //
  577. // Description:
  578. //
  579. // Parameters:
  580. //
  581. // Return:
  582. //
  583. // History: 08-16-2000 stevebl rewrote to use WBEMTime class
  584. //
  585. //******************************************************************************
  586. HRESULT WbemTimeToSystemTime(XBStr& xbstrWbemTime, SYSTEMTIME& sysTime)
  587. {
  588. HRESULT hr = E_FAIL;
  589. WBEMTime wt(xbstrWbemTime);
  590. if (wt.GetSYSTEMTIME(&sysTime))
  591. {
  592. hr = S_OK;
  593. }
  594. return hr;
  595. }