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.

222 lines
5.8 KiB

  1. /************************************************************/
  2. /* Windows Write, Copyright 1985-1992 Microsoft Corporation */
  3. /************************************************************/
  4. #define NOCLIPBOARD
  5. #define NOGDICAPMASKS
  6. #define NOCTLMGR
  7. #define NOVIRTUALKEYCODES
  8. #define NOWINMESSAGES
  9. #define NOWINSTYLES
  10. #define NOSYSMETRICS
  11. #define NOMENUS
  12. #include <windows.h>
  13. #include "mw.h"
  14. #include "doslib.h"
  15. #include "cmddefs.h"
  16. #include "docdefs.h"
  17. #include "filedefs.h"
  18. #include "str.h"
  19. #include "debug.h"
  20. extern int vfnWriting;
  21. #define IibpHash(fn,pn) ((int) ((fn + 1) * (pn + 1)) & 077777) % iibpHashMax
  22. #define FcMin(a,b) CpMin(a,b)
  23. extern CHAR *rgibpHash;
  24. extern int vfSysFull;
  25. extern struct BPS *mpibpbps;
  26. extern struct FCB (**hpfnfcb)[];
  27. extern typeTS tsMruBps;
  28. extern CHAR (*rgbp)[cbSector];
  29. #ifdef CKSM
  30. #ifdef DEBUG
  31. extern unsigned (**hpibpcksm) [];
  32. #endif
  33. #endif
  34. /* WriteDirtyPages kicks out of memory as much of the previous files as it can
  35. in order to fill the page buffers with a new file. This is called on
  36. every transfer load of a file. */
  37. WriteDirtyPages()
  38. {/*
  39. Description: Cleans the buffer pool of all dirty pages by writing them
  40. out to disk. If a disk full condition is reached, only
  41. pages which actually made it to disk are marked as non
  42. dirty.
  43. Returns: nothing.
  44. */
  45. int ibp;
  46. struct BPS *pbps = &mpibpbps [0];
  47. for (ibp = 0; ibp < ibpMax; ++ibp, ++pbps)
  48. {
  49. #ifdef CKSM
  50. #ifdef DEBUG
  51. if (pbps->fn != fnNil && !pbps->fDirty)
  52. Assert( (**hpibpcksm) [ibp] == CksmFromIbp( ibp ) );
  53. #endif
  54. #endif
  55. if (pbps->fn != fnNil && pbps->fDirty)
  56. {
  57. FFlushFn(pbps->fn);
  58. /* keep on flushing if failure ? */
  59. }
  60. }
  61. }
  62. ReadFilePages(fn)
  63. int fn;
  64. {
  65. /*
  66. Description: ReadFilePages tries to read in as much of a file as
  67. it can. The idea is to fill the page buffers in anticipation of
  68. much access. This is called on every Transfer Load of a file.
  69. If fn == fnNil or there are no characters in the file, ReadFilePages
  70. simply returns.
  71. Returns: nothing
  72. */
  73. int ibp;
  74. int cfcRead;
  75. int cpnRead;
  76. int dfcMac;
  77. typeFC fcMac;
  78. int ibpReadMax;
  79. int cfcLastPage;
  80. int iibp;
  81. struct FCB *pfcb;
  82. typeTS ts;
  83. if (fn == fnNil)
  84. return;
  85. /* Write ALL dirty pages to disk */
  86. WriteDirtyPages(); /* Just in case */
  87. pfcb = &(**hpfnfcb)[fn];
  88. /* we read as much of the file as will fit in the page buffers */
  89. /* Note that we assume that fcMax is coercable to an integer. This
  90. is valid as long as ibpMax*cbSector < 32k */
  91. dfcMac = (int) FcMin(pfcb->fcMac, (typeFC) (ibpMax * cbSector));
  92. if (dfcMac == 0)
  93. return;
  94. if (vfSysFull) /* call to FFlushFn in WriteDirtyPages failed.
  95. the buffer algorithm assures us that the first
  96. cbpMustKeep ibp's do not contain scratch file
  97. information. Thus, there is no danger in overwriting
  98. these ibps. */
  99. dfcMac = imin( dfcMac, (cbpMustKeep * cbSector) );
  100. Assert( ((int)dfcMac) >= 0 );
  101. /* Read pages from the file */
  102. cfcRead = CchReadAtPage( fn, (typePN) 0, rgbp [0], (int) dfcMac, FALSE );
  103. /* cfcRead contains a count of bytes read from the file */
  104. ibpReadMax = ((cfcRead-1) / cbSector) + 1;
  105. cfcLastPage = cfcRead - (ibpReadMax-1)*cbSector;
  106. ts = ibpMax;
  107. /* order time stamps so the beginning slots have the greatest ts.
  108. Lru allocation will start at the end of the buffer table and work
  109. backward. Thus, the first page of the current file is considered
  110. the most recently used item.
  111. */
  112. /* describe the newly filled pages */
  113. for(ibp = 0; ibp < ibpReadMax; ++ibp)
  114. {
  115. struct BPS *pbps = &mpibpbps[ibp];
  116. pbps->fn = fn;
  117. pbps->pn = ibp;
  118. pbps->ts = --ts;
  119. pbps->fDirty = false;
  120. pbps->cch = cbSector;
  121. pbps->ibpHashNext = ibpNil;
  122. }
  123. #ifdef CKSM
  124. #ifdef DEBUG
  125. {
  126. int ibpT;
  127. for ( ibpT = 0; ibpT < ibpReadMax; ibpT++ )
  128. (**hpibpcksm) [ibpT] = CksmFromIbp( ibpT );
  129. }
  130. #endif
  131. #endif
  132. /* fix some boundary conditions */
  133. mpibpbps[ibpReadMax-1].cch = cfcLastPage; /* ?????? */
  134. #ifdef CKSM
  135. #ifdef DEBUG
  136. (**hpibpcksm) [ibpReadMax - 1] = CksmFromIbp( ibpReadMax - 1 );
  137. #endif
  138. #endif
  139. /* update descriptions of untouched page buffers */
  140. for (ibp=ibpReadMax; ibp < ibpMax; ibp++)
  141. {
  142. struct BPS *pbps = &mpibpbps[ibp];
  143. pbps->ts = --ts;
  144. pbps->fDirty = false;
  145. pbps->ibpHashNext = ibpNil;
  146. #ifdef CKSM
  147. #ifdef DEBUG
  148. if (pbps->fn != fnNil)
  149. (**hpibpcksm) [ibp] = CksmFromIbp( ibp );
  150. #endif
  151. #endif
  152. }
  153. tsMruBps = ibpMax - 1;
  154. /* recalculate the hash table */
  155. RehashRgibpHash();
  156. } /* end of R e a d F i l e P a g e s */
  157. RehashRgibpHash()
  158. {
  159. int iibp;
  160. register struct BPS *pbps;
  161. struct BPS *pbpsMax = &mpibpbps[ibpMax];
  162. int iibpHash;
  163. int ibpT;
  164. int ibpPrev;
  165. int ibp;
  166. for (iibp = 0; iibp < iibpHashMax; iibp++)
  167. rgibpHash[iibp] = ibpNil;
  168. for (ibp = 0, pbps = &mpibpbps[0]; pbps < pbpsMax; pbps++, ibp++)
  169. {
  170. if (pbps->fn == fnNil)
  171. continue;
  172. iibpHash = IibpHash(pbps->fn, pbps->pn);
  173. ibpT = rgibpHash[iibpHash];
  174. ibpPrev = ibpNil;
  175. while (ibpT != ibpNil)
  176. {
  177. ibpPrev = ibpT;
  178. ibpT = mpibpbps[ibpT].ibpHashNext;
  179. }
  180. if (ibpPrev == ibpNil)
  181. rgibpHash[iibpHash] = ibp;
  182. else
  183. mpibpbps[ibpPrev].ibpHashNext = ibp;
  184. }
  185. #ifdef DEBUG
  186. CheckIbp();
  187. #endif
  188. } /* end of RehashRgibpHash */
  189. 
  190.