Anda di halaman 1dari 60

Microsoft Application

Virtualization File Format


Specification
This specification describes the file format, internal structure, and
layout of SFT, DSFT, and CP files used by the Microsoft Application
Virtualization product.

Contents
Overview of SFT/DSFT File Format................................................. ........................3

Internal Directory Layout............................................................................. ..........4

Osguard.cp File................................................................................................ ..4

Virtual File System (VFS) Directory................................................... .................4

SoftgridUserSettings Directory...................................................... ....................4

Header Metadata Sections..................................................................................... 5

Common Section Header............................................................................. ......5

DSFT Header (DSFT)................................................................................. .............7

SFT Header (SMFF).............................................................................. ..................9

Index Header (INDX)....................................................................................... .....11

Compressed Index Header (CIDX)....................................................................... .13

CIDX Header................................................................................................ ....14

Security Descriptors Subsection (SECD Entries)....................... .......................15

SECD Entry Header............................................................ .........................17

Security Descriptor Structure.................................................... ..................17

Directory Map Subsection............................................................................. ...17

Block Map Header (BMAP).............................................................. .....................21

BMAP Header....................................................................... ...........................21

Block Map Entries................................................................................... .........22

Block Map Entry Header.................................................................. ............23

CONT Header........................................................................ ..........................24

Data Block (DATA)................................................................... ............................37


Overview of CP file format.................................................................... ...........39

CP File Header Section..................................................................................... 41

Data Section Header............................................................... ........................43

Data Page Header................................................................... ........................44

Parsing Section Data................................................................ .......................45

CP File Section Types....................................................................... ................45

Section 0x00 – Mapping data for VFS Entries................... ...........................45

Section 0x01 – Virtual Registry data.................................................... ........47

Section 0x05 – Font Data................................................. ...........................52

Section 0x06 – List of VFS source paths........................... ...........................53

Section 0x07 – NT Object Exclusion List................................ ......................54

Section 0x09 –Virtual registry data - Machine.............................................55

Section 0x0A – Virtual registry data - User........................... .......................60

Section 0x0B – Unique ID Copy........................................... ........................60

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.

Overview of SFT/DSFT File Format


An SFT file consists of metadata sections followed by blocks of
data. The purpose of the metadata sections is allowing the correct
interpretation of the SFT file content. The blocks of data that
immediately follow the metadata sections carry the actual
contents of the SFT file.
Files are stored in runs of fixed-size data blocks. Each logical run of
blocks carries one file in the SFT. The last data block in the run
should not be padded and therefore may be of a smaller size than
the preceding fixed-size blocks in the run for that file. Each data
block belongs to a Feature Block (FB): FB1 or FB2. The data blocks
in FB1 will be loaded first and will gate execution of the
application.
DSFT files are meant to hold only the differences between an older
and new version SFT. A DSFT file is an SFT file with an additional
metadata section, the identical metadata sections from the SFT
file, and only the changed data blocks
SFT files support compression of the internal data. The header
sections cannot be compressed.
Internal Directory Layout
Each SFT file has an internal directory structure that gets mounted
by the App-V client. Every package has an internal root directory
name under which all the other directories and files are located.

rootdirectory\
MyApplication\

VFS\

osguard.cp
SoftGridUserSettings\
Myapp.exe
MyLibrary.dll

Example of internal directory structure

Care must be taken to ensure that the package root directory


name be unique.

Osguard.cp File
The osguard.cp file is used to establish the virtualization
environment.

Virtual File System (VFS) Directory


Each package contains a subdirectory with the predefined name
VFS under the root directory. This special directory is used for the
purpose of holding all the files and directories that need to be
managed.

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)

• SMFF Header (SMFF)

• Properties Header (PROP)

• Index Header (INDX)

• Compressed Index Header (CIDX)


o Security Descriptor Header (SECD)
o Directory Map

• Block Map (BMAP)

• Content Header (CONT)


Additionally for the data blocks, type identifier DATA has been
defined. While other sections can appear only once (with the
exception of the SECD subsection) per SFT file, there can—and, in
practice, will—be a multitude of DATA sections.
All currently defined header sections are mandatory for the SFT
file.

Common Section Header


All the sections (both header metadata sections and data blocks)
in the SFT file begin with a common header that is 9 bytes in
size.
The format of the common header is listed in the following table.
Common Header Fields Size (bytes)
Type Identifier 4
Section Size 4
Revision 1

Common Section Header Field Descriptions


The following provides detailed definitions of the fields used in a
common section header:
Type Identifier

This field identifies the content type of the section as a 4-byte-


long ASCII character string.
The following type identifier codes are defined:
Type identifier Data Type
code
SMFF SFT File Header
DSFT Differential SFT Header
PROP Properties Header
INDX Index Header
CIDX Compressed Index Header
SECD Security Descriptor
BMAP Block Map
CONT Content Header
DATA Data Block

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 revision number of the section and is


reserved. This value represents the version and format of the
section’s fields.
The following revision numbers for the sections are defined:
Section Revision
SMFF 2
PROP 1
INDX 2
CIDX 3
BMAP 2
CONT 1
DATA 1
DSFT 1
SED 1
DSFT Header (DSFT)
Although normal SFT files always begin with the SMFF header
metadata section, differential SFTs, introduced in version 4.5, add
an extra header metadata section before the SMFF section and all
the other sections.
This header section’s purpose is to carry indices to the so-called
base-SFT (the SFT file that the differential SFT is based on). These
index entries tell the offsets and sizes of both the FB1 and FB2
parts and the points where the newest data blocks on the base
SFT start.
All the other header metadata sections in the differential SFT are
exact copies of the ones found in the base SFT. The data blocks
are in reduced form so that the DSFT file contains only the data
blocks that have been changed in that particular version of the
package.
This section should not be compressed.
The format of the DSFT header section is listed in the following
table.
DSFT Fields Size (bytes)
Common section header 9
Size of old blocks in FB1 8
Size of old blocks in FB2 8
Size of new blocks in FB1 8
Size of new blocks in FB2 8
Offset to new blocks in FB1 8
Offset to new blocks in FB2 8
FB1 Size 8
FB2 Size 8
Offset to old blocks in FB1 8
Offset to old blocks in FB2 8
Reserved 32

