COM automation using tlb file - c++

Consider me a novice to windows environment and COM programming.
I have to automate an application (CANoe) access. CANoe exposes itself as a COM server and provides CANoe.h , CANoe_i.c and CANoe.tlb files.
Can anyone specify how to write a C++ client, for accessing the object, functions of the application.
Also, please specify how to access the code present in tlb file from C++.

Visual studio has a lot of built in support for importing type libraries into your C++ project and using the objects thus defined. For example, you can use the #import directive:
#import "CANoe.tlb"
This will import the type library, and convert it to header files and implementation files - also it will cause the implementation files to be built with your project and the header files to be included, so this is lots of magic stuff right there.
Then, you get a whole lot of typedefs for smart pointer wrappers for the types and objects defined in the type library. For example, if there was a CoClass called Application which implemented the interface IApplication, you could do this:
ApplicationPtr app(__uuidof(Application));
This would cause at run time, the coclass application to be created and bound to the variable app, and you can call on it like so:
app->DoSomeCoolStuff();
Error handling is done by checking the result of COM calls, and throwing the appropriate _com_error exception as necessary so this implies you need to write exception safely.

Use import directive to import the .tlb file - this will give you a C++ equivalent of the interfaces exposed by the COM component.
You will also need to register the COM component to the registry (run regsvr32 on the .dll file of the component). After that you can call CoCreateInstance() (or _com_ptr_t::CreateInstance() as it is usually more convenient) to create an instance of the class that implements the interface. You can then call methods of the interface - it will work almost the same way as if it was a plain C++ interface and class.

The easier way is to include both .h and _i.c project in your .cpp file using #include statements.
Since you haven't been given the dll and only tlb is provided, you can register the tlb using regtlibv12.exe which is a part of visual studio (this is the VS2005 version). By registering tlb, appropriate entries will be made in the registry and then you can use the COM library functionality as you need.
EDIT: BTW, you need DLL anyway to instantiate the COM Component successfully.
To create an interface pointer, one of the safer ways is to use CComPTR like:
CComPtr myPtr;
myPtr.CoCreateInstance(__uuidof("ClassNamehere"));
myPtr->Method(....);

Related

Loadlibrary excatly what #import does?

As per my understanding #import is taking the required headers/dependencies in compilation time.
Load library takes its dependencies in run-time from running pc. If it is wrong please correct me.
Whether LoadLibrary exactly what #import does?
The #import directive is a code generator. It takes the path to a type library, a language-independent way to describe types exposed by code written in an arbitrary language. Equivalent to an .h file in C or C++. Could be a .tlb file, most commonly type libraries are embedded as a resource in an executable file. The compiler de-compiles the type library content into equivalent C and C++ declarations.
The directive produces two files, you can find them back in your build directory. The .tlh file is a header file that a C or C++ compiler can use. The .tli file contains C++ wrapper functions that makes calling the interface methods much less error-prone. Based on the _com_ptr_t smart pointer class that takes care of the required reference counting, the wrapper functions turn error codes into C++ exceptions.
No LoadLibrary at all, that's taken care of by the COM infrastructure. Automatically invoked when you create an object of the exposed type. CoCreateInstance() is the factory function that takes care of it. The registry contains the required information to locate the matching executable file.
There is a learning curve, avoid cutting corners. Lots and lots of books about it, although many are out-of-print today, the MSDN landing page for the C++ wrapper classes is here.

DLL monitoring

