module NPGRT::Win32API
Constants
- CP_ACP
- CP_ANSI
- CP_GBK
- CP_UTF8
- CloseFile
- CloseSocket
- Connect
- CreatePipe
- INI_VALUE_MAX
- OS64
- OpenSocket
- PTRLEN
- ReadFile
- Recv
- STARTUPINFOTYPE
- Send
- TYPE_VOIDP
- W
- Win32File
- WriteFile
Public Instance Methods
addressof(dll, func)
click to toggle source
# File lib/npgrt/win32api.rb, line 49 def addressof(dll, func) dl = api('kernel32', 'GetModuleHandle').call(dll) dl = (dl == 0) ? dl : api('kernel32', 'LoadLibrary').call(dll) api('kernel32', 'GetProcAddress').call dl, func end
api(dll, func, params = nil, ret = "L")
click to toggle source
# File lib/npgrt/win32api.rb, line 42 def api(dll, func, params = nil, ret = "L") API.new dll, func, params, ret end
checked_api(dll, func, params = nil, ret = "L", info = "Error!", exclass = RuntimeError)
click to toggle source
# File lib/npgrt/win32api.rb, line 46 def checked_api(dll, func, params = nil, ret = "L", info = "Error!", exclass = RuntimeError) lambda{|*a| raise exclass, info if 0 != API.new(dll, func, params, ret).call(*a)} end
grant_all(addr, size)
click to toggle source
# File lib/npgrt/win32api.rb, line 65 def grant_all(addr, size) api('Kernel32', 'VirtualProtect').call addr, size, 0x40, "RGBARGBARGBARGBA" addr end
hfileread(handle, len)
click to toggle source
# File lib/npgrt/win32api.rb, line 240 def hfileread(handle, len) buf = "\0"*len llen = [0].pack(TYPE_VOIDP) ret = ReadFile.call(handle, buf, len, llen, 0) outlen = llen.unpack(TYPE_VOIDP).first ret != 0 ? buf[0, outlen] : nil end
hfilereada(handle, len)
click to toggle source
# File lib/npgrt/win32api.rb, line 255 def hfilereada(handle, len) ret = hfileread(handle, len) !ret ? ret : to_codepage(to_unicode(ret+"\0\0", CP_ACP)+"\0\0") end
hfilereadw(handle, len)
click to toggle source
# File lib/npgrt/win32api.rb, line 260 def hfilereadw(handle, len) ret = hfileread(handle, len) !ret ? ret : to_codepage(ret+"\0\0") end
hfilewrite(handle, buf, len = buf.to_str.length)
click to toggle source
# File lib/npgrt/win32api.rb, line 248 def hfilewrite(handle, buf, len = buf.to_str.length) llen = [0].pack(TYPE_VOIDP) ret = WriteFile.call(handle, buf.to_str, len, llen, 0) outlen = llen.unpack(TYPE_VOIDP).first ret != 0 ? outlen : nil end
iniread(app, key, ini = "Game.ini")
click to toggle source
# File lib/npgrt/win32api.rb, line 114 def iniread(app, key, ini = "Game.ini") buf = "\0\0"*INI_VALUE_MAX ini = normalize_pathsep_os ini app, key, ini = [app, key, ini].map{|x| to_unicode(x + "\0\0")+"\0\0"} len = api('kernel32', 'GetPrivateProfileStringW').call(app, key, "", buf, INI_VALUE_MAX, ini) to_codepage buf end
iniwrite(app, key, value, ini = "Game.ini")
click to toggle source
# File lib/npgrt/win32api.rb, line 122 def iniwrite(app, key, value, ini = "Game.ini") ini = normalize_pathsep_os ini app, key, value, ini = [app, key, value, ini].map{|x| to_unicode(x + "\0\0")+"\0\0"} api('kernel32', 'WritePrivateProfileStringW').call( app, key, value, ini ) end
memread(addr, size)
click to toggle source
# File lib/npgrt/win32api.rb, line 59 def memread(addr, size) buf = "\0"*size api('Kernel32','RtlMoveMemory').call buf, addr, size buf end
memread!(addr, size)
click to toggle source
# File lib/npgrt/win32api.rb, line 70 def memread!(addr, size) memread(grant_all(addr, size), size) end
memwrite(addr, buf, len = buf.length)
click to toggle source
# File lib/npgrt/win32api.rb, line 55 def memwrite(addr, buf, len = buf.length) api('Kernel32', 'RtlMoveMemory').call addr, buf, len end
memwrite!(addr, buf, len = buf.length)
click to toggle source
# File lib/npgrt/win32api.rb, line 74 def memwrite!(addr, buf, len = buf.length) memwrite(grant_all(addr, len), buf, len) end
open3(path, dir = nil, env = nil) { |stdin, stdout, stderr, proc_info| ... }
click to toggle source
# File lib/npgrt/win32api.rb, line 281 def open3(path, dir = nil, env = nil) si = "\0"*STARTUPINFOTYPE[:sizeof] api('Kernel32', 'GetStartupInfoW').call si si[STARTUPINFOTYPE[:show], 2] = [0].pack("S") stdin, stdout, stderr = winpipe, winpipe, winpipe si[STARTUPINFOTYPE[:handles][0], PTRLEN] = [stdin[:in]].pack(TYPE_VOIDP) si[STARTUPINFOTYPE[:handles][1], PTRLEN] = [stdout[:out]].pack(TYPE_VOIDP) si[STARTUPINFOTYPE[:handles][2], PTRLEN] = [stderr[:out]].pack(TYPE_VOIDP) pi = "\0"*PTRLEN*4 path = to_unicode(path + "\0\0")+"\0\0" dir = dir == nil ? nil : to_unicode(dir + "\0\0")+"\0\0" env = env == nil ? nil : to_unicode(env + "\0\0")+"\0\0" api('Kernel32', 'CreateProcessW').call( 0, path, 0, 0, 1, 0, 0, dir, si, pi, ) CloseFile.call(stdin[:in]) CloseFile.call(stdout[:out]) CloseFile.call(stderr[:out]) u = pi.unpack(TYPE_VOIDP*4) proc_info = Hash[ [:process, :thread, :pid, :tid].zip(u) ] CloseFile.call(proc_info[:process]) CloseFile.call(proc_info[:thread]) ret = yield stdin[:out], stdout[:in], stderr[:in], proc_info api('Kernel32', 'TerminateProcess').call proc_info[:process], ret end
popen(path, dir = nil, env = nil) { |a,b| ... }
click to toggle source
# File lib/npgrt/win32api.rb, line 316 def popen(path, dir = nil, env = nil) open3 path, dir, env do |a, b, c, d| yield a,b end end
regclosekey(key)
click to toggle source
# File lib/npgrt/win32api.rb, line 179 def regclosekey(key) api('advapi32', 'RegCloseKey').call key end
regopenkey(path, valuename)
click to toggle source
# File lib/npgrt/win32api.rb, line 158 def regopenkey(path, valuename) path =~ /([^\\]*)\\(.*)/ whole, main, child = *$~ main = REG.const_get(main) key = [0].pack(NPGRT::PtrType) child = to_unicode(child + "\0\0")+"\0\0" valuename = case valuename when 0, nil 0 else to_unicode(valuename+"\0\0")+"\0\0" end checked_api( 'advapi32', 'RegOpenKeyW', nil, 'L', "Open Key #{path} Error!" ).call( main, child, key ) key = key.unpack(NPGRT::PtrType).first [key, valuename] end
regread(path, valuename = 0, type = :REG_SZ)
click to toggle source
# File lib/npgrt/win32api.rb, line 182 def regread(path, valuename = 0, type = :REG_SZ) type = REG.const_get(type) if Symbol === type key, valuename = regopenkey(path, valuename) len = REG::BYTEINC plen = [len].pack(NPGRT::PtrType) buf = "\0\0"*len ptype = [type].pack(NPGRT::PtrType) ret = api('advapi32', 'RegQueryValueExW').call(key, valuename, 0, ptype, buf, plen) while ret == REG::EMOREDATA len += REG::BYTEINC plen = [len].pack(NPGRT::PtrType) buf = "\0\0"*len ret = api('advapi32', 'RegQueryValueExW').call(key, valuename, 0, ptype, buf, plen) end if ret == REG::ESUCCESS return buf[0, plen.unpack(NPGRT::PtrType).first*2] else raise "Query Key #{path} failed" end ensure regclosekey key end
regstrread(type, valuename = "")
click to toggle source
# File lib/npgrt/win32api.rb, line 206 def regstrread(type, valuename = "") val = regread(type, valuename) to_codepage val + "\0\0" end
regstrwrite(path, valuename = nil, value = "")
click to toggle source
# File lib/npgrt/win32api.rb, line 227 def regstrwrite(path, valuename = nil, value = "") regwrite(path, valuename, to_unicode(value+"\0\0")+"\0\0", :REG_SZ) end
regwrite(path, valuename = nil, value = "", type = :REG_SZ)
click to toggle source
# File lib/npgrt/win32api.rb, line 211 def regwrite(path, valuename = nil, value = "", type = :REG_SZ) key, valuename = regopenkey(path, valuename) type = REG.const_get(type) if Symbol === type raise "RegWrite #{path} Error!" if 0 != api('advapi32', 'RegSetValueExW').call( key, valuename, 0, type, value, value.length ) return true ensure regclosekey key end
simplehttpread(addr, hostname = addr[/http:\/\/([^\/]*)/, 1], resource = addr[/http:\/\/([^\/]*)(.*)$/, 2]) { |responseheader, nil| ... }
click to toggle source
# File lib/npgrt/win32api.rb, line 369 def simplehttpread(addr, hostname = addr[/http:\/\/([^\/]*)/, 1], resource = addr[/http:\/\/([^\/]*)(.*)$/, 2]) request = "GET #{resource} HTTP/1.1\r\n"\ "host:#{hostname}\r\n"\ "\r\n\r\n\r\n\r\n" t = tcpnew if hostname[0][/[0-9]/] u = addr = api('ws2_32', 'inet_addr').call( to_codepage(to_unicode(hostname+"\0\0")+"\0", CP_ANSI)+"\0" ) else hostent = api('ws2_32', 'gethostbyname').call( to_codepage(to_unicode(hostname+"\0\0")+"\0", CP_ANSI)+"\0" ) addr = memread(hostent+PTRLEN*3, PTRLEN) addr = addr.unpack(TYPE_VOIDP).first addr = memread(addr, PTRLEN) addr = addr.unpack(TYPE_VOIDP).first addr = memread(addr, PTRLEN) u = addr.unpack("L").first end uaddr = [2, 0, 0, 80, u].pack("CCCCLx8") raise "Can't connect to Server " if -1 == Connect.call(t, uaddr, 16) socketwrite t, request responseheader = "" while v = socketread(t, 20480) responseheader << v if pos = responseheader.index("\r\n\r\n") responsebody = responseheader[pos+4..-1] responseheader = responseheader[0...pos] break end yield responseheader, nil if block_given? end if !(length = responseheader[/Content-length:\s*(\d+)/i, 1]) length = 1e100 else length = length.to_i end while responsebody.length < length && (v = socketread(t, 20480)) responsebody << v yield responseheader, responsebody if block_given? end tcpclose t true end
sockaddr(host, port)
click to toggle source
# File lib/npgrt/win32api.rb, line 341 def sockaddr(host, port) [2, port, *host].pack("snCCCCx8") end
socketread(h, size)
click to toggle source
# File lib/npgrt/win32api.rb, line 357 def socketread(h, size) buf = "\0" * size ret = Recv.call h, buf, size, 0 case ret when -1, 0 nil else buf[0, ret] end end
socketwrite(h, buf)
click to toggle source
# File lib/npgrt/win32api.rb, line 353 def socketwrite(h, buf) Send.call h, buf, buf.length, 0 end
strread(addr)
click to toggle source
# File lib/npgrt/win32api.rb, line 103 def strread(addr) len = api('Kernel32', 'lstrlenA').call(addr) to_codepage(to_unicode(memread(addr, len+1), CP_ANSI), CP_UTF8) end
tcpclose(u)
click to toggle source
# File lib/npgrt/win32api.rb, line 349 def tcpclose(u) CloseSocket.call u end
tcpnew(addr = nil)
click to toggle source
# File lib/npgrt/win32api.rb, line 334 def tcpnew(addr = nil) addr = sockaddr(*addr) if Array === addr so = OpenSocket.call 2, 1, 6 Connect.call so, addr, addr.size if addr so end
to_codepage(string, codepage = CP_UTF8)
click to toggle source
# File lib/npgrt/win32api.rb, line 90 def to_codepage(string, codepage = CP_UTF8) len = api('Kernel32', 'WideCharToMultiByte').call codepage[:cp], 0, string, -1, 0, 0, 0, 0 buf = "\0"*len api('Kernel32', 'WideCharToMultiByte').call codepage[:cp], 0, string, -1, buf, len, 0, 0 if buf.respond_to?(:force_encoding) buf.force_encoding(defined?($RGSS_SCRIPTS) ? 'utf-8' : codepage[:encoding]) else buf end[0..-1].sub(/\0+$/){} end
to_unicode(string, codepage = CP_UTF8)
click to toggle source
# File lib/npgrt/win32api.rb, line 83 def to_unicode(string, codepage = CP_UTF8) len = api('Kernel32', 'MultiByteToWideChar').call codepage[:cp], 0, string, -1, 0, 0 buf = "\0\0"*len api('Kernel32', 'MultiByteToWideChar').call codepage[:cp], 0, string, -1, buf, len buf[0..-3] end
udpclose(u)
click to toggle source
# File lib/npgrt/win32api.rb, line 345 def udpclose(u) CloseSocket.call u end
udpnew(addr = nil)
click to toggle source
# File lib/npgrt/win32api.rb, line 327 def udpnew(addr = nil) addr = sockaddr(*addr) if Array === addr so = OpenSocket.call 2, 2, 0 Connect.call so, addr, addr.size if addr so end
winpipe()
click to toggle source
# File lib/npgrt/win32api.rb, line 273 def winpipe buf = "\0"*(PTRLEN*2) sa = [8+PTRLEN, nil, 1].pack(TYPE_VOIDP + "p" + TYPE_VOIDP) addr = [buf].pack("p").unpack(TYPE_VOIDP).first CreatePipe.call addr, addr+PTRLEN, sa, 1 ret = buf.unpack(TYPE_VOIDP*2) {:in => ret[0], :out => ret[1]} end
wstrread(addr)
click to toggle source
# File lib/npgrt/win32api.rb, line 108 def wstrread(addr) len = api('Kernel32', 'lstrlenW').call(addr) to_codepage(memread(addr, len*2+2)) end