DSFT Field Descriptions


The following provides detailed definitions of the fields used in the
DSFT header section:
Common section header

Fields as specified by the common section header.


Size of old blocks in FB1

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.

Offset to new 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 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 is reserved and is initialized to all zeroes.


SFT Header (SMFF)
The SFT header section starts the normal (non-differential) SFT file.
This section should not be compressed.
The format of the SFT header section is listed in the following
table.
SMFF Fields Size (bytes)
Common section header 9
Package Version 4
Creation Timestamp 8
Modification Timestamp 8

SMFF Field Descriptions


The following provides detailed definitions of the fields used in the
SFT header section:
Common section header

Fields as specified by the common section header.


Package Version

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 contains the original creation timestamp for the


package file, and it is stored as a win32 FILETIME structure. The
format is the UTC (GMT) time zone.
Modification Timestamp

This field contains the last modification timestamp for the


package file, and it is stored as a win32 FILETIME structure. The
format is the UTC (GMT) time zone.

Properties Header (PROP)


The properties section of the SFT file stores basic package
properties.
This section should not be compressed.
The format of the Properties header section is listed in the
following table.
PROP Fields Size (bytes)
Common section header 9
Bitrate 4
Reserved 4
Stream ID 4
Compression Type 4
Package Blocksize 4
Reserved 4

PROP Field Descriptions


The following provides detailed definitions of the fields used in the
Properties header section:
Common section header

Fields as specified by the common section header.


Bitrate

This field is reserved and should be initialized to 0x0000E000


(56K).
Note: Some older SFT files may store 0x00020000 in this field.
Reserved

This field is reserved and is initialized to all zeroes.


Stream ID

This must have the value 0x00000001.


Compression Type

This field stores the compression type as a numeric value.


When this field is initialized to any of the compression types
defining effective compression, all the sections marked as
being compressible need to be compressed. Note that the
compression type must be uniform throughout the SFT file.

The following compression types are defined:


Type Compression
0x00 No compression is
applied to the
package
0x84 Package is
compressed with
BZIP2 (deprecated)
0x88 Package is
compressed with
ZLIB

Note: The compression method of “BZIP2” has been


deprecated starting with the App-V 4.5 release and should not
be used.
Package Blocksize

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 is reserved and is initialized to all zeroes.

Index Header (INDX)


The Index header section stores information about the location of
various other sections in the SFT file (offsetting information) and
the overall sizes of the data payload.
This section should not be compressed.
The format of the Index Header section is listed in the following
table.
INDX Fields Size
(bytes)
Common section header 9
Stream ID 4
Package ID 16
Directory Map Version 4
SECD Map Size 4
Directory Map Size 4
Total Filedata Size 4
Blockmap Size 4
FB1 Data Size 8
SECD Offset 8
Directory Map Offset 8
FB1 Offset 8
Blockmap Offset 8
Directory Map Creation Timestamp 8
Directory Map Modification 8
Timestamp

INDX Field Descriptions


The following provides detailed definitions of the fields used in the
Index header section:
Common section header

Fields as specified by the common section header.


Stream ID

This field is initialized to all zeroes.


Note: Older SFT files may contain nonzero data in this field.
Package ID

This field stores the package’s unique ID case-insensitive value


(GUID).

Directory Map Version

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 is reserved and is initialized to all zeroes.


Directory Map 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

This field contains the original creation timestamp for the


directory map, and it is stored as the win32 FILETIME structure.
The format is the UTC (GMT) time zone. The FILETIME structure
is defined in the Microsoft Developer Network (MSDN).
Directory Map Modification Timestamp

This field contains the last modification timestamp for the


directory map, and it is stored as the win32 FILETIME structure.
The format is the UTC (GMT) time zone.

Compressed Index Header (CIDX)


The Compressed Index header carries two separate data payloads.
The CIDX section’s primary purpose is to store the ACLs and
Access Control Entries (ACEs) in the Security Descriptor (SECD)
subsection. The secondary purpose is to describe the internal
directory structure—or directory map—for the files and directories
stored within the SFT file, as illustrated below.
Common section header
CIDX Header
CIDX Section

SECD Entries

Directory Map 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.

Uncompressed CIDX Header

Compressed SECD Subsection

Compressed Directory Map Subsection

Compression for CIDX subsections

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

CIDX Header Field Descriptions


The following provides detailed definitions of the fields used in the
CIDX section header:
Common section header

Fields as specified by the common section header.


Compression Type

This field is reserved and is initialized to all zeroes. Currently


this section is always compressed, so this field is not used.
Security Descriptors Enforced

This field has a flag that indicates whether the security


descriptors, which are present in the package, are enforced (set
by the App-V client) at package runtime or not. The default
value is 0x01.
The following flags are defined:
Flag Setting
0x00 Security descriptors are not
enforced
0x01 Security descriptors are enforced

Note: This field is not used for packages prior to the 4.5
version of App-V.
Reserved

This field is reserved and should be initialized to all zeroes.


Note: This field is not used for packages prior to the 4.5
version of App-V.
Security Descriptor Subsection Size

This field stores the total size of the security descriptor


subsection in the CIDX section.
Note: If compression is used for the package, size in this field
indicates the compressed size, not the uncompressed one.
Directory Map Subsection Size

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.

Security Descriptors Subsection (SECD Entries)


The purpose of the security descriptors subsection is to store all
the ACL and ACE entries needed to secure files and directories in
the internal directory structure.

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.

For the purpose of linking directory entries (following immediately


after security descriptors) to the correct security descriptor entry,
each directory entry contains an index offset to a security
descriptor entry. This relative offset is within the Security
Descriptor subsection + 1. For example, if the first SECD entry
starts at byte offset 0, the index (from directory entry) to it
contains 1, and so forth, as illustrated below.

Security Descriptor

Securtiy Descriptors
Security Descriptor

