📄 fat_open.c
字号:
/*
**********************************************************************
* Micrium, Inc.
* 949 Crestview Circle
* Weston, FL 33327-1848
*
* uC/FS
*
* (c) Copyright 2001 - 2003, Micrium, Inc.
* All rights reserved.
*
***********************************************************************
----------------------------------------------------------------------
File : fat_open.c
Purpose : FAT routines for open/delete files
----------------------------------------------------------------------
Known problems or limitations with current version
----------------------------------------------------------------------
None.
---------------------------END-OF-HEADER------------------------------
*/
/*********************************************************************
*
* #include Section
*
**********************************************************************
*/
#include "fs_conf.h"
#include "fs_port.h"
#ifndef FS_FARCHARPTR
#define FS_FARCHARPTR char *
#endif
#include "fs_dev.h"
#include "fs_api.h"
#include "fs_fsl.h"
#include "fs_int.h"
#include "fs_os.h"
#include "fs_lbl.h"
#include "fs_fat.h"
#include "fs_clib.h"
/*********************************************************************
*
* #define constants
*
**********************************************************************
*/
#ifndef FS_FAT_NOFAT32
#define FS_FAT_NOFAT32 0
#endif /* FS_FAT_NOFAT32 */
/*********************************************************************
*
* Local functions
*
**********************************************************************
*/
/*********************************************************************
*
* _FS_fat_find_file
*
Description:
FS internal function. Find the file with name pFileName in directory
DirStart. Copy its directory entry to pDirEntry.
Parameters:
Idx - Index of device in the device information table
referred by FS__pDevInfo.
Unit - Unit number.
pFileName - File name.
pDirEntry - Pointer to an FS__fat_dentry_type data structure.
DirStart - 1st cluster of the directory.
DirSize - Sector (not cluster) size of the directory.
Return value:
>=0 - File found. Value is the first cluster of the file.
<0 - An error has occured.
*/
static FS_i32 _FS_fat_find_file(int Idx, FS_u32 Unit, const char *pFileName,
FS__fat_dentry_type *pDirEntry,
FS_u32 DirStart, FS_u32 DirSize) {
FS__fat_dentry_type *s;
FS_u32 i;
FS_u32 dsec;
int len;
int err;
int c;
char *buffer;
buffer = FS__fat_malloc(FS_FAT_SEC_SIZE);
if (!buffer) {
return -1;
}
len = FS__CLIB_strlen(pFileName);
if (len > 11) {
len = 11;
}
/* Read directory */
for (i = 0; i < DirSize; i++) {
dsec = FS__fat_dir_realsec(Idx, Unit, DirStart, i);
if (dsec == 0) {
FS__fat_free(buffer);
return -1;
}
err = FS__lb_read(FS__pDevInfo[Idx].devdriver, Unit, dsec, (void*)buffer);
if (err < 0) {
FS__fat_free(buffer);
return -1;
}
s = (FS__fat_dentry_type*)buffer;
while (1) {
if (s >= (FS__fat_dentry_type*)(buffer + FS_FAT_SEC_SIZE)) {
break; /* End of sector reached */
}
c = FS__CLIB_strncmp((char*)s->data, pFileName, len);
if (c == 0) { /* Name does match */
if (s->data[11] & FS_FAT_ATTR_ARCHIVE) {
break; /* Entry found */
}
}
s++;
}
if (s < (FS__fat_dentry_type*)(buffer + FS_FAT_SEC_SIZE)) {
/* Entry found. Return number of 1st block of the file */
if (pDirEntry) {
FS__CLIB_memcpy(pDirEntry, s, sizeof(FS__fat_dentry_type));
}
FS__fat_free(buffer);
dsec = (FS_u32)s->data[26];
dsec += (FS_u32)s->data[27] * 0x100UL;
dsec += (FS_u32)s->data[20] * 0x10000UL;
dsec += (FS_u32)s->data[21] * 0x1000000UL;
return ((FS_i32)dsec);
}
}
FS__fat_free(buffer);
return -1;
}
/*********************************************************************
*
* _FS_fat_IncDir
*
Description:
FS internal function. Increase directory starting at DirStart.
Parameters:
Idx - Index of device in the device information table
referred by FS__pDevInfo.
Unit - Unit number.
DirStart - 1st cluster of the directory.
pDirSize - Pointer to an FS_u32, which is used to return the new
sector (not cluster) size of the directory.
Return value:
==1 - Success.
==-1 - An error has occured.
*/
static int _FS_fat_IncDir(int Idx, FS_u32 Unit, FS_u32 DirStart, FS_u32 *pDirSize) {
FS_u32 i;
FS_u32 dsec;
FS_i32 last;
char *buffer;
int err;
if (DirStart == 0) {
/* Increase root directory only, if not FAT12/16 */
i = FS__FAT_aBPBUnit[Idx][Unit].RootEntCnt;
if (i != 0) {
return -1; /* Not FAT32 */
}
}
last = FS__fat_FAT_find_eof(Idx, Unit, DirStart, 0);
if (last < 0) {
return -1; /* No EOF marker found */
}
last = FS__fat_FAT_alloc(Idx, Unit, last); /* Allocate new cluster */
if (last < 0) {
return -1;
}
*pDirSize = *pDirSize + FS__FAT_aBPBUnit[Idx][Unit].SecPerClus;
/* Clean new directory cluster */
buffer = FS__fat_malloc(FS_FAT_SEC_SIZE);
if (!buffer) {
return -1;
}
FS__CLIB_memset(buffer, 0x00, (FS_size_t)FS_FAT_SEC_SIZE);
for (i = *pDirSize - FS__FAT_aBPBUnit[Idx][Unit].SecPerClus; i < *pDirSize; i++) {
dsec = FS__fat_dir_realsec(Idx, Unit, DirStart, i);
if (dsec == 0) {
FS__fat_free(buffer);
return -1;
}
err = FS__lb_write(FS__pDevInfo[Idx].devdriver, Unit, dsec, (void*)buffer);
if (err < 0) {
FS__fat_free(buffer);
return -1;
}
}
FS__fat_free(buffer);
return 1;
}
/*********************************************************************
*
* _FS_fat_create_file
*
Description:
FS internal function. Create a file in the directory specified
with DirStart. Do not call, if you have not checked before for
existing file with name pFileName.
Parameters:
Idx - Index of device in the device information table
referred by FS__pDevInfo.
Unit - Unit number, which is passed to the device driver.
pFileName - File name.
DirStart - Start of directory, where to create pDirName.
DirSize - Sector size of the directory starting at DirStart.
Return value:
>=0 - 1st cluster of the new file.
==-1 - An error has occured.
==-2 - Cannot create, because directory is full.
*/
static FS_i32 _FS_fat_create_file(int Idx, FS_u32 Unit, const char *pFileName,
FS_u32 DirStart, FS_u32 DirSize) {
FS__fat_dentry_type *s;
FS_u32 i;
FS_u32 dsec;
FS_i32 cluster;
int len;
int err;
FS_u16 val;
char *buffer;
buffer = FS__fat_malloc(FS_FAT_SEC_SIZE);
if (!buffer) {
return -1;
}
len = FS__CLIB_strlen(pFileName);
if (len > 11) {
len = 11;
}
/* Read directory */
for (i = 0; i < DirSize; i++) {
dsec = FS__fat_dir_realsec(Idx, Unit, DirStart, i);
if (dsec == 0) {
FS__fat_free(buffer);
return -1;
}
err = FS__lb_read(FS__pDevInfo[Idx].devdriver, Unit, dsec, (void*)buffer);
if (err < 0) {
FS__fat_free(buffer);
return -1;
}
s = (FS__fat_dentry_type*)buffer;
while (1) {
if (s >= (FS__fat_dentry_type*)(buffer + FS_FAT_SEC_SIZE)) {
break; /* End of sector reached */
}
if (s->data[0] == 0x00) {
break; /* Empty entry found */
}
if (s->data[0] == (unsigned char)0xe5) {
break; /* Deleted entry found */
}
s++;
}
if (s < (FS__fat_dentry_type*)(buffer + FS_FAT_SEC_SIZE)) {
/* Free entry found. Make entry and return 1st block of the file */
FS__CLIB_strncpy((char*)s->data, pFileName, len);
s->data[11] = FS_FAT_ATTR_ARCHIVE;
/* Alloc block in FAT */
cluster = FS__fat_FAT_alloc(Idx, Unit, -1);
if (cluster >= 0) {
s->data[12] = 0x00; /* Res */
s->data[13] = 0x00; /* CrtTimeTenth (optional, not supported) */
s->data[14] = 0x00; /* CrtTime (optional, not supported) */
s->data[15] = 0x00;
s->data[16] = 0x00; /* CrtDate (optional, not supported) */
s->data[17] = 0x00;
s->data[18] = 0x00; /* LstAccDate (optional, not supported) */
s->data[19] = 0x00;
val = FS_X_OS_GetTime();
s->data[22] = (unsigned char)(val & 0xff); /* WrtTime */
s->data[23] = (unsigned char)(val / 256);
val = FS_X_OS_GetDate();
s->data[24] = (unsigned char)(val & 0xff); /* WrtDate */
s->data[25] = (unsigned char)(val / 256);
s->data[26] = (unsigned char)(cluster & 0xff); /* FstClusLo / FstClusHi */
s->data[27] = (unsigned char)((cluster / 256) & 0xff);
s->data[20] = (unsigned char)((cluster / 0x10000L) & 0xff);
s->data[21] = (unsigned char)((cluster / 0x1000000L) & 0xff);
s->data[28] = 0x00; /* FileSize */
s->data[29] = 0x00;
s->data[30] = 0x00;
s->data[31] = 0x00;
err = FS__lb_write(FS__pDevInfo[Idx].devdriver, Unit, dsec, (void*)buffer);
if (err < 0) {
FS__fat_free(buffer);
return -1;
}
}
FS__fat_free(buffer);
return cluster;
}
}
FS__fat_free(buffer);
return -2; /* Directory is full */
}
/*********************************************************************
*
* Global functions section 1
*
**********************************************************************
Functions in this section are global, but are used inside the FAT
File System Layer only.
*/
/*********************************************************************
*
* FS__fat_DeleteFileOrDir
*
Description:
FS internal function. Delete a file or directory.
Parameters:
Idx - Index of device in the device information table
referred by FS__pDevInfo.
Unit - Unit number, which is passed to the device driver.
pName - File or directory name.
DirStart - Start of directory, where to create pDirName.
DirSize - Sector size of the directory starting at DirStart.
RmFile - 1 => remove a file
0 => remove a directory
Return value:
>=0 - Success.
<0 - An error has occured.
*/
FS_i32 FS__fat_DeleteFileOrDir(int Idx, FS_u32 Unit, const char *pName,
FS_u32 DirStart, FS_u32 DirSize, char RmFile) {
FS__fat_dentry_type *s;
FS_u32 dsec;
FS_u32 i;
FS_u32 value;
FS_u32 fatsize;
FS_u32 filesize;
FS_i32 len;
FS_i32 bytespersec;
FS_i32 fatindex;
FS_i32 fatsec;
FS_i32 fatoffs;
FS_i32 lastsec;
FS_i32 curclst;
FS_i32 todo;
char *buffer;
int fattype;
int err;
int err2;
int lexp;
int x;
unsigned char a;
unsigned char b;
#if (FS_FAT_NOFAT32==0)
unsigned char c;
unsigned char d;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -