Hi,
2010/7/27 Jing Li <>:
> =C2=A0Hi all,
>
> As titled, I want to read text content from a standard syslistview32 cont=
rol
> in an application. =C2=A0And the syslistview32 control is not a pop-up bu=
t
> embedded in the application, which means the control has same process ID =
as
> the application. =C2=A0In that case, I don't have to call VirtualAllocEx =
or
> WriteProcessMemory.
>
> So far, I could successfully get syslistview32 control's handle, count ho=
w
> many items listed. =C2=A0But still can not read its content. =C2=A0Could =
you please
> tell me how to do it correctly?
>
> require 'Win32API'
> findwin =3D Win32API.new('user32', 'FindWindow', 'PP', 'L')
> getdlg =3D Win32API.new('user32', 'GetDlgItem', 'LL', 'L')
> sendmsg =3D Win32API.new('user32', 'SendMessage', 'LLLP', 'L')
>
> #Some irrelevant details are ignored
> #Here I've already got syslistview32 control's handle, let's assume it is
> resultslist =3D 3739380
>
> puts "Count of items =3D #{sendmsg.call(resultslist, 4100, 0, nil)}"
> #LVM_GETITEMCOUNT =3D 0x1004
> puts header =3D getdlg.call(resultslist, 0).to_s(16).upcase
> #No problem, this works
>
> #From here I tried to SendMessage with LVM_GETITEMTEXT parameter to get
> syslistview32's content
> #Solution I: define a struct as described in MSDN, but something wrong wh=
en
> I tried to pack, this is due to my lack of knowledge on pack&unpack
> LV_item =3D Struct.new(:mask, :iItem, :iSubItem, :state, :stateMask,
sz=
Text,
> :cchTextMax, :iImage, :lParam)
> lv_item =3D LV_item.new()
> puts sendmsg.call(resultslist, 4165, 1, lv_item.to_a.pack("p"))
> =C2=A0 =C2=A0=3D> return value is 1, success?
> puts lv_item.inspect
> =C2=A0 =C2=A0=3D> #<struct LV_item mask=3Dnil, iItem=3Dnil, iSubItem=3Dni=
l, state=3Dnil,
> stateMask=3Dnil, pszText=3Dnil, cchTextMax=3Dnil, iImage=3Dnil, lParam=3D=
nil>
> absolutely not succeed
> #If I initiate lv_item =3D LV_item.new(0, 0, 0, 0, 0, "", 0, 0, ""), then
> error occurs at packing: can't convert Fixnum into String (TypeError). =
=C2=A0Can
> I pack integer pointer except pack("p")?
>
> #Solution II: Directly pack an array and pass to SendMessage, return valu=
e
> is still nil
> lv_item =3D [0, 0, 0, 0, 0, "\000", 0, 0, "\000"]
> lv_item =3D lv_item.pack("IiiIIpiip")
> puts sendmsg.call(resultslist, 4165, 1, lv_item)
> =C2=A0 =C2=A0=3D> return value is 1, success?
> lv_item =3D lv_item.unpack("IiiIIpiip")
> puts lv_item.inspect
> =C2=A0 =C2=A0=3D> [0, 0, 0, 0, 0, "\000", 0, 0, "\000"], nothing is padde=
d actually
>
> I really appreciate if you can answer my question, thanks in advance.
>
Here is a code using VirtualAllocEx and WriteProcessMemory for a
general purpose.
require 'Win32API'
findwin =3D Win32API.new('user32', 'FindWindow', 'PP', 'L')
getdlg =3D Win32API.new('user32', 'GetDlgItem', 'LL', 'L')
sendmsg =3D Win32API.new('user32', 'SendMessage', 'LLLP', 'L')
getWindowThreadProcessId =3D Win32API.new('user32',
'GetWindowThreadProcessId', 'LP', 'L')
openProcess =3D Win32API.new('kernel32', 'OpenProcess', 'LIL', 'L')
virtualAllocEx =3D Win32API.new('kernel32', 'VirtualAllocEx', 'LPLLL', 'L')
virtualFreeEx =3D Win32API.new('kernel32', 'VirtualFreeEx', 'LLLL', 'L')
writeProcessMemory =3D Win32API.new('kernel32', 'WriteProcessMemory',
'LLPLP', 'I')
readProcessMemory =3D Win32API.new('kernel32', 'ReadProcessMemory', 'LLPLP'=
, 'I')
PROCESS_VM_OPERATION =3D 0x08
PROCESS_VM_READ =3D 0x10
PROCESS_VM_WRITE =3D 0x20
PROCESS_QUERY_INFORMATION =3D 0x400
MEM_COMMIT =3D 0x1000
MEM_RELEASE =3D 0x8000
PAGE_READWRITE =3D 0x04
LVM_GETITEMTEXT =3D 0x1000+45
LVM_GETITEMCOUNT =3D 0x1000+4
SIZE_OF_LVITEM =3D 60
resultslist =3D 0xB0044 ##<=3D=3D start with some given handle
count =3D sendmsg.call(resultslist,LVM_GETITEMCOUNT, 0, nil)
lv_item =3D [0, 0, 0, 0, 0, nil, 512, 0, 0,0,0,0,0,0,0]
lv_item =3D lv_item.pack("LiiLLpiiLiiLLLL")
pid =3D 0.chr*4
getWindowThreadProcessId.call(resultslist, pid)
pid =3D pid.unpack('L').first
process =3D openProcess.call(PROCESS_VM_OPERATION|PROCESS_VM_R EAD|PROCESS_V=
M_WRITE|PROCESS_QUERY_INFORMATION,0,pid)
_lvi=3DvirtualAllocEx.call(process, nil, SIZE_OF_LVITEM,MEM_COMMIT,
PAGE_READWRITE)
_item=3DvirtualAllocEx.call(process, nil, 512, MEM_COMMIT,PAGE_READWRITE)
_subitem=3DvirtualAllocEx.call(process, nil, 512, MEM_COMMIT,PAGE_READWRITE=
)
for i in 0..count
lv_item[8,4] =3D [0].pack('L')
item =3D 0.chr * 512
lv_item[20,4] =3D [_item].pack('L')
writeProcessMemory.call(process, _lvi, lv_item, SIZE_OF_LVITEM, nil)
sendmsg.call(resultslist, LVM_GETITEMTEXT, i, _lvi)
subitem =3D 0.chr * 512
lv_item[8,4] =3D [1].pack('L')
lv_item[20,4] =3D [_subitem].pack('L')
writeProcessMemory.call(process, _lvi, lv_item, SIZE_OF_LVITEM, nil)
sendmsg.call(resultslist, LVM_GETITEMTEXT, i, _lvi)
readProcessMemory.call(process, _item, item, 512, nil)
readProcessMemory.call(process, _item, subitem, 512, nil)
item =3D item.strip!
subitem =3D subitem.strip!
puts "#{item} - #{subitem}"
end
virtualFreeEx.call(process, _lvi, 0, MEM_RELEASE)
virtualFreeEx.call(process, _item, 0, MEM_RELEASE)
virtualFreeEx.call(process, _subitem, 0, MEM_RELEASE)
Regards,
Park Heesob