Subsection
Security Descriptor

...
Security Descriptor

Offset + 1

Directory Entry

Directory Entry

Directory Entry

Directory entries refer to security descriptors using relative offsets + 1

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

SECD Entry Header Field Descriptions


The following provides detailed definitions of the fields used in the
SECD Entry header:
Common section header

Fields as specified by the common section header.


Reserved

This field is reserved and is initialized to all zeroes.


Security Descriptor Index

This field contains the index of this entry in the list of SECD
entries.
Reserved

This field is reserved and is initialized to all zeroes.


Security Descriptor Size

This field stores the total length of the Security Descriptor


structure, which follows immediately after this field.

Security Descriptor Structure


The Security Descriptors can be created and decoded by the APIs
defined in MSDN.

Directory Map Subsection


The Directory Map subsection stores the actual directory entries
for the SFT file’s internal file structure.

The root directory of the directory tree is mounted on the root of


the virtual drive in order to make files and directories accessible to
the application being run.

The directory map is physically stored as a series of directory


entries, making up a logical tree structure where each directory
entry has a back-link to its parent entry and a list of attributes.
This linking is constructed by having a unique identifier (GUID) for
each directory entry, and all the child entries will have a reference
to it via the Parent Id field.
Each one of the directory entries also has a version number to it,
which in pre-4.5 packages is incremented on each change to that
entry. Starting with the 4.5 release of App-V, this version number
follows the overall package version number in such a way that it is
set to match the package’s current version if the directory entry
has been changed from the last package save (i.e., the file’s
version is incremented to the package’s version on the basis of
any change to that entry).

The format of the Directory Entry is listed in the following table.


Directory Entry Size (bytes)

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

Directory Entry Field Descriptions


The following provides detailed definitions of the fields used in the
Directory Entry:
Common section header

Fields as specified by the common section header.


Version

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

This field describes the type of the directory entry.


Possible values for directory entries are as follows:
Value Entry Type
0x00000 File
001
0x00000 Directory
002

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 is reserved and should be initialized to all zeroes.


Filesystem Attributes

This field is a bit field containing the file system attributes


associated with the directory entry. See the Microsoft Windows
SDK for a complete listing of FILE_ATTR_ attributes.
App-V Attributes

This field is a bit field containing App-V–specific attributes


associated with the directory entry.
These attributes control the behavior of the file/directory in the
event of an upgraded package arriving on the client and/or
when a file is branched on the client.
The following attributes are defined:
Value (in Attribute
binary)
000001 Application Data
000010 Application Configuration
000100 User Data
001000 User Configuration
010000 Permanent
100000 Override

Note: Application Configuration, User Configuration,


Override, and Permanent attributes have been deprecated
starting in App-V version 4.5.
Reserved2

This field is reserved and should be initialized to all zeroes.


Creation Timestamp

This field contains the original creation timestamp for the


file/directory, and it is stored as a win32 FILETIME structure.
The format is the UTC (GMT) time zone.
Modification Timestamp

This field contains the last modification timestamp for the


file/directory, and it is stored as a win32 FILETIME structure.
The format is the UTC (GMT) time zone.
Last Accessed Timestamp

This field contains the last accessed timestamp for the


file/directory, and it is stored as a win32 FILETIME structure.
The format is the UTC (GMT) time zone.
Note: For packages created with a directory structure from the
FAT file system, this field is initialized to all zeroes.
Security Descriptor Offset

This field stores the security descriptor offset, relative to the


security descriptor inside the CIDX section.
Note: If the entry does not have a security descriptor attached
to it, this field is initialized to zero.
Long Filename

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

Block Map Header Field Descriptions


The following provides detailed definitions of the fields used in the
Block Map header.
Common section header

Fields as specified by the common section header.


Id

This field stores the case-insensitive unique identifier (GUID) for


the block map. It is generated once when the package is
originally created and remains unchanged for the whole life
cycle of the package.
Block Map Version

This field has the value 0x04.


Number of bits per block

This field has the value 0x20.


Compression Type

This field specifies the compression used in the block map


data. It must match the SFT package’s compression setting in
Properties Header.

The Block Map header continues with either compressed


or not compressed data.

BMAP Header Fields Size


(Compressed) (bytes)
Reserved 4
Compressed Size 4
Compressed Block Map Entries Variable

Reserved

This field is reserved and must have the value 0.


Note: This field only exists if compression is used.

Compressed Size

This field stores the size in bytes of the compressed block


map entries.

BMAP Header Fields (Not Size


Compressed) (bytes)
Block Map Entry Count 4
Block Map Entries Variable

Block Map Entry Count

This field indicates the number of Block Map Entry


structures that follow the header.

Block Map Entries


Each Block Map entry is constructed from the header for that entry
and the list of 32-bit offsets to the data blocks, as illustrated
below.

Block Map Entry

Offset Offset Offset


Header ...
#1 #2 #3

Block Map entry structure


The data blocks offsets in an entry are not absolute offset from the
SFT file beginning, but relative from the beginning of the first data
block entry in the file (offset of 0x00000000 being the first data
block in the file and so forth).

Block Map Entry Header


The format of the Block Map Entry header is listed in the following
table.
Block Map Entry Header Fields Size
(bytes)
Directory Entry Id 4
Data Block Count 4

Block Map Entry Header Field Descriptions


The following provides detailed definitions of the fields used in the
Block Map Entry header:
Directory Entry Id

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.

Content Header (CONT)


The Content header serves the purpose of storing the historical
metadata about the environment under which the package was
created and subsequently updated. Another critical function for
Content header section is to store linearity for the package,
namely a list of past and current version GUID(s) which are
used by App-V to track the lineage of a package.
The CONT header metadata section does not exist in versions
older than 4.0.
This section should not be compressed.
The Content header section is internally divided into a header
part, containing the version lineage, and a list of history
entries, as illustrated below.
Common section header
CONT Header

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

CONT Header Field Descriptions


The following provides detailed definitions of the fields used in
CONT header:
Common section header

Fields as specified by the common section header.


Reserved

