fx_rtn fx_write_panic0(u32_t pstart, u32_t pend) { panic0_hdr_t *p; uint16_t *ptr, i, sum; assert(fx_buf); memset(fx_buf, 0, MS_BUF_SIZE); p = (void *) fx_buf; p->sig_a = CT_LE_32(PANIC0_MAJIK); p0c.sig_a = CF_LE_32(p->sig_a); p->panic_start = CT_LE_32(pstart); p0c.panic_start= CF_LE_32(p->panic_start); p->panic_nxt = CT_LE_32(pstart); p0c.panic_nxt = CF_LE_32(p->panic_nxt); p->panic_end = CT_LE_32(pend); p0c.panic_end = CF_LE_32(p->panic_end); p->fubar = 0; p0c.fubar = 0; p->sig_b = CT_LE_32(PANIC0_MAJIK); p0c.sig_b = CF_LE_32(p->sig_b); p->chksum = 0; ptr = (void *) p; sum = 0; for (i = 0; i < PANIC0_SIZE_SHORTS; i++) sum += CF_LE_16(ptr[i]); p->chksum = CT_LE_16((uint16_t) (0 - sum)); p0c.chksum = CF_LE_16(p->chksum); assert(!ms_write_blk(PANIC0_SECTOR, fx_buf)); return(FX_OK); }
fx_rtn fx_cap_dblk(char *name, char *ext, char *n_name, char *n_ext, u32_t size, fat_dir_entry_t **rtn_de) { fat_dir_entry_t *de, *n_de; u32_t rds, n_rds, o_size, cluster; u32_t *fat, fat_sector, fat_offset; assert(fx_buf); if (strlen(name) != 8 || strlen(ext) != 3 || strlen(n_name) != 8 || strlen(n_ext) != 3) return(FX_INTERNAL); /* check to see if new name already exists */ de = f32_get_de(n_name, n_ext, &rds); if (de) return(FX_EXIST); de = f32_get_de(name, ext, &rds); if (!de) return(FX_NOT_FOUND); if (size >= CF_LE_32(de->size)) return(FX_INTERNAL); if (!f32_find_empty(&n_de, &n_rds)) return(FX_NO_ROOM); /* * read dir entry of original file and tweak size. */ assert(! ms_read_blk(rds, fx_buf)); o_size = CF_LE_32(de->size); de->size = CT_LE_32(size); assert(! ms_write_blk(rds, fx_buf)); /* * compute eof cluster. write it to eof. */ cluster = (CF_LE_16(de->starthi) << 16) | CF_LE_16(de->start); cluster += (size + (FX_CLUSTER_SIZE * SECTOR_SIZE - 1))/(FX_CLUSTER_SIZE * SECTOR_SIZE) - 1; fat_sector = FAT_SECTOR(cluster) + fx_fat_start; fat_offset = FAT_OFFSET(cluster); assert(! ms_read_blk(fat_sector, fx_buf)); fat = fx_buf; fat[fat_offset] = CT_LE_32(EOF_FAT32); assert(! ms_write_blk(fat_sector, fx_buf)); /* * now read the directory sector for the new file */ cluster++; assert(! ms_read_blk(n_rds, fx_buf)); memcpy(n_de->name, n_name, 8); memcpy(n_de->ext, n_ext, 3); n_de->starthi = CT_LE_16(cluster >> 16); n_de->start = CT_LE_16(cluster & 0xffff); size += (FX_CLUSTER_SIZE * SECTOR_SIZE - 1); size &= ~FX_CB_MASK; /* round up to next cluster */ n_de->size = CT_LE_32(o_size - size); assert(! ms_write_blk(n_rds, fx_buf)); return(FX_OK); }
fx_rtn fx_write_locator(u32_t pstart, u32_t pend, u32_t cstart, u32_t cend, u32_t dstart, u32_t dend) { boot_sector_t *bs; dblk_loc_t *dbl; uint16_t *p, i, sum; assert(fx_buf); assert(!ms_read_blk(0, fx_buf)); bs = fx_buf; if (bs->sig != CT_LE_16(BOOT_SIG)) return(FX_BAD_BOOT_SIG); dbl = fx_buf + DBLK_LOC_OFFSET; dbl->sig = CT_LE_32(TAG_DBLK_SIG); dbl->panic_start = CT_LE_32(pstart); msc.panic_start = pstart; dbl->panic_end = CT_LE_32(pend); msc.panic_end = pend; dbl->config_start = CT_LE_32(cstart); msc.config_start = cstart; dbl->config_end = CT_LE_32(cend); msc.config_end = cend; dbl->dblk_start = CT_LE_32(dstart); msc.dblk_start = dstart; dbl->dblk_end = CT_LE_32(dend); msc.dblk_end = dend; dbl->dblk_chksum = 0; p = (void *) dbl; sum = 0; for (i = 0; i < DBLK_LOC_SIZE_SHORTS; i++) sum += CF_LE_16(p[i]); dbl->dblk_chksum = CT_LE_16((uint16_t) (0 - sum)); assert(!ms_write_blk(0, fx_buf)); /* see if there is a backup at sector 6, just assume it is so */ assert(!ms_read_blk(6, fx_buf)); bs = fx_buf; if (bs->sig != CT_LE_16(BOOT_SIG)) /* if not, its okay */ return(FX_OK); dbl = fx_buf + DBLK_LOC_OFFSET; dbl->sig = CT_LE_32(TAG_DBLK_SIG); dbl->panic_start = CT_LE_32(pstart); dbl->panic_end = CT_LE_32(pend); dbl->config_start = CT_LE_32(cstart); dbl->config_end = CT_LE_32(cend); dbl->dblk_start = CT_LE_32(dstart); dbl->dblk_end = CT_LE_32(dend); dbl->dblk_chksum = 0; p = (void *) dbl; sum = 0; for (i = 0; i < DBLK_LOC_SIZE_SHORTS; i++) sum += CF_LE_16(p[i]); dbl->dblk_chksum = CT_LE_16((uint16_t) (0 - sum)); assert(!ms_write_blk(6, fx_buf)); return(FX_OK); }
void dbg_mangle_root(void) { u32_t rsec, cluster, start, end; int writeit, idx; fat_dir_entry_t *de; for (rsec = fx_rdir_start; rsec <= fx_rdir_end; rsec++) { writeit = 0; ms_read_blk(rsec, fx_buf); de = fx_buf; for(idx = 0; idx < DE_PER_BLK; idx++, de++) { if (writeit > 1) /* bail if writing */ break; if (!de->name[0]) /* 0 indicates nothing beyond */ continue; if (de->name[0] == DELETED_FLAG) continue; if ((de->attr & ATTR_LFN) == ATTR_EXT) continue; if ((de->attr & ATTR_VOLUME) || (de->attr & ATTR_DIR)) continue; cluster = (CF_LE_16(de->starthi) << 16) | CF_LE_16(de->start); if (cluster < 2 || cluster >= BAD_FAT32) continue; if (!f32_get_chain(cluster, &start, &end)) { ms_read_blk(rsec, fx_buf); continue; } /* MUST reread after get_chain, which uses the buffer */ ms_read_blk(rsec, fx_buf); if (start == 0 || end == 0) /* do nothing */ continue; } switch(writeit) { default: break; case 1: case 2: ms_write_blk(rsec, fx_buf); break; case 3: memset(fx_buf, 0, SECTOR_SIZE); ms_write_blk(rsec, fx_buf); break; } } }
fx_rtn fx_find_file(char *name, char *ext, u32_t *start, u32_t *end) { u32_t rds, cluster; fat_dir_entry_t *de; if(strlen(name) != 8 || strlen(ext) != 3) return(FX_INTERNAL); de = f32_get_de(name, ext, &rds); if (!de) return(FX_NOT_FOUND); cluster = (CF_LE_16(de->starthi) << 16) | CF_LE_16(de->start); if (cluster < 2 || cluster >= BAD_FAT32) return(FX_INTERNAL); if (!f32_get_chain(cluster, start, end)) return(FX_NOT_CONTIGUOUS); return(FX_OK); }
void display_info(void) { fat_dir_entry_t *de; u32_t rds; fprintf(stderr, "fs_loc: p: s: %-8x e: %x\n", loc.locators[FS_LOC_PANIC].start, loc.locators[FS_LOC_PANIC].end); fprintf(stderr, " c: s: %-8x e: %x\n", loc.locators[FS_LOC_CONFIG].start, loc.locators[FS_LOC_CONFIG].end); fprintf(stderr, " i: s: %-8x e: %x\n", loc.locators[FS_LOC_IMAGE].start, loc.locators[FS_LOC_IMAGE].end); fprintf(stderr, " d: s: %-8x e: %-8x n: %x\n", loc.locators[FS_LOC_DBLK].start, loc.locators[FS_LOC_DBLK].end, msc_dblk_nxt); if (p0c.panic_start) fprintf(stderr, "panic0: p: %-8x %-8x (nxt) %-8x\n", p0c.panic_start, p0c.panic_end, p0c.panic_nxt); else fprintf(stderr, "panic0: no panic0 block\n"); de = f32_get_de("PANIC001", " ", &rds); if (de) { rds = (CF_LE_16(de->starthi) << 16) | CF_LE_16(de->start); fprintf(stderr, "PANIC001: start 0x%04x size: %10u (0x%x)\n", fx_clu2sec(rds), CF_LE_32(de->size), CF_LE_32(de->size)); } else fprintf(stderr, "PANIC001: not found\n"); de = f32_get_de("CNFG0001", " ", &rds); if (de) { rds = (CF_LE_16(de->starthi) << 16) | CF_LE_16(de->start); fprintf(stderr, "CNFG0001: start 0x%04x size: %10u (0x%x)\n", fx_clu2sec(rds), CF_LE_32(de->size), CF_LE_32(de->size)); } else fprintf(stderr, "CNFG0001: not found\n"); de = f32_get_de("IMAGE001", " ", &rds); if (de) { rds = (CF_LE_16(de->starthi) << 16) | CF_LE_16(de->start); fprintf(stderr, "IMAGE001: start 0x%04x size: %10u (0x%x)\n", fx_clu2sec(rds), CF_LE_32(de->size), CF_LE_32(de->size)); } else fprintf(stderr, "IMAGE001: not found\n"); de = f32_get_de("DBLK0001", " ", &rds); if (de) { rds = (CF_LE_16(de->starthi) << 16) | CF_LE_16(de->start); fprintf(stderr, "DBLK0001: start 0x%04x size: %10u (0x%x)\n", fx_clu2sec(rds), CF_LE_32(de->size), CF_LE_32(de->size)); } else fprintf(stderr, "DBLK0001: not found\n"); }
void display_info(void) { fat_dir_entry_t *de; u32_t rds; if (msc.dblk_start) { fprintf(stderr, "dblk_loc: p: %-8x %-8x\n", msc.panic_start, msc.panic_end); fprintf(stderr, " c: %-8x %-8x\n", msc.config_start, msc.config_end); fprintf(stderr, " d: %-8x %-8x (nxt) %-8x\n", msc.dblk_start, msc.dblk_end, msc.dblk_nxt); } if (p0c.panic_start) fprintf(stderr, "panic0: p: %-8x %-8x (nxt) %-8x\n", p0c.panic_start, p0c.panic_end, p0c.panic_nxt); else fprintf(stderr, "panic0: no panic0 block\n"); de = f32_get_de("PANIC001", " ", &rds); if (de) { rds = (CF_LE_16(de->starthi) << 16) | CF_LE_16(de->start); fprintf(stderr, "PANIC001: start 0x%04x size: %10u (0x%x)\n", fx_clu2sec(rds), CF_LE_32(de->size), CF_LE_32(de->size)); } else fprintf(stderr, "PANIC001: not found\n"); de = f32_get_de("CNFG0001", " ", &rds); if (de) { rds = (CF_LE_16(de->starthi) << 16) | CF_LE_16(de->start); fprintf(stderr, "CNFG0001: start 0x%04x size: %10u (0x%x)\n", fx_clu2sec(rds), CF_LE_32(de->size), CF_LE_32(de->size)); } else fprintf(stderr, "CNFG0001: not found\n"); de = f32_get_de("DBLK0001", " ", &rds); if (de) { rds = (CF_LE_16(de->starthi) << 16) | CF_LE_16(de->start); fprintf(stderr, "DBLK0001: start 0x%04x size: %10u (0x%x)\n", fx_clu2sec(rds), CF_LE_32(de->size), CF_LE_32(de->size)); } else fprintf(stderr, "DBLK0001: not found\n"); }
fx_rtn fx_init(void) { boot_sector_t *bs; info_sector_t *info; mbr_t *mbr; u32_t start, size; assert(fx_buf); assert(! ms_read_blk(0, fx_buf)); /* First sector is either an MBR or the boot_sector of the partition. It * had better have the 2 byte signature at the end. ie. 0xaa55. * * Start by looking for a boot sector rather than the MBR. */ bs = fx_buf; if (bs->sig != CT_LE_16(BOOT_SIG)) return(FX_BAD_BOOT_SIG); start = fx_data_start = 0; if ( ! fat32_boot_sector(bs)) { /* * something doesn't look right. Look at the sector as an MBR and see * if it makes sense. We only look at partition 1. */ mbr = fx_buf; start = (mbr->p1.start4[3] << 24) | (mbr->p1.start4[2] << 16) | (mbr->p1.start4[1] << 8) | mbr->p1.start4[0]; size = (mbr->p1.size4[3] << 24) | (mbr->p1.size4[2] << 16) | (mbr->p1.size4[1] << 8 ) | mbr->p1.size4[0]; /* check for reasonableness, boot_ind can be 0x00 or 0x80 */ if ((mbr->p1.boot_ind != 0 && mbr->p1.boot_ind != 0x80) || !fat32_part(mbr->p1.part_type) || /* reasonable fat32 partition? */ start == 0 || /* can't start at 0 */ size == 0) /* zero means nothing, bail */ return(FX_NO_PARTITION); assert(! ms_read_blk(start, fx_buf)); bs = fx_buf; if (CF_LE_16(bs->sig) != BOOT_SIG) return(FX_BAD_BOOT_SIG); if (!fat32_boot_sector(bs)) /* make sure what we got is good */ return(FX_NO_PARTITION); /* check mbr partition size vs. total_sect entry in the file system header only accept if the same or if file system size is one less than the partition header */ if (size != CF_LE_32(bs->total_sect)) { /* and partition size should match internal */ if (debug) printf("*** mbr/fs size mismatch: mbr: %lu (%lx), fs: %lu (%lx)\n", size, size, CF_LE_32(bs->total_sect), CF_LE_32(bs->total_sect)); if (size != CF_LE_32(bs->total_sect) + 1) return(FX_SIZE_MISMATCH); } fx_data_start = start; } if (debug) printf("Partition start: %lx, size: %lx\n", (u32_t) fx_data_start, CF_LE_32(bs->total_sect)); /* buf contains the boot_sector. compute total data sectors and make sure that it conforms to FAT32. */ fx_cluster_size = bs->cluster_size; /* u8 */ fx_reserved = CF_LE_16(bs->reserved); fx_num_fats = bs->fats; /* u8 */ fx_total_sectors = CF_LE_32(bs->total_sect); fx_fat_size = CF_LE_32(bs->fat32_length); fx_info_sector = start + CF_LE_16(bs->info_sector); fx_data_end = fx_data_start + fx_total_sectors - 1; fx_fat_start = fx_data_start + fx_reserved; fx_fat_end = fx_fat_start + fx_fat_size - 1; fx_data_start = fx_fat_start + fx_fat_size * FX_NUM_FATS; size = fx_total_sectors; size -= (fx_reserved + (fx_fat_size * fx_num_fats)); fx_max_cluster = size/fx_cluster_size; /* last cluster */ if (debug) printf("phys data sectors: %lx, phys clusters: %lx, unused sectors: %lx\n", size, fx_max_cluster, size - fx_max_cluster * fx_cluster_size); if (fx_max_cluster < 65525) /* if less, not FAT32 */ return(FX_NOT_FAT32); fx_max_cluster++; /* make into cluster id */ fx_data_end = clu2sec(fx_max_cluster + 1) - 1; /* get last usable data sector */ if (fx_cluster_size != FX_CLUSTER_SIZE) fprintf(stderr, "*** bad fx_cluster_size (%u) should be (%u)\n", fx_cluster_size, FX_CLUSTER_SIZE); if (fx_num_fats != FX_NUM_FATS) fprintf(stderr, "*** wrong number of FATS: (%u) should be (%u)\n", fx_num_fats, FX_NUM_FATS); f32_get_chain(CF_LE_32(bs->root_cluster), &fx_rdir_start, &fx_rdir_end); assert(fx_rdir_start && fx_rdir_end); assert(!ms_read_blk(fx_info_sector, fx_buf)); info = fx_buf; if (info->boot_sig == CT_LE_16(BOOT_SIG) && IS_FSINFO(info)) { fx_free_clusters = CF_LE_32(info->free_clusters); fx_next_cluster = CF_LE_32(info->next_cluster); } else { fx_info_sector = 0; fx_free_clusters = (u32_t) -1; fx_next_cluster = (u32_t) -1; } if (debug) { printf("ts: %lx, r: %x, fat_s: %lx, n: %d, ds: %lx\n", fx_total_sectors, fx_reserved, fx_fat_size, fx_num_fats, fx_total_sectors-fx_reserved-(fx_num_fats*fx_fat_size)); printf("fat_size (secs): %lx, (clus) %lx, %lx bytes\n", fx_fat_size, fx_fat_size * SECTOR_SIZE / sizeof(u32_t), fx_fat_size * SECTOR_SIZE); printf("data_start: %lx, end: %lx, usable sectors: %lx, last phys sector: %lx\n", fx_data_start, fx_data_end, fx_data_end - fx_data_start + 1, /* usable */ fx_data_start + (fx_total_sectors - fx_reserved - (fx_num_fats * fx_fat_size)) - 1); printf("unused fat entries: %lx, cluster ids: 2 - %lx\n", (fx_fat_end - fx_fat_start + 1) * FAT32_CPB - (fx_max_cluster + 1), fx_max_cluster); printf("Last cluster: %lx, sectors: %lx - %lx, fat sector: %lx, off: %lx\n", fx_max_cluster, clu2sec(fx_max_cluster), clu2sec(fx_max_cluster + 1) - 1, FAT_SECTOR(fx_max_cluster) + fx_fat_start, FAT_OFFSET(fx_max_cluster)); printf(" fat_start: %5lx, fat_end: %5lx\n", fx_fat_start, fx_fat_end); printf(" info: free %5lx, next: %5lx\n", fx_free_clusters, fx_next_cluster); } return(FX_OK); }