Video Screencast Help
Protect Your POS Environment Against Retail Data Breaches. Learn More.

SVS 2.X SDK Guide Part 2: Layer Management

Created: 21 Apr 2008 • Updated: 29 Jul 2010
Language Translations
Jordan's picture
0 0 Votes
Login to vote

In part one of my SVS SDK series I covered why I'm creating these articles and how to use the SDK to properly initialize SVS. Please read over it before reading this article because I won't cover anything mentioned in Part One here and many of the methods covered in Part Two won't work without what was mentioned in Part One.

As with Part One the code in this article is done in C# and the class used is a .Net one however for those using just the SDK and C++ this article will still be useful. You'll just have to change some code around to get examples to work.

Changes to FLS2 Class

I've added all the new methods discussed to ManagedSVS.cs

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

Layer Management

What's a Layer Management method? Well I grouped the methods most used (and available in WMI) as Layer Management Methods and they're relatively simple to use. These exclude Capture, Export and Import because of the complexity involved in using them. However don't fret too much-- I'll be covering Export and Import in Part Three because they deserve (and require) a much more in depth look then the others.

Due of the complexity of Import and Export I wanted to cover some of the simpler functions and show you how they're used and how you can build an SVS app using the SDK so as not to overwhelm anyone.

Activate

public static extern UInt32 ActivateLayer
(
 string fslGUID,
 bool bRunAppsInStartupFolder
 );

Activate is the workhorse of SVS, it's definitely used more then most other methods and is one of the few that can use used without initializing SVS. To activate a layer you need two parameters: a Guid and a Boolean expression. One of the interesting things about going through the SDK is you find features that aren't common knowledge, like the second action that activate can do: run anything that's in the startup folder if you pass in a true.

Deactivate

public static extern UInt32 DeactivateLayer
 (
  string fslGUID,
  bool force,
  UInt32 pPid
 );

Deactivate takes two parameters and returns a third. All three have to be passed in though, which are a Guid, a Boolean if the method should force close any process running from that layer and it returns pPid which contains the process ID of any processes running. I'm not sure how this works if there are more then one, I assume this would return the last process found but I could be wrong.

This is useful if you have some program that won't let SVS close it. We all run into it from time-to-time where you have to kill a process via TaskMon so you can deactivate a layer even with force on, so you could write a tool that would then kill that process via a different method or notify the user to the problem instead of getting the 1053 error that SVSAdmin and SVSCmd give you right now.

Delete

public static extern UInt32 DeleteLayer
 (
  string fslGUID,
  bool deletePeer
 );

Delete, like all common methods, require a Guid and a Boolean (though technically there's one method that doesn't follow this format) to do it's work. Like Activate there's a feature here that's not common knowledge - which is you can choose to not delete the Read/Write layer. So, remember to pass in True by default unless you want a mess to clean up.

Rename

public static extern UInt32 RenameLayer
 (
  string fslGUID,
  string newName
 );

Speaking of the method that doesn't take a Boolean, RenameLayer is it. This is the simplest of the methods since it just takes a Guid and a string containing the new name. Remember that layer names have a size limit (64 characters) and recommended "Do not use" characters (& <>) though I believe they have been allowed since version 2.1.

Reset

public static extern UInt32 ResetPeer
 (
  string fslGUID,
  bool force,
  UInt32 pPid
 );
 

So wait, the method is actually called RestPeer and not RestLayer? Yep, and it's much like Delete (in fact it's kind of the opposite of delete.) It takes a Guid and Boolean and will return a PID of any process running at the time of the rest. The difference between Delete and Rest is Delete well deletes the read-only layer (unless told otherwise) while Rest deletes only the Read/Write layer and then creates a new empty Read/Write layer.

Auto Activate

public static extern UInt32 SetActiveOnStart
 (
  string fslGUID,
  bool bActiveOnStart
 );

The last of the Common Methods is SetActiveOnStart which will change the Auto Activate flag. To do so you just need to pass in a Guid and a Boolean. True sets a layer to Auto Activate while false will clear the flag.

Seeing It in Action: Commandline App

One of the easiest ways to show how this works is to make a command line tool much like SVSCmd. Our command line tool will take in a Guid and an argument for what to do with the layer associated with the Guid. By using the FSL2 class, making something like SVSCmd is very simple and can be done in only a few minutes.

