⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fcbfns.c

📁 GNU FreeDOS兼容MS DOS很好的东东.
💻 C
📖 第 1 页 / 共 2 页
字号:
/****************************************************************//*                                                              *//*                          fcbfns.c                            *//*                                                              *//*           Old CP/M Style Function Handlers for Kernel        *//*                                                              *//*                      Copyright (c) 1995                      *//*                      Pasquale J. Villani                     *//*                      All Rights Reserved                     *//*                                                              *//* This file is part of DOS-C.                                  *//*                                                              *//* DOS-C is free software; you can redistribute it and/or       *//* modify it under the terms of the GNU General Public License  *//* as published by the Free Software Foundation; either version *//* 2, or (at your option) any later version.                    *//*                                                              *//* DOS-C is distributed in the hope that it will be useful, but *//* WITHOUT ANY WARRANTY; without even the implied warranty of   *//* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See    *//* the GNU General Public License for more details.             *//*                                                              *//* You should have received a copy of the GNU General Public    *//* License along with DOS-C; see the file COPYING.  If not,     *//* write to the Free Software Foundation, 675 Mass Ave,         *//* Cambridge, MA 02139, USA.                                    *//****************************************************************/#include "portab.h"#include "globals.h"#ifdef VERSION_STRINGSstatic BYTE *RcsId =    "$Id: fcbfns.c,v 1.47 2004/07/25 08:04:54 bartoldeman Exp $";#endif#define FCB_SUCCESS     0#define FCB_ERR_NODATA  1#define FCB_ERR_SEGMENT_WRAP 2#define FCB_ERR_EOF     3#define FCB_ERROR       0xffSTATIC fcb FAR *ExtFcbToFcb(xfcb FAR * lpExtFcb);STATIC fcb FAR *CommonFcbInit(xfcb FAR * lpExtFcb, BYTE * pszBuffer,                       COUNT * pCurDrive);STATIC void FcbNameInit(fcb FAR * lpFcb, BYTE * pszBuffer, COUNT * pCurDrive);STATIC void FcbNextRecord(fcb FAR * lpFcb);STATIC void FcbCalcRec(xfcb FAR * lpXfcb);#define TestCmnSeps(lpFileName) (*lpFileName && strchr(":<|>+=,", *lpFileName) != NULL)#define TestFieldSeps(lpFileName) ((unsigned char)*lpFileName <= ' ' || strchr("/\"[]<>|.", *lpFileName) != NULL)static dmatch Dmatch;BYTE FAR *FatGetDrvData(UBYTE drive, UBYTE * pspc, UWORD * bps, UWORD * nc){  static BYTE mdb;  UWORD spc;  /* get the data available from dpb                       */  spc = DosGetFree(drive, NULL, bps, nc);  if (spc != 0xffff)  {    struct dpb FAR *dpbp = get_dpb(drive == 0 ? default_drive : drive - 1);    /* Point to the media desctriptor for this drive               */    *pspc = (UBYTE)spc;    if (dpbp == NULL)    {      mdb = spc >> 8;      spc &= 0xff;      return &mdb;    }    else    {      return (BYTE FAR *) & (dpbp->dpb_mdb);    }  }  return NULL;}#define PARSE_SEP_STOP          0x01#define PARSE_DFLT_DRIVE        0x02#define PARSE_BLNK_FNAME        0x04#define PARSE_BLNK_FEXT         0x08#define PARSE_RET_NOWILD        0#define PARSE_RET_WILD          1#define PARSE_RET_BADDRIVE      0xff#ifndef IPLUWORD FcbParseFname(UBYTE *wTestMode, const BYTE FAR * lpFileName, fcb FAR * lpFcb){  WORD wRetCodeName = FALSE, wRetCodeExt = FALSE;  /* pjv -- ExtFcbToFcb?                                          */  /* Start out with some simple stuff first.  Check if we are     */  /* going to use a default drive specificaton.                   */  if (!(*wTestMode & PARSE_DFLT_DRIVE))    lpFcb->fcb_drive = FDFLT_DRIVE;  if (!(*wTestMode & PARSE_BLNK_FNAME))  {    fmemset(lpFcb->fcb_fname, ' ', FNAME_SIZE);  }  if (!(*wTestMode & PARSE_BLNK_FEXT))  {    fmemset(lpFcb->fcb_fext, ' ', FEXT_SIZE);  }  /* Undocumented behavior, set record number & record size to 0  */  lpFcb->fcb_cublock = lpFcb->fcb_recsiz = 0;  if (!(*wTestMode & PARSE_SEP_STOP))  {    lpFileName = ParseSkipWh(lpFileName);    if (TestCmnSeps(lpFileName))      ++lpFileName;  }  /* Undocumented "feature," we skip white space anyway           */  lpFileName = ParseSkipWh(lpFileName);  /* Now check for drive specification                            */  if (*(lpFileName + 1) == ':')  {    /* non-portable construct to be changed                 */    REG UBYTE Drive = DosUpFChar(*lpFileName) - 'A';    if (Drive >= lastdrive)    {      *wTestMode = PARSE_RET_BADDRIVE;      return FP_OFF(lpFileName);    }    lpFcb->fcb_drive = Drive + 1;    lpFileName += 2;  }  /* special cases: '.' and '..' */  if (*lpFileName == '.')  {    lpFcb->fcb_fname[0] = '.';    ++lpFileName;    if (*lpFileName == '.')    {      lpFcb->fcb_fname[1] = '.';      ++lpFileName;    }    *wTestMode = PARSE_RET_NOWILD;    return FP_OFF(lpFileName);  }  /* Now to format the file name into the string                  */  lpFileName =      GetNameField(lpFileName, (BYTE FAR *) lpFcb->fcb_fname, FNAME_SIZE,                   (BOOL *) & wRetCodeName);  /* Do we have an extension? If do, format it else return        */  if (*lpFileName == '.')    lpFileName =        GetNameField(++lpFileName, (BYTE FAR *) lpFcb->fcb_fext,                     FEXT_SIZE, (BOOL *) & wRetCodeExt);  *wTestMode = (wRetCodeName | wRetCodeExt) ? PARSE_RET_WILD : PARSE_RET_NOWILD;  return FP_OFF(lpFileName);}const BYTE FAR * ParseSkipWh(const BYTE FAR * lpFileName){  while (*lpFileName == ' ' || *lpFileName == '\t')    ++lpFileName;  return lpFileName;}#if 0                           /* defined above */BOOL TestCmnSeps(BYTE FAR * lpFileName){  BYTE *pszTest, *pszCmnSeps = ":<|>+=,";  for (pszTest = pszCmnSeps; *pszTest != '\0'; ++pszTest)    if (*lpFileName == *pszTest)      return TRUE;  return FALSE;}#endif#if 0BOOL TestFieldSeps(BYTE FAR * lpFileName){  BYTE *pszTest, *pszCmnSeps = "/\"[]<>|.";  /* Another non-portable construct                               */  if (*lpFileName <= ' ')    return TRUE;  for (pszTest = pszCmnSeps; *pszTest != '\0'; ++pszTest)    if (*lpFileName == *pszTest)      return TRUE;  return FALSE;}#endifconst BYTE FAR * GetNameField(const BYTE FAR * lpFileName, BYTE FAR * lpDestField,                       COUNT nFieldSize, BOOL * pbWildCard){  COUNT nIndex = 0;  BYTE cFill = ' ';  while (*lpFileName != '\0' && !TestFieldSeps(lpFileName)         && nIndex < nFieldSize)  {    if (*lpFileName == ' ')      break;    if (*lpFileName == '*')    {      *pbWildCard = TRUE;      cFill = '?';      ++lpFileName;      break;    }    if (*lpFileName == '?')      *pbWildCard = TRUE;    *lpDestField++ = DosUpFChar(*lpFileName++);    ++nIndex;  }  /* Blank out remainder of field on exit                         */  fmemset(lpDestField, cFill, nFieldSize - nIndex);  return lpFileName;}STATIC VOID FcbNextRecord(fcb FAR * lpFcb){  if (++lpFcb->fcb_curec >= 128)  {    lpFcb->fcb_curec = 0;    ++lpFcb->fcb_cublock;  }}STATIC ULONG FcbRec(fcb FAR *lpFcb){  return ((ULONG) lpFcb->fcb_cublock * 128) + lpFcb->fcb_curec;}UBYTE FcbReadWrite(xfcb FAR * lpXfcb, UCOUNT recno, int mode){  ULONG lPosit;  long nTransfer;  fcb FAR *lpFcb;  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) * recsiz;  if ((CritErrCode = -SftSeek(lpFcb->fcb_sftno, lPosit, 0)) != SUCCESS)    return FCB_ERR_NODATA;  /* Do the read                                                  */  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 (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)  {    FcbNextRecord(lpFcb);    return FCB_SUCCESS;  }  size %= lpFcb->fcb_recsiz;  if (mode & XFR_READ && size > 0)  {    fmemset((char FAR *)dta + (unsigned)nTransfer, 0, size);    FcbNextRecord(lpFcb);    return FCB_ERR_EOF;  }  return FCB_ERR_NODATA;}UBYTE FcbGetFileSize(xfcb FAR * lpXfcb){  int FcbDrive, sft_idx;  unsigned recsiz;  /* Build a traditional DOS file name                            */  fcb FAR *lpFcb = CommonFcbInit(lpXfcb, SecPathName, &FcbDrive);  recsiz = lpFcb->fcb_recsiz;  /* check for a device                                           */  if (!lpFcb || IsDevice(SecPathName) || (recsiz == 0))    return FCB_ERROR;  sft_idx = (short)DosOpenSft(SecPathName, O_LEGACY | O_RDONLY | O_OPEN, 0);  if (sft_idx >= 0)  {    ULONG fsize;    /* Get the size                                         */    fsize = SftGetFsize(sft_idx);    /* compute the size and update the fcb                  */    lpFcb->fcb_rndm = (fsize + (recsiz - 1)) / recsiz;    /* close the file and leave                             */    if ((CritErrCode = -DosCloseSft(sft_idx, FALSE)) == SUCCESS)      return FCB_SUCCESS;  }  else    CritErrCode = -sft_idx;  return FCB_ERROR;}void FcbSetRandom(xfcb FAR * lpXfcb){  /* Convert to fcb if necessary                                  */  fcb FAR *lpFcb = ExtFcbToFcb(lpXfcb);  /* Now update the fcb and compute where we need to position     */  /* to. */  lpFcb->fcb_rndm = FcbRec(lpFcb);}void FcbCalcRec(xfcb FAR * lpXfcb){  /* Convert to fcb if necessary                                  */  fcb FAR *lpFcb = ExtFcbToFcb(lpXfcb);  /* Now update the fcb and compute where we need to position     */  /* to.                                                          */  lpFcb->fcb_cublock = (UWORD)(lpFcb->fcb_rndm / 128);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -