SWV 6.1 SDK Guide Part 5: Layer Visibility & Dependencies
The last set of new features to Software Virtual Solution 6.1 is Layer Visibility, which is called Layer Isolation by some, and Dependent Layers-layers that are required by other layers to work. Both of these two features work together in that a layer set to be hidden from all other layers will still be visible to the dependent layer, likewise a layer that's flagged to not be able to see any other layers will be able to see it's dependent layers.
Changes to the FSL2 Class
ManagedSVS.cs has several new methods added.
SVSConst.cs has had some new flags added.
You can download the newest version of the FSL2 Class from the download portal.
In SWV 6.1 there are three visibility flags, or rules, that can be set that effetely hide the layer from something or something from the layer, these flags can also be combined to allow for less visibility. The three flags are:
- Hide Other Layers (LAYER_VIS_FLAG_HIDE_OTHER_LAYERS)
- Hide From Other Layers (LAYER_VIS_FLAG_HIDE_FROM_OTHERS)
- Hide From Base (LAYER_VIS_FLAG_HIDE_FROM_BASE)
When one, or multiple, of these flags are set a layer's registry and files are hidden and can't be seen by who the layer is being hidden from. In the case of the base nothing, including Explorer, will be able to see the files so to be able to launch the app inside you'll need a layer dependency or you'll need to run a command prompt from the layer so you'll be able to see inside.
With the two other visibility rules, Hide Other Layers and Hide From Other Layers, it's an all or nothing approach as you cannot designate what layer's can or cannot see the layer(s) in question. The exception to this rule is Dependent Layers which ignore layer visibility.
An example of this would be having two conflicting Java Runtime Environments (JREs) in two different layers, you can set Hide From Other Layers for both of them and then add any layers that have the Java apps in them to each JRE layer so your apps only see the version of Java that they need to run.
private static extern UInt32 getLayerVisibility ( string fslGUID, ref UInt32 flags );
The first of the two visibility API GetLayerVisibility returns an integer based off the visibility flags that are set. Since you can have more then one flag set per layer, by adding the flags together, this number could be several different combinations. The values for each flag, as defined in SVSConst.cs, are:
LAYER_VIS_FLAG_HIDE_OTHER_LAYERS = 1
So if you got a 12 returned you would know that the layer was hidden from the base as well as all other layers.
private static extern UInt32 setLayerVisibility ( string fslGUID, UInt32 flags );
SetLayerVisibility is pretty much identically to GetLayerVisbility in terms of operations the only different is you're passing in a number for flags that is a combination of the three available visibility rules. To set more the one visibility rule just add the flags together like so:
A Dependent Layer is one that is required by a second layer to run properly, such as Java is required by a Java App so you'd set your Java layer as dependent to your Java app. As explained above in Layer Visibility any dependencies ignore visibility, but they do more then that. If a layer has a dependent layer, and that layer isn't active, when you try to activate the main layer the dependent layer will activate first thus allowing the layer with the dependency to work. In our above java example if you activate your Java app layer SWV would activate the Java Runtime Environment layer first making sure that your Java app could run.
It is possible to chain dependencies, so A depends on B which depends on C, but if B was already activate, and C wasn't, C will never activate so you need to be aware of possible problems that can arrive from doing this.
private static extern UInt32 addDependentLayer ( string fslGUID, string fslDependentGUID );
To add a Dependent Layer you need to know what the layer is that needs the dependency, a Java app for example, which is the fslGUID parameter and which layer is the dependent layer, JRE, which is the fslDependentGUID. AddDepenentLayer only allows for you to add one layer dependency at a time, if you need to do multiple entries use SetDependentLayer.
private static extern UInt32 getDependentLayerList ( string fslGUID, string lpData, UInt32 lpcbData );
SetDependentLayerList will return a list of all the dependent layers associated with a specific layer. To use this API you need to first call it once with lpData set to null which will return the size of the string buffer. With .Net this will not work, you get an access violation if you do but there's another way to get this function to work-if you set lpData to being empty ("") then the error code returned will be the size of your buffer. The following code demonstrates what you need to do for .Net:
string myDependentList=""; UInt32 myBuffer = 0; UInt32 result = 1; myBuffer = FSL2.getDependentLayerList(myGuid.ToString(), myDependentList, myBuffer); result = FSL2.getDependentLayerList(myGuid.ToString(), myDependentList, myBuffer);
The first time we're calling getDependentLayerList we're not checking for a valid result, instead we want to get the buffer size and then the second time, once we have the correct buffer size, we want to actually see if anything is returned. Note that if the buffer size comes back as 0 there are no dependent layers.
In the list that's returned each Dependent Layer's GUID is separated by a null character (\0) and the end of the list is designated by two null characters (\0\0). If you read Part 4 of the SWV guide you'll recognize this as the same as the AutoRun Process list that's returned.
public static extern UInt32 removeDependentLayer ( string fslGUID, string fslDependentGUID );
RemoveDependentLayer works just like AddDependentLayer, you pass in the GUID of the layer with the dependencies and then the GUID of the Dependent Layer you want to remove.
public static extern UInt32 setDependentLayerList ( string fslGUID, string lpData, UInt32 lpcbData );
SetDependentLayerList works very much like GetDependentLayerList except you don't have to initialize the buffer first. You first need to create a string containing all the GUIDs you want to add with each GUID separated by a null character (\0) and then end the string with a double null character (\0\0). To get the buffer size, lpcbData, you can use the following C# code:
Basically, the above code, takes the length of the string being passed in, converting that length to a string and then parsing it into an unsigned integer.
If you pass in an empty string for lpData then SetDependentLayerList will delete all dependent layers from the layer who's GUID is passed in.
Seeing it in Action
This basic example will show you how to set up two layers, each with their own dependencies, with isolation set for each layer.
FSL2 mySVS = new FSL2(); StringBuilder myGuid = new StringBuilder(FSL2.MAXIDLEN); StringBuilder myGuid2 = new StringBuilder(FSL2.MAXIDLEN); StringBuilder myGuid3 = new StringBuilder(FSL2.MAXIDLEN); StringBuilder myGuid4 = new StringBuilder(FSL2.MAXIDLEN); FSL2.createLayer("testLayer", FSL2.LAYER_TYPE_NORMAL, true, myGuid); FSL2.createLayer("testLayer2", FSL2.LAYER_TYPE_NORMAL, true, myGuid2); FSL2.createLayer("depenentLayer", FSL2.LAYER_TYPE_NORMAL, true, myGuid3); FSL2.createLayer("depenentLayer2", FSL2.LAYER_TYPE_NORMAL, true, myGuid3); FSL2.addDependentLayer(myGuid.ToString(), myGuid3.ToString()); FSL2.addDependentLayer(myGuid2.ToString(), myGuid4.ToString()); FSL2.setLayerVisibility(myGuid.ToString(), FSL2.LAYER_VIS_FLAG_HIDE_FROM_BASE); FSL2.setLayerVisibility(myGuid2.ToString(), FSL2.LAYER_VIS_FLAG_HIDE_FROM_OTHERS + FSL2.LAYER_VIS_FLAG_HIDE_OTHER_LAYERS);
Here we're creating four layers, so we have to define 4 GUID StringBuilders, and then we take the third and fourth layers and add them as Dependent Layers to the first and second layers. Lastly we define the layer visibility of the first two layers.
This ends the SWV 6.1 SDK Guide for now. I may revisit the guide to add KepInLayerPattern which I've avoided for now since the feature isn't fully finished at the time of the release of SWV 6.1 MP1 (which this guide was based off of).