/* (C) 2003-2007 Willem Jan Hengeveld * Web: http://www.xs4all.nl/~itsme/ * http://wiki.xda-developers.com/ * * $Id: ppostmsg.cpp 1921 2008-07-31 17:08:31Z itsme $ * * 0x0002= WM_DESTROY (0,0) * 0x0010= WM_CLOSE (0,0) * 0x000A= WM_ENABLE (fEnable, 0) * 0x0012= WM_QUIT (nExitCode, 0) * 0x0111= WM_COMMAND (wNotify<<16 | wId, hWndCtl) * BN_CLICKED = 0 * * * todo: add parser to pass struct contents, like this: * * { dw:0x124, w:0x1234, w:0, {"ptrtostring"} , sz32:"fixedstring" } * * example usage: * ppostmsg -w Listview 0x104b 0 -rl 44 { dw:0 dw:2 } * should return info about the item at position 2 * */ #include #ifdef WINCEPOSTMSG #include "ItsUtils.h" #include "wintrace.h" #include "dllversion.h" #include #endif #include "debug.h" #include "stringutils.h" #include "args.h" #include "ptrutils.h" #include "vectorutils.h" #include #include #ifdef WINCEPOSTMSG struct show_value_map { DWORD dwShowValue; std::string command; }; show_value_map showvalues[]= { { SW_HIDE , "hide" }, { SW_SHOWNORMAL , "shownormal" }, { SW_SHOWNOACTIVATE , "shownoactivate" }, { SW_SHOW , "show" }, { SW_MINIMIZE , "minimize" }, { SW_SHOWNA , "showna" }, { SW_SHOWMAXIMIZED , "showmaximized" }, { SW_MAXIMIZE , "maximize" }, { SW_RESTORE , "restore" }, { SW_SETFOREGROUND , "setforeground" }, { SW_SETACTIVE , "setactive" }, { SW_SETCAPTURE , "setcapture" }, { SW_BRINGTOTOP , "bringtotop" }, { SW_DRAWMENUBAR , "drawmenubar" }, { SW_DESTROYWINDOW , "destroywindow" }, { SW_UPDATEWINDOW , "updatewindow" }, { SW_HIDECARET , "hidecaret" }, { SW_SHOWCARET , "showcaret" }, { SW_SETFOCUS , "setfocus" }, { SW_ENABLEWINDOW , "enablewindow" }, { SW_DISABLEWINDOW , "disablewindow" }, { SW_ENDDIALOGOK , "enddialogok" }, { SW_ENDDIALOGCANCEL , "enddialogcancel" }, { SW_ENDDIALOGCLOSE , "enddialogclose" }, { SW_ENDDIALOGABORT , "enddialogabort" }, }; #define N_SHOWVALS (sizeof(showvalues)/sizeof(*showvalues)) #endif bool g_verbose= false; #ifdef WINCEPOSTMSG HANDLE ITGetProcessHandle(const std::string& processname); typedef std::vector WindowInfoList; bool ITGetWindowList(WindowInfoList& list); bool ITTraceWindow(int cmd, DWORD hWnd); #endif HWND ITGetForegroundWindow(); HWND ITFindWindow(const std::string& classname, const std::string& windowname); bool ITShowWindow(HWND hWnd, DWORD dwShow); bool ITSendMessage(HWND hWnd, DWORD nMsg, DWORD wParam, DWORD lParam, DWORD dwFlags, const ByteVector &indata, DWORD *plResult, ByteVector &outdata); #ifdef WINCEPOSTMSG void ListWindows(); void ShowWindowInfo(HWND hWnd); #endif #ifdef WIN32POSTMSG #define SMGS_WPARAM_IS_INPUTOFS 1 #define SMGS_WPARAM_IS_OUTPUTOFS 2 #define SMGS_LPARAM_IS_INPUTOFS 4 #define SMGS_LPARAM_IS_OUTPUTOFS 8 #define SMGS_POSTMESSAGE 16 #define SMGS_WAITWINDOW 32 #endif bool ParseParamString(const char *arg, ByteVector& wParamSend, DWORD& wParam) { char *p= NULL; DWORD value= strtoul(arg, &p, 0); if (p!=arg) { wParam= value; return true; } wParamSend.resize(strlen(arg)); memcpy(vectorptr(wParamSend), arg, wParamSend.size()); return true; } #ifdef WIN32POSTMSG char *GetAppPath() { static char appname[1024]; if (!GetModuleFileName(NULL, appname, 1024)) return NULL; return appname; } #endif DWORD ParseMessage(const char *msg) { char *p= NULL; DWORD dwMsg= strtoul(msg, &p, 0); if (p!=msg) return dwMsg; std::string approot= GetAppPath(); approot.resize(approot.find_last_of('\\')); approot += "\\its_windows_message_list.txt"; FILE *f= fopen(approot.c_str(), "r"); if (f==NULL) return 0; char linebuf[256]; while (fgets(linebuf, sizeof(linebuf), f)) { if (isspace(linebuf[0])) continue; char *p= strtok(linebuf, "\t \r\n"); // get message class ( 'WM' ) if (p==NULL || *p==0) continue; p= strtok(NULL, "\t \r\n"); // get message nr if (p==NULL || *p==0) continue; DWORD dwMsg= strtoul(p, 0, 0); p= strtok(NULL, "\t \r\n"); // get message name if (p==NULL || *p==0) continue; if (_stricmp(msg, p)==0) { fclose(f); return dwMsg; } } fclose(f); return 0; } void usage() { printf("(C) 2003-2008 Willem jan Hengeveld itsme@xs4all.nl\n"); printf("Usage: psendmsg [options] msg wparam lparam\n"); printf(" numbers can be specified as 0x1234abcd\n"); printf(" either specify a handle, or a name+class\n"); printf(" -p POST instead of SEND\n"); printf(" -l list all windows\n"); printf(" -v more info in list\n"); printf(" -W after message, wait until window disappears\n"); printf(" -show show window\n"); printf(" -hide hide window\n"); printf(" -t CMD trace window messages\n"); printf(" CMD: start, stop, add, del\n"); printf(" -h HANDLE use window handle - default = foreground\n"); printf(" -w WINDOWNAME find window by name\n"); printf(" -c CLASSNAME limit find to classname\n"); printf(" -rw SIZE wparam is buffer of SIZE bytes\n"); printf(" -rl SIZE lparam is buffer of SIZE bytes\n"); printf(" wparam and lparam may be specified as hexnumber\n"); printf(" or as quoted string\n"); #ifdef WINCEPOSTMSG printf(" --WNDCOMMAND one of:\n"); size_t col=0; for (size_t i=0 ; i=80) { putchar('\n'); col=0; } else { putchar(' '); col++; } } printf("%s", showvalues[i].command.c_str()); col += showvalues[i].command.size(); } printf("\n"); #endif } #ifdef WINCEPOSTMSG DWORD getShowValue(const char*name) { for (size_t i=0 ; ihWnd; LocalFree(outbuf); return hWnd; } HWND ITGetForegroundWindow() { DWORD outsize=0; GetForegroundWindowResult *outbuf=NULL; HRESULT res= ItsutilsInvoke(L"ITGetForegroundWindow", 0, NULL, &outsize, (BYTE**)&outbuf); if (res || outbuf==NULL) { error(res, "ITGetForegroundWindow"); return 0; } HWND hWnd= outbuf->hwnd; LocalFree(outbuf); return hWnd; } bool ITGetWindowList(WindowInfoList& list) { DWORD outsize=0; GetWindowListResult *outbuf=NULL; HRESULT res= ItsutilsInvoke(L"ITGetWindowList", 0, NULL, &outsize, (BYTE**)&outbuf); if (res || outbuf==NULL) { error(res, "ITGetWindowList"); return false; } list.resize(outbuf->count); memcpy(vectorptr(list), outbuf->info, outbuf->count*sizeof(ITSWindowInfo)); LocalFree(outbuf); return true; } bool ITShowWindow(HWND hWnd, DWORD dwShow) { ShowWindowParams request; DWORD reqsize= sizeof(request); request.hWnd= hWnd; request.dwShow= dwShow; DWORD repsize=0; HRESULT res= ItsutilsInvoke(L"ITShowWindow", reqsize, (BYTE*)&request, &repsize, NULL); if (res) { error(res, "ITShowWindow"); return false; } return true; } bool ITSendMessage(HWND hWnd, DWORD nMsg, DWORD wParam, DWORD lParam, DWORD dwFlags, const ByteVector &indata, DWORD *plResult, ByteVector &outdata) { SendMessageParams *request= NULL; DWORD reqsize= PTR_DIFF(request, request->buf+indata.size()); request= (SendMessageParams*)LocalAlloc(LPTR, reqsize); request->hWnd= hWnd; request->nMsg= nMsg; request->wParam= wParam; request->lParam= lParam; if (!indata.empty()) memcpy(request->buf, vectorptr(indata), indata.size()); request->dwResultAlloc= outdata.size(); request->dwFlags= dwFlags; DWORD repsize=0; SendMessageResult *reply= NULL; HRESULT res= ItsutilsInvoke(L"ITSendMessage", reqsize, (BYTE*)request, &repsize, (BYTE**)&reply); if (res) { error(res, "ITSendMessage"); return false; } if (reply==NULL) { debug("ITSendMessage: reply=NULL, repsize=%d\n", repsize); return false; } *plResult= reply->lResult; DWORD outresult= repsize - PTR_DIFF(reply, reply->buf); if (outdata.size() != outresult) debug("WARNING: ITSendMessage: outsize(%d) != resultsize(%d)\n", outdata.size(), outresult); if (!outdata.empty()) { outdata.resize(outresult); memcpy(vectorptr(outdata), reply->buf, outdata.size()); } LocalFree(reply); return true; } bool ITTraceWindow(int cmd, DWORD hWnd) { TraceWindowParams request; DWORD reqsize= sizeof(request); request.cmd= cmd; request.hWnd= hWnd; DWORD repsize=0; HRESULT res= ItsutilsInvoke(L"ITTraceWindow", reqsize, (BYTE*)&request, &repsize, NULL); if (res) { error(res, "ITTraceWindow"); return false; } return true; } #endif #ifdef WIN32POSTMSG HWND ITFindWindow(const std::string& classname, const std::string& windowname) { return FindWindowEx(NULL, NULL, classname.empty() ? NULL : classname.c_str(), windowname.empty() ? NULL : windowname.c_str()); } HWND ITGetForegroundWindow() { return GetForegroundWindow(); } bool ITShowWindow(HWND hWnd, DWORD dwShow) { return FALSE!=ShowWindow(hWnd, dwShow); } bool ITSendMessage(HWND hWnd, DWORD nMsg, DWORD inpwParam, DWORD inplParam, DWORD dwFlags, const ByteVector &indata, DWORD *plResult, ByteVector &outdata) { WPARAM wParam = inpwParam; if (dwFlags&SMGS_WPARAM_IS_INPUTOFS) wParam += (DWORD)vectorptr(indata); else if (dwFlags&SMGS_WPARAM_IS_OUTPUTOFS) wParam += (DWORD)vectorptr(outdata); LPARAM lParam = inplParam; if (dwFlags&SMGS_LPARAM_IS_INPUTOFS) lParam += (DWORD)vectorptr(indata); else if (dwFlags&SMGS_LPARAM_IS_OUTPUTOFS) lParam += (DWORD)vectorptr(outdata); if (dwFlags&SMGS_POSTMESSAGE) { debug("PostMessage(%08lx, %08lx, %08lx, %08lx) [%x]\n", hWnd, nMsg, wParam, lParam, dwFlags&15); if (!PostMessage(hWnd, nMsg, wParam, lParam)) { error("PostMessage"); return false; } } else { debug("SendMessage(%08lx, %08lx, %08lx, %08lx) [%x]\n", hWnd, nMsg, wParam, lParam, dwFlags&15); *plResult= SendMessage(hWnd, nMsg, wParam, lParam); } if (dwFlags&SMGS_WAITWINDOW) { DWORD pid; GetWindowThreadProcessId(hWnd, &pid); HANDLE hProc= OpenProcess(0,0, pid); if (WAIT_TIMEOUT==WaitForSingleObject(hProc, 20000)) return false; CloseHandle(hProc); } return true; } #endif