win32-dir 0.4.6 → 0.4.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 25ed1b84d472bc93aebe5c716279d7257ee195f8
4
- data.tar.gz: 034fa5750ff550ee2d16b576141764ada29afe99
3
+ metadata.gz: e5e981af6ec776b828331968e333f10e07a00da1
4
+ data.tar.gz: 6d4998906fc38e42b166b4f169bcd3e209e8fe50
5
5
  SHA512:
6
- metadata.gz: d497ce2b9d5e8ad5ffc218b1b135b833145a473dd2a639c4c043ca7d6424914a6cb05ec0cc1977dac7e54451e51de03908b59668b12a6b0449794cc4b8bbc9e0
7
- data.tar.gz: b41580cef0a66660329635b7ea5ebbe613ec5f856ca0883d00de049240c52086af88dade08d45254939f42e8cb5c824a47b3ec651e14186992bb767a41583f69
6
+ metadata.gz: 3f6d943d7546b4b5a6df5507bf06e2dca571fe4f708eac4cf6f483f24cb20e304f3ab5cbbfb075d98cce0112e6e676069f0551d555f7e37ac78f536f2a5b45a9
7
+ data.tar.gz: cb65e88ec9fa7d671c4a2744ed4f7e0cb80405d88f63a22a15411b33b04bbfef00adf37fa24a3120f1f274569e92fd06bcadb465ddefc63f591a541c5b9f44db
data/CHANGES CHANGED
@@ -1,3 +1,14 @@
1
+ == 0.4.7 - 26-Apr-2014
2
+ * All arguments to methods are now interpolated so that they'll use whatever
3
+ to_str implemenation the argument provides instead of assuming String
4
+ arguments. This change was made because it turns out that at least some
5
+ of the overridden methods in MRI accept Pathname objects. Thanks go to
6
+ Josh Cooper/Puppet Labs for the spot.
7
+ * Refactored the Dir.getwd method to use bonafide FFI buffers instead of
8
+ naked Ruby char buffers.
9
+ * Internally various functions now fail in the event that the resulting
10
+ paths would exceed their buffers.
11
+
1
12
  == 0.4.6 - 21-Oct-2013
2
13
  * Fixed the INVALID_HANDLE_VALUE and INVALID_FILE_ATTRIBUTES constants for
3
14
  64-bit versions of Ruby.
data/README CHANGED
@@ -233,6 +233,8 @@ Dir::TEMPLATES
233
233
  only instead of an actual path.
234
234
 
235
235
  == Known Bugs
236
+ The Dir.create_junction and Dir.read_junction methods do not work with JRuby.
237
+
236
238
  Please log any bug reports on the project page at
237
239
  http://www.github.com/djberg96/win32-dir
238
240
 
@@ -259,7 +261,7 @@ Dir::TEMPLATES
259
261
  http://www.gittip.com/djberg96/
260
262
 
261
263
  == Copyright
262
- (C) 2003-2013 Daniel J. Berger, All Rights Reserved
264
+ (C) 2003-2014 Daniel J. Berger, All Rights Reserved
263
265
 
264
266
  == Warranty
265
267
  This package is provided "as is" and without any express or
data/Rakefile CHANGED
@@ -19,7 +19,7 @@ namespace 'gem' do
19
19
  end
20
20
 
21
21
  desc "Install the win32-dir gem"
22
- task :install => [:build] do
22
+ task :install => [:create] do
23
23
  file = Dir["*.gem"].first
24
24
  sh "gem install #{file}"
25
25
  end
@@ -8,7 +8,7 @@ class Dir
8
8
  extend Dir::Functions
9
9
 
10
10
  # The version of the win32-dir library.
11
- VERSION = '0.4.6'
11
+ VERSION = '0.4.7'
12
12
 
13
13
  # CSIDL constants
