Way to get IShellExtInit to work out-of-process - winapi

I'd like to pass an IShellItemArray to an out-of-process COM object residing within an exe. I'd prefer to use existing interfaces before creating my own, so I thought I'd try having the out-of-process object implement IShellExtInit. Seemed like a good fit.
Anyway, it appears that attempting to create/query interface for IShellExtInit fails for out-of-process COM servers. I found some additional evidence indicating that it's not possible because that particular interface lacks marshaling support.
Is there anything that can be done to fix that, short of defining my own similar interface (with the oleautomation attribute)? Alternatively, are there any other existing generic interfaces, that work out of process, for passing an IShellItemArray? Thanks for any info.

IExecuteCommand is supported out-of-proc where IObjectWithSelection is the way the array is passed. Might only work on Win7 and later.
IDropTarget is also supported out-of-proc but it is more work (fake dropping a data object). It works back to at least WinXP if you care about that.

Related

How does COM/Automation do IPC under the hood?

In its simplest form, COM allows you to instantiate C++-like classes from DLL in your application. Basically it's a glorified wrapper around LoadLibrary and some conventions regarding the interface. This is called using an in-process component.
But COM also supports out-of-process components. If you instantiate a class from such a component, COM starts a new process. Your objects live in said process, and are marshalled transparently over to you, so you don't care too much about where they live. They might even be on a different computer (DCOM). You can also fetch objects from already running applications. A well-known example is controlling MS Office via a script. This is called Automation (formerly OLE Automation, and there is a bit of confusion around what exactly this term encompasses).
There are a couple of nice articles explaining how (in-process) COM works low-level (e.g. COM from scratch. I'd like to know how it works when your component is out-of-process. Especially, what IPC does COM use beneath the hood to communicate between the processes? Window messages, shared memory, sockets, or something else? MSDN lists COM as an IPC method by itself, but I'm guessing it has to use something else underneath. Are different IPC methods used in different cases (instantiating an OOP component from C++, accessing an Excel document from VBScript, embedding a document in another via OLE)? It seems like it is all the same underlying technology. And lastly, how does marshalling fit in the picture? I believe it is neccessary to serialize method parameters for transmitting between processes, correct?
According to this MSDN article, it's RPC.
When you instantiate an OOP component, the COM subsystem generates an in-process proxy. This proxy is responsible for packing parameters and unpacking return values. It also generates a stub in the server process, which, expectably, unpacks parameters and packs return values.
Interestingly enough, the whole marshaling process can be customized, by implementing IMarshal.
DCOM was originally added as an extension to COM, precisely for cross apartment calls. Note cross apartment calls are not always from process to process. A process can have many apartments (0 or 1 MTA and/or 0 to n STAs, etc.) . There is at least one apartment per process, etc.
DCOM, some kind of a "middleware", needed a technology for all this low-level work: data representation, caller/callee convention, memory management, wire marshaling, session handling, security, error handling, etc. so Microsoft naturally used the in-house implementation of DCE/RPC: MSRPC. Note that as Microsoft says on its site,
"With the exception of some of its advanced features, Microsoft RPC is
interoperable with other vendors’ implementations of OSF RPC."
There was some tentative work to have all this implemented by other vendors, but they were basically killed by the rise of the internet and HTTP.
Also, note this RPC uses Windows Messages for STA apartement messages. I suggest you read carefully this document (not available any more on Microsoft site, shame on them :-) for more details:
DCOM Architecture by Markus Horstmann and Mary Kirtland - July 23, 1997 .
See also this interesting case study about a DCOM/RCP issue that should tell you a lot of how RPC over Windows message works under the scene: Troubleshooting a DCOM issue: Case Study

Requirement for exposing a COM Object

In powershell, when using new-object to instantiate, or get a reference to (or whatever you want to call it), a COM object I recall that the COM object needed to have a certain property to be able to expose it's functionality (through the registry I think is how it did it, via its Class-Id or something).
I can't for the life of me remember what the technical term for the "exposing" was, just that if the object/module/dll/assembly wasn't configured appropriately, the object wasn't available for instantiating with new-object (so that you couldn't just start instantiating objects within 3rd party software I assume is why an explicit setting must be made).
If anyone knows what this term is called it would be very helpful. Its the first step I'm taking in reusing a clients software functionality from a webservice, so I don't have to rewrite all over.
Much appreciated...
You have to register the COM server (binary) which creates a number of registry entries. The primary one PowerShell needs is the ProgID. Also, register a typelib should help PowerShell provide you with member information on the created object. You typically use regsvr32 for a native COM binary and regasm for a managed COM binary.

Does proxy/stub expose the interface?

Suppose I introduced a COM interface and don't want any third party to use it. I have full control over the sources of the COM component and the IDL file that holds the interface definition. My COM component will need marshalling stuff fro that interface, so I'll need to either implement IMarshal or provide a typelib or provide a proxy/stub.
Obviously if I provide a typelib anyone can inspect it and find what my interface is and how it can be used. That's not what I want.
What if I use proxy/stub? Will it expose the interface and let anyone inspect it or will it keep the interface details covert?
Unfortunately this is not possible. The idea of COM is that clients can discover the components and the interfaces.
In a previous job I worked on a digital rights equipped application and there we deliberately did NOT use COM just to make it more difficult for people to tap into our application. We had to build our own component infrastructure (in addition to other security measures).

How to tell, using Perl, if a windows service is stalled, but still running

I have a problem that probably is not unique, but certainly does not seem to be widely reported.
I need a method to ping a windows service that will tell me if it has stalled out, even if windows is reporting that it is running.
I would prefer to use have a Perl solution but would accept any solution that someone can come up with.
Thanks,
Jeremy
What service are you dealing with? I don't think there is any generic solution to your question if the Services control panel doesn't indicate a problem. In order to detect a running-but-no-longer-functioning-properly process, you have to know what "functioning properly" looks like.
You could use the Win32::Service module
use Win32::Service;
GetStatus(hostName, serviceName, status);
From http://metacpan.org/pod/Win32::Service:
Get the status of a service. The third argument must be a hash reference that will be populated with entries corresponding to the SERVICE_STATUS structure of the Win32 API. See the Win32 Platform SDK documentation for details of this structure. You can even grab the service with GetServices(hostName, hashref).

Is it possible to prohibit putting my in-proc component into COM+?

I have an ATL C++ in-proc COM component. This component is not for external use - I only need it for use in our application.
Once in a while users put it into COM+ and this leads to all sorts of weird errors - "Access denied", etc which I'd like to just never hear about. The best way would be to do something that would prohibit putting the component into COM+ so that it can only be used as an in-proc server. Is there a way to do this?
Do you implement only your own interfaces? If so, you should be able to mark them "[local]" in the IDL, and then strip the module of all marshalling information (type library, P/S), etc.
If there's no basis for marshalling available, COM+ shouldn't be able to register the module. COM+'s mechanism for interception relies on forcing objects into a remote context and getting in between the proxy and stub and their corresponding parties. So, if you remove every opportunity for marshalling, it shouldn't be able to intercept your interface methods.
Prevent registering your module is finalized and then use your DLL as described in this article Creating COM objects directly from the dll.

Resources