npgrt 0.0.3 → 0.0.4
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/lib/npgrt.rb +12 -1
- data/lib/npgrt.rb~ +13 -1
- data/lib/npgrt/.version.rb.swp +0 -0
- data/lib/npgrt/algorithm.rb +178 -0
- data/lib/npgrt/algorithm.rb~ +179 -0
- data/lib/npgrt/filesystem.rb +8 -0
- data/lib/npgrt/filesystem.rb~ +9 -0
- data/lib/npgrt/find.rb +31 -0
- data/lib/npgrt/find.rb~ +31 -0
- data/lib/npgrt/message.rb +0 -1
- data/lib/npgrt/message.rb~ +1 -1
- data/lib/npgrt/query.rb +6 -0
- data/lib/npgrt/report.rb +182 -0
- data/lib/npgrt/report.rb~ +183 -0
- data/lib/npgrt/require.rb +23 -1
- data/lib/npgrt/require.rb~ +24 -1
- data/lib/npgrt/version.rb +3 -1
- data/lib/npgrt/version.rb~ +3 -1
- data/lib/npgrt/win32api.rb +335 -16
- data/lib/npgrt/win32api.rb~ +334 -15
- data/lib/test_32.dll +0 -0
- data/lib/test_64.dll +0 -0
- metadata +14 -2
data/lib/npgrt/require.rb~
CHANGED
@@ -6,8 +6,31 @@ module NPGRT
|
|
6
6
|
super a
|
7
7
|
end
|
8
8
|
|
9
|
-
|
9
|
+
ADDPATH = []
|
10
|
+
|
11
|
+
def binary_forms(a)
|
12
|
+
w = NPGRT::PlatformWidth.to_s
|
13
|
+
[ a, a+".dll", a+".so",
|
14
|
+
File.basename(a) + "_" + w + File.extname(a),
|
15
|
+
File.basename(a) + "_" + w + ".dll",
|
16
|
+
File.basename(a) + "_" + w + ".so"
|
17
|
+
]
|
18
|
+
end
|
10
19
|
|
20
|
+
def require_binary(a)
|
21
|
+
path = binary_forms(a).inject([]){|ret, v|
|
22
|
+
ret.concat Gem.find_files v
|
23
|
+
}
|
24
|
+
v = path.map{|x|
|
25
|
+
FileTest.file?(x) ? NPGRT.normalize_pathsep_os(File.dirname(x)) : nil
|
26
|
+
}.compact - ADDPATH
|
27
|
+
ENV['path'] += ";" + v.join(";")
|
28
|
+
ADDPATH.concat v
|
29
|
+
end
|
30
|
+
|
31
|
+
alias primitive_require require
|
32
|
+
private :primitive_require
|
33
|
+
|
11
34
|
def require(a)
|
12
35
|
primitive_require(a) do |x|
|
13
36
|
try_build x
|
data/lib/npgrt/version.rb
CHANGED
data/lib/npgrt/version.rb~
CHANGED
data/lib/npgrt/win32api.rb
CHANGED
@@ -1,16 +1,32 @@
|
|
1
1
|
module NPGRT
|
2
2
|
require 'Win32API' unless defined? ::Win32API
|
3
3
|
module Win32API
|
4
|
+
|
4
5
|
W = ::Win32API
|
5
6
|
class API
|
6
7
|
def initialize(dll, func, param = nil, ret = "L")
|
7
|
-
@dll, @func, @param, @ret = dll, func, param, ret
|
8
|
-
|
8
|
+
@dll, @func, @param, @ret = dll, func, param, ret
|
9
|
+
end
|
10
|
+
|
11
|
+
def findapi(dll, func, param, ret)
|
12
|
+
[dll, File.basename(dll) + "_" + NPGRT::PlatformWidth.to_s + File.extname(dll)].each{|d|
|
13
|
+
[func, func + "A", func + "W"].each{|f|
|
14
|
+
if (a = begin
|
15
|
+
W.new(d, f, param, ret)
|
16
|
+
rescue LoadError, RuntimeError
|
17
|
+
nil
|
18
|
+
end
|
19
|
+
)
|
20
|
+
return a
|
21
|
+
end
|
22
|
+
}
|
23
|
+
}
|
24
|
+
raise Errno::ENOENT, " NPGRT::API: Can't find a proper DLL for #{dll}!#{func}"
|
9
25
|
end
|
10
26
|
|
11
27
|
def call(*args)
|
12
28
|
param = @param || guess(args)
|
13
|
-
@api ||=
|
29
|
+
@api ||= findapi(@dll, @func, param, @ret)
|
14
30
|
@api.call(*args)
|
15
31
|
end
|
16
32
|
|
@@ -27,13 +43,16 @@ module NPGRT
|
|
27
43
|
API.new dll, func, params, ret
|
28
44
|
end
|
29
45
|
|
46
|
+
def checked_api(dll, func, params = nil, ret = "L", info = "Error!", exclass = RuntimeError)
|
47
|
+
lambda{|*a| raise exclass, info if 0 != API.new(dll, func, params, ret).call(*a)}
|
48
|
+
end
|
30
49
|
def addressof(dll, func)
|
31
50
|
dl = api('kernel32', 'GetModuleHandle').call(dll)
|
32
51
|
dl = (dl == 0) ? dl : api('kernel32', 'LoadLibrary').call(dll)
|
33
52
|
api('kernel32', 'GetProcAddress').call dl, func
|
34
53
|
end
|
35
54
|
|
36
|
-
def memwrite(addr, buf, len = buf.
|
55
|
+
def memwrite(addr, buf, len = buf.length)
|
37
56
|
api('Kernel32', 'RtlMoveMemory').call addr, buf, len
|
38
57
|
end
|
39
58
|
|
@@ -52,13 +71,13 @@ module NPGRT
|
|
52
71
|
memread(grant_all(addr, size), size)
|
53
72
|
end
|
54
73
|
|
55
|
-
def memwrite!(addr, buf, len = buf.
|
56
|
-
|
74
|
+
def memwrite!(addr, buf, len = buf.length)
|
75
|
+
memwrite(grant_all(addr, len), buf, len)
|
57
76
|
end
|
58
77
|
|
59
78
|
CP_UTF8 = {cp: 65001, suffix:"\0", encoding: "utf-8"}
|
60
|
-
CP_ANSI = {cp: 0, suffix:"\0", encoding: "ascii
|
61
|
-
CP_OEM = CP_ANSI
|
79
|
+
CP_ANSI = {cp: 0, suffix:"\0", encoding: "us-ascii"}
|
80
|
+
CP_ACP = CP_OEM = CP_ANSI
|
62
81
|
CP_GBK = {cp: 65001, suffix: "\0", encoding: "gbk"}
|
63
82
|
|
64
83
|
def to_unicode(string, codepage = CP_UTF8)
|
@@ -72,14 +91,13 @@ module NPGRT
|
|
72
91
|
len = api('Kernel32', 'WideCharToMultiByte').call codepage[:cp], 0, string, -1, 0, 0, 0, 0
|
73
92
|
buf = "\0"*len
|
74
93
|
api('Kernel32', 'WideCharToMultiByte').call codepage[:cp], 0, string, -1, buf, len, 0, 0
|
75
|
-
|
76
|
-
|
77
|
-
b.force_encoding(defined?($RGSS_SCRIPTS) ?
|
94
|
+
if buf.respond_to?(:force_encoding)
|
95
|
+
buf.force_encoding(defined?($RGSS_SCRIPTS) ?
|
78
96
|
'utf-8' :
|
79
97
|
codepage[:encoding])
|
80
98
|
else
|
81
|
-
|
82
|
-
end
|
99
|
+
buf
|
100
|
+
end[0..-1].sub(/\0+$/){}
|
83
101
|
end
|
84
102
|
|
85
103
|
def strread(addr)
|
@@ -92,13 +110,314 @@ module NPGRT
|
|
92
110
|
to_codepage(memread(addr, len*2+2))
|
93
111
|
end
|
94
112
|
|
95
|
-
|
113
|
+
INI_VALUE_MAX = 2048
|
114
|
+
def iniread(app, key, ini = "Game.ini")
|
115
|
+
buf = "\0\0"*INI_VALUE_MAX
|
116
|
+
ini = normalize_pathsep_os ini
|
117
|
+
app, key, ini = [app, key, ini].map{|x| to_unicode(x + "\0\0")+"\0\0"}
|
118
|
+
len = api('kernel32', 'GetPrivateProfileStringW').call(app, key, "", buf, INI_VALUE_MAX, ini)
|
119
|
+
to_codepage buf
|
120
|
+
end
|
96
121
|
|
122
|
+
def iniwrite(app, key, value, ini = "Game.ini")
|
123
|
+
ini = normalize_pathsep_os ini
|
124
|
+
app, key, value, ini = [app, key, value, ini].map{|x| to_unicode(x + "\0\0")+"\0\0"}
|
125
|
+
api('kernel32', 'WritePrivateProfileStringW').call(
|
126
|
+
app, key, value, ini
|
127
|
+
)
|
128
|
+
end
|
97
129
|
|
98
130
|
|
131
|
+
module REG
|
132
|
+
HKEY_CLASSES_ROOT,
|
133
|
+
HKEY_CURRENT_USER,
|
134
|
+
HKEY_LOCAL_MACHINE,
|
135
|
+
HKEY_USERS,
|
136
|
+
HKEY_PERFORMANCE_DATA,
|
137
|
+
HKEY_CURRENT_CONFIG,
|
138
|
+
HKEY_DYN_DATA = *(0x80000000..0x80000010)
|
139
|
+
|
140
|
+
HKCR = HKEY_CLASSES_ROOT
|
141
|
+
HKCU = HKEY_CURRENT_USER
|
142
|
+
HKLM = HKEY_LOCAL_MACHINE
|
143
|
+
|
144
|
+
REG_NONE = 0
|
145
|
+
REG_SZ = 1
|
146
|
+
REG_EXPAND_SZ = 2
|
147
|
+
REG_BINARY = 3
|
148
|
+
REG_DWORD = 4
|
149
|
+
REG_DWORD_BIG_ENDIAN = 5
|
150
|
+
REG_MULTI_SZ = 7
|
151
|
+
|
152
|
+
|
153
|
+
ESUCCESS = 0
|
154
|
+
EMOREDATA = 234
|
155
|
+
BYTEINC = 4096
|
156
|
+
end
|
157
|
+
|
158
|
+
def regopenkey(path, valuename)
|
159
|
+
path =~ /([^\\]*)\\(.*)/
|
160
|
+
whole, main, child = *$~
|
161
|
+
main = REG.const_get(main)
|
162
|
+
key = [0].pack(NPGRT::PtrType)
|
163
|
+
child = to_unicode(child + "\0\0")+"\0\0"
|
164
|
+
valuename = case valuename
|
165
|
+
when 0, nil
|
166
|
+
0
|
167
|
+
else
|
168
|
+
to_unicode(valuename+"\0\0")+"\0\0"
|
169
|
+
end
|
170
|
+
checked_api(
|
171
|
+
'advapi32', 'RegOpenKeyW', nil, 'L', "Open Key #{path} Error!"
|
172
|
+
).call(
|
173
|
+
main, child, key
|
174
|
+
)
|
175
|
+
key = key.unpack(NPGRT::PtrType).first
|
176
|
+
[key, valuename]
|
177
|
+
end
|
178
|
+
|
179
|
+
def regclosekey(key)
|
180
|
+
api('advapi32', 'RegCloseKey').call key
|
181
|
+
end
|
182
|
+
def regread(path, valuename = 0, type = :REG_SZ)
|
183
|
+
type = REG.const_get(type) if Symbol === type
|
184
|
+
key, valuename = regopenkey(path, valuename)
|
185
|
+
len = REG::BYTEINC
|
186
|
+
plen = [len].pack(NPGRT::PtrType)
|
187
|
+
buf = "\0\0"*len
|
188
|
+
ptype = [type].pack(NPGRT::PtrType)
|
189
|
+
ret = api('advapi32', 'RegQueryValueExW').call(key, valuename, 0, ptype, buf, plen)
|
190
|
+
while ret == REG::EMOREDATA
|
191
|
+
len += REG::BYTEINC
|
192
|
+
plen = [len].pack(NPGRT::PtrType)
|
193
|
+
buf = "\0\0"*len
|
194
|
+
ret = api('advapi32', 'RegQueryValueExW').call(key, valuename, 0, ptype, buf, plen)
|
195
|
+
|
196
|
+
end
|
197
|
+
if ret == REG::ESUCCESS
|
198
|
+
return buf[0, plen.unpack(NPGRT::PtrType).first*2]
|
199
|
+
else
|
200
|
+
raise "Query Key #{path} failed"
|
201
|
+
end
|
202
|
+
ensure
|
203
|
+
regclosekey key
|
204
|
+
end
|
205
|
+
|
206
|
+
def regstrread(type, valuename = "")
|
207
|
+
val = regread(type, valuename)
|
208
|
+
to_codepage val + "\0\0"
|
209
|
+
end
|
210
|
+
|
211
|
+
def regwrite(path, valuename = nil, value = "", type = :REG_SZ)
|
212
|
+
key, valuename = regopenkey(path, valuename)
|
213
|
+
type = REG.const_get(type) if Symbol === type
|
214
|
+
raise "RegWrite #{path} Error!" if 0 != api('advapi32', 'RegSetValueExW').call(
|
215
|
+
key,
|
216
|
+
valuename,
|
217
|
+
0,
|
218
|
+
type,
|
219
|
+
value,
|
220
|
+
value.length
|
221
|
+
)
|
222
|
+
return true
|
223
|
+
ensure
|
224
|
+
regclosekey key
|
225
|
+
end
|
226
|
+
|
227
|
+
def regstrwrite(path, valuename = nil, value = "")
|
228
|
+
regwrite(path, valuename, to_unicode(value+"\0\0")+"\0\0", :REG_SZ)
|
229
|
+
end
|
230
|
+
|
231
|
+
extend self
|
232
|
+
Win32File = Struct.new(:read, :write, :close, :flush)
|
233
|
+
ReadFile = api('kernel32', 'ReadFile')
|
234
|
+
WriteFile = api('kernel32', 'WriteFile')
|
235
|
+
CloseFile = api('Kernel32', 'CloseHandle')
|
236
|
+
TYPE_VOIDP = NPGRT::PtrType
|
237
|
+
OS64 = TYPE_VOIDP == "Q"
|
238
|
+
PTRLEN = OS64 ? 8 : 4
|
239
|
+
|
240
|
+
def hfileread(handle, len)
|
241
|
+
buf = "\0"*len
|
242
|
+
llen = [0].pack(TYPE_VOIDP)
|
243
|
+
ret = ReadFile.call(handle, buf, len, llen, 0)
|
244
|
+
outlen = llen.unpack(TYPE_VOIDP).first
|
245
|
+
ret != 0 ? buf[0, outlen] : nil
|
246
|
+
end
|
247
|
+
|
248
|
+
def hfilewrite(handle, buf, len = buf.to_str.length)
|
249
|
+
llen = [0].pack(TYPE_VOIDP)
|
250
|
+
ret = WriteFile.call(handle, buf.to_str, len, llen, 0)
|
251
|
+
outlen = llen.unpack(TYPE_VOIDP).first
|
252
|
+
ret != 0 ? outlen : nil
|
253
|
+
end
|
254
|
+
|
255
|
+
def hfilereada(handle, len)
|
256
|
+
ret = hfileread(handle, len)
|
257
|
+
!ret ? ret : to_codepage(to_unicode(ret+"\0\0", CP_ACP)+"\0\0")
|
258
|
+
end
|
259
|
+
|
260
|
+
def hfilereadw(handle, len)
|
261
|
+
ret = hfileread(handle, len)
|
262
|
+
!ret ? ret : to_codepage(ret+"\0\0")
|
263
|
+
end
|
264
|
+
|
265
|
+
|
266
|
+
STARTUPINFOTYPE = {
|
267
|
+
:sizeof => OS64 ? 104 : 68,
|
268
|
+
:show => OS64 ? 64 : 48,
|
269
|
+
:handles => OS64 ? [80, 88, 96] : [56, 60, 64]
|
270
|
+
}
|
271
|
+
|
272
|
+
CreatePipe = api('Kernel32', 'CreatePipe')
|
273
|
+
def winpipe
|
274
|
+
buf = "\0"*(PTRLEN*2)
|
275
|
+
sa = [8+PTRLEN, nil, 1].pack(TYPE_VOIDP + "p" + TYPE_VOIDP)
|
276
|
+
addr = [buf].pack("p").unpack(TYPE_VOIDP).first
|
277
|
+
CreatePipe.call addr, addr+PTRLEN, sa, 1
|
278
|
+
ret = buf.unpack(TYPE_VOIDP*2)
|
279
|
+
{:in => ret[0], :out => ret[1]}
|
280
|
+
end
|
281
|
+
def open3(path, dir = nil, env = nil)
|
282
|
+
si = "\0"*STARTUPINFOTYPE[:sizeof]
|
283
|
+
api('Kernel32', 'GetStartupInfoW').call si
|
284
|
+
si[STARTUPINFOTYPE[:show], 2] = [0].pack("S")
|
285
|
+
stdin, stdout, stderr = winpipe, winpipe, winpipe
|
286
|
+
si[STARTUPINFOTYPE[:handles][0], PTRLEN] = [stdin[:in]].pack(TYPE_VOIDP)
|
287
|
+
si[STARTUPINFOTYPE[:handles][1], PTRLEN] = [stdout[:out]].pack(TYPE_VOIDP)
|
288
|
+
si[STARTUPINFOTYPE[:handles][2], PTRLEN] = [stderr[:out]].pack(TYPE_VOIDP)
|
289
|
+
pi = "\0"*PTRLEN*4
|
290
|
+
path = to_unicode(path + "\0\0")+"\0\0"
|
291
|
+
dir = dir == nil ? nil : to_unicode(dir + "\0\0")+"\0\0"
|
292
|
+
env = env == nil ? nil : to_unicode(env + "\0\0")+"\0\0"
|
293
|
+
api('Kernel32', 'CreateProcessW').call(
|
294
|
+
0,
|
295
|
+
path,
|
296
|
+
0,
|
297
|
+
0,
|
298
|
+
1,
|
299
|
+
0,
|
300
|
+
0,
|
301
|
+
dir,
|
302
|
+
si,
|
303
|
+
pi,
|
304
|
+
)
|
305
|
+
CloseFile.call(stdin[:in])
|
306
|
+
CloseFile.call(stdout[:out])
|
307
|
+
CloseFile.call(stderr[:out])
|
308
|
+
u = pi.unpack(TYPE_VOIDP*4)
|
309
|
+
proc_info = Hash[ [:process, :thread, :pid, :tid].zip(u) ]
|
310
|
+
CloseFile.call(proc_info[:process])
|
311
|
+
CloseFile.call(proc_info[:thread])
|
312
|
+
ret = yield stdin[:out], stdout[:in], stderr[:in], proc_info
|
313
|
+
api('Kernel32', 'TerminateProcess').call proc_info[:process], ret
|
314
|
+
end
|
315
|
+
|
316
|
+
def popen(path, dir = nil, env = nil)
|
317
|
+
open3 path, dir, env do |a, b, c, d|
|
318
|
+
yield a,b
|
319
|
+
end
|
320
|
+
end
|
321
|
+
|
322
|
+
CloseSocket = api('ws2_32', 'closesocket')
|
323
|
+
OpenSocket = api('ws2_32', 'socket')
|
324
|
+
Connect = api('ws2_32', 'connect')
|
325
|
+
Send = api('ws2_32', 'send')
|
326
|
+
Recv = api('ws2_32', 'recv')
|
327
|
+
def udpnew(addr = nil)
|
328
|
+
addr = sockaddr(*addr) if Array === addr
|
329
|
+
so = OpenSocket.call 2, 2, 0
|
330
|
+
Connect.call so, addr, addr.size if addr
|
331
|
+
so
|
332
|
+
end
|
333
|
+
|
334
|
+
def tcpnew(addr = nil)
|
335
|
+
addr = sockaddr(*addr) if Array === addr
|
336
|
+
so = OpenSocket.call 2, 1, 6
|
337
|
+
Connect.call so, addr, addr.size if addr
|
338
|
+
so
|
339
|
+
end
|
340
|
+
|
341
|
+
def sockaddr(host, port)
|
342
|
+
[2, port, *host].pack("snCCCCx8")
|
343
|
+
end
|
344
|
+
|
345
|
+
def udpclose(u)
|
346
|
+
CloseSocket.call u
|
347
|
+
end
|
348
|
+
|
349
|
+
def tcpclose(u)
|
350
|
+
CloseSocket.call u
|
351
|
+
end
|
352
|
+
|
353
|
+
def socketwrite(h, buf)
|
354
|
+
Send.call h, buf, buf.length, 0
|
355
|
+
end
|
356
|
+
|
357
|
+
def socketread(h, size)
|
358
|
+
buf = "\0" * size
|
359
|
+
ret = Recv.call h, buf, size, 0
|
360
|
+
case ret
|
361
|
+
when -1, 0
|
362
|
+
nil
|
363
|
+
else
|
364
|
+
buf[0, ret]
|
365
|
+
end
|
366
|
+
end
|
99
367
|
|
100
|
-
|
368
|
+
|
369
|
+
def simplehttpread(addr, hostname = addr[/http:\/\/([^\/]*)/, 1],
|
370
|
+
resource = addr[/http:\/\/([^\/]*)(.*)$/, 2])
|
371
|
+
request = "GET #{resource} HTTP/1.1\r\n"\
|
372
|
+
"host:#{hostname}\r\n"\
|
373
|
+
"\r\n\r\n\r\n\r\n"
|
374
|
+
t = tcpnew
|
375
|
+
if hostname[0][/[0-9]/]
|
376
|
+
u = addr = api('ws2_32', 'inet_addr').call(
|
377
|
+
to_codepage(to_unicode(hostname+"\0\0")+"\0", CP_ANSI)+"\0"
|
378
|
+
)
|
379
|
+
else
|
380
|
+
hostent = api('ws2_32', 'gethostbyname').call(
|
381
|
+
to_codepage(to_unicode(hostname+"\0\0")+"\0", CP_ANSI)+"\0"
|
382
|
+
)
|
383
|
+
|
384
|
+
addr = memread(hostent+PTRLEN*3, PTRLEN)
|
385
|
+
addr = addr.unpack(TYPE_VOIDP).first
|
386
|
+
addr = memread(addr, PTRLEN)
|
387
|
+
addr = addr.unpack(TYPE_VOIDP).first
|
388
|
+
addr = memread(addr, PTRLEN)
|
389
|
+
u = addr.unpack("L").first
|
390
|
+
end
|
391
|
+
uaddr = [2, 0, 0, 80, u].pack("CCCCLx8")
|
392
|
+
|
393
|
+
raise "Can't connect to Server " if -1 == Connect.call(t, uaddr, 16)
|
394
|
+
socketwrite t, request
|
395
|
+
responseheader = ""
|
396
|
+
while v = socketread(t, 20480)
|
397
|
+
responseheader << v
|
398
|
+
if pos = responseheader.index("\r\n\r\n")
|
399
|
+
responsebody = responseheader[pos+4..-1]
|
400
|
+
responseheader = responseheader[0...pos]
|
401
|
+
break
|
402
|
+
end
|
403
|
+
yield responseheader, nil if block_given?
|
404
|
+
end
|
405
|
+
|
406
|
+
if !(length = responseheader[/Content-length:\s*(\d+)/i, 1])
|
407
|
+
length = 1e100
|
408
|
+
else
|
409
|
+
length = length.to_i
|
410
|
+
end
|
411
|
+
|
412
|
+
while responsebody.length < length && (v = socketread(t, 20480))
|
413
|
+
responsebody << v
|
414
|
+
yield responseheader, responsebody if block_given?
|
415
|
+
end
|
416
|
+
tcpclose t
|
417
|
+
true
|
418
|
+
end
|
419
|
+
|
420
|
+
|
101
421
|
end
|
102
422
|
|
103
|
-
extend Win32API
|
104
423
|
end
|