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.

2069 lines
63 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1997 - 2000.
  5. //
  6. // File: cimbmgr.cxx
  7. //
  8. // Contents: Content Index Meta Base Manager
  9. //
  10. // Classes: CMetaDataMgr
  11. //
  12. // History: 07-Feb-1997 dlee Created
  13. // 24-Apr-1997 dlee Converted to new Unicode interface
  14. //
  15. //----------------------------------------------------------------------------
  16. #include <pch.cxx>
  17. #pragma hdrstop
  18. #include <cimbmgr.hxx>
  19. #define MYDEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
  20. EXTERN_C const GUID name \
  21. = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } }
  22. MYDEFINE_GUID(CLSID_MSAdminBase_W, 0xa9e69610, 0xb80d, 0x11d0, 0xb9, 0xb9, 0x0, 0xa0, 0xc9, 0x22, 0xe7, 0x50);
  23. MYDEFINE_GUID(IID_IMSAdminBase_W, 0x70b51430, 0xb6ca, 0x11d0, 0xb9, 0xb9, 0x0, 0xa0, 0xc9, 0x22, 0xe7, 0x50);
  24. MYDEFINE_GUID(CLSID_MSAdminBaseExe_W, 0xa9e69611, 0xb80d, 0x11d0, 0xb9, 0xb9, 0x0, 0xa0, 0xc9, 0x22, 0xe7, 0x50);
  25. MYDEFINE_GUID(IID_IMSAdminBaseSink_W, 0xa9e69612, 0xb80d, 0x11d0, 0xb9, 0xb9, 0x0, 0xa0, 0xc9, 0x22, 0xe7, 0x50);
  26. //+-------------------------------------------------------------------------
  27. //
  28. // Member: CMetaDataMgr::CMetaDataMgr, public
  29. //
  30. // Synopsis: Creates an object for talking to the IIS metabase.
  31. //
  32. // Arguments: [fTopLevel] - TRUE for the top level, FALSE for a
  33. // vserver instance
  34. // [dwInstance] - instance # of the server
  35. // [eType] - type of vroot provider -- W3, NNTP, or IMAP
  36. // [pwcMachine] - the machine to open, L"." for local machine
  37. //
  38. // History: 07-Feb-1997 dlee Created
  39. //
  40. //--------------------------------------------------------------------------
  41. CMetaDataMgr::CMetaDataMgr(
  42. BOOL fTopLevel,
  43. CiVRootTypeEnum eType,
  44. DWORD dwInstance,
  45. WCHAR const * pwcMachine ) :
  46. _fNotifyEnabled( FALSE ),
  47. _fTopLevel( fTopLevel )
  48. {
  49. // -1 is a valid instance number, so this is a bogus assert, but it'll
  50. // never be hit unless something else is broken or someone hacked the
  51. // registry.
  52. #if CIDBG == 1
  53. if ( fTopLevel )
  54. Win4Assert( 0xffffffff == dwInstance );
  55. else
  56. Win4Assert( 0xffffffff != dwInstance );
  57. #endif // CIDBG == 1
  58. if ( fTopLevel )
  59. swprintf( _awcInstance, L"/lm/%ws", GetVRootService( eType ) );
  60. else
  61. swprintf( _awcInstance,
  62. L"/lm/%ws/%d",
  63. GetVRootService( eType ),
  64. dwInstance );
  65. IMSAdminBase * pcAdmCom;
  66. if ( !_wcsicmp( pwcMachine, L"." ) )
  67. {
  68. SCODE sc = CoCreateInstance( GETAdminBaseCLSID(TRUE),
  69. NULL,
  70. CLSCTX_ALL,
  71. IID_IMSAdminBase,
  72. (void **) &pcAdmCom );
  73. if ( FAILED(sc) )
  74. {
  75. ciDebugOut(( DEB_WARN, "CMetaDataMgr can't CoCreateInstance: %x\n", sc ));
  76. THROW( CException(sc) );
  77. }
  78. }
  79. else
  80. {
  81. COSERVERINFO info;
  82. RtlZeroMemory( &info, sizeof info );
  83. info.pwszName = (WCHAR *) pwcMachine;
  84. XInterface<IClassFactory> xFactory;
  85. SCODE sc = CoGetClassObject( GETAdminBaseCLSID(TRUE),
  86. CLSCTX_SERVER,
  87. &info,
  88. IID_IClassFactory,
  89. xFactory.GetQIPointer() );
  90. if ( FAILED(sc) )
  91. {
  92. ciDebugOut(( DEB_WARN, "CMetaDataMgr can't CoGetClassObject: %x\n", sc ));
  93. THROW( CException(sc) );
  94. }
  95. sc = xFactory->CreateInstance( 0, IID_IMSAdminBase, (void**) &pcAdmCom );
  96. if ( FAILED(sc) )
  97. {
  98. ciDebugOut(( DEB_WARN, "CMetaDataMgr can't CreateInstance: %x\n", sc ));
  99. THROW( CException(sc) );
  100. }
  101. }
  102. _xAdminBase.Set( pcAdmCom );
  103. } //CMetaDataMgr
  104. //+-------------------------------------------------------------------------
  105. //
  106. // Member: CMetaDataMgr::~CMetaDataMgr, public
  107. //
  108. // Synopsis: Destroys an object for talking to the IIS metabase
  109. //
  110. // History: 07-Feb-1997 dlee Created
  111. //
  112. //--------------------------------------------------------------------------
  113. CMetaDataMgr::~CMetaDataMgr()
  114. {
  115. if ( !_xAdminBase.IsNull() )
  116. {
  117. // just in case we are still connected
  118. DisableVPathNotify();
  119. }
  120. } //~CMetaDataMgr
  121. //+-------------------------------------------------------------------------
  122. //
  123. // Member: CMetaDataMgr::IsIISAdminUp, public/static
  124. //
  125. // Synopsis: Returns TRUE if iisadmin svc is up
  126. //
  127. // Arguments: [fIISAdminInstalled] - returns TRUE if it's installed,
  128. // FALSE otherwise
  129. //
  130. // History: 07-Feb-1997 dlee Created
  131. //
  132. //--------------------------------------------------------------------------
  133. BOOL CMetaDataMgr::IsIISAdminUp(
  134. BOOL & fIISAdminInstalled )
  135. {
  136. fIISAdminInstalled = TRUE;
  137. BOOL fIsUp = TRUE;
  138. TRY
  139. {
  140. // The constructor will throw if the iisadmin svc is unavailable.
  141. CMetaDataMgr( TRUE, W3VRoot );
  142. }
  143. CATCH( CException, e )
  144. {
  145. fIsUp = FALSE;
  146. if ( REGDB_E_CLASSNOTREG == e.GetErrorCode() )
  147. fIISAdminInstalled = FALSE;
  148. }
  149. END_CATCH
  150. return fIsUp;
  151. } //IsIISAdminUp
  152. //+-------------------------------------------------------------------------
  153. //
  154. // Member: CMetaDataMgr::EnumVPaths, public
  155. //
  156. // Synopsis: Enumerates vpaths by calling the callback
  157. //
  158. // Arguments: [callBack] - called for each vpath
  159. //
  160. // History: 07-Feb-1997 dlee Created
  161. //
  162. //--------------------------------------------------------------------------
  163. void CMetaDataMgr::EnumVPaths(
  164. CMetaDataCallBack & callBack )
  165. {
  166. Win4Assert( !_fTopLevel );
  167. CMetaDataHandle mdRoot( _xAdminBase, _awcInstance );
  168. CVRootStack vrootStack;
  169. Enum( vrootStack, callBack, mdRoot, L"" );
  170. } //EnumVPaths
  171. //+-------------------------------------------------------------------------
  172. //
  173. // Member: CMetaDataMgr::AddVRoot, public
  174. //
  175. // Synopsis: Adds a VRoot to the metabase
  176. //
  177. // Arguments: [pwcVRoot] - name of the vroot, e.g.: /here
  178. // [pwcPRoot] - physical path of the vroot, e.g.: x:\here
  179. // [dwAccess] - access rights to the vroot
  180. //
  181. // History: 07-Feb-1997 dlee Created
  182. //
  183. //--------------------------------------------------------------------------
  184. void CMetaDataMgr::AddVRoot(
  185. WCHAR const * pwcVRoot,
  186. WCHAR const * pwcPRoot,
  187. DWORD dwAccess )
  188. {
  189. Win4Assert( !_fTopLevel );
  190. // blow it away if it currently exists
  191. RemoveVRoot( pwcVRoot );
  192. {
  193. unsigned cwc = wcslen( _awcInstance ) + wcslen( L"/Root" );
  194. if ( cwc >= METADATA_MAX_NAME_LEN )
  195. THROW( CException( E_INVALIDARG ) );
  196. WCHAR awc[ METADATA_MAX_NAME_LEN ];
  197. wcscpy( awc, _awcInstance );
  198. wcscat( awc, L"/Root" );
  199. CMetaDataHandle mdRoot( _xAdminBase, awc, TRUE );
  200. _xAdminBase->AddKey( mdRoot.Get(), pwcVRoot );
  201. }
  202. WCHAR awcVRootPath[ METADATA_MAX_NAME_LEN ];
  203. unsigned cwc = wcslen( _awcInstance ) + wcslen( L"/Root" ) + wcslen( pwcVRoot );
  204. if ( cwc >= METADATA_MAX_NAME_LEN )
  205. THROW( CException( E_INVALIDARG ) );
  206. wcscpy( awcVRootPath, _awcInstance );
  207. wcscat( awcVRootPath, L"/Root" );
  208. wcscat( awcVRootPath, pwcVRoot );
  209. CMetaDataHandle mdVRoot( _xAdminBase, awcVRootPath, TRUE );
  210. {
  211. METADATA_RECORD mdr;
  212. RtlZeroMemory( &mdr, sizeof mdr );
  213. mdr.dwMDIdentifier = MD_VR_PATH;
  214. mdr.dwMDAttributes = METADATA_INHERIT;
  215. mdr.dwMDUserType = IIS_MD_UT_FILE;
  216. mdr.dwMDDataType = STRING_METADATA;
  217. mdr.pbMDData = (BYTE *) pwcPRoot;
  218. mdr.dwMDDataLen = sizeof WCHAR * ( 1 + wcslen( pwcPRoot ) );
  219. DWORD cbRequired = 0;
  220. SCODE sc = _xAdminBase->SetData( mdVRoot.Get(),
  221. L"",
  222. &mdr );
  223. if ( FAILED( sc ) )
  224. {
  225. ciDebugOut(( DEB_WARN, "SetData PRoot failed: 0x%x\n", sc ));
  226. THROW( CException( sc ) );
  227. }
  228. }
  229. {
  230. // must set a null username to enforce metadata consistency
  231. METADATA_RECORD mdr;
  232. RtlZeroMemory( &mdr, sizeof mdr );
  233. mdr.dwMDIdentifier = MD_VR_USERNAME;
  234. mdr.dwMDAttributes = METADATA_INHERIT;
  235. mdr.dwMDUserType = IIS_MD_UT_SERVER;
  236. mdr.dwMDDataType = STRING_METADATA;
  237. mdr.pbMDData = (BYTE *) L"";
  238. mdr.dwMDDataLen = sizeof WCHAR;
  239. DWORD cbRequired = 0;
  240. SCODE sc = _xAdminBase->SetData( mdVRoot.Get(),
  241. L"",
  242. &mdr );
  243. if ( FAILED( sc ) )
  244. {
  245. ciDebugOut(( DEB_WARN, "SetData user failed: 0x%x\n", sc ));
  246. THROW( CException( sc ) );
  247. }
  248. }
  249. {
  250. METADATA_RECORD mdr;
  251. RtlZeroMemory( &mdr, sizeof mdr );
  252. mdr.dwMDIdentifier = MD_ACCESS_PERM;
  253. mdr.dwMDAttributes = METADATA_INHERIT;
  254. mdr.dwMDUserType = IIS_MD_UT_FILE;
  255. mdr.dwMDDataType = DWORD_METADATA;
  256. mdr.pbMDData = (BYTE *) &dwAccess;
  257. mdr.dwMDDataLen = sizeof dwAccess;
  258. DWORD cbRequired = 0;
  259. SCODE sc = _xAdminBase->SetData( mdVRoot.Get(),
  260. L"",
  261. &mdr );
  262. if ( FAILED( sc ) )
  263. {
  264. ciDebugOut(( DEB_WARN, "SetData accessperm failed: 0x%x\n", sc ));
  265. THROW( CException( sc ) );
  266. }
  267. }
  268. } //AddVRoot
  269. //+-------------------------------------------------------------------------
  270. //
  271. // Member: CMetaDataMgr::Flush, public
  272. //
  273. // Synopsis: Flushes the metabase, since it's not robust.
  274. //
  275. // History: 4-Dec-1998 dlee Created
  276. //
  277. //--------------------------------------------------------------------------
  278. void CMetaDataMgr::Flush()
  279. {
  280. SCODE sc = _xAdminBase->SaveData();
  281. if ( FAILED( sc ) )
  282. {
  283. ciDebugOut(( DEB_WARN, "CMetaDataMgr::Flush failed: %#x\n", sc ));
  284. THROW( CException( sc ) );
  285. }
  286. } //Flush
  287. //+-------------------------------------------------------------------------
  288. //
  289. // Member: CMetaDataMgr::RemoveVRoot, public
  290. //
  291. // Synopsis: Removes a VRoot from the metabase
  292. //
  293. // Arguments: [pwcVRoot] - name of the vroot. e.g.: /scripts
  294. //
  295. // Notes: Doesn't throw on failure to remove the root.
  296. //
  297. // History: 07-Feb-1997 dlee Created
  298. //
  299. //--------------------------------------------------------------------------
  300. SCODE CMetaDataMgr::RemoveVRoot(
  301. WCHAR const * pwcVRoot )
  302. {
  303. Win4Assert( !_fTopLevel );
  304. unsigned cwc = wcslen( _awcInstance ) + wcslen( L"/Root" );
  305. if ( cwc >= METADATA_MAX_NAME_LEN )
  306. THROW( CException( E_INVALIDARG ) );
  307. WCHAR awcRoot[ METADATA_MAX_NAME_LEN ];
  308. wcscpy( awcRoot, _awcInstance );
  309. wcscat( awcRoot, L"/Root" );
  310. CMetaDataHandle mdRoot( _xAdminBase, awcRoot, TRUE );
  311. // don't throw on error deleting vroot -- the root may not exist
  312. return _xAdminBase->DeleteKey( mdRoot.Get(), pwcVRoot );
  313. } //RemoveVRoot
  314. //+-------------------------------------------------------------------------
  315. //
  316. // Member: CMetaDataMgr::WriteRootValue, private
  317. //
  318. // Synopsis: Retrieves data for the key and identifier
  319. //
  320. // Arguments: [mdRoot] - Metabase key where data reside
  321. // [mdr] - Scratch pad for the record. On output, can be
  322. // used to write the data, since all the
  323. // fields are initialized properly.
  324. // [xData] - Where data is written
  325. // [dwIdentifier] - The metabase id
  326. //
  327. // History: 24-Feb-1998 dlee Created
  328. //
  329. //--------------------------------------------------------------------------
  330. void CMetaDataMgr::ReadRootValue(
  331. CMetaDataHandle & mdRoot,
  332. METADATA_RECORD & mdr,
  333. XGrowable<WCHAR> & xData,
  334. DWORD dwIdentifier )
  335. {
  336. RtlZeroMemory( &mdr, sizeof mdr );
  337. mdr.dwMDIdentifier = dwIdentifier;
  338. // script maps, etc. can be enormous due to bugs in ISV apps
  339. do
  340. {
  341. mdr.pbMDData = (BYTE *) xData.Get();
  342. mdr.dwMDDataLen = xData.SizeOf();
  343. DWORD cbRequired = 0;
  344. SCODE sc = _xAdminBase->GetData( mdRoot.Get(),
  345. L"",
  346. &mdr,
  347. &cbRequired );
  348. if ( HRESULT_FROM_WIN32( ERROR_INSUFFICIENT_BUFFER ) == sc )
  349. {
  350. xData.SetSizeInBytes( cbRequired );
  351. continue;
  352. }
  353. else if ( FAILED( sc ) )
  354. {
  355. ciDebugOut(( DEB_WARN, "GetData root value failed: 0x%x\n", sc ));
  356. THROW( CException( sc ) );
  357. }
  358. break;
  359. } while ( TRUE );
  360. } //ReadRootValue
  361. //+-------------------------------------------------------------------------
  362. //
  363. // Member: CMetaDataMgr::WriteRootValue, private
  364. //
  365. // Synopsis: Writes data to the key
  366. //
  367. // Arguments: [mdRoot] - Metabase key where data resides
  368. // [mdr] - Metadata record suitable for writing data
  369. // [pwcData] - Multi-sz string with data
  370. // [cwcData] - Total length including all terminating nulls
  371. //
  372. // History: 24-Feb-1998 dlee Created
  373. //
  374. //--------------------------------------------------------------------------
  375. void CMetaDataMgr::WriteRootValue(
  376. CMetaDataHandle & mdRoot,
  377. METADATA_RECORD & mdr,
  378. WCHAR const * pwcData,
  379. unsigned cwcData )
  380. {
  381. // note: the other fields in mdr were initialized properly by a call
  382. // to ReadRootValue.
  383. mdr.dwMDDataLen = sizeof WCHAR * cwcData;
  384. mdr.pbMDData = (BYTE *) pwcData;
  385. SCODE sc = _xAdminBase->SetData( mdRoot.Get(),
  386. L"",
  387. &mdr );
  388. if ( FAILED( sc ) )
  389. {
  390. ciDebugOut(( DEB_WARN, "SetData root value failed: 0x%x\n", sc ));
  391. THROW( CException( sc ) );
  392. }
  393. } //WriteRootValue
  394. //+-------------------------------------------------------------------------
  395. //
  396. // Member: CMetaDataMgr::AddApplicationDependency, public
  397. //
  398. // Synopsis: Adds an entry to the application dependency list
  399. //
  400. // Arguments: [pwcApp] - The entry to add, like this:
  401. // "Indexing Service;IndexingService"
  402. //
  403. // History: 01-Jun-2002 dlee Created
  404. //
  405. //--------------------------------------------------------------------------
  406. void CMetaDataMgr::AddApplicationDependency( WCHAR const * pwcApp )
  407. {
  408. CMetaDataHandle mdRoot( _xAdminBase, L"/lm/w3svc", TRUE );
  409. XGrowable<WCHAR> xApps;
  410. METADATA_RECORD mdr;
  411. ReadRootValue( mdRoot, mdr, xApps, MD_APP_DEPENDENCIES );
  412. // add the new entry to the existing ones
  413. XGrowable<WCHAR> xTemp;
  414. xTemp.SetSize( xApps.Count() + wcslen( pwcApp ) + 1 );
  415. WCHAR *pwcTemp = xTemp.Get();
  416. wcscpy( pwcTemp, pwcApp );
  417. pwcTemp += ( 1 + wcslen( pwcTemp ) );
  418. WCHAR * pwcOldApps = xApps.Get();
  419. while ( 0 != *pwcOldApps )
  420. {
  421. wcscpy( pwcTemp, pwcOldApps );
  422. int x = 1 + wcslen( pwcOldApps );
  423. pwcTemp += x;
  424. pwcOldApps += x;
  425. }
  426. *pwcTemp++ = 0;
  427. // write the new set of apps
  428. WriteRootValue( mdRoot, mdr, xTemp.Get(), (UINT)( pwcTemp - xTemp.Get() ) );
  429. } //AddApplicationDependency
  430. //+-------------------------------------------------------------------------
  431. //
  432. // Member: CMetaDataMgr::AddRestrictionList, public
  433. //
  434. // Synopsis: Adds an entry to the restriction list.
  435. //
  436. // Arguments: [pwcRestriction] - The entry to add, like this:
  437. // "0,c:\windows\system32\webhits.dll,0,IndexingService,Indexing Service"
  438. //
  439. // History: 01-Jun-2002 dlee Created
  440. //
  441. //--------------------------------------------------------------------------
  442. void CMetaDataMgr::AddRestrictionList( WCHAR const * pwcRestriction )
  443. {
  444. CMetaDataHandle mdRoot( _xAdminBase, L"/lm/w3svc", TRUE );
  445. XGrowable<WCHAR> xList;
  446. METADATA_RECORD mdr;
  447. ReadRootValue( mdRoot, mdr, xList, MD_WEB_SVC_EXT_RESTRICTION_LIST );
  448. // add the new entry to the existing ones
  449. XGrowable<WCHAR> xTemp;
  450. xTemp.SetSize( xList.Count() + wcslen( pwcRestriction ) + 1 );
  451. WCHAR *pwcTemp = xTemp.Get();
  452. wcscpy( pwcTemp, pwcRestriction );
  453. pwcTemp += ( 1 + wcslen( pwcTemp ) );
  454. WCHAR * pwcOldEntries = xList.Get();
  455. while ( 0 != *pwcOldEntries )
  456. {
  457. wcscpy( pwcTemp, pwcOldEntries );
  458. int x = 1 + wcslen( pwcOldEntries );
  459. pwcTemp += x;
  460. pwcOldEntries += x;
  461. }
  462. *pwcTemp++ = 0;
  463. // write the new set of restrictions
  464. WriteRootValue( mdRoot, mdr, xTemp.Get(), (UINT)( pwcTemp - xTemp.Get() ) );
  465. } //AddRestrictionList
  466. //+-------------------------------------------------------------------------
  467. //
  468. // Member: CMetaDataMgr::RemoveApplicationDependency, public
  469. //
  470. // Synopsis: Removes an entry from the application dependency list
  471. //
  472. // Arguments: [pwcKey] - Name of the key. e.g.
  473. // "IndexingService"
  474. // for entry like this one:
  475. // "Indexing Service;IndexingService"
  476. //
  477. // History: 01-Jun-2002 dlee Created
  478. //
  479. //--------------------------------------------------------------------------
  480. void CMetaDataMgr::RemoveApplicationDependency( WCHAR const * pwcKey )
  481. {
  482. // retrieve the existing apps
  483. CMetaDataHandle mdRoot( _xAdminBase, L"/lm/w3svc", TRUE );
  484. XGrowable<WCHAR> xApps;
  485. METADATA_RECORD mdr;
  486. ReadRootValue( mdRoot, mdr, xApps, MD_APP_DEPENDENCIES );
  487. // awcApps is a multi-sz string
  488. XGrowable<WCHAR> xNew( xApps.Count() );
  489. WCHAR *pwcNew = xNew.Get();
  490. pwcNew[0] = 0;
  491. BOOL fFound = FALSE;
  492. // re-add all Apps other than those containing pwcKey
  493. WCHAR const *pwcCur = xApps.Get();
  494. while ( 0 != *pwcCur )
  495. {
  496. // if we didn't find the key, copy what we did find.
  497. WCHAR const * pwcSemi = wcschr( pwcCur, L';' );
  498. if ( ( 0 == pwcSemi ) ||
  499. ( 0 != wcscmp( pwcSemi + 1, pwcKey ) ) )
  500. {
  501. wcscpy( pwcNew, pwcCur );
  502. pwcNew += ( 1 + wcslen( pwcNew ) );
  503. }
  504. else
  505. {
  506. fFound = TRUE;
  507. }
  508. int cwc = wcslen( pwcCur );
  509. pwcCur += ( cwc + 1 );
  510. }
  511. // If the key wasn't found, don't do the write
  512. if ( !fFound )
  513. return;
  514. *pwcNew++ = 0;
  515. // got the string, now pound it in the metabase
  516. WriteRootValue( mdRoot, mdr, xNew.Get(), (UINT)(pwcNew - xNew.Get()) );
  517. } //RemoveApplicationDependency
  518. //+-------------------------------------------------------------------------
  519. //
  520. // Member: CMetaDataMgr::RemoveRestrictionList, public
  521. //
  522. // Synopsis: Removes entries from the restriction list that references
  523. // the application specified.
  524. //
  525. // Arguments: [pwcKey] - Name of the key. e.g.
  526. // "IndexingService"
  527. // for entries like:
  528. // "0,c:\windows\system32\idq.dll,0,IndexingService,Indexing Service"
  529. // "0,c:\windows\system32\webhits.dll,0,IndexingService,Indexing Service"
  530. //
  531. // History: 01-Jun-2002 dlee Created
  532. //
  533. //--------------------------------------------------------------------------
  534. void CMetaDataMgr::RemoveRestrictionList( WCHAR const * pwcKey )
  535. {
  536. // retrieve the existing apps
  537. CMetaDataHandle mdRoot( _xAdminBase, L"/lm/w3svc", TRUE );
  538. XGrowable<WCHAR> xList;
  539. METADATA_RECORD mdr;
  540. ReadRootValue( mdRoot, mdr, xList, MD_WEB_SVC_EXT_RESTRICTION_LIST );
  541. // awcApps is a multi-sz string
  542. XGrowable<WCHAR> xNew( xList.Count() );
  543. WCHAR *pwcNew = xNew.Get();
  544. pwcNew[0] = 0;
  545. int cwcKey = wcslen( pwcKey );
  546. BOOL fFound = FALSE;
  547. // re-add all Entries other than those containing pwcKey
  548. WCHAR const *pwcCur = xList.Get();
  549. while ( 0 != *pwcCur )
  550. {
  551. // if we didn't find the key, then copy the entry
  552. WCHAR const * pwcFound = wcsstr( pwcCur, pwcKey );
  553. if ( ( 0 == pwcFound ) ||
  554. ( pwcFound == pwcCur ) ||
  555. ( L',' != * ( pwcFound - 1 ) ) ||
  556. ( L',' != pwcFound[ cwcKey ] ) )
  557. {
  558. wcscpy( pwcNew, pwcCur );
  559. pwcNew += ( 1 + wcslen( pwcNew ) );
  560. }
  561. else
  562. {
  563. fFound = TRUE;
  564. }
  565. int cwc = wcslen( pwcCur );
  566. pwcCur += ( cwc + 1 );
  567. }
  568. // If the key wasn't found, don't do the write
  569. if ( !fFound )
  570. return;
  571. *pwcNew++ = 0;
  572. // got the string, now pound it in the metabase
  573. WriteRootValue( mdRoot, mdr, xNew.Get(), (UINT)(pwcNew - xNew.Get()) );
  574. } //RemoveRestrictionList
  575. //+-------------------------------------------------------------------------
  576. //
  577. // Member: CMetaDataMgr::AddScriptMap, public
  578. //
  579. // Synopsis: Adds a script map to the metabase
  580. //
  581. // Arguments: [pwcMap] - script map of the form:
  582. // L".idq,d:\\winnt\\system32\\idq.dll,0"
  583. //
  584. // History: 07-Feb-1997 dlee Created
  585. //
  586. //--------------------------------------------------------------------------
  587. void CMetaDataMgr::AddScriptMap(
  588. WCHAR const * pwcMap )
  589. {
  590. // remove the existing script map if it exists. have to get the
  591. // extension first.
  592. if ( wcslen( pwcMap ) > MAX_PATH )
  593. THROW( CException( HRESULT_FROM_WIN32( ERROR_INVALID_PARAMETER ) ) );
  594. WCHAR awcExt[ MAX_PATH ];
  595. wcscpy( awcExt, pwcMap );
  596. WCHAR *pwc = wcschr( awcExt, L',' );
  597. if ( !pwc )
  598. THROW( CException( HRESULT_FROM_WIN32( ERROR_INVALID_PARAMETER ) ) );
  599. *pwc = 0;
  600. RemoveScriptMap( awcExt );
  601. CMetaDataHandle mdRoot( _xAdminBase, L"/lm/w3svc", TRUE );
  602. XGrowable<WCHAR> xMaps;
  603. METADATA_RECORD mdr;
  604. ReadRootValue( mdRoot, mdr, xMaps, MD_SCRIPT_MAPS );
  605. // add the new script map to the existing ones
  606. XGrowable<WCHAR> xTemp;
  607. xTemp.SetSize( xMaps.Count() + wcslen( pwcMap ) + 1 );
  608. WCHAR *pwcTemp = xTemp.Get();
  609. wcscpy( pwcTemp, pwcMap );
  610. pwcTemp += ( 1 + wcslen( pwcTemp ) );
  611. WCHAR * pwcOldMaps = xMaps.Get();
  612. while ( 0 != *pwcOldMaps )
  613. {
  614. wcscpy( pwcTemp, pwcOldMaps );
  615. int x = 1 + wcslen( pwcOldMaps );
  616. pwcTemp += x;
  617. pwcOldMaps += x;
  618. }
  619. *pwcTemp++ = 0;
  620. // write the new set of script maps
  621. WriteRootValue( mdRoot, mdr, xTemp.Get(), (UINT)( pwcTemp - xTemp.Get() ) );
  622. } //AddScriptMap
  623. //+-------------------------------------------------------------------------
  624. //
  625. // Member: CMetaDataMgr::RemoveScriptMap, public
  626. //
  627. // Synopsis: Removes a script map from the metabase
  628. //
  629. // Arguments: [pwcExt] - extension of map to remove: L".idq"
  630. //
  631. // History: 07-Feb-1997 dlee Created
  632. //
  633. //--------------------------------------------------------------------------
  634. void CMetaDataMgr::RemoveScriptMap(
  635. WCHAR const * pwcExt )
  636. {
  637. // retrieve the existing script maps
  638. CMetaDataHandle mdRoot( _xAdminBase, L"/lm/w3svc", TRUE );
  639. XGrowable<WCHAR> xMaps;
  640. METADATA_RECORD mdr;
  641. ReadRootValue( mdRoot, mdr, xMaps, MD_SCRIPT_MAPS );
  642. // awcMaps is a multi-sz string
  643. XGrowable<WCHAR> xNew( xMaps.Count() );
  644. WCHAR *pwcNew = xNew.Get();
  645. pwcNew[0] = 0;
  646. int cwcExt = wcslen( pwcExt );
  647. BOOL fFound = FALSE;
  648. // re-add all mappings other than pwcExt
  649. WCHAR const *pwcCur = xMaps.Get();
  650. while ( 0 != *pwcCur )
  651. {
  652. if ( _wcsnicmp( pwcCur, pwcExt, cwcExt ) ||
  653. L',' != pwcCur[cwcExt] )
  654. {
  655. wcscpy( pwcNew, pwcCur );
  656. pwcNew += ( 1 + wcslen( pwcNew ) );
  657. }
  658. else
  659. {
  660. fFound = TRUE;
  661. }
  662. int cwc = wcslen( pwcCur );
  663. pwcCur += ( cwc + 1 );
  664. }
  665. // If the script map wasn't found, don't do the write
  666. if ( !fFound )
  667. return;
  668. *pwcNew++ = 0;
  669. // got the string, now pound it in the metabase
  670. WriteRootValue( mdRoot, mdr, xNew.Get(), (UINT)(pwcNew - xNew.Get()) );
  671. } //RemoveScriptMap
  672. //+-------------------------------------------------------------------------
  673. //
  674. // Member: CMetaDataMgr::ExtensionHasScriptMap, public
  675. //
  676. // Synopsis: Finds a script map in the metabase
  677. //
  678. // Arguments: [pwcExt] - extension of map to lookup: L".idq"
  679. //
  680. // Returns: TRUE if the extension has a script map association
  681. // FALSE otherwise
  682. //
  683. // History: 10-Jul-1997 dlee Created
  684. //
  685. //--------------------------------------------------------------------------
  686. BOOL CMetaDataMgr::ExtensionHasScriptMap(
  687. WCHAR const * pwcExt )
  688. {
  689. CMetaDataHandle mdRoot( _xAdminBase, L"/lm/w3svc", FALSE );
  690. XGrowable<WCHAR> xMaps;
  691. METADATA_RECORD mdr;
  692. ReadRootValue( mdRoot, mdr, xMaps, MD_SCRIPT_MAPS );
  693. // xMaps is a multi-sz string, look for pwcExt
  694. int cwcExt = wcslen( pwcExt );
  695. WCHAR *pwcCur = xMaps.Get();
  696. while ( 0 != *pwcCur )
  697. {
  698. if ( !_wcsnicmp( pwcCur, pwcExt, cwcExt ) &&
  699. L',' == pwcCur[cwcExt] )
  700. return TRUE;
  701. int cwc = wcslen( pwcCur );
  702. pwcCur += ( cwc + 1 );
  703. }
  704. return FALSE;
  705. } //ExtensionHasScriptMap
  706. //+-------------------------------------------------------------------------
  707. //
  708. // Member: CMetaDataMgr::ExtensionHasTargetScriptMap, public
  709. //
  710. // Synopsis: Sees if a scriptmap is pointing at a given dll
  711. //
  712. // Arguments: [pwcExt] - extension of map to lookup: L".idq"
  713. // [pwcDll] - DLL to check, e.g. L"idq.dll"
  714. //
  715. // Returns: TRUE if the extension has a script map association
  716. // FALSE otherwise
  717. //
  718. // History: 10-Jul-1997 dlee Created
  719. //
  720. // Note: scriptmaps look like ".idq,c:\\windows\\system32\\idq.dll,3,GET,HEAD,POST"
  721. //
  722. //--------------------------------------------------------------------------
  723. BOOL CMetaDataMgr::ExtensionHasTargetScriptMap(
  724. WCHAR const * pwcExt,
  725. WCHAR const * pwcDll )
  726. {
  727. CMetaDataHandle mdRoot( _xAdminBase, L"/lm/w3svc", FALSE );
  728. XGrowable<WCHAR> xMaps;
  729. METADATA_RECORD mdr;
  730. ReadRootValue( mdRoot, mdr, xMaps, MD_SCRIPT_MAPS );
  731. // xMaps is a multi-sz string, look for pwcExt
  732. int cwcExt = wcslen( pwcExt );
  733. WCHAR *pwcCur = xMaps.Get();
  734. int cwcDll = wcslen( pwcDll );
  735. while ( 0 != *pwcCur )
  736. {
  737. if ( !_wcsnicmp( pwcCur, pwcExt, cwcExt ) &&
  738. L',' == pwcCur[cwcExt] )
  739. {
  740. // Skip to the end of the full path and check the dll name
  741. WCHAR const * pwcSlash = wcsrchr( pwcCur, L'\\' );
  742. if ( 0 != pwcSlash )
  743. {
  744. if ( !_wcsnicmp( pwcSlash + 1, pwcDll, cwcDll ) )
  745. return TRUE;
  746. }
  747. }
  748. int cwc = wcslen( pwcCur );
  749. pwcCur += ( cwc + 1 );
  750. }
  751. return FALSE;
  752. } //ExtensionHasTargetScriptMap
  753. //+-------------------------------------------------------------------------
  754. //
  755. // Member: CMetaDataMgr::AddInProcessApp, public
  756. //
  757. // Synopsis: Adds an app to the list of in-process apps
  758. //
  759. // Arguments: [pwcApp] - App in the form "d:\\winnt\\system32\\idq.dll"
  760. //
  761. // History: 09-Dec-1998 dlee Created
  762. //
  763. //--------------------------------------------------------------------------
  764. void CMetaDataMgr::AddInProcessIsapiApp( WCHAR const * pwcApp )
  765. {
  766. //
  767. // Read the existing multi-sz value
  768. //
  769. CMetaDataHandle mdRoot( _xAdminBase, L"/lm/w3svc", TRUE );
  770. XGrowable<WCHAR> xApps;
  771. METADATA_RECORD mdr;
  772. ReadRootValue( mdRoot, mdr, xApps, MD_IN_PROCESS_ISAPI_APPS );
  773. WCHAR *pwcCur = xApps.Get();
  774. //
  775. // Look for an existing entry so a duplicate isn't added
  776. //
  777. while ( 0 != *pwcCur )
  778. {
  779. //
  780. // If it's already there, leave it alone
  781. //
  782. if ( !_wcsicmp( pwcCur, pwcApp ) )
  783. return;
  784. int cwc = wcslen( pwcCur );
  785. pwcCur += ( cwc + 1 );
  786. }
  787. unsigned cwcOld = 1 + (unsigned) ( pwcCur - xApps.Get() );
  788. //
  789. // It wasn't found, so add it
  790. //
  791. unsigned cwc = wcslen( pwcApp ) + 1;
  792. XGrowable<WCHAR> xNew( cwcOld + cwc );
  793. RtlCopyMemory( xNew.Get(), pwcApp, cwc * sizeof WCHAR );
  794. RtlCopyMemory( xNew.Get() + cwc, xApps.Get(), cwcOld * sizeof WCHAR );
  795. WriteRootValue( mdRoot, mdr, xNew.Get(), cwcOld + cwc );
  796. } //AddInProcessIsapiApp
  797. //+-------------------------------------------------------------------------
  798. //
  799. // Member: CMetaDataMgr::EnableVPathNotify, public
  800. //
  801. // Synopsis: Enables notification of vpaths
  802. //
  803. // Arguments: [pCallBack] - called on a change to any vpaths
  804. //
  805. // History: 07-Feb-1997 dlee Created
  806. //
  807. //--------------------------------------------------------------------------
  808. void CMetaDataMgr::EnableVPathNotify(
  809. CMetaDataVPathChangeCallBack *pCallBack )
  810. {
  811. Win4Assert( !_fTopLevel );
  812. Win4Assert( !_fNotifyEnabled );
  813. if ( _fNotifyEnabled )
  814. THROW( CException( HRESULT_FROM_WIN32( ERROR_INVALID_PARAMETER ) ) );
  815. ciDebugOut(( DEB_WARN,
  816. "enabling vpath notifications on '%ws'\n",
  817. _awcInstance ));
  818. Win4Assert( _xSink.IsNull() );
  819. //
  820. // NOTE: This new will be reported as a leak if iisamin dies or fails
  821. // to call Release() on the sink the right number of times.
  822. //
  823. XInterface<CMetaDataComSink> xSink( new CMetaDataComSink() );
  824. xSink->SetCallBack( pCallBack );
  825. xSink->SetInstance( _awcInstance );
  826. XInterface< IConnectionPointContainer > xCPC;
  827. SCODE sc = _xAdminBase->QueryInterface( IID_IConnectionPointContainer,
  828. xCPC.GetQIPointer() );
  829. if ( FAILED( sc ) )
  830. {
  831. ciDebugOut(( DEB_WARN, "could not get cpc: 0x%x\n", sc ));
  832. THROW( CException( sc ) );
  833. }
  834. XInterface< IConnectionPoint> xCP;
  835. sc = xCPC->FindConnectionPoint( IID_IMSAdminBaseSink, xCP.GetPPointer() );
  836. if ( FAILED( sc ) )
  837. {
  838. ciDebugOut(( DEB_WARN, "could not get cp: 0x%x\n", sc ));
  839. THROW( CException( sc ) );
  840. }
  841. //
  842. // Tell COM to impersonate at IMPERSONATE level instead of the default
  843. // IDENTITY level. This is to work-around a change made in IIS in
  844. // Windows 2000 SP1.
  845. //
  846. sc = CoSetProxyBlanket( xCP.GetPointer(),
  847. RPC_C_AUTHN_WINNT, // use NT default security
  848. RPC_C_AUTHZ_NONE, // use NT default authentication
  849. NULL, // must be null if default
  850. RPC_C_AUTHN_LEVEL_CALL, // call
  851. RPC_C_IMP_LEVEL_IMPERSONATE,
  852. NULL, // use process token
  853. EOAC_STATIC_CLOAKING );
  854. if ( FAILED( sc ) )
  855. {
  856. ciDebugOut(( DEB_WARN, "could not set proxy blanket: %#x\n", sc ));
  857. THROW( CException( sc ) );
  858. }
  859. sc = xCP->Advise( xSink.GetPointer(), &_dwCookie);
  860. if ( FAILED( sc ) )
  861. {
  862. ciDebugOut(( DEB_WARN, "could not advise cp: 0x%x\n", sc ));
  863. THROW( CException( sc ) );
  864. }
  865. _xCP.Set( xCP.Acquire() );
  866. _xSink.Set( xSink.Acquire() );
  867. _fNotifyEnabled = TRUE;
  868. } //EnableVPathNotify
  869. //+-------------------------------------------------------------------------
  870. //
  871. // Member: CMetaDataMgr::DisableVPathNotify, public
  872. //
  873. // Synopsis: Disables notification on VPaths
  874. //
  875. // History: 07-Feb-1997 dlee Created
  876. //
  877. //--------------------------------------------------------------------------
  878. void CMetaDataMgr::DisableVPathNotify()
  879. {
  880. if ( _fNotifyEnabled )
  881. {
  882. SCODE sc = _xCP->Unadvise( _dwCookie );
  883. ciDebugOut(( DEB_ITRACE, "result of unadvise: 0x%x\n", sc ));
  884. _fNotifyEnabled = FALSE;
  885. //
  886. // Note: The sink may still have a refcount after the free if
  887. // iisadmin has a bug or their process died. We can't just
  888. // delete it here because CoUninitialize() will realize
  889. // iisadmin messed up and try to help by calling Release()
  890. // for iisadmin.
  891. //
  892. _xSink.Free();
  893. _xCP.Free();
  894. }
  895. } //DisableVPathNotify
  896. //+-------------------------------------------------------------------------
  897. //
  898. // Member: CMetaDataMgr::ReportVPath, private
  899. //
  900. // Synopsis: Helper method for reporting a vpath via callback
  901. //
  902. // Arguments: [vrootStack] - stack of vroots for depth-first search
  903. // [mdRoot] - handle to the root of the enumeration
  904. // [callBack] - callback to call for vpath
  905. // [pwcRelative] - relative path in metabase
  906. //
  907. // Returns: TRUE if the vpath is a vroot and was pushed on vrootStack
  908. //
  909. // History: 07-Feb-1997 dlee Created
  910. //
  911. //--------------------------------------------------------------------------
  912. BOOL CMetaDataMgr::ReportVPath(
  913. CVRootStack & vrootStack,
  914. CMetaDataCallBack & callBack,
  915. CMetaDataHandle & mdRoot,
  916. WCHAR const * pwcRelative )
  917. {
  918. Win4Assert( !_fTopLevel );
  919. // read the path, username, access permissions, and password
  920. WCHAR awcPPath[ METADATA_MAX_NAME_LEN ];
  921. awcPPath[0] = 0;
  922. WCHAR awcUser[ METADATA_MAX_NAME_LEN ];
  923. awcUser[0] = 0;
  924. DWORD dwAccess = 0;
  925. WCHAR awcPassword[ METADATA_MAX_NAME_LEN ];
  926. awcPassword[0] = 0;
  927. BOOL fIsIndexed = TRUE;
  928. BOOL fVRoot = TRUE;
  929. // Get the metabase access permission mask
  930. {
  931. METADATA_RECORD mdr;
  932. RtlZeroMemory( &mdr, sizeof mdr );
  933. mdr.dwMDIdentifier = MD_ACCESS_PERM;
  934. mdr.dwMDAttributes = METADATA_INHERIT;
  935. mdr.pbMDData = (BYTE *) &dwAccess;
  936. mdr.dwMDDataLen = sizeof dwAccess;
  937. DWORD cbRequired = 0;
  938. SCODE sc = _xAdminBase->GetData( mdRoot.Get(),
  939. pwcRelative,
  940. &mdr,
  941. &cbRequired );
  942. if ( ( FAILED( sc ) ) &&
  943. ( (MD_ERROR_DATA_NOT_FOUND) != sc ) )
  944. {
  945. ciDebugOut(( DEB_WARN, "GetData awccessperm failed: 0x%x\n", sc ));
  946. THROW( CException( sc ) );
  947. }
  948. }
  949. // Get the physical path if one exists
  950. {
  951. METADATA_RECORD mdr;
  952. RtlZeroMemory( &mdr, sizeof mdr );
  953. mdr.dwMDIdentifier = MD_VR_PATH;
  954. mdr.pbMDData = (BYTE *) awcPPath;
  955. mdr.dwMDDataLen = sizeof awcPPath;
  956. DWORD cbRequired = 0;
  957. SCODE sc = _xAdminBase->GetData( mdRoot.Get(),
  958. pwcRelative,
  959. &mdr,
  960. &cbRequired );
  961. if ( ( FAILED( sc ) ) &&
  962. ( (MD_ERROR_DATA_NOT_FOUND) != sc ) )
  963. {
  964. ciDebugOut(( DEB_WARN, "GetData PRoot failed: 0x%x\n", sc ));
  965. THROW( CException( sc ) );
  966. }
  967. }
  968. //
  969. // Only look for a username/access/password if there is a physical path,
  970. // since it can only be a virtual root if it has a physical path.
  971. //
  972. if ( 0 != awcPPath[0] )
  973. {
  974. // Trim any trailing backslash from the physical path
  975. unsigned cwcPRoot = wcslen( awcPPath );
  976. Win4Assert( 0 != cwcPRoot );
  977. if ( L'\\' == awcPPath[ cwcPRoot - 1 ] )
  978. awcPPath[ cwcPRoot - 1 ] = 0;
  979. {
  980. METADATA_RECORD mdr;
  981. RtlZeroMemory( &mdr, sizeof mdr );
  982. mdr.dwMDIdentifier = MD_VR_USERNAME;
  983. mdr.pbMDData = (BYTE *) awcUser;
  984. mdr.dwMDDataLen = sizeof awcUser;
  985. DWORD cbRequired = 0;
  986. SCODE sc = _xAdminBase->GetData( mdRoot.Get(),
  987. pwcRelative,
  988. &mdr,
  989. &cbRequired );
  990. if ( ( FAILED( sc ) ) &&
  991. ( (MD_ERROR_DATA_NOT_FOUND) != sc ) )
  992. {
  993. ciDebugOut(( DEB_WARN, "GetData user failed: 0x%x\n", sc ));
  994. THROW( CException( sc ) );
  995. }
  996. }
  997. {
  998. METADATA_RECORD mdr;
  999. RtlZeroMemory( &mdr, sizeof mdr );
  1000. mdr.dwMDIdentifier = MD_VR_PASSWORD;
  1001. mdr.pbMDData = (BYTE *) awcPassword;
  1002. mdr.dwMDDataLen = sizeof awcPassword;
  1003. DWORD cbRequired = 0;
  1004. SCODE sc = _xAdminBase->GetData( mdRoot.Get(),
  1005. pwcRelative,
  1006. &mdr,
  1007. &cbRequired );
  1008. if ( ( FAILED( sc ) ) &&
  1009. ( (MD_ERROR_DATA_NOT_FOUND) != sc ) )
  1010. {
  1011. ciDebugOut(( DEB_WARN, "GetData password failed: 0x%x\n", sc ));
  1012. THROW( CException( sc ) );
  1013. }
  1014. }
  1015. }
  1016. {
  1017. METADATA_RECORD mdr;
  1018. RtlZeroMemory( &mdr, sizeof mdr );
  1019. mdr.dwMDIdentifier = MD_IS_CONTENT_INDEXED;
  1020. mdr.dwMDAttributes = METADATA_INHERIT;
  1021. mdr.pbMDData = (BYTE *) &fIsIndexed;
  1022. mdr.dwMDDataLen = sizeof fIsIndexed;
  1023. DWORD cbRequired = 0;
  1024. SCODE sc = _xAdminBase->GetData( mdRoot.Get(),
  1025. pwcRelative,
  1026. &mdr,
  1027. &cbRequired );
  1028. if ( MD_ERROR_DATA_NOT_FOUND == sc )
  1029. {
  1030. fIsIndexed = FALSE;
  1031. }
  1032. else if ( FAILED( sc ) )
  1033. {
  1034. ciDebugOut(( DEB_WARN, "GetData isindexed failed: 0x%x\n", sc ));
  1035. THROW( CException( sc ) );
  1036. }
  1037. }
  1038. WCHAR awcVPath[METADATA_MAX_NAME_LEN];
  1039. wcscpy( awcVPath, pwcRelative );
  1040. WCHAR *pwcVPath = awcVPath;
  1041. // Important: The metabase names root "/Root" the rest of the world
  1042. // names root "/".
  1043. if ( !_wcsicmp( awcVPath, L"/Root" ) )
  1044. awcVPath[1] = 0;
  1045. else if ( !_wcsnicmp( awcVPath, L"/Root", 5 ) )
  1046. {
  1047. Win4Assert( L'/' == awcVPath[5] );
  1048. pwcVPath = awcVPath + 5;
  1049. }
  1050. if ( 0 == awcPPath[0] )
  1051. {
  1052. // if there isn't a physical path, it isn't a virtual root.
  1053. fVRoot = FALSE;
  1054. if ( vrootStack.IsEmpty() )
  1055. {
  1056. awcPPath[0] = 0;
  1057. }
  1058. else
  1059. {
  1060. // generate a physical path based on the virtual path and
  1061. // the most recent vroot parent on the stack
  1062. ciDebugOut(( DEB_ITRACE,
  1063. "making vpath from vroot '%ws' proot '%ws' vpath '%ws'\n",
  1064. vrootStack.PeekTopVRoot(),
  1065. vrootStack.PeekTopPRoot(),
  1066. pwcVPath ));
  1067. wcscpy( awcPPath, vrootStack.PeekTopPRoot() );
  1068. unsigned cwcVRoot = wcslen( vrootStack.PeekTopVRoot() );
  1069. unsigned cwcPRoot = wcslen( vrootStack.PeekTopPRoot() );
  1070. // The metabase can contain trailing backslashes in physical paths
  1071. if ( L'\\' == awcPPath[ cwcPRoot - 1 ] )
  1072. cwcPRoot--;
  1073. wcscpy( awcPPath + cwcPRoot,
  1074. pwcVPath + ( ( 1 == cwcVRoot ) ? 0 : cwcVRoot ) );
  1075. for ( WCHAR *pwc = awcPPath + cwcPRoot;
  1076. 0 != *pwc;
  1077. pwc++ )
  1078. {
  1079. if ( L'/' == *pwc )
  1080. *pwc = L'\\';
  1081. }
  1082. ciDebugOut(( DEB_ITRACE, "resulting ppath: '%ws'\n", awcPPath ));
  1083. }
  1084. }
  1085. // now we can finally call the callback
  1086. if ( 0 != awcPPath[0] )
  1087. callBack.CallBack( pwcVPath,
  1088. awcPPath,
  1089. fIsIndexed,
  1090. dwAccess,
  1091. awcUser,
  1092. awcPassword,
  1093. fVRoot );
  1094. if ( fVRoot )
  1095. vrootStack.Push( pwcVPath, awcPPath, dwAccess );
  1096. return fVRoot;
  1097. } //ReportVPath
  1098. //+-------------------------------------------------------------------------
  1099. //
  1100. // Member: CMetaDataMgr::EnumVServers, public
  1101. //
  1102. // Synopsis: Enumerates virtual servers by calling the callback
  1103. //
  1104. // Arguments: [callBack] - called for each vroot
  1105. //
  1106. // History: 07-Feb-1997 dlee Created
  1107. //
  1108. //--------------------------------------------------------------------------
  1109. void CMetaDataMgr::EnumVServers( CMetaDataVirtualServerCallBack & callBack )
  1110. {
  1111. Win4Assert( _fTopLevel );
  1112. CMetaDataHandle mdRoot( _xAdminBase, _awcInstance );
  1113. Enum( callBack, mdRoot, L"" );
  1114. } //EnumVRoots
  1115. //+-------------------------------------------------------------------------
  1116. //
  1117. // Member: CMetaDataMgr::ReportVirtualServer, private
  1118. //
  1119. // Synopsis: Helper method for reporting a virtual server via callback
  1120. //
  1121. // Arguments: [callBack] - callback to call for virtual server
  1122. // [pwcRelative] - relative path in metabase
  1123. //
  1124. // History: 07-Feb-1997 dlee Created
  1125. //
  1126. //--------------------------------------------------------------------------
  1127. void CMetaDataMgr::ReportVirtualServer(
  1128. CMetaDataVirtualServerCallBack & callBack,
  1129. CMetaDataHandle & mdRoot,
  1130. WCHAR const * pwcRelative )
  1131. {
  1132. Win4Assert( _fTopLevel );
  1133. // read the comment
  1134. WCHAR awcComment[ METADATA_MAX_NAME_LEN ];
  1135. awcComment[0] = 0;
  1136. {
  1137. METADATA_RECORD mdr;
  1138. RtlZeroMemory( &mdr, sizeof mdr );
  1139. mdr.dwMDIdentifier = MD_SERVER_COMMENT;
  1140. mdr.pbMDData = (BYTE *) awcComment;
  1141. mdr.dwMDDataLen = sizeof awcComment;
  1142. DWORD cbRequired = 0;
  1143. SCODE sc = _xAdminBase->GetData( mdRoot.Get(),
  1144. pwcRelative,
  1145. &mdr,
  1146. &cbRequired );
  1147. if ( ( FAILED( sc ) ) &&
  1148. ( (MD_ERROR_DATA_NOT_FOUND) != sc ) )
  1149. {
  1150. ciDebugOut(( DEB_WARN, "GetData virtual server failed: 0x%x\n", sc ));
  1151. THROW( CException( sc ) );
  1152. }
  1153. }
  1154. //
  1155. // Convert ID to integer
  1156. //
  1157. DWORD iInstance = wcstoul( pwcRelative, 0, 10 );
  1158. // now we can finally call the callback
  1159. callBack.CallBack( iInstance, awcComment );
  1160. } //ReportVirtualServer
  1161. //+-------------------------------------------------------------------------
  1162. //
  1163. // Member: CMetaDataMgr::Enum, private
  1164. //
  1165. // Synopsis: Helper method for enumerating vpaths
  1166. //
  1167. // Arguments: [vrootStack] - stack of vroots for depth-first search
  1168. // [callBack] - callback to call when a vpath is found
  1169. // [mdRoot] - root of the enumeration
  1170. // [pwcRelative] - relative location in enumeration
  1171. //
  1172. // History: 07-Feb-1997 dlee Created
  1173. //
  1174. //--------------------------------------------------------------------------
  1175. void CMetaDataMgr::Enum(
  1176. CVRootStack & vrootStack,
  1177. CMetaDataCallBack & callBack,
  1178. CMetaDataHandle & mdRoot,
  1179. WCHAR const * pwcRelative )
  1180. {
  1181. // enumerate looking for vpaths
  1182. int c = wcslen( pwcRelative );
  1183. WCHAR awcNewRelPath[ METADATA_MAX_NAME_LEN ];
  1184. RtlCopyMemory( awcNewRelPath, pwcRelative, (c + 1) * sizeof WCHAR );
  1185. if ( 0 == c ||
  1186. L'/' != pwcRelative[c-1] )
  1187. {
  1188. wcscpy( awcNewRelPath + c, L"/" );
  1189. c++;
  1190. }
  1191. for ( int i = 0; ; i++ )
  1192. {
  1193. WCHAR NameBuf[METADATA_MAX_NAME_LEN];
  1194. SCODE sc =_xAdminBase->EnumKeys( mdRoot.Get(),
  1195. pwcRelative,
  1196. NameBuf,
  1197. i );
  1198. if ( RETURNCODETOHRESULT(ERROR_NO_MORE_ITEMS) == sc )
  1199. break;
  1200. if ( FAILED( sc ) )
  1201. {
  1202. ciDebugOut(( DEB_WARN, "EnumKeys error 0x%x\n", sc ));
  1203. THROW( CException( sc ) );
  1204. }
  1205. Win4Assert( 0 != NameBuf[0] );
  1206. Win4Assert( ( c + wcslen( NameBuf ) ) < METADATA_MAX_NAME_LEN );
  1207. wcscpy( awcNewRelPath + c, NameBuf );
  1208. BOOL fVRoot = ReportVPath( vrootStack,
  1209. callBack,
  1210. mdRoot,
  1211. awcNewRelPath );
  1212. Enum( vrootStack, callBack, mdRoot, awcNewRelPath );
  1213. if ( fVRoot )
  1214. vrootStack.Pop();
  1215. }
  1216. } //Enum
  1217. //+-------------------------------------------------------------------------
  1218. //
  1219. // Member: CMetaDataMgr::Enum, private
  1220. //
  1221. // Synopsis: Helper method for enumerating virtual servers
  1222. //
  1223. // Arguments: [callBack] - callback to call when a vserver is found
  1224. // [mdRoot] - root of the enumeration
  1225. // [pwcRelative] - relative location in enumeration
  1226. //
  1227. // History: 07-Feb-1997 dlee Created
  1228. //
  1229. //--------------------------------------------------------------------------
  1230. void CMetaDataMgr::Enum(
  1231. CMetaDataVirtualServerCallBack & callBack,
  1232. CMetaDataHandle & mdRoot,
  1233. WCHAR const * pwcRelative )
  1234. {
  1235. // enumerate looking for virtual servers
  1236. for ( int i = 0; ; i++ )
  1237. {
  1238. WCHAR NameBuf[METADATA_MAX_NAME_LEN];
  1239. SCODE sc =_xAdminBase->EnumKeys( mdRoot.Get(),
  1240. pwcRelative,
  1241. NameBuf,
  1242. i );
  1243. if ( RETURNCODETOHRESULT(ERROR_NO_MORE_ITEMS) == sc )
  1244. break;
  1245. if ( FAILED( sc ) )
  1246. {
  1247. ciDebugOut(( DEB_WARN, "EnumKeys error 0x%x\n", sc ));
  1248. THROW( CException( sc ) );
  1249. }
  1250. ciDebugOut(( DEB_WARN, "Key: %ws\n", NameBuf ));
  1251. //
  1252. // Ignore things that don't look like virtual servers.
  1253. //
  1254. if ( !isdigit( NameBuf[0] ) )
  1255. continue;
  1256. //
  1257. // Assume we just got a virtual server.
  1258. //
  1259. ReportVirtualServer( callBack, mdRoot, NameBuf );
  1260. }
  1261. } //Enum
  1262. //+-------------------------------------------------------------------------
  1263. //
  1264. // Member: CMetaDataMgr::GetVRoot, public
  1265. //
  1266. // Synopsis: Returns the physical root corresponding to a virtual root
  1267. //
  1268. // Arguments: [pwcVRoot] - VRoot to lookup
  1269. // [pwcPRoot] - where pwcVRoot's physical root is returned
  1270. //
  1271. // History: 07-Feb-1997 dlee Created
  1272. //
  1273. //--------------------------------------------------------------------------
  1274. void CMetaDataMgr::GetVRoot(
  1275. WCHAR const * pwcVRoot,
  1276. WCHAR * pwcPRoot )
  1277. {
  1278. Win4Assert( !_fTopLevel );
  1279. unsigned cwc = wcslen( _awcInstance ) + wcslen( L"/Root" ) + wcslen( pwcVRoot );
  1280. if ( cwc >= METADATA_MAX_NAME_LEN )
  1281. THROW( CException( E_INVALIDARG ) );
  1282. WCHAR awcVRootPath[ METADATA_MAX_NAME_LEN ];
  1283. wcscpy( awcVRootPath, _awcInstance );
  1284. wcscat( awcVRootPath, L"/Root" );
  1285. wcscat( awcVRootPath, pwcVRoot );
  1286. CMetaDataHandle mdVRoot( _xAdminBase, awcVRootPath, FALSE );
  1287. *pwcPRoot = 0;
  1288. {
  1289. METADATA_RECORD mdr;
  1290. RtlZeroMemory( &mdr, sizeof mdr );
  1291. mdr.dwMDIdentifier = MD_VR_PATH;
  1292. mdr.pbMDData = (BYTE *) pwcPRoot;
  1293. mdr.dwMDDataLen = METADATA_MAX_NAME_LEN * sizeof WCHAR;
  1294. DWORD cbRequired = 0;
  1295. SCODE sc = _xAdminBase->GetData( mdVRoot.Get(),
  1296. L"",
  1297. &mdr,
  1298. &cbRequired );
  1299. if ( FAILED( sc ) )
  1300. {
  1301. ciDebugOut(( DEB_WARN, "GetData PRoot failed: 0x%x\n", sc ));
  1302. THROW( CException( sc ) );
  1303. }
  1304. }
  1305. } //GetVRoot
  1306. //+-------------------------------------------------------------------------
  1307. //
  1308. // Member: CMetaDataMgr::GetVRootPW, public
  1309. //
  1310. // Synopsis: Returns the physical root corresponding to a virtual root
  1311. //
  1312. // Arguments: [pwcVRoot] - VRoot to lookup
  1313. // [pwcPRoot] - where pwcVRoot's physical root is returned
  1314. //
  1315. // History: 07-Feb-1997 dlee Created
  1316. //
  1317. //--------------------------------------------------------------------------
  1318. void CMetaDataMgr::GetVRootPW(
  1319. WCHAR const * pwcVRoot,
  1320. WCHAR * pwcPW )
  1321. {
  1322. Win4Assert( !_fTopLevel );
  1323. unsigned cwc = wcslen( _awcInstance ) + wcslen( L"/Root" ) + wcslen( pwcVRoot );
  1324. if ( cwc >= METADATA_MAX_NAME_LEN )
  1325. THROW( CException( E_INVALIDARG ) );
  1326. WCHAR awcVRootPath[ METADATA_MAX_NAME_LEN ];
  1327. wcscpy( awcVRootPath, _awcInstance );
  1328. wcscat( awcVRootPath, L"/Root" );
  1329. wcscat( awcVRootPath, pwcVRoot );
  1330. CMetaDataHandle mdVRoot( _xAdminBase, awcVRootPath, FALSE );
  1331. *pwcPW = 0;
  1332. {
  1333. METADATA_RECORD mdr;
  1334. RtlZeroMemory( &mdr, sizeof mdr );
  1335. mdr.dwMDIdentifier = MD_VR_PASSWORD;
  1336. mdr.pbMDData = (BYTE *) pwcPW;
  1337. mdr.dwMDDataLen = METADATA_MAX_NAME_LEN * sizeof WCHAR;
  1338. DWORD cbRequired = 0;
  1339. SCODE sc = _xAdminBase->GetData( mdVRoot.Get(),
  1340. L"",
  1341. &mdr,
  1342. &cbRequired );
  1343. //char ac[ 1000 ];
  1344. //sprintf( ac, "result: 0x%x, cbResult: 0x%x, string: '%ws', char 1: 0x%x\n",
  1345. // sc, mdr.dwMDDataLen, pwcPW, (ULONG) *pwcPW );
  1346. //DbgPrint( ac );
  1347. if ( FAILED( sc ) )
  1348. {
  1349. ciDebugOut(( DEB_WARN, "GetData PRoot failed: 0x%x\n", sc ));
  1350. THROW( CException( sc ) );
  1351. }
  1352. }
  1353. } //GetVRootPW
  1354. //+-------------------------------------------------------------------------
  1355. //
  1356. // Member: CMetaDataMgr::SetIsIndexed, public
  1357. //
  1358. // Synopsis: Sets the indexed state of a virtual path
  1359. //
  1360. // Arguments: [pwcPath] - Virtual path (optionally a vroot) to set
  1361. // [fIsIndexed] - if TRUE, path is indexed, if FALSE it isn't
  1362. //
  1363. // History: 19-Mar-1997 dlee Created
  1364. //
  1365. //--------------------------------------------------------------------------
  1366. void CMetaDataMgr::SetIsIndexed(
  1367. WCHAR const * pwcVPath,
  1368. BOOL fIsIndexed )
  1369. {
  1370. // Add the key if it doesn't exist yet
  1371. {
  1372. unsigned cwc = wcslen( _awcInstance ) + wcslen( L"/Root" );
  1373. if ( cwc >= METADATA_MAX_NAME_LEN )
  1374. THROW( CException( E_INVALIDARG ) );
  1375. WCHAR awc[ METADATA_MAX_NAME_LEN ];
  1376. wcscpy( awc, _awcInstance );
  1377. wcscat( awc, L"/Root" );
  1378. CMetaDataHandle mdRoot( _xAdminBase, awc, TRUE );
  1379. _xAdminBase->AddKey( mdRoot.Get(), pwcVPath );
  1380. }
  1381. unsigned cwc = wcslen( _awcInstance ) + wcslen( L"/Root" ) + wcslen( pwcVPath );
  1382. if ( cwc >= METADATA_MAX_NAME_LEN )
  1383. THROW( CException( E_INVALIDARG ) );
  1384. WCHAR awcCompleteVPath[ METADATA_MAX_NAME_LEN ];
  1385. wcscpy( awcCompleteVPath, _awcInstance );
  1386. wcscat( awcCompleteVPath, L"/Root" );
  1387. wcscat( awcCompleteVPath, pwcVPath );
  1388. CMetaDataHandle mdVRoot( _xAdminBase, awcCompleteVPath, TRUE );
  1389. {
  1390. METADATA_RECORD mdr;
  1391. RtlZeroMemory( &mdr, sizeof mdr );
  1392. mdr.dwMDIdentifier = MD_IS_CONTENT_INDEXED;
  1393. mdr.dwMDAttributes = METADATA_INHERIT;
  1394. mdr.dwMDUserType = IIS_MD_UT_FILE;
  1395. mdr.dwMDDataType = DWORD_METADATA;
  1396. mdr.pbMDData = (BYTE *) &fIsIndexed;
  1397. mdr.dwMDDataLen = sizeof fIsIndexed;
  1398. DWORD cbRequired = 0;
  1399. SCODE sc = _xAdminBase->SetData( mdVRoot.Get(),
  1400. L"",
  1401. &mdr );
  1402. if ( FAILED( sc ) )
  1403. {
  1404. ciDebugOut(( DEB_WARN, "SetData isindexed failed: 0x%x\n", sc ));
  1405. THROW( CException( sc ) );
  1406. }
  1407. }
  1408. } //SetIsIndexed
  1409. //+-------------------------------------------------------------------------
  1410. //
  1411. // Member: CMetaDataMgr::IsIndexed, public
  1412. //
  1413. // Synopsis: Checks the path to return the state of the IsIndexed flag.
  1414. // The default for no value is TRUE. No checking is made to
  1415. // if a parent directory is indexed or not.
  1416. //
  1417. // Arguments: [pwcVPath] - Virtual path (optionally a vroot) to check
  1418. //
  1419. // History: 19-Mar-1997 dlee Created
  1420. //
  1421. //--------------------------------------------------------------------------
  1422. BOOL CMetaDataMgr::IsIndexed(
  1423. WCHAR const * pwcVPath )
  1424. {
  1425. BOOL fIsIndexed = TRUE;
  1426. unsigned cwc = wcslen( _awcInstance ) + wcslen( L"/Root" ) + wcslen( pwcVPath );
  1427. if ( cwc >= METADATA_MAX_NAME_LEN )
  1428. THROW( CException( E_INVALIDARG ) );
  1429. WCHAR awcCompletePath[ METADATA_MAX_NAME_LEN ];
  1430. wcscpy( awcCompletePath, _awcInstance );
  1431. wcscat( awcCompletePath, L"/Root" );
  1432. wcscat( awcCompletePath, pwcVPath );
  1433. TRY
  1434. {
  1435. CMetaDataHandle mdVRoot( _xAdminBase, awcCompletePath, FALSE );
  1436. {
  1437. METADATA_RECORD mdr;
  1438. RtlZeroMemory( &mdr, sizeof mdr );
  1439. mdr.dwMDIdentifier = MD_IS_CONTENT_INDEXED;
  1440. mdr.dwMDAttributes = METADATA_INHERIT;
  1441. mdr.pbMDData = (BYTE *) &fIsIndexed;
  1442. mdr.dwMDDataLen = sizeof fIsIndexed;
  1443. DWORD cbRequired = 0;
  1444. SCODE sc = _xAdminBase->GetData( mdVRoot.Get(),
  1445. L"",
  1446. &mdr,
  1447. &cbRequired );
  1448. if ( MD_ERROR_DATA_NOT_FOUND == sc )
  1449. {
  1450. fIsIndexed = FALSE;
  1451. }
  1452. else if ( FAILED( sc ) )
  1453. {
  1454. ciDebugOut(( DEB_WARN, "GetData isindexed failed: 0x%x\n", sc ));
  1455. THROW( CException( sc ) );
  1456. }
  1457. }
  1458. }
  1459. CATCH( CException, e )
  1460. {
  1461. // ignore -- assume IsIndexed
  1462. }
  1463. END_CATCH;
  1464. return fIsIndexed;
  1465. } //IsIndexed
  1466. //+-------------------------------------------------------------------------
  1467. //
  1468. // Member: CMetaDataMgr::GetVPathFlags, public
  1469. //
  1470. // Synopsis: Returns flag settings on a virtual path
  1471. //
  1472. // Arguments: [pwcVPath] - Virtual path (optionally a vroot) to check
  1473. // [mdID] - MD_x constant for the data
  1474. // [ulDefault] - Default if no value is in the metabase
  1475. //
  1476. // History: 18-Aug-1997 dlee Created
  1477. //
  1478. //--------------------------------------------------------------------------
  1479. ULONG CMetaDataMgr::GetVPathFlags(
  1480. WCHAR const * pwcVPath,
  1481. ULONG mdID,
  1482. ULONG ulDefault )
  1483. {
  1484. unsigned cwc = wcslen( _awcInstance ) + wcslen( L"/Root" ) + wcslen( pwcVPath );
  1485. if ( cwc >= METADATA_MAX_NAME_LEN )
  1486. THROW( CException( E_INVALIDARG ) );
  1487. WCHAR awcCompletePath[ METADATA_MAX_NAME_LEN ];
  1488. wcscpy( awcCompletePath, _awcInstance );
  1489. wcscat( awcCompletePath, L"/Root" );
  1490. wcscat( awcCompletePath, pwcVPath );
  1491. DWORD dwFlags = ulDefault;
  1492. // Keep removing path components on the right of the path until
  1493. // either out of path or the metabase recognizes the path.
  1494. METADATA_HANDLE h;
  1495. do
  1496. {
  1497. SCODE sc = _xAdminBase->OpenKey( METADATA_MASTER_ROOT_HANDLE,
  1498. awcCompletePath,
  1499. METADATA_PERMISSION_READ,
  1500. cmsCIMetabaseTimeout,
  1501. &h );
  1502. if ( S_OK == sc )
  1503. {
  1504. break;
  1505. }
  1506. else if ( HRESULT_FROM_WIN32( ERROR_PATH_NOT_FOUND ) == sc )
  1507. {
  1508. WCHAR * pwc = wcsrchr( awcCompletePath, L'/' );
  1509. if ( 0 == pwc )
  1510. THROW( CException( sc ) );
  1511. *pwc = 0;
  1512. }
  1513. else
  1514. THROW( CException( sc ) );
  1515. } while ( TRUE );
  1516. CMetaDataHandle mdVRoot( _xAdminBase, h );
  1517. {
  1518. METADATA_RECORD mdr;
  1519. RtlZeroMemory( &mdr, sizeof mdr );
  1520. mdr.dwMDIdentifier = mdID;
  1521. mdr.dwMDAttributes = METADATA_INHERIT;
  1522. mdr.pbMDData = (BYTE *) &dwFlags;
  1523. mdr.dwMDDataLen = sizeof dwFlags;
  1524. DWORD cbRequired = 0;
  1525. SCODE sc = _xAdminBase->GetData( mdVRoot.Get(),
  1526. L"",
  1527. &mdr,
  1528. &cbRequired );
  1529. if ( MD_ERROR_DATA_NOT_FOUND == sc )
  1530. {
  1531. // no value specified for this flag; use default
  1532. dwFlags = ulDefault;
  1533. }
  1534. else if ( FAILED( sc ) )
  1535. {
  1536. ciDebugOut(( DEB_WARN, "GetData mdid %d failed: 0x%x on '%ws'\n",
  1537. mdID, sc, awcCompletePath ));
  1538. THROW( CException( sc ) );
  1539. }
  1540. }
  1541. return dwFlags;
  1542. } //GetVPathFlags
  1543. //+-------------------------------------------------------------------------
  1544. //
  1545. // Member: CMetaDataMgr::GetVPathAccess, public
  1546. //
  1547. // Synopsis: Returns access permission settings on a virtual path
  1548. //
  1549. // Arguments: [pwcVPath] - Virtual path (optionally a vroot) to check
  1550. //
  1551. // History: 18-Aug-1997 dlee Created
  1552. //
  1553. //--------------------------------------------------------------------------
  1554. ULONG CMetaDataMgr::GetVPathAccess(
  1555. WCHAR const * pwcVPath )
  1556. {
  1557. // note: the default of 0 is from IIS' metabase guru
  1558. return GetVPathFlags( pwcVPath, MD_ACCESS_PERM, 0 );
  1559. } //GetVPathAccess
  1560. //+-------------------------------------------------------------------------
  1561. //
  1562. // Member: CMetaDataMgr::GetVPathSSLAccess, public
  1563. //
  1564. // Synopsis: Returns SSL access permission settings on a virtual path
  1565. //
  1566. // Arguments: [pwcVPath] - Virtual path (optionally a vroot) to check
  1567. //
  1568. // History: 18-Aug-1997 dlee Created
  1569. //
  1570. //--------------------------------------------------------------------------
  1571. ULONG CMetaDataMgr::GetVPathSSLAccess(
  1572. WCHAR const * pwcVPath )
  1573. {
  1574. // note: the default of 0 is from IIS' metabase guru
  1575. return GetVPathFlags( pwcVPath, MD_SSL_ACCESS_PERM, 0 );
  1576. } //GetVPathSSLAccess
  1577. //+-------------------------------------------------------------------------
  1578. //
  1579. // Member: CMetaDataMgr::GetVPathAuthorization, public
  1580. //
  1581. // Synopsis: Returns authorization on a virtual path
  1582. //
  1583. // Arguments: [pwcVPath] - Virtual path (optionally a vroot) to check
  1584. //
  1585. // History: 18-Aug-1997 dlee Created
  1586. //
  1587. //--------------------------------------------------------------------------
  1588. ULONG CMetaDataMgr::GetVPathAuthorization(
  1589. WCHAR const * pwcVPath )
  1590. {
  1591. // note: the default of MD_AUTH_ANONYMOUS is from IIS' metabase guru
  1592. return GetVPathFlags( pwcVPath, MD_AUTHORIZATION, MD_AUTH_ANONYMOUS );
  1593. } //GetVPathAuthorization
  1594. //+-------------------------------------------------------------------------
  1595. //
  1596. // Member: CMetaDataComSink::SinkNotify, public
  1597. //
  1598. // Synopsis: Called for any metadata change
  1599. //
  1600. // Arguments: [cChanges] - # of changes in pcoChangeList
  1601. // [pcoChangeList] - list of changes
  1602. //
  1603. // History: 07-Feb-1997 dlee Created
  1604. //
  1605. //--------------------------------------------------------------------------
  1606. SCODE STDMETHODCALLTYPE CMetaDataComSink::SinkNotify(
  1607. DWORD cChanges,
  1608. MD_CHANGE_OBJECT pcoChangeList[] )
  1609. {
  1610. // This is called by an RPC worker thread -- assimilate it
  1611. TRANSLATE_EXCEPTIONS;
  1612. TRY
  1613. {
  1614. int cwcInstance = wcslen( _awcInstance );
  1615. BOOL fInterestingChange = FALSE;
  1616. ciDebugOut(( DEB_WARN, "iis sinknotify '%ws', cchanges: %d\n",
  1617. _awcInstance, cChanges ));
  1618. for ( DWORD i = 0; !fInterestingChange && i < cChanges; i++ )
  1619. {
  1620. MD_CHANGE_OBJECT & co = pcoChangeList[i];
  1621. // we only care about notifications to our instance
  1622. if ( _wcsnicmp( co.pszMDPath, _awcInstance, cwcInstance ) != 0 ||
  1623. ( L'/' != co.pszMDPath[cwcInstance] &&
  1624. L'\0' != co.pszMDPath[cwcInstance] ) )
  1625. continue;
  1626. // Ignore adds of vroots -- we'll get a set_data for its
  1627. // parameters and trigger on that.
  1628. if ( ( MD_CHANGE_TYPE_DELETE_OBJECT & co.dwMDChangeType ) ||
  1629. ( MD_CHANGE_TYPE_RENAME_OBJECT & co.dwMDChangeType ) )
  1630. {
  1631. // guess that the deletion was a vroot
  1632. fInterestingChange = TRUE;
  1633. }
  1634. else if ( ( MD_CHANGE_TYPE_SET_DATA & co.dwMDChangeType ) ||
  1635. ( MD_CHANGE_TYPE_DELETE_DATA & co.dwMDChangeType ) )
  1636. {
  1637. for ( DWORD x = 0; x < co.dwMDNumDataIDs; x++ )
  1638. {
  1639. DWORD id = co.pdwMDDataIDs[x];
  1640. if ( MD_VR_PATH == id ||
  1641. MD_VR_USERNAME == id ||
  1642. MD_VR_PASSWORD == id ||
  1643. MD_ACCESS_PERM == id ||
  1644. MD_IS_CONTENT_INDEXED == id )
  1645. {
  1646. fInterestingChange = TRUE;
  1647. break;
  1648. }
  1649. }
  1650. }
  1651. }
  1652. if ( fInterestingChange && ( 0 != _pCallBack ) )
  1653. _pCallBack->CallBack( FALSE );
  1654. }
  1655. CATCH (CException, e)
  1656. {
  1657. ciDebugOut(( DEB_WARN,
  1658. "SinkNotify caught 0x%x\n",
  1659. e.GetErrorCode() ));
  1660. }
  1661. END_CATCH
  1662. UNTRANSLATE_EXCEPTIONS;
  1663. return S_OK;
  1664. } //SinkNotify
  1665. //+-------------------------------------------------------------------------
  1666. //
  1667. // Member: CMetaDataComSink::ShutdownNotify, public
  1668. //
  1669. // Synopsis: Called when iisadmin is going down cleanly
  1670. //
  1671. // History: 07-Feb-1997 dlee Created
  1672. //
  1673. //--------------------------------------------------------------------------
  1674. SCODE STDMETHODCALLTYPE CMetaDataComSink::ShutdownNotify()
  1675. {
  1676. // This is called by an RPC worker thread -- assimilate it
  1677. TRANSLATE_EXCEPTIONS;
  1678. TRY
  1679. {
  1680. ciDebugOut(( DEB_WARN, "iis shutdownnotify '%ws'\n", _awcInstance ));
  1681. // in case we get more random notifications, ignore them
  1682. CMetaDataVPathChangeCallBack * pCallBack = _pCallBack;
  1683. _pCallBack = 0;
  1684. pCallBack->CallBack( TRUE );
  1685. }
  1686. CATCH (CException, e)
  1687. {
  1688. ciDebugOut(( DEB_WARN,
  1689. "ShutdownNotify caught 0x%x\n",
  1690. e.GetErrorCode() ));
  1691. }
  1692. END_CATCH
  1693. UNTRANSLATE_EXCEPTIONS;
  1694. return S_OK;
  1695. } //ShutdownNotify