dir.c

来自「Atmega64单片机程序(完整工程)」· C语言 代码 · 共 504 行

C
504
字号

#define IN_DIR 

#include "SYS_Config.h" 
#include "SD_Drive.h" 
#include "fat.h" 
#include "time.h" 

static INT8U CurrentDrive ;

char *strupr(char *Str);

INT32U GetDirClusIndex(char *Path);

/*********************************************************************************************************
** 函数名称: StrToFDTName
** 功能描述: 用户文件\目录名转换为系统名
** 输   入: Str:用户名称
** 输   出: 驱动器号
** 全局变量: 无
** 调用模块: 无
********************************************************************************************************/
INT8U StrToFDTName(char *FDTName,char *Str)
{
    INT8U i,temp ;
    
    /* 文件\目录名是否有效 */
    if(Str[0]==0x20||Str[0]==0)
    {
        return FILE_NAME_ERR ;
    }
    
    for(i=11;i!=0;i--)
    {
        *FDTName++=0x20 ;//0x20表示为空
    }
    FDTName-=11 ;
    
    /* 是否为"." */
    if(Str[0]=='.')
    if(Str[1]==0||Str[1]=='\\')
    {
        FDTName[0]='.' ;
        return RETURN_OK ;
    }
    
    /* 是否为".." */
    if(Str[0]=='.')
    if(Str[1]=='.')
    if(Str[2]==0||Str[2]=='\\')
    {
        FDTName[0]='.' ;
        FDTName[1]='.' ;
        return RETURN_OK ;
    }
    
    /* 获取主文件/目录名 */
    for(i=8;i!=0;i--)
    {
        temp=*Str ;
        if(temp==0||temp=='\\')
        {
            break ;
        }
        Str++;
        if(temp=='.')
        {
            break ;
        }
        *FDTName++=temp ;
    }
    FDTName+=i ;
    
    /* 获取文件\目录扩展名 */
    for(i=3;i!=0;i--)
    {
        temp=*Str ;
        if(temp==0||temp=='\\')
        {
            break ;
        }
        Str++;
        *FDTName++=temp ;
    }
    return RETURN_OK ;
}

/*********************************************************************************************************
** 函数名称: _GetFDTInfo
** 功能描述: 获取FDT所在的目录的开始簇号及系统内名称,内部使用
** 输   入: DirFileName:用户使用的FDT名(包括路径)
**           FDTName:用于返回系统使用的FDT名(不包括路径)
** 输   出: FDT所在的目录的开始簇号,BAD_CLUS表示找不到路径
** 全局变量: 无
** 调用模块: GetDirClusIndex,StrToFDTName
********************************************************************************************************/
INT32U _GetFDTInfo(char *FDTName,char *DirFileName)
{
    INT32U Rt ;
    char   *temp ;
    INT8U  i ;
    
    temp=DirFileName ;/* 获取字符串结束位置 */
    while(*temp!=0)
    {
        temp++;
    }
    temp--;
    
    if(*temp=='\\')/* 最后字符为\不是有效文件/目录名 */
    {
        return BAD_CLUS ;
    }
    
    /* 获取目录开始簇号 */
    Rt=BAD_CLUS ;
    while(1)
    {
        if(*temp=='\\'||*temp==':')
        {
            /* 找到目录分割符号'\' 或 */
            /* 找到逻辑盘分割符号':',表明是指定逻辑盘当前目录 */
            temp++;
            i=*temp ;
            *temp=0 ;
            Rt=GetDirClusIndex(DirFileName);
            *temp=i ;
            break ;
        }
        if(temp==DirFileName)
        {
            /* 只有文件\目录名,表明是当前逻辑盘当前目录 */
            Rt=GetDirClusIndex(".");
            break ;
        }
        temp--;
    }
    /* 获取系统内文件\目录名 */
    if(StrToFDTName(FDTName,temp)!=RETURN_OK)
    {
        Rt=BAD_CLUS ;
    }
    return Rt ;
}

/*********************************************************************************************************
** 函数名称: GetDrive
** 功能描述: 获取指定目录的驱动器
** 输   入: Path:路径名
** 输   出: 驱动器号
** 全局变量: 无
** 调用模块: 无
********************************************************************************************************/
INT8U GetDrive(char *Path)
{
    INT8U Drive ;
    
    Drive=CurrentDrive ;
    if(Path!=NULL)
    {
        strupr(Path);/* 变为大写 */
        
        if(Path[1]==':')
        {
            Drive=Path[0]-'A' ;
        }
    }
    return Drive ;
}