We'll use the following arguments:

  • /a = activate
  • /d = deactivate
  • /auto = auto activate
  • /r = rest
  • /del = delete

Those are all commands you can do with SVScmd. So let's use some of the features that SVScmd doesn't use with those actions that we can take advantage of. Since we're adding this new functionality we can add in all the Boolean flags for the other commands as well.

For activate we'll take a third argument, either true or false, that will allow us to decide if we want things in the start up folder to launch or not. And with Delete we'll do the same for deleting peers or not.

In the command line we want our arguments to be arranged thusly:
MySVSCmd myMethod, myGuid, myBool

static void Main(string[] args)
{
 FSL2 mySVS = new FSL2();
 UInt32 result = 2;
 UInt32 myPid = 0;
 if (args[0] == "/a") {
  if(args[2]=="true"){
   result= FSL2.ActivateLayer(args[1],true );
  }else{
   result = FSL2.ActivateLayer(args[1], false);
  }      
  if (result == 0) {
   Console.WriteLine("Layer Activated");
  }else {
   Console.WriteLine("Error Number " + result);
  }
 }else if (args[0] == "/d") {
  if (args[2] == "true") {
   result = FSL2.DeactivateLayer(args[1],true, myPid);
   }else {
    result = FSL2.DeactivateLayer(args[1], false, myPid);
   }
   if (result == 0) {
    Console.WriteLine("Layer Deactivated");
   }else {
    Console.WriteLine("Error Number " + result);
   }
 }else if (args[0] == "/auto") {
   if (args[2] == "true") {
    result = FSL2.SetActiveOnStart(args[1], true);
   }else {
    result = FSL2.SetActiveOnStart(args[1], false);
   }if (result == 0) {
     if (args[2] == "true") {
      Console.WriteLine("Layer Set to AutoActivate");
     }else {
       Console.WriteLine("Layer Cleared of AutoActivate");
     }
     Console.WriteLine("Layer Deactivated");
   } else {
     Console.WriteLine("Error Number " + result);
   }
 }else if (args[0] == "/r") {
   if (args[2] == "true") {
     result = FSL2.ResetPeer(args[1], true, myPid);
   }else {
     result = FSL2.ResetPeer(args[1], false, myPid);
   }
   if (result == 0) {
     Console.WriteLine("Layer Rest");
   }else {
     Console.WriteLine("Error Number " + result);
   }
 }else if (args[0] == "/del") {
   if (args[2] == "true") {
     result = FSL2.DeleteLayer(args[1], true);
    }else {
     result = FSL2.DeleteLayer(args[1], false);
    }
    if (result == 0) {
     Console.WriteLine("Layer Deleted");
    }else {
      Console.WriteLine("Error Number " + result);
    }
 }
   Console.Read();
}

After looking through the code you can see it's fairly straight forward, though there are a few things worth pointing out.

FSL2 mySVS = new FSL2();

You may remember from Part One that we have to initialize SVS before most of it's features are useable. Forgetting this is something that many people do, so I suggested adding it to the constructor of our SVS class. What we're doing with this line of code is creating a new object of type FLS2 which will call that constructor which makes sure SVS is ready to go. Since all the methods and constants are public you don't have to do it this way, you could create an initialize method in your main as well-or you could make all the methods private.

UInt32 result = 2;

Each method used returns a result upon success which is a 0. I'm creating a default result variable of type UInt32 (which is what the methods use) but can't set it's default to 0 like you'd normally do since 0 means success. SVS doesn't use the number 2 as an error code so I'm using that (it could be anything 3 digits or less). Since every method uses result I'm defining it outside the if statements to save myself from having to type it multiple times.

UInt32 myPid = 0;

Both Deactivate and RestPeer require a UInt32 to be passed so they can populate it with any possibly Process ID running from that layer at the time. So, like result, I'm creating this outside of my if statements so I only have to type this code once.

if (args[2] == "true") {}

This isn't related to SVS directly but I couldn't figure out how to convert type String to type Boolean so I'm using if statements to do so. If anyone has a better way to do this let me know in the comments section.

Conclusion

SVS's Common Methods are all very simple to use, which is a good thing, and with them you can perform a lot of functionality. But they're just the tip of the iceberg so to speak. There's a lot more to SVS outside of these and we'll start with Import and Export with Part Three.

Remember that future versions will be listed in the FSL2 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