Process Path

Hello there!

I’m writing a device driver under Windows NT and I need to get the
full path for the executable file of a process given its process id.
Anyone know how to do that? I’ve traced the execution of GetModuleFileName in Kernel32.dll but I din’t find anything interesting, this function doesn’t seem to relay on kernel-mode subsystems. Any hint will be welcome.

Thanks in advance


You are currently subscribed to ntfsd as: $subst(‘Recip.EmailAddr’)
To unsubscribe send a blank email to leave-ntfsd-$subst(‘Recip.MemberIDChar’)@lists.osr.com

Well, it seems that this list filters e-mail with attachments (or is it just
.cpp extension that you, guys, filter? :wink:

So, here is a code that I use in my system:

#include “C:\Program Files\Microsoft Platform SDK\Include\psapi.h”

BOOL GetProcessPathFromKMProcID( DWORD dwKMProcID, CString& aProcModulePath)
{
HANDLE hProcess = NULL;
HMODULE* pModules = NULL;
BOOL bRet = FALSE;

try
{
aProcModulePath = _T(“Not Available”);

hProcess = OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
FALSE, (DWORD)dwKMProcID );

if( hProcess )
{
DWORD dwSize = 10240*sizeof(HMODULE); // Don’t bother with actual proc.
number

pModules = new HMODULE[dwSize/sizeof(HMODULE)];

if( EnumProcessModules( hProcess, pModules, dwSize, &dwSize ) )
{
dwSize /= sizeof(HMODULE);

for( DWORD nMod = 0; nMod < dwSize; nMod++ )
{
TCHAR szModPath[MAX_PATH+1];

if( GetModuleFileNameEx( hProcess, pModules[nMod], szModPath,
sizeof(szModPath)/sizeof(TCHAR)) )
{
//
// Not sure it’s the right way, but works for me se far!
//

LPCTSTR pszExtension = GetFileExtension( szModPath );

if( !lstrcmpi( pszExtension, _T(“EXE”)) ||
!lstrcmpi( pszExtension, _T(“COM”)) ||
!lstrcmpi( pszExtension, _T(“CMD”)) )
{
aProcModulePath = szModPath;
bRet = TRUE;
break;
}
}
}
}
}
}
catch( … )
{
bRet = FALSE;
}

if( pModules )
{
delete pModules;
}

if( hProcess )
{
CloseHandle(hProcess);
}

return bRet;
}

-----Original Message-----
From: Francisco Avila Gonz?lez [mailto:xxxxx@seg.inf.cu]
Sent: Tuesday, April 03, 2001 7:45 AM
To: File Systems Developers
Subject: [ntfsd] Process Path

Hello there!

I’m writing a device driver under Windows NT and I need to get the
full path for the executable file of a process given its process id.
Anyone know how to do that? I’ve traced the execution of GetModuleFileName
in Kernel32.dll but I din’t find anything interesting, this function doesn’t
seem to relay on kernel-mode subsystems. Any hint will be welcome.

Thanks in advance

You are currently subscribed to ntfsd as: xxxxx@Starbase.com
To unsubscribe send a blank email to leave-ntfsd-$subst(‘Recip.MemberIDChar’)@lists.osr.com


You are currently subscribed to ntfsd as: $subst(‘Recip.EmailAddr’)
To unsubscribe send a blank email to leave-ntfsd-$subst(‘Recip.MemberIDChar’)@lists.osr.com

you cannot count on this working as there are many cases under which you
will never get the name. this has been a constant problem for debuggers and
they have played many tricks to work around this. i do believe that this is
much better on whistler, but on win2k you’ll have to work a lot harder.

-----Original Message-----
From: Chtchetkine, Vladimir [mailto:xxxxx@Starbase.com]
Sent: Tuesday, April 03, 2001 11:15 AM
To: File Systems Developers
Subject: [ntfsd] RE: Process Path

