Module: Winhelper

Extended by:
FFI::Library
Defined in:
lib/filewatch/winhelper.rb

Defined Under Namespace

Classes: FileId128, FileIdInfo, FileInformation, FileTime

Constant Summary collapse

FileInfoEnum =
enum(
  :FileBasicInfo,
  :FileStandardInfo,
  :FileNameInfo,
  :FileRenameInfo,
  :FileDispositionInfo,
  :FileAllocationInfo,
  :FileEndOfFileInfo,
  :FileStreamInfo,
  :FileCompressionInfo,
  :FileAttributeTagInfo,
  :FileIdBothDirectoryInfo,
  :FileIdBothDirectoryRestartInfo,
  :FileIoPriorityHintInfo,
  :FileRemoteProtocolInfo,
  :FileFullDirectoryInfo,
  :FileFullDirectoryRestartInfo,
  :FileStorageInfo,
  :FileAlignmentInfo,
  :FileIdInfo,
  :FileIdExtdDirectoryInfo,
  :FileIdExtdDirectoryRestartInfo
)

Class Method Summary collapse

Class Method Details

.char_pointer_to_ruby_string(char_pointer, length = 256) ⇒ Object



183
184
185
186
187
188
# File 'lib/filewatch/winhelper.rb', line 183

def self.char_pointer_to_ruby_string(char_pointer, length = 256)
  bytes = char_pointer.get_array_of_uchar(0, length)
  ignore = bytes.reverse.index{|b| b != 0} - 1
  our_bytes = bytes[0, bytes.length - ignore]
  our_bytes.pack("C*").force_encoding("UTF-16LE").encode("UTF-8")
end

.file_system_type_from_handle(handle, close_handle = true) ⇒ Object



113
114
115
116
117
118
119
120
121
122
# File 'lib/filewatch/winhelper.rb', line 113

def self.file_system_type_from_handle(handle, close_handle = true)
  out = FFI::MemoryPointer.new(:char, 256, true)
  if GetVolumeInformationByHandleW(handle, nil, 0, nil, nil, nil, out, 256) > 0
    char_pointer_to_ruby_string(out)
  else
    "unknown"
  end
ensure
  CloseHandle(handle) if close_handle
end

.file_system_type_from_io(io) ⇒ Object



107
108
109
110
111
# File 'lib/filewatch/winhelper.rb', line 107

def self.file_system_type_from_io(io)
  FileWatch::FileExt.io_handle(io) do |pointer|
    file_system_type_from_handle(pointer, false)
  end
end

.file_system_type_from_path(path) ⇒ Object



103
104
105
# File 'lib/filewatch/winhelper.rb', line 103

def self.file_system_type_from_path(path)
  file_system_type_from_handle(open_handle_from_path(path))
end

.identifier_from_handle(handle, close_handle = true) ⇒ Object



159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
# File 'lib/filewatch/winhelper.rb', line 159

def self.identifier_from_handle(handle, close_handle = true)
  fileInfo = Winhelper::FileInformation.new
  success = GetFileInformationByHandle(handle, fileInfo)
  if  success > 0
    #args = [
    #   fileInfo[:fileAttributes], fileInfo[:volumeSerialNumber], fileInfo[:fileSizeHigh], fileInfo[:fileSizeLow],
    #   fileInfo[:numberOfLinks], fileInfo[:fileIndexHigh], fileInfo[:fileIndexLow]
    # ]
    #p "Information: %u %u %u %u %u %u %u " % args
    #this is only guaranteed on NTFS, for ReFS on windows 2012, GetFileInformationByHandleEx should be used with FILE_ID_INFO, which returns a 128 bit identifier
    return "#{fileInfo[:volumeSerialNumber]}-#{fileInfo[:fileIndexLow]}-#{fileInfo[:fileIndexHigh]}"
  else
    return 'unknown'
  end
ensure
  CloseHandle(handle) if close_handle
end

.identifier_from_handle_ex(handle, close_handle = true) ⇒ Object



144
145
146
147
148
149
150
151
152
153
154
155
156
157
# File 'lib/filewatch/winhelper.rb', line 144

def self.identifier_from_handle_ex(handle, close_handle = true)
  fileIdInfo = Winhelper::FileIdInfo.new
  success = GetFileInformationByHandleEx(handle, :FileIdInfo, fileIdInfo, fileIdInfo.size)
  if success > 0
    vsn   = fileIdInfo[:volumeSerialNumber]
    lpfid = fileIdInfo[:fileId][:lowPart]
    hpfid = fileIdInfo[:fileId][:highPart]
    return "#{vsn}-#{lpfid}-#{hpfid}"
  else
    return 'unknown'
  end
ensure
  CloseHandle(handle) if close_handle
end

.identifier_from_io(io) ⇒ Object



124
125
126
127
128
# File 'lib/filewatch/winhelper.rb', line 124

def self.identifier_from_io(io)
  FileWatch::FileExt.io_handle(io) do |pointer|
    identifier_from_handle(pointer, false)
  end
end

.identifier_from_io_ex(io) ⇒ Object



138
139
140
141
142
# File 'lib/filewatch/winhelper.rb', line 138

def self.identifier_from_io_ex(io)
  FileWatch::FileExt.io_handle(io) do |pointer|
    identifier_from_handle_ex(pointer, false)
  end
end

.identifier_from_path(path) ⇒ Object



130
131
132
# File 'lib/filewatch/winhelper.rb', line 130

def self.identifier_from_path(path)
  identifier_from_handle(open_handle_from_path(path))
end

.identifier_from_path_ex(path) ⇒ Object



134
135
136
# File 'lib/filewatch/winhelper.rb', line 134

def self.identifier_from_path_ex(path)
  identifier_from_handle_ex(open_handle_from_path(path))
end

.open_handle_from_path(path) ⇒ Object



179
180
181
# File 'lib/filewatch/winhelper.rb', line 179

def self.open_handle_from_path(path)
  CreateFileW(utf16le(path), 0, 7, nil, 3, 128, nil)
end

.to_cstring(rubystring) ⇒ Object



194
195
196
# File 'lib/filewatch/winhelper.rb', line 194

def self.to_cstring(rubystring)
  rubystring + 0.chr
end

.utf16le(string) ⇒ Object



190
191
192
# File 'lib/filewatch/winhelper.rb', line 190

def self.utf16le(string)
  to_cstring(string).encode("UTF-16LE")
end

.win1252(string) ⇒ Object



198
199
200
# File 'lib/filewatch/winhelper.rb', line 198

def self.win1252(string)
  string.encode("Windows-1252")
end