fseeko/ftello

gccベース?の場合は、fseeko/ftelloで、何となく動いてくれました。
Large File Support (LFS) うんたらかんたらといった記事をいくつか見付けましたが、
大半が数年前の内容で、今時、もしかしたら、当たり前の内容なのかもしれません。(^^;;;
該当関数を有効にするには、特別な#defineが必要であるみたいな記述もあったりしましたが、
色々と実験してみた結果、普通にコンパイルしても、全然問題なく動いてしまいました。


とりあえず、ヘッダ

//
//
//

typedef	unsigned char	BYTE;
typedef	int		UINT32;

//
// Master Boot Record
//

#pragma pack(1)

typedef struct _MasterBootRecord
{
	BYTE	code[440];
	BYTE	id[4];
	BYTE	unused[2];
	struct
	{
		BYTE	bootable;
		BYTE	firstSectorCHS[3];
		BYTE	type;
		BYTE	lastSectorCHS[3];
		UINT32	firstSectorLBA;
		UINT32	sectors;
	}
	partition[4];
	BYTE	signature[2];
}
MBR;

typedef struct _ExtendedBootRecord
{
	BYTE	reserved[446];
	struct
	{
		BYTE	bootable;
		BYTE	firstSectorCHS[3];
		BYTE	type;
		BYTE	lastSectorCHS[3];
		UINT32	firstSectorLBA;
		UINT32	sectors;
	}
	partition[4];
	BYTE	signature[2];
}
EBR;

#pragma pack(0)


ちょっとした定義

#define		BLOCK_SIZE		512

unsigned char	buff[BLOCK_SIZE];

MBR		curMBR;
EBR		curEBR;


ファイルのオープン

	FILE *	fp;
//	fp = fopen("\\\\.\\PHYSICALDRIVE0", "rb");		// ←OK
//	fp = fopen("\\Device\\Harddisk0\\Partition0", "rb");	// ←NG
	fp = fopen("/dev/sda", "rb");

Windowsの特殊ファイル名?も使える物があるようだが、全部ではないのかなぁ?
PHYSICALDRIVE0は、\Device\Harddisk0\Partition0のリンクだとかいう説明もあったけど、
何度か試してみた結果、手元の環境では、NGの模様。
また、当然かもしれないけれど、Unixのデバイスファイル形式でもオープン出来た。
Cygwin環境下では、この形式が、本来の形式と言うか、正統な形式のような感じ?


とりあえず、最初のセクタを読み込む

	int result;
	result = fread(buff, BLOCK_SIZE, 1, fp);

こいつがMBRなので、中身を見てみる。

bootable = 80
firstSectorCHS = 01, 01, 00
type = 7
lastSectorCHS  = FE, FF, FF
firstSectorLBA = 0000003F
sectors        = 03C02ECE

bootable = 00
firstSectorCHS = 00, C1, FF
type = 15
lastSectorCHS  = FE, FF, FF
firstSectorLBA = 03C02F0D
sectors        = 059076F3

bootable = 00
firstSectorCHS = 00, 00, 00
type = 0
lastSectorCHS  = 00, 00, 00
firstSectorLBA = 00000000
sectors        = 00000000

bootable = 00
firstSectorCHS = 00, 00, 00
type = 0
lastSectorCHS  = 00, 00, 00
firstSectorLBA = 00000000
sectors        = 00000000

ここまでは、前にもやった。


問題は、ここから。
二番目のパーティションは、拡張領域で、先頭のセクタは、0x03C02F0D(62,926,605)。
シークはバイト単位だから、これにブロックサイズの512を掛けると、32bitをオーバーしてしまう。
なので、こうする。

	result = fseeko(fp, (off_t) curMBR.partition[1].firstSectorLBA * 512, SEEK_SET);
	printf("seek result = %d\n", result);
	off_t pos;
	pos = ftello(fp);
	printf("tell result = %016llX\n", pos);

結果

seek result = 0
tell result = 00000007805E1A00

OK!!


で、ここには、EBRが存在するはずなので、中身を見てみると...

bootable = 00
firstSectorCHS = 01, C1, FF
type = 7
lastSectorCHS  = FE, FF, FF
firstSectorLBA = 0000003F
sectors        = 059076B4

bootable = 00
firstSectorCHS = 00, 00, 00
type = 0
lastSectorCHS  = 00, 00, 00
firstSectorLBA = 00000000
sectors        = 00000000

ばっちりですね。