322 lines
7.8 KiB
C
322 lines
7.8 KiB
C
|
/************************************************************/
|
|||
|
/* Windows Write, Copyright 1985-1992 Microsoft Corporation */
|
|||
|
/************************************************************/
|
|||
|
|
|||
|
/* fileres.c -- functions from file.c that are usually resident */
|
|||
|
|
|||
|
#define NOCLIPBOARD
|
|||
|
#define NOGDICAPMASKS
|
|||
|
#define NOCTLMGR
|
|||
|
#define NOVIRTUALKEYCODES
|
|||
|
#define NOWINMESSAGES
|
|||
|
#define NOWINSTYLES
|
|||
|
#define NOSYSMETRICS
|
|||
|
#define NOMENUS
|
|||
|
#define NOICON
|
|||
|
#define NOKEYSTATE
|
|||
|
#define NORASTEROPS
|
|||
|
#define NOSHOWWINDOW
|
|||
|
#define NOSYSCOMMANDS
|
|||
|
#define NOATOM
|
|||
|
#define NOCOLOR
|
|||
|
#define NOCREATESTRUCT
|
|||
|
#define NOCTLMGR
|
|||
|
#define NODRAWTEXT
|
|||
|
#define NOMETAFILE
|
|||
|
#define NOMSG
|
|||
|
#define NOHDC
|
|||
|
#define NOGDI
|
|||
|
#define NOMB
|
|||
|
#define NOFONT
|
|||
|
#define NOPEN
|
|||
|
#define NOBRUSH
|
|||
|
#define NOWNDCLASS
|
|||
|
#define NOSOUND
|
|||
|
#define NOCOMM
|
|||
|
#define NOPOINT
|
|||
|
#define NORECT
|
|||
|
#define NOREGION
|
|||
|
#define NOSCROLL
|
|||
|
#define NOTEXTMETRIC
|
|||
|
#define NOWH
|
|||
|
#define NOWINOFFSETS
|
|||
|
#include <windows.h>
|
|||
|
|
|||
|
#include "mw.h"
|
|||
|
#include "doslib.h"
|
|||
|
#define NOUAC
|
|||
|
#include "cmddefs.h"
|
|||
|
#include "docdefs.h"
|
|||
|
#include "filedefs.h"
|
|||
|
#include "str.h"
|
|||
|
#include "debug.h"
|
|||
|
|
|||
|
|
|||
|
extern int vfDiskFull;
|
|||
|
extern int vfSysFull;
|
|||
|
extern int vfnWriting;
|
|||
|
extern CHAR (*rgbp)[cbSector];
|
|||
|
extern typeTS tsMruRfn;
|
|||
|
extern struct BPS *mpibpbps;
|
|||
|
extern int ibpMax;
|
|||
|
extern struct FCB (**hpfnfcb)[];
|
|||
|
extern typeTS tsMruBps;
|
|||
|
extern struct ERFN dnrfn[rfnMax];
|
|||
|
extern int iibpHashMax;
|
|||
|
extern CHAR *rgibpHash;
|
|||
|
extern int rfnMac;
|
|||
|
extern int ferror;
|
|||
|
extern CHAR szWriteDocPrompt[];
|
|||
|
extern CHAR szScratchFilePrompt[];
|
|||
|
extern CHAR szSaveFilePrompt[];
|
|||
|
|
|||
|
|
|||
|
#define IibpHash(fn,pn) ((int) ((fn + 1) * (pn + 1)) & 077777) % iibpHashMax
|
|||
|
|
|||
|
|
|||
|
#ifdef DEBUG
|
|||
|
#define STATIC
|
|||
|
#else
|
|||
|
#define STATIC static
|
|||
|
#define ErrorWithMsg( idpmt, szModule ) Error( idpmt )
|
|||
|
#define DiskErrorWithMsg( idpmt, szModule ) DiskError( idpmt )
|
|||
|
#endif
|
|||
|
|
|||
|
#define osfnNil (-1)
|
|||
|
|
|||
|
|
|||
|
CHAR *PchFromFc(fn, fc, pcch)
|
|||
|
int fn;
|
|||
|
typeFC fc;
|
|||
|
int *pcch;
|
|||
|
{ /*
|
|||
|
Description: Reads from a file, starting at virtual character
|
|||
|
position fc. Reads until end of buffer page.
|
|||
|
Returns: Pointer to char buffer starting at fc.
|
|||
|
The number of characters read is returned in *pcch.
|
|||
|
*/
|
|||
|
int dfc;
|
|||
|
CHAR *pch;
|
|||
|
typePN pn;
|
|||
|
int ibp;
|
|||
|
struct BPS *pbps;
|
|||
|
|
|||
|
dfc = (int) (fc % cfcPage);
|
|||
|
pn = (typePN) (fc / cfcPage);
|
|||
|
|
|||
|
ibp = IbpEnsureValid(fn, pn);
|
|||
|
pbps = &mpibpbps[ibp];
|
|||
|
*pcch = pbps->cch - dfc;
|
|||
|
return &rgbp[ibp][dfc];
|
|||
|
}
|
|||
|
/* end of P c h F r o m F c */
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
/*** PchGetPn - Assure file page loaded, return pointer
|
|||
|
*
|
|||
|
*/
|
|||
|
|
|||
|
CHAR *PchGetPn(fn, pn, pcch, fWrite)
|
|||
|
int fn;
|
|||
|
typePN pn;
|
|||
|
int *pcch;
|
|||
|
BOOL fWrite; // missing before?? (2.11.91) D. Kent
|
|||
|
{ /*
|
|||
|
Description: Get char pointer to page buffer, option to mark
|
|||
|
page as dirty.
|
|||
|
Returns: Pointer to buffer.
|
|||
|
cch in *pcch
|
|||
|
*/
|
|||
|
|
|||
|
int ibp = IbpEnsureValid(fn, pn);
|
|||
|
struct BPS *pbps = &mpibpbps[ibp];
|
|||
|
|
|||
|
*pcch = pbps->cch;
|
|||
|
pbps->fDirty |= fWrite;
|
|||
|
return rgbp[ibp];
|
|||
|
} /* end of P c h G e t P n */
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
int IbpEnsureValid(fn, pn)
|
|||
|
int fn;
|
|||
|
typePN pn;
|
|||
|
{ /*
|
|||
|
Description: Get page pn of file fn into memory.
|
|||
|
If already in memory, return.
|
|||
|
Returns: Bp index (buffer slot #) where the page resides
|
|||
|
in memory.
|
|||
|
*/
|
|||
|
|
|||
|
int ibp;
|
|||
|
register struct BPS *pbps;
|
|||
|
|
|||
|
#ifdef DEBUG
|
|||
|
CheckIbp();
|
|||
|
#endif /* DEBUG */
|
|||
|
|
|||
|
/* Is the page currently in memory? */
|
|||
|
ibp = rgibpHash[IibpHash(fn,pn)];
|
|||
|
/* ibp is the first in a linked list of possible matches */
|
|||
|
/* resident in memory */
|
|||
|
|
|||
|
Scribble(3,'V');
|
|||
|
|
|||
|
while (ibp != ibpNil) /* while not end of linked list */
|
|||
|
{ /* check if any buffers in memory match */
|
|||
|
pbps = &mpibpbps[ibp];
|
|||
|
if (pbps->fn == fn && pbps->pn == pn)
|
|||
|
{ /* Found it */
|
|||
|
pbps->ts = ++tsMruBps; /* mark page as MRUsed */
|
|||
|
Scribble(3,' ');
|
|||
|
return ibp;
|
|||
|
}
|
|||
|
ibp = pbps->ibpHashNext;
|
|||
|
}
|
|||
|
|
|||
|
/* page is not currently in memory */
|
|||
|
|
|||
|
return IbpMakeValid( fn, pn );
|
|||
|
} /* end of I b p E n s u r e V a l i d */
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
CloseEveryRfn( fHardToo )
|
|||
|
{ /* Close all files we have open. Close only files on removable media
|
|||
|
if fHardToo is FALSE; ALL files if fHardToo is TRUE */
|
|||
|
int rfn;
|
|||
|
|
|||
|
for (rfn = 0; rfn < rfnMac; rfn++)
|
|||
|
{
|
|||
|
int fn = dnrfn [rfn].fn;
|
|||
|
|
|||
|
if (fn != fnNil)
|
|||
|
if ( fHardToo ||
|
|||
|
!((POFSTRUCT)((**hpfnfcb)[fn].rgbOpenFileBuf))->fFixedDisk )
|
|||
|
{
|
|||
|
CloseRfn( rfn );
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
typeFC FcWScratch(pch, cch)
|
|||
|
CHAR *pch;
|
|||
|
int cch;
|
|||
|
{ /*
|
|||
|
Description: Write chars at end of scratch file.
|
|||
|
Returns: first fc written.
|
|||
|
*/
|
|||
|
typeFC fc = (**hpfnfcb)[fnScratch].fcMac;
|
|||
|
#if 0
|
|||
|
extern BOOL bNo64KLimit;
|
|||
|
|
|||
|
if ((!bNo64KLimit) && (((long) fc) + ((long) cch) > 65536L)) /* scratch file to big */
|
|||
|
{
|
|||
|
DiskErrorWithMsg(IDPMTSFER, " FcWScratch"); /* session too long */
|
|||
|
|
|||
|
vfSysFull = fTrue;
|
|||
|
/* recovery is accomplished: all that happens is that a few
|
|||
|
characters do not get written to the scratch file - the
|
|||
|
user loses only a little bit of his work. */
|
|||
|
}
|
|||
|
else
|
|||
|
#endif
|
|||
|
WriteRgch(fnScratch, pch, cch);
|
|||
|
return fc;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
WriteRgch(fn, pch, cch)
|
|||
|
int fn;
|
|||
|
CHAR *pch;
|
|||
|
int cch;
|
|||
|
{ /*
|
|||
|
Description: Writes char string pch, length cch, to end of
|
|||
|
file fn.
|
|||
|
Returns: nothing
|
|||
|
*/
|
|||
|
extern vfDiskError;
|
|||
|
struct FCB *pfcb = &(**hpfnfcb)[fn];
|
|||
|
typePN pn = (typePN) (pfcb->fcMac / cfcPage);
|
|||
|
#ifdef WIN30
|
|||
|
/* Error checking was horrendous in these early days, right?
|
|||
|
Ha. It still is. In any case, don't know WHAT we can do
|
|||
|
if the page number has gotten too large, so just fake a
|
|||
|
disk error so that IbpEnsureValid() doesn't go off into
|
|||
|
never-never land! This catch effectively limits us to
|
|||
|
4M files ..pault 11/1/89 */
|
|||
|
|
|||
|
if (pn > pgnMax)
|
|||
|
#ifdef DEBUG
|
|||
|
DiskErrorWithMsg(IDPMTSDE2, "writergch");
|
|||
|
#else
|
|||
|
DiskError(IDPMTSDE2);
|
|||
|
#endif
|
|||
|
else
|
|||
|
#endif
|
|||
|
|
|||
|
while (cch > 0)
|
|||
|
{ /* One page at a time */
|
|||
|
int ibp = IbpEnsureValid(fn, pn++);
|
|||
|
struct BPS *pbps = &mpibpbps[ibp];
|
|||
|
int cchBp = pbps->cch;
|
|||
|
int cchBlt = min((int)cfcPage - cchBp, cch);
|
|||
|
|
|||
|
Assert( vfDiskError ||
|
|||
|
cchBp == pfcb->fcMac - (pn - 1) * cfcPage);
|
|||
|
|
|||
|
bltbyte(pch, &rgbp[ibp][cchBp], cchBlt);
|
|||
|
pbps->cch += cchBlt;
|
|||
|
pbps->fDirty = true;
|
|||
|
pfcb->fcMac += cchBlt;
|
|||
|
pfcb->pnMac = pn;
|
|||
|
pch += cchBlt;
|
|||
|
cch -= cchBlt;
|
|||
|
}
|
|||
|
} /* end of W r i t e R g c h */
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
CloseRfn( rfn )
|
|||
|
int rfn;
|
|||
|
{/*
|
|||
|
Description: Close a file and delete its Rfn entry
|
|||
|
Returns: nothing
|
|||
|
*/
|
|||
|
struct ERFN *perfn = &dnrfn[rfn];
|
|||
|
int fn = perfn->fn;
|
|||
|
|
|||
|
Assert (rfn >= 0 &&
|
|||
|
rfn < rfnMac &&
|
|||
|
perfn->osfn != osfnNil &&
|
|||
|
fn != fnNil);
|
|||
|
|
|||
|
#ifdef DEBUG
|
|||
|
#ifdef DFILE
|
|||
|
CommSzSz( "Closing file: ", &(**(**hpfnfcb)[fn].hszFile)[0] );
|
|||
|
#endif
|
|||
|
#endif
|
|||
|
/* Close may fail if windows already closed the file for us,
|
|||
|
but that's OK */
|
|||
|
FCloseDoshnd( perfn->osfn );
|
|||
|
|
|||
|
{ /* Just like the statement below, but 28 bytes less
|
|||
|
under CMERGE V13 */
|
|||
|
REG1 struct FCB *pfcb = &(**hpfnfcb) [fn];
|
|||
|
pfcb->rfn = rfnNil;
|
|||
|
}
|
|||
|
/* (**hpfnfcb)[fn].rfn = rfnNil; */
|
|||
|
|
|||
|
|
|||
|
perfn->fn = fnNil;
|
|||
|
}
|
|||
|
|