I really need help...
I have implemented a COM component (i.e A.dll) with IDL, also coded a wrapper DLL (B.dll) for that component. I have implemented required export functions for DLL "A" and registered it with "regsvr32.exe".
Problem is that I have 3 EXE files that uses B.dll to access methods of A.dll. But, I could not manage to create a local server for A.dll, therefore every EXE loads a new A.dll and B.dll. I want to load A.dll only once, and need to realize this functionality in B.dll. Last statement is open for discussion also.
However, I could not manage to find any useful example or resource regarding this problem. Any help will be appreciated, thanks in advance.
A DLL mediated by COM is known as an in-process server. Which suggests your problem: it will always be mapped into the memory space of its clients, just like any other DLL. Similarly any DLLs it loads will be mapped into the original process. It is not clear from your question why you don't want to use a DLL. If it is to save resources then consider that only data will be duplicated; the code will only be loaded once. If it is because you want them to share data, then consider using shared memory. If you really want all three .exe's to be served by an instance then what you need is a COM local server, which will be implemented by an .exe, not a .dll.
There's no such thing as "create a local server". In-proc server has to be loaded into each consumer process, there's no way around that - each consumer is a separate process, so it has its own copy of code and data.
In order to have a single process executing COM server code for all of the consumers you have to create an out-proc server. To do the latter you can either reengineer your COM server or try to use COM+ server application. This way you can have a separate process running the COM server code several consumers can connect to.
Related
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.
What I've seen so far, there can only be one plugin per .dll file, is that correct? The Browser calls NP_GetEntryPoints, NP_Initialize and NP_Shutdown only "once" per dll, right?
What I'm aiming for is to create multiple plugins in one dynamic library. Is that possible, and if, how?
What I've seen so far, there can only be one plugin per .dll file, is that correct?
No, you can have multiple plugins implemented in one DLL.
The Browser calls NP_GetEntryPoints, NP_Initialize and NP_Shutdown only "once" per dll, right?
Only once per process and loading (keep in mind that it will be unloaded while when no instance is alive anymore).
What I'm aiming for is to create multiple plugins in one dynamic library. Is that possible, and if, how?
It's possible. You just register the different mimetypes for the same dynamic library (e.g. on Windows several mimetype entries in the registry pointing to the same DLL).
NPP_New() gets a NPMIMEType as it's first parameter, which let's you identify which "plugin" was requested.
Also, NP_GetMIMEDescription() needs to be adjusted (used on Linux and Mac OS).
On Windows you should have the list of mimetypes, seperated by |, in the version info (entry MIMEType).
I have 10.000 devices and I want to control them by one c++ application. Devices are server and I can control them only by dll. Dll is written for MFC and it wasn't written by me so i cant chance anything on it.
Dll establishs the TCP/IP communication between devices and my application.Every device has different variables. I need to open a new thread for each incoming connection and load an instance of my dll. I couldn't load the different instances of a dll for each thread. everytime it is using the same dll and same data.
How can load multiple instance of a dll ?
Is there any way to do it with c++.
Thanks in Advance
If the data are static it is not possible to have more instance in the same process. You have to modify the dll to have some sort of per context data ( usually class instance would do ). As a general suggestion anyway, never starts up to 10000 thread on a process, this will kill the performance. Write a thread pool and let manage the client be served by that pool.
Your situation does not sound hopeful.
Windows will not load more than one instance of a DLL within a given process, ever. If the DLL itself doesn't have the functionality to connect to multiple servers, you would have to create a separate process for each server you need to connect to. In practice, this would be a Bad Idea.
You COULD use LoadLibrary() and UnloadLibrary() to "restart" the DLL multiple times and switch frantically between the different servers that way. Sort of a LoadLibrary()... mess with server... UnloadLibrary()... do it againandagainandagain situation. It would be painful and slow, but might work for you.
The only (ugly) way to load a dll multiple times is for every new load you make a copy of the original dll with a unique name in a location that you're in control of.
Load the copy with LoadLibrary and setup appropiate function-pointers (GetProcAddress(...)) to functions in newly loaded dll for use in your program.
After you're done with it Unload the copy with FreeLibrary and remove the copy from disk.
I don't see an easy solution to this, as previously covered, you can't create multiple instances of a DLL within an app.
There may be a horrible solution, which is to write a lightweight proxy to listen for inbound requests, and spawn a new instance of the real app on each request, and forward traffic to it - there should be a way to load a new copy of a DLL in each instance (technically you'll be re-opening the same loaded DLL, but it should have separate data spaces).
However, with 10k devices, performance will be horrible. It sounds like the best solution is either to re-implement the protocol (either use a published spec, or reverse-engineer it).
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.
One part of some software I have written is a COM dll.
Other software uses this COM dll.
My software has an update function where it will download a newer version of the dll, but the update will fail if the dll is in use because the file cannot be deleted or written to.
The question is, how can I update a COM dll that is in use?
I have considered popping up a message asking the user to close any applications that are using the DLL if it is in use, if this is the best solution how would I go about detecting if the COM dll was in use before popping up the message?
Thanks in advance.
You cannot update it in place for existing applications, but one way to do this would be to save it with a different file name or different folder and call DllRegisterServer on the DLL to register it under the new name. New applications which begin using your object should now use the new version.
If this is just a matter of detecting whether you can replace the file then it is easy. Just try to open it with a share flag that denies reading. That's going to fail if the DLL is loaded in another process. Use _fsopen() or CreateFile(). Beware of the race condition.
Detecting which processes have the file loaded is a harder problem, CreateToolhelp32Snapshot() and Process32First/Next plus Module32First/Next to enumerate processes and the DLLs they have loaded. Still tough to generate a good diagnostic for the user, the process name isn't that helpful.
When you have downloaded the update, you must launch a third program (which you write) that does not have any dependancies on your COM component, or any other piece that is to be updated. This launcher, or bootstrapper, must shut down all your pieces, uninstall them, and install the update. When the update is installed you may then re-launch your application.
If you need also to download updates to the updater itself, your main program can do that.
Here is a simple solution for you. Create a wrapper DLL, which will be used by the other processes. Inside that DLL you explicitly load/unload your DLL, which is subject to updates. Of course you will have to suspend all callers when an update process kicks in.