From an out-of-process COM object (LocalServer32) can I determine the client process that requested the creation of the object? - to be specific I need to get hold of the client processes command line.
This question arrises because (due to poor standardisation, implementation and support) the potential 3rd party clients of the object have a variety of idiosyncracies which the object needs to workaround.
To do this the object needs to be able to identify its current client.
Extending the interface of the COM object so that the client can identify itself is unfortunately not possible ... or to be more precise the interface can be extended but I won't be able to get the clients to call the extension.
Having looked into this further I suspect the answer is going to be "NO", but by all means tell me I'm wrong.
Using Process Explorer I can see that the parent process for my COM object is an instance of "svchost.exe", and not the client application.
Because COM server processes are shared by all clients of the same AppID, it's not possible to actually get the PID of the client application. As #Anders said, you can use CoImpersonateClient (or, better, call CoGetCallContext and interrogate the resulting IServerSecurity) to find the account and login session of the caller, but you cannot get the process itself.
If you are trying to work around bugs in legacy clients, I would recommend you create a new set of CLSIDs (or IIDs, if you can emulate all the bugs the legacy clients rely on with shims) for new (non-legacy) clients with VERY strict input validation, and implement new features only in these new CLSIDs. Legacy clients stick with their older CLSID, in which you can simply use the existing, legacy implementation (or a bug-for-bug compatible clone).
Maybe CoImpersonateClient()
Related
I have an application that imitates state of a vehicle and uses various plugins to transmit data. Each plugin is loaded dynamically and provides protocol-specific implementation for an interface to send the data. By specification each plugin may be operating concurrently and a sending method may be asynchronous.
I would like to be able to share asio::io_context or asio::thread_pool to utilize those resources allocated by the application (core). Each plugin would use asio::strand if needed. I really wouldn't want plugins to spawn new threads.
To provide compiler independence the API for a plugin is in C, hence I can't pass asio entities just like that.
Is it possible though to expose a context or a thread pool to a dynamically loaded dll which may be compiled with another toolchain?
Maybe via some kind of native handles?
Maybe I could wrap a custom executor?
I didn't find any constructors in the reference which would use native handles, etc.
I have an out of process com server, specifying CLSCTX_LOCAL_SERVER as the context, and REGCLS_MULTIPLEUSE for the connection type. This results in a single server process being reused by multiple calls from multiple clients.
I’m now wanting to make some changes to the server, which unfortunately can not work with a single process shared amongst clients (there are reasons for this, but they're long winded). I know you can set the server to use REGCLS_SINGLEUSE as the connection type, and this will create a new process for the OOP server each call. This solves my issue, but is a non-starter in terms of process usage; multiple calls over short periods result in many processes and this particular server might be hit incredibly often.
Does anyone happen to know of a mechanism to mix those two connection types? Essentially what I want is a single server process per calling process. (ie, client one creates a process, and that process is reused for subsequent calls from that client. Client two tries to call the server, and a new process is created). I suspect I could achieve it by forcing a REGCLS_SINGLEUSE server to stay open permanently in the client, but this is neither elegant nor possible (since I can’t change one of the clients).
Thoughts?
UPDATE
As expected, it seems there is no way to do this. If time and resource permitted I would most likely convert this to an In-Proc solution. For now though, I'm having to go with the new behaviour being used for any calling client. Fortunately, the impact of this change is incredibly small, and acceptable by the clients. I'll look into more drastic and appropriate changes later.
NOTE
I've marked Hans' reply as the answer, as it does in fact give a solution to the problem which maintains the OOP solution. I merely don't have capacity to implement it.
cal
COM does not support this activation scenario. It is supposed to be covered by an in-process server, do make sure that isn't the way you want to do it given its rather major advantages.
Using REGCLS_SINGLEUSE is the alternative, but this requires you extending your object model to avoid the storm of server instances you now create. The Application coclass is the boilerplate approach. Provide it with factory methods that gives you instances to your existing interfaces.
I'll mention a drastically different approach, one I used when I wanted to solve the same problem as well but required an out-of-process server to take advantage of bridging a bitness gap. You are not stuck with COM launching the server process for you, a client can start it as well. Provided of course that it knows enough about the server's installation location. Now a client of course has complete control over the server instance. The server called CoRegisterClassObject() with an altered CLSID, I xored part of the guid with the process ID. The client did the same so it always connected with the correct server. Extra code was required in the client to ensure it waits long enough to give the server a chance to register its object factories. Worked well.
I am using a COM dll from a web service.
The COM dll is added as reference. And I am declaring the object as static in Global.asax.
I am creating the COM object in the Application_Start.
I have to call the COM dll interface function in each request.
I am getting exceptions here as memory corruption.I could see the logs that it happens when simultaneous requests come up.
Please let me know what is the best way to do that. How to make it thread safe.?
Try creating a new instance in each request and not use application scope for the object.
If you are accessing it at application scope(eg through Application_Start) you will need to make sure it is safe for multithreading. I don't know how C++ dlls handle threading but you might be able to manage multithreading at the asp.net level.
For example To manage a simple application level counter the code is something like:
Application.Lock();
Application["SomeGlobalCounter"] =
(int)Application["SomeGlobalCounter"] + 1;
Application.UnLock();
For more information you might want to see the MSDN page on Application State.
If the COM object is apartment threaded, COM provides the synchronization to enforce a single execution of a method per thread.
Generally, though, COM should be complaining of multiple threads trying to access an instance of an object using the same pointer shared across threads. Having a static variable holding a pointer to the object is probably a bad idea.
Once the COM object shared library is loaded somewhere (in-proc or out-of-proc) by creating an instance, creation of additional instances per thread should be fairly quick. That is, of course, dependent on what types of things that are being done during object construction.
First what I did (minimum sample will be provided if it's not just me doing something plain stupid):
I have a GUI application that shall support several network interfaces to change content that's displayed in the GUI. The network interfaces are realized as plugins that are dynamically loaded on GUI startup. The GUI application provides a boost::asio::io_service object that it passes via reference to the interfaces so they can use that to build the asynchronous I/O. In the GUI thread this io_service object is than polled to synchronise the network interfaces' access to the content.
The problem now is that the handlers don't get called by the io_service object when it is polled. To narrow this down I implemented only one interface and created the io_service object therein, still calling the poll from the GUI thread and that works.
My question now is: is it possible that there is a general problem with passing the io_service object into DLL functions loaded at runtime?
If the scenario is too unclear, I'll provide a minimum example.
EDIT: I feel really stupid :) Just hacked together a minimum example and that - of course - works like a charm. That pretty much means the problem origins from some other part of the software.
So thanks everyone for their input!
To make this question at least a little bit useful:
Anyone who wants to do something similar (plugins for network synchronized via boost::asio::io_service), you can download the minimum example here.
I would check several options:
* Maybe the object is copied at some point rather than passed by reference; you can make it boost::noncopyable to prevent this from happening.
* Check the return value of poll if it is bigger than 0 some handler was run; if it is 0 the problem is boost think there are no handler.
* Add a test handler in your GUI app to rule out the option it is DLL-related problem.
Happy debugging!
I have an application (A) that needs to launch another application (B). I need to pass data between the applications. I can think of two approaches. The first is to open a socket. The second is to share data via a dll.
The opening socket approach is straight forward.
The dll approach I have some questions? I can load plug-in dlls into B. I want to create a dll that A can use to pass data to B. When loading dlls, is only one instance of the dll loaded? If so, does this mean that data can be shared between applications that load the dll?
What is the better choice?
Are there other ways of doing this?
You can't effectively share data via a DLL. Other ways:
disk files
pipes
shared memory
messages
RPC
CORBA
COM
etc.
The simplest method (assuming Windows since you mention a DLL) is probably to use CreateProcess and open a pipe to the child process, as described in simplified form here: http://msdn.microsoft.com/en-us/library/ms682499.aspx
Named Pipes can be an alternative, especially if you aren't in control of the lifetime of all of the processes. http://msdn.microsoft.com/en-us/library/aa365590.aspx
For simple cases, mailslots may be a sufficient alternative.
http://msdn.microsoft.com/en-us/library/aa365574.aspx#base.using_a_mailslot_for_ipc
Here's a longer list of various Interprocess Communication techniques for Windows.
http://msdn.microsoft.com/en-us/library/aa365574.aspx
For something happening locally, using sockets seems sort of overkill. Plus you have to implement your own security mechanism to prevent spoofing attacks, rather than depending on the integrated security mechanism of most of the other IPC methods.
Its always good to explore alternative possible solutions, but I personally believe that using sockets as a transport layer for data between applications is not only future proof, but scalable as well. Using sockets will eliminate the need for you to write copious amounts of OS specific code, which could proclude you from porting your application in the future to non-Windows operating systems.
I would suggest sockets.
You can have a shared cache (example a windows service or hidden process) that can be listening - returning data to all subscribers. This using a Observer pattern approach.
I would agree somewhat with Juan Zamora M except that the service providing the data should have an API that can be requested when needed not pushed when changed via listeners.
This might help. Sharing Files and Memory