修改主分区表给U盘分区

最近在学习文件系统,突发奇想想给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];			//分区开始CHS
	BYTE PartitionType;		//分区类型
	BYTE EndCHS[3];			//分区接收CHS
	DWORD StartLBA;			//分区开始LBA
	DWORD 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);

	//写入新的MBR
	bRet = 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;
}

修改主分区表给U盘分区_第1张图片

未改之前的分区表修改主分区表给U盘分区_第2张图片


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

修改主分区表给U盘分区_第3张图片

改了之后的分区表

修改主分区表给U盘分区_第4张图片

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

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

你可能感兴趣的:(修改主分区表给U盘分区)