VC Win32 读取 磁盘MBR 和 EBR扩展分区 数据

相关MBR结构定义头文件
</pre><pre name="code" class="cpp">//备注: UCHAR占1字节、ULONG占4字节、一个扇区等于512字节

#pragma pack(1)				//字节对齐

#define BOOTRECORDSIZE		440
#define PARTITIONTABLE		4	

//分区表结构
//typedef struct _PARTITION_ENTRY{
//	UCHAR	BootSign;					//引导标志(是否被激活)
//	UCHAR	StartHsc[3];				//包含起始磁头、扇区、柱面(Head、Sector、Cylinder H\S\C)
//	UCHAR	PartitionType;				//分区类型描述
//	UCHAR	EndHsc[3];					//包含结束磁头、扇区、柱面
//	ULONG	SectorsPrecedingPartiton;	//本分区之前使用的扇区数
//	ULONG	SectorsInPartition;			//分区的总扇区数
//}PARTITION_ENTRY, *PPARTITION_ENTRY;

typedef struct _PARTITION_ENTRY{
	UCHAR	BootSign;			//引导标志(是否被激活)
	UCHAR	StartHead;			//开始磁头 Head
	USHORT	StartSC;			//开始扇区、柱面 Sector、Cylinder (H\S\C描述)
	UCHAR	PartitionType;		//分区类型描述
	UCHAR	EndHead;			//结束磁头
	USHORT	EndSC;				//结束扇区、柱面
	ULONG	SectorsPrecedingPartiton;	//本分区之前使用的扇区数
	ULONG	SectorsInPartition; //分区的总扇区数
}PARTITION_ENTRY, *PPARTITION_ENTRY;

//引导区MBR结构 512字节
typedef struct _MBR_SECTOR{

	UCHAR	BootRecord[BOOTRECORDSIZE];				//引导程序	 440byte	
	ULONG	DiskSignatrue;							//磁盘		 4byte
	USHORT	NoneDisk;								//占位		 2byte
	PARTITION_ENTRY Partition[PARTITIONTABLE];	    //分区表结构 64byte
	USHORT	Signatrue;								//结束标志   2byte
}MBR_SECTOR, *PMBR_SECTOR;

//读取MBR
BOOL ReadMbr(HANDLE hDevice,PMBR_SECTOR _pReadMbr);
//读取EBR
BOOL ReadEbr(HANDLE hDevice, ULONG uAbsolutePtBase,ULONG uOffsetPt, PMBR_SECTOR _pReadEbr);//偏移基数

//解析MBR填充到列表
ULONG ParseMbrToListBox(HWND hWnmd, MBR_SECTOR _ReadMbr, BOOL& bHaveExtented);
//解析EBR填充到列表
ULONG ParseEbrToListBox(HWND hWnmd, MBR_SECTOR _ReadEbr);

//打印结束符
void PrintEnd(MBR_SECTOR _ReadMbrOrEbr);

#pragma pack()
</pre><pre name="code" class="cpp">Win32窗口交互相关定义

 

#pragma once

#include "resource.h"
#include <windef.h>

//LISTBOX
#define LISTBOX_DELETEALLITEM(hWnd)		SendMessageW(hWnd,LB_RESETCONTENT,0,0)
#define LISTBOX_ADDSTRING(hWnd,wstr)	SendMessageW(hWnd,LB_ADDSTRING,0,(LPARAM)wstr)
#define LISTBOX_GETCOUNT(hWnd)			SendMessageW(hWnd,LB_GETCOUNT,0,0)

//
// 此代码模块中包含的函数的前向声明: 
ATOM				MyRegisterClass(HINSTANCE hInstance);
BOOL				InitInstance(HINSTANCE, int);
LRESULT CALLBACK	WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK	About(HWND, UINT, WPARAM, LPARAM);

//
//创建静态标签
HWND CrateStaticForMainWnd(HWND hWnd, LPWSTR lpStrText, LONG lStyle, int x, int y, int cx, int cy);
//创建按钮
void CreateButtonForMainWnd(HWND hWnd, LPWSTR lpStrText, UINT uID, LONG lStyle, int x, int y, int cx, int cy);
//创建列表框
HWND CreateListBoxForMainWnd(HWND hWnd, LPWSTR lpStrText, UINT uID, LONG lStyle, int x, int y, int cx, int cy);
//设置默认字体
void SetDefaultFont(HWND& hWnd);
//添加文本
void AddStringForListBox(HWND hWnd, LPWSTR lpStrText = L"");
//获取总共项
int GetItemCountForListBox(HWND hWnd);
//删除所有项
void DeleteAllItemForListBox(HWND hWnd);
//删除单个项
void DeleteItemForListBox(HWND hWnd, int iIndex);


