ragweed 0.1.7.3 → 0.2.0.pre1
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +33 -8
- data/Rakefile +80 -23
- data/VERSION +1 -0
- data/examples/hittracertux.rb +2 -6
- data/examples/hook_notepad.rb +1 -1
- data/examples/tux-example.rb +3 -2
- data/lib/.DS_Store +0 -0
- data/lib/ragweed/debugger32.rb +188 -145
- data/lib/ragweed/debuggerosx.rb +13 -13
- data/lib/ragweed/debuggertux.rb +267 -140
- data/lib/ragweed/rasm.rb +1 -1
- data/lib/ragweed/wrap32/debugging.rb +184 -64
- data/lib/ragweed/wrap32/hooks.rb +27 -11
- data/lib/ragweed/wrap32/process.rb +114 -7
- data/lib/ragweed/wrap32/process_token.rb +23 -7
- data/lib/ragweed/wrap32/thread_context.rb +100 -166
- data/lib/ragweed/wrap32/wrap32.rb +127 -72
- data/lib/ragweed/wrap32.rb +1 -1
- data/lib/ragweed/wraposx/constants.rb +1 -9
- data/lib/ragweed/wraposx/region_info.rb +209 -188
- data/lib/ragweed/wraposx/structs.rb +102 -0
- data/lib/ragweed/wraposx/thread_context.rb +636 -159
- data/lib/ragweed/wraposx/thread_info.rb +40 -107
- data/lib/ragweed/wraposx/thread_info.rb.old +121 -0
- data/lib/ragweed/wraposx/wraposx.rb +154 -231
- data/lib/ragweed/wraposx.rb +2 -1
- data/lib/ragweed/wraptux/constants.rb +46 -22
- data/lib/ragweed/wraptux/struct_helpers.rb +25 -0
- data/lib/ragweed/wraptux/threads.rb +0 -0
- data/lib/ragweed/wraptux/wraptux.rb +58 -62
- data/lib/ragweed/wraptux.rb +3 -4
- data/lib/ragweed.rb +36 -8
- data/ragweed.gemspec +85 -15
- metadata +50 -18
@@ -1,7 +1,11 @@
|
|
1
|
-
|
1
|
+
require 'ffi'
|
2
|
+
require 'ostruct'
|
3
|
+
require 'Win32API'
|
4
|
+
require 'pp'
|
2
5
|
|
3
6
|
module Ragweed;end
|
4
7
|
module Ragweed::Wrap32
|
8
|
+
|
5
9
|
NULL = 0x0
|
6
10
|
|
7
11
|
module PagePerms
|
@@ -68,32 +72,73 @@ module Ragweed::Wrap32
|
|
68
72
|
ALLOCATE_BUFFER = 256
|
69
73
|
end
|
70
74
|
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
75
|
+
module Win
|
76
|
+
extend FFI::Library
|
77
|
+
|
78
|
+
ffi_lib 'kernel32', 'Advapi32'
|
79
|
+
ffi_convention :stdcall
|
80
|
+
attach_function 'OpenProcess', [ :long, :long, :long ], :long
|
81
|
+
attach_function 'OpenThread', [ :long, :long, :long ], :long
|
82
|
+
attach_function 'CloseHandle', [ :long ], :long
|
83
|
+
attach_function 'GetLastError', [ ], :long
|
84
|
+
attach_function 'FormatMessageA', [ :long, :pointer, :long, :long, :pointer, :long, :pointer ], :void
|
85
|
+
attach_function 'VirtualAllocEx', [ :long, :long, :long, :long, :long ], :long
|
86
|
+
attach_function 'VirtualFreeEx', [ :long, :long, :long, :long, ], :long
|
87
|
+
attach_function 'WriteProcessMemory', [ :long, :long, :pointer, :long, :long ], :long
|
88
|
+
attach_function 'ReadProcessMemory', [ :long, :long, :pointer, :long, :long ], :long
|
89
|
+
attach_function 'VirtualQueryEx', [ :long, :long, :pointer, :long ], :long
|
90
|
+
attach_function 'VirtualProtectEx', [ :long, :long, :long, :long, :pointer ], :void
|
91
|
+
attach_function 'GetCurrentProcessId', [], :long
|
92
|
+
attach_function 'GetProcessId', [ :long ], :long
|
93
|
+
attach_function 'GetCurrentThreadId', [], :long
|
94
|
+
attach_function 'GetModuleHandleA', [ :pointer ], :long
|
95
|
+
attach_function 'LoadLibraryA', [ :pointer ], :long
|
96
|
+
attach_function 'GetProcAddress', [ :long, :pointer], :long
|
97
|
+
attach_function 'WaitForSingleObject', [ :long, :long ], :long
|
98
|
+
attach_function 'Process32First', [ :long, :pointer ], :long
|
99
|
+
attach_function 'Process32Next', [ :long, :pointer ], :long
|
100
|
+
attach_function 'Module32First', [ :long, :pointer ], :long
|
101
|
+
attach_function 'Module32Next', [ :long, :pointer ], :long
|
102
|
+
attach_function 'CreateToolhelp32Snapshot', [ :long, :long ], :long
|
103
|
+
attach_function 'Thread32First', [ :long, :pointer ], :long
|
104
|
+
attach_function 'Thread32Next', [ :long, :pointer ], :long
|
105
|
+
attach_function 'SuspendThread', [ :long ], :long
|
106
|
+
attach_function 'ResumeThread', [ :long ], :long
|
107
|
+
attach_function 'CreateRemoteThread', [ :long, :long, :long, :long, :long, :long, :long ], :long
|
108
|
+
attach_function 'Sleep', [ :long ], :long
|
109
|
+
attach_function 'DuplicateHandle', [ :long, :long, :long, :pointer, :long, :long, :long ], :long
|
110
|
+
attach_function 'CreateFileA', [ :pointer, :long, :long, :pointer, :long, :long, :pointer ], :long
|
111
|
+
attach_function 'OpenEventA', [ :long, :long, :pointer ], :long
|
112
|
+
attach_function 'CreateEventA', [ :long, :long, :long, :pointer ], :long
|
113
|
+
attach_function 'SetEvent', [ :long ], :long
|
114
|
+
attach_function 'ResetEvent', [ :long ], :long
|
115
|
+
attach_function 'WriteFile', [ :long, :pointer, :long, :pointer, :pointer ], :long
|
116
|
+
attach_function 'ReadFile', [ :long, :pointer, :long, :pointer, :pointer ], :long
|
117
|
+
attach_function 'DeviceIoControl', [ :long, :long, :pointer, :long, :pointer, :long, :pointer, :pointer ], :long
|
118
|
+
attach_function 'GetOverlappedResult', [ :long, :pointer, :pointer, :long ], :long
|
119
|
+
attach_function 'WaitForMultipleObjects', [ :long, :pointer, :long, :long ], :long
|
120
|
+
|
121
|
+
ffi_lib 'ntdll'
|
122
|
+
ffi_convention :stdcall
|
123
|
+
attach_function 'NtQueryInformationProcess', [ :long, :long, :pointer, :long, :pointer ], :long
|
124
|
+
|
125
|
+
ffi_lib 'msvcrt'
|
126
|
+
ffi_convention :stdcall
|
127
|
+
attach_function 'malloc', [ :long ], :long
|
128
|
+
attach_function 'memcpy', [ :pointer, :pointer, :long ], :long
|
129
|
+
|
130
|
+
## XXX This shouldnt be in psapi in win7, need to clean this up
|
131
|
+
## XXX Also the unicode version should be supported, this is NOT complete
|
132
|
+
ffi_lib 'psapi'
|
133
|
+
ffi_convention :stdcall
|
134
|
+
attach_function 'GetMappedFileNameA', [ :long, :long, :pointer, :long ], :long
|
88
135
|
end
|
89
136
|
|
90
|
-
# --------------------------------------------------------------------------------------
|
91
|
-
|
92
137
|
class << self
|
93
138
|
|
94
139
|
# Get a process handle given a pid
|
95
140
|
def open_process(pid)
|
96
|
-
r =
|
141
|
+
r = Win.OpenProcess(0x1F0FFF, 0, pid)
|
97
142
|
raise WinX.new(:open_process) if r == 0
|
98
143
|
return r
|
99
144
|
end
|
@@ -101,7 +146,7 @@ module Ragweed::Wrap32
|
|
101
146
|
# Get a thread handle given a tid; if a block is provided, the semantics are
|
102
147
|
# as File#open with a block.
|
103
148
|
def open_thread(tid, &block)
|
104
|
-
h =
|
149
|
+
h = Win.OpenThread(0x1F03FF, 0, tid)
|
105
150
|
raise WinX.new(:open_thread) if h == 0
|
106
151
|
if block_given?
|
107
152
|
ret = yield h
|
@@ -114,34 +159,32 @@ module Ragweed::Wrap32
|
|
114
159
|
# Close any Win32 handle. Reminder: Win32 handles are just integers, like file
|
115
160
|
# descriptors in Posix.
|
116
161
|
def close_handle(h)
|
117
|
-
|
162
|
+
raise WinX.new(:close_handle) if Win.CloseHandle(h) == 0
|
118
163
|
end
|
119
164
|
|
120
165
|
# Get the last error code (errno) (can't fail)
|
121
166
|
def get_last_error
|
122
|
-
|
167
|
+
Win.GetLastError()
|
123
168
|
end
|
124
169
|
|
125
170
|
# strerror(errno) (can't fail)
|
126
171
|
def format_message(code=nil)
|
127
172
|
code ||= get_last_error
|
128
|
-
buf = "\x00" * 4096
|
129
|
-
|
130
|
-
|
131
|
-
return buf.split("\x00")[0]
|
173
|
+
buf = FFI::MemoryPointer.from_string("\x00" * 4096)
|
174
|
+
Win.FormatMessageA(4096, nil, code, 0x00000400, buf, 4096, nil)
|
175
|
+
return buf.to_s.split("\x00")[0]
|
132
176
|
end
|
133
177
|
|
134
178
|
# Allocate memory in a remote process (or yourself, with handle -1)
|
135
179
|
def virtual_alloc_ex(h, sz, addr=NULL, prot=0x40)
|
136
|
-
r =
|
137
|
-
call(h, addr, sz, 0x1000, prot)
|
180
|
+
r = Win.VirtualAllocEx(h, addr, sz, 0x1000, prot)
|
138
181
|
raise WinX.new(:virtual_alloc_ex) if r == 0
|
139
182
|
return r
|
140
183
|
end
|
141
184
|
|
142
185
|
# Free memory in a remote process given the pointer returned from virtual_alloc_ex
|
143
186
|
def virtual_free_ex(h, ptr, type=0x8000)
|
144
|
-
r =
|
187
|
+
r = Win.VirtualFreeEx(h, ptr.to_i, 0, type)
|
145
188
|
raise WinX.new(:virtual_free_ex) if r == 0
|
146
189
|
return r
|
147
190
|
end
|
@@ -149,19 +192,27 @@ module Ragweed::Wrap32
|
|
149
192
|
# Write a string into the memory of a remote process given its handle and an address
|
150
193
|
def write_process_memory(h, dst, val)
|
151
194
|
val = val.to_s if not val.kind_of? String
|
152
|
-
r =
|
195
|
+
r = Win.WriteProcessMemory(h, dst.to_i, val, val.size, NULL)
|
153
196
|
raise WinX.new(:write_process_memory) if r == 0
|
154
197
|
return r
|
155
198
|
end
|
156
199
|
|
157
200
|
# Read from a remote process given an address and length, returning a string.
|
158
201
|
def read_process_memory(h, ptr, len)
|
202
|
+
# val = FFI::MemoryPointer.from_string("\x00" * len)
|
159
203
|
val = "\x00" * len
|
160
|
-
r =
|
204
|
+
r = Win.ReadProcessMemory(h, ptr.to_i, val, len, NULL)
|
161
205
|
raise WinX.new(:read_process_memory) if r == 0
|
162
206
|
return val ## don't handle short reads XXX
|
163
207
|
end
|
164
208
|
|
209
|
+
def get_mapped_filename(h, lpv, size)
|
210
|
+
val = "\x00" * size
|
211
|
+
r = Win.GetMappedFileNameA(h, lpv.to_i, val, size)
|
212
|
+
raise WinX.new(:get_mapped_filename) if r == 0
|
213
|
+
return val
|
214
|
+
end
|
215
|
+
|
165
216
|
def str2memory_basic_info(mbi)
|
166
217
|
s = OpenStruct.new
|
167
218
|
s.BaseAddress,
|
@@ -179,7 +230,7 @@ module Ragweed::Wrap32
|
|
179
230
|
# flags.
|
180
231
|
def virtual_query_ex(h, ptr)
|
181
232
|
mbi = [0,0,0,0,0,0,0].pack("LLLLLLL")
|
182
|
-
if
|
233
|
+
if Win.VirtualQueryEx(h, ptr, mbi, mbi.size)
|
183
234
|
str2memory_basic_info(mbi)
|
184
235
|
else
|
185
236
|
nil
|
@@ -192,7 +243,7 @@ module Ragweed::Wrap32
|
|
192
243
|
base = virtual_query_ex(h, addr).BaseAddress if size == 0
|
193
244
|
base ||= addr
|
194
245
|
|
195
|
-
if
|
246
|
+
if Win.VirtualProtectEx(h, base, size, prot, old)
|
196
247
|
old.unpack("L").first
|
197
248
|
else
|
198
249
|
raise WinX.new(:virtual_protect_ex)
|
@@ -201,26 +252,31 @@ module Ragweed::Wrap32
|
|
201
252
|
|
202
253
|
# getpid
|
203
254
|
def get_current_process_id
|
204
|
-
|
255
|
+
Win.GetCurrentProcessId() # can't realistically fail
|
256
|
+
end
|
257
|
+
|
258
|
+
# get_processid
|
259
|
+
def get_process_id(h)
|
260
|
+
Win.GetProcessId(h)
|
205
261
|
end
|
206
262
|
|
207
263
|
# gettid
|
208
264
|
def get_current_thread_id
|
209
|
-
|
265
|
+
Win.GetCurrentThreadId() # can't realistically fail
|
210
266
|
end
|
211
267
|
|
212
268
|
# Given a DLL name, get a handle to the DLL.
|
213
269
|
def get_module_handle(name)
|
214
|
-
name = name
|
215
|
-
r =
|
270
|
+
name = name
|
271
|
+
r = Win.GetModuleHandleA(name)
|
216
272
|
raise WinX.new(:get_module_handle) if r == 0
|
217
273
|
return r
|
218
274
|
end
|
219
275
|
|
220
276
|
# load a library explicitly from a dll
|
221
277
|
def load_library(name)
|
222
|
-
name = name
|
223
|
-
r =
|
278
|
+
name = name
|
279
|
+
r = Win.LoadLibraryA(name)
|
224
280
|
raise WinX.new(:load_library) if r == 0
|
225
281
|
return r
|
226
282
|
end
|
@@ -236,13 +292,13 @@ module Ragweed::Wrap32
|
|
236
292
|
meth = y
|
237
293
|
end
|
238
294
|
|
239
|
-
r =
|
295
|
+
r = Win.GetProcAddress(h, meth)
|
240
296
|
return r # pass error through
|
241
297
|
end
|
242
298
|
|
243
299
|
# Select(2), for a single object handle.
|
244
300
|
def wait_for_single_object(h)
|
245
|
-
r =
|
301
|
+
r = Win.WaitForSingleObject(h, -1)
|
246
302
|
raise WinX.new(:wait_for_single_object) if r == -1
|
247
303
|
end
|
248
304
|
|
@@ -265,12 +321,12 @@ module Ragweed::Wrap32
|
|
265
321
|
# Use Toolhelp32 to enumerate all running processes on the box, returning
|
266
322
|
# a struct with PIDs and executable names.
|
267
323
|
def all_processes
|
268
|
-
h =
|
324
|
+
h = Win.CreateToolhelp32Snapshot(0x2, 0)
|
269
325
|
if h != -1
|
270
326
|
pi = [(9*4)+2048,0,0,0,0,0,0,0,0,"\x00"*2048].pack("LLLLLLLLLa2048")
|
271
|
-
if
|
327
|
+
if Win.Process32First(h, pi) != 0
|
272
328
|
yield str2process_info(pi)
|
273
|
-
while
|
329
|
+
while Win.Process32Next(h, pi) != 0
|
274
330
|
yield str2process_info(pi)
|
275
331
|
end
|
276
332
|
end
|
@@ -299,12 +355,12 @@ module Ragweed::Wrap32
|
|
299
355
|
# Given a pid, enumerate the modules loaded into the process, returning base
|
300
356
|
# addresses, memory ranges, and the module name.
|
301
357
|
def list_modules(pid=0)
|
302
|
-
h =
|
358
|
+
h = Win.CreateToolhelp32Snapshot(0x8, pid)
|
303
359
|
if h != -1
|
304
360
|
mi = [260+256+(8*4),0,0,0,0,0,0,0,"\x00"*256,"\x00"*260].pack("LLLLLLLLa256a260")
|
305
|
-
if
|
361
|
+
if Win.Module32First(h, mi) != 0
|
306
362
|
yield str2module_info(mi)
|
307
|
-
while
|
363
|
+
while Win.Module32Next(h, mi) != 0
|
308
364
|
yield str2module_info(mi)
|
309
365
|
end
|
310
366
|
end
|
@@ -327,7 +383,7 @@ module Ragweed::Wrap32
|
|
327
383
|
# interface is Ioctl-style; provide an ordinal and a buffer to pass results through.
|
328
384
|
def nt_query_information_process(h, ord, buf)
|
329
385
|
lenp = [0].pack("L")
|
330
|
-
if
|
386
|
+
if Win.NtQueryInformationProcess(h, ord, buf, buf.size, lenp) == 0
|
331
387
|
len = lenp.unpack("L").first
|
332
388
|
return buf[0..(len-1)]
|
333
389
|
end
|
@@ -349,13 +405,13 @@ module Ragweed::Wrap32
|
|
349
405
|
# List all the threads in a process given its pid, returning a struct containing
|
350
406
|
# tids and run state. This is relatively expensive, because it uses Toolhelp32.
|
351
407
|
def threads(pid)
|
352
|
-
h =
|
408
|
+
h = Win.CreateToolhelp32Snapshot(0x4, pid)
|
353
409
|
if h != -1
|
354
410
|
mi = [(7*4),0,0,0,0,0,0].pack("LLLLLLL")
|
355
|
-
if
|
411
|
+
if Win.Thread32First(h, mi) != 0
|
356
412
|
ti = str2thread_info(mi)
|
357
413
|
yield str2thread_info(mi) if ti.th32OwnerProcessID == pid
|
358
|
-
while
|
414
|
+
while Win.Thread32Next(h, mi) != 0
|
359
415
|
ti = str2thread_info(mi)
|
360
416
|
yield str2thread_info(mi) if ti.th32OwnerProcessID == pid
|
361
417
|
end
|
@@ -367,7 +423,7 @@ module Ragweed::Wrap32
|
|
367
423
|
|
368
424
|
# Suspend a thread given its handle.
|
369
425
|
def suspend_thread(h)
|
370
|
-
r =
|
426
|
+
r = Win.SuspendThread(h)
|
371
427
|
raise WinX.new(:suspend_thread) if r == 0
|
372
428
|
return r
|
373
429
|
end
|
@@ -375,25 +431,25 @@ module Ragweed::Wrap32
|
|
375
431
|
# Resume a suspended thread, returning nonzero if the thread was suspended,
|
376
432
|
# and 0 if it was running.
|
377
433
|
def resume_thread(h)
|
378
|
-
|
434
|
+
ResumeThread(h)
|
379
435
|
end
|
380
436
|
|
381
437
|
# Create a remote thread in the process, starting at the location
|
382
438
|
# "start", with the threadproc argument "arg"
|
383
439
|
def create_remote_thread(h, start, arg)
|
384
|
-
r =
|
440
|
+
r = Win.CreateRemoteThread(h, NULL, 0, start.to_i, arg.to_i, 0, 0)
|
385
441
|
raise WinX.new(:create_remote_thread) if r == 0
|
386
442
|
return r
|
387
443
|
end
|
388
444
|
|
389
445
|
def sleep(ms=0)
|
390
|
-
|
446
|
+
Win.Sleep(ms)
|
391
447
|
end
|
392
448
|
|
393
449
|
# clone a handle out of another open process (or self, with -1)
|
394
450
|
def duplicate_handle(ph, h)
|
395
451
|
ret = "\x00\x00\x00\x00"
|
396
|
-
r =
|
452
|
+
r = Win.DuplicateHandle(ph, h, -1, ret, 0, 0, 0x2)
|
397
453
|
raise WinX.new(:duplicate_handle) if r == 0
|
398
454
|
ret.to_l32
|
399
455
|
end
|
@@ -404,29 +460,28 @@ module Ragweed::Wrap32
|
|
404
460
|
opts[:access] ||= FileAccess::GENERIC_ALL
|
405
461
|
opts[:flags] ||= 0
|
406
462
|
|
407
|
-
r =
|
408
|
-
call(name, opts[:access], opts[:sharing], NULL, opts[:disposition], opts[:flags], NULL)
|
463
|
+
r = Win.CreateFileA(name, opts[:access], opts[:sharing], NULL, opts[:disposition], opts[:flags], NULL)
|
409
464
|
raise WinX.new(:create_file) if r == -1
|
410
465
|
return r
|
411
466
|
end
|
412
467
|
|
413
468
|
# i haven't made this work, but named handles are kind of silly anyways
|
414
469
|
def open_event(name)
|
415
|
-
r =
|
470
|
+
r = Win.OpenEventA(0, 0, name)
|
416
471
|
raise WinX.new(:open_event) if r == 0
|
417
472
|
return r
|
418
473
|
end
|
419
474
|
|
420
475
|
# signal an event
|
421
476
|
def set_event(h)
|
422
|
-
r =
|
477
|
+
r = Win.SetEvent(h)
|
423
478
|
raise WinX.new(:set_event) if r == 0
|
424
479
|
return r
|
425
480
|
end
|
426
481
|
|
427
482
|
# force-unsignal event (waiting on the event handle also does this)
|
428
483
|
def reset_event(h)
|
429
|
-
r =
|
484
|
+
r = Win.ResetEvent(h)
|
430
485
|
raise WinX.new(:reset_event) if r == 0
|
431
486
|
return r
|
432
487
|
end
|
@@ -437,7 +492,7 @@ module Ragweed::Wrap32
|
|
437
492
|
signalled = (1 if signalled) || 0
|
438
493
|
name ||= 0
|
439
494
|
|
440
|
-
r =
|
495
|
+
r = Win.CreateEventA(0, auto, signalled, name);
|
441
496
|
raise WinX.new(:create_event) if r == 0
|
442
497
|
return r
|
443
498
|
end
|
@@ -450,7 +505,7 @@ module Ragweed::Wrap32
|
|
450
505
|
end
|
451
506
|
|
452
507
|
outw = "\x00" * 4
|
453
|
-
r =
|
508
|
+
r = Win.WriteFile(h, buf, buf.size, outw, opp)
|
454
509
|
raise WinX.new(:write_file) if r == 0 and get_last_error != 997
|
455
510
|
return buf, outw.unpack("L").first
|
456
511
|
end
|
@@ -467,7 +522,7 @@ module Ragweed::Wrap32
|
|
467
522
|
overlapped.target = buf if overlapped
|
468
523
|
end
|
469
524
|
|
470
|
-
r =
|
525
|
+
r = Win.ReadFile(h, buf, count, outw, opp)
|
471
526
|
raise WinX.new(:read_file) if r == 0 and get_last_error != 997
|
472
527
|
return buf, outw.unpack("L").first
|
473
528
|
end
|
@@ -475,8 +530,7 @@ module Ragweed::Wrap32
|
|
475
530
|
def device_io_control(h, code, inbuf, outbuf, overlapped=NULL)
|
476
531
|
overlapped = overlapped.to_s if overlapped
|
477
532
|
outw = "\x00" * 4
|
478
|
-
r =
|
479
|
-
call(h, code, inbuf, inbuf.size, outbuf, outbuf.size, outw, overlapped)
|
533
|
+
r = Win.DeviceIoControl(h, code, inbuf, inbuf.size, outbuf, outbuf.size, outw, overlapped)
|
480
534
|
raise WinX.new(:device_io_control) if r == 0 and get_last_error != 997
|
481
535
|
return outw.unpack("L").first
|
482
536
|
end
|
@@ -484,20 +538,21 @@ module Ragweed::Wrap32
|
|
484
538
|
def get_overlapped_result(h, overlapped)
|
485
539
|
overlapped = overlapped.to_s
|
486
540
|
outw = "\x00" * 4
|
487
|
-
r =
|
541
|
+
r = Win.GetOverlappedResult(h, overlapped, outw, 0)
|
488
542
|
raise WinX.new(:get_overlapped_result) if r == 0
|
489
543
|
return outw.unpack("L").first
|
490
544
|
end
|
491
545
|
|
492
546
|
# just grab some local memory
|
547
|
+
# XXX same as FFI name ?
|
493
548
|
def malloc(sz)
|
494
|
-
r =
|
549
|
+
r = Win.malloc(sz)
|
495
550
|
raise WinX.new(:malloc) if r == 0
|
496
551
|
return r
|
497
552
|
end
|
498
553
|
|
499
554
|
def memcpy(dst, src, size)
|
500
|
-
|
555
|
+
Win.memcpy(dst, src, size)
|
501
556
|
end
|
502
557
|
|
503
558
|
# Block wrapper for thread suspension
|
@@ -514,7 +569,7 @@ module Ragweed::Wrap32
|
|
514
569
|
|
515
570
|
def wfmo(handles, ms=100)
|
516
571
|
hp = handles.to_ptr
|
517
|
-
r =
|
572
|
+
r = Win.WaitForMultipleObjects(handles.size, hp, 0, ms)
|
518
573
|
raise WinX(:wait_for_multiple_objects) if r == 0xFFFFFFFF
|
519
574
|
if r < handles.size
|
520
575
|
return handles[r]
|
data/lib/ragweed/wrap32.rb
CHANGED
@@ -5,7 +5,7 @@ module Ragweed; end
|
|
5
5
|
module Ragweed::Wrap32
|
6
6
|
|
7
7
|
# :stopdoc:
|
8
|
-
VERSION =
|
8
|
+
VERSION = File.read(File.join(File.dirname(__FILE__),"..","..","VERSION"))
|
9
9
|
LIBPATH = ::File.expand_path(::File.dirname(__FILE__)) + ::File::SEPARATOR
|
10
10
|
PATH = ::File.dirname(LIBPATH) + ::File::SEPARATOR
|
11
11
|
# :startdoc:
|
@@ -86,6 +86,7 @@ module Ragweed::Wraposx::Vm::Prot
|
|
86
86
|
NONE = 0x0 #no rights
|
87
87
|
ALL = 0x7 #all permissions
|
88
88
|
end
|
89
|
+
|
89
90
|
module Ragweed::Wraposx::Vm::Sm
|
90
91
|
# share mode constants
|
91
92
|
COW = 1
|
@@ -97,15 +98,6 @@ module Ragweed::Wraposx::Vm::Sm
|
|
97
98
|
SHARED_ALIASED = 7
|
98
99
|
end
|
99
100
|
|
100
|
-
# this should be moved to an include for all wrappers
|
101
|
-
module Ragweed::Wraposx::SizeOf
|
102
|
-
INT = [1].pack("I_").size
|
103
|
-
SHORT = [1].pack("S_").size
|
104
|
-
LONG = [1].pack("L_").size
|
105
|
-
DOUBLE = [1].pack("D").size
|
106
|
-
FLOAT = [1].pack("F").size
|
107
|
-
end
|
108
|
-
|
109
101
|
module Ragweed::Wraposx::Dl
|
110
102
|
RTLD_LAZY = 0x1
|
111
103
|
RTLD_NOW = 0x2
|