tagCANDY CGI VBレスキュー(花ちゃん) の Visual Basic 2010 用 掲示板(VB.NET 掲示板)
VBレスキュー(花ちゃん) の Visual Basic 2010 用 掲示板(VB.NET 掲示板)
[ツリー表示へ]  [ワード検索]  [Home]

タイトル unlha32のコールバックを受け取った時の構造体がおかしい?
投稿日: 2011/02/05(Sat) 20:41
投稿者A.K
こんにちは。
前回 http://hanatyan.sakura.ne.jp/vbnetbbs/wforum.cgi?no=10429&reno=no&oya=10429&mode=msgview&page=0
に引き続きの質問で申し訳ないのですが、どうにもよく分からないので質問させて下さい。

前回の質問のソースコードで、UnlhaSetOwnerWindowEx64を使用したコールバックの設定を行いました。
そこで、書庫を解凍する際のコールバックを受け取るために、下記のようなコードを書きました。
(unlhaが返すWM_ARCEXTRACTの値は、あらかじめRegisterWindowMessageで取得済みです)

Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
    MyBase.WndProc(m)

    If m.HWnd = _HWnd Then
        If m.Msg = wm_arcextractMsg AndAlso m.WParam.ToInt64 = 1 Then
            'mode=1:解凍処理
            Dim extractingInfo As New EXTRACTINGINFO64
            Dim typeHandle As System.RuntimeTypeHandle = System.Type.GetTypeHandle(extractingInfo)
            Dim extractingInfoType As Type = Type.GetTypeFromHandle(typeHandle)

            '構造体の取得
            extractingInfo = DirectCast(Marshal.PtrToStructure(m.LParam, extractingInfoType), EXTRACTINGINFO64)

            Debug.Print("SourceFileName : " & extractingInfo.szSourceFileName)
            Debug.Print("DestFileName : " & extractingInfo.szDestFileName)

            Debug.Print("FileSize : " & extractingInfo.llFileSize.ToString)
            Debug.Print("WriteSize : " & extractingInfo.llWriteSize.ToString)

        End If
    End If
End Sub

すると、ファイルサイズがあり得ない程大きくなっていたり、ファイル名の文字が欠けていたりと、extractingInfo構造体から得られる値がおかしくなっていました。
ファイル名の文字は、例えば本来は「あいうえお.jpg」であるべきところ、「うえお.jpg」と戻ってきていたため、「もしかしたら、読み出し位置が32ビット分ずれているのでは?」と思い、EXTRACTINGINFO64の宣言を以下のように書き換えてみたところ、ファイル名・サイズ等の情報が正常に得られるようになりました。

    <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Ansi, Pack:=1)> _
      Public Structure EXTRACTINGINFO64
'        Public dwStructSize As Integer  ←ここをコメントアウトした
        Public exinfo As EXTRACTINGINFO
        Public llFileSize As Long
        Public llCompressedSize As Long
        Public llWriteSize As Long
        Public dwAttributes As Integer
        Public dwCRC As Integer
        Public uOSType As Integer
        Public wRatio As Short
        Public ftCreateTime As Long
        Public ftAccessTime As Long
        Public ftWriteTime As Long
        <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=8)> _
           Public szMode As String
        <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=513)> _
           Public szSourceFileName As String
        <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=3)> _
           Public dummy1 As String
        <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=513)> _
           Public szDestFileName As String
        <MarshalAs(UnmanagedType.ByValTStr, SizeConst:=3)> _
           Public dummy As String
    End Structure

これはコールバックを受け取るフォーム側での宣言です。
UnlhaSetOwnerWindowEx64を呼び出す側のクラスでは、コメントアウトを行わないで構造体宣言を行っています

つまり、現在
○unlha32を使って解凍処理を行うクラス
 EXTRACTINGINFO64の構造を変えずに宣言
 UnlhaSetOwnerWindowEx64を使用
○unlha32のコールバックを受け取るFormクラス
 EXTRACTINGINFO64の構造を変えて宣言(32バイト切り詰め)

という状態にして、ようやく正常に動いている状態です。(これを正常と言えるならですが…)
現状問題ないとはいえ、EXTRACTINGINFO64の宣言が二つあって統一されていないのは気持ち悪いですし、どこか私の方法が間違えているなら直しておきたいです。

当方WinXP、VB2005です。
よろしくお願いします。
どなたか、分かる方がいらっしゃいましたら、よろしくお願いします。



〜UNLHA32 WINMES.TXTより〜
-----------------------------------------------------------------------
%3. ARCHIVERPROC の定義
-----------------------------------------------------------------------

-----------------------------------------------------------------------
BOOL CALLBACK ARCHIVERPROC(
                          HWND    _hwnd,
                          UINT    _uMsg,
                          UINT    _nState,
                          LPVOID  _lpEis
                      );
-----------------------------------------------------------------------

引数
        _hwnd           UnlhaSetOwnerWindowEx で指定したウィンドウハンド
                        ルが渡されます。
        _uMsg           現在のところは wm_arcextract となります。
        _nState         wm_arcextract の wParam,つまり nMode が格納され
                        ます。
        _lpEis          構造体へのポインタです。格納ファイルに関する情報
                        が得られます。実際には,次のどれかとなります。

            LPEXTRACTINGINFOEX _lpEis
                    UnlhaSetOwnerWindowEx() か  sizeof(EXTRACTINGINFOEX)
                    を指定して UnlhaSetOwnerWindowEx64() を使用した場合。
            LPEXTRACTINGINFOEX32 _lpEis
                    sizeof(EXTRACTINGINFOEX32) を指定して UnlhaSetOwner-
                    WindowEx64() を使用した場合。
            LPEXTRACTINGINFOEX64 _lpEis
                    sizeof(EXTRACTINGINFOEX64) を指定して UnlhaSetOwner-
                    WindowEx64() を使用した場合。

戻り値
        TRUE            UNLHA32.DLL に処理の継続を指示します。
        FALSE           UNLHA32.DLL に処理を中止させます。 ただし,
                        _nState が 4  の場合 (作業書庫の書き戻し時) は中
                        止させることができません。

- 関連一覧ツリー をクリックするとツリー全体を一括表示します)

古いスレッドにレスはつけられません。