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

📄 fatdir.c

📁 GNU FreeDOS兼容MS DOS很好的东东.
💻 C
📖 第 1 页 / 共 2 页
字号:
/****************************************************************//*                                                              *//*                          fatdir.c                            *//*                            DOS-C                             *//*                                                              *//*                 FAT File System dir Functions                *//*                                                              *//*                      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 *fatdirRcsId =    "$Id: fatdir.c,v 1.47 2004/05/23 18:28:18 bartoldeman Exp $";#endif/* Description. *  Initialize a fnode so that it will point to the directory with  *  dirstart starting cluster; in case of passing dirstart == 0 *  fnode will point to the start of a root directory */VOID dir_init_fnode(f_node_ptr fnp, CLUSTER dirstart){  /* reset the directory flags    */  fnp->f_flags = F_DDIR;  fnp->f_diroff = 0;  fnp->f_offset = 0l;  fnp->f_cluster_offset = 0;  /* root directory */#ifdef WITHFAT32  if (dirstart == 0)    if (ISFAT32(fnp->f_dpb))      dirstart = fnp->f_dpb->dpb_xrootclst;#endif  fnp->f_cluster = fnp->f_dirstart = dirstart;}f_node_ptr dir_open(register const char *dirname){  f_node_ptr fnp;  int i;  char fcbname[FNAME_SIZE + FEXT_SIZE];  /* Allocate an fnode if possible - error return (0) if not.     */  if ((fnp = get_f_node()) == (f_node_ptr) 0)  {    return (f_node_ptr) 0;  }  /* Force the fnode into read-write mode                         */  fnp->f_mode = RDWR;  /* determine what drive and dpb we are using...                 */  fnp->f_dpb = get_dpb(dirname[0]-'A');  /* Perform all directory common handling after all special      */  /* handling has been performed.                                 */  if (media_check(fnp->f_dpb) < 0)  {    release_f_node(fnp);    return (f_node_ptr) 0;  }  /* Walk the directory tree to find the starting cluster         */  /*                                                              */  /* Start from the root directory (dirstart = 0)                 */  /* The CDS's cdsStartCls may be used to shorten the search     beginning at the CWD, see mapPath() and CDS.H in order     to enable this behaviour there.           -- 2001/09/04 ska*/  dir_init_fnode(fnp, 0);  dirname += 2;               /* Assume FAT style drive       */  while(*dirname != '\0')  {    /* skip all path seperators                             */    while (*dirname == '\\')      ++dirname;    /* don't continue if we're at the end                   */    if (*dirname == '\0')      break;    /* Convert the name into an absolute name for           */    /* comparison...                                        */    memset(fcbname, ' ', FNAME_SIZE + FEXT_SIZE);    for (i = 0; i < FNAME_SIZE + FEXT_SIZE; i++, dirname++)    {      char c = *dirname;      if (c == '.')        i = FNAME_SIZE - 1;      else if (c != '\0' && c != '\\')        fcbname[i] = c;      else        break;    }    /* Now search through the directory to  */    /* find the entry...                    */    i = FALSE;    while (dir_read(fnp) == 1)    {      if (!(fnp->f_dir.dir_attrib & D_VOLID) &&          fcbmatch(fcbname, fnp->f_dir.dir_name))      {        i = TRUE;        break;      }      fnp->f_diroff++;    }    if (!i || !(fnp->f_dir.dir_attrib & D_DIR))    {      release_f_node(fnp);      return (f_node_ptr) 0;    }    else    {      /* make certain we've moved off */      /* root                         */      dir_init_fnode(fnp, getdstart(fnp->f_dpb, &fnp->f_dir));    }  }  return fnp;}/* swap internal and external delete flags */STATIC void swap_deleted(char *name){  if (name[0] == DELETED || name[0] == EXT_DELETED)    name[0] ^= EXT_DELETED - DELETED; /* 0xe0 */}STATIC struct buffer FAR *getblock_from_off(f_node_ptr fnp, unsigned secsize){  /* Compute the block within the cluster and the */  /* offset within the block.                     */  unsigned sector;  sector = (UBYTE)(fnp->f_offset / secsize) & fnp->f_dpb->dpb_clsmask;  /* Get the block we need from cache             */  return getblock(clus2phys(fnp->f_cluster, fnp->f_dpb) + sector,                  fnp->f_dpb->dpb_unit);}/* Description. *  Read next consequitive directory entry, pointed by fnp. *  If some error occures the other critical *  fields aren't changed, except those used for caching. *  The fnp->f_diroff always corresponds to the directory entry *  which has been read. * Return value. *  1              - all OK, directory entry having been read is not empty. *  0              - Directory entry is empty. *  DE_SEEK        - Attempt to read beyound the end of the directory. *  DE_BLKINVLD    - Invalid block. * Note. Empty directory entries always resides at the end of the directory. */COUNT dir_read(REG f_node_ptr fnp){  struct buffer FAR *bp;  REG UWORD secsize = fnp->f_dpb->dpb_secsize;  /* can't have more than 65535 directory entries */  if (fnp->f_diroff >= 65535U)      return DE_SEEK;  /* Determine if we hit the end of the directory. If we have,    */  /* bump the offset back to the end and exit. If not, fill the   */  /* dirent portion of the fnode, clear the f_dmod bit and leave, */  /* but only for root directories                                */  if (fnp->f_dirstart == 0)  {    if (fnp->f_diroff >= fnp->f_dpb->dpb_dirents)      return DE_SEEK;    bp = getblock(fnp->f_diroff / (secsize / DIRENT_SIZE)                           + fnp->f_dpb->dpb_dirstrt, fnp->f_dpb->dpb_unit);#ifdef DISPLAY_GETBLOCK    printf("DIR (dir_read)\n");#endif  }  else  {    /* Do a "seek" to the directory position        */    fnp->f_offset = fnp->f_diroff * (ULONG)DIRENT_SIZE;    /* Search through the FAT to find the block     */    /* that this entry is in.                       */#ifdef DISPLAY_GETBLOCK    printf("dir_read: ");#endif    if (map_cluster(fnp, XFR_READ) != SUCCESS)      return DE_SEEK;    bp = getblock_from_off(fnp, secsize);#ifdef DISPLAY_GETBLOCK    printf("DIR (dir_read)\n");#endif  }  /* Now that we have the block for our entry, get the    */  /* directory entry.                                     */  if (bp == NULL)    return DE_BLKINVLD;  bp->b_flag &= ~(BFR_DATA | BFR_FAT);  bp->b_flag |= BFR_DIR | BFR_VALID;  getdirent((BYTE FAR *) & bp->            b_buffer[(fnp->f_diroff * DIRENT_SIZE) % fnp->f_dpb->dpb_secsize],            &fnp->f_dir);  swap_deleted(fnp->f_dir.dir_name);  /* Update the fnode's directory info                    */  fnp->f_flags &= ~F_DMOD;  /* and for efficiency, stop when we hit the first       */  /* unused entry.                                        */  /* either returns 1 or 0                                */  return (fnp->f_dir.dir_name[0] != '\0');}/* Description. *  Writes directory entry pointed by fnp to disk. In case of erroneous *  situation fnode is released. *  The caller should set *    1. F_DMOD flag if original directory entry was modified. * Return value. *  TRUE  - all OK. *  FALSE - error occured (fnode is released). */#ifndef IPLBOOL dir_write(REG f_node_ptr fnp){  struct buffer FAR *bp;  REG UWORD secsize = fnp->f_dpb->dpb_secsize;  if (!(fnp->f_flags & F_DDIR))    return FALSE;  /* Update the entry if it was modified by a write or create...  */  if (fnp->f_flags & F_DMOD)  {    /* Root is a consecutive set of blocks, so handling is  */    /* simple.                                              */    if (fnp->f_dirstart == 0)    {      bp = getblock(fnp->f_diroff / (secsize / DIRENT_SIZE)                             + fnp->f_dpb->dpb_dirstrt,                    fnp->f_dpb->dpb_unit);#ifdef DISPLAY_GETBLOCK      printf("DIR (dir_write)\n");#endif    }    /* All other directories are just files. The only       */    /* special handling is resetting the offset so that we  */    /* can continually update the same directory entry.     */    else    {      /* Do a "seek" to the directory position        */      /* and convert the fnode to a directory fnode.  */      fnp->f_offset = fnp->f_diroff * (ULONG)DIRENT_SIZE;      fnp->f_cluster = fnp->f_dirstart;      fnp->f_cluster_offset = 0;

⌨️ 快捷键说明

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