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

📄 grub-0.97-patch3-ntfs

📁 grub for dos ,people can use it in dos for calling linux
💻 97-PATCH3-NTFS
📖 第 1 页 / 共 3 页
字号:
++#ifndef NO_ATTRIBUTE_LIST+static __u32 get_next_attribute_list(MFTR *mftr, int *size) {+    int l, t, mftno;+#ifdef DEBUG_NTFS+    printf("get_next_attribute_list: type=%x\n",mftr->attr_type);+#endif+again:+    while(mftr->attr_list_len>0x14) {+	t = *(__u32 *)(mftr->attr_list + 0);+	l = *(__u16 *)(mftr->attr_list + 4);+#ifdef DEBUG_NTFS+	printf("attr_list type=%x len=%x remain=%x\n", t, l, mftr->attr_list_len);+#endif+	if(l==0 || l>mftr->attr_list_len) return 0;+	mftno = *(__u32 *)(mftr->attr_list + 0x10);+	mftr->attr_list_len -= l;+	mftr->attr_list += l;+	if(t==mftr->attr_type)+	{+#ifdef DEBUG_NTFS+	printf("attr_list mftno=%x\n", mftno);+#endif+	    if(read_mft_record(mftno, mftr->mft2, (mftr==mmft))==0)+		break;+	    if(find_attribute(mftr->mft2, mftr->attr_type, mftr->attr_name,+			&mftr->attr, size, &mftr->attr_len, &mftr->attr_flag))+		return 1;+	}+    }+#ifndef NO_NON_RESIDENT_ATTRIBUTE_LIST+    if(mftr->attr_list_off < mftr->attr_list_size) {+	int len = mftr->attr_list_size - mftr->attr_list_off;+	if(len > BLOCK_SIZE) len = BLOCK_SIZE;++	if(mftr->attr_list_len)+	    memmove(mftr->attr_list_buf, mftr->attr_list, mftr->attr_list_len);+	mftr->attr_list = mftr->attr_list_buf;++	if(read_attribute( NULL, mftr->attr_list_off,+			mftr->attr_list_buf + mftr->attr_list_len,+			len, &mftr->attr_list_runl) != len)+	{+#ifdef DEBUG_NTFS+	    printf("CORRUPT NON-RESIDENT ATTRIBUTE_LIST\n");+#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;+}+#endif++static int search_attribute( MFTR *mftr, int 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, (__u32 *)&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 int get_run( RUNL *rl, int vcn, int *clp, int *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 int search_run(MFTR *mftr, int 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 int read_attribute(MFTR *mftr, int offset, char *buf, int len, RUNL *from_rl) {+    int vcn;+    int cnum, clen;+    int done = 0;+    int 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;+    }+    return done;+}++static int read_mft_record(int mftno, char *mft, int 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_DECOMPRESSION+static int get_16_cluster(MFTR *mftr, int vcn) {+    int 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 int compressed_block_size( unsigned char *src ) {+    return 3 + (*(__u16 *)src & 0xfff);+}++static int decompress_block(unsigned char *dest, unsigned char *src) {+    int head;+    int copied=0;+    unsigned char *last;+    int bits;+    int tag=0;++    /* high bit indicates that compression was performed */+    if(!(*(__u16 *)src & 0x8000)) {+	memmove(dest,src+2,0x1000);+	return 0x1000;+    }++    if((head = *(__u16 *)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=*(__u8 *)src;+	    bits=8;+	    src++;+	    if(src>last)+		break;+	}+	if(tag & 1){+	    int i,len,delta,code,lmask,dshift;+	    code = *(__u16 *)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++]=*(__u8 *)src++;+	tag>>=1;+	bits--;+    }++    return copied;+}+#endif++int ntfs_read(char *buf, int len){+    int 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;+    int 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_NTFS+printf("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_NTFS+printf("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)+	    disk_read_func = disk_read_hook;+	ret = read_attribute(cmft, filepos, buf, len, 0);+	if(cmft->attr_flag==ATTR_NORMAL)+	    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_NTFS+printf("Reading filepos=%x len=%x\n", filepos, len);+#endif+	if(filepos >= dcoff && filepos < (dcoff+dclen)) {+#ifdef DEBUG_NTFS+printf("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;+	    ret += size;+	    buf += size;+	    if(len==0) {+		if(len0) {+#ifdef DEBUG_NTFS+printf("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_NTFS+printf("vcn %x off %x dcrem %x\n", vcn, off, dcrem);+#endif+	if(dcrem) {+	    int 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_NTFS+printf("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++;+		}+	    }+	    /* flush destination */+	    dcoff += dclen;+	    dclen = 0;++	    while(dcrem && dclen < DECOMP_DEST_BUFFER_SIZE &&+		  dcslen >= 2 && (head=compressed_block_size(dcsptr)) <= dcslen) {+		size = decompress_block(dcdbuf+dclen, dcsptr);+		if(dcrem>=0x1000 && size!=0x1000) {+		    errnum = ERR_FSYS_CORRUPT;+		    return ret;+		}+		dcrem -= size;+		dclen += size;+		dcsptr += head;+		dcslen -= head;+	    }+	    continue;+	}+	dclen = dcrem = 0;+#ifdef DEBUG_NTFS+printf("get next 16 clusters\n");+#endif+	switch(get_16_cluster(cmft, vcn)) {+	case 0:+#ifdef DEBUG_NTFS+printf("sparse\n");+#endif+	    /* sparse */+	    size = 16 * clustersize - off;+	    if( len < size )+		size = len;+#ifndef STAGE1_5+	    memset( buf, 0, size);+#endif+	    filepos += size;+	    len -= size;+	    ret += size;+	    buf += size;+	    break;++	case 16:+#ifdef DEBUG_NTFS+printf("uncompressed\n");+#endif+	    /* uncompressed */+	    index16 = off / clustersize;+	    off %= clustersize;+	    while(index16 < 16) {+		size = clustersize - off;+		if( len < size )+		    size = len;+		if(!devread(cluster16[index16]*(clustersize>>9)+(off>>9), off&0x1ff, size, buf))+		    return ret;+		filepos += size;+		len -= size;+		ret += size;+		if(len==0)+		    return ret;+		off = 0;+		buf += size;+		index16++;+	    }+	    break;

⌨️ 快捷键说明

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