是Win98下还是WinNT下?在这转贴两篇陆大侠的文章吧:
不过9x版的现在有所不同了,因为CreateToolhelp32Snapshot函数已经不是未公开函数了(#include<tlhelp32.h>),查MSDN就可以查到,所以前面GetProcAddress都可以去掉,直接调用就可以了。
/////////////////////////////////////////////////////////////////////////////
历遍进程(9X版) 
作者:陆麟 
转载请征得作者同意. 
2000.6.7 
--------------------------------------------------------------------------------一直有人写MAIL.如何历遍进程.很显然,NT和9X是不同的. 
OS支持的接口为:9X:TOOLHELP32,NT:PSAPI,2000:BOTH TOOLHELP AND PSAPI. 
这几天就写个DEMO上来.大家看看关键的部分吧.等写完了.编译好的版本放在UTILITYS栏里.这里不贴完整的代码.但是可以看到核心部分.而且看本例程可以看到VC的TRY,FINALLY的用法. 
多谢观赏.:) 
/*+++ 
9xProcessInfo.cpp 
Written by Lu Lin 2000.6.2 
Abstract: 
 main programme for enumerateing informations in WIN9X 
---*/ // 
//Headers 
// 
#include <windows.h> 
#include "procex.h" // 
//External vars 
// 
extern char ostype[]; // 
//Func prototype 
// 
typedef HANDLE (WINAPI *_CreateToolhelp32Snapshot) 
     (DWORD dwFlags,DWORD th32ProcessID); 
typedef BOOL (WINAPI *_Process32First) 
     (HANDLE hSnapshot,LPPROCESSENTRY32 lppe); 
typedef BOOL (WINAPI *_Process32Next) 
     (HANDLE hSnapshot,LPPROCESSENTRY32 lppe); 
typedef BOOL (WINAPI *_Module32First) 
     (HANDLE hSnapshot,LPMODULEENTRY32 lpme); 
typedef BOOL (WINAPI *_Module32Next) 
     (HANDLE hSnapshot,LPMODULEENTRY32 lpme); 
typedef BOOL (WINAPI *_Thread32First) 
     (HANDLE hSnapshot,LPTHREADENTRY32 lpte); 
typedef BOOL (WINAPI *_Thread32Next) 
     (HANDLE hSnapshot,LPTHREADENTRY32 lpte); 
  //Global vars 