Is there an application which allows me to see what is being sent to a DLL from a process?
I have a process and I have a DLL and I would like to monitor the parameters that are being sent to the functions so that I can use the DLL myself.
The EXPORT of the DLL is.
??0CCPCompressor##AAE#XZ
??0CCPExpandor##AAE#XZ
??1CCPCompressor##AAE#XZ
??1CCPExpandor##AAE#XZ
?Clear#CCPCompressor##QAEHXZ
?Clear#CCPExpandor##QAEHXZ
..Compress#CCPCompressor..
..Delete#CCPCompressor..
..Delete#CCPExpandor..
..Expand#CCPExpandor..
..Free#CCPCompressor..
..Free#CCPExpandor..
..Init#CCPCompressor..
..Init#CCPExpandor..
..New#CCPCompressor..
..New#CCPExpandor..
In general, this is a bad idea. Even if you have some set of captured parameters, without deep analysis of the DLL code you don't know what to do with those parameters and what ranges of parameters are accepted by certain methods. Example: if I call a method DoMathOperation(Add, 1, 2), you can mimic this call, but you won't be able to do DoMathOperation(Multiply, 2, 2) as you don't know that this is possible.
The simplest approach has been to simply relocate the original dll, and create a new dll that you make yourself, with the same exports. This dll would LoadLibrary the old dll from the alternate location.
This doesn't quite apply here - the dll is exporting c++ class members which has two consequences: c++ classes have to be statically loaded as there is no c++ mechanism to 'glue' c++ function pointers (obtained via GetProcAddress) into a class instance.
This means your shim dll would be in the unfortunate place of having to both import, and export, and identical set of symbols.
The only way around this is to write your shim dll in two parts:
Shim1:
One part would get the name of the original dll, and would export the same class defintion the original dll exported:
class __decldpec(dllexport) CCPCompressor {
...
Depends can crack the name decoration, or Undname.exe is distributed with Visual Studio.
This part would LoadLibrary() using an explicit path to shimdll2.dll located in some other folder, along with the original dll. GetProcAddress() would be needed to import functions exported by shimdll2.dll
Shim2:
The other shim dll would be located in a folder with the dll you are trying to intercept. This dll would have to import the class from the original compressor dll:
class __declspec(dllimport) CCPCompressor {
...
You can use the dll import library made by the first dll to actually link the symbols.
Then its a case of exporting functions from shim2.dll that shim1.dll will call whenever a CCPCompressor method is called.
NB. Other things: your version of the CCPCompressor class will need to have, at least, a large dummy array as you can't know from the dll exports how big the application expects the class to be (unless you happen to have an actual header file describing the class).
To decompose the exported names to build a class definition:
Open up the Visual Studio 20XX Command Prompt from the Start > Programs > Visual Studio 20XX -> Tools menu.
c:\...\VC>undname ?Clear#CCPCompressor##QAEHXZ
Microsoft (R) C++ Name Undecorator
Undecoration of :- "?Clear#CCPCompressor##QAEHXZ"
is :- "public: int __thiscall CCPCompressor:Clear(void)"
c:\...\VC>_
Do that for each function exported from the original dll (undname accepts some kind of text file to speed this process up) to find out how to declare a matching class def.
Is using detours compatible with your requirements?
From the site:
Overview
Innovative systems research hinges on the ability to easily instrument and extend existing operating system and application functionality. With access to appropriate source code, it is often trivial to insert new instrumentation or extensions by rebuilding the OS or application. However, in today's world systems researchers seldom have access to all relevant source code.
Detours is a library for instrumenting arbitrary Win32 functions on x86, x64, and IA64 machines. Detours intercepts Win32 functions by re-writing the in-memory code for target functions. The Detours package also contains utilities to attach arbitrary DLLs and data segments (called payloads) to any Win32 binary.
Detours preserves the un-instrumented target function (callable through a trampoline) as a subroutine for use by the instrumentation. Our trampoline design enables a large class of innovative extensions to existing binary software.
We have used Detours to create an automatic distributed partitioning system, to instrument and analyze the DCOM protocol stack, and to create a thunking layer for a COM-based OS API. Detours is used widely within Microsoft and within the industry.
The only reliable way is to debug your program (using any debugger like OllyDBG) and set breakpoint on required export function. Then you can simply trace the stack parameters sent to the calling function. This is only the start, you need to fully analyze function instructions within a debugger or disassembler to see what each parameter is doing and its type.

plugin pattern with .dll. how can I extract plugin interface from dll?

I have an application that's suppose to be realized in plugin pattern.
Plugins are located in dll files and I'm loading them on the fly, depending on the parameter given from a user via command line. That is, if user wants to use plugin1 he types that name as a parameter in command line when running the app and I am supposed to load it on the fly.
Since I'm using plugin pattern I have an interface (since working in c++ it's an abstract class), that all of the plugins classes implement.
My dilemma is where to put the interface class? In order to have dlls built I will have to have a declaration of interface in every dll.
I want to avoid the need for changing the interface in all of dlls when there is a need for change in interface.
On the other hand if I declare interface class in main app my dlls wont be compiled and built?
Do you have a suggestion on how to extract the interface class from dlls and put it in the main app, so when I want to change it's code, wouldn't need to change it in a dozen of places (that is, in every dll).
Thanks in advance,
Cheers
You will have to store the interface definition in a common location (separate .h file in say \inc subdirectory) and you will have to recompile all the libraries once you change the interface. There's no way around that in C++. If you need the ability to uniquely indentify interfaces you can use something like COM and change interface id each time you break the interface (again you will have to recompile the implementations, but with COM the client will not run into undefined behavior because of DLL hell).
If by "interface" you are talking about the header file that describes your base-abstract class, I see no real issue.
You can share and use a file (here, a "header file") among several projects (a "project" is either your main application or one of your plugins). In your case, it actually makes perfect sense.
Every DLL needs to have the same exported function that returns a pointer to your interface. Each DLL should be responsible for instantiating the 'interface' (Really subclass actually).
So the main app will come along, call LoadLibrary on the DLL, and then using GetProcAddress, will call the exported function on the DLL. The exported function should then instantiate the concrete interface and return a pointer to it.
Question:
"Where to put the interface"
Answer:
In your 'public' API folder.
I once did this in C#, but maybe it can help you. I created an interface and abstract class in a separate project, which the main app and the plugins reference to. That way there is only one place for edits if necessary.
Main App.exe <-> PluginInterface.dll <-> APlugin.dll
Not sure how you would accomplish this in C++, I guess you could create a separate dll for the plugin interface and load it from your exe and your plugin dll's.
Hope that helps.

What's the point of _MERGE_PROXYSTUB?

I have generated an ATL COM object using VS2008 and the code contains references to a definition called _MERGE_PROXYSTUB (because I chose the 'Merge proxy/stub' option when I initially ran the wizard.)
What is the point of a proxy/stub? If I don't select the the merge option then I get a separate MyControlPS.DLL instead - when would this ever be used?
FWIW the control seems to register and work fine if I remove all the code surrounded by the _MERGE_PROXYSTUB defines. A debug build doesn't even define _MERGE_PROXYSTUB and it still works OK.
So, can I do without a proxy/stub?
You need a proxy/stub if you want your COM object to be called from an application using a different threading model than your COM object.
For example, we have a plug in that gets loaded by an application that uses a particular threading model (can't remember which), but our COM object is multithreaded apartment (MTA) - so the the proxy/stub is required to marshall the data between the objects when a function call is made, while still adhering to the rules of the threading model.
If these rules are broken, then COM will either throw an exception or return a failure HRESULT such as RPC_E_WRONG_THREAD
If you don't check the merge proxy/stub option, then visual studio produces a seperate project for the proxy/stubs which get build into a seperate dll. This makes things more difficult for deployment if they are required, but you can basically just ignore them if you are not affected by threading model issues.
So you can do without proxy/stubs if the application calling the COM object is using the same threading model as your object
Larry Osterman provides a readable introduction to threading models on his blog.
Also, if your interfaces contain only type-library-friendly types (BSTR, VARIANT, etc) and appear in the library block of your IDL, you can elect to have them "type library marshalled" meaning that a system-provided proxy/stub uses the meta-data from the type library.
When interfaces are put inside the library block, and DllRegisterServer is customized to register the type library (pass TRUE to XxxModule::DllRegisterServer, if I recall correctly) your interfaces will be marshalled by the system, if necessary, as described by John Sibly.
At that point, the proxy/stub isn't even used, so _MERGE_PROXYSTUB has no effect.

Registering implementation of a COM interface

I'm new to COM programming. I've got a COM object (and associated IClassFactory) all ready to go, but I can't quite figure out how to go about registering the resulting DLL for use by other programs. The number of GUIDs I need to sling around is also unclear to me.
The COM object I'm trying to register implements the IAudioSessionEvents interface.
I have come across the DllRegisterServer and DllUnregisterServer functions, but I haven't found any clear demonstrations of their usage. What keys do they deal with, how are they invoked, by what and when, etc.?
Thanks,
-Kevin Montrose
I'm not sure from this post whether you are implementing or consuming the DLL that supports IAudioSessionEvents. If you're consuming this DLL, then you can register the component using the comment line utility regsvr32. To register use:
regsvr32
To unregister:
regsvr32 /u
regsvr32 should be on your path, so this command will work from any directory.
If you are implementing the DLL in question, then you must provide an implementaion of the DllRegisterServer and DllUnRegisterServer functions. These functions must set up and clean up registry entries for your component. The purpose of the registry entries is to provide a ProgID, map it to a CLSID, and provid interface ID for the interfaces that the component supports. For example, the interface ID for IAudioSessionEvent. If you're implementing the DLL, you'll have to provide code to perform all of these tasks.
Note: these functions are called by regsvr32 in order to register the component.
If very unusual to actually write this code, generally you'll want to use a framework like ATL, which takes care of the busywork for you. It is a good exercise to write this code at least once if you really want to know COM from the ground up.
You need one GUID for every class you expose to COM and one GUID for every new interface you introduce and want to make available through COM.
DllRegisterServer/DllUnregister server are called when you use regsvr32 utility (ships with Windows) to register your COM-exposed classes. It adds/removes keys to HKCR/CLSID branch for every class you expose to COM. These keys are used by CoCreateInstance() to find out which DLL to load for creating an instance of a class with a given GUID.
If you use ATL or something similar usually don't need to completely implement DllRegisterServer/DllUnRegisterServer but use the implementation provided with the library.
Quite often the easiest way to implement self registration is to use the ATL server classes, have a global variable that derives from CComModule (or some other similar class) and define a COM_MAP in your module. You then ask the com module to handle the registration based on the .rgs files that you have added to your project.