配色: 字号:
Windows文件系统分析
2020-10-02 | 阅:  转:  |  分享 
  












目录



一、…………………………………………………..实验目的

二、…………………………………………………..实验内容

三.…………………………………………………..实验原理

四、…………………………………………………….流程图

五、……………………………………………………源代码

六、………………………………………………….运行结果

七、………………………………………………….心得体会

八、………………………………………………….参考目录





























Windows文件系统分析

一、实验目的

通过linux系统对windows磁盘文件的调用,熟悉windows系统文件的结构,对Fat文件及Pdisk和hd磁盘结构的分析。通过本周的课程设计能熟悉掌握在虚拟机下的各种操作命令。了解文件的具体结构形式。

二、实验内容

在Linux系统下,使用与文件相关的系统调用实现对物理设备文件的读写,参照Linux系统源代码以及Grub系统的源代码,对不同介质上的FAT格式文件系统进行分析。要求在Linux环境下设计出C语言程序,实现以下功能:

1)、分析DOS/Windows系统引导记录DBR(DOSBootRecord)和引导机制;

2)、通过DBR中的BPB(BIOSParameterBlock)信息分析,构建相关信息的数据结构,比较FAT16、FAT32和VFAT等文件系统的区别与联系。

3)、至少要实现对给出第一FAT入口文件的只读访问。

4)、分析NTFS的引导记录与DBR的区别与联系。

5)、熟悉在虚拟机下的各种操作命令。

三.实验原理

文件系统就是在硬盘上存储信息的格式。在所有的计算机系统中,都存在一个相应的文件系统,它规定了计算机对文件和文件夹进行操作处理的各种标准和机制。因此,用户对所有的文件和文件夹的操作都是通过文件系统来完成的。其中Windows文件系统包括:



标准文件分配表(FAT),pdisk,WindowsNT、Windows95、MS-Dos或OS/2可以存取主分区或者逻辑分区FAT上的文件。



增强的文件分配表(FAT32),这是在大型磁盘驱动器(超过512兆字节)上存储文件的极有效的系统,如果用户的驱动器使用了这种格式,则会在驱动器上创建多至几百兆的额外硬盘空间,从而更高效地存储数据。此外,可使程序运行加快50%,而使用的计算机系统资源却更少。

FAT文件系统最初用于小型磁盘和简单文件结构的简单文件系统。FAT文件系统得名于它的组织方法:放置在卷起始位置的文件分配表。为了保护卷,使用了两份拷贝,确保即使损坏了一份也能正常工作。另外,为确保正确装卸启动系统所必须的文件,文件分配表和根文件夹必须存放在固定的位置。



采用FAT文件系统格式化的卷以簇的形式进行分配。默认的簇大小由卷的大小决定。对于FAT文件系统,簇数目必须可以用16位的二进制数字表示,并且是2的乘方,默认的簇大小见表5-2所示。通过使用命令行提示符下的format程序,用户可以指定簇的大小。不过,用户所指定的簇的大小必须大于表中给出的大小。由于额外开销的原因,在大于511MB的卷中不推荐使用FAT文件系统。

FAT32文件系统



FAT32文件系统提供了比FAT文件系统更为先进的文件管理特性,例如,支持超过32GB的卷以及通过使用更小的簇来更有效率地使用磁盘空间。作为FAT文件系统的增强版本,它可以在容量从512MB到2TB的驱动器上使用。

DBR区(DOSBOOTRECORD)即操作系统引导记录区的意思,通常占用分区的第0扇区共512个字节(特殊情况也要占用其它保留扇区,我们先说第0扇)。在这512个字节中,其实又是由跳转指令,厂商标志和操作系统版本号,BPB(BIOSParameterBlock),扩展BPB,os引导程序,结束标志几部分组成。以用的最多的FAT32为例说明分区DBR各字节的含义。见图8。???图8的对应解释见表3???

