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