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.

766 lines
20 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Copyright (C) Microsoft Corporation, 1992 - 1997
  4. //
  5. // File: vrootenm.cxx
  6. //
  7. // Contents: Virtual roots enumerator
  8. //
  9. // History: 12-Dec-96 SitaramR Created
  10. //
  11. //--------------------------------------------------------------------------
  12. #include <pch.cxx>
  13. #pragma hdrstop
  14. #include <vrtenum.hxx>
  15. #include <catalog.hxx>
  16. #include <smatch.hxx>
  17. //+-------------------------------------------------------------------------
  18. //
  19. // Member: CVRootEnum::CVRootEnum, public
  20. //
  21. // Synopsis: Constructor
  22. //
  23. // Arguments: [cat] -- Catalog
  24. // [pQueryPropMapper] -- Pid Remapper associated with the query
  25. // [secCache] -- Cache of AccessCheck() results
  26. // [fUsePathAlias] -- TRUE if client is going through rdr/svr
  27. //
  28. // History: 19-Aug-93 KyleP Created
  29. //
  30. //--------------------------------------------------------------------------
  31. CVRootEnum::CVRootEnum( PCatalog & cat,
  32. ICiQueryPropertyMapper *pQueryPropMapper,
  33. CSecurityCache & secCache,
  34. BOOL fUsePathAlias )
  35. : CGenericPropRetriever( cat,
  36. pQueryPropMapper,
  37. secCache,
  38. 0, // Always return local roots. No fixups.
  39. FALSE ), // No per-root security check
  40. _iBmk( 0 )
  41. {
  42. //
  43. // You must be an admin to use this cursor, since per-object
  44. // security checkin is turned off. This function throws.
  45. //
  46. VerifyThreadHasAdminPrivilege();
  47. _Path.Buffer = (WCHAR*)_lcaseFunnyPath.GetActualPath(); // points to actual path
  48. _VPath.Buffer = _xwcsVPath.Get();
  49. //
  50. // No filename for roots.
  51. //
  52. _Name.Buffer = 0;
  53. _Name.Length = 0;
  54. }
  55. //+-------------------------------------------------------------------------
  56. //
  57. // Member: CVRootEnum::~CVRootEnum, public
  58. //
  59. // Synopsis: Clean up context index cursor
  60. //
  61. // History: 19-Aug-93 KyleP Created
  62. //
  63. //--------------------------------------------------------------------------
  64. CVRootEnum::~CVRootEnum()
  65. {
  66. }
  67. //+-------------------------------------------------------------------------
  68. //
  69. // Member: CVRootEnum::NextObject, public
  70. //
  71. // Synopsis: Move to next object
  72. //
  73. // Returns: Work id of next valid object, or widInvalid if end of
  74. // iteration.
  75. //
  76. // History: 19-Aug-93 KyleP Created
  77. //
  78. //--------------------------------------------------------------------------
  79. WORKID CVRootEnum::NextObject()
  80. {
  81. PurgeCachedInfo();
  82. WORKID wid;
  83. unsigned ccVPath = 0;
  84. unsigned ccPPath = 0;
  85. _Type = _cat.EnumerateVRoot( _xwcsVPath, // Full virtual root
  86. ccVPath, // + max length / return length
  87. _lcaseFunnyPath, // Full physical root
  88. ccPPath, // + max length / return length
  89. _iBmk ); // Bookmark
  90. if ( _Type != PCatalog::EndRoot )
  91. {
  92. _VPath.Length = (USHORT)(ccVPath * sizeof(WCHAR));
  93. _VPath.Buffer = _xwcsVPath.Get(); // buffer might have reallocated
  94. _Path.Length = (USHORT)((_lcaseFunnyPath.GetActualLength()) * sizeof(WCHAR));
  95. _Path.Buffer = (WCHAR*)_lcaseFunnyPath.GetActualPath(); // buffer might have reallocated
  96. wid = _cat.PathToWorkId( _lcaseFunnyPath, TRUE );
  97. }
  98. else
  99. wid = widInvalid;
  100. return( wid );
  101. }
  102. //+---------------------------------------------------------------------------
  103. //
  104. // Member: CVRootEnum::GetPath, public
  105. //
  106. // Returns: A path to file
  107. //
  108. // History: 07-Feb-96 KyleP Added header
  109. //
  110. //----------------------------------------------------------------------------
  111. UNICODE_STRING const * CVRootEnum::GetPath()
  112. {
  113. return &_Path;
  114. }
  115. //+---------------------------------------------------------------------------
  116. //
  117. // Member: CVRootEnum::GetVirtualPath, public
  118. //
  119. // Returns: A virtual path to file, or 0 if none exists.
  120. //
  121. // History: 07-Feb-96 KyleP Added header
  122. //
  123. //----------------------------------------------------------------------------
  124. UNICODE_STRING const * CVRootEnum::GetVirtualPath()
  125. {
  126. return &_VPath;
  127. }
  128. //+---------------------------------------------------------------------------
  129. //
  130. // Member: CVRootEnum::GetShortName, public
  131. //
  132. // Returns: Shortname of physical path
  133. //
  134. // History: 07-Feb-96 KyleP Added header
  135. //
  136. //----------------------------------------------------------------------------
  137. inline UNICODE_STRING const * CVRootEnum::GetShortName()
  138. {
  139. if ( !_fFindLoaded )
  140. Refresh( FALSE );
  141. _ShortName.Length = (USHORT)wcslen( _finddata.cAlternateFileName );
  142. if ( _ShortName.Length == 0 )
  143. return &_Name;
  144. _ShortName.MaximumLength = _ShortName.Length;
  145. _ShortName.Buffer = &_finddata.cAlternateFileName[0];
  146. return( &_ShortName );
  147. }
  148. //+---------------------------------------------------------------------------
  149. //
  150. // Member: CVRootEnum::CreateTime, public
  151. //
  152. // Returns: Create time of physical path
  153. //
  154. // History: 07-Feb-96 KyleP Added header
  155. //
  156. //----------------------------------------------------------------------------
  157. inline LONGLONG CVRootEnum::CreateTime()
  158. {
  159. //
  160. // First, should we try a fast path?
  161. //
  162. if ( 0 == (_fFastStatLoaded & fsCreate) )
  163. {
  164. //
  165. // Try property store?
  166. //
  167. if ( 0 == (_fFastStatNeverLoad & fsCreate) )
  168. {
  169. PROPVARIANT var;
  170. unsigned cb = sizeof(var);
  171. if ( FetchValue( pidCreateTime, &var, &cb ) )
  172. {
  173. _finddata.ftCreationTime.dwLowDateTime = var.hVal.LowPart;
  174. _finddata.ftCreationTime.dwHighDateTime = var.hVal.HighPart;
  175. }
  176. else
  177. {
  178. _fFastStatNeverLoad |= fsCreate;
  179. Refresh( TRUE );
  180. }
  181. }
  182. else
  183. {
  184. Win4Assert( !_fFastFindLoaded );
  185. Refresh( TRUE );
  186. }
  187. }
  188. LARGE_INTEGER li;
  189. li.LowPart = _finddata.ftCreationTime.dwLowDateTime;
  190. li.HighPart = _finddata.ftCreationTime.dwHighDateTime;
  191. return( litoll(li) );
  192. }
  193. //+---------------------------------------------------------------------------
  194. //
  195. // Member: CVRootEnum::ModifyTime, public
  196. //
  197. // Returns: Last write time of physical path
  198. //
  199. // History: 07-Feb-96 KyleP Added header
  200. //
  201. //----------------------------------------------------------------------------
  202. inline LONGLONG CVRootEnum::ModifyTime()
  203. {
  204. //
  205. // First, should we try a fast path?
  206. //
  207. if ( 0 == (_fFastStatLoaded & fsModify) )
  208. {
  209. //
  210. // Try property store?
  211. //
  212. if ( 0 == (_fFastStatNeverLoad & fsModify) )
  213. {
  214. PROPVARIANT var;
  215. unsigned cb = sizeof(var);
  216. if ( FetchValue( pidWriteTime, &var, &cb ) )
  217. {
  218. _finddata.ftLastWriteTime.dwLowDateTime = var.hVal.LowPart;
  219. _finddata.ftLastWriteTime.dwHighDateTime = var.hVal.HighPart;
  220. }
  221. else
  222. {
  223. _fFastStatNeverLoad |= fsModify;
  224. Refresh( TRUE );
  225. }
  226. }
  227. else
  228. {
  229. Win4Assert( !_fFastFindLoaded );
  230. Refresh( TRUE );
  231. }
  232. }
  233. LARGE_INTEGER li;
  234. li.LowPart = _finddata.ftLastWriteTime.dwLowDateTime;
  235. li.HighPart = _finddata.ftLastWriteTime.dwHighDateTime;
  236. return( litoll(li) );
  237. }
  238. //+---------------------------------------------------------------------------
  239. //
  240. // Member: CVRootEnum::AccessTime, public
  241. //
  242. // Returns: Last access time of physical path
  243. //
  244. // History: 07-Feb-96 KyleP Added header
  245. //
  246. //----------------------------------------------------------------------------
  247. inline LONGLONG CVRootEnum::AccessTime()
  248. {
  249. //
  250. // First, should we try a fast path?
  251. //
  252. if ( 0 == (_fFastStatLoaded & fsAccess) )
  253. {
  254. //
  255. // Try property store?
  256. //
  257. if ( 0 == (_fFastStatNeverLoad & fsAccess) )
  258. {
  259. PROPVARIANT var;
  260. unsigned cb = sizeof(var);
  261. if ( FetchValue( pidAccessTime, &var, &cb ) )
  262. {
  263. _finddata.ftLastAccessTime.dwLowDateTime = var.hVal.LowPart;
  264. _finddata.ftLastAccessTime.dwHighDateTime = var.hVal.HighPart;
  265. }
  266. else
  267. {
  268. _fFastStatNeverLoad |= fsAccess;
  269. Refresh( TRUE );
  270. }
  271. }
  272. else
  273. {
  274. Win4Assert( !_fFastFindLoaded );
  275. Refresh( TRUE );
  276. }
  277. }
  278. LARGE_INTEGER li;
  279. li.LowPart = _finddata.ftLastAccessTime.dwLowDateTime;
  280. li.HighPart = _finddata.ftLastAccessTime.dwHighDateTime;
  281. return( litoll(li) );
  282. }
  283. //+---------------------------------------------------------------------------
  284. //
  285. // Member: CVRootEnum::AccessTime, public
  286. //
  287. // Returns: Zero, which is always size of directory.
  288. //
  289. // History: 07-Feb-96 KyleP Added header
  290. //
  291. //----------------------------------------------------------------------------
  292. inline LONGLONG CVRootEnum::ObjectSize()
  293. {
  294. return 0;
  295. }
  296. //+---------------------------------------------------------------------------
  297. //
  298. // Member: CVRootEnum::Attributes, public
  299. //
  300. // Returns: File attributes for physical root.
  301. //
  302. // History: 07-Feb-96 KyleP Added header
  303. //
  304. //----------------------------------------------------------------------------
  305. inline ULONG CVRootEnum::Attributes()
  306. {
  307. //
  308. // First, should we try a fast path?
  309. //
  310. if ( 0 == (_fFastStatLoaded & fsAttrib) )
  311. {
  312. //
  313. // Try property store?
  314. //
  315. if ( 0 == (_fFastStatNeverLoad & fsAttrib) )
  316. {
  317. PROPVARIANT var;
  318. unsigned cb = sizeof(var);
  319. if ( FetchValue( pidAttrib, &var, &cb ) )
  320. {
  321. _finddata.dwFileAttributes = var.ulVal;
  322. }
  323. else
  324. {
  325. _fFastStatNeverLoad |= fsAttrib;
  326. Refresh( TRUE );
  327. }
  328. }
  329. else
  330. {
  331. Win4Assert( !_fFastFindLoaded );
  332. Refresh( TRUE );
  333. }
  334. }
  335. return( _finddata.dwFileAttributes );
  336. }
  337. //+---------------------------------------------------------------------------
  338. //
  339. // Member: CVRootEnum::GetVRootType, public
  340. //
  341. // Returns: Stat info for virtual root
  342. //
  343. // History: 11-Apr-96 KyleP Created
  344. //
  345. //----------------------------------------------------------------------------
  346. BOOL CVRootEnum::GetVRootType( ULONG & ulType )
  347. {
  348. ulType = _Type;
  349. return TRUE;
  350. }
  351. //+-------------------------------------------------------------------------
  352. //
  353. // Member: CVRootEnum::Refresh, private
  354. //
  355. // Synopsis: Load stat properties for current object
  356. //
  357. // Arguments: [fFast] -- If TRUE, make fast call and don't load alternate
  358. // file name.
  359. //
  360. // Returns: TRUE if load successful
  361. //
  362. // History: 19-Aug-93 KyleP Created
  363. // 29-Feb-96 KyleP Added GetFileAttributesEx support
  364. //
  365. //--------------------------------------------------------------------------
  366. BOOL CVRootEnum::Refresh( BOOL fFast )
  367. {
  368. if ( CImpersonateRemoteAccess::IsNetPath(_Path.Buffer) )
  369. {
  370. WCHAR const * pwszVPath = _VPath.Buffer;
  371. _remoteAccess.ImpersonateIf( _Path.Buffer,
  372. pwszVPath );
  373. }
  374. else if ( _remoteAccess.IsImpersonated() )
  375. {
  376. _remoteAccess.Release();
  377. }
  378. if ( fFast )
  379. {
  380. if ( !GetFileAttributesEx( _lcaseFunnyPath.GetPath(), GetFileExInfoStandard, &_finddata ) )
  381. {
  382. vqDebugOut(( DEB_ERROR, "Can't retrieve fast findfirst data for %ws. Error = %d\n",
  383. _lcaseFunnyPath.GetActualPath(), GetLastError() ));
  384. return FALSE;
  385. }
  386. _fFastFindLoaded = TRUE;
  387. _fFastStatLoaded = fsCreate | fsModify | fsAccess | fsSize | fsAttrib;
  388. }
  389. else
  390. {
  391. HANDLE h = FindFirstFile( _lcaseFunnyPath.GetPath(), &_finddata );
  392. if ( INVALID_HANDLE_VALUE == h )
  393. {
  394. vqDebugOut(( DEB_ERROR, "Can't retrieve findfirst data for %ws\n",
  395. _lcaseFunnyPath.GetActualPath() ));
  396. return FALSE;
  397. }
  398. else
  399. {
  400. FindClose( h );
  401. _fFindLoaded = TRUE;
  402. _fFastFindLoaded = TRUE;
  403. _fFastStatLoaded = fsCreate | fsModify | fsAccess | fsSize | fsAttrib;
  404. }
  405. }
  406. return TRUE;
  407. }
  408. //+-------------------------------------------------------------------------
  409. //
  410. // Member: CVRootEnum::BeginPropertyRetrieval
  411. //
  412. // Synopsis: Prime wid for property retrieval
  413. //
  414. // Arguments: [wid] -- Wid to prime
  415. //
  416. // History: 12-Dec-96 SitaramR Created
  417. //
  418. //--------------------------------------------------------------------------
  419. SCODE STDMETHODCALLTYPE CVRootEnum::BeginPropertyRetrieval( WORKID wid )
  420. {
  421. //
  422. // Check that we are retrieving the property for the wid on
  423. // which we are currently positioned
  424. //
  425. Win4Assert( wid == _widCurrent );
  426. Win4Assert( _widPrimedForPropRetrieval == widInvalid );
  427. if ( wid == _widCurrent )
  428. {
  429. _widPrimedForPropRetrieval = _widCurrent;
  430. return S_OK;
  431. }
  432. else
  433. return E_FAIL;
  434. }
  435. //+-------------------------------------------------------------------------
  436. //
  437. // Member: CVRootEnum::EndPropertyRetrieval
  438. //
  439. // Synopsis: Reset wid for property retrieval
  440. //
  441. // History: 12-Dec-96 SitaramR Created
  442. //
  443. //--------------------------------------------------------------------------
  444. SCODE STDMETHODCALLTYPE CVRootEnum::EndPropertyRetrieval( )
  445. {
  446. PurgeCachedInfo();
  447. SCODE sc = CGenericPropRetriever::EndPropertyRetrieval();
  448. return sc;
  449. }
  450. //+-------------------------------------------------------------------------
  451. //
  452. // Member: CVRootEnum::IsInScope
  453. //
  454. // Synopsis: Checks if current wid is in scope
  455. //
  456. // Arguments: [pfInScope] -- Scope check result returned here
  457. //
  458. // History: 12-Dec-96 SitaramR Created
  459. //
  460. //--------------------------------------------------------------------------
  461. SCODE STDMETHODCALLTYPE CVRootEnum::IsInScope( BOOL *pfInScope )
  462. {
  463. if ( widInvalid == _widPrimedForPropRetrieval )
  464. return CI_E_WORKID_NOTVALID;
  465. *pfInScope = TRUE;
  466. return S_OK;
  467. }
  468. //+-------------------------------------------------------------------------
  469. //
  470. // Member: CVRootEnum::Begin
  471. //
  472. // Synopsis: Begins an enumeration
  473. //
  474. // History: 12-Dec-96 SitaramR Created
  475. //
  476. //--------------------------------------------------------------------------
  477. SCODE STDMETHODCALLTYPE CVRootEnum::Begin()
  478. {
  479. SCODE sc = S_OK;
  480. TRY
  481. {
  482. _iBmk = 0;
  483. _fFindLoaded = FALSE;
  484. _fFastFindLoaded = FALSE;
  485. _fFastStatLoaded = 0;
  486. _fFastStatNeverLoad = 0;
  487. _Path.Length = 0xFFFF;
  488. _VPath.Length = 0xFFFF;
  489. _widCurrent = NextObject();
  490. }
  491. CATCH( CException, e )
  492. {
  493. sc = e.GetErrorCode();
  494. vqDebugOut(( DEB_ERROR,
  495. "CVRootEnum::Begin - Exception caught 0x%x\n",
  496. sc ));
  497. }
  498. END_CATCH;
  499. return sc;
  500. }
  501. //+-------------------------------------------------------------------------
  502. //
  503. // Member: CVRootEnum::CurrentDocument
  504. //
  505. // Synopsis: Returns current document
  506. //
  507. // Arguments: [pWorkId] -- Wid of current doc returned here
  508. //
  509. // History: 12-Dec-96 SitaramR Created
  510. //
  511. //--------------------------------------------------------------------------
  512. SCODE STDMETHODCALLTYPE CVRootEnum::CurrentDocument( WORKID *pWorkId )
  513. {
  514. *pWorkId = _widCurrent;
  515. if ( _widCurrent == widInvalid )
  516. return CI_S_END_OF_ENUMERATION;
  517. else
  518. return S_OK;
  519. }
  520. //+-------------------------------------------------------------------------
  521. //
  522. // Member: CVRootEnum::NextDocument
  523. //
  524. // Synopsis: Returns next document
  525. //
  526. // Arguments: [pWorkId] -- Wid of next doc returned here
  527. //
  528. // History: 12-Dec-96 SitaramR Created
  529. //
  530. //--------------------------------------------------------------------------
  531. SCODE STDMETHODCALLTYPE CVRootEnum::NextDocument( WORKID *pWorkId )
  532. {
  533. SCODE sc = S_OK;
  534. TRY
  535. {
  536. _widCurrent = NextObject();
  537. sc = CurrentDocument( pWorkId );
  538. }
  539. CATCH( CException, e )
  540. {
  541. sc = e.GetErrorCode();
  542. vqDebugOut(( DEB_ERROR,
  543. "CVRootEnum::NextDocument - Exception caught 0x%x\n",
  544. sc ));
  545. }
  546. END_CATCH;
  547. return sc;
  548. }
  549. //+-------------------------------------------------------------------------
  550. //
  551. // Member: CVRootEnum::End
  552. //
  553. // Synopsis: Ends an enumeration
  554. //
  555. // History: 12-Dec-96 SitaramR Created
  556. //
  557. //--------------------------------------------------------------------------
  558. SCODE STDMETHODCALLTYPE CVRootEnum::End()
  559. {
  560. _widCurrent = widInvalid;
  561. return S_OK;
  562. }
  563. //+-------------------------------------------------------------------------
  564. //
  565. // Method: CVRootEnum::AddRef
  566. //
  567. // Synopsis: Increments refcount
  568. //
  569. // History: 12-Dec-1996 SitaramR Created
  570. //
  571. //--------------------------------------------------------------------------
  572. ULONG STDMETHODCALLTYPE CVRootEnum::AddRef()
  573. {
  574. return CGenericPropRetriever::AddRef();
  575. }
  576. //+-------------------------------------------------------------------------
  577. //
  578. // Method: CVRootEnum::Release
  579. //
  580. // Synopsis: Decrement refcount. Delete if necessary.
  581. //
  582. // History: 12-Dec-1996 SitaramR Created
  583. //
  584. //--------------------------------------------------------------------------
  585. ULONG STDMETHODCALLTYPE CVRootEnum::Release()
  586. {
  587. return CGenericPropRetriever::Release();
  588. }
  589. //+-------------------------------------------------------------------------
  590. //
  591. // Method: CVRootEnum::QueryInterface
  592. //
  593. // Synopsis: Rebind to other interface
  594. //
  595. // Arguments: [riid] -- IID of new interface
  596. // [ppvObject] -- New interface * returned here
  597. //
  598. // Returns: S_OK if bind succeeded, E_NOINTERFACE if bind failed
  599. //
  600. // History: 12-Dec-1996 SitaramR Created
  601. //
  602. //--------------------------------------------------------------------------
  603. SCODE STDMETHODCALLTYPE CVRootEnum::QueryInterface(
  604. REFIID riid,
  605. void ** ppvObject)
  606. {
  607. if ( IID_ICiCPropRetriever == riid )
  608. *ppvObject = (ICiCPropRetriever *)this;
  609. else if ( IID_ICiCScopeEnumerator == riid )
  610. *ppvObject = (ICiCScopeEnumerator *)this;
  611. else if ( IID_IUnknown == riid )
  612. *ppvObject = (IUnknown *)(ICiCScopeEnumerator *) this;
  613. else
  614. {
  615. *ppvObject = 0;
  616. return E_NOINTERFACE;
  617. }
  618. AddRef();
  619. return S_OK;
  620. }
  621. //+---------------------------------------------------------------------------
  622. //
  623. // Member: CVRootEnum::RatioFinished, public
  624. //
  625. // Synopsis: Returns query progress estimate
  626. //
  627. // Arguments: [denom] -- Denominator returned here
  628. // [num] -- Numerator returned here
  629. //
  630. // History: 12-Dec-96 SitaramR Created
  631. //
  632. //----------------------------------------------------------------------------
  633. SCODE STDMETHODCALLTYPE CVRootEnum::RatioFinished (ULONG *pDenom, ULONG *pNum)
  634. {
  635. *pNum = 50;
  636. *pDenom = 100;
  637. return S_OK;
  638. }