using com 32 bits library on 64 bits application - c++

i have a 32 com library and would like to use its functionality by a 64 bits application , i 've searched on the internet and managed to get this workaround
Locate your COM object GUID under the HKey_Classes_Root\Wow6432Node\CLSID\[GUID]
Once located add a new REG_SZ (string) Value. Name should be AppID and data should be the same COM object GUID you have just searched for
Add a new key under HKey_Classes_Root\Wow6432Node\AppID\
The new key should be called the same as the com object GUID
Under the new key you just added, add a new REG_SZ (string) Value, and call it DllSurrogate. Leave the value empty
Create a new Key under HKey_Local_Machine\Software\Classes\AppID\
but it does not work on Windows 7 64 bits , the main problem is when i do the step 6
i found the key already existed, any body knows why ? or how can i overcome it ?
the documentation here is very brief

So, what you need to do here is start up this 32bit COM component in its own process, ie by calling CoCreateInstance with CLSCTX_LOCAL_SERVER.
Either this will be straight forward with the existing DLL, or if not you should wrap it with your own 32bit simple COM component which supports running as a local server...
Trying to tweak the registry is a no-win game - use the Dll as it was intended and save yourself the pain.

It could be caused by registry virtualization. Ive had problems like this in the past. The biggest annoyance is that you cant see the values or keys that the editor is complaining already exist. They actually exist in a different part of the registry (likely the users hive).
Good luck

64-bit executable cannot call a 32-bit DLL (and vice versa). You should compile your 64-bit application as 32-bit. That way you will be able to use the DLL and run all that on 32-bit and 64-bit OS.

Registry is just a suitable way to locate required dll.
If you know path to the 32bit dll on each system or you can pass it with your application, and you control the code of your 64bit app, then you can use following techniques:
1) SxS mechanism + manifests allows to load dll from a local folder without registring it and create COM components from it
2) Make this manually http://www.codeproject.com/Articles/18433/Emulating-CoCreateInstance
The 2nd solution is much simpler...

Related

Can I have a COM interface in a service to be called from Windows Script Host?

My goal is to create a COM interface in my Windows local service, written with C++/MFC, whose methods could be called from a Windows Script Host JScript code running under a logged in interactive user account.
For instance, if I have a test.js that can be started with credentials of a logged in user, that does the following:
var Obj = new ActiveXObject("myservice.somename");
var Result = Obj.MyMethod("some data");
and then have MyMethod function processed in my service & return a value.
I know it's a general concept. At this stage I'm curious if such is possible (from a Windows security stand-point, i.e. calling system service from a user process) and if so, if there's any sample code that I can use as a basis for this?
I'm assuming that it must be some COM interface, right? But usually those go into a DLL. I've never tried to put them in a service.
Thank you!
I'm posting it for my own future reference, in despite of the treatment I got in the comments to my original post. It would've saved me a day of search if someone pointed me to this article...
This CodeGuru article, "COM in plain C, Part 2" explains how to create a COM interface that can be called from the Windows Script Host. His IExample2 project shows how to create an in-proc DLL that hosts the COM interface that can be called from a VBScript included in the same project. Then regiexample2 and unregiexample2 projects also show how to register/unregister the COM interface. The VBScript can be easily adjusted to work with JScript in my OP.
One word of caution though, that project is intended to be used for installation on a 32-bit OS. For 64-bit OS, you will need to build and register a 64-bit version of the in-proc COM Dll. The registration part from a 32-bit process is similar to the one shown, except that one needs to include the KEY_WOW64_64KEY flag when opening/creating registry keys.

What could cause an intermittent "Class not Registered" (0x80040154) error on a third party dll?

My 32-bit MFC C++ (VS 2010) application uses a 32-bit dll COM component that is registered by our installer with the vsdrfCOM option. The application runs on Windows 7 Pro 64-bit.
We are getting a new error that is intermittent on only one system that is based on the same drive image as several other systems that have never seen this error. We are calling this code several times a second. Looks like there is room to make more efficient, but why never any problems before?
// Initialize SPC I/O Library COM object
(void)CoInitialize(NULL); // Initialize COM
CComPtr<IGSpcIO> pSpcIO; // define COM pointer to the SPC I/O Library object
HRESULT hr = pSpcIO.CoCreateInstance(CLSID_GSpcIO); // Create COM pointer
The code above works most of the time but I'm getting an intermittent failure on the CoCreateInstance() call.
What other issues should I be looking for that might be returning 0x80040154?
I have no idea why it would be intermittent. I would use procmon.exe to look at registry access and file access to see what the conditions are when it fails. You need to know whether it cannot find the class in the registry or whether it is having problems loading the DLL (COM server).

COM & CoGetClassObject()

I have a little problem with CoGetClassObject().
I have an application which must use some DLLs of a specific version,
but they are also present in the system, in a more recent version.
So I start hooking the CoCreateInstance() and loadLibrary(), which I guess are good.
The problem is that the DLLs in the two versions are loaded.
So I think that CoGetClassObject() is the problem/solution because it provides a pointer to an interface of an object associated with a CLSID containing a DLL that the application must use in an older version.
But I don't know what this function "does", so how can I "override" this function ?
thanks.
PS : I'm new in the COM programming.
CoGetClassObject() simply does half the job that CoCreateInstance() does. It returns a class factory. CoCreateInstance() then call IClassFactory::CreateInstance() and releases the IClassFactory. You would only use it if you have a need to create many objects of a certain coclass and want to optimize that. It avoids the cost of creating and releasing the factory over and over again.
You are possibly overlooking a far simpler solution to this problem. You can simply copy the new version of the COM server DLL into the same directory as the client EXE. And create a zero byte file with the name "app.exe.local" where "app" is the name of the EXE. That's enough to force that copied DLL to be loaded instead of the one that the registry points to. The MSDN Library article about DLL redirection is here.
The very simple explanation is CoGetClassObject() opens HKCR\CLSID\{ClassId} and looks at InProcServer32 or LocalServer32 depending on what CLSCTX_* value is passed - that is the COM server path.
Once it find a COM server file path is loads (LoadLibraryEx() with LOAD_WITH_ALTERED_SEARCH_PATH flag in case of in-proc or CreateProcess() in case of out-proc) the COM server. Then it locates and calls DllGetClassObject() for in-proc servers or waits until a class factory is registered for out-proc servers.
This of course ignores stuff like DCOM etc. You can get a better idea of how it traverses the registry using Process Monitor utility.
If you want to load a specific COM DLL regardless of whether there is a newer version installed, and regardless of where the older DLL is located, then simply ignore CoCreateInstance() and CoGetClassObject() altogether. Load the older DLL yourself via LoadLibrary(), then call its exported DllGetClassObject() function directly to get the DLL's IClassFactory interface, then call IClassFactory::CreateInstance() as needed. This is all CoCreateInstance() and CoGetClassObject() do internally anyway, but this bypasses the Registry lookups they perform to determine the DLL path to load.

Catch Registry request C++

I known such tools
http://portableapps.com/development/projects/registry_rapper
RegRap.exe can get through param other .exe file and catch requests to registry and save it into .ini
That is good, but I need snippt code to set such hundler inside my C++ program and for given Reg KEY return my value...
RegRap.exe written with NSIS scripts that is why is not helpful for me :(
But may be somebody known other project only with c++?
Thx, and sorry for my bad english.
If you want to track registry access within YOUR program, you can #define away the registry API functions, provide your hooks instead, and track it in your hooks.
//in your stdafx.h, or some other universally included file
#define RegCreateKeyEx MyRegCreateKeyEx
//somewhere else
#undef RegCreateKeyEx
LONG WINAPI MyRegCreateKeyEx(stuff...)
{
//Track
//Call the real RegCreateKeyEx
}
That's probably the easiest way of hooking an API. Will not work if you want to track registry usage by your program but outside of your code (i. e. in libraries or DLLs). Then more advanced techniques are in order.
Also, consider Process Monitor by Mark Russinovich: http://technet.microsoft.com/en-us/sysinternals/bb896645
It's not a programmatic hook, but an awesome tool all around, and therefore worth plugging. It monitors registry access by your process(es) and then some.
This post seems to say that there are no hooks for the registry and you can only long poll. Simple way to hook registry access for specific process
If you want to use pure C++, check out the libraries EasyHook and Detours. Both are intended for this sort of function-level hooking. EasyHook works in C++ and C#, 32 and 64-bit, while Detours is somewhat outdated and only for 32-bit C++ (even running it on a 64-bit OS can crash your program).
You need to install the hook within the target process, either by loading your code as a DLL or creating the process (suspended), installing the hooks and then running it.
In EasyHook that goes something like:
LhInstallHook(&RegCreateKeyEx, &MyRegCreateKeyEx, &hookstruct);
You can also hook functions your library is not linked to using the Windows API to get the address.

retrieve the global hook chain in windows

I need to get the list of functions in global hook chain in Windows and get their corresponding application if it's possible. I don't know how to retrieve information from the global hook chain however.
As far as I know there is no windows API for doing this so I think I have to find them by parsing the hook chain link list. The problem is that I don't know the data structure of this link list and it's begin address.
Does anyone know how windows manages its global hook chain?
One approach I've seen is shown in this blog post. It was referenced by this code (beware of slow server). Crazy stuff of course, no idea how well this will port between different Windows versions.
Instead of trying to walk an internal Windows structure, you know that all Window hooks must have a loaded module associated with them that has been injected into the target process; if you're trying to ensure that your own application isn't being hooked, enumerate the loaded module list and look for modules that shouldn't be there.