Layer Definition Files provide a powerful way to create Symantec Workspace Virtualization (SWV) virtual application layers for scenarios where capturing an application install in not possible or produces inconsistent results. This article walks the reader through the steps required to create an LDF file.
A Symantec Connect reader requested that an LDF be created for the Visual C++ 2008 Redistributable package. This is a good candidate because it cannot be captured on Windows 7 (due to issues related to capturing applications whose installation routine makes use transactions) and capturing on a Windows XP system can produce inconsistent results, especially if a prior version of the package is already installed. Following are the steps that can be used to create virtually (no pun intended) any LDF:
Step A - Create a Virtual Application Layer
We’ll do this by capturing the Visual C++ 2008 Redistributable install on Windows XP. This needs to be done on a “clean” machine. In other words, no instances of VC++Redist are installed on the system. In addition, a layer can be imported or created by hand.
Step B - Create the “file sources” for the Virtual Application Layer.
The “<file-sources>” tags of an LDF are used to create a local “file repository” from which files are copied into a virtual application layer. These files can be copied from a network file share, a local path on the file system or downloaded from a website. In our case, we’ll need to find from where to download the installer for VC++ 2008 Redistributable package. A quick search of the Microsoft site revealed the download location. The easiest way to find the direct download path for a file is to look for the “direct download link”. Right-click the link and copy the link location. Once this is retrieved the path will be used to create a <file-source> tag that can be used to download a file. The direct download path for VC++Redist 2008 is:
With this information we can begin to construct our <file-sources> tags. We can begin with the following template:
<pkg-config version="1" name="" >
<file-source name="" srcpath="" type="http" file-repo="%cfgpath%\filerepo\" search-paths="" dwnload-dir="%cfgpath%\downloads">
<src-file name="" type="" />
We need to add the download location to the “<file-source>” tag and add the file to be downloaded from the download location. The first “<file-source>” tag should appear as follows:
cmd-line="%src-file-path% /Q /X:%dwnload-dir%\vc++temp" />
type="cust" cmd-line="msiexec /a %dwnload-dir%\vc++temp\%src-file% /qn TARGETDIR=%cfgpath%\filerepo\VisualC++_Redist" />
Following is a description of the attributes of the <file-source> tag used to download and extract the files from the VC++Redist 2008 package:
The “name” attribute is a description of the file source tag.
The “srcpath” attribute specifies the location from which the file will be copied. In this case, it is an HTTP URL as defined by the “type” attribute. Notice that this matches the location (excluding file name) of the file to be retrieved from the URL.
The “type” attribute specifies the type of path specified by “srcpath”. In this case, the path type is “http”, meaning that the file is to be downloaded from the URL specified by “srcpath”.
The “file-repo” specifies the location where the files extracted files are to reside. These are the files that will be copied to the virtual layer. The “%cfgpath% macro defines the location where the LDF file resides.
The “dwnload-dir” attribute specifies the location to which the file will be downloaded.
With the file location, download and extraction paths all defined we are ready to define the <src-file> tags. The <src-file> tags define what files are to be downloaded from the “srcpath” and how these files are to be extracted. They also define how files extracted from a downloaded file are to be handled. The files specified are always copied (downloaded, etc) to the path specified by the “dwnload-dir” attribute of the parent <file-source> tag.
The first <src-file> tag “instructs” the swvldf.exe parser to download a file named “vcredist_x86.exe” from the “srcpath” defined on it’s parent <file-source> tag and to extract it to the path “%dwnload-dir%\vc++temp” (the %dwnload-dir% macro expands to a value of the “dwnload-dir” attribute of the parent <file-source> tag). Following is a description of each of the attributes of the first <src-file> tags:
The “name” attribute specifies a file to be downloaded from the “srcpath” of its parent <file-source> tag. This must match the name of the file to be downloaded.
The “type” attribute specifies how the file is to be handled (i.e. extracted). In this case the type is “cust” which means that a custom mechanism is used to extract the file. The “cmd-line” attribute defines the command line to be executed to handle the file. This attribute can be set to some “well known” file types that will expand to the path specified by “file-repo” (e.g. mssp=Microsoft Service Pack, mssetup – Microsoft Setup file).
The “cmd-line” is executed by the swvldf.exe parser to extract the contents of the file specified by the “name” attribute of the <src-file>. In this case the command line to be executed is as follows: "%src-file-path% /Q /X:%dwnload-dir%\vc++temp". The %src-file-path% macro expands to the full path of the file specified by the “name” attribute of the <src-file> tag. The “/Q” specifies “quiet” output, the /X defines the location to where the file is to be executed: “%dwnload-dir%\vc++temp”. It is often necessary to research the type of file that is downloaded and the commands required to extract the files.
The second <src-file> specifies how to extract the contents of a file that was extracted from the downloaded “vcredist_x86.exe” file. A description of each of the second <src-file> attributes follows:
The name="vc_red.msi" attribute defines a file that was extracted from “vcredist_x86.exe”.
The copy="false" attribute specifies that this file is not to be copied (i.e. downloaded) as it already exists in the “dwnload-dir”.
The type="cust" cmd-line="msiexec /a %dwnload-dir%\vc++temp\%src-file% /qn TARGETDIR=%cfgpath%\filerepo\VisualC++_Redist" specifies that the contents of “vc_red.msi” are to be extracted to the following path ”%cfgpath%\filerepo\VisualC++_Redist”. Notice that in this case the files are extracted to the “file repository” as these are the uncompressed files to be copied to the virtual layer. This command line extracts the contents of the “msi” file package.
Now that the <file-sources> tags are defined, the file can be saved as: “VCredist-9.0.30729.17-file-sources.ldf”
The final part of this step is to test these file source tags to ensure they download and extract the files properly.
The “swvldf.exe” tool can be used to parse and test just the <file-sources> tags. This is accomplished by using the following command line syntax:
swvldf -si c:\projects\vcredist\VCredist-9.0.30729.17-file-sources.ldf
The “-si” instructs the tool to parse only the <file-sources> tags and to create the corresponding file repository. After executing this command, a directory listing containing the LDF file should appear as follows:
downloads\ vc++temp\ (folder contains extracted contents of vcredist_x86.exe, including vc_red.msi)
filerepo\VisualC++_Redist\ (folder contains extracted contents of vc_red.msi)
Once the <file-sources> tags are properly defined and working as expected, create a directory named “merge” in the same directory where the VCredist-9.0.30729.17-file-sources.ldf file resides and copy this LDF file into the newly created “merge” directory. The contents of the “merge” directory are in fact “merged” to the contents of an LDF file when creating an LDF file using the swvldf.exe tool to extract an LDF from an existing virtual layer using the "-x" parameter. This will be discussed in more detail in step C.
Step C – Create a “usable” LDF from an existing Virtual Application Layer and File Repository
In this step we create an LDF that contains everything required to create an exact copy of an existing virtual application layer. The swvldf.exe tool is used to extract the definition of a virtual application layer while at the same time searching the file repository and establishing file matchs between files in the layer and files in the file repository. This match is established by creating a file CRC (Cyclic Redundancy Check – a numeric calculation that represents a signature for the contents of the file) for each file in the layer and doing the same for each file in the file repository. When the CRC of a file in the layer matches the CRC for a file in the file repository a match has been established and the path to the matched file is added to the “srcpath” attribute of each <dest-file> tag (e.g. srcpath="%filerepo%\VisualC++_Redist\filex” ).
The syntax used to create this LDF file is as follows:
swvldf -geox c:\projects\vcredistv9-x86\VCredist-9.0.30729.17.ldf -l "Visual C++ Runtime 9.0.30729.17 (x86)"
The “-g” is the parameter that instructs swvldf.exe to generate a match between files in the layer and the file repository (created earlier using the “VCredist-9.0.30729.17-file-sources.ldf” file).
The resultant VCredist-9.0.30729.17.ldf file contains the entire file, folder and registry definitions for the “Visual C++ Runtime 9.0.30729.17 (x86)” layer, including the <file-sources> tags (merged from the VCredist-9.0.30729.17-file-sources.ldf file found in the “merge” directory).
This generated LDF file should now contain everything required to create a copy of the original layer. Create a copy of the original VC++Redist 2008 by invoking swvldf.exe with the following command-line parameters:
swvldf –ni c:\projects\vcredistv9-x86\VCredist-9.0.30729.17.ldf
The “-n” instructs swvldf.exe to create a virtual application layer defined by the passed LDF with a new layer ID. Using “-n” allows multiple “copies” of a virtual layer to be exist simultaneously as each has a unique layer ID.
Execution of this command may result in a 6012 error (file not found in file repository). This happens when the LDF contains <dest-file> tags that cannot be resolved (i.e. found) in the file repository. If this occurs, take a close look at the LDF file and find any <dest-file> tags that have an empty value for the “srcpath” attribute. Unless the file is a .lnk file or a file created by the LDF (see <shortcuts> and <created-file> tags) there should be a path value defined for the “srcpath” for every <dest-file> tag. If not, evaluate whether the file may have been created when activating and running the “original” layer (i.e. the layer from which the LDF was extracted). Sometimes there are log files or other files added by the installation of the application that are not required for execution of the application. Remove any <dest-file> tags that meet these criteria and invoke the above swvldf command line to create the layer.
It is a good idea to compare the contents of an LDF of the original virtual layer and the copy created with created LDF. A tool such as WinMerge can be used to compare the two files and find discrepancies in their definitions.
Invoking swvldf with the following syntax can be used to create LDFs of the original and copy virtual layers:
swvldf -x c:\projects\vcredistv9-x86\original.ldf –l “original layer ID”
swvldf -x c:\projects\vcredistv9-x86\copy.ldf –l “copy layer ID”
The layer ID of each layer must be used because the layer name would be the same for both the original and the copy. The layer ID can be determined by invoking the following at a command prompt:
svscmd enum –v
The use of Layer Definition Files provides a mechanism for creating virtual application layers in cases where capturing the installation is not possible or produces inconsistent results. This article has described the process for creating an LDF file for the Visual C++ 2008 Redistributable package.