//
//响应WM_CREATE消息
void OnCreate(HWND& hWnd);
//按钮IDC_BTN_OUTPUT被单击
void OnBtnRead1Click();
//删除按钮
void OnBtnRead2Click();


Win32 窗口实现

 

 

// MastBoot.cpp : 定义应用程序的入口点。
//

#include "stdafx.h"
#include "MastBoot.h"
#include "mbr.h"
#include <map>
#include <Winioctl.h>
using namespace std;

#define MAX_LOADSTRING 100
#define MAINWND_DEFAULT_WIDTH	300
#define MAINWND_DEFAULT_HEIGHT	500

#define IDC_BTN_READ1	 10001
#define IDC_LISTBOX_INFO 10002
#define IDC_BTN_READ2	 10003

// 全局变量: 
HINSTANCE hInst;								//当前实例
TCHAR szTitle[MAX_LOADSTRING];					//标题栏文本
TCHAR szWindowClass[MAX_LOADSTRING];			//主窗口类名
map<HANDLE, RECT>	mapControls;				//控件集合
HWND				hWndListBox;				//

int APIENTRY _tWinMain(_In_ HINSTANCE hInstance,
                     _In_opt_ HINSTANCE hPrevInstance,
                     _In_ LPTSTR    lpCmdLine,
                     _In_ int       nCmdShow)
{
	UNREFERENCED_PARAMETER(hPrevInstance);
	UNREFERENCED_PARAMETER(lpCmdLine);

 	// TODO:  在此放置代码。
	MSG msg;
	HACCEL hAccelTable;

	// 初始化全局字符串
	LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
	LoadString(hInstance, IDC_MASTBOOT, szWindowClass, MAX_LOADSTRING);
	MyRegisterClass(hInstance);

	// 执行应用程序初始化: 
	if (!InitInstance (hInstance, nCmdShow))
	{
		return FALSE;
	}

	hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_MASTBOOT));

	// 主消息循环: 
	while (GetMessage(&msg, NULL, 0, 0))
	{
		if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
		{
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
	}

	return (int) msg.wParam;
}


//
//  函数:  MyRegisterClass()
//
//  目的:  注册窗口类。
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
	WNDCLASSEX wcex;

	wcex.cbSize = sizeof(WNDCLASSEX);

	wcex.style			= CS_HREDRAW | CS_VREDRAW;
	wcex.lpfnWndProc	= WndProc;
	wcex.cbClsExtra		= 0;
	wcex.cbWndExtra		= 0;
	wcex.hInstance		= hInstance;
	wcex.hIcon			= LoadIcon(hInstance, MAKEINTRESOURCE(IDI_MASTBOOT));
	wcex.hCursor		= LoadCursor(NULL, IDC_ARROW);
	wcex.hbrBackground	= (HBRUSH)(COLOR_WINDOW+1);
	wcex.lpszMenuName	= MAKEINTRESOURCE(IDC_MASTBOOT);
	wcex.lpszClassName	= szWindowClass;
	wcex.hIconSm		= LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));

	return RegisterClassEx(&wcex);
}

//
//   函数:  InitInstance(HINSTANCE, int)
//
//   目的:  保存实例句柄并创建主窗口
//
//   注释: 
//
//        在此函数中,我们在全局变量中保存实例句柄并
//        创建和显示主程序窗口。
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
   HWND hWnd;

   hInst = hInstance; // 将实例句柄存储在全局变量中

   hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT, CW_USEDEFAULT, MAINWND_DEFAULT_WIDTH, MAINWND_DEFAULT_HEIGHT, NULL, NULL, hInstance, NULL);

   if (!hWnd)
   {
      return FALSE;
   }

   ShowWindow(hWnd, nCmdShow);
   UpdateWindow(hWnd);

   return TRUE;
}

