Module: Omnizip::Formats::Msi::Constants

Included in:
CabExtractor, DirectoryResolver, Entry, Reader, StringPool, TableParser
Defined in:
lib/omnizip/formats/msi/constants.rb

Overview

MSI-specific constants

MSI files use OLE compound document format with additional semantic structures for database tables and embedded cabinets.

Constant Summary collapse

STRING_TYPE =

String types: s0-s255 String index into string pool, category indicates max length

"s"
INT16_TYPE =

Integer types

"i2"
INT32_TYPE =

2-byte signed integer

"i4"
BINARY_TYPE =

Binary/stream type

"v0"
OBJECT_TYPE =

Object type (temporary)

"O0"
CATEGORY_TEXT =

Special column category values

0
CATEGORY_UPPERCASE =
1
CATEGORY_LOWERCASE =
2
CATEGORY_PATH =
3
CATEGORY_FILENAME =
4
CATEGORY_CONDITION =
5
CATEGORY_GUID =
6
CATEGORY_VERSION =
7
CATEGORY_LANGUAGE =
8
CATEGORY_BINARY =
9
CATEGORY_TEMPLATE =
10
CATEGORY_DOUBLE =
11
CATEGORY_CABINET =
12
CATEGORY_SHORTCUT =
13
CATEGORY_DEFAULT =
14
CATEGORY_IDENTIFIER =
15
TABLES_STREAM =

Standard MSI table names

"_Tables"
COLUMNS_STREAM =
"_Columns"
STRING_POOL_STREAM =
"_StringPool"
STRING_DATA_STREAM =
"_StringData"
FILE_TABLE =

Application tables

"File"
COMPONENT_TABLE =
"Component"
DIRECTORY_TABLE =
"Directory"
MEDIA_TABLE =
"Media"
STREAMS_TABLE =
"_Streams"
FILE_ATTR_READONLY =

File attributes (File.Attributes column)

0x00000001
FILE_ATTR_HIDDEN =
0x00000002
FILE_ATTR_SYSTEM =
0x00000004
FILE_ATTR_VITAL =
0x00000100
FILE_ATTR_CHECKSUM =
0x00000400
FILE_ATTR_PATCHADDED =
0x00001000
FILE_ATTR_NONCOMPRESSED =
0x00002000
FILE_ATTR_COMPRESSED =
0x00004000
TARGET_DIR =

Directory table special values

"TARGETDIR"
SOURCE_DIR =
"SourceDir"
PROGRAM_FILES =
"ProgramFilesFolder"
PROGRAM_FILES_X64 =
"ProgramFiles64Folder"
WINDOWS_FOLDER =
"WindowsFolder"
SYSTEM_FOLDER =
"SystemFolder"
SYSTEM_X64_FOLDER =
"System64Folder"
COMP_ATTR_LOCAL_ONLY =

Component attributes

0x00000000
COMP_ATTR_SOURCE_ONLY =
0x00000001
COMP_ATTR_OPTIONAL =
0x00000002
COMP_ATTR_REGISTRY_KEY_PATH =
0x00000004
COMP_ATTR_SHARED_DLL =
0x00000008
COMP_ATTR_PERMANENT =
0x00000010
COMP_ATTR_ODBC =
0x00000020
COMP_ATTR_TRANSITIVE =
0x00000040
COMP_ATTR_NEVER_OVERWRITE =
0x00000080
COMP_ATTR_64BIT =
0x00000100
COMP_ATTR_DISABLE_REGISTRY =
0x00000200
COMP_ATTR_UNINSTALL_ON_SUPERSEDE =
0x00000400
COMP_ATTR_SHARED =
0x00000800
EMBEDDED_CAB_PREFIX =

Media table cabinet name prefix Cabinet names starting with # indicate embedded cabinets

"#"

Class Method Summary collapse

Class Method Details

.decode_stream_name(encoded_name) ⇒ String

Decode MSI stream name from OLE storage

MSI uses a custom encoding where characters in the range 0x3800-0x4800 are encoded using a MIME-like base64 scheme. Characters 0x4840 and 0x5 are prefix markers that should be skipped.

Based on ReactOS/Wine's decode_streamname from msi/table.c

Parameters:

  • encoded_name (String)

    Encoded stream name (UTF-16LE with special encoding)

Returns:

  • (String)

    Decoded stream name



107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# File 'lib/omnizip/formats/msi/constants.rb', line 107

def self.decode_stream_name(encoded_name)
  result = +""
  i = 0

  while i < encoded_name.length
    ch = encoded_name[i].ord

    if ch >= 0x3800 && ch < 0x4800
      # MIME-like encoding: two 6-bit values
      c = ch - 0x3800
      result << mime_char(c & 0x3f)
      result << mime_char((c >> 6) & 0x3f)
    elsif ch >= 0x4800 && ch < 0x4840
      # Single character encoding
      result << mime_char(ch - 0x4800)
    elsif i.zero? && [0x4840, 0x0005].include?(ch)
      # Prefix character to skip (0x4840 is always first for tables)
      # 0x5 is also a prefix seen in some streams
    else
      # Regular character (including ASCII)
      result << encoded_name[i]
    end

    i += 1
  end

  result
end