Video Screencast Help
Symantec to Separate Into Two Focused, Industry-Leading Technology Companies. Learn more.

SVS 2.X SDK Guide Part 6: OnEvents and Excludes

Created: 13 May 2008 • Updated: 29 Jul 2010 | 2 comments
Language Translations
Jordan's picture
0 0 Votes
Login to vote

OnEvents are one of my favorite features of SVS, they allow you to really expand what you can do with a layer. The currently available tools, however, (SVSCmd, SVSAdmin and even Wise Studio) either don't offer any way to manage them or offer a very poor system for doing so. Thankfully, managing OnEvents with the SDK is very easy.

Changes to the FSL2 Class

  • Several methods have been added.
  • A new Enumeration VzNotification, has been added to SVSStruct.cs
  • Some new constants have been added.

You can download the newest version of the FSL2 Class from the download portal.

OnEvents

There are four onEvent specific functions and one Enumeration. If you read Part 4 -- about layer attributes -- these will look very familiar to you. While we refer to them by OnEvents, the SDK labels them as Layer Notifications.

VzGetLayerNotification

public static extern UInt32 VzGetLayerNotification
 (
   string layerId,
   VzNotification notification,
  [MarshalAs(UnmanagedType.LPStr)] StringBuilder buffer,
   ref UInt32 cbBuffer
 );

VzGetLayerNotification is pretty straight forward. By now nothing here should look unfamiliar. a Guid is passed in as well as a buffer that will contain the value of the OnEvent. Upon success and lastly the size of the buffer is passed. VzNotication is our enumeration that we'll cover shortly. If you pass a null into layerId this method will look in the Global onEvent list.

VzSetLayerNotification

public static extern UInt32 vzSetLayerNotification
(
   string layerId,
   VzNotification notification,
   string buffer,
   UInt32 cbBuffer
);

VzSetLayerNotification is almost identical to VzGetLayerNotification except that instead of a stringbuilder buffer we've got a regular string because we're passing in a value and not expecting one to be returned. If you pass a null into layerId this method will set a global OnEvent action.

VzNotification

public enum VzNotification
 {
    VzNotificationOnPostActivate,
    VzNotificationOnPostCapture,
    VzNotificationOnPostCreate,
    VzNotificationOnPostDeactivate,
    VzNotificationOnPostDelete,
    VzNotificationOnPostExport,
    VzNotificationOnPostImport,
    VzNotificationOnPostReset,
    VzNotificationOnPreActivate,
    VzNotificationOnPreCapture,
    VzNotificationOnPreCreate,
    VzNotificationOnPreDeactivate,
    VzNotificationOnPreDelete,
    VzNotificationOnPreExport,
    VzNotificationOnPreImport,
    VzNotificationOnPreReset
 };

VzNotification is an enumeration and used in the same manner as VzLayerAttribute that was discussed in Part 4. There are 2 event actions for each SVS layer method; pre and post. Some of these can only be used globally while others can be used in layers -- but only if the action you're trying to perform isn't in that layer.

I've created a chart for easy reference in a separate article. It covers how each of the OnEvent actions work under specific situations and who owns the changes caused by an onEvent.

NotificationEventsFlag

SVS 2.1 SP 2 (in beta at the time of this writing) added NotificationEventsFlags which are basically a flag you can set on the layer to ignore global OnEvent actions.

FSL2GetNotificationEventsFlag

public static extern UInt32 getNotificationEventsFlag
 (
    string fslGuid,
    ref bool pbSuppressEvents
 );

GetNotificationEventsFlag takes a Guid and returns a boolean; true if a layer's flag is set to ignore and false if it isn't.

FSL2SetNotificationEventsFlag

public static extern UInt32 setNotificationEventsFlag
 (
    string fslGuid,
    bool bSuppressEvents
 );

setNotificationEventsFlag takes in a Guid and sets the flag to whatever bolean was passed in.

The Meta Directory

I covered Layer Meta Directories in length sometime ago, for those of you that don't want to read the linked article, anything placed in the Meta Directory will not get run from the layer when called by an OnEvent action effectively placing any changes by that process into the layer. There are exceptions, onPreCapture using a global capture, but these will be listed in the aforementioned chart.

