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

📄 super.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *  super.c * *  Copyright (C) 1995-1997, 1999 Martin von L鰓is *  Copyright (C) 1996-1997 R間is Duchesne *  Copyright (C) 1999 Steve Dodd *  Copyright (C) 2000 Anton Altparmakov */#include "ntfstypes.h"#include "struct.h"#include "super.h"#include <linux/errno.h>#include "macros.h"#include "inode.h"#include "support.h"#include "util.h"/* * All important structures in NTFS use 2 consistency checks : * . a magic structure identifier (FILE, INDX, RSTR, RCRD...) * . a fixup technique : the last word of each sector (called a fixup) of a *   structure's record should end with the word at offset <n> of the first *   sector, and if it is the case, must be replaced with the words following *   <n>. The value of <n> and the number of fixups is taken from the fields *   at the offsets 4 and 6. * * This function perform these 2 checks, and _fails_ if : * . the magic identifier is wrong * . the size is given and does not match the number of sectors * . a fixup is invalid */int ntfs_fixup_record(ntfs_volume *vol, char *record, char *magic, int size){	int start, count, offset;	ntfs_u16 fixup;	if(!IS_MAGIC(record,magic))		return 0;	start=NTFS_GETU16(record+4);	count=NTFS_GETU16(record+6);	count--;	if(size && vol->blocksize*count != size)		return 0;	fixup = NTFS_GETU16(record+start);	start+=2;	offset=vol->blocksize-2;	while(count--){		if(NTFS_GETU16(record+offset)!=fixup)			return 0;		NTFS_PUTU16(record+offset, NTFS_GETU16(record+start));		start+=2;		offset+=vol->blocksize;	}	return 1;}/* Get vital informations about the ntfs partition from the boot sector */int ntfs_init_volume(ntfs_volume *vol,char *boot){	/* Historical default values, in case we don't load $AttrDef */	vol->at_standard_information=0x10;	vol->at_attribute_list=0x20;	vol->at_file_name=0x30;	vol->at_volume_version=0x40;	vol->at_security_descriptor=0x50;	vol->at_volume_name=0x60;	vol->at_volume_information=0x70;	vol->at_data=0x80;	vol->at_index_root=0x90;	vol->at_index_allocation=0xA0;	vol->at_bitmap=0xB0;	vol->at_symlink=0xC0;	/* Sector size */	vol->blocksize=NTFS_GETU16(boot+0xB);	vol->clusterfactor=NTFS_GETU8(boot+0xD);	vol->mft_clusters_per_record=NTFS_GETS8(boot+0x40);	vol->index_clusters_per_record=NTFS_GETS8(boot+0x44);		/* Just some consistency checks */	if(NTFS_GETU32(boot+0x40)>256)		ntfs_error("Unexpected data #1 in boot block\n");	if(NTFS_GETU32(boot+0x44)>256)		ntfs_error("Unexpected data #2 in boot block\n");	if(vol->index_clusters_per_record<0){		ntfs_error("Unexpected data #3 in boot block\n");		/* If this really means a fraction, setting it to 1		   should be safe. */		vol->index_clusters_per_record=1;	}	/* in some cases, 0xF6 meant 1024 bytes. Other strange values have not	   been observed */	if(vol->mft_clusters_per_record<0 && vol->mft_clusters_per_record!=-10)		ntfs_error("Unexpected data #4 in boot block\n");	vol->clustersize=vol->blocksize*vol->clusterfactor;	if(vol->mft_clusters_per_record>0)		vol->mft_recordsize=			vol->clustersize*vol->mft_clusters_per_record;	else		vol->mft_recordsize=1<<(-vol->mft_clusters_per_record);	vol->index_recordsize=vol->clustersize*vol->index_clusters_per_record;	/* FIXME: long long value */	vol->mft_cluster=NTFS_GETU64(boot+0x30);	/* This will be initialized later */	vol->upcase=0;	vol->upcase_length=0;	vol->mft_ino=0;	return 0;}static void ntfs_init_upcase(ntfs_inode *upcase){	ntfs_io io;#define UPCASE_LENGTH  256	upcase->vol->upcase = ntfs_malloc(2*UPCASE_LENGTH);	if( !upcase->vol->upcase )		return;	io.fn_put=ntfs_put;	io.fn_get=0;	io.param=(char*)upcase->vol->upcase;	io.size=2*UPCASE_LENGTH;	ntfs_read_attr(upcase,upcase->vol->at_data,0,0,&io);	upcase->vol->upcase_length = io.size / 2;}static intprocess_attrdef(ntfs_inode* attrdef,ntfs_u8* def){	int type = NTFS_GETU32(def+0x80);	int check_type = 0;	ntfs_volume *vol=attrdef->vol;	ntfs_u16* name = (ntfs_u16*)def;	if(ntfs_ua_strncmp(name,"$STANDARD_INFORMATION",64)==0){		vol->at_standard_information=type;		check_type=0x10;	}else if(ntfs_ua_strncmp(name,"$ATTRIBUTE_LIST",64)==0){		vol->at_attribute_list=type;		check_type=0x20;	}else if(ntfs_ua_strncmp(name,"$FILE_NAME",64)==0){		vol->at_file_name=type;		check_type=0x30;	}else if(ntfs_ua_strncmp(name,"$VOLUME_VERSION",64)==0){		vol->at_volume_version=type;		check_type=0x40;	}else if(ntfs_ua_strncmp(name,"$SECURITY_DESCRIPTOR",64)==0){		vol->at_security_descriptor=type;		check_type=0x50;	}else if(ntfs_ua_strncmp(name,"$VOLUME_NAME",64)==0){		vol->at_volume_name=type;		check_type=0x60;	}else if(ntfs_ua_strncmp(name,"$VOLUME_INFORMATION",64)==0){		vol->at_volume_information=type;		check_type=0x70;	}else if(ntfs_ua_strncmp(name,"$DATA",64)==0){		vol->at_data=type;		check_type=0x80;	}else if(ntfs_ua_strncmp(name,"$INDEX_ROOT",64)==0){		vol->at_index_root=type;		check_type=0x90;	}else if(ntfs_ua_strncmp(name,"$INDEX_ALLOCATION",64)==0){		vol->at_index_allocation=type;		check_type=0xA0;	}else if(ntfs_ua_strncmp(name,"$BITMAP",64)==0){		vol->at_bitmap=type;		check_type=0xB0;	}else if(ntfs_ua_strncmp(name,"$SYMBOLIC_LINK",64)==0 ||		 ntfs_ua_strncmp(name,"$REPARSE_POINT",64)==0){		vol->at_symlink=type;		check_type=0xC0;	}	if(check_type && check_type!=type){		ntfs_error("Unexpected type %x for %x\n",type,check_type);		return EINVAL;	}	return 0;}intntfs_init_attrdef(ntfs_inode* attrdef){	ntfs_u8 *buf;	ntfs_io io;	int offset,error,i;	ntfs_attribute *data;	buf=ntfs_malloc(4050); /* 90*45 */	if(!buf)return ENOMEM;	io.fn_put=ntfs_put;	io.fn_get=ntfs_get;	io.do_read=1;	offset=0;	data=ntfs_find_attr(attrdef,attrdef->vol->at_data,0);	if(!data){		ntfs_free(buf);		return EINVAL;	}	do{		io.param=buf;		io.size=4050;		error=ntfs_readwrite_attr(attrdef,data,offset,&io);		for(i=0;!error && i<io.size-0xA0;i+=0xA0)			error=process_attrdef(attrdef,buf+i);		offset+=4096;	}while(!error && io.size);	ntfs_free(buf);	return error;}/* ntfs_get_version will determine the NTFS version of the    volume and will return the version in a BCD format, with   the MSB being the major version number and the LSB the   minor one. Otherwise return <0 on error.    Example: version 3.1 will be returned as 0x0301.   This has the obvious limitation of not coping with version   numbers above 0x80 but that shouldn't be a problem... */int ntfs_get_version(ntfs_inode* volume){	ntfs_attribute *volinfo;	volinfo = ntfs_find_attr(volume, volume->vol->at_volume_information, 0);	if (!volinfo) 		return -EINVAL;	if (!volinfo->resident) {		ntfs_error("Volume information attribute is not resident!\n");		return -EINVAL;	}	return ((ntfs_u8*)volinfo->d.data)[8] << 8 | ((ntfs_u8*)volinfo->d.data)[9];}int ntfs_load_special_files(ntfs_volume *vol){	int error;	ntfs_inode upcase, attrdef, volume;	vol->mft_ino=(ntfs_inode*)ntfs_calloc(3*sizeof(ntfs_inode));	error=ENOMEM;	ntfs_debug(DEBUG_BSD,"Going to load MFT\n");	if(!vol->mft_ino || (error=ntfs_init_inode(vol->mft_ino,vol,FILE_MFT)))	{		ntfs_error("Problem loading MFT\n");		return error;	}	ntfs_debug(DEBUG_BSD,"Going to load MIRR\n");	vol->mftmirr=vol->mft_ino+1;	if((error=ntfs_init_inode(vol->mftmirr,vol,FILE_MFTMIRR))){		ntfs_error("Problem %d loading MFTMirr\n",error);		return error;	}	ntfs_debug(DEBUG_BSD,"Going to load BITMAP\n");	vol->bitmap=vol->mft_ino+2;	if((error=ntfs_init_inode(vol->bitmap,vol,FILE_BITMAP))){		ntfs_error("Problem loading Bitmap\n");		return error;	}	ntfs_debug(DEBUG_BSD,"Going to load UPCASE\n");	error=ntfs_init_inode(&upcase,vol,FILE_UPCASE);	if(error)return error;	ntfs_init_upcase(&upcase);	ntfs_clear_inode(&upcase);	ntfs_debug(DEBUG_BSD,"Going to load ATTRDEF\n");	error=ntfs_init_inode(&attrdef,vol,FILE_ATTRDEF);	if(error)return error;	error=ntfs_init_attrdef(&attrdef);	ntfs_clear_inode(&attrdef);	if(error)return error;	/* Check for NTFS version and if Win2k version (ie. 3.0+)	   do not allow write access since the driver write support	   is broken, especially for Win2k. */	ntfs_debug(DEBUG_BSD,"Going to load VOLUME\n");	error = ntfs_init_inode(&volume,vol,FILE_VOLUME);	if (error) return error;	if ((error = ntfs_get_version(&volume)) >= 0x0300) {		NTFS_SB(vol)->s_flags |= MS_RDONLY;		ntfs_error("Warning! NTFS volume version is Win2k+: Mounting read-only\n");	}	ntfs_clear_inode(&volume);	if (error < 0) return error;	ntfs_debug(DEBUG_BSD, "NTFS volume is version %d.%d\n", error >> 8, error & 0xff);	return 0;}int ntfs_release_volume(ntfs_volume *vol){	if(vol->mft_ino){		ntfs_clear_inode(vol->mft_ino);		ntfs_clear_inode(vol->mftmirr);		ntfs_clear_inode(vol->bitmap);		ntfs_free(vol->mft_ino);		vol->mft_ino=0;	}	ntfs_free(vol->mft);	ntfs_free(vol->upcase);	return 0;}/* * Writes the volume size into vol_size. Returns 0 if successful * or error. */int ntfs_get_volumesize(ntfs_volume *vol, ntfs_u64 *vol_size ){	ntfs_io io;	char *cluster0;

⌨️ 快捷键说明

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