修改主分区表给U盘分区

来源:互联网 发布:ubuntu 压缩软件 编辑:程序博客网 时间:2024/06/02 10:01
最近在学习文件系统,突发奇想想给U盘分个区,发现用DiskGenius分出两Fat32的主分区发现只能显示一个
后来在百度知道找到一个比较靠谱的答案——windows下U盘只能显示第一个分区(原理没说)
不过其他分区还是有存在的,用winhex可以看得到
而且分区的顺序跟在 u盘mbr0扇区的分区表有关(通过windows自带的快速格式化会把mbr给清没了 只留下dbr)

于是就有了这个更给分区顺序的小程序(更改第一分区与第二分区)


主要缺陷:1.没有判断有没有第二分区
2.U盘要拔下再插上才能显示另外一个分区
备注:环境 win7 + VS2008 U盘金士顿8g
看雪上有人说要 发送FSCTL_LOCK_VOLUME给设备
测试了一下貌似不用
`bRet = DeviceIoControl(
hDisk,
FSCTL_LOCK_VOLUME,
NULL,
0,
NULL,
0,
Output,
NULL);


///=====================================================//////名称:main.cpp//////描述:读取硬盘扇区//////作者:echo//////时间:2012/10/30//////=====================================================///#include<windows.h>#include<stdio.h>//#define DISK L"\\\\.\\H:"#define DISKPHYSICALDRIVE L"\\\\.\\PhysicalDrive1"//磁盘1 磁盘0为本机系统盘#pragma pack (1)//以一字节对齐//分区表结构体typedef struct __MAINPARTITIONTABLE{BYTE GuideSign;//引导标志BYTE StartCHS[3];//分区开始CHSBYTE PartitionType;//分区类型BYTE EndCHS[3];//分区接收CHSDWORD StartLBA;//分区开始LBADWORD SectorNum;//分区扇区数}MainPartitionTable,*pMainPartitionTable;#pragma pack ()int main(){DWORD StartSector = 0;//创建读取U盘句柄HANDLE hDisk = CreateFile(DISKPHYSICALDRIVE,GENERIC_READ | GENERIC_WRITE,FILE_SHARE_WRITE,NULL,OPEN_EXISTING, 0, NULL);if(INVALID_HANDLE_VALUE == hDisk){printf("打开磁盘失败");return 0;}//定位文件指针到0扇区SetFilePointer(hDisk,0x0200 * StartSector,0,FILE_BEGIN);DWORD dwCB;BYTE lpSectBuff[0x200];BOOL bRet = ReadFile(hDisk,//句柄lpSectBuff,//缓冲区0x200,//一个扇区大小&dwCB,//读取字节数NULL);//不是很懂if(bRet){/*ShowSector(lpSectBuff);*/printf("\n");printf("读取扇区成功\n");}else{printf("\n");printf("读取扇区失败 错误号为%ld\n",GetLastError());CloseHandle(hDisk);return 0;}printf("\n");//获取分区参数 第一个分区位于偏移0x1be处pMainPartitionTable p1 = new MainPartitionTable();//获取分区1参数memcpy(p1,(lpSectBuff + 0x1be + 0x00),sizeof(MainPartitionTable));pMainPartitionTable p2 = new MainPartitionTable();//获取分区2参数memcpy(p2,(lpSectBuff + 0x1be + 0x10),sizeof(MainPartitionTable));//ShowMAINPARTITIONTABLE(p1);//ShowMAINPARTITIONTABLE(p2);printf("\n");//交换分区参数memcpy((lpSectBuff + 0x1be + 0x00),p2,sizeof(MainPartitionTable));memcpy((lpSectBuff + 0x1be + 0x10),p1,sizeof(MainPartitionTable));/*ShowSector(lpSectBuff);*///重新定位文件指针SetFilePointer(hDisk,0x0200 * StartSector,0,FILE_BEGIN);//写入新的MBRbRet = WriteFile(hDisk,lpSectBuff,0x200,&dwCB,NULL);if(bRet){printf("\n");printf("写入成功\n");printf("%ld\n",dwCB);}else{printf("\n");printf("写入失败 错误号:%ld\n",GetLastError());}delete p1,p2;CloseHandle(hDisk);printf("操作结束 按回车键退出");getchar();return 0;}


未改之前的分区表


未改之前分区图 盘符h:为第一分区 第一分区可见


改了之后的分区表


改了之后第二分区得到了盘符h:变为了可见分区

备注:在linux下所有分区可见