/*********************************************************************************************************
** 函数名称: ChangeDrive
** 功能描述: 改变当前逻辑盘
** 输   入: Drive:逻辑盘符字符串
** 输   出: RETURN_OK:成功
**           NOT_FIND_DISK:逻辑盘不存在
**           PARAMETER_ERR:非法参数
** 全局变量: 无
** 调用模块: strupr,GetDiskInfo
********************************************************************************************************/
INT8U ChangeDrive(char *Drive)
{
    INT8U Rt ;
    Disk_Info *Disk ;
    
    Rt=PARAMETER_ERR ;
    strupr(Drive);/* 变为大写 */
    
    if(Drive[1]==':')
    {
        Rt=NOT_FIND_DISK ;
        Disk=GetDiskInfo(Drive[0]-'A');
        if(Disk!=NULL)
        {
            CurrentDrive=Drive[0]-'A' ;
            Rt=RETURN_OK ;
        }
    }
    return Rt ;
}

/*********************************************************************************************************
** 函数名称: GetDirClusIndex
** 功能描述: 获取指定目录开始簇号
** 输   入: Path:路径名
** 输   出: 开始簇号,EMPTY_CLUS:为根目录
** 全局变量: 无
** 调用模块: strupr,GetDiskInfo,FindFDTInfo
********************************************************************************************************/
INT32U GetDirClusIndex(char *Path)
{
    char DirName[12];
    INT8U Drive ;
    INT32U Rt ;
    FDT temp ;
    Disk_Info *Disk ;
    
    Rt=BAD_CLUS ;
    if(Path!=NULL)
    {
        strupr(Path);/* 变为大写 */
        Drive=GetDrive(Path);/* 获取路基盘符 */
        if(Path[1]==':')
        {
            Path+=2 ;
        }
        Disk=GetDiskInfo(Drive);/* 获取逻辑盘信息 */
        if(Disk!=NULL)
        {
            Rt=0 ;
            if(Disk->FATType==FAT32)/* FAT32 根目录 */
            {
                Rt=Disk->RootDirTable ;
            }
            if(Path[0]!='\\')/* 不是目录分隔符号,表明起点是当前路径 */
            {
                Rt=Disk->PathClusIndex ;
            }
            else 
            {
                Path++;
            }
            /* '\.'表明起点是当前路径 */
            if(Path[0]=='.')
            {
                Rt=Disk->PathClusIndex ;
                if(Path[1]==0||Path[1]=='\\')
                {
                    Path++;
                }
            }
            if(Path[0]=='\\')
            {
                Path++;
            }
            
            DirName[11]=0 ;
            while(Path[0]!=0)
            {
                /* 获取子目录名 */
                StrToFDTName(DirName,Path);
                
                /* 子目录名开始簇号 */
                if(DirName[0]==0x20)
                {
                    Rt=BAD_CLUS ;
                    break ;
                }
                /* 获取FDT信息 */
                if(FindFDTInfo(&temp,Drive,Rt,DirName)!=RETURN_OK)
                {
                    Rt=BAD_CLUS ;
                    break ;
                }
                /* FDT是否是目录 */
                if((temp.Attr&ATTR_DIRECTORY)==0)
                {
                    Rt=BAD_CLUS ;
                    break ;
                }
                Rt=temp.FstClusLO+((INT32U)(temp.FstClusHI)<<16);
                /* 字符串到下一个目录 */
                while(1)
                {
                    if(*Path=='\\')
                    {
                        Path++;
                        break ;
                    }
                    if(*Path==0)
                    {
                        break ;
                    }
                    Path++;
                }
            }
        }
        if(Disk->FATType==FAT32)
        if(Rt!=BAD_CLUS)
        if(Rt==Disk->RootDirTable)
        {
            Rt=0 ;
        }
    }
    return Rt ;
}

