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.

1338 lines
30 KiB

  1. //***************************************************************************
  2. //
  3. // metsbase.cpp
  4. //
  5. // Module: WBEM Instance provider
  6. //
  7. // Purpose: IIS metabase class
  8. //
  9. // Copyright (c)1998 Microsoft Corporation, All Rights Reserved
  10. //
  11. //***************************************************************************
  12. #include "iisprov.h"
  13. #include "debug.h"
  14. CMetabase::CMetabase()
  15. {
  16. HRESULT hr = CoCreateInstance(
  17. CLSID_MSAdminBase,
  18. NULL,
  19. CLSCTX_ALL,
  20. IID_IMSAdminBase,
  21. (void**)&m_pIABase
  22. );
  23. THROW_ON_ERROR(hr);
  24. }
  25. CMetabase::~CMetabase()
  26. {
  27. if(m_pIABase)
  28. m_pIABase->Release();
  29. }
  30. HRESULT CMetabase::Backup(
  31. LPCWSTR pszMDBackupLocation,
  32. DWORD dwMDVersion,
  33. DWORD dwMDFlags
  34. )
  35. {
  36. HRESULT hr;
  37. hr = m_pIABase->Backup(
  38. pszMDBackupLocation,
  39. dwMDVersion,
  40. dwMDFlags);
  41. return hr;
  42. }
  43. HRESULT CMetabase::DeleteBackup(
  44. LPCWSTR pszMDBackupLocation,
  45. DWORD dwMDVersion
  46. )
  47. {
  48. HRESULT hr;
  49. hr = m_pIABase->DeleteBackup(
  50. pszMDBackupLocation,
  51. dwMDVersion
  52. );
  53. return hr;
  54. }
  55. HRESULT CMetabase::EnumBackups(
  56. LPWSTR pszMDBackupLocation,
  57. DWORD* pdwMDVersion,
  58. PFILETIME pftMDBackupTime,
  59. DWORD dwMDEnumIndex
  60. )
  61. {
  62. HRESULT hr;
  63. hr = m_pIABase->EnumBackups(
  64. pszMDBackupLocation,
  65. pdwMDVersion,
  66. pftMDBackupTime,
  67. dwMDEnumIndex
  68. );
  69. return hr;
  70. }
  71. HRESULT CMetabase::Restore(
  72. LPCWSTR pszMDBackupLocation,
  73. DWORD dwMDVersion,
  74. DWORD dwMDFlags
  75. )
  76. {
  77. HRESULT hr;
  78. hr = m_pIABase->Restore(
  79. pszMDBackupLocation,
  80. dwMDVersion,
  81. dwMDFlags);
  82. return hr;
  83. }
  84. void CMetabase::CloseKey(METADATA_HANDLE a_hKey)
  85. {
  86. if(a_hKey && m_pIABase)
  87. {
  88. m_pIABase->CloseKey(a_hKey);
  89. TRACE1(L"Close Key: %x\n", a_hKey);
  90. }
  91. }
  92. // open key handle
  93. METADATA_HANDLE CMetabase::OpenKey(LPCWSTR a_pstrKey, BOOL bWrite)
  94. {
  95. METADATA_HANDLE t_hKey = NULL;
  96. DWORD dwMDAccessRequested;
  97. if(bWrite)
  98. dwMDAccessRequested = METADATA_PERMISSION_READ | METADATA_PERMISSION_WRITE;
  99. else
  100. dwMDAccessRequested = METADATA_PERMISSION_READ;
  101. HRESULT t_hr = m_pIABase->OpenKey(
  102. METADATA_MASTER_ROOT_HANDLE,
  103. a_pstrKey,
  104. dwMDAccessRequested,
  105. METABASE_TIMEOUT, // 5 seconds
  106. &t_hKey
  107. );
  108. if(t_hr == ERROR_PATH_BUSY) // retry one time
  109. t_hr = m_pIABase->OpenKey(
  110. METADATA_MASTER_ROOT_HANDLE,
  111. a_pstrKey,
  112. dwMDAccessRequested,
  113. METABASE_TIMEOUT, // 5 seconds
  114. &t_hKey
  115. );
  116. THROW_ON_ERROR(t_hr);
  117. TRACE2(L"Open Key on %s, returned handle %x\n", a_pstrKey, t_hKey);
  118. return t_hKey;
  119. }
  120. // force to create or open a key by read/write permision
  121. METADATA_HANDLE CMetabase::CreateKey(LPCWSTR a_pstrKey)
  122. {
  123. HRESULT t_hr;
  124. METADATA_HANDLE t_hKey;
  125. // open and return key if exists
  126. t_hr = m_pIABase->OpenKey(
  127. METADATA_MASTER_ROOT_HANDLE,
  128. a_pstrKey,
  129. METADATA_PERMISSION_READ | METADATA_PERMISSION_WRITE,
  130. METABASE_TIMEOUT, // 5 seconds
  131. &t_hKey
  132. );
  133. if (t_hr == ERROR_SUCCESS)
  134. {
  135. TRACE2(L"Open Key on %s, returned handle %x\n", a_pstrKey, t_hKey);
  136. return t_hKey;
  137. }
  138. // create key if not there
  139. t_hr = m_pIABase->OpenKey(
  140. METADATA_MASTER_ROOT_HANDLE,
  141. NULL,
  142. METADATA_PERMISSION_READ | METADATA_PERMISSION_WRITE,
  143. METABASE_TIMEOUT, // 5 seconds
  144. &t_hKey
  145. );
  146. THROW_ON_ERROR(t_hr);
  147. // add key
  148. t_hr = m_pIABase->AddKey(t_hKey, a_pstrKey);
  149. // close this root key first
  150. CloseKey(t_hKey);
  151. THROW_ON_ERROR(t_hr);
  152. // now open the key just created
  153. t_hr = m_pIABase->OpenKey(
  154. METADATA_MASTER_ROOT_HANDLE,
  155. a_pstrKey,
  156. METADATA_PERMISSION_READ | METADATA_PERMISSION_WRITE,
  157. METABASE_TIMEOUT, // 5 seconds
  158. &t_hKey
  159. );
  160. THROW_ON_ERROR(t_hr);
  161. TRACE2(L"Open Key on %s, returned handle %x\n", a_pstrKey, t_hKey);
  162. return t_hKey;
  163. }
  164. // Check if the key is existed
  165. bool CMetabase::CheckKey(LPCWSTR a_pstrKey)
  166. {
  167. METADATA_HANDLE t_hKey = NULL;
  168. HRESULT t_hr = m_pIABase->OpenKey(
  169. METADATA_MASTER_ROOT_HANDLE,
  170. a_pstrKey,
  171. METADATA_PERMISSION_READ,
  172. METABASE_TIMEOUT, // 5 seconds
  173. &t_hKey
  174. );
  175. if(t_hr == ERROR_SUCCESS)
  176. {
  177. TRACE2(L"Open Key on %s, returned handle %x\n", a_pstrKey, t_hKey);
  178. CloseKey(t_hKey);
  179. }
  180. return (t_hr == ERROR_PATH_BUSY) | (t_hr == ERROR_SUCCESS) ? true : false;
  181. }
  182. HRESULT CMetabase::DeleteKey(
  183. METADATA_HANDLE a_hKey,
  184. LPCWSTR a_szKeyPath)
  185. {
  186. return m_pIABase->DeleteKey(
  187. a_hKey,
  188. a_szKeyPath
  189. );
  190. }
  191. //
  192. // GetDword
  193. //
  194. // A long or bool is returned in the VARIANT. The value is a bool if the
  195. // METABASE_PROPERTY has a mask otherwise the DWORD is returned as a long.
  196. // The METADATA_HANDLE is expected to be valid and open.
  197. //
  198. void CMetabase::GetDword(
  199. METADATA_HANDLE a_hKey,
  200. METABASE_PROPERTY* a_pmbp,
  201. _variant_t& a_vt
  202. )
  203. {
  204. DWORD t_dw;
  205. DWORD t_dwRet;
  206. HRESULT t_hr;
  207. if(a_hKey == NULL || a_pmbp == NULL)
  208. throw WBEM_E_INVALID_PARAMETER;
  209. METADATA_RECORD t_mr = {
  210. a_pmbp->dwMDIdentifier,
  211. a_pmbp->dwMDAttributes,
  212. a_pmbp->dwMDUserType,
  213. a_pmbp->dwMDDataType,
  214. sizeof(DWORD),
  215. (unsigned char*)&t_dw,
  216. 0
  217. };
  218. t_hr = m_pIABase->GetData(a_hKey, NULL, &t_mr, &t_dwRet);
  219. if (t_hr == MD_ERROR_DATA_NOT_FOUND)
  220. a_vt.vt = VT_NULL;
  221. else
  222. {
  223. THROW_E_ON_ERROR(t_hr,a_pmbp);
  224. if (a_pmbp->dwMDMask)
  225. {
  226. a_vt.vt = VT_BOOL;
  227. a_vt.boolVal = (t_dw & a_pmbp->dwMDMask? -1 : 0);
  228. }
  229. else
  230. {
  231. a_vt.vt = VT_I4;
  232. a_vt.lVal = t_dw;
  233. }
  234. }
  235. }
  236. //
  237. // GetStringFromMetabase
  238. //
  239. void CMetabase::GetString(
  240. METADATA_HANDLE a_hKey,
  241. METABASE_PROPERTY* a_pmbp,
  242. _variant_t& a_vt
  243. )
  244. {
  245. DWORD t_dwRet;
  246. HRESULT t_hr;
  247. WCHAR t_buffer[MAX_BUF_SIZE];
  248. if(a_hKey == NULL || a_pmbp == NULL)
  249. throw WBEM_E_INVALID_PARAMETER;
  250. METADATA_RECORD t_mr = {
  251. a_pmbp->dwMDIdentifier,
  252. a_pmbp->dwMDAttributes,
  253. a_pmbp->dwMDUserType,
  254. a_pmbp->dwMDDataType,
  255. MAX_BUF_SIZE*sizeof(WCHAR),
  256. (unsigned char*)t_buffer,
  257. 0
  258. };
  259. t_hr = m_pIABase->GetData(a_hKey, NULL, &t_mr, &t_dwRet);
  260. if (t_hr == MD_ERROR_DATA_NOT_FOUND)
  261. {
  262. a_vt.vt = VT_NULL;
  263. return;
  264. }
  265. THROW_E_ON_ERROR(t_hr, a_pmbp);
  266. a_vt = t_buffer;
  267. }
  268. //
  269. // GetMultiSz
  270. //
  271. //
  272. void CMetabase::GetMultiSz(
  273. METADATA_HANDLE a_hKey,
  274. METABASE_PROPERTY* a_pmbp,
  275. _variant_t& a_vt
  276. )
  277. {
  278. DWORD t_dwRet;
  279. HRESULT t_hr;
  280. WCHAR *t_buffer = NULL;
  281. try
  282. {
  283. if(a_hKey == NULL || a_pmbp == NULL)
  284. throw WBEM_E_INVALID_PARAMETER;
  285. if ((t_buffer = (WCHAR*)new WCHAR[10*MAX_BUF_SIZE])==NULL)
  286. throw WBEM_E_OUT_OF_MEMORY;
  287. METADATA_RECORD t_mr = {
  288. a_pmbp->dwMDIdentifier,
  289. a_pmbp->dwMDAttributes,
  290. a_pmbp->dwMDUserType,
  291. a_pmbp->dwMDDataType,
  292. 10*MAX_BUF_SIZE*sizeof(WCHAR),
  293. (unsigned char*)t_buffer,
  294. 0
  295. };
  296. t_hr = m_pIABase->GetData(a_hKey, NULL, &t_mr, &t_dwRet);
  297. if (t_hr == ERROR_INSUFFICIENT_BUFFER)
  298. {
  299. delete [] t_buffer;
  300. if ((t_buffer = (WCHAR*)new WCHAR[t_dwRet/sizeof(WCHAR) +1])==NULL)
  301. throw WBEM_E_OUT_OF_MEMORY;
  302. t_mr.pbMDData = (unsigned char*)t_buffer;
  303. t_hr = m_pIABase->GetData(a_hKey, NULL, &t_mr, &t_dwRet);
  304. }
  305. if (t_hr == MD_ERROR_DATA_NOT_FOUND) {
  306. a_vt.vt = VT_NULL;
  307. delete [] t_buffer;
  308. return;
  309. }
  310. THROW_E_ON_ERROR(t_hr,a_pmbp);
  311. LoadSafeArrayFromMultiSz(t_buffer,a_vt);
  312. delete [] t_buffer;
  313. }
  314. catch (...)
  315. {
  316. if (t_buffer)
  317. delete [] t_buffer;
  318. throw;
  319. }
  320. }
  321. //
  322. // PutDword
  323. //
  324. void CMetabase::PutDword(
  325. METADATA_HANDLE a_hKey,
  326. METABASE_PROPERTY* a_pmbp,
  327. _variant_t& a_vt,
  328. _variant_t* a_vtOld,
  329. bool a_boolOverrideParent // optional
  330. )
  331. {
  332. DWORD t_dw=0;
  333. DWORD t_dwOld=0;
  334. DWORD t_dwRet=0;
  335. HRESULT t_hr=0;
  336. if(a_hKey == NULL || a_pmbp == NULL)
  337. throw WBEM_E_INVALID_PARAMETER;
  338. if((a_vtOld) &&
  339. (a_vtOld->vt != VT_BOOL) &&
  340. (a_vtOld->vt != VT_I4) &&
  341. (a_vtOld->vt != VT_NULL) && (a_vtOld->vt != VT_EMPTY))
  342. throw WBEM_E_INVALID_PARAMETER;
  343. if( a_pmbp->fReadOnly )
  344. return;
  345. METADATA_RECORD t_mr;
  346. t_mr.dwMDIdentifier = a_pmbp->dwMDIdentifier;
  347. t_mr.dwMDAttributes = a_pmbp->dwMDAttributes;
  348. t_mr.dwMDUserType = a_pmbp->dwMDUserType;
  349. t_mr.dwMDDataType = a_pmbp->dwMDDataType;
  350. t_mr.dwMDDataLen = sizeof(DWORD_METADATA);
  351. t_mr.pbMDData = (unsigned char*)&t_dwOld;
  352. t_mr.dwMDDataTag = 0;
  353. // if it's the bit of a flag
  354. if (a_vt.vt == VT_BOOL && a_pmbp->dwMDMask != 0)
  355. {
  356. // Read the entire flag from in the metabase so we can set the bit
  357. t_hr = m_pIABase->GetData(a_hKey, NULL, &t_mr, &t_dwRet);
  358. if (t_hr == ERROR_SUCCESS)
  359. {
  360. if (a_vt.boolVal)
  361. t_dw = t_dwOld | a_pmbp->dwMDMask;
  362. else
  363. t_dw = t_dwOld & ~a_pmbp->dwMDMask;
  364. }
  365. else if (t_hr == MD_ERROR_DATA_NOT_FOUND)
  366. {
  367. t_dw = (a_vt.boolVal ? a_pmbp->dwMDMask : 0);
  368. t_hr = 0;
  369. }
  370. else
  371. THROW_ON_ERROR(t_hr);
  372. if(t_dw == -1)
  373. t_dw = 1; // true
  374. }
  375. else if (a_vt.vt == VT_I4)
  376. {
  377. t_dw = a_vt.lVal;
  378. }
  379. else if (a_vt.vt == VT_BOOL)
  380. {
  381. t_dw = a_vt.bVal;
  382. }
  383. else
  384. throw WBEM_E_INVALID_OBJECT;
  385. // Decide whether to write to metabase
  386. if ((a_boolOverrideParent) ||
  387. (a_vtOld == NULL) ||
  388. (*a_vtOld != a_vt))
  389. {
  390. t_mr.pbMDData = (unsigned char*)&t_dw;
  391. t_hr = m_pIABase->SetData(a_hKey, NULL, &t_mr);
  392. }
  393. THROW_E_ON_ERROR(t_hr,a_pmbp);
  394. }
  395. //
  396. // PutString
  397. //
  398. void CMetabase::PutString(
  399. METADATA_HANDLE a_hKey,
  400. METABASE_PROPERTY* a_pmbp,
  401. _variant_t& a_vt,
  402. _variant_t* a_vtOld,
  403. bool a_boolOverrideParent // optional
  404. )
  405. {
  406. HRESULT t_hr=0;
  407. if(a_hKey == NULL || a_pmbp == NULL || a_vt.vt != VT_BSTR)
  408. throw WBEM_E_INVALID_PARAMETER;
  409. if((a_vtOld) &&
  410. (a_vtOld->vt != VT_BSTR) &&
  411. (a_vtOld->vt != VT_NULL) && (a_vtOld->vt != VT_EMPTY))
  412. throw WBEM_E_INVALID_PARAMETER;
  413. if( a_pmbp->fReadOnly )
  414. return;
  415. METADATA_RECORD t_mr;
  416. t_mr.dwMDIdentifier = a_pmbp->dwMDIdentifier;
  417. t_mr.dwMDAttributes = a_pmbp->dwMDAttributes;
  418. t_mr.dwMDUserType = a_pmbp->dwMDUserType;
  419. t_mr.dwMDDataType = a_pmbp->dwMDDataType;
  420. t_mr.dwMDDataTag = 0;
  421. // Set the value, only if old and new values differ.
  422. if ((a_boolOverrideParent) ||
  423. (a_vtOld == NULL) ||
  424. (a_vtOld->vt == VT_NULL) || (a_vtOld->vt == VT_EMPTY) ||
  425. (_wcsicmp(a_vtOld->bstrVal, a_vt.bstrVal) != NULL))
  426. {
  427. t_mr.dwMDDataLen = (wcslen(a_vt.bstrVal)+1)*sizeof(WCHAR);
  428. t_mr.pbMDData = (unsigned char*)a_vt.bstrVal;
  429. t_hr = m_pIABase->SetData(a_hKey, NULL, &t_mr);
  430. }
  431. THROW_E_ON_ERROR(t_hr,a_pmbp);
  432. }
  433. //
  434. // PutMultiSz
  435. //
  436. //
  437. void CMetabase::PutMultiSz(
  438. METADATA_HANDLE a_hKey,
  439. METABASE_PROPERTY* a_pmbp,
  440. _variant_t& a_vt,
  441. _variant_t* a_vtOld,
  442. bool a_boolOverrideParent // optional
  443. )
  444. {
  445. DWORD t_dwRet;
  446. DWORD t_dwRetOld;
  447. WCHAR *t_buffer = NULL;
  448. WCHAR *t_bufferOld = NULL;
  449. HRESULT t_hr=0;
  450. bool t_boolChange=false;
  451. if(a_hKey == NULL || a_pmbp == NULL || a_vt.vt != (VT_ARRAY | VT_BSTR))
  452. throw WBEM_E_INVALID_PARAMETER;
  453. if((a_vtOld) &&
  454. (a_vtOld->vt != (VT_ARRAY | VT_BSTR)) &&
  455. (a_vtOld->vt != VT_NULL) && (a_vtOld->vt != VT_EMPTY))
  456. throw WBEM_E_INVALID_PARAMETER;
  457. if( a_pmbp->fReadOnly )
  458. return;
  459. METADATA_RECORD t_mr;
  460. t_mr.dwMDIdentifier = a_pmbp->dwMDIdentifier;
  461. t_mr.dwMDAttributes = a_pmbp->dwMDAttributes;
  462. t_mr.dwMDUserType = a_pmbp->dwMDUserType;
  463. t_mr.dwMDDataType = a_pmbp->dwMDDataType;
  464. t_mr.dwMDDataTag = 0;
  465. try
  466. {
  467. // If we didn't get an old value
  468. // or if the flag is set, write to MB
  469. if(a_vtOld == NULL || a_vtOld->vt == VT_NULL || a_vtOld->vt == VT_EMPTY ||
  470. (a_boolOverrideParent))
  471. {
  472. t_boolChange = true;
  473. CreateMultiSzFromSafeArray(a_vt, &t_buffer, &t_dwRet);
  474. }
  475. // If we did get an old value, see if there's been a change
  476. else {
  477. CreateMultiSzFromSafeArray(*a_vtOld, &t_bufferOld, &t_dwRetOld);
  478. CreateMultiSzFromSafeArray(a_vt, &t_buffer, &t_dwRet);
  479. if(!CompareMultiSz(t_bufferOld, t_buffer)) {
  480. // they're different
  481. t_boolChange = true;
  482. }
  483. delete [] t_bufferOld;
  484. t_bufferOld = NULL;
  485. }
  486. if (t_boolChange)
  487. {
  488. t_mr.pbMDData = (unsigned char*)t_buffer;
  489. t_mr.dwMDDataLen = t_dwRet*sizeof(WCHAR);
  490. t_hr = m_pIABase->SetData(a_hKey, NULL, &t_mr);
  491. }
  492. delete [] t_buffer;
  493. t_buffer = NULL;
  494. THROW_E_ON_ERROR(t_hr,a_pmbp);
  495. }
  496. catch (...)
  497. {
  498. if(t_buffer)
  499. delete [] t_buffer;
  500. if(t_bufferOld)
  501. delete [] t_bufferOld;
  502. throw;
  503. }
  504. }
  505. //
  506. // DeleteData
  507. //
  508. void CMetabase::DeleteData(
  509. METADATA_HANDLE a_hKey,
  510. METABASE_PROPERTY* a_pmbp)
  511. {
  512. HRESULT t_hr;
  513. if(a_hKey == NULL || a_pmbp == NULL)
  514. throw WBEM_E_INVALID_PARAMETER;
  515. if(a_pmbp->fReadOnly)
  516. return;
  517. t_hr = m_pIABase->DeleteData(
  518. a_hKey,
  519. NULL,
  520. a_pmbp->dwMDIdentifier,
  521. a_pmbp->dwMDDataType
  522. );
  523. if (t_hr == MD_ERROR_DATA_NOT_FOUND ||t_hr == ERROR_SUCCESS)
  524. return;
  525. THROW_E_ON_ERROR(t_hr,a_pmbp);
  526. }
  527. //
  528. // DeleteData
  529. //
  530. void CMetabase::DeleteData(
  531. METADATA_HANDLE i_hKey,
  532. DWORD i_dwMDIdentifier,
  533. DWORD i_dwMDDataType)
  534. {
  535. HRESULT t_hr;
  536. if(i_hKey == NULL)
  537. throw WBEM_E_INVALID_PARAMETER;
  538. t_hr = m_pIABase->DeleteData(
  539. i_hKey,
  540. NULL,
  541. i_dwMDIdentifier,
  542. i_dwMDDataType
  543. );
  544. if (t_hr == MD_ERROR_DATA_NOT_FOUND ||t_hr == ERROR_SUCCESS)
  545. return;
  546. THROW_ON_ERROR(t_hr);
  547. }
  548. HRESULT CMetabase::EnumKeys(
  549. METADATA_HANDLE a_hKey,
  550. LPCWSTR a_pszMDPath, //path to the key
  551. LPWSTR a_pszMDName, //receives the name of the subkey --must be METADATA_MAX_NAME_LEN
  552. DWORD* a_pdwMDEnumKeyIndex, //index of the subkey
  553. enum_KEY_TYPE& a_eKeyType
  554. )
  555. {
  556. HRESULT t_hr;
  557. DWORD t_dwRet;
  558. WCHAR t_buffer[MAX_BUF_SIZE];
  559. if(a_hKey == NULL)
  560. throw WBEM_E_INVALID_PARAMETER;
  561. while ( ERROR_SUCCESS == (
  562. t_hr = m_pIABase->EnumKeys(
  563. a_hKey,
  564. a_pszMDPath,
  565. a_pszMDName,
  566. *a_pdwMDEnumKeyIndex
  567. )
  568. )
  569. )
  570. {
  571. t_buffer[0] = L'\0';
  572. METADATA_RECORD t_mr = {
  573. MD_KEY_TYPE,
  574. METADATA_NO_ATTRIBUTES,
  575. IIS_MD_UT_SERVER,
  576. STRING_METADATA,
  577. MAX_BUF_SIZE*sizeof(WCHAR),
  578. (unsigned char*)t_buffer,
  579. 0
  580. };
  581. _bstr_t t_bstrPath = L"";
  582. if(a_pszMDPath)
  583. {
  584. t_bstrPath += a_pszMDPath;
  585. t_bstrPath += L"/";
  586. }
  587. t_bstrPath += a_pszMDName;
  588. t_hr = m_pIABase->GetData(
  589. a_hKey,
  590. t_bstrPath,
  591. &t_mr,
  592. &t_dwRet);
  593. // found and return
  594. if (t_hr == ERROR_SUCCESS && CheckKeyType(a_eKeyType,t_buffer))
  595. {
  596. break;
  597. }
  598. (*a_pdwMDEnumKeyIndex) = (*a_pdwMDEnumKeyIndex)+1;
  599. }
  600. return t_hr;
  601. }
  602. void CMetabase::PutMethod(
  603. METADATA_HANDLE a_hKey,
  604. DWORD a_id
  605. )
  606. {
  607. HRESULT t_hr;
  608. if(a_hKey == NULL )
  609. throw WBEM_E_INVALID_PARAMETER;
  610. METADATA_RECORD t_mr = {
  611. MD_SERVER_COMMAND,
  612. METADATA_NO_ATTRIBUTES,
  613. IIS_MD_UT_SERVER,
  614. DWORD_METADATA,
  615. sizeof(DWORD),
  616. (unsigned char*)&a_id,
  617. 0
  618. };
  619. t_hr = m_pIABase->SetData(a_hKey, NULL, &t_mr);
  620. THROW_ON_ERROR(t_hr);
  621. }
  622. long CMetabase::GetWin32Error(
  623. METADATA_HANDLE a_hKey
  624. )
  625. {
  626. if(a_hKey == NULL )
  627. throw WBEM_E_INVALID_PARAMETER;
  628. long lWin32Error = 0;
  629. DWORD dwLen;
  630. METADATA_RECORD t_mr = {
  631. MD_WIN32_ERROR,
  632. METADATA_NO_ATTRIBUTES,
  633. IIS_MD_UT_SERVER,
  634. DWORD_METADATA,
  635. sizeof(DWORD),
  636. (unsigned char*)&lWin32Error,
  637. 0
  638. };
  639. HRESULT t_hr = m_pIABase->GetData(a_hKey, NULL, &t_mr, &dwLen);
  640. if (t_hr != MD_ERROR_DATA_NOT_FOUND)
  641. {
  642. THROW_ON_ERROR(t_hr);
  643. }
  644. return lWin32Error;
  645. }
  646. //
  647. // LoadSafeArrayFromMultiSz
  648. //
  649. void CMetabase::LoadSafeArrayFromMultiSz(
  650. WCHAR* a_pmsz,
  651. _variant_t& a_vt
  652. )
  653. {
  654. WCHAR* t_pmsz;
  655. HRESULT t_hr = ERROR_SUCCESS;
  656. DWORD t_c;
  657. SAFEARRAYBOUND t_aDim;
  658. SAFEARRAY* t_psa = NULL;
  659. long t_i = 0;
  660. try
  661. {
  662. if(a_pmsz == NULL)
  663. throw WBEM_E_INVALID_PARAMETER;
  664. // figure the dimensions of the multisz
  665. for (t_c=1,t_pmsz=a_pmsz; *t_pmsz||*(t_pmsz+1); t_pmsz++)
  666. if(!*t_pmsz) t_c++;
  667. t_aDim.lLbound = 0;
  668. t_aDim.cElements= t_c;
  669. t_psa = SafeArrayCreate(VT_BSTR, 1, &t_aDim);
  670. if (!t_psa)
  671. throw WBEM_E_FAILED;
  672. for (t_pmsz=a_pmsz; ; t_i++)
  673. {
  674. _bstr_t t_bstr = t_pmsz;
  675. t_hr = SafeArrayPutElement(t_psa,&t_i,BSTR(t_bstr));
  676. THROW_ON_ERROR(t_hr);
  677. for ( ; *t_pmsz; t_pmsz++);
  678. t_pmsz++;
  679. if (!*t_pmsz)
  680. break;
  681. }
  682. a_vt.vt = VT_ARRAY | VT_BSTR;
  683. a_vt.parray = t_psa;
  684. }
  685. catch (...)
  686. {
  687. if (t_psa)
  688. SafeArrayDestroy(t_psa);
  689. throw;
  690. }
  691. }
  692. //
  693. // CreateMultiSzFromSafeArray
  694. //
  695. void CMetabase::CreateMultiSzFromSafeArray(
  696. _variant_t& a_vt,
  697. WCHAR** a_ppsz,
  698. DWORD* a_pdw
  699. )
  700. {
  701. WCHAR* t_psz = NULL;
  702. long t_iLo,t_iUp,t_c;
  703. SAFEARRAY* t_psa = NULL;
  704. long t_i = 0;
  705. BSTR t_pstr = NULL;
  706. if((t_psa = a_vt.parray) == NULL)
  707. throw WBEM_E_INVALID_PARAMETER;
  708. THROW_ON_ERROR(SafeArrayGetLBound(t_psa,1,&t_iLo));
  709. THROW_ON_ERROR(SafeArrayGetUBound(t_psa,1,&t_iUp));
  710. try
  711. {
  712. CUtils obj;
  713. for (*a_pdw=0, t_c = t_iLo; t_c <= t_iUp; t_c++)
  714. {
  715. THROW_ON_ERROR(SafeArrayGetElement(t_psa,&t_c,&t_pstr));
  716. *a_pdw = *a_pdw + wcslen(t_pstr) + 1;
  717. obj.MzCat(&t_psz,t_pstr);
  718. SysFreeString(t_pstr);
  719. t_pstr = NULL;
  720. }
  721. *a_pdw +=1;
  722. *a_ppsz = t_psz;
  723. }
  724. catch (...)
  725. {
  726. if(t_psz)
  727. delete t_psz;
  728. if (t_pstr)
  729. SysFreeString(t_pstr);
  730. throw;
  731. }
  732. }
  733. bool CMetabase::CompareMultiSz(
  734. WCHAR* a_pmsz1,
  735. WCHAR* a_pmsz2
  736. )
  737. {
  738. if(a_pmsz1 == NULL && a_pmsz2 == NULL)
  739. return true;
  740. else if(a_pmsz1 == NULL || a_pmsz2 == NULL)
  741. return false;
  742. // compare the two multisz buffers.
  743. for ( ; (*a_pmsz1 && *a_pmsz2); )
  744. {
  745. if (_wcsicmp(a_pmsz1, a_pmsz2) != NULL)
  746. return false;
  747. a_pmsz1 += wcslen(a_pmsz1) + 1;
  748. a_pmsz2 += wcslen(a_pmsz2) + 1;
  749. }
  750. if (!*a_pmsz1 && !*a_pmsz2)
  751. {
  752. return true;
  753. }
  754. return false;
  755. }
  756. // DESC: You are enumming all a_eKeyTypes by going through the entire tree
  757. // and are currently at an a_pszTemp. You want to see if you should
  758. // continue recursing down this branch or not.
  759. // FIX: This information can be obtained from the associations in the schema.
  760. // But, it may not be trivial to implement.
  761. bool CMetabase::CheckKeyType(
  762. enum_KEY_TYPE& a_eKeyType,
  763. LPCWSTR a_pszTemp
  764. )
  765. {
  766. bool bRet = false;
  767. enum_KEY_TYPE eType = NO_TYPE;
  768. if(a_eKeyType == NO_TYPE)
  769. return false;
  770. CUtils obj;
  771. if( !obj.TypeStringToEnum(eType, a_pszTemp) )
  772. return false;
  773. if(eType == a_eKeyType)
  774. return true;
  775. switch(a_eKeyType)
  776. {
  777. case IIsLogModule:
  778. if( eType == IIsLogModules )
  779. bRet = true;
  780. break;
  781. case IIsFtpInfo:
  782. if( eType == IIsFtpService )
  783. bRet = true;
  784. break;
  785. case IIsFtpServer:
  786. if( eType == IIsFtpService )
  787. bRet = true;
  788. break;
  789. case IIsFtpVirtualDir:
  790. if( eType == IIsFtpService ||
  791. eType == IIsFtpServer ||
  792. eType == IIsFtpVirtualDir
  793. )
  794. bRet = true;
  795. break;
  796. case IIsWebInfo:
  797. if( eType == IIsWebService )
  798. bRet = true;
  799. break;
  800. case IIsFilters:
  801. if( eType == IIsWebService ||
  802. eType == IIsWebServer
  803. )
  804. bRet = true;
  805. break;
  806. case IIsFilter:
  807. if( eType == IIsWebService ||
  808. eType == IIsWebServer ||
  809. eType == IIsFilters
  810. )
  811. bRet = true;
  812. break;
  813. case IIsCompressionSchemes:
  814. if( eType == IIsWebService ||
  815. eType == IIsWebServer ||
  816. eType == IIsFilters )
  817. bRet = true;
  818. break;
  819. case IIsCompressionScheme:
  820. if( eType == IIsWebService ||
  821. eType == IIsWebServer ||
  822. eType == IIsFilters ||
  823. eType == IIsCompressionSchemes)
  824. bRet = true;
  825. break;
  826. case IIsWebServer:
  827. if( eType == IIsWebService )
  828. bRet = true;
  829. break;
  830. case IIsCertMapper:
  831. if( eType == IIsWebService ||
  832. eType == IIsWebServer
  833. )
  834. bRet = true;
  835. break;
  836. case IIsWebVirtualDir:
  837. if( eType == IIsWebService ||
  838. eType == IIsWebServer ||
  839. eType == IIsWebVirtualDir ||
  840. eType == IIsWebDirectory
  841. )
  842. bRet = true;
  843. break;
  844. case IIsWebDirectory:
  845. if( eType == IIsWebService ||
  846. eType == IIsWebServer ||
  847. eType == IIsWebVirtualDir ||
  848. eType == IIsWebDirectory
  849. )
  850. bRet = true;
  851. break;
  852. case IIsWebFile:
  853. if( eType == IIsWebService ||
  854. eType == IIsWebServer ||
  855. eType == IIsWebVirtualDir ||
  856. eType == IIsWebDirectory
  857. )
  858. bRet = true;
  859. break;
  860. case TYPE_AdminACL:
  861. case TYPE_AdminACE:
  862. if( eType == IIsWebService ||
  863. eType == IIsWebServer ||
  864. eType == IIsWebVirtualDir ||
  865. eType == IIsWebDirectory ||
  866. eType == IIsWebFile ||
  867. eType == IIsFtpService ||
  868. eType == IIsFtpServer ||
  869. eType == IIsFtpVirtualDir
  870. )
  871. bRet = true;
  872. break;
  873. case TYPE_IPSecurity:
  874. if( eType == IIsWebService ||
  875. eType == IIsWebServer ||
  876. eType == IIsWebVirtualDir ||
  877. eType == IIsWebDirectory ||
  878. eType == IIsWebFile ||
  879. eType == IIsFtpService ||
  880. eType == IIsFtpServer ||
  881. eType == IIsFtpVirtualDir
  882. )
  883. bRet = true;
  884. break;
  885. default:
  886. break;
  887. }
  888. if(bRet)
  889. a_eKeyType = eType;
  890. return bRet;
  891. }
  892. HRESULT CMetabase::WebAppCheck(
  893. METADATA_HANDLE a_hKey
  894. )
  895. {
  896. HRESULT hr = S_OK;
  897. DWORD dwBufferSize;
  898. METADATA_RECORD mdrMDData;
  899. WCHAR DataBuf[MAX_PATH];
  900. DWORD dwState;
  901. dwBufferSize = MAX_PATH;
  902. MD_SET_DATA_RECORD(
  903. &mdrMDData,
  904. MD_APP_ROOT,
  905. METADATA_INHERIT|METADATA_ISINHERITED,
  906. IIS_MD_UT_FILE,
  907. STRING_METADATA,
  908. dwBufferSize,
  909. &DataBuf
  910. );
  911. hr = m_pIABase->GetData(
  912. a_hKey,
  913. NULL,
  914. &mdrMDData,
  915. &dwBufferSize
  916. );
  917. THROW_ON_ERROR(hr);
  918. if (mdrMDData.dwMDAttributes & METADATA_ISINHERITED)
  919. {
  920. hr = MD_ERROR_DATA_NOT_FOUND;
  921. THROW_ON_ERROR(hr);
  922. }
  923. dwBufferSize = sizeof(DWORD);
  924. MD_SET_DATA_RECORD(
  925. &mdrMDData,
  926. MD_APP_ISOLATED,
  927. METADATA_INHERIT|METADATA_ISINHERITED,
  928. IIS_MD_UT_WAM,
  929. DWORD_METADATA,
  930. dwBufferSize,
  931. &dwState
  932. );
  933. hr = m_pIABase->GetData(
  934. a_hKey,
  935. NULL,
  936. &mdrMDData,
  937. &dwBufferSize
  938. );
  939. THROW_ON_ERROR(hr);
  940. if (mdrMDData.dwMDAttributes & METADATA_ISINHERITED)
  941. {
  942. hr = MD_ERROR_DATA_NOT_FOUND;
  943. THROW_ON_ERROR(hr);
  944. }
  945. return hr;
  946. }
  947. HRESULT CMetabase::WebAppGetStatus(
  948. METADATA_HANDLE a_hKey,
  949. PDWORD pdwState)
  950. {
  951. HRESULT hr = S_OK;
  952. DWORD dwBufferSize = sizeof(DWORD);
  953. METADATA_RECORD mdrMDData;
  954. MD_SET_DATA_RECORD(
  955. &mdrMDData,
  956. MD_ASP_ENABLEAPPLICATIONRESTART,
  957. METADATA_INHERIT,
  958. ASP_MD_UT_APP,
  959. DWORD_METADATA,
  960. dwBufferSize,
  961. pdwState
  962. );
  963. hr = m_pIABase->GetData(
  964. a_hKey,
  965. NULL,
  966. &mdrMDData,
  967. &dwBufferSize
  968. );
  969. return hr;
  970. }
  971. HRESULT CMetabase::WebAppSetStatus(
  972. METADATA_HANDLE a_hKey,
  973. DWORD dwState
  974. )
  975. {
  976. HRESULT hr = S_OK;
  977. DWORD dwBufferSize = sizeof(DWORD);
  978. METADATA_RECORD mdrMDData;
  979. MD_SET_DATA_RECORD(
  980. &mdrMDData,
  981. MD_ASP_ENABLEAPPLICATIONRESTART,
  982. METADATA_INHERIT,
  983. ASP_MD_UT_APP,
  984. DWORD_METADATA,
  985. dwBufferSize,
  986. &dwState
  987. );
  988. hr = m_pIABase->SetData(
  989. a_hKey,
  990. NULL,
  991. &mdrMDData
  992. );
  993. return hr;
  994. }
  995. //
  996. // CWebAppMethod
  997. //
  998. CWebAppMethod::CWebAppMethod()
  999. {
  1000. HRESULT hr = CoCreateInstance(
  1001. CLSID_WamAdmin,
  1002. NULL,
  1003. CLSCTX_ALL,
  1004. IID_IWamAdmin2,
  1005. (void**)&m_pWamAdmin
  1006. );
  1007. THROW_ON_ERROR(hr);
  1008. }
  1009. CWebAppMethod::~CWebAppMethod()
  1010. {
  1011. if(m_pWamAdmin)
  1012. m_pWamAdmin->Release();
  1013. }
  1014. HRESULT CWebAppMethod::AppCreate(
  1015. LPCWSTR szMetaBasePath,
  1016. bool bInProcFlag
  1017. )
  1018. {
  1019. HRESULT hr;
  1020. hr = m_pWamAdmin->AppCreate(
  1021. szMetaBasePath,
  1022. bInProcFlag);
  1023. return hr;
  1024. }
  1025. HRESULT CWebAppMethod::AppCreate2(
  1026. LPCWSTR szMetaBasePath,
  1027. long lAppMode
  1028. )
  1029. {
  1030. HRESULT hr;
  1031. hr = m_pWamAdmin->AppCreate2(
  1032. szMetaBasePath,
  1033. lAppMode);
  1034. return hr;
  1035. }
  1036. HRESULT CWebAppMethod::AppDelete(
  1037. LPCWSTR szMetaBasePath,
  1038. bool bRecursive
  1039. )
  1040. {
  1041. HRESULT hr;
  1042. hr = m_pWamAdmin->AppDelete(
  1043. szMetaBasePath,
  1044. bRecursive);
  1045. return hr;
  1046. }
  1047. HRESULT CWebAppMethod::AppUnLoad(
  1048. LPCWSTR szMetaBasePath,
  1049. bool bRecursive
  1050. )
  1051. {
  1052. HRESULT hr;
  1053. hr = m_pWamAdmin->AppUnLoad(
  1054. szMetaBasePath,
  1055. bRecursive);
  1056. return hr;
  1057. }
  1058. HRESULT CWebAppMethod::AppDisable(
  1059. LPCWSTR szMetaBasePath,
  1060. bool bRecursive
  1061. )
  1062. {
  1063. HRESULT hr;
  1064. hr = m_pWamAdmin->AppDeleteRecoverable(
  1065. szMetaBasePath,
  1066. bRecursive);
  1067. return hr;
  1068. }
  1069. HRESULT CWebAppMethod::AppEnable(
  1070. LPCWSTR szMetaBasePath,
  1071. bool bRecursive
  1072. )
  1073. {
  1074. HRESULT hr;
  1075. hr = m_pWamAdmin->AppRecover(
  1076. szMetaBasePath,
  1077. bRecursive);
  1078. return hr;
  1079. }
  1080. HRESULT CWebAppMethod::AppGetStatus(
  1081. LPCWSTR szMetaBasePath,
  1082. DWORD* pdwStatus
  1083. )
  1084. {
  1085. HRESULT hr;
  1086. hr = m_pWamAdmin->AppGetStatus(
  1087. szMetaBasePath,
  1088. pdwStatus);
  1089. return hr;
  1090. }
  1091. HRESULT CWebAppMethod::AspAppRestart(
  1092. LPCWSTR a_szMetaBasePath
  1093. )
  1094. {
  1095. HRESULT hr = S_OK;
  1096. DWORD dwState;
  1097. METADATA_HANDLE t_hKey = NULL;
  1098. CMetabase t_mb;
  1099. try
  1100. {
  1101. // open key
  1102. t_hKey = t_mb.OpenKey(a_szMetaBasePath, true);
  1103. // check app
  1104. hr = t_mb.WebAppCheck(t_hKey);
  1105. THROW_ON_ERROR(hr);
  1106. // get state
  1107. hr = t_mb.WebAppGetStatus(t_hKey, &dwState);
  1108. THROW_ON_ERROR(hr);
  1109. // change state value
  1110. dwState = dwState ? 0 : 1;
  1111. hr = t_mb.WebAppSetStatus(t_hKey, dwState);
  1112. THROW_ON_ERROR(hr);
  1113. // re-set back state value
  1114. dwState = dwState ? 0 : 1;
  1115. hr = t_mb.WebAppSetStatus(t_hKey, dwState);
  1116. THROW_ON_ERROR(hr);
  1117. t_mb.CloseKey(t_hKey);
  1118. }
  1119. catch (...)
  1120. {
  1121. t_mb.CloseKey(t_hKey);
  1122. throw;
  1123. };
  1124. return hr;
  1125. }