This field is reserved and is initialized to all zeroes.


Version GUID Count

This field stores the number of version GUIDs following


immediately after the CONT header.
Note: For version 4.5 and above packages, this count is reset
back to one (the list containing only the current version GUID) if
a package is branched to a new package.
History Entry Count

This field stores the number of history entries following the


version GUID list.
Version GUID(s)
The package version GUIDs are stored in time order, oldest to
newest, immediately following the CONT header.
History Entries
Following the list of GUIDs is the list of history entries,
documenting statistics of the environment used to create that
particular version.
Because the layout of History Entry changed between versions
4.2 and 4.5 of App-V, packages created according to 4.5
specifications are not compatible with versions older than 4.5.
The format of the History Entry for 4.x versions prior to App-V
4.5 is listed in the following table.
Two tables of the History Size
Entry Fields are presented (bytes)
because the format for
these entries changed with
version 4.5.History Entry
Fields – 4.0-4.2
Entry Size 4
Sequencer Version Major 4
Sequencer Version Minor 4
Sequencer Version Patch 4
Sequencer Version Build 4
Account Name Size 4
Windows Version Major 4
Windows Version Minor 4
Windows Version Build 4
Platform Id 4
Service Pack Version Major 2
Service Pack Version Minor 2
Suite Mask 2
System Type 2
Processor 4
Processor Family 4
Page Size 4
Minimum Address 4
Maximum Address 4
Processor Mask 4
Number Of Processors 4
Processor Level 4
Processor Revision 4
Modification Timestamp Year 2
Modification Timestamp Month 2
Modification Timestamp Weekday 2
Modification Timestamp Day 2
Modification Timestamp Hour 2
Modification Timestamp Minute 2
Modification Timestamp Second 2
Modification Timestamp, 2
Millisecond
Hostname Size 4
System Directory Path Size 4
Windows Directory Path Size 4
User Directory Path Size 4
Last Boot 4
Reserved 4
Reserved 4
Remote Desktop 4
Terminal Services 4
Reserved 4
Upgrade Mode 1
Save Mode 4
Account Name variable
Two tables of the History Size
Entry Fields are presented (bytes)
because the format for
these entries changed with
version 4.5.History Entry
Fields – 4.0-4.2
Hostname variable
System Directory Path variable
Windows Directory Path variable
User Directory Path variable
The format of the History Entry for App-V version 4.5 and onward
is listed in the following table.
History Entry Fields – 4.5 and Size
Above (bytes)
Entry Size 4
Sequencer Version Major 4
Sequencer Version Minor 4
Sequencer Version Revision 4
Sequencer Version Build 4
Account Name Size 4
Windows Version Major 4
Windows Version Minor 4
Windows Version Build 4
Platform Id 4
Service Pack Version Major 2
Service Pack Version Minor 2
Suite Mask 2
System Type 2
Processor 4
Processor Family 4
Page Size 4
Minimum Address 4
Maximum Address 4
Processor Mask 4
Number Of Processors 4
Processor Level 4
Processor Revision 4
Modification Timestamp Year 2
Modification Timestamp Month 2
Modification Timestamp Weekday 2
Modification Timestamp Day 2
Modification Timestamp Hour 2
Modification Timestamp Minute 2
Modification Timestamp Second 2
Modification Timestamp, 2
Millisecond
Hostname Size 4
System Directory Path Size 4
Windows Directory Path Size 4
User Directory Path Size 4
Last Boot 4
Reserved 4
Reserved 4
Remote Desktop 4
Terminal Services 4
Reserved 4
Upgrade Mode 1
Save Mode 4
.NET Version Size 4
IE Version Size 4
Media Player Version Size 4
Account Name variable
Hostname variable
History Entry Fields – 4.5 and Size
Above (bytes)
System Directory Path variable
Windows Directory Path variable
User Directory Path variable
.NET Version variable
IE Version variable
Media Player Version variable

History Entry Field Descriptions


The following provides detailed definitions of the fields used in the
History Entry:
Entry Size

This field stores the full length of the history entry.


Sequencer Version Major

This field stores the major version number of App-V Sequencer


used to create the package. The default value is 0x00000000.
Sequencer Version Minor

This field stores the minor version number of App-V Sequencer


used to create the package. The default value is 0x00000000.
Sequencer Version Revision

This field stores the revision version of App-V Sequencer used


to create the package. The default value is 0x00000000.
Sequencer Version Build

This field stores the build version of App-V Sequencer used to


create the package. The default value is 0x00000000.
Account Name Size

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 major version number of Microsoft


Windows under which the package was created. The default
value is 0x00000000.
Windows Version Minor

This field stores the minor version number of Microsoft


Windows under which the package was created. The default
value is 0x00000000.
Windows Version Build

This field stores the build version of Microsoft Windows under


which the package was created. The default value is
0x00000000.
Platform Id

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 additional information about the operating


system under which the package was created. The default
value should be VER_NT_WORKSTATION.
The following system types are defined:
Value Product Type
0x0000002 VER_NT_DOMAIN_CONTROLLER
0x0000003 VER_NT_SERVER
0x0000001 VER_NT_WORKSTATION
Note: Please refer to the Microsoft Windows SDK for detailed
descriptions of different system types and their respective
meanings.
Processor

This field is reserved and initialized to all zeroes.


Processor Family

This field stores the information about a processor’s family


used in the system under which the package was created. The
default value is 0x0000024A (PROCESSOR_INTEL_PENTIUM =
586).
For a complete list of processor family ids, please refer to the
Microsoft Windows SDK documentation and WinNT.h header
file.
Page Size

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 lowest memory address accessible to


applications and dynamic-link libraries (DLLs) used in the
system under which the package was created. The default
value is 0x00010000 (65536).
Maximum Address

This field stores the highest memory address accessible to


applications and DLLs used in the system under which the
package was created. The default value is 0x7FFEFFFF
(2147418111).
Processor Mask

This field is a bitfield which stores a mask representing the


number of processors configured for the system on which the
package was created. Bit 0 is processor 0; bit 31 is processor
31.
Number of Processors

