Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 3080
  • Last Modified:

C++ DLL For VB .NET (Win API Hooking)

For a better explanation of what I'm trying to do, go here: http://www.experts-exchange.com/Programming/Programming_Languages/Dot_Net/VB_DOT_NET/Q_21815892.html -- Anyone who answers this question can also have the points from that question.

Essentially, I need a way to hook WM_USER messages sent to a specific control in an external application.  I've been writing the application in VB .NET but can only find the control's window handle--apparently VB isn't capable of installing this kind of hook.  Unfortunately, I've not written a line of C or C++ code in my life, so I'm a little stuck.

Does anyone know of a free pre-written library that would let me see the lParam of any WM_USER (+ 1004) event sent to a window I have the handle for?  If not, can anyone post a bit of code that could accomplish this?

Thanks,

Chris
0
inxil
Asked:
inxil
  • 12
  • 11
3 Solutions
 
jkrCommented:
If you have the handle, that's not a big deal. Just use

#define __DLL

#ifndef _DEBUG
#define WIN32_LEAN_AND_MEAN
#endif
#include <windows.h>

#ifdef _DEBUG
#include <crtdbg.h>
#endif

#ifdef __DLL
#define __DYNLINK __declspec( dllexport)
#else
#define __DYNLINK __declspec( dllimport)
#endif

#pragma data_seg( ".shared")
HHOOK   g_hhk   =   NULL;
HWND    g_hWnd  =   NULL;
UINT    g_unMsg =   0;
#pragma data_seg()
#pragma comment(linker,"/section:.shared,rws")

HINSTANCE   g_hThisDll;


LRESULT CALLBACK    HookProc    (   int     nCode,  
                                    WPARAM  wParam,
                                    LPARAM  lParam  
                                );

int APIENTRY    DllMain (   HINSTANCE   hInstance,
                            DWORD       dwReason,
                            LPVOID      lpReserved
                        )
{
    if  (   dwReason    ==  DLL_PROCESS_ATTACH)
        {
            g_hThisDll  =   hInstance;

            return  (   DisableThreadLibraryCalls   (   g_hThisDll));
        }

    return( TRUE);
}

LRESULT CALLBACK HookProc   (   int     nCode,  // hook code
                                WPARAM  wParam, // removal flag
                                LPARAM  lParam  // address of structure with message
                            )
{
    PMSG    pmsg    =   ( PMSG) lParam;

    if  (   0   >   nCode   ||  PM_NOREMOVE ==  wParam)
        {
            return  (   CallNextHookEx  (   g_hhk,
                                            nCode,
                                            wParam,
                                            lParam
                                        )
                    );
        }

    if  (   g_hWnd  ==  pmsg->hWnd && g_unMsg == pmsg->message)
        {
            /* this one is for us */
            char buf[255];
            wsprintf(buf,"Message: %d lParam: %d\n", pmsg->message, pmsg->lParam);
            OutputDebugString   (   buf);

        }

    return  (   CallNextHookEx  (   g_hhk,
                                    nCode,
                                    wParam,
                                    lParam
                                )
            );
}

extern "C"
LONG __DYNLINK MsgSpyInit   ( HWND  hWnd, UINT unMsg)
{

    if  (   g_hhk)  return  (   ERROR_ALREADY_EXISTS);

    g_hhk   =   SetWindowsHookEx    (   WH_GETMESSAGE,
                                        ( HOOKPROC) HookProc,
                                        g_hThisDll,
                                        0
                                    );

    g_hWnd = hWnd;
    g_unMsg = unMsg;

    return  (   0);
}

extern "C"
LONG __DYNLINK MsgSpyTerm   ( void)
{
    UnhookWindowsHookEx (   g_hhk);

    g_hhk   =   NULL;

    return  (   0);
}

and call 'MsgSpyInit()' supplying the window handle and the message you want to monitor.
0
 
inxilAuthor Commented:
Excuse my complete ignorance--I'm not really an application programmer (mostly a PHP Web programmer) and I've never used C++ before.

So I downloaded the free Visual C++ Express Edition 2005, but I don't really know how to use your code.  When I create a new project it offers me the following options: Class Library, CLR Console Application, CLR Empty Project, Makefile Project, Win32 Console Application, Windows Forms Application, and emptyproj.

I've played around with some of 'em, but I can't get it to even pretend to work...  I know I really aught to go out an do a C++ tutorial, but I'm really just trying to create this one library for my VB app and then I'll be done with it for a while--a little bit more of a walkthrough would be much appreciated!

Thanks,

Chris
0
 
jkrCommented:
That should be a Win32 DLL. You can compile that on the command line like

cl.exe msgspy.cpp /link /dll
0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
inxilAuthor Commented:
fatal error C1083: Cannot open include file: 'windows.h': No such file or directory
0
 
jkrCommented:
Ah ;o)

You need to execute the 'vcvars32.bat' file from your Visual Studio installation forlder, so it will set the INCLUDE and LIB environment variables correctly before compiling. That should be done in the same console window.
0
 
inxilAuthor Commented:
C:\Program Files\Microsoft Visual Studio 8\VC\bin>vcvars32.bat

C:\Program Files\Microsoft Visual Studio 8\VC\bin>"C:\Program Files\Microsoft Visual Studio 8\Common7\Tools\vsvars32.bat"
Setting environment for using Microsoft Visual Studio 2005 x86 tools.

C:\Program Files\Microsoft Visual Studio 8\VC\bin>cl.exe "C:\Documents and Settings\MyUserName\My Documents\Visual Studio 2005\Projects\MsgSpy\MsgSpy.cpp" /link /dll
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 14.00.50727.42 for 80x86
Copyright (C) Microsoft Corporation.  All rights reserved.

