windows-pr 1.0.8 → 1.0.9

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,159 +1,159 @@
1
- require 'windows/api'
2
-
3
- module Windows
4
- module MSVCRT
5
- module String
6
- API.auto_constant = false # We want multiple versions
7
- API.auto_method = false # We need to handle 0 & nil explicitly
8
- API.auto_unicode = false
9
-
10
- Strchr = API.new('strchr', 'PI', 'P', MSVCRT_DLL)
11
- Strcmp = API.new('strcmp', 'PP', 'I', MSVCRT_DLL)
12
- Strcpy = API.new('strcpy', 'PL', 'L', MSVCRT_DLL)
13
- Strcspn = API.new('strcspn', 'PP', 'L', MSVCRT_DLL)
14
- Strlen = API.new('strlen', 'P', 'L', MSVCRT_DLL)
15
- Strncpy = API.new('strncpy', 'PPL', 'P', MSVCRT_DLL)
16
- Strpbrk = API.new('strpbrk', 'PP', 'P', MSVCRT_DLL)
17
- Strrchr = API.new('strrchr', 'PI', 'P', MSVCRT_DLL)
18
- Strrev = API.new('_strrev', 'P', 'P', MSVCRT_DLL)
19
- Strspn = API.new('strspn', 'PP', 'L', MSVCRT_DLL)
20
- Strstr = API.new('strstr', 'PP', 'P', MSVCRT_DLL)
21
- Strtok = API.new('strtok', 'PP', 'P', MSVCRT_DLL)
22
-
23
- Mbscmp = API.new('_mbscmp', 'PP', 'I', 'msvcrt')
24
- Mbscpy = API.new('_mbscpy', 'PL', 'L', 'msvcrt')
25
- Mbslen = API.new('_mbslen', 'P', 'L', 'msvcrt')
26
- Mbsrev = API.new('_mbsrev', 'P', 'P', 'msvcrt')
27
-
28
- Wcscmp = API.new('wcscmp', 'PP', 'I', MSVCRT_DLL)
29
- Wcscpy = API.new('wcscpy', 'PL', 'L', MSVCRT_DLL)
30
- Wcslen = API.new('wcslen', 'P', 'L', MSVCRT_DLL)
31
- Wcsncpy = API.new('wcsncpy', 'PPL', 'P', MSVCRT_DLL)
32
- Wcsrev = API.new('_wcsrev', 'P', 'P', MSVCRT_DLL)
33
-
34
- begin
35
- Strtok_s = API.new('strtok_s', 'PPI', 'P', MSVCRT_DLL)
36
- rescue Win32::API::LoadLibraryError
37
- # Do nothing. Not supported on your system.
38
- end
39
-
40
- def strchr(string, char)
41
- return nil if string == 0 || char == 0
42
- Strchr.call(string, char)
43
- end
44
-
45
- def strcmp(str1, str2)
46
- if str1 == 0 || str2 == 0
47
- return nil
48
- end
49
- Strcmp.call(str1, str2)
50
- end
51
-
52
- def strcpy(dest, src)
53
- return nil if src == 0
54
- Strcpy.call(dest, src)
55
- end
56
-
57
- def strlen(string)
58
- return nil if string == 0
59
- Strlen.call(string)
60
- end
61
-
62
- def strcspn(string, charset)
63
- return nil if string == 0
64
- Strcspn.call(string, charset)
65
- end
66
-
67
- def strncpy(dest, source, count)
68
- return nil if source == 0
69
- Strncpy.call(dest, source, count)
70
- end
71
-
72
- def strpbrk(string, charset)
73
- return nil if string == 0 || charset == 0
74
- Strpbrk.call(string, charset)
75
- end
76
-
77
- def strrchr(string, int)
78
- return nil if string == 0
79
- Strrchr.call(string, int)
80
- end
81
-
82
- def strrev(str)
83
- return nil if str == 0
84
- Strrev.call(str)
85
- end
86
-
87
- def strspn(string, charset)
88
- return nil if string == 0 || charset == 0
89
- Strspn.call(string, charset)
90
- end
91
-
92
- def strstr(string, search)
93
- return nil if string == 0 || search == 0
94
- Strstr.call(string, search)
95
- end
96
-
97
- def strtok(token, delimeter)
98
- return nil if token == 0 || delimeter == 0
99
- Strtok.call(token, delimeter)
100
- end
101
-
102
- if defined? Strtok_s
103
- def strtok_s(token, delimeter, context)
104
- return nil if [token, delimter, context].include?(0)
105
- Strtok_s.call(token, delimeter, context)
106
- end
107
- end
108
-
109
- def mbscmp(str1, str2)
110
- if str1 == 0 || str2 == 0
111
- return nil
112
- end
113
- Mbscmp.call(str1, str2)
114
- end
115
-
116
- def mbscpy(dest, src)
117
- return nil if src == 0
118
- Mbscpy.call(dest, src)
119
- end
120
-
121
- def mbslen(string)
122
- return nil if string == 0
123
- Mbslen.call(string)
124
- end
125
-
126
- def mbsrev(str)
127
- return nil if str == 0
128
- Mbsrev.call(str)
129
- end
130
-
131
- def wcscmp(str1, str2)
132
- if str1 == 0 || str2 == 0
133
- return nil
134
- end
135
- Wcscmp.call(str1, str2)
136
- end
137
-
138
- def wcscpy(dest, src)
139
- return nil if src == 0
140
- Wcscpy.call(dest, src)
141
- end
142
-
143
- def wcslen(string)
144
- return nil if string == 0
145
- Wcslen.call(string)
146
- end
147
-
148
- def wcsncpy(dest, source, count)
149
- return nil if source == 0
150
- Wcsncpy.call(dest, source, count)
151
- end
152
-
153
- def wcsrev(str)
154
- return nil if str == 0
155
- Wcsrev.call(str)
156
- end
157
- end
158
- end
159
- end
1
+ require 'windows/api'
2
+
3
+ module Windows
4
+ module MSVCRT
5
+ module String
6
+ API.auto_constant = false # We want multiple versions
7
+ API.auto_method = false # We need to handle 0 & nil explicitly
8
+ API.auto_unicode = false
9
+
10
+ Strchr = API.new('strchr', 'PI', 'P', MSVCRT_DLL)
11
+ Strcmp = API.new('strcmp', 'PP', 'I', MSVCRT_DLL)
12
+ Strcpy = API.new('strcpy', 'PL', 'L', MSVCRT_DLL)
13
+ Strcspn = API.new('strcspn', 'PP', 'L', MSVCRT_DLL)
14
+ Strlen = API.new('strlen', 'P', 'L', MSVCRT_DLL)
15
+ Strncpy = API.new('strncpy', 'PPL', 'P', MSVCRT_DLL)
16
+ Strpbrk = API.new('strpbrk', 'PP', 'P', MSVCRT_DLL)
17
+ Strrchr = API.new('strrchr', 'PI', 'P', MSVCRT_DLL)
18
+ Strrev = API.new('_strrev', 'P', 'P', MSVCRT_DLL)
19
+ Strspn = API.new('strspn', 'PP', 'L', MSVCRT_DLL)
20
+ Strstr = API.new('strstr', 'PP', 'P', MSVCRT_DLL)
21
+ Strtok = API.new('strtok', 'PP', 'P', MSVCRT_DLL)
22
+
23
+ Mbscmp = API.new('_mbscmp', 'PP', 'I', 'msvcrt')
24
+ Mbscpy = API.new('_mbscpy', 'PL', 'L', 'msvcrt')
25
+ Mbslen = API.new('_mbslen', 'P', 'L', 'msvcrt')
26
+ Mbsrev = API.new('_mbsrev', 'P', 'P', 'msvcrt')
27
+
28
+ Wcscmp = API.new('wcscmp', 'PP', 'I', MSVCRT_DLL)
29
+ Wcscpy = API.new('wcscpy', 'PL', 'L', MSVCRT_DLL)
30
+ Wcslen = API.new('wcslen', 'P', 'L', MSVCRT_DLL)
31
+ Wcsncpy = API.new('wcsncpy', 'PPL', 'P', MSVCRT_DLL)
32
+ Wcsrev = API.new('_wcsrev', 'P', 'P', MSVCRT_DLL)
33
+
34
+ begin
35
+ Strtok_s = API.new('strtok_s', 'PPI', 'P', MSVCRT_DLL)
36
+ rescue Win32::API::LoadLibraryError
37
+ # Do nothing. Not supported on your system.
38
+ end
39
+
40
+ def strchr(string, char)
41
+ return nil if string == 0 || char == 0
42
+ Strchr.call(string, char)
43
+ end
44
+
45
+ def strcmp(str1, str2)
46
+ if str1 == 0 || str2 == 0
47
+ return nil
48
+ end
49
+ Strcmp.call(str1, str2)
50
+ end
51
+
52
+ def strcpy(dest, src)
53
+ return nil if src == 0
54
+ Strcpy.call(dest, src)
55
+ end
56
+
57
+ def strlen(string)
58
+ return nil if string == 0
59
+ Strlen.call(string)
60
+ end
61
+
62
+ def strcspn(string, charset)
63
+ return nil if string == 0
64
+ Strcspn.call(string, charset)
65
+ end
66
+
67
+ def strncpy(dest, source, count)
68
+ return nil if source == 0
69
+ Strncpy.call(dest, source, count)
70
+ end
71
+
72
+ def strpbrk(string, charset)
73
+ return nil if string == 0 || charset == 0
74
+ Strpbrk.call(string, charset)
75
+ end
76
+
77
+ def strrchr(string, int)
78
+ return nil if string == 0
79
+ Strrchr.call(string, int)
80
+ end
81
+
82
+ def strrev(str)
83
+ return nil if str == 0
84
+ Strrev.call(str)
85
+ end
86
+
87
+ def strspn(string, charset)
88
+ return nil if string == 0 || charset == 0
89
+ Strspn.call(string, charset)
90
+ end
91
+
92
+ def strstr(string, search)
93
+ return nil if string == 0 || search == 0
94
+ Strstr.call(string, search)
95
+ end
96
+
97
+ def strtok(token, delimeter)
98
+ return nil if token == 0 || delimeter == 0
99
+ Strtok.call(token, delimeter)
100
+ end
101
+
102
+ if defined? Strtok_s
103
+ def strtok_s(token, delimeter, context)
104
+ return nil if [token, delimter, context].include?(0)
105
+ Strtok_s.call(token, delimeter, context)
106
+ end
107
+ end
108
+
109
+ def mbscmp(str1, str2)
110
+ if str1 == 0 || str2 == 0
111
+ return nil
112
+ end
113
+ Mbscmp.call(str1, str2)
114
+ end
115
+
116
+ def mbscpy(dest, src)
117
+ return nil if src == 0
118
+ Mbscpy.call(dest, src)
119
+ end
120
+
121
+ def mbslen(string)
122
+ return nil if string == 0
123
+ Mbslen.call(string)
124
+ end
125
+
126
+ def mbsrev(str)
127
+ return nil if str == 0
128
+ Mbsrev.call(str)
129
+ end
130
+
131
+ def wcscmp(str1, str2)
132
+ if str1 == 0 || str2 == 0
133
+ return nil
134
+ end
135
+ Wcscmp.call(str1, str2)
136
+ end
137
+
138
+ def wcscpy(dest, src)
139
+ return nil if src == 0
140
+ Wcscpy.call(dest, src)
141
+ end
142
+
143
+ def wcslen(string)
144
+ return nil if string == 0
145
+ Wcslen.call(string)
146
+ end
147
+
148
+ def wcsncpy(dest, source, count)
149
+ return nil if source == 0
150
+ Wcsncpy.call(dest, source, count)
151
+ end
152
+
153
+ def wcsrev(str)
154
+ return nil if str == 0
155
+ Wcsrev.call(str)
156
+ end
157
+ end
158
+ end
159
+ end
@@ -81,6 +81,7 @@ module Windows
81
81
  SERVICE_ACCEPT_HARDWAREPROFILECHANGE = 0x00000020
