Home All Groups Group Topic Archive Search About

Knowing what launched an EXE that used CreateProcess()?

Author
16 Mar 2009 5:37 PM
SupaFly
It's hard to explain I guess, but maybe that's why it's been difficult for
me to find.

Basically, I want to try and find out which EXE (or Process ID?) launched my
EXE when using CreateProcess(), or in other words, the "parent" process that
started the EXE I'm in.

I don't even know if this is possible, because I sure can't find anything
and I've been looking.  I try not to bother people here if I can figure it
out myself, but I really appreciate the help!

Author
16 Mar 2009 6:10 PM
Nobody
Show quote Hide quote
"SupaFly" <superfly9***@hotmail.com> wrote in message
news:%23M%23Yw3lpJHA.5880@TK2MSFTNGP05.phx.gbl...
> It's hard to explain I guess, but maybe that's why it's been difficult for
> me to find.
>
> Basically, I want to try and find out which EXE (or Process ID?) launched
> my
> EXE when using CreateProcess(), or in other words, the "parent" process
> that
> started the EXE I'm in.
>
> I don't even know if this is possible, because I sure can't find anything
> and I've been looking.  I try not to bother people here if I can figure it
> out myself, but I really appreciate the help!

There is no simple function to find out, other than looping through the list
of processes. See GetParentProcessID() below:

Option Explicit

Public Const MAX_PATH As Long = 260

' ToolHelp32
Public Const TH32CS_SNAPPROCESS As Long = 2&
Public Const TH32CS_SNAPTHREAD As Long = 4&
Public Const TH32CS_SNAPMODULE As Long = 8&
Public 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
Public Declare Function CreateToolhelp32Snapshot Lib "kernel32" ( _
    ByVal lFlags As Long, ByVal lProcessID As Long) As Long
Public Declare Function Process32First Lib "kernel32" ( _
    ByVal hSnapShot As Long, uProcess As PROCESSENTRY32) As Long
Public Declare Function Process32Next Lib "kernel32" ( _
    ByVal hSnapShot As Long, uProcess As PROCESSENTRY32) As Long
Public Declare Function CloseHandle Lib "kernel32" ( _
    ByVal hObject As Long) As Long

' Returns the parent ProcessID, require Win 9x/2000+, does not work in NT4.
Public Function GetParentProcessID(ByVal ProcessId As Long) As Long
    Dim hSnapShot As Long
    Dim uProcess As PROCESSENTRY32
    Dim success As Long

    hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0&)

    If hSnapShot = -1 Then Exit Function

    uProcess.dwSize = Len(uProcess)
    success = Process32First(hSnapShot, uProcess)

    If success = 1 Then

        Do
            If uProcess.th32ProcessID = ProcessId Then
                GetParentProcessID = uProcess.th32ParentProcessID
                Exit Do
            End If
        Loop While Process32Next(hSnapShot, uProcess)

    End If

    Call CloseHandle(hSnapShot)

End Function
Are all your drivers up to date? click for free checkup

Author
16 Mar 2009 6:36 PM
SupaFly
Thank you so much!

After posting, I did find this:
http://www.codeproject.com/KB/threads/ParentPID.aspx

But it's in C++.  I was either going to have to translate it or find VB
sample code, but you saved me some time.  Thanks again!
Author
17 Mar 2009 1:30 AM
Karl E. Peterson
SupaFly wrote:
> Basically, I want to try and find out which EXE (or Process ID?) launched my
> EXE when using CreateProcess(), or in other words, the "parent" process that
> started the EXE I'm in.

