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.

951 lines
26 KiB

  1. /*++
  2. Copyright (C) 1998-2001 Microsoft Corporation
  3. Module Name:
  4. REGMETHODS.CPP
  5. Abstract:
  6. Purpose: Implements the registry provider methods.
  7. History:
  8. --*/
  9. #include "precomp.h"
  10. #include "perfprov.h"
  11. #include "cvariant.h"
  12. #include "provreg.h"
  13. #include "reg.h"
  14. #include "genutils.h"
  15. #include <cominit.h>
  16. #include <arrtempl.h>
  17. #include <userenv.h>
  18. #include <lmcons.h>
  19. enum StringType{SIMPLE, EXPANDED};
  20. AutoProfile::AutoProfile() : m_bLoaded(FALSE), m_hToken(NULL),
  21. m_hRoot(NULL)
  22. {
  23. }
  24. AutoProfile::~AutoProfile()
  25. {
  26. if(m_bLoaded)
  27. {
  28. UnloadUserProfile(m_hToken, m_hRoot);
  29. }
  30. if(m_hToken != NULL)
  31. CloseHandle(m_hToken);
  32. }
  33. HRESULT AutoProfile::LoadProfile(HKEY & hRoot)
  34. {
  35. PROFILEINFO pi;
  36. HRESULT hr;
  37. // If the profile is already loaded, there is no need to do it
  38. DWORD dwFlags, dwLastError;
  39. if(GetProfileType(&dwFlags))
  40. {
  41. hRoot = HKEY_CURRENT_USER;
  42. return S_OK;
  43. }
  44. memset((void *)&pi, 0, sizeof(pi));
  45. pi.dwSize = sizeof(pi);
  46. BOOL bRes;
  47. bRes = OpenThreadToken(GetCurrentThread(),
  48. TOKEN_IMPERSONATE | TOKEN_DUPLICATE | TOKEN_QUERY,
  49. TRUE, &m_hToken);
  50. if(!bRes)
  51. return WBEM_E_FAILED;
  52. TCHAR cUsername[UNLEN + 1];
  53. cUsername[0] = 0;
  54. DWORD dwSize = UNLEN + 1;
  55. BOOL bRet = GetUserName(cUsername, &dwSize);
  56. if(!bRet)
  57. return WBEM_E_FAILED;
  58. pi.lpUserName = cUsername;
  59. pi.dwFlags = 1;
  60. CoRevertToSelf();
  61. bRet = LoadUserProfile(m_hToken, &pi);
  62. if(bRet == 0)
  63. {
  64. hRoot = NULL;
  65. dwLastError = GetLastError();
  66. HRESULT hr2 = CoImpersonateClient();
  67. if(FAILED(hr2))
  68. ERRORTRACE((LOG_STDPROV, "Registry event provider unable "
  69. "to CoImpersonateClient hr2= 0x%x.\n", hr2));
  70. if(dwLastError == ERROR_ACCESS_DENIED ||dwLastError == ERROR_PRIVILEGE_NOT_HELD)
  71. hr = WBEM_E_ACCESS_DENIED;
  72. else
  73. hr = WBEM_E_FAILED;
  74. }
  75. else
  76. {
  77. hr = CoImpersonateClient();
  78. m_bLoaded = TRUE;
  79. m_hRoot = (HKEY)pi.hProfile;
  80. hRoot = (HKEY)pi.hProfile;
  81. }
  82. return hr;
  83. }
  84. void CopyOrConvert(TCHAR * pTo, WCHAR * pFrom, int iLen)
  85. {
  86. #ifdef UNICODE
  87. wcsncpy(pTo, pFrom,iLen);
  88. #else
  89. wcstombs(pTo, pFrom, iLen);
  90. #endif
  91. pTo[iLen-1] = 0;
  92. return;
  93. }
  94. BSTR GetBSTR(TCHAR * pIn)
  95. {
  96. #ifdef UNICODE
  97. return SysAllocString(pIn);
  98. #else
  99. int iBuffLen = lstrlen(pIn)+1;
  100. WCHAR * pTemp = new WCHAR[iBuffLen];
  101. if(pTemp == NULL)
  102. return NULL;
  103. mbstowcs(pTemp, pIn, iBuffLen);
  104. BSTR bRet = SysAllocString(pTemp);
  105. delete []pTemp;
  106. return bRet;
  107. #endif
  108. }
  109. BOOL IsTypeMismatch(Registry & reg, TCHAR * pValueName, DWORD dwExpectedType)
  110. {
  111. DWORD dwType;
  112. long lRet = reg.GetType(pValueName, &dwType);
  113. if(lRet == ERROR_SUCCESS && dwExpectedType != dwType)
  114. return TRUE;
  115. else
  116. return FALSE;
  117. }
  118. //***************************************************************************
  119. //
  120. // HRESULT SetStatusAndReturnOK;
  121. //
  122. // Purpose: Sets the status code in the sink.
  123. //
  124. //***************************************************************************
  125. HRESULT SetStatusAndReturnOK(SCODE sc, IWbemObjectSink* pSink)
  126. {
  127. pSink->SetStatus(0,sc, NULL, NULL);
  128. return S_OK;
  129. }
  130. //***************************************************************************
  131. //
  132. // SAFEARRAY FAR* MySafeArrayCreate
  133. //
  134. // Purpose: Creates a safearray.
  135. //
  136. // Return: pointer to safearray, NULL if error.
  137. //
  138. //***************************************************************************
  139. SAFEARRAY FAR* MySafeArrayCreate(long lNumElement, VARTYPE vt)
  140. {
  141. SAFEARRAYBOUND rgsabound[1];
  142. rgsabound[0].lLbound = 0;
  143. rgsabound[0].cElements = lNumElement;
  144. return SafeArrayCreate( vt, 1 , rgsabound );
  145. }
  146. //***************************************************************************
  147. //
  148. // bool GetInArgString
  149. //
  150. // Purpose: Reads a string argument from the input object and puts it into
  151. // a value allocated by the caller.
  152. //
  153. // Return: true if OK.
  154. //
  155. //***************************************************************************
  156. TCHAR * GetInArgString(IWbemClassObject* pInParams, WCHAR * pwcName)
  157. {
  158. TCHAR * pOut = NULL;
  159. if(pInParams == NULL || pwcName == NULL)
  160. return NULL;
  161. VARIANT var;
  162. VariantInit(&var);
  163. SCODE sc = pInParams->Get(pwcName, 0, &var, NULL, NULL);
  164. if(sc == S_OK && var.vt == VT_BSTR)
  165. {
  166. DWORD dwLen = wcslen(var.bstrVal) + 1;
  167. pOut = new TCHAR[dwLen];
  168. if(pOut)
  169. StringCchCopyW(pOut, dwLen, var.bstrVal);
  170. }
  171. VariantClear(&var);
  172. return pOut;
  173. }
  174. //***************************************************************************
  175. //
  176. // SCODE EnumKey
  177. //
  178. // Purpose: Enumerate the subkeys and loads them into the output arguments.
  179. //
  180. // Return: error code or 0 if OK.
  181. //
  182. //***************************************************************************
  183. SCODE EnumKey(HKEY hRoot, TCHAR * cSubKey, IWbemClassObject* pOutParams)
  184. {
  185. SCODE sc;
  186. DWORD dwNumSubKeys, dwMaxSubKeyLen, dwNumValues, dwMaxValueNameLen;
  187. TCHAR * pcTemp = NULL;
  188. // Open the key
  189. HKEY hKey;
  190. long lRet = RegOpenKeyEx(hRoot, cSubKey, 0, KEY_ENUMERATE_SUB_KEYS|KEY_QUERY_VALUE , &hKey);
  191. if(lRet != ERROR_SUCCESS)
  192. return lRet;
  193. CRegCloseMe cm(hKey);
  194. // Count the number of keys and the max size
  195. lRet = RegQueryInfoKey(hKey, NULL, NULL, NULL,
  196. &dwNumSubKeys, // number of subkeys
  197. &dwMaxSubKeyLen, // longest subkey name
  198. NULL,
  199. &dwNumValues, // number of value entries
  200. &dwMaxValueNameLen, // longest value name
  201. NULL, NULL, NULL);
  202. if(lRet != ERROR_SUCCESS || dwMaxSubKeyLen == 0)
  203. return lRet;
  204. pcTemp = new TCHAR[dwMaxSubKeyLen+1];
  205. if(pcTemp == NULL)
  206. return WBEM_E_OUT_OF_MEMORY;
  207. CVectorDeleteMe<TCHAR> dm(pcTemp);
  208. // Create the safe array for returning the data
  209. SAFEARRAY FAR* psa = MySafeArrayCreate(dwNumSubKeys, VT_BSTR);
  210. if(psa == NULL)
  211. {
  212. return WBEM_E_OUT_OF_MEMORY;
  213. }
  214. // Put each value name into the array
  215. for(long lTry = 0; lTry < dwNumSubKeys; lTry++)
  216. {
  217. lRet = RegEnumKey(hKey, lTry, pcTemp, dwMaxSubKeyLen+1);
  218. if(lRet == ERROR_SUCCESS)
  219. {
  220. pcTemp[dwMaxSubKeyLen] = 0;
  221. BSTR bstr = GetBSTR(pcTemp);
  222. if(bstr)
  223. {
  224. sc = SafeArrayPutElement(psa, &lTry, bstr);
  225. SysFreeString(bstr);
  226. if(FAILED(sc))
  227. {
  228. SafeArrayDestroy(psa);
  229. return sc;
  230. }
  231. }
  232. }
  233. }
  234. // Write the data back!
  235. VARIANT var;
  236. var.vt = VT_BSTR | VT_ARRAY;
  237. var.parray = psa;
  238. sc = pOutParams->Put( L"sNames", 0, &var, 0);
  239. VariantClear(&var);
  240. return sc;
  241. }
  242. //***************************************************************************
  243. //
  244. // SCODE EnumValue
  245. //
  246. // Purpose: Enumerates the value names and types and puts the results into
  247. // the output object.
  248. //
  249. // Return: error code or 0 if OK.
  250. //
  251. //***************************************************************************
  252. SCODE EnumValue(HKEY hRoot, TCHAR * cSubKey, IWbemClassObject* pOutParams)
  253. {
  254. SCODE sc1, sc2;
  255. DWORD dwNumSubKeys, dwMaxSubKeyLen, dwNumValues, dwMaxValueNameLen;
  256. TCHAR * pcTemp = NULL;
  257. DWORD dwType, dwSize;
  258. // Open the registry key
  259. HKEY hKey;
  260. long lRet = RegOpenKeyEx((HKEY)hRoot, cSubKey, 0, KEY_QUERY_VALUE, &hKey);
  261. if(lRet != ERROR_SUCCESS)
  262. return lRet;
  263. CRegCloseMe cm(hKey);
  264. // Count the number of values and the max size
  265. lRet = RegQueryInfoKey(hKey, NULL, NULL, NULL,
  266. &dwNumSubKeys, // number of subkeys
  267. &dwMaxSubKeyLen, // longest subkey name
  268. NULL,
  269. &dwNumValues, // number of value entries
  270. &dwMaxValueNameLen, // longest value name
  271. NULL, NULL, NULL);
  272. if(lRet != ERROR_SUCCESS || dwMaxValueNameLen == 0)
  273. return lRet;
  274. pcTemp = new TCHAR[dwMaxValueNameLen+1];
  275. if(pcTemp == NULL)
  276. return WBEM_E_OUT_OF_MEMORY;
  277. CVectorDeleteMe<TCHAR> dm(pcTemp);
  278. // Create safe arrays for the data names and types
  279. SAFEARRAY FAR* psaNames = MySafeArrayCreate(dwNumValues, VT_BSTR);
  280. if(psaNames == NULL)
  281. {
  282. return WBEM_E_OUT_OF_MEMORY;
  283. }
  284. SAFEARRAY FAR* psaTypes = MySafeArrayCreate(dwNumValues, VT_I4);
  285. if(psaTypes == NULL)
  286. {
  287. SafeArrayDestroy(psaNames);
  288. return WBEM_E_OUT_OF_MEMORY;
  289. }
  290. // Fill in the arrays
  291. for(long lTry = 0; lTry < dwNumValues; lTry++)
  292. {
  293. dwSize = dwMaxValueNameLen+1;
  294. lRet = RegEnumValue(hKey, lTry, pcTemp, &dwSize, 0, &dwType, NULL, 0);
  295. if(lRet == ERROR_SUCCESS)
  296. {
  297. pcTemp[dwMaxValueNameLen] = 0;
  298. BSTR bstr = GetBSTR(pcTemp);
  299. if(bstr)
  300. {
  301. sc1 = SafeArrayPutElement(psaNames, &lTry, bstr);
  302. sc2 = SafeArrayPutElement(psaTypes, &lTry, &dwType);
  303. SysFreeString(bstr);
  304. if(FAILED(sc1) || FAILED(sc2))
  305. {
  306. SafeArrayDestroy(psaNames);
  307. SafeArrayDestroy(psaTypes);
  308. return WBEM_E_OUT_OF_MEMORY;
  309. }
  310. }
  311. }
  312. }
  313. // Put the arrays containing the value names and types into the output object
  314. VARIANT var;
  315. var.vt = VT_BSTR | VT_ARRAY;
  316. var.parray = psaNames;
  317. pOutParams->Put( L"sNames", 0, &var, 0);
  318. VariantClear(&var);
  319. var.vt = VT_I4 | VT_ARRAY;
  320. var.parray = psaTypes;
  321. SCODE sc = pOutParams->Put( L"Types", 0, &var, 0);
  322. VariantClear(&var);
  323. return sc;
  324. }
  325. //***************************************************************************
  326. //
  327. // SCODE GetStr
  328. //
  329. // Purpose: Reads a string and puts it into the output argument. Note that
  330. // this works with either normal strings or expanded registry strings.
  331. //
  332. // Return: error code or 0 if OK.
  333. //
  334. //***************************************************************************
  335. SCODE GetStr(HKEY hRoot, TCHAR * cSubKey, TCHAR * cValueName, IWbemClassObject* pOutParams)
  336. {
  337. Registry reg(hRoot, KEY_QUERY_VALUE, (TCHAR *)cSubKey);
  338. long lRet = reg.GetLastError();
  339. if(lRet != ERROR_SUCCESS)
  340. return lRet;
  341. // Get the string
  342. TCHAR * pcValue;
  343. lRet = reg.GetStr(cValueName, &pcValue);
  344. if(lRet != ERROR_SUCCESS)
  345. {
  346. DWORD dwType;
  347. long lRet2 = reg.GetType(cValueName, &dwType);
  348. if(lRet2 == ERROR_SUCCESS && dwType != REG_SZ && dwType != REG_EXPAND_SZ)
  349. return WBEM_E_TYPE_MISMATCH;
  350. return lRet;
  351. }
  352. CDeleteMe<TCHAR> dm(pcValue);
  353. VARIANT var;
  354. var.bstrVal = GetBSTR(pcValue);
  355. var.vt = VT_BSTR;
  356. if(var.bstrVal == NULL)
  357. return WBEM_E_OUT_OF_MEMORY;
  358. lRet = pOutParams->Put( L"sValue", 0, &var, 0);
  359. VariantClear(&var);
  360. return lRet;
  361. }
  362. //***************************************************************************
  363. //
  364. // SCODE SetMultiStrValue
  365. //
  366. // Purpose: Writes multi string values to the registry.
  367. //
  368. // Return: error code or 0 if OK.
  369. //
  370. //***************************************************************************
  371. SCODE SetMultiStrValue(HKEY hRoot, TCHAR * cSubKey, TCHAR * cValueName, IWbemClassObject* pInParams)
  372. {
  373. SCODE sc;
  374. Registry reg(hRoot, KEY_SET_VALUE, (TCHAR *)cSubKey);
  375. if(reg.GetLastError() != 0)
  376. return reg.GetLastError();
  377. VARIANT var;
  378. VariantInit(&var);
  379. sc = pInParams->Get(L"sValue", 0, &var, NULL, NULL);
  380. if(sc != S_OK)
  381. return sc;
  382. CClearMe cm(&var);
  383. if(var.vt != (VT_ARRAY | VT_BSTR))
  384. {
  385. return WBEM_E_INVALID_PARAMETER;
  386. }
  387. SAFEARRAY * psa = var.parray;
  388. long lLbound, lUbound;
  389. sc = SafeArrayGetLBound(psa, 1, &lLbound );
  390. sc |= SafeArrayGetUBound(psa, 1, &lUbound );
  391. if(sc != S_OK)
  392. {
  393. return WBEM_E_INVALID_PARAMETER;
  394. }
  395. long lNumElements = lUbound - lLbound + 1;
  396. // Calculate the necessary size
  397. long lSize = 1, lTry;
  398. for(lTry = lLbound; lTry <= lUbound; lTry++)
  399. {
  400. BSTR bstr = NULL;
  401. if(S_OK == SafeArrayGetElement(psa, &lTry, &bstr) && bstr)
  402. {
  403. lSize += SysStringLen(bstr) + 1;
  404. SysFreeString(bstr);
  405. }
  406. else
  407. {
  408. return WBEM_E_INVALID_PARAMETER;
  409. }
  410. }
  411. WCHAR * pMulti = new WCHAR [lSize];
  412. if(pMulti == NULL)
  413. {
  414. return WBEM_E_OUT_OF_MEMORY;
  415. }
  416. memset(pMulti, 0, lSize * sizeof(WCHAR));
  417. WCHAR * pNext = pMulti;
  418. // Do the conversion;
  419. for(lTry = lLbound; lTry <= lUbound; lTry++)
  420. {
  421. BSTR bstr;
  422. if(S_OK == SafeArrayGetElement(psa, &lTry, &bstr))
  423. {
  424. StringCchCopyW(pNext, lSize - (pNext - pMulti), bstr);
  425. pNext += SysStringLen(bstr) + 1;
  426. SysFreeString(bstr);
  427. }
  428. }
  429. long lRet;
  430. lRet = reg.SetMultiStr(cValueName, pMulti, lSize * sizeof(WCHAR));
  431. delete [] pMulti;
  432. return lRet;
  433. }
  434. //***************************************************************************
  435. //
  436. // SCODE GetMultiStrValue
  437. //
  438. // Purpose: Reads multi strings from the registry.
  439. //
  440. // Return: error code or 0 if OK.
  441. //
  442. //***************************************************************************
  443. SCODE GetMultiStrValue(HKEY hRoot, TCHAR * cSubKey, TCHAR * cValueName, IWbemClassObject* pOutParams)
  444. {
  445. SCODE sc;
  446. Registry reg(hRoot, KEY_QUERY_VALUE, (TCHAR *)cSubKey);
  447. if(reg.GetLastError() != 0)
  448. return reg.GetLastError();
  449. DWORD dwSize = 0;
  450. TCHAR * pMulti = reg.GetMultiStr(cValueName, dwSize);
  451. if(pMulti == NULL)
  452. return reg.GetLastError();
  453. CVectorDeleteMe<TCHAR> dm(pMulti);
  454. // count the number of strings
  455. long lNumString = 0;
  456. TCHAR * pNext;
  457. DWORD dwNumChar = dwSize / sizeof(WCHAR);
  458. WCHAR * pFinalNull = pMulti + dwNumChar - 1;
  459. for(pNext = pMulti; pNext < pFinalNull; pNext += lstrlen(pNext) + 1)
  460. lNumString++;
  461. // create the bstr array
  462. SAFEARRAY FAR* psa = MySafeArrayCreate(lNumString, VT_BSTR);
  463. if(psa == NULL)
  464. {
  465. return WBEM_E_OUT_OF_MEMORY;
  466. }
  467. pNext = pMulti;
  468. for(long lTry = 0; lTry < lNumString; lTry++, pNext += lstrlen(pNext) + 1)
  469. {
  470. int iLen = lstrlen(pNext) + 1;
  471. BSTR bstr = GetBSTR(pNext);
  472. if(bstr)
  473. {
  474. sc = SafeArrayPutElement(psa, &lTry, bstr);
  475. SysFreeString(bstr);
  476. if(FAILED(sc))
  477. {
  478. SafeArrayDestroy(psa);
  479. return sc;
  480. }
  481. }
  482. }
  483. // put the data
  484. VARIANT var;
  485. var.vt = VT_BSTR | VT_ARRAY;
  486. var.parray = psa;
  487. sc = pOutParams->Put( L"sValue", 0, &var, 0);
  488. VariantClear(&var);
  489. return sc;
  490. }
  491. //***************************************************************************
  492. //
  493. // SCODE SetStringValue
  494. //
  495. // Purpose: Writes strings to the registry. These strings may
  496. // contain environment strings.
  497. //
  498. // Return: error code or 0 if OK.
  499. //
  500. //***************************************************************************
  501. SCODE SetStringValue(HKEY hRoot, TCHAR * cSubKey, TCHAR * cValueName, IWbemClassObject* pInParams,
  502. StringType st)
  503. {
  504. Registry reg(hRoot, KEY_SET_VALUE, (TCHAR *)cSubKey);
  505. long lRet = reg.GetLastError();
  506. if(lRet != ERROR_SUCCESS)
  507. return lRet;
  508. VARIANT var;
  509. VariantInit(&var);
  510. SCODE sc = pInParams->Get(L"sValue", 0, &var, NULL, NULL);
  511. if(sc != S_OK)
  512. return sc;
  513. if(var.vt != VT_BSTR)
  514. {
  515. VariantClear(&var);
  516. return WBEM_E_INVALID_PARAMETER;
  517. }
  518. int iLen = 2*wcslen(var.bstrVal) + 2;
  519. TCHAR * pValue = new TCHAR[iLen];
  520. if(pValue)
  521. {
  522. CopyOrConvert(pValue, var.bstrVal, iLen);
  523. if(st == SIMPLE)
  524. sc = reg.SetStr(cValueName, pValue);
  525. else
  526. sc = reg.SetExpandStr(cValueName, pValue);
  527. delete [] pValue;
  528. }
  529. else
  530. sc = WBEM_E_OUT_OF_MEMORY;
  531. VariantClear(&var);
  532. return sc;
  533. }
  534. //***************************************************************************
  535. //
  536. // SCODE SetBinaryValue
  537. //
  538. // Purpose: Writes binary data to the registry.
  539. //
  540. // Return: error code or 0 if OK.
  541. //
  542. //***************************************************************************
  543. SCODE SetBinaryValue(HKEY hRoot, TCHAR * cSubKey, TCHAR * cValueName, IWbemClassObject* pInParams)
  544. {
  545. Registry reg(hRoot, KEY_SET_VALUE, (TCHAR *)cSubKey);
  546. if(reg.GetLastError() != 0)
  547. return reg.GetLastError();
  548. VARIANT var;
  549. VariantInit(&var);
  550. SCODE sc = pInParams->Get(L"uValue", 0, &var, NULL, NULL);
  551. if(sc != S_OK)
  552. return sc;
  553. if(var.vt != (VT_ARRAY | VT_UI1) || var.parray == NULL)
  554. {
  555. VariantClear(&var);
  556. return WBEM_E_INVALID_PARAMETER;
  557. }
  558. SAFEARRAY * psa = var.parray;
  559. long lLbound, lUbound;
  560. sc = SafeArrayGetLBound(psa, 1, &lLbound );
  561. sc |= SafeArrayGetUBound(psa, 1, &lUbound );
  562. if(sc == S_OK)
  563. {
  564. byte * pData;
  565. sc = SafeArrayAccessData(psa, (void HUGEP* FAR*)&pData);
  566. if(sc == S_OK)
  567. {
  568. sc = reg.SetBinary(cValueName, pData, DWORD(lUbound - lLbound + 1));
  569. }
  570. }
  571. VariantClear(&var);
  572. return sc;
  573. }
  574. //***************************************************************************
  575. //
  576. // SCODE GetBinaryValue
  577. //
  578. // Purpose: Reads binary data from the registry.
  579. //
  580. // Return: error code or 0 if OK.
  581. //
  582. //***************************************************************************
  583. SCODE GetBinaryValue(HKEY hRoot, TCHAR * cSubKey, TCHAR * cValueName, IWbemClassObject* pOutParams)
  584. {
  585. Registry reg(hRoot, KEY_QUERY_VALUE, (TCHAR *)cSubKey);
  586. if(reg.GetLastError() != 0)
  587. return reg.GetLastError();
  588. SCODE sc;
  589. DWORD dwSize;
  590. byte * pRegData;
  591. long lRet = reg.GetBinary(cValueName, &pRegData, &dwSize);
  592. if(lRet != ERROR_SUCCESS || pRegData == NULL)
  593. {
  594. if(IsTypeMismatch(reg, cValueName, REG_BINARY))
  595. return WBEM_E_TYPE_MISMATCH;
  596. else
  597. return lRet;
  598. }
  599. SAFEARRAY FAR* psa = MySafeArrayCreate(dwSize, VT_UI1);
  600. if(psa)
  601. {
  602. TCHAR * pData = NULL;
  603. sc = SafeArrayAccessData(psa, (void HUGEP* FAR*)&pData);
  604. if(sc == S_OK)
  605. {
  606. memcpy(pData, pRegData, dwSize);
  607. SafeArrayUnaccessData(psa);
  608. VARIANT var;
  609. var.vt = VT_UI1|VT_ARRAY;
  610. var.parray = psa;
  611. sc = pOutParams->Put(L"uValue" , 0, &var, 0);
  612. VariantClear(&var);
  613. }
  614. }
  615. else
  616. sc = WBEM_E_OUT_OF_MEMORY;
  617. delete [] pRegData;
  618. return sc;
  619. }
  620. /************************************************************************
  621. * *
  622. *CMethodPro::ExecMethodAsync *
  623. * *
  624. *Purpose: This is the Async function implementation. *
  625. * *
  626. ************************************************************************/
  627. SCODE CImpReg::MethodAsync(const BSTR ObjectPath, const BSTR MethodName,
  628. long lFlags, IWbemContext* pCtx, IWbemClassObject* pInParams,
  629. IWbemObjectSink* pSink)
  630. {
  631. HRESULT hr;
  632. IWbemClassObject * pClass = NULL;
  633. IWbemClassObject * pOutClass = NULL;
  634. IWbemClassObject* pOutParams = NULL;
  635. TCHAR * pcValueName = NULL;
  636. TCHAR * pcSubKey = NULL;
  637. long lRet = 0;
  638. AutoProfile ap;
  639. if(ObjectPath == NULL || MethodName == NULL || pInParams == NULL || pSink == NULL)
  640. return WBEM_E_INVALID_PARAMETER;
  641. // Kevin needs a way to tell if something is write
  642. // Get the class object, this is hard coded and matches the class
  643. // in the MOF. Then create the output argument
  644. hr = m_pGateway->GetObject(L"StdRegProv", 0, pCtx, &pClass, NULL);
  645. if(hr == S_OK)
  646. {
  647. hr = pClass->GetMethod(MethodName, 0, NULL, &pOutClass);
  648. if(hr == S_OK)
  649. {
  650. hr = pOutClass->SpawnInstance(0, &pOutParams);
  651. pOutClass->Release();
  652. }
  653. pClass->Release();
  654. }
  655. if(hr != S_OK)
  656. return SetStatusAndReturnOK(hr, pSink);
  657. CReleaseMe rm0(pOutParams);
  658. // Get the root key and subkeys
  659. VARIANT var;
  660. VariantInit(&var); // Get the input argument
  661. hr = pInParams->Get(L"hDefKey", 0, &var, NULL, NULL);
  662. if(hr != S_OK)
  663. return SetStatusAndReturnOK(hr, pSink);
  664. #ifdef _WIN64
  665. HKEY hRoot = (HKEY)IntToPtr(var.lVal);
  666. #else
  667. HKEY hRoot = (HKEY)var.lVal;
  668. #endif
  669. pcSubKey = GetInArgString(pInParams, L"sSubKeyName");
  670. if(pcSubKey == NULL)
  671. return SetStatusAndReturnOK(WBEM_E_INVALID_PARAMETER, pSink);
  672. CVectorDeleteMe<TCHAR> dm1(pcSubKey);
  673. // This may or may not work since the value name isnt required
  674. pcValueName = GetInArgString(pInParams, L"sValueName");
  675. CVectorDeleteMe<TCHAR> dm2(pcValueName);
  676. SCODE sc = S_OK;
  677. // Impersonate if using NT
  678. if(IsNT() && IsDcomEnabled())
  679. {
  680. sc = WbemCoImpersonateClient();
  681. if(sc != S_OK)
  682. return sc;
  683. }
  684. // If we are using HKCU, the hive may need to be loaded
  685. bool bUsingHKCU = IsNT() && hRoot == HKEY_CURRENT_USER;
  686. if(bUsingHKCU)
  687. sc = ap.LoadProfile(hRoot);
  688. if(sc != S_OK)
  689. return sc;
  690. if(!wbem_wcsicmp(MethodName, L"CreateKey"))
  691. {
  692. HKEY hKey;
  693. if(lstrlen(pcSubKey) < 1)
  694. sc = WBEM_E_INVALID_PARAMETER;
  695. else
  696. {
  697. lRet = RegCreateKey(hRoot, pcSubKey, &hKey);
  698. if(lRet == ERROR_SUCCESS)
  699. RegCloseKey(hKey);
  700. }
  701. }
  702. else if(!wbem_wcsicmp(MethodName, L"DeleteKey"))
  703. {
  704. if(lstrlen(pcSubKey) < 1)
  705. sc = WBEM_E_INVALID_PARAMETER;
  706. else
  707. lRet = RegDeleteKey(hRoot, pcSubKey);
  708. }
  709. else if(!wbem_wcsicmp(MethodName, L"DeleteValue"))
  710. {
  711. HKEY hKey;
  712. lRet = RegOpenKey(hRoot, pcSubKey, &hKey);
  713. if(lRet == ERROR_SUCCESS)
  714. {
  715. lRet = RegDeleteValue(hKey, pcValueName);
  716. RegCloseKey(hKey);
  717. }
  718. }
  719. else if(!wbem_wcsicmp(MethodName, L"EnumKey"))
  720. {
  721. lRet = EnumKey(hRoot, pcSubKey, pOutParams);
  722. }
  723. else if(!wbem_wcsicmp(MethodName, L"EnumValues"))
  724. {
  725. lRet = EnumValue(hRoot, pcSubKey, pOutParams);
  726. }
  727. else if(!wbem_wcsicmp(MethodName, L"GetStringValue") ||
  728. !wbem_wcsicmp(MethodName, L"GetExpandedStringValue"))
  729. {
  730. lRet = GetStr(hRoot, pcSubKey, pcValueName, pOutParams);
  731. }
  732. else if(!wbem_wcsicmp(MethodName, L"SetMultiStringValue"))
  733. {
  734. lRet = SetMultiStrValue(hRoot,pcSubKey,pcValueName,pInParams);
  735. }
  736. else if(!wbem_wcsicmp(MethodName, L"GetMultiStringValue"))
  737. {
  738. lRet = GetMultiStrValue(hRoot,pcSubKey,pcValueName,pOutParams);
  739. }
  740. else if(!wbem_wcsicmp(MethodName, L"SetExpandedStringValue"))
  741. {
  742. lRet = SetStringValue(hRoot, pcSubKey, pcValueName, pInParams, EXPANDED);
  743. }
  744. else if(!wbem_wcsicmp(MethodName, L"SetStringValue"))
  745. {
  746. lRet = SetStringValue(hRoot, pcSubKey, pcValueName, pInParams, SIMPLE);
  747. }
  748. else if(!wbem_wcsicmp(MethodName, L"SetBinaryValue"))
  749. {
  750. lRet = SetBinaryValue(hRoot, pcSubKey, pcValueName, pInParams);
  751. }
  752. else if(!wbem_wcsicmp(MethodName, L"SetDWORDValue"))
  753. {
  754. lRet = pInParams->Get(L"uValue", 0, &var, NULL, NULL);
  755. if(lRet == S_OK)
  756. {
  757. DWORD dwValue = var.lVal;
  758. Registry reg(hRoot, KEY_SET_VALUE, (TCHAR *)pcSubKey);
  759. lRet = reg.GetLastError();
  760. if(lRet ==0)
  761. lRet = reg.SetDWORD(pcValueName, dwValue);
  762. }
  763. }
  764. else if(!wbem_wcsicmp(MethodName, L"GetDWORDValue"))
  765. {
  766. // Get the value name
  767. Registry reg(hRoot, KEY_QUERY_VALUE, (TCHAR *)pcSubKey);
  768. lRet = reg.GetLastError();
  769. if(lRet == 0)
  770. lRet = reg.GetDWORD(pcValueName, (DWORD *)&var.lVal);
  771. if(lRet == ERROR_SUCCESS)
  772. {
  773. var.vt = VT_I4;
  774. lRet = pOutParams->Put( L"uValue", 0, &var, 0);
  775. }
  776. else if(IsTypeMismatch(reg, pcValueName, REG_DWORD))
  777. lRet = WBEM_E_TYPE_MISMATCH;
  778. }
  779. else if(!wbem_wcsicmp(MethodName, L"GetBinaryValue"))
  780. {
  781. lRet = GetBinaryValue(hRoot,pcSubKey,pcValueName,pOutParams);
  782. }
  783. else if(!wbem_wcsicmp(MethodName, L"CheckAccess"))
  784. {
  785. lRet = pInParams->Get(L"uRequired", 0, &var, NULL, NULL);
  786. if(lRet == S_OK)
  787. {
  788. BOOL bSuccess = FALSE;
  789. DWORD dwValue = var.lVal;
  790. HKEY hKey;
  791. lRet = RegOpenKeyEx(hRoot, pcSubKey, 0, dwValue, &hKey);
  792. if(lRet == ERROR_SUCCESS)
  793. {
  794. RegCloseKey(hKey);
  795. bSuccess = TRUE;
  796. }
  797. var.vt = VT_BOOL;
  798. var.boolVal = (bSuccess) ? VARIANT_TRUE : VARIANT_FALSE;
  799. pOutParams->Put( L"bGranted", 0, &var, 0);
  800. }
  801. }
  802. else
  803. sc = WBEM_E_INVALID_METHOD;
  804. if(bUsingHKCU)
  805. {
  806. WbemCoRevertToSelf();
  807. }
  808. // Set the return value
  809. if(sc == S_OK)
  810. {
  811. BSTR retValName = SysAllocString(L"ReturnValue");
  812. if(retValName)
  813. {
  814. var.vt = VT_I4;
  815. var.lVal = lRet;
  816. pOutParams->Put(retValName , 0, &var, 0);
  817. SysFreeString(retValName);
  818. }
  819. hr = pSink->Indicate(1, &pOutParams);
  820. }
  821. return SetStatusAndReturnOK(sc, pSink);
  822. }