[StructLayout(LayoutKind.Sequential)]
struct RAROpenArchiveDataEx
{
	[MarshalAs(UnmanagedType.LPStr)]
	public string ArcName;
	[MarshalAs(UnmanagedType.LPWStr)]
	public string ArcNameW;
	public OpenMode OpenMode;
	public ReturnCode OpenResult;
	[MarshalAs(UnmanagedType.LPStr)]
	public string CmtBuf;
	private int CmtBufSize;
	private int CmtSize;
	public CmtState CmtState;
	public ArchiveFlag Flags;
	public IntPtr Callback;
	public IntPtr UserData;
	[MarshalAs(UnmanagedType.ByValArray, SizeConst = 28)]
	private uint[] Reserved;

	public void SetCommentBuffer(bool reqComment)
	{
		if (reqComment)
		{
			int bufSize = 64 * 1024;
			CmtBuf = new string('\0', bufSize);
			CmtBufSize = bufSize;
		}
		else
		{
			CmtBuf = null;
			CmtBufSize = 0;
		}
	}
}

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
struct RARHeaderDataEx
{
	[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 1024 / 2)]
	private string ArcName;
	[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 1024)]
	public readonly string ArcNameW;
	[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 1024 / 2)]
	private string FileName;
	[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 1024)]
	public readonly string FileNameW;
	private uint FlagBits;
	private uint PackSizeLow;
	private uint PackSizeHigh;
	private uint UnpSizeLow;
	private uint UnpSizeHigh;
	public readonly HostOS HostOS;
	public readonly uint FileCRC;
	private uint MsDosFileTime;
	public readonly uint UnpackVer;
	public readonly Method Method;
	public readonly FileAttributes FileAttr;
	[MarshalAs(UnmanagedType.LPStr)]
	private string CmtBuf;
	private int CmtBufSize;
	private int CmtSize;
	private CmtState CmtState;
	[MarshalAs(UnmanagedType.ByValArray, SizeConst = 1024)]
	private uint[] Reserved;

	public FileFlag Flag { get { return (FileFlag)(FlagBits & 0x1F); } }	//uint dicSizeBits = (FlagBits & 0xE0);
	public long PackSize { get { return (PackSizeHigh * (uint.MaxValue + 1L) + PackSizeLow); } }
	public long UnpackSize { get { return (UnpSizeHigh * (uint.MaxValue + 1L) + UnpSizeLow); } }
	public DateTime FileTimeLocal { get; private set; }

	public void SetCommentBuffer()
	{
		CmtBuf = null;
		CmtBufSize = 0;
	}

	public void DosDateTimeToFileTime()
	{
		//参考	http://msdn.microsoft.com/ja-jp/library/cc429703.aspx

		uint fatDate = ((MsDosFileTime >> 16) & 0xFFFF);
		uint fatTime = (MsDosFileTime & 0xFFFF);

		//bit15-9:year(+1980), bit8-5:month, bit4-0:day
		int day = (int)(fatDate & 0x1F); fatDate >>= 5;
		int month = (int)(fatDate & 0x0F); fatDate >>= 4;
		int year = (int)(fatDate & 0x7F) + 1980;

		//bit15-11:hour{00-23}, bit10-5:minute{00-59}, bit4-0:second{00-29}(*2)
		int second = (int)(fatTime & 0x1F) * 2; fatTime >>= 5;
		int minute = (int)(fatTime & 0x3F); fatTime >>= 6;
		int hour = (int)(fatTime & 0x1F);

		//MsDosFileTimeにはローカル時刻が格納されている
		//MS-DOS形式のタイムスタンプの仕様上、2秒の誤差が出る場合がある
		FileTimeLocal = new DateTime(year, month, day, hour, minute, second, DateTimeKind.Local);
	}
}