前提・実現したいこと
C#よりDLL(C++)を使用し、グローバルフック (HCBT_XXXX&WM_XXXX)をおこないたい
ここに質問の内容を詳しく書いてください。
C#より32Bitで作成されたDLL(C++)を呼び出す処理を作成し32Bit上では動作しますが、
64Bit上で正常に動作しません。
OS 呼出EXE 呼出先EXE DLL
32BitOS 32BitEXE 32BitEXE 32BitDLL OK
64BitOS 32BitEXE 32BitEXE 32BitDLL OK
64BitOS 64BitEXE 64BitEXE 64BitDLL NG
グローバルフックの機能としては、フック対象のEXEの移動および終了を禁止します。
フックのメッセージをSPY++でメッセージを確認したところ、
メッセージ自体は相手のプロセスが受信し、SetWindowsHookExの結果を返却後、
相手側プロセスが落ちてしまいます。
32Bit上では動作しているので、なんらかの個所が正しく64Bit化できていないのだと
思いますがわかりません。
よろしくお願いします。
### 該当のソースコード
◆◆◆DLL側(C++)1個目◆◆
(HCBTフック)
#define STRICT #include <windows.h> #define DllExport __declspec( dllexport ) void __stdcall MB(LPCTSTR str); DllExport bool CALLBACK CloseHook64(HWND); DllExport bool CALLBACK UnCloseHook64(void); #pragma data_seg("share") HHOOK hHookWnd = NULL; HINSTANCE hdll = NULL; HWND hTarget = NULL; #pragma data_seg() LRESULT CALLBACK CallWndProc(int nCode,WPARAM wParam,LPARAM lParam) { if (nCode >= 0) { switch (nCode) { case HCBT_MINMAX: case HCBT_MOVESIZE: case HCBT_DESTROYWND://ウインドウの閉じるを禁止 { if((HWND)wParam==hTarget) { return 1; break; } } } } return CallNextHookEx(hHookWnd, nCode, wParam, lParam); //次のフックを呼ぶ } // フックを組み込む bool CALLBACK CloseHook64(HWND HandleofTarget) { if(hdll == NULL) return false; hTarget = HandleofTarget; hHookWnd = SetWindowsHookEx(WH_CBT,(HOOKPROC)CallWndProc, hdll, 0); if(hHookWnd == NULL) { return false; } else { return true; } } // フックを解除する bool CALLBACK UnCloseHook64(void) { int ans = UnhookWindowsHookEx(hHookWnd); hHookWnd = NULL; if(ans == 0) { return false; } else { return true; } }
◆◆◆DLL側(C++)2個目◆◆
(WM系フック)
#define STRICT #include <windows.h> #define DllExport __declspec( dllexport ) void __stdcall MB(LPCTSTR str); #define pCW ((CWPSTRUCT*)lParam) DllExport bool CALLBACK MoveHook64(HWND); DllExport bool CALLBACK UnMoveHook64(void); LRESULT CALLBACK NewProc( HWND,UINT,WPARAM,LPARAM ); #pragma data_seg("share") HHOOK hHookWnd = NULL; HINSTANCE hdll = NULL; HWND hTarget = NULL; int g_bSubclassed = 0; UINT WM_HOOKEX = 0; WNDPROC OldProc = NULL; #pragma data_seg() LRESULT CALLBACK NewProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { switch(message) { case WM_CLOSE: // ウインドウあるいはアプリケーションをクローズされた case WM_DESTROY: // ウインドウが破棄された case WM_SIZE: // ウインドウのサイズが変更(マウス操作) case WM_MOVE: // ウインドウが移動した { return 1; break; } case WM_MOVING: // リサイズ中にウィンドウに送られる(マウス操作) case WM_ENTERSIZEMOVE: // ウィンドウが移動・サイズ変更した(マウス操作) case WM_EXITSIZEMOVE: // ウィンドウの移動・サイズ変更の処理が終了したとき(マウス操作) { return 1; break; } case WM_SYSCOMMAND: { //右上のボタン系 switch (wParam & 0xFFF0) { case SC_CLOSE: { return 1; break; } case SC_MOVE: { return 1; break; } case SC_MAXIMIZE: { return 1; break; } case SC_MINIMIZE: { return 1; break; } case SC_RESTORE: { return 1; break; } case SC_SIZE: { return 1; break; } } } } return CallWindowProc(OldProc, hwnd, message, wParam, lParam); } LRESULT CALLBACK HookProc(int code, WPARAM wParam, LPARAM lParam) { if( (pCW->message == WM_HOOKEX) && pCW->lParam ) { ::UnhookWindowsHookEx( hHookWnd ); if( g_bSubclassed ) goto END; TCHAR lib_name[MAX_PATH]; ::GetModuleFileName( hdll, lib_name, MAX_PATH ); if( !::LoadLibrary( lib_name ) ) goto END; //32Bit //OldProc = (WNDPROC)(LONG_PTR)::SetWindowLongPtr( hTarget, GWL_WNDPROC, (__int3264)(LONG_PTR)NewProc ); //64Bit OldProc = (WNDPROC)::SetWindowLongPtr(hTarget, GWLP_WNDPROC, (LONG)NewProc); if( OldProc==NULL )::FreeLibrary( hdll ); else { ::MessageBeep(MB_OK); g_bSubclassed = true; } } else if( pCW->message == WM_HOOKEX ) { ::UnhookWindowsHookEx( hHookWnd ); //32 //if( !SetWindowLongPtr( hTarget, GWL_WNDPROC, (__int3264)(LONG_PTR)OldProc ) ) //64Bit if( !SetWindowLongPtr( hTarget, GWLP_WNDPROC, (LONG)OldProc ) ) goto END; ::FreeLibrary( hdll ); ::MessageBeep(MB_OK); g_bSubclassed = false; } END: return ::CallNextHookEx(hHookWnd, code, wParam, lParam); } // フックを組み込む bool CALLBACK MoveHook64(HWND HandleofTarget) { if(hdll == NULL) return false; hTarget = HandleofTarget; hHookWnd = SetWindowsHookEx( WH_CALLWNDPROC,(HOOKPROC)HookProc, hdll, GetWindowThreadProcessId(HandleofTarget,NULL) ); if( hHookWnd==NULL ) { return false; } else { SendMessage( HandleofTarget,WM_HOOKEX,0,1 ); return true; } } // フックを解除する bool CALLBACK UnMoveHook64(void) { hHookWnd = SetWindowsHookEx( WH_CALLWNDPROC,(HOOKPROC)HookProc, hdll, GetWindowThreadProcessId(hTarget,NULL) ); if( hHookWnd == NULL ) { return false; } else { hHookWnd = NULL; SendMessage( hTarget,WM_HOOKEX,0,0 ); return (g_bSubclassed == NULL); } }
◆◆◆EXE側(C#)◆◆
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Runtime.InteropServices; using System.Windows.Forms; namespace Hook64 { class Program { [DllImport("CloseHook64.dll")] private extern static bool CloseHook64(IntPtr hWnd); [DllImport("MoveHook64.dll")] private extern static bool MoveHook64(IntPtr hWnd); static void Main(string[] args) { if (args.Length == 0) { Environment.ExitCode = 100; return; } else if (args.Length == 1) { try { //32 //IntPtr handle = (IntPtr)Convert.ToInt32(args[0]); //64 Int64 val = 0; if (Int64.TryParse(args[0], out val)) { IntPtr handle = (IntPtr)val; if (!CloseHook64(handle)) { Environment.ExitCode = 101; return; } if (!MoveHook64(handle)) { Environment.ExitCode = 102; return; } } } catch (Exception Ex) { Environment.ExitCode = 255; MessageBox.Show(Ex.Message); return; } } else if (args.Length > 1) { Environment.ExitCode = 104; return; } //処理成功 Environment.ExitCode = 0; } } }
補足情報(FW/ツールのバージョンなど)
Microsoft Visual C# 2010 01018-532-2002102-70943 .NET3.5
Microsoft Visual C++ 2010 01018-532-2002102-70943

回答3件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/08/21 01:11