Class: Omnizip::Formats::Msi::StringPool

Inherits:
Object
  • Object
show all
Includes:
Constants
Defined in:
lib/omnizip/formats/msi/string_pool.rb

Overview

MSI String Pool

Manages the interned string pool used by MSI files. Strings are stored in _StringPool (UTF-16LE data with length prefix) and _StringData (raw concatenated data).

Based on Wine's msi_load_string_table implementation.

Constant Summary

Constants included from Constants

Constants::BINARY_TYPE, Constants::CATEGORY_BINARY, Constants::CATEGORY_CABINET, Constants::CATEGORY_CONDITION, Constants::CATEGORY_DEFAULT, Constants::CATEGORY_DOUBLE, Constants::CATEGORY_FILENAME, Constants::CATEGORY_GUID, Constants::CATEGORY_IDENTIFIER, Constants::CATEGORY_LANGUAGE, Constants::CATEGORY_LOWERCASE, Constants::CATEGORY_PATH, Constants::CATEGORY_SHORTCUT, Constants::CATEGORY_TEMPLATE, Constants::CATEGORY_TEXT, Constants::CATEGORY_UPPERCASE, Constants::CATEGORY_VERSION, Constants::COLUMNS_STREAM, Constants::COMPONENT_TABLE, Constants::COMP_ATTR_64BIT, Constants::COMP_ATTR_DISABLE_REGISTRY, Constants::COMP_ATTR_LOCAL_ONLY, Constants::COMP_ATTR_NEVER_OVERWRITE, Constants::COMP_ATTR_ODBC, Constants::COMP_ATTR_OPTIONAL, Constants::COMP_ATTR_PERMANENT, Constants::COMP_ATTR_REGISTRY_KEY_PATH, Constants::COMP_ATTR_SHARED, Constants::COMP_ATTR_SHARED_DLL, Constants::COMP_ATTR_SOURCE_ONLY, Constants::COMP_ATTR_TRANSITIVE, Constants::COMP_ATTR_UNINSTALL_ON_SUPERSEDE, Constants::DIRECTORY_TABLE, Constants::EMBEDDED_CAB_PREFIX, Constants::FILE_ATTR_CHECKSUM, Constants::FILE_ATTR_COMPRESSED, Constants::FILE_ATTR_HIDDEN, Constants::FILE_ATTR_NONCOMPRESSED, Constants::FILE_ATTR_PATCHADDED, Constants::FILE_ATTR_READONLY, Constants::FILE_ATTR_SYSTEM, Constants::FILE_ATTR_VITAL, Constants::FILE_TABLE, Constants::INT16_TYPE, Constants::INT32_TYPE, Constants::MEDIA_TABLE, Constants::OBJECT_TYPE, Constants::PROGRAM_FILES, Constants::PROGRAM_FILES_X64, Constants::SOURCE_DIR, Constants::STREAMS_TABLE, Constants::STRING_DATA_STREAM, Constants::STRING_POOL_STREAM, Constants::STRING_TYPE, Constants::SYSTEM_FOLDER, Constants::SYSTEM_X64_FOLDER, Constants::TABLES_STREAM, Constants::TARGET_DIR, Constants::WINDOWS_FOLDER

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Constants

decode_stream_name

Constructor Details

#initialize(ole, stream_reader = nil) ⇒ StringPool

Initialize string pool from OLE storage

Parameters:

  • ole (Ole::Storage)

    OLE storage object

  • stream_reader (Proc, Optional proc to read streams) (defaults to: nil)

    tream_reader [Proc, Optional proc to read streams



36
37
38
39
40
41
42
43
44
# File 'lib/omnizip/formats/msi/string_pool.rb', line 36

def initialize(ole, stream_reader = nil)
  @ole = ole
  @strings = [nil] # Index 0 is unused (1-based indexing)
  @codepage = 0
  @pool_cache = {}
  @stream_name_map = {}
  @stream_reader = stream_reader
  load
end

Instance Attribute Details

#codepageInteger (readonly)

Returns Codepage for string encoding.

Returns:

  • (Integer)

    Codepage for string encoding



27
28
29
# File 'lib/omnizip/formats/msi/string_pool.rb', line 27

def codepage
  @codepage
end

#oleOle::Storage (readonly)

Returns OLE storage reference.

Returns:



21
22
23
# File 'lib/omnizip/formats/msi/string_pool.rb', line 21

def ole
  @ole
end

#stream_name_mapHash (readonly)

Returns Stream name map (decoded name => encoded name).

Returns:

  • (Hash)

    Stream name map (decoded name => encoded name)



30
31
32
# File 'lib/omnizip/formats/msi/string_pool.rb', line 30

def stream_name_map
  @stream_name_map
end

#stringsArray<String> (readonly)

Returns Decoded strings indexed by pool position (1-based).

Returns:

  • (Array<String>)

    Decoded strings indexed by pool position (1-based)



24
25
26
# File 'lib/omnizip/formats/msi/string_pool.rb', line 24

def strings
  @strings
end

Instance Method Details

#[](index) ⇒ String?

Look up string by index

Parameters:

  • index (Integer)

    String index (1-based)

Returns:

  • (String, nil)

    Decoded string or nil if not found



50
51
52
53
54
# File 'lib/omnizip/formats/msi/string_pool.rb', line 50

def [](index)
  return nil if index.nil? || index <= 0

  @strings[index]
end

#read_stream(base_name) ⇒ String?

Read stream from OLE, handling MSI stream name encoding

Parameters:

  • base_name (String)

    Base stream name (e.g., "_StringPool")

Returns:

  • (String, nil)

    Stream content or nil



67
68
69
70
71
72
73
74
75
76
77
# File 'lib/omnizip/formats/msi/string_pool.rb', line 67

def read_stream(base_name)
  # Try various encodings of the stream name
  candidates = build_stream_name_candidates(base_name)

  candidates.each do |name|
    data = try_read_stream(name)
    return data if data && !data.empty?
  end

  nil
end

#sizeInteger

Get string count

Returns:

  • (Integer)


59
60
61
# File 'lib/omnizip/formats/msi/string_pool.rb', line 59

def size
  @strings.size - 1 # Subtract 1 for nil at index 0
end