fsys_ntfs.c

来自「grub4dos-0.4.4-2008- 08-src.zip」· C语言 代码 · 共 1,445 行 · 第 1/3 页

C
1,445
字号
                      dbg_printf("B2\n");                      return 0;                    }                  for (i = copied - 1, lmask = 0xFFF, dshift = 12; i >= 0x10; i >>= 1)                    {                      lmask >>= 1;                      dshift--;                    }                  delta = code >> dshift;                  len = (code & lmask) + 3;                  for (i = 0; i < len; i++)                    {                      dest[copied] = dest[copied - delta - 1];                      copied++;                    }                } else                  {                    dest[copied++] = decomp_getch();                    cnt--;                  }              tag >>= 1;              bits--;            }          return 1;        }      else        {          if (cnt!=4096)            {              dbg_printf("B3\n");              return 0;            }        }    }  while (cnt>0)    {      int n;      n=(spc << BLK_SHR) - cbuf_ofs;      if (n>cnt)        n=cnt;      if ((dest) && (n))        {          memcpy(dest,&cbuf[cbuf_ofs],n);          dest+=n;        }      cnt-=n;      cbuf_ofs+=n;      if ((cnt) && (! decomp_nextvcn()))        return 0;    }  return 1;}static int read_block(read_ctx* ctx,char* buf,int num){  if (get_rflag(RF_COMP))    {      int cpb=(8/spc);      while (num)        {          int nn;          if ((ctx->target_vcn & 0xF)==0)            {              if (comp_head!=comp_tail)                {                  dbg_printf("A1\n");                  return 0;                }              comp_head=comp_tail=0;              cbuf_vcn=ctx->target_vcn;              cbuf_ofs=(spc<<BLK_SHR);              if (ctx->target_vcn>=ctx->next_vcn)                {                  ctx->cur_run=read_run_list(ctx,ctx->cur_run);                  if (ctx->cur_run==NULL)                    return 0;                }              while (ctx->target_vcn+16>ctx->next_vcn)                {                  if (get_rflag(RF_BLNK))                    break;                  comp_table[comp_tail][0]=ctx->next_vcn;                  comp_table[comp_tail][1]=ctx->curr_lcn + ctx->next_vcn - ctx->curr_vcn;                  comp_tail++;                  ctx->cur_run=read_run_list(ctx,ctx->cur_run);                  if (ctx->cur_run==NULL)                    return 0;                }              //if (ctx->target_vcn+16<ctx->next_vcn)              //  {              //    dbg_printf("A2\n");              //    return 0;              //  }            }          nn=(16 - (ctx->target_vcn & 0xF)) / cpb;          if (nn>num)            nn=num;          num-=nn;          if (get_rflag(RF_BLNK))            {              ctx->target_vcn+=nn * cpb;              if (comp_tail==0)                {                  if (buf)                    {                      memset(buf,0,nn*4096);                      buf+=nn*4096;                    }                }              else                {                  while (nn)                    {                      if (! decomp_block(buf))                        return 0;                      if (buf)                        buf+=4096;                      nn--;                    }                }            }          else            {              nn*=cpb;              while ((comp_head<comp_tail) && (nn))                {                  int tt;                  tt=comp_table[comp_head][0] - ctx->target_vcn;                  if (tt>nn)                    tt=nn;                  ctx->target_vcn+=tt;                  if (buf)                    {                      if (! devread((comp_table[comp_head][1]-(comp_table[comp_head][0] - ctx->target_vcn))*spc,0,tt*(spc << BLK_SHR),buf))                        {                          dbg_printf("Read Error\n");                          return 0;                        }                      buf+=tt*(spc << BLK_SHR);                    }                  nn-=tt;                  if (ctx->target_vcn>=comp_table[comp_head][0])                    comp_head++;                }              if (nn)                {                  if (buf)                    {                      if (! devread((ctx->target_vcn - ctx->curr_vcn + ctx->curr_lcn)*spc,0,nn*(spc << BLK_SHR),buf))                        {                          dbg_printf("Read Error\n");                          return 0;                        }                      buf+=nn*(spc << BLK_SHR);                    }                  ctx->target_vcn+=nn;                }            }        }    }  else    {      while (num)        {          int nn,ss;          nn=(ctx->next_vcn - ctx->target_vcn) * spc - ctx->vcn_offset;          if (nn>num)            nn=num;          if ((buf) && (nn))            {              if (get_rflag(RF_BLNK))                memset(buf,0,nn << BLK_SHR);              else                if (! devread((ctx->target_vcn - ctx->curr_vcn + ctx->curr_lcn)*spc                              + ctx->vcn_offset,0,nn << BLK_SHR,buf))                  {                    dbg_printf("Read Error\n");                    return 0;                  }              buf+=(nn << BLK_SHR);            }          ss=ctx->target_vcn * spc + ctx->vcn_offset + nn;          ctx->target_vcn=ss / spc;          ctx->vcn_offset=ss % spc;          num-=nn;          if (num==0)            break;          if (ctx->target_vcn>=ctx->next_vcn)            {              ctx->cur_run=read_run_list(ctx,ctx->cur_run);              if (ctx->cur_run==NULL)                return 0;            }        }    }  return 1;}static int read_data(char* cur_mft,char* pa,char* dest,unsigned long ofs,unsigned long len,int cached){  unsigned long vcn,blk_size;  read_ctx cc,*ctx;  int ret;  if (len==0)    return 1;  ctx=&cc;  if (pa[8]==0)    {      if (ofs+len>valueat(pa,0x10,unsigned long))        {          dbg_printf("Read out of range\n");          return 0;        }      memcpy(dest,pa+valueat(pa,0x14,unsigned long)+ofs,len);      return 1;    }  ctx->mft=cur_mft;  set_rflag(RF_COMP,valueat(pa,0xC,unsigned short) & FLAG_COMPRESSED);  ctx->cur_run=pa+valueat(pa,0x20,unsigned short);  blk_size=(get_rflag(RF_COMP))?4096:512;  if ((get_rflag(RF_COMP)) && (! cached))    {      dbg_printf("Attribute can\'t be compressed\n");      return 0;    }  if (cached)    {      if ((ofs & (~(blk_size-1)))==save_pos)        {          int n;          n=blk_size - (ofs - save_pos);          if (n>len)            n=len;          memcpy(dest,sbuf + ofs - save_pos,n);          if (n==len)            return 1;          dest+=n;          len-=n;          ofs+=n;        }    }  if (get_rflag(RF_COMP))    {      vcn=ctx->target_vcn=(ofs / 4096) * (8 / spc);      ctx->vcn_offset=0;      ctx->target_vcn &= ~0xF;      comp_head=comp_tail=0;    }  else    {      vcn=ctx->target_vcn=(ofs >> BLK_SHR) / spc;      ctx->vcn_offset=(ofs >> BLK_SHR) % spc;    }  ctx->next_vcn=valueat(pa,0x10,unsigned long);  ctx->curr_lcn=0;  while (ctx->next_vcn<= ctx->target_vcn)    {      ctx->cur_run=read_run_list(ctx,ctx->cur_run);      if (ctx->cur_run==NULL)        return 0;    }  if (get_aflag(AF_GPOS))    {      valueat(dest,0,unsigned long)=(ctx->target_vcn - ctx->curr_vcn + ctx->curr_lcn)*spc + ctx->vcn_offset;      valueat(dest,4,unsigned long)=valueat(dest,0,unsigned long)+1;      if (valueat(dest,4,unsigned long)==(ctx->next_vcn - ctx->curr_vcn + ctx->curr_lcn)*spc)        {          ctx->cur_run=read_run_list(ctx,ctx->cur_run);          if (ctx->cur_run==NULL)            return 0;          valueat(dest,4,unsigned long)=ctx->curr_lcn*spc;        }      return 1;    }  if ((vcn>ctx->target_vcn) &&      (! read_block(ctx,NULL,((vcn - ctx->target_vcn) * spc) / 8 )))    return 0;  ret=0;  if ((cached) && (valueat(pa,0xC,unsigned short) & (FLAG_COMPRESSED + FLAG_SPARSE))==0)    disk_read_func = disk_read_hook;  if (ofs % blk_size)    {      unsigned long t,n,o;      if (! cached)        {          dbg_printf("Invalid range\n");          goto fail;        }      t=ctx->target_vcn*(spc << BLK_SHR);      if (! read_block(ctx,sbuf,1))        goto fail;      save_pos=t;      o=ofs % blk_size;      n=blk_size - o;      if (n>len)        n=len;      memcpy(dest,&sbuf[o],n);      if (n==len)        goto done;      dest+=n;      len-=n;    }  if (! read_block(ctx,dest,len / blk_size))    goto fail;  dest+=(len / blk_size) * blk_size;  len=len % blk_size;  if (len)    {      unsigned long t;      if (! cached)        {          dbg_printf("Invalid range\n");          goto fail;        }      t=ctx->target_vcn * (spc << BLK_SHR);      if (! read_block(ctx,sbuf,1))        goto fail;      save_pos=t;      memcpy(dest,sbuf,len);    }done:  ret=1;fail:  disk_read_func = NULL;  return ret;}static int read_attr(char* cur_mft,char* dest,unsigned long ofs,unsigned long len,int cached){  unsigned short save_cur;  unsigned char attr;  char* pp;  int ret;  save_cur=attr_cur;  attr_nxt=attr_cur;  attr=valueat(ofs2ptr(attr_nxt),0,unsigned char);  if (get_aflag(AF_ALST))    {      unsigned short new_pos;      unsigned long vcn;      vcn=ofs / (spc<<BLK_SHR);      new_pos=attr_nxt+valueat(ofs2ptr(attr_nxt),4,unsigned short);      while (new_pos<attr_end)        {          char *pa;          pa=ofs2ptr(new_pos);          if (*pa!=attr)            break;          if (valueat(pa,8,unsigned long)>vcn)            break;          attr_nxt=new_pos;          new_pos+=valueat(pa,4,unsigned short);        }    }  pp=find_attr(cur_mft,attr);  ret=(pp)?read_data(cur_mft,pp,dest,ofs,len,cached):0;  attr_cur=save_cur;  return ret;}static int read_mft(char* buf,unsigned long mftno){  if (! read_attr(mmft,buf,mftno*(mft_size << BLK_SHR),mft_size << BLK_SHR,0))    {      dbg_printf("Read MFT 0x%X fails\n",mftno);      return 0;    }  return fixup(buf,mft_size,"FILE");}static int init_file(char* cur_mft,unsigned long mftno){  unsigned short flag;  if (! read_mft(cur_mft,mftno))    goto error;  flag=valueat(cur_mft,0x16,unsigned short);  if ((flag & 1)==0)    {      dbg_printf("MFT 0x%X is not in use\n",mftno);      goto error;    }  if (flag & 2)    filemax=0;  else    {      char *pa;      pa=locate_attr(cur_mft,AT_DATA);      if (pa==NULL)        {          dbg_printf("No $DATA in MFT 0x%X\n",mftno);          goto error;        }      if (! pa[8])        filemax=valueat(pa,0x10,unsigned long);      else        filemax=valueat(pa,0x30,unsigned long);      if (! get_aflag(AF_ALST))        attr_end=0;		// Don't jump to attribute list    }  filepos=0;  save_pos=1;  return 1;error:  errnum=ERR_FSYS_CORRUPT;  return 0;}static int list_file(char* cur_mft,char *fn,char *pos){  char *np;  unsigned char *utf8 = (unsigned char *)(NAME_BUF);  int i,ns,len;  len=strlen(fn);  while (1)    {      if (pos[0xC] & 2)			// end signature        break;      np=pos+0x52;      ns=valueat(np,-2,unsigned char);      unicode_to_utf8((unsigned short *)np, utf8, ns);      if (((print_possibilities) && (ns>=len)) ||          ((! print_possibilities) && (ns==len)))        {          for (i=0;i<len;i++)            if (tolower(fn[i])!=tolower(utf8[i]/*np[i*2]*/))              break;          if (i>=len)            {              if (print_possibilities)                {                  if ((i) || ((utf8[0]!='$') && ((utf8[0]!='.') || (ns!=1))))                    {

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?