???表3??FAT32分区上DBR中各部分的位置划分??? 字节位移 字段长度 字段名 对应图8颜色 0x00 3个字节 跳转指令 0x03 8个字节 厂商标志和os版本号 0x0B 53个字节 BPB 0x40 26个字节 扩展BPB 0x5A 420个字节 引导程序代码 0x01FE 2个字节 有效结束标志 9给出了winhex对图8DBR的相关参数解释:??????根据上边图例,我们来讨论DBR各字节的参数意义。?????????MBR将CPU执行转移给引导扇区,因此,引导扇区的前三个字节必须是合法的可执行的基于x86的CPU指令。这通常是一条跳转指令,该指令负责跳过接下来的几个不可执行的字节(BPB和扩展BPB),跳到操作系统引导代码部分。???跳转指令之后是8字节长的OEMID,它是一个字符串,OEMID标识了格式化该分区的操作系统的名称和版本号。为了保留与MS-DOS的兼容性,通常Windows2000格式化该盘是在FAT16和FAT32磁盘上的该字段中记录了“MSDOS5.0”,在NTFS磁盘上(关于ntfs,另述),Windows2000记录的是“NTFS”。通常在被Windows95格式化的磁盘上OEMID字段出现“MSWIN4.0”,在被Windows95OSR2和Windows98格式化的磁盘上OEMID字段出现“MSWIN4.1”。???接下来的从偏移0x0B开始的是一段描述能够使可执行引导代码找到相关参数的信息。通常称之为BPB(BIOSParameterBlock),BPB一般开始于相同的位移量,因此,标准的参数都处于一个已知的位置。磁盘容量和几何结构变量都被封在BPB之中。由于引导扇区的第一部分是一个x86跳转指令。因此,将来通过在BPB末端附加新的信息,可以对BPB进行扩展。只需要对该跳转指令作一个小的调整就可以适应BPB的变化。图9已经列出了项目的名称和取值,为了系统的研究,针对图8,将FAT32分区格式的BPB含义和扩展BPB含义释义为表格,见表4和表5。