Here's a snippet similar to the other one offered, but it covers a few more oddball
situations (in the VB IDE or NT4).  It was taken from
http://vb.mvps.org/samples/Console - indented to highlight wordwrap...

   Private Function GetProcessParent() As String
      ' *** Added at v1.01 (entire routine) ***
      Dim ProcessID As Long
      Dim os As OSVERSIONINFO
      Dim hProcess As Long
      Dim info As PROCESS_BASIC_INFORMATION
      Dim Buffer As String
      Dim hSnap As Long
      Dim ProcEntry As PROCESSENTRY32
      Dim nRet As Long

      Const STATUS_SUCCESS As Long = 0

      ' Windows 2000+ and Windows 9x ship with the
      ' ToolHelp routines, so we only need to use
      ' NTDLL on NT4 and lower.
      os.dwOSVersionInfoSize = Len(os)
      Call GetVersionEx(os)

      ' We are after the parent of *this* process.
      ProcessID = GetCurrentProcessId()

      If m_Compiled = False Then
         ' If uncompiled, we are running under the VB IDE process.
         ' Return full name/path and current process ID.
         GetProcessParent = GetProcessFileName(0&)
         m_ParentProcessID = ProcessID

      ElseIf os.dwPlatformId = VER_PLATFORM_WIN32_NT And os.dwMajorVersion < 5 Then
         ' *** Use undocumented calls only when needed. ***
         ' This is a version of NT prior to Win2000!
         ' Make sure we have the needed function.
         If Exported("ntdll", "NtQueryInformationProcess") Then
            ' Obtain a handle to the current process.
            hProcess = OpenProcess(PROCESS_QUERY_INFORMATION Or PROCESS_VM_READ, 0,
ProcessID)
            If hProcess Then
               nRet = NtQueryInformationProcess(hProcess, SystemBasicInformation,
info, Len(info), ByVal 0&)
               If nRet = STATUS_SUCCESS Then
                  m_ParentProcessID = info.InheritedFromUniqueProcessId
               End If
               ' Done with this process.
               Call CloseHandle(hProcess)
            End If
            ' Return results.
            GetProcessParent = GetProcessFileName(m_ParentProcessID)
         End If

      Else
         ' Use the documented methods...
         ' Make sure we have the needed function.
         hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0&)
         If hSnap Then
            ProcEntry.dwSize = Len(ProcEntry)

            ' Iterate through the processes once to find the parent:
            If Process32First(hSnap, ProcEntry) Then
               Do
                  If ProcEntry.th32ProcessID = ProcessID Then
                     ' This is us.  Get the parent ID:
                     m_ParentProcessID = ProcEntry.th32ParentProcessID
                     Exit Do
                  End If
               Loop While Process32Next(hSnap, ProcEntry)
            End If

            ' Now get the parent name.
            If os.dwPlatformId = VER_PLATFORM_WIN32_NT Then
               ' Newer NT version toolhelp libraries do not
               ' provide path information, so it's better to
               ' use GetModuleFileNameEx for max info.
               GetProcessParent = GetProcessFileName(m_ParentProcessID)
            Else
               ' In Win9x versions, iterate the process snapshot. Again.
               If Process32First(hSnap, ProcEntry) Then
                  Do
                     If ProcEntry.th32ProcessID = m_ParentProcessID Then
                        ' This is the parent process -- get its filename.
                        GetProcessParent = TrimNull(ProcEntry.szExeFile)
                        Exit Do
                     End If
                  Loop While Process32Next(hSnap, ProcEntry)
               End If
            End If

         End If
      End If
   End Function

--
..NET: It's About Trust!
http://vfred.mvps.org
Author
17 Mar 2009 6:22 AM
Eduardo
"Karl E. Peterson" <k***@mvps.org> escribió en el mensaje
news:O3yal$ppJHA.1184@TK2MSFTNGP04.phx.gbl...
> SupaFly wrote:
>> Basically, I want to try and find out which EXE (or Process ID?) launched
>> my
>> EXE when using CreateProcess(), or in other words, the "parent" process
>> that
>> started the EXE I'm in.
>
> Here's a snippet similar to the other one offered, but it covers a few
> more oddball situations (in the VB IDE or NT4).  It was taken from
> http://vb.mvps.org/samples/Console - indented to highlight wordwrap...
[...]

Hi, I tested it but it always return the current process exe (in IDE and
compiled, Win XP SP2).
Author
17 Mar 2009 5:29 PM
Karl E. Peterson
Eduardo wrote:
> "Karl E. Peterson" <k***@mvps.org> escribió en el mensaje...
>> SupaFly wrote:
>>> Basically, I want to try and find out which EXE (or Process ID?) launched
>>> my EXE when using CreateProcess(), or in other words, the "parent" process
>>> that started the EXE I'm in.
>>
>> Here's a snippet similar to the other one offered, but it covers a few
>> more oddball situations (in the VB IDE or NT4).  It was taken from
>> http://vb.mvps.org/samples/Console - indented to highlight wordwrap... [...]
>
> Hi, I tested it but it always return the current process exe (in IDE and
> compiled, Win XP SP2).

Take a look at the Startup.VBP project that comes with that sample.  It's able to
distinguish whether the EXE was started in Explorer (with a double-click), at the
command line, or from within the VB IDE.  It does that by querying the LaunchMode
property of the Con class:

   Public Property Get LaunchMode() As ConsoleLaunchModes
      ' *** Added at v1.01 (entire routine) ***
      ' Assumes parent name is found at Initialize.
      Dim ParentName As String
      Const OldAppMod As String = "winoa386.mod"

      ' On "advanced" operating systems, console apps will
      ' always be running under the process shown in
      ' %COMSPEC%, but on early 9x systems they'll be
      ' running under WINOA386.MOD
      ParentName = LCase$(m_ParentFilename)
      If Len(m_ParentFilename) Then
         If m_Compiled = False Then
            ' Running under the VB IDE.
            LaunchMode = conLaunchVBIDE

         ElseIf (LCase$(Environ("Comspec")) = ParentName) Then
            ' Ex: C:\WINNT\system32\cmd.exe
            LaunchMode = conLaunchConsole

         ElseIf (InStr(ParentName, OldAppMod) = (Len(ParentName) - Len(OldAppMod) +
1)) Then
            ' Ex: C:\WINDOWS\SYSTEM\WINOA386.MOD
            LaunchMode = conLaunchConsole

         Else
            ' Ex: C:\WINNT\Explorer.EXE
            LaunchMode = conLaunchExplorer

         End If
      Else
         ' This could happen in NT 3.51 and earlier,
         ' if PSAPI.DLL is not present.
         LaunchMode = conLaunchUnknown

      End If
   End Property

It's involved, but I think this demo shows that it does indeed work.
--
..NET: It's About Trust!
http://vfred.mvps.org

Bookmark and Share