82
82
  SERVICE_ACCEPT_POWEREVENT = 0x00000040
83
83
  SERVICE_ACCEPT_SESSIONCHANGE = 0x00000080
84
+ SERVICE_ACCEPT_PRESHUTDOWN = 0x00000100
84
85
 
85
86
  # Service states
86
87
  SERVICE_ACTIVE = 0x00000001
@@ -1,142 +1,153 @@
1
- require 'windows/api'
2
- require 'windows/msvcrt/string'
3
- require 'windows/error'
4
-
5
- module Windows
6
- module Unicode
7
- include Windows::MSVCRT::String
8
- include Windows::Error
9
-
10
- API.auto_namespace = 'Windows::Unicode'
11
- API.auto_constant = true
12
- API.auto_method = true
13
- API.auto_unicode = false
14
-
15
- CP_ACP = 0
16
- CP_OEMCP = 1
17
- CP_MACCP = 2
18
- CP_THREAD_ACP = 3
19
- CP_SYMBOL = 42
20
- CP_UTF7 = 65000
21
- CP_UTF8 = 65001
22
-
23
- MB_PRECOMPOSED = 0x00000001
24
- MB_COMPOSITE = 0x00000002
25
- MB_USEGLYPHCHARS = 0x00000004
26
- MB_ERR_INVALID_CHARS = 0x00000008
27
-
28
- WC_COMPOSITECHECK = 0x00000200
29
- WC_DISCARDNS = 0x00000010
30
- WC_SEPCHARS = 0x00000020
31
- WC_DEFAULTCHAR = 0x00000040
32
- WC_NO_BEST_FIT_CHARS = 0x00000400
33
-
34
- ANSI_CHARSET = 0
35
- DEFAULT_CHARSET = 1
36
- SYMBOL_CHARSET = 2
37
- SHIFTJIS_CHARSET = 128
38
- HANGEUL_CHARSET = 129
39
- HANGUL_CHARSET = 129
40
- GB2312_CHARSET = 134
41
- CHINESEBIG5_CHARSET = 136
42
- OEM_CHARSET = 255
43
- JOHAB_CHARSET = 130
44
- HEBREW_CHARSET = 177
45
- ARABIC_CHARSET = 178
46
- GREEK_CHARSET = 161
47
- TURKISH_CHARSET = 162
48
- VIETNAMESE_CHARSET = 163
49
- THAI_CHARSET = 222
50
- EASTEUROPE_CHARSET = 238
51
- RUSSIAN_CHARSET = 204
52
-
53
- IS_TEXT_UNICODE_ASCII16 = 0x0001
54
- IS_TEXT_UNICODE_REVERSE_ASCII16 = 0x0010
55
- IS_TEXT_UNICODE_STATISTICS = 0x0002
56
- IS_TEXT_UNICODE_REVERSE_STATISTICS = 0x0020
57
- IS_TEXT_UNICODE_CONTROLS = 0x0004
58
- IS_TEXT_UNICODE_REVERSE_CONTROLS = 0x0040
59
- IS_TEXT_UNICODE_SIGNATURE = 0x0008
60
- IS_TEXT_UNICODE_REVERSE_SIGNATURE = 0x0080
61
- IS_TEXT_UNICODE_ILLEGAL_CHARS = 0x0100
62
- IS_TEXT_UNICODE_ODD_LENGTH = 0x0200
63
- IS_TEXT_UNICODE_DBCS_LEADBYTE = 0x0400
64
- IS_TEXT_UNICODE_NULL_BYTES = 0x1000
65
- IS_TEXT_UNICODE_UNICODE_MASK = 0x000F
66
- IS_TEXT_UNICODE_REVERSE_MASK = 0x00F0
67
- IS_TEXT_UNICODE_NOT_UNICODE_MASK = 0x0F00
68
- IS_TEXT_UNICODE_NOT_ASCII_MASK = 0xF000
69
-
70
- TCI_SRCCHARSET = 1
71
- TCI_SRCCODEPAGE = 2
72
- TCI_SRCFONTSIG = 3
73
- TCI_SRCLOCALE = 0x100
74
-
75
- API.new('GetTextCharset', 'L', 'I', 'gdi32')
76
- API.new('GetTextCharsetInfo', 'LPL', 'I', 'gdi32')
77
- API.new('IsDBCSLeadByte', 'P', 'B')
78
- API.new('IsDBCSLeadByteEx', 'IP', 'B')
79
- API.new('IsTextUnicode', 'SIP', 'B', 'advapi32')
80
- API.new('MultiByteToWideChar', 'ILSIPI', 'I')
81
- API.new('TranslateCharsetInfo', 'PPL', 'B', 'gdi32')
82
- API.new('WideCharToMultiByte', 'ILSIPIPP', 'I')
83
-
84
- # Convenient wrapper methods
85
-
86
- # Maps a wide character string to a new character string using the
87
- # specified +encoding+. If no encoding is specified, then CP_UTF8
88
- # iss used if $KCODE is set to UTF8. Otherwise, CP_ACP is used.
89
- #
90
- # If the function fails it simply returns the string as-is.
91
- #
92
- def multi_to_wide(string, encoding=nil)
93
- return nil unless string
94
- raise TypeError unless string.is_a?(String)
95
- return string if IsTextUnicode(string, string.size, nil)
96
-
97
- unless encoding
98
- encoding = ($KCODE == 'UTF8') ? CP_UTF8 : CP_ACP
99
- end
100
-
101
- int = MultiByteToWideChar(encoding, 0, string, -1, nil, 0)
102
-
103
- # Trailing nulls are retained
104
- if int > 0
105
- buf = ' ' * int * 2
106
- MultiByteToWideChar(encoding, 0, string, -1, buf, int)
107
- buf
108
- else
109
- raise ArgumentError, get_last_error
110
- end
111
- end
112
-
113
- # Maps a wide character string to a new character string using the
114
- # specified +encoding+. If no encoding is specified, then CP_UTF8
115
- # iss used if $KCODE is set to UTF8. Otherwise, CP_ACP is used.
116
- #
117
- # If the function fails it simply returns the string as-is.
118
- #
119
- def wide_to_multi(wstring, encoding=nil)
120
- return nil unless wstring
121
- raise TypeError unless wstring.is_a?(String)
122
-
123
- unless encoding
124
- encoding = ($KCODE == 'UTF8') ? CP_UTF8 : CP_ACP
125
- end
126
-
127
- # Add a trailing double null if necessary
128
- wstring << "\000\000" if wstring[-1].chr != "\000"
129
-
130
- int = WideCharToMultiByte(encoding, 0, wstring, -1, 0, 0, nil, nil)
131
-
132
- # Trailing nulls are stripped
133
- if int > 0
134
- buf = ' ' * int
135
- WideCharToMultiByte(encoding, 0, wstring, -1, buf, strlen(buf), nil, nil)
136
- buf[ /^[^\0]*/ ]
137
- else
138
- raise ArgumentError, get_last_error
139
- end
140
- end
141
- end
142
- end
1
+ # encoding: ascii-8bit
2
+ require 'windows/api'
3
+ require 'windows/msvcrt/string'
4
+ require 'windows/error'
5
+
6
+ module Windows
7
+ module Unicode
8
+ include Windows::MSVCRT::String
9
+ include Windows::Error
10
+
11
+ API.auto_namespace = 'Windows::Unicode'
12
+ API.auto_constant = true
13
+ API.auto_method = true
14
+ API.auto_unicode = false
15
+
16
+ CP_ACP = 0
17
+ CP_OEMCP = 1
18
+ CP_MACCP = 2
19
+ CP_THREAD_ACP = 3
20
+ CP_SYMBOL = 42
21
+ CP_UTF7 = 65000
22
+ CP_UTF8 = 65001
23
+
24
+ MB_PRECOMPOSED = 0x00000001
25
+ MB_COMPOSITE = 0x00000002
26
+ MB_USEGLYPHCHARS = 0x00000004
27
+ MB_ERR_INVALID_CHARS = 0x00000008
28
+
29
+ WC_COMPOSITECHECK = 0x00000200
30
+ WC_DISCARDNS = 0x00000010
31
+ WC_SEPCHARS = 0x00000020
32
+ WC_DEFAULTCHAR = 0x00000040
33
+ WC_NO_BEST_FIT_CHARS = 0x00000400
34
+
35
+ ANSI_CHARSET = 0
36
+ DEFAULT_CHARSET = 1
37
+ SYMBOL_CHARSET = 2
38
+ SHIFTJIS_CHARSET = 128
39
+ HANGEUL_CHARSET = 129
40
+ HANGUL_CHARSET = 129
41
+ GB2312_CHARSET = 134
42
+ CHINESEBIG5_CHARSET = 136
43
+ OEM_CHARSET = 255
44
+ JOHAB_CHARSET = 130
45
+ HEBREW_CHARSET = 177
46
+ ARABIC_CHARSET = 178
47
+ GREEK_CHARSET = 161
48
+ TURKISH_CHARSET = 162
49
+ VIETNAMESE_CHARSET = 163
50
+ THAI_CHARSET = 222
51
+ EASTEUROPE_CHARSET = 238
52
+ RUSSIAN_CHARSET = 204
53
+
54
+ IS_TEXT_UNICODE_ASCII16 = 0x0001
55
+ IS_TEXT_UNICODE_REVERSE_ASCII16 = 0x0010
56
+ IS_TEXT_UNICODE_STATISTICS = 0x0002
57
+ IS_TEXT_UNICODE_REVERSE_STATISTICS = 0x0020
58
+ IS_TEXT_UNICODE_CONTROLS = 0x0004
59
+ IS_TEXT_UNICODE_REVERSE_CONTROLS = 0x0040
60
+ IS_TEXT_UNICODE_SIGNATURE = 0x0008
61
+ IS_TEXT_UNICODE_REVERSE_SIGNATURE = 0x0080
62
+ IS_TEXT_UNICODE_ILLEGAL_CHARS = 0x0100
63
+ IS_TEXT_UNICODE_ODD_LENGTH = 0x0200
64
+ IS_TEXT_UNICODE_DBCS_LEADBYTE = 0x0400
65
+ IS_TEXT_UNICODE_NULL_BYTES = 0x1000
66
+ IS_TEXT_UNICODE_UNICODE_MASK = 0x000F
67
+ IS_TEXT_UNICODE_REVERSE_MASK = 0x00F0
68
+ IS_TEXT_UNICODE_NOT_UNICODE_MASK = 0x0F00
69
+ IS_TEXT_UNICODE_NOT_ASCII_MASK = 0xF000
70
+
71
+ TCI_SRCCHARSET = 1
72
+ TCI_SRCCODEPAGE = 2
73
+ TCI_SRCFONTSIG = 3
74
+ TCI_SRCLOCALE = 0x100
75
+
76
+ API.new('GetTextCharset', 'L', 'I', 'gdi32')
77
+ API.new('GetTextCharsetInfo', 'LPL', 'I', 'gdi32')
78
+ API.new('IsDBCSLeadByte', 'P', 'B')
79
+ API.new('IsDBCSLeadByteEx', 'IP', 'B')
80
+ API.new('IsTextUnicode', 'SIP', 'B', 'advapi32')
81
+ API.new('MultiByteToWideChar', 'ILSIPI', 'I')
82
+ API.new('TranslateCharsetInfo', 'PPL', 'B', 'gdi32')
83
+ API.new('WideCharToMultiByte', 'ILSIPIPP', 'I')
84
+
85
+ # Convenient wrapper methods
86
+
87
+ # Maps a wide character string to a new character string using the
88
+ # specified +encoding+. If no encoding is specified, then CP_UTF8
89
+ # is used if $KCODE (or the encoding name in Ruby 1.9.x) is set to UTF8.
90
+ # Otherwise, CP_ACP is used.
91
+ #
92
+ # If the function fails it simply returns the string as-is.
93
+ #
94
+ def multi_to_wide(string, encoding=nil)
95
+ return nil unless string
96
+ raise TypeError unless string.is_a?(String)
97
+ return string if IsTextUnicode(string, string.size, nil)
98
+
99
+ unless encoding
100
+ if RUBY_VERSION.to_f >= 1.9
101
+ encoding = (string.encoding.name == 'UTF-8') ? CP_UTF8 : CP_ACP
102
+ else
103
+ encoding = ($KCODE == 'UTF8') ? CP_UTF8 : CP_ACP
104
+ end
105
+ end
106
+
107
+ int = MultiByteToWideChar(encoding, 0, string, -1, nil, 0)
108
+
109
+ # Trailing nulls are retained
110
+ if int > 0
111
+ buf = ' ' * int * 2
112
+ MultiByteToWideChar(encoding, 0, string, -1, buf, int)
113
+ buf
114
+ else
115
+ raise ArgumentError, get_last_error
116
+ end
117
+ end
118
+
119
+ # Maps a wide character string to a new character string using the
120
+ # specified +encoding+. If no encoding is specified, then CP_UTF8
121
+ # is used if $KCODE (or the encoding name in Ruby 1.9.x) is set to UTF8.
122
+ # Otherwise, CP_ACP is used.
123
+ #
124
+ # If the function fails it simply returns the string as-is.
125
+ #
126
+ def wide_to_multi(wstring, encoding=nil)
127
+ return nil unless wstring
128
+ raise TypeError unless wstring.is_a?(String)
129
+
130
+ unless encoding
131
+ if RUBY_VERSION.to_f >= 1.9
132
+ encoding = (wstring.encoding.name == 'UTF-8') ? CP_UTF8 : CP_ACP
133
+ else
134
+ encoding = ($KCODE == 'UTF8') ? CP_UTF8 : CP_ACP
135
+ end
136
+ end
137
+
138
+ # Add a trailing double null if necessary
139
+ wstring << "\000\000" if wstring[-1].chr != "\000"
140
+
141
+ int = WideCharToMultiByte(encoding, 0, wstring, -1, 0, 0, nil, nil)
142
+
143
+ # Trailing nulls are stripped
144
+ if int > 0
145
+ buf = ' ' * int
146
+ WideCharToMultiByte(encoding, 0, wstring, -1, buf, strlen(buf), nil, nil)
147
+ buf[ /^[^\0]*/ ]
148
+ else
149
+ raise ArgumentError, get_last_error
150
+ end
151
+ end
152
+ end
153
+ end