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 +4 -4
- data/CHANGES +11 -0
- data/README +3 -1
- data/Rakefile +1 -1
- data/lib/win32/dir.rb +34 -34
- data/lib/win32/dir/functions.rb +10 -0
- data/lib/win32/dir/structs.rb +8 -0
- data/test/test_win32_dir.rb +31 -1
- data/win32-dir.gemspec +1 -1
- metadata +7 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e5e981af6ec776b828331968e333f10e07a00da1
|
4
|
+
data.tar.gz: 6d4998906fc38e42b166b4f169bcd3e209e8fe50
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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-
|
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
data/lib/win32/dir.rb
CHANGED
@@ -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.
|
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 =
|
152
|
-
path2 =
|
153
|
-
path3 =
|
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.
|
155
|
+
length = GetCurrentDirectoryW(path1.size, path1)
|
156
156
|
|
157
|
-
if
|
157
|
+
if length == 0 || length > path1.size
|
158
158
|
raise SystemCallError.new("GetCurrentDirectoryW", FFI.errno)
|
159
159
|
end
|
160
160
|
|
161
|
-
path2.
|
161
|
+
length = GetShortPathNameW(path1, path2, path2.size)
|
162
162
|
|
163
|
-
if
|
163
|
+
if length == 0 || length > path2.size
|
164
164
|
raise SystemCallError.new("GetShortPathNameW", FFI.errno)
|
165
165
|
end
|
166
166
|
|
167
|
-
path3.
|
167
|
+
length = GetLongPathNameW(path2, path3, path3.size)
|
168
168
|
|
169
|
-
if
|
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
|
-
|
176
|
+
path.encode(Encoding.default_external)
|
174
177
|
rescue Encoding::UndefinedConversionError
|
175
|
-
|
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] +
|
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
|
282
|
-
#
|
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")
|
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 ||
|
data/lib/win32/dir/functions.rb
CHANGED
@@ -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
|
data/lib/win32/dir/structs.rb
CHANGED
@@ -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
|
data/test/test_win32_dir.rb
CHANGED
@@ -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.
|
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
|
data/win32-dir.gemspec
CHANGED
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.
|
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:
|
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.
|
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.
|