diff --git a/kernel/fcbfns.c b/kernel/fcbfns.c index e002988..c2dbbb1 100644 --- a/kernel/fcbfns.c +++ b/kernel/fcbfns.c @@ -244,39 +244,50 @@ UBYTE FcbReadWrite(xfcb FAR * lpXfcb, UCOUNT recno, int mode) { ULONG lPosit; long nTransfer; - BYTE FAR * FcbIoPtr = dta; fcb FAR *lpFcb; - - FcbIoPtr += recno * lpFcb->fcb_recsiz; - - if ((ULONG)recno * lpFcb->fcb_recsiz >= 0x10000ul || - FP_OFF(FcbIoPtr) < FP_OFF(dta)) - return FCB_ERR_SEGMENT_WRAP; + unsigned size; + unsigned long bigsize; + unsigned recsiz; /* Convert to fcb if necessary */ lpFcb = ExtFcbToFcb(lpXfcb); + recsiz = lpFcb->fcb_recsiz; + bigsize = (ULONG)recsiz * recno; + if (bigsize > 0xffff) + return FCB_ERR_SEGMENT_WRAP; + size = (unsigned)bigsize; + + if (FP_OFF(dta) + size < FP_OFF(dta)) + return FCB_ERR_SEGMENT_WRAP; /* Now update the fcb and compute where we need to position */ /* to. */ - lPosit = FcbRec(lpFcb) * lpFcb->fcb_recsiz; + lPosit = FcbRec(lpFcb) * recsiz; if ((CritErrCode = -SftSeek(lpFcb->fcb_sftno, lPosit, 0)) != SUCCESS) return FCB_ERR_NODATA; /* Do the read */ - nTransfer = DosRWSft(lpFcb->fcb_sftno, lpFcb->fcb_recsiz, FcbIoPtr, mode); + nTransfer = DosRWSft(lpFcb->fcb_sftno, size, dta, mode & ~XFR_FCB_RANDOM); if (nTransfer < 0) CritErrCode = -(int)nTransfer; /* Now find out how we will return and do it. */ - if (nTransfer == lpFcb->fcb_recsiz) + if (mode & XFR_WRITE) + lpFcb->fcb_fsize = SftGetFsize(lpFcb->fcb_sftno); + + /* if end-of-file, then partial read should count last record */ + if (mode & XFR_FCB_RANDOM && recsiz > 0) + lpFcb->fcb_rndm += ((unsigned)nTransfer + recsiz - 1) / recsiz; + size -= (unsigned)nTransfer; + if (size == 0) { - if (mode == XFR_WRITE) lpFcb->fcb_fsize = SftGetFsize(lpFcb->fcb_sftno); FcbNextRecord(lpFcb); return FCB_SUCCESS; } - if (mode == XFR_READ && nTransfer > 0) + size %= lpFcb->fcb_recsiz; + if (mode & XFR_READ && size > 0) { - fmemset(FcbIoPtr + (unsigned)nTransfer, 0, lpFcb->fcb_recsiz - (unsigned)nTransfer); + fmemset((char FAR *)dta + (unsigned)nTransfer, 0, size); FcbNextRecord(lpFcb); return FCB_ERR_EOF; } @@ -340,28 +351,21 @@ void FcbCalcRec(xfcb FAR * lpXfcb) UBYTE FcbRandomBlockIO(xfcb FAR * lpXfcb, UWORD *nRecords, int mode) { - unsigned recno; - UBYTE nErrorCode = FCB_SUCCESS; + UBYTE nErrorCode; fcb FAR *lpFcb; + unsigned long old; FcbCalcRec(lpXfcb); /* Convert to fcb if necessary */ lpFcb = ExtFcbToFcb(lpXfcb); - for (recno = 0; recno < *nRecords; recno++) - { - nErrorCode = FcbReadWrite(lpXfcb, recno, mode); - /* end-of-file, partial read should count last record */ - if (nErrorCode == FCB_ERR_EOF) - recno++; - if (nErrorCode != FCB_SUCCESS) - break; - } - *nRecords = recno; + old = lpFcb->fcb_rndm; + nErrorCode = FcbReadWrite(lpXfcb, *nRecords, mode); + *nRecords = lpFcb->fcb_rndm - old; /* Now update the fcb */ - lpFcb->fcb_rndm = FcbRec(lpFcb); + FcbCalcRec(lpXfcb); return nErrorCode; } @@ -381,7 +385,7 @@ UBYTE FcbRandomIO(xfcb FAR * lpXfcb, int mode) uwCurrentBlock = lpFcb->fcb_cublock; ucCurrentRecord = lpFcb->fcb_curec; - nErrorCode = FcbReadWrite(lpXfcb, 0, mode); + nErrorCode = FcbReadWrite(lpXfcb, 1, mode); lpFcb->fcb_cublock = uwCurrentBlock; lpFcb->fcb_curec = ucCurrentRecord; diff --git a/kernel/globals.h b/kernel/globals.h index 5b15fa4..6365b35 100644 --- a/kernel/globals.h +++ b/kernel/globals.h @@ -111,6 +111,8 @@ FAR * ASM DPBp; /* First drive Parameter Block */ #define XFR_READ 1 #define XFR_WRITE 2 #define XFR_FORCE_WRITE 3 +/* flag to update fcb_rndm field */ +#define XFR_FCB_RANDOM 4 #define RDONLY 0 #define WRONLY 1 diff --git a/kernel/inthndlr.c b/kernel/inthndlr.c index 1290538..e799738 100644 --- a/kernel/inthndlr.c +++ b/kernel/inthndlr.c @@ -556,12 +556,12 @@ dispatch: case 0x14: /* FCB read */ - lr.AL = FcbReadWrite(FP_DS_DX, 0, XFR_READ); + lr.AL = FcbReadWrite(FP_DS_DX, 1, XFR_READ); break; case 0x15: /* FCB write */ - lr.AL = FcbReadWrite(FP_DS_DX, 0, XFR_WRITE); + lr.AL = FcbReadWrite(FP_DS_DX, 1, XFR_WRITE); break; case 0x16: @@ -622,7 +622,8 @@ dispatch: /* Get default DPB */ /* case 0x1f: see case 0x32 */ - /* Random read using FCB */ + /* Random read using FCB: fields not updated + (XFR_RANDOM should not be used here) */ case 0x21: lr.AL = FcbRandomIO(FP_DS_DX, XFR_READ); break; @@ -658,12 +659,12 @@ dispatch: /* Read random record(s) using FCB */ case 0x27: - lr.AL = FcbRandomBlockIO(FP_DS_DX, &lr.CX, XFR_READ); + lr.AL = FcbRandomBlockIO(FP_DS_DX, &lr.CX, XFR_READ | XFR_FCB_RANDOM); break; /* Write random record(s) using FCB */ case 0x28: - lr.AL = FcbRandomBlockIO(FP_DS_DX, &lr.CX, XFR_WRITE); + lr.AL = FcbRandomBlockIO(FP_DS_DX, &lr.CX, XFR_WRITE | XFR_FCB_RANDOMXS); break; /* Parse File Name */