|
Hello,
Let me first start by telling you I have very little (read: none, ive read some parts in an ebook but..) experience with c++.
I'm trying to manage a callback to a more 'trusted' managed environment.
I'm trying to use SetWindowsHookEx(WH_CBT) on a specified application to monitor and alter window behavior.
I've created the HookProc in unmanaged c++ (see below) together with a Initialize function that takes as argument void* so I can call the function inside my managed application.
I pass the function of my managed application with Managed.getFunctionPointerforDelegate().
This seems to work.
However. If I hook the external process. (Read: Inject all of its threads seperately) it doesn't seem todo the callback to my managed application.
Winapi Override shows my unmanaged dll as being linked. (If I however can't find it through System.Diagnostics.Process.Modules)
The code:
The unmanaged part:
<FONT COLOR="#000099">#include "Hook.h"
</FONT><FONT COLOR="#999999">
</FONT><FONT COLOR="#FF6633">int</FONT><FONT COLOR="#663300"> (*</FONT>pfnCallback<FONT COLOR="#663300">) (</FONT><FONT COLOR="#FF6633">void</FONT><FONT COLOR="#663300">);</FONT><FONT COLOR="#FF6633">
void</FONT> Initialize<FONT COLOR="#663300">(</FONT>HANDLE retFunc<FONT COLOR="#663300">)
{</FONT><FONT COLOR="#FF0000">
if</FONT><FONT COLOR="#663300"> (</FONT>retFunc<FONT COLOR="#663300"> !=</FONT> INVALID_HANDLE_VALUE<FONT COLOR="#663300">)
{</FONT>
pfnCallback<FONT COLOR="#663300"> = (</FONT><FONT COLOR="#FF6633">int</FONT><FONT COLOR="#663300"> (</FONT>_cdecl<FONT COLOR="#663300"> *) (</FONT><FONT COLOR="#FF6633">void</FONT><FONT COLOR="#663300">))</FONT> retFunc<FONT COLOR="#663300">;</FONT><FONT COLOR="#FF6633">
int</FONT> a<FONT COLOR="#663300"> =</FONT> ThrowMessage<FONT COLOR="#663300">();</FONT><FONT COLOR="#FF0000">
if</FONT><FONT COLOR="#663300"> (</FONT>a<FONT COLOR="#663300">==</FONT><FONT COLOR="#999900">5</FONT><FONT COLOR="#663300">)
{</FONT>
ThrowMessage<FONT COLOR="#663300">();
}</FONT>
ThrowMessage<FONT COLOR="#663300">();
}
}</FONT><FONT COLOR="#FF6633">
int</FONT> ThrowMessage<FONT COLOR="#663300">()
{</FONT><FONT COLOR="#999999">
</FONT><FONT COLOR="#FF0000"> return</FONT><FONT COLOR="#663300"> (*</FONT>pfnCallback<FONT COLOR="#663300">)();
}</FONT><FONT COLOR="#FF6633">
int</FONT> HookProc<FONT COLOR="#663300">(</FONT><FONT COLOR="#FF6633">int</FONT> nCode<FONT COLOR="#663300">,</FONT> WPARAM wParam<FONT COLOR="#663300">,</FONT> LPARAM lParam<FONT COLOR="#663300">)
{</FONT>
ThrowMessage<FONT COLOR="#663300">();</FONT><FONT COLOR="#FF0000">
return</FONT> CallNextHookEx<FONT COLOR="#663300">(</FONT>NULL<FONT COLOR="#663300">,</FONT>nCode<FONT COLOR="#663300">,</FONT>wParam<FONT COLOR="#663300">,</FONT>lParam<FONT COLOR="#663300">);
}</FONT>
The c# part:
<FONT COLOR="#990000"> public class</FONT> HookManager<FONT COLOR="#663300">
{</FONT><FONT COLOR="#990000">
private</FONT> GCHandle gch<FONT COLOR="#663300">;</FONT><FONT COLOR="#999999">
</FONT><FONT COLOR="#990000"> private</FONT> delegate<FONT COLOR="#FF6633"> int</FONT> HookProc<FONT COLOR="#663300">();</FONT><FONT COLOR="#999999">
</FONT><FONT COLOR="#990000"> private static</FONT> HookProc hookProc<FONT COLOR="#663300">;</FONT><FONT COLOR="#999999">
</FONT><FONT COLOR="#990000">
private static</FONT> Stack<FONT COLOR="#663300"><</FONT>IntPtr<FONT COLOR="#663300">></FONT> hookList<FONT COLOR="#663300"> =</FONT><FONT COLOR="#990000"> new</FONT> Stack<FONT COLOR="#663300"><</FONT>IntPtr<FONT COLOR="#663300">>();</FONT><FONT COLOR="#990000">
public</FONT> HookManager<FONT COLOR="#663300">()
{</FONT>
hookProc<FONT COLOR="#663300"> =</FONT><FONT COLOR="#990000"> new</FONT> HookProc<FONT COLOR="#663300">(</FONT>HookEvent<FONT COLOR="#663300">);</FONT>
gch<FONT COLOR="#663300"> =</FONT> GCHandle<FONT COLOR="#663300">.</FONT>Alloc<FONT COLOR="#663300">(</FONT>hookProc<FONT COLOR="#663300">,</FONT> GCHandleType<FONT COLOR="#663300">.</FONT>Normal<FONT COLOR="#663300">);</FONT>
IntPtr managedReference<FONT COLOR="#663300"> =</FONT> Marshal<FONT COLOR="#663300">.</FONT>GetFunctionPointerForDelegate<FONT COLOR="#663300">(</FONT>hookProc<FONT COLOR="#663300">);</FONT>
Poseidon<FONT COLOR="#663300">.</FONT>Initialize<FONT COLOR="#663300">(</FONT>managedReference<FONT COLOR="#663300">);
}</FONT><FONT COLOR="#990000">
public</FONT><FONT COLOR="#FF6633"> void</FONT> HookIt<FONT COLOR="#663300">(</FONT>Process hook<FONT COLOR="#663300">)
{</FONT><FONT COLOR="#999999">
</FONT> IntPtr hModule<FONT COLOR="#663300"> =</FONT> Win32<FONT COLOR="#663300">.</FONT>GetModuleHandle<FONT COLOR="#663300">(</FONT><FONT COLOR="#009900">"Poseidon.dll"</FONT><FONT COLOR="#663300">);</FONT>
IntPtr ProcAddress<FONT COLOR="#663300"> =</FONT> Win32<FONT COLOR="#663300">.</FONT>GetProcAddress<FONT COLOR="#663300">(</FONT>hModule<FONT COLOR="#663300">,</FONT><FONT COLOR="#009900"> "HookProc"</FONT><FONT COLOR="#663300">);</FONT>
ProcessThread<FONT COLOR="#663300">[]</FONT> threads<FONT COLOR="#663300"> =</FONT><FONT COLOR="#990000"> new</FONT> ProcessThread<FONT COLOR="#663300">[</FONT>hook<FONT COLOR="#663300">.</FONT>Threads<FONT COLOR="#663300">.</FONT>Count<FONT COLOR="#663300">];</FONT>
hook<FONT COLOR="#663300">.</FONT>Threads<FONT COLOR="#663300">.</FONT>CopyTo<FONT COLOR="#663300">(</FONT>threads<FONT COLOR="#663300">,</FONT><FONT COLOR="#999900"> 0</FONT><FONT COLOR="#663300">);</FONT>
foreach<FONT COLOR="#663300"> (</FONT>ProcessThread thread in threads<FONT COLOR="#663300">)
{</FONT>
IntPtr HHOOK<FONT COLOR="#663300"> =</FONT> Win32<FONT COLOR="#663300">.</FONT>SetWindowsHookEx<FONT COLOR="#663300">(</FONT>Win32<FONT COLOR="#663300">.</FONT>HookType<FONT COLOR="#663300">.</FONT>WH_CBT<FONT COLOR="#663300">,</FONT> ProcAddress<FONT COLOR="#663300">,</FONT> hModule<FONT COLOR="#663300">, (</FONT>uint<FONT COLOR="#663300">)</FONT>thread<FONT COLOR="#663300">.</FONT>Id<FONT COLOR="#663300">);</FONT>
Console<FONT COLOR="#663300">.</FONT>WriteLine<FONT COLOR="#663300">(</FONT><FONT COLOR="#009900">"{0}, {1}, {2}"</FONT><FONT COLOR="#663300">,</FONT> hModule<FONT COLOR="#663300">,</FONT> ProcAddress<FONT COLOR="#663300">,</FONT> HHOOK<FONT COLOR="#663300">);</FONT>
hookList<FONT COLOR="#663300">.</FONT>Push<FONT COLOR="#663300">(</FONT>HHOOK<FONT COLOR="#663300">);
}
}</FONT><FONT COLOR="#990000">
public</FONT><FONT COLOR="#FF6633"> int</FONT> HookEvent<FONT COLOR="#663300">()
{</FONT>
Console<FONT COLOR="#663300">.</FONT>WriteLine<FONT COLOR="#663300">(</FONT><FONT COLOR="#009900">"Hookevent called!"</FONT><FONT COLOR="#663300">);</FONT><FONT COLOR="#FF0000">
return</FONT><FONT COLOR="#999900"> 5</FONT><FONT COLOR="#663300">;
}</FONT><FONT COLOR="#990000">
private static class</FONT> Poseidon<FONT COLOR="#663300">
{
[</FONT>DllImport<FONT COLOR="#663300">(</FONT><FONT COLOR="#009900">"Poseidon.dll"</FONT><FONT COLOR="#663300">)]</FONT><FONT COLOR="#990000">
public static extern</FONT><FONT COLOR="#FF6633"> void</FONT> Initialize<FONT COLOR="#663300">(</FONT>IntPtr callback<FONT COLOR="#663300">);
}
}</FONT>
Thanks already for reading this far. Does anyone have any idea this is ? Or suggestions?
I desperately try to get this to work. It's driving me nuts right now.
|
|
|
|
|
AlmightyEdge wrote: I've created the HookProc in unmanaged c++ (see below) together with a Initialize function that takes as argument void* so I can call the function inside my managed application.
[EDIT]Why do you need to work around?In case it's not global hook you could use it directly from your .NET app but if it is you can't do it it using managed code[/EDIT]
I believe that this article is exactly for you.
Life is a stage and we are all actors!
modified on Wednesday, June 16, 2010 5:21 PM
|
|
|
|
|
I thought that, in order to hook an external thread you needed to use unmanaged code .
Thanks alot for the example, looks promising. I will try it out tomorrow .
|
|
|
|
|
Unfortunately it doesn't seem to work for external threads
|
|
|
|
|
This whole area is a tricky subject. For starters the hook procedure for WH_CBT hooks that run in other processes must be in a DLL (which is injected into all the processes being hooked). Since you're trying to call a managed function from this DLL in the context of every hooked process, the managed code must also (somehow) be injected along with the DLL that contains the hook procedure. This could lead to a common problem which can occur when trying to build component systems using .NET: trying to load multiple versions of the CLR into a single process. See In-Process Side-by-Side[^] for details on this.
Perhaps you'd be better using some kind of IPC instead of a direct function call.
Steve
|
|
|
|
|
I thought a direct function call would be the fastest.
You got any suggestion for IPC?
|
|
|
|
|
A direct function call would be the fastest, but direct function calls can only occur within a process. Since you're hooking other processes this could cause problems.
Steve
|
|
|
|
|
I need to create a dll that will wrap Microsoft wininet.dll
The idea is to install this Dll instead of the regular one in all the organization workstation and add some adjustments to few actions in the wininet.dll, especially logs
Is it possible? I need to do it so the application that use the wininet.dll wont be noticed the different.
|
|
|
|
|
alto wrote: I need to create a dll that will wrap Microsoft wininet.dll
The idea is to install this Dll instead of the regular one in all the organization workstation and add some adjustments to few actions in the wininet.dll, especially logs
Is it possible? I need to do it so the application that use the wininet.dll wont be noticed the different
little difficult task but achievable! you need to program all the function exposed by WinInet with same order and need to deploy it over wininet!
"Opinions are neither right nor wrong. I cannot change your opinion. I can, however, change what influences your opinion." - David Crow Never mind - my own stupidity is the source of every "problem" - Mixture
cheers,
Alok Gupta
VC Forum Q&A :- I/ IV
Support CRY- Child Relief and You
|
|
|
|
|
Probably a bad idea... thinking about how many legal scenarios there are to change wininet.dll.
|
|
|
|
|
Fat file system store file create date in 2 bytes. Same way it stores file create time in 2 bytes.
Is there any function which tells whether this 2 bytes date/time is valid or not?
|
|
|
|
|
Provided you have the reference documentation, I suppose you (or we) may possibly write it.
If the Lord God Almighty had consulted me before embarking upon the Creation, I would have recommended something simpler.
-- Alfonso the Wise, 13th Century King of Castile.
This is going on my arrogant assumptions. You may have a superb reason why I'm completely wrong.
-- Iain Clarke
[My articles]
|
|
|
|
|
Hi,
I got the following code from Niklas Lindquist
CBitmap *bm = new CBitmap;
bm->LoadBitmap((UINT) IDD_BITMAP);
CDC *cdcwindow = this->GetDC();
CDC cdcimage;
cdcimage.CreateCompatibleDC(cdcwindow);
CBitmap *oldbit = cdcimage.SelectObject(bm);
cdcimage.SetDCBrushColor(RGB(125,125,125));
COLORREF cr = cdcimage.GetPixel(0,0);
LPVOID bitptr = NULL;
if (bitptr == NULL)
bitptr = new char[4000];
bm->GetBitmapBits(4000,bitptr);
cdcimage.FloodFill(0,0,cr);
bm = cdcimage.SelectObject(oldbit);
What I am trying to do is fill the background of a Bitmap with a Gray Color
When I look at what is in the bitmap via bm->GetBitmapBits I see a whole buch of white Color
e.g. FF FF FF 00 FF FF FF 00 this pattern continues for many many bytes
After execution of the Floodfill shouldn't the white be whats in the current brush which is gray so that
FF FF FF 00 is now 80 80 80 00
When I look at that adddress in code it still FF FF FF 00
|
|
|
|
|
i think you need to select a brush (specifically, GetStockObject(DC_BRUSH)) into the DC before calling SetDCBrushColor.
|
|
|
|
|
I believe this is the code I gave you here[^]
CDC cdcimage;
cdcimage.CreateCompatibleDC(&cdcwindow);
COLORREF clrFill = RGB(128, 128, 128);
CBrush brush;
brush.CreateSolidBrush(clrFill);
CBrush *pOldBrush = cdcimage.SelectObject(&brush);
CBitmap *oldbit = cdcimage.SelectObject(&m_bitmap);
COLORREF clr = cdcimage.GetPixel(0, 0);
cdcimage.ExtFloodFill(0, 0, clr, FLOODFILLSURFACE);
cdcimage.SelectObject(oldbit);
cdcimage.SelectObject(pOldBrush);
|
|
|
|
|
OK I have a boat load of code, it works, bit its unaware of vectors etc.
I have a vector template that fully supports all standard operators, including scalars
I have a matrix template that supports all standard operators, including vectors and scalars
So give some matrix<template_class> m
int rows=m.data.size()
int cols=m.data[0].size();
what can we do to make m become reduced row echelon form
no back substitution yet, I just wanted to see a vector way to identify a pivot from m
and make it reduced form
this way I it should be easier to find the rank etc.
So as I see it we need to find a pivot
My matrix works with std::swap for any 2 rows
My m[] returns a vector, m[][] returns template_class
m = m + v[] works
m = m + template_class works
so do the other operators
I made it assignable by element or row
BTW my vector and matrix templates are parallel, hence the reason I wanted to leverage them
http://www.contract-developer.tk
|
|
|
|
|
Hi.
I am very new to C and C++, what is the best way of downloading data from a HTTP server, meaning, how to i download the HTML from http://www.google.com?
|
|
|
|
|
Have a look at the MFC classes CHttpFile and CHttpConnection ...
also, look at this article on CP : Retrieving a file via. HTTP[^]
Max.
Watched code never compiles.
|
|
|
|
|
Hi. i am developing to a linux device, is there any way without MFC?
|
|
|
|
|
Well, since it's a Windows development site, I assume you were developing for Windows.
on linux, yeah, there's probably something that does it; but it's probably more complicated.
a quick googling returns this : http://curl.haxx.se/[^] or this : http://rosettacode.org/wiki/Web_scraping[^]
just to give you a good start.
good luck.
Watched code never compiles.
|
|
|
|
|
One way would be with URLDownloadToFile() . Other ways exist, too.
"One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"Man who follows car will be exhausted." - Confucius
|
|
|
|
|
I'd recommend cURL, it's got an interface only it's programmer could love but it's actually fairly easy to do what you want to do. Run, don't walk to http://curl.haxx.se/[^] and download it. Actually if you're using Linux it's probably available as a package in your distro.
Cheers,
Ash
|
|
|
|
|
very simple and good article for achieving your goal :-
AmHttpUtilities[^]
"Opinions are neither right nor wrong. I cannot change your opinion. I can, however, change what influences your opinion." - David Crow Never mind - my own stupidity is the source of every "problem" - Mixture
cheers,
Alok Gupta
VC Forum Q&A :- I/ IV
Support CRY- Child Relief and You
|
|
|
|
|
|
I have the following code:
class A
{
public:
A(void);
~A(void);
};
class B
{
public:
B(void);
~B(void);
};
void testfunction(A* x){};
I want to be able to directly use:
B* x;
testfunction(x);
instead of doing an explicit cast, like
B* x;
testfunction((A*)x);
Is there a way to do this. I tried using a conversion constructor in testclass (i.e. A::A(B)) but that didn't work, also I tried defining a A* operator in B but that also failed. Is there any way I can do this?
|
|
|
|