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 + -
显示快捷键?