[2 days left] What’s wrong with your cloud strategy? Learn why multicloud solutions matter with Nimble Storage.Register Now

x
?
Solved

How do i get the file path of a running process in Windows NT.

Posted on 2001-08-03
5
Medium Priority
?
1,316 Views
Last Modified: 2013-12-03
Hello,

How do i get the file path of a running process in Windows NT.
Following is the code to get names of processes running in NT system, which
i got from MSDN.
Is it possible to get Process file path by modifiying following code ?

-------------------------------------------------------
// #define INITIAL_SIZE        51200
#define EXTEND_SIZE         25600
#define REGKEY_PERF         "software\\microsoft\\windows
nt\\currentversion\\perflib"
#define REGSUBKEY_COUNTERS  "Counters"
#define PROCESS_COUNTER     "process"
#define PROCESSID_COUNTER   "id process"
#define UNKNOWN_TASK        "unknown"

DWORD
GetTaskListNT(
PTASK_LIST pTask,
DWORD dwNumTasks
)

/*++

Routine Description:

Provides an API for getting a list of tasks running at the time of the
API call. This function uses the registry performance data to get the
task list and is therefore straight WIN32 calls that anyone can call.

Arguments:

dwNumTasks - maximum number of tasks that the pTask array can hold

Return Value:

Number of tasks placed into the pTask array.

--*/

{
DWORD rc;
HKEY hKeyNames;
DWORD dwType;
DWORD dwSize;
LPBYTE buf = NULL;
CHAR szSubKey[1024];
LANGID lid;
LPSTR p;
LPSTR p2;
PPERF_DATA_BLOCK pPerf;
PPERF_OBJECT_TYPE pObj;
PPERF_INSTANCE_DEFINITION pInst;
PPERF_COUNTER_BLOCK pCounter;
PPERF_COUNTER_DEFINITION pCounterDef;
DWORD i;
DWORD dwProcessIdTitle;
DWORD dwProcessIdCounter;
CHAR szProcessName[MAX_PATH];
DWORD dwLimit = dwNumTasks - 1;



//
// Look for the list of counters. Always use the neutral
// English version, regardless of the local language. We
// are looking for some particular keys, and we are always
// going to do our looking in English. We are not going
// to show the user the counter names, so there is no need
// to go find the corresponding name in the local language.
//
lid = MAKELANGID( LANG_ENGLISH, SUBLANG_NEUTRAL );
sprintf( szSubKey, "%s\\%03x", REGKEY_PERF, lid );
rc = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
szSubKey,
0,
KEY_READ,
&hKeyNames
);
if (rc != ERROR_SUCCESS) {
goto exit;
}

//
// get the buffer size for the counter names
//
rc = RegQueryValueEx( hKeyNames,
REGSUBKEY_COUNTERS,
NULL,
&dwType,
NULL,
&dwSize
);

if (rc != ERROR_SUCCESS) {
goto exit;
}

//
// allocate the counter names buffer
//
buf = (LPBYTE) malloc( dwSize );
if (buf == NULL) {
goto exit;
}
memset( buf, 0, dwSize );

//
// read the counter names from the registry
//
rc = RegQueryValueEx( hKeyNames,
REGSUBKEY_COUNTERS,
NULL,
&dwType,
buf,
&dwSize
);

if (rc != ERROR_SUCCESS) {
goto exit;
}

//
// now loop thru the counter names looking for the following counters:
//
// 1. "Process" process name
// 2. "ID Process" process id
//
// the buffer contains multiple null terminated strings and then
// finally null terminated at the end. the strings are in pairs of
// counter number and counter name.
//

p = buf;
while (*p) {
if (p > buf) {
for( p2=p-2; isdigit(*p2); p2--) ;
}
if (stricmp(p, PROCESS_COUNTER) == 0) {
//
// look backwards for the counter number
//
for( p2=p-2; isdigit(*p2); p2--) ;
strcpy( szSubKey, p2+1 );
}
else
if (stricmp(p, PROCESSID_COUNTER) == 0) {
//
// look backwards for the counter number
//
for( p2=p-2; isdigit(*p2); p2--) ;
dwProcessIdTitle = atol( p2+1 );
}
//
// next string
//
p += (strlen(p) + 1);
}

//
// free the counter names buffer
//
free( buf );


//
// allocate the initial buffer for the performance data
//
dwSize = INITIAL_SIZE;
buf = malloc( dwSize );
if (buf == NULL) {
goto exit;
}
memset( buf, 0, dwSize );


while (TRUE) {

rc = RegQueryValueEx( HKEY_PERFORMANCE_DATA,
szSubKey,
NULL,
&dwType,
buf,
&dwSize
);

pPerf = (PPERF_DATA_BLOCK) buf;

//
// check for success and valid perf data block signature
//
if ((rc == ERROR_SUCCESS) &&
(dwSize > 0) &&
(pPerf)->Signature[0] == (WCHAR)'P' &&
(pPerf)->Signature[1] == (WCHAR)'E' &&
(pPerf)->Signature[2] == (WCHAR)'R' &&
(pPerf)->Signature[3] == (WCHAR)'F' ) {
break;
}

//
// if buffer is not big enough, reallocate and try again
//
if (rc == ERROR_MORE_DATA) {
dwSize += EXTEND_SIZE;
buf = realloc( buf, dwSize );
memset( buf, 0, dwSize );
}
else {
goto exit;
}
}

//
// set the perf_object_type pointer
//
pObj = (PPERF_OBJECT_TYPE) ((DWORD)pPerf + pPerf->HeaderLength);

