Solved

GetModuleFileNameEx problem in visual basic process paths

Posted on 2004-09-13
6
1,064 Views
Last Modified: 2008-02-01
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_ACCESS, 0, ProcessIDs(iCounter))
       'Got a Process handle
       If hwndProcess <> 0 Then
           'Get an array of the module handles for the specified
           'process
           lRet = EnumProcessModules(hwndProcess, arrModules(1), 200, cbNeeded2)
           'If the Module Array is retrieved, Get the ModuleFileName
           If lRet <> 0 Then
               sModName = Space(255)
               lRet = GetModuleFileNameExA(hwndProcess, 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
0
Comment
Question by:bluedragon99
  • 3
  • 3
6 Comments
 
LVL 11

Expert Comment

by:lbertacco
Comment Utility
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.
0
 
LVL 1

Author Comment

by:bluedragon99
Comment Utility
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.
0
 
LVL 11

Expert Comment

by:lbertacco
Comment Utility
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_INFORMATION, 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(hwndProcess, 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
0
IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 
LVL 1

Author Comment

by:bluedragon99
Comment Utility
Nice!  but now the paths are \device\harddiskvolume2\windows\system32\winlogon.exe

any easy way to convert or have it spit out C:\windows\system32\winlogon.exe


it's getting close!
0
 
LVL 11

Accepted Solution

by:
lbertacco earned 500 total points
Comment Utility
Well, sorry if I didn't mention but you can keep using your previous code to get names. The only relevant changes were the rights passed to OpenProcess and the handling of an error in return:

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 hModule        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_INFORMATION Or PROCESS_VM_READ, 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 = EnumProcessModules(hwndProcess, hModule, 4, cbNeeded2)
           'If the Module Array is retrieved, Get the ModuleFileName
           If lRet <> 0 Then
               sModName = Space(SIZE)
               lRet = GetModuleFileNameExA(hwndProcess, hModule, sModName, SIZE)
                If lRet = 0 Then
                    sModName = ""
                Else
                    sModName = Left(sModName, lRet)
                End If
           Else
               sModName = "[EnumProcessModules Failed]"
           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



0
 
LVL 1

Author Comment

by:bluedragon99
Comment Utility
Thanks man!
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

Purpose To explain how to place a textual stamp on a PDF document.  This is commonly referred to as an annotation, or possibly a watermark, but a watermark is generally different in that it is somewhat translucent.  Watermark’s may be text or graph…
I know it’s not a new topic to discuss and it has lots of online contents already available over the net. But Then I thought it would be useful to this site’s visitors and can have online repository on vim most commonly used commands. This post h…
Viewers will learn how to properly install Eclipse with the necessary JDK, and will take a look at an introductory Java program. Download Eclipse installation zip file: Extract files from zip file: Download and install JDK 8: Open Eclipse and …
In this fourth video of the Xpdf series, we discuss and demonstrate the PDFinfo utility, which retrieves the contents of a PDF's Info Dictionary, as well as some other information, including the page count. We show how to isolate the page count in a…

772 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now