win32 (Partition boot record) read/write by C++
Master boot record (FOR xp/2k)
以下是 win32 console program , 用來備份 boot sector (446 bytes) , 和寫入 boot sector.
測試環境是用 vs2005 , project property 用 /MT (靜態連結,省得 RUN-TIME-DLL 版本問題)
,用 MBCS 字集.
----------------
// bootsec.cpp : /dump to backup current harddisk boot sector to hex file, /fix to restore from hex file
//
#include "stdafx.h"
HANDLE hDevice=NULL;
unsigned char * WriteSector(int drive, DWORD startinglogicalsector, int numberofsectors,unsigned char *buffer)
{
SetFilePointer (hDevice, (startinglogicalsector*512), NULL, FILE_BEGIN);
DWORD byteswrite=0;
BOOL ret=WriteFile(hDevice,buffer,512*numberofsectors,&byteswrite,NULL);
ret = FlushFileBuffers(hDevice);
return buffer;
}
unsigned char * ReadSector(int drive, DWORD startinglogicalsector, int numberofsectors)
{
// All msdos data structures must be packed on a 1 byte boundary
#pragma pack (1)
struct
{
DWORD StartingSector ;
WORD NumberOfSectors ;
DWORD pBuffer;
}ControlBlock;
#pragma pack ()
#pragma pack (1)
typedef struct _DIOC_REGISTERS
{
DWORD reg_EBX;
DWORD reg_EDX;
DWORD reg_ECX;
DWORD reg_EAX;
DWORD reg_EDI;
DWORD reg_ESI;
DWORD reg_Flags;
} DIOC_REGISTERS ;
#pragma pack ()
unsigned char* buffer = (unsigned char*)malloc (512*numberofsectors);
DIOC_REGISTERS reg ;
BOOL fResult ;
DWORD cb ;
// Creating handle to vwin32.vxd (win 9x)
hDevice = CreateFile ( "\\\\.\\vwin32",
0,
0,
NULL,
0,
FILE_FLAG_DELETE_ON_CLOSE,
NULL );
if ( hDevice == INVALID_HANDLE_VALUE )
{
// win 2k code
DWORD bytesread;
// Creating a handle to drive a: using CreateFile () function ..
char _devicename[] = "\\\\.\\A:";
_devicename[4] += drive;
hDevice = CreateFile(_devicename,
// GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
GENERIC_WRITE | GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, 0, NULL);
if (hDevice == INVALID_HANDLE_VALUE)
return NULL;
SetFilePointer (hDevice, (startinglogicalsector*512), NULL, FILE_BEGIN);
if (!ReadFile (hDevice, buffer, 512*numberofsectors, &bytesread, NULL) )
return NULL;
}
else
{
// code for win 95/98
ControlBlock.StartingSector = (DWORD)startinglogicalsector;
ControlBlock.NumberOfSectors = (DWORD)numberofsectors ;
ControlBlock.pBuffer = (DWORD)buffer ;
//-----------------------------------------------------------
// SI contains read/write mode flags
// SI=0h for read and SI=1h for write
// CX must be equal to ffffh for
// int 21h's 7305h extention
// DS:BX -> base addr of the
// control block structure
// DL must contain the drive number
// (01h=A:, 02h=B: etc)
//-----------------------------------------------------------
reg.reg_ESI = 0x00 ;
reg.reg_ECX = -1 ;
reg.reg_EBX = (DWORD)(&ControlBlock);
reg.reg_EDX = drive+1;
reg.reg_EAX = 0x7305 ;
// 6 == VWIN32_DIOC_DOS_DRIVEINFO
fResult = DeviceIoControl ( hDevice,
6,
&(reg),
sizeof (reg),
&(reg),
sizeof (reg),
&cb,
0);
if (!fResult || (reg.reg_Flags & 0x0001)) return NULL;
}
// CloseHandle(hDevice);
return buffer;
}
int _tmain(int argc, _TCHAR* argv[])
{
const int mbr_drive = 'C' - 'A';
const int mbr_sector_start = 0;
const int mbr_sectors = 1;
if(argc==1)
{
printf("\nmbr v002");
printf("\nmbr /dump > mbr.hex");
printf("\nmbr /fix < mbr.hex");
printf("\n");
}
unsigned char * pmbr=NULL;
pmbr=ReadSector(mbr_drive,mbr_sector_start,mbr_sectors);
if(pmbr==NULL)
{
printf("Read error\n");
return -1;
}
if(argc==1)
{
printf("Read ok\n");
for(int i=0;i<16;i++)
{
printf("%02x ",pmbr[i]);
}
printf("\n");
}
const int MBR_BYTES = 446;
if(argc==2)
{
if(0==memcmp(argv[1],"/dump",5))
{
for(int i=0; i<MBR_BYTES; i++)
{
if (i%16==0) printf("\n");
printf("%02x ",pmbr[i]);
}
}
else if(0==memcmp(argv[1],"/fix",4))
{
unsigned char mbr_new[512];
int count = 0; // 446 hex byte expected
const int BUF_SIZE=2048;
char hexbuf[BUF_SIZE];
printf("\n/fix");
while(count<MBR_BYTES)
{
memset(hexbuf,0,BUF_SIZE);
gets(hexbuf);
char * phex=hexbuf;
// printf("\n[%s]",hexbuf);
printf("\n");
for(int i=0;i<16;i++)
{
unsigned int value;
int item=sscanf(phex,"%02x",&value);
if(item!=1)
break;
phex=phex+3;
printf("%02x ",value);
mbr_new[count]=value;
count++;
if(count >= MBR_BYTES)
break;
}
}
int diff = 0;
for(int i=0; i<MBR_BYTES; i++)
{
if(mbr_new[i]!=pmbr[i]) diff++;
}
if(diff!=0)
{
for(int i=0;i<MBR_BYTES; i++) pmbr[i]=mbr_new[i];
printf("\nneed write new mbr 446 bytes record into harddisk\n");
WriteSector(mbr_drive,mbr_sector_start,mbr_sectors,pmbr);
}
}
}
printf("\n");
if(hDevice!=NULL)
CloseHandle(hDevice);
if(pmbr)
free(pmbr);
return 0;
}
以下是 win32 console program , 用來備份 boot sector (446 bytes) , 和寫入 boot sector.
測試環境是用 vs2005 , project property 用 /MT (靜態連結,省得 RUN-TIME-DLL 版本問題)
,用 MBCS 字集.
----------------
// bootsec.cpp : /dump to backup current harddisk boot sector to hex file, /fix to restore from hex file
//
#include "stdafx.h"
HANDLE hDevice=NULL;
unsigned char * WriteSector(int drive, DWORD startinglogicalsector, int numberofsectors,unsigned char *buffer)
{
SetFilePointer (hDevice, (startinglogicalsector*512), NULL, FILE_BEGIN);
DWORD byteswrite=0;
BOOL ret=WriteFile(hDevice,buffer,512*numberofsectors,&byteswrite,NULL);
ret = FlushFileBuffers(hDevice);
return buffer;
}
unsigned char * ReadSector(int drive, DWORD startinglogicalsector, int numberofsectors)
{
// All msdos data structures must be packed on a 1 byte boundary
#pragma pack (1)
struct
{
DWORD StartingSector ;
WORD NumberOfSectors ;
DWORD pBuffer;
}ControlBlock;
#pragma pack ()
#pragma pack (1)
typedef struct _DIOC_REGISTERS
{
DWORD reg_EBX;
DWORD reg_EDX;
DWORD reg_ECX;
DWORD reg_EAX;
DWORD reg_EDI;
DWORD reg_ESI;
DWORD reg_Flags;
} DIOC_REGISTERS ;
#pragma pack ()
unsigned char* buffer = (unsigned char*)malloc (512*numberofsectors);
DIOC_REGISTERS reg ;
BOOL fResult ;
DWORD cb ;
// Creating handle to vwin32.vxd (win 9x)
hDevice = CreateFile ( "\\\\.\\vwin32",
0,
0,
NULL,
0,
FILE_FLAG_DELETE_ON_CLOSE,
NULL );
if ( hDevice == INVALID_HANDLE_VALUE )
{
// win 2k code
DWORD bytesread;
// Creating a handle to drive a: using CreateFile () function ..
char _devicename[] = "\\\\.\\A:";
_devicename[4] += drive;
hDevice = CreateFile(_devicename,
// GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
GENERIC_WRITE | GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, 0, NULL);
if (hDevice == INVALID_HANDLE_VALUE)
return NULL;
SetFilePointer (hDevice, (startinglogicalsector*512), NULL, FILE_BEGIN);
if (!ReadFile (hDevice, buffer, 512*numberofsectors, &bytesread, NULL) )
return NULL;
}
else
{
// code for win 95/98
ControlBlock.StartingSector = (DWORD)startinglogicalsector;
ControlBlock.NumberOfSectors = (DWORD)numberofsectors ;
ControlBlock.pBuffer = (DWORD)buffer ;
//-----------------------------------------------------------
// SI contains read/write mode flags
// SI=0h for read and SI=1h for write
// CX must be equal to ffffh for
// int 21h's 7305h extention
// DS:BX -> base addr of the
// control block structure
// DL must contain the drive number
// (01h=A:, 02h=B: etc)
//-----------------------------------------------------------
reg.reg_ESI = 0x00 ;
reg.reg_ECX = -1 ;
reg.reg_EBX = (DWORD)(&ControlBlock);
reg.reg_EDX = drive+1;
reg.reg_EAX = 0x7305 ;
// 6 == VWIN32_DIOC_DOS_DRIVEINFO
fResult = DeviceIoControl ( hDevice,
6,
&(reg),
sizeof (reg),
&(reg),
sizeof (reg),
&cb,
0);
if (!fResult || (reg.reg_Flags & 0x0001)) return NULL;
}
// CloseHandle(hDevice);
return buffer;
}
int _tmain(int argc, _TCHAR* argv[])
{
const int mbr_drive = 'C' - 'A';
const int mbr_sector_start = 0;
const int mbr_sectors = 1;
if(argc==1)
{
printf("\nmbr v002");
printf("\nmbr /dump > mbr.hex");
printf("\nmbr /fix < mbr.hex");
printf("\n");
}
unsigned char * pmbr=NULL;
pmbr=ReadSector(mbr_drive,mbr_sector_start,mbr_sectors);
if(pmbr==NULL)
{
printf("Read error\n");
return -1;
}
if(argc==1)
{
printf("Read ok\n");
for(int i=0;i<16;i++)
{
printf("%02x ",pmbr[i]);
}
printf("\n");
}
const int MBR_BYTES = 446;
if(argc==2)
{
if(0==memcmp(argv[1],"/dump",5))
{
for(int i=0; i<MBR_BYTES; i++)
{
if (i%16==0) printf("\n");
printf("%02x ",pmbr[i]);
}
}
else if(0==memcmp(argv[1],"/fix",4))
{
unsigned char mbr_new[512];
int count = 0; // 446 hex byte expected
const int BUF_SIZE=2048;
char hexbuf[BUF_SIZE];
printf("\n/fix");
while(count<MBR_BYTES)
{
memset(hexbuf,0,BUF_SIZE);
gets(hexbuf);
char * phex=hexbuf;
// printf("\n[%s]",hexbuf);
printf("\n");
for(int i=0;i<16;i++)
{
unsigned int value;
int item=sscanf(phex,"%02x",&value);
if(item!=1)
break;
phex=phex+3;
printf("%02x ",value);
mbr_new[count]=value;
count++;
if(count >= MBR_BYTES)
break;
}
}
int diff = 0;
for(int i=0; i<MBR_BYTES; i++)
{
if(mbr_new[i]!=pmbr[i]) diff++;
}
if(diff!=0)
{
for(int i=0;i<MBR_BYTES; i++) pmbr[i]=mbr_new[i];
printf("\nneed write new mbr 446 bytes record into harddisk\n");
WriteSector(mbr_drive,mbr_sector_start,mbr_sectors,pmbr);
}
}
}
printf("\n");
if(hDevice!=NULL)
CloseHandle(hDevice);
if(pmbr)
free(pmbr);
return 0;
}
標籤: MBR, READ/WRITE, SOURCE, xp