//
//  函数:  WndProc(HWND, UINT, WPARAM, LPARAM)
//
//  目的:    处理主窗口的消息。
//
//  WM_COMMAND	- 处理应用程序菜单
//  WM_PAINT	- 绘制主窗口
//  WM_DESTROY	- 发送退出消息并返回
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	int wmId, wmEvent;
	PAINTSTRUCT ps;
	HDC hdc;

	switch (message)
	{
	case WM_CREATE:
		OnCreate(hWnd);
		break;
	case WM_COMMAND:
		wmId    = LOWORD(wParam);
		wmEvent = HIWORD(wParam);
		// 分析菜单选择: 
		switch (wmId)
		{
		case IDM_ABOUT:
			DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
			break;
		case IDM_EXIT:
			DestroyWindow(hWnd);
			break;
		case IDC_BTN_READ1:
			OnBtnRead1Click();
			break;
		case IDC_BTN_READ2:
			OnBtnRead2Click();
			break;
		default:
			return DefWindowProc(hWnd, message, wParam, lParam);
		}
		break;
	case WM_PAINT:
		hdc = BeginPaint(hWnd, &ps);
		// TODO:  在此添加任意绘图代码...
		EndPaint(hWnd, &ps);
		break;
	case WM_DESTROY:
		PostQuitMessage(0);
		break;
	default:
		return DefWindowProc(hWnd, message, wParam, lParam);
	}
	return 0;
}

// “关于”框的消息处理程序。
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
	UNREFERENCED_PARAMETER(lParam);
	switch (message)
	{
	case WM_INITDIALOG:
		return (INT_PTR)TRUE;

	case WM_COMMAND:
		if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
		{
			EndDialog(hDlg, LOWORD(wParam));
			return (INT_PTR)TRUE;
		}
		break;
	}
	return (INT_PTR)FALSE;
}

void SetDefaultFont(HWND& hWnd)
{
	LOGFONT lf;
	memset(&lf, 0, sizeof(LOGFONT));
	lf.lfHeight = 15;
	lf.lfWeight = 12;
	memcpy(lf.lfFaceName, L"Arial", sizeof(L"Arial"));

	HFONT hFont = CreateFontIndirect(&lf);

	SendMessageW(hWnd, WM_SETFONT, (WPARAM)hFont, 0);
}

void AddStringForListBox(HWND hWnd, LPWSTR lpStrText)
{
	SendMessageW(hWnd, LB_ADDSTRING, 0, (LPARAM)lpStrText);
}

int GetItemCountForListBox(HWND hWnd)
{
	return SendMessageW(hWnd, LB_GETCOUNT, 0, 0);
}

void DeleteItemForListBox(HWND hWnd, int iIndex)
{
	SendMessageW(hWnd, LB_DELETESTRING, (WPARAM)iIndex, 0); 
}

void DeleteAllItemForListBox(HWND hWnd)
{	
	SendMessageW(hWnd, LB_RESETCONTENT, 0, 0);
}

HWND CrateStaticForMainWnd(HWND hWnd, LPWSTR lpStrText, LONG lStyle, int x, int y, int cx, int cy)
{
	HWND hWndStatic = CreateWindowW(L"STATIC", 
		lpStrText,
		lStyle,
		x, y, cx, cy,
		hWnd,
		NULL,
		hInst,NULL);
	if (hWndStatic == NULL)
	{
		return hWndStatic;
	}

	//设置默认字体
	SetDefaultFont(hWndStatic);

	RECT rect = {x,y,cx,cy};

	mapControls.insert(pair<HWND, RECT>(hWndStatic, rect));

	return hWndStatic;
}

void CreateButtonForMainWnd(HWND hWnd, LPWSTR lpStrText, UINT uID, LONG lStyle, int x, int y, int cx, int cy)
{
	HWND hWndButton = CreateWindowW(L"BUTTON",
		lpStrText,
		lStyle,
		x, y, cx, cy,
		hWnd,
		(HMENU)uID,
		hInst, NULL);
	if (hWndButton == NULL)
	{
		return;
	}

	//设置默认字体
	SetDefaultFont(hWndButton);

	RECT rect = { x, y, cx, cy };

	mapControls.insert(pair<HWND, RECT>(hWndButton, rect));
}

HWND  CreateListBoxForMainWnd(HWND hWnd, UINT uID, LONG lStyle, int x, int y, int cx, int cy)
{
	HWND hWndListBox = CreateWindowW(L"LISTBOX",
		NULL,lStyle,
		x, y, cx, cy,
		hWnd,
		(HMENU)uID, 
		hInst, NULL);

	if (hWndListBox == NULL)
	{
		return NULL;
	}

	//设置默认字体
	SetDefaultFont(hWndListBox);

	RECT rect = { x, y, cx, cy };

	mapControls.insert(pair<HWND, RECT>(hWndListBox, rect));

	return hWndListBox;
}


