win32-dir 0.4.6 → 0.4.7

Sign up to get free protection for your applications and to get access to all the features.
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.