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

📄 fsys_ntfs.c.org

📁 grub4dos-0.4.4-2008- 08-src.zip
💻 ORG
📖 第 1 页 / 共 3 页
字号:
/* vim: set sw=4 :*//* *  GRUB  --  GRand Unified Bootloader *  Copyright (C) 1999  Free Software Foundation, Inc. * *  This program is free software; you can redistribute it and/or modify *  it under the terms of the GNU General Public License as published by *  the Free Software Foundation; either version 2 of the License, or *  (at your option) any later version. * *  This program is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *  GNU General Public License for more details. * *  You should have received a copy of the GNU General Public License *  along with this program; if not, write to the Free Software *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *//* * Samuel Leo <samuel@_.remove.me._szonline.net> * Limitations: * 1. Only 32 bit size support * 2. don't support >1k MFT record size, >16k INDEX record size * 3. don't support recursive at_attribute_list * 4. don't support compressed attribute other than Datastream * 5. all MFT's at_attribute_list must resident at first run list * 6. don't support journaling * 7. don't support EFS encryption * 8. don't support mount point and junction */#ifdef FSYS_NTFS//#define DEBUG_NTFS 1/*#define NO_ATTRIBUTE_LIST 1   totally disable at_attribute_list support,   if no compressed/fragment file and MFT,   not recommended#define NO_NON_RESIDENT_ATTRIBUTE_LIST 1   disable non-resident at_attribute_list support,   if no huge compressed/fragment file and MFT#define NO_NTFS_DECOMPRESSION 1   disable ntfs compressed file support#define NO_ALTERNATE_DATASTREAM 1   disable ntfs alternate datastream support*//*#ifdef STAGE1_5*/#include <shared.h>#include <filesys.h>#include "ntfs.h"/* safe turn off non-resident attribute list if MFT fragments < 4000 *///#define NO_NON_RESIDENT_ATTRIBUTE_LIST 1#define NO_NTFS_DECOMPRESSION 1#endif#define MAX_MFT_RECORD_SIZE 1024#define MAX_INDEX_RECORD_SIZE 16384#define MAX_INDEX_BITMAP_SIZE 4096#define DECOMP_DEST_BUFFER_SIZE 16384#define DECOMP_SOURCE_BUFFER_SIZE (8192+2)#define MAX_DIR_DEPTH 64/* sizes are always in bytes, BLOCK values are always in DEV_BSIZE (sectors) */#define DEV_BSIZE 512/* include/linux/fs.h */#define BLOCK_SIZE 	512#define WHICH_SUPER 1#define SBLOCK (WHICH_SUPER * BLOCK_SIZE / DEV_BSIZE)	/* = 2 *//* include/asm-i386/type.h *///typedef __signed__ char __s8;//typedef unsigned char __u8;//typedef __signed__ short __s16;//typedef unsigned short __u16;//typedef __signed__ int __s32;//typedef unsigned int __u32;//typedef __signed__ long long __s64;//typedef unsigned long long __u64;#define FILE_MFT      0#define FILE_MFTMIRR  1#define FILE_LOGFILE  2#define FILE_VOLUME   3#define FILE_ATTRDEF  4#define FILE_ROOT     5#define FILE_BITMAP   6#define FILE_BOOT     7#define FILE_BADCLUS  8#define FILE_QUOTA    9#define FILE_UPCASE  10#define at_standard_information 0x10#define at_attribute_list 	0x20#define at_filename		0x30#define at_security_descriptor	0x50#define at_data			0x80#define at_index_root		0x90#define at_index_allocation	0xa0#define at_bitmap		0xb0#define at_symlink		0xc0#define NONAME	""#define ATTR_NORMAL	0#define ATTR_COMPRESSED	1#define ATTR_RESIDENT	2#define ATTR_ENCRYPTED	16384#define ATTR_SPARSE	32768#define index_data	((char *)FSYS_BUF)#define bitmap_data	((unsigned char *)(FSYS_BUF+MAX_INDEX_RECORD_SIZE))#define dcdbuf	((unsigned char *)index_data)#define dcsbuf	(bitmap_data)#define dcend	(dcsbuf+DECOMP_SOURCE_BUFFER_SIZE)#define fnbuf ((char *)(bitmap_data+MAX_INDEX_BITMAP_SIZE))#define mmft	((MFTR *)dcend)#define cmft	((MFTR *)(dcend+sizeof(MFTR)))#define mft_run	((RUNL *)(dcend+2*sizeof(MFTR)))#define path_ino ((unsigned long *)(dcend+2*sizeof(MFTR)+sizeof(RUNL)))#define cluster16 (path_ino+MAX_DIR_DEPTH)#define index16 cluster16[16]#define blocksize cluster16[17]#define clustersize cluster16[18]#define mft_record_size cluster16[19]#define index_record_size cluster16[20]#define dcvcn cluster16[21]#define dcoff cluster16[22]#define dclen cluster16[23]#define dcrem cluster16[24]#define dcslen cluster16[25]#define dcsptr ((unsigned char *)cluster16[26])#define is_ads_completion cluster16[27]typedef struct run_list {	char *start;	char *ptr;	unsigned long svcn;	unsigned long evcn;	unsigned long vcn;	unsigned long cnum0;	unsigned long cnum;	unsigned long clen;} RUNL;typedef struct ntfs_mft_record {	char mft[MAX_MFT_RECORD_SIZE];	char mft2[MAX_MFT_RECORD_SIZE];	unsigned long attr_type;	char *attr_name;	unsigned long attr_flag;	unsigned long attr_size;	char *attr;	unsigned long attr_len;	RUNL runl;	char *attr_list;	unsigned long attr_list_len;	unsigned long attr_list_size;	unsigned long attr_list_off;	unsigned long attr_inited;	char attr_list_buf[2*BLOCK_SIZE];	RUNL attr_list_runl;} MFTR;static int read_mft_record(unsigned long mftno, char *mft, unsigned long self);static unsigned long read_attribute(MFTR *mftr, unsigned long offset, char *buf, unsigned long len, RUNL *from_rl);static int get_next_run(RUNL *runl);#if 0static inline intnsubstring (char *s1, char *s2){    while (tolower(*s1) == tolower(*s2))    {	/* The strings match exactly. */	if (! *(s1++))	    return 0;	s2 ++;    }    /* S1 is a substring of S2. */    if (*s1 == 0)	return -1;    /* S1 isn't a substring. */    return 1;}#endifstatic intfixup_record (char *record, char *magic, unsigned long size){    unsigned long start, count, offset;    unsigned short fixup;    if (*(int *)record != *(int *)magic)	return 0;        start = *(unsigned short *)(record + 4);    count = *(unsigned short *)(record + 6);    count--;        if (size && blocksize * count != size)	return 0;        fixup = *(unsigned short *)(record + start);    start += 2;    offset = blocksize - 2;    while (count--)    {	if(*(unsigned short *)(record + offset) != fixup)	    return 0;		*(unsigned short *)(record + offset) = *(unsigned short *)(record + start);		start += 2;	offset += blocksize;    }    return 1;}static voidrewind_run_list( RUNL *runl){    runl->vcn = runl->svcn;    runl->ptr = runl->start;    runl->cnum0 = 0;    runl->cnum = 0;    runl->clen = 0;}static intget_next_run (RUNL *runl){    unsigned long t, n, v;#ifdef DEBUG_NTFS    printf("get_next_run: s=%d e=%d c=%d start=%x ptr=%x\n",	   runl->svcn, runl->evcn, runl->vcn, runl->start, runl->ptr);#endif    runl->vcn += runl->clen;    if (runl->vcn > runl->evcn)    	return 0;    t = *((runl->ptr)++);    n = t & 0xf;    runl->clen = 0;    v = 1;        while (n--)    {	runl->clen += v * (*(unsigned char *)((runl->ptr)++));	v <<= 8;    }        n = (t >> 4) & 0xf;        if (n == 0)	runl->cnum = 0;    else    {	unsigned long c = 0;	v = 1;	while(n--)       	{	    c += v * (*(unsigned char *)((runl->ptr)++));	    v <<= 8;	}		if (c & (v>>1))	    c -= v;	runl->cnum0 += c;	runl->cnum = runl->cnum0;    }#ifdef DEBUG_NTFS    printf ("got_next_run: t=%x cluster %x len %x vcn=%x ecn=%x\n",    	t, runl->cnum, runl->clen, runl->vcn, runl->evcn);#endif    return 1;}#ifndef NO_ATTRIBUTE_LISTstatic voidinit_run_list (char *attr, unsigned long len, RUNL *runl, unsigned long *initp){    unsigned long allocated;    /* int inited; */    runl->svcn = *(unsigned long *)(attr + 0x10); /* only support 32 bit */    runl->evcn = *(unsigned long *)(attr + 0x18); /* only support 32 bit */    runl->start = attr + (*(unsigned short *)(attr + 0x20));    allocated = *(unsigned long *)(attr + 0x28);        if (initp)       	*initp = *(unsigned long *)(attr + 0x38);        if (! runl->evcn)       	runl->evcn = (allocated - 1) / clustersize;    #ifdef DEBUG_NTFS    printf("size %d allocated=%d inited=%d cegin=%x csize=%d vcn=%d-%d\n",	    /*attr_size*/ *(unsigned long *)(attr+0x30),	    /*allocated*/ *(unsigned long *)(attr+0x28),	    /*attr_inited*/ *(unsigned long *)(attr+0x38),	    /*cengin*/ *(unsigned short *)(attr+0x22),	    /*csize*/ *(unsigned short *)(attr+0x40),	    runl->svcn, runl->evcn);#endif    rewind_run_list(runl);}#endifstatic intfind_attribute (char *mft, unsigned long type, char *name, char **attr, unsigned long *size, unsigned long *len, unsigned long *flag){    unsigned long t, l, r, n, i, namelen;    unsigned short *attr_name;    n = strlen (name);    r = mft_record_size - *(unsigned short *)(mft + 0x14);    mft += *(unsigned short *)(mft + 0x14);    while ((t = *(unsigned long *)mft) != -1)    {	l = *(unsigned long *)(mft+4);	if (l > r)	    break;#ifdef DEBUG_NTFS	printf("type = %x len = %d namelen=%d resident=%d compresed=%d attrno=%d\n",		t, l,		/*namelen*/ *(mft+9),		//name = (unsigned short *)(mft + *(unsigned short *)(mft+10)),		/*resident */ (*(mft+8) == 0),		/*compressed*/ *(unsigned short *)(mft+12),		/*attrno*/ *(unsigned short *)(mft+14));#endif	namelen = (*(mft + 9));	if (t == type)       	{#ifndef STAGE1_5#ifndef NO_ALTERNATE_DATASTREAM	    if(is_ads_completion && type == at_data)	    {		if(namelen && namelen >= n &&		   (! *(mft + 8)/*resident*/ || ! *(unsigned long *)(attr + 0x10)/*svcn==0*/))		{		    for (i = 0, attr_name = (unsigned short *)(mft + *(unsigned short *)(mft + 10)); i < n; i++)			if (tolower(name[i]) != tolower(attr_name[i]))			    break;		    		    if (i >= n)		    {			for(; i < namelen; i++)			    name[i] = attr_name[i];						name[i] = '\0';						if (print_possibilities > 0)			    print_possibilities = -print_possibilities;						print_a_completion(fnbuf);						name[n] = '\0';		    }		}	    } else#endif#endif	    if (namelen == n)	    {		for (i = 0, attr_name = (unsigned short *)(mft + *(unsigned short *)(mft + 10)); i < n; i++)		    if(tolower(name[i]) != tolower(attr_name[i]))			break;				if (i >= n)	       	{		    if (flag)			*flag = *(unsigned short *)(mft + 12);		    		    if (*(mft + 8) == 0)		    {			if (flag)			    *flag |= ATTR_RESIDENT;#ifdef DEBUG_NTFS			printf("resident data at %x size %x indexed=%d\n",			       /*data*/ *(unsigned short *)(mft+0x14),			       /*attr_size*/ *(unsigned short *)(mft+0x10),			       /*indexed*/ *(unsigned short *)(mft+0x16));#endif			if (attr)			    *attr = mft + (*(unsigned short *)(mft + 0x14));						if (size)  			    *size = (*(unsigned short *)(mft + 0x10));						if (len)  			    *len = (*(unsigned short *)(mft + 0x10));					    } else {						if (attr)  			    *attr = mft;						if (size)  			    *size = *(unsigned long *)(mft+0x30);						if (len)  			    *len = l;		    }		    		    return 1;		}	    }	}		mft += l;	r -= l;    }    return 0;}#ifndef NO_ATTRIBUTE_LISTstatic unsigned longget_next_attribute_list (MFTR *mftr, unsigned long *size){    unsigned long l, t, mftno;#ifdef DEBUG_NTFS    printf("get_next_attribute_list: type=%x\n",mftr->attr_type);#endifagain:    while (mftr->attr_list_len > 0x14)    {	t = *(unsigned long *)(mftr->attr_list + 0);	l = *(unsigned short *)(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 = *(unsigned long *)(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)    {	unsigned long 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");

⌨️ 快捷键说明

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