static int _FS_fat_format(const FS__device_type *pDriver,FS_u32 Unit, char SecPerClus, FS_u16 RootEntCnt, FS_u16 TotSec16, FS_u32 TotSec32, char Media, FS_u16 FATSz16, FS_u32 FATSz32, FS_u16 SecPerTrk,FS_u16 NumHeads, FS_u32 HiddSec, char FSysType) { FS__FAT_BPB bpb; FS_u32 sector; FS_u32 value; char *buffer; int i; int j; int n; buffer = FS__fat_malloc(FS_FAT_SEC_SIZE); if (!buffer) { return -1; } FS__CLIB_memset(buffer, 0x00, (FS_size_t)FS_FAT_SEC_SIZE); /* Setup BPB */ FS__CLIB_memset(&bpb, 0x00, (FS_size_t)sizeof(bpb)); bpb.BytesPerSec = 0x0200; /* _512_,1024,2048,4096 */ bpb.SecPerClus = SecPerClus; /* sec in allocation unit */ if (FSysType != 2) { bpb.RsvdSecCnt = 0x0001; /* 1 for FAT12 & FAT16 */ } #if (FS_FAT_NOFAT32==0) else { bpb.RsvdSecCnt = 0x0020; /* 32 for FAT32 */ } #else /* FAT32 disabled */ else {
static void *FS_malloc(void) { FS_i32 i; FS_X_OS_LockMem(); for (i = 0; i < FS_MAX_MEM; i++) { if (_FS_memblock[i].status == 0) { _FS_memblock[i].status = 1; FS__CLIB_memset((void*)&_FS_memblock[i].memory, 0, (FS_size_t)FS_MEM_SIZE); FS_X_OS_UnlockMem(); return ((void*)&(_FS_memblock[i].memory)); } } FS_X_OS_UnlockMem(); return 0; }
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; }
static int _FS_fat_create_directory(int Idx, FS_u32 Unit, const char *pDirName, FS_u32 DirStart, FS_u32 DirSize) { char *buffer; FS__fat_dentry_type *s; FS_u32 dirindex; FS_u32 dsec; FS_i32 cluster; FS_u16 val_time; FS_u16 val_date; int err; int len; int j; buffer = FS__fat_malloc(FS_FAT_SEC_SIZE); if (!buffer) { return -1; } len = FS__CLIB_strlen(pDirName); if (len > 11) { len = 11; } /* Read directory */ for (dirindex = 0; dirindex < DirSize; dirindex++) { dsec = FS__fat_dir_realsec(Idx, Unit, DirStart, dirindex); if (dsec == 0) { /* Translation of relativ directory sector to an absolute sector failed */ FS__fat_free(buffer); return -1; } err = FS__lb_read(FS__pDevInfo[Idx].devdriver, Unit, dsec, (void*)buffer); /* Read directory sector */ if (err < 0) { /* Read error */ FS__fat_free(buffer); return -1; } /* Scan the directory sector for a free or deleted entry */ 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; /* Found a free entry */ } if (s->data[0] == (unsigned char)0xe5) { break; /* Found a deleted entry */ } 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, pDirName, len); s->data[11] = FS_FAT_ATTR_DIRECTORY; cluster = FS__fat_FAT_alloc(Idx, Unit, -1); /* Alloc block in FAT */ 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_time = FS_X_OS_GetTime(); s->data[22] = (unsigned char)(val_time & 0xff); /* WrtTime */ s->data[23] = (unsigned char)(val_time / 256); val_date = FS_X_OS_GetDate(); s->data[24] = (unsigned char)(val_date & 0xff); /* WrtDate */ s->data[25] = (unsigned char)(val_date / 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); /* Write the modified directory sector */ if (err < 0) { FS__fat_free(buffer); return -1; } /* Clear new directory and make '.' and '..' entries */ /* Make "." entry */ FS__CLIB_memset(buffer, 0x00, (FS_size_t)FS_FAT_SEC_SIZE); s = (FS__fat_dentry_type*)buffer; FS__CLIB_strncpy((char*)s->data, ". ", 11); s->data[11] = FS_FAT_ATTR_DIRECTORY; s->data[22] = (unsigned char)(val_time & 0xff); /* WrtTime */ s->data[23] = (unsigned char)(val_time / 256); s->data[24] = (unsigned char)(val_date & 0xff); /* WrtDate */ s->data[25] = (unsigned char)(val_date / 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); /* Make entry ".." */ s++; FS__CLIB_strncpy((char*)s->data, ".. ", 11); s->data[11] = FS_FAT_ATTR_DIRECTORY; s->data[22] = (unsigned char)(val_time & 0xff); /* WrtTime */ s->data[23] = (unsigned char)(val_time / 256); s->data[24] = (unsigned char)(val_date & 0xff); /* WrtDate */ s->data[25] = (unsigned char)(val_date / 256); s->data[26] = (unsigned char)(DirStart & 0xff); /* FstClusLo / FstClusHi */ s->data[27] = (unsigned char)((DirStart / 256) & 0xff); s->data[20] = (unsigned char)((DirStart / 0x10000L) & 0xff); s->data[21] = (unsigned char)((DirStart / 0x1000000L) & 0xff); dsec = FS__fat_dir_realsec(Idx, Unit, cluster, 0); /* Find 1st absolute sector of the new directory */ if (dsec == 0) { FS__fat_free(buffer); return -1; } /* Write "." & ".." entries into the new directory */ err = FS__lb_write(FS__pDevInfo[Idx].devdriver, Unit, dsec, (void*)buffer); if (err < 0) { FS__fat_free(buffer); return -1; } /* Clear rest of the directory cluster */ FS__CLIB_memset(buffer, 0x00, (FS_size_t)FS_FAT_SEC_SIZE); for (j = 1; j < FS__FAT_aBPBUnit[Idx][Unit].SecPerClus; j++) { dsec = FS__fat_dir_realsec(Idx, Unit, cluster, j); 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_free(buffer); return -1; } } FS__fat_free(buffer); return -2; /* Directory is full */ }