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

📄 fatlite.c

📁 VxWorks BSP框架源代码包含头文件和驱动
💻 C
📖 第 1 页 / 共 5 页
字号:
  Volume vol = file->fileVol;  unsigned i;  SectorNo sectorOfDir;  unsigned offsetInSector;  /* Assuming the current position is at the end-of-file, this will     */  /* extend the directory.						*/  checkStatus(getSectorAndOffset(file,&sectorOfDir,&offsetInSector));  for (i = 0; i < vol.sectorsPerCluster; i++) {    /* Write binary zeroes to indicate never-used entries */    checkStatus(updateSector(&vol,sectorOfDir + i,FALSE));    buffer.checkPoint = TRUE;    if (file->currentPosition == 0 && i == 0) {      /* Add the mandatory . and .. entries */      tffscpy(directory[0].name,".          ",sizeof directory[0].name);      directory[0].attributes = ATTR_ARCHIVE | ATTR_DIRECTORY;      toLE2(directory[0].startingCluster,file->currentCluster);      toLE4(directory[0].fileSize,0);      setCurrentDateTime(&directory[0]);      tffscpy(&directory[1],&directory[0],sizeof directory[0]);      directory[1].name[1] = '.';	/* change . to .. */      toLE2(directory[1].startingCluster,ownerDir);    }    file->fileSize += SECTOR_SIZE;  }  /* Update the parent directory by closing the file */  file->flags |= FILE_MODIFIED;  return closeFile(file);}#endif	/* SUB_DIRECTORY *//*----------------------------------------------------------------------*//*		        f i n d D i r E n t r y				*//*									*//* Finds a directory entry by path-name, or finds an available directory*//* entry if the file does not exist.					*//* Most fields necessary for opening a file are set by this routine.	*//*                                                                      *//* Parameters:                                                          *//*	vol		: Pointer identifying drive			*//*	path		: path to find					*//*      file            : File in which to record directory information.*//*                        Specific fields on entry:			*//*			    flags: if FILE_MUST_OPEN = 1, directory 	*//*				   will be extended if necessary.	*//*			  on exit:					*//*			    flags: FILE_IS_DIRECTORY and            	*//*				   FILE_IS_ROOT_DIR set if true.	*//*			    fileSize: Set for non-directory files.  	*//*                          currentCluster: Set to 0 (unknown)		*//*			    ownerDirCluster: Set to 1st cluster of      *//*				      owning directory.			*//*			    directorySector: Sector of directory. If 0  *//*				      entry not found and directory full*//*			    directoryEntry: Entry # in directory sector *//*			    currentPosition: not set by this routine.   *//*									*//* Returns:                                                             *//*	FLStatus	: 0 on success and file found			*//*			  flFileNotFound on success and file not found	*//*			  otherwise failed.				*//*----------------------------------------------------------------------*/static FLStatus findDirEntry(Volume vol, FLSimplePath FAR1 *path, File *file){  File scanFile;		/* Internal file of search */  unsigned dirBackPointer = 0;	/* 1st cluster of previous directory */  FLStatus status = flOK;		/* root directory exists */  file->flags |= (FILE_IS_ROOT_DIR | FILE_IS_DIRECTORY);  file->fileSize = (long) (vol.sectorsInRootDirectory) << SECTOR_SIZE_BITS;  file->fileVol = &vol;#ifdef SUB_DIRECTORY  for (; path->name[0]; path++) /* while we have another path segment */#else  if (path->name[0])    /* search the root directory */#endif  {    status = flFileNotFound;		/* not yet */    if (!(file->flags & FILE_IS_DIRECTORY))      return flPathNotFound;  /* if we don't have a directory,			       we have no business here */    scanFile = *file;	    /* the previous file found becomes the scan file */    scanFile.currentPosition = 0;    file->directorySector = 0;	/* indicate no entry found yet */    file->flags &= ~(FILE_IS_ROOT_DIR | FILE_IS_DIRECTORY);    file->ownerDirCluster = dirBackPointer;    file->fileSize = 0;    file->currentCluster = 0;    /* Scan directory */    while (scanFile.currentPosition < scanFile.fileSize) {      int i;      DirectoryEntry FAR0 *dirEntry;      SectorNo sectorOfDir;      unsigned offsetInSector;      FLStatus readStatus = getSectorAndOffset(&scanFile,&sectorOfDir,&offsetInSector);      if (readStatus == flInvalidFATchain) {	scanFile.fileSize = scanFile.currentPosition;	/* now we know */	break;		/* we ran into the end of the directory file */      }      else if (readStatus != flOK)	return readStatus;      dirEntry = (DirectoryEntry FAR0 *) findSector(&vol,sectorOfDir);      if (dirEntry == NULL)	return flSectorNotFound;      scanFile.currentPosition += SECTOR_SIZE;      for (i = 0; i < DIRECTORY_ENTRIES_PER_SECTOR; i++, dirEntry++) {	if (tffscmp(path,dirEntry->name,sizeof dirEntry->name) == 0 &&	    !(dirEntry->attributes & ATTR_VOL_LABEL)) {	  /* Found a match */	  file->directorySector = sectorOfDir;	  file->directoryIndex = i;	  file->fileSize = LE4(dirEntry->fileSize);	  if (dirEntry->attributes & ATTR_DIRECTORY) {	    file->flags |= FILE_IS_DIRECTORY;	    file->fileSize = 0x7fffffffl;	    /* Infinite. Directories don't have a recorded size */	  }	  if (dirEntry->attributes & ATTR_READ_ONLY)	    file->flags |= FILE_READ_ONLY;	  dirBackPointer = LE2(dirEntry->startingCluster);	  status = flOK;	  goto endOfPathSegment;	}	else if (dirEntry->name[0] == NEVER_USED_DIR_ENTRY ||		 dirEntry->name[0] == DELETED_DIR_ENTRY) {	  /* Found a free entry. Remember it in case we don't find a match */	  if (file->directorySector == 0) {	    file->directorySector = sectorOfDir;	    file->directoryIndex = i;	  }	  if (dirEntry->name[0] == NEVER_USED_DIR_ENTRY)	/* end of dir */	    goto endOfPathSegment;	}      }    }endOfPathSegment:    ;  }  if (status == flFileNotFound && (file->flags & FILE_MUST_OPEN) &&      file->directorySector == 0) {    /* We did not find a place in the directory for this new entry. The */    /* directory should be extended. 'scanFile' refers to the directory */    /* to extend, and the current pointer is at its end			*/#ifdef SUB_DIRECTORY    checkStatus(extendDirectory(&scanFile,(unsigned) file->ownerDirCluster));    file->directorySector = firstSectorOfCluster(&vol,scanFile.currentCluster);    file->directoryIndex = 0;	      /* Has to be. This is a new cluster */#else    status = flRootDirectoryFull;#endif  }  return status;}/*----------------------------------------------------------------------*//*		      	 r e a d F i l e				*//*									*//* Reads from the current position in the file to the user-buffer.	*//* Parameters:                                                          *//*      file		: File to read.					*//*      ioreq->irData	: Address of user buffer			*//*	ioreq->irLength	: Number of bytes to read. If the read extends  *//*			  beyond the end-of-file, the read is truncated *//*			  at the end-of-file.				*//*                                                                      *//* Returns:                                                             *//*	FLStatus	: 0 on success, otherwise failed                *//*	ioreq->irLength	: Actual number of bytes read			*//*----------------------------------------------------------------------*/static FLStatus readFile(File *file,IOreq FAR2 *ioreq){  Volume vol = file->fileVol;  char FAR1 *userData = (char FAR1 *) ioreq->irData;   /* user buffer address */  unsigned long stillToRead = ioreq->irLength;  unsigned long remainingInFile = file->fileSize - file->currentPosition;  ioreq->irLength = 0;		/* read so far */  /* Should we return an end of file status ? */  if (stillToRead > remainingInFile)    stillToRead = (unsigned) remainingInFile;  while (stillToRead > 0) {    SectorNo sectorToRead;    unsigned offsetInSector;    unsigned readThisTime;    const char FAR0 *sector;    checkStatus(getSectorAndOffset(file,&sectorToRead,&offsetInSector));    sector = (const char FAR0 *) findSector(&vol,sectorToRead);    readThisTime = SECTOR_SIZE - offsetInSector;    if (readThisTime > stillToRead)      readThisTime = (unsigned) stillToRead;    if (sector)      tffscpy(userData,sector + offsetInSector,readThisTime);    else      return flSectorNotFound;		/* Sector does not exist */    stillToRead -= readThisTime;    ioreq->irLength += readThisTime;    userData += readThisTime;    file->currentPosition += readThisTime;  }  return flOK;}/*----------------------------------------------------------------------*//*		 f l F i n d N e x t F i l e				*//*                                                                      *//* See the description of 'flFindFirstFile'.				*//*                                                                      *//* Parameters:                                                          *//*	irHandle	: File handle returned by flFindFirstFile.	*//*	irData		: Address of user buffer to receive a		*//*			  DirectoryEntry structure			*//*                                                                      *//* Returns:                                                             *//*	FLStatus	: 0 on success, otherwise failed                *//*----------------------------------------------------------------------*/static FLStatus findNextFile(File *file, IOreq FAR2 *ioreq){  DirectoryEntry FAR1 *irDirEntry = (DirectoryEntry FAR1 *) ioreq->irData;  /* Do we have a directory ? */  if (!(file->flags & FILE_IS_DIRECTORY))    return flNotADirectory;  ioreq->irLength = DIRECTORY_ENTRY_SIZE;  do {    readFile(file,ioreq);    if (ioreq->irLength != DIRECTORY_ENTRY_SIZE ||	irDirEntry->name[0] == NEVER_USED_DIR_ENTRY) {      checkStatus(closeFile(file));      return flNoMoreFiles;    }  } while (irDirEntry->name[0] == DELETED_DIR_ENTRY ||	   (irDirEntry->attributes & ATTR_VOL_LABEL));  return flOK;}/*----------------------------------------------------------------------*//*		         d e l e t e F i l e				*//*									*//* Deletes a file or directory.                                         *//*                                                                      *//* Parameters:                                                          *//*	ioreq->irPath	: path of file to delete			*//*	isDirectory	: 0 = delete file, other = delete directory	*//*                                                                      *//* Returns:                                                             *//*	FLStatus	: 0 on success, otherwise failed                *//*----------------------------------------------------------------------*/static FLStatus deleteFile(Volume vol, IOreq FAR2 *ioreq, FLBoolean isDirectory){  File file;		/* Our private file */  DirectoryEntry *dirEntry;  file.flags = 0;  checkStatus(findDirEntry(&vol,ioreq->irPath,&file));  if (file.flags & FILE_READ_ONLY)    return flNoWriteAccess;  if (isDirectory) {    DirectoryEntry fileFindInfo;    ioreq->irData = &fileFindInfo;    if (!(file.flags & FILE_IS_DIRECTORY))      return flNotADirectory;    /* Verify that directory is empty */    file.currentPosition = 0;    for (;;) {      FLStatus status = findNextFile(&file,ioreq);      if (status == flNoMoreFiles)	break;      if (status != flOK)	return status;      if (!((fileFindInfo.attributes & ATTR_DIRECTORY) &&	    (tffscmp(fileFindInfo.name,".          ",sizeof fileFindInfo.name) == 0 ||	     tffscmp(fileFindInfo.name,"..         ",sizeof fileFindInfo.name) == 0)))	return flDirectoryNotEmpty;    }  }  else {    /* Did we find a directory ? */    if (file.flags & FILE_IS_DIRECTORY)      return flFileIsADirectory;  }  /* Mark directory entry deleted */  checkStatus(getDirEntryForUpdate(&file,&dirEntry));  dirEntry->name[0] = DELETED_DIR_ENTRY;  /* Delete FAT entries */  file.currentPosition = 0;  file.currentCluster = LE2(dirEntry->startingCluster);  while (file.currentPosition < file.fileSize) {    unsigned nextCluster;    if (file.currentCluster < 2 || file.currentCluster > vol.maxCluster)      /* We have a bad file size, or the FAT is bad */      return isDirectory ? flOK : flInvalidFATchain;    nextCluster = getFATentry(&vol,file.currentCluster);    /* mark FAT free */    checkStatus(setFATentry(&vol,file.currentCluster,FAT_FREE));    buffer.checkPoint = TRUE;    /* mark sectors free */    checkStatus(vol.tl.deleteSector(vol.tl.rec,				    firstSectorOfCluster(&vol,file.currentCluster),				    vol.sectorsPerCluster));    file.currentPosition += vol.bytesPerCluster;    file.currentCluster = nextCluster;  }  return flOK;}/*----------------------------------------------------------------------*//*		     s e t N a m e I n D i r E n t r y			*//*									*//* Sets the file name in a directory entry from a path name             *//*                                                                      *//* Parameters:                                                          *//*	dirEntry	: directory entry				*//*	path		: path the last segment of which is the name	*//*                                                                      *//*----------------------------------------------------------------------*/static void setNameInDirEntry(DirectoryEntry *dirEntry, FLSimplePath FAR1 *path){  FLSimplePath FAR1 *lastSegment;  for (lastSegment = pat

⌨️ 快捷键说明

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