Hi All,
I have managed VirtualAllocEx. Before I declared this function as Private. Then when I moved it to Module file and changed it to Public, I don't get 0 anymore for bufferMem. Also I need to set lpAddress as ByVal. Otherwise, the length of controlName that given is twice than correct length (I don't know exactly how this happens).
Declare Function VirtualAllocEx Lib "kernel32" _
(ByVal hProcess As Long, _
ByVal lpAddress As Long, _
ByVal dwSize As Long, _
ByVal flAllocationType As Long, _
ByVal flProtect As Long) As Long
Now I got the correct retLength, but unfortunately retVal is 0, return the error description: Invalid procedure call or argument.
If retLength <> 0 Then
'Now read the component's name from the shared memory location.
retVal = ReadProcessMemory(processHandle, bufferMem, bytearray, size, VarPtr(written))
If retVal = 0 Then
Error Err 'ReadProcessMemory API Failed
End If
End If
My declaration of ReadProcessMemory is:
Declare Function ReadProcessMemory Lib "kernel32" _
(ByVal hProcess As Long, _
ByVal lpBaseAddress As Long, _
lpBuffer As Any, _
ByVal nSize As Long, _
lpNumberOfBytesRead As Long) As Long
And when I run the whole thing (ignore the retVal value), I got error in WideCharToMultiByte:
Function ByteArrayToString(bytes As String, length As Long) As String
Dim retValStr As String
Dim l As Long
If IsWin9x() Then
retValStr = Left(bytes, InStr(1, bytes, Chr(0)) - 1)
Else
retValStr = String$(length + 1, Chr(0))
l = WideCharToMultiByte(CP_ACP, 0, bytes, -1, retValStr, length + 1, Null, Null)
End If
ByteArrayToString = retValStr
End Function
The error is saying:
Run-time error '94':
Invalid use of Null
Any idea?
Here is the code:
Function GetWindowsFormsID(ByVal wnd As Long) As String
Dim PID As Long 'pid of the process that contains the control
Dim msg As Long
' Define the buffer that will eventually contain the desired
' component's name.
Dim bytearray As String * 65526
' Allocate space in the target process for the buffer as shared
' memory.
Dim bufferMem As Long
' Base address of the allocated region for the buffer.
Dim size As Long
' The amount of memory to be allocated.
Dim written As Long
' Number of bytes written to memory.
Dim retLength As Long
Dim retVal As Long
Dim errNum As Integer
Dim errDescription As String
size = 65527 'Len(bytearray)
' Creating and reading from a shared memory region is done
' differently in Win9x than in newer Oss.
Dim processHandle As Long
Dim fileHandle As Long
msg = RegisterWindowMessage("WM_GETCONTROLNAME")
If Not IsWin9x() Then
On Local Error GoTo Error_Handler_NT
Dim dwResult As Long
Call GetWindowThreadProcessId(wnd, PID)
processHandle = OpenProcess(PROCESS_VM_OPERATION Or PROCESS_VM_READ Or PROCESS_VM_WRITE, 0, PID)
If processHandle = 0 Then
Error Err 'OpenProcess API Failed
End If
bufferMem = VirtualAllocEx(processHandle, 0, size, MEM_RESERVE Or MEM_COMMIT, PAGE_READWRITE)
If bufferMem = 0 Then
Error Err 'VirtualAllocEx API Failed
End If
' Send message to the control's HWND for getting the
' Specified control name.
retLength = SendMessage(wnd, msg, size, ByVal bufferMem)
If retLength <> 0 Then
' Now read the component's name from the shared memory location.
retVal = ReadProcessMemory(processHandle, bufferMem, bytearray, size, VarPtr(written))
If retVal = 0 Then
Error Err 'ReadProcessMemory API Failed
End If
End If
Error_Handler_NT:
errNum = Err
errDescription = Error$
' Free the memory that was allocated.
retVal = VirtualFreeEx(processHandle, bufferMem, 0, MEM_RELEASE)
If retVal = 0 Then
Error Err 'VirtualFreeEx API Failed
End If
CloseHandle (processHandle)
If errNum <> 0 Then
On Local Error GoTo 0
Error errNum 'errDescription
End If
On Local Error GoTo 0
Else
On Local Error GoTo Error_Handler_9x
Dim SA As SECURITY_ATTRIBUTES
fileHandle = CreateFileMapping(INVALID_HANDLE_VALUE, SA, PAGE_READWRITE, 0, size, Null)
If fileHandle = 0 Then
Error Err 'CreateFileMapping API Failed
End If
bufferMem = MapViewOfFile(fileHandle, FILE_MAP_ALL_ACCESS, 0, 0, 0)
If bufferMem = 0 Then
Error Err 'MapViewOfFile API Failed
End If
Call CopyMemory(bufferMem, bytearray, size)
' Send message to the treeview control's HWND for
' getting the specified control's name.
retLength = SendMessage(wnd, msg, size, bufferMem)
' Read the control's name from the specific shared memory
' for the buffer.
Call CopyMemoryA(bytearray, bufferMem, 1024)
Error_Handler_9x:
errNum = Err
errDescription = Error$
' Unmap and close the file.
UnmapViewOfFile (bufferMem)
CloseHandle (fileHandle)
If errNum <> 0 Then
On Local Error GoTo 0
Error errNum 'errDescription
End If
On Local Error GoTo 0
End If
If retLength <> 0 Then
' Get the string value for the Control name.
GetWindowsFormsID = ByteArrayToString(bytearray, retLength)
End If
End Function