2 K to enumerate the process by reading the Registry's performance metrics

Source: Internet
Author: User
Obtain local/remote system process information from PDH

The preceding three methods can only enumerate local system processes. How can we enumerate remote system processes? Currently, I only know how to obtain process information from PDH.

OK! Let me briefly talk about What PDH is, Hoho ~ It's not difficult. PDH is short for performance data helper. Windows NT has been updating this database called performance data, which contains a lot of information, such as CPU usage, memory usage, a lot of useful information such as system process information can be accessed through registry functions. Note that this database is not configured in Windows 9X. However, the information layout in this database is very complex, and many people do not want to use it, including me. In addition, at the beginning, it did not have its own specific functions and can only be operated through the existing registry functions. Later, to make the database easy to use, Ms developed a set of performance data helper functions, which are included in the PDH. dll file.

Windows 2000 allows remote registry operations by default, so we can obtain the required system process information from its PDH by connecting to the registry of the remote system, of course, this requires the admin permission of the remote system.

OK! The following example uses the registry function to retrieve the required data from the local/remote PDH database. We did not use the pdh api.

The program code is as follows:

/*************************************** ***********************************

Module: PS. c

Author: mikeblas@nwlink.com

Modify: ey4s

Http: // www.ey4s.org

Date: 2001/6/23

**************************************** **********************************/

# Include

# Include

# Include

# Define initial_size 51200

# Define extend_size 12800

# 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"

# Define maxprocessnum 52 // maximum number of processes

# Pragma comment (Lib, "MIP. lib ")

Typedef struct processinfo

{

Char processname [128];

DWORD dwprocessid;

} PI;

Void banner ();

Int connipc (char *, char *, char *);

DWORD getprocessinfo (pI *, char *);

Int main (INT argc, char ** argv)

{

Int I, iret;

Pi tasklist [maxprocessnum];

Banner ();

If (argc = 1)

{

Iret = getprocessinfo (tasklist, null );

Printf ("/nprocess info for [local]:");

}

Else if (argc = 4)

{

Iret = getprocessinfo (tasklist, argv [1], argv [2], argv [3]);

Printf ("/nprocess info for [% s]:", argv [1]);

}

Else

{

Printf ("/nusage: % s ", Argv [0]);

Return 1;

}

If (iret> 0)

For (I = 0, printf ("/nprocessname processid ");

I
Printf ("/n %-20 S % d", tasklist [I]. processname, tasklist [I]. dwprocessid), I ++ );

Return 0;

}

DWORD getprocessinfo (pI * prolist, char * IP, char * user, char * pass)

{

Dword rc, dwtype, dwsize, I, dwprocessidtitle, dwprocessidcounter, dwret =-1;

Hkey hkeynames;

Lpstr Buf = NULL, P, P2;

Char szsubkey [1024], szprocessname [max_path];

Pperf_data_block pperf;

Pperf_object_type pobj;

Pperf_instance_definition pinst;

Pperf_counter_block pcounter;

Pperf_counter_definition pcounterdef;

Hkey ghperfkey = NULL, // get perf data from this key

Ghmachinekey = NULL; // get Title Index from this key

Bool bremote = false;

// Look for the list of counters. Always use the neutral

// English version, regardless of the local language. We

// Are looking for some special 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.

_ Try

{

If (IP) & (User) & (PASS ))

{

If (connipc (IP, user, pass )! = 0)

{

Printf ("/nconnect to % s failed.", ip );

_ Leave;

}

Else

Bremote = true;

}

// Connect to the local or remote registry

If (regconnectregistry (IP, hkey_performance_data,

& Ghperfkey )! = Error_success)

{

Printf ("/nregconnectregistry () 1 failed: % d", getlasterror ());

_ Leave;

}

'If (regconnectregistry (IP, HKEY_LOCAL_MACHINE, & ghmachinekey )! = Error_success)

{

Printf ("/nregconnectregistry () 2 failed: % d", getlasterror ());

_ Leave;

}

Sprintf (szsubkey, "% S // % 03x", regkey_perf, makelangid (lang_english, sublang_neutral ));

If (regopenkeyex (ghmachinekey, szsubkey, 0, key_read, & hkeynames )! = Error_success)

_ Leave;

// Obtain the required buffer size from counter names

If (regqueryvalueex (hkeynames, regsubkey_counters, null, & dwtype, null, & dwsize )! = Error_success)

_ Leave;

// Allocate memory

Buf = (lpstr) malloc (dwsize );

If (BUF = NULL)

_ Leave;

Memset (BUF, 0, dwsize );

// Read the counter names from the Registry

If (regqueryvalueex (ghperfkey, regsubkey_counters, null, & dwtype, (lpbyte) BUF, & dwsize )! = Error_success)

_ Leave;

// 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

// 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 = (lpstr) malloc (dwsize );

While (true)

{

If (BUF = NULL)

_ Leave;

Memset (BUF, 0, dwsize );

Rc = regqueryvalueex (ghperfkey, szsubkey, null, & dwtype, (lpbyte) 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 = (lpstr) realloc (BUF, dwsize );

}

Else _ leave;

}

// 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 ++;

}

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 <(DWORD) pobj-> NumInstances-1 & 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 we cant convert the string then use a default value

If (! RC) strcpy (prolist [I]. processname, unknown_task );

Else strncpy (prolist [I]. processname, szprocessname, sizeof (prolist [I]. processname)-1 );

// Get the process ID

Pcounter = (pperf_counter_block) (DWORD) pinst + pinst-> bytelength );

Prolist [I]. dwprocessid = * (lpdword) (DWORD) pcounter + dwprocessidcounter ));

// Next process

Pinst = (pperf_instance_definition) (DWORD) pcounter + pcounter-> bytelength );

}

Dwret = I;

} // End of try

_ Finally

{

If (BUF) Free (BUF );

Regclosekey (hkeynames );

Regclosekey (hkey_performance_data );

If (bremote)

{

Char TMP [52], tmp2 [96];

Strncpy (TMP, IP, sizeof (TMP)-1 );

Wsprintf (tmp2, "/// % S // IPC $", TMP );

Wnetcancelconnection2 (tmp2, connect_update_profile, true );

}

}

Return dwret;

}

//////////////////////////////////////// ////////////////////////////////////////

Int connipc (char * remotename, char * user, char * pass)

{

Netresource NR;

Char rn [50] = "////";

Strncat (RN, remotename, sizeof (RN)-11 );

Strcat (RN, "// IPC $ ");

Nr. dwtype = resourcetype_any;

Nr. lplocalname = NULL;

Nr. lpremotename = rn;

Nr. lpprovider = NULL;

If (wnetaddconnection2 (& NR, pass, user, false) = no_error)

Return 0;

Else

Return 1;

}

//////////////////////////////////////// ////////////////////////////////////////

Void banner ()

{

Printf ("/npslist ==> local and remote process list"

"/Npower by ey4s"

"/Nhttp: // www.ey4s.org"

"/N2001/6/22/N ");

}

//////////////////////////////////////// ////////////////////////////////////////

The program is compiled and runs well in Windows 6.0 and VC ++ environments. Note: the remote machine must allow IPC connection and remote registry operation, and the admin permission is required.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.