Kieron
2008-02-25 08:47:05 UTC
Hi,
I'm trying to write an automation tool for vb6 (therefore i am not within
the process)
Investigation has led me to the CreateToolhelp32Snapshot api.
Which works, but Heap32listnext & Heap32Next is much too slow on a large
application (taking over 6 minutes) to start with.
I investigated further and HeapWalk seemed to be the way forward, however,
this works for a few iterations of heapwalk then crashes. HeapLock and
HeapValidate always return zero.
This code is in vb6 at the moment and being ported to c#.
How do I use either the toolhelp api, or stop heapwalk from crashing?
Heapwalk crashes without me attempting to read the process memory.
My code is:
Public Function EnumVBControls(ByVal hForm As Long, cbControls As ComboBox,
blnUseHeapWalk As Boolean)
Dim hSnapshot As Long
Dim lRes As Long, lRes2 As Long, idx As Long
Dim pid As Long, tid As Long
Dim tHL As HEAPLIST32
Dim tHE As HEAPENTRY32
Dim lf As LOGFONT
Dim i As Long, lVal As Long, lVal1 As Long
Dim sCaption As String
Dim bDone As Boolean
Dim fout As Integer
tid = GetWindowThreadProcessId(hForm, pid) ' Get ProcessID
If pid = 0 Then Exit Function
' Create a snapshot of the process
hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPHEAPLIST, pid)
tHL.dwSize = Len(tHL)
' Find first heap
lRes = Heap32ListFirst(hSnapshot, tHL)
Do While lRes = 1
tHE.dwSize = Len(tHE)
If blnUseHeapWalk Then
DoHeapWalk tHL.th32HeapID, tHL.th32ProcessID
Else
' Find first heap
lRes2 = Heap32First(tHE, tHL.th32ProcessID, tHL.th32HeapID)
Do While lRes2 = 1
lRes2 = Heap32Next(tHE)
Loop
End If
' Find next heap
lRes = Heap32ListNext(hSnapshot, tHL)
Loop
' Close the snapshot
CloseToolhelp32Snapshot hSnapshot
Set cb = Nothing
End Function
Public Sub DoHeapWalk(lngHeapID As Long, lngProcID As Long)
Dim tDetails As PROCESS_HEAP_ENTRY
Dim meminfo As MEMORY_BASIC_INFORMATION
Dim lngBlockSize As Long
Dim lngRet As Long
Dim lngBytes As Long
tDetails.lpData = 0
Debug.Assert (lngHeapID <> 0)
' Heaplock always 0
If HeapLock(lngHeapID) <> 0 Or True Then
blnOk = True
' Heapvalidate always 0
lngRet = HeapValidate(lngHeapID, &H1, &H0)
MsgBox "HeapValidate : " & lngRet
If True Then
Do While HeapWalk(lngHeapID, tDetails) <> 0
l = l + 1
Loop
End If
HeapUnlock lngHeapID
End If
End Sub
I'm trying to write an automation tool for vb6 (therefore i am not within
the process)
Investigation has led me to the CreateToolhelp32Snapshot api.
Which works, but Heap32listnext & Heap32Next is much too slow on a large
application (taking over 6 minutes) to start with.
I investigated further and HeapWalk seemed to be the way forward, however,
this works for a few iterations of heapwalk then crashes. HeapLock and
HeapValidate always return zero.
This code is in vb6 at the moment and being ported to c#.
How do I use either the toolhelp api, or stop heapwalk from crashing?
Heapwalk crashes without me attempting to read the process memory.
My code is:
Public Function EnumVBControls(ByVal hForm As Long, cbControls As ComboBox,
blnUseHeapWalk As Boolean)
Dim hSnapshot As Long
Dim lRes As Long, lRes2 As Long, idx As Long
Dim pid As Long, tid As Long
Dim tHL As HEAPLIST32
Dim tHE As HEAPENTRY32
Dim lf As LOGFONT
Dim i As Long, lVal As Long, lVal1 As Long
Dim sCaption As String
Dim bDone As Boolean
Dim fout As Integer
tid = GetWindowThreadProcessId(hForm, pid) ' Get ProcessID
If pid = 0 Then Exit Function
' Create a snapshot of the process
hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPHEAPLIST, pid)
tHL.dwSize = Len(tHL)
' Find first heap
lRes = Heap32ListFirst(hSnapshot, tHL)
Do While lRes = 1
tHE.dwSize = Len(tHE)
If blnUseHeapWalk Then
DoHeapWalk tHL.th32HeapID, tHL.th32ProcessID
Else
' Find first heap
lRes2 = Heap32First(tHE, tHL.th32ProcessID, tHL.th32HeapID)
Do While lRes2 = 1
lRes2 = Heap32Next(tHE)
Loop
End If
' Find next heap
lRes = Heap32ListNext(hSnapshot, tHL)
Loop
' Close the snapshot
CloseToolhelp32Snapshot hSnapshot
Set cb = Nothing
End Function
Public Sub DoHeapWalk(lngHeapID As Long, lngProcID As Long)
Dim tDetails As PROCESS_HEAP_ENTRY
Dim meminfo As MEMORY_BASIC_INFORMATION
Dim lngBlockSize As Long
Dim lngRet As Long
Dim lngBytes As Long
tDetails.lpData = 0
Debug.Assert (lngHeapID <> 0)
' Heaplock always 0
If HeapLock(lngHeapID) <> 0 Or True Then
blnOk = True
' Heapvalidate always 0
lngRet = HeapValidate(lngHeapID, &H1, &H0)
MsgBox "HeapValidate : " & lngRet
If True Then
Do While HeapWalk(lngHeapID, tDetails) <> 0
l = l + 1
Loop
End If
HeapUnlock lngHeapID
End If
End Sub