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.

461 lines
11 KiB

  1. //+-------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1996.
  5. //
  6. // File: fat.hxx
  7. //
  8. // Contents: Header file for fat classes
  9. //
  10. // Classes: CFatSect - sector sized array of sector info
  11. // CFatVector - resizable array of CFatSect
  12. // CFat - Grouping of FatSect
  13. //
  14. //--------------------------------------------------------------------
  15. #ifndef __FAT_HXX__
  16. #define __FAT_HXX__
  17. #include "vect.hxx"
  18. #define DEB_FAT (DEB_ITRACE|0x00010000)
  19. //+----------------------------------------------------------------------
  20. //
  21. // Class: CFatSect (fs)
  22. //
  23. // Purpose: Holds one sector worth of FAT data
  24. //
  25. // Interface: getsize - Returns the size of the FAT (in sectors)
  26. // contents - Returns contents of any given FAT entry
  27. //
  28. // Notes:
  29. //
  30. //-----------------------------------------------------------------------
  31. class CFatSect
  32. {
  33. public:
  34. SCODE Init(FSOFFSET uEntries);
  35. SCODE InitCopy(USHORT uSize, CFatSect& fsOld);
  36. inline SECT GetSect(const FSOFFSET sect) const;
  37. inline void SetSect(const FSOFFSET sect,const SECT sectNew);
  38. inline SECT GetNextFat(USHORT uSize) const;
  39. inline void SetNextFat(USHORT uSize, const SECT sect);
  40. inline void ByteSwap(USHORT cbSector);
  41. private:
  42. #ifdef _MSC_VER
  43. #pragma warning(disable: 4200)
  44. SECT _asectEntry[];
  45. #pragma warning(default: 4200)
  46. #endif
  47. #ifdef __GNUC__
  48. SECT _asectEntry[0];
  49. #endif
  50. };
  51. inline SECT CFatSect::GetSect(const FSOFFSET sect) const
  52. {
  53. return _asectEntry[sect];
  54. }
  55. inline void CFatSect::SetSect(const FSOFFSET sect,
  56. const SECT sectNew)
  57. {
  58. _asectEntry[sect] = sectNew;
  59. }
  60. inline SECT CFatSect::GetNextFat(USHORT uSize) const
  61. {
  62. return _asectEntry[uSize];
  63. }
  64. inline void CFatSect::SetNextFat(USHORT uSize, const SECT sect)
  65. {
  66. _asectEntry[uSize] = sect;
  67. }
  68. inline void CFatSect::ByteSwap(FSOFFSET cbSector)
  69. {
  70. // swap all sectors in the sector
  71. for (FSOFFSET i=0; i < cbSector; i++)
  72. ::ByteSwap(&(_asectEntry[i]));
  73. }
  74. //+-------------------------------------------------------------------------
  75. //
  76. // Class: CFatVector (fv)
  77. //
  78. // Purpose: *finish this*
  79. //
  80. // Interface:
  81. //
  82. // Notes:
  83. //
  84. //--------------------------------------------------------------------------
  85. class CFatVector: public CPagedVector
  86. {
  87. public:
  88. inline CFatVector( const SID sid,
  89. FSOFFSET csectBlock,
  90. FSOFFSET csectTable);
  91. SCODE InitPage(FSINDEX iPage);
  92. inline FSOFFSET GetSectBlock() const;
  93. inline FSOFFSET GetSectTable() const;
  94. inline SCODE GetTable( const FSINDEX iTable,
  95. const DWORD dwFlags,
  96. CFatSect **pfs);
  97. private:
  98. FSOFFSET const _csectTable;
  99. FSOFFSET const _csectBlock;
  100. inline void operator = (const CFatVector &that);
  101. #ifdef _MSC_VER
  102. #pragma warning(disable:4512)
  103. // since there is a const member, there should be no assignment operator
  104. #endif // _MSC_VER
  105. };
  106. #ifdef _MSC_VER
  107. #pragma warning(default:4512)
  108. #endif // _MSC_VER
  109. inline CFatVector::CFatVector(
  110. const SID sid,
  111. FSOFFSET csectBlock,
  112. FSOFFSET csectTable)
  113. : CPagedVector(sid),
  114. _csectTable(csectTable),
  115. _csectBlock(csectBlock)
  116. {
  117. }
  118. //+-------------------------------------------------------------------------
  119. //
  120. // Method: CFatVector::GetSectTable, public
  121. //
  122. // Synopsis: Returns count of sector entries per table
  123. //
  124. // Returns: count of sector entries per table
  125. //
  126. //--------------------------------------------------------------------------
  127. inline FSOFFSET CFatVector::GetSectTable() const
  128. {
  129. return _csectTable;
  130. }
  131. //+-------------------------------------------------------------------------
  132. //
  133. // Method: CFatVector::GetSectTable, public
  134. //
  135. // Synopsis: Returns count of sector entries per block
  136. //
  137. // Returns: count of sector entries per block
  138. //
  139. //--------------------------------------------------------------------------
  140. inline FSOFFSET CFatVector::GetSectBlock() const
  141. {
  142. return _csectBlock;
  143. }
  144. //+-------------------------------------------------------------------------
  145. //
  146. // Method: CFatVector::GetTable, public
  147. //
  148. // Synopsis: Return a pointer to a FatSect for the given index
  149. // into the vector.
  150. //
  151. // Arguments: [iTable] -- index into vector
  152. //
  153. // Returns: Pointer to CFatSect indicated by index
  154. //
  155. // Notes:
  156. //
  157. //--------------------------------------------------------------------------
  158. inline SCODE CFatVector::GetTable(
  159. const FSINDEX iTable,
  160. const DWORD dwFlags,
  161. CFatSect **ppfs)
  162. {
  163. SCODE sc;
  164. sc = CPagedVector::GetTable(iTable, dwFlags, (void **)ppfs);
  165. if (sc == STG_S_NEWPAGE)
  166. {
  167. (*ppfs)->Init(_csectBlock);
  168. }
  169. return sc;
  170. }
  171. //CSEG determines the maximum number of segments that will be
  172. //returned by a single Contig call.
  173. #define CSEG 32
  174. //+-------------------------------------------------------------------------
  175. //
  176. // Class: SSegment (seg)
  177. //
  178. // Purpose: Used for contiguity tables for multi-sector reads and
  179. // writes.
  180. //
  181. // Interface: None.
  182. //
  183. // Notes:
  184. //
  185. //--------------------------------------------------------------------------
  186. struct SSegment {
  187. public:
  188. SECT sectStart;
  189. ULONG cSect;
  190. };
  191. class CMStream;
  192. //+----------------------------------------------------------------------
  193. //
  194. // Class: CFat (fat)
  195. //
  196. // Purpose: Main interface to allocation routines
  197. //
  198. // Interface: Allocate - allocates new chain in the FAT
  199. // Extend - Extends an existing FAT chain
  200. // GetNext - Returns next sector in a chain
  201. // GetSect - Returns nth sector in a chain
  202. // GetESect - Returns nth sector in a chain, extending
  203. // if necessary
  204. // GetLength - Returns the # of sectors in a chain
  205. // setup - Initializes for an existing stream
  206. // setupnew - Initializes for a new stream
  207. //
  208. // checksanity - Debugging routine
  209. //
  210. // Notes:
  211. //
  212. //-----------------------------------------------------------------------
  213. class CFat
  214. {
  215. public:
  216. CFat(SID sid, USHORT cbSector, USHORT uSectorShift);
  217. ~CFat();
  218. VOID Empty(VOID);
  219. inline SCODE Allocate(ULONG ulSize, SECT *psectFirst);
  220. SCODE GetNext(const SECT sect, SECT * psRet);
  221. SCODE GetSect(
  222. SECT sectStart,
  223. ULONG ulOffset,
  224. SECT *psectReturn);
  225. SCODE GetESect(
  226. SECT sectStart,
  227. ULONG ulOffset,
  228. SECT *psectReturn);
  229. SCODE SetNext(SECT sectFirst, SECT sectNext);
  230. SCODE GetFree(ULONG ulCount, SECT *sect);
  231. SCODE GetLength(SECT sect, ULONG * pulRet);
  232. SCODE SetChainLength(SECT,ULONG);
  233. SCODE Init(
  234. CMStream *pmsParent,
  235. FSINDEX cFatSect,
  236. BOOL fConvert);
  237. SCODE InitNew(CMStream *pmsParent);
  238. SCODE InitConvert(
  239. CMStream *pmsParent,
  240. ULONG cbSize);
  241. SCODE FindLast(SECT *psectRet);
  242. SCODE FindMaxSect(SECT *psectRet);
  243. inline SCODE GetMaxSect(SECT *psectRet);
  244. SCODE Contig(
  245. SSegment STACKBASED *aseg,
  246. SECT sect,
  247. ULONG ulLength);
  248. inline SCODE Flush(VOID);
  249. inline void SetParent(CMStream *pms);
  250. inline BOOL IsRangeLocksSector (SECT sect);
  251. private:
  252. CFatVector _fv;
  253. CMStream * _pmsParent;
  254. const SID _sid;
  255. const USHORT _uFatShift;
  256. const USHORT _uFatMask;
  257. FSINDEX _cfsTable;
  258. ULONG _ulFreeSects;
  259. SECT _sectFirstFree;
  260. SECT _sectMax;
  261. FSINDEX _ipfsRangeLocks;
  262. FSOFFSET _isectRangeLocks;
  263. SCODE CountFree(ULONG * ulRet);
  264. SCODE Resize(ULONG);
  265. SCODE Extend(SECT,ULONG);
  266. inline VOID SectToPair(
  267. SECT sect,
  268. FSINDEX *pipfs,
  269. FSOFFSET *pisect) const;
  270. inline SECT PairToSect(FSINDEX ipfs, FSOFFSET isect) const;
  271. friend class CDIFat;
  272. inline void InitRangeLocksSector();
  273. #ifdef _MSC_VER
  274. #pragma warning(disable:4512)
  275. // since there is a const member, there should be no assignment operator
  276. #endif // _MSC_VER
  277. };
  278. #ifdef _MSC_VER
  279. #pragma warning(default:4512)
  280. #endif // _MSC_VER
  281. inline VOID CFat::SectToPair(SECT sect,FSINDEX *pipfs,FSOFFSET *pisect) const
  282. {
  283. *pipfs = (FSINDEX)(sect >> _uFatShift);
  284. *pisect = (FSOFFSET)(sect & _uFatMask);
  285. }
  286. inline SECT CFat::PairToSect(FSINDEX ipfs, FSOFFSET isect) const
  287. {
  288. return (ipfs << _uFatShift) + isect;
  289. }
  290. inline SCODE CFat::GetMaxSect(SECT *psectRet)
  291. {
  292. SCODE sc;
  293. msfChk(FindMaxSect(&_sectMax));
  294. *psectRet = _sectMax;
  295. Err:
  296. return sc;
  297. }
  298. inline void CFat::SetParent(CMStream *pms)
  299. {
  300. _pmsParent = pms;
  301. _fv.SetParent(pms);
  302. }
  303. //+-------------------------------------------------------------------------
  304. //
  305. // Member: CFat::Flush, public
  306. //
  307. // Synposis: Write all modified FatSects out to stream
  308. //
  309. // Effects: Resets all dirty bit fields on FatSects
  310. //
  311. // Arguments: Void
  312. //
  313. // Returns: S_OK if call completed OK.
  314. // Error code of parent write otherwise.
  315. //
  316. // Algorithm: Linearly scan through FatSects, writing any sector
  317. // that has the dirty bit set. Reset all dirty bits.
  318. //
  319. // Notes:
  320. //
  321. //---------------------------------------------------------------------------
  322. inline SCODE CFat::Flush(VOID)
  323. {
  324. return _fv.Flush();
  325. }
  326. //+-------------------------------------------------------------------------
  327. //
  328. // Member: CFat::Allocate, public
  329. //
  330. // Synposis: Allocates a chain within a FAT
  331. //
  332. // Effects: Modifies a single sector within the fat. Causes a
  333. // one sector stream write.
  334. //
  335. // Arguments: [ulSize] -- Number of sectors to allocate in chain
  336. //
  337. // Returns: Sector ID of first sector in chain
  338. //
  339. // Algorithm: Use repetitive calls to GetFree to construct a new chain
  340. //
  341. // Notes:
  342. //
  343. //---------------------------------------------------------------------------
  344. inline SCODE CFat::Allocate(ULONG ulSize, SECT * psectFirst)
  345. {
  346. return GetFree(ulSize, psectFirst);
  347. }
  348. inline void CFat::InitRangeLocksSector ()
  349. {
  350. const ULONG ulHeaderSize = 1 << (_uFatShift + 2);
  351. SECT sect = (OLOCKREGIONEND - ulHeaderSize) >> (_uFatShift + 2);
  352. SectToPair (sect, &_ipfsRangeLocks, &_isectRangeLocks);
  353. }
  354. inline BOOL CFat::IsRangeLocksSector (SECT sect)
  355. {
  356. FSINDEX ipfs;
  357. FSOFFSET isect;
  358. SectToPair(sect, &ipfs, &isect);
  359. return (ipfs == _ipfsRangeLocks && isect == _isectRangeLocks);
  360. }
  361. #endif //__FAT_HXX__