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
ばっちりですね。