表4?FAT32分区的BPB字段????? 字节位移 字段长度(字节) 图8对应取值 名称和定义 0x0B 2 0x0200 扇区字节数(BytesPerSector)硬件扇区的大小。本字段合法的十进制值有512、1024、2048和4096。对大多数磁盘来说,本字段的值为512 0x0D 1 0x08 每簇扇区数(SectorsPerCluster),一簇中的扇区数。由于FAT32文件系统只能跟踪有限个簇(最多为4294967296个),因此,通过增加每簇扇区数,可以使FAT32文件系统支持最大分区数。一个分区缺省的簇大小取决于该分区的大小。本字段的合法十进制值有1、2、4、8、16、32、64和128。Windows2000的FAT32实现只能创建最大为32GB的分区。但是,Windows2000能够访问由其他操作系统(Windows95、OSR2及其以后的版本)所创建的更大的分区 0x0e 2 0x0020 保留扇区数(ReservedSector)第一个FAT开始之前的扇区数,包括引导扇区。本字段的十进制值一般为32 0x10 1 0x02 FAT数(NumberofFAT)该分区上FAT的副本数。本字段的值一般为2 0x11 2 0x0000 根目录项数(RootEntries)只有FAT12/FAT16使用此字段。对FAT32分区而言,本字段必须设置为0 0x13 2 0x0000 小扇区数(SmallSector)(只有FAT12/FAT16使用此字段)对FAT32分区而言,本字段必须设置为0 0x15 1 0xF8 媒体描述符(MediaDescriptor)提供有关媒体被使用的信息。值0xF8表示硬盘,0xF0表示高密度的3.5寸软盘。媒体描述符要用于MS-DOSFAT16磁盘,在Windows2000中未被使用 0x16 2 0x0000 每FAT扇区数(SectorsPerFAT)只被FAT12/FAT16所使用,对FAT32分区而言,本字段必须设置为0 0x18 2 0x003F 每道扇区数(SectorsPerTrack)包含使用INT13h的磁盘的“每道扇区数”几何结构值。该分区被多个磁头的柱面分成了多个磁道 0x1A 2 0x00FF 磁头数(NumberofHead)本字段包含使用INT13h的磁盘的“磁头数”几何结构值。例如,在一张1.44MB3.5英寸的软盘上,本字段的值为2 0x1C 4 0x0000003F 隐藏扇区数(HiddenSector)该分区上引导扇区之前的扇区数。在引导序列计算到根目录的数据区的绝对位移的过程中使用了该值。本字段一般只对那些在中断13h上可见的媒体有意义。在没有分区的媒体上它必须总是为0 0x20 4 0x007D043F 总扇区数(LargeSector)本字段包含FAT32分区中总的扇区数 0x24 4 0x00001F32 每FAT扇区数(SectorsPerFAT)(只被FAT32使用)该分区每个FAT所占的扇区数。计算机利用这个数和FAT数以及隐藏扇区数(本表中所描述的)来决定根目录从哪里开始。该计算机还可以从目录中的项数决定该分区的用户数据区从哪里开始 0x28 2 0x00 扩展标志(ExtendedFlag)(只被FAT32使用)该两个字节结构中各位的值为:位0-3:活动FAT数(从0开始计数,而不是1).??????只有在不使用镜像时才有效位4-6:保留位7:0值意味着在运行时FAT被映射到所有的FAT????1值表示只有一个FAT是活动的位8-15:保留 0x2A 2 0x0000 文件系统版本(FileystemVersion)只供FAT32使用,高字节是主要的修订号,而低字节是次要的修订号。本字段支持将来对该FAT32媒体类型进行扩展。如果本字段非零,以前的Windows版本将不支持这样的分区 0x2C 4 0x00000002 根目录簇号(RootClusterNumber)(只供FAT32使用)根目录第一簇的簇号。本字段的值一般为2,但不总是如此 0x30 2 0x0001 文件系统信息扇区号(FileSystemInformationSectorNumber)(只供FAT32使用)FAT32分区的保留区中的文件系统信息(FileSystemInformation,FSINFO)结构的扇区号。其值一般为1。在备份引导扇区(BackupBootSector)中保留了该FSINFO结构的一个副本,但是这个副本不保持更新 0x34 2 0x0006 备份引导扇区(只供FAT32使用)为一个非零值,这个非零值表示该分区保存引导扇区的副本的保留区中的扇区号。本字段的值一般为6,建议不要使用其他值 0x36 12 12个字节均为0x00 保留(只供FAT32使用)供以后扩充使用的保留空间。本字段的值总为0 ????DBR的偏移0x5A开始的数据为操作系统引导代码。这是由偏移0x00开始的跳转指令所指向的。在图8所列出的偏移0x00~0x02的跳转指令"EB5890"清楚地指明了OS引导代码的偏移位置。jump58H加上跳转指令所需的位移量,即开始于0x5A。此段指令在不同的操作系统上和不同的引导方式上,其内容也是不同的。大多数的资料上都说win98,构建于fat基本分区上的win2000,winxp所使用的DBR只占用基本分区的第0扇区。他们提到,对于fat32,一般的32个基本分区保留扇区只有第0扇区是有用的。实际上,以FAT32构建的操作系统如果是win98,系统会使用基本分区的第0扇区和第2扇区存储os引导代码;以FAT32构建的操作系统如果是win2000或winxp,系统会使用基本分区的第0扇区和第0xC扇区(win2000或winxp,其第0xC的位置由第0扇区的0xAB偏移指出)存储os引导代码。所以,在fat32分区格式上,如果DBR一扇区的内容正确而缺少第2扇区(win98系统)或第0xC扇区(win2000或winxp系统),系统也是无法启动的。如果自己手动设置NTLDR双系统,必须知道这一点。????DBR扇区的最后两个字节一般存储值为0x55AA的DBR有效标志,对于其他的取值,系统将不会执行DBR相关指令。上面提到的其他几个参与os引导的扇区也需以0x55AA为合法结束标志。





四、流程图

(1)Fat文件流程图:

























五、源代码

(1)Fat文件的源代码

#include

structfat_boot_sector{

__s8 ignored[3]; /0x00,Bootstrapshortornearjump/

__s8 system_id[8]; /0x03,Name-canbeusedtospecialcasepartitionmanagervolumes/

__u8 sector_size[2]; /0x0B,bytesperlogicalsector/

__u8 cluster_size; /0x0D,sectors/cluster/

__u16 reserved; /0x0E,reservedsectors/

__u8 fats; /0x10,numberofFATs/

__u8 dir_entries[2]; /0x12,rootdirectoryentries/

__u8 sectors[2]; /0x13,numberofsectors/

__u8 media; /0x15,mediacode(unused)/

__u16 fat_length; /0x16,sectors/FAT/

__u16 secs_track; /0x18,sectorspertrack/

__u16 heads; /0x1A,numberofheads/

__u32 hidden; /0x1C,hiddensectors(unused)/

__u32 total_sect; /0x20,numberofsectors(ifsectors==0)/

__u32 fat32_length; /0x24,sectors/FAT/

__u16 flags; /0x28,bit8:fatmirroring,low4:activefat/

__u8 version[2]; /0x2A,major,minorfilesystemversion/

__u32 root_cluster; /0x2C,firstclusterinrootdirectory/

__u16 info_sector; /0x30,filesysteminfosector/

__u16 backup_boot; /0x34,backupbootsector/

__u16 reserved2[6]; /0x36,Unused/

};

