winevt_c 0.7.2 → 0.9.0
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/README.md +55 -0
- data/Rakefile +1 -1
- data/example/eventlog.rb +7 -1
- data/example/locale.rb +13 -0
- data/example/rate_limit.rb +1 -1
- data/example/tailing.rb +10 -2
- data/ext/winevt/winevt.c +7 -0
- data/ext/winevt/winevt_bookmark.c +2 -0
- data/ext/winevt/winevt_c.h +46 -8
- data/ext/winevt/winevt_channel.c +2 -0
- data/ext/winevt/winevt_locale.c +92 -0
- data/ext/winevt/winevt_locale_info.c +68 -0
- data/ext/winevt/winevt_query.c +138 -9
- data/ext/winevt/winevt_session.c +425 -0
- data/ext/winevt/winevt_subscribe.c +136 -10
- data/ext/winevt/winevt_utils.cpp +42 -8
- data/lib/winevt.rb +1 -0
- data/lib/winevt/session.rb +15 -0
- data/lib/winevt/subscribe.rb +5 -2
- data/lib/winevt/version.rb +1 -1
- data/winevt_c.gemspec +1 -1
- metadata +9 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fd29b4664130c80249811fb66df434aaa9219d6d375bcdaa7adfdd3fe72dd25e
|
4
|
+
data.tar.gz: 2a1e3ec7cb528269ebb65f4b1df72d6045f882d865956fb85def8bcb925d6944
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0f80978e4268c233d2e309c0e9556f38386b35300381c04f4d84226ce239a85ccb48b20a2c2a3c59c3d0557347e95ff11e0ca11945eaa128ba2c78c67ebc9250
|
7
|
+
data.tar.gz: a8ff4fae4995b41910352186898d54c929a918f86a6a4efe29c0a5c93433d9c95d91be5c9f81fdb52ff5f2307cbb2e2e61790a22fe076b7221ba03c89aed48d5
|
data/README.md
CHANGED
@@ -31,6 +31,61 @@ Or install it yourself as:
|
|
31
31
|
## Usage
|
32
32
|
|
33
33
|
Usage examples are found in [example directory](example).
|
34
|
+
|
35
|
+
### Multilingual description
|
36
|
+
|
37
|
+
Currently, the following locales should be supported to output description:
|
38
|
+
|
39
|
+
locale | language
|
40
|
+
---------:|:--------
|
41
|
+
bg\_BG | Bulgarian
|
42
|
+
zh\_CN | Simplified Chinese
|
43
|
+
zh\_TW | Traditional Chinese
|
44
|
+
zh\_HK | Chinese (Hong Kong)
|
45
|
+
zh\_SG | Chinese (Singapore)
|
46
|
+
hr\_HR | Croatian
|
47
|
+
cz\_CZ | Czech
|
48
|
+
da\_DK | Danish
|
49
|
+
nl\_NL | Dutch
|
50
|
+
nl\_BG | Dutch (Belgium)
|
51
|
+
en\_US | English (United States)
|
52
|
+
en\_GB | English (UK)
|
53
|
+
en\_AU | English (Australia)
|
54
|
+
en\_CA | English (Canada)
|
55
|
+
en\_NZ | English (New Zealand)
|
56
|
+
en\_IE | English (Ireland)
|
57
|
+
fi\_FI | Finnish
|
58
|
+
fr\_FR | French
|
59
|
+
fr\_BE | French (Belgium)
|
60
|
+
fr\_CA | French (Canada)
|
61
|
+
fr\_CH | French (Swiss)
|
62
|
+
de\_DE | German
|
63
|
+
de\_CH | German (Swiss)
|
64
|
+
de\_AT | German (Austria)
|
65
|
+
el\_GR | Greek (Ελληνικά)
|
66
|
+
hu\_HU | Hungarian
|
67
|
+
is\_IS | Icelandic
|
68
|
+
it\_IT | Italian (Italy)
|
69
|
+
it\_CH | Italian (Swiss)
|
70
|
+
ja\_JP | Japanese
|
71
|
+
ko\_KO | Korean
|
72
|
+
no\_NO | Norwegian (Bokmål)
|
73
|
+
nb\_NO | Norwegian (Bokmål)
|
74
|
+
nn\_NO | Norwegian (Nynorsk)
|
75
|
+
pl\_PL | Polish (Poland)
|
76
|
+
pt\_PT | Portuguese
|
77
|
+
pt\_BR | Portuguese (Brazil)
|
78
|
+
ro\_RO | Romanian
|
79
|
+
ru\_RU | Russian (русский язык)
|
80
|
+
sk\_SK | Slovak
|
81
|
+
sl\_SI | Slovenian
|
82
|
+
es\_ES | Spanish
|
83
|
+
es\_ES\_T | Spanish (Traditional)
|
84
|
+
es\_MX | Spanish (Mexico)
|
85
|
+
es\_ES\_M | Spanish (Modern)
|
86
|
+
sv\_SE | Swedish
|
87
|
+
tr\_TR | Turkish
|
88
|
+
|
34
89
|
## Development
|
35
90
|
|
36
91
|
After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
data/Rakefile
CHANGED
@@ -28,7 +28,7 @@ task 'gem:native' do
|
|
28
28
|
# See RUBY_CC_VERSION in https://github.com/rake-compiler/rake-compiler-dock/blob/master/Dockerfile.mri
|
29
29
|
RakeCompilerDock.sh <<-EOS
|
30
30
|
gem install bundler yard --no-doc && bundle
|
31
|
-
rake cross native gem RUBY_CC_VERSION=2.4.0:2.5.0:2.6.0
|
31
|
+
rake cross native gem RUBY_CC_VERSION=2.4.0:2.5.0:2.6.0:2.7.0
|
32
32
|
EOS
|
33
33
|
end
|
34
34
|
|
data/example/eventlog.rb
CHANGED
@@ -1,7 +1,13 @@
|
|
1
1
|
require 'winevt'
|
2
2
|
|
3
|
-
@
|
3
|
+
@session = Winevt::EventLog::Session.new("127.0.0.1") # Or remote box ip
|
4
|
+
# @session.domain = "<EXAMPLEGROUP>"
|
5
|
+
# @session.username = "<username>"
|
6
|
+
# @session.password = "<password>"
|
7
|
+
@query = Winevt::EventLog::Query.new("Application", "*[System[(Level <= 4) and TimeCreated[timediff(@SystemTime) <= 86400000]]]", @session)
|
4
8
|
|
9
|
+
@query.render_as_xml = true
|
10
|
+
@query.preserve_qualifiers = true
|
5
11
|
@query.each do |eventlog, message, string_inserts|
|
6
12
|
puts ({eventlog: eventlog, data: message})
|
7
13
|
end
|
data/example/locale.rb
ADDED
data/example/rate_limit.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'winevt'
|
2
2
|
|
3
3
|
@subscribe = Winevt::EventLog::Subscribe.new
|
4
|
-
@subscribe.
|
4
|
+
@subscribe.read_existing_events = true
|
5
5
|
@subscribe.rate_limit = 80
|
6
6
|
@subscribe.subscribe(
|
7
7
|
"Application", "*[System[(Level <= 4) and TimeCreated[timediff(@SystemTime) <= 86400000]]]"
|
data/example/tailing.rb
CHANGED
@@ -1,9 +1,17 @@
|
|
1
1
|
require 'winevt'
|
2
2
|
|
3
|
+
@session = Winevt::EventLog::Session.new("127.0.0.1") # Or remote box ip
|
4
|
+
# @session.domain = "<EXAMPLEGROUP>"
|
5
|
+
# @session.username = "<username>"
|
6
|
+
# @session.password = "<password>"
|
7
|
+
@bookmark = Winevt::EventLog::Bookmark.new
|
3
8
|
@subscribe = Winevt::EventLog::Subscribe.new
|
4
|
-
@subscribe.
|
9
|
+
@subscribe.read_existing_events = true
|
10
|
+
@subscribe.preserve_qualifiers = true
|
11
|
+
@subscribe.render_as_xml = true
|
5
12
|
@subscribe.subscribe(
|
6
|
-
"Security", "*[System[(Level <= 4) and TimeCreated[timediff(@SystemTime) <= 86400000]]]"
|
13
|
+
"Security", "*[System[(Level <= 4) and TimeCreated[timediff(@SystemTime) <= 86400000]]]",
|
14
|
+
@bookmark, @session
|
7
15
|
)
|
8
16
|
while true do
|
9
17
|
@subscribe.each do |eventlog, message, string_inserts|
|
data/ext/winevt/winevt.c
CHANGED
@@ -1,7 +1,11 @@
|
|
1
1
|
#include <winevt_c.h>
|
2
2
|
|
3
3
|
VALUE rb_mWinevt;
|
4
|
+
VALUE rb_cQuery;
|
4
5
|
VALUE rb_cEventLog;
|
6
|
+
VALUE rb_cSubscribe;
|
7
|
+
VALUE rb_eWinevtQueryError;
|
8
|
+
VALUE rb_eRemoteHandlerError;
|
5
9
|
|
6
10
|
static ID id_call;
|
7
11
|
|
@@ -13,11 +17,14 @@ Init_winevt(void)
|
|
13
17
|
rb_cQuery = rb_define_class_under(rb_cEventLog, "Query", rb_cObject);
|
14
18
|
rb_cSubscribe = rb_define_class_under(rb_cEventLog, "Subscribe", rb_cObject);
|
15
19
|
rb_eWinevtQueryError = rb_define_class_under(rb_cQuery, "Error", rb_eStandardError);
|
20
|
+
rb_eRemoteHandlerError = rb_define_class_under(rb_cSubscribe, "RemoteHandlerError", rb_eRuntimeError);
|
16
21
|
|
17
22
|
Init_winevt_channel(rb_cEventLog);
|
18
23
|
Init_winevt_bookmark(rb_cEventLog);
|
19
24
|
Init_winevt_query(rb_cEventLog);
|
20
25
|
Init_winevt_subscribe(rb_cEventLog);
|
26
|
+
Init_winevt_locale(rb_cEventLog);
|
27
|
+
Init_winevt_session(rb_cEventLog);
|
21
28
|
|
22
29
|
id_call = rb_intern("call");
|
23
30
|
}
|
data/ext/winevt/winevt_c.h
CHANGED
@@ -21,28 +21,58 @@
|
|
21
21
|
#define EventQuery(object) ((struct WinevtQuery*)DATA_PTR(object))
|
22
22
|
#define EventBookMark(object) ((struct WinevtBookmark*)DATA_PTR(object))
|
23
23
|
#define EventChannel(object) ((struct WinevtChannel*)DATA_PTR(object))
|
24
|
+
#define EventSession(object) ((struct WinevtSession*)DATA_PTR(object))
|
25
|
+
|
26
|
+
typedef struct {
|
27
|
+
LANGID langID;
|
28
|
+
CHAR* langCode;
|
29
|
+
CHAR* description;
|
30
|
+
} LocaleInfo;
|
24
31
|
|
25
32
|
#ifdef __cplusplus
|
26
33
|
extern "C" {
|
27
34
|
#endif /* __cplusplus */
|
28
35
|
|
29
36
|
VALUE wstr_to_rb_str(UINT cp, const WCHAR* wstr, int clen);
|
37
|
+
#if defined(__cplusplus)
|
38
|
+
[[ noreturn ]]
|
39
|
+
#endif /* __cplusplus */
|
30
40
|
void raise_system_error(VALUE error, DWORD errorCode);
|
31
41
|
VALUE render_to_rb_str(EVT_HANDLE handle, DWORD flags);
|
32
|
-
|
42
|
+
EVT_HANDLE connect_to_remote(LPWSTR computerName, LPWSTR domain,
|
43
|
+
LPWSTR username, LPWSTR password,
|
44
|
+
EVT_RPC_LOGIN_FLAGS flags);
|
45
|
+
WCHAR* get_description(EVT_HANDLE handle, LANGID langID, EVT_HANDLE hRemote);
|
33
46
|
VALUE get_values(EVT_HANDLE handle);
|
34
|
-
VALUE render_system_event(EVT_HANDLE handle);
|
47
|
+
VALUE render_system_event(EVT_HANDLE handle, BOOL preserve_qualifiers);
|
48
|
+
LocaleInfo* get_locale_info_from_rb_str(VALUE rb_locale_str);
|
35
49
|
|
36
50
|
#ifdef __cplusplus
|
37
51
|
}
|
38
52
|
#endif /* __cplusplus */
|
39
53
|
|
40
|
-
VALUE rb_cQuery;
|
41
|
-
VALUE rb_cFlag;
|
42
|
-
VALUE rb_cChannel;
|
43
|
-
VALUE rb_cBookmark;
|
44
|
-
VALUE rb_cSubscribe;
|
45
|
-
VALUE rb_eWinevtQueryError;
|
54
|
+
extern VALUE rb_cQuery;
|
55
|
+
extern VALUE rb_cFlag;
|
56
|
+
extern VALUE rb_cChannel;
|
57
|
+
extern VALUE rb_cBookmark;
|
58
|
+
extern VALUE rb_cSubscribe;
|
59
|
+
extern VALUE rb_eWinevtQueryError;
|
60
|
+
extern VALUE rb_eRemoteHandlerError;
|
61
|
+
extern VALUE rb_cLocale;
|
62
|
+
extern VALUE rb_cSession;
|
63
|
+
|
64
|
+
struct WinevtSession {
|
65
|
+
LPWSTR server;
|
66
|
+
LPWSTR domain;
|
67
|
+
LPWSTR username;
|
68
|
+
LPWSTR password;
|
69
|
+
EVT_RPC_LOGIN_FLAGS flags;
|
70
|
+
};
|
71
|
+
|
72
|
+
extern LocaleInfo localeInfoTable[];
|
73
|
+
extern LocaleInfo default_locale;
|
74
|
+
|
75
|
+
struct WinevtLocale {};
|
46
76
|
|
47
77
|
struct WinevtChannel
|
48
78
|
{
|
@@ -66,6 +96,9 @@ struct WinevtQuery
|
|
66
96
|
LONG offset;
|
67
97
|
LONG timeout;
|
68
98
|
BOOL renderAsXML;
|
99
|
+
BOOL preserveQualifiers;
|
100
|
+
LocaleInfo *localeInfo;
|
101
|
+
EVT_HANDLE remoteHandle;
|
69
102
|
};
|
70
103
|
|
71
104
|
#define SUBSCRIBE_ARRAY_SIZE 10
|
@@ -84,11 +117,16 @@ struct WinevtSubscribe
|
|
84
117
|
time_t lastTime;
|
85
118
|
DWORD currentRate;
|
86
119
|
BOOL renderAsXML;
|
120
|
+
BOOL preserveQualifiers;
|
121
|
+
LocaleInfo* localeInfo;
|
122
|
+
EVT_HANDLE remoteHandle;
|
87
123
|
};
|
88
124
|
|
89
125
|
void Init_winevt_query(VALUE rb_cEventLog);
|
90
126
|
void Init_winevt_channel(VALUE rb_cEventLog);
|
91
127
|
void Init_winevt_bookmark(VALUE rb_cEventLog);
|
92
128
|
void Init_winevt_subscribe(VALUE rb_cEventLog);
|
129
|
+
void Init_winevt_locale(VALUE rb_cEventLog);
|
130
|
+
void Init_winevt_session(VALUE rb_cEventLog);
|
93
131
|
|
94
132
|
#endif // _WINEVT_C_H
|
data/ext/winevt/winevt_channel.c
CHANGED
@@ -19,6 +19,8 @@
|
|
19
19
|
* print channels
|
20
20
|
*/
|
21
21
|
|
22
|
+
VALUE rb_cChannel;
|
23
|
+
|
22
24
|
DWORD is_subscribable_channel_p(EVT_HANDLE hChannel, BOOL force_enumerate);
|
23
25
|
DWORD check_subscribable_with_channel_config_type(int Id, PEVT_VARIANT pProperty, BOOL force_enumerate);
|
24
26
|
static void channel_free(void* ptr);
|
@@ -0,0 +1,92 @@
|
|
1
|
+
#include <winevt_c.h>
|
2
|
+
|
3
|
+
|
4
|
+
/* clang-format off */
|
5
|
+
/*
|
6
|
+
* Document-class: Winevt::EventLog::Locale
|
7
|
+
*
|
8
|
+
* handle locales for Windows EventLog's description.
|
9
|
+
*
|
10
|
+
* @example
|
11
|
+
* require 'winevt'
|
12
|
+
*
|
13
|
+
* @locale = Winevt::EventLog::Locale.new
|
14
|
+
* @locale.each {|code, desc|
|
15
|
+
* print code, desc
|
16
|
+
* }
|
17
|
+
* @since v0.8.1
|
18
|
+
*/
|
19
|
+
/* clang-format on */
|
20
|
+
|
21
|
+
VALUE rb_cLocale;
|
22
|
+
|
23
|
+
static void locale_free(void* ptr);
|
24
|
+
|
25
|
+
static const rb_data_type_t rb_winevt_locale_type = { "winevt/locale",
|
26
|
+
{
|
27
|
+
0,
|
28
|
+
locale_free,
|
29
|
+
0,
|
30
|
+
},
|
31
|
+
NULL,
|
32
|
+
NULL,
|
33
|
+
RUBY_TYPED_FREE_IMMEDIATELY };
|
34
|
+
|
35
|
+
static void
|
36
|
+
locale_free(void* ptr)
|
37
|
+
{
|
38
|
+
xfree(ptr);
|
39
|
+
}
|
40
|
+
|
41
|
+
static VALUE
|
42
|
+
rb_winevt_locale_alloc(VALUE klass)
|
43
|
+
{
|
44
|
+
VALUE obj;
|
45
|
+
struct WinevtLocale* winevtLocale;
|
46
|
+
obj = TypedData_Make_Struct(
|
47
|
+
klass, struct WinevtLocale, &rb_winevt_locale_type, winevtLocale);
|
48
|
+
return obj;
|
49
|
+
}
|
50
|
+
|
51
|
+
/*
|
52
|
+
* Initalize Locale class.
|
53
|
+
*
|
54
|
+
* @return [Locale]
|
55
|
+
*
|
56
|
+
*/
|
57
|
+
static VALUE
|
58
|
+
rb_winevt_locale_initialize(VALUE self)
|
59
|
+
{
|
60
|
+
return Qnil;
|
61
|
+
}
|
62
|
+
|
63
|
+
/*
|
64
|
+
* Enumerate supported locales and its descriptions
|
65
|
+
*
|
66
|
+
* @yield (String, String)
|
67
|
+
*
|
68
|
+
*/
|
69
|
+
static VALUE
|
70
|
+
rb_winevt_locale_each(VALUE self)
|
71
|
+
{
|
72
|
+
RETURN_ENUMERATOR(self, 0, 0);
|
73
|
+
|
74
|
+
for (int i = 0; localeInfoTable[i].langCode != NULL; i++) {
|
75
|
+
rb_yield_values(2,
|
76
|
+
rb_utf8_str_new_cstr(localeInfoTable[i].langCode),
|
77
|
+
rb_utf8_str_new_cstr(localeInfoTable[i].description));
|
78
|
+
}
|
79
|
+
|
80
|
+
return Qnil;
|
81
|
+
}
|
82
|
+
|
83
|
+
void
|
84
|
+
Init_winevt_locale(VALUE rb_cEventLog)
|
85
|
+
{
|
86
|
+
rb_cLocale = rb_define_class_under(rb_cEventLog, "Locale", rb_cObject);
|
87
|
+
|
88
|
+
rb_define_alloc_func(rb_cLocale, rb_winevt_locale_alloc);
|
89
|
+
|
90
|
+
rb_define_method(rb_cLocale, "initialize", rb_winevt_locale_initialize, 0);
|
91
|
+
rb_define_method(rb_cLocale, "each", rb_winevt_locale_each, 0);
|
92
|
+
}
|
@@ -0,0 +1,68 @@
|
|
1
|
+
#include <winevt_c.h>
|
2
|
+
|
3
|
+
LocaleInfo localeInfoTable [] = {
|
4
|
+
{ MAKELANGID(LANG_BULGARIAN, SUBLANG_DEFAULT), "bg_BG", "Bulgarian"},
|
5
|
+
{ MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED), "zh_CN", "Simplified Chinese "},
|
6
|
+
{ MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_TRADITIONAL), "zh_TW", "Traditional Chinese"},
|
7
|
+
{ MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_HONGKONG), "zh_HK", "Chinese (Hong Kong)"},
|
8
|
+
{ MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_SINGAPORE), "zh_SG", "Chinese (Singapore)"},
|
9
|
+
{ MAKELANGID(LANG_CROATIAN, SUBLANG_DEFAULT), "hr_HR", "Croatian"},
|
10
|
+
{ MAKELANGID(LANG_CZECH, SUBLANG_DEFAULT), "cs_CZ", "Czech"},
|
11
|
+
{ MAKELANGID(LANG_DANISH, SUBLANG_DEFAULT), "da_DK", "Dannish"},
|
12
|
+
{ MAKELANGID(LANG_DUTCH, SUBLANG_DUTCH), "nl_NL", "Dutch"},
|
13
|
+
{ MAKELANGID(LANG_DUTCH, SUBLANG_DUTCH_BELGIAN), "nl_BE", "Dutch (Belgium)"},
|
14
|
+
{ MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT), "en_US", "English (United States)"},
|
15
|
+
{ MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_UK), "en_GB", "English (UK)"},
|
16
|
+
{ MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_AUS), "en_AU", "English (Australia)"},
|
17
|
+
{ MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_CAN), "en_CA", "English (Canada)"},
|
18
|
+
{ MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_NZ), "en_NZ", "English (New Zealand)"},
|
19
|
+
{ MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_EIRE), "en_IE", "English (Ireland)"},
|
20
|
+
{ MAKELANGID(LANG_FINNISH, SUBLANG_DEFAULT), "fi_FI", "Finnish"},
|
21
|
+
{ MAKELANGID(LANG_FRENCH, SUBLANG_FRENCH), "fr_FR", "French"},
|
22
|
+
{ MAKELANGID(LANG_FRENCH, SUBLANG_FRENCH_BELGIAN), "fr_BE", "French (Belgium)"},
|
23
|
+
{ MAKELANGID(LANG_FRENCH, SUBLANG_FRENCH_CANADIAN), "fr_CA", "French (Canada)"},
|
24
|
+
{ MAKELANGID(LANG_FRENCH, SUBLANG_FRENCH_SWISS), "fr_CH", "French (Swiss)"},
|
25
|
+
{ MAKELANGID(LANG_GERMAN, SUBLANG_GERMAN), "de_DE", "German"},
|
26
|
+
{ MAKELANGID(LANG_GERMAN, SUBLANG_GERMAN_SWISS), "de_CH", "German (Swiss)"},
|
27
|
+
{ MAKELANGID(LANG_GERMAN, SUBLANG_GERMAN_AUSTRIAN), "de_AT", "German (Austria))"},
|
28
|
+
{ MAKELANGID(LANG_GREEK, SUBLANG_DEFAULT), "el_GR", "Greek (Ελληνικά)"},
|
29
|
+
{ MAKELANGID(LANG_HUNGARIAN, SUBLANG_DEFAULT), "hu_HU", "Hungarian"},
|
30
|
+
{ MAKELANGID(LANG_ICELANDIC, SUBLANG_DEFAULT), "is_IS", "Icelandic"},
|
31
|
+
{ MAKELANGID(LANG_ITALIAN, SUBLANG_ITALIAN), "it_IT", "Italian (Italy)"},
|
32
|
+
{ MAKELANGID(LANG_ITALIAN, SUBLANG_ITALIAN_SWISS), "it_CH", "Italian (Swiss)"},
|
33
|
+
{ MAKELANGID(LANG_JAPANESE, SUBLANG_DEFAULT), "ja_JP", "Japanases"},
|
34
|
+
{ MAKELANGID(LANG_KOREAN, SUBLANG_DEFAULT), "ko_KO", "Korean"},
|
35
|
+
{ MAKELANGID(LANG_NORWEGIAN, SUBLANG_NORWEGIAN_BOKMAL), "no_NO", "Norwegian (Bokmål)"},
|
36
|
+
{ MAKELANGID(LANG_NORWEGIAN, SUBLANG_NORWEGIAN_BOKMAL), "nb_NO", "Norwegian (Bokmål)"},
|
37
|
+
{ MAKELANGID(LANG_NORWEGIAN, SUBLANG_NORWEGIAN_NYNORSK), "nn_NO", "Norwegian (Nynorsk)"},
|
38
|
+
{ MAKELANGID(LANG_POLISH, SUBLANG_DEFAULT), "pl_PL", "Polish"},
|
39
|
+
{ MAKELANGID(LANG_PORTUGUESE, SUBLANG_PORTUGUESE), "pt_PT", "Portuguese"},
|
40
|
+
{ MAKELANGID(LANG_PORTUGUESE, SUBLANG_PORTUGUESE_BRAZILIAN), "pt_BR", "Portuguese (Brazil)"},
|
41
|
+
{ MAKELANGID(LANG_ROMANIAN, SUBLANG_DEFAULT), "ro_RO", "Romanian"},
|
42
|
+
{ MAKELANGID(LANG_RUSSIAN, SUBLANG_DEFAULT), "ru_RU", "Russian (русский язык)"},
|
43
|
+
{ MAKELANGID(LANG_SLOVAK, SUBLANG_DEFAULT), "sk_SK", "Slovak"},
|
44
|
+
{ MAKELANGID(LANG_SLOVENIAN, SUBLANG_DEFAULT), "sl_SI", "Slovenian"},
|
45
|
+
{ MAKELANGID(LANG_SPANISH, SUBLANG_SPANISH), "es_ES", "Spanish"},
|
46
|
+
{ MAKELANGID(LANG_SPANISH, SUBLANG_SPANISH), "es_ES_T", "Spanish (Traditional)"},
|
47
|
+
{ MAKELANGID(LANG_SPANISH, SUBLANG_SPANISH_MEXICAN), "es_MX", "Spanish (Mexico)"},
|
48
|
+
{ MAKELANGID(LANG_SPANISH, SUBLANG_SPANISH_MODERN), "es_ES_M", "Spanish (Modern)"},
|
49
|
+
{ MAKELANGID(LANG_SWEDISH, SUBLANG_DEFAULT), "sv_SE", "Swedish"},
|
50
|
+
{ MAKELANGID(LANG_TURKISH, SUBLANG_DEFAULT), "tr_TR", "Turkish"},
|
51
|
+
{ 0, NULL, NULL}
|
52
|
+
};
|
53
|
+
|
54
|
+
LocaleInfo default_locale = {MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL), "neutral", "Default"};
|
55
|
+
|
56
|
+
LocaleInfo*
|
57
|
+
get_locale_info_from_rb_str(VALUE rb_locale_str)
|
58
|
+
{
|
59
|
+
CHAR* locale_str = StringValuePtr(rb_locale_str);
|
60
|
+
|
61
|
+
for (int i = 0; localeInfoTable[i].langCode != NULL; i++) {
|
62
|
+
if (stricmp(localeInfoTable[i].langCode, locale_str) == 0) {
|
63
|
+
return &localeInfoTable[i];
|
64
|
+
}
|
65
|
+
}
|
66
|
+
|
67
|
+
rb_raise(rb_eArgError, "Unknown locale: %s", locale_str);
|
68
|
+
}
|