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.

1069 lines
28 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1995 - 2000.
  5. //
  6. // File: pathstor.cxx
  7. //
  8. // Classes: CSplitPath, CSplitPathCompare, CPathStore
  9. //
  10. // Functions:
  11. //
  12. // History: 5-02-95 srikants Created
  13. //
  14. //----------------------------------------------------------------------------
  15. #include "pch.cxx"
  16. #pragma hdrstop
  17. #include "pathstor.hxx"
  18. #include "pathcomp.hxx"
  19. #include "tabledbg.hxx"
  20. const WCHAR CSplitPath::_awszPathSep[] = L"\\";
  21. //+---------------------------------------------------------------------------
  22. //
  23. // Function: CSplitPath
  24. //
  25. // Synopsis: ~ctor for CSplitPath which can be initialized given the
  26. // "pathId".
  27. //
  28. // Arguments: [pathStore] - Reference to the path store.
  29. // [pathid] - PathId to be used for initialization.
  30. //
  31. // History: 5-09-95 srikants Created
  32. //
  33. //----------------------------------------------------------------------------
  34. CSplitPath::CSplitPath( CPathStore & pathStore, PATHID pathid )
  35. {
  36. const CShortPath & path = pathStore.GetShortPath( pathid );
  37. CStringStore & strStore = pathStore.GetStringStore();
  38. if ( stridInvalid != path.GetParent() )
  39. {
  40. _pParent = strStore.GetCountedWStr( path.GetParent(), _cwcParent );
  41. }
  42. else
  43. {
  44. _pParent = 0;
  45. _cwcParent = 0;
  46. }
  47. if ( stridInvalid != path.GetFileName() )
  48. {
  49. _pFile = strStore.GetCountedWStr( path.GetFileName(), _cwcFile );
  50. }
  51. else
  52. {
  53. _pFile = 0;
  54. _cwcParent = 0;
  55. }
  56. }
  57. //+---------------------------------------------------------------------------
  58. //
  59. // Function: CSplitPath
  60. //
  61. // Synopsis: ~ctor - initialized using a NULL terminated path.
  62. //
  63. // Arguments: [pwszPath] - The null terminated path.
  64. //
  65. // History: 5-09-95 srikants Created
  66. //
  67. //----------------------------------------------------------------------------
  68. CSplitPath::CSplitPath( const WCHAR * pwszPath )
  69. {
  70. const ULONG cwcPath = wcslen( pwszPath );
  71. Win4Assert( 0 != cwcPath );
  72. const WCHAR * pwszFinalComponent = wcsrchr(pwszPath, wchPathSep);
  73. if ( 0 == pwszFinalComponent )
  74. {
  75. _pParent = 0;
  76. _cwcParent = 0;
  77. _pFile = pwszPath;
  78. _cwcFile = cwcPath;
  79. }
  80. else
  81. {
  82. _pParent = pwszPath;
  83. _cwcParent = (DWORD)(pwszFinalComponent - pwszPath);
  84. _cwcFile = cwcPath - ( _cwcParent + 1 ); // skip over the path separator
  85. if ( 0 != _cwcFile )
  86. {
  87. _pFile = pwszPath + ( _cwcParent + 1 );
  88. }
  89. else
  90. {
  91. //
  92. // There is a path separator at the end of the string.
  93. //
  94. _pFile = 0;
  95. }
  96. }
  97. }
  98. //+---------------------------------------------------------------------------
  99. //
  100. // Function: Advance
  101. //
  102. // Synopsis: Advances the current pointer by "cwc" characters during
  103. // comparison of split paths.
  104. //
  105. // Arguments: [cwc] - Number of characters to advance by.
  106. //
  107. // History: 5-09-95 srikants Created
  108. //
  109. //----------------------------------------------------------------------------
  110. inline void CSplitPath::Advance( ULONG cwc )
  111. {
  112. Win4Assert( cwc <= _cwcCurr );
  113. Win4Assert( !IsDone() );
  114. _cwcCurr -= cwc;
  115. if ( 0 == _cwcCurr )
  116. {
  117. //
  118. // We must go to the next step.
  119. //
  120. switch ( _step )
  121. {
  122. case eUseParent:
  123. if ( 0 != _pParent )
  124. {
  125. _SetUsePathSep();
  126. }
  127. else
  128. {
  129. if ( 0 != _pFile )
  130. {
  131. _SetUseFile();
  132. }
  133. else
  134. {
  135. _SetUsePathSep();
  136. }
  137. }
  138. break;
  139. case eUsePathSep:
  140. if ( 0 == _pFile )
  141. {
  142. _SetDone();
  143. }
  144. else
  145. {
  146. _SetUseFile();
  147. }
  148. break;
  149. case eUseFile:
  150. _SetDone();
  151. break;
  152. default:
  153. Win4Assert( !"Impossible Case Condition" );
  154. break;
  155. }
  156. }
  157. else
  158. {
  159. _pCurr += cwc;
  160. }
  161. }
  162. //+---------------------------------------------------------------------------
  163. //
  164. // Function: GetFullPathLen
  165. //
  166. // Synopsis: Determines the length of the fully path (in characters)
  167. // INCLUDING the NULL terminator.
  168. //
  169. // History: 5-10-95 srikants Created
  170. //
  171. //----------------------------------------------------------------------------
  172. ULONG CSplitPath::GetFullPathLen() const
  173. {
  174. ULONG cwcTotal = 0;
  175. if ( 0 != _cwcParent )
  176. {
  177. cwcTotal += (_cwcParent+1); // extra 1 is for the path separator
  178. }
  179. cwcTotal += GetFileNameLen();
  180. Win4Assert( cwcTotal > 1 );
  181. return cwcTotal;
  182. }
  183. //+---------------------------------------------------------------------------
  184. //
  185. // Function: FormFullPath
  186. //
  187. // Synopsis: Forms the full path and copies it to pwszPath. It will
  188. // be NULL terminated.
  189. //
  190. // Arguments: [pwszPath] - OUTPUT buffer for the path
  191. // [cwcPath] - INPUT max. length of the buffer
  192. //
  193. // History: 5-10-95 srikants Created
  194. //
  195. //----------------------------------------------------------------------------
  196. void CSplitPath::FormFullPath( WCHAR * pwszPath, ULONG cwcPath ) const
  197. {
  198. ULONG cwcParent;
  199. Win4Assert( cwcPath >= GetFullPathLen() );
  200. if ( 0 != _pParent )
  201. {
  202. cwcParent = _cwcParent;
  203. RtlCopyMemory( pwszPath, _pParent, cwcParent * sizeof(WCHAR) );
  204. //
  205. // Append a backslash after the parent's part.
  206. //
  207. Win4Assert( cwcParent < cwcPath );
  208. pwszPath[cwcParent++] = wchPathSep; // Append a backslash
  209. pwszPath += cwcParent;
  210. }
  211. ULONG cwcFileName = _cwcFile;
  212. if ( 0 != _pFile )
  213. {
  214. Win4Assert( 0 != _cwcFile );
  215. RtlCopyMemory( pwszPath, _pFile, _cwcFile * sizeof(WCHAR) );
  216. }
  217. pwszPath[cwcFileName] = L'\0';
  218. }
  219. //+---------------------------------------------------------------------------
  220. //
  221. // Function: FormFileName
  222. //
  223. // Synopsis: Fills just the "FileName" component of the path in the
  224. // given buffer.
  225. //
  226. // Arguments: [pwszPath] - OUTPUT buffer - will contain the NULL
  227. // terminated filename.
  228. // [cwcFileName] - MAXLEN of pwszPath
  229. //
  230. // History: 5-10-95 srikants Created
  231. //
  232. //----------------------------------------------------------------------------
  233. inline
  234. void CSplitPath::FormFileName( WCHAR * pwszPath, ULONG cwcFileName ) const
  235. {
  236. Win4Assert( cwcFileName >= GetFileNameLen() );
  237. if ( 0 != _pFile )
  238. {
  239. RtlCopyMemory( pwszPath, _pFile, sizeof(WCHAR)*_cwcFile );
  240. }
  241. pwszPath[_cwcFile] = L'\0';
  242. return;
  243. }
  244. //+---------------------------------------------------------------------------
  245. //
  246. // Function: _Compare
  247. //
  248. // Synopsis: Compars the lhs and rhs split paths.
  249. //
  250. // Returns: -1, 0, +1 depending on whether lhs <, =, > rhs
  251. //
  252. // History: 5-23-95 srikants Created
  253. //
  254. //----------------------------------------------------------------------------
  255. int CSplitPathCompare::_Compare()
  256. {
  257. int iComp = 0;
  258. while ( !_IsDone() )
  259. {
  260. iComp = _lhs.CompareCurr( _rhs );
  261. if ( 0 != iComp )
  262. {
  263. return iComp;
  264. }
  265. ULONG cwcMin = min ( _lhs.GetCurrLen(), _rhs.GetCurrLen() );
  266. _lhs.Advance( cwcMin );
  267. _rhs.Advance( cwcMin );
  268. }
  269. iComp = _rhs.GetStep() - _lhs.GetStep();
  270. if ( iComp > 0 )
  271. {
  272. iComp = 1;
  273. }
  274. else if ( iComp < 0 )
  275. {
  276. iComp = -1;
  277. }
  278. return iComp;
  279. }
  280. //+---------------------------------------------------------------------------
  281. //
  282. // Function: ComparePaths
  283. //
  284. // Synopsis: Compares the two paths.
  285. //
  286. // Returns: 0 if equal
  287. // -1 if lhs < rhs
  288. // +1 if lhs > rhs
  289. //
  290. // History: 5-09-95 srikants Created
  291. //
  292. //----------------------------------------------------------------------------
  293. int CSplitPathCompare::ComparePaths()
  294. {
  295. _lhs.InitForPathCompare();
  296. _rhs.InitForPathCompare();
  297. return _Compare();
  298. }
  299. //+---------------------------------------------------------------------------
  300. //
  301. // Function: CompareNames
  302. //
  303. // Synopsis: Compares the "Name" component of two paths.
  304. //
  305. // Returns: 0 if equal
  306. // -1 if lhs < rhs
  307. // +1 if lhs > rhs
  308. //
  309. // History: 5-11-95 srikants Created
  310. //
  311. //----------------------------------------------------------------------------
  312. int CSplitPathCompare::CompareNames()
  313. {
  314. _lhs.InitForNameCompare();
  315. _rhs.InitForNameCompare();
  316. return _Compare();
  317. }
  318. //+---------------------------------------------------------------------------
  319. //
  320. // Function: Constructor for the CStringStore
  321. //
  322. // History: 5-03-95 srikants Created
  323. //
  324. //----------------------------------------------------------------------------
  325. CStringStore::CStringStore() : _pStrHash(0)
  326. {
  327. _pStrHash = new CCompressedColHashString( FALSE );
  328. // Don't optimize for ascii
  329. END_CONSTRUCTION( CStringStore );
  330. }
  331. //+---------------------------------------------------------------------------
  332. //
  333. // Function: CStringStore
  334. //
  335. // Synopsis: Destructor for CStringStore.
  336. //
  337. // History: 5-03-95 srikants Created
  338. //
  339. //----------------------------------------------------------------------------
  340. CStringStore::~CStringStore()
  341. {
  342. delete _pStrHash;
  343. }
  344. //+---------------------------------------------------------------------------
  345. //
  346. // Function: Add
  347. //
  348. // Synopsis: Adds the NULL terminated pwszStr to the string store.
  349. //
  350. // Arguments: [pwszStr] - NULL terminated string to be added.
  351. //
  352. // Returns: The STRINGID of the string in the store.
  353. //
  354. // History: 5-03-95 srikants Created
  355. //
  356. //----------------------------------------------------------------------------
  357. STRINGID CStringStore::Add( const WCHAR * pwszStr )
  358. {
  359. ULONG strId;
  360. GetValueResult gvr;
  361. _pStrHash->AddData( pwszStr, strId, gvr );
  362. Win4Assert( GVRSuccess == gvr );
  363. return strId;
  364. }
  365. //+---------------------------------------------------------------------------
  366. //
  367. // Function: AddCountedWStr
  368. //
  369. // Synopsis: Adds a "counted" string to the store.
  370. //
  371. // Arguments: [pwszStr] - Pointer to the string to be added.
  372. // [cwcStr] - Number of WCHARS in the string.
  373. //
  374. // Returns: The ID of the string.
  375. //
  376. // History: 5-09-95 srikants Created
  377. //
  378. //----------------------------------------------------------------------------
  379. STRINGID CStringStore::AddCountedWStr( const WCHAR * pwszStr, ULONG cwcStr )
  380. {
  381. ULONG strId;
  382. GetValueResult gvr;
  383. _pStrHash->AddCountedWStr( pwszStr, cwcStr, strId, gvr );
  384. Win4Assert( GVRSuccess == gvr );
  385. return strId;
  386. }
  387. //+---------------------------------------------------------------------------
  388. //
  389. // Function: FindCountedWStr
  390. //
  391. // Synopsis: Finds a "counted" string in the store.
  392. //
  393. // Arguments: [pwszStr] - Pointer to the string to be added.
  394. // [cwcStr] - Number of WCHARS in the string.
  395. //
  396. // Returns: The ID of the string.
  397. //
  398. // History: 7-17-95 dlee Created
  399. //
  400. //----------------------------------------------------------------------------
  401. STRINGID CStringStore::FindCountedWStr( const WCHAR * pwszStr, ULONG cwcStr )
  402. {
  403. if ( 0 != pwszStr )
  404. return _pStrHash->FindCountedWStr( pwszStr, cwcStr );
  405. else
  406. return stridInvalid;
  407. }
  408. //+---------------------------------------------------------------------------
  409. //
  410. // Function: StrLen
  411. //
  412. // Synopsis: Length of the String associated with strId EXCLUDING the
  413. // terminating NULL.
  414. //
  415. // Arguments: [strId] - Id of the string whose length is needed.
  416. //
  417. // Returns:
  418. //
  419. // History: 5-09-95 srikants Created
  420. //
  421. //----------------------------------------------------------------------------
  422. ULONG CStringStore::StrLen( STRINGID strId )
  423. {
  424. return _pStrHash->DataLength( strId )-1;
  425. }
  426. //+---------------------------------------------------------------------------
  427. //
  428. // Function: GetCountedWStr
  429. //
  430. // Synopsis: Gets the string identified by the "strId.
  431. //
  432. // Arguments: [strId] - The id of the string to lookup.
  433. // [cwcStr] - On output, will have the count of the chars
  434. // in the string.
  435. //
  436. //
  437. // Returns: Pointer to the string - NOT NULL terminated.
  438. //
  439. // History: 5-03-95 srikants Created
  440. //
  441. //----------------------------------------------------------------------------
  442. const WCHAR * CStringStore::GetCountedWStr( STRINGID strId, ULONG & cwcStr )
  443. {
  444. return _pStrHash->GetCountedWStr( strId, cwcStr );
  445. }
  446. //+---------------------------------------------------------------------------
  447. //
  448. // Function: GetString
  449. //
  450. // Synopsis: Returns the string identified by the strId.
  451. //
  452. // Arguments: [strId] - ID of the string to retrieve
  453. // [pwszPath] - Pointer to the buffer to hold the string
  454. // [cwcPath] - On input, the max capacity of pwszPath. On
  455. // output, it will have the count of the chars
  456. // in the string, excluding the terminating NULL.
  457. //
  458. // Returns:
  459. //
  460. // Modifies:
  461. //
  462. // History: 5-09-95 srikants Created
  463. //
  464. //----------------------------------------------------------------------------
  465. GetValueResult
  466. CStringStore::GetString( STRINGID strId, WCHAR * pwszPath, ULONG & cwcPath )
  467. {
  468. return _pStrHash->GetData( strId, pwszPath, cwcPath );
  469. }
  470. CPathStore::~CPathStore()
  471. {
  472. }
  473. //+---------------------------------------------------------------------------
  474. //
  475. // Function: FindData
  476. //
  477. // Synopsis: Finds the given data (pidPath/pidName) in the path store.
  478. //
  479. // Arguments: [pVarnt] - string to look for
  480. // [rKey] - returns key
  481. //
  482. // Returns: TRUE if found, FALSE otherwise
  483. //
  484. // History: 7-3-95 dlee Created
  485. //
  486. //----------------------------------------------------------------------------
  487. BOOL CPathStore::FindData(
  488. PROPVARIANT const * const pvarnt,
  489. ULONG & rKey )
  490. {
  491. Win4Assert(pvarnt->vt == VT_LPWSTR);
  492. WCHAR * pwszData = pvarnt->pwszVal;
  493. CSplitPath path( pwszData );
  494. STRINGID idParent = _strStore.FindCountedWStr( path._pParent, path._cwcParent );
  495. STRINGID idName = _strStore.FindCountedWStr( path._pFile, path._cwcFile );
  496. CShortPath shortPath( idParent, idName );
  497. for ( unsigned i = 0; i < _aShortPath.Count(); i++ )
  498. {
  499. if ( shortPath.IsSame( _aShortPath[ i ] ) )
  500. {
  501. rKey = i + 1; // keys are 1-based
  502. return TRUE;
  503. }
  504. }
  505. return FALSE;
  506. } //FindData
  507. //+---------------------------------------------------------------------------
  508. //
  509. // Function: AddData
  510. //
  511. // Synopsis: Adds the given data (pidPath/pidName) to the path store.
  512. //
  513. // Arguments: [pVarnt] -
  514. // [pKey] -
  515. // [reIndicator] -
  516. //
  517. // History: 5-09-95 srikants Created
  518. //
  519. //----------------------------------------------------------------------------
  520. void CPathStore::AddData( PROPVARIANT const * const pVarnt,
  521. ULONG* pKey,
  522. GetValueResult& reIndicator
  523. )
  524. {
  525. //
  526. // Specially handle the VT_EMPTY case
  527. //
  528. if (pVarnt->vt == VT_EMPTY)
  529. {
  530. *pKey = 0;
  531. reIndicator = GVRSuccess;
  532. return;
  533. }
  534. Win4Assert(pVarnt->vt == VT_LPWSTR);
  535. WCHAR * pwszData = pVarnt->pwszVal;
  536. *pKey = AddPath( pwszData );
  537. reIndicator = GVRSuccess;
  538. return;
  539. }
  540. //+---------------------------------------------------------------------------
  541. //
  542. // Function: GetData
  543. //
  544. // Synopsis:
  545. //
  546. // Arguments: [pVarnt] - OUTPUT- Variant to hold the data.
  547. // [PreferredType] - UNUSED
  548. // [ulKey] - The "Key" (PathId) of the path to be
  549. // retrieved.
  550. // [PropId] - pidPath/pidWorkId/pidName
  551. //
  552. // Returns: GVRSuccess if successful.
  553. // a GVR* failure code o/w.
  554. //
  555. // History: 5-09-95 srikants Created
  556. //
  557. // Notes: FreeVariant MUST be called.
  558. //
  559. //----------------------------------------------------------------------------
  560. GetValueResult
  561. CPathStore::GetData( PROPVARIANT * pVarnt,
  562. VARTYPE PreferredType,
  563. ULONG ulKey,
  564. PROPID PropId )
  565. {
  566. if (ulKey == 0)
  567. {
  568. pVarnt->vt = VT_EMPTY;
  569. return GVRNotAvailable;
  570. }
  571. Win4Assert( _IsValid( ulKey ) );
  572. if ( pidWorkId == PropId )
  573. {
  574. pVarnt->vt = VT_I4;
  575. pVarnt->lVal = (LONG) ulKey;
  576. return GVRSuccess;
  577. }
  578. CSplitPath path( *this, ulKey );
  579. if ( pidName == PropId )
  580. {
  581. ULONG cwcFileName = path.GetFileNameLen();
  582. Win4Assert( cwcFileName > 0 );
  583. WCHAR * pwszFileName = _GetPathBuffer( cwcFileName );
  584. path.FormFileName( pwszFileName, cwcFileName );
  585. pVarnt->vt = VT_LPWSTR;
  586. pVarnt->pwszVal = pwszFileName;
  587. return GVRSuccess;
  588. }
  589. else
  590. {
  591. Win4Assert( pidPath == PropId );
  592. //
  593. // Retrieve entire path name.
  594. //
  595. // First, compute the required size of the return buffer.
  596. //
  597. ULONG cwcPathLen = path.GetFullPathLen( );
  598. WCHAR * pwszDest = _GetPathBuffer( cwcPathLen );
  599. pVarnt->vt = VT_LPWSTR;
  600. pVarnt->pwszVal = pwszDest;
  601. path.FormFullPath( pwszDest, cwcPathLen );
  602. return GVRSuccess;
  603. }
  604. }
  605. //+---------------------------------------------------------------------------
  606. //
  607. // Function: FreeVariant
  608. //
  609. // Synopsis: Frees the variant created in the "GetData" call.
  610. //
  611. // Arguments: [pVarnt] - Pointer to the variant to be freed.
  612. //
  613. // History: 5-09-95 srikants Created
  614. //
  615. //----------------------------------------------------------------------------
  616. void CPathStore::FreeVariant(PROPVARIANT * pVarnt)
  617. {
  618. if ( pVarnt->vt != VT_EMPTY && pVarnt->vt != VT_I4 )
  619. {
  620. Win4Assert(pVarnt->vt == VT_LPWSTR);
  621. _strStore.FreeVariant( pVarnt );
  622. pVarnt->pwszVal = 0; // To prevent accidental re-use
  623. }
  624. }
  625. //+---------------------------------------------------------------------------
  626. //
  627. // Function: _AddPath
  628. //
  629. // Synopsis: Adds the given path to the store.
  630. //
  631. // Arguments: [path] -
  632. //
  633. // Returns: ID of the path.
  634. //
  635. // History: 5-23-95 srikants Created
  636. //
  637. //----------------------------------------------------------------------------
  638. PATHID CPathStore::_AddPath( CSplitPath & path )
  639. {
  640. STRINGID idParent = stridInvalid;
  641. STRINGID idName = stridInvalid;
  642. if ( 0 != path._pParent )
  643. {
  644. idParent = _strStore.AddCountedWStr( path._pParent, path._cwcParent );
  645. }
  646. if ( 0 != path._pFile )
  647. {
  648. idName = _strStore.AddCountedWStr( path._pFile, path._cwcFile );
  649. }
  650. return _AddEntry( idParent, idName );
  651. }
  652. //+---------------------------------------------------------------------------
  653. //
  654. // Function: AddPath
  655. //
  656. // Synopsis: Adds the given path to the path store.
  657. //
  658. // Arguments: [pwszPath] - Pointer to the path to be added.
  659. //
  660. // Returns: An ID for the path.
  661. //
  662. // History: 5-03-95 srikants Created
  663. //
  664. // Notes: There is NO duplicate detection for paths. A new ID is given
  665. // everytime this method is called.
  666. //
  667. //----------------------------------------------------------------------------
  668. PATHID CPathStore::AddPath( WCHAR * pwszPath )
  669. {
  670. Win4Assert( 0 != pwszPath );
  671. CSplitPath path( pwszPath );
  672. PATHID pathId = _AddPath( path );
  673. tbDebugOut(( DEB_BOOKMARK,
  674. "WorkId=0x%8X Path=%ws\n", pathId, pwszPath ));
  675. return pathId;
  676. }
  677. //+---------------------------------------------------------------------------
  678. //
  679. // Function: AddPath
  680. //
  681. // Synopsis: Given a source path store and an id in the source pathstore,
  682. // this method adds the path from the source pathstore to this
  683. // store.
  684. //
  685. // Arguments: [srcStore] - Reference to the source path store.
  686. // [srcPathId] - Id in the source path store.
  687. //
  688. // Returns: PATHID for the path added.
  689. //
  690. // History: 5-23-95 srikants Created
  691. //
  692. //----------------------------------------------------------------------------
  693. PATHID CPathStore::AddPath( CPathStore & srcStore, PATHID srcPathId )
  694. {
  695. CSplitPath srcPath( srcStore, srcPathId );
  696. return _AddPath( srcPath );
  697. }
  698. //+---------------------------------------------------------------------------
  699. //
  700. // Function: PathLen
  701. //
  702. // Synopsis: Length of the path (INCLUDING terminating NULL) given the
  703. // pathid.
  704. //
  705. // Arguments: [pathId] - Id of the path whose length is requested.
  706. //
  707. // Returns: Length of the path including terminating null.
  708. //
  709. // History: 5-03-95 srikants Created
  710. //
  711. //----------------------------------------------------------------------------
  712. ULONG CPathStore::PathLen( PATHID pathId )
  713. {
  714. CSplitPath path( *this, pathId );
  715. return path.GetFullPathLen();
  716. }
  717. //+---------------------------------------------------------------------------
  718. //
  719. // Function: GetPath
  720. //
  721. // Synopsis: Given a pathId, it returns the path for that pathid.
  722. //
  723. // Arguments: [pathId] - Id of the path to be retrieved
  724. // [vtPath] - Variant to hold the output
  725. // [cbVarnt] - On Input, the maximum length of the variant.
  726. // On output, the actual length of the variant.
  727. //
  728. // Returns: GVRSuccess if successful
  729. // GVRNotEnoughSpace if the length of the variant is less
  730. // than needed.
  731. //
  732. // History: 5-08-95 srikants Created
  733. //
  734. //----------------------------------------------------------------------------
  735. GetValueResult
  736. CPathStore::GetPath( PATHID pathId, PROPVARIANT & vtPath, ULONG & cbVarnt )
  737. {
  738. CSplitPath splitPath( *this, pathId );
  739. const ULONG cbPath = splitPath.GetFullPathLen() * sizeof(WCHAR);
  740. const ULONG cbHeader = sizeof(PROPVARIANT);
  741. const ULONG cbTotal = cbHeader + cbPath;
  742. if ( cbVarnt < cbTotal )
  743. {
  744. cbVarnt = cbTotal;
  745. return GVRNotEnoughSpace;
  746. }
  747. const ULONG cwcPath = (cbTotal-cbHeader)/sizeof(WCHAR);
  748. WCHAR * pwszPath = (WCHAR *) ( ((BYTE*) &vtPath) + cbHeader );
  749. splitPath.FormFullPath( pwszPath, cwcPath );
  750. vtPath.vt = VT_LPWSTR;
  751. vtPath.pwszVal = pwszPath;
  752. cbVarnt = cbTotal;
  753. return GVRSuccess;
  754. }
  755. //+---------------------------------------------------------------------------
  756. //
  757. // Function: Get
  758. //
  759. // Synopsis: Retrieves the path specified by the pathId into a buffer
  760. // allocated from the dstPool.
  761. //
  762. // Arguments: [pathId] - Id of the path to be retrieved.
  763. // [propId] - pidName/pidPath
  764. // [dstPool] - Pool from which to allocate memory.
  765. //
  766. // Returns: Pointer to a WCHAR * containing the requested data
  767. // (NULL Terminated).
  768. //
  769. // History: 5-23-95 srikants Created
  770. //
  771. //----------------------------------------------------------------------------
  772. WCHAR *
  773. CPathStore::Get( PATHID pathId, PROPID propId, PVarAllocator & dstPool )
  774. {
  775. // summary catalogs can have empty paths
  776. if ( 0 == pathId )
  777. return 0;
  778. CSplitPath path( *this, pathId );
  779. WCHAR * pwszDest = 0;
  780. if ( pidName == propId )
  781. {
  782. ULONG cwcFileName = path.GetFileNameLen();
  783. ULONG cbDst = cwcFileName * sizeof(WCHAR);
  784. Win4Assert( cwcFileName > 0 );
  785. pwszDest = (WCHAR *) dstPool.Allocate( cbDst );
  786. path.FormFileName( pwszDest, cwcFileName );
  787. }
  788. else
  789. {
  790. Win4Assert( pidPath == propId );
  791. //
  792. // Retrieve entire path name.
  793. //
  794. // First, compute the required size of the return buffer.
  795. //
  796. ULONG cwcPathLen = path.GetFullPathLen();
  797. Win4Assert( cwcPathLen > 0 );
  798. ULONG cbDst = cwcPathLen * sizeof(WCHAR);
  799. pwszDest = (WCHAR *) dstPool.Allocate( cbDst );
  800. path.FormFullPath( pwszDest, cwcPathLen );
  801. }
  802. return pwszDest;
  803. }
  804. //+---------------------------------------------------------------------------
  805. //
  806. // Function: _AddEntry
  807. //
  808. // Synopsis: Adds an entry consisting of a ParentId and a FileId to the
  809. // store and returns a PATHID representing this short path.
  810. //
  811. // Arguments: [idParent] - Id of the parent in the path
  812. // [idFileName] - Id of the file in the path.
  813. //
  814. // History: 5-10-95 srikants Created
  815. //
  816. //----------------------------------------------------------------------------
  817. PATHID CPathStore::_AddEntry( STRINGID idParent, STRINGID idFileName )
  818. {
  819. CShortPath path( idParent, idFileName );
  820. _aShortPath.Add( path, _aShortPath.Count() );
  821. return _aShortPath.Count();
  822. }
  823. //+---------------------------------------------------------------------------
  824. //
  825. // Function: Compare
  826. //
  827. // Synopsis: Compares two paths given their pathids.
  828. //
  829. // Arguments: [pathid1] -
  830. // [pathid2] -
  831. // [propId] - pidName/pidFile
  832. //
  833. // History: 5-11-95 srikants Created
  834. //
  835. //----------------------------------------------------------------------------
  836. int CPathStore::Compare( PATHID pathid1, PATHID pathid2,
  837. PROPID propId
  838. )
  839. {
  840. // summary catalogs can have empty paths
  841. if ( 0 == pathid1 || 0 == pathid2 )
  842. return pathid1 - pathid2;
  843. Win4Assert( pidName == propId || pidPath == propId );
  844. CSplitPath path1( *this, pathid1 );
  845. CSplitPath path2( *this, pathid2 );
  846. CSplitPathCompare comp( path1, path2 );
  847. if ( pidName == propId )
  848. {
  849. return comp.CompareNames();
  850. }
  851. else
  852. {
  853. return comp.ComparePaths();
  854. }
  855. }
  856. //+---------------------------------------------------------------------------
  857. //
  858. // Function: Compare
  859. //
  860. // Synopsis: Compares a NULL terminated path with a pathid.
  861. //
  862. // Arguments: [pwszPath1] - NULL terminated path.
  863. // [pathid2] - Id of the second path.
  864. // [propId] - pidName/pidPath
  865. //
  866. // History: 5-11-95 srikants Created
  867. //
  868. //----------------------------------------------------------------------------
  869. int CPathStore::Compare( const WCHAR * pwszPath1, PATHID pathid2,
  870. PROPID propId )
  871. {
  872. if ( 0 == pathid2 )
  873. return 0;
  874. Win4Assert( pidName == propId || pidPath == propId );
  875. CSplitPath path1( pwszPath1 );
  876. CSplitPath path2( *this, pathid2 );
  877. CSplitPathCompare comp( path1, path2 );
  878. if ( pidName == propId )
  879. {
  880. return comp.CompareNames();
  881. }
  882. else
  883. {
  884. return comp.ComparePaths();
  885. }
  886. }
  887. //+---------------------------------------------------------------------------
  888. //
  889. // Function: Compare
  890. //
  891. // Synopsis: Compares a path in the variant form to a pathId.
  892. //
  893. // Arguments: [varnt] -
  894. // [pathid2] -
  895. // [propId] -
  896. //
  897. // History: 5-11-95 srikants Created
  898. //
  899. //----------------------------------------------------------------------------
  900. int CPathStore::Compare( PROPVARIANT &varnt, PATHID pathid2,
  901. PROPID propId )
  902. {
  903. Win4Assert( pidName == propId || pidPath == propId );
  904. Win4Assert( varnt.vt == VT_LPWSTR );
  905. const WCHAR * pwszPath1 = varnt.pwszVal;
  906. return Compare( pwszPath1, pathid2, propId );
  907. }