void read_fat_bs(uint8_t* buf, struct fat_BS* bs) { memcpy(bs->bootjmp,buf,3); memcpy(bs->oem_name,buf+3,8); bs->bytes_per_sector = read_halfword(buf, 11); bs->sectors_per_cluster = read_byte(buf, 13); bs->reserved_sector_count = read_halfword(buf, 14); bs->table_count = read_byte(buf, 16); bs->root_entry_count = read_halfword(buf, 17); bs->total_sectors_16 = read_halfword(buf, 19); bs->media_type = read_byte(buf, 21); bs->table_size_16 = read_halfword(buf, 22); bs->sectors_per_track = read_halfword(buf, 24); bs->head_side_count = read_halfword(buf, 26); bs->hidden_sector_count = read_word(buf, 28); bs->total_sectors_32 = read_word(buf, 32); if (bs->table_size_16==0) { memcpy(&bs->ext,buf+36,sizeof(struct fat_extBS_32)); } else { bs->ext.fat16.bios_drive_num = read_byte(buf,36); bs->ext.fat16.reserved1 = read_byte(buf,37); bs->ext.fat16.boot_signature = read_byte(buf,38); bs->ext.fat16.volume_id = read_word(buf,39); memcpy(&bs->ext.fat16.volume_label,buf+43,11); memcpy(&bs->ext.fat16.fat_type_label,buf+54,8); } }
struct dirent *fat_read_dir(struct fat_fs *fs, struct dirent *d) { printf("[fat_read_dir]\r\n"); int is_root = 0; struct fat_fs *fat = (struct fat_fs *)fs; if(d == (void*)0) is_root = 1; uint32_t cur_cluster; uint32_t cur_root_cluster_offset = 0; if(is_root) cur_cluster = fat->root_dir_cluster; else cur_cluster = (uint32_t)d->opaque; struct dirent *ret = (void *)0; struct dirent *prev = (void *)0; #ifdef FAT_DEBUG printf("FAT: read_dir: starting directory read from cluster %i\r\n", cur_cluster); #endif do { /* Read this cluster */ uint32_t cluster_size = fat->bytes_per_sector * fat->sectors_per_cluster; //("FAT: 10\r\n"); uint8_t *buf = (uint8_t *)memalign(16,cluster_size); /* Interpret the cluster number to an absolute address */ uint32_t absolute_cluster = cur_cluster - 2; uint32_t first_data_sector = fat->first_data_sector; //printf("FAT: 11\r\n"); if(!is_root) first_data_sector = fat->first_non_root_sector; //printf("FAT: 12\r\n"); #ifdef FAT_DEBUG printf("FAT: reading cluster %i (sector %i)\r\n", cur_cluster, absolute_cluster * fat->sectors_per_cluster + first_data_sector); #endif int br_ret = block_read(fat->b.parent, buf, cluster_size, absolute_cluster * fat->sectors_per_cluster + first_data_sector); //printf("FAT: 13\r\n"); if(br_ret < 0) { printf("FAT: block_read returned %i\r\n", br_ret); return (void*)0; } for(uint32_t ptr = 0; ptr < cluster_size; ptr += 32) { //printf("FAT: 14 %d\r\n",ptr); // Does the entry exist (if the first byte is zero of 0xe5 it doesn't) if((buf[ptr] == 0) || (buf[ptr] == 0xe5)) continue; // Is it the directories '.' or '..'? if(buf[ptr] == '.') continue; // Is it a long filename entry (if so ignore) if(buf[ptr + 11] == 0x0f) continue; // Else read it struct dirent *de = (struct dirent *)memalign(16,sizeof(struct dirent)); memset(de, 0, sizeof(struct dirent)); if(ret == (void *)0) ret = de; if(prev != (void *)0) prev->next = de; prev = de; de->name = (char *)memalign(16,13); de->fs = &fs->b; // Convert to lowercase on load int d_idx = 0; int in_ext = 0; int has_ext = 0; for(int i = 0; i < 11; i++) { char cur_v = (char)buf[ptr + i]; if(i == 8) { in_ext = 1; de->name[d_idx++] = '.'; } if(cur_v == ' ') continue; if(in_ext) has_ext = 1; if((cur_v >= 'A') && (cur_v <= 'Z')) cur_v = 'a' + cur_v - 'A'; de->name[d_idx++] = cur_v; } if(!has_ext) de->name[d_idx - 1] = 0; else de->name[d_idx] = 0; if(buf[ptr + 11] & 0x10) de->is_dir = 1; de->next = (void *)0; de->byte_size = read_word(buf, ptr + 28); uint32_t opaque = read_halfword(buf, ptr + 26) | ((uint32_t)read_halfword(buf, ptr + 20) << 16); de->opaque = (void*)opaque; #ifdef FAT_DEBUG printf("FAT: read dir entry: %s, size %i, cluster %i, ptr %i\r\n", de->name, de->byte_size, opaque, ptr); #endif } free(buf); // Get the next cluster if(is_root && (fs->fat_type != FAT32)) { cur_root_cluster_offset++; if(cur_root_cluster_offset < (fat->root_dir_sectors / fat->sectors_per_cluster)) cur_cluster++; else cur_cluster = 0x0ffffff8; } else cur_cluster = get_next_fat_entry(fat, cur_cluster); #ifdef FAT_DEBUG printf("FAT: read dir: next cluster %x\r\n", cur_cluster); #endif } while(cur_cluster < 0x0ffffff7); return ret; }
/* * read a compression-header from the file */ Header * read_header(FILE *ifp) { static Header header; register int i; register char *cptr; Byte byte; #ifdef BSD bzero((char *) &header, sizeof(header)); #else /* not BSD */ memset((char *) &header, '\0', sizeof(header)); #endif /* BSD */ if (arcfs) return (arcfs_read_header(ifp)); header.comptype = read_byte(ifp); if (!(header.comptype & ~ARCHPACK)) return (&header); /* EOF */ for (i = 0, cptr = header.name; i <= 12; i++, cptr++) { byte = read_byte(ifp); #ifdef RISCOS if (byte < ' ') #else if (byte < ' ' || byte > '~') #endif byte = '\0'; else if (byte == PATHSEP) /* illegal in filename */ byte = '_'; *cptr = byte; } *cptr = '\0'; /* null terminate */ if (singlecase) { for (i = 0, cptr = header.name; i <= 12; i++, cptr++) if (isascii(*cptr) && isupper(*cptr)) *cptr = tolower(*cptr); } header.complen = read_word(ifp); header.date = read_halfword(ifp); header.time = read_halfword(ifp); header.crc = read_halfword(ifp); if ((header.comptype & ~ARCHPACK) > CT_NOTCOMP) header.origlen = read_word(ifp); else header.origlen = header.complen; if (header.comptype & ARCHPACK) { header.load = read_word(ifp); header.exec = read_word(ifp); header.attr = read_word(ifp); } if (check_stream(ifp) == FRWERR) return (NULL); return (&header); }