aboutsummaryrefslogtreecommitdiff
path: root/Src/Winamp/setup/httpgrab.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Src/Winamp/setup/httpgrab.cpp')
-rw-r--r--Src/Winamp/setup/httpgrab.cpp183
1 files changed, 183 insertions, 0 deletions
diff --git a/Src/Winamp/setup/httpgrab.cpp b/Src/Winamp/setup/httpgrab.cpp
new file mode 100644
index 00000000..6f45914a
--- /dev/null
+++ b/Src/Winamp/setup/httpgrab.cpp
@@ -0,0 +1,183 @@
+#include "main.h"
+#include "./httpgrab.h"
+
+
+static HHOOK g_hook = NULL;
+static HWND g_hook_host = NULL;
+static HWND g_hook_fwd = NULL;
+static DWORD g_hook_flags = 0;
+static HWND *g_hook_phwnd =NULL;
+
+static LRESULT CALLBACK TargetWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
+static LRESULT CALLBACK LabelWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
+
+static BOOL IsDialog(HWND hwnd)
+{
+ wchar_t szName[256] = {0};
+ return (GetClassNameW(hwnd, szName, sizeof(szName)/sizeof(wchar_t)) &&
+ CSTR_EQUAL == CompareStringW(MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT),
+ NORM_IGNORECASE, szName, -1, L"#32770", -1));
+}
+
+static LRESULT CALLBACK HookProc(int code, WPARAM wParam, LPARAM lParam)
+{
+ if (HCBT_CREATEWND == code && IsDialog((HWND)wParam) && ((CBT_CREATEWND*)lParam)->lpcs->hwndParent == g_hook_host)
+ {
+ LRESULT result;
+
+ result = CallNextHookEx(g_hook, code, wParam, lParam);
+ UnhookWindowsHookEx(g_hook);
+ g_hook = NULL;
+
+ if (0 == result)
+ {
+ ((CBT_CREATEWND*)lParam)->lpcs->style &= ~WS_VISIBLE;
+ WNDPROC oldProc = (WNDPROC)SetWindowLongPtrW((HWND)wParam, GWLP_WNDPROC, (LONG_PTR)TargetWndProc);
+ if (oldProc)
+ {
+ SetPropW((HWND)wParam, L"WNDPROC", oldProc);
+ if (g_hook_fwd) SetPropW((HWND)wParam, L"FWDHWND", g_hook_fwd);
+ if (g_hook_flags) SetPropW((HWND)wParam, L"FLAGS", (HANDLE)(INT_PTR)g_hook_flags);
+ if (g_hook_phwnd) *g_hook_phwnd = (HWND)wParam;
+ }
+ }
+ else if (g_hook_host && IsWindow(g_hook_host)) DestroyWindow(g_hook_host);
+
+ g_hook_fwd = NULL;
+ g_hook_flags = 0;
+ g_hook_host = NULL;
+ return result;
+ }
+ return CallNextHookEx(g_hook, code, wParam, lParam);
+}
+
+HWND BeginGrabHTTPText(HWND hwndFwd, UINT flags, HWND *phwndTarget)
+{
+
+ 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);
+ if (!g_hook_host) return NULL;
+
+ g_hook = SetWindowsHookEx(WH_CBT, HookProc, NULL, GetCurrentThreadId());
+ if (!g_hook)
+ {
+ if (g_hook_host) DestroyWindow(g_hook_host);
+ g_hook_host = NULL;
+ g_hook_fwd = NULL;
+ g_hook_flags = 0;
+ g_hook_phwnd = NULL;
+ }
+ else
+ {
+ g_hook_fwd = hwndFwd;
+ g_hook_flags = flags;
+ g_hook_phwnd = phwndTarget;
+ }
+ return g_hook_host;
+}
+
+void EndGrabHTTPText(HWND hwndHost)
+{
+ if (g_hook_host == hwndHost)
+ {
+ if (g_hook) UnhookWindowsHookEx(g_hook);
+ g_hook = NULL;
+ g_hook_host = NULL;
+ g_hook_fwd = NULL;
+ g_hook_flags = 0;
+ }
+ if (IsWindow(hwndHost)) DestroyWindow(hwndHost);
+}
+
+static LRESULT CALLBACK TargetWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ WNDPROC fnOldProc = (WNDPROC)GetPropW(hwnd, L"WNDPROC");
+
+ switch(uMsg)
+ {
+ case WM_INITDIALOG:
+ {
+ HWND hwndFwd;
+
+ hwndFwd = (HWND)GetPropW(hwnd, L"FWDHWND");
+ DWORD flags = (DWORD)(INT_PTR)GetPropW(hwnd, L"FLAGS");
+ RemovePropW(hwnd, L"FLAGS");
+ RemovePropW(hwnd, L"FWDHWND");
+
+ if (hwndFwd)
+ {
+ HWND hwndText;
+ if (HTTPGRAB_USESTATUSTEXT & flags)
+ {
+ hwndText = GetDlgItem(hwnd, 1180/*IDC_STATUS*/);
+ WNDPROC oldProc = (WNDPROC)SetWindowLongPtrW(hwndText, GWLP_WNDPROC, (LONG_PTR)LabelWndProc);
+ if (oldProc) SetPropW(hwndText, L"WNDPROC", oldProc);
+ else hwndText = hwnd;
+ }
+ else hwndText = hwnd;
+ SetPropW(hwndText, L"FWDTEXT", hwndFwd);
+
+ WCHAR szText[256] = {0};
+ GetWindowTextW(hwndText, szText, sizeof(szText)/sizeof(wchar_t));
+ SetWindowTextW(hwndFwd, szText);
+ }
+ }
+ break;
+ case WM_DESTROY:
+ {
+ RemovePropW(hwnd, L"WNDPROC");
+ RemovePropW(hwnd, L"FWDTEXT");
+ if (fnOldProc) SetWindowLongPtrW(hwnd, GWLP_WNDPROC, (LONG_PTR)fnOldProc);
+ HWND hwndOwner;
+ hwndOwner = GetWindow(hwnd, GW_OWNER);
+ if (hwndOwner) DestroyWindow(hwndOwner);
+ }
+ break;
+ case WM_STYLECHANGING:
+ if (GWL_STYLE & wParam) ((STYLESTRUCT*)lParam)->styleNew &= ~WS_VISIBLE;
+ return 0;
+ case WM_STYLECHANGED:
+ if ((GWL_STYLE & wParam) && (WS_VISIBLE & ((STYLESTRUCT*)lParam)->styleNew))
+ SetWindowLongPtrW(hwnd, GWL_STYLE, (((STYLESTRUCT*)lParam)->styleNew & ~WS_VISIBLE));
+ return 0;
+ case WM_WINDOWPOSCHANGING:
+ ((WINDOWPOS*)lParam)->flags = (((WINDOWPOS*)lParam)->flags & ~(SWP_SHOWWINDOW | SWP_FRAMECHANGED)) | SWP_NOACTIVATE | SWP_NOZORDER;
+ return 0;
+ case WM_SETTEXT:
+ {
+ HWND hwndFwd = (HWND)GetPropW(hwnd, L"FWDTEXT");
+ if (hwndFwd)
+ {
+ (IsWindowUnicode(hwndFwd)) ? SendMessageW(hwndFwd, WM_SETTEXT, wParam, lParam) :
+ SendMessageA(hwndFwd, WM_SETTEXT, wParam, lParam);
+ }
+ }
+ break;
+ }
+ if (!fnOldProc) return DefWindowProc(hwnd, uMsg, wParam, lParam);
+ return (IsWindowUnicode(hwnd)) ? CallWindowProcW(fnOldProc, hwnd, uMsg, wParam, lParam) : CallWindowProcA(fnOldProc, hwnd, uMsg, wParam, lParam);
+}
+
+static LRESULT CALLBACK LabelWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ WNDPROC fnOldProc = (WNDPROC)GetPropW(hwnd, L"WNDPROC");
+
+ switch(uMsg)
+ {
+ case WM_SETTEXT:
+ {
+ HWND hwndFwd = (HWND)GetPropW(hwnd, L"FWDTEXT");
+ if (hwndFwd)
+ {
+ (IsWindowUnicode(hwndFwd)) ? SendMessageW(hwndFwd, WM_SETTEXT, wParam, lParam) :
+ SendMessageA(hwndFwd, WM_SETTEXT, wParam, lParam);
+ }
+ }
+ case WM_DESTROY:
+ RemovePropW(hwnd, L"WNDPROC");
+ RemovePropW(hwnd, L"FWDTEXT");
+ if (fnOldProc) SetWindowLongPtrW(hwnd, GWLP_WNDPROC, (LONG_PTR)fnOldProc);
+ break;
+ }
+ if (!fnOldProc) return DefWindowProc(hwnd, uMsg, wParam, lParam);
+ return (IsWindowUnicode(hwnd)) ? CallWindowProcW(fnOldProc, hwnd, uMsg, wParam, lParam) : CallWindowProcA(fnOldProc, hwnd, uMsg, wParam, lParam);
+}