This field stores the number of a processor in the system under


which the package was created. The default value is 1.
Processor Level

This field stores an architecture-dependant processor level in


the system under which the package was created.
Processor Revision

This field stores an architecture-dependant processor revision


in the system under which the package was created. The
default value is 0.
Modification Timestamp Year

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 milliseconds part of the timestamp when


this version of the package was saved.
Hostname Size

This field stores the length of the machine hostname under


which the package was created. The actual hostname is stored
in the end of the history entry and has a length of this many
bytes. The default value is 0.
System Directory Path Size

This field stores the length of the system directory’s name


(typically “c:\windows\system32”) in the operating system
under which the package was created. The actual system
directory name is stored in the end of the history entry and has
a length of this many bytes. The default value is 0.
Windows Directory Path Size

This field stores the length of the Windows directory’s name


(typically “c:\windows”) in the operating system under which
the package was created. The actual Windows directory name
is stored in the end of the history entry and has a length of this
many bytes. The default value is 0.
User Directory Path Size

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

This field is reserved and initialized to all zeroes.


Reserved

This field is reserved and initialized to all zeroes.


Remote Desktop

This field contains a flag that indicates whether the current


session was remotely controlled in a Terminal Services
environment during the package creation. The default value is
0.
Currently used values are as follows:
Value Meaning
0x00000 No
000
0x00000 Yes
001

Terminal Services

This field contains a flag that indicates whether the package


was created under a Terminal Services session. The default
value is 0.
Currently used values are as follows:
Value Meaning
0x00000 No
000
0x00000 Yes
001

Reserved

This field is reserved and initialized to all zeroes.


Upgrade Mode

This field contains a flag that indicates whether the package


was upgraded. This value must match the Save Mode history
entry.
Currently used values are as follows:
Value Meaning
0x00000 No
000
0x00000 Yes
001

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 version information for the IE 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.
Media Player Version (4.5 packages and upward only)

This field stores the version information for the Microsoft


Windows Media Player 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.
Account Name

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.

Data Block (DATA)


Immediately after the header sections come the actual data
contents for the files contained within the SFT file. Each file is
internally divided into equally sized chunks of data, called blocks,
having a predetermined size, as illustrated below. Any remainder
that does not fill the selected block size is stored in a data block
having a size less than the default size.

FILE A FILE B

DATA DATA DATA DATA DATA DATA DATA DATA

DATA DATA DATA DATA

Files’ contents split into data blocks

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.

The data blocks for a given file do not necessarily appear in


ascending order of their relative positions inside the file, but rather
those parts (blocks) of the file that are included in the logical FB1
section of the data blocks appear first and the ones that belong to
the FB2 follow

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

Data block structure

This section data can be compressed if the SFT file compression is


in use. When using compression, the header fields remain in an
uncompressed state and the compression is applied for the data.
The format of the data block header is listed in the following table.
Data Block Fields Size
(bytes)
Common section header 9
Reserved 10
Directory Entry Id 16
Feature Block Number 2
Data Offset 4
Data Size 2
Physical Data Size 2
Data Blocks Field Descriptions
The following provides detailed definitions of the fields used in
Data Block:
Common Section Header

Fields as specified by the common section header.


Reserved

This field is reserved and is initialized to all zeroes.


Directory Entry Id

This field stores the id (GUID) of a directory entry which this


block belongs to. The value is case insensitive.
Feature Block Number

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

..

Section 1 header (40 bytes)


Data page 0 header (12 bytes) + data

...

