Wrong method called in ATL COM dll - c++

I have created a COM dll using ATL. When I attempt to use it within unmanaged C++ I find that I get a buffer overrun. I am currently testing using one simple method called OnInitIDA() and all I do within this is a cout statement and return. When I ran this the HRESULT returned would be 0 however it would not output the line I expected. By using the step over and step into functions of the debugger I found that rather than entering the code for OnInitIDA when called this actually went into another method called GetInclusionList. Once I placed a statement within this method and when the app was run this line was printed off. Does anyone have any idea why the wrong method would be invoked?
If it helps my code has been posted here: https://docs.google.com/open?id=0B3ehFEncKJH7ZDgxMGI1YjgtZTE2MS00ZTBkLWI2NzgtYzVhZjUxOWEzZGI0

This sounds like you've changed your interface since building your client.
It would be a good idea to clean and rebuild all your projects.

I found an answer to my question. Basically, when I created my dll project it inherited from IDispatch, however the interface I was using in the test app expected it to inherit from IUnknown. This meant the interfaces did not match, with IDispatch inheriting from IUnknown and adding a number of methods. Change changing these to match the dll worked.

Related

Hooking/Detouring a DLL function by creating a wrapper DLL

i am currently stuck in the process of trying to create a wrapper DLL for another DLL which i want to replace but then include in my own created DLL.
When the dll is getting attached by the main program i would load the original DLL and then setup a hook function that let's me decide what i want to send to the original DLL function.
I already have the basic structure to import the dll, but my problem is that i don't really know what the best way of doing it is, because i only want to hook one function and the others should still just work normally without me doing anything.
Is there an easier solution than defining every function and just redirecting it to the original DLL? And also how would i even make it that my DLL function is exactly the same as the original one? I got a basic prototype but i don't know if i need anything else:
typedef int(__cdecl *PROC_cef_parse_url)(
const cef_string_t* url,
cef_urlparts_t* parts
);
And i can call it probably like this:
PROC_cef_parse_url _cef_parse_url = (PROC_cef_parse_url) GetProcAddress(hModule, "cef_parse_url");
But because i actually have no idea if this works or not and have no experience in DLL creation and stuff like this, i wanted to ask if i need something else, or if someone can provide me with an easy example.

How would I go about invoking the ui from within a DLL?

This may be too broad a question, but I have a DLL that contains a UI. It is currently invoked by an EXE. What steps would I do to try and invoke the UI within the DLL? Or put another way, how would I go about teasing out the code that would invoke the UI as it happens in the EXE?
Looks like you have access to source for both dll and executable that uses it. so what you are doing is writing a host for that dll from scratch.
Create a MFC application from VS project templates (make it the same kind as main executable, dialog, single document, multiple document, etc).
Look at what function dll exports, also look at its headers and best of all -- documentation.
Search source code of main exe and find the places the dll functions are called.
Figure out what is being done and why.
Narrow down scenarios you want to reproduce (initialize dll, show basic UI and tear down)
Start reproducing that code in your example app.
Copy the dll call, see what parameters it takes, see how those are initialized, etc.
Fix errors as they come up.

Convert Win32 Application to Object

I'm pretty new to WinAPI programming, and have written a Win32 application for screen capture. When I run the program, the cursor immediately changes to a crosshair and I can click and drag to capture a portion of the screen and save it to file.
However, I'd now like to modify my program so that it doesn't contain a main method (WinMain) and essentially turn it into an object class rather than an application class so I can call functions from other programs. I haven't been able to find a good resource on how to do this, as I believe WinMain carries out special functionality under the hood so I can't simply change the name of the method.
Can anyone suggest some good resources or tutorials that address this?
There are many ways to do that, but you have fist move one step back:
How do yopu expect your "program" (let us continue to call that way) to be called?
With which parameters and what return type?
Then, what kind of API do you want to expose? A C++ class in header? a C++ class from a static library?
A C function exported from a DLL? an COM object?
There are many sample on how a library or a DLL or a COM library looks like (just try google those keywords).
The simple way is most likely to set up a library or a DLL project (most IDE have wizard that provide empty skeletons), than paste in it the relevant code that you require to leave there, letting it be called from the exposed function or class method.
A more precise answer can be given only after you decided which "form" your "object" should have.

Problems getting access to a STA object from another process

