httpgrab.cpp 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. #include "main.h"
  2. #include "./httpgrab.h"
  3. static HHOOK g_hook = NULL;
  4. static HWND g_hook_host = NULL;
  5. static HWND g_hook_fwd = NULL;
  6. static DWORD g_hook_flags = 0;
  7. static HWND *g_hook_phwnd =NULL;
  8. static LRESULT CALLBACK TargetWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  9. static LRESULT CALLBACK LabelWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  10. static BOOL IsDialog(HWND hwnd)
  11. {
  12. wchar_t szName[256] = {0};
  13. return (GetClassNameW(hwnd, szName, sizeof(szName)/sizeof(wchar_t)) &&
  14. CSTR_EQUAL == CompareStringW(MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT),
  15. NORM_IGNORECASE, szName, -1, L"#32770", -1));
  16. }
  17. static LRESULT CALLBACK HookProc(int code, WPARAM wParam, LPARAM lParam)
  18. {
  19. if (HCBT_CREATEWND == code && IsDialog((HWND)wParam) && ((CBT_CREATEWND*)lParam)->lpcs->hwndParent == g_hook_host)
  20. {
  21. LRESULT result;
  22. result = CallNextHookEx(g_hook, code, wParam, lParam);
  23. UnhookWindowsHookEx(g_hook);
  24. g_hook = NULL;
  25. if (0 == result)
  26. {
  27. ((CBT_CREATEWND*)lParam)->lpcs->style &= ~WS_VISIBLE;
  28. WNDPROC oldProc = (WNDPROC)SetWindowLongPtrW((HWND)wParam, GWLP_WNDPROC, (LONG_PTR)TargetWndProc);
  29. if (oldProc)
  30. {
  31. SetPropW((HWND)wParam, L"WNDPROC", oldProc);
  32. if (g_hook_fwd) SetPropW((HWND)wParam, L"FWDHWND", g_hook_fwd);
  33. if (g_hook_flags) SetPropW((HWND)wParam, L"FLAGS", (HANDLE)(INT_PTR)g_hook_flags);
  34. if (g_hook_phwnd) *g_hook_phwnd = (HWND)wParam;
  35. }
  36. }
  37. else if (g_hook_host && IsWindow(g_hook_host)) DestroyWindow(g_hook_host);
  38. g_hook_fwd = NULL;
  39. g_hook_flags = 0;
  40. g_hook_host = NULL;
  41. return result;
  42. }
  43. return CallNextHookEx(g_hook, code, wParam, lParam);
  44. }
  45. HWND BeginGrabHTTPText(HWND hwndFwd, UINT flags, HWND *phwndTarget)
  46. {
  47. g_hook_host = CreateWindowExW(0x08000000/*WS_EX_NOACTIVATE*/ | WS_EX_NOPARENTNOTIFY, L"STATIC", L"", WS_DISABLED | WS_POPUP, -10000, -10000, 0, 0, NULL, NULL, NULL, NULL);
  48. if (!g_hook_host) return NULL;
  49. g_hook = SetWindowsHookEx(WH_CBT, HookProc, NULL, GetCurrentThreadId());
  50. if (!g_hook)
  51. {
  52. if (g_hook_host) DestroyWindow(g_hook_host);
  53. g_hook_host = NULL;
  54. g_hook_fwd = NULL;
  55. g_hook_flags = 0;
  56. g_hook_phwnd = NULL;
  57. }
  58. else
  59. {
  60. g_hook_fwd = hwndFwd;
  61. g_hook_flags = flags;
  62. g_hook_phwnd = phwndTarget;
  63. }
  64. return g_hook_host;
  65. }
  66. void EndGrabHTTPText(HWND hwndHost)
  67. {
  68. if (g_hook_host == hwndHost)
  69. {
  70. if (g_hook) UnhookWindowsHookEx(g_hook);
  71. g_hook = NULL;
  72. g_hook_host = NULL;
  73. g_hook_fwd = NULL;
  74. g_hook_flags = 0;
  75. }
  76. if (IsWindow(hwndHost)) DestroyWindow(hwndHost);
  77. }
  78. static LRESULT CALLBACK TargetWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  79. {
  80. WNDPROC fnOldProc = (WNDPROC)GetPropW(hwnd, L"WNDPROC");
  81. switch(uMsg)
  82. {
  83. case WM_INITDIALOG:
  84. {
  85. HWND hwndFwd;
  86. hwndFwd = (HWND)GetPropW(hwnd, L"FWDHWND");
  87. DWORD flags = (DWORD)(INT_PTR)GetPropW(hwnd, L"FLAGS");
  88. RemovePropW(hwnd, L"FLAGS");
  89. RemovePropW(hwnd, L"FWDHWND");
  90. if (hwndFwd)
  91. {
  92. HWND hwndText;
  93. if (HTTPGRAB_USESTATUSTEXT & flags)
  94. {
  95. hwndText = GetDlgItem(hwnd, 1180/*IDC_STATUS*/);
  96. WNDPROC oldProc = (WNDPROC)SetWindowLongPtrW(hwndText, GWLP_WNDPROC, (LONG_PTR)LabelWndProc);
  97. if (oldProc) SetPropW(hwndText, L"WNDPROC", oldProc);
  98. else hwndText = hwnd;
  99. }
  100. else hwndText = hwnd;
  101. SetPropW(hwndText, L"FWDTEXT", hwndFwd);
  102. WCHAR szText[256] = {0};
  103. GetWindowTextW(hwndText, szText, sizeof(szText)/sizeof(wchar_t));
  104. SetWindowTextW(hwndFwd, szText);
  105. }
  106. }
  107. break;
  108. case WM_DESTROY:
  109. {
  110. RemovePropW(hwnd, L"WNDPROC");
  111. RemovePropW(hwnd, L"FWDTEXT");
  112. if (fnOldProc) SetWindowLongPtrW(hwnd, GWLP_WNDPROC, (LONG_PTR)fnOldProc);
  113. HWND hwndOwner;
  114. hwndOwner = GetWindow(hwnd, GW_OWNER);
  115. if (hwndOwner) DestroyWindow(hwndOwner);
  116. }
  117. break;
  118. case WM_STYLECHANGING:
  119. if (GWL_STYLE & wParam) ((STYLESTRUCT*)lParam)->styleNew &= ~WS_VISIBLE;
  120. return 0;
  121. case WM_STYLECHANGED:
  122. if ((GWL_STYLE & wParam) && (WS_VISIBLE & ((STYLESTRUCT*)lParam)->styleNew))
  123. SetWindowLongPtrW(hwnd, GWL_STYLE, (((STYLESTRUCT*)lParam)->styleNew & ~WS_VISIBLE));
  124. return 0;
  125. case WM_WINDOWPOSCHANGING:
  126. ((WINDOWPOS*)lParam)->flags = (((WINDOWPOS*)lParam)->flags & ~(SWP_SHOWWINDOW | SWP_FRAMECHANGED)) | SWP_NOACTIVATE | SWP_NOZORDER;
  127. return 0;
  128. case WM_SETTEXT:
  129. {
  130. HWND hwndFwd = (HWND)GetPropW(hwnd, L"FWDTEXT");
  131. if (hwndFwd)
  132. {
  133. (IsWindowUnicode(hwndFwd)) ? SendMessageW(hwndFwd, WM_SETTEXT, wParam, lParam) :
  134. SendMessageA(hwndFwd, WM_SETTEXT, wParam, lParam);
  135. }
  136. }
  137. break;
  138. }
  139. if (!fnOldProc) return DefWindowProc(hwnd, uMsg, wParam, lParam);
  140. return (IsWindowUnicode(hwnd)) ? CallWindowProcW(fnOldProc, hwnd, uMsg, wParam, lParam) : CallWindowProcA(fnOldProc, hwnd, uMsg, wParam, lParam);
  141. }
  142. static LRESULT CALLBACK LabelWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  143. {
  144. WNDPROC fnOldProc = (WNDPROC)GetPropW(hwnd, L"WNDPROC");
  145. switch(uMsg)
  146. {
  147. case WM_SETTEXT:
  148. {
  149. HWND hwndFwd = (HWND)GetPropW(hwnd, L"FWDTEXT");
  150. if (hwndFwd)
  151. {
  152. (IsWindowUnicode(hwndFwd)) ? SendMessageW(hwndFwd, WM_SETTEXT, wParam, lParam) :
  153. SendMessageA(hwndFwd, WM_SETTEXT, wParam, lParam);
  154. }
  155. }
  156. case WM_DESTROY:
  157. RemovePropW(hwnd, L"WNDPROC");
  158. RemovePropW(hwnd, L"FWDTEXT");
  159. if (fnOldProc) SetWindowLongPtrW(hwnd, GWLP_WNDPROC, (LONG_PTR)fnOldProc);
  160. break;
  161. }
  162. if (!fnOldProc) return DefWindowProc(hwnd, uMsg, wParam, lParam);
  163. return (IsWindowUnicode(hwnd)) ? CallWindowProcW(fnOldProc, hwnd, uMsg, wParam, lParam) : CallWindowProcA(fnOldProc, hwnd, uMsg, wParam, lParam);
  164. }