Windows NT 4.0 source code leak
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.

307 lines
7.0 KiB

4 years ago
  1. /***************************************************************************\
  2. *
  3. * FSREAD.C
  4. *
  5. * Copyright (C) Microsoft Corporation 1990.
  6. * All Rights reserved.
  7. *
  8. *****************************************************************************
  9. *
  10. * Program Description: File System Manager functions for read and seek
  11. *
  12. *****************************************************************************
  13. *
  14. * Revision History: Created 03/12/90 by JohnSc
  15. *
  16. *
  17. *****************************************************************************
  18. *
  19. * Known Bugs: None
  20. *
  21. \***************************************************************************/
  22. #include <windows.h>
  23. #include <orkin.h>
  24. #include "_mvfs.h"
  25. #include "imvfs.h"
  26. #include "fspriv.h"
  27. /***************************************************************************\
  28. * *
  29. * Private Functions *
  30. * *
  31. \***************************************************************************/
  32. /***************************************************************************\
  33. *
  34. * Function: FPlungeQfshr( qfshr )
  35. *
  36. * Purpose: Get back a qfshr->fid that was flushed
  37. *
  38. * ASSUMES
  39. *
  40. * args IN: qfshr - fid need not be valid
  41. *
  42. * PROMISES
  43. *
  44. * returns: fTruth of success
  45. *
  46. * args OUT: qfshr->fid is valid (or we return FALSE)
  47. *
  48. * globals OUT: rcFSError
  49. *
  50. \***************************************************************************/
  51. BOOL PASCAL
  52. FPlungeQfshr( qfshr )
  53. #ifdef SCROLL_TUNE
  54. #pragma alloc_text(SCROLLER_TEXT, FPlungeQfshr)
  55. #endif
  56. QFSHR qfshr;
  57. {
  58. if ( qfshr->fid == fidNil )
  59. {
  60. qfshr->fid = FidOpenFm( (qfshr->fm),
  61. qfshr->fsh.bFlags & fFSOpenReadOnly
  62. ? wReadOnly | wShareRead
  63. : wReadWrite | wShareRead );
  64. if ( qfshr->fid == fidNil )
  65. {
  66. SetFSErrorRc( RcGetIOError() );
  67. return FALSE;
  68. }
  69. /*
  70. Check size of file, then reset file pointer.
  71. Certain 0-length files (eg con) give us no end of grief if
  72. we try to read from them, and since a 0-length file could
  73. not possibly be a valid FS, we reject the notion.
  74. */
  75. if ( LSeekFid( qfshr->fid, 0L, wSeekEnd ) < sizeof(FSH) )
  76. {
  77. SetFSErrorRc( rcInvalid );
  78. return FALSE;
  79. }
  80. LSeekFid( qfshr->fid, 0L, wSeekSet );
  81. }
  82. SetFSErrorRc( rcSuccess );
  83. return TRUE;
  84. }
  85. /***************************************************************************\
  86. * *
  87. * Public Functions *
  88. * *
  89. \***************************************************************************/
  90. /***************************************************************************\
  91. *
  92. * Function: LcbReadHf()
  93. *
  94. * Purpose: read bytes from a file in a file system
  95. *
  96. * ASSUMES
  97. *
  98. * args IN: hf - file
  99. * lcb - number of bytes to read
  100. *
  101. * PROMISES
  102. *
  103. * returns: number of bytes actually read; -1 on error
  104. *
  105. * args OUT: qb - data read from file goes here (must be big enough)
  106. *
  107. * Notes: These are signed longs we're dealing with. This means
  108. * behaviour is different from read() when < 0.
  109. *
  110. \***************************************************************************/
  111. LONG PASCAL
  112. LcbReadHf( hf, qb, lcb )
  113. #ifdef SCROLL_TUNE
  114. #pragma alloc_text(SCROLLER_TEXT,LcbReadHf)
  115. #endif
  116. HF hf;
  117. QV qb;
  118. LONG lcb;
  119. {
  120. QRWFO qrwfo;
  121. LONG lcbTotalRead;
  122. FID fid;
  123. LONG lifOffset;
  124. DPF3("LcbRead hf %u, bytes %lu ", hf, lcb);
  125. assert( hf != NULL );
  126. qrwfo = QLockGh( hf );
  127. assert( qrwfo != NULL );
  128. DPF3(" current %ld ", qrwfo->lifCurrent);
  129. SetFSErrorRc( rcSuccess );
  130. if ( lcb < (LONG)0 )
  131. {
  132. SetFSErrorRc( rcBadArg );
  133. UnlockGh( hf );
  134. DPF3(" error, lcb<0\n");
  135. return (LONG)-1;
  136. }
  137. if ( qrwfo->lifCurrent + lcb > qrwfo->lcbFile )
  138. {
  139. lcb = qrwfo->lcbFile - qrwfo->lifCurrent;
  140. if ( lcb <= (LONG)0 )
  141. {
  142. UnlockGh( hf );
  143. DPF3(" error, returning 0\n");
  144. return (LONG)0;
  145. }
  146. }
  147. /* position file pointer for read */
  148. if ( qrwfo->bFlags & fFSDirty )
  149. {
  150. fid = qrwfo->fidT;
  151. lifOffset = (LONG)0;
  152. }
  153. else
  154. {
  155. QFSHR qfshr = QLockGh( qrwfo->hfs );
  156. if ( !FPlungeQfshr( qfshr ) )
  157. {
  158. UnlockGh( qrwfo->hfs );
  159. UnlockGh( hf );
  160. DPF3(" error, returning -1\n");
  161. return (LONG)-1;
  162. }
  163. fid = qfshr->fid;
  164. lifOffset = qrwfo->lifBase;
  165. UnlockGh( qrwfo->hfs );
  166. }
  167. if ( LSeekFid( fid, lifOffset + sizeof( FH ) + qrwfo->lifCurrent, wSeekSet )
  168. !=
  169. lifOffset + sizeof( FH ) + qrwfo->lifCurrent )
  170. {
  171. if ( RcGetIOError() == rcSuccess )
  172. SetFSErrorRc( rcInvalid );
  173. else
  174. SetFSErrorRc( RcGetIOError() );
  175. UnlockGh( hf );
  176. DPF3(" error 2, returning -1\n");
  177. return (LONG)-1;
  178. }
  179. /* read the data */
  180. lcbTotalRead = LcbReadFid( fid, qb, lcb );
  181. SetFSErrorRc( RcGetIOError() );
  182. /* update file pointer */
  183. if ( lcbTotalRead >= 0 )
  184. {
  185. qrwfo->lifCurrent += lcbTotalRead;
  186. assert(qrwfo->lifCurrent>=0);
  187. }
  188. UnlockGh( hf );
  189. DPF3(" now %ld ", qrwfo->lifCurrent);
  190. DPF3(" read %ld\n", lcbTotalRead);
  191. return lcbTotalRead;
  192. }
  193. /***************************************************************************\
  194. *
  195. * Function: LSeekHf( hf, lOffset, wOrigin )
  196. *
  197. * Purpose: set current file pointer
  198. *
  199. * ASSUMES
  200. *
  201. * args IN: hf - file
  202. * lOffset - offset from origin
  203. * wOrigin - origin (wSeekSet, wSeekCur, or wSeekEnd)
  204. *
  205. * PROMISES
  206. *
  207. * returns: new position offset in bytes from beginning of file
  208. * if successful, or -1L if not
  209. *
  210. * state OUT: File pointer is set to new position unless error occurs,
  211. * in which case it stays where it was.
  212. *
  213. \***************************************************************************/
  214. LONG PASCAL
  215. LSeekHf(
  216. HF hf,
  217. LONG lOffset, /* should this be named li? */
  218. WORD wOrigin)
  219. {
  220. QRWFO qrwfo;
  221. LONG lif;
  222. DPF3("LSeekHf %u, offs %ld, origin %u ", hf, lOffset, wOrigin);
  223. assert( hf != NULL );
  224. qrwfo = QLockGh( hf );
  225. assert( qrwfo != NULL );
  226. DPF3(" current %ld ", qrwfo->lifCurrent);
  227. switch ( wOrigin )
  228. {
  229. case wFSSeekSet:
  230. {
  231. lif = lOffset;
  232. break;
  233. }
  234. case wFSSeekCur:
  235. {
  236. lif = qrwfo->lifCurrent + lOffset;
  237. break;
  238. }
  239. case wFSSeekEnd:
  240. {
  241. lif = qrwfo->lcbFile + lOffset;
  242. break;
  243. }
  244. default:
  245. {
  246. lif = (LONG)-1;
  247. break;
  248. }
  249. }
  250. if ( lif >= (LONG)0 )
  251. {
  252. qrwfo->lifCurrent = lif;
  253. assert(qrwfo->lifCurrent>=0);
  254. SetFSErrorRc( rcSuccess );
  255. }
  256. else
  257. {
  258. lif = (LONG)-1;
  259. SetFSErrorRc( rcInvalid );
  260. }
  261. DPF3(" now %ld ", qrwfo->lifCurrent);
  262. UnlockGh( hf );
  263. DPF3(" returning %ld\n", lif);
  264. return lif;
  265. }