Section n header (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

CP File Format Header Field Descriptions


The following provides detailed definitions of the fields used in the
CP file format header section:
Identifier

This field has the value 0x00010000 ({0x00, 0x00, 0x01,


0x00}).
First Section Offset

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 is reserved and is always initialized to 0xFFFFFFFE


({0xFE, 0xFF, 0xFF, 0xFF}).
Header Size

This field has the value 0x00000038 ({0x38, 0x00, 0x00,


0x00}).
Unique ID

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 is used to store the total number of sections to be


found in the CP file, including the header section.
Reserved

This field is reserved and is initialized to all zeroes.


Required Client Version Build

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 revision number for a client


version required to run the virtual environment configuration.
This value should be 0.
Required Client Version Minor

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.

Data Section Header


Each unique data section inside the CP file format consists of a
section header (40 bytes in size) and one or more data pages.
When all the pages for the section are read, the next section is
located through the offset in the field “Next Section Offset.”
The format of the section header is listed in the following table.
Section Header Fields Size (bytes)
Section Identifier 2
Reserved 26
Section Size 4
First Page Offset 4
Next Section Offset 4

Section Header Field Descriptions


The following provides detailed definitions of the section header
fields:
Section Identifier

This field contains identifying code in the numeric format for


the type of data contained in the section. These data formats
are documented later in this paper and identified by the
identifier code value.
The following type identifier codes are used:
Section Data Type
Identifier
0x00 Mapping data for VFS entries
0x01 Virtual registry data
0x05 Fonts
0x06 List of VFS source paths
0x07 NT Object Exclusion List
0x09 Virtual registry data –
Machine
0x0A Virtual registry data - User
0x0B Unique ID Copy

Reserved

This field is reserved and is initialized to all zeroes.


Section Size

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.

Data Page Header


Each page of data inside the CP file format consists of a small
page header (12 bytes) immediately followed by actual data
content for that page. The size of the data for the page is always
1024 bytes if exactly 1024 or more bytes remain to be read for the
section (as can be tracked by using the “Section Size” field in the
section header). Otherwise, the page data size will be the total
number of bytes still not read for the whole section.
When parsing the section data, page content is read and added to
the buffer (consisting of previously read page data), after which
parsing must seek to the next page using offset in the field “Next
Page Offset.”
The format of the page header is listed in the following table.
Section Header Fields Size (bytes)
Reserved 4
Reserved 4
Next Page Offset 4

Page Header Field Descriptions


The following provides detailed definitions of the page header
fields:
Reserved

This field is reserved and is initialized to 0x00000001 ({0x01,


0x00, 0x00, 0x00}).
Reserved

This field is reserved and is initialized to all zeroes.


Next Page Offset

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.

Parsing Section Data


When all the sections and associated data pages in the CP file
have been read by following section/page links, actual parsing of
data payload for sections remains.
All the sections contain differently formatted data specially
targeted to reflect the intended use for it, such as registry key and
value entries for forming a virtual registry or mapping information
for virtual file system (VFS) entries.
If a particular section is missing in the CP file, that information will
not be present in the package’s virtual environment either.

CP File Section Types


The following subsections document and describe each different
type of data found inside the CP file’s sections. Any other sections
present in the CP file and not documented here are reserved.

Section 0x00 – Mapping data for VFS Entries


Mapping data for VFS entries consists of information that
SystemGuard will use to virtualize entries defined in the Virtual File
system (physically located under the VFS subdirectory inside the
package’s internal file system’s asset or root directory) against the
target system’s real file system. An example of this mapping
would be the path %SFT_MNT%\pkg\VFS\CSIDL_WINDOWS\app.dll
(“source” or “from”) mapping into the path of
%CSIDL_WINDOWS%\app.dll (“target” or “to”). This would make
file app.dll appear under the Windows directory (typically
c:\Windows) on package execution time—even though it is not in
that directory physically—and all I/O requests to said file will go to
the VFS\CSIDL_WINDOWS directory underneath the package’s file
structure on the virtual drive at the client.
VFS mapping entries will hold this mapping information but does
not describe any other file system level or virtualization aspects or
semantics for that file/directory. Furthermore, all the entries on this
list are files and directories that need to appear as fully virtualized;
partially virtualized directories—ones effectively acting as having
both local and virtual entries—do not appear in the mapping data
section or any other section in the CP file, but they can be
deducted from the fully virtualized file information which does
appear here. As an example: the previously mentioned
%SFT_MNT%\pkg\VFS\CSIDL_WINDOWS\app.dll mapping indicates
that the Windows directory needs to display app.dll as a virtualized
entry, but there is not mapping for
%SFT_MNT%\pkg\VFS\CSIDL_WINDOWS as its own entry since that
directory—or, more appropriately, the directory it maps to,
%CSIDL_WINDOWS%—needs to be in a semi-virtualized state.
All the paths referenced by the entries in this section use similar
notation that NT uses internally for file system paths in an object
manager’s namespace. That is to have \??\ in front of paths, so
the path from the previous mapping example is actually stored as
\??\%SFT_MNT%\pkg\VFS\CSIDL_WINDOWS\app.dll inside the 0x00
section. In addition, all paths are stored using intermediate values
(CSIDL_... values) inside the path—as defined by the SystemGuard
—if an appropriate substitutable string is found (i.e., a user’s
application data directory, gets changed to “%CSIDL_APPDATA%”
when stored in the VFS mapping entry).
All of the paths are stored as wide-char (double-byte) strings
without the terminating null character (0x0000).
This mapping data itself is stored as continuous blocks (of fields)
of individual mapping entries in a section’s data content. Each
entry is 32 bytes plus the actual strings of the paths. There is no
terminating information in the last block or in the section itself, but
rather the list stops when the end of the section data size is
reached.
The format of the mapping entry block is listed in the following
table.
VFS Mapping Entry Block Size (bytes)
Fields
Entry Size 4
Entry Block Header Size 4
Virtualized Path Size 4
Virtualized Path Offset 4
Package Path Size 4
Package Path Offset 4
PathFlags 4
Attributes 4
Paths variable

VFS Mapping Entry Block Field Descriptions


The following provides detailed definitions of the VFS mapping
entry fields:
Entry Size

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

This field contains the size of the virtualized (“target”) path


string in bytes.
Virtualized Path Offset

This field stores the relative byte offset to the virtualized


(“target”) path string inside mapping entry block. The offset is
relative to the beginning of the entry block header.
Package Path Size

This field contains the size of the physical (“source”) path


string in bytes.
Package Path Offset

This field stores the relative byte offset to the physical


(“source”) path string inside mapping entry block. The offset is
relative to the beginning of the entry block header.
PathFlags

This bitfield indicates the presence of virtualized and package


paths.
Type of Entry Value
Virtualized Path 0x00000001 ({0x01, 0x00, 0x00,
0x00})
Package Path 0x00000002 ({0x02, 0x00, 0x00,
0x00})

Attributes

This bitfield indicates the type of virtualized path.


Type of Entry Value
Directory 0x00000004 ({0x04, 0x00, 0x00,
0x00})
Deleted 0x00000008 ({0x08, 0x00, 0x00,
0x00})

Immediately following the fixed-length fields are the source and


target strings. The exact starting location and length are defined
using the offset and size fields.

Section 0x01 – Virtual Registry data


The Virtual Registry section contains the entire virtual registry for
the package. It is divided into the machine-specific registry branch
(“\REGISTRY\MACHINE\”) and the user-specific registry branch
(“\REGISTRY\USER\”), which map into their respective registry
hives of HKEY_LOCAL_MACHINE and HKEY_USERS in the Windows
registry.
All the registry keys referenced by the entries in this section use
notation wherein the path starts with “\REGISTRY\” and depending
on the hive has “MACHINE” or “USER” as identification for the
hive. The complete path value then would be, for example,
“\REGISTRY\MACHINE\Software\Microsoft”. There is not a separate
base-level key for HKEY_CURRENT_USER, but rather the
intermediate values are again used for the path of
\REGISTRY\USER\%SFT_SID% that denotes the path to the current
user’s registry hive which resolves to HKEY_USERS\<user’s sid>
when running in the Virtual Environment.
All the virtual registry entries are either of type registry key or
value, depending on the information found in the registry entry’s
header part. All the registry values for a given key are listed
immediately following it, so when parsing the data, the state
needs to be kept to track which values are associated with which
key.
The names of the keys and values are stored as wide-char strings
without the terminating null character (0x0000), whereas string
value data (REG_SZ etc.) are stored with a terminating null.
Virtual registry entry data itself is stored as continuous blocks (of
fields) of key or value entries in a section’s data content. Each
entry is 52 bytes plus the actual string of the key/value name, and
in the case of value, the value data itself. In order to parse the
entry data, entries need to be read in sequence, stopping when
an end-of-data marker is detected (0x00 value for “Entry Size”), in
which case there is no more data than that first field.
The format of the virtual registry entry block is listed in the
following table.
VREG Entry Block Fields Size (bytes)
Entry Size 4
Entry Block Header Size 4
Entry Type 4
Name Offset 4
Name Size 4
Data Offset 4
Data Length 4
Attributes 4
Last Write Timestamp 8
Value Type 4
Virtualize 4
Flags 4
Name variable
Value Data variable

Virtual Registry Entry Block Field Descriptions


The following provides detailed definitions of the Virtual Registry
entry fields:
Entry Size
This field contains the size of the entry block in total number of
bytes.
Note: If 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). This field has
the value 0x00000030 ({0x30, 0x00, 0x00, 0x00}) always.
Entry Type
This field stores the type of the registry entry.
Type of Entry Value
Registry key 0x00000001 ({0x01, 0x00, 0x00,
0x00})
Registry value 0x00000002 ({0x02, 0x00, 0x00,
0x00})

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.

