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.

415 lines
10 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1992.
  5. //
  6. // File: mread.hxx
  7. //
  8. // Contents: Multistream inline functions
  9. //
  10. // Classes: None.
  11. //
  12. // Functions: None
  13. //
  14. // History: 21-Apr-92 PhilipLa Created.
  15. //
  16. //--------------------------------------------------------------------------
  17. #ifndef __MREAD_HXX__
  18. #define __MREAD_HXX__
  19. #include <difat.hxx>
  20. #include <sstream.hxx>
  21. //+-------------------------------------------------------------------------
  22. //
  23. // Function: ConvertSectAndOffset
  24. //
  25. // Synopsis: Convert a sector and offset into a byte offset in
  26. // a stream.
  27. //
  28. // Arguments: [sect] -- Sector
  29. // [off] -- Offset
  30. // [uShift] -- Shift count for sectorsize
  31. //
  32. // Returns: Byte offset into stream.
  33. //
  34. // Algorithm: The byte offset is sect left-shifted uShift times,
  35. // plus the offset, plus SECTORSIZE bytes for the
  36. // header.
  37. //
  38. // History: 21-Apr-92 PhilipLa Created.
  39. // 05-May-92 PhilipLa Changed to use << instead of *
  40. //
  41. //--------------------------------------------------------------------------
  42. #ifdef LARGE_DOCFILE
  43. inline ULONGLONG ConvertSectOffset(SECT sect,
  44. OFFSET off,
  45. USHORT uShift)
  46. {
  47. ULONGLONG ulTemp = ((ULONGLONG)(sect+1) << uShift) + (ULONG)off;
  48. msfDebugOut((DEB_ITRACE,"Convert got %Lu\n",ulTemp));
  49. return ulTemp;
  50. }
  51. #else
  52. inline ULONG ConvertSectOffset(SECT sect,
  53. OFFSET off,
  54. USHORT uShift)
  55. {
  56. ULONG ulTemp = ((ULONG)sect << uShift) + HEADERSIZE +
  57. (ULONG)off;
  58. msfDebugOut((DEB_ITRACE,"Convert got %lu\n",ulTemp));
  59. return ulTemp;
  60. }
  61. #endif
  62. //+-------------------------------------------------------------------------
  63. //
  64. // Method: CMStream::GetStart, public
  65. //
  66. // Synopsis: Given an SID, return the starting sector
  67. //
  68. // Arguments: [sid] -- Sid to find start for
  69. //
  70. // Returns: Starting sector for given SID.
  71. //
  72. // History: 21-Apr-92 PhilipLa Created.
  73. //
  74. // Notes: This function only works for controls structures,
  75. // not for ordinary streams.
  76. //
  77. //--------------------------------------------------------------------------
  78. inline SECT CMStream::GetStart(SID sid) const
  79. {
  80. SECT sectRet = ENDOFCHAIN;
  81. msfAssert(sid > MAXREGSID);
  82. switch (sid)
  83. {
  84. case SIDFAT:
  85. sectRet = _hdr.GetFatStart();
  86. break;
  87. case SIDDIR:
  88. sectRet = _hdr.GetDirStart();
  89. break;
  90. case SIDDIF:
  91. sectRet = _hdr.GetDifStart();
  92. break;
  93. case SIDMINIFAT:
  94. sectRet = _hdr.GetMiniFatStart();
  95. break;
  96. default:
  97. msfAssert(FALSE && aMsg("Bad SID passed to CMStream::GetStart()"));
  98. }
  99. return sectRet;
  100. }
  101. //+---------------------------------------------------------------------------
  102. //
  103. // Member: CMStream::GetSize, public
  104. //
  105. // Synopsis: Return the size (in bytes) of a control structure chain
  106. //
  107. // Arguments: [sid] -- SID of chain
  108. // [pulSize] -- Location for return
  109. //
  110. // Returns: Appropriate status code
  111. //
  112. // History: 01-Jun-94 PhilipLa Created
  113. //
  114. // Notes: SID must be SIDDIR or SIDMINIFAT - other structures
  115. // do not have chains.
  116. //
  117. //----------------------------------------------------------------------------
  118. #ifdef LARGE_STREAMS
  119. inline SCODE CMStream::GetSize(SID sid, ULONGLONG *pulSize)
  120. #else
  121. inline SCODE CMStream::GetSize(SID sid, ULONG *pulSize)
  122. #endif
  123. {
  124. msfAssert(((sid == SIDDIR) || (sid == SIDMINIFAT)) &&
  125. aMsg("Bad SID passed to CMStream::GetSize()"));
  126. ULONG csect;
  127. if (SIDDIR == sid)
  128. {
  129. csect = _dir.GetNumDirSects();
  130. }
  131. else
  132. {
  133. csect = _hdr.GetMiniFatLength();
  134. }
  135. *pulSize = csect * GetSectorSize();
  136. return S_OK;
  137. }
  138. //+---------------------------------------------------------------------------
  139. //
  140. // Member: CMStream::GetSect, private
  141. //
  142. // Synopsis: For a given SID and sect, return the location of that
  143. // sector in the multistream.
  144. //
  145. // Arguments: [sid] -- SID of sector to locate
  146. // [sect] -- Offset into chain to locate
  147. // [psect] -- Pointer to return location.
  148. //
  149. // Returns: Appropriate status code
  150. //
  151. // Modifies:
  152. //
  153. // History: 22-Oct-92 PhilipLa Created
  154. //
  155. // Notes:
  156. //
  157. //----------------------------------------------------------------------------
  158. inline SCODE CMStream::GetSect(SID sid, SECT sect, SECT *psect)
  159. {
  160. SCODE sc = S_OK;
  161. SECT start = ENDOFCHAIN;
  162. switch (sid)
  163. {
  164. case SIDFAT:
  165. msfChk(_fatDif.GetFatSect(sect, &start));
  166. break;
  167. case SIDDIF:
  168. msfChk(_fatDif.GetSect(sect, &start));
  169. break;
  170. case SIDMINIFAT:
  171. case SIDDIR:
  172. CStreamCache *pstmc;
  173. pstmc = (sid == SIDDIR) ? &_stmcDir : &_stmcMiniFat;
  174. msfChk(pstmc->GetSect(sect, &start));
  175. break;
  176. default:
  177. msfAssert(FALSE && aMsg("Bad SID passed to CMStream::GetSect()"));
  178. }
  179. *psect = start;
  180. Err:
  181. return sc;
  182. }
  183. //+---------------------------------------------------------------------------
  184. //
  185. // Member: CMStream::GetESect, private
  186. //
  187. // Synopsis: For a given SID and sect, return the location of that
  188. // sector in the multistream.
  189. //
  190. // Arguments: [sid] -- SID of sector to locate
  191. // [sect] -- Offset into chain to locate
  192. // [psect] -- Pointer to return location.
  193. //
  194. // Returns: Appropriate status code
  195. //
  196. // Modifies:
  197. //
  198. // History: 22-Oct-92 PhilipLa Created
  199. //
  200. // Notes:
  201. //
  202. //----------------------------------------------------------------------------
  203. inline SCODE CMStream::GetESect(SID sid, SECT sect, SECT *psect)
  204. {
  205. SCODE sc = S_OK;
  206. SECT start = ENDOFCHAIN;
  207. SECT sectNewStart, sectOldStart, sectNewEnd, sectOldEnd;
  208. if ((_fBlockHeader) && (!_fBlockWrite))
  209. {
  210. switch (sid)
  211. {
  212. case SIDFAT:
  213. SECT sectTest;
  214. msfChk(_fatDif.Remap(sect, &sectTest));
  215. if (sectTest != ENDOFCHAIN)
  216. {
  217. msfChk(_fatDif.Fixup(BP_TO_P(CMStream *, _pmsShadow)));
  218. }
  219. break;
  220. case SIDMINIFAT:
  221. case SIDDIR:
  222. CStreamCache *pstmc;
  223. pstmc = (sid == SIDDIR) ? &_stmcDir : &_stmcMiniFat;
  224. if (sect != 0)
  225. {
  226. msfChk(pstmc->GetSect(sect - 1, &start));
  227. msfChk(_fat.Remap(
  228. start,
  229. 1,
  230. 1,
  231. &sectOldStart,
  232. &sectNewStart,
  233. &sectOldEnd,
  234. &sectNewEnd));
  235. }
  236. else
  237. {
  238. start = GetStart(sid);
  239. msfChk(_fat.Remap(
  240. start,
  241. 0,
  242. 1,
  243. &sectOldStart,
  244. &sectNewStart,
  245. &sectOldEnd,
  246. &sectNewEnd));
  247. }
  248. //Must drop this value from the cache if it's in there.
  249. if (sc != S_FALSE)
  250. {
  251. pstmc->EmptyRegion(sect, sect + 1);
  252. }
  253. break;
  254. case SIDDIF:
  255. break;
  256. default:
  257. msfAssert(FALSE && aMsg("Bad SID passed to CMStream::GetESect()"));
  258. }
  259. }
  260. switch (sid)
  261. {
  262. case SIDFAT:
  263. msfChk(_fatDif.GetFatSect(sect, &start));
  264. break;
  265. case SIDDIF:
  266. msfChk(_fatDif.GetSect(sect, &start));
  267. break;
  268. case SIDMINIFAT:
  269. case SIDDIR:
  270. CStreamCache *pstmc;
  271. pstmc = (sid == SIDDIR) ? &_stmcDir : &_stmcMiniFat;
  272. msfChk(pstmc->GetESect(sect, &start));
  273. break;
  274. default:
  275. msfAssert(FALSE && aMsg("Bad SID passed to CMStream::GetESect()"));
  276. }
  277. *psect = start;
  278. Err:
  279. return sc;
  280. }
  281. //+-------------------------------------------------------------------------
  282. //
  283. // Member: CMStream::SetSize, public
  284. //
  285. // Synposis: Sets the size of the parent LStream to match
  286. // current Fat information.
  287. //
  288. // Arguments: None.
  289. //
  290. // Returns: Error code from call to parent LStream SetSize()
  291. //
  292. // Algorithm: Query the Fat for the last sector used.
  293. // Convert that sector into a byte offset.
  294. // Call SetSize on the parent LStream.
  295. //
  296. // History: 30-Jul-91 PhilipLa Created.
  297. // 07-Jan-92 PhilipLa Converted to use handles.
  298. // 14-May-92 AlexT Move code to CDirectStream::SetSize
  299. //
  300. //
  301. //---------------------------------------------------------------------------
  302. inline SCODE CMStream::SetSize(VOID)
  303. {
  304. SCODE sc = S_OK;
  305. #ifdef LARGE_DOCFILE
  306. ULONGLONG ulSize;
  307. #else
  308. ULONG ulSize;
  309. #endif
  310. ULARGE_INTEGER cbSize;
  311. msfDebugOut((DEB_ITRACE, "In CMStream::SetSize()\n"));
  312. SECT sectMax;
  313. if (!_fBlockWrite)
  314. {
  315. msfChk(_fat.GetMaxSect(&sectMax));
  316. ulSize = ConvertSectOffset(sectMax, 0, GetSectorShift());
  317. if (ulSize > _ulParentSize)
  318. {
  319. #ifdef LARGE_DOCFILE
  320. cbSize.QuadPart = ulSize;
  321. #else
  322. ULISet32(cbSize, ulSize);
  323. #endif
  324. msfHChk((*_pplstParent)->SetSize(cbSize));
  325. }
  326. }
  327. msfDebugOut((DEB_ITRACE, "Out CMStream::SetSize()\n"));
  328. Err:
  329. return sc;
  330. }
  331. //+-------------------------------------------------------------------------
  332. //
  333. // Member: CMStream::SetMiniSize, public
  334. //
  335. // Synposis: Sets the size of the MiniFat storage stream to match
  336. // current Fat information.
  337. //
  338. // Arguments: None.
  339. //
  340. // Returns: Error code from call to stream SetSize()
  341. //
  342. // Algorithm: Query the Fat for the last sector used.
  343. // Convert that sector into a byte offset.
  344. // Call SetSize on the Minifat storage stream.
  345. //
  346. // History: 14-May-92 AlexT Created.
  347. //
  348. //
  349. //---------------------------------------------------------------------------
  350. inline SCODE CMStream::SetMiniSize(VOID)
  351. {
  352. SCODE sc;
  353. ULONG ulNewSize;
  354. SECT sectMax;
  355. msfChk(_fatMini.GetMaxSect(&sectMax));
  356. ulNewSize = sectMax << MINISECTORSHIFT;
  357. msfChk(_pdsministream->CDirectStream::SetSize(ulNewSize));
  358. Err:
  359. return sc;
  360. }
  361. #endif //__MREAD_HXX__