#include #include "stringutils.h" #include "debug.h" #include struct propinfo { DWORD dwLevel; DWORD dwIndex; }; std::string stringofname(LPSTR lpszString) { if (!IsBadReadPtr(lpszString, 4)) return stringformat("'%s'", lpszString); else return stringformat("%08lx", lpszString); } bool isasciistring(BYTE *p) { while (1) { if (IsBadReadPtr(p,1)) return false; if (p[0]==0) return true; if (!isprint(p[0])) return false; p+=1; } } bool isunicodestring(BYTE *p) { while (1) { if (IsBadReadPtr(p,2)) return false; if (p[1]) return false; if (p[0]==0) return true; if (!isprint(p[0])) return false; p+=2; } } DWORD FindDataLen(BYTE *p, DWORD dwMax) { for (DWORD dwI= 0 ; dwI < dwMax ; dwI++) { if (IsBadReadPtr(p+dwI, 1)) return dwI; } return dwMax; } std::string stringofdata(HANDLE hData) { if (!IsBadReadPtr(hData, 4)) { if (isunicodestring((BYTE*)hData)) return stringformat("L'%ls'", hData); else if (isasciistring((BYTE*)hData)) return stringformat("'%s'", hData); else { BYTE *p= (BYTE*)hData; DWORD dwLen= FindDataLen(p, 16); return stringformat("%08lx: ", hData) + ascdump(ByteVector(p, p+dwLen), "\r\n\t\"'"); } } else return stringformat("%08lx", hData); } BOOL CALLBACK enumprop(HWND hWnd, LPSTR lpszString, HANDLE hData, ULONG_PTR dwData) { struct propinfo *pi= (struct propinfo *)dwData; if (pi->dwIndex==0 && pi->dwLevel>0) debug("%*sproperties of wnd%08lx {\n", (pi->dwLevel-1)*3, "", hWnd); debug("%*sproperty%02d %s=%s\n", pi->dwLevel*3, "", pi->dwIndex, stringofname(lpszString).c_str(), stringofdata(hData).c_str()); pi->dwIndex++; return TRUE; } //---------------------------------------------------------------- struct childwininfo { DWORD dwIndex; DWORD dwLevel; HWND hParentWnd; }; std::string stringofwtext(HWND hWnd) { TCHAR text[1024]; if (GetWindowText(hWnd, text, 1024)) return stringformat("'%s'", text); else return "-"; } // todo: use these functions. // get instance id from somewhere. // // use psapi, to get process information std::string stringofwclass(HWND hWnd) { DWORD tid, pid; tid= GetWindowThreadProcessId(hWnd, &pid); debug("hw=%08lx: pid=%08lx tid=%08lx\n", hWnd, tid, pid); ByteVector bv_wi; bv_wi.resize(sizeof(WINDOWINFO)); WINDOWINFO *wi= (WINDOWINFO*)vectorptr(bv_wi); wi->cbSize= bv_wi.size(); if (!GetWindowInfo(hWnd, wi)) { error("GetWindowInfo(wnd%08lx)", hWnd); return "-nowindowinfo-"; } debug("wi: %s\n", hexdump(bv_wi, 4).c_str()); ByteVector bv_wc; bv_wc.resize(sizeof(WNDCLASSEX)); WNDCLASSEX *wc= (WNDCLASSEX *)vectorptr(bv_wc); wc->cbSize= bv_wc.size(); if (!GetClassInfoEx(NULL, (LPCSTR)wi->atomWindowType, wc)) { error("GetClassInfoEx(%04x)", wi->atomWindowType); return "-noclassinfo-"; } debug("wc: %s\n", hexdump(bv_wc, 4).c_str()); if (wc->cbWndExtra) { bv_wi.resize(sizeof(WINDOWINFO)+wc->cbWndExtra); wi= (WINDOWINFO*)vectorptr(bv_wi); wi->cbSize= bv_wi.size(); if (!GetWindowInfo(hWnd, wi)) { error("GetWindowInfo#2(wnd%08lx)", hWnd); return "-nowindowinfo2-"; } debug("wnd extra=%04x %s\n", wc->cbWndExtra, hexdump((BYTE*)(wi+1), wc->cbWndExtra).c_str()); } if (wc->cbClsExtra) { bv_wc.resize(sizeof(WNDCLASSEX)+wc->cbClsExtra); wc= (WNDCLASSEX *)vectorptr(bv_wc); wc->cbSize= bv_wc.size(); if (!GetClassInfoEx(NULL, (LPCSTR)wi->atomWindowType, wc)) { error("GetClassInfoEx#2(%04x)", wi->atomWindowType); return "-noclassinfo2-"; } debug("cls extra=%04x %s\n", wc->cbClsExtra, hexdump((BYTE*)(wc+1), wc->cbClsExtra).c_str()); } if ( (((DWORD)wc->lpszClassName)&~0xffff)==0 ) { TCHAR name[1024]; if (!GlobalGetAtomName((ATOM)wc->lpszClassName, name, 1024)) return stringformat("%04x: %04x", wi->atomWindowType, wc->lpszClassName); else return stringformat("%04x: %04x: '%s'", wi->atomWindowType, wc->lpszClassName, name); } else { return stringformat("%04x: '%s'", wi->atomWindowType, wc->lpszClassName); } } std::string stringofwmodule(HWND hWnd) { TCHAR text[1024]; if (!GetWindowModuleFileName(hWnd, text, 1024)) return "-nomoduleinfo-"; else return stringformat("'%s'", text); } BOOL CALLBACK EnumChildWinProc(HWND hWnd, LPARAM lParam) { struct childwininfo *wi= (struct childwininfo *)lParam; if (wi->dwIndex==0 && wi->dwLevel>0) debug("%*schildren of wnd%08lx {\n", (wi->dwLevel-1)*3, "", wi->hParentWnd); DWORD pid; DWORD tid= GetWindowThreadProcessId(hWnd, &pid); debug("%*swin%02d wnd%08lx : tid=%08lx pid=%08lx %s\n", wi->dwLevel*3, "", wi->dwIndex, hWnd, tid, pid, stringofwtext(hWnd).c_str()); debug("%*swin%02d wnd%08lx : class %s\n", wi->dwLevel*3, "", wi->dwIndex, hWnd, stringofwclass(hWnd).c_str()); debug("%*swin%02d wnd%08lx : module %s\n", wi->dwLevel*3, "", wi->dwIndex, hWnd, stringofwmodule(hWnd).c_str()); struct propinfo pi; pi.dwIndex= 0; pi.dwLevel= wi->dwLevel+1; if (EnumPropsEx(hWnd, &enumprop, (LPARAM)&pi)==-1) debug("%*s- no properties found\n", wi->dwLevel*3, "", hWnd); if (pi.dwIndex) debug("%*s}\n", wi->dwLevel*3, ""); struct childwininfo cwi; cwi.dwIndex= 0; cwi.dwLevel= wi->dwLevel+1; cwi.hParentWnd= hWnd; if (!EnumChildWindows(hWnd, &EnumChildWinProc, (LPARAM)&cwi)) error("%*sEnumChildWindows(%08lx)\n", wi->dwLevel*3, "", hWnd); if (cwi.dwIndex) debug("%*s}\n", wi->dwLevel*3, ""); wi->dwIndex++; return TRUE; } //---------------------------------------------------------------- int main(int , char **) { DebugStdOut(); struct childwininfo cwi; cwi.dwIndex= 0; cwi.dwLevel= 0; cwi.hParentWnd= 0; if (!EnumWindows(&EnumChildWinProc, (LPARAM)&cwi)) error("EnumWindows"); debug("\n\n------------------------local atoms:\n\n"); char name[1024]; for (int atom= 0 ; atom<65536 ; atom++) { if (GetAtomName(atom, name, 1024)) { if (atom<1 || atom>=0xc000 || stringformat("#%d", atom)!=name) debug("atom %04x : %s\n", atom, name); } } debug("\n\n------------------------global atoms:\n\n"); for (int atom= 0 ; atom<65536 ; atom++) { if (GlobalGetAtomName(atom, name, 1024)) if (atom<1 || atom>=0xc000 || stringformat("#%d", atom)!=name) debug("globalatom %04x : %s\n", atom, name); } }