App-V: On COM Isolation and Interaction

 

Through the history of Windows, the COM (Component Object Model) has been integral to application development the as an interprocess communication mechanism. The roadmap from DDE (Dynamic Data Exchange,) to OLE (Object Linking and Embedding,) to OCX (OLE Custom Controls,) to ActiveX – and so on – allowed and continues to allow multiple languages and development environments to develop applications on this language-agnostic platform.

Because COM facilitates communication channels and data exchanges between applications, it requires both significant consideration and planning when determining the feasibility of application virtualization. App-V has its own virtual COM subsystem which is designed to isolate the COM interactions from the local operating system. The primary way it does this is through GUID spoofing.

COM uses CLSIDs (Class Library Shell Identifiers) to identify all of its components and interfaces. These are labeled using GUIDs just as many other things are in Windows Different component types are identified by class IDs (CLSIDs), which are Globally Unique Identifiers (GUIDs). Each COM component exposes its functionality through one or more interfaces ({7312498D-E87A-11d1-81E0-0000F87557DB} is my favorite because it is “blur.”) The different interfaces supported by a component are distinguished from each other using these identifiers. One of the strengths of App-V is that it prevents COM conflicts among native and virtual applications and among applications running in different virtual environments. App-V is also able to isolate native and virtual COM servers within a virtual environment.

When App-V hooks into a process, the virtual COM subsystem is able to intercept and virtualize COM object instantiations by dynamically cloning COM registration within the virtual environment using auto-generated CLSIDs and start instances of the cloned COM server. The GUID mappings will be maintained throughout the life of the process. While the hook model is different between App-V 4.x and 5.x, the overall process is very similar. When you combine applications into multiple virtual environments (DSC, Connection Groups) or package multiple applications together into a single package, all of these applications will still be able to communicate with each other at the application level through COM.

Basic Planning

For the majority of applications, you will likely only need to consider COM at a high level when planning. I like to use scenarios and I often do when I am explaining this to customers.

 

In the example above, we have a simple scenario. We have Application A (Word) and there is an embedded object type of Application B that can be inserted and modified leveraging the controls of Application B. Oldest and most known method as it goes all the way back to OLE. In the world of App-V this may still be needed with virtual applications. How do we facilitate this?

1.)    If your plan is that Application A is virtual and Application B is virtual – then you will have to either:

-          Package Application A and B together in a single sequenced virtual application package

-          Package Application A and B separately but join them via a unified virtual environment (using DSC with 4.6 or Connection Groups with 5.x.)

2.)    If your plan is that Application A is virtual and Application B will be locally installed – then you will need to:

-          Configure COM integration/interaction with the local operating system. The method varies depending on the version of App-V you are using.

3.)    If your plan is that Application A will be local and that Application B will be virtual – then you will have to do one of the following:

-          Create an extension point (shortcut) to the local application (A) within the configuration of the virtual application (B) and will have to launch the local application using that extension point so it will be hooked.

-          Create an extension point (shortcut) to the local application (A) within the configuration of an otherwise empty virtual package. Bring that package and the virtual application (B) into the same virtual environment using DSC or a Connection Group (depending on what version you are using.)

-          Use the “RunVirtual” registry key if you are using App-V 5.0 to allow the local process (A) to operate inside the virtual environment of the virtual application (B.)

 