/*********************************************************************************************************
** 函数名称: MakeDir
** 功能描述: 建立目录
** 输   入: Path:路径名
** 输   出: RETURN_OK:成功
**           其它参考fat.h中关于返回值的说明
** 全局变量: 无
** 调用模块: strupr,ClearClus,AddFDT
********************************************************************************************************/
INT8U MakeDir(char *Path)
{
    INT32U ClusIndex,Temp1 ;
    INT8U  Drive,Rt ;
    FDT    temp ;
    
    strupr(Path);/* 变为大写 */
    
    ClusIndex=_GetFDTInfo(temp.Name,Path);
    if(ClusIndex==BAD_CLUS)
    {
        return PATH_NOT_FIND ;
    }
    
    Drive=GetDrive(Path);
    
    /* FDT是否存在 */
    Rt=FDTIsLie(Drive,ClusIndex,temp.Name);
    if(Rt!=NOT_FIND_FDT)
    {
        return Rt ;
    }
    
    /* 不存在 */
    Temp1=FATAddClus(Drive,0);
    
    if((Temp1<=EMPTY_CLUS_1)||(Temp1>=BAD_CLUS))/* 获取目录所需磁盘空间 */
    {
        /* 没有空闲空间 */
        return DISK_FULL ;
    }
    
    ClearClus(Drive,Temp1);
    /* 清空簇 */
    
    /* 设置FDT属性 */
    temp.Attr=ATTR_DIRECTORY ;
    temp.FileSize=0 ;
    
    temp.NTRes=0 ;
    temp.CrtTimeTenth=time_getTime();
    temp.CrtTime=time_getTime();
    temp.CrtDate=time_getDate();
    temp.LstAccDate=time_getDate();
    temp.WrtTime=time_getTime();
    temp.WrtDate=time_getDate();
    
    temp.FstClusLO=(INT16U)(Temp1&0xffff);
    //temp.FstClusHI=Temp1/0x10000 ;
    temp.FstClusHI=(INT16U)(Temp1>>16);
    
    Rt=AddFDT(Drive,ClusIndex,&temp);
    /* 增加目录项 */
    if(Rt==RETURN_OK)
    {
        /* 建立'.'目录 */
        temp.Name[0]='.' ;
        temp.Name[1]=0x20 ;
        temp.Name[2]=0x20 ;
        temp.Name[3]=0x20 ;
        temp.Name[4]=0x20 ;
        temp.Name[5]=0x20 ;
        temp.Name[6]=0x20 ;
        temp.Name[7]=0x20 ;
        temp.Name[8]=0x20 ;
        temp.Name[9]=0x20 ;
        temp.Name[10]=0x20 ;
        
        AddFDT(Drive,Temp1,&temp);
        
        /* 建立'..'目录 */
        temp.Name[1]='.' ;
        
        temp.FstClusLO=(INT16U)(ClusIndex&0xffff);
        //temp.FstClusHI=ClusIndex/0x10000 ;
	    temp.FstClusHI=(INT16U)(Temp1>>16);
	
        Rt=AddFDT(Drive,Temp1,&temp);
    }
    else 
    {
        FATDelClusChain(Drive,Temp1);
    }
    return Rt ;
}

/*********************************************************************************************************
** 函数名称: RemoveDir
** 功能描述: 删除目录
** 输   入: Path:路径名
** 输   出: RETURN_OK:成功
**           其它参考fat.h中关于返回值的说明
** 全局变量: 无
** 调用模块: strupr,DelFDT
********************************************************************************************************/
INT8U RemoveDir(char *Path)
{
    INT32U ClusIndex,ClusIndex1 ;
    INT8U Drive,Rt ;
    char DirName[12];
    FDT temp ;
    
    strupr(Path);
    /* 变为大写 */
    ClusIndex=_GetFDTInfo(DirName,Path);
    if(ClusIndex==BAD_CLUS)
    {
        return PATH_NOT_FIND ;
    }
    
    Drive=GetDrive(Path);
    
    /* 获取FDT其信息 */
    Rt=FindFDTInfo(&temp,Drive,ClusIndex,DirName);
    if(Rt==RETURN_OK)
    {
        /* 是否是目录 */
        if((temp.Attr&ATTR_DIRECTORY)!=0)
        {
            /* 是 */
            ClusIndex1=temp.FstClusLO+((INT32U)(temp.FstClusHI)<<16);
            /* 是否是空目录 */
            Rt=DirIsEmpty(Drive,ClusIndex1);
            if(Rt==DIR_EMPTY)
            {
                /* 是,删除 */
                FATDelClusChain(Drive,ClusIndex1);
                Rt=DelFDT(Drive,ClusIndex,DirName);
            }
        }
        else 
        {
            return PATH_NOT_FIND ;
        }
    }
    return Rt ;
}

/*********************************************************************************************************
** 函数名称: ChangeDir
** 功能描述: 改变当前目录
** 输   入: Path:路径名
** 输   出: RETURN_OK:成功
**           其它参考fat.h中关于返回值的说明
** 全局变量: 无
** 调用模块: GetDirClusIndex,GetDiskInfo
********************************************************************************************************/
INT8U ChangeDir(char *Path)
{
    INT32U ClusIndex ;
    INT8U Rt,Drive ;
    Disk_Info *Disk ;
    
    Rt=PATH_NOT_FIND ;
    ClusIndex=GetDirClusIndex(Path);
    if(ClusIndex!=BAD_CLUS)
    {
        Drive=GetDrive(Path);
        Disk=GetDiskInfo(Drive);
        Rt=NOT_FIND_DISK ;
        if(Disk!=NULL)
        {
            Rt=RETURN_OK ;
            Disk->PathClusIndex=ClusIndex ;
        }
    }
    return Rt ;
}


char *strupr(char *Str)
{
    char *cp;
    cp = Str;
    
    while (*cp != 0)
    {
        if (*cp >= 'a' && *cp <= 'z' )
        {
            *cp -=  'a' - 'A';
        }
        cp++;
    }
    return Str;
}
/*********************************************************************************************************
**                            End Of File
********************************************************************************************************/

⌨️ 快捷键说明

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