bluedragon99
asked on
GetModuleFileNameEx problem in visual basic process paths
Hello,
I am using this module to grab path's from pid's. This code only grabs paths to processes with windows. I can't seem to find any code that works properly and actually grabs ALL of the process paths (or atleast most of them). Any ideas??
Option Explicit
Public Declare Function CloseHandle Lib "Kernel32.dll" (ByVal Handle As Long) As Long
Public Declare Function OpenProcess Lib "Kernel32.dll" (ByVal dwDesiredAccessas As Long, ByVal bInheritHandle As Long, ByVal dwProcId As Long) As Long
Public Declare Function EnumProcesses Lib "psapi.dll" (ByRef lpidProcess As Long, ByVal cb As Long, ByRef cbNeeded As Long) As Long
Public Declare Function GetModuleFileNameExA Lib "psapi.dll" (ByVal hProcess As Long, ByVal hModule As Long, ByVal ModuleName As String, ByVal nSize As Long) As Long
Public Declare Function EnumProcessModules Lib "psapi.dll" (ByVal hProcess As Long, ByRef lphModule As Long, ByVal cb As Long, ByRef cbNeeded As Long) As Long
Public Declare Function TerminateProcess Lib "kernel32" (ByVal hProcess As Long, ByVal uExitCode As Long) As Long
Public Declare Sub ExitProcess Lib "kernel32" (ByVal uExitCode As Long)
Public Sub GetProcesses(lstAddTo As ListBox)
Dim lProcCount As Long
Dim lProcPoss As Long
Dim lNum As Long
Dim ProcessIDs() As Long
Dim cbNeeded2 As Long
Dim NumElements2 As Long
Dim arrModules(1 To 200) As Long
Dim lRet As Long
Dim sModName As String
Dim hwndProcess As Long
Dim iCounter As Long
Const SIZE = 500
Const PROCESS_QUERY_INFORMATION = 1024
Const PROCESS_VM_READ = 16
Const PROCESS_ALL_ACCESS = &H1F0FFF
'need to get the array containing the process id's for each process object
lProcCount = 8
lProcPoss = 96
Do While lProcCount <= lProcPoss
lProcCount = lProcCount * 2
ReDim ProcessIDs(lProcCount / 4) As Long
lRet = EnumProcesses(ProcessIDs(1 ), lProcCount, lProcPoss)
Loop
lNum = lProcPoss / 4
For iCounter = 1 To lNum
'Get a handle to the Process
hwndProcess = OpenProcess(PROCESS_ALL_AC CESS, 0, ProcessIDs(iCounter))
'Got a Process handle
If hwndProcess <> 0 Then
'Get an array of the module handles for the specified
'process
lRet = EnumProcessModules(hwndPro cess, arrModules(1), 200, cbNeeded2)
'If the Module Array is retrieved, Get the ModuleFileName
If lRet <> 0 Then
sModName = Space(255)
lRet = GetModuleFileNameExA(hwndP rocess, arrModules(1), sModName, SIZE)
lstAddTo.AddItem ProcessIDs(iCounter) & vbTab & Left(sModName, lRet)
End If
End If
'Close the handle
lRet = CloseHandle(hwndProcess)
Next
End Sub
I am using this module to grab path's from pid's. This code only grabs paths to processes with windows. I can't seem to find any code that works properly and actually grabs ALL of the process paths (or atleast most of them). Any ideas??
Option Explicit
Public Declare Function CloseHandle Lib "Kernel32.dll" (ByVal Handle As Long) As Long
Public Declare Function OpenProcess Lib "Kernel32.dll" (ByVal dwDesiredAccessas As Long, ByVal bInheritHandle As Long, ByVal dwProcId As Long) As Long
Public Declare Function EnumProcesses Lib "psapi.dll" (ByRef lpidProcess As Long, ByVal cb As Long, ByRef cbNeeded As Long) As Long
Public Declare Function GetModuleFileNameExA Lib "psapi.dll" (ByVal hProcess As Long, ByVal hModule As Long, ByVal ModuleName As String, ByVal nSize As Long) As Long
Public Declare Function EnumProcessModules Lib "psapi.dll" (ByVal hProcess As Long, ByRef lphModule As Long, ByVal cb As Long, ByRef cbNeeded As Long) As Long
Public Declare Function TerminateProcess Lib "kernel32" (ByVal hProcess As Long, ByVal uExitCode As Long) As Long
Public Declare Sub ExitProcess Lib "kernel32" (ByVal uExitCode As Long)
Public Sub GetProcesses(lstAddTo As ListBox)
Dim lProcCount As Long
Dim lProcPoss As Long
Dim lNum As Long
Dim ProcessIDs() As Long
Dim cbNeeded2 As Long
Dim NumElements2 As Long
Dim arrModules(1 To 200) As Long
Dim lRet As Long
Dim sModName As String
Dim hwndProcess As Long
Dim iCounter As Long
Const SIZE = 500
Const PROCESS_QUERY_INFORMATION = 1024
Const PROCESS_VM_READ = 16
Const PROCESS_ALL_ACCESS = &H1F0FFF
'need to get the array containing the process id's for each process object
lProcCount = 8
lProcPoss = 96
Do While lProcCount <= lProcPoss
lProcCount = lProcCount * 2
ReDim ProcessIDs(lProcCount / 4) As Long
lRet = EnumProcesses(ProcessIDs(1
Loop
lNum = lProcPoss / 4
For iCounter = 1 To lNum
'Get a handle to the Process
hwndProcess = OpenProcess(PROCESS_ALL_AC
'Got a Process handle
If hwndProcess <> 0 Then
'Get an array of the module handles for the specified
'process
lRet = EnumProcessModules(hwndPro
'If the Module Array is retrieved, Get the ModuleFileName
If lRet <> 0 Then
sModName = Space(255)
lRet = GetModuleFileNameExA(hwndP
lstAddTo.AddItem ProcessIDs(iCounter) & vbTab & Left(sModName, lRet)
End If
End If
'Close the handle
lRet = CloseHandle(hwndProcess)
Next
End Sub
I tried it and it seems to work fine with vb6 but not with visualStudio.net. Which one are you using? With VS.NET it seems that calling EnumProcesses doesn't properly update the lProcPoss variable (so you jsut get the first 12 processes). To check if this is the problem in your case, try initializing both lproccount and lprocposs to 400 and 800 repsectively (instead of 8 and 96) thus you should get (the first) 200 processes (instead of 12). Note that this is not a solution, but is just to verify where the problem is.
ASKER
I'm using vb6. It is only showing proccesses with windows. I was able to get it to show more than 12 by opening a bunch of apps with windows.
Ok so you are actually retrieving all the processes in the array ProcessIds, but then openProcess fails because of access rights. Try with the following. I'm not sure about the remaining openprocess errors (some process might have died...)
Option Explicit
Public Declare Function CloseHandle Lib "Kernel32.dll" (ByVal Handle As Long) As Long
Public Declare Function OpenProcess Lib "Kernel32.dll" (ByVal dwDesiredAccessas As Long, ByVal bInheritHandle As Long, ByVal dwProcId As Long) As Long
Public Declare Function EnumProcesses Lib "psapi.dll" (ByRef lpidProcess As Long, ByVal cb As Long, ByRef cbNeeded As Long) As Long
Public Declare Function GetModuleFileNameExA Lib "psapi.dll" (ByVal hProcess As Long, ByVal hModule As Long, ByVal ModuleName As String, ByVal nSize As Long) As Long
Public Declare Function GetProcessImageFileNameA Lib "psapi.dll" (ByVal hProcess As Long, ByVal ModuleName As String, ByVal nSize As Long) As Long
Public Declare Function EnumProcessModules Lib "psapi.dll" (ByVal hProcess As Long, ByRef lphModule As Long, ByVal cb As Long, ByRef cbNeeded As Long) As Long
Public Declare Function TerminateProcess Lib "kernel32" (ByVal hProcess As Long, ByVal uExitCode As Long) As Long
Public Declare Sub ExitProcess Lib "kernel32" (ByVal uExitCode As Long)
Public Sub GetProcesses(lstAddTo As ListBox)
Dim lProcCount As Long
Dim lProcPoss As Long
Dim lNum As Long
Dim ProcessIDs() As Long
Dim cbNeeded2 As Long
Dim NumElements2 As Long
Dim arrModules(1 To 200) As Long
Dim lRet As Long
Dim sModName As String
Dim hwndProcess As Long
Dim iCounter As Long
Const SIZE = 500
Const PROCESS_QUERY_INFORMATION = 1024
Const PROCESS_VM_READ = 16
Const PROCESS_ALL_ACCESS = &H1F0FFF
'need to get the array containing the process id's for each process object
lProcCount = 8
lProcPoss = 96
Do While lProcCount <= lProcPoss
lProcCount = lProcCount * 2
ReDim ProcessIDs(lProcCount / 4) As Long
lRet = EnumProcesses(ProcessIDs(1 ), lProcCount, lProcPoss)
Loop
lNum = lProcPoss / 4
Debug.Print lProcPoss / 4
For iCounter = 1 To lNum
'Get a handle to the Process
hwndProcess = OpenProcess(PROCESS_QUERY_ INFORMATIO N, 0, ProcessIDs(iCounter))
'Got a Process handle
If hwndProcess = 0 Then
sModName = "[OpenProcess Failed]"
Else
'Get an array of the module handles for the specified
'process
sModName = Space(SIZE)
lRet = GetProcessImageFileNameA(h wndProcess , sModName, SIZE)
If lRet = 0 Then
sModName = ""
Else
sModName = Left(sModName, lRet \ 2 + 1)
End If
End If
lstAddTo.AddItem ProcessIDs(iCounter) & vbTab & sModName
Debug.Print iCounter, ProcessIDs(iCounter), sModName
'Close the handle
lRet = CloseHandle(hwndProcess)
Next
End Sub
Option Explicit
Public Declare Function CloseHandle Lib "Kernel32.dll" (ByVal Handle As Long) As Long
Public Declare Function OpenProcess Lib "Kernel32.dll" (ByVal dwDesiredAccessas As Long, ByVal bInheritHandle As Long, ByVal dwProcId As Long) As Long
Public Declare Function EnumProcesses Lib "psapi.dll" (ByRef lpidProcess As Long, ByVal cb As Long, ByRef cbNeeded As Long) As Long
Public Declare Function GetModuleFileNameExA Lib "psapi.dll" (ByVal hProcess As Long, ByVal hModule As Long, ByVal ModuleName As String, ByVal nSize As Long) As Long
Public Declare Function GetProcessImageFileNameA Lib "psapi.dll" (ByVal hProcess As Long, ByVal ModuleName As String, ByVal nSize As Long) As Long
Public Declare Function EnumProcessModules Lib "psapi.dll" (ByVal hProcess As Long, ByRef lphModule As Long, ByVal cb As Long, ByRef cbNeeded As Long) As Long
Public Declare Function TerminateProcess Lib "kernel32" (ByVal hProcess As Long, ByVal uExitCode As Long) As Long
Public Declare Sub ExitProcess Lib "kernel32" (ByVal uExitCode As Long)
Public Sub GetProcesses(lstAddTo As ListBox)
Dim lProcCount As Long
Dim lProcPoss As Long
Dim lNum As Long
Dim ProcessIDs() As Long
Dim cbNeeded2 As Long
Dim NumElements2 As Long
Dim arrModules(1 To 200) As Long
Dim lRet As Long
Dim sModName As String
Dim hwndProcess As Long
Dim iCounter As Long
Const SIZE = 500
Const PROCESS_QUERY_INFORMATION = 1024
Const PROCESS_VM_READ = 16
Const PROCESS_ALL_ACCESS = &H1F0FFF
'need to get the array containing the process id's for each process object
lProcCount = 8
lProcPoss = 96
Do While lProcCount <= lProcPoss
lProcCount = lProcCount * 2
ReDim ProcessIDs(lProcCount / 4) As Long
lRet = EnumProcesses(ProcessIDs(1
Loop
lNum = lProcPoss / 4
Debug.Print lProcPoss / 4
For iCounter = 1 To lNum
'Get a handle to the Process
hwndProcess = OpenProcess(PROCESS_QUERY_
'Got a Process handle
If hwndProcess = 0 Then
sModName = "[OpenProcess Failed]"
Else
'Get an array of the module handles for the specified
'process
sModName = Space(SIZE)
lRet = GetProcessImageFileNameA(h
If lRet = 0 Then
sModName = ""
Else
sModName = Left(sModName, lRet \ 2 + 1)
End If
End If
lstAddTo.AddItem ProcessIDs(iCounter) & vbTab & sModName
Debug.Print iCounter, ProcessIDs(iCounter), sModName
'Close the handle
lRet = CloseHandle(hwndProcess)
Next
End Sub
ASKER
Nice! but now the paths are \device\harddiskvolume2\wi ndows\syst em32\winlo gon.exe
any easy way to convert or have it spit out C:\windows\system32\winlog on.exe
it's getting close!
any easy way to convert or have it spit out C:\windows\system32\winlog
it's getting close!
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Thanks man!