void OnCreate(HWND& hWnd)
{
	//创建一个调试按钮
	CreateButtonForMainWnd(hWnd, L"读取MBR1", IDC_BTN_READ1, WS_CHILD | WS_VISIBLE, 10, 20, 70, 30);
	//创建一个删除按钮
	CreateButtonForMainWnd(hWnd, L"读取MBR2", IDC_BTN_READ2, WS_CHILD | WS_VISIBLE, 90, 20, 70, 30);
	//创建一个ListBox
	hWndListBox = CreateListBoxForMainWnd(hWnd, IDC_LISTBOX_INFO, LBS_NOTIFY | WS_BORDER | WS_CHILD | WS_OVERLAPPED | WS_VISIBLE | WS_VSCROLL,
		10, 60, 260, 320);
}

void OnBtnRead1Click()
{	

}

BOOL ReadMbr(HANDLE hDevice,PMBR_SECTOR _pReadMbr)
{	
	DWORD dwLeng = 512,dwCount = 0;
	
	//清空结构
	memset(_pReadMbr, 0, 512);

	//锁定目标磁盘
	DeviceIoControl(hDevice, FSCTL_LOCK_VOLUME, NULL, 0, NULL, 0, &dwCount, NULL);

	//读取MBR数据
	BOOL bCheck = ReadFile(hDevice, _pReadMbr, 512, &dwLeng, NULL);

	//解锁目标
	DeviceIoControl(hDevice, FSCTL_UNLOCK_VOLUME, NULL, 0, NULL, 0, &dwCount, NULL);

	return bCheck;
}

BOOL ReadEbr(HANDLE hDevice, ULONG uAbsolutePtBase, ULONG uOffsetPt, PMBR_SECTOR _pReadEbr)
{
	DWORD dwLeng = 512, dwCount = 0;

	//清空结构
	memset(_pReadEbr, 0, 512);
	
	//计算读取位置
	LARGE_INTEGER EPOffsetByte;
	
	//扇区绝对地址+偏移地址
	EPOffsetByte.QuadPart = ((DWORD64)uAbsolutePtBase + uOffsetPt) * 512;
	
	//锁定目标磁盘
	DeviceIoControl(hDevice, FSCTL_LOCK_VOLUME, NULL, 0, NULL, 0, &dwCount, NULL);

	//移动读取位置
	SetFilePointer(hDevice, EPOffsetByte.LowPart, &EPOffsetByte.HighPart, FILE_BEGIN);	// SetFilePointerEx(hDevice, EPOffsetByte, 0, FILE_BEGIN);
	
	//读取EBR数据
	BOOL bCheck = ReadFile(hDevice, _pReadEbr, 512, &dwLeng, NULL);

	//解锁目标
	DeviceIoControl(hDevice, FSCTL_UNLOCK_VOLUME, NULL, 0, NULL, 0, &dwCount, NULL);

	return bCheck;
}

ULONG ParseMbrToListBox(HWND hwnd, MBR_SECTOR _ReadMbr,BOOL& bHaveExtented)
{	
	WCHAR wstr[64] = { 0 };			//临时缓冲区
	
	ULONG uAbsolutePt = 0;			//扇区绝对起始位置
	
	bHaveExtented = FALSE;			//是否存在扩展分区

	for (int i = 0; i < PARTITIONTABLE; i++)
	{
		memset(wstr, 0, 64);
		wsprintf(wstr, L"引导标志:%02X", _ReadMbr.Partition[i].BootSign);
		LISTBOX_ADDSTRING(hwnd, wstr);

		memset(wstr, 0, 64);
		wsprintf(wstr, L"开始磁头:%d", _ReadMbr.Partition[i].StartHead);
		LISTBOX_ADDSTRING(hwnd, wstr);

		memset(wstr, 0, 64);
		wsprintf(wstr, L"起始扇区:%d", _ReadMbr.Partition[i].StartSC & 63);
		LISTBOX_ADDSTRING(hwnd, wstr);

		memset(wstr, 0, 64);
		wsprintf(wstr, L"起始柱面:%d", _ReadMbr.Partition[i].StartSC >> 6);
		LISTBOX_ADDSTRING(hwnd, wstr);

		memset(wstr, 0, 64);
		wsprintf(wstr, L"分区类型:%02X", _ReadMbr.Partition[i].PartitionType);
		LISTBOX_ADDSTRING(hwnd, wstr);

		memset(wstr, 0, 64);
		wsprintf(wstr, L"结束磁头:%d", _ReadMbr.Partition[i].EndHead);
		LISTBOX_ADDSTRING(hwnd, wstr);

		memset(wstr, 0, 64);
		wsprintf(wstr, L"结束扇区:%d", _ReadMbr.Partition[i].EndSC & 63);
		LISTBOX_ADDSTRING(hwnd, wstr);

		memset(wstr, 0, 64);
		wsprintf(wstr, L"结束柱面:%d", _ReadMbr.Partition[i].EndSC >> 6);
		LISTBOX_ADDSTRING(hwnd, wstr);

		memset(wstr, 0, 64);
		wsprintf(wstr, L"之前使用扇区数:%d", _ReadMbr.Partition[i].SectorsPrecedingPartiton);
		LISTBOX_ADDSTRING(hwnd, wstr);

		memset(wstr, 0, 64);
		wsprintf(wstr, L"总扇区数:%d", _ReadMbr.Partition[i].SectorsInPartition);
		LISTBOX_ADDSTRING(hwnd, wstr);

		//插入换行符
		LISTBOX_ADDSTRING(hwnd, L"");


		//表示第没有扩展分区了
		if (_ReadMbr.Partition[i].PartitionType == 0x00)
		{
			break;
		}

		//如果为0x05或0x0F表明该分区为扩展分区 不处理第三和第四分区表
		if (_ReadMbr.Partition[i].PartitionType == 0x05 || _ReadMbr.Partition[i].PartitionType == 0x0F)
		{
			//保存0扇区到扩展分区的绝对扇区
			uAbsolutePt = _ReadMbr.Partition[i].SectorsPrecedingPartiton;
			//设置为扩展分区
			bHaveExtented = TRUE;
			break;
		}

	}

	return uAbsolutePt;
}

void OnBtnRead2Click()
{
	WCHAR		szDevicename[64] = { 0 };	//临时路径换成区
	MBR_SECTOR	_ReadMbr,_ReadEbr;			//MBR、EBR结构
	BOOL bHaveExtented;						//是否包含扩展分区
	wsprintf(szDevicename, L"\\\\.\\PHYSICALDRIVE0");
	
	//打开磁盘
	HANDLE	hDevice = CreateFileW(szDevicename,
		GENERIC_READ | GENERIC_WRITE,
		FILE_SHARE_READ | FILE_SHARE_WRITE,
		NULL,
		OPEN_EXISTING,
		0,
		NULL);
	
	//判断磁盘是否打开成功
	if (hDevice == INVALID_HANDLE_VALUE)
	{
		WCHAR lpwstrError[50] = { 0 };
		wsprintf(lpwstrError, L"打开失败,错误:%d", GetLastError());
		MessageBox(NULL, lpwstrError, L"", MB_OK);
		return;
	}

	//读取MBR
	ReadMbr(hDevice, &_ReadMbr);

	//解析MBR数据并填充到LIST_BOX中
	ULONG uAbsolutePtBase = ParseMbrToListBox(hWndListBox, _ReadMbr,bHaveExtented);
	ULONG uOffsetPt = 0;

	//打印出结束符
	PrintEnd(_ReadMbr);
	
	//循环读取扩展分区(EBR)
	while (bHaveExtented)
	{
		//清空EBR
		memset(&_ReadEbr, 0, sizeof(_MBR_SECTOR));
		//读取EBR
		BOOL bCheck = ReadEbr(hDevice, uAbsolutePtBase, uOffsetPt, &_ReadEbr);
		//填充EBR
		uOffsetPt = ParseMbrToListBox(hWndListBox, _ReadEbr, bHaveExtented);
		//打印出结束符
		PrintEnd(_ReadEbr);
	}
	//关闭句柄
	CloseHandle(hDevice);
}


void PrintEnd(MBR_SECTOR _ReadMbrOrEbr)
{

	WCHAR wstr[63] = { 0 };	//临时缓冲区
	wsprintf(wstr, L"%02X", _ReadMbrOrEbr.Signatrue); 
	LISTBOX_ADDSTRING(hWndListBox, wstr);
	LISTBOX_ADDSTRING(hWndListBox, L"");
}

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值