source: trunk/MFCtooling/userlog/userlog.cpp @ 47

Last change on this file since 47 was 47, checked in by sherbold, 13 years ago
  • changed message filter of the monitoring such that only messages present in the rules are logged
  • improved filtering of duplicate keyboard messages
File size: 19.7 KB
Line 
1#include "stdafx.h"
2#include "userlog.h"
3
4#include <map>
5#include <cstdio>
6
7#ifdef __USING_MTRACE__
8#define OS_WIN32
9#include "msl/merror/inc/trace.h"
10
11#ifdef __ENCODE_BASE64__
12#include  "encode.h"
13#endif
14
15const static int traceLevel = 3;
16static int level;
17#endif
18
19#ifdef __USING_COSTUMLOG__
20static std::ofstream logfile;
21#endif
22
23#ifdef __TIMING__
24static unsigned long long timing = 0;
25static unsigned long long msgCounter = 0;
26static unsigned long long totalMsgCounter = 0;
27static bool msgCounterChange = false;
28#endif
29
30static MSG lastmsg;
31
32static bool keysPressed[256];
33
34inline bool keyAlreadyPressed(const MSG & msg) {
35        return (msg.message==WM_KEYDOWN || msg.message==WM_SYSKEYDOWN) && keysPressed[msg.wParam];
36}
37
38inline bool keyNotPressed(const MSG & msg) {
39        return (msg.message==WM_KEYUP || msg.message==WM_SYSKEYUP) && !keysPressed[msg.wParam];
40}
41
42
43HANDLE mutex;
44
45
46
47USERLOG_API void __cdecl InitUsagelog() {
48
49        mutex = CreateMutex(NULL, FALSE, TEXT("USAGELOGMUTEX"));
50        if( mutex == NULL ) {
51                MessageBox(0, L"MutexFailure", L"MutexFailure", 0);
52        }
53        for(int i=0; i<256; i++) {
54                keysPressed[i] = false;
55        }
56
57#ifdef __USING_COSTUMLOG__
58        InitLogfile();
59#endif
60        InitHookdata();
61        InitHooks();
62#ifdef __USING_MTRACE__
63        MTrace_AddToLevel(traceLevel,"%s<session>", LOGPREFIX);
64#endif
65#ifdef __USING_COSTUMLOG__
66        logfile << LOGPREFIX << "<session>" << std::endl;
67#endif
68}
69
70USERLOG_API void __cdecl ReleaseUsagelog() {
71        ReleaseHooks();
72#ifdef __USING_MTRACE__
73#ifdef __TIMING__
74        char * mtraceBuffer = new char[128];
75        sprintf(mtraceBuffer, "ul timing: %llu \t\t %llu \t\t %llu", timing, msgCounter, totalMsgCounter);
76        MTrace_AddToLevel(traceLevel,mtraceBuffer);
77        delete mtraceBuffer;
78        msgCounterChange = false;
79#endif
80        MTrace_AddToLevel(traceLevel,"%s</session>", LOGPREFIX);
81#endif
82#ifdef __USING_COSTUMLOG__
83        logfile << LOGPREFIX << "</session>" << std::endl;
84        CloseLogfile();
85#endif
86}
87
88#ifdef __USING_COSTUMLOG__
89void InitLogfile() {
90        logfile.open(LOGFILE, std::ios_base::app);
91        if( logfile.fail() ) {
92                MessageBox(0, L"Logfile could not be opend", L"Error", MB_OK);
93        }
94}
95#endif
96
97#ifdef __USING_COSTUMLOG__
98void CloseLogfile() {
99        logfile.close();
100}
101#endif
102
103void InitHookdata() {
104        myhookdata[CALLWNDHOOKID].nType = WH_CALLWNDPROC;
105        myhookdata[CALLWNDHOOKID].hkproc = CallWndProc;
106        myhookdata[GETMSGHOOKID].nType = WH_GETMESSAGE;
107        myhookdata[GETMSGHOOKID].hkproc = GetMsgProc;
108}
109
110void InitHooks() {
111        for( int i=0 ; i<NUMHOOKS ; i++ ) {
112                myhookdata[i].hookhandle = SetWindowsHookEx(myhookdata[i].nType, myhookdata[i].hkproc, (HINSTANCE) NULL, GetCurrentThreadId());
113                if( myhookdata[i].hookhandle!=NULL ) {
114                        myhookdata[i].active = true;
115                } else {
116                        myhookdata[i].active = false;
117                }
118        }
119}
120
121void ReleaseHooks() {
122        int counter = 0;
123        for( int i=0 ; i<NUMHOOKS ; i++ ) {
124                if( UnhookWindowsHookEx(myhookdata[i].hookhandle) ) counter++;
125        }
126}
127
128
129LRESULT CALLBACK CallWndProc(int nCode, WPARAM wParam, LPARAM lParam) {
130       
131        PCWPSTRUCT cwpMsg = (PCWPSTRUCT) lParam;
132        // Create a MSG struct from the cwpMsg struct
133        // The missing parameters are filled with dummy values
134        MSG msg;
135        msg.hwnd = cwpMsg->hwnd;
136        msg.message = cwpMsg->message;
137        msg.lParam = cwpMsg->lParam;
138        msg.wParam = cwpMsg->wParam;
139        msg.pt.x = -1;
140        msg.pt.y = -1;
141        msg.time = -1;
142        HookProc(CALLWNDHOOKID, nCode, &msg);
143
144        return CallNextHookEx(myhookdata[CALLWNDHOOKID].hookhandle, nCode, wParam, lParam);
145}
146
147LRESULT CALLBACK GetMsgProc(int nCode, WPARAM wParam, LPARAM lParam) {
148        PMSG msg = (PMSG) lParam;
149        HookProc(GETMSGHOOKID,nCode, msg);
150
151        return CallNextHookEx(myhookdata[GETMSGHOOKID].hookhandle, nCode, wParam, lParam);
152}
153
154void HookProc(int nFrom, int nCode, PMSG msg) {
155#ifdef __TIMING__
156        SYSTEMTIME systemTime;
157        GetSystemTime( &systemTime );
158        int startTime = systemTime.wMilliseconds+systemTime.wSecond*1000;
159#endif
160
161        DWORD waitResult;
162        // simple heuristic to eliminate duplicate messages
163        if( !( MessageEquals(*msg, lastmsg) || keyAlreadyPressed(*msg) || keyNotPressed(*msg) ) ) {
164                lastmsg = *msg;
165                if( msg->message==WM_KEYDOWN || msg->message==WM_SYSKEYDOWN ) {
166                        keysPressed[msg->wParam] = true;
167                }
168                if( msg->message==WM_KEYUP || msg->message==WM_SYSKEYUP ) {
169                        keysPressed[msg->wParam] = false;
170                }
171
172                // message filter:
173                // all messages that are defined in this switch statement will be part of the log
174                switch(msg->message) {
175                        // messages for monitoring GUI state
176                        case WM_CREATE:
177                        case WM_DESTROY:
178                        case WM_SETTEXT:
179
180                        // mouse messages
181                        case WM_LBUTTONDOWN:
182                        case WM_LBUTTONUP:
183                        case WM_LBUTTONDBLCLK:
184                        case WM_RBUTTONDOWN:
185                        case WM_RBUTTONUP:
186                        case WM_RBUTTONDBLCLK:
187                        case WM_MBUTTONDOWN:
188                        case WM_MBUTTONUP:
189                        case WM_MBUTTONDBLCLK:
190                        case WM_XBUTTONDOWN:
191                        case WM_XBUTTONUP:
192                        case WM_XBUTTONDBLCLK:
193                        case WM_NCLBUTTONDOWN:
194                        case WM_NCLBUTTONUP:
195                        case WM_NCLBUTTONDBLCLK:
196                        case WM_NCRBUTTONDOWN:
197                        case WM_NCRBUTTONUP:
198                        case WM_NCRBUTTONDBLCLK:
199                        case WM_NCMBUTTONDOWN:
200                        case WM_NCMBUTTONUP:
201                        case WM_NCMBUTTONDBLCLK:
202                        case WM_NCXBUTTONDOWN:
203                        case WM_NCXBUTTONUP:
204                        case WM_NCXBUTTONDBLCLK:
205
206                        // keyboard messages
207                        case WM_KEYDOWN:
208                        case WM_KEYUP:
209                        case WM_SYSKEYDOWN:
210                        case WM_SYSKEYUP:
211
212                        // internal messages usefull for replay/matching of events
213                        case WM_KILLFOCUS:
214                        case WM_SETFOCUS:
215                        case WM_COMMAND:
216                        case WM_HSCROLL:
217                        case WM_VSCROLL:
218                        case WM_MENUSELECT:
219                        case WM_USER:
220                                waitResult = WaitForSingleObject(mutex, 1000);
221                                if( waitResult==WAIT_OBJECT_0 ) {
222                                        WriteLogentryWString(msg, nFrom);
223                                        ReleaseMutex(mutex);
224                                }
225#ifdef __TIMING__
226                                msgCounter++;
227                                msgCounterChange = true;
228#endif // __TIMING__
229                                break;
230                        default:
231                                break;
232                }
233        }
234
235        /* Source code for an inverse filter
236
237        // inverse filter: defined messages will be filtered, all else just passes through
238        // may be replaced with a lookup-table to improve perfomance
239        // upon completion of the rules, i.e., when it is clear which messages are required,
240        // this should be changed to a "normal" filter.
241        switch(msg->message) {
242                case WM_NULL:
243                case WM_MOVE:
244                case WM_SIZE:
245                case WM_GETTEXT:
246                case WM_GETTEXTLENGTH:
247                case WM_PAINT:
248                case WM_ERASEBKGND:
249                case WM_SHOWWINDOW:
250                case WM_CANCELMODE:
251                case WM_SETCURSOR:
252                case WM_GETMINMAXINFO:
253                case WM_GETFONT:
254                case WM_WINDOWPOSCHANGING:
255                case WM_WINDOWPOSCHANGED:
256                case WM_NOTIFY:
257                case WM_STYLECHANGING:
258                case WM_STYLECHANGED:
259                case WM_GETICON:
260                case WM_NCCREATE:
261                case WM_NCDESTROY:
262                case WM_NCCALCSIZE:
263                case WM_NCHITTEST:
264                case WM_NCPAINT:
265                case WM_GETDLGCODE:
266                case 0x0090: // WM_UAHDESTROYWINDOW
267                case 0x0091: // WM_UAHDRAWMENU
268                case 0x0092: // WM_UADRAWMENUITEM
269                case 0x0093: // WM_UAHINITMENU
270                case 0x0094: // WM_UAHMEASUREMENUITEM
271                case 0x0095: // WM_UAHNCPAINTMENUPOPUP
272                case WM_NCMOUSEMOVE:
273                case WM_TIMER:
274                case WM_ENTERIDLE:
275                case WM_CTLCOLORMSGBOX:
276                case WM_CTLCOLOREDIT:
277                case WM_CTLCOLORLISTBOX:
278                case WM_CTLCOLORBTN:
279                case WM_CTLCOLORDLG:
280                case WM_CTLCOLORSCROLLBAR:
281                case WM_CTLCOLORSTATIC:
282                case WM_MOUSEMOVE:
283                case WM_PARENTNOTIFY:
284                case WM_MDIGETACTIVE:
285                case WM_IME_NOTIFY:
286                case WM_IME_SETCONTEXT:
287                case WM_AFXFIRST:
288                case WM_AFXFIRST+1:
289                case WM_AFXFIRST+2:
290                case WM_AFXFIRST+3:
291                case WM_AFXFIRST+4:
292                case WM_AFXFIRST+5:
293                case WM_AFXFIRST+6:
294                case WM_AFXFIRST+7:
295                case WM_AFXFIRST+8:
296                case WM_AFXFIRST+9:
297                case WM_AFXFIRST+10:
298                case WM_AFXFIRST+11:
299                case WM_AFXFIRST+12:
300                case WM_AFXFIRST+13:
301                case WM_AFXFIRST+14:
302                case WM_AFXFIRST+15:
303                case WM_AFXFIRST+16:
304                case WM_AFXFIRST+17:
305                case WM_AFXFIRST+18:
306                case WM_AFXFIRST+19:
307                case WM_AFXFIRST+20:
308                case WM_AFXFIRST+21:
309                case WM_AFXFIRST+22:
310                case WM_AFXFIRST+23:
311                case WM_AFXFIRST+24:
312                case WM_AFXFIRST+25:
313                case WM_AFXFIRST+26:
314                case WM_AFXFIRST+27:
315                case WM_AFXFIRST+28:
316                case WM_AFXFIRST+29:
317                case WM_AFXFIRST+30:
318                case WM_AFXLAST:
319                case 1025:
320                case 1031:
321                case 1142:
322                case 2024:
323                case 4100:
324                case 4101:
325                case 4103:
326                case 4352:
327                case 4362:
328                case 4363:
329                case 4364:
330                case 4365:
331                case 4372:
332                case 4613:
333                        break;
334                default:
335                        // exclude messages 0xC000-0xFFFF
336                        if( !(msg->message>=0xC000 && msg->message<=0xFFFF) ) {
337                                // CODE HERE!
338                        }
339                        break;
340        } */
341
342#ifdef __TIMING__
343        GetSystemTime( &systemTime );
344        timing += systemTime.wMilliseconds+systemTime.wSecond*1000-startTime;
345        totalMsgCounter++;
346        if( msgCounterChange && msgCounter%100==0 ) {
347#ifdef __USING_MTRACE__
348                char * mtraceBuffer = new char[128];
349                sprintf(mtraceBuffer, "ul timing: %llu \t\t %llu \t\t %llu", timing, msgCounter, totalMsgCounter);
350                MTrace_AddToLevel(traceLevel,mtraceBuffer);
351                delete mtraceBuffer;
352                msgCounterChange = false;
353#endif // __USING_MTRACE__
354        }
355#endif // __TIMING__
356}
357
358
359///////////////////////////////////////////////////////////
360// 2 Byte character functions
361///////////////////////////////////////////////////////////
362
363bool MessageEquals(const MSG & msg1, const MSG & msg2) {
364        bool retVal = false;
365        if( (msg1.time==-1 && msg1.pt.x==-1 && msg1.pt.y==-1) || (msg2.time==-1 && msg2.pt.x==-1 && msg2.pt.y==-1) ) {
366                retVal = msg1.hwnd==msg2.hwnd && msg1.message==msg2.message && msg1.lParam==msg2.lParam &&
367                        msg1.wParam==msg2.wParam;
368        } else {
369                retVal = msg1.hwnd==msg2.hwnd && msg1.message==msg2.message && msg1.lParam==msg2.lParam &&
370                        msg1.wParam==msg2.wParam && msg1.time==msg2.time && msg1.pt.x==msg2.pt.x && msg1.pt.y==msg2.pt.y;
371        }
372        return retVal;
373}
374
375int replaceWithXmlEntitiesWString(const wchar_t * source, wchar_t ** target, size_t sourceLength) {
376        size_t j=0;
377        size_t extraLength = 0;
378        size_t bufsize = 300;
379        wchar_t * tmpTarget = new wchar_t[sourceLength+bufsize];
380        size_t i;
381        for( i=0; i<sourceLength && j<sourceLength+bufsize-5; i++ ) {
382                switch (source[i]) {
383                        case L'&':
384                                tmpTarget[j] = L'&';
385                                tmpTarget[j+1]=L'a';
386                                tmpTarget[j+2]=L'm';
387                                tmpTarget[j+3]=L'p';
388                                tmpTarget[j+4]=L';';
389                                j += 5;
390                                extraLength += 4;
391                                break;
392                        case L'<':
393                                tmpTarget[j] = L'&';
394                                tmpTarget[j+1]=L'l';
395                                tmpTarget[j+2]=L't';
396                                tmpTarget[j+3]=L';';
397                                j += 4;
398                                extraLength += 3;
399                                break;
400                        case L'>':
401                                tmpTarget[j] = L'&';
402                                tmpTarget[j+1]=L'g';
403                                tmpTarget[j+2]=L't';
404                                tmpTarget[j+3]=L';';
405                                j += 4;
406                                extraLength += 3;
407                                break;
408                        case L'\"':
409                                tmpTarget[j] = L'&';
410                                tmpTarget[j+1]=L'q';
411                                tmpTarget[j+2]=L'u';
412                                tmpTarget[j+3]=L'o';
413                                tmpTarget[j+4]=L't';
414                                tmpTarget[j+5]=L';';
415                                j += 6;
416                                extraLength += 5;
417                                break;
418                        case L'\'':
419                                tmpTarget[j] = L'&';
420                                tmpTarget[j+1]=L'a';
421                                tmpTarget[j+2]=L'p';
422                                tmpTarget[j+3]=L'o';
423                                tmpTarget[j+4]=L's';
424                                tmpTarget[j+5]=L';';
425                                j += 6;
426                                extraLength += 5;
427                                break;
428                        case L'%':
429                                tmpTarget[j] = L'\\';
430                                tmpTarget[j+1] = L'%';
431                                j += 2;
432                                extraLength += 1;
433                                break;
434                        default:
435                                tmpTarget[j] = source[i];
436                                j++;
437                }
438        }
439        *target = new wchar_t[j+1];
440        memcpy(*target,tmpTarget,j*sizeof(wchar_t));
441        (*target)[j] = '\0';
442        return j;
443}
444
445
446void WriteLogentryWString(PMSG msg, int nFrom) {
447        wchar_t * messageStr = NULL;
448        wchar_t buffer[128];
449        wchar_t * newWindowText = NULL;
450        wchar_t * windowName = NULL;
451        unsigned int command = 0;
452        int sourceType = -1;
453        HWND source = NULL;
454        HWND parentHandle = NULL;
455        wchar_t * windowClass = NULL;
456        bool isPopup = false;
457        bool isModal = false;
458        bool htMenu = false;
459        HWND menuHandle = NULL;
460        int scrollPos = -1;
461        unsigned int scrollType = 0;
462        HWND scrollBarHandle = NULL;
463        int retVal = 0;
464
465        // debug vars
466       
467        retVal = GetWindowText(msg->hwnd, buffer, 128);
468        if( retVal > 0  && retVal<MAXINT ) {
469                /*
470                 * In one case at the start of MarWin, when a resource with DlgId 1049 is created,
471                 * GetWindowText returns MAXINT. This behaviour is undocumented.
472                 */
473                replaceWithXmlEntitiesWString(buffer, &windowName, retVal+1);
474        }
475        int windowResourceId = GetDlgCtrlID(msg->hwnd);
476        if( windowResourceId<0 ) {
477                windowResourceId = 0;
478        }
479
480        //**************************************
481        // Message specific variables
482        //**************************************
483
484        if( msg->message==WM_COMMAND ) {
485                command = LOWORD(msg->wParam);
486                sourceType = HIWORD(msg->wParam);
487                source = (HWND) msg->lParam;
488        }
489        if( msg->message==WM_SYSCOMMAND ) {
490                command = LOWORD(msg->wParam);
491        }
492
493        if( msg->message==WM_CREATE ) {
494                parentHandle = GetParent(msg->hwnd);
495               
496                retVal = GetClassName(msg->hwnd, buffer, 128);
497                if( retVal > 0  && retVal<MAXINT ) {
498                        replaceWithXmlEntitiesWString(buffer, &windowClass, retVal+1);
499                }
500
501                // check is dialog is modal
502                // this check is not always accurate, but the best that I could come up with
503                isModal = IsWindowEnabled(parentHandle)==false;
504        }
505
506        if( msg->message==WM_SETTEXT ) {
507                wchar_t * newWindowTextBuffer = (wchar_t*)msg->lParam;
508                if( newWindowTextBuffer!=NULL ) {
509                        size_t len = wcslen(newWindowTextBuffer);
510                        replaceWithXmlEntitiesWString(newWindowTextBuffer, &newWindowText, len+1);
511                }
512        }
513
514        if( msg->message==WM_NCLBUTTONDOWN ) {
515                if( msg->wParam==HTMENU ) {
516                        htMenu = true;
517                }
518        }
519       
520        if( msg->message==WM_INITMENU ) {
521                menuHandle = (HWND) msg->wParam;
522        }
523
524        if( msg->message==WM_HSCROLL || msg->message==WM_VSCROLL ) {
525                scrollType = LOWORD(msg->wParam);
526                scrollPos = HIWORD(msg->wParam);
527                scrollBarHandle = (HWND) msg->lParam;
528        }
529
530        /***************************************/
531        // put debugging variables here
532        /***************************************/
533
534
535        /***************************************
536         * Printing part
537         ***************************************/
538       
539        size_t bufsize = 2048;
540        wchar_t * msgBuffer = new wchar_t[bufsize];
541        size_t pos = 0;
542        //pos += swprintf_s(msgBuffer+pos, bufsize-pos,LOGPREFIXWSTRING);
543
544       
545        // print msg information
546        pos += swprintf_s(msgBuffer+pos,bufsize-pos,L"<msg type=\"%i\">",msg->message);
547        pos += swprintf_s(msgBuffer+pos,bufsize-pos,L"<param name=\"WPARAM\" value=\"%i\"/>", msg->wParam);
548        pos += swprintf_s(msgBuffer+pos,bufsize-pos,L"<param name=\"LPARAM\" value=\"%i\"/>", msg->lParam);
549
550        pos += swprintf_s(msgBuffer+pos,bufsize-pos,L"<param name=\"window.hwnd\" value=\"%i\"/>", msg->hwnd);
551        if( msg->message==WM_COMMAND ) {
552                pos += swprintf_s(msgBuffer+pos,bufsize-pos,L"<param name=\"command\" value=\"%i\"/>",command);
553                pos += swprintf_s(msgBuffer+pos,bufsize-pos,L"<param name=\"sourceType\" value=\"%i\"/>",sourceType);
554                pos += swprintf_s(msgBuffer+pos,bufsize-pos,L"<param name=\"source\" value=\"%i\"/>",source);
555        }
556        if( msg->message==WM_SYSCOMMAND ) {
557                pos += swprintf_s(msgBuffer+pos,bufsize-pos,L"<param name=\"command\" value=\"%i\"/>", command);
558        }
559
560        if( msg->message==WM_LBUTTONUP || msg->message==WM_RBUTTONUP || msg->message==WM_MBUTTONUP ||
561                msg->message==WM_LBUTTONDOWN || msg->message==WM_RBUTTONDOWN || msg->message==WM_MBUTTONDOWN ||
562                msg->message==WM_LBUTTONDBLCLK || msg->message==WM_RBUTTONDBLCLK || msg->message==WM_MBUTTONDBLCLK) {
563                if( msg->time>-1 ) {
564                        pos += swprintf_s(msgBuffer+pos,bufsize-pos,L"<param name=\"point.x\" value=\"%i\"/>", msg->pt.x);
565                        pos += swprintf_s(msgBuffer+pos,bufsize-pos,L"<param name=\"point.x\" value=\"%i\"/>", msg->pt.y);
566                }
567
568                if(msg->message == WM_LBUTTONUP)
569                {
570                        //check the listBox selection, store it in "scrollPos"
571                        //no selection = -1
572                        //this is only working for listBoxes with style 'selection = single'
573                        retVal = GetClassName(msg->hwnd, buffer, 128);
574                        if( retVal >= -1  && retVal < MAXINT && !lstrcmpi(buffer, L"ListBox") )
575                        {
576                                scrollPos = (int)SendMessage(msg->hwnd, LB_GETCURSEL, 0, 0);
577                                pos += swprintf_s(msgBuffer+pos,bufsize-pos,L"<param name=\"scrollPos\" value=\"%i\"/>", scrollPos);
578                        }
579
580
581                        //check the TabControl selection, store it in "scrollPos"
582                        //no selection = -1
583                        retVal = GetClassName(msg->hwnd, buffer, 128);
584                        if( retVal >= -1  && retVal < MAXINT && !lstrcmpi(buffer, L"SysTabControl32") )
585                        {
586                                scrollPos = (int)SendMessage(msg->hwnd, (UINT)4875, 0, 0);
587                                pos += swprintf_s(msgBuffer+pos,bufsize-pos,L"<param name=\"scrollPos\" value=\"%i\"/>", scrollPos);
588                        }
589                }
590        }
591        if( msg->message==WM_MOUSEACTIVATE ) {
592                pos += swprintf_s(msgBuffer+pos,bufsize-pos,L"<param name=\"toplevelwindow.hwnd\" value=\"%i\"/>", (HWND) msg->wParam);
593        }
594        if( msg->message==WM_KEYUP || msg->message==WM_KEYDOWN || msg->message==WM_SYSKEYUP || msg->message==WM_SYSKEYDOWN ) {
595                pos += swprintf_s(msgBuffer+pos,bufsize-pos,L"<param name=\"key\" value=\"%i\"/>", LOWORD(msg->wParam));
596        }
597        if( msg->message==WM_SETTEXT ) {
598                if( newWindowText!=NULL ) {
599                        pos += swprintf_s(msgBuffer+pos,bufsize-pos,L"<param name=\"window.newText\" value=\"%s\"/>", newWindowText);
600                }
601        }
602       
603        if( msg->message==WM_NCLBUTTONDOWN && htMenu ) {
604                pos += swprintf_s(msgBuffer+pos, bufsize-pos,L"<param name=\"isMenu\" value=\"true\"/>");
605        }
606
607        if( msg->message==WM_INITMENU ) {
608                pos += swprintf_s(msgBuffer+pos,bufsize-pos,L"<param name=\"menu.hwnd\" value=\"%i\"/>", menuHandle);
609        }
610
611        if( msg->message==WM_CREATE ) {
612                // print window information
613                if( windowName!=NULL ) {
614                        pos += swprintf_s(msgBuffer+pos,bufsize-pos,L"<param name=\"window.name\" value=\"%s\"/>", windowName);
615                }
616                if( windowResourceId>0 ) {
617                        pos += swprintf_s(msgBuffer+pos,bufsize-pos,L"<param name=\"window.resourceId\" value=\"%i\"/>", windowResourceId);
618                }
619                if( msg->message==WM_CREATE ) {
620                        if( parentHandle!=NULL ) {
621                                pos += swprintf_s(msgBuffer+pos,bufsize-pos,L"<param name=\"window.parent.hwnd\" value=\"%i\"/>", parentHandle);
622                        }
623                        if( windowClass!=NULL ) {
624                                pos += swprintf_s(msgBuffer+pos,bufsize-pos,L"<param name=\"window.class\" value=\"%s\"/>", windowClass);
625                        }
626                        if( isModal ) {
627                                pos += swprintf_s(msgBuffer+pos,bufsize-pos,L"<param name=\"window.ismodal\" value=\"true\"/>");
628                        }
629
630                }
631        }
632        if( msg->message==WM_HSCROLL || msg->message==WM_VSCROLL ) {
633                pos += swprintf_s(msgBuffer+pos,bufsize-pos,L"<param name=\"scrollType\" value=\"%i\"/>", scrollType);
634                pos += swprintf_s(msgBuffer+pos,bufsize-pos,L"<param name=\"scrollPos\" value=\"%i\"/>", scrollPos);
635                pos += swprintf_s(msgBuffer+pos,bufsize-pos,L"<param name=\"scrollBarHandle\" value=\"%i\"/>", scrollBarHandle);
636        }
637
638        if( msg->time!=-1 ) {
639                pos += swprintf_s(msgBuffer+pos,bufsize-pos,L"<param name=\"time\" value=\"%i\"/>", msg->time);
640        }
641       
642        /***************************************/
643        // put debugging and experimental output stuff here
644        /***************************************/
645
646#ifdef __INCLUDEHOOKINFO__
647        pos += swprintf_s(msgBuffer+pos,bufsize-pos,L"<param name=\"hook\" value=\"%i\"/>", nFrom);
648#endif
649       
650
651        pos += swprintf_s(msgBuffer+pos,bufsize-pos,L"</msg>", msg->hwnd);
652#ifdef __USING_MTRACE__
653#ifdef __ENCODE_BASE64__
654        size_t arraySize = (pos+1)*2;
655        size_t encodingSize = arraySize*2;
656        char * base64Buffer = new char[encodingSize];
657
658        base64::encoder enc;
659        retVal = enc.encode((char*)msgBuffer, arraySize, base64Buffer);
660        base64Buffer[retVal] = '\0';
661
662        char * mtraceBuffer = new char[retVal+30];
663        sprintf_s(mtraceBuffer,retVal+29,"%s%s", LOGPREFIX, base64Buffer);
664        delete base64Buffer;
665#else
666        char * mtraceBuffer = new char[pos+1];
667        size_t numConverted;
668        wcstombs_s(&numConverted,mtraceBuffer, pos+1, msgBuffer, pos);
669#endif // __ENCODE_BASE64__
670        MTrace_AddToLevel(traceLevel,mtraceBuffer);
671        delete mtraceBuffer;
672#endif // __USING_MTRACE__
673#ifdef __USING_COSTUMLOG__
674        SYSTEMTIME currentTime;
675        GetSystemTime(&currentTime);
676        logfile << currentTime.wDay << "." << currentTime.wMonth << "." << currentTime.wYear << " ";
677        logfile << currentTime.wHour << ":" << currentTime.wMinute << ":" << currentTime.wSecond << ":";
678        logfile << currentTime.wMilliseconds << "\t";
679        logfile << buffer << std::endl;
680#endif
681        delete messageStr;
682        delete newWindowText;
683        delete windowName;
684        delete windowClass;
685        delete msgBuffer;
686}
Note: See TracBrowser for help on using the repository browser.