int main() { BLOCK_DEVICE *device; FSFILE *file; unsigned char i; unsigned long filepos; /* avoid issues with the interrupt routine hijacking the IY register - not sure how big a problem this really is, but can't hurt... */ #asm di #endasm buffer_emptybuffers(); // TODO: Can this be sensibly incorporated into fatfs_init? printf("Initializing fatfs library\n"); fatfs_init(); printf("opening DivIDE master drive\n"); device = divide_open_drive(DIVIDE_DRIVE_MASTER); printf("opening FATfs filesystem on it\n"); fatfs_fsopen(device, &fs); printf("fatfs filesystem at %04x\n", &fs); open_root_dir(&fs, &dir); printf("dir handle at %04x\n", &dir); for (i = 0; i < 13; i++) { read_dir(&dir, &entry); /* printf("%s\n", entry.filename); */ } printf("dirent at %04x\n", &entry); file = open_dirent(&entry, FILE_MODE_EXC_READ); printf("file handle at %04x\n", file); read_file(file, buffer1, 5); printf("first 5 chars stored at %04x\n", buffer1); seek_file(file, 2L); read_file(file, buffer2, 5); printf("chars 2-6 stored at %04x\n", buffer2); i = read_byte(file); printf("char 7 is %02x\n", i); filepos = get_file_pos(file); printf("file position is now %08lx\n", filepos); close_file(file); #asm ei #endasm return 0; }
static int common_dos_loop(MainParam_t *mp, const char *pathname, lookupState_t *lookupState, int open_mode) { Stream_t *RootDir; char *cwd; char *drive; char *rest; int ret; mp->loop = _dos_loop; drive='\0'; cwd = ""; if((rest = skip_drive(pathname)) > pathname) { drive = get_drive(pathname, NULL); if (strncmp(pathname, mp->mcwd, rest - pathname) == 0) cwd = skip_drive(mp->mcwd); pathname = rest; } else { drive = get_drive(mp->mcwd, NULL); cwd = skip_drive(mp->mcwd); } if(*pathname=='/') /* absolute path name */ cwd = ""; RootDir = mp->File = open_root_dir(drive, open_mode); if(!mp->File) return ERROR_ONE; ret = recurs_dos_loop(mp, cwd, pathname, lookupState); if(ret & NO_CWD) { /* no CWD */ *mp->mcwd = '\0'; unlink_mcwd(); ret = recurs_dos_loop(mp, "", pathname, lookupState); } FREE(&RootDir); return ret; }
/* 在磁盘上搜索文件系统,若没有则格式化分区创建文件系统 */ void filesys_init() { uint8_t channel_no = 0, dev_no, part_idx = 0; /* sb_buf用来存储从硬盘上读入的超级块 */ struct super_block* sb_buf = (struct super_block*)sys_malloc(SECTOR_SIZE); if (sb_buf == NULL) { PANIC("alloc memory failed!"); } printk("searching filesystem......\n"); while (channel_no < channel_cnt) { dev_no = 0; while(dev_no < 2) { if (dev_no == 0) { // 跨过裸盘hd60M.img dev_no++; continue; } struct disk* hd = &channels[channel_no].devices[dev_no]; struct partition* part = hd->prim_parts; while(part_idx < 12) { // 4个主分区+8个逻辑 if (part_idx == 4) { // 开始处理逻辑分区 part = hd->logic_parts; } /* channels数组是全局变量,默认值为0,disk属于其嵌套结构, * partition又为disk的嵌套结构,因此partition中的成员默认也为0. * 若partition未初始化,则partition中的成员仍为0. * 下面处理存在的分区. */ if (part->sec_cnt != 0) { // 如果分区存在 memset(sb_buf, 0, SECTOR_SIZE); /* 读出分区的超级块,根据魔数是否正确来判断是否存在文件系统 */ ide_read(hd, part->start_lba + 1, sb_buf, 1); /* 只支持自己的文件系统.若磁盘上已经有文件系统就不再格式化了 */ if (sb_buf->magic == 0x19590318) { printk("%s has filesystem\n", part->name); } else { // 其它文件系统不支持,一律按无文件系统处理 printk("formatting %s`s partition %s......\n", hd->name, part->name); partition_format(part); } } part_idx++; part++; // 下一分区 } dev_no++; // 下一磁盘 } channel_no++; // 下一通道 } sys_free(sb_buf); /* 确定默认操作的分区 */ char default_part[8] = "sdb1"; /* 挂载分区 */ list_traversal(&partition_list, mount_partition, (int)default_part); /* 将当前分区的根目录打开 */ open_root_dir(cur_part); /* 初始化文件表 */ uint32_t fd_idx = 0; while (fd_idx < MAX_FILE_OPEN) { file_table[fd_idx++].fd_inode = NULL; } }
void mlabel(int argc, char **argv, int type) { char *newLabel; int verbose, clear, interactive, show; direntry_t entry; int result=0; char longname[VBUFSIZE]; char shortname[45]; ClashHandling_t ch; struct MainParam_t mp; Stream_t *RootDir; int c; int mangled; enum { SER_NONE, SER_RANDOM, SER_SET } set_serial = SER_NONE; long serial = 0; int need_write_boot = 0; int have_boot = 0; char *eptr; union bootsector boot; Stream_t *Fs=0; int r; struct label_blk_t *labelBlock; int isRo=0; int *isRop=NULL; init_clash_handling(&ch); ch.name_converter = label_name; ch.ignore_entry = -2; verbose = 0; clear = 0; show = 0; if(helpFlag(argc, argv)) usage(0); while ((c = getopt(argc, argv, "i:vcsnN:h")) != EOF) { switch (c) { case 'i': set_cmd_line_image(optarg, 0); break; case 'v': verbose = 1; break; case 'c': clear = 1; break; case 's': show = 1; break; case 'n': set_serial = SER_RANDOM; srandom((long)time (0)); serial=random(); break; case 'N': set_serial = SER_SET; serial = strtol(optarg, &eptr, 16); if(*eptr) { fprintf(stderr, "%s not a valid serial number\n", optarg); exit(1); } break; case 'h': usage(0); default: usage(1); } } if (argc - optind != 1 || !argv[optind][0] || argv[optind][1] != ':') usage(1); init_mp(&mp); newLabel = argv[optind]+2; if(strlen(newLabel) > VBUFSIZE) { fprintf(stderr, "Label too long\n"); FREE(&RootDir); exit(1); } interactive = !show && !clear &&!newLabel[0] && (set_serial == SER_NONE); if(!clear && !newLabel[0]) { isRop = &isRo; } RootDir = open_root_dir(argv[optind][0], isRop ? 0 : O_RDWR, isRop); if(isRo) { show = 1; interactive = 0; } if(!RootDir) { fprintf(stderr, "%s: Cannot initialize drive\n", argv[0]); exit(1); } initializeDirentry(&entry, RootDir); r=vfat_lookup(&entry, 0, 0, ACCEPT_LABEL | MATCH_ANY, shortname, longname); if (r == -2) { FREE(&RootDir); exit(1); } if(show || interactive){ if(isNotFound(&entry)) printf(" Volume has no label\n"); else if (*longname) printf(" Volume label is %s (abbr=%s)\n", longname, shortname); else printf(" Volume label is %s\n", shortname); } /* ask for new label */ if(interactive){ newLabel = longname; fprintf(stderr,"Enter the new volume label : "); if(fgets(newLabel, VBUFSIZE, stdin) == NULL) { newLabel[0] = '\0'; fprintf(stderr, "\n"); } if(newLabel[0]) newLabel[strlen(newLabel)-1] = '\0'; } if((!show || newLabel[0]) && !isNotFound(&entry)){ /* if we have a label, wipe it out before putting new one */ if(interactive && newLabel[0] == '\0') if(ask_confirmation("Delete volume label (y/n): ")){ FREE(&RootDir); exit(0); } entry.dir.attr = 0; /* for old mlabel */ wipeEntry(&entry); } if (newLabel[0] != '\0') { ch.ignore_entry = 1; result = mwrite_one(RootDir,newLabel,0,labelit,NULL,&ch) ? 0 : 1; } have_boot = 0; if( (!show || newLabel[0]) || set_serial != SER_NONE) { Fs = GetFs(RootDir); have_boot = (force_read(Fs,boot.characters,0,sizeof(boot)) == sizeof(boot)); } if(WORD_S(fatlen)) { labelBlock = &boot.boot.ext.old.labelBlock; } else { labelBlock = &boot.boot.ext.fat32.labelBlock; } if(!show || newLabel[0]){ dos_name_t dosname; const char *shrtLabel; doscp_t *cp; if(!newLabel[0]) shrtLabel = "NO NAME "; else shrtLabel = newLabel; cp = GET_DOSCONVERT(Fs); label_name(cp, shrtLabel, verbose, &mangled, &dosname); if(have_boot && boot.boot.descr >= 0xf0 && labelBlock->dos4 == 0x29) { strncpy(labelBlock->label, dosname.base, 11); need_write_boot = 1; } } if((set_serial != SER_NONE) & have_boot) { if(have_boot && boot.boot.descr >= 0xf0 && labelBlock->dos4 == 0x29) { set_dword(labelBlock->serial, serial); need_write_boot = 1; } } if(need_write_boot) { force_write(Fs, (char *)&boot, 0, sizeof(boot)); } FREE(&RootDir); exit(result); }
void mbadblocks(int argc, char **argv, int type) { unsigned int i; unsigned int startSector=2; unsigned int endSector=0; struct MainParam_t mp; Fs_t *Fs; Stream_t *Dir; int ret; char *filename = NULL; char c; unsigned int badClus; int sectorMode=0; int writeMode=0; while ((c = getopt(argc, argv, "i:s:cwS:E:")) != EOF) { switch(c) { case 'i': set_cmd_line_image(optarg, 0); break; case 'c': checkListTwice(filename); filename = strdup(optarg); break; case 's': checkListTwice(filename); filename = strdup(optarg); sectorMode = 1; break; case 'S': startSector = atol(optarg); break; case 'E': endSector = atol(optarg); break; case 'w': writeMode = 1; break; case 'h': usage(0); default: usage(1); } } if (argc != optind+1 || !argv[optind][0] || argv[optind][1] != ':' || argv[optind][2]) { usage(1); } init_mp(&mp); Dir = open_root_dir(argv[optind][0], O_RDWR, NULL); if (!Dir) { fprintf(stderr,"%s: Cannot initialize drive\n", argv[0]); exit(1); } Fs = (Fs_t *)GetFs(Dir); in_len = Fs->cluster_size * Fs->sector_size; in_buf = malloc(in_len); if(!in_buf) { printOom(); ret = 1; goto exit_0; } if(writeMode) { int i; pat_buf=malloc(in_len * N_PATTERN); if(!pat_buf) { printOom(); ret = 1; goto exit_0; } srandom(time(NULL)); for(i=0; i < in_len * N_PATTERN; i++) { pat_buf[i] = random(); } } for(i=0; i < Fs->clus_start; i++ ){ ret = READS(Fs->Next, in_buf, sectorsToBytes((Stream_t*)Fs, i), Fs->sector_size); if( ret < 0 ){ perror("early error"); goto exit_0; } if(ret < (signed int) Fs->sector_size){ fprintf(stderr,"end of file in file_read\n"); ret = 1; goto exit_0; } } ret = 0; badClus = Fs->last_fat + 1; if(startSector < 2) startSector = 2; if(endSector > Fs->num_clus + 2 || endSector <= 0) endSector = Fs->num_clus + 2; if(filename) { char line[80]; FILE *f = fopen(filename, "r"); if(f == NULL) { fprintf(stderr, "Could not open %s (%s)\n", filename, strerror(errno)); ret = 1; goto exit_0; } while(fgets(line, sizeof(line), f)) { char *ptr = line + strspn(line, " \t"); long offset = strtoul(ptr, 0, 0); if(sectorMode) offset = (offset-Fs->clus_start)/Fs->cluster_size + 2; if(offset < 2) { fprintf(stderr, "Sector before start\n"); } else if(offset >= Fs->num_clus) { fprintf(stderr, "Sector beyond end\n"); } else { mark(Fs, offset, badClus); ret = 1; } } } else { Stream_t *dev; dev = Fs->Next; if(dev->Next) dev = dev->Next; in_len = Fs->cluster_size * Fs->sector_size; if(writeMode) { /* Write pattern */ for(i=startSector; i< endSector; i++){ if(got_signal) break; progress(i, Fs->num_clus); ret |= scan(Fs, dev, i, badClus, pat_buf + in_len * (i % N_PATTERN), 1); } /* Flush cache, so that we are sure we read the data back from disk, rather than from the cache */ if(!got_signal) DISCARD(dev); /* Read data back, and compare to pattern */ for(i=startSector; i< endSector; i++){ if(got_signal) break; progress(i, Fs->num_clus); ret |= scan(Fs, dev, i, badClus, pat_buf + in_len * (i % N_PATTERN), 0); } } else { for(i=startSector; i< endSector; i++){ if(got_signal) break; progress(i, Fs->num_clus); ret |= scan(Fs, dev, i, badClus, NULL, 0); } } } exit_0: FREE(&Dir); exit(ret); }