| 赞 | 76 |
| VIP | |
| 好人卡 | |
| 积分 | 99 |
| 经验 | |
| 最后登录 | 2026-3-14 |
| 在线时间 | 580 小时 |
- 梦石
- 0
- 星屑
- 9862
- 在线时间
- 580 小时
- 注册时间
- 2017-9-28
- 回帖
- 203
|
发表于 2017-10-20 23:25:20
|
显示全部楼层
本帖最后由 hyrious 于 2017-11-1 22:50 编辑
触瞎
想学口算虚函数表(不
[fold=看代码的时候顺手封装了一个整齐点的(][pre lang="ruby"]
#==============================================================================
# </> Downloader SixRC / 2017.10.17
#------------------------------------------------------------------------------
# Usage
# x = Downloader.download(url[, filename=url.basename[, cache=true]])
# x.ok? # true if downloaded or stopped
# x.info, [x.now, x.max] # progress information
# x.stop! # terminate downloading process
#
# * files using `stop!` stopped can be resumed by downloading it again.
#
# Example
# x = Downloader.download "http://zt.bdinfo.net/speedtest/wo3G.rar"
# loop do
# Input.update
# puts "#{x.now}/#{x.max}"
# break if x.ok?
# x.stop! if Input.trigger? Input::C
# Graphics.update
# end
# puts "Done!"
#
#==============================================================================
module Downloader
LoadLibrary = Win32API.new 'kernel32', 'LoadLibrary' , 'p' , 'l'
GetProcAddress = Win32API.new 'kernel32', 'GetProcAddress', 'lp' , 'l'
Urlmon = LoadLibrary.call 'urlmon.dll'
URLDownloadToFile = GetProcAddress.call Urlmon, 'URLDownloadToFileA'
CreateThread = Win32API.new 'kernel32', 'CreateThread' , 'llppll', 'l'
CloseHandle = Win32API.new 'kernel32', 'CloseHandle' , 'l' , 'l'
CallWindowProc = Win32API.new 'user32' , 'CallWindowProc', 'ppLLL' , 'i'
HRESULT_E_NOTIMPL = 0x80004001
EAT1 = [0xb8, HRESULT_E_NOTIMPL, 0xc2, 8].pack('CLCS')
EAT2 = [0xb8, HRESULT_E_NOTIMPL, 0xc2, 12].pack('CLCS')
EAT4 = [0xb8, HRESULT_E_NOTIMPL, 0xc2, 20].pack('CLCS')
RET0 = [0x31, 0300, 0xc2, 4].pack('CCCS')
PROC = [
# a0 = [URLDownloadToFile, url, dest, data, state]
0x8b, 0104,0044, 4, # mov 4(%esp), %eax |
0xff, 0160, 12, # pushl 12(%eax) |
0x6a, 0, # push 0 |
0xff, 0160, 8, # pushl 8(%eax) |
0xff, 0160, 4, # pushl 4(%eax) |
0x6a, 0, # push 0 |
0xff, 0020, # call *(%eax) | a0_0(0, a0_1, a0_2, 0, a0_3)
0x8b, 0104,0044, 4, # mov 4(%esp), %eax |
0x8b, 0100,0020, # mov 16(%eax), %eax |
0xc7, 0000,1,0,0,0, # movl 1 ,(%eax) | arg[0][4] = 1 # state
0xc3, # ret
].pack('C*')
OnProgress = [
# (ulProgress, ulProgressMax, ulStatusCode, szStatusText)
0x56, 0x57, # push %esi;push %edi |
0x8b, 0164,0044,12, # mov 12(%esp), %esi |
0x8b, 0176, 8, # mov 8(%esi), %edi |
0x8b, 0104,0044,16, # mov 16(%esp), %eax |
0x89, 0007, # mov %eax , (%edi) | arg[2][2][0] = arg[3]
0x8b, 0104,0044,20, # mov 20(%esp), %eax |
0x89, 0107, 4, # mov %eax ,4(%edi) | arg[2][2][1] = arg[4]
0x8b, 0166, 4, # mov 4(%esi), %esi |
0x8b, 0006, # mov (%esi), %eax | return arg[2][1][0]
0x5f, 0x5e, # pop %edi;pop %esi |
0xc2, 20,0, # ret 20
].pack('C*')
HRESULT_E_ABORT = 0x80004004
Abort = [
0x8b, 0104,0044, 4,
0xc7, 0,HRESULT_E_ABORT, # arg[0] = HRESULT_E_ABORT
0xc2, 16,
].pack('CCCCCCLCS')
VTBL = [
EAT2,RET0,RET0,
# IUnknown { QueryInterface, AddRef, Release }
EAT2,EAT1,EAT1,OnProgress,EAT2,EAT2,EAT4,EAT2,
# IBindStatusCallback
].pack('p*')
class Downloading
def initialize url, filename
@url, @filename = url, filename
@state = [0].pack('L')
@info = [0, 0].pack('LL')
@data = [VTBL, @state, @info].pack('p*')
@param = [URLDownloadToFile, url, filename, @data, @state].pack('Lp*')
@handle = CreateThread.call(0, 0, PROC, @param, 0, 0)
@disposed = false
end
def info
@info.unpack('LL')
end
def now
@info.unpack('LL')[0]
end
def max
@info.unpack('LL')[1]
end
def ok?
return true if @disposed
CloseHandle.call @handle if @disposed = @state.unpack('L')[0] == 1
@disposed
end
def stop
return if ok?
CallWindowProc.call(Abort, @state, 0, 0, 0)
end
def stop!
return if ok?
CallWindowProc.call(Abort, @state, 0, 0, 0)
until ok?
yield if block_given?
Graphics.update
end
end
end
Pool = []
def self.download url, filename = File.basename(url), cache = true
url += "?#{rand 2333333}" unless cache
x = Downloading.new url, filename
Pool << x
x
end
def self.clear
Pool.each { |x| x.stop }
Graphics.update until Pool.all? { |x| x.ok? }
Pool.clear
end
end
[/pre][/fold]
|
评分
-
查看全部评分
|