structfat_boot_fsinfo{

__u32signature1; /0x41615252L/

__u32reserved1[120]; /NothingasfarasIcantell/

__u32signature2; /0x61417272L/

__u32free_clusters; /Freeclustercount.-1ifunknown/

__u32next_cluster; /Mostrecentlyallocatedcluster.

UnusedunderLinux./

__u32reserved2[4];

};

structmsdos_dir_entry{

__s8 name[8],ext[3]; /nameandextension/

__u8 attr; /attributebits/

__u8lcase; /Caseforbaseandextension/

__u8 ctime_ms; /Creationtime,milliseconds/

__u16 ctime; /Creationtime/

__u16 cdate; /Creationdate/

__u16 adate; /Lastaccessdate/

__u16starthi; /High16bitsofclusterinFAT32/

__u16 time,date,start;/time,dateandfirstcluster/

__u32 size; /filesize(inbytes)/

};

structmsdos_dir_slot{

__u8id; /sequencenumberforslot/

__u8name0_4[10]; /first5charactersinname/

__u8attr; /attributebyte/

__u8reserved; /always0/

__u8alias_checksum; /checksumfor8.3alias/

__u8name5_10[12]; /6morecharactersinname/

__u16start; /startingclusternumber,0inlongslots/

__u8name11_12[4]; /last2charactersinname/

};

structvfat_slot_info{

intis_long; /wasthefoundentrylong/

intlong_slots; /numberoflongslotsinfilename/

inttotal_slots; /totalslots(longandshort)/

loff_tlongname_offset; /diroffsetforlongnamestart/

loff_tshortname_offset;/diroffsetforshortnamestart/

intino; /inoforthefile/

};

#include "msdos_fs.h"

#include

main(intargc,charargv)

{

int i,j;

__u32 data_entry,sectors;

char tmp_c[100],t_c;

unsignedchar sct[513];

typedef structfat_boot_sectorf_b_s;

f_b_sfbs;

if(argc==0){

fprintf(stderr,"Usage:\n\t%s%s\n",argv[0],"Disk");

exit(1);

}

if((i=open(argv[1],0))==-1){

fprintf(stderr,"Disk/File%sopenerror!\n",argv[0]);

exit(2);

}

if(read(i,sct,512)!=512){

fprintf(stderr,"Disk/File%sreaderror!\n",argv[0]);

close(i);exit(3);

}

close(i);

fbs=(f_b_s)&sct;

printf("\nDBRInformationondevice%s\n",argv[1]);

printf("system_id[8]=%s\n",fbs->system_id);

printf("sector_size[2]=%ud\n",fbs->sector_size[1]256+fbs->sector_size[0]);

printf("cluster_size=%du\n",fbs->cluster_size);

printf("reserved=%ud\n", fbs->reserved);

printf("fats=%ud\n",fbs->fats);

printf("dir_entries[2]=%ud\n",fbs->dir_entries[1]256+fbs->dir_entries[0]);

printf("sectors[2]=%ud\n",fbs->sectors[1]256+fbs->sectors[0]);

printf("media=%2.2x\n",fbs->media);

printf("fat_length=%ul\n",fbs->fat_length);

printf("secs_track=%ud\n",fbs->secs_track);

printf("heads=%ud\n",fbs->heads);

printf("hidden=%ud\n",fbs->hidden);

printf("total_sect=%ul\n",fbs->total_sect);

printf("fat32_length=%ul\n",fbs->fat32_length);

printf("flags=%2.2x\n",fbs->flags);

printf("version[2]=%ud|%ud\n",fbs->version[1],fbs->version[0]);

printf("root_cluster=%ud\n",fbs->root_cluster);

printf("info_sector=%ul\n",fbs->info_sector);

printf("backup_boot=%ud\n",fbs->backup_boot);

printf("reserved2[6]=");

for(i=0;i<6;i++)printf("%2.2x",fbs->reserved2[i]);

printf("\n");

sectors=fbs->sectors[1]256+fbs->sectors[0];

printf("fbs->sectors=%u\n",sectors);

if(sectors==0)

data_entry=fbs->fat32_lengthfbs->fats+fbs->reserved;

elsedata_entry=fbs->fat_lengthfbs->fats+fbs->reserved;

printf("Data_entry=%ul\n",data_entry);

exit(0);}

