ISO 9660 ディレクトリレコード
構造としては、こんな感じになるわけだけど...
// // Directory Record // (ディレクトリレコード) // typedef struct ISO_DR_t { uint8 Length; // [0000] このディレクトリのデータ長 uint8 ExtLength; // [0001] 拡張属性レコードのデータ長 uint32 LocationL; // [0002] エクステントの位置 uint32 LocationB; // [0006] エクステントの位置 uint32 DataLengthL; // [0010] データ長 uint32 DataLengthB; // [0014] データ長 ISO9660_DateTimeShort RecordingDateTime; // [0018] 記録日時 byte FileFlags; // [0025] ファイルフラグ uint8 FileUnitSize; // [0026] ファイルユニットサイズ uint8 InterleaveGapSize; // [0027] インターリーブギャップサイズ } ISO_DR;
先頭に8bit長の要素が2つで2Byte。
その次に32bit長のデータが続くわけで...
アラインメントが4Byteであれば、
当然、2Byteのパディングが挟まれて、
LocationLは、4Byte境界に配置されてしまうと...
これが、16bitCPUであれば、多分、問題なかったんだろうけど、
32bit以上のCPUだと、ちと辛い事になりそうな...
まぁ、とにかく、このままでは、意図した通りに動かないわけで、
何とかしなくてはいけないんだけど、規格の方が悪い気もしなくもない。
面倒な話だ。
とりあえず、
__attribute__(( aligned(2), packed ))
を指定して、期待通りの結果を得た。
が... これって、きっと、gcc系のコンパイラしか通用しないんじゃないかな?
もっと一般的な方法を考えないといけないかもしれない。
皆さん、どうやって対処しているのかな?
後でmkisofsとかのソースを覗いてみようかな?
と思ったら、EL TORITO のブートレコードなんて、こんなだ!!
typedef struct ELTORITO_BRVD_t { ISO_VDH header; // [0000] Type = 0 astr BootSystemIdentifier[32]; // [0007] 起動システム識別子 [Any] astr BootIdentifier[32]; // [0039] 起動識別子 [Any] dword BootCatalogPtr; // [0071] ブートカタログへのポインタ }
ISO_VDH が7バイトってのが、そもそも問題のような気がするけど、
パディングも無しに、文字列領域が、微妙にアラインメントを意識したサイズで続いて、
最後に32bit整数が置かれている。
これだと2Byteアラインメントでも無理だ〜。
仕方ないから、1Byteアラインメントでパックするって事になるのかなぁ... 嫌じゃ〜 (T_T