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.

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