fsys_ntfs.c
来自「grub4dos-0.4.4-2008- 08-src.zip」· C语言 代码 · 共 1,445 行 · 第 1/3 页
C
1,445 行
#ifndef STAGE1_5 if (print_possibilities>0) print_possibilities=-print_possibilities;#endif// for (i=1;i<ns;i++)// np[i]=np[i*2];// np[ns]=0;#ifdef FS_UTIL print_completion_ex(utf8,valueat(pos,0,unsigned long),valueat(pos,0x40,unsigned long),(valueat(pos,0x48,unsigned long) & ATTR_DIRECTORY)?FS_ATTR_DIRECTORY:0);#else print_a_completion((char *)utf8);#endif } } else { if (valueat(pos,4,unsigned short)) { dbg_printf("64-bit MFT number\n"); return 0; } return init_file(cur_mft,valueat(pos,0,unsigned long)); } } } pos+=valueat(pos,8,unsigned short); } return -1;}static int scan_dir(char* cur_mft,char *fn){ unsigned char *bitmap; char *cur_pos; int bitmap_len,ret; if ((valueat(cur_mft,0x16,unsigned short) & 2)==0) { errnum=ERR_FILE_NOT_FOUND; return 0; } init_attr(cur_mft); while (1) { if ((cur_pos=find_attr(cur_mft,AT_INDEX_ROOT))==NULL) { dbg_printf("No $INDEX_ROOT\n"); goto error; } // Resident, Namelen=4, Offset=0x18, Flags=0x00 // Name="$I30" if ((valueat(cur_pos,8,unsigned long)!=0x180400) || (valueat(cur_pos,0x18,unsigned long)!=0x490024) || (valueat(cur_pos,0x1C,unsigned long)!=0x300033)) continue; cur_pos+=valueat(cur_pos,0x14,unsigned short); if (*cur_pos!=0x30) // Not filename index continue; break; } cur_pos+=0x10; // Skip index root ret=list_file(cur_mft,fn,cur_pos+valueat(cur_pos,0,unsigned short)); if (ret>=0) goto done; bitmap=NULL; bitmap_len=0; init_attr(cur_mft); while ((cur_pos=find_attr(cur_mft,AT_BITMAP))!=NULL) { int ofs=(unsigned char)cur_pos[0xA]; // Namelen=4, Name="$I30" if ((cur_pos[9]==4) && (valueat(cur_pos,ofs,unsigned long)==0x490024) && (valueat(cur_pos,ofs+4,unsigned long)==0x300033)) { if ((get_aflag(AF_ALST)) && (cur_pos[8]==0)) { dbg_printf("$BITMAP should be non-resident when in attribute list\n"); goto error; } if (cur_pos[8]==0) { bitmap=(unsigned char*)(cur_pos+valueat(cur_pos,0x14,unsigned short)); bitmap_len=valueat(cur_pos,0x10,unsigned long); break; } if (valueat(cur_pos,0x28,unsigned long)>4096) { dbg_printf("Non-resident $BITMAP too large\n"); goto error; } bitmap=(unsigned char*)cbuf; bitmap_len=valueat(cur_pos,0x30,unsigned long); if (! read_data(cur_mft,cur_pos,cbuf,0,valueat(cur_pos,0x28,unsigned long),0)) { dbg_printf("Fails to read non-resident $BITMAP\n"); goto error; } break; } } cur_pos=locate_attr(cur_mft,AT_INDEX_ALLOCATION); while (cur_pos!=NULL) { // Non-resident, Namelen=4, Offset=0x40, Flags=0 // Name="$I30" if ((valueat(cur_pos,8,unsigned long)==0x400401) && (valueat(cur_pos,0x40,unsigned long)==0x490024) && (valueat(cur_pos,0x44,unsigned long)==0x300033)) break; cur_pos=find_attr(cur_mft,AT_INDEX_ALLOCATION); } if ((! cur_pos) && (bitmap)) { dbg_printf("$BITMAP without $INDEX_ALLOCATION\n"); goto error; } if (bitmap) { unsigned long v,i; v=1; for (i=0;i<bitmap_len*8;i++) { if (*bitmap & v) { if ((! read_attr(cur_mft,sbuf,i*(idx_size<<BLK_SHR),(idx_size<<BLK_SHR),0)) || (! fixup(sbuf,idx_size,"INDX"))) goto error; ret=list_file(cur_mft,fn,&sbuf[0x18+valueat(sbuf,0x18,unsigned short)]); if (ret>=0) goto done; } v<<=1; if (v >= 0x100) { v=1; bitmap++; } } } ret=(print_possibilities<0);done: if (! ret) errnum = ERR_FILE_NOT_FOUND; return ret;error: errnum = ERR_FSYS_CORRUPT; return 0;}int ntfs_mount (void){#if 0 if (((current_drive & 0x80) || (current_slice != 0)) && (current_slice != 7) && (current_slice != 0x17)) return 0;#endif if (! devread (0, 0, 512, mmft)) return 0;#if 0 if (valueat(mmft,3,unsigned long)!=0x5346544E) return 0;#endif blocksize=valueat(mmft,0xb,unsigned short); if (blocksize != 512) return 0; spc=(blocksize*valueat(mmft,0xd,unsigned char)) >> BLK_SHR; if (!spc || (128 % spc)) return 0; if (valueat(mmft,0x10,unsigned long) != 0) return 0; if (mmft[0x14] != 0) return 0; if (valueat(mmft,0x16,unsigned short) != 0) return 0; if ((unsigned short)(valueat(mmft,0x18,unsigned short) - 1) > 62) return 0; if ((unsigned short)(valueat(mmft,0x1A,unsigned short) - 1) > 255) return 0; if (valueat(mmft,0x20,unsigned long) != 0) return 0; if (mmft[0x44]>0) idx_size=spc*mmft[0x44]; else idx_size=1<<(-mmft[0x44]-BLK_SHR); if (mmft[0x40]>0) mft_size=spc*mmft[0x40]; else mft_size=1<<(-mmft[0x40]-BLK_SHR); mft_start=spc*valueat(mmft,0x30,unsigned long); if ((mft_size>MAX_MFT) ||(idx_size>MAX_IDX)) return 0; if (! devread(mft_start,0,mft_size << BLK_SHR,mmft)) return 0; if (! fixup(mmft,mft_size,"FILE")) return 0; if (! locate_attr(mmft,AT_DATA)) { dbg_printf("No $DATA in master MFT\n"); return 0; } return 1;}int ntfs_dir (char *dirname){ int ret;#ifndef STAGE1_5 int is_print=print_possibilities;#endif filepos=filemax=0; if (*dirname=='/') dirname++;#ifndef STAGE1_5 if ((*dirname=='#') && (dirname[1]>='0') && (dirname[1]<='9')) { int mftno; dirname++; if (! safe_parse_maxint(&dirname,&mftno)) return 0; return init_file(cmft,mftno); }#endif if (! init_file(cmft,FILE_ROOT)) return 0; ret=0; while (1) { char *next, ch; /* skip to next slash or end of filename (space) */ for (next = dirname; (ch = *next) && ch != '/' && !isspace (ch); next++) { if (ch == '\\') { next++; if (! (ch = *next)) break; } } *next = 0;#ifndef STAGE1_5 print_possibilities=(ch=='/')?0:is_print;#endif ret=scan_dir(cmft,dirname); *next=ch; if (! ret) break; if (ch=='/') dirname=next+1; else break; }#ifndef STAGE1_5 print_possibilities=is_print;#endif return ret;}unsigned long ntfs_read(char *buf, unsigned long len){ char *cur_mft; cur_mft=cmft; if (valueat(cur_mft,0x16,unsigned short) & 2) goto error; if (disk_read_hook) save_pos=1; if (! read_attr(cmft,buf,filepos,len,1)) goto error; filepos+=len; return len;error: errnum=ERR_FSYS_CORRUPT; return 0;}#ifdef FS_UTILvoid ntfs_info(int level){ dbg_printf("blocksize: %u\nspc: %u\nmft_size: %u\nidx_size: %u\nmft_start: 0x%X\n", blocksize,spc,mft_size,idx_size,mft_start);}int ntfs_inode_read(char* buf){ if (buf) memcpy(buf,cmft,mft_size<<BLK_SHR); return mft_size<<BLK_SHR;}static char* attr2str(unsigned char attr){ switch (attr) { case AT_STANDARD_INFORMATION: return "$STANDARD_INFORMATION"; case AT_ATTRIBUTE_LIST: return "$ATTRIBUTE_LIST"; case AT_FILENAME: return "$FILENAME"; case AT_OBJECT_ID: return "$OBJECT_ID"; case AT_SECURITY_DESCRIPTOR: return "$SECURITY_DESCRIPTOR"; case AT_VOLUME_NAME: return "$VOLUME_NAME"; case AT_VOLUME_INFORMATION: return "$VOLUME_INFORMATION"; case AT_DATA: return "$DATA"; case AT_INDEX_ROOT: return "$INDEX_ROOT"; case AT_INDEX_ALLOCATION: return "$INDEX_ALLOCATION"; case AT_BITMAP: return "$BITMAP"; case AT_SYMLINK: return "$SYMLINK"; case AT_EA_INFORMATION: return "$EA_INFORMATION"; case AT_EA: return "$EA"; } return "$UNKNOWN";}static void print_name(char* s,int len){ int i; for (i=0;i<len;i++) putchar(s[i*2]);}void print_runlist(char *run){ read_ctx ctx; int first; memset(&ctx,0,sizeof(ctx)); first=1; while (run=read_run_list(&ctx,run)) { if (first) first=0; else putchar(','); if (ctx.flags & RF_BLNK) printf("(+%d)",(ctx.next_vcn-ctx.curr_vcn)*spc); else printf("%d+%d",ctx.curr_lcn*spc,(ctx.next_vcn-ctx.curr_vcn)*spc); if (*run==0) break; } printf("\n");}void ntfs_inode_info(int level){ char *cur_mft,*pos; int first; cur_mft=cmft; printf("Type: %s\n",(valueat(cur_mft,0x16,unsigned short) & 2)?"Directory":"File"); if (valueat(cur_mft,0x20,unsigned long)) printf("Base: 0x%X\n",valueat(cur_mft,0x20,unsigned long)); printf("Attr:\n"); first=1; init_attr(cur_mft); while ((pos=find_attr(cur_mft,0))!=NULL) { unsigned long fg; if (get_aflag(AF_ALST)) { if (first) { printf("Attr List:\n"); first=0; } } printf(" %s (0x%X) ",attr2str(*pos),(unsigned char)*pos); printf((pos[8])?"(nr":"(r"); fg=valueat(pos,0xC,unsigned short); if (fg & FLAG_COMPRESSED) printf(",c"); if (fg & FLAG_ENCRYPTED) printf(",e"); if (fg & FLAG_SPARSE) printf(",s"); if (get_aflag(AF_ALST)) { printf(",mft=0x%X",valueat(ofs2ptr(attr_cur),0x10,unsigned long)); if (pos[8]) printf(",vcn=0x%X",valueat(ofs2ptr(attr_cur),0x8,unsigned long)); } if (pos[9]) { printf(",nm="); print_name(pos+valueat(pos,0xA,unsigned short),pos[9]); } printf(",sz=%d",valueat(pos,((pos[8])?0x30:0x10),unsigned long)); printf(")\n"); if ((pos[8]) && (! get_aflag(AF_ALST))) { printf(" "); print_runlist(pos+valueat(pos,0x20,unsigned short)); } switch ((unsigned char)pos[0]) { case AT_FILENAME: pos+=valueat(pos,0x14,unsigned short); if (pos[0x40]) { printf(" "); print_name(pos+0x42,(unsigned char)pos[0x40]); printf("\n"); } break; } }}#endif#endif /* FSYS_NTFS */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?