Module: Omnizip::Platform::NtfsStreams
- Defined in:
- lib/omnizip/platform/ntfs_streams.rb
Overview
NTFS Alternate Data Streams handler Windows-only feature for managing file alternate streams
Class Method Summary collapse
-
.archive_streams(file_path) ⇒ Hash<String, String>
Archive streams to a hash.
-
.available? ⇒ Boolean
Check if NTFS streams are available.
-
.copy_streams(source_path, dest_path) ⇒ Integer
Copy all alternate streams from source to destination.
-
.delete_stream(file_path, stream_name) ⇒ Boolean
Delete alternate data stream.
-
.has_streams?(file_path) ⇒ Boolean
Check if file has any alternate streams.
-
.list_streams(file_path) ⇒ Array<String>
List alternate data streams for a file.
-
.read_stream(file_path, stream_name) ⇒ String?
Read alternate data stream.
-
.restore_streams(file_path, streams_data) ⇒ Integer
Restore streams from hash.
-
.stream_info(file_path, stream_name) ⇒ Hash?
Get stream information.
-
.write_stream(file_path, stream_name, data) ⇒ Boolean
Write alternate data stream.
Class Method Details
.archive_streams(file_path) ⇒ Hash<String, String>
Archive streams to a hash
165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 |
# File 'lib/omnizip/platform/ntfs_streams.rb', line 165 def self.archive_streams(file_path) return {} unless available? streams_data = {} streams = list_streams(file_path) streams.each do |stream| next if stream == "$DATA" data = read_stream(file_path, stream) streams_data[stream] = data if data end streams_data end |
.available? ⇒ Boolean
Check if NTFS streams are available
13 14 15 |
# File 'lib/omnizip/platform/ntfs_streams.rb', line 13 def self.available? Platform.supports_ntfs_streams? end |
.copy_streams(source_path, dest_path) ⇒ Integer
Copy all alternate streams from source to destination
113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 |
# File 'lib/omnizip/platform/ntfs_streams.rb', line 113 def self.copy_streams(source_path, dest_path) return 0 unless available? return 0 unless File.exist?(source_path) return 0 unless File.exist?(dest_path) copied = 0 streams = list_streams(source_path) streams.each do |stream| next if stream == "$DATA" # Skip main data stream data = read_stream(source_path, stream) copied += 1 if data && write_stream(dest_path, stream, data) end copied end |
.delete_stream(file_path, stream_name) ⇒ Boolean
Delete alternate data stream
92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 |
# File 'lib/omnizip/platform/ntfs_streams.rb', line 92 def self.delete_stream(file_path, stream_name) return false unless available? return false unless File.exist?(file_path) begin # Use PowerShell to remove stream cmd = "powershell -Command \"Remove-Item -Path '#{file_path}' " \ "-Stream '#{stream_name}'\"" system(cmd) $CHILD_STATUS.success? rescue StandardError => e warn "Failed to delete NTFS stream: #{e.}" if ENV["DEBUG"] false end end |
.has_streams?(file_path) ⇒ Boolean
Check if file has any alternate streams
154 155 156 157 158 159 |
# File 'lib/omnizip/platform/ntfs_streams.rb', line 154 def self.has_streams?(file_path) return false unless available? streams = list_streams(file_path) streams.any? { |s| s != "$DATA" } end |
.list_streams(file_path) ⇒ Array<String>
List alternate data streams for a file
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
# File 'lib/omnizip/platform/ntfs_streams.rb', line 21 def self.list_streams(file_path) return [] unless available? return [] unless File.exist?(file_path) streams = [] begin # Use PowerShell to list streams cmd = "powershell -Command \"Get-Item '#{file_path}' -Stream * | " \ "Select-Object -ExpandProperty Stream\"" output = `#{cmd} 2>&1` if $CHILD_STATUS.success? streams = output.lines.map(&:strip).reject do |s| s.empty? || s == ":$DATA" end end rescue StandardError => e warn "Failed to list NTFS streams: #{e.}" if ENV["DEBUG"] end streams end |
.read_stream(file_path, stream_name) ⇒ String?
Read alternate data stream
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
# File 'lib/omnizip/platform/ntfs_streams.rb', line 50 def self.read_stream(file_path, stream_name) return nil unless available? return nil unless File.exist?(file_path) begin # Read using alternate stream syntax: file.txt:StreamName stream_path = "#{file_path}:#{stream_name}" File.binread(stream_path) rescue Errno::ENOENT, Errno::EINVAL nil rescue StandardError => e warn "Failed to read NTFS stream: #{e.}" if ENV["DEBUG"] nil end end |
.restore_streams(file_path, streams_data) ⇒ Integer
Restore streams from hash
186 187 188 189 190 191 192 193 194 195 196 197 |
# File 'lib/omnizip/platform/ntfs_streams.rb', line 186 def self.restore_streams(file_path, streams_data) return 0 unless available? return 0 unless File.exist?(file_path) restored = 0 streams_data.each do |stream_name, data| restored += 1 if write_stream(file_path, stream_name, data) end restored end |
.stream_info(file_path, stream_name) ⇒ Hash?
Get stream information
136 137 138 139 140 141 142 143 144 145 146 147 148 |
# File 'lib/omnizip/platform/ntfs_streams.rb', line 136 def self.stream_info(file_path, stream_name) return nil unless available? return nil unless File.exist?(file_path) data = read_stream(file_path, stream_name) return nil unless data { name: stream_name, size: data.bytesize, exists: true, } end |
.write_stream(file_path, stream_name, data) ⇒ Boolean
Write alternate data stream
72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
# File 'lib/omnizip/platform/ntfs_streams.rb', line 72 def self.write_stream(file_path, stream_name, data) return false unless available? return false unless File.exist?(file_path) begin # Write using alternate stream syntax: file.txt:StreamName stream_path = "#{file_path}:#{stream_name}" File.binwrite(stream_path, data) true rescue StandardError => e warn "Failed to write NTFS stream: #{e.}" if ENV["DEBUG"] false end end |