//
// loop thru the performance counter definition records looking
// for the process id counter and then save its offset
//
pCounterDef = (PPERF_COUNTER_DEFINITION) ((DWORD)pObj + pObj->HeaderLength);
for (i=0; i<(DWORD)pObj->NumCounters; i++) {
if (pCounterDef->CounterNameTitleIndex == dwProcessIdTitle) {
dwProcessIdCounter = pCounterDef->CounterOffset;
break;
}
pCounterDef++;
}

dwNumTasks = min( dwLimit, (DWORD)pObj->NumInstances );

pInst = (PPERF_INSTANCE_DEFINITION) ((DWORD)pObj + pObj->DefinitionLength);

//
// loop thru the performance instance data extracting each process name
// and process id
//
for (i=0; i<dwNumTasks; i++) {
//
// pointer to the process name
//
p = (LPSTR) ((DWORD)pInst + pInst->NameOffset);

//
// convert it to ascii
//
rc = WideCharToMultiByte( CP_ACP,
0,
(LPCWSTR)p,
-1,
szProcessName,
sizeof(szProcessName),
NULL,
NULL
);

if (!rc) {
//
// if we cant convert the string then use a default value
//
strcpy( pTask->ProcessName, UNKNOWN_TASK );
}

if (strlen(szProcessName)+4 <= sizeof(pTask->ProcessName)) {
strcpy( pTask->ProcessName, szProcessName );
strcat( pTask->ProcessName, ".exe" );
}

//
// get the process id
//
pCounter = (PPERF_COUNTER_BLOCK) ((DWORD)pInst + pInst->ByteLength);
pTask->flags = 0;
pTask->dwProcessId = *((LPDWORD) ((DWORD)pCounter + dwProcessIdCounter));
if (pTask->dwProcessId == 0) {
pTask->dwProcessId = (DWORD)-2;
}

//
// next process
//
pTask++;
pInst = (PPERF_INSTANCE_DEFINITION) ((DWORD)pCounter +
pCounter->ByteLength);
}

exit:
if (buf) {
free( buf );
}

RegCloseKey( hKeyNames );
RegCloseKey( HKEY_PERFORMANCE_DATA );

return dwNumTasks;
}
-------------------------------------------------------


Thanx,

Nagaraj





0
Comment
Question by:Nagarajhr
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 2
  • 2
5 Comments
 
LVL 15

Expert Comment

by:NickRepin
ID: 6351003
HOWTO: Enumerate Applications in Win32
http://support.microsoft.com/support/kb/articles/Q175/0/30.ASP

<<the PSAPI.DLL also contains a variety of useful functions. .... EnumProcesses(), EnumProcessModules(), GetModuleFileNameEx(), GetModuleBaseName()
EnumProcesses()

......

Now you have an array with each process ID in the system. If your goal is to get the name of the process, then you must first get a handle. To get a handle from a process ID, use OpenProcess().

....

To get the first module of a process call the EnumProcessModules()

....

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. Now you can use the hModule with the GetModuleFileNameEx(), GetModuleBaseName() to get the full path name, or the simple module name for the process executable.

....

By repeating this for each process ID returned with the EnumProcesses(),you create a list of processes under Windows NT.

>>
0
 

Author Comment

by:Nagarajhr
ID: 6351138
Thank you Mr. NickRepin,

I will check it in my code and reply in another two days.

But i want to know that is it possible to get process file path ( i.e. complete file path of a process in hard disk as C:\WinNT\...\..EXE ) with the help of Process ID or Process name without using PSAPI functions. Because PSAPI functions requires PSAPI DLL, which is not included  in Windows NT ( ver.4 ) system DLLs.
0
 
LVL 15

Accepted Solution

by:
NickRepin earned 600 total points
ID: 6351149
You can re-distribute PSAPI DLL with your application, in case of NT4 prior to Service Pack XXX (sorry, cannot recall the exact number).
0
 
LVL 20

Expert Comment

by:Madshi
ID: 6354946
Both NT4 and Win2k only give you the executable *names*, not the *paths*, when using the performance counters, or when using the undocumented NtGetSystemInformation, or when using the toolhelp functions (Win2k).
The only way of getting the full paths is to either use PsApi.dll (as Nick already pointed out), or doing exactly what PsApi.dll does internally. You can reverse engineer PsApi.dll, it's no big problem (I've done that already).

Regards, Madshi.
0
 

Author Comment

by:Nagarajhr
ID: 6355050
Thank you for your suggestions.

Nagaraj
0

Featured Post

On Demand Webinar - Networking for the Cloud Era

This webinar discusses:
-Common barriers companies experience when moving to the cloud
-How SD-WAN changes the way we look at networks
-Best practices customers should employ moving forward with cloud migration
-What happens behind the scenes of SteelConnect’s one-click button

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

In this article, I will show how to use the Ribbon IDs Tool Window to assign the built-in Office icons to a ribbon button.  This tool will help us to find the OfficeImageId that corresponds to our desired built-in Office icon. The tool is part of…
For most people, the WrapPanel seems like a magic when they switch from WinForms to WPF. Most of us will think that the code that is used to write a control like that would be difficult. However, most of the work is done by the WPF engine, and the W…
This is Part 3 in a 3-part series on Experts Exchange to discuss error handling in VBA code written for Excel. Part 1 of this series discussed basic error handling code using VBA. http://www.experts-exchange.com/videos/1478/Excel-Error-Handlin…
Video by: ITPro.TV
In this episode Don builds upon the troubleshooting techniques by demonstrating how to properly monitor a vSphere deployment to detect problems before they occur. He begins the show using tools found within the vSphere suite as ends the show demonst…

649 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