[2 days left] What’s wrong with your cloud strategy? Learn why multicloud solutions matter with Nimble Storage.Register Now

x
?
Solved

redirecting function to another version of dll

Posted on 2009-04-09
2
Medium Priority
?
799 Views
Last Modified: 2013-12-14
Hi,

I would like to redirect a COM interface method into another version of same dll. I use Detours 2.1 Express to hook the function. in the snippet you can see a sample of hooking the IWebBrowser2::Navigate2 method. it works as expected but not as needed :) what I need is to call the Navigate2 method from custom dll (redirect it).

This is not a problem when it's an ordinary function like i.e. Sleep from kernel32.dll (I can use LoadLibrary, GetProcAddress or DetourFindFunction which in fact tries to use LoadLibrary...). Problem is how to call a COM interface method from custom dll. Any suggestions? Will appreciate any help. Thank you in advance.
#define CINTERFACE
 
#include <windows.h>
#include "detours.h"
#include <stdlib.h>
#include <iostream>
#include <string.h>
 
#include <ObjBase.h>
#include <ExDisp.h>
 
using namespace std;
 
//function prototype
HRESULT (__stdcall *RealNavigate2)(IWebBrowser2 *This,
								VARIANT *URL,
								VARIANT *flags,
								VARIANT *TargetFrameName,
								VARIANT *PostData,
								VARIANT *Headers) = NULL;
 
//detour function
HRESULT __stdcall NewNavigate2(IWebBrowser2 *This,
							VARIANT *URL,
							VARIANT *flags,
							VARIANT *TargetFrameName,
							VARIANT *PostData,
							VARIANT *Headers)
{
	//HERE IT CALLS THE ORIGINAL IWebBrowser2::Navigate2
	//I NEED TO REDIRECT IT TO OTHER VERSION OF SAME DLL
	cout << "hooked Navigate2 :)" << endl;
	HRESULT hr = RealNavigate2(This, URL, flags, TargetFrameName, PostData, Headers);
	return hr;
}
 
 
int main(int argc, char **argv){
	
	if(SUCCEEDED(OleInitialize(NULL))){
		
		IWebBrowser2 *pBr;
		CoCreateInstance(CLSID_InternetExplorer, NULL, CLSCTX_LOCAL_SERVER, IID_IWebBrowser2, (void**)&pBr);
		
		//assigning the target function for detouring
		RealNavigate2 = pBr->lpVtbl->Navigate2;
		
		//this part is not important, only some string processing
		string url = "http://www.google.com";
		VARIANT myURL;
		VariantInit(&myURL);
		myURL.vt = VT_BSTR;
 
		#ifndef UNICODE
		{
			wchar_t		*buffer;
			DWORD		size;
 
			size = MultiByteToWideChar(CP_ACP, 0, url.c_str(), -1, 0, 0);
			if (!(buffer = (wchar_t *)GlobalAlloc(GMEM_FIXED, sizeof(wchar_t) * size))){
				cout << "badalloc" << endl;
				getchar();
				return 0;
			}
			MultiByteToWideChar(CP_ACP, 0, url.c_str(), -1, buffer, size);
			myURL.bstrVal = SysAllocString(buffer);
			GlobalFree(buffer);
		}
		#else
		myURL.bstrVal = SysAllocString(url);
		#endif		
		
		//attaching target and detour function
		DetourTransactionBegin();
		DetourUpdateThread(GetCurrentThread());
		DetourAttach(&(PVOID&)RealNavigate2, NewNavigate2);
		DetourTransactionCommit();
 
		VARIANT vFlags;
		V_VT(&vFlags) = VT_I4;
		V_I4(&vFlags) = navOpenInNewWindow;
		
		VARIANT vEmpty;
		VariantInit(&vEmpty);
 
		//calling the target function, which gets hooked and it will jump to execution of NewNavigate2 detour function
		HRESULT hr = pBr->lpVtbl->Navigate2(pBr, &myURL, &vEmpty, &vEmpty, &vEmpty, &vEmpty);
		if (SUCCEEDED(hr))
		{
			pBr->lpVtbl->put_Visible(pBr, VARIANT_TRUE);
		}
		else
		{
			pBr->lpVtbl->Quit(pBr);
		}
 
		pBr->lpVtbl->Release(pBr);
 
		OleUninitialize();
 
		
	}
	
	return 0;
}

Open in new window

0
Comment
Question by:StraySod
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
2 Comments
 
LVL 39

Accepted Solution

by:
itsmeandnobodyelse earned 2000 total points
ID: 24105537
A COM Dll is registered in registry what means that only one (probably the youngest) version is currently active.

The only way I know to call a dll of different version (beside of explicitly loading from file) is to register it in the .manifest file of your application. AFAIK that could be done with MSI but I never did it myself. And I don't know either whether it works for COM as well (but there is a good chance cause the .manifest simply overrules normal registry entries).

Note, for using .manifest files you need XP or Vista.
0
 
LVL 7

Author Closing Comment

by:StraySod
ID: 31568438
Ok, thank you for your reply :) will try it
0

Featured Post

Moving data to the cloud? Find out if you’re ready

Before moving to the cloud, it is important to carefully define your db needs, plan for the migration & understand prod. environment. This wp explains how to define what you need from a cloud provider, plan for the migration & what putting a cloud solution into practice entails.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

In this article, I'll describe -- and show pictures of -- some of the significant additions that have been made available to programmers in the MFC Feature Pack for Visual C++ 2008.  These same feature are in the MFC libraries that come with Visual …
Introduction: Finishing the grid – keyboard support for arrow keys to manoeuvre, entering the numbers.  The PreTranslateMessage function is to be used to intercept and respond to keyboard events. Continuing from the fourth article about sudoku. …
This tutorial covers a step-by-step guide to install VisualVM launcher in eclipse.
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.

656 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question