I have been trying something which may turn to be impossible in the end. It's been a long while since I've been in COM land.
Consider two apps and a COM STA DLL. First app loads COM STA DLL as a plugin and this DLL tries to register itself "globally" so that the second app sees it. Something like GetObject("Excel.Application").
I have tried two approaches (which may turn to be the same thing).
Approach 1: I have tried using CoRegisterClassObject to register my STA instance of an object. This call succeeds with S_OK. But if I try to GetActiveObject using the same CLSID immediately after CoRegisterClassObject, I get MK_E_UNAVAILABLE - 0x800401e3.
Is GetActiveObject the wrong API to call? If not, why would it fail?
Approach 2: I have also tried using GetRunningObjectTable, IRunningObjectTable:Register and CreateClassMoniker but when trying to get to the object from ROT in a second app, I am faced with another failure.
My STA DLL is properly registered and uses typelib for marshaling (which is also registered).
Am I missing something or is what I am trying to do not possible at all? If latter, are there any simple alternatives for me?
It seems when you want to use GetActiveObject your friends are RegisterActiveObject and RevokeActiveObject. I was totally off. It works perfectly now! I hope this helps someone.

How do you create a COM DLL in Visual Studio 2008?

It's been ages since I've written a COM dll. I've made a couple of classes now, that inherit from some COM interfaces, but I want to test it out. I know I have to put a GUID somewhere and then register it with regsvr32, but what are the steps involved?
Edit: Sorry, forgot to mention I'm using C++.
To create a new ATL COM project you can proceed as follow:
File/New Project
Visual C++/ATL/ATL Project
Customize it settings, and press finish when done
You have created a new dll, but it is empty, to add a COM object you can do this:
Project/Add Class
Visual C++/ATL/ATL simple object, press add
Give the name you want (like MyObject), and press finish to add it
If you want that an object implement an interface
In the class view select the object class (CMyObject)
Right click/Add/Implement Interface...
You can select which Interface will implement
From an .idl file already in your projects files
From a .tlb/.dll/.exe which have a type library embedded
From an object already registered
When done press finish
PS: It is much easier to create a new ATL project with the same name in a different folder, and add the files you have customized. The wizard does several tasks and create several customized files.
For larger projects that are difficult to add file by file, I do the same but instead of adding my files to the new project I start copying the settings from the new projects to the old one, and adding any additional file that the wizard has created and fixing headers like stdafx.h to merge the new settings.
PPS: If you want that your dll to support MFC, instead of selecting ATL Project you have to select MFC/MFC Dll. When you add the ATL Simple Object the wizard will ask to add ATL support to the project.
You need to write a function called DllGetClassObject and export it. That function is responsible for allocating a "class factory", which you also have to write, and which is in turn capable of allocating instances of your COM object. It has to implement IClassFactory.
It's not too hard to do. The alternative is to use ATL (see xhantt's answer) which in theory does this for you, but in practice it's a real mess. Somehow it manages to encapsulate the complexity of COM inside an abstraction layer that is even more complicated. Good luck trying to move an object between DLLs for example.
But you could run the ATL wizard just to see an example of how to declare DllGetClassObject. Implementing IClassFactory is very easy - just one method that news-up an object.
Then you need to register your DLL - i.e. put keys into the registry. The regsvr32 tool cannot do this without further help from you. You have to write and export another function called DllRegisterServer, which does all the hard work. All that regsvr32 does is load the DLL, look up DllRegisterServer and call it.
Again, ATL has a way of implementing this for you, but it does it by reading a kind of script full of registry modification instructions, stored in an .rgs file that gets embedded into your DLL's resources. If you accidentally put any kind of syntax error into this file, the registration fails silently.
So again, you may actually find it simpler to write a few lines of code to tweak the registry yourself. Here are the details.
If you used C# instead, you wouldn't have any of these problems. Everything is encapsulated very cleanly. It actually works much better than C++ as a tool for developing COM objects.
When you build the solution, it automatically registers the dll.
And also it creates two files _i.c and .h file.
To test the dll create the sample application:
Create sample Win32 application. Include the _i.c and .h in the cpp file of the win32 application which has main function
Call CoInitialize();
Declare a interface pointer
CComPtr pMyInterface = NULL; // where IMyInterface is declared in _i.c
Create the instance
pMyInterface.CoCreateInstance(CLSID_MyClass); // CLSID_MyClass is GUID representing the
CoClass
Call the APIs present in the Interface
Call CoUnInitialize();