Well, it seems that this list filters e-mail with attachments (or is it just
.cpp extension that you, guys, filter? :wink:

So, here is a code that I use in my system:

#include “C:\Program Files\Microsoft Platform SDK\Include\psapi.h”

BOOL GetProcessPathFromKMProcID( DWORD dwKMProcID, CString& aProcModulePath)
{
HANDLE hProcess = NULL;
HMODULE* pModules = NULL;
BOOL bRet = FALSE;

try
{
aProcModulePath = _T(“Not Available”);

hProcess = OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
FALSE, (DWORD)dwKMProcID );

if( hProcess )
{
DWORD dwSize = 10240*sizeof(HMODULE); // Don’t bother with actual proc.
number

pModules = new HMODULE[dwSize/sizeof(HMODULE)];

if( EnumProcessModules( hProcess, pModules, dwSize, &dwSize ) )
{
dwSize /= sizeof(HMODULE);

for( DWORD nMod = 0; nMod < dwSize; nMod++ )
{
TCHAR szModPath[MAX_PATH+1];

if( GetModuleFileNameEx( hProcess, pModules[nMod], szModPath,
sizeof(szModPath)/sizeof(TCHAR)) )
{
//
// Not sure it’s the right way, but works for me se far!
//

LPCTSTR pszExtension = GetFileExtension( szModPath );

if( !lstrcmpi( pszExtension, _T(“EXE”)) ||
!lstrcmpi( pszExtension, _T(“COM”)) ||
!lstrcmpi( pszExtension, _T(“CMD”)) )
{
aProcModulePath = szModPath;
bRet = TRUE;
break;
}
}
}
}
}
}
catch( … )
{
bRet = FALSE;
}

if( pModules )
{
delete pModules;
}

if( hProcess )
{
CloseHandle(hProcess);
}

return bRet;
}

-----Original Message-----
From: Francisco Avila Gonz?lez [mailto:xxxxx@seg.inf.cu]
Sent: Tuesday, April 03, 2001 7:45 AM
To: File Systems Developers
Subject: [ntfsd] Process Path

Hello there!

I’m writing a device driver under Windows NT and I need to get the
full path for the executable file of a process given its process id.
Anyone know how to do that? I’ve traced the execution of GetModuleFileName
in Kernel32.dll but I din’t find anything interesting, this function doesn’t
seem to relay on kernel-mode subsystems. Any hint will be welcome.

Thanks in advance

You are currently subscribed to ntfsd as: xxxxx@Starbase.com
To unsubscribe send a blank email to leave-ntfsd-$subst(‘Recip.MemberIDChar’)@lists.osr.com


You are currently subscribed to ntfsd as: xxxxx@veritas.com
To unsubscribe send a blank email to leave-ntfsd-$subst(‘Recip.MemberIDChar’)@lists.osr.com


You are currently subscribed to ntfsd as: $subst(‘Recip.EmailAddr’)
To unsubscribe send a blank email to leave-ntfsd-$subst(‘Recip.MemberIDChar’)@lists.osr.com

Can you give some “demos” when it’s not going to work? It was working just
fine (well, for me) on W2K and, as I can recall, on NT. So, I started to
worry :slight_smile:

Vladimir

-----Original Message-----
From: Wesley Witt [mailto:xxxxx@veritas.com]
Sent: Tuesday, April 03, 2001 11:35 AM
To: File Systems Developers
Subject: [ntfsd] RE: Process Path

you cannot count on this working as there are many cases under which you
will never get the name. this has been a constant problem for debuggers and
they have played many tricks to work around this. i do believe that this is
much better on whistler, but on win2k you’ll have to work a lot harder.

-----Original Message-----
From: Chtchetkine, Vladimir [mailto:xxxxx@Starbase.com]
Sent: Tuesday, April 03, 2001 11:15 AM
To: File Systems Developers
Subject: [ntfsd] RE: Process Path

Well, it seems that this list filters e-mail with attachments (or is it just
.cpp extension that you, guys, filter? :wink:

So, here is a code that I use in my system:

#include “C:\Program Files\Microsoft Platform SDK\Include\psapi.h”

BOOL GetProcessPathFromKMProcID( DWORD dwKMProcID, CString& aProcModulePath)
{
HANDLE hProcess = NULL;
HMODULE* pModules = NULL;
BOOL bRet = FALSE;

try
{
aProcModulePath = _T(“Not Available”);

hProcess = OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
FALSE, (DWORD)dwKMProcID );

if( hProcess )
{
DWORD dwSize = 10240*sizeof(HMODULE); // Don’t bother with actual proc.
number

pModules = new HMODULE[dwSize/sizeof(HMODULE)];

if( EnumProcessModules( hProcess, pModules, dwSize, &dwSize ) )
{
dwSize /= sizeof(HMODULE);

for( DWORD nMod = 0; nMod < dwSize; nMod++ )
{
TCHAR szModPath[MAX_PATH+1];

if( GetModuleFileNameEx( hProcess, pModules[nMod], szModPath,
sizeof(szModPath)/sizeof(TCHAR)) )
{
//
// Not sure it’s the right way, but works for me se far!
//

LPCTSTR pszExtension = GetFileExtension( szModPath );

if( !lstrcmpi( pszExtension, _T(“EXE”)) ||
!lstrcmpi( pszExtension, _T(“COM”)) ||
!lstrcmpi( pszExtension, _T(“CMD”)) )
{
aProcModulePath = szModPath;
bRet = TRUE;
break;
}
}
}
}
}
}
catch( … )
{
bRet = FALSE;
}

if( pModules )
{
delete pModules;
}

if( hProcess )
{
CloseHandle(hProcess);
}

return bRet;
}

-----Original Message-----
From: Francisco Avila Gonz?lez [mailto:xxxxx@seg.inf.cu]
Sent: Tuesday, April 03, 2001 7:45 AM
To: File Systems Developers
Subject: [ntfsd] Process Path

Hello there!

I’m writing a device driver under Windows NT and I need to get the
full path for the executable file of a process given its process id.
Anyone know how to do that? I’ve traced the execution of GetModuleFileName
in Kernel32.dll but I din’t find anything interesting, this function doesn’t
seem to relay on kernel-mode subsystems. Any hint will be welcome.

Thanks in advance

You are currently subscribed to ntfsd as: xxxxx@Starbase.com
To unsubscribe send a blank email to leave-ntfsd-$subst(‘Recip.MemberIDChar’)@lists.osr.com


You are currently subscribed to ntfsd as: xxxxx@veritas.com
To unsubscribe send a blank email to leave-ntfsd-$subst(‘Recip.MemberIDChar’)@lists.osr.com


You are currently subscribed to ntfsd as: xxxxx@Starbase.com
To unsubscribe send a blank email to leave-ntfsd-$subst(‘Recip.MemberIDChar’)@lists.osr.com


You are currently subscribed to ntfsd as: $subst(‘Recip.EmailAddr’)
To unsubscribe send a blank email to leave-ntfsd-$subst(‘Recip.MemberIDChar’)@lists.osr.com

>> if( !lstrcmpi( pszExtension, _T(“EXE”)) ||

> !lstrcmpi( pszExtension, _T(“COM”)) ||
> !lstrcmpi( pszExtension, _T(“CMD”)) )

Vladimir,

I can think of two cases where you might have trouble. The first is where the file used to create the process has been renamed and is no longer an EXE file. You can pass anything you like into CreateProcess!

The second is where someone has done a LoadLibrary on an EXE in order to extract resources.

In one case, there may be no .EXE files loaded in your process; in the other, there may be several. A combination of the two could result in you getting a single EXE back which is the wrong file!

I’m also surprised you check for .CMD files. I haven’t tried this, but I would have expected .CMD files, like .BAT files, to be executed as if the active EXE were cmd.exe.

If you look at http://support.microsoft.com/support/kb/articles/Q175/0/30.ASP you’ll find that it says

“Once you have a handle you will need to get the “first” module of the process. To get the first module of a process call the EnumProcessModules() API with the following parameters:
EnumProcessModules( hProcess, &hModule, sizeof(hModule), &cbReturned );
This will put the handle of the first module of the process in the hModule variable. Remember that a process doesn’t really have a name, but that the first module in the process is going to be the executable of the process.”

Rgds

Andy


Get your free email from AltaVista at http://altavista.iname.com


You are currently subscribed to ntfsd as: $subst(‘Recip.EmailAddr’)
To unsubscribe send a blank email to leave-ntfsd-$subst(‘Recip.MemberIDChar’)@lists.osr.com