Source code of Windows XP (NT5)
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.

556 lines
11 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1992.
  5. //
  6. // File: dirfunc.hxx
  7. //
  8. // Contents: Inline functions for Directory code
  9. //
  10. // Classes:
  11. //
  12. // Functions:
  13. //
  14. // History: 28-Oct-92 PhilipLa Created
  15. //
  16. //----------------------------------------------------------------------------
  17. #ifndef __DIRFUNC_HXX__
  18. #define __DIRFUNC_HXX__
  19. #include <page.hxx>
  20. inline void CDirEntry::Init(MSENTRYFLAGS mse)
  21. {
  22. msfAssert(sizeof(CDirEntry) == DIRENTRYSIZE);
  23. memset(this, 0, sizeof(CDirEntry));
  24. msfAssert(mse <= 0xff);
  25. _mse = (BYTE) mse;
  26. _bflags = 0;
  27. _dfn.Set((WORD)0, (BYTE *)NULL);
  28. _sidLeftSib = _sidRightSib = _sidChild = NOSTREAM;
  29. if (STORAGELIKE(_mse))
  30. {
  31. _clsId = IID_NULL;
  32. _dwUserFlags = 0;
  33. }
  34. if (STREAMLIKE(_mse))
  35. {
  36. _sectStart = ENDOFCHAIN;
  37. _ulSize.QuadPart = 0;
  38. }
  39. }
  40. inline BOOL CDirEntry::IsFree(VOID) const
  41. {
  42. return _mse == 0;
  43. }
  44. inline BOOL CDirEntry::IsEntry(CDfName const * pdfn) const
  45. {
  46. return !IsFree() && pdfn->IsEqual(&_dfn);
  47. }
  48. inline void CDirEntry::SetLeftSib(const SID sid)
  49. {
  50. _sidLeftSib = sid;
  51. }
  52. inline void CDirEntry::SetRightSib(const SID sid)
  53. {
  54. _sidRightSib = sid;
  55. }
  56. inline void CDirEntry::SetChild(const SID sid)
  57. {
  58. _sidChild = sid;
  59. }
  60. inline void CDirEntry::SetName(const CDfName *pdfn)
  61. {
  62. _dfn.Set(pdfn->GetLength(), pdfn->GetBuffer());
  63. }
  64. inline void CDirEntry::SetStart(const SECT sect)
  65. {
  66. msfAssert(STREAMLIKE(_mse));
  67. _sectStart=sect;
  68. }
  69. #ifdef LARGE_STREAMS
  70. inline void CDirEntry::SetSize(const ULONGLONG ulSize)
  71. #else
  72. inline void CDirEntry::SetSize(const ULONG ulSize)
  73. #endif
  74. {
  75. msfAssert(STREAMLIKE(_mse));
  76. _ulSize.QuadPart=ulSize;
  77. }
  78. inline void CDirEntry::SetFlags(const MSENTRYFLAGS mse)
  79. {
  80. msfAssert(mse <= 0xff);
  81. _mse = (const BYTE) mse;
  82. }
  83. inline void CDirEntry::SetBitFlags(BYTE bValue, BYTE bMask)
  84. {
  85. _bflags = (_bflags & ~bMask) | (bValue & bMask);
  86. }
  87. inline void CDirEntry::SetColor(DECOLOR color)
  88. {
  89. SetBitFlags(color, DECOLORBIT);
  90. }
  91. inline void CDirEntry::SetTime(WHICHTIME tt, TIME_T nt)
  92. {
  93. msfAssert((tt == WT_CREATION) || (tt == WT_MODIFICATION));
  94. _time[tt] = nt;
  95. }
  96. inline void CDirEntry::SetAllTimes(TIME_T atm, TIME_T mtm, TIME_T ctm)
  97. {
  98. _time[WT_MODIFICATION] = mtm;
  99. _time[WT_CREATION] = ctm;
  100. }
  101. inline void CDirEntry::SetClassId(GUID cls)
  102. {
  103. msfAssert(STORAGELIKE(_mse));
  104. _clsId = cls;
  105. }
  106. inline void CDirEntry::SetUserFlags(DWORD dwUserFlags, DWORD dwMask)
  107. {
  108. msfAssert(STORAGELIKE(_mse));
  109. _dwUserFlags = (_dwUserFlags & ~dwMask) | (dwUserFlags & dwMask);
  110. }
  111. inline SID CDirEntry::GetLeftSib(VOID) const
  112. {
  113. return _sidLeftSib;
  114. }
  115. inline SID CDirEntry::GetRightSib(VOID) const
  116. {
  117. return _sidRightSib;
  118. }
  119. inline SID CDirEntry::GetChild(VOID) const
  120. {
  121. return _sidChild;
  122. }
  123. inline GUID CDirEntry::GetClassId(VOID) const
  124. {
  125. msfAssert(STORAGELIKE(_mse));
  126. return _clsId;
  127. }
  128. inline CDfName const * CDirEntry::GetName(VOID) const
  129. {
  130. return &_dfn;
  131. }
  132. inline SECT CDirEntry::GetStart(VOID) const
  133. {
  134. msfAssert(STREAMLIKE(_mse));
  135. return _sectStart;
  136. }
  137. #ifdef LARGE_STREAMS
  138. inline ULONGLONG CDirEntry::GetSize(BOOL fLarge) const
  139. #else
  140. inline ULONG CDirEntry::GetSize(VOID) const
  141. #endif
  142. {
  143. msfAssert(STREAMLIKE(_mse));
  144. #ifdef LARGE_STREAMS
  145. return (fLarge) ? _ulSize.QuadPart : _ulSize.LowPart;
  146. #else
  147. return _ulSize.LowPart;
  148. #endif
  149. }
  150. inline MSENTRYFLAGS CDirEntry::GetFlags(VOID) const
  151. {
  152. return (MSENTRYFLAGS) _mse;
  153. }
  154. inline BYTE CDirEntry::GetBitFlags(VOID) const
  155. {
  156. return _bflags;
  157. }
  158. inline DECOLOR CDirEntry::GetColor(VOID) const
  159. {
  160. return((DECOLOR) (GetBitFlags() & DECOLORBIT));
  161. }
  162. inline TIME_T CDirEntry::GetTime(WHICHTIME tt) const
  163. {
  164. msfAssert((tt == WT_CREATION) || (tt == WT_MODIFICATION));
  165. return _time[tt];
  166. }
  167. inline void CDirEntry::GetAllTimes(TIME_T *patm, TIME_T *pmtm, TIME_T *pctm)
  168. {
  169. *patm = *pmtm = _time[WT_MODIFICATION];
  170. *pctm = _time[WT_CREATION];
  171. }
  172. inline DWORD CDirEntry::GetUserFlags(VOID) const
  173. {
  174. msfAssert(STORAGELIKE(_mse));
  175. return _dwUserFlags;
  176. }
  177. inline CDirEntry * CDirSect::GetEntry(DIROFFSET iEntry)
  178. {
  179. return &(_adeEntry[iEntry]);
  180. }
  181. //+-------------------------------------------------------------------------
  182. //
  183. // Method: CDirVector::CDirVector, public
  184. //
  185. // Synopsis: Default constructor
  186. //
  187. // History: 20-Apr-92 PhilipLa Created.
  188. //
  189. // Notes:
  190. //
  191. //--------------------------------------------------------------------------
  192. inline CDirVector::CDirVector()
  193. : CPagedVector(SIDDIR)
  194. {
  195. _cbSector = 0;
  196. }
  197. //+-------------------------------------------------------------------------
  198. //
  199. // Method: CDirVector::GetTable, public
  200. //
  201. // Synopsis: Return a pointer to a DirSect for the given index
  202. // into the vector.
  203. //
  204. // Arguments: [iTable] -- index into vector
  205. //
  206. // Returns: Pointer to CDirSect indicated by index
  207. //
  208. // History: 27-Dec-91 PhilipLa Created.
  209. //
  210. // Notes:
  211. //
  212. //--------------------------------------------------------------------------
  213. inline SCODE CDirVector::GetTable(
  214. const DIRINDEX iTable,
  215. const DWORD dwFlags,
  216. CDirSect **ppds)
  217. {
  218. SCODE sc;
  219. sc = CPagedVector::GetTable(iTable, dwFlags, (void **)ppds);
  220. if (sc == STG_S_NEWPAGE)
  221. {
  222. (*ppds)->Init(_cbSector);
  223. }
  224. return sc;
  225. }
  226. inline DIRINDEX CDirectory::SidToTable(SID sid) const
  227. {
  228. return (DIRINDEX)(sid / _cdeEntries);
  229. }
  230. inline SCODE CDirectory::GetName(const SID sid, CDfName *pdfn)
  231. {
  232. SCODE sc;
  233. CDirEntry *pde;
  234. msfChk(GetDirEntry(sid, FB_NONE, &pde));
  235. *pdfn = *(CDfName *)pde->GetName();
  236. ReleaseEntry(sid);
  237. Err:
  238. return sc;
  239. }
  240. //+-------------------------------------------------------------------------
  241. //
  242. // Member: CDirectory::GetStart, public
  243. //
  244. // Synposis: Retrieves the starting sector of a directory entry
  245. //
  246. // Arguments: [sid] -- Stream ID of stream in question
  247. //
  248. // Returns: Starting sector of stream
  249. //
  250. // Algorithm: Return the starting sector of the stream. If the
  251. // identifier is SIDFAT, return 0. If the identifier
  252. // is SIDDIR, return 1. Otherwise, return the starting
  253. // sector of the entry in question.
  254. //
  255. // History: 18-Jul-91 PhilipLa Created.
  256. // 15-May-92 AlexT Made inline, restricted sid.
  257. //
  258. // Notes:
  259. //
  260. //---------------------------------------------------------------------------
  261. inline SCODE CDirectory::GetStart(const SID sid, SECT *psect)
  262. {
  263. msfAssert(sid <= MAXREGSID);
  264. SCODE sc;
  265. CDirEntry *pde;
  266. msfChk(GetDirEntry(sid, FB_NONE, &pde));
  267. *psect = pde->GetStart();
  268. ReleaseEntry(sid);
  269. Err:
  270. return sc;
  271. }
  272. inline SCODE CDirectory::GetSize(
  273. const SID sid,
  274. #ifdef LARGE_STREAMS
  275. ULONGLONG * pulSize)
  276. #else
  277. ULONG * pulSize)
  278. #endif
  279. {
  280. SCODE sc;
  281. CDirEntry *pde;
  282. msfChk(GetDirEntry(sid, FB_NONE, &pde));
  283. #ifdef LARGE_STREAMS
  284. *pulSize = pde->GetSize(IsLargeSector());
  285. #else
  286. *pulSize = pde->GetSize();
  287. #endif
  288. ReleaseEntry(sid);
  289. Err:
  290. return sc;
  291. }
  292. inline SCODE CDirectory::GetChild(const SID sid, SID * psid)
  293. {
  294. SCODE sc;
  295. CDirEntry *pde;
  296. msfChk(GetDirEntry(sid, FB_NONE, &pde));
  297. *psid = pde->GetChild();
  298. ReleaseEntry(sid);
  299. Err:
  300. return sc;
  301. }
  302. inline SCODE CDirectory::GetFlags(
  303. const SID sid,
  304. MSENTRYFLAGS *pmse)
  305. {
  306. SCODE sc;
  307. CDirEntry *pde;
  308. msfChk(GetDirEntry(sid, FB_NONE, &pde));
  309. *pmse = pde->GetFlags();
  310. ReleaseEntry(sid);
  311. Err:
  312. return sc;
  313. }
  314. inline SCODE CDirectory::GetClassId(const SID sid, GUID *pcls)
  315. {
  316. SCODE sc;
  317. CDirEntry *pde;
  318. msfChk(GetDirEntry(sid, FB_NONE, &pde));
  319. *pcls = pde->GetClassId();
  320. ReleaseEntry(sid);
  321. Err:
  322. return sc;
  323. }
  324. inline SCODE CDirectory::GetUserFlags(const SID sid,
  325. DWORD *pdwUserFlags)
  326. {
  327. SCODE sc;
  328. CDirEntry *pde;
  329. msfChk(GetDirEntry(sid, FB_NONE, &pde));
  330. *pdwUserFlags = pde->GetUserFlags();
  331. ReleaseEntry(sid);
  332. Err:
  333. return sc;
  334. }
  335. inline SCODE CDirectory::GetTime(
  336. const SID sid,
  337. WHICHTIME tt,
  338. TIME_T *ptime)
  339. {
  340. SCODE sc;
  341. CDirEntry *pde;
  342. msfChk(GetDirEntry(sid, FB_NONE, &pde));
  343. *ptime = pde->GetTime(tt == WT_ACCESS ? WT_MODIFICATION : tt);
  344. ReleaseEntry(sid);
  345. Err:
  346. return sc;
  347. }
  348. inline SCODE CDirectory::GetAllTimes(
  349. const SID sid,
  350. TIME_T *patm,
  351. TIME_T *pmtm,
  352. TIME_T *pctm)
  353. {
  354. SCODE sc;
  355. CDirEntry *pde;
  356. msfChk(GetDirEntry(sid, FB_NONE, &pde));
  357. pde->GetAllTimes(patm, pmtm, pctm);
  358. ReleaseEntry(sid);
  359. Err:
  360. return sc;
  361. }
  362. inline SID CDirectory::PairToSid(
  363. DIRINDEX iTable,
  364. DIROFFSET iEntry) const
  365. {
  366. return (SID)((iTable * _cdeEntries) + iEntry);
  367. }
  368. inline SCODE CDirectory::SidToPair(
  369. SID sid,
  370. DIRINDEX* pipds,
  371. DIROFFSET* pide) const
  372. {
  373. *pipds = (DIRINDEX)(sid / _cdeEntries);
  374. *pide = (DIROFFSET)(sid % _cdeEntries);
  375. return S_OK;
  376. }
  377. inline void CDirectory::SetParent(CMStream *pms)
  378. {
  379. _pmsParent = P_TO_BP(CBasedMStreamPtr, pms);
  380. _dv.SetParent(pms);
  381. }
  382. inline SCODE CDirectory::IsEntry(SID const sidParent,
  383. CDfName const *pdfn,
  384. SEntryBuffer *peb)
  385. {
  386. return FindEntry(sidParent, pdfn, DEOP_FIND, peb);
  387. }
  388. //+-------------------------------------------------------------------------
  389. //
  390. // Method: CDirectory::Flush, private
  391. //
  392. // Synopsis: Write a dirsector out to the parent
  393. //
  394. // Arguments: [sid] -- SID of modified dirEntry
  395. //
  396. // Returns: S_OK if call completed OK.
  397. //
  398. // Algorithm: Convert SID into table number, then write that
  399. // table out to the parent Multistream
  400. //
  401. // History: 18-Feb-92 PhilipLa Created.
  402. //
  403. // Notes:
  404. //
  405. //--------------------------------------------------------------------------
  406. inline SCODE CDirectory::Flush(VOID)
  407. {
  408. return _dv.Flush();
  409. }
  410. //+---------------------------------------------------------------------------
  411. //
  412. // Member: CDirectory::GetNumDirSects, public
  413. //
  414. // Synopsis: Return the size of the directory in sectors
  415. //
  416. // Arguments: None.
  417. //
  418. // Returns: Size of directory chain in sectors
  419. //
  420. // History: 01-Jun-94 PhilipLa Created
  421. //
  422. //----------------------------------------------------------------------------
  423. inline ULONG CDirectory::GetNumDirSects(void) const
  424. {
  425. return _cdsTable;
  426. }
  427. //+---------------------------------------------------------------------------
  428. //
  429. // Member: CDirectory::GetNumDirEntries, public
  430. //
  431. // Synopsis: Return the size of the directory in Entries.
  432. //
  433. // Arguments: None.
  434. //
  435. // Returns: Size of directory chain in Directory Entries.
  436. //
  437. // History: 14-Feb-97 BChapman Created
  438. //
  439. //----------------------------------------------------------------------------
  440. inline ULONG CDirectory::GetNumDirEntries(void) const
  441. {
  442. return (_cdsTable * _cdeEntries);
  443. }
  444. //+---------------------------------------------------------------------------
  445. //
  446. // Member: CDirectory::IsLargeSector, public
  447. //
  448. // Synopsis: Return true if this is a large sector docfile
  449. //
  450. // Arguments: None.
  451. //
  452. // Returns: true if _cdeEntries > 4
  453. //
  454. // History: 03-Sep-98 HenryLee Created
  455. //
  456. //----------------------------------------------------------------------------
  457. inline BOOL CDirectory::IsLargeSector () const
  458. {
  459. return (_cdeEntries > (HEADERSIZE / DIRENTRYSIZE));
  460. }
  461. #endif // #ifndef __DIRFUNC_HXX__