14
14
  csidl = Hash[
@@ -113,9 +113,9 @@ class Dir
113
113
  #
114
114
  def glob(glob_pattern, flags = 0, &block)
115
115
  if glob_pattern.is_a?(Array)
116
- temp = glob_pattern.map!{ |pattern| pattern.tr("\\", "/") }
116
+ temp = glob_pattern.map!{ |pattern| "#{pattern}".tr("\\", "/") }
117
117
  else
118
- temp = glob_pattern.tr("\\", "/")
118
+ temp = "#{glob_pattern}".tr("\\", "/")
119
119
  end
120
120
 
121
121
  old_glob(temp, flags, &block)
@@ -127,7 +127,7 @@ class Dir
127
127
  # backslashes in path names.
128
128
  #
129
129
  def [](*glob_patterns)
130
- temp = glob_patterns.map!{ |pattern| pattern.tr("\\", "/") }
130
+ temp = glob_patterns.map!{ |pattern| "#{pattern}".tr("\\", "/") }
131
131
  old_ref(*temp)
132
132
  end
133
133
 
@@ -148,31 +148,34 @@ class Dir
148
148
  # Dir.getwd # => C:\Program Files
149
149
  #
150
150
  def getwd
151
- path1 = 0.chr * 1024
152
- path2 = 0.chr * 1024
153
- path3 = 0.chr * 1024
151
+ path1 = FFI::Buffer.new(:wint_t, 1024, true)
152
+ path2 = FFI::Buffer.new(:wint_t, 1024, true)
153
+ path3 = FFI::Buffer.new(:wint_t, 1024, true)
154
154
 
155
- path1.encode!('UTF-16LE')
155
+ length = GetCurrentDirectoryW(path1.size, path1)
156
156
 
157
- if GetCurrentDirectoryW(path1.size, path1) == 0
157
+ if length == 0 || length > path1.size
158
158
  raise SystemCallError.new("GetCurrentDirectoryW", FFI.errno)
159
159
  end
160
160
 
161
- path2.encode!('UTF-16LE')
161
+ length = GetShortPathNameW(path1, path2, path2.size)
162
162
 
163
- if GetShortPathNameW(path1, path2, path2.size) == 0
163
+ if length == 0 || length > path2.size
164
164
  raise SystemCallError.new("GetShortPathNameW", FFI.errno)
165
165
  end
166
166
 
167
- path3.encode!('UTF-16LE')
167
+ length = GetLongPathNameW(path2, path3, path3.size)
168
168
 
169
- if GetLongPathNameW(path2, path3, path3.size) == 0
169
+ if length == 0 || length > path3.size
170
170
  raise SystemCallError.new("GetLongPathNameW", FFI.errno)
171
171
  end
172
+
173
+ path = path3.read_bytes(length * 2).wstrip
174
+
172
175
  begin
173
- path3.strip.encode(Encoding.default_external)
176
+ path.encode(Encoding.default_external)
174
177
  rescue Encoding::UndefinedConversionError
175
- path3.strip.encode('UTF-8')
178
+ path.encode('UTF-8')
176
179
  end
177
180
  end
178
181
 
@@ -189,26 +192,24 @@ class Dir
189
192
  # Dir.create_junction('C:/to', 'C:/from')
190
193
  #
191
194
  def self.create_junction(to, from)
192
- to = to.wincode
193
- from = from.wincode
195
+ to = "#{to}".wincode
196
+ from = "#{from}".wincode
194
197
 
195
- from_path = 0.chr * 1024
196
- from_path.encode!('UTF-16LE')
198
+ from_path = (0.chr * 1024).encode('UTF-16LE')
197
199
 
198
200
  length = GetFullPathNameW(from, from_path.size, from_path, nil)
199
201
 
200
- if length == 0
202
+ if length == 0 || length > from_path.size
201
203
  raise SystemCallError.new("GetFullPathNameW", FFI.errno)
202
204
  else
203
205
  from_path.strip!
204
206
  end
205
207
 
206
- to_path = 0.chr * 1024
207
- to_path.encode!('UTF-16LE')
208
+ to_path = (0.chr * 1024).encode('UTF-16LE')
208
209
 
209
210
  length = GetFullPathNameW(to, to_path.size, to_path, nil)
210
211
 
211
- if length == 0
212
+ if length == 0 || length > to_path.size
212
213
  raise SystemCallError.new("GetFullPathNameW", FFI.errno)
213
214
  else
214
215
  to_path.strip!
@@ -257,7 +258,7 @@ class Dir
257
258
  handle,
258
259
  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 41, METHOD_BUFFERED, 0),
