I would like to have multiple test clients, and would like to associate one one com server exe for serving each of test clients.
So far what I can see is in my system there is only one COM server exe running which is serving all my test clients.
Please advice how to achieve this in COM.
Regards
Ashish
Your first server probably calls CoRegisterClassObject, which means that the second client finds an available class object (using CoGetClassObject, probably via CoCreateInstance).
CoRegisterClassObject has optional REGCLS flags which control reuse. Sounds you want REGCLS_MULTI_SEPARATE.
Related
I will try to explain this problem to the best of my abilities. I have a VB6 application (call it APP1) that consumes a DLL, which in turns communicates with a COM port (probably irrelevant). The issue with the DLL(probably because of the com port) that it can be consumed only by one application at a time. I am running another application (APP2) that wants to get a status reading from APP1 on that comm port, at any time. Both apps are running independently. Is there a way to expose something out of APP1 so I can read it real time in APP2? Again, my limitation is that both apps are written in VB6, and currently I have no resources to re-write them.
Thank you.
I have a network critical Windows 7 service. It must start before any network related service on the system, or that network service may fail. My service requires that Winsock is fully initialized by the time it runs.
How can I coerce Windows to load my service at the appropriate time? i.e. Immediately after Winsock is available.
I used the LoadOrder utility by MS Sysinternals. Found out the group should be "NetworkProvider". Also, since the loader loads in lexicographical alphabetical order, I named my process prefixing "Z" so it will load last in the "NetworkProvider" LoadOrderGroup.
You can make your service depend on other services using the depends option. To make other services dependent on your service, you'd need to set their dependencies.
I have a COM server LocalServer32 EXE started when a client application calls c_com_ptr::CreateInstance (using ATL wrappers.)
On Windows 7, when a second client application running under the same user account also calls c_com_ptr::CreateInstance, a second copy of the EXE is launched running under the same user account. I was under the impression, from a past life, that the second client would share the first EXE.
Is the LocalServer32 process shared, or not? When, or when not? Googling for an answer gives me a huge noise to signal ratio and I can't find the answer.
My CLSID registry key has the LocalServer32 value giving the EXE path, ProgID, Programmable (empty string), TypeLib (GUID), and a VersionIndependentProgId. I have an AppID key.
I do not want to run the EXE as a service, and I don't mind that the process is not shared. I just want to know the rules so I know what to expect (on Windows Server 2003 onwards.)
EDIT: Following Chris' answer below, I examined the CoRegisterClassObject call in my server. I'm using ATL, and I overrode MyServer::RegisterClassObjects to hook into the calling chain to CAtlExeModuleT::RegisterClassObjects and see that ATL is using CLSCTX_LOCAL_SERVER and REGCLS_MULTIPLEUSE.
Changing this to CLSCTX_LOCAL_SERVER and REGCLS_SINGLEUSE causes more processes to be started, depending on the number of COM objects created by the client, as expected.
Still, going back to REGCLS_MULTIPLEUSE, I get one COM server process per COM client process, each server process containing all of the COM objects for its client, as expected, except that if two COM clients are running under the same user account, they each get their own server which is not how I understood REGCLS_MULTIPLEUSE.
Could the difference be that the clients themselves are actually Windows services? (They are.) When a Windows service process running as a user account creates a COM object under REGCLS_MULTIPLEUSE, is this treated differently, causing the observed behavior? Why am I getting more than one process? (And just to clarify, I do not want my COM server to run as a Windows service, but the clients that use it do run as Windows services.)
Also, running the clients as either Local System, or Network Service, REGCLS_MULTIPLEUSE works as I would have expected: only a single COM server EXE process is started. The multiple processes are started when the COM clients are Windows services running under user accounts.
The routing of out-of-process activation requests is controlled by the registration of class objects with the COM Service Control Manager. If the SCM has a usable registered class object, that will be used to service the request. If it doesn't, it will start an exe process instance of the COM server to get one. Whether multiple activation requests are routed to a single COM server exe process therefore depends on the following factors at least (I'm not sure if this is a complete list):
the activation flags specified by the COM server when it calls CoRegisterClassObject to register with the SCM can cause future activation requests to result in a new exe process instance being started, the simplest and commonest case being the use of the flag REGCLS_SINGLEUSE, which allows the registered class object to be used for a single activation only.
Depending on how the class is registered, activation requests from different security contexts may be serviced by different COM server exe instances (it seems this won't apply in your scenario as your client applications run under the same security contexts).
I would like to improve the way how an application is checking that another instance is not already running. Right now we are using named mutexes with checking of running processes.
The goal is to prevent security attacks (as this is security software). My idea right now is that "bulletproof" solution is only to write an driver, that will serve this kind of information and will authenticate client via signed binaries.
Does anyone solved such problem?
What are your opinions and recommendations?
First, let me say that there is ultimately no way to protect your process from agents that have administrator or system access. Even if you write a rootkit driver that intercepts all system calls (a difficult and unsafe practice in of itself), there are still ways to use admin access to get in. You have the wrong design if this is a requirement.
If you set up your secure process to run as a service, you can use the Service Control Manager to start it. The SCM will only start one instance, will monitor that it stays up, allow you to define actions to execute if it crashes, and allow you to query the current status. Since this is controlled by the SCM and the service database can only be modified by administrators, an attacking process would not be able to spoof it.
I don't think there's a secure way of doing this. No matter what kind of system-unique, or user-unique named object you use - malicious 3rd party software can still use the exact same name and that would prevent your application from starting at all.
If you use the method of checking the currently executing processes, and checking if no executable with the same name is running - you'd run into problems, if the malicious software has the same executable name. If you also check the path, of that executable - then it would be possible to run two copies of your app from different locations.
If you create/delete a file when starting/finishing - that might be tricked as well.
The only thing that comes to my mind is you may be able to achieve the desired effect by putting all the logic of your app into a COM object, and then have a GUI application interact with it through COM interfaces. This would, only ensure, that there is only one COM object - you would be able to run as many GUI clients as you want. Note, that I'm not suggesting this as a bulletproof method - it may have it's own holes (for example - someone could make your GUI client to connect to a 3rd party COM object, by simply editing the registry).
So, the short answer - there is no truly secure way of doing this.
I use a named pipe¹, where the name is derived from the conditions that must be unique:
Name of the application (this is not the file name of the executable)
Username of the user who launched the application
If the named pipe creation fails because a pipe with that name already exists, then I know an instance is already running. I use a second lock around this check for thread (process) safety. The named pipe is automatically closed when the application terminates (even if the termination was due to an End Process command).
¹ This may not be the best general option, but in my case I end up sending data on it at a later point in the application lifetime.
In pseudo code:
numberofapps = 0
for each process in processes
if path to module file equals path to this module file
increment numberofapps
if number of apps > 1
exit
See msdn.microsoft.com/en-us/library/ms682623(VS.85).aspx for details on how to enumerate processes.
we have a windows service running and we also have a console application that we use to configure this service, we also have an option to see some log being recorded.
The very ugly thing with this is that this communication is made by a text file, the console app writes to a text file and the service reads it and vice versa.
What would you use for this communication? TCP/IP is not an option because the console app will be used for the local running service only.
Windows API SendMessage should be the way to go?
thanks!
I would recommend WCF as the first thing to consider for all comms on windows if using .net as its built for this kind of thing and its relatively easy to use. Since you're excluding TCP, I'd suggest using the Named Pipes Binding.
There are also an number of windows comms apis available for intra-machine comms. Named Pipes (as mentioned), MailSlots, Shared Memory (Memory Mapped files) etc.
My suggestion would be be use Named Pipes either with WCF or natively.
You run less risk of deadlocks if you use non-blocking methods of message passing. PostMessage, or SendNotifyMessage are better than SendMessage because they don't block the caller.
But they depend on the service having a window handle. Does it?
You can also use the WM_COPYDATA message, to pass more than just a wParam a lParam. If you use this message with PostMessage, you need to be careful not to free the memory until the receiver is done with it. It's safest to use SendMessage for WM_COPYDATA.
Shared Memory? See here for an article on Codeproject, here's another fastipc article on the same site. There's a blog entry detailing on how to use a memory mapped file for sharing via a wrapper.
Hope this helps,
Best regards,
Tom.