_CreateToolhelp32Snapshot pCreateToolhelp32Snapshot; 
_Process32First pProcess32First; 
_Process32Next pProcess32Next; 
_Module32First pModule32First; 
_Module32Next pModule32Next; 
_Thread32First pThread32First; 
_Thread32Next pThread32Next; HANDLE h; //handle to snapshoot 
PROCS procs; //Header of PROCESSENTRY32 struct // 
//Init function: get all proc address 
// 
BOOL Init(){ 
 BOOL ret=0; 
 __try{ 
  // 
  //Get the TOOLHELP32 func addresses 
  // 
  pCreateToolhelp32Snapshot=(_CreateToolhelp32Snapshot) 
   GetProcAddress(GetModuleHandle("KERNEL32"), 
   "CreateToolhelp32Snapshot"); 
  pProcess32First=(_Process32First) 
   GetProcAddress(GetModuleHandle("KERNEL32"), 
   "Process32First"); 
  pProcess32Next=(_Process32Next) 
   GetProcAddress(GetModuleHandle("KERNEL32"), 
   "Process32Next"); 
  pModule32First=(_Module32First) 
   GetProcAddress(GetModuleHandle("KERNEL32"), 
   "Module32First"); 
  pModule32Next=(_Module32Next) 
   GetProcAddress(GetModuleHandle("KERNEL32"), 
   "Module32Next"); 
  pThread32First=(_Thread32First) 
   GetProcAddress(GetModuleHandle("KERNEL32"), 
   "Thread32First"); 
  pThread32Next=(_Thread32Next) 
   GetProcAddress(GetModuleHandle("KERNEL32"), 
   "Thread32Next");   if ((!(UINT)pCreateToolhelp32Snapshot)|| 
   (!(UINT)pProcess32First)|| 
   (!(UINT)pProcess32Next)|| 
   (!(UINT)pModule32First)|| 
   (!(UINT)pModule32Next)|| 
   (!(UINT)pThread32First)|| 
   (!(UINT)pThread32Next)){ 
   MessageBox(0, 
    "Can't locate ToolHelp32 functions!", 
    "Error", 
    MB_OK); 
   __leave; 
  }   ZeroMemory(&procs,sizeof(procs)); 
  ret=1; 
 } 
 __finally{ 
  return ret; 
 } 

  // 
//GetModuleInfo gets module information 
// 
BOOL GetModuleInfo(PPROCS p){ 
 HANDLE hm; 
 MODULEENTRY32 me; 
 PMODULES pm; 
 BOOL ret=0; 
 __try{ 
  hm=pCreateToolhelp32Snapshot(TH32CS_SNAPMODULE, 
   p->ProcessEntry32.th32ProcessID); 
  if (hm==(HANDLE)-1){ 
   __leave; 
  } 
  ZeroMemory(&me,sizeof(me)); 
  me.dwSize=sizeof(me); 
  if (!pModule32First(hm,&me)){ 
   __leave; 
  } 
  pm=&p->Modules; 
  pm->ModuleEntry32=me; 
  while (pModule32Next(hm,&me)){ 
   pm->pNextModule=new MODULES; 
   pm=pm->pNextModule; 
   if (!pm){ 
    __leave; 
   } 
   ZeroMemory(pm,sizeof(MODULES)); 
   pm->ModuleEntry32=me; 
  } 
  ret=1; 
 } 
 __finally{ 
  if (hm!=(HANDLE)-1){ 
   CloseHandle(hm); 
  } 
  return ret; 
 } 

  // 
//Win9xProcessInfo enumerates Process 
// 
void Win9xProcessInfo(){ 
 PPROCS p,q; 
 //VAR for storing temp ProcessEntry32 
 PROCESSENTRY32 ProcessEntry32; 
 __try{ 
  if (!Init()){ 
   __leave; 
  }   // 
  //Get primary snapshot of system 
  // 
  h=pCreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0); 
  if (h==(HANDLE)-1){ 
   MessageBox(0, 
    "CreateToolHelp32Snapshot return 0!", 
    "Error", 
    MB_OK); 
   __leave; 
  }   ZeroMemory(&ProcessEntry32,sizeof(ProcessEntry32)); 
  ProcessEntry32.dwSize=sizeof(ProcessEntry32); 
  if (!pProcess32First(h,&ProcessEntry32)){ 
   __leave; 
  }   p=&procs; 
  p->ProcessEntry32=ProcessEntry32; 
  GetModuleInfo(p); 
  while(pProcess32Next(h,&ProcessEntry32)){ 
   p->pNextProc=new PROCS; 
   p=p->pNextProc; 
   if (!p){ 
    __leave; 
   } 
   ZeroMemory(p,sizeof(PROCS)); 
   p->ProcessEntry32=ProcessEntry32; 
   GetModuleInfo(p); 
   }; 
  MessageBox(0,"Done",ostype,MB_OK); 
 } 
 __finally{ 
  PMODULES pma,pmb; 
  if (h!=(HANDLE)-1) CloseHandle(h); 
  p=procs.pNextProc; 
  while (p){ 
   pma=p->Modules.pNextModule; 
   while(pma){ 
    pmb=pma->pNextModule; 
    delete pma; 
    pma=pmb; 
   } 
   q=p->pNextProc; 
   delete p; 
   p=q;   } 
 } 

////////////////////////////////////////////////////////////////////////////////
作者:陆麟 
转载请征得作者同意. 
2000.7.7 
--------------------------------------------------------------------------------话说那NT也有历遍进程的函数,那就是PSAPI.函数为: 
BOOL EnumProcesses( 
  DWORD *lpidProcess,  // array of process identifiers 
  DWORD cb,            // size of array 
  DWORD *cbNeeded      // number of bytes returned 
); 
和 
BOOL EnumProcessModules( 
  HANDLE hProcess,      // handle to process 
  HMODULE *lphModule,   // array of module handles 
  DWORD cb,             // size of array 
  LPDWORD lpcbNeeded    // number of bytes required 
); 
前一函数返回所有进程的ID.而后一函数根据进程句柄来获取该进程的模块句柄数组.这里介绍的乃是另外一种方法.该方法比上述方法速度快很多.就是运用NATIVE API.下面乃是公开的秘密.:)网络上已经有很多关于此函数的论述,该函数查询功能之大,超乎想象,几乎任何系统信息都可以查询,现在披露有关历遍进程的部分.:) 
typedef struct ThreadSysInfo_t { 
 LARGE_INTEGER ThreadKernelTime; 
 LARGE_INTEGER ThreadUserTime; 
 LARGE_INTEGER ThreadCreateTime; 
 ULONG TickCount; 
 ULONG StartEIP; 
 CLIENT_ID ClientId; 
 ULONG DynamicPriority; 
 ULONG BasePriority; 
 ULONG nSwitches; 
 ULONG Unknown; 
 KWAIT_REASON WaitReason; 
}THREADSYSINFO, *PTHREADSYSINFO; typedef struct ProcessThreadSystemInfo { 
 ULONG RelativeOffset; 
 ULONG nThreads; 
 ULONG Unused1[6]; 
 LARGE_INTEGER ProcessCreateTime; 
 LARGE_INTEGER ProcessUserTime; 
 LARGE_INTEGER ProcessKernelTime; 
 UNICODE_STRING ProcessName; 
 ULONG BasePriority; 
 ULONG ProcessId; 
 ULONG ParentProcessId; 
 ULONG HandleCount; 
 ULONG Unused2[2]; 
 ULONG PeakVirtualSizeBytes; 
 ULONG TotalVirtualSizeBytes; 
 ULONG nPageFaults; 
 ULONG PeakWorkingSetSizeBytes; 
 ULONG TotalWorkingSetSizeBytes; 
 ULONG PeakPagedPoolUsagePages; 
 ULONG TotalPagedPoolUsagePages; 
 ULONG PeakNonPagedPoolUsagePages; 
 ULONG TotalNonPagedPoolUsagePages; 
 ULONG TotalPageFileUsageBytes; 
 ULONG PeakPageFileUsageBytes; 
 ULONG TotalPrivateBytes; 
 THREADSYSINFO ThreadSysInfo[1]; 
} PROCESSTHREADSYSTEMINFO, *PPROCESSTHREADSYSTEMINFO; NTSYSAPI 
NTSTATUS 
NTAPI 
NtQuerySystemInformation( 
 IN SYSTEMINFOCLASS SystemInfoClass, //Set to 5 for enumerate all process 
 OUT PVOID SystemInfoBuffer, 
 IN ULONG SystemInfoBufferSize, 
 OUT PULONG BytesReturned OPTIONAL 
); 当然,KMD也可以在PASSIVE LEVEL运用此函数的内核引出: 
NTSYSAPI 
NTSTATUS 
NTAPI 
ZwQuerySystemInformation( 
 IN SYSTEMINFOCLASS SystemInfoClass, //Set to 5 for enumerate all process 
 OUT PVOID SystemInfoBuffer, 
 IN ULONG SystemInfoBufferSize, 
 OUT PULONG BytesReturned OPTIONAL 
); 
妙极否?:)由于查询功能太过强大,此函数必须有SE_TCB_NAME特权才能运作.大家感受到了SE_TCB_NAME特权的吸引人之处了吧!:DDD特权特权我所爱也.;)))