259
260
  rdb,
260
- rdb[:ReparseDataLength] + 8,
261
+ rdb[:ReparseDataLength] + rdb.header_size,
261
262
  nil,
262
263
  0,
263
264
  bytes,
@@ -278,27 +279,26 @@ class Dir
278
279
  self
279
280
  end
280
281
 
281
- # Returns the+ +path+ that a given +symlink+ points to.
282
- # Raises +ENOENT+ if given path does not exist, returns +false+
282
+ # Returns the path that a given junction points to. Raises an
283
+ # Errno::ENOENT error if the given path does not exist. Returns false
283
284
  # if it is not a junction.
284
285
  #
285
286
  # Example:
286
287
  #
287
288
  # Dir.mkdir('C:/from')
288
289
  # Dir.create_junction('C:/to', 'C:/from')
289
- # Dir.read_junction("c:/to") => "c:/from"
290
+ # Dir.read_junction("c:/to") # => "c:/from"
290
291
  #
291
292
  def self.read_junction(junction)
292
- return false unless Dir.junction?(junction)
293
+ return false unless Dir.junction?("#{junction}")
293
294
 
294
- junction = junction.wincode
295
+ junction = "#{junction}".wincode
295
296
 
296
- junction_path = 0.chr * 1024
297
- junction_path.encode!('UTF-16LE')
297
+ junction_path = (0.chr * 1024).encode('UTF-16LE')
298
298
 
299
299
  length = GetFullPathNameW(junction, junction_path.size, junction_path, nil)
300
300
 
301
- if length == 0
301
+ if length == 0 || length > junction_path.size
302
302
  raise SystemCallError.new("GetFullPathNameW", FFI.errno)
303
303
  else
304
304
  junction_path.strip!
@@ -370,7 +370,7 @@ class Dir
370
370
  # a directory, or contains any files other than '.' or '..'.
371
371
  #
372
372
  def self.empty?(path)
373
- PathIsDirectoryEmptyW(path.wincode)
373
+ PathIsDirectoryEmptyW("#{path}".wincode)
374
374
  end
375
375
 
376
376
  # Returns whether or not +path+ is a junction.
@@ -378,7 +378,7 @@ class Dir
378
378
  def self.junction?(path)
379
379
  bool = true
380
380
 
381
- attrib = GetFileAttributesW(path.wincode)
381
+ attrib = GetFileAttributesW("#{path}".wincode)
382
382
 
383
383
  # Only directories with a reparse point attribute can be junctions
384
384
  if attrib == INVALID_FILE_ATTRIBUTES ||
@@ -23,16 +23,19 @@ module Dir::Functions
23
23
  typedef :pointer, :ptr
24
24
 
25
25
  ffi_lib :shell32
26
+ ffi_convention :stdcall
26
27
 
27
28
  attach_pfunc :SHGetFolderPathW, [:hwnd, :int, :handle, :dword, :buffer_out], :dword
28
29
  attach_pfunc :SHGetFolderLocation, [:hwnd, :int, :handle, :dword, :ptr], :dword
29
30
  attach_pfunc :SHGetFileInfo, [:dword, :dword, :ptr, :uint, :uint], :dword
30
31
 
31
32
  ffi_lib :shlwapi
33
+ ffi_convention :stdcall
32
34
 
33
35
  attach_pfunc :PathIsDirectoryEmptyW, [:buffer_in], :bool
34
36
 
35
37
  ffi_lib :kernel32