There's only one function for the meta directory, but it's very useful.

VzGetLayerMetadirectory

public static extern UInt32 VzGetLayerMetadirectory
 (
     string layerId,
     [MarshalAs(UnmanagedType.LPStr)] StringBuilder directory,
     UInt32 cbDirectroy
 );

VzGetLayerMetadirectory takes a Guid and returns the FSLRDR path (for example: c:\fslrdr\2\Meta) of a layer's Meta Directory as a StringBuilder. If the Meta Directory doesn't exist, then this function will create one before returning the path.

Calling an item in the Meta Directory

When setting up the OnEvent of a layer to call its Meta Directory you need to use %VZ_LAYER_METADIR% as the variable in the onEvent action. For example, if you wanted to do a onPostImport call to run CopyFont.exe then you'd use the following as your string:

string myBuffer = "w, %VZ_LAYER_METADIR%\\CopyFont.exe";

The "w," in that string tells SVS to wait until the OnEvent action is complete before doing anything else.

Global Excludes

Global Excludes are a little different then the other SVS features we’ve covered so far not just because they affect everything in SVS (Global OnEvents do that as well) but because they don’t get their own function for editing and changing them, but instead were added into the layer exclude API. If you pass a Null into FSL2SetLayerExclude then you’ll be setting the Global Exclude list.

However that means that there’s no way, in .Net to enumerate through all the global excludes (because .Net doesn’t like the API in the SDK for doing this), luckily they’re easy to get at because they’re just a key off of FSL in the registry, named “Exclude” which is convenient. Below I’ll give sample code to enumerate through all a layer’s exclude items (which is similar to the datalayer function I gave in Part Five), well you can do the same here by just changing that code to point at the right place in the registry. Like datalayers there are three different exclude types that all excludes use:

  • File extension = 0 (LAYER_EXCLUDE_EXT)
  • Directory Only = 1 (LAYER_EXCLUDE_DIR)
  • Directory and Sub-Directories = 2 (LAYER_EXCLUDE_DIR_AND_SUBDIR)

FSL2ReloadExcludeList

public static extern UInt32 reloadExcludeList();

Once you make any change to the Exclude registry key you need to call reloadExcludeList if you want those changes to take effect without restarting your computer.

FSL2GetGlobalExcludeListIgnoreFlag

public static extern bool getGlobalExcludeListIgnoreFlag
 (
    string fslGUID
 );

Like global OnEvents you can flag a layer to ignore Global Excludes. This is similar to the OnEvent function but it returns a Boolean instead of having a reference passed to it.

FSL2SetGlobalExcludeListIgnoreFlag

public static extern UInt32 setGlobalExcludeListIgnoreFlag
 (
    string fslGUID,
    bool bIgnoreGlobalExcludeList
 );

setGlobalExcludeListIgnoreFlag is the long named function that will tell a layer if it should ignore the Global Exclude list or not. True for yes, false for no.

Layer Excludes

These work the same as Data Layer capture items which means that the enumeration function won't work in C#.

FSL2EnumLayerExclude

public static extern UInt32 enumLayerExclude
 (
     string fslGUID,
     int index,
     [MarshalAs(UnmanagedType.LPStr)] StringBuilder dataPatternBuffer,
     ref UInt32 excludePathBufferLen,
     ref  UInt32 excludeType
 );

This function is almost an exact duplicate of the datalayer enumeration method in the SDK. The only difference is the variable names. As with enumDataLayerItem, the index you pass in doesn't auto increment so you need to take care of that with a loop.

Note: As mentioned above this function doesn't work in C#. However, the excludes are easy to get at and are contained in the Exclude Key under each layer's key. You'll need to know a layer's magic number but that's easy to get at since one of the SVS attributes returns the layer's registry location which is what we need.

Here's a sample function (this isn't in the FSL2 class)

public static void getLayerExcludes(string myGuid, FSL2 mySVS) 
 {
   mySVS.pInfo.dwStructSize = (UInt32) Marshal.SizeOf(mySVS.pInfo);
   UInt32 result = FSL2.getLayerInfo(myGuid, mySVS.pInfo);
   string mySubKey = mySVS.pInfo.regPath;
   RegistryKey myKey = Registry.LocalMachine.OpenSubKey(mySubKey, true).OpenSubKey("Exclude", true);
   foreach (string subKeyName in myKey.GetValueNames()) {
    Console.WriteLine("Exclude Name: " + subKeyName + " value: " + myKey.GetValue(subKeyName).ToString());
   }
 }