Attribute Value (bits)


DeletedNode 0x00000040 ({0x40, 0x00, 0x00,
0x00})
VirtualNode 0x00000080 ({0x80, 0x00, 0x00,
0x00})
HasValue 0x00000400 ({0x00,
0x04,0x00,0x00})
VirtualValue 0x00001000 ({0x00, 0x10, 0x00,
0x00})
DeletedValue 0x00002000 ({0x00, 0x20, 0x00,
0x00})

Last Write Timestamp

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

This field has the value 1 if this registry entry is to be


virtualized and 0 if it is not a virtualized entry.
Flags

This field indicates the type of registry entry.


Attribute Value (bits)
ParsedKey 0x00000001 ({0x01, 0x00, 0x00,
0x00})
ParsedData 0x00000002 ({0x02, 0x00, 0x00,
0x00})

Immediately following the fixed-length fields are the key/value


name string and, optionally, the value data. Presence of value data
must be looked at using the “Value data present” bit flag or by
examining the “Value Data Size” field.

Different types of value data are stored in the following way:


REG_SZ, REG_EXPAND_SZ and REG_MULTI_SZ
All the string formats store the content in the same way. A
terminating character of null (0x0000) is at the end of the string,
and the string is wide-char array, starting from “Value Data Offset”
and having a length of Value Data Offset + Value Data Size.

An exception to the normal form for strings is when value data


begins with a 0x0101 marker. This special notation means that the
value data string contains SystemGuard intermediate values that
need to be converted to their respective resolved forms when
displayed at target virtual environment.
After the marker, a list of offset locations for intermediate form
strings follows before the actual full string begins; this list has the
following form:

Field Size (bytes)


Count 4
Offset #1 4
Offset #2 4
… 4
Intermediate Location Field Descriptions
The following provides detailed definitions of the fields for the
intermediate string location list:
Count

This field stores the total number of intermediate-form strings


contained within the actual value data string. By reading this
count, the number of offset locations immediately following the
count can be resolved.
Offset #1 … #n

This field stores the relative byte offset to the intermediate


form string #n starting from the beginning of the actual string.
This location can be jumped to and replaced with the actual
parsed string; the end of the intermediate string can be found
by following the virtual variable (in the form of %XXX%) until
the ending percent character.
When intermediate locations are read in, the actual array of
characters for the string begins.
REG_BINARY
The binary value data contains the “Value Data Size” number of
bytes making up the value. No special processing applies to this
data type.

REG_DWORD
The double-word value data contains normal 32-bit value as the
data. No special processing applies to this data type.

Section 0x05 – Font Data


This section is used to store virtualized Font paths.

Font Path Entry Block Size (bytes)


Fields
Entry Size 4
Entry Block Header Size 4
Entry Flags 4
Path Offset 4
Path Size 4
Font Path variable

Font Path Entry Block Field Descriptions


The following provides detailed definitions of the Font Path entry
fields:
Entry Size

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 has the value 0x00000001 ({0x01, 0x00, 0x00,


0x00}).
Path Offset

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.

Section 0x06 – List of VFS source paths


This list of VFS short path entries consists of file and directory
names that VFS entries were originally called on the source
machine, i.e., hard-coded path names without having been
converted to intermediate names, such as CSIDL_WINDOWS
instead of C:\Windows (or rather C: and Windows as separate
entries).
For example, if a file was virtualized from the path
C:\folder\foo.dat, this section would contain entries for “C:”,
“folder,” and “foo.dat.” These entries would appear in alphabetical
order, but there would be no information stored about mutual
parent/child relationship of the entries marking for directories, so it
(previously given the list for C:\folder\foo.dat) could continue by
“folder2” and that would either be the subdirectory for C:\folder or
C:\.
All names in this section are as wide-char strings without the
terminating null character (0x0000).
The list itself is stored as continuous blocks (of fields) of individual
entries in the section’s data content. Each entry is 20 bytes plus
the actual strings of the paths. There is no terminating information
in the last block or in the section itself, but rather the list stops
when the end of the section data size is reached.
The format of the fully virtualized VFS entry block is listed in the
following table.
Fully Virtualized VFS Entry Size (bytes)
Block Fields
Entry Size 4
Entry Block Header Size 4
Reserved 4
Subentry Count 4
Name Offset 4
Name Size 4
Shortname Offset 4
Shortname Size 4
Names variable
Fully virtualized VFS Entry Block Field Descriptions
The following provides detailed definitions of the fully virtualized
VFS entry fields:
Entry Size

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.

Section 0x07 – NT Object Exclusion List