MsgSpy.cpp
C:\Documents and Settings\MyUserName\My Documents\Visual Studio 2005\Projects\MsgSpy\MsgSpy.cpp(6) : fatal error C1083: Cannot open include file: 'windows.h': No such file or directory
0
 
inxilAuthor Commented:
Do I need the Windows Server 2003 R2 Platform SDK?
0
 
jkrCommented:
No, you should be fine with what you have.

After

C:\Program Files\Microsoft Visual Studio 8\VC\bin>"C:\Program Files\Microsoft Visual Studio 8\Common7\Tools\vsvars32.bat"
Setting environment for using Microsoft Visual Studio 2005 x86 tools.

what does

echo %INCLUDE%

give?

BTW, isn't there a "Win32 DLL Project" option available also in the IDE?
0
 
inxilAuthor Commented:
No Win32 DLL project option available... and a search of my C drive doesn't turn up a windows.h anywhere...
0
 
inxilAuthor Commented:
C:\Program Files\Microsoft Visual Studio 8\VC\bin>echo %INCLUDE%
C:\Program Files\Microsoft Visual Studio 8\VC\INCLUDE;C:\Program Files\Microsoft Visual Studio 8\VC\INCLUDE;C:\Program Files\Microsoft Visual Studio 8\VC\INCLUDE;C:\Program Files\Microsoft Visual Studio 8\VC\INCLUDE;C:\Program Files\Microsoft Visual Studio .NET 2003\SDK\v1.1\include\
0
 
jkrCommented:
>>and a search of my C drive doesn't turn up a windows.h anywhere...

Now that's bad, since it should 'live' in one of the directories. In that case, you'll have to download teh Platform SDK. This is kinda disappointing, since I would assume that one to ship with the 'Express' versions also.
0
 
inxilAuthor Commented:
MsgSpy.cpp(48) : error C2039: 'hWnd' : is not a member of 'tagMSG'
        C:\Program Files\Microsoft Platform SDK for Windows Server 2003 R2\Include\winuser.h(1571) : see declaration of 'tagMSG'
0
 
jkrCommented:
Ooops, simple typo - that's all lowercase, make that line read

    if  (   g_hWnd  ==  pmsg->hwnd && g_unMsg == pmsg->message)
0
 
inxilAuthor Commented:
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 14.00.50727.42 for 80x86
Copyright (C) Microsoft Corporation.  All rights reserved.

MsgSpy.cpp
Microsoft (R) Incremental Linker Version 8.00.50727.42
Copyright (C) Microsoft Corporation.  All rights reserved.

/out:MsgSpy.exe
/dll
MsgSpy.obj
   Creating library MsgSpy.lib and object MsgSpy.exp
MsgSpy.obj : error LNK2019: unresolved external symbol __imp__wsprintfA referenced in function "long __stdcall HookProc(int,unsigned int,long)" (?HookProc@@YGJHIJ@Z)
MsgSpy.obj : error LNK2019: unresolved external symbol __imp__CallNextHookEx@16 referenced in function "long __stdcall HookProc(int,unsigned int,long)" (?HookProc@@YGJHIJ@Z)
MsgSpy.obj : error LNK2019: unresolved external symbol __imp__SetWindowsHookExA@16 referenced in function _MsgSpyInit
MsgSpy.obj : error LNK2019: unresolved external symbol __imp__UnhookWindowsHookEx@4 referenced in function _MsgSpyTerm
MsgSpy.exe : fatal error LNK1120: 4 unresolved externals
0
 
jkrCommented:
Ah, we're getting somewhere ;o)

Just add

#pragma comment(lib,"user32.lib")

to the code.
0
 
inxilAuthor Commented:
Okay, so now it created an executable but I'm pretty sure it should have created a library...

MsgSpy.exe
MsgSpy.exp
MsgSpy.lib
MsgSpy.obj
0
 
jkrCommented:
Huh? That should not even work, there is no entry point for an executable. What was the command line you were using for the build?
0
 
inxilAuthor Commented:
cl.exe MsgSpy.cpp /link /dll
0
 
jkrCommented:
I was afraid you would write that ;o)

OK, what do you get when you rename that .exe file to DLL and open if with the DependencyWalker (www.dependencywalker.com)?
0
 
inxilAuthor Commented:
It loads a big tree of libraries, which I'm guessing is good.  It does say that it can't load MSJAVA.DLL, but I'm also guessing that that's Okay.
0
 
jkrCommented:
OK, so you have your DLL now. As long as you can see 'MsgSpyInit()' being exported, that's OK.
0
 
inxilAuthor Commented:
Thanks jkr!  I'm going to need a little more help but I've started it in a new thread because it's pretty much a new question.  If you're up for it, please take a look at:

http://www.experts-exchange.com/Programming/Programming_Languages/Cplusplus/Q_21816860.html

Also, please go to:
http://www.experts-exchange.com/Programming/Programming_Languages/Dot_Net/VB_DOT_NET/Q_21815892.html

And post a link to this thread so I can accept your answer there as well.

Cheers,

Chris
0
 
jkrCommented:
You're most welcome ;o)

>>And post a link to this thread so I can accept your answer there as well.

I am not absolutely sure whether that would comply with the EE rules, but I tend to say 'no'. Nevertheless, the hint to use C/C++ was helpful, so you could (if you want to) have the points decreased (500 for the pointer and the work done here compared makes that seem a little overpriced) and accept that as an answer.
0

Featured Post

[Webinar On Demand] Database Backup and Recovery

Does your company store data on premises, off site, in the cloud, or a combination of these? If you answered “yes”, you need a data backup recovery plan that fits each and every platform. Watch now as as Percona teaches us how to build agile data backup recovery plan.

  • 12
  • 11
Tackle projects and never again get stuck behind a technical roadblock.
Join Now