App-V: On Named Kernel Object Virtualization (a.k.a. the VObjects Subsystem)
Virtual Objects: You have also possibly heard this referred to as virtual eventing. You have seen references to this in the context of troubleshooting. You may have possibly used this as a workaround when troubleshooting in 4.x:
Add an asterisk wildcard in the following registry path: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\SoftGrid\4.5\SystemGuard\ObjExclusions
Before you ever do the above again, please read this article.
The question is: what exactly are you doing when you do this and what are the ramifications? Well, first of all, this should NEVER be disabled ad-hominem unless you have a specific reason for doing so. This is especially important in versions prior to V5 where disabling this subsystem actually disabled it for the entire client. Second, if possible, only disable using specific markers for objects pertaining to the application in question. It is understandable to avoid this method as it can be a daunting and tedious task to track these down in the case of some applications. The concept of “disabling virtual objects” in App-V really refers to disabling eventing and essentially everything else under the App-V virtual object isolation subsystem by name or wildcard mask. To understand the function of the virtual object subsystem (or VOBJECT) it will help to have a good understanding of kernel objects in general.
When we speak of kernel objects we are talking about all of the object types that fall into this category, i.e. mutexes, semaphores, base named objects, events, file-mappings, etc. Applications work with objects through the use of handles. This is accomplished by calling a Win32 API that is specific to the kernel object being instantiated. If you want to know more about these individual object types and how they work within the operating system, I would suggest picking up the latest copy of Windows Internals.
When an object is instantiated it is often identified using a string. Because the object is managed by the kernel, this means this object can be leveraged by multiple applications. In the case of App-V, like COM, there is name obfuscation that serves as the isolating factor so it allows for the kernel to still manage these objects and the virtual object subsystem within App-V can allow multiple processes within the same virtual environment to share access to the object.
App1.exe -----> Handle ----> Named Object (ObjEvt1)
App2.exe -----> Handle ----> Named Object (ObjEvt1) (previously created)
Many kernel objects can be named using a string. Because the kernel manages the objects, the name can be used by multiple processes. In the case of the above, Both App1.exe and App2.exe have handles to the named object ObjEvt1. App1.exe can now wait for eventing from App2.exe.
Isolation
Named Kernel objects are isolated by App-V intercepting calls made to create the kernel object and modifying the name in a manner that only the current virtual environment understands. So if you have multiple applications that need to communicate to each other this way, you will need to ensure they belong to the same virtual environment. If you have a virtual application and a local application that will need to communicate with each other in this way, then you will need to disable naming of these objects.
In the case of application conflict resolution, this isolation process allows the virtual applications running in different virtual environments to create the same kernel object, yet have these objects handled differently by the kernel because the names will be different as far as the kernel is concerned. To put it crudely, if two versions of an application called GROUCHOv1.EXE and GROUCHOv2.EXE respectively need to create and “use” the same object (we’ll call it “cigar”) – then virtualizing them separately under App-V will make this possible as one object will actually be called sg<16-hex digit random ID>_cigar and the other will be sg<16-hex digit different random ID>_cigar.
Now, a pre-populated list of exclusions will show up in the registry under both 4.x and 5.x in order for App-V to be happy in the world of Windows. Adding further exclusions and disabling objects as a whole can be done, however, do NOT remove any existing exclusions that are already populated in the client registry. There is absolutely no reason for you to REMOVE any existing exclusions that you did not put in to begin with. When you are troubleshooting the virtual object subsystem, you may want to add in a single “*” to disable eventing for all objects or add in a specific kernel object name or names (preferred.)
4.6 Object Exclusions
In version 4.6, the legacy list of excluded objects were listed here:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\SoftGrid\4.5\SystemGuard\ObjExclusions
A quick way of troubleshooting would be to create a new string value (I’d usually use 1001001) and enter an asterisk (*) as the value. When the application started to work, I could now use Process Explorer or WinObj to help determine what objects were being created. If I weren't lazy, I would go back and only enter those object names for exclusion. If I were lazy, I’d leave in the asterisk. This can be dangerous – especially if I were on RDS or Citrix servers where you may have multiple versions of applications/middleware.
One thing I want to drive home is that changes here were MACHINE WIDE. If you wanted to apply these changes to one package only, you would leverage the LOCAL_INTERACTION_ALLOWED policy in the application’s OSD file – however this would also disable some COM virtualization features which you may not want. Bear in mind this policy element in the OSD file still looks up the objects in the virtual environment, but if not found, it will fall back to the native and check there as well. This is why it was and still is a great troubleshooting AND workaround for App-V 4.x.
To enable local interaction, your OSD VIRTUALENV tag should look like the following:
<VIRTUALENV TERMINATECHILDREN="FALSE">
<POLICIES><LOCAL_INTERACTION_ALLOWED>TRUE</LOCAL_INTERACTION_ALLOWED></POLICIES>
</VIRTUALENV>
App-V 5 and the VObjects Subsystem
There is not much new under the hood in V5 with regards to how isolation of kernel objects happens. There is more flexibility and granularity with configuration.
There is an element within the Deployment Configuration that you can use to turn on or off the VObjects subsystem for a package:
<!--
Objects
-->
<Objects Enabled="true" />
What is great about this is that it will allow you to disable the VObjects subsystem for a package but still allow for COM to be virtualized. During the start of a virtual environment, the subsystem will read the manifest and Deployment Configuration file and combines them together. If there are multiple packages within a connection group, they will be combined as well.
You also still have the method of using the registry to exclude specific objects although I see no reason to use this as a means of disabling the entire object subsystem since you can do this through the XML on a per-package basis.
The exclusion locations in V5 are found in:
HKLM\SOFTWARE\Microsoft\AppV\Subsystem\ObjExclusions
Tools to Isolate Objects
So, when you launch a virtual application, you can easily compare on a clean test machine whether this newly added virtual application package creates kernel objects. All you do is look for the objects that start with the name “sg” then remove that as well as the 16 character numeric identifier preceeding the underscore and everything else to the right of the underscore character is the actual name of the object which you can then use to create a mask for a custom object exclusion. There are two free tools that are great for this:
Process Explorer
When you run Process Explorer and turn on the bottom pane, there will be a view of objects. When you select the virtual processes, you can identify the objects that are virtualized. You will need to sort the object view by name in some cases to make this easier.
WinObj
Winobj is another tool from the Sysinternals Toolkit that is great to use however, you need to ensure that you run it as an administrator in order to get the right session context since this does not view from a process context. It will allow you to catch any objects you may have missed with the above.