38
+ ffi_convention :stdcall
36
39
 
37
40
  attach_pfunc :CloseHandle, [:handle], :bool
38
41
  attach_pfunc :CreateDirectoryW, [:buffer_in, :ptr], :bool
@@ -53,4 +56,11 @@ class String
53
56
  def wincode
54
57
  (self.tr(File::SEPARATOR, File::ALT_SEPARATOR) + 0.chr).encode('UTF-16LE')
55
58
  end
59
+
60
+ # Read a wide character string up until the first double null, and delete
61
+ # any remaining null characters.
62
+ def wstrip
63
+ self.force_encoding('UTF-16LE').encode('UTF-8',:invalid=>:replace,:undef=>:replace).
64
+ split("\x00")[0].encode(Encoding.default_external)
65
+ end
56
66
  end
@@ -25,5 +25,13 @@ module Dir::Structs
25
25
  :PrintNameLength, :ushort,
26
26
  :PathBuffer, [:char, 1024]
27
27
  )
28
+
29
+ # The REPARSE_DATA_BUFFER_HEADER_SIZE which is calculated as:
30
+ #
31
+ # sizeof(ReparseTag) + sizeof(ReparseDataLength) + sizeof(Reserved)
32
+ #
33
+ def header_size
34
+ FFI::Type::ULONG.size + FFI::Type::USHORT.size + FFI::Type::USHORT.size
35
+ end
28
36
  end
29
37
  end
@@ -9,6 +9,7 @@ require 'test-unit'
9
9
  require 'win32/dir'
10
10
  require 'tmpdir'
11
11
  require 'fileutils'
12
+ require 'pathname'
12
13
 
13
14
  class TC_Win32_Dir < Test::Unit::TestCase
14
15
  def self.startup
@@ -25,7 +26,7 @@ class TC_Win32_Dir < Test::Unit::TestCase
25
26
  end
26
27
 
27
28
  test "version number is set to expected value" do
28
- assert_equal('0.4.6', Dir::VERSION)
29
+ assert_equal('0.4.7', Dir::VERSION)
29
30
  end
30
31
 
31
32
  test 'glob handles backslashes' do
@@ -52,6 +53,13 @@ class TC_Win32_Dir < Test::Unit::TestCase
52
53
  assert_true(array.include?('.'))
53
54
  end
54
55
 
56
+ test 'glob handles Pathname objects' do
57
+ pattern1 = Pathname.new("C:\\Program Files\\Common Files\\System\\*.dll")
58
+ pattern2 = Pathname.new("C:\\Windows\\*.exe")
59
+ assert_nothing_raised{ Dir.glob([pattern1, pattern2]) }
60
+ assert_true(Dir.glob([pattern1, pattern2]).size > 0)
61
+ end
62
+
55
63
  test 'ref handles backslashes' do
56
64
  pattern = "C:\\Program Files\\Common Files\\System\\*.dll"
57
65
  assert_nothing_raised{ Dir[pattern] }
@@ -65,6 +73,13 @@ class TC_Win32_Dir < Test::Unit::TestCase
65
73
  assert_true(Dir[pattern1, pattern2].size > 0)
66
74
  end
67
75
 
76
+ test 'ref handles pathname arguments' do
77
+ pattern1 = Pathname.new("C:\\Program Files\\Common Files\\System\\*.dll")
78
+ pattern2 = Pathname.new("C:\\Windows\\*.exe")
79
+ assert_nothing_raised{ Dir[pattern1, pattern2] }
80
+ assert_true(Dir[pattern1, pattern2].size > 0)
81
+ end
82
+
68
83
  test "create_junction basic functionality" do
69
84
  assert_respond_to(Dir, :create_junction)
70
85
  end
@@ -83,6 +98,13 @@ class TC_Win32_Dir < Test::Unit::TestCase
83
98
  assert_equal(Dir.entries(@@from), Dir.entries(@unicode_to))
84
99
  end
85
100
 
