Class: Omnizip::Formats::Msi::DirectoryResolver

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

Overview

MSI Directory Resolver

Resolves the full installation path for files by traversing the Directory table hierarchy. MSI uses a self-referential structure where each directory entry references its parent.

Directory table columns:

  • Directory: Primary key (directory identifier)
  • Directory_Parent: Parent directory reference (nil for root)
  • DefaultDir: Directory name format "Source|Target" or "Name"

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(directory_table) ⇒ DirectoryResolver

Initialize resolver with directory table

Parameters:

  • directory_table (Array<Hash>)

    Parsed Directory table rows



33
34
35
36
37
38
# File 'lib/omnizip/formats/msi/directory_resolver.rb', line 33

def initialize(directory_table)
  @directory_table = directory_table || []
  @path_cache = {}
  @directories = {}
  build_directory_map
end

Instance Attribute Details

#directoriesHash (readonly)

Returns Directory info (key => name, default_dir).

Returns:

  • (Hash)

    Directory info (key => name, default_dir)



28
29
30
# File 'lib/omnizip/formats/msi/directory_resolver.rb', line 28

def directories
  @directories
end

#directory_tableHash (readonly)

Returns Directory table data.

Returns:

  • (Hash)

    Directory table data



22
23
24
# File 'lib/omnizip/formats/msi/directory_resolver.rb', line 22

def directory_table
  @directory_table
end

#path_cacheHash (readonly)

Returns Directory cache (key => full path).

Returns:

  • (Hash)

    Directory cache (key => full path)



25
26
27
# File 'lib/omnizip/formats/msi/directory_resolver.rb', line 25

def path_cache
  @path_cache
end

Instance Method Details

#resolve_path(directory_key) ⇒ String

Resolve full path for a directory key

Parameters:

  • directory_key (String)

    Directory identifier

Returns:

  • (String)

    Full path (empty string if not found)



44
45
46
47
48
49
50
51
52
53
54
# File 'lib/omnizip/formats/msi/directory_resolver.rb', line 44

def resolve_path(directory_key)
  return "" if directory_key.nil? || directory_key.empty?

  # Check cache
  return @path_cache[directory_key] if @path_cache.key?(directory_key)

  # Resolve path
  path = build_path(directory_key, Set.new)
  @path_cache[directory_key] = path
  path
end

#source_name(directory_key) ⇒ String?

Get the source directory name for a directory key

Parameters:

  • directory_key (String)

    Directory identifier

Returns:

  • (String, nil)

    Source directory name



60
61
62
63
64
65
# File 'lib/omnizip/formats/msi/directory_resolver.rb', line 60

def source_name(directory_key)
  dir_info = @directories[directory_key]
  return nil unless dir_info

  parse_default_dir(dir_info[:default_dir])[:source]
end

#target_name(directory_key) ⇒ String?

Get the target directory name for a directory key

Parameters:

  • directory_key (String)

    Directory identifier

Returns:

  • (String, nil)

    Target directory name



71
72
73
74
75
76
# File 'lib/omnizip/formats/msi/directory_resolver.rb', line 71

def target_name(directory_key)
  dir_info = @directories[directory_key]
  return nil unless dir_info

  parse_default_dir(dir_info[:default_dir])[:target]
end