Hoping there are one or two windows developer gurus around that can help me with some IPC.
Currently developing an automation tool to test new desktop OS builds at work. Need to be able to open menu items on toolbarwindow32 windows (main menu of explorer windows). Now this requires retrieving information of all the buttons on the toolbar, obtaining the button ID of desired menu and sending a WM_COMMAND message with the ID. I'm having trouble retrieving button information.
Now im using openprocess, virtualallocex to allocate virtual memory in the target process, and then sending the TB_GETBUTTON message with a pointer to the allocated memory then reading out the result. Allocation and the send message works fine but reading the processmemory back out is failing but not returning an error code, getlastwin32error returns nothing either.
Sorry for vb code, not my choice
Declarations
Function
As mentioned above, the read process memoery call fails, the return value is -1
The documentation states it returns 0 for fail, non zero for pass.
Wondering if the problem lies in incorrect use of types in pinvoke calls or the struct tbbutton is incorrect, or my use of a pinned pointer is wrong, or whether I need to use adjusttokenpriviledges to ensure I have rights. Though I'm running under admin and examples similar to this don't use it.
Relevant documentation
Virtualallocex
Read Process Memory
TBBUTTON Struct
Currently developing an automation tool to test new desktop OS builds at work. Need to be able to open menu items on toolbarwindow32 windows (main menu of explorer windows). Now this requires retrieving information of all the buttons on the toolbar, obtaining the button ID of desired menu and sending a WM_COMMAND message with the ID. I'm having trouble retrieving button information.
Now im using openprocess, virtualallocex to allocate virtual memory in the target process, and then sending the TB_GETBUTTON message with a pointer to the allocated memory then reading out the result. Allocation and the send message works fine but reading the processmemory back out is failing but not returning an error code, getlastwin32error returns nothing either.
Sorry for vb code, not my choice
Declarations
Code:
<StructLayout(LayoutKind.Sequential)> _
Public Structure TBBUTTON
Public iBitmap As Integer
Public idCommand As Integer
Public fsState As Byte
Public fsStyle As Byte
'Public bReserved1 As Byte
Public bReserved2() As Byte
Public dwData As Integer
Public iString As Integer
End Structure
<DllImport("kernel32.dll", CharSet:=CharSet.Auto, SetLastError:=True)> _
Private Shared Function VirtualAllocEx(ByVal hProcess As IntPtr, ByVal lpAddress As IntPtr, _
ByVal dwSize As IntPtr, ByVal flAllocationType As VMemAllocType, ByVal flProtect As MemProtection) As IntPtr
End Function
<DllImport("kernel32.dll", CharSet:=CharSet.Auto, SetLastError:=True)> _
Private Shared Function VirtualFreeEx(ByVal hProcess As IntPtr, ByVal lpAddress As IntPtr, _
ByVal dwSize As IntPtr, ByVal dwFreeType As UInteger) As <MarshalAs(UnmanagedType.Bool)> Boolean
End Function
<DllImport("kernel32.dll", CharSet:=CharSet.Auto, SetLastError:=True)> _
Public Shared Function WriteProcessMemory(ByVal hProcess As IntPtr, ByVal lpBaseAddress As IntPtr, ByVal lpBuffer As IntPtr, ByVal nSize As IntPtr, ByVal lpNumberOfBytesWritten As IntPtr) As Integer
End Function
<DllImport("kernel32.dll", CharSet:=CharSet.Auto, SetLastError:=True)> _
Public Shared Function ReadProcessMemory(ByVal hProcess As IntPtr, ByVal lpBaseAddress As Integer, ByVal lpBuffer As Integer, _
ByVal iSize As IntPtr, ByVal lpNumberOfBytesRead As IntPtr) As Boolean
End Function
<DllImport("kernel32.dll", CharSet:=CharSet.Auto, SetLastError:=True)> _
Public Shared Function ReadProcessMemory(ByVal hProcess As IntPtr, ByVal lpBaseAddress As IntPtr, ByVal lpBuffer As Byte(), _
ByVal iSize As IntPtr, ByVal lpNumberOfBytesRead As IntPtr) As Boolean
End Function
<DllImport("kernel32.dll", CharSet:=CharSet.Auto, SetLastError:=True)> _
Public Shared Function OpenProcess(ByVal dwDesiredAccess As ProcessFlags, ByVal bInheritHandle As Boolean, ByVal dwProcessId As UInteger) As IntPtr
End Function
<DllImport("user32.dll", CharSet:=CharSet.Auto, SetLastError:=True)> _
Private Shared Function GetWindowThreadProcessId(ByVal hwnd As IntPtr, ByRef lpdwProcessId As UInteger) As UInteger
End Function
Function
Code:
Dim bInfo As TBBUTTON
Dim localPtr As Integer
Dim remotePtr As Integer
Dim bInfoSize As Integer
Dim res As Integer
Dim hwndProcess As IntPtr
Dim pid As UInteger
Dim bText As String
Dim tbCount As Integer
Dim lret As Integer
ReDim bInfo.bReserved2(1)
tbCount = SendMessageSync(hwnd, Methods.TB_BUTTONCOUNT, IntPtr.Zero, IntPtr.Zero)
bInfoSize = Marshal.SizeOf(bInfo)
If tbCount > 0 Then
GetWindowThreadProcessId(hwnd, pid)
hwndProcess = OpenProcess(ProcessFlags.PROC_VM_OPREADWRITE, False, pid)
remotePtr = VirtualAllocEx(hwndProcess, Nothing, bInfoSize, VMemAllocType.MEM_RESERVECOMMIT, MemProtection.PAGE_READWRITE)
For tbIndex As Integer = 0 To tbCount - 1
Dim hret As Integer = SendMessageSync(hwnd, Methods.TB_GETBUTTON, tbIndex, remotePtr)
gcInfo = GCHandle.Alloc(bInfo, GCHandleType.Pinned)
localPtr = gcInfo.AddrOfPinnedObject().ToInt32()
gcInfo.Free()
[COLOR="Red"]res = ReadProcessMemory(hwndProcess, remotePtr, localPtr, Len(bInfo), IntPtr.Zero)[/COLOR]
Dim str As String = Marshal.GetLastWin32Error()
VirtualFreeEx(hwnd, remotePtr, Marshal.SizeOf(remotePtr), &H8000UI)
CloseHandle(hwndProcess)
End If
As mentioned above, the read process memoery call fails, the return value is -1

Wondering if the problem lies in incorrect use of types in pinvoke calls or the struct tbbutton is incorrect, or my use of a pinned pointer is wrong, or whether I need to use adjusttokenpriviledges to ensure I have rights. Though I'm running under admin and examples similar to this don't use it.
Relevant documentation
Virtualallocex
Read Process Memory
TBBUTTON Struct