101
+ test "create_junction works as expected with pathname objects" do
102
+ assert_nothing_raised{ Dir.create_junction(Pathname.new(@ascii_to), Pathname.new(@@from)) }
103
+ assert_true(File.exists?(@ascii_to))
104
+ File.open(@test_file, 'w'){ |fh| fh.puts "Hello World" }
105
+ assert_equal(Dir.entries(@@from), Dir.entries(@ascii_to))
106
+ end
107
+
86
108
  test "read_junction works as expected with ascii characters" do
87
109
  assert_nothing_raised{ Dir.create_junction(@ascii_to, @@from) }
88
110
  assert_true(File.exists?(@ascii_to))
@@ -101,11 +123,18 @@ class TC_Win32_Dir < Test::Unit::TestCase
101
123
  assert_nothing_raised{ File.join(Dir.read_junction(@unicode_to), 'foo') }
102
124
  end
103
125
 
126
+ test "read_junction works as expected with pathname objects" do
127
+ assert_nothing_raised{ Dir.create_junction(Pathname.new(@ascii_to), Pathname.new(@@from)) }
128
+ assert_true(File.exists?(@ascii_to))
129
+ assert_equal(Dir.read_junction(@ascii_to), @@from)
130
+ end
131
+
104
132
  test "junction? method returns boolean value" do
105
133
  assert_respond_to(Dir, :junction?)
106
134
  assert_nothing_raised{ Dir.create_junction(@ascii_to, @@from) }
107
135
  assert_false(Dir.junction?(@@from))
108
136
  assert_true(Dir.junction?(@ascii_to))
137
+ assert_true(Dir.junction?(Pathname.new(@ascii_to)))
109
138
  end
110
139
 
111
140
  test "reparse_dir? is an aliase for junction?" do
@@ -117,6 +146,7 @@ class TC_Win32_Dir < Test::Unit::TestCase
117
146
  assert_respond_to(Dir, :empty?)
118
147
  assert_false(Dir.empty?("C:\\")) # One would think
119
148
  assert_true(Dir.empty?(@@from))
149
+ assert_true(Dir.empty?(Pathname.new(@@from)))
120
150
  end
121
151
 
122
152
  test "pwd basic functionality" do
@@ -2,7 +2,7 @@ require 'rubygems'
2
2
 
3
3
  Gem::Specification.new do |spec|
4
4
  spec.name = 'win32-dir'
5
- spec.version = '0.4.6'
5
+ spec.version = '0.4.7'
6
6
  spec.authors = ['Daniel J. Berger', 'Park Heesob']
7
7
  spec.license = 'Artistic 2.0'
8
8
  spec.email = 'djberg96@gmail.com'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: win32-dir
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.6
4
+ version: 0.4.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel J. Berger
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-10-21 00:00:00.000000000 Z
12
+ date: 2014-04-26 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: ffi
@@ -68,14 +68,14 @@ extra_rdoc_files:
68
68
  - MANIFEST
69
69
  files:
70
70
  - CHANGES
71
+ - MANIFEST
72
+ - README
73
+ - Rakefile
71
74
  - examples/dir_example.rb
75
+ - lib/win32/dir.rb
72
76
  - lib/win32/dir/constants.rb
73
77
  - lib/win32/dir/functions.rb
74
78
  - lib/win32/dir/structs.rb
75
- - lib/win32/dir.rb
76
- - MANIFEST
77
- - Rakefile
78
- - README
79
79
  - test/test_win32_dir.rb
80
80
  - win32-dir.gemspec
81
81
  homepage: http://github.com/djberg96/win32-dir
@@ -98,7 +98,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
98
98
  version: '0'
99
99
  requirements: []
100
100
  rubyforge_project: win32utils
101
- rubygems_version: 2.1.9
101
+ rubygems_version: 2.2.2
102
102
  signing_key:
103
103
  specification_version: 4
104
104
  summary: Extra constants and methods for the Dir class on Windows.