(2)Hd文件的源代码

#define L53//可以对一些常见的变量,字符串等,进行宏定义

#include

main(intargc,charargv)//其中,intargc表示命令行参数的个数(包括可执行程序名本身)//charargv[]表示每个参数的具体内容,//命令行参数用的最多还是在诸如DIRA:等之类带有盘符、路径或文件名这样的命令行中,所以说灵活处理这一类参数才能有效地提高程序的运行效果

{

int i,j,k,l,fd;

unsignedlong ll;

unsignedchar b[17];

char buffo[100],b_t[5];

if(argc==1){

fprintf(stderr,"Noinputfile!\nUsage:\n\t%sin_file1in_file2...\n",argv[0]);

exit(-1);

}

for(i=1;i
printf("%s\n",argv[i]);

if((fd=open(argv[i],0))==-1){

fprintf(stderr,"File:\''%s\''doesnotexist\n",argv[i]);

continue;

}

ll=0;

loop1:

j=read(fd,b,16);

if(j==16)

sprintf(buffo,"%4.4x:%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x",\

ll,b[0],b[1],b[2],b[3],b[4],b[5],b[6],b[7],b[8],b[9],b[10],b[11],b[12],b[13],b[14],b[15]);

else{

sprintf(buffo,"%4.4x:",ll);

for(k=0;k
sprintf(b_t,"%2x",b[k]);

strcat(buffo,b_t);

}

l=strlen(buffo);

for(k=l;k<=L;k++)buffo[k]='''';

buffo[k]=''\0'';

}

l=strlen(buffo);

buffo[l++]='''';buffo[l++]='''';buffo[l++]='''';

for(k=0;k
if(b[k]>=''''&&b[k]<''z'')

buffo[l++]=b[k];

else

buffo[l++]=''.'';

}

buffo[l++]=''\n'';buffo[l]=''\0'';

printf("%s",buffo);

ll+=j;

if(j==16)gotoloop1;

else{

close(fd);

printf("\n");

}

}

}



(3)Pdisk文件的源代码

#include

structpart_int{

unsignedcharboot_ind; /0x80-active/

unsignedcharhead; /startinghead/

unsignedcharsector; /startingsector/

unsignedintcyl; /startingcylinder/

unsignedcharsys_ind; /Whatpartitiontype/

unsignedcharend_head; /endhead/

unsignedcharend_sector; /endsector/

unsignedintend_cyl; /endcylinder/

unsignedintstart_sect; /startingsectorcountingfrom0/

unsignedintnr_sects; /nrofsectorsinpartition/

}p_t[4];

#include

#define sct_sz 512

main(intargc,charargv)

{int i,fd,j,k;

unsignedchar tmp_c[100],t_c;

unsignedchar sct[sct_sz+1];

structpartitionpt,part;

unsignedint cyls,heads,sects,S,W;

if(argc==0){

fprintf(stderr,"Usage:\n\t%s%s\n",argv[0],"Disk");

exit(1);

}

if((fd=open(argv[1],0))==-1){

fprintf(stderr,"Disk/File%sopenerror!\n",argv[0]);

exit(2);

}

if(read(fd,sct,sct_sz)!=sct_sz){

fprintf(stderr,"Disk/File%sreaderror!\n",argv[0]);

close(i);exit(3);

}

if(!(sct[510]==0x55&&sct[511]==0xaa)){

fprintf(stderr,"%sisnotavaliddisk!",argv[0]);

exit(4);

}

printf("PartitionTablesAre:\n");

S=0x1be;t_c=sct;

for(i=0;i<4;i++){

pt=t_c+S;

for(j=0;j<16;j++)printf("%2.2x",sct[S+j]);printf("\n");

p_t[i].boot_ind=pt->boot_ind;

p_t[i].head=pt->head;

W=0xFFC0&(unsignedint)pt->sector;

W<<=2;

p_t[i].sector=0x3F&(unsignedint)pt->sector;

p_t[i].cyl=W|pt->cyl;

p_t[i].sys_ind=pt->sys_ind;

p_t[i].end_head=pt->end_head;

W=0xFFC0&(unsignedint)pt->end_sector;

W<<=2;

p_t[i].end_sector=0x3F&(unsignedint)pt->end_sector;

p_t[i].end_cyl=W|pt->end_cyl;

p_t[i].start_sect=pt->start_sect;

p_t[i].nr_sects=pt->nr_sects;

S+=0x10;

}

if(disp_part2(argv[1],&cyls,&heads,§s)!=3){

fprintf(stderr,"%s:GetParametererror!\n",argv[1]);

exit-1;

}

printf("Geometry(Cylinders,Headers,Sectors)=(%d,%d,%d)\n",cyls,heads,sects);

printf("\nDEV:ActS_headS_sectorS_cylTypeE_headE_sectorE_cylStartTotal\n");

for(i=0;i<4;i++){

disp_part1(argv[1],i,&p_t[i]);

}

exit(0);

}

disp_part1(chardev,intcnt,structpart_intpt){

printf("%2.2d:",cnt);

if(pt->boot_ind&&80)printf("A");elseprintf("");

printf("%6u",pt->head);

printf("%6u",pt->sector);

printf("%6u",pt->cyl);

printf("%2.2x",pt->sys_ind);

printf("%6u",pt->end_head);

printf("%6u",pt->end_sector);

printf("%6u",pt->end_cyl);

printf("%6u",pt->start_sect);

printf("%6u\n",pt->nr_sects);

}

disp_part2(chardev,intc,inth,ints){

charcmd[100];

intret,cyl,head,sect;

FILE fp;

pid_t pid;

pid=getpid();

sprintf(cmd,"sfdisk-g%s|awk''{print$2,$4,$6}''>pid%d",dev,pid);

ret=system(cmd);

sprintf(cmd,"pid%d",pid);

if((fp=fopen(cmd,"r"))==NULL){

fprintf(stderr,"%s:openerrorforread!\n",cmd);

return-1;

}

ret=fscanf(fp,"%d%d%d",c,h,s);

fclose(fp);

printf("ret=%d\tcyls=%d\theads=%d\tsects=%d\n",ret,c,h,s);

unlink(cmd);

returnret;

}

六、运行结果











七、心得体会

这一周的操作系统课程设计终于结束了,总的说来收获还是爆多的,在了解了我们的课程设计题目和要求后,当时真是一片茫然啊,没办法只有向老师请教了。我们请带我们班的课程设计老师张老师给我们具体讲解了一下我们设计所要做的具体工作,老师很耐心的跟我们解释和讨论,并且给我们提供了参考资料和参考网站。等我们每个人都了解了我们组所要完成的任务以后,分工、开始进行我们各自的工作。

大家再实际的工作中都遇到了或多或少的问题,但是,我们并没有退却,俗话说“三个臭皮匠,顶一个诸葛亮”。这部分的知识我们学习的程度都有所不同,彼此互相提供帮助。使我们对进程的通信与控制有了更深一层次的了解。

经过大概两天的奋斗,基本上各部分的源程序已经出来了,但是具体的方案,我们还是不能确定,又得麻烦老师了。偶尔请教老师跟我们一起进行了方案讨论,帮助我们确定了最后的方案。接下来就要完成相应的文字内容了,看清要求,完成课程设计报告。

通过与同组同学的合作,加强了我们的团体合作能力。通过对Linux这种大型软件代码的分析,看到大型软件的编程习惯,我们组成员深感我们平时的编程习惯与良好的编程习惯相差甚远,小组成员决定在以后的编程过程中养成良好的编程习惯,这样有助于自己所编的程序清晰明了便于该错还有助于别人来立解你的程序。同时通过这次课程设计我们形成了通过从各方面查找资料来丰富自己的知识的能力。





八、参考目录

计算机操作系统教程(第3版)张尧学,史美林清华大学出版社

计算机操作系统汤子瀛主编西安电子科技大学出版社

.操作系统原理及应用刘乃琦等北京经济科学出版社,1996.5

AbrahamSilberschatz.AppliedOperatingSystemConcepts北京:高等教育出版社[5]严数据数据结构尉敏吴伟民北京:清华大学出版社

C语言设计谭浩强主编北京:清华大学出版社.























21





开始传入参数



判断参数



参数正确



显示结果设备的信息



提示错误退出



Ifargv=0



Ifargv=1



提示读入错误

退出



初始化



传入参数



判断磁盘分区



不成功



成功



显示出磁盘分区情况及其特性



开始传入参数



判断参数



参数正确



显示设备的信息结构



Ifargv=1







献花(0)
+1
(本文系暴风雪中原创)