win32-file-security 1.0.6 → 1.0.7

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,149 +1,149 @@
1
- module Windows
2
- module File
3
- module Constants
4
- SE_DACL_PRESENT = 4
5
- OWNER_SECURITY_INFORMATION = 1
6
- GROUP_SECURITY_INFORMATION = 2
7
- DACL_SECURITY_INFORMATION = 4
8
- ACCESS_ALLOWED_ACE_TYPE = 0
9
- ERROR_INSUFFICIENT_BUFFER = 122
10
- ACL_REVISION2 = 2
11
- ALLOW_ACE_LENGTH = 62
12
- OBJECT_INHERIT_ACE = 0x1
13
- CONTAINER_INHERIT_ACE = 0x2
14
- INHERIT_ONLY_ACE = 0x8
15
- MAXDWORD = 0xFFFFFFFF
16
- TOKEN_QUERY = 0x00000008
17
- TOKEN_ADJUST_PRIVILEGES = 0x0020
18
-
19
- ERROR_NOT_SUPPORTED = 50
20
- ERROR_NO_SECURITY_ON_OBJECT = 1350
21
-
22
- TokenUser = 1
23
- TokenGroups = 2
24
-
25
- SECURITY_DESCRIPTOR_REVISION = 1
26
- SECURITY_DESCRIPTOR_MIN_LENGTH = 20
27
-
28
- SE_KERNEL_OBJECT = 6
29
- SE_FILE_OBJECT = 1
30
- SE_PRIVILEGE_ENABLED = 0x00000002
31
- SE_SECURITY_NAME = "SeSecurityPrivilege"
32
- SE_TAKE_OWNERSHIP_NAME = "SeTakeOwnershipPrivilege"
33
- SE_BACKUP_NAME = "SeBackupPrivilege"
34
- SE_RESTORE_NAME = "SeRestorePrivilege"
35
- SE_CHANGE_NOTIFY_NAME = "SeChangeNotifyPrivilege"
36
-
37
- ## Security Rights
38
-
39
- SYNCHRONIZE = 0x100000
40
- STANDARD_RIGHTS_REQUIRED = 0xf0000
41
- STANDARD_RIGHTS_READ = 0x20000
42
- STANDARD_RIGHTS_WRITE = 0x20000
43
- STANDARD_RIGHTS_EXECUTE = 0x20000
44
- STANDARD_RIGHTS_ALL = 0x1F0000
45
- SPECIFIC_RIGHTS_ALL = 0xFFFF
46
- ACCESS_SYSTEM_SECURITY = 0x1000000
47
- MAXIMUM_ALLOWED = 0x2000000
48
- GENERIC_READ = 0x80000000
49
- GENERIC_WRITE = 0x40000000
50
- GENERIC_EXECUTE = 0x20000000
51
- GENERIC_ALL = 0x10000000
52
- GENERIC_RIGHTS_CHK = 0xF0000000
53
- REST_RIGHTS_MASK = 0x001FFFFF
54
- READ_CONTROL = 0x20000
55
- WRITE_DAC = 0x40000
56
- WRITE_OWNER = 0x80000
57
-
58
- FILE_READ_DATA = 1
59
- FILE_LIST_DIRECTORY = 1
60
- FILE_WRITE_DATA = 2
61
- FILE_ADD_FILE = 2
62
- FILE_APPEND_DATA = 4
63
- FILE_ADD_SUBDIRECTORY = 4
64
- FILE_CREATE_PIPE_INSTANCE = 4
65
- FILE_READ_EA = 8
66
- FILE_READ_PROPERTIES = 8
67
- FILE_WRITE_EA = 16
68
- FILE_WRITE_PROPERTIES = 16
69
- FILE_EXECUTE = 32
70
- FILE_TRAVERSE = 32
71
- FILE_DELETE_CHILD = 64
72
- FILE_READ_ATTRIBUTES = 128
73
- FILE_WRITE_ATTRIBUTES = 256
74
-
75
- FILE_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x1FF
76
-
77
- FILE_GENERIC_READ =
78
- STANDARD_RIGHTS_READ |
79
- FILE_READ_DATA |
80
- FILE_READ_ATTRIBUTES |
81
- FILE_READ_EA |
82
- SYNCHRONIZE
83
-
84
- FILE_GENERIC_WRITE =
85
- STANDARD_RIGHTS_WRITE |
86
- FILE_WRITE_DATA |
87
- FILE_WRITE_ATTRIBUTES |
88
- FILE_WRITE_EA |
89
- FILE_APPEND_DATA |
90
- SYNCHRONIZE
91
-
92
- FILE_GENERIC_EXECUTE =
93
- STANDARD_RIGHTS_EXECUTE |
94
- FILE_READ_ATTRIBUTES |
95
- FILE_EXECUTE |
96
- SYNCHRONIZE
97
-
98
- FILE_SHARE_READ = 1
99
- FILE_SHARE_WRITE = 2
100
- FILE_SHARE_DELETE = 4
101
- FILE_NOTIFY_CHANGE_FILE_NAME = 1
102
- FILE_NOTIFY_CHANGE_DIR_NAME = 2
103
- FILE_NOTIFY_CHANGE_ATTRIBUTES = 4
104
- FILE_NOTIFY_CHANGE_SIZE = 8
105
- FILE_NOTIFY_CHANGE_LAST_WRITE = 16
106
- FILE_NOTIFY_CHANGE_LAST_ACCESS = 32
107
- FILE_NOTIFY_CHANGE_CREATION = 64
108
- FILE_NOTIFY_CHANGE_SECURITY = 256
109
- FILE_CASE_SENSITIVE_SEARCH = 1
110
- FILE_CASE_PRESERVED_NAMES = 2
111
- FILE_UNICODE_ON_DISK = 4
112
- FILE_PERSISTENT_ACLS = 8
113
- FILE_FILE_COMPRESSION = 16
114
- FILE_VOLUME_QUOTAS = 32
115
- FILE_SUPPORTS_SPARSE_FILES = 64
116
- FILE_SUPPORTS_REPARSE_POINTS = 128
117
- FILE_SUPPORTS_REMOTE_STORAGE = 256
118
- FILE_VOLUME_IS_COMPRESSED = 0x8000
119
- FILE_SUPPORTS_OBJECT_IDS = 0x10000
120
- FILE_SUPPORTS_ENCRYPTION = 0x20000
121
-
122
- FILE_ENCRYPTABLE = 0
123
- FILE_IS_ENCRYPTED = 1
124
- FILE_ROOT_DIR = 3
125
- FILE_SYSTEM_ATTR = 2
126
- FILE_SYSTEM_DIR = 4
127
- FILE_UNKNOWN = 5
128
- FILE_SYSTEM_NOT_SUPPORT = 6
129
- FILE_READ_ONLY = 8
130
-
131
- # Read and execute privileges
132
- READ = FILE_GENERIC_READ | FILE_EXECUTE
133
-
134
- # Add privileges
135
- ADD = 0x001201bf
136
-
137
- # Delete privileges
138
- DELETE = 0x00010000
139
-
140
- # Generic write, generic read, execute and delete privileges
141
- CHANGE = FILE_GENERIC_WRITE | FILE_GENERIC_READ | FILE_EXECUTE | DELETE
142
-
143
- # Full security rights - read, write, append, execute, and delete.
144
- FULL = STANDARD_RIGHTS_ALL | FILE_READ_DATA | FILE_WRITE_DATA |
145
- FILE_APPEND_DATA | FILE_READ_EA | FILE_WRITE_EA | FILE_EXECUTE |
146
- FILE_DELETE_CHILD | FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES
147
- end
148
- end
149
- end
1
+ module Windows
2
+ module File
3
+ module Constants
4
+ SE_DACL_PRESENT = 4
5
+ OWNER_SECURITY_INFORMATION = 1
6
+ GROUP_SECURITY_INFORMATION = 2
7
+ DACL_SECURITY_INFORMATION = 4
8
+ ACCESS_ALLOWED_ACE_TYPE = 0
9
+ ERROR_INSUFFICIENT_BUFFER = 122
10
+ ACL_REVISION2 = 2
11
+ ALLOW_ACE_LENGTH = 62
12
+ OBJECT_INHERIT_ACE = 0x1
13
+ CONTAINER_INHERIT_ACE = 0x2
14
+ INHERIT_ONLY_ACE = 0x8
15
+ MAXDWORD = 0xFFFFFFFF
16
+ TOKEN_QUERY = 0x00000008
17
+ TOKEN_ADJUST_PRIVILEGES = 0x0020
18
+
19
+ ERROR_NOT_SUPPORTED = 50
20
+ ERROR_NO_SECURITY_ON_OBJECT = 1350
21
+
22
+ TokenUser = 1
23
+ TokenGroups = 2
24
+
25
+ SECURITY_DESCRIPTOR_REVISION = 1
26
+ SECURITY_DESCRIPTOR_MIN_LENGTH = 20
27
+
28
+ SE_KERNEL_OBJECT = 6
29
+ SE_FILE_OBJECT = 1
30
+ SE_PRIVILEGE_ENABLED = 0x00000002
31
+ SE_SECURITY_NAME = "SeSecurityPrivilege"
32
+ SE_TAKE_OWNERSHIP_NAME = "SeTakeOwnershipPrivilege"
33
+ SE_BACKUP_NAME = "SeBackupPrivilege"
34
+ SE_RESTORE_NAME = "SeRestorePrivilege"
35
+ SE_CHANGE_NOTIFY_NAME = "SeChangeNotifyPrivilege"
36
+
37
+ ## Security Rights
38
+
39
+ SYNCHRONIZE = 0x100000
40
+ STANDARD_RIGHTS_REQUIRED = 0xf0000
41
+ STANDARD_RIGHTS_READ = 0x20000
42
+ STANDARD_RIGHTS_WRITE = 0x20000
43
+ STANDARD_RIGHTS_EXECUTE = 0x20000
44
+ STANDARD_RIGHTS_ALL = 0x1F0000
45
+ SPECIFIC_RIGHTS_ALL = 0xFFFF
46
+ ACCESS_SYSTEM_SECURITY = 0x1000000
47
+ MAXIMUM_ALLOWED = 0x2000000
48
+ GENERIC_READ = 0x80000000
49
+ GENERIC_WRITE = 0x40000000
50
+ GENERIC_EXECUTE = 0x20000000
51
+ GENERIC_ALL = 0x10000000
52
+ GENERIC_RIGHTS_CHK = 0xF0000000
53
+ REST_RIGHTS_MASK = 0x001FFFFF
54
+ READ_CONTROL = 0x20000
55
+ WRITE_DAC = 0x40000
56
+ WRITE_OWNER = 0x80000
57
+
58
+ FILE_READ_DATA = 1
59
+ FILE_LIST_DIRECTORY = 1
60
+ FILE_WRITE_DATA = 2
61
+ FILE_ADD_FILE = 2
62
+ FILE_APPEND_DATA = 4
63
+ FILE_ADD_SUBDIRECTORY = 4
64
+ FILE_CREATE_PIPE_INSTANCE = 4
65
+ FILE_READ_EA = 8
66
+ FILE_READ_PROPERTIES = 8
67
+ FILE_WRITE_EA = 16
68
+ FILE_WRITE_PROPERTIES = 16
69
+ FILE_EXECUTE = 32
70
+ FILE_TRAVERSE = 32
71
+ FILE_DELETE_CHILD = 64
72
+ FILE_READ_ATTRIBUTES = 128
73
+ FILE_WRITE_ATTRIBUTES = 256
74
+
75
+ FILE_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x1FF
76
+
77
+ FILE_GENERIC_READ =
78
+ STANDARD_RIGHTS_READ |
79
+ FILE_READ_DATA |
80
+ FILE_READ_ATTRIBUTES |
81
+ FILE_READ_EA |
82
+ SYNCHRONIZE
83
+
84
+ FILE_GENERIC_WRITE =
85
+ STANDARD_RIGHTS_WRITE |
86
+ FILE_WRITE_DATA |
87
+ FILE_WRITE_ATTRIBUTES |
88
+ FILE_WRITE_EA |
89
+ FILE_APPEND_DATA |
90
+ SYNCHRONIZE
91
+
92
+ FILE_GENERIC_EXECUTE =
93
+ STANDARD_RIGHTS_EXECUTE |
94
+ FILE_READ_ATTRIBUTES |
95
+ FILE_EXECUTE |
96
+ SYNCHRONIZE
97
+
98
+ FILE_SHARE_READ = 1
99
+ FILE_SHARE_WRITE = 2
100
+ FILE_SHARE_DELETE = 4
101
+ FILE_NOTIFY_CHANGE_FILE_NAME = 1
102
+ FILE_NOTIFY_CHANGE_DIR_NAME = 2
103
+ FILE_NOTIFY_CHANGE_ATTRIBUTES = 4
104
+ FILE_NOTIFY_CHANGE_SIZE = 8
105
+ FILE_NOTIFY_CHANGE_LAST_WRITE = 16
106
+ FILE_NOTIFY_CHANGE_LAST_ACCESS = 32
107
+ FILE_NOTIFY_CHANGE_CREATION = 64
108
+ FILE_NOTIFY_CHANGE_SECURITY = 256
109
+ FILE_CASE_SENSITIVE_SEARCH = 1
110
+ FILE_CASE_PRESERVED_NAMES = 2
111
+ FILE_UNICODE_ON_DISK = 4
112
+ FILE_PERSISTENT_ACLS = 8
113
+ FILE_FILE_COMPRESSION = 16
114
+ FILE_VOLUME_QUOTAS = 32
115
+ FILE_SUPPORTS_SPARSE_FILES = 64
116
+ FILE_SUPPORTS_REPARSE_POINTS = 128
117
+ FILE_SUPPORTS_REMOTE_STORAGE = 256
118
+ FILE_VOLUME_IS_COMPRESSED = 0x8000
119
+ FILE_SUPPORTS_OBJECT_IDS = 0x10000
120
+ FILE_SUPPORTS_ENCRYPTION = 0x20000
121
+
122
+ FILE_ENCRYPTABLE = 0
123
+ FILE_IS_ENCRYPTED = 1
124
+ FILE_ROOT_DIR = 3
125
+ FILE_SYSTEM_ATTR = 2
126
+ FILE_SYSTEM_DIR = 4
127
+ FILE_UNKNOWN = 5
128
+ FILE_SYSTEM_NOT_SUPPORT = 6
129
+ FILE_READ_ONLY = 8
130
+
131
+ # Read and execute privileges
132
+ READ = FILE_GENERIC_READ | FILE_EXECUTE
133
+
134
+ # Add privileges
135
+ ADD = 0x001201bf
136
+
137
+ # Delete privileges
138
+ DELETE = 0x00010000
139
+
140
+ # Generic write, generic read, execute and delete privileges
141
+ CHANGE = FILE_GENERIC_WRITE | FILE_GENERIC_READ | FILE_EXECUTE | DELETE
142
+
143
+ # Full security rights - read, write, append, execute, and delete.
144
+ FULL = STANDARD_RIGHTS_ALL | FILE_READ_DATA | FILE_WRITE_DATA |
145
+ FILE_APPEND_DATA | FILE_READ_EA | FILE_WRITE_EA | FILE_EXECUTE |
146
+ FILE_DELETE_CHILD | FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES
147
+ end
148
+ end
149
+ end
@@ -1,63 +1,63 @@
1
- require 'ffi'
2
-
3
- module Windows
4
- module File
5
- module Functions
6
- extend FFI::Library
7
-
8
- private
9
-
10
- def self.attach_pfunc(*args)
11
- attach_function(*args)
12
- private args[0]
13
- end
14
-
15
- # For convenience
16
- typedef :pointer, :ptr
17
- typedef :buffer_in, :buf_in
18
- typedef :buffer_out, :buf_out
19
- typedef :string, :str
20
- typedef :ulong, :dword
21
- typedef :uintptr_t, :handle
22
-
23
- ffi_lib :advapi32
24
-
25
- attach_pfunc :AddAce, [:ptr, :dword, :dword, :ptr, :dword], :bool
26
- attach_pfunc :AdjustTokenPrivileges, [:handle, :bool, :ptr, :dword, :ptr, :ptr], :bool
27
- attach_pfunc :CopySid, [:dword, :ptr, :ptr], :bool
28
- attach_pfunc :EncryptFileW, [:buf_in], :bool
29
- attach_pfunc :DecryptFileW, [:buf_in, :dword], :bool
30
- attach_pfunc :FileEncryptionStatusW, [:buf_in, :ptr], :bool
31
- attach_pfunc :GetAce, [:ptr, :dword, :ptr], :bool
32
- attach_pfunc :GetFileSecurityW, [:buf_in, :dword, :ptr, :dword, :ptr], :bool
33
- attach_pfunc :GetLengthSid, [:ptr], :dword
34
- attach_pfunc :GetSecurityDescriptorControl, [:ptr, :ptr, :ptr], :bool
35
- attach_pfunc :GetSecurityDescriptorOwner, [:ptr, :ptr, :ptr], :bool
36
- attach_pfunc :GetSecurityDescriptorGroup, [:ptr, :ptr, :ptr], :bool
37
- attach_pfunc :GetSecurityDescriptorDacl, [:ptr, :ptr, :ptr, :ptr], :bool
38
- attach_pfunc :GetSecurityInfo, [:handle, :dword, :dword, :ptr, :ptr, :ptr, :ptr, :ptr], :dword
39
- attach_pfunc :GetTokenInformation, [:handle, :int, :ptr, :dword, :ptr], :bool
40
- attach_pfunc :InitializeAcl, [:ptr, :dword, :dword], :bool
41
- attach_pfunc :InitializeSecurityDescriptor, [:ptr, :dword], :bool
42
- attach_pfunc :LookupAccountNameW, [:buf_in, :buf_in, :ptr, :ptr, :ptr, :ptr, :ptr], :bool
43
- attach_pfunc :LookupAccountSidW, [:buf_in, :ptr, :ptr, :ptr, :ptr, :ptr, :ptr], :bool
44
- attach_pfunc :LookupPrivilegeValueA, [:str, :str, :ptr], :bool
45
- attach_pfunc :OpenProcessToken, [:handle, :dword, :ptr], :bool
46
- attach_pfunc :SetFileSecurityW, [:buf_in, :dword, :ptr], :bool
47
- attach_pfunc :SetSecurityDescriptorDacl, [:ptr, :bool, :ptr, :bool], :bool
48
- attach_pfunc :SetSecurityDescriptorOwner, [:ptr, :ptr, :bool], :bool
49
- attach_pfunc :ConvertSidToStringSidA, [:ptr,:ptr] ,:bool
50
-
51
- ffi_lib :kernel32
52
-
53
- attach_pfunc :CloseHandle, [:handle], :bool
54
- attach_pfunc :GetCurrentProcess, [], :handle
55
- attach_pfunc :GetVolumeInformationW, [:buf_in, :buf_out, :dword, :ptr, :ptr, :ptr, :buf_out, :dword], :bool
56
-
57
- ffi_lib :shlwapi
58
-
59
- attach_pfunc :PathStripToRootW, [:buf_in], :bool
60
- attach_pfunc :PathIsRootW, [:buf_in], :bool
61
- end
62
- end
63
- end
1
+ require 'ffi'
2
+
3
+ module Windows
4
+ module File
5
+ module Functions
6
+ extend FFI::Library
7
+
8
+ private
9
+
10
+ def self.attach_pfunc(*args)
11
+ attach_function(*args)
12
+ private args[0]
13
+ end
14
+
15
+ # For convenience
16
+ typedef :pointer, :ptr
17
+ typedef :buffer_in, :buf_in
18
+ typedef :buffer_out, :buf_out
19
+ typedef :string, :str
20
+ typedef :ulong, :dword
21
+ typedef :uintptr_t, :handle
22
+
23
+ ffi_lib :advapi32
24
+
25
+ attach_pfunc :AddAce, [:ptr, :dword, :dword, :ptr, :dword], :bool
26
+ attach_pfunc :AdjustTokenPrivileges, [:handle, :int, :ptr, :dword, :ptr, :ptr], :bool
27
+ attach_pfunc :CopySid, [:dword, :ptr, :ptr], :bool
28
+ attach_pfunc :EncryptFileW, [:buf_in], :bool
29
+ attach_pfunc :DecryptFileW, [:buf_in, :dword], :bool
30
+ attach_pfunc :FileEncryptionStatusW, [:buf_in, :ptr], :bool
31
+ attach_pfunc :GetAce, [:ptr, :dword, :ptr], :bool
32
+ attach_pfunc :GetFileSecurityW, [:buf_in, :dword, :ptr, :dword, :ptr], :bool
33
+ attach_pfunc :GetLengthSid, [:ptr], :dword
34
+ attach_pfunc :GetSecurityDescriptorControl, [:ptr, :ptr, :ptr], :bool
35
+ attach_pfunc :GetSecurityDescriptorOwner, [:ptr, :ptr, :ptr], :bool
36
+ attach_pfunc :GetSecurityDescriptorGroup, [:ptr, :ptr, :ptr], :bool
37
+ attach_pfunc :GetSecurityDescriptorDacl, [:ptr, :ptr, :ptr, :ptr], :bool
38
+ attach_pfunc :GetSecurityInfo, [:handle, :dword, :dword, :ptr, :ptr, :ptr, :ptr, :ptr], :dword
39
+ attach_pfunc :GetTokenInformation, [:handle, :int, :ptr, :dword, :ptr], :bool
40
+ attach_pfunc :InitializeAcl, [:ptr, :dword, :dword], :bool
41
+ attach_pfunc :InitializeSecurityDescriptor, [:ptr, :dword], :bool
42
+ attach_pfunc :LookupAccountNameW, [:buf_in, :buf_in, :ptr, :ptr, :ptr, :ptr, :ptr], :bool
43
+ attach_pfunc :LookupAccountSidW, [:buf_in, :ptr, :ptr, :ptr, :ptr, :ptr, :ptr], :bool
44
+ attach_pfunc :LookupPrivilegeValueA, [:str, :str, :ptr], :bool
45
+ attach_pfunc :OpenProcessToken, [:handle, :dword, :ptr], :bool
46
+ attach_pfunc :SetFileSecurityW, [:buf_in, :dword, :ptr], :bool
47
+ attach_pfunc :SetSecurityDescriptorDacl, [:ptr, :int, :ptr, :int], :bool
48
+ attach_pfunc :SetSecurityDescriptorOwner, [:ptr, :ptr, :int], :bool
49
+ attach_pfunc :ConvertSidToStringSidA, [:ptr,:ptr] ,:bool
50
+
51
+ ffi_lib :kernel32
52
+
53
+ attach_pfunc :CloseHandle, [:handle], :bool
54
+ attach_pfunc :GetCurrentProcess, [], :handle
55
+ attach_pfunc :GetVolumeInformationW, [:buf_in, :buf_out, :dword, :ptr, :ptr, :ptr, :buf_out, :dword], :bool
56
+
57
+ ffi_lib :shlwapi
58
+
59
+ attach_pfunc :PathStripToRootW, [:buf_in], :bool
60
+ attach_pfunc :PathIsRootW, [:buf_in], :bool
61
+ end
62
+ end
63
+ end
@@ -1,23 +1,23 @@
1
- class String
2
- unless instance_methods.include?(:wincode)
3
- # Convenience method for converting strings to UTF-16LE for wide character
4
- # functions that require it.
5
- def wincode
6
- unless encoding == Encoding::UTF_16LE
7
- (self.tr(File::SEPARATOR, File::ALT_SEPARATOR) + 0.chr).encode('UTF-16LE')
8
- end
9
- end
10
- end
11
-
12
- unless instance_methods.include?(:wstrip)
13
- # Read a wide character string up until the first double null, and delete
14
- # any remaining null characters.
15
- def wstrip
16
- unless encoding == Encoding::UTF_16LE
17
- self.force_encoding('UTF-16LE')
18
- end
19
-
20
- self.encode('UTF-8',:invalid=>:replace,:undef=>:replace).split("\x00")[0].encode(Encoding.default_external)
21
- end
22
- end
23
- end
1
+ class String
2
+ unless instance_methods.include?(:wincode)
3
+ # Convenience method for converting strings to UTF-16LE for wide character
4
+ # functions that require it.
5
+ def wincode
6
+ unless encoding == Encoding::UTF_16LE
7
+ (self.tr(File::SEPARATOR, File::ALT_SEPARATOR) + 0.chr).encode('UTF-16LE')
8
+ end
9
+ end
10
+ end
11
+
12
+ unless instance_methods.include?(:wstrip)
13
+ # Read a wide character string up until the first double null, and delete
14
+ # any remaining null characters.
15
+ def wstrip
16
+ unless encoding == Encoding::UTF_16LE
17
+ self.force_encoding('UTF-16LE')
18
+ end
19
+
20
+ self.encode('UTF-8',:invalid=>:replace,:undef=>:replace).split("\x00")[0].encode(Encoding.default_external)
21
+ end
22
+ end
23
+ end