Contents
Overview of SFT/DSFT File Format................................................. ........................3
Introduction
This specification describes the file format, internal structure, and
layout of SFT, DSFT, and CP files used by the Microsoft Application
Virtualization (hereafter App-V) product.
The reader should be familiar with the overall concept of
application virtualization technology as well as concepts and
terminology commonly used in conjunction with App-V.
The following terminology is used in this paper:
Absolute Byte Offset
Refers to the byte offset from the beginning of a file.
Data Block Section
Refers to a part of a file included in the package and stored as
an individual data block section.
Data Page
Refers to the single logical unit of information stored inside one
section.
Header Metadata Section
Refers to the bookkeeping and metadata information section
stored in the header portion of the SFT file.
Page Relative Byte Offset
Refers to the byte offset from the beginning of a CP data page.
Pointer
Refers to the byte offset from the beginning of a file to the next
unit of data.
Relative Byte Offset
Refers to the byte offset from the beginning of an SFT file
section.
Reserved
Fields marked reserved are deprecated or reserved for future
use.
Section
Refers to the single logical unit of information stored inside a
CP file.
Section ID
Refers to the identifier of sections by which the logical meaning
of a section is deducted.
Section Relative Byte Offset
Refers to the byte offset from the beginning of a CP section.
Type Identifier
Refers to the four-byte identifier that all sections (header and
data block) begin with and that identifies their type.
All values are stored in little endian order.
rootdirectory\
MyApplication\
…
VFS\
…
osguard.cp
SoftGridUserSettings\
Myapp.exe
MyLibrary.dll
Osguard.cp File
The osguard.cp file is used to establish the virtualization
environment.
SoftgridUserSettings Directory
The SoftgridUserSettings directory must exist at the root and be
empty.
Header Metadata Sections
All SFT files contain a number of metadata—or bookkeeping—
header sections at the beginning of the SFT file before the actual
data blocks start. The list of header metadata sections is as follows
(section type identifier codes are in parentheses after each
section’s name):
• Differential SFT Header (DSFT)
Section Size
This field stores the total size (in bytes) for the section. The size
is calculated starting from the beginning of the common
section header until the last byte contained within the section.
Revision
This field stores the total length of all data blocks in FB1
belonging to the old versions of this package, i.e., those blocks
that make up any and all files not updated in the current
version of SFT.
Size of old blocks in FB2
This field stores the total length of all data blocks in FB2
belonging to the old versions of this package, i.e., those blocks
that make up any and all files not updated in the current
version of SFT.
Size of new blocks in FB1
This field stores the total length of all data blocks in FB1
belonging to the files updated in this version of the package.
These data blocks are also the ones that get physically
included in the DSFT file.
Size of new blocks in FB2
This field stores the total length of all data blocks in FB2
belonging to the files updated in this version of the package.
These data blocks are also the ones that get physically
included in the DSFT file.
This field stores the absolute byte offset inside the base SFT file
to the beginning of part of FB1 making up the blocks updated
in this version of the file.
Offset to new blocks in FB2
This field stores the absolute byte offset inside the base SFT file
to the beginning of part of FB2 making up the blocks updated
in this version of the file.
FB1 Size
This field holds the total length of all the blocks in FB1.
FB2 Size
This field holds the total length of all the blocks in FB2.
Offset to old blocks in FB1
This field stores the absolute byte offset inside the base SFT file
to the beginning of part of FB1 making up the blocks not
updated in this version of the file.
Offset to old blocks in FB2
This field stores the absolute byte offset inside the base SFT file
to the beginning of part of FB2 making up the blocks not
updated in this version of the file.
Reserved
This field stores the internal version number for the package.
This value is initialized to 1 and monotonically increases by 1
each time the package is saved.
Note: For packages created in version 4.5 and upwards of App-
V, this package version number is also applied to all files that
have been changed since the previous version. See the
“Compressed Index Header (CIDX)” section for more
information on file versions.
Creation Timestamp
This field stores the data block size used in the package. No
actual data block stored later in the file is expected to be less
or more than this value unless it is either a file that is a size
less than the block size or is the last block from multiple blocks
belonging to a larger file.
Currently two officially supported values for the block size are
the default 32768 (0x00008000) bytes and 65536
(0x00010000) bytes.
Reserved
This field contains the internal version number for the directory
map. It starts initially from one for the newly created package
and then increments by one per each additional resave of that
same package following the package’s version number.
SECD Map Size
This field stores the total size, in bytes, of the SECD entries in
the compressed index (CIDX) section.
Directory Map Size
This field stores the total size, in bytes, of the directory map
subsection in the compressed index (CIDX) section.
Total Filedata Size
This field stores the total size, in bytes, of all the files that are
stored inside data blocks (DATA). This value does not include
the DATA section headers.
Blockmap Size
This field stores the total size, in bytes, of all the block map
entries in the BMAP section. This value does not include the
BMAP section header.
FB1 Data Size
This field stores the total length, in bytes, of all the FB1 DATA
block payloads.
SECD Offset
This field contains the absolute byte offset inside the SFT file to
the beginning of the directory map section (CIDX).
FB1 Offset
This field contains the byte offset to the beginning of the FB1
data blocks relative to the start of the SFT file.
Blockmap Offset
This field contains the absolute byte offset inside the SFT file to
the beginning of the block map header section (BMAP).
Directory Map Creation Timestamp
SECD Entries
CIDX structure
Although App-V versions prior to 4.5 did not include any security in
the virtualized file system, one empty SECD entry is stored in the
SFT file nevertheless. This empty SECD section needs to be
applied for new packages in case ACLs are not recorded and
stored for the SFT file.
This section’s data can be compressed if the SFT file compression
is in use. Only the SECD and Directory Map subsections are
compressed, while the common CIDX header is not. The
compression is applied per subsection and not as one combined
datastream, as illustrated below.
CIDX Header
The header part of the CIDX section contains the common section
header, like the other sections, and the sizing information for the
SECD and Directory Map subsections.
The format of the CIDX header prior to App-V version 4.5 is listed
in the following table.
CIDX Header Fields Size
(bytes)
Common section header 9
Reserved 8
Security Descriptor Subsection 4
Size
Directory Map Subsection Size 4
The format of the CIDX header for App-V version 4.5 onward is
listed in the following table.
CIDX Header Fields Size
(bytes)
Common section header 9
Compression Type 4
Security Descriptors Enforced 1
Reserved 3
Security Descriptor Subsection 4
Size
Directory Map Subsection Size 4
Note: This field is not used for packages prior to the 4.5
version of App-V.
Reserved
This field stores the size of the directory map subsection that
immediately follows the security descriptor subsection.
Note: If compression is used for the package, size in this field
indicates the compressed size, not the uncompressed one.
The format in which security descriptors are stored in the SFT file
is identical to the format used by the Windows NT lineage of
operating systems to store security descriptors.
Security Descriptor
Securtiy Descriptors
Security Descriptor
Subsection
Security Descriptor
...
Security Descriptor
Offset + 1
Directory Entry
Directory Entry
Directory Entry
Although SFT packages created before version 4.5 of App-V did not
enforce or store security for the internal file system, the security
descriptors subsection is present in all those packages with one
empty (without ACL) SECD Entry.
SECD Entry Header
The format of the SECD Entry header is listed in the following
table.
SECD Entry Header Size (bytes)
Common section header 9
Reserved 8
Security Descriptor Index 2
Reserved 8
Security Descriptor Size 4
This field contains the index of this entry in the list of SECD
entries.
Reserved
Version 4
Id 16
Parent Id 16
Long Filename Size 2
Short Filename Size 2
Entry Type 4
Size 4
Reserved1 4
Filesystem Attributes 4
App-V Attributes 2
Reserved2 8
Creation Timestamp 8
Modification Timestamp 8
Last Accessed Timestamp 8
Security Descriptor Offset 2
Long Filename variable
Short Filename variable
This field stores the internal version number for the directory
entry. This value is initialized to 1 and monotonically increases
by 1 each time the file is updated.
Id
This field stores the unique identifier (GUID) for the directory
entry. This entry is not case sensitive. The first 4 bytes must
uniquely identify this Directory Entry in a single SFT file.
Parent Id
This field stores the Id for this entry’s parent and is used as a
back-link. This entry is not case sensitive.
The root directory entry has the value “FFFFFFFF-FFFF-FFFF-
FFFF-FFFFFFFFFFFF”.
Long Filename Size
This field stores the total size in bytes for this entry’s file-
/directoryname in long filename format. This value does not
include a null terminator.
Short Filename Size
This field stores the total size in bytes for this entry’s file-
/directoryname in short (8+3) filename format. This value does
not include a null terminator.
Entry Type
Size
This field stores the total length, in bytes, of all the DATA block
payloads for FB1 and FB2.
Note: For directories, this field is initialized to zero.
Reserved1
This field stores the long filename for the directory entry. The
filename is stored as wide-char (double-byte) string, without
the terminating null character (0x0000).
Short Filename
This field stores the short —8+3 format —filename for the
directory entry. The filename is stored as wide-char (double-
byte) string, without the terminating null character (0x0000).
Block Map Header (BMAP)
The Block Map header contains a lookup index to the actual data
blocks and thus maps a directory entry to all the data blocks
associated with it.
The section contains a short header and the actual block map
entries, consisting of a list of blocks for each individual file entry in
the directory structure.
This section’s data can be compressed if the SFT file compression
is in use. When compression is used, the header of the section is
always in an uncompressed state and the block map entries are
compressed in one datastream as a whole.
BMAP Header
The header part of the BMAP section contains the common section
header, like the other sections, and the sizing information for
BMAP data. Depending on whether the compression is in use or
not, the BMAP’s header field count changes.
The format of the BMAP header is listed in the following table.
BMAP Header Fields Size
(bytes)
Common section header 9
Id 16
Block Map Version 4
Number of bits per block 1
Compression Type 1
Reserved
Compressed Size
This field contains the first 4 bytes from the full 16 bytes GUID
from the Id field in the entry found in the Directory Map
Subsection.
Data Block Count
This field stores the number of data block offsets that follow.
Each data block offset is the offset to the data block, relative to
the start of the file.
CONT Section
Version GUID(s)
History Entry #1
History Entry #2
...
CONT Header
The header part of the CONT section contains the common section
header like the other sections, sizing information for history
entries, and the list of version GUIDs for the current version of the
package and one for each previous version.
The format of the CONT header is listed in the following table.
CONT Header Fields Size
(bytes)
Common section header 9
Reserved 12
Version GUID Count 4
History Entry Count 4
This field stores the length of the account name under which
the package was created. The name is stored immediately
following the last history entry. The size does not include a null
terminator.
Windows Version Major
This field stores the platform id for the operating system under
which the package was created. This field is currently always
initialized to 0x000000002 (VER_PLATFORM_WIN32_NT).
For more detailed description on platform ids, please refer to
the Microsoft Windows SDK documentation.
Service Pack Version Major
This field stores the major version number of the Service Pack
for Windows under which this package was created. The default
value is 0x00000000.
Service Pack Version Minor
This field stores the minor version number of the Service Pack
for Windows under which this package was created. The default
value is 0x00000000.
Suite Mask
This is a bit field that identifies the product suites for the
system under which the package was created.
The following suite masks are defined:
Mask Suite
0x00000004 VER_SUITE_BACKOFFICE
0x00000400 VER_SUITE_BLADE
0x00000080 VER_SUITE_DATACENTER
0x00000002 VER_SUITE_ENTERPRISE
0x00000040 VER_SUITE_EMBEDDEDNT
0x00000200 VER_SUITE_PERSONAL
0x00000100 VER_SUITE_SINGLEUSERTS
0x00000001 VER_SUITE_SMALLBUSINESS
0x00000020 VER_SUITE_SMALLBUSINESS_RESTRICTED
0x00000010 VER_SUITE_TERMINAL
Note: Please refer to the Microsoft Windows SDK for detailed
descriptions of different suites and their respective meanings.
System Type
This field stores the memory page size and the granularity of
page protection and commitment used in the system under
which the package was created. This field is usually initialized
to 0x00001000 (4096). The default value is 0x00001000
(4096).
Minimum Address
This field stores the year part of the timestamp when this
version of the package was saved.
Modification Timestamp Month
This field stores the month part (in number) of the timestamp
when this version of the package was saved.
Modification Timestamp Weekday
This field stores the weekday when this version of the package
was saved. The weekday numbering starts from zero, which
denotes Sunday, one denotes Monday, and so forth.
Modification Timestamp Day
This field stores the day part of the timestamp when this
version of the package was saved.
Modification Timestamp Hour
This field stores the hour part of the timestamp when this
version of the package was saved. It is in the UTC (GMT) time
zone.
Modification Timestamp Minute
This field stores the minute part of the timestamp when this
version of the package was saved.
Modification Timestamp Second
This field stores the seconds part of the timestamp when this
version of the package was saved.
Modification Timestamp Millisecond
This field stores the length of the user’s directory name in the
operating system under which the package was created. The
actual user directory name is stored in the end of the history
entry and has a length of this many bytes. The default value is
0.
Last Boot
This field contains the information if the last boot was normal
for the machine under which the package was created. The
default value is 0.
Currently values are as follows:
Value Meaning
0x00000 Yes
000
0x00000 No
001
Reserved
Terminal Services
Reserved
Save Mode
This field contains the information about how the package was
saved. Normal Save is the upgrade to an existing package,
whereas Save As is a package’s initial save. This value must
match the Upgrade Mode history entry.
Currently used values are as follows:
Value Mode
0x00 Save
0x01 Save As
0x02 Save As New Package
Note: This does not appear in pre-version 4.5 packages.
.NET Version Size
This field stores the byte length of the .NET version string,
excluding the null terminator.
IE Version Size
This field stores the byte length of the Internet Explorer (IE)
version string, excluding the null terminator.
Media Player Version Size
This field stores the byte length of the Media Player version
string, excluding the null terminator.
.NET Version (4.5 packages and upward only)
This field stores the version information for the Microsoft .NET
Framework installed on the machine under which the package
was created. It is stored as a wide-char (double-byte) string
without the terminating null character (0x0000) at the end.
IE Version (4.5 packages and upward only)
This field stores the account name logged on under which the
package was created. It is stored as a wide-char (double-byte)
string without the terminating null character (0x0000) at the
end.
Hostname
This field stores the hostname of the machine under which the
package was created. It is stored as a wide-char (double-byte)
string without the terminating null character (0x0000) at the
end.
System Directory Path
This field stores the full path of the system directory on the
operating system under which the package was created. It is
stored as a wide-char (double-byte) string without the
terminating null character (0x0000) at the end.
Windows Directory Path
This field stores the full path of the Windows directory on the
operating system under which the package was created. It is
stored as a wide-char (double-byte) string without the
terminating null character (0x0000) at the end.
User Directory Path
This field stores the full path of the user directory on the
operating system under which the package was created. It is
stored as a wide-char (double-byte) string without the
terminating null character (0x0000) at the end.
FILE A FILE B
That predetermined size —into which files are split and which
constitutes a single data block—is stored inside the Properties
header (PROP) and can range between 4 and 64 kilobytes,
although the most commonly used size is 32 kilobytes.
Although the data blocks are not part of the SFT’s header
metadata sections—but rather the actual payload of the SFT—the
field layouts of each block’s header follows the same convention
as with the header metadata sections. After the data block header
fields, the actual data contained in the block begins immediately,
as illustrated below.
Data Block
Data
Header
Content
This field stores the Feature Block (FB) number which this block
belongs to. It must be initialized either to one (for FB1 files) or
to two (for FB2 files).
Data Offset
This field stores the relative offset inside the file—to which this
block belongs—for the data contained within the data block.
Data Size
This field stores the size of the data contained within the data
block.
Note: If compression is used, this field will reflect the
uncompressed size of the data block’s content.
Note: If a block size of 64 kilobytes (0x10000 bytes) is used for
the SFT package, it is stored as 0x0000 in this field.
Physical Data Size
This field stores the actual size of the data that begins
immediately after this field in the data block’s content part.
Note: If compression is used, this field will reflect the
compressed size of the data block’s content.
Note: If a block size of 64 kilobytes (0x10000 bytes) is used for
the SFT package, it is stored as 0x0000 in this field.
osguard.cp
Overview of CP file format
App-V uses CP files internally for two purposes. The primary use
for the CP file is to store an application package’s virtual
environment configuration inside the App-V container format (SFT
file format). This configuration information is in a file called
osguard.cp, and it is always placed at the root directory of the
internal file hierarchy of the package container file. The secondary
use for the CP file is to store the virtual environment configuration
that has changed for the user at the execution time at the client.
This configuration information is in a file called settings.cp, and it
appears in a virtual path under the package’s file structure at the
virtual drive (so-called Q: drive), whereas physically it is stored
inside a PKG file format residing in the App-V client’s data directory
or directories.
Internally, the CP file itself is logically divided into multiple
sections—including the header section—each describing its own
set of functionality needed by the App-V client to establish a
virtualized environment for the application being executed.
Sections are then further divided into data pages that when put
together make up the actual data for that section. Both sections
and data pages are linked together in a linked-list manner using
32-bit pointers to absolute offsets inside the CP file as the linkage
mechanism, as illustrated below.
CP File header (56 bytes)
Section 0 header 0 (40 bytes)
Data page 0 header (12 bytes) + data
..
...
...
When using the linked-list method, all the pages for a given
section are not guaranteed to be arranged in sorted order.
CP File Header Section
All CP files begin with a small header section of 56 bytes. This
special section contains initial pointers to the first section in the
chain of all sections, which must be traversed in order to parse a
file successfully.
The format of the CP header is listed in the following table.
CP File Header Fields Size (bytes)
Identifier 4
First Section Offset 4
Reserved 4
Header Size 4
Unique ID 16
Section Count 4
Reserved 4
Required Client Version Build 2
Required Client Version 2
Revision
Required Client Version Minor 2
Required Client Version Major 2
Sequencer Version Build 2
Sequencer Version Revision 2
Sequencer Version Minor 2
Sequencer Version Major 2
This field stores the absolute byte offset pointer, from the
beginning of the CP file to the start of the first section. This
value is then the initial link through which all the sections can
be found.
Reserved
This field stores the unique identifier (GUID) for the CP file. This
identifier is not related to the package or version GUIDs found
in the associated SFT file, but rather it is a unique GUID
generated just for the CP file at the time of creation.
Section Count
This field stores the minimum build number for a client version
required to run the virtual environment configuration. This
value should be 0.
Required Client Version Revision
This field stores the minimum minor version number for a client
required to run the virtual environment configuration. This
value should be 1.
Required Client Version Major
This field stores the minimum major version number for a client
required to run the virtual environment configuration. This
value should be 3.
Sequencer Version Build
This field stores the build number for the App-V Sequencer
version used to create the CP file initially. The default value
should be 0.
Sequencer Version Revision
This field stores the revision number for the App-V Sequencer
version used to create the CP file initially. The default value
should be 0.
Sequencer Version Minor
This field stores the minor version number for the App-V
Sequencer version used to create the CP file initially. The
default value should be 0.
Sequencer Version Major
This field stores the major version number for the App-V
Sequencer version used to create the CP file initially. The
default value should be 0.
Reserved
This field stores the total number of bytes for the section data.
First Page Offset
This field stores the byte offset to the first data page for this
section inside the CP file. This value is relative to the start of
the CP file.
Next Section Offset
This field stores the absolute byte offset to the next section
header inside the CP file. This value is relative to the start of
the CP file.
If there are no more sections in the linked-list, the field value
will be initialized to 0xFFFFFFFF.
This field stores the byte offset inside the CP file to the next
page for the section. This value is relative to the start of the CP
file. If there are no more pages in the linked-list, the value of
this field will be 0xFFFFFFFF.
This field contains the size of the entry block in total number of
bytes.
Entry Block Header Size
This field contains the size of the entry block header (i.e., all
the data before path strings). This size is fixed at 0x00000020
({0x20, 0x00, 0x00, 0x00}).
Virtualized Path Size
Attributes
Name Offset
This field stores the relative byte offset to the key or value
name string inside entry block. The offset is relative to the
beginning of the entry block header.
Name Size
This field contains the size of the key or value name string in
bytes.
Data Offset
This field stores the relative byte offset to the value data inside
entry block. The offset is relative to the beginning of the entry
block header.
Note: This field is used with registry values and keys having
default value; otherwise, the field is initialized to 0x00000000
on key entries.
Data Length
This field contains the size of the value data in bytes.
Note: This field is used with registry values and keys having
default value; otherwise, the field is initialized to 0x00000000
on key entries.
Attributes
This is a bit field used to indicate attributes for virtual registry
value. The following table displays the list of attributes. Any
fields not listed are reserved.
This field contains the last written timestamp for the registry
entry, and it is stored as win32 FILETIME structure. The format
is the UTC (GMT) time zone.
Value Type
This field stores the type of the registry value. See the
Microsoft Windows SDK for a complete listing of registry value
types.
Virtualize
REG_DWORD
The double-word value data contains normal 32-bit value as the
data. No special processing applies to this data type.
This field contains the size of the entry block in total number of
bytes.
Note: If the Entry Size is 0x00000000, the end of the section
has been reached and parsing must be stopped.
Entry Block Header Size
This field contains the size of the entry block header (i.e., all
the data before key/value names and value data).
Entry Flags
This field stores the relative byte offset to the font path string
inside entry block. The offset is relative to the beginning of the
entry block header.
Path Size
This field stores the size of the path, in bytes. This value does
not include a null terminator as there is no null terminator
stored with the path.
This field contains the size of the entry block in total number of
bytes.
Entry Block Header Size
This field contains the size of the entry block header (i.e. all the
data before path strings).
Reserved
This field is reserved and is initialized to all zeroes.
Subentry Count
This field contains the number of subentries (file names)
following this entry.
Files always have zero subentries, whereas directories always
have one or more subentries (an entry for a directory cannot
have a zero subentry so directories without files cannot be fully
virtualized).
Name Offset
This field stores the relative byte offset to the full (long)
filename for the directory or file inside entry block. The offset is
relative to the beginning of the entry block header.
Name Size
This field contains the size of the full filename in bytes.
Shortname Offset
This field stores the relative byte offset to the short (max 8+3)
filename for the directory or file inside entry block.
Shortname Size
This field contains the size of the short filename in bytes.
Immediately following the fixed-length fields are the strings for full
filename and short filename. Exact starting location and length are
defined using the offset- and size-fields.
String/value table
Value data present. This bit is set if the entry is of value type
and there is value data present. If the bit is not set, registry
value contains no value data. This bit needs to be observed
when parsing virtual registry values.
Override local key. This bit is set if the entry is of key type
and it must override local key of the same path completely.
This bit controls the visibility (or lack of) of the local registry
underneath the virtualized registry entry.
Deleted key. This bit is set if the entry is of key type and key
in question has been deleted from registry and it needs to
appear as deleted in virtual environment.
Reserved. This bit must always be set to ‘1’.
Reserved. This might be set to ‘1’.
All other bits are also reserved and should be set to 0.
Reserved
This field is reserved and is initialized to all zeroes.
Entry Type
This field stores the type of the registry entry.
The following entry type identifier codes are in use:
Type of Entry Value
Registry key 0x00000001 ({0x01 0x00 0x00
0x00})
Registry value 0x00000002 ({0x02 0x00 0x00
0x00})
Value Type
This field stores the type of the registry value. This field must
be observed in order to decode the value data successfully.
The following registry value types are commonly used:
Type of Entry Value
REG_SZ 0x01
REG_EXPAND_SZ 0x02
REG_BINARY 0x03
REG_DWORD 0x04
REG_MULTI_SZ 0x07
This field stores the pointer to the first child key entry (or
subkey) of the key in the form of an index number. After
reading in all the entries, this pointer points to the correct
entry’s index number.
Note: If there are no keys beneath this key—or the entry being
parsed is a value entry—this field is initialized to 0xFFFFFFFF.
Pointer to Next Key
This field stores the pointer to the next key entry in the same
parent key in the form of an index number. This information can
be used to traverse all keys inside a given key. After reading in
all the entries, this pointer points to the correct entry’s index
number.
Note: If there are no more additional keys under the same
parent key—or the entry being parsed is a value entry—this
field is initialized to 0xFFFFFFFF.
String/Value Table Field Descriptions
The String/Value table at the end of the section is stored as
continuous runs of character arrays (strings) and/or value data.
The table is accessed from virtual registry entries using offsets
(offsets being relative from the beginning of the string/value table)
and sizes so that the offset is from the starting position of the
string/value table.