Linux 访问fat格式文件系统 |
您所在的位置:网站首页 › vfat文件系统特点 › Linux 访问fat格式文件系统 |
#ifndef __KERNEL__ # define __KERNEL__ #endif
#ifndef MODULE # define MODULE #endif
#include #include #include #include #include #include #include
#include #include #include #include #include #include
#ifdef CONFIG_SMP #define __SMP__ #endif
/* 系统调用号的定义在 /usr/include/asm/unistd.h 文件中 printk结果通过dmesg查看。 可以用cat /boot/System.map-`uname -r` |grep sys_call_table 查看table的地址 */ #define __NR_get_FAT_boot 39 #define __NR_get_FAT_dir 15 //替换chmod系统调用
unsigned long **sys_call_table;//调用表 unsigned long * savedcall; //存放被替换的调用指针 struct idt_tag { unsigned short offset_low,segment_select; unsigned char reserved,flags; unsigned short offset_high; };
asmlinkage long testsyscall(char *buf)//测试系统调用 { printk("hello world/n"); char* b="hello world/n"; int n=copy_to_user(buf,b,strlen(b)); printk("复制成功/n"); return n; }
asmlinkage long get_files_info(char * filesystem_type)//取得当前目录的文件系统信息 { struct fs_struct *fs ; struct vfsmount *mnt ; struct super_block *mnt_sb ; struct file_system_type *s_type; read_lock(¤t->fs->lock); fs = current->fs; mnt = fs->pwdmnt; mnt_sb = mnt-> mnt_sb ; s_type = mnt_sb -> s_type;
printk("PWD Filesystem Type is : %s/n",s_type->name); copy_to_user(filesystem_type,s_type->name,strlen(s_type->name));
printk("PWD= %ld/n",mnt_sb->s_blocksize);
read_unlock(¤t->fs->lock); return 0; }
/* http://linux.chinaunix.net/bbs/viewthread.php?tid=916894&rpid=6437642&ordertype=0&page=1#pid6437642 //fat_boot_sector是一个定义在include/linux/msdos_fs.h中的结构体。 //它的内容结构和磁盘中的super block完全一样。所有可用直接赋值,这样变量b //就有了这个设备的SB信息。 b = (struct fat_boot_sector *) bh->b_data; /home/god/linux-2.6.24/include/linux */ /*get_FAT_boot*/ asmlinkage long get_FAT_boot(char * filesystem_type)//取得fat文件系统的信息 { struct fs_struct *fs ; struct vfsmount *mnt ; struct super_block *mnt_sb ; struct buffer_head * bh=NULL; struct fat_boot_sector *fat_sector; char c[512]; int len;
read_lock(¤t->fs->lock); fs = current->fs; mnt = fs->pwdmnt; mnt_sb = mnt-> mnt_sb ; char *fsname=mnt_sb -> s_type->name; char *sfs="vfat"; if(strcmp(fsname,sfs)==0)//此时文件系统是vfat { sb_min_blocksize(mnt_sb, 512); bh = sb_bread(mnt_sb, 0); if(bh!=NULL) { fat_sector=(struct fat_boot_sector *)bh->b_data;
len=sprintf(c,"FAT文件系统具体参数如下:/n"); len=sprintf(c,"%sbackup boot sector= %d/n",c,fat_sector->backup_boot); len=sprintf(c,"%ssectors/cluster= %d/n",c,fat_sector->sec_per_clus); len=sprintf(c,"%snumber of heads= %d/n",c,fat_sector->heads); len=sprintf(c,"%shidden sectors (unused)= %d/n",c,fat_sector->hidden); len=sprintf(c,"%smedia code= %d/n",c,fat_sector->media); len=sprintf(c,"%sbytes per logical sector= %d/n",c,(fat_sector->sector_size[1]fs->lock); return len; }
/*http://linux.chinaunix.net/bbs/thread-916894-1-1.html*/ /*目录文件的目录项在内核中用struct msdos_dir_entry(定义在 include/linux/msdos_fs.h中)来表示*/ /*可见这个数据结构与磁盘中的目录项基本一致*/ /*http://blog.chinaunix.net/u2/87570/showart_2126000.html*/
static bool isEmpty(unsigned char c) { if(c==0x00||c==0xE5) return true; else return false; } static void memswap(unsigned char *dest,unsigned char *src, int count){//交换两块内存 int i=0; unsigned char t; while(i struct fs_struct *fs ; struct vfsmount *mnt ;//当前挂载点 struct file_system_type *s_type; //struct dentry *pwdentry;//当前目录项 struct super_block *mnt_sb ; // struct inode *inode; //struct list_head d_subdirs;
struct dentry *cpwd; struct inode *ci; struct msdos_sb_info * dos_sb; struct msdos_dir_entry *dos_de; struct msdos_inode_info *dos_si; struct fat_boot_sector *fbs; struct buffer_head *bh=NULL; struct msdos_dir_entry *dir0,*dir1;
int len; len=0; char c[2048]; len=sprintf(c,"当前目录信息如下:/n");
read_lock(¤t->fs->lock); fs = current->fs; mnt = fs->pwdmnt; mnt_sb = mnt-> mnt_sb ; s_type = mnt_sb -> s_type; cpwd = fs->pwd; ci = cpwd->d_inode; mnt_sb = ci->i_sb;
char *fsname=s_type->name; char *sfs="vfat"; if(strcmp(fsname,sfs)==0)//此时文件系统是vfat { /* len=sprintf(c,"当前目录下的信息为:/n");*/ /* struct dentry *p;*/ /* list_for_each(p,d_subdirs)*/ /* {*/ /* len=sprintf(c,"%s目录 %p/n",c,p);*/ /* }*/
dos_sb = (struct msdos_sb_info *)mnt_sb->s_fs_info; len=sprintf(c,"%s每簇扇数=%d/n",c,dos_sb->sec_per_clus); len=sprintf(c,"%s簇大小=%d/n",c,dos_sb->cluster_size); len=sprintf(c,"%sFAT位数=%d/n",c,dos_sb->fat_bits); len=sprintf(c,"%sFAT开始扇=%d/n",c,dos_sb->fat_start); len=sprintf(c,"%sFAT长度=%ld/n",c,dos_sb->fat_length); len=sprintf(c,"%s目录开始扇=%ld/n",c,dos_sb->dir_start); len=sprintf(c,"%s目录入口=%d/n",c,dos_sb->dir_entries); len=sprintf(c,"%s数据开始扇=%ld/n",c,dos_sb->data_start); len=sprintf(c,"%s最大簇号=%ld/n",c,dos_sb->max_cluster); len=sprintf(c,"%s根开始扇=%ld/n",c,dos_sb->root_cluster);
dos_si = container_of(ci, struct msdos_inode_info, vfs_inode); bh = sb_bread(mnt_sb, 0); if(bh == NULL) { printk(KERN_ERR "Boot failed/n"); }
fbs = (struct fat_boot_sector *)(bh->b_data); len=sprintf(c,"%s系统信息=%s/n/n",c,fbs->system_id); bh = sb_bread(mnt_sb, dos_sb->dir_start);//根据目录开始扇地址读出目录项 if (bh == NULL) { printk(KERN_ERR "FAT: Directory bread failed/n"); }
len=sprintf(c,"%s##整理前##/n",c); dos_de = (struct msdos_dir_entry *)(bh->b_data); int i=0; for(i=0; i
if(dir0==NULL) dir0 =(struct msdos_dir_entry*)(bh->b_data + i*sizeof(struct msdos_dir_entry)); if(dir1==NULL) dir1 =(struct msdos_dir_entry*)(bh->b_data + j*sizeof(struct msdos_dir_entry)); head = dir0->name[0]; tail = dir1->name[0];
if(isEmpty(head)&&!isEmpty(tail))//前空后满则直接跳过 { i++; j--; dir0=NULL; dir1=NULL; printk("i++=%d,j--=%d/n",i,j); } else if(isEmpty(head)&&isEmpty(tail))//前空后空则跳过前 { i++; dir0=NULL; printk("i++=%d,j=%d/n",i,j); } else if(!isEmpty(head)&&!isEmpty(tail))//前满后满则跳过后 { j--; dir1=NULL; printk("i=%d,j--=%d/n",i,j); } else if(!isEmpty(head)&&isEmpty(tail))//前满后空则交换两块内存 { memswap((unsigned char*)dir0,(unsigned char*)dir1,sizeof(struct msdos_dir_entry));//交换内存 i++; j--; dir0=NULL; dir1=NULL; printk("交换后 i++=%d,j--=%d/n",i,j); } }
len=sprintf(c,"%s##整理后##/n",c); i=0; while(i < 16){ len=sprintf(c,"%s %d :%s/t",c,i,dos_de->name+ i*sizeof(struct msdos_dir_entry)); head = (dos_de->name+ i*sizeof(struct msdos_dir_entry))[0]; if(head == 0xE5){ len+=sprintf(c+len,"E5已删除/n"); }else if(head == 0x00){ len+=sprintf(c+len,"00未用/n"); }else{ len+=sprintf(c+len,"已用/n"); }
i++; } } else//此时文件系统是vfat len=sprintf(c,"Wrong !! The filesystem is %s!!/n",fsname); c[len]='/0'; len++; printk("/nLen= %d/n/n",len); copy_to_user(filesystem_type,c,len);
read_unlock(¤t->fs->lock); return len; }
static unsigned long getSyscallTable(void) { unsigned char idtr[6],*shell,*sort; struct idt_tag *idt; unsigned long system_call,sct; unsigned short offset_low,offset_high; char *p; int i; __asm__("sidt %0":"=m"(idtr)); idt = (struct idt_tag*)((*(unsigned long*)&idtr[2]) + 8 * 0x80); offset_low = idt->offset_low; offset_high = idt->offset_high; system_call = (offset_high) printk("恢复前的%d系统调用为: %p/n",__NR_get_FAT_boot,sys_call_table[__NR_get_FAT_boot]); sys_call_table[__NR_get_FAT_boot]=savedcall; printk("恢复后的%d系统调用为: %p/n",__NR_get_FAT_boot,sys_call_table[__NR_get_FAT_boot]); printk("unloaded success/n"); }
MODULE_LICENSE("GPL"); MODULE_AUTHOR("QCH"); |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |