Modifying/Adding Side-By-Side Assembly search sequence - c++

This question is a bit similar to this one, except for a little twist :
Can I modify the side-by-side assembly search sequence?
We have a couple different softwares, made with different languages, that talk to each other when they run. To achieve this we made .NET COM objects that we load using Registration-Free COM Activation. This works well. Some of the languages we use can't load COMs, so we made a C++ Wrapper DLL that uses ACTCTX to activate the COMs from their embeded manifests. Also working well.
But now, we have a case where our C++ Wrapper is loaded by code that is ran by an application that isn't ours (let's call it the runtime) that is located somewhere and our application is located somewhere else. We'd rather deploy our COM objects at the same place as application is deployed rather than next to the runtime application.
Not that it is important as the concept remains the same, but the runner is FourJ's Genero (fgl.exe) and the code that calls our C++ wrapper are in .42m files. The runner (fgl.exe) is installed with Genero, by default in Program Files\FourJs and our applications are in another directory with our company's name ie : Program Files\MyCompany
This is similar to what you'd get with Java. Runtime at one place, applcation somewhere else.
So in our case, our .42m loads the C++ Wrapper properly, the wrappers activates the COM (located in the same directory as our .42m and the wrapper) properly but once we try to instanciate an object, we get a "80070002" file not found error.
I've read
Assembly Searching Sequence and noticed the described behavior using Process Monitor.
So what happens is, since ultimately it's fgl.exe that is running, the Windows Side-By-Side loader looks into :
C:\Program Files(x86)\FourJs\fgl\gen2.50\bin\MyCom.dll
C:\Program Files(x86)\FourJs\fgl\gen2.50\bin\MyCom.dll\MyCom.dll
While my COM is really inside of C:\Program Files(x86)\MyCompany\MyApplication\MyCom.dll
To confirm the behavior, we copied the COM in the same directory as fgl.exe and as expected, it works.
So i would like to be able to add a Search Directory to my Activation Context so that it looks for this DLL in my deployment directory.
Is this possible ?
If i can't find another solution, we'll end up deploying our COMs inside of that directory, but that's just not the right.
Thanks

Related

How to detect if QT main class is already present in memory

During the last ten years, we have programmed different functional extensions (as DLLs) using the API of a CAD program, all use QT. All serve other purposes and are individual projects in various IDEs (QTCreator / VS2010 / VS2015).
Apparently, for the first time now, a customer needs to run two or three of these extension DLLs concurrently.
We have no control over which DLL gets loaded (the individual user determines this) or in which order these are loaded (the CAD application determines this).
With the secondly loaded DLL, we get runtime errors as the QT main object can only exist once. Strange things happen.
Question: How can a DLL at its start inquire about the presence of the global QT object (without having a reference to it) and then either create a new one or attach to the existing one?
Sorry, but we could not find a solution in the QT doc or by asking Ma Google; the QT support was of no help, too.
Why not check the value returned by QCoreApplication::instance() before you create a new one?

Loading custom DLLs instead of original DLLs

The question below is for educational purposes only and the discussed featured are not meant to alter registered DLLs or develop a malware but for learning and experiencing.
Recently I've been exploring few methods to load my own custom DLLs instead of an application's original DLLs.
One of the methods that came up was the <exe>.local method.
After experiencing with this method a little bit and after I removed the KnownDlls entry from the registry I managed to replace some system DLLs with my patched DLLs successfully.
These are the DLLs:
However, the DLLs are IN the local folder:
However, there are still some DLLs that insist loading from the system32 directory, although they are present in the local folder.
Is there any way I can force the DLL's to load from the local folder instead of the system32 folder?
This is not an answer so much as a rambling, unsourced, brain dump.
It does serve to explain why I am not surprised at your result. This boils down, for me, to the crucial difference between CreateProcess and LoadLibrary, and how Win32 processes work.
Normally, when using LoadLibrary, you are using it from within the process you want the dll to be loaded into. As such, it can take advantage of a whole bunch of in-process context information about activation contexts, dll search paths etc. including knowledge of things like the app.local flag.
All these values are specific to the current process and it is not the job of any other process (or even the Kernel) to track stuff like this.
But, if we look at CreateProcess we can see some problems. When it is initially called, it is called in the context of the launching, not destination, process, so it knows nothing of the destination processes activation context. In fact, the destination process does not exist yet.
The CreateProcess implementation needs to create a NT process, and execute some code in it asap to perform the process load as it doesn't make any sense to instantiate all that per process context stuff in the current process.
But, to do that, there needs to be at least some code in the destination process: The kernel code responsible for parsing the EXE files header, extracting the headers and building the activation contexts that will be used to load the remaining dlls.
This means that, unfortunately for you, kernel32.dll and some dependencies need to be mapped into a process long before that process is capable of building a dll search context, noticing the app.local flag etc.
You should look at how the Windows loader works. This is OS version dependent, but some of those DLLs load before your program and the loader always looks for them on a path provided by the system. Look at the sequence by starting your program with WinDbg.

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.

One C++ client fails to load with our new COM registered .NET .dll, another works

We have an old C/C++ .dll that a customer accesses via COM.
We have tried to replace our old .dll with a new one written i .NET.
Customer cannot recompile their client so it is important that the old .dll can be replaced simply by COM unregister / register new (using regsvr32 / regasm).
We believe we have built the .NET .dll with the same COM interface as the old; GUID's, names, dispid's etc. all match. We have verified this by writing our own C++ test application and it continues to work when we unregister old .dll / register new one.
The problem is that the customer's client failes to start.
Strangely if we leave the old .dll registered (e.g. both .dll's are registerd) it works; The customer's application starts and calls methods in our new .dll. But as soon as we unregister the old .dll the application fails to start again.
We have tried different ways to register the new .dll; using regasm with /codebase option, /tbl, etc.
If I inspect with OLE/COM Viewer I can see some minor differences between new and old .dll, for example the type library "name" differs. But I suppose since our own C++ test client works with either .dll the COM interfaces are enough similar?
Please, anyone has any idea? How is it possible for one C++ client to load with our new .dll while another fails? Why do both work if we leave the old .dll registered in parallel to the new one? Is there any explanation why the two C++ clients behave differently?
UPDATE:
The error message in the client says:
"failed when running: CLSIDFromProgID. Check if [myDll].dll is registered."
Kind Regards P.T
There are many possibilities. First, ensure you are registering the type library of your new DLL. The old one may be doing it as part of DllRegisterServer, but AFAIK, .Net DLLs do not. Register it with REGTLB.exe.
Also check the threading models are the same in both DLLs.
If neither of those help, I suggest you keep on until OLEVIEW says they are identical - you never know what the client is doing which is different from yours.

How can I run Visual Basic code in a running Visual Basic 6.0 process (e.g. MSVBVM60.DLL)?

I'm working on debugging a legacy Visual Basic 6.0 application; the application was built into native code, but unfortunately we just have the binaries, but no source code. So I'm rather limited as far as modifications to the program go.
My final goal is to get the value of the 'Name' property of some controls given their HWND. I can easily write VisualBasic code to do this, but unfortunately I don't see how to execute this code in the context of the running application.
My first attempt was to create an ActiveX DLL in VisualBasic which exposes my 'controlNameForHWND' function. At runtime, I then had a little utility injected a second helper DLL into the VB running process, and that helper DLL then called CoCreateInstance so that my ActiveX control (which features the 'controlNameForHWND' function I wrote in VB) is instantiated inside the process of the application.
This worked well, but unfortunately the ActiveX control is apparently not executed in the same context as the application to be debugged. For instance, the global App.hInstance value is different, the array returned by the global Forms array is always empty, and so on. So all my VisualBasic script code is running in a parallel universe. Bad luck. :-/
Does anybody else have ideas how to be able to "inject" VisualBasic code into a VB6 process? Looking at the process using Process Explorer shows that the library MSVBVM60.DLL is loaded (the Microsoft Visual Basic Virtual Machine), but not e.g. VBA.DLL. The latter would be interesting since it exports an undocumented EbExecuteLine function to execute script statements.
I'm running a bit low on ideas, so I'm grateful for the craziest ideas, too. :-)
A VB6 ActiveX DLL will run in the client process, but it won't have access to the Forms collection of the client process. I think the App.hInstance should return the same value though.
If you are debugging your DLL in the VB6 IDE debugger, that will cause it to run in a separate process. That debugger does some crazy things. You might be better to build a PDB file from the ActiveX DLL and debug in the Visual C++ debugger.