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

📄 fsys_ntfs.c

📁 open source bios with linux platform, very good and can be reused.
💻 C
📖 第 1 页 / 共 2 页
字号:
    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;}#endifint 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;#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(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;#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)	    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_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;	    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) {	    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_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++;		}	    }	    /* 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_NTFSprintf("get next 16 clusters\n");#endif	switch(get_16_cluster(cmft, vcn)) {	case 0:#ifdef DEBUG_NTFSprintf("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_NTFSprintf("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;	default:#ifdef DEBUG_NTFSprintf("compressed\n");#endif	    index16 = 0;	    dcvcn = vcn;	    dcoff = vcn * clustersize;	    dcrem = cmft->attr_inited - dcoff;	    if(dcrem > 16 * clustersize)		dcrem = 16 * clustersize;	    dcsptr = dcsbuf;	    dcslen = 0;	}    }    if(len0) {#ifdef DEBUG_NTFSprintf("reading uninitialized data 3\n");#endif	memset(buf, 0, len0);	filepos += len0;	ret += len0;    }#else    errnum = FSYS_CORRUPT;   #endif /*NO_NTFS_DECOMPRESSION*/#endif /*STAGE1_5*/    return ret;}int ntfs_mount (void){    char *sb = (char *)FSYS_BUF;    int mft_record;    int spc;  if (((current_drive & 0x80) || (current_slice != 0))       && (current_slice != /*PC_SLICE_TYPE_NTFS*/7)       && (current_slice != /*PC_SLICE_TYPE_NTFS*/0x17))      return 0;    if (!devread (0, 0, 512, (char *) FSYS_BUF))	return 0;			/* Cannot read superblock */    if(sb[3]!='N' || sb[4]!='T' || sb[5]!='F' || sb[6]!='S')	return 0;    blocksize = *(__u16 *)(sb+0xb);    spc = *(unsigned char *)(sb+0xd);    clustersize = spc * blocksize;    mft_record_size = *(char *)(sb+0x40);    index_record_size = *(char *)(sb+0x44);    if(mft_record_size>0)	mft_record_size *= clustersize;    else	mft_record_size = 1 << (-mft_record_size);    index_record_size *= clustersize;    mft_record = *(__u32 *)(sb+0x30); /* only support 32 bit */    spc = clustersize / 512;    if(mft_record_size > MAX_MFT_RECORD_SIZE || index_record_size > MAX_INDEX_RECORD_SIZE) {	/* only support 1k MFT record, 4k INDEX record */	return 0;    }#ifdef DEBUG_NTFS    printf("spc=%x mft_record=%x:%x\n", spc, *(__s64 *)(sb+0x30));#endif    if (!devread (mft_record*spc, 0, mft_record_size, mmft->mft))	return 0;			/* Cannot read superblock */    if(!fixup_record( mmft->mft, "FILE", mft_record_size))	return 0;#ifndef NO_ALTERNATE_DATASTREAM    is_ads_completion = 0;#endif    if(!search_attribute(mmft, at_data, NONAME)) return 0;    *mft_run = mmft->runl;    *path_ino = FILE_ROOT;    return 1;}intntfs_dir (char *dirname){    char *rest, ch;    int namelen;    int depth = 0;    int chk_sfn = 1;    int flag = 0;    int record_offset;    int my_index_record_size;    unsigned char *index_entry = 0, *entry, *index_end;    int i;    /* main loop to find desired directory entry */loop:#ifdef DEBUG_NTFS    printf("dirname=%s\n", dirname);#endif    if(!read_mft_record(path_ino[depth], cmft->mft, 0))    {#ifdef DEBUG_NTFS	printf("MFT error 1\n");#endif	errnum = ERR_FSYS_CORRUPT;	return 0;    }    /* if we have a real file (and we're not just printing possibilities),       then this is where we want to exit */    if (!*dirname || isspace (*dirname) || *dirname==':')    {#ifndef STAGE1_5#ifndef NO_ALTERNATE_DATASTREAM	if (*dirname==':' && print_possibilities) {	    char *tmp;	    /* preparing ADS name completion */	    for(tmp = dirname; *tmp != '/'; tmp--);	    for(tmp++, rest=fnbuf; *tmp && !isspace(*tmp); *rest++ = *tmp++)		if(*tmp==':') dirname = rest;	    *rest++ = '\0';	    is_ads_completion = 1;	    search_attribute(cmft, at_data, dirname+1);	    is_ads_completion = 0;	    if(errnum==0) {		if(print_possibilities < 0)		    return 1;		errnum = ERR_FILE_NOT_FOUND;	    }	    return 0;	}#endif#endif	if (*dirname==':') dirname++;	for (rest = dirname; (ch = *rest) && !isspace (ch); rest++);	*rest = 0;#ifdef DEBUG_NTFS	printf("got file: search at_data\n");#endif	if (!search_attribute(cmft, at_data, dirname)) {	    errnum = *(dirname-1)==':'?ERR_FILE_NOT_FOUND:ERR_BAD_FILETYPE;	    *rest = ch;	    return 0;	}	*rest = ch;	filemax = cmft->attr_size;#ifdef DEBUG_NTFS	printf("filemax=%x\n", filemax);#endif	return 1;    }    if(depth >= (MAX_DIR_DEPTH-1)) {	errnum = ERR_FSYS_CORRUPT;	return 0;    }    /* continue with the file/directory name interpretation */    while (*dirname == '/')	dirname++;    for (rest = dirname; (ch = *rest) && !isspace (ch) && ch != '/' && ch != ':'; rest++);    *rest = 0;    if (!search_attribute(cmft, at_index_root, "$I30"))    {	errnum = ERR_BAD_FILETYPE;	return 0;    }    read_attribute(cmft, 0, fnbuf, 16, 0);    my_index_record_size = *(__u32 *)(fnbuf+8);    if(my_index_record_size > MAX_INDEX_RECORD_SIZE) {	errnum = ERR_FSYS_CORRUPT;	return 0;    }#ifdef DEBUG_NTFS    printf("index_record_size=%x\n", my_index_record_size);#endif    if(cmft->attr_size > MAX_INDEX_RECORD_SIZE) {	errnum = ERR_FSYS_CORRUPT;	return 0;    }    read_attribute(cmft, 0, index_data, cmft->attr_size, 0);    index_end = index_data + cmft->attr_size;    index_entry = index_data + 0x20;    record_offset = -1;#ifndef STAGE1_5    if (print_possibilities && ch != '/' && ch != ':' && !*dirname)    {	print_possibilities = -print_possibilities;	/* fake '.' for empty directory */	print_a_completion (".");    }#endif    if (search_attribute(cmft, at_bitmap, "$I30")) {	if(cmft->attr_size > MAX_INDEX_BITMAP_SIZE) {	    errnum = ERR_FSYS_CORRUPT;	    return 0;	}	read_attribute(cmft, 0, bitmap_data, cmft->attr_size, 0);	if (search_attribute(cmft, at_index_allocation, "$I30")==0) {	    errnum = ERR_FSYS_CORRUPT;	    return 0;	}	for(record_offset = 0; record_offset*my_index_record_size<cmft->attr_size; record_offset++){	    int bit = 1 << (record_offset&3);	    int byte = record_offset>>3;#ifdef DEBUG_NTFS	    printf("record_offset=%x\n", record_offset);#endif	    if((bitmap_data[byte]&bit))		break;	}	if(record_offset*my_index_record_size>=cmft->attr_size) record_offset = -1;    }    do    {	entry = index_entry; index_entry += *(__u16 *)(entry+8);	if(entry+0x50>=index_entry||entry>=index_end||	   index_entry>=index_end||(entry[0x12]&2)){	    if(record_offset < 0 ||	       !read_attribute(cmft, record_offset*my_index_record_size, index_data, my_index_record_size, 0)){		if (!errnum)		{		    if (print_possibilities < 0)		    {#if 0			putchar ('\n');#endif			return 1;		    }		    errnum = ERR_FILE_NOT_FOUND;		    *rest = ch;		}		return 0;	    }	    if(!fixup_record( index_data, "INDX", my_index_record_size))	    {#ifdef DEBUG_NTFS		printf("index error\n");#endif		errnum = ERR_FSYS_CORRUPT;		return 0;	    }	    entry = index_data + 0x18 + *(__u16 *)(index_data+0x18);	    index_entry = entry + *(__u16 *)(entry+8);	    index_end = index_data + my_index_record_size - 0x52;	    for(record_offset++; record_offset*my_index_record_size<cmft->attr_size; record_offset++){		int bit = 1 << (record_offset&3);		int byte = record_offset>>3;		if((bitmap_data[byte]&bit)) break;	    }	    if(record_offset*my_index_record_size>=cmft->attr_size) record_offset = -1;#ifdef DEBUG_NTFS	    printf("record_offset=%x\n", record_offset);#endif	}	flag = entry[0x51];	path_ino[depth+1] = *(__u32 *)entry;	if(path_ino[depth+1] < 16)	    continue;	namelen = entry[0x50];	//if(index_data[0x48]&2) printf("hidden file\n");#ifndef STAGE1_5	/* skip short file name */	if( flag == 2 && print_possibilities && ch != '/' && ch != ':' )	    continue;#endif	for( i = 0, entry+=0x52; i < namelen; i++, entry+=2 )	{	    int c = *(__u16 *)entry;	    if(c==' '||c>=0x100)		fnbuf[i] = '_';	    else		fnbuf[i] = c;	}	fnbuf[namelen] = 0;#ifdef DEBUG_NTFS	printf("FLAG: %d  NAME: %s  inum=%d\n", flag,fnbuf,path_ino[depth+1]);#endif	//uncntrl(fnbuf);	chk_sfn = nsubstring(dirname,fnbuf);#ifndef STAGE1_5	if (print_possibilities && ch != '/' && ch != ':'	    && (!*dirname || chk_sfn <= 0))	{	    if (print_possibilities > 0)		print_possibilities = -print_possibilities;	    print_a_completion (fnbuf);	}#endif /* STAGE1_5 */    }    while (chk_sfn != 0 ||	   (print_possibilities && ch != '/' && ch != ':'));    *(dirname = rest) = ch;    depth++;    /* go back to main loop at top of function */    goto loop;}#ifdef DEBUG_NTFSint dump_block(char *msg, char *buf, int size){    int l = (size+15)/16;    int off;    int i, j;    int c;    printf("----- %s -----\n", msg);    for( i = 0, off = 0; i < l; i++, off+=16)    {	if(off<16)	    printf("000%x:", off);	else if(off<256)	    printf("00%x:", off);	else	    printf("0%x:", off);	for(j=0;j<16;j++)	{	    c = buf[off+j]&0xff;	    if( c >= 16 )		printf("%c%x",j==8?'-':' ',c);	    else		printf("%c0%x",j==8?'-':' ',c);	}	printf("  ");	for(j=0;j<16;j++) {	    char c = buf[off+j];	    printf("%c",c<' '||c>='\x7f'?'.':c);	}	printf("\n");    }}#endif#endif /* FSYS_NTFS */

⌨️ 快捷键说明

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