FSL2SetLayerExclude

public static extern UInt32 setLayerExclude
 (
    string fslGUID,
    string excludePath,
    int excludeType
 );

With setLayerExclude we're just adding a value to that registry key we enumerated through in the previous section. It doesn't matter if you use this method or if you write your own but a layer will need to be reactivated (not reset) for the exclude to take place. It has to be deactivated when you make the change or deactivated afterwords and then reactivated for the changes to take affect. ExcludeType is one of the numerical values that listed under Global Excludes.

Setting and removing Exclude items is very simple. You pass in a GUID, a value, and the type (which are the same mentioned in the previous section). If you pass in a -1 for the type (LAYER_EXCLUDE_NONE is the constant) that item will get deleted from the Exclude list.

When passing in a directory, this function will not automatically format the path to use the variable system SVS has. For example, C:\Test won't get translated into [SystemDrive]\Test. There is a way to get SVS to do this for you, but it requires multiple steps and there isn't space for in this article. You may want to write your own function to do this.

Seeing it in Action

For this article I'm going to show a function that creates an onEvent handler and adds a file to a layer's meta directory.

Static bool onPostActivate(string myGuid, string myFilePath, string myFileName){
StringBuilder myMetaDir = new StringBuilder(FSL2.MAXNAMELEN);
            FSL2.VzGetLayerMetadirectory(myGuid.ToString(), myMetaDir, myMetaDir.Capacity);
            addToMeta(myMetaDir.ToString(),myFilePath,myFileName);
string myBuffer = "%VZ_LAYER_METADIR%\\"+myFileName;
            UInt32 myBufferSize = (UInt32)myBuffer.Length;
            UInt32 result = FSL2.VzSetLayerNotification(myGuid.ToString(), FSL2.VzNotification.VzNotificationOnPostActivate, myBuffer, myBufferSize);
}

onPostActivate is creating an OnEvent for post activate. The first thing we do is get the Meta Directory location which we then use to move our file, that would come from a command-line argument, into. We then create the string to add to the registry. Notice the use of %VZ_LAYER_METADIR%. We then create our new onEvent entry.

static bool addToMeta(string myMetaDir, string myFilePath, string myFileName) {
            FileInfo myFile = new FileInfo(myFilePath+"\\"+myFileName)
            try {
                myFile.CopyTo(myMetaDir+myFileName, true);

            }
            catch {
                return false;
            }
            return true;
        }

AddToMeta takes three parameters, myMetaDir which is the path to the Meta Directory of a layer, myFilePath which is the path to the file you want to add (so c:\\test as an example) and myFileName is the name of the file (so test.exe) to be copied.

Conclusion

With the addition of onEvents and Excludes, this series of articles is almost complete. You can do just about anything you want with the tools provided. The next article will probably focus on files, directories, and the paths to them when they're virtualized.

Remember that future versions will be listed in the FSL2 Class Portal where the FSL2 class is available for download. Be sure to subscribe to that thread which will inform you of any new articles and updates to the class.

Return to the Virtualization SDK Book

Comments 2 CommentsJump to latest comment

erikw's picture

Jordan,

Thanxss for the good work. I rated all your articles with a big Awesome.

Regards
Erik
www.dvs4sbc.nl

Regards Erik www.DinamiQs.com Dinamiqs is the home of VirtualStorm (www.virtualstorm.org)

*************************************************************
If your issue has been solved, Please mark it as solved
***********

0
Login to vote
Jordan's picture

Thanks Erik,

I know the audience for this type of article isn't as large as for others on the Juice but I wanted to support all those making tools and new ways to interact with SVS since you guys are very strong group of supporters for the technology. I thought this would be the best thing to do because the default help file in the SDK is lacking on certain info and there are some things that don't make much sense without seeing them used (Import for example).

If a forum post solves your problem please flag is as the solution

0
Login to vote