⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fsys_ntfs.c.org

📁 grub4dos-0.4.4-2008- 08-src.zip
💻 ORG
📖 第 1 页 / 共 3 页
字号:
#endif	    /* corrupt */	    errnum = ERR_FSYS_CORRUPT;	    mftr->attr_list_size = 0;	    mftr->attr_len = 0;	    mftr->attr_list = NULL;	    return 0;	}	mftr->attr_list_len += len;	mftr->attr_list_off += len;	goto again;    }#endif    mftr->attr_list = NULL;    return 0;}#endifstatic intsearch_attribute (MFTR *mftr, unsigned long type, char *name){#ifdef DEBUG_NTFS    printf("searching attribute %x <%s>\n", type, name);#endif     mftr->attr_type = type;    mftr->attr_name = name;    mftr->attr_list = NULL;    mftr->attr_list_len = 0;    mftr->attr_list_size = 0;    mftr->attr_list_off = 0;    dcrem = dclen = 0;#ifndef NO_ATTRIBUTE_LIST    if (find_attribute (mftr->mft, at_attribute_list, NONAME,		      &mftr->attr_list, &mftr->attr_list_size,		      &mftr->attr_list_len, &mftr->attr_list_off))    {	if (mftr->attr_list_off&ATTR_RESIDENT)       	{	    /* resident at_attribute_list */	    mftr->attr_list_size = 0;#ifdef DEBUG_NTFS	    printf("resident attribute_list len=%x\n", mftr->attr_list_len);#endif	} else {#ifdef DEBUG_NTFS	    printf("non-resident attribute_list len=%x size=%x\n",		   mftr->attr_list_len, mftr->attr_list_size);#endif#ifndef NO_NON_RESIDENT_ATTRIBUTE_LIST	    init_run_list(mftr->attr_list, mftr->attr_list_len, &mftr->attr_list_runl, NULL);	    if (get_next_run (&mftr->attr_list_runl) == 0 || mftr->attr_list_runl.cnum == 0)		mftr->attr_list_size = 0;#endif	    mftr->attr_list = NULL;	    mftr->attr_list_len = 0;	}    }#endif    if (find_attribute (mftr->mft, type, name, &mftr->attr, &mftr->attr_size, &mftr->attr_len, &mftr->attr_flag)#ifndef NO_ATTRIBUTE_LIST       || get_next_attribute_list (mftr, &mftr->attr_size)#endif       )    {#ifndef NO_ATTRIBUTE_LIST	if (! (mftr->attr_flag & ATTR_RESIDENT))	{	    init_run_list (mftr->attr, mftr->attr_len, &mftr->runl, (unsigned long *)&mftr->attr_inited);	    	    if (mftr->attr_inited > mftr->attr_size)	    	mftr->attr_inited = mftr->attr_size;	    	    if (get_next_run (&mftr->runl) == 0)	    {		mftr->attr_flag |= ATTR_RESIDENT;		mftr->attr_len = 0;	    }	} else	    mftr->attr_inited = mftr->attr_size;#endif	return 1;    }    mftr->attr_type = 0;    return 0;}static intget_run (RUNL *rl, unsigned long vcn, unsigned long *clp, unsigned long *lenp){    if (rl->evcn < vcn)	return 0;    if (rl->vcn > vcn)    {    	rewind_run_list(rl);	get_next_run(rl);    }    while (rl->vcn + rl->clen <= vcn)    {	if (get_next_run (rl) == 0)	    return 0;    }    if (clp)       	*clp = rl->cnum == 0 ? 0 : rl->cnum + vcn - rl->vcn;        if (lenp)       	*lenp = rl->clen - vcn + rl->vcn;        return 1;}static intsearch_run (MFTR *mftr, unsigned long vcn){    if (mftr->attr == NULL && ! search_attribute (mftr, mftr->attr_type, mftr->attr_name))	return 0;    if (mftr->runl.svcn > vcn)	search_attribute (mftr, mftr->attr_type, mftr->attr_name);#ifdef NO_ATTRIBUTE_LIST    if (mftr->runl.evcn < vcn)	return 0;#else    while (mftr->runl.evcn < vcn)    {	if (get_next_attribute_list (mftr, NULL) == 0)       	{	    mftr->attr = NULL;	    return 0;	}		init_run_list (mftr->attr, mftr->attr_len, &mftr->runl, NULL);	if (get_next_run (&mftr->runl) == 0)       	{	    mftr->attr = NULL;	    return 0;	}    }#endif    return 1;}static unsigned longread_attribute (MFTR *mftr, unsigned long offset, char *buf, unsigned long len, RUNL *from_rl){    unsigned long vcn;    unsigned long cnum, clen;    unsigned long done = 0;    unsigned long n;    RUNL *rl;    if (! from_rl && (mftr->attr_flag & ATTR_RESIDENT))    {	/* resident attribute */	if (offset > mftr->attr_len)	    return 0;		if (offset + len > mftr->attr_len)	    len = mftr->attr_len - offset;		memmove (buf, mftr->attr + offset, len);	return len;    }    vcn = offset / clustersize;    offset %= clustersize;    while (len > 0)    {	if (from_rl)	    rl = from_rl;	else if (search_run (mftr, vcn) == 0)	    break;	else	    rl = &mftr->runl;		if (get_run (rl, vcn, &cnum, &clen) == 0)	    break;		if (cnum == 0 && from_rl)	    break;		n = clen * clustersize - offset;		if (n > len)	    n = len;	if (cnum == 0)       	{	    memset (buf, 0, n);	} else if (! devread (cnum * (clustersize >> 9) + (offset >> 9), offset & 0x1ff, n, buf))	    break;	buf += n;	vcn += (offset + n) / clustersize;	done += n;	offset = 0;	len -= n;	/* len always >= 0 */    }        return done;}static int read_mft_record (unsigned long mftno, char *mft, unsigned long self){#ifdef DEBUG_NTFS    printf("Reading MFT record: mftno=%d\n", mftno);#endif    if (read_attribute (mmft, mftno * mft_record_size,	    mft, mft_record_size, self ? mft_run : NULL) != mft_record_size)	return 0;        if (! fixup_record (mft, "FILE", mft_record_size))	return 0;        return 1;}#ifndef NO_NTFS_DECOMPRESSIONstatic unsigned long get_16_cluster (MFTR *mftr, unsigned long vcn){    unsigned long n = 0, cnum, clen;    while (n < 16 && search_run (mftr, vcn) && get_run (&mftr->runl, vcn, &cnum, &clen) && cnum)    {	if (clen > 16 - n)	    clen = 16 - n;		vcn += clen;		while (clen--)	    cluster16[n++] = cnum++;    }        cluster16[n] = 0;    return n;}static inline unsigned long compressed_block_size (unsigned char *src){    return 3 + (*(unsigned short *)src & 0xfff);}static unsigned long decompress_block (unsigned char *dest, unsigned char *src){    unsigned long head;    unsigned long copied=0;    unsigned char *last;    unsigned long bits;    unsigned long tag=0;    /* high bit indicates that compression was performed */    if (! (*(unsigned short *)src & 0x8000))    {	memmove (dest, src + 2, 0x1000);	return 0x1000;    }    if ((head = *(unsigned short *)src & 0xFFF) == 0)	/* block is not used */	return 0;    src += 2;    last = src + head;    bits = 0;    while (src <= last)    {	if (copied > 4096)	{#ifdef DEBUG_NTFS	    printf("decompress error 1\n");#endif	    errnum = ERR_FSYS_CORRUPT;	    return 0;	}	if (! bits)	{	    tag = *(unsigned char *)src;	    bits = 8;	    src++;	    if (src > last)		break;	}	if (tag & 1)	{	    unsigned long i, len, delta, code, lmask, dshift;	    code = *(unsigned short *)src;	    src += 2;	    if (! copied)	    {#ifdef DEBUG_NTFS		printf("decompress error 2\n");#endif		errnum = ERR_FSYS_CORRUPT;		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++] = *(unsigned char *)src++;	tag >>= 1;	bits--;    }    return copied;}#endifunsigned longntfs_read(char *buf, unsigned long len){    unsigned long ret;#ifdef STAGE1_5/* stage2 can't be resident/compressed/encrypted files, * but does sparse flag, cause stage2 never sparsed */    if ((cmft->attr_flag & ~ATTR_SPARSE) != ATTR_NORMAL)	return 0;    disk_read_func = disk_read_hook;    ret = read_attribute (cmft, filepos, buf, len, 0);    disk_read_func = NULL;    filepos += ret;#else/*#ifndef NO_NTFS_DECOMPRESSION*/    //int off;    //int vcn;    //int size;    unsigned long len0 = 0;/*endif*/    if (len <= 0 || filepos >= cmft->attr_size || (cmft->attr_flag & ATTR_ENCRYPTED))	return 0;    if (filepos + len > cmft->attr_size)	len = cmft->attr_size - filepos;#if 0    if(filepos >= cmft->attr_inited) {#ifdef DEBUG_NTFSprintf("reading uninitialized data 1\n");#endif    	memset(buf, 0, len);	return len;    } else if(filepos+len > cmft->attr_inited) {    	len0 = len;	len = cmft->attr_inited - filepos;	len0 -= len;    } else    	len0 = 0;#endif#ifdef DEBUG_NTFSprintf("read filepos=%x filemax=%x inited=%x len=%x len0=%x\n",filepos,filemax,cmft->attr_inited,len,len0);#endif    if ((cmft->attr_flag & (ATTR_COMPRESSED | ATTR_RESIDENT)) != ATTR_COMPRESSED)    {	if (cmft->attr_flag == ATTR_NORMAL)	//if((cmft->attr_flag | ATTR_RESIDENT) == ATTR_RESIDENT)	    disk_read_func = disk_read_hook;	ret = read_attribute (cmft, filepos, buf, len, 0);	if (cmft->attr_flag == ATTR_NORMAL)	//if((cmft->attr_flag | ATTR_RESIDENT) == ATTR_RESIDENT)	    disk_read_func = NULL;	filepos += ret;	if(ret == len && len0)       	{		memset (buf + len, 0, len0);		filepos += len0;		ret += len0;	}	return ret;    }    ret = 0;#ifndef NO_NTFS_DECOMPRESSION    /* NTFS don't support compression if cluster size > 4k */    if (clustersize > 4096)    {	errnum = ERR_FSYS_CORRUPT;	return 0;    }    while (len > 0)    {#ifdef DEBUG_NTFSprintf("Reading filepos=%x len=%x\n", filepos, len);#endif	if (filepos >= dcoff && filepos < (dcoff + dclen))       	{#ifdef DEBUG_NTFSprintf("decompress cache %x+%x\n", dcoff, dclen);#endif	    size = dcoff + dclen - filepos;	    	    if (size > len)	       	size = len;	    	    memmove (buf, dcdbuf + filepos - dcoff, size);	    	    filepos += size;	    len -= size;	/* len always >= 0 */	    ret += size;	    buf += size;	    	    if (len == 0)	    {		if (len0)	       	{#ifdef DEBUG_NTFSprintf("reading uninitialized data 2\n");#endif		    memset (buf, 0, len0);		    filepos += len0;		    ret += len0;		}				return ret;	    }	}	vcn = filepos / clustersize / 16;	vcn *= 16;	off = filepos % (16 * clustersize);		if (dcvcn != vcn || filepos < dcoff)	    dcrem = 0;#ifdef DEBUG_NTFSprintf("vcn %x off %x dcrem %x\n", vcn, off, dcrem);#endif	if (dcrem)       	{	    unsigned long head;	    /* reading source */	    if (dcslen < 2 || compressed_block_size (dcsptr) > dcslen)	    {		if (cluster16[index16] == 0)	       	{		    errnum = ERR_FSYS_CORRUPT;		    return ret;		}			if (dcslen)		    memmove (dcsbuf, dcsptr, dcslen);				dcsptr = dcsbuf;				while ((dcslen + clustersize) < DECOMP_SOURCE_BUFFER_SIZE)	       	{		    if (cluster16[index16] == 0)			break;#ifdef DEBUG_NTFSprintf("reading dcslen=%x cluster %x\n", dcslen, cluster16[index16]);#endif		    if (! devread (cluster16[index16] * (clustersize >> 9), 0, clustersize, dcsbuf + dcslen))			return ret;		    dcslen += clustersize;		    index16++;

⌨️ 快捷键说明

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