diff options
author | Sergey Nazaryev <sergey@nazaryev.ru> | 2016-01-11 01:06:54 +0300 |
---|---|---|
committer | Sergey Nazaryev <sergey@nazaryev.ru> | 2016-01-11 01:06:54 +0300 |
commit | 08b1b6757e0c4f1ddb50fd8cf63945d3c1aa9d97 (patch) | |
tree | 82307a8f16b7fe21586528781c1dcb713384a91b | |
download | nms-rebuild-master.zip nms-rebuild-master.tar.gz nms-rebuild-master.tar.bz2 |
-rw-r--r-- | nms.cpp | 228 |
1 files changed, 228 insertions, 0 deletions
@@ -0,0 +1,228 @@ +#include <windows.h> +#include <winuser.h> +#include <stdio.h> + +#include <iostream> +#include <sstream> +#include <mshtml.h> +#include <atlbase.h> +#include <oleacc.h> + +#include <psapi.h> + +int skipFirstProcess = 1; // TODO: bad global variable +CComPtr<IHTMLDocument2> spDoc; // TODO: bad global variable + +struct handle_data { + unsigned long process_id; + HWND best_handle; +}; + +BOOL CALLBACK FindWindowByProcessRoutine(HWND handle, LPARAM lParam) +{ + handle_data& data = *(handle_data*)lParam; + unsigned long process_id = 0; + GetWindowThreadProcessId(handle, &process_id); + if (data.process_id != process_id) { + return TRUE; + } + data.best_handle = handle; + return FALSE; +} + +HWND FindWindowByProcess(unsigned long process_id) +{ + handle_data data; + data.process_id = process_id; + data.best_handle = 0; + EnumWindows(FindWindowByProcessRoutine, (LPARAM)&data); + return data.best_handle; +} + +BOOL CALLBACK FindIEWindow(HWND hwnd, LPARAM lParam) +{ + TCHAR buf[100]; + + ::GetClassName( hwnd, (LPTSTR)&buf, 100 ); + if ( _tcscmp( buf, _T("Internet Explorer_Server") ) == 0 ) + { + *(HWND*)lParam = hwnd; + if( skipFirstProcess == 1 ) { + skipFirstProcess = 0; + return TRUE; + } + return FALSE; + } + else + return TRUE; +} + +BOOL GetDocInterface(HWND hWnd) +{ + CoInitialize( NULL ); + HINSTANCE hInst = ::LoadLibrary( _T("OLEACC.DLL") ); + if ( hInst != NULL ) { + if ( hWnd != NULL ) { + HWND hWndChild = NULL; + ::EnumChildWindows( hWnd, FindIEWindow, (LPARAM)&hWndChild ); + if ( hWndChild ) { + LRESULT lRes; + + UINT nMsg = ::RegisterWindowMessage( _T("WM_HTML_GETOBJECT") ); + ::SendMessageTimeout( hWndChild, nMsg, 0L, 0L, SMTO_ABORTIFHUNG, 1000, (DWORD*)&lRes ); + + LPFNOBJECTFROMLRESULT pfObjectFromLresult = (LPFNOBJECTFROMLRESULT)::GetProcAddress( hInst, "ObjectFromLresult" ); + if ( pfObjectFromLresult != NULL ) { + HRESULT hr; + hr = (*pfObjectFromLresult)( lRes, IID_IHTMLDocument2, 0, (void**)&spDoc ); + if ( SUCCEEDED(hr) ) + return TRUE; + } + } + } + ::FreeLibrary( hInst ); + } + CoUninitialize(); + return FALSE; +} + +const char* GetBody() { + IHTMLElement *p = 0; + + IHTMLElement *pp = 0; + spDoc->get_body(&p); + if (p) { + BSTR bstrContent; + p->get_parentElement( &pp ); + pp->get_outerHTML( &bstrContent ); + + std::wstring ws(bstrContent, SysStringLen(bstrContent)); + std::string s(ws.begin(), ws.end()); + + p->Release(); + + MessageBox( NULL, s.c_str(), "Testing", MB_OK ); + + return s.c_str(); + } + return NULL; +} + +void ExecScript(char* script) { + IHTMLWindow2 *w = NULL; + if (SUCCEEDED(spDoc->get_parentWindow(&w))) { + CComBSTR temp(script); + + VARIANT pvarRet = {0}; + w->execScript(temp.Detach(), SysAllocString(L"javascript"), &pvarRet); + VariantClear(&pvarRet); + w->Release(); + } +} + +BOOL IsEtesterProcess( DWORD processID ) +{ + TCHAR szProcessName[MAX_PATH] = TEXT("<unknown>"); + HANDLE hProcess = OpenProcess( PROCESS_QUERY_INFORMATION | + PROCESS_VM_READ, + FALSE, processID ); + + if (NULL != hProcess ) + { + HMODULE hMod; + DWORD cbNeeded; + + if ( EnumProcessModules( hProcess, &hMod, sizeof(hMod), + &cbNeeded) ) + { + GetModuleBaseName( hProcess, hMod, szProcessName, + sizeof(szProcessName)/sizeof(TCHAR) ); + } + } + + CloseHandle( hProcess ); + + if( _tcsstr( szProcessName, "eTester" ) != NULL ) + return TRUE; +} + +DWORD FindEtesterProcess() { + DWORD aProcesses[1024], cbNeeded, cProcesses; + unsigned int i; + + if ( !EnumProcesses( aProcesses, sizeof(aProcesses), &cbNeeded ) ) + return 0; + + cProcesses = cbNeeded / sizeof(DWORD); + for ( i = 0; i < cProcesses; i++ ) + if( aProcesses[i] != 0 ) + if( IsEtesterProcess( aProcesses[i] ) ) + return aProcesses[i]; + return 0; +} + +BOOL AttachEtester( DWORD processId ) { + HWND window = FindWindowByProcess( processId ); + return GetDocInterface( window ); +} + +BOOL RegisterHotkeys(HINSTANCE hInstance) { + WNDCLASSEX wc; + HWND hwnd; + MSG Msg; + + wc.cbSize = sizeof(WNDCLASSEX); + wc.lpfnWndProc = DefWindowProc; + + wc.style = 0; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + + wc.hInstance = hInstance; + wc.lpszClassName = "a"; + + wc.hIconSm = NULL; + wc.hIcon = NULL; + wc.hCursor = NULL; + wc.hbrBackground = NULL; + wc.lpszMenuName = NULL; + + if(!RegisterClassEx(&wc)) + return FALSE; + + hwnd = CreateWindowEx( + WS_EX_CLIENTEDGE, + "a", + NULL, + WS_OVERLAPPEDWINDOW, + CW_USEDEFAULT, CW_USEDEFAULT, 240, 120, + NULL, NULL, hInstance, NULL); + + if(hwnd == NULL) + return FALSE; + + ShowWindow(hwnd, SW_HIDE); + RegisterHotKey(hwnd, 100, 0, VK_OEM_6); + return TRUE; +} + +int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { + RegisterHotkeys( hInstance ); + + DWORD lastEtesterProcess = 0; + + MSG msg = {0}; + while (GetMessage(&msg, NULL, 0, 0) != 0) { + if (msg.message == WM_HOTKEY) { + DWORD etesterProcess = FindEtesterProcess(); + if( etesterProcess ) { + if( lastEtesterProcess != etesterProcess ) { + AttachEtester( etesterProcess ); // only one attachment to process allowed + lastEtesterProcess = etesterProcess; + } + GetBody(); + //ExecScript( "document.body.innerHTML += 'hi everybody';" ); + } + } + } +} |