Because some applications may still need to communicate with the local operating system, there may be the need to adjust and fine-tune COM behavior for certain applications (as in the case of #2 above.) App-V historically has had ways of doing this.

 

App-V 4.x: LOCAL_INTERACTION_ALLOWED

This is a tag in the XML configuration (OSD file) of an App-V 4.x application. Whehn this tage exists and is set to TRUE, this means that BOTH object/eventing virtualization (spoofing) and COM GUID virtualization (also spoofing) are turned off. This DOES NOT mean the virtual COM or the virtual object subsystems are turned off. The objects will still be looked up in the virtual environment, but if not found, App-V will revert to the native OS and look there as well. This is why it is usualy a fairly safe thing to implement. The primary App-V 4.x hook DLL (SFTLDR.DLL) is still injected with all of its subsystems.

To enable local interaction, the OSD VIRTUALENV element is configured as follows:

<VIRTUALENV>

<POLICIES><LOCAL_INTERACTION_ALLOWED>TRUE</LOCAL_INTERACTION_ALLOWED></POLICIES>

</VIRTUALENV>

Objects/Eventing will be discussed more in detail and in a forthcoming post.

 

App-V 4.x: Disabling and/or Micromanaging Virtual COM

You can manage COM in more detail within App-V 4.6 by configuring the client registry. This is generally not preferred as it globally affects the App-V Client where LOCAL_INTERACTION_ALLOWED applies only to the application package. If you want to disable the Virtual COM subsystem, you can navigate to the following registry key and set the following value:

HKEY_LOCAL_MACHINE\Software\Microsoft\Softgrid\4.5\SystemGuard\Overrides

Value: DisableGuidMapping

Data Type: REG_DWORD

Value: 1

Outside of troubleshooting, I find it illogical and dangerous to disable this as a solution to any virtualization problem. I would only advise doing this as a troubleshooting step. Once you realize what may be happening you can simply apply a more granular approach to permanently fixing the solution by excluding COM GUID spoofing for the troublesome application. You do this through COM exclusions. First create a subkey called ComExclusions beneath:

HKLM\SOFTWARE\Microsoft\SoftGrid\4.5\SystemGuard

Then create a value called “Exclusions” with a data type of REG_MULTI_SZ and then you will list all of the CLSID GUIDs that you want excluded on each line.

The App-V 5.0 Virtual COM Subsystem

COM integration in App-V 5 does out-of-process (its own process) and in certain cases - in-process (within a process) COM registration (Office 2013 Click2Run.) COM is also handled a little more granularly in the dynamic configuration files in App-V 5.0. This is to encourage more handling of COM through configuration policy on a per-package or per-connection group basis. Within this policy, you can set one of three modes:

  • Off
  • Isolated (Virtualized)
  • Integrated (through in-process or out-of-process registration.)

The overall effects are outlined in the following boring chart:

 

 COM Mode in XML

 OS Integration

 COM Virtualization

     <COM Mode=“Off">

    </COM>

 No integration

 Off

     <COM Mode=“Isolated">

          </COM>

 No integration

 On – w/ GUID Spoofing

     <COM Mode=“Integrated">

      <IntegratedCOMAttributes OutOfProcessEnabled="false" InProcessEnabled="false" />

    </COM>

 No integration

 On – no GUID Spoofing

     <COM Mode=“Integrated">

      <IntegratedCOMAttributes OutOfProcessEnabled="true" InProcessEnabled="false" />

    </COM>

 Integrate out-of-process

 On – No GUID Spoofing

     <COM Mode=“Integrated">

      <IntegratedCOMAttributes OutOfProcessEnabled="false" InProcessEnabled="true" />

    </COM>

 Integrate in-process

 On – No GUID Spoofing

     <COM Mode=“Integrated">

      <IntegratedCOMAttributes OutOfProcessEnabled="true" InProcessEnabled="true" />

    </COM>

 Integrate both

 On – No GUID Spoofing

 

I felt it important that you get a sense of all of the possible permutations of COM policy configuration. Especially if you are toggling the sequencer defaults in the “Advanced” tab. All this does is set the default policy in the dynamic configuration file (deployment_config.xml) generated by the sequencer.

 

When “Allow all COM Objects to interact with the local system” is turned off, the COM policy will default to:

    <COM Mode=”Isolated”>

 

When turned on (checked) it sets it to:

    <COM Mode=“Integrated">

      <IntegratedCOMAttributes OutOfProcessEnabled="false" InProcessEnabled="false" />

    </COM>

 

COM Mappings and Exclusions in App-V 5.0

COM GUID Mappings are stored in a COM Class Maps located in the following registry locations:

Per User:

   HKEY_CURRENT_USER\Software\Microsoft\AppV\Client\Packages\{PACKAGE_GUID}\REGISTRY\USER\{SID}\SOFTWARE\Microsoft\AppV\Client\COM Class Map

Per Machine:

   HKEY_LOCAL_MACHINE\Software\Microsoft\AppV\Client\Packages\{PACKAGE_GUID}\REGISTRY\USER\{SID}\SOFTWARE\Microsoft\AppV\Client\COM Class Map

These are helpful when troubleshooting COM. Like 4.6, you can also add individual exclusions within the registry by adding the GUID as a REG_SZ value in

   HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\AppV\Subsystem\ComExclusions

Use the value itself to give a description for humans to read :) For example:

   Value: HKEY_CLASSES_ROOT\CLSID\{7312498D-E87A-11d1-81E0-0000F87557DB}
   Data Type: REG_SZ
   Data: Blur