The NT object list stores the list of object names in NT’s Object
Manager namespace that will get special handling (exclusion) by
the virtual environment at the App-V client. App-V Sequencer
populates this list from a predefined list of values stored in the
App-V Sequencer machine’s registry.
All strings in this section are stored as wide-char strings with the
terminating null character (0x0000).
The list itself is stored as continuous blocks (of fields) of individual
entries in the section’s data content. Each entry is 14 bytes plus
the actual object name string. The list stops when an entry with
the size of 0 is reached (this entry is only 4 bytes long, the first
field).
The format of the NT object list block is listed in the following
table.
NT Object List Entry Block Size (bytes)
Fields
Entry Size 4
Entry Block Header Size 4
Name Size 4
Name Offset 4
Reserved 4
Object Name variable

NT Object List Entry Block Field Descriptions


The following provides detailed definitions of the entry fields:
Entry Size
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 the object name).
Name Size
This field contains the size of the object name in bytes.
Name Offset
This field stores the relative byte offset to the name of the NT
Object Manager object inside entry block. The offset is relative
to the beginning of the entry block header.
Reserved
This field is reserved and is initialized to all zeroes.

Immediately following the fixed-length fields is the string for the


object’s name or partial name. The exact starting location and
length are defined using the offset and size fields.

Section 0x09 –Virtual registry data - Machine


This section contains the partial copy of the virtual registry, but it
is stored in a different format from section 0x01. The registry
content in this section is only the machine, non-user, data found in
section 0x01.
Keys and values in this section are also stored unlike those in the
full registry copy in that they contain only the key/value name, not
the whole key path. The registry key hierarchy is maintained using
pointer fields linking to the parent key, first subkey, etc., using an
identification number. For this to work, when parsing the entries,
an incrementing counter needs to be kept and the id associated
with each entry from that counter. This counter starts from zero
and is for the root level element (“REGISTRY”). After all blocks
have been read in, hierarchy can be constructed using the id
pointers in each entry’s data. In this data, the value of 0xFFFFFFFF
means that the pointer cannot be followed anymore in such
direction.
The names of the keys and values are stored separately from the
actual entries as a string/value table at the end of the section. In
terms of layout, the first portion of data is a small header block (12
bytes), which is followed by registry entries blocks and, lastly, the
string/value table, as illustrated below. String values in the table
are wide-char strings with the terminating null character (0x00).

Header (12 bytes)


Entry 0 (72 bytes)
Entry 1 (72 bytes)
...
Entry n(72 bytes)

String/value table

Virtual registry entry data itself is stored as continuous blocks (of


fields) of key or value entries, each entry being 72 bytes in size. In
order to parse the entry data, entries need to be read in sequence,
stopping when a predefined number of entries have been read in
(“Entry Count” in header field).
After the virtual registry entries, the string/value table begins
immediately.
The format of the header block is listed in the following table.
Header Block Fields Size (bytes)
Reserved 4
Entry Count 4
String-table Size 4

Header Block Field Descriptions


The following provides detailed definitions of the Virtual Registry
entry fields:
Reserved
This field is reserved. For current packages, this field is
initialized to 0x00000002 ({0x02, 0x00, 0x00, 0x00}).
Entry Count
This field contains the number of entry blocks following the
header block.
String-table Size
This field stores the byte size of the string-table that follows
immediately after the registry entry blocks.
The format of the virtual registry entry block is listed in the
following table.
VREG Entry Block fields Size (bytes)
Name Offset 4
Name Size 4
Value Data Offset 4
Value Data Size 4
Reserved 8
Last-written Timestamp 8
Reserved 4
Attributes 4
Entry Type 4
Value Type 4
Has Values 4
Reserved 4
Pointer to Parent 4
Pointer to Value 4
Pointer to Child Key 4
Pointer to Next Key 4

Virtual Registry Entry Block Field Descriptions


The following provides detailed definitions of the Virtual Registry
entry fields:
Name Offset
This field stores the relative byte offset to the name of the
entry inside string/value block.
Name Size
This field contains the size of the name in bytes.
Value Data Offset
This field stores the relative byte offset to the value data inside
string/value block.
Note: This field is only used with registry values and keys
having default value; otherwise, the field is initialized to
0xFFFFFFFF on key entries.
Value Data Size
This field contains the size of the value data in bytes.
Note: This field is only used with registry values and keys
having default value; otherwise, the field is initialized to
0x00000000 on key entries.
Reserved
This field is reserved and is initialized to all zeroes.
Last-written Timestamp
This field contains the last written timestamp for the registry
entry, and it is stored as a win32 FILETIME structure. The
format is the UTC (GMT) time zone.
Reserved
This field is reserved and is initialized to all zeroes.
Attributes
This is a bit field used to indicate attributes for the virtual
registry key and value. The following table displays the list of
attributes. Any fields not listed are reserved.

Attribute Value (in binary)


Value data present ‘00000100’
Override local key ‘00010000’
Deleted key ‘00100000’
Reserved ‘01000000’
Reserved ‘10000000’

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

Note: Although, technically, other types of values could exist


within a virtual registry, types in the previous table are the
ones described in more detail in this paper.
Note: A Registry key entry without a default value has this field
initialized to all zeroes.
Has Values
This is a Boolean field is set to 1 if the entry for this value if
Section 1’s .Attributes field has the HasValue flag (0x00000400
({0x00, 0x04,0x00,0x00})) set.
Reserved
This field is reserved and is initialized to all zeroes.
Pointer to Parent
This field stores the pointer to the parent entry 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 is not a parent entry (the root element) for this
key, this field is initialized to 0xFFFFFFFF.
Pointer to Value
This field stores the pointer to the first value entry 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 values beneath this key—or the entry
being parsed is a value entry—this field is initialized to
0xFFFFFFFF.
Pointer to Child Key

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.

Section 0x0A – Virtual registry data - User


The registry content in this section is only the user-specific, non-
machine, data found in section 0x01
This section format is identical to section 0x01.

Section 0x0B – Unique ID Copy


This section contains the copy of the unique identifier of the CP file
(defined in the CP File Header Section field “Unique ID”).
Therefore, the size of this section is always exactly 16 bytes and
has the GUID itself as the only data content.

Anda mungkin juga menyukai