Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Registration Free Com and dll manifests

I'm trying to setup registration free COM, but have a slight problem in that I another COM object may be the client.

App.exe----->COM Server/Client dll(registered or not)-------->COM Server DLL (NOT Registered)

My questions is, is it possible to create a manifest for the second dll (COM Server/Client dll)? I do not have control of the executable, but if I did, this works if I create a client manifest for the executable and a server manifest for the COM server dll.

this is the manifest file for the middle dll. I tried embedding it and tried it external. Still doesn't work.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
  <assemblyIdentity type="win32" 
                    name="COMCliSer.dll" 
                    version="1.0.0.0" 
  />
  <dependency>
    <dependentAssembly>
      <assemblyIdentity 
                     name="COMSer.dll" 
                    version="1.0.0.0"                    
      />
    </dependentAssembly>
  </dependency>
</assembly>

On further investigation, I can get this all to work as long as the middle dll is also registration free and the exe has an application manifest. As soon as I register the middle dll, and drop the application manifest (I do not have control of what exe will use my dll), the whole thing stops working.

If the exe has no manifest, then the dll's manifest is not taken into consideration. I can prove this by setting up everything to work. Then putting a mistake in the assembly manifest. This pops up the usual message :

Unable to create process: This application has failed to start because the application configuration is incorrect. Reinstalling the application may fix this problem.

If I then drop the application manifest, the application loads (albeit the CoCreateInstance fails because the dependencies are not taken into consideration)

like image 911
Steve Avatar asked Oct 19 '10 16:10

Steve


1 Answers

Just add an assembly dependency to the server/client dll's manifest that points to the com server dll.

Remember that assembly manifests are different to 'application' manifests: An assembly manifest describes an assembly: gives it a name, and lists its dlls. An application manifest is the RT_MANIFEST embedded resource, which describes the current modules dependencies.

So, in the final analysis, you would have:

  • app.exe, with an external (app.exe.manifest) or embedded RT_MANIFEST describing a dependency on an assembly called 'acme.clientserver'
  • acme.clientserver.manifest describing an assembly, and listing 'clisrv.dll' as a registration free com dll.
  • clisrv.dll, with an external (clisrv.dll.2.manifest) or embedded RT_MANIFEST, describing a dependency on an assembly called 'acme.server'
  • acme.server.manifest, describing an assembly, listing serv.dll as a registration free com dll.
  • serv.dll - which may, or may not in turn have a manifest listing yet more dependent assemblies.

It is technically possible to call the assembly by the dll's name, and merge both the assembly and dll manifest together - the win32 loader supports this, but some settings that are valid in application manifests are not valid in assembly manifests, which can cause the resulting assembly to fail to load. It also makes it very hard to digitally sign.


WRT the exe having to have a manifest: Usually the exe's manifest sets up the processes default activation context. I'm not 100% sure how windows behaves when the exe has no manifest, but I'm pretty sure that manifests in dlls will still be processed.

Which means the problem comes down to the lack of isolation support in CoCreateInstance - for some reason - by default - CoCreateInstance only looks in the default activation context for reg free com entries.

The way to override it is to manually build your own activation context, using the Activation Context API

The basic method would be to call:

  • CreateActCtx - to create an activation context from your dlls manifest.
  • ActivateActCtx - to activate the context
  • CoCreateInstance - will now search the current activation context for reg free com entries.
  • DeactivateActCtx - to restore the default activation context.

You can add /D ISOLATION_AWARE_ENABLED to wrap most windows calls that are effected by activation contexts, for some reason CoCreateInstance is not wrapped :/

like image 192
Chris Becke Avatar answered Nov 11 '22 23:11

Chris Becke