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.

2135 lines
52 KiB

  1. /*++
  2. Copyright (c) 1998-2000 Microsoft Corporation
  3. Module Name:
  4. metabase.cpp
  5. Abstract:
  6. This file contains implementation of:
  7. CMetabase, CServerMethod
  8. CMetabase encapsulates an IMSAdminBase pointer.
  9. Author:
  10. ???
  11. Revision History:
  12. Mohit Srivastava 18-Dec-00
  13. --*/
  14. #include "iisprov.h"
  15. #include "MultiSzHelper.h"
  16. extern CDynSchema* g_pDynSch;
  17. //
  18. // CMetabaseCache
  19. //
  20. HRESULT CMetabaseCache::Populate(
  21. IMSAdminBase* i_pIABase,
  22. METADATA_HANDLE i_hKey)
  23. {
  24. DBG_ASSERT(i_pIABase);
  25. DBG_ASSERT(m_pBuf == NULL); // only call populate once
  26. DWORD dwDataSetNumber = 0;
  27. DWORD dwRequiredBufSize = 0;
  28. HRESULT hr = WBEM_S_NO_ERROR;
  29. m_pBuf = m_pBufFixed;
  30. m_cbBuf = m_cbBufFixed;
  31. hr = i_pIABase->GetAllData(
  32. i_hKey,
  33. NULL,
  34. METADATA_INHERIT | METADATA_ISINHERITED,
  35. ALL_METADATA,
  36. ALL_METADATA,
  37. &m_dwNumEntries,
  38. &dwDataSetNumber,
  39. m_cbBuf,
  40. m_pBuf,
  41. &dwRequiredBufSize);
  42. if(hr == HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER))
  43. {
  44. m_pBufDynamic = new BYTE[dwRequiredBufSize];
  45. if(m_pBufDynamic == NULL)
  46. {
  47. hr = WBEM_E_OUT_OF_MEMORY;
  48. goto exit;
  49. }
  50. m_pBuf = m_pBufDynamic;
  51. m_cbBuf = dwRequiredBufSize;
  52. hr = i_pIABase->GetAllData(
  53. i_hKey,
  54. NULL,
  55. METADATA_INHERIT | METADATA_ISINHERITED,
  56. ALL_METADATA,
  57. ALL_METADATA,
  58. &m_dwNumEntries,
  59. &dwDataSetNumber,
  60. m_cbBuf,
  61. m_pBuf,
  62. &dwRequiredBufSize);
  63. if(FAILED(hr))
  64. {
  65. DBG_ASSERT(hr != HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER));
  66. goto exit;
  67. }
  68. }
  69. else if(FAILED(hr))
  70. {
  71. goto exit;
  72. }
  73. //
  74. // If we are here, we have a valid data buffer
  75. //
  76. m_hKey = i_hKey;
  77. exit:
  78. if(FAILED(hr))
  79. {
  80. m_pBuf = NULL;
  81. m_cbBuf = 0;
  82. }
  83. return hr;
  84. }
  85. HRESULT CMetabaseCache::GetProp(
  86. DWORD i_dwId,
  87. DWORD i_dwUserType,
  88. DWORD i_dwDataType,
  89. LPBYTE* o_ppData,
  90. METADATA_GETALL_RECORD** o_ppmr) const
  91. {
  92. DBG_ASSERT(o_ppmr != NULL);
  93. DBG_ASSERT(o_ppData != NULL);
  94. *o_ppmr = NULL;
  95. *o_ppData = NULL;
  96. if(m_pBuf == NULL)
  97. {
  98. return MD_ERROR_DATA_NOT_FOUND;
  99. }
  100. for(ULONG i = 0; i < m_dwNumEntries; i++)
  101. {
  102. METADATA_GETALL_RECORD* pmr = ((METADATA_GETALL_RECORD*)m_pBuf) + i;
  103. if( i_dwId == pmr->dwMDIdentifier &&
  104. i_dwUserType == pmr->dwMDUserType &&
  105. i_dwDataType == pmr->dwMDDataType)
  106. {
  107. *o_ppmr = pmr;
  108. *o_ppData = m_pBuf + pmr->dwMDDataOffset;
  109. return S_OK;
  110. }
  111. }
  112. return MD_ERROR_DATA_NOT_FOUND;
  113. }
  114. //
  115. // CMetabase
  116. //
  117. CMetabase::CMetabase()
  118. {
  119. m_pNodeCache = NULL;
  120. HRESULT hr = CoCreateInstance(
  121. CLSID_MSAdminBase,
  122. NULL,
  123. CLSCTX_ALL,
  124. IID_IMSAdminBase2,
  125. (void**)&m_pIABase
  126. );
  127. THROW_ON_ERROR(hr);
  128. }
  129. CMetabase::~CMetabase()
  130. {
  131. CacheFree();
  132. const LIST_ENTRY* ple = m_keyList.GetHead()->Flink;
  133. while(ple != m_keyList.GetHead())
  134. {
  135. const CMetabaseKeyList::CKeyListNode* pNode =
  136. CONTAINING_RECORD(ple, CMetabaseKeyList::CKeyListNode, m_leEntry);
  137. DBG_ASSERT(pNode);
  138. ple = ple->Flink;
  139. CloseKey(pNode->hKey);
  140. }
  141. if(m_pIABase)
  142. m_pIABase->Release();
  143. }
  144. HRESULT CMetabase::SaveData()
  145. {
  146. HRESULT hr = m_pIABase->SaveData();
  147. return hr;
  148. }
  149. HRESULT CMetabase::BackupWithPasswd(
  150. LPCWSTR i_wszMDBackupLocation,
  151. DWORD i_dwMDVersion,
  152. DWORD i_dwMDFlags,
  153. LPCWSTR i_wszPassword
  154. )
  155. {
  156. HRESULT hr;
  157. hr = m_pIABase->BackupWithPasswd(
  158. i_wszMDBackupLocation,
  159. i_dwMDVersion,
  160. i_dwMDFlags,
  161. i_wszPassword);
  162. return hr;
  163. }
  164. HRESULT CMetabase::DeleteBackup(
  165. LPCWSTR i_wszMDBackupLocation,
  166. DWORD i_dwMDVersion
  167. )
  168. {
  169. HRESULT hr;
  170. hr = m_pIABase->DeleteBackup(
  171. i_wszMDBackupLocation,
  172. i_dwMDVersion
  173. );
  174. return hr;
  175. }
  176. HRESULT CMetabase::EnumBackups(
  177. LPWSTR io_wszMDBackupLocation,
  178. DWORD* o_pdwMDVersion,
  179. PFILETIME o_pftMDBackupTime,
  180. DWORD i_dwMDEnumIndex
  181. )
  182. {
  183. HRESULT hr;
  184. hr = m_pIABase->EnumBackups(
  185. io_wszMDBackupLocation,
  186. o_pdwMDVersion,
  187. o_pftMDBackupTime,
  188. i_dwMDEnumIndex
  189. );
  190. return hr;
  191. }
  192. HRESULT CMetabase::RestoreWithPasswd(
  193. LPCWSTR i_wszMDBackupLocation,
  194. DWORD i_dwMDVersion,
  195. DWORD i_dwMDFlags,
  196. LPCWSTR i_wszPassword
  197. )
  198. {
  199. HRESULT hr;
  200. hr = m_pIABase->RestoreWithPasswd(
  201. i_wszMDBackupLocation,
  202. i_dwMDVersion,
  203. i_dwMDFlags,
  204. i_wszPassword);
  205. return hr;
  206. }
  207. HRESULT CMetabase::Export(
  208. LPCWSTR i_wszPasswd,
  209. LPCWSTR i_wszFileName,
  210. LPCWSTR i_wszSourcePath,
  211. DWORD i_dwMDFlags)
  212. {
  213. HRESULT hr;
  214. hr = m_pIABase->Export(
  215. i_wszPasswd,
  216. i_wszFileName,
  217. i_wszSourcePath,
  218. i_dwMDFlags);
  219. return hr;
  220. }
  221. HRESULT CMetabase::Import(
  222. LPCWSTR i_wszPasswd,
  223. LPCWSTR i_wszFileName,
  224. LPCWSTR i_wszSourcePath,
  225. LPCWSTR i_wszDestPath,
  226. DWORD i_dwMDFlags)
  227. {
  228. HRESULT hr;
  229. hr = m_pIABase->Import(
  230. i_wszPasswd,
  231. i_wszFileName,
  232. i_wszSourcePath,
  233. i_wszDestPath,
  234. i_dwMDFlags);
  235. return hr;
  236. }
  237. HRESULT CMetabase::RestoreHistory(
  238. LPCWSTR i_wszMDHistoryLocation,
  239. DWORD i_dwMDMajorVersion,
  240. DWORD i_dwMDMinorVersion,
  241. DWORD i_dwMDFlags)
  242. {
  243. HRESULT hr;
  244. hr = m_pIABase->RestoreHistory(
  245. i_wszMDHistoryLocation,
  246. i_dwMDMajorVersion,
  247. i_dwMDMinorVersion,
  248. i_dwMDFlags);
  249. return hr;
  250. }
  251. HRESULT CMetabase::EnumHistory(
  252. LPWSTR io_wszMDHistoryLocation,
  253. DWORD* o_pdwMDMajorVersion,
  254. DWORD* o_pdwMDMinorVersion,
  255. PFILETIME o_pftMDHistoryTime,
  256. DWORD i_dwMDEnumIndex)
  257. {
  258. HRESULT hr;
  259. hr = m_pIABase->EnumHistory(
  260. io_wszMDHistoryLocation,
  261. o_pdwMDMajorVersion,
  262. o_pdwMDMinorVersion,
  263. o_pftMDHistoryTime,
  264. i_dwMDEnumIndex);
  265. return hr;
  266. }
  267. void CMetabase::CloseKey(METADATA_HANDLE i_hKey)
  268. {
  269. m_keyList.Remove(i_hKey);
  270. if(i_hKey && m_pIABase)
  271. {
  272. m_pIABase->CloseKey(i_hKey);
  273. DBGPRINTF((DBG_CONTEXT, "Close Key: %x\n", i_hKey));
  274. }
  275. }
  276. METADATA_HANDLE CMetabase::OpenKey(LPCWSTR i_wszKey, BOOL i_bWrite)
  277. {
  278. METADATA_HANDLE hKey = NULL;
  279. DWORD dwMDAccessRequested;
  280. if(i_bWrite)
  281. dwMDAccessRequested = METADATA_PERMISSION_READ | METADATA_PERMISSION_WRITE;
  282. else
  283. dwMDAccessRequested = METADATA_PERMISSION_READ;
  284. HRESULT hr = m_pIABase->OpenKey(
  285. METADATA_MASTER_ROOT_HANDLE,
  286. i_wszKey,
  287. dwMDAccessRequested,
  288. DEFAULT_TIMEOUT_VALUE, // 30 seconds
  289. &hKey
  290. );
  291. THROW_ON_ERROR(hr);
  292. hr = m_keyList.Add(hKey);
  293. if(FAILED(hr))
  294. {
  295. m_pIABase->CloseKey(hKey);
  296. THROW_ON_ERROR(hr);
  297. }
  298. DBGPRINTF((DBG_CONTEXT, "Open Key on %ws, returned handle %x\n", i_wszKey, hKey));
  299. return hKey;
  300. }
  301. //
  302. // force to create or open a key by read/write permision
  303. //
  304. METADATA_HANDLE CMetabase::CreateKey(LPCWSTR i_wszKey)
  305. {
  306. HRESULT hr;
  307. METADATA_HANDLE hKey;
  308. // open and return key if exists
  309. hr = m_pIABase->OpenKey(
  310. METADATA_MASTER_ROOT_HANDLE,
  311. i_wszKey,
  312. METADATA_PERMISSION_READ | METADATA_PERMISSION_WRITE,
  313. DEFAULT_TIMEOUT_VALUE, // 30 seconds
  314. &hKey
  315. );
  316. if(FAILED(hr))
  317. {
  318. // create key if not there
  319. hr = m_pIABase->OpenKey(
  320. METADATA_MASTER_ROOT_HANDLE,
  321. NULL,
  322. METADATA_PERMISSION_READ | METADATA_PERMISSION_WRITE,
  323. DEFAULT_TIMEOUT_VALUE, // 30 seconds
  324. &hKey
  325. );
  326. THROW_ON_ERROR(hr);
  327. // add key
  328. hr = m_pIABase->AddKey(hKey, i_wszKey);
  329. // close this root key first
  330. m_pIABase->CloseKey(hKey);
  331. THROW_ON_ERROR(hr);
  332. // now open the key just created
  333. hr = m_pIABase->OpenKey(
  334. METADATA_MASTER_ROOT_HANDLE,
  335. i_wszKey,
  336. METADATA_PERMISSION_READ | METADATA_PERMISSION_WRITE,
  337. DEFAULT_TIMEOUT_VALUE, // 30 seconds
  338. &hKey
  339. );
  340. THROW_ON_ERROR(hr);
  341. }
  342. hr = m_keyList.Add(hKey);
  343. if(FAILED(hr))
  344. {
  345. m_pIABase->CloseKey(hKey);
  346. THROW_ON_ERROR(hr);
  347. }
  348. DBGPRINTF((DBG_CONTEXT, "Create Key on %ws, returned handle %x\n", i_wszKey, hKey));
  349. return hKey;
  350. }
  351. //
  352. // Check if the key is existed
  353. //
  354. bool CMetabase::CheckKey(LPCWSTR i_wszKey)
  355. {
  356. METADATA_HANDLE hKey = NULL;
  357. HRESULT hr = m_pIABase->OpenKey(
  358. METADATA_MASTER_ROOT_HANDLE,
  359. i_wszKey,
  360. METADATA_PERMISSION_READ,
  361. DEFAULT_TIMEOUT_VALUE, // 30 seconds
  362. &hKey
  363. );
  364. if(hr == ERROR_SUCCESS)
  365. {
  366. DBGPRINTF((DBG_CONTEXT, "Open Key on %ws, returned handle %x\n", i_wszKey, hKey));
  367. CloseKey(hKey);
  368. }
  369. return (hr == ERROR_PATH_BUSY) || (hr == ERROR_SUCCESS) ? true : false;
  370. }
  371. //
  372. // Check if the key is existed
  373. //
  374. HRESULT CMetabase::CheckKey(
  375. LPCWSTR i_wszKey,
  376. METABASE_KEYTYPE* i_pktSearchKeyType)
  377. {
  378. WCHAR wszBuf[MAX_BUF_SIZE];
  379. METADATA_RECORD mr = {
  380. MD_KEY_TYPE,
  381. METADATA_NO_ATTRIBUTES,
  382. IIS_MD_UT_SERVER,
  383. STRING_METADATA,
  384. MAX_BUF_SIZE*sizeof(WCHAR),
  385. (unsigned char*)wszBuf,
  386. 0
  387. };
  388. DWORD dwLen;
  389. HRESULT hr = m_pIABase->GetData(
  390. METADATA_MASTER_ROOT_HANDLE,
  391. i_wszKey,
  392. &mr,
  393. &dwLen);
  394. if( hr == MD_ERROR_DATA_NOT_FOUND &&
  395. METABASE_PROPERTY_DATA::s_KeyType.pDefaultValue )
  396. {
  397. mr.pbMDData = (LPBYTE)METABASE_PROPERTY_DATA::s_KeyType.pDefaultValue;
  398. hr = S_OK;
  399. }
  400. else if(FAILED(hr))
  401. {
  402. return hr;
  403. }
  404. if( i_pktSearchKeyType &&
  405. CUtils::CompareKeyType((LPCWSTR)mr.pbMDData, i_pktSearchKeyType) )
  406. {
  407. return S_OK;
  408. }
  409. return MD_ERROR_DATA_NOT_FOUND;
  410. }
  411. HRESULT CMetabase::DeleteKey(
  412. METADATA_HANDLE i_hKey,
  413. LPCWSTR i_wszKeyPath)
  414. {
  415. return m_pIABase->DeleteKey(
  416. i_hKey,
  417. i_wszKeyPath
  418. );
  419. }
  420. void CMetabase::CacheInit(
  421. METADATA_HANDLE i_hKey)
  422. {
  423. HRESULT hr = S_OK;
  424. delete m_pNodeCache;
  425. m_pNodeCache = new CMetabaseCache();
  426. if(m_pNodeCache == NULL)
  427. {
  428. THROW_ON_ERROR(WBEM_E_OUT_OF_MEMORY);
  429. }
  430. hr = m_pNodeCache->Populate(
  431. m_pIABase,
  432. i_hKey);
  433. THROW_ON_ERROR(hr);
  434. }
  435. void CMetabase::CacheFree()
  436. {
  437. delete m_pNodeCache;
  438. m_pNodeCache = NULL;
  439. }
  440. void CMetabase::Get(
  441. METADATA_HANDLE i_hKey,
  442. METABASE_PROPERTY* i_pmbp,
  443. CWbemServices* i_pNamespace,
  444. _variant_t& io_vt,
  445. BOOL* io_pbIsInherited,
  446. BOOL* io_pbIsDefault
  447. )
  448. {
  449. DBG_ASSERT(i_hKey != NULL);
  450. DBG_ASSERT(i_pmbp != NULL);
  451. switch (i_pmbp->dwMDDataType)
  452. {
  453. case DWORD_METADATA:
  454. GetDword(i_hKey, i_pmbp, io_vt, io_pbIsInherited, io_pbIsDefault);
  455. break;
  456. case EXPANDSZ_METADATA:
  457. case STRING_METADATA:
  458. GetString(i_hKey, i_pmbp, io_vt, io_pbIsInherited, io_pbIsDefault);
  459. break;
  460. case MULTISZ_METADATA:
  461. GetMultiSz(i_hKey, i_pmbp, i_pNamespace, io_vt, io_pbIsInherited, io_pbIsDefault);
  462. break;
  463. case BINARY_METADATA:
  464. GetBinary(i_hKey, i_pmbp, io_vt, io_pbIsInherited, io_pbIsDefault);
  465. break;
  466. default:
  467. DBGPRINTF((DBG_CONTEXT,
  468. "[CMetabase::Get] Cannot retrieve %ws because type %u is unknown\n",
  469. i_pmbp->pszPropName,
  470. i_pmbp->dwMDDataType));
  471. break;
  472. }
  473. }
  474. //
  475. // GetDword
  476. //
  477. // A long or bool is returned in the VARIANT. The value is a bool if the
  478. // METABASE_PROPERTY has a mask otherwise the DWORD is returned as a long.
  479. // The METADATA_HANDLE is expected to be valid and open.
  480. //
  481. void CMetabase::GetDword(
  482. METADATA_HANDLE i_hKey,
  483. METABASE_PROPERTY* i_pmbp,
  484. _variant_t& io_vt,
  485. BOOL* io_pbIsInherited,
  486. BOOL* io_pbIsDefault
  487. )
  488. {
  489. DWORD dw = 0;
  490. DWORD dwRet = 0;
  491. HRESULT hr = WBEM_S_NO_ERROR;
  492. BOOL bIsInherited = false;
  493. BOOL bIsDefault = false;
  494. DBG_ASSERT(i_hKey != NULL);
  495. DBG_ASSERT(i_pmbp != NULL);
  496. METADATA_RECORD mr = {
  497. i_pmbp->dwMDIdentifier,
  498. i_pmbp->dwMDAttributes | METADATA_ISINHERITED,
  499. i_pmbp->dwMDUserType,
  500. i_pmbp->dwMDDataType,
  501. sizeof(DWORD),
  502. (unsigned char*)&dw,
  503. 0
  504. };
  505. if(m_pNodeCache && m_pNodeCache->GetHandle() == i_hKey)
  506. {
  507. METADATA_GETALL_RECORD* pmr = NULL;
  508. hr = m_pNodeCache->GetProp(
  509. i_pmbp->dwMDIdentifier,
  510. i_pmbp->dwMDUserType,
  511. i_pmbp->dwMDDataType,
  512. &mr.pbMDData,
  513. &pmr);
  514. if(SUCCEEDED(hr))
  515. {
  516. DBG_ASSERT(pmr);
  517. mr.dwMDAttributes = pmr->dwMDAttributes;
  518. dw = *((DWORD*)mr.pbMDData);
  519. }
  520. }
  521. else
  522. {
  523. hr = m_pIABase->GetData(i_hKey, NULL, &mr, &dwRet);
  524. }
  525. //
  526. // Set out parameters
  527. //
  528. if (hr == MD_ERROR_DATA_NOT_FOUND)
  529. {
  530. bIsInherited = false;
  531. if(i_pmbp->pDefaultValue == NULL)
  532. {
  533. io_vt.vt = VT_NULL;
  534. bIsDefault = false;
  535. }
  536. else
  537. {
  538. if(i_pmbp->dwMDMask)
  539. {
  540. io_vt.vt = VT_BOOL;
  541. io_vt.boolVal = (i_pmbp->dwDefaultValue & i_pmbp->dwMDMask ? -1 : 0);
  542. }
  543. else
  544. {
  545. io_vt.vt = VT_I4;
  546. io_vt.lVal = i_pmbp->dwDefaultValue;
  547. }
  548. bIsDefault = true;
  549. }
  550. }
  551. else
  552. {
  553. THROW_E_ON_ERROR(hr,i_pmbp);
  554. if (i_pmbp->dwMDMask)
  555. {
  556. io_vt.vt = VT_BOOL;
  557. io_vt.boolVal = (dw & i_pmbp->dwMDMask? -1 : 0);
  558. }
  559. else
  560. {
  561. io_vt.vt = VT_I4;
  562. io_vt.lVal = dw;
  563. }
  564. bIsDefault = false;
  565. bIsInherited = mr.dwMDAttributes & METADATA_ISINHERITED;
  566. }
  567. if(io_pbIsInherited != NULL)
  568. {
  569. *io_pbIsInherited = bIsInherited;
  570. }
  571. if(io_pbIsDefault != NULL)
  572. {
  573. *io_pbIsDefault = bIsDefault;
  574. }
  575. }
  576. //
  577. // GetStringFromMetabase
  578. //
  579. void CMetabase::GetString(
  580. METADATA_HANDLE i_hKey,
  581. METABASE_PROPERTY* i_pmbp,
  582. _variant_t& io_vt,
  583. BOOL* io_pbIsInherited,
  584. BOOL* io_pbIsDefault
  585. )
  586. {
  587. DWORD dwRet;
  588. HRESULT hr;
  589. WCHAR wszBufStack[MAX_BUF_SIZE];
  590. BOOL bIsDefault = false;
  591. BOOL bIsInherited = false;
  592. DBG_ASSERT(i_hKey != NULL);
  593. DBG_ASSERT(i_pmbp != NULL);
  594. METADATA_RECORD mr = {
  595. i_pmbp->dwMDIdentifier,
  596. i_pmbp->dwMDAttributes | METADATA_ISINHERITED,
  597. i_pmbp->dwMDUserType,
  598. i_pmbp->dwMDDataType,
  599. MAX_BUF_SIZE*sizeof(WCHAR),
  600. (LPBYTE)wszBufStack,
  601. 0
  602. };
  603. if(m_pNodeCache && m_pNodeCache->GetHandle() == i_hKey)
  604. {
  605. METADATA_GETALL_RECORD* pmr = NULL;
  606. hr = m_pNodeCache->GetProp(
  607. i_pmbp->dwMDIdentifier,
  608. i_pmbp->dwMDUserType,
  609. i_pmbp->dwMDDataType,
  610. &mr.pbMDData,
  611. &pmr);
  612. if(SUCCEEDED(hr))
  613. {
  614. DBG_ASSERT(pmr);
  615. mr.dwMDAttributes = pmr->dwMDAttributes;
  616. }
  617. }
  618. else
  619. {
  620. hr = m_pIABase->GetData(i_hKey, NULL, &mr, &dwRet);
  621. }
  622. //
  623. // Set out parameters.
  624. //
  625. if (hr == MD_ERROR_DATA_NOT_FOUND)
  626. {
  627. bIsInherited = false;
  628. if(i_pmbp->pDefaultValue == NULL)
  629. {
  630. io_vt.vt = VT_NULL;
  631. bIsDefault = false;
  632. }
  633. else
  634. {
  635. io_vt = (LPWSTR)i_pmbp->pDefaultValue;
  636. bIsDefault = true;
  637. }
  638. }
  639. else
  640. {
  641. THROW_E_ON_ERROR(hr, i_pmbp);
  642. io_vt = (LPWSTR)mr.pbMDData;
  643. bIsInherited = mr.dwMDAttributes & METADATA_ISINHERITED;
  644. bIsDefault = false;
  645. }
  646. if(io_pbIsDefault)
  647. {
  648. *io_pbIsDefault = bIsDefault;
  649. }
  650. if(io_pbIsInherited)
  651. {
  652. *io_pbIsInherited = bIsInherited;
  653. }
  654. }
  655. //
  656. // GetMultiSz
  657. //
  658. void CMetabase::GetMultiSz(
  659. METADATA_HANDLE i_hKey,
  660. METABASE_PROPERTY* i_pmbp,
  661. CWbemServices* i_pNamespace,
  662. _variant_t& io_vt,
  663. BOOL* io_pbIsInherited,
  664. BOOL* io_pbIsDefault
  665. )
  666. {
  667. DBG_ASSERT(i_hKey != NULL);
  668. DBG_ASSERT(i_pmbp != NULL);
  669. DWORD dwRet;
  670. HRESULT hr;
  671. WCHAR *buffer = NULL;
  672. BOOL bIsDefault = false;
  673. BOOL bIsInherited = false;
  674. METADATA_RECORD mr;
  675. mr.dwMDIdentifier = i_pmbp->dwMDIdentifier;
  676. mr.dwMDAttributes = i_pmbp->dwMDAttributes | METADATA_ISINHERITED;
  677. mr.dwMDUserType = i_pmbp->dwMDUserType;
  678. mr.dwMDDataType = i_pmbp->dwMDDataType;
  679. mr.pbMDData = NULL;
  680. mr.dwMDDataLen = 0;
  681. mr.dwMDDataTag = 0;
  682. try
  683. {
  684. if(m_pNodeCache && m_pNodeCache->GetHandle() == i_hKey)
  685. {
  686. METADATA_GETALL_RECORD* pmr = NULL;
  687. hr = m_pNodeCache->GetProp(
  688. i_pmbp->dwMDIdentifier,
  689. i_pmbp->dwMDUserType,
  690. i_pmbp->dwMDDataType,
  691. &mr.pbMDData,
  692. &pmr);
  693. if(SUCCEEDED(hr))
  694. {
  695. DBG_ASSERT(pmr);
  696. mr.dwMDAttributes = pmr->dwMDAttributes;
  697. }
  698. }
  699. else
  700. {
  701. buffer = new WCHAR[10*MAX_BUF_SIZE];
  702. if(buffer == NULL)
  703. {
  704. throw WBEM_E_OUT_OF_MEMORY;
  705. }
  706. buffer[0] = L'\0';
  707. mr.pbMDData = (LPBYTE)buffer;
  708. mr.dwMDDataLen = 10*MAX_BUF_SIZE*sizeof(WCHAR);
  709. hr = m_pIABase->GetData(i_hKey, NULL, &mr, &dwRet);
  710. if (hr == HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER))
  711. {
  712. delete [] buffer;
  713. buffer = new WCHAR[dwRet/sizeof(WCHAR) + 1];
  714. if(buffer == NULL)
  715. {
  716. throw (HRESULT)WBEM_E_OUT_OF_MEMORY;
  717. }
  718. buffer[0] = L'\0';
  719. mr.pbMDData = (LPBYTE)buffer;
  720. mr.dwMDDataLen = sizeof(WCHAR) + dwRet;
  721. hr = m_pIABase->GetData(i_hKey, NULL, &mr, &dwRet);
  722. }
  723. }
  724. CMultiSz MultiSz(i_pmbp, i_pNamespace);
  725. if (hr == MD_ERROR_DATA_NOT_FOUND)
  726. {
  727. bIsInherited = false;
  728. if(i_pmbp->pDefaultValue == NULL)
  729. {
  730. io_vt.vt = VT_NULL;
  731. bIsDefault = false;
  732. }
  733. else
  734. {
  735. hr = MultiSz.ToWmiForm((LPWSTR)i_pmbp->pDefaultValue, &io_vt);
  736. THROW_E_ON_ERROR(hr,i_pmbp);
  737. bIsDefault = true;
  738. }
  739. }
  740. else
  741. {
  742. THROW_E_ON_ERROR(hr,i_pmbp);
  743. hr = MultiSz.ToWmiForm((LPWSTR)mr.pbMDData,&io_vt);
  744. THROW_E_ON_ERROR(hr,i_pmbp);
  745. bIsInherited = mr.dwMDAttributes & METADATA_ISINHERITED;
  746. bIsDefault = false;
  747. }
  748. if(io_pbIsDefault)
  749. {
  750. *io_pbIsDefault = bIsDefault;
  751. }
  752. if(io_pbIsInherited)
  753. {
  754. *io_pbIsInherited = bIsInherited;
  755. }
  756. //
  757. // Cleanup
  758. //
  759. delete [] buffer;
  760. }
  761. catch (...)
  762. {
  763. delete [] buffer;
  764. throw;
  765. }
  766. }
  767. void CMetabase::GetBinary(
  768. METADATA_HANDLE i_hKey,
  769. METABASE_PROPERTY* i_pmbp,
  770. _variant_t& io_vt,
  771. BOOL* io_pbIsInherited,
  772. BOOL* io_pbIsDefault
  773. )
  774. {
  775. DBG_ASSERT(i_hKey != NULL);
  776. DBG_ASSERT(i_pmbp != NULL);
  777. DWORD dwRet = 0;
  778. HRESULT hr = S_OK;
  779. CHAR* pszBuf = NULL;
  780. SAFEARRAY* safeArray = NULL;
  781. BOOL bIsDefault = false;
  782. BOOL bIsInherited = false;
  783. pszBuf = new CHAR[10*MAX_BUF_SIZE];
  784. if(pszBuf == NULL)
  785. {
  786. throw (HRESULT)WBEM_E_OUT_OF_MEMORY;
  787. }
  788. METADATA_RECORD mr = {
  789. i_pmbp->dwMDIdentifier,
  790. (i_pmbp->dwMDAttributes & !METADATA_REFERENCE) | METADATA_ISINHERITED,
  791. i_pmbp->dwMDUserType,
  792. i_pmbp->dwMDDataType,
  793. 10*MAX_BUF_SIZE*sizeof(CHAR),
  794. (unsigned char*)pszBuf,
  795. 0
  796. };
  797. hr = m_pIABase->GetData(i_hKey, NULL, &mr, &dwRet);
  798. if (hr == ERROR_INSUFFICIENT_BUFFER)
  799. {
  800. delete [] pszBuf;
  801. pszBuf = new CHAR[dwRet/sizeof(CHAR) + 1];
  802. if(pszBuf == NULL)
  803. {
  804. hr = WBEM_E_OUT_OF_MEMORY;
  805. goto exit;
  806. }
  807. mr.pbMDData = (unsigned char*)pszBuf;
  808. mr.dwMDDataLen = dwRet/sizeof(CHAR) + 1;
  809. hr = m_pIABase->GetData(i_hKey, NULL, &mr, &dwRet);
  810. }
  811. if (hr == MD_ERROR_DATA_NOT_FOUND)
  812. {
  813. bIsInherited = false;
  814. if(i_pmbp->pDefaultValue == NULL)
  815. {
  816. io_vt.vt = VT_NULL;
  817. bIsDefault = false;
  818. hr = S_OK;
  819. }
  820. else
  821. {
  822. hr = CUtils::LoadSafeArrayFromByteArray(
  823. (LPBYTE)i_pmbp->pDefaultValue,
  824. i_pmbp->dwDefaultValue,
  825. io_vt);
  826. if(FAILED(hr))
  827. {
  828. goto exit;
  829. }
  830. bIsDefault = true;
  831. }
  832. }
  833. else if(FAILED(hr))
  834. {
  835. goto exit;
  836. }
  837. else
  838. {
  839. hr = CUtils::LoadSafeArrayFromByteArray((LPBYTE)pszBuf, mr.dwMDDataLen, io_vt);
  840. if(FAILED(hr))
  841. {
  842. goto exit;
  843. }
  844. bIsInherited = mr.dwMDAttributes & METADATA_ISINHERITED;
  845. bIsDefault = false;
  846. }
  847. //
  848. // If everything succeeded, set out parameters.
  849. //
  850. if(io_pbIsInherited)
  851. {
  852. *io_pbIsInherited = bIsInherited;
  853. }
  854. if(io_pbIsDefault)
  855. {
  856. *io_pbIsDefault = bIsDefault;
  857. }
  858. exit:
  859. delete [] pszBuf;
  860. if(FAILED(hr))
  861. {
  862. throw (HRESULT)hr;
  863. }
  864. }
  865. //
  866. // Put
  867. //
  868. void CMetabase::Put(
  869. METADATA_HANDLE i_hKey,
  870. METABASE_PROPERTY* i_pmbp,
  871. CWbemServices* i_pNamespace,
  872. _variant_t& i_vt,
  873. _variant_t* i_pvtOld, // can be NULL
  874. DWORD i_dwQuals, // optional
  875. BOOL i_bDoDiff // optional
  876. )
  877. {
  878. DBG_ASSERT(i_hKey != NULL);
  879. DBG_ASSERT(i_pmbp != NULL);
  880. switch(i_pmbp->dwMDDataType)
  881. {
  882. case DWORD_METADATA:
  883. PutDword(i_hKey, i_pmbp, i_vt, i_pvtOld, i_dwQuals, i_bDoDiff);
  884. break;
  885. case STRING_METADATA:
  886. case EXPANDSZ_METADATA:
  887. PutString(i_hKey, i_pmbp, i_vt, i_pvtOld, i_dwQuals, i_bDoDiff);
  888. break;
  889. case MULTISZ_METADATA:
  890. PutMultiSz(i_hKey, i_pmbp, i_pNamespace, i_vt, i_pvtOld, i_dwQuals, i_bDoDiff);
  891. break;
  892. case BINARY_METADATA:
  893. PutBinary(i_hKey, i_pmbp, i_vt, i_pvtOld, i_dwQuals, i_bDoDiff);
  894. break;
  895. default:
  896. DBGPRINTF((DBG_CONTEXT,
  897. "[CMetabase::Put] Cannot set %ws because type %u is unknown\n",
  898. i_pmbp->pszPropName,
  899. i_pmbp->dwMDDataType));
  900. break;
  901. }
  902. }
  903. //
  904. // PutDword
  905. //
  906. void CMetabase::PutDword(
  907. METADATA_HANDLE i_hKey,
  908. METABASE_PROPERTY* i_pmbp,
  909. _variant_t& i_vt,
  910. _variant_t* i_pvtOld, // can be NULL
  911. DWORD i_dwQuals, // optional
  912. BOOL i_bDoDiff // optional
  913. )
  914. {
  915. DWORD dw=0;
  916. DWORD dwOld=0;
  917. DWORD dwRet=0;
  918. HRESULT hr=0;
  919. DBG_ASSERT(i_hKey != NULL);
  920. DBG_ASSERT(i_pmbp != NULL);
  921. METADATA_RECORD mr;
  922. mr.dwMDIdentifier = i_pmbp->dwMDIdentifier;
  923. mr.dwMDAttributes = i_pmbp->dwMDAttributes;
  924. mr.dwMDUserType = i_pmbp->dwMDUserType;
  925. mr.dwMDDataType = i_pmbp->dwMDDataType;
  926. mr.dwMDDataLen = sizeof(DWORD_METADATA);
  927. mr.pbMDData = (unsigned char*)&dwOld;
  928. mr.dwMDDataTag = 0;
  929. // if it's the bit of a flag
  930. if (i_vt.vt == VT_BOOL && i_pmbp->dwMDMask != 0)
  931. {
  932. // Read the entire flag from in the metabase so we can set the bit
  933. hr = m_pIABase->GetData(i_hKey, NULL, &mr, &dwRet);
  934. if(hr == MD_ERROR_DATA_NOT_FOUND)
  935. {
  936. if(i_pmbp->pDefaultValue != NULL)
  937. {
  938. dwOld = i_pmbp->dwDefaultValue;
  939. }
  940. else
  941. {
  942. dwOld = 0;
  943. }
  944. hr = ERROR_SUCCESS;
  945. }
  946. if (hr == ERROR_SUCCESS)
  947. {
  948. if (i_vt.boolVal)
  949. dw = dwOld | i_pmbp->dwMDMask;
  950. else
  951. dw = dwOld & ~i_pmbp->dwMDMask;
  952. }
  953. else
  954. THROW_ON_ERROR(hr);
  955. if(dw == -1)
  956. dw = 1; // true
  957. }
  958. else if (i_vt.vt == VT_I4)
  959. {
  960. dw = i_vt.lVal;
  961. }
  962. else if (i_vt.vt == VT_BOOL)
  963. {
  964. DBG_ASSERT(false && "i_pmbp->dwMDMask should not be 0");
  965. dw = i_vt.bVal;
  966. }
  967. else
  968. throw WBEM_E_INVALID_OBJECT;
  969. // Decide whether to write to metabase
  970. bool bWriteToMb = true;
  971. if( (i_dwQuals & g_fForcePropertyOverwrite) == 0 && i_bDoDiff )
  972. {
  973. bool bMatchOld = i_pvtOld != NULL &&
  974. (i_pvtOld->vt == VT_I4 || i_pvtOld->vt == VT_BOOL) &&
  975. *i_pvtOld == i_vt;
  976. bWriteToMb = !bMatchOld;
  977. }
  978. if (bWriteToMb)
  979. {
  980. if( i_pmbp->fReadOnly )
  981. {
  982. THROW_E_ON_ERROR(WBEM_E_READ_ONLY, i_pmbp);
  983. }
  984. mr.pbMDData = (unsigned char*)&dw;
  985. hr = m_pIABase->SetData(i_hKey, NULL, &mr);
  986. }
  987. THROW_E_ON_ERROR(hr,i_pmbp);
  988. }
  989. //
  990. // PutString
  991. //
  992. void CMetabase::PutString(
  993. METADATA_HANDLE i_hKey,
  994. METABASE_PROPERTY* i_pmbp,
  995. _variant_t& i_vt,
  996. _variant_t* i_pvtOld, // can be NULL
  997. DWORD i_dwQuals, // optional
  998. BOOL i_bDoDiff // optional
  999. )
  1000. {
  1001. HRESULT hr=0;
  1002. DBG_ASSERT(i_hKey != NULL);
  1003. DBG_ASSERT(i_pmbp != NULL);
  1004. if(i_vt.vt != VT_BSTR)
  1005. {
  1006. throw (HRESULT)WBEM_E_INVALID_OBJECT;
  1007. }
  1008. METADATA_RECORD mr;
  1009. mr.dwMDIdentifier = i_pmbp->dwMDIdentifier;
  1010. mr.dwMDAttributes = i_pmbp->dwMDAttributes;
  1011. mr.dwMDUserType = i_pmbp->dwMDUserType;
  1012. mr.dwMDDataType = i_pmbp->dwMDDataType;
  1013. mr.dwMDDataTag = 0;
  1014. // Decide whether to write to metabase
  1015. bool bWriteToMb = true;
  1016. if( (i_dwQuals & g_fForcePropertyOverwrite) == 0 && i_bDoDiff )
  1017. {
  1018. bool bMatchOld = i_pvtOld != NULL &&
  1019. i_pvtOld->vt == VT_BSTR &&
  1020. _wcsicmp(i_pvtOld->bstrVal, i_vt.bstrVal) == 0;
  1021. bWriteToMb = !bMatchOld;
  1022. }
  1023. // Set the value, only if old and new values differ.
  1024. if(bWriteToMb)
  1025. {
  1026. if( i_pmbp->fReadOnly )
  1027. {
  1028. THROW_E_ON_ERROR(WBEM_E_READ_ONLY, i_pmbp);
  1029. }
  1030. mr.dwMDDataLen = (wcslen(i_vt.bstrVal)+1)*sizeof(WCHAR);
  1031. mr.pbMDData = (unsigned char*)i_vt.bstrVal;
  1032. hr = m_pIABase->SetData(i_hKey, NULL, &mr);
  1033. }
  1034. THROW_E_ON_ERROR(hr,i_pmbp);
  1035. }
  1036. //
  1037. // PutMultiSz
  1038. //
  1039. void CMetabase::PutMultiSz(
  1040. METADATA_HANDLE i_hKey,
  1041. METABASE_PROPERTY* i_pmbp,
  1042. CWbemServices* i_pNamespace,
  1043. _variant_t& i_vt,
  1044. _variant_t* i_pvtOld, // can be NULL
  1045. DWORD i_dwQuals, // optional
  1046. BOOL i_bDoDiff // optional
  1047. )
  1048. {
  1049. DWORD dwRet;
  1050. DWORD dwRetOld;
  1051. WCHAR *buffer = NULL;
  1052. WCHAR *bufferOld = NULL;
  1053. HRESULT hr=0;
  1054. DBG_ASSERT(i_hKey != NULL);
  1055. DBG_ASSERT(i_pmbp != NULL);
  1056. DBG_ASSERT(i_pNamespace != NULL);
  1057. if(i_vt.vt != (VT_ARRAY | VT_BSTR) && i_vt.vt != (VT_ARRAY | VT_UNKNOWN))
  1058. {
  1059. throw (HRESULT)WBEM_E_INVALID_OBJECT;
  1060. }
  1061. METADATA_RECORD mr;
  1062. mr.dwMDIdentifier = i_pmbp->dwMDIdentifier;
  1063. mr.dwMDAttributes = i_pmbp->dwMDAttributes;
  1064. mr.dwMDUserType = i_pmbp->dwMDUserType;
  1065. mr.dwMDDataType = i_pmbp->dwMDDataType;
  1066. mr.dwMDDataTag = 0;
  1067. try
  1068. {
  1069. CMultiSz MultiSz(i_pmbp, i_pNamespace);
  1070. hr = MultiSz.ToMetabaseForm(&i_vt, &buffer, &dwRet);
  1071. THROW_ON_ERROR(hr);
  1072. // Decide whether to write to metabase
  1073. bool bWriteToMb = true;
  1074. if( (i_dwQuals & g_fForcePropertyOverwrite) == 0 && i_bDoDiff )
  1075. {
  1076. bool bMatchOld = false;
  1077. if(i_pvtOld != NULL &&
  1078. (i_pvtOld->vt == (VT_ARRAY | VT_BSTR) || i_pvtOld->vt == (VT_ARRAY | VT_UNKNOWN)))
  1079. {
  1080. hr = MultiSz.ToMetabaseForm(i_pvtOld, &bufferOld, &dwRetOld);
  1081. THROW_ON_ERROR(hr);
  1082. if(CUtils::CompareMultiSz(buffer, bufferOld))
  1083. {
  1084. bMatchOld = true;
  1085. }
  1086. delete [] bufferOld;
  1087. bufferOld = NULL;
  1088. }
  1089. bWriteToMb = !bMatchOld;
  1090. }
  1091. if (bWriteToMb)
  1092. {
  1093. if( i_pmbp->fReadOnly )
  1094. {
  1095. THROW_E_ON_ERROR(WBEM_E_READ_ONLY, i_pmbp);
  1096. }
  1097. mr.pbMDData = (unsigned char*)buffer;
  1098. mr.dwMDDataLen = dwRet*sizeof(WCHAR);
  1099. if(buffer != NULL)
  1100. {
  1101. hr = m_pIABase->SetData(i_hKey, NULL, &mr);
  1102. }
  1103. else
  1104. {
  1105. //
  1106. // non-fatal if it fails
  1107. //
  1108. m_pIABase->DeleteData(i_hKey,
  1109. NULL,
  1110. i_pmbp->dwMDIdentifier,
  1111. ALL_METADATA);
  1112. }
  1113. }
  1114. delete [] buffer;
  1115. buffer = NULL;
  1116. THROW_E_ON_ERROR(hr,i_pmbp);
  1117. }
  1118. catch (...)
  1119. {
  1120. delete [] buffer;
  1121. delete [] bufferOld;
  1122. throw;
  1123. }
  1124. }
  1125. //
  1126. // PutBinary
  1127. //
  1128. void CMetabase::PutBinary(
  1129. METADATA_HANDLE i_hKey,
  1130. METABASE_PROPERTY* i_pmbp,
  1131. _variant_t& i_vt,
  1132. _variant_t* i_pvtOld, // can be NULL
  1133. DWORD i_dwQuals, // optional
  1134. BOOL i_bDoDiff // optional
  1135. )
  1136. {
  1137. DWORD dwRet;
  1138. DWORD dwRetOld;
  1139. LPBYTE buffer = NULL;
  1140. LPBYTE bufferOld = NULL;
  1141. HRESULT hr=0;
  1142. bool bWriteToMb = true;
  1143. DBG_ASSERT(i_hKey != NULL);
  1144. DBG_ASSERT(i_pmbp != NULL);
  1145. if(i_vt.vt != (VT_ARRAY | VT_UI1))
  1146. {
  1147. throw (HRESULT)WBEM_E_INVALID_OBJECT;
  1148. }
  1149. METADATA_RECORD mr;
  1150. mr.dwMDIdentifier = i_pmbp->dwMDIdentifier;
  1151. mr.dwMDAttributes = i_pmbp->dwMDAttributes & !METADATA_REFERENCE;
  1152. mr.dwMDUserType = i_pmbp->dwMDUserType;
  1153. mr.dwMDDataType = i_pmbp->dwMDDataType;
  1154. mr.dwMDDataTag = 0;
  1155. hr = CUtils::CreateByteArrayFromSafeArray(i_vt, &buffer, &dwRet);
  1156. if(FAILED(hr))
  1157. {
  1158. goto exit;
  1159. }
  1160. // Decide whether to write to metabase
  1161. if( (i_dwQuals & g_fForcePropertyOverwrite) == 0 && i_bDoDiff )
  1162. {
  1163. bool bMatchOld = false;
  1164. if(i_pvtOld != NULL &&
  1165. i_pvtOld->vt == (VT_ARRAY | VT_UI1))
  1166. {
  1167. hr = CUtils::CreateByteArrayFromSafeArray(*i_pvtOld, &bufferOld, &dwRetOld);
  1168. if(FAILED(hr))
  1169. {
  1170. goto exit;
  1171. }
  1172. if(CUtils::CompareByteArray(buffer, dwRet, bufferOld, dwRetOld))
  1173. {
  1174. bMatchOld = true;
  1175. }
  1176. delete [] bufferOld;
  1177. bufferOld = NULL;
  1178. }
  1179. bWriteToMb = !bMatchOld;
  1180. }
  1181. if (bWriteToMb)
  1182. {
  1183. if( i_pmbp->fReadOnly )
  1184. {
  1185. hr = WBEM_E_READ_ONLY;
  1186. goto exit;
  1187. }
  1188. mr.pbMDData = buffer;
  1189. mr.dwMDDataLen = dwRet;
  1190. if(buffer != NULL)
  1191. {
  1192. hr = m_pIABase->SetData(i_hKey, NULL, &mr);
  1193. }
  1194. else
  1195. {
  1196. //
  1197. // non-fatal if it fails
  1198. //
  1199. m_pIABase->DeleteData(i_hKey,
  1200. NULL,
  1201. i_pmbp->dwMDIdentifier,
  1202. ALL_METADATA);
  1203. }
  1204. }
  1205. delete [] buffer;
  1206. buffer = NULL;
  1207. if(FAILED(hr))
  1208. {
  1209. goto exit;
  1210. }
  1211. exit:
  1212. delete [] buffer;
  1213. delete [] bufferOld;
  1214. THROW_E_ON_ERROR(hr, i_pmbp);
  1215. }
  1216. //
  1217. // DeleteData
  1218. //
  1219. void CMetabase::DeleteData(
  1220. METADATA_HANDLE i_hKey,
  1221. DWORD i_dwMDIdentifier,
  1222. DWORD i_dwMDDataType)
  1223. {
  1224. HRESULT hr;
  1225. if(i_hKey == NULL)
  1226. throw WBEM_E_INVALID_PARAMETER;
  1227. hr = m_pIABase->DeleteData(
  1228. i_hKey,
  1229. NULL,
  1230. i_dwMDIdentifier,
  1231. i_dwMDDataType
  1232. );
  1233. if (hr == MD_ERROR_DATA_NOT_FOUND || hr == ERROR_SUCCESS)
  1234. return;
  1235. THROW_ON_ERROR(hr);
  1236. }
  1237. //
  1238. // DeleteData
  1239. //
  1240. void CMetabase::DeleteData(
  1241. METADATA_HANDLE i_hKey,
  1242. METABASE_PROPERTY* i_pmbp,
  1243. bool i_bThrowOnRO)
  1244. {
  1245. HRESULT hr;
  1246. if(i_hKey == NULL || i_pmbp == NULL)
  1247. throw WBEM_E_INVALID_PARAMETER;
  1248. if(i_pmbp->fReadOnly && i_bThrowOnRO)
  1249. {
  1250. THROW_E_ON_ERROR(WBEM_E_READ_ONLY, i_pmbp);
  1251. }
  1252. hr = m_pIABase->DeleteData(
  1253. i_hKey,
  1254. NULL,
  1255. i_pmbp->dwMDIdentifier,
  1256. i_pmbp->dwMDDataType
  1257. );
  1258. if (hr == MD_ERROR_DATA_NOT_FOUND || hr == ERROR_SUCCESS)
  1259. return;
  1260. THROW_E_ON_ERROR(hr,i_pmbp);
  1261. }
  1262. //
  1263. // Enumuerates all the subkeys of i_wszMDPath under i_hKey.
  1264. // If we hit a 'valid' subkey, set io_pktKeyTypeSearch to this subkey and return.
  1265. // A 'valid' subkey is one where io_pktKeyTypeSearch can be a (grand*)child.
  1266. //
  1267. HRESULT CMetabase::EnumKeys(
  1268. METADATA_HANDLE i_hKey,
  1269. LPCWSTR i_wszMDPath, //path to the key
  1270. LPWSTR io_wszMDName, //receives the name of the subkey --must be METADATA_MAX_NAME_LEN
  1271. DWORD* io_pdwMDEnumKeyIndex, //index of the subkey
  1272. METABASE_KEYTYPE*& io_pktKeyTypeSearch,
  1273. bool i_bLookForMatchAtCurrentLevelOnly
  1274. )
  1275. {
  1276. HRESULT hr;
  1277. DWORD dwRet;
  1278. WCHAR wszBuf[MAX_BUF_SIZE];
  1279. // DBG_ASSERT(i_hKey != NULL);
  1280. // DBG_ASSERT(i_wszMDPath != NULL);
  1281. DBG_ASSERT(io_wszMDName != NULL);
  1282. DBG_ASSERT(io_pdwMDEnumKeyIndex != NULL);
  1283. DBG_ASSERT(io_pktKeyTypeSearch != NULL);
  1284. while(1)
  1285. {
  1286. hr = m_pIABase->EnumKeys(
  1287. i_hKey,
  1288. i_wszMDPath,
  1289. io_wszMDName,
  1290. *io_pdwMDEnumKeyIndex);
  1291. if(hr != ERROR_SUCCESS)
  1292. {
  1293. break;
  1294. }
  1295. wszBuf[0] = L'\0';
  1296. METADATA_RECORD mr = {
  1297. METABASE_PROPERTY_DATA::s_KeyType.dwMDIdentifier,
  1298. METADATA_NO_ATTRIBUTES,
  1299. IIS_MD_UT_SERVER,
  1300. STRING_METADATA,
  1301. MAX_BUF_SIZE*sizeof(WCHAR),
  1302. (unsigned char*)wszBuf,
  1303. 0
  1304. };
  1305. //
  1306. // Eg. blah/
  1307. //
  1308. _bstr_t bstrPath = L"";
  1309. if(i_wszMDPath)
  1310. {
  1311. bstrPath += i_wszMDPath;
  1312. bstrPath += L"/";
  1313. }
  1314. //
  1315. // Eg. blah/1
  1316. //
  1317. bstrPath += io_wszMDName;
  1318. DBGPRINTF((DBG_CONTEXT, "CMetabase::EnumKeys::GetData (Key = 0x%x, bstrPath = %ws)\n", i_hKey, (LPWSTR)bstrPath));
  1319. hr = m_pIABase->GetData(
  1320. i_hKey,
  1321. bstrPath,
  1322. &mr,
  1323. &dwRet);
  1324. if( hr == MD_ERROR_DATA_NOT_FOUND &&
  1325. METABASE_PROPERTY_DATA::s_KeyType.pDefaultValue )
  1326. {
  1327. mr.pbMDData = (LPBYTE)METABASE_PROPERTY_DATA::s_KeyType.pDefaultValue;
  1328. hr = S_OK;
  1329. }
  1330. //
  1331. // If this is a 'valid' subkey, then set io_pktKeyTypeSearch and return.
  1332. //
  1333. if (hr == ERROR_SUCCESS)
  1334. {
  1335. if(i_bLookForMatchAtCurrentLevelOnly == false)
  1336. {
  1337. if(CheckKeyType((LPCWSTR)mr.pbMDData,io_pktKeyTypeSearch))
  1338. {
  1339. break;
  1340. }
  1341. }
  1342. else
  1343. {
  1344. if(CUtils::CompareKeyType((LPWSTR)mr.pbMDData,io_pktKeyTypeSearch))
  1345. {
  1346. break;
  1347. }
  1348. }
  1349. }
  1350. //
  1351. // Otherwise, go to next subkey.
  1352. //
  1353. (*io_pdwMDEnumKeyIndex) = (*io_pdwMDEnumKeyIndex)+1;
  1354. }
  1355. return hr;
  1356. }
  1357. void CMetabase::PutMethod(
  1358. LPWSTR i_wszPath,
  1359. DWORD i_id)
  1360. {
  1361. HRESULT hr = S_OK;
  1362. CServerMethod method;
  1363. hr = method.Initialize(m_pIABase, i_wszPath);
  1364. THROW_ON_ERROR(hr);
  1365. hr = method.ExecMethod(i_id);
  1366. THROW_ON_ERROR(hr);
  1367. }
  1368. //
  1369. // You are currently at i_wszKeyTypeCurrent in the metabase. You want to see
  1370. // if io_pktKeyTypeSearch can be contained somewhere further down the tree.
  1371. //
  1372. bool CMetabase::CheckKeyType(
  1373. LPCWSTR i_wszKeyTypeCurrent,
  1374. METABASE_KEYTYPE*& io_pktKeyTypeSearch
  1375. )
  1376. {
  1377. bool bRet = false;
  1378. METABASE_KEYTYPE* pktKeyTypeCurrent = &METABASE_KEYTYPE_DATA::s_NO_TYPE;
  1379. if(io_pktKeyTypeSearch == &METABASE_KEYTYPE_DATA::s_NO_TYPE)
  1380. {
  1381. return false;
  1382. }
  1383. if(FAILED(g_pDynSch->GetHashKeyTypes()->Wmi_GetByKey(i_wszKeyTypeCurrent, &pktKeyTypeCurrent)))
  1384. {
  1385. return (io_pktKeyTypeSearch == &METABASE_KEYTYPE_DATA::s_IIsObject) ? true : false;
  1386. }
  1387. if(pktKeyTypeCurrent == io_pktKeyTypeSearch)
  1388. {
  1389. return true;
  1390. }
  1391. if( io_pktKeyTypeSearch == &METABASE_KEYTYPE_DATA::s_TYPE_AdminACL ||
  1392. io_pktKeyTypeSearch == &METABASE_KEYTYPE_DATA::s_TYPE_AdminACE ||
  1393. io_pktKeyTypeSearch == &METABASE_KEYTYPE_DATA::s_TYPE_IPSecurity )
  1394. {
  1395. bRet = true;
  1396. }
  1397. else
  1398. {
  1399. bRet = g_pDynSch->IsContainedUnder(pktKeyTypeCurrent, io_pktKeyTypeSearch);
  1400. }
  1401. if(bRet)
  1402. {
  1403. io_pktKeyTypeSearch = pktKeyTypeCurrent;
  1404. }
  1405. return bRet;
  1406. /*if(io_pktKeyTypeSearch == &METABASE_KEYTYPE_DATA::s_IIsLogModule)
  1407. {
  1408. if( pktKeyTypeCurrent == &METABASE_KEYTYPE_DATA::s_IIsLogModules )
  1409. bRet = true;
  1410. }
  1411. else if(io_pktKeyTypeSearch == &METABASE_KEYTYPE_DATA::s_IIsFtpInfo)
  1412. {
  1413. if( pktKeyTypeCurrent == &METABASE_KEYTYPE_DATA::s_IIsFtpService )
  1414. bRet = true;
  1415. }
  1416. else if(io_pktKeyTypeSearch == &METABASE_KEYTYPE_DATA::s_IIsFtpServer)
  1417. {
  1418. if( pktKeyTypeCurrent == &METABASE_KEYTYPE_DATA::s_IIsFtpService )
  1419. bRet = true;
  1420. }
  1421. else if(io_pktKeyTypeSearch == &METABASE_KEYTYPE_DATA::s_IIsFtpVirtualDir)
  1422. {
  1423. if( pktKeyTypeCurrent == &METABASE_KEYTYPE_DATA::s_IIsFtpService ||
  1424. pktKeyTypeCurrent == &METABASE_KEYTYPE_DATA::s_IIsFtpServer ||
  1425. pktKeyTypeCurrent == &METABASE_KEYTYPE_DATA::s_IIsFtpVirtualDir
  1426. )
  1427. bRet = true;
  1428. }
  1429. else if(io_pktKeyTypeSearch == &METABASE_KEYTYPE_DATA::s_IIsWebInfo)
  1430. {
  1431. if( pktKeyTypeCurrent == &METABASE_KEYTYPE_DATA::s_IIsWebService )
  1432. bRet = true;
  1433. }
  1434. else if(io_pktKeyTypeSearch == &METABASE_KEYTYPE_DATA::s_IIsFilters)
  1435. {
  1436. if( pktKeyTypeCurrent == &METABASE_KEYTYPE_DATA::s_IIsWebService ||
  1437. pktKeyTypeCurrent == &METABASE_KEYTYPE_DATA::s_IIsWebServer
  1438. )
  1439. bRet = true;
  1440. }
  1441. else if(io_pktKeyTypeSearch == &METABASE_KEYTYPE_DATA::s_IIsFilter)
  1442. {
  1443. if( pktKeyTypeCurrent == &METABASE_KEYTYPE_DATA::s_IIsWebService ||
  1444. pktKeyTypeCurrent == &METABASE_KEYTYPE_DATA::s_IIsWebServer ||
  1445. pktKeyTypeCurrent == &METABASE_KEYTYPE_DATA::s_IIsFilters
  1446. )
  1447. bRet = true;
  1448. }
  1449. else if(io_pktKeyTypeSearch == &METABASE_KEYTYPE_DATA::s_IIsCompressionSchemes)
  1450. {
  1451. if( pktKeyTypeCurrent == &METABASE_KEYTYPE_DATA::s_IIsWebService ||
  1452. pktKeyTypeCurrent == &METABASE_KEYTYPE_DATA::s_IIsWebServer ||
  1453. pktKeyTypeCurrent == &METABASE_KEYTYPE_DATA::s_IIsFilters )
  1454. bRet = true;
  1455. }
  1456. else if(io_pktKeyTypeSearch == &METABASE_KEYTYPE_DATA::s_IIsCompressionScheme)
  1457. {
  1458. if( pktKeyTypeCurrent == &METABASE_KEYTYPE_DATA::s_IIsWebService ||
  1459. pktKeyTypeCurrent == &METABASE_KEYTYPE_DATA::s_IIsWebServer ||
  1460. pktKeyTypeCurrent == &METABASE_KEYTYPE_DATA::s_IIsFilters ||
  1461. pktKeyTypeCurrent == &METABASE_KEYTYPE_DATA::s_IIsCompressionSchemes)
  1462. bRet = true;
  1463. }
  1464. else if(io_pktKeyTypeSearch == &METABASE_KEYTYPE_DATA::s_IIsWebServer)
  1465. {
  1466. if( pktKeyTypeCurrent == &METABASE_KEYTYPE_DATA::s_IIsWebService )
  1467. bRet = true;
  1468. }
  1469. else if(io_pktKeyTypeSearch == &METABASE_KEYTYPE_DATA::s_IIsCertMapper)
  1470. {
  1471. if( pktKeyTypeCurrent == &METABASE_KEYTYPE_DATA::s_IIsWebService ||
  1472. pktKeyTypeCurrent == &METABASE_KEYTYPE_DATA::s_IIsWebServer
  1473. )
  1474. bRet = true;
  1475. }
  1476. else if(io_pktKeyTypeSearch == &METABASE_KEYTYPE_DATA::s_IIsWebVirtualDir)
  1477. {
  1478. if( pktKeyTypeCurrent == &METABASE_KEYTYPE_DATA::s_IIsWebService ||
  1479. pktKeyTypeCurrent == &METABASE_KEYTYPE_DATA::s_IIsWebServer ||
  1480. pktKeyTypeCurrent == &METABASE_KEYTYPE_DATA::s_IIsWebVirtualDir ||
  1481. pktKeyTypeCurrent == &METABASE_KEYTYPE_DATA::s_IIsWebDirectory
  1482. )
  1483. bRet = true;
  1484. }
  1485. else if(io_pktKeyTypeSearch == &METABASE_KEYTYPE_DATA::s_IIsWebDirectory)
  1486. {
  1487. if( pktKeyTypeCurrent == &METABASE_KEYTYPE_DATA::s_IIsWebService ||
  1488. pktKeyTypeCurrent == &METABASE_KEYTYPE_DATA::s_IIsWebServer ||
  1489. pktKeyTypeCurrent == &METABASE_KEYTYPE_DATA::s_IIsWebVirtualDir ||
  1490. pktKeyTypeCurrent == &METABASE_KEYTYPE_DATA::s_IIsWebDirectory
  1491. )
  1492. bRet = true;
  1493. }
  1494. else if(io_pktKeyTypeSearch == &METABASE_KEYTYPE_DATA::s_IIsWebFile)
  1495. {
  1496. if( pktKeyTypeCurrent == &METABASE_KEYTYPE_DATA::s_IIsWebService ||
  1497. pktKeyTypeCurrent == &METABASE_KEYTYPE_DATA::s_IIsWebServer ||
  1498. pktKeyTypeCurrent == &METABASE_KEYTYPE_DATA::s_IIsWebVirtualDir ||
  1499. pktKeyTypeCurrent == &METABASE_KEYTYPE_DATA::s_IIsWebDirectory
  1500. )
  1501. bRet = true;
  1502. }
  1503. else if(io_pktKeyTypeSearch == &METABASE_KEYTYPE_DATA::s_TYPE_AdminACL ||
  1504. io_pktKeyTypeSearch == &METABASE_KEYTYPE_DATA::s_TYPE_AdminACE)
  1505. {
  1506. if( pktKeyTypeCurrent == &METABASE_KEYTYPE_DATA::s_IIsWebService ||
  1507. pktKeyTypeCurrent == &METABASE_KEYTYPE_DATA::s_IIsWebServer ||
  1508. pktKeyTypeCurrent == &METABASE_KEYTYPE_DATA::s_IIsWebVirtualDir ||
  1509. pktKeyTypeCurrent == &METABASE_KEYTYPE_DATA::s_IIsWebDirectory ||
  1510. pktKeyTypeCurrent == &METABASE_KEYTYPE_DATA::s_IIsWebFile ||
  1511. pktKeyTypeCurrent == &METABASE_KEYTYPE_DATA::s_IIsFtpService ||
  1512. pktKeyTypeCurrent == &METABASE_KEYTYPE_DATA::s_IIsFtpServer ||
  1513. pktKeyTypeCurrent == &METABASE_KEYTYPE_DATA::s_IIsFtpVirtualDir
  1514. )
  1515. bRet = true;
  1516. }
  1517. else if(io_pktKeyTypeSearch == &METABASE_KEYTYPE_DATA::s_TYPE_IPSecurity)
  1518. {
  1519. if( pktKeyTypeCurrent == &METABASE_KEYTYPE_DATA::s_IIsWebService ||
  1520. pktKeyTypeCurrent == &METABASE_KEYTYPE_DATA::s_IIsWebServer ||
  1521. pktKeyTypeCurrent == &METABASE_KEYTYPE_DATA::s_IIsWebVirtualDir ||
  1522. pktKeyTypeCurrent == &METABASE_KEYTYPE_DATA::s_IIsWebDirectory ||
  1523. pktKeyTypeCurrent == &METABASE_KEYTYPE_DATA::s_IIsWebFile ||
  1524. pktKeyTypeCurrent == &METABASE_KEYTYPE_DATA::s_IIsFtpService ||
  1525. pktKeyTypeCurrent == &METABASE_KEYTYPE_DATA::s_IIsFtpServer ||
  1526. pktKeyTypeCurrent == &METABASE_KEYTYPE_DATA::s_IIsFtpVirtualDir
  1527. )
  1528. bRet = true;
  1529. }*/
  1530. }
  1531. HRESULT CMetabase::WebAppCheck(
  1532. METADATA_HANDLE a_hKey
  1533. )
  1534. {
  1535. HRESULT hr = S_OK;
  1536. DWORD dwBufferSize;
  1537. METADATA_RECORD mdrMDData;
  1538. WCHAR DataBuf[MAX_PATH];
  1539. DWORD dwState;
  1540. dwBufferSize = MAX_PATH;
  1541. MD_SET_DATA_RECORD(
  1542. &mdrMDData,
  1543. MD_APP_ROOT,
  1544. METADATA_INHERIT|METADATA_ISINHERITED,
  1545. IIS_MD_UT_FILE,
  1546. STRING_METADATA,
  1547. dwBufferSize,
  1548. &DataBuf
  1549. );
  1550. hr = m_pIABase->GetData(
  1551. a_hKey,
  1552. NULL,
  1553. &mdrMDData,
  1554. &dwBufferSize
  1555. );
  1556. THROW_ON_ERROR(hr);
  1557. if (mdrMDData.dwMDAttributes & METADATA_ISINHERITED)
  1558. {
  1559. hr = MD_ERROR_DATA_NOT_FOUND;
  1560. THROW_ON_ERROR(hr);
  1561. }
  1562. dwBufferSize = sizeof(DWORD);
  1563. MD_SET_DATA_RECORD(
  1564. &mdrMDData,
  1565. MD_APP_ISOLATED,
  1566. METADATA_INHERIT|METADATA_ISINHERITED,
  1567. IIS_MD_UT_WAM,
  1568. DWORD_METADATA,
  1569. dwBufferSize,
  1570. &dwState
  1571. );
  1572. hr = m_pIABase->GetData(
  1573. a_hKey,
  1574. NULL,
  1575. &mdrMDData,
  1576. &dwBufferSize
  1577. );
  1578. THROW_ON_ERROR(hr);
  1579. if (mdrMDData.dwMDAttributes & METADATA_ISINHERITED)
  1580. {
  1581. hr = MD_ERROR_DATA_NOT_FOUND;
  1582. THROW_ON_ERROR(hr);
  1583. }
  1584. return hr;
  1585. }
  1586. HRESULT CMetabase::WebAppGetStatus(
  1587. METADATA_HANDLE a_hKey,
  1588. PDWORD pdwState)
  1589. {
  1590. HRESULT hr = S_OK;
  1591. DWORD dwBufferSize = sizeof(DWORD);
  1592. METADATA_RECORD mdrMDData;
  1593. MD_SET_DATA_RECORD(
  1594. &mdrMDData,
  1595. MD_ASP_ENABLEAPPLICATIONRESTART,
  1596. METADATA_INHERIT,
  1597. ASP_MD_UT_APP,
  1598. DWORD_METADATA,
  1599. dwBufferSize,
  1600. pdwState
  1601. );
  1602. hr = m_pIABase->GetData(
  1603. a_hKey,
  1604. NULL,
  1605. &mdrMDData,
  1606. &dwBufferSize
  1607. );
  1608. return hr;
  1609. }
  1610. HRESULT CMetabase::WebAppSetStatus(
  1611. METADATA_HANDLE a_hKey,
  1612. DWORD dwState
  1613. )
  1614. {
  1615. HRESULT hr = S_OK;
  1616. DWORD dwBufferSize = sizeof(DWORD);
  1617. METADATA_RECORD mdrMDData;
  1618. MD_SET_DATA_RECORD(
  1619. &mdrMDData,
  1620. MD_ASP_ENABLEAPPLICATIONRESTART,
  1621. METADATA_INHERIT,
  1622. ASP_MD_UT_APP,
  1623. DWORD_METADATA,
  1624. dwBufferSize,
  1625. &dwState
  1626. );
  1627. hr = m_pIABase->SetData(
  1628. a_hKey,
  1629. NULL,
  1630. &mdrMDData
  1631. );
  1632. return hr;
  1633. }
  1634. HRESULT
  1635. CServerMethod::ExecMethod(
  1636. DWORD dwControl
  1637. )
  1638. {
  1639. DWORD dwTargetState;
  1640. DWORD dwPendingState;
  1641. DWORD dwState = 0;
  1642. DWORD dwSleepTotal = 0L;
  1643. METADATA_HANDLE hKey = 0;
  1644. HRESULT hr = S_OK;
  1645. HRESULT hrMbNode = S_OK;
  1646. switch(dwControl)
  1647. {
  1648. case MD_SERVER_COMMAND_STOP:
  1649. dwTargetState = MD_SERVER_STATE_STOPPED;
  1650. dwPendingState = MD_SERVER_STATE_STOPPING;
  1651. break;
  1652. case MD_SERVER_COMMAND_START:
  1653. dwTargetState = MD_SERVER_STATE_STARTED;
  1654. dwPendingState = MD_SERVER_STATE_STARTING;
  1655. break;
  1656. case MD_SERVER_COMMAND_CONTINUE:
  1657. dwTargetState = MD_SERVER_STATE_STARTED;
  1658. dwPendingState = MD_SERVER_STATE_CONTINUING;
  1659. break;
  1660. case MD_SERVER_COMMAND_PAUSE:
  1661. dwTargetState = MD_SERVER_STATE_PAUSED;
  1662. dwPendingState = MD_SERVER_STATE_PAUSING;
  1663. break;
  1664. default:
  1665. hr = RETURNCODETOHRESULT(ERROR_INVALID_PARAMETER);
  1666. if(FAILED(hr))
  1667. {
  1668. goto error;
  1669. }
  1670. }
  1671. hr = IISGetServerState(METADATA_MASTER_ROOT_HANDLE, &dwState);
  1672. if(FAILED(hr))
  1673. {
  1674. goto error;
  1675. }
  1676. if (dwState == dwTargetState)
  1677. {
  1678. return (hr);
  1679. }
  1680. //
  1681. // Write the command to the metabase
  1682. //
  1683. hr = m_pIABase->OpenKey(
  1684. METADATA_MASTER_ROOT_HANDLE,
  1685. m_wszPath,
  1686. METADATA_PERMISSION_READ | METADATA_PERMISSION_WRITE,
  1687. DEFAULT_TIMEOUT_VALUE, // 30 seconds
  1688. &hKey);
  1689. if(FAILED(hr))
  1690. {
  1691. goto error;
  1692. }
  1693. hr = IISSetDword(hKey, MD_WIN32_ERROR, 0);
  1694. if(FAILED(hr))
  1695. {
  1696. m_pIABase->CloseKey(hKey);
  1697. goto error;
  1698. }
  1699. hr = IISSetDword(hKey, MD_SERVER_COMMAND, dwControl);
  1700. if(FAILED(hr))
  1701. {
  1702. m_pIABase->CloseKey(hKey);
  1703. goto error;
  1704. }
  1705. m_pIABase->CloseKey(hKey);
  1706. while (dwSleepTotal < MAX_SLEEP_INST)
  1707. {
  1708. hr = IISGetServerState(METADATA_MASTER_ROOT_HANDLE, &dwState);
  1709. if(FAILED(hr))
  1710. {
  1711. goto error;
  1712. }
  1713. hrMbNode = 0;
  1714. hr = IISGetServerWin32Error(METADATA_MASTER_ROOT_HANDLE, &hrMbNode);
  1715. if(FAILED(hr))
  1716. {
  1717. goto error;
  1718. }
  1719. //
  1720. // First check if we've hit target state
  1721. //
  1722. if (dwState != dwPendingState)
  1723. {
  1724. //
  1725. // Done one way or another
  1726. //
  1727. if (dwState == dwTargetState)
  1728. {
  1729. break;
  1730. }
  1731. }
  1732. //
  1733. // If we haven't check the Win32 Error from the metabase
  1734. //
  1735. if(FAILED(hrMbNode))
  1736. {
  1737. hr = hrMbNode;
  1738. goto error;
  1739. }
  1740. //
  1741. // Still pending...
  1742. //
  1743. ::Sleep(SLEEP_INTERVAL);
  1744. dwSleepTotal += SLEEP_INTERVAL;
  1745. }
  1746. if (dwSleepTotal >= MAX_SLEEP_INST)
  1747. {
  1748. //
  1749. // Timed out. If there is a real error in the metabase
  1750. // use it, otherwise use a generic timeout error
  1751. //
  1752. hr = HRESULT_FROM_WIN32(ERROR_SERVICE_REQUEST_TIMEOUT);
  1753. }
  1754. error :
  1755. return (hr);
  1756. }
  1757. //
  1758. // Helper routine for ExecMethod.
  1759. // Gets Win32 error from the metabase
  1760. //
  1761. HRESULT
  1762. CServerMethod::IISGetServerWin32Error(
  1763. METADATA_HANDLE hObjHandle,
  1764. HRESULT* phrError)
  1765. {
  1766. DBG_ASSERT(phrError != NULL);
  1767. long lWin32Error = 0;
  1768. DWORD dwLen;
  1769. METADATA_RECORD mr = {
  1770. MD_WIN32_ERROR,
  1771. METADATA_NO_ATTRIBUTES,
  1772. IIS_MD_UT_SERVER,
  1773. DWORD_METADATA,
  1774. sizeof(DWORD),
  1775. (unsigned char*)&lWin32Error,
  1776. 0
  1777. };
  1778. HRESULT hr = m_pIABase->GetData(
  1779. hObjHandle,
  1780. m_wszPath,
  1781. &mr,
  1782. &dwLen);
  1783. if(hr == MD_ERROR_DATA_NOT_FOUND)
  1784. {
  1785. hr = S_FALSE;
  1786. }
  1787. //
  1788. // Set out param
  1789. //
  1790. *phrError = HRESULT_FROM_WIN32(lWin32Error);
  1791. return hr;
  1792. }
  1793. //
  1794. // Helper routine for ExecMethod.
  1795. // Gets server state from the metabase.
  1796. //
  1797. HRESULT
  1798. CServerMethod::IISGetServerState(
  1799. METADATA_HANDLE hObjHandle,
  1800. PDWORD pdwState
  1801. )
  1802. {
  1803. HRESULT hr = S_OK;
  1804. DWORD dwBufferSize = sizeof(DWORD);
  1805. METADATA_RECORD mdrMDData;
  1806. LPBYTE pBuffer = (LPBYTE)pdwState;
  1807. MD_SET_DATA_RECORD(&mdrMDData,
  1808. MD_SERVER_STATE, // server state
  1809. METADATA_NO_ATTRIBUTES,
  1810. IIS_MD_UT_SERVER,
  1811. DWORD_METADATA,
  1812. dwBufferSize,
  1813. pBuffer);
  1814. hr = m_pIABase->GetData(
  1815. hObjHandle,
  1816. m_wszPath,
  1817. &mdrMDData,
  1818. &dwBufferSize
  1819. );
  1820. if( hr == MD_ERROR_DATA_NOT_FOUND )
  1821. {
  1822. //
  1823. // If the data is not there, but the path exists, then the
  1824. // most likely cause is that the service is not running and
  1825. // this object was just created.
  1826. //
  1827. // Since MD_SERVER_STATE would be set as stopped if the
  1828. // service were running when the key is added, we'll just
  1829. // say that it's stopped.
  1830. //
  1831. // Note: starting the server or service will automatically set
  1832. // the MB value.
  1833. //
  1834. *pdwState = MD_SERVER_STATE_STOPPED;
  1835. hr = S_FALSE;
  1836. }
  1837. else
  1838. {
  1839. if(FAILED(hr))
  1840. {
  1841. goto error;
  1842. }
  1843. }
  1844. error:
  1845. return(hr);
  1846. }
  1847. //
  1848. // Helper routine for ExecMethod.
  1849. // Used to sets the command or Win32Error in the metabase.
  1850. //
  1851. HRESULT
  1852. CServerMethod::IISSetDword(
  1853. METADATA_HANDLE hKey,
  1854. DWORD dwPropId,
  1855. DWORD dwValue
  1856. )
  1857. {
  1858. HRESULT hr = S_OK;
  1859. DWORD dwBufferSize = sizeof(DWORD);
  1860. METADATA_RECORD mdrMDData;
  1861. LPBYTE pBuffer = (LPBYTE)&dwValue;
  1862. MD_SET_DATA_RECORD(&mdrMDData,
  1863. dwPropId,
  1864. METADATA_NO_ATTRIBUTES,
  1865. IIS_MD_UT_SERVER,
  1866. DWORD_METADATA,
  1867. dwBufferSize,
  1868. pBuffer);
  1869. hr = m_pIABase->SetData(
  1870. hKey,
  1871. L"",
  1872. &mdrMDData
  1873. );
  1874. if(FAILED(hr))
  1875. {
  1876. goto error;
  1877. }
  1878. error:
  1879. return(hr);
  1880. }