VERSION 1.0 CLASS
BEGIN
  MultiUse = -1  'True
  Persistable = 0  'NotPersistable
  DataBindingBehavior = 0  'vbNone
  DataSourceBehavior  = 0  'vbNone
  MTSTransactionMode  = 0  'NotAnMTSObject
END
Attribute VB_Name = "cProcessInformation"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = False
Attribute VB_Exposed = False
Option Explicit


Private Declare Function GetCurrentProcessId Lib "kernel32" () As Long
Private Declare Function GetModuleBaseName Lib "psapi.dll" Alias "GetModuleBaseNameA" (ByVal hProcess As Long, ByVal hModule As Long, ByVal lpBaseName As String, ByVal nSize As Long) As Long
Private Declare Function EnumProcessModules Lib "psapi.dll" (ByVal hProcess As Long, ByRef lphModule As Long, ByVal cb As Long, ByRef lpcbNeeded As Long) As Long
Private Declare Function EnumProcesses Lib "psapi.dll" (ByRef lpidProcess As Long, ByVal cb As Long, ByRef cbNeeded As Long) As Long
Private Declare Function OpenProcess Lib "kernel32.dll" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
Private Declare Function CloseHandle Lib "kernel32.dll" (ByVal hObject As Long) As Long
Private Declare Function CreateToolhelp32Snapshot Lib "kernel32.dll" (ByVal dwFlags As Long, ByVal th32ProcessID As Long) As Long
Private Declare Function Process32First Lib "kernel32.dll" (ByVal hSnapshot As Long, ByRef lppe As PROCESSENTRY32) As Long
Private Declare Function Process32Next Lib "kernel32.dll" (ByVal hSnapshot As Long, ByRef lppe As PROCESSENTRY32) As Long
Private Declare Function lstrlen Lib "kernel32.dll" Alias "lstrlenA" (ByVal lpString As String) As Long
Private Declare Function GetVersionEx Lib "kernel32.dll" Alias "GetVersionExA" (ByRef lpVersionInformation As OSVERSIONINFO) As Long


Private Const PROCESS_QUERY_INFORMATION         As Long = &H400
Private Const PROCESS_VM_READ                   As Long = &H10
Private Const TH32CS_SNAPPROCESS                As Long = &H2
Private Const MAX_PATH                          As Long = 260
Private Const VER_PLATFORM_WIN32_NT             As Long = 2


Private Type PROCESSENTRY32
    dwSize              As Long
    cntUsage            As Long
    th32ProcessID       As Long
    th32DefaultHeapID   As Long
    th32ModuleID        As Long
    cntThreads          As Long
    th32ParentProcessID As Long
    pcPriClassBase      As Long
    dwFlags             As Long
    szExeFile           As String * MAX_PATH
End Type
Private Type OSVERSIONINFO
    dwOSVersionInfoSize As Long
    dwMajorVersion As Long
    dwMinorVersion As Long
    dwBuildNumber As Long
    dwPlatformId As Long
    szCSDVersion As String * 128
End Type
Private Function IsWinNT() As Boolean
    
    Dim osvi                As OSVERSIONINFO
    Dim bOsVersionInfo      As Boolean
    
    
    osvi.dwOSVersionInfoSize = Len(osvi)
    bOsVersionInfo = GetVersionEx(osvi)
    
    IsWinNT = (bOsVersionInfo And (osvi.dwPlatformId = VER_PLATFORM_WIN32_NT))
    
End Function
Private Function pvCheckProcess( _
            ByVal m_pid As Long, _
            ByVal m_ExeName As String) As Boolean
    
    
    Dim p_lProcess              As Long, _
        p_lRet                  As Long, _
        p_lModules(1 To 1024)   As Long, _
        p_lNeeded               As Long, _
        p_sBaseName             As String
    
    
    pvCheckProcess = False
    p_lProcess = OpenProcess(PROCESS_QUERY_INFORMATION Or PROCESS_VM_READ, 0, m_pid)
    
    If (p_lProcess) Then
        
        p_lRet = EnumProcessModules(p_lProcess, p_lModules(1), 1024 * 4, p_lNeeded)
        
        If (p_lRet) Then

            p_sBaseName = String(255, 0)
            p_lRet = GetModuleBaseName(p_lProcess, p_lModules(1), p_sBaseName, 255)
                
            If (p_lRet > 0) Then
                p_sBaseName = Left$(p_sBaseName, p_lRet)
            Else
                ' no base name (system?)
                CloseHandle p_lProcess
                Exit Function
            End If
            
            If (LCase(p_sBaseName) = LCase(m_ExeName)) Then
                pvCheckProcess = True
            End If

        End If
        
        CloseHandle p_lProcess
        
    End If
    
End Function
Public Function GetMyProcessId() As Long
    GetMyProcessId = GetCurrentProcessId()
End Function


Public Function GetProcessIdByName( _
            ByVal m_ExeFileName As String, _
            ByRef r_ProcessId As Long) As Boolean


    m_ExeFileName = LCase(m_ExeFileName)
    
    If (IsWinNT()) Then
        r_ProcessId = pvScanForProcess_NT(m_ExeFileName)
    Else
        r_ProcessId = pvScanForProcess_9x(m_ExeFileName)
    End If

    GetProcessIdByName = IIf((r_ProcessId = -1), False, True)

End Function


Private Function pvScanForProcess_9x(ByVal m_ExeName As String) As Long
    
    Dim p_eProcessEntry         As PROCESSENTRY32, _
        p_lSnapshot             As Long, _
        p_lProcess              As Long, _
        p_lProcessID            As Long, _
        p_sExeFile              As String
    
    
    pvScanForProcess_9x = -1
    p_lSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0&)
    
    If (p_lSnapshot) Then
        p_eProcessEntry.dwSize = Len(p_eProcessEntry)
        p_lProcess = Process32First(p_lSnapshot, p_eProcessEntry)
        
        Do While (p_lProcess)
            
            p_lProcessID = p_eProcessEntry.th32ProcessID
            
            p_sExeFile = p_eProcessEntry.szExeFile
            p_sExeFile = Left$(p_sExeFile, lstrlen(p_sExeFile))
            
            If (LCase(p_sExeFile) = m_ExeName) Then
                pvScanForProcess_9x = p_lProcessID
                Exit Function
            End If
            
            p_eProcessEntry.szExeFile = String$(MAX_PATH, 0)
            p_lProcess = Process32Next(p_lSnapshot, p_eProcessEntry)
            
        Loop
    End If
    
End Function

Private Function pvScanForProcess_NT(ByVal m_ExeName As String) As Long
    
    Dim p_lProcesses(1 To 1024)         As Long, _
        p_lNeeded                       As Long, _
        p_lProcess                      As Long
    
    
    pvScanForProcess_NT = -1
    If (EnumProcesses(p_lProcesses(1), 1024 * 4, p_lNeeded)) Then
    
        p_lNeeded = p_lNeeded \ 4
            
        For p_lProcess = 1 To p_lNeeded
            If (pvCheckProcess(p_lProcesses(p_lProcess), m_ExeName)) Then
                pvScanForProcess_NT = p_lProcesses(p_lProcess)
                Exit Function
            End If
        Next p_lProcess

    End If
    
End Function
