windows-nt/Source/XPSP1/NT/base/mvdm/wow16/write/transfer.c
2020-09-26 16:20:57 +08:00

223 lines
5.8 KiB
C
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/************************************************************/
/* Windows Write, Copyright 1985-1992 Microsoft Corporation */
/************************************************************/
#define NOCLIPBOARD
#define NOGDICAPMASKS
#define NOCTLMGR
#define NOVIRTUALKEYCODES
#define NOWINMESSAGES
#define NOWINSTYLES
#define NOSYSMETRICS
#define NOMENUS
#include <windows.h>
#include "mw.h"
#include "doslib.h"
#include "cmddefs.h"
#include "docdefs.h"
#include "filedefs.h"
#include "str.h"
#include "debug.h"
extern int vfnWriting;
#define IibpHash(fn,pn) ((int) ((fn + 1) * (pn + 1)) & 077777) % iibpHashMax
#define FcMin(a,b) CpMin(a,b)
extern CHAR *rgibpHash;
extern int vfSysFull;
extern struct BPS *mpibpbps;
extern struct FCB (**hpfnfcb)[];
extern typeTS tsMruBps;
extern CHAR (*rgbp)[cbSector];
#ifdef CKSM
#ifdef DEBUG
extern unsigned (**hpibpcksm) [];
#endif
#endif
/* WriteDirtyPages kicks out of memory as much of the previous files as it can
in order to fill the page buffers with a new file. This is called on
every transfer load of a file. */
WriteDirtyPages()
{/*
Description: Cleans the buffer pool of all dirty pages by writing them
out to disk. If a disk full condition is reached, only
pages which actually made it to disk are marked as non
dirty.
Returns: nothing.
*/
int ibp;
struct BPS *pbps = &mpibpbps [0];
for (ibp = 0; ibp < ibpMax; ++ibp, ++pbps)
{
#ifdef CKSM
#ifdef DEBUG
if (pbps->fn != fnNil && !pbps->fDirty)
Assert( (**hpibpcksm) [ibp] == CksmFromIbp( ibp ) );
#endif
#endif
if (pbps->fn != fnNil && pbps->fDirty)
{
FFlushFn(pbps->fn);
/* keep on flushing if failure ? */
}
}
}
ReadFilePages(fn)
int fn;
{
/*
Description: ReadFilePages tries to read in as much of a file as
it can. The idea is to fill the page buffers in anticipation of
much access. This is called on every Transfer Load of a file.
If fn == fnNil or there are no characters in the file, ReadFilePages
simply returns.
Returns: nothing
*/
int ibp;
int cfcRead;
int cpnRead;
int dfcMac;
typeFC fcMac;
int ibpReadMax;
int cfcLastPage;
int iibp;
struct FCB *pfcb;
typeTS ts;
if (fn == fnNil)
return;
/* Write ALL dirty pages to disk */
WriteDirtyPages(); /* Just in case */
pfcb = &(**hpfnfcb)[fn];
/* we read as much of the file as will fit in the page buffers */
/* Note that we assume that fcMax is coercable to an integer. This
is valid as long as ibpMax*cbSector < 32k */
dfcMac = (int) FcMin(pfcb->fcMac, (typeFC) (ibpMax * cbSector));
if (dfcMac == 0)
return;
if (vfSysFull) /* call to FFlushFn in WriteDirtyPages failed.
the buffer algorithm assures us that the first
cbpMustKeep ibp's do not contain scratch file
information. Thus, there is no danger in overwriting
these ibps. */
dfcMac = imin( dfcMac, (cbpMustKeep * cbSector) );
Assert( ((int)dfcMac) >= 0 );
/* Read pages from the file */
cfcRead = CchReadAtPage( fn, (typePN) 0, rgbp [0], (int) dfcMac, FALSE );
/* cfcRead contains a count of bytes read from the file */
ibpReadMax = ((cfcRead-1) / cbSector) + 1;
cfcLastPage = cfcRead - (ibpReadMax-1)*cbSector;
ts = ibpMax;
/* order time stamps so the beginning slots have the greatest ts.
Lru allocation will start at the end of the buffer table and work
backward. Thus, the first page of the current file is considered
the most recently used item.
*/
/* describe the newly filled pages */
for(ibp = 0; ibp < ibpReadMax; ++ibp)
{
struct BPS *pbps = &mpibpbps[ibp];
pbps->fn = fn;
pbps->pn = ibp;
pbps->ts = --ts;
pbps->fDirty = false;
pbps->cch = cbSector;
pbps->ibpHashNext = ibpNil;
}
#ifdef CKSM
#ifdef DEBUG
{
int ibpT;
for ( ibpT = 0; ibpT < ibpReadMax; ibpT++ )
(**hpibpcksm) [ibpT] = CksmFromIbp( ibpT );
}
#endif
#endif
/* fix some boundary conditions */
mpibpbps[ibpReadMax-1].cch = cfcLastPage; /* ?????? */
#ifdef CKSM
#ifdef DEBUG
(**hpibpcksm) [ibpReadMax - 1] = CksmFromIbp( ibpReadMax - 1 );
#endif
#endif
/* update descriptions of untouched page buffers */
for (ibp=ibpReadMax; ibp < ibpMax; ibp++)
{
struct BPS *pbps = &mpibpbps[ibp];
pbps->ts = --ts;
pbps->fDirty = false;
pbps->ibpHashNext = ibpNil;
#ifdef CKSM
#ifdef DEBUG
if (pbps->fn != fnNil)
(**hpibpcksm) [ibp] = CksmFromIbp( ibp );
#endif
#endif
}
tsMruBps = ibpMax - 1;
/* recalculate the hash table */
RehashRgibpHash();
} /* end of R e a d F i l e P a g e s */
RehashRgibpHash()
{
int iibp;
register struct BPS *pbps;
struct BPS *pbpsMax = &mpibpbps[ibpMax];
int iibpHash;
int ibpT;
int ibpPrev;
int ibp;
for (iibp = 0; iibp < iibpHashMax; iibp++)
rgibpHash[iibp] = ibpNil;
for (ibp = 0, pbps = &mpibpbps[0]; pbps < pbpsMax; pbps++, ibp++)
{
if (pbps->fn == fnNil)
continue;
iibpHash = IibpHash(pbps->fn, pbps->pn);
ibpT = rgibpHash[iibpHash];
ibpPrev = ibpNil;
while (ibpT != ibpNil)
{
ibpPrev = ibpT;
ibpT = mpibpbps[ibpT].ibpHashNext;
}
if (ibpPrev == ibpNil)
rgibpHash[iibpHash] = ibp;
else
mpibpbps[ibpPrev].ibpHashNext = ibp;
}
#ifdef DEBUG
CheckIbp();
#endif
} /* end of RehashRgibpHash */