home *** CD-ROM | disk | FTP | other *** search
/ PC World 2004 November / PCWorld_2004-11_cd.bin / software / temacd / poweroff / pwroff30.exe / src / processbrowser.c < prev    next >
C/C++ Source or Header  |  2002-10-16  |  19KB  |  674 lines

  1. #include "poweroff.h"
  2.  
  3. #include <tlhelp32.h>
  4. #include <vdmdbg.h>
  5.  
  6. typedef struct
  7. {
  8.   DWORD          dwPID ;
  9.   PROCENUMPROC   lpProc ;
  10.   DWORD          lParam ;
  11.   BOOL           bEnd ;
  12. } EnumInfoStruct ;
  13.  
  14. typedef PERF_DATA_BLOCK             PERF_DATA,      *PPERF_DATA;
  15. typedef PERF_OBJECT_TYPE            PERF_OBJECT,    *PPERF_OBJECT;
  16. typedef PERF_INSTANCE_DEFINITION    PERF_INSTANCE,  *PPERF_INSTANCE;
  17. typedef PERF_COUNTER_DEFINITION     PERF_COUNTER,   *PPERF_COUNTER;
  18.  
  19.  
  20. // ToolHelp Function Pointers.
  21. HINSTANCE      hInstLib=NULL;
  22. HANDLE (WINAPI *lpfCreateToolhelp32Snapshot)(DWORD,DWORD) ;
  23. BOOL (WINAPI *lpfProcess32First)(HANDLE,LPPROCESSENTRY32) ;
  24. BOOL (WINAPI *lpfProcess32Next)(HANDLE,LPPROCESSENTRY32) ;
  25. BOOL (WINAPI *lpfModule32First)(HANDLE,LPMODULEENTRY32) ;
  26. BOOL (WINAPI *lpfModule32Next)(HANDLE,LPMODULEENTRY32) ;
  27.  
  28. BOOL WINAPI Enum16( DWORD dwThreadId, WORD hMod16, WORD hTask16,
  29.   PSZ pszModName, PSZ pszFileName, LPARAM lpUserDefined ) ;
  30.  
  31. BOOL GetProcessModule (DWORD dwPID, DWORD dwModuleID, 
  32.      LPMODULEENTRY32 lpMe32, DWORD cbMe32) 
  33.     BOOL          bRet        = FALSE; 
  34.     BOOL          bFound      = FALSE; 
  35.     HANDLE        hModuleSnap = NULL; 
  36.     MODULEENTRY32 me32        = {0}; 
  37.  
  38.     // Take a snapshot of all modules in the specified process. 
  39.  
  40.     Log("GetProcessModule start");
  41.     hModuleSnap = lpfCreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwPID); 
  42.     if (hModuleSnap == (HANDLE)-1) 
  43.     {
  44.       Log("CreateToolhelp32Snapshot failed");
  45.       Log("GetProcessModule end");
  46.       return (FALSE); 
  47.     }
  48.  
  49.     // Fill the size of the structure before using it. 
  50.  
  51.     me32.dwSize = sizeof(MODULEENTRY32); 
  52.  
  53.     // Walk the module list of the process, and find the module of 
  54.     // interest. Then copy the information to the buffer pointed 
  55.     // to by lpMe32 so that it can be returned to the caller. 
  56.  
  57.     if (lpfModule32First(hModuleSnap, &me32)) 
  58.     { 
  59.         do 
  60.         { 
  61.             if (me32.th32ModuleID == dwModuleID) 
  62.             { 
  63.                 CopyMemory (lpMe32, &me32, cbMe32); 
  64.                 bFound = TRUE; 
  65.             } 
  66.         } 
  67.         while (!bFound && lpfModule32Next(hModuleSnap, &me32)); 
  68.  
  69.         bRet = bFound;   // if this sets bRet to FALSE, dwModuleID 
  70.                          // no longer exists in specified process 
  71.     } 
  72.     else 
  73.         bRet = FALSE;           // could not walk module list 
  74.  
  75.     // Do not forget to clean up the snapshot object. 
  76.  
  77.     CloseHandle (hModuleSnap); 
  78.  
  79.     Log("GetProcessModule end (bret=%d)",(int)bRet);
  80.     return (bRet); 
  81.  
  82. PPERF_OBJECT FirstObject (PPERF_DATA pData)
  83. {
  84.   Log("FirstObject, pData=%p",pData);
  85.   if (pData)
  86.     return ((PPERF_OBJECT) ((PBYTE) pData + pData->HeaderLength));
  87.   else
  88.     return NULL;
  89. }
  90.  
  91. PPERF_OBJECT NextObject (PPERF_OBJECT pObject)
  92. {
  93.   Log("NextObject, pData=%p",pObject);
  94.   if (pObject)
  95.     return ((PPERF_OBJECT) ((PBYTE) pObject + pObject->TotalByteLength));
  96.   else
  97.     return NULL;
  98. }
  99.  
  100. PPERF_OBJECT FindObject (PPERF_DATA pData, DWORD TitleIndex)
  101. {
  102.   PPERF_OBJECT pObject;
  103.   DWORD        i = 0;
  104.  
  105.   Log("FindObject start");
  106.   if (pObject = FirstObject(pData))
  107.   {
  108.     Log("pData->NumObjectTypes=%d",(int)pData->NumObjectTypes);
  109.     while (i < pData->NumObjectTypes)
  110.     {
  111.       Log("pObject->ObjectNameTitleIndex=%d, TitleIndex=%d",(int)pObject->ObjectNameTitleIndex,(int)TitleIndex);
  112.       if (pObject->ObjectNameTitleIndex == TitleIndex)
  113.       {
  114.         Log("FindObject end, pObject=%p",pObject);
  115.         return pObject;
  116.       }
  117.       pObject = NextObject(pObject);
  118.       i++;
  119.     }
  120.   }
  121.   Log("FindObject end");
  122.   return NULL;
  123. }
  124.  
  125. DWORD GetPerfData(HKEY        hPerfKey,
  126.                   LPTSTR      szObjectIndex,
  127.                   PPERF_DATA  *ppData,
  128.                   DWORD       *pDataSize)
  129. {
  130.   DWORD   DataSize;
  131.   DWORD   dwR;
  132.   DWORD   Type;
  133.  
  134.   Log("GetPerfData start (szObjectIndex=%s,pDataSize=%d)",szObjectIndex,(int)*pDataSize);
  135.   if (!*ppData)
  136.     *ppData = (PPERF_DATA) LocalAlloc (LMEM_FIXED, *pDataSize);
  137.   Log("ppData=%p",*ppData);
  138.  
  139.   do  
  140.   {
  141.     DataSize = *pDataSize;
  142.     dwR = RegQueryValueEx (hPerfKey,
  143.                            szObjectIndex,
  144.                            NULL,
  145.                            &Type,
  146.                            (BYTE *)*ppData,
  147.                            &DataSize);
  148.  
  149.     Log("dwR=%d",(int)dwR);
  150.     if (dwR == ERROR_MORE_DATA)
  151.     {
  152.       LocalFree (*ppData);
  153.       *pDataSize += 1024;
  154.       *ppData = (PPERF_DATA) LocalAlloc (LMEM_FIXED, *pDataSize);
  155.       Log("ppData=%p, size=%d",*ppData,(int)*pDataSize);
  156.     }
  157.  
  158.     if (!*ppData)
  159.     {
  160.       LocalFree (*ppData);
  161.       Log("GetPerfData end (ERROR_NOT_ENOUGH_MEMORY)");
  162.       return ERROR_NOT_ENOUGH_MEMORY;
  163.     }
  164.  
  165.   } while (dwR == ERROR_MORE_DATA);
  166.  
  167.   Log("GetPerfData end (dwR=%d)",(int)dwR);
  168.   return dwR;
  169. }
  170.  
  171.  
  172. PPERF_DATA RefreshPerfData (HKEY        hPerfKey,
  173.                             LPTSTR      szObjectIndex,
  174.                             PPERF_DATA  pData,
  175.                             DWORD       *pDataSize)
  176. {
  177.   Log("RefreshPerfData");
  178.   if (GetPerfData (hPerfKey, szObjectIndex, &pData, pDataSize) == ERROR_SUCCESS)
  179.     return pData;
  180.   else
  181.     return NULL;
  182. }
  183.  
  184. DWORD   GetPerfTitleSz (HKEY    hKeyMachine,
  185.                         HKEY    hKeyPerf,
  186.                         LPTSTR  *TitleBuffer,
  187.                         LPTSTR  *TitleSz[],
  188.                         DWORD   *TitleLastIdx)
  189. {
  190.   HKEY      hKey1;
  191.   HKEY    hKey2;
  192.   DWORD   Type;
  193.   DWORD   DataSize;
  194.   DWORD   dwR;
  195.   DWORD   Len;
  196.   DWORD   Index;
  197.   DWORD   dwTemp;
  198.   BOOL    bNT10;
  199.   LPTSTR  szCounterValueName;
  200.   LPTSTR  szTitle;
  201.  
  202.   Log("GetPerfTitleSz start");
  203.   // Initialize
  204.   //
  205.   hKey1        = NULL;
  206.   hKey2        = NULL;
  207.   *TitleBuffer = NULL;
  208.   *TitleSz     = NULL;
  209.  
  210.   // Open the perflib key to find out the last counter's index and system version.
  211.   //
  212.   dwR = RegOpenKeyEx (hKeyMachine,
  213.                       TEXT("software\\microsoft\\windows nt\\currentversion\\perflib"),
  214.                       0,
  215.                       KEY_READ,
  216.                       &hKey1);
  217.   Log("RegOpenKeyEx: dwR=%d",(int)dwR);
  218.   if (dwR != ERROR_SUCCESS)
  219.       goto done;
  220.  
  221.   // Get the last counter's index so we know how much memory to allocate for TitleSz
  222.   //
  223.   DataSize = sizeof (DWORD);
  224.   dwR = RegQueryValueEx (hKey1, TEXT("Last Counter"), 0, &Type, (LPBYTE)TitleLastIdx, &DataSize);
  225.   Log("RegQueryValueEx(Last Counter): dwR=%d, TitleLastIdx=%d",(int)dwR,(int)*TitleLastIdx);
  226.   if (dwR != ERROR_SUCCESS)
  227.     goto done;
  228.  
  229.  
  230.  
  231.   // Find system version, for system earlier than 1.0a, there's no version value.
  232.   //
  233.   dwR = RegQueryValueEx (hKey1, TEXT("Version"), 0, &Type, (LPBYTE)&dwTemp, &DataSize);
  234.   Log("RegQueryValueEx(Version): dwR=%d, dwTemp=%d",(int)dwR,(int)dwTemp);
  235.  
  236.   if (dwR != ERROR_SUCCESS)
  237.     // unable to read the value, assume NT 1.0
  238.     bNT10 = TRUE;
  239.   else
  240.     // found the value, so, NT 1.0a or later
  241.     bNT10 = FALSE;
  242.  
  243.   // Now, get ready for the counter names and indexes.
  244.   //
  245.   if (bNT10)
  246.   {
  247.     // NT 1.0, so make hKey2 point to ...\perflib\009 and get
  248.     //  the counters from value "Counters"
  249.     //
  250.     szCounterValueName = TEXT("Counters");
  251.     dwR = RegOpenKeyEx (hKeyMachine,
  252.                         TEXT("software\\microsoft\\windows nt\\currentversion\\perflib\\009"),
  253.                         0,
  254.                         KEY_READ,
  255.                         &hKey2);
  256.     Log("RegOpenKeyEx: dwR=%d",(int)dwR);
  257.     if (dwR != ERROR_SUCCESS)
  258.         goto done;
  259.   }
  260.   else
  261.   {
  262.     // NT 1.0a or later.  Get the counters in key HKEY_PERFORMANCE_KEY
  263.     //  and from value "Counter 009"
  264.     //
  265.     szCounterValueName = TEXT("Counter 009");
  266.     hKey2 = hKeyPerf;
  267.   }
  268.  
  269.   // Find out the size of the data.
  270.   //
  271.   dwR = RegQueryValueEx (hKey2, szCounterValueName, 0, &Type, 0, &DataSize);
  272.   Log("RegQueryValueEx(%s): dwR=%d, Type=%d",szCounterValueName,(int)dwR,(int)Type);
  273.   if (dwR != ERROR_SUCCESS)
  274.     goto done;
  275.  
  276.   // Allocate memory
  277.   //
  278.   *TitleBuffer = (LPTSTR)LocalAlloc (LMEM_FIXED, DataSize);
  279.   if (!*TitleBuffer)
  280.   {
  281.     dwR = ERROR_NOT_ENOUGH_MEMORY;
  282.     Log("ERROR_NOT_ENOUGH_MEMORY");
  283.     goto done;
  284.   }
  285.   Log("TitleBuffer=%p",TitleBuffer);
  286.  
  287.   *TitleSz = (LPTSTR *)LocalAlloc (LPTR, (*TitleLastIdx+1) * sizeof (LPTSTR));
  288.   if (!*TitleSz)
  289.   {
  290.     dwR = ERROR_NOT_ENOUGH_MEMORY;
  291.     Log("ERROR_NOT_ENOUGH_MEMORY");
  292.     goto done;
  293.   }
  294.   Log("TitleSz=%p",TitleSz);
  295.  
  296.   // Query the data
  297.   //
  298.   dwR = RegQueryValueEx (hKey2, szCounterValueName, 0, &Type, (BYTE *)*TitleBuffer, &DataSize);
  299.   Log("RegQueryValueEx(%s): dwR=%d, TitleBuffer=%s",szCounterValueName,(int)dwR,*TitleBuffer);
  300.   if (dwR != ERROR_SUCCESS)
  301.     goto done;
  302.  
  303.   // Setup the TitleSz array of pointers to point to beginning of each title string.
  304.   // TitleBuffer is type REG_MULTI_SZ.
  305.   //
  306.   szTitle = *TitleBuffer;
  307.  
  308.   while (Len = lstrlen (szTitle))
  309.   {
  310.     Index = atoi (szTitle);
  311.     Log("Index=%d",(int)Index);
  312.     szTitle = szTitle + Len +1;
  313.  
  314.     Log("Index=%d, *TitleLastIdx=%d",(int)Index,(int)*TitleLastIdx);
  315.     if (Index <= *TitleLastIdx)
  316.     {
  317.       Log("Title=%s",szTitle);
  318.       (*TitleSz)[Index] = szTitle;
  319.     }
  320.     szTitle = szTitle + lstrlen (szTitle) +1;
  321.   }
  322.  
  323. done:
  324.  
  325.   Log("Done");
  326.   // Done. Now cleanup!
  327.   //
  328.   if (dwR != ERROR_SUCCESS)
  329.   {
  330.     // There was an error, free the allocated memory
  331.     //
  332.     if (*TitleBuffer) LocalFree (*TitleBuffer);
  333.     if (*TitleSz)     LocalFree (*TitleSz);
  334.   }
  335.  
  336.   // Close the hKeys.
  337.   //
  338.   if (hKey1) 
  339.     RegCloseKey (hKey1);
  340.   if (hKey2 && hKey2 != hKeyPerf) 
  341.     RegCloseKey (hKey2);
  342.  
  343.   Log("GetPerfTitleSz end");
  344.   return dwR;
  345. }
  346.  
  347.  
  348. DWORD GetTitleIdx(char *name)
  349. {
  350.   DWORD   Index;
  351.   LPTSTR  TitleBuffer;
  352.   LPTSTR  *Title;
  353.   DWORD   Last;
  354.   DWORD   dwR;
  355.  
  356.   Log("GetTitleIdx start");
  357.   dwR = GetPerfTitleSz (HKEY_LOCAL_MACHINE, HKEY_PERFORMANCE_DATA, &TitleBuffer, &Title, &Last);
  358.  
  359.   Log("dwR=%d",(int)dwR);
  360.   if (dwR != ERROR_SUCCESS)
  361.   {
  362.     Log("GetTitleIdx start");
  363.     return 0;
  364.   }
  365.  
  366.   for (Index = 0; Index <= Last; Index++)
  367.   {
  368.     if (Title[Index])
  369.     {
  370.       Log("Title[%d]=%s, name=%s",Index,Title[Index], name);
  371.       if (!lstrcmpi (Title[Index], name))
  372.       {
  373.         LocalFree (TitleBuffer);
  374.         LocalFree (Title);
  375.         Log("GetTitleIdx end (Index=%d)",(int)Index);
  376.         return Index;
  377.       }
  378.     }
  379.   }
  380.  
  381.   LocalFree (TitleBuffer);
  382.   LocalFree (Title);
  383.   Log("GetTitleIdx end");
  384.   return 0;
  385. }
  386.  
  387. PPERF_COUNTER FirstCounter (PPERF_OBJECT pObject)
  388. {
  389.   Log("FirstCounter, pObject=%p",pObject);
  390.   if (pObject)
  391.     return (PPERF_COUNTER)((PCHAR) pObject + pObject->HeaderLength);
  392.   else
  393.     return NULL;
  394. }
  395.  
  396. PPERF_COUNTER NextCounter (PPERF_COUNTER pCounter)
  397. {
  398.   Log("NextCounter, pCounter=%p",pCounter);
  399.   if (pCounter)
  400.     return (PPERF_COUNTER)((PCHAR) pCounter + pCounter->ByteLength);
  401.   else
  402.     return NULL;
  403. }
  404.  
  405. PPERF_COUNTER FindCounter (PPERF_OBJECT pObject, DWORD TitleIndex)
  406. {
  407.   PPERF_COUNTER pCounter;
  408.   DWORD         i = 0;
  409.  
  410.   Log("FindCounter start, pObject=%p, TitleIndex=%d",pObject,(int)TitleIndex);
  411.   if (pCounter = FirstCounter (pObject))
  412.   {
  413.     Log("pObject->NumCounters=%d",(int)pObject->NumCounters);
  414.     while (i < pObject->NumCounters)
  415.     {
  416.       Log("pCounter->CounterNameTitleIndex=%d",(int)pCounter->CounterNameTitleIndex);
  417.       if (pCounter->CounterNameTitleIndex == TitleIndex)
  418.       {
  419.         Log("FindCounter end (pCounter=%p)",pCounter);
  420.         return pCounter;
  421.       }
  422.  
  423.       pCounter = NextCounter (pCounter);
  424.       i++;
  425.     }
  426.   }
  427.  
  428.   Log("FindCounter end");
  429.   return NULL;
  430. }
  431.  
  432. PPERF_INSTANCE FirstInstance (PPERF_OBJECT pObject)
  433. {
  434.   Log("FirstInstance (pObject=%p)",pObject);
  435.   if (pObject)
  436.     return (PPERF_INSTANCE)((PCHAR) pObject + pObject->DefinitionLength);
  437.   else
  438.     return NULL;
  439. }
  440.  
  441. PPERF_INSTANCE NextInstance (PPERF_INSTANCE pInst)
  442. {
  443.   PERF_COUNTER_BLOCK *pCounterBlock;
  444.  
  445.   Log("NextInstance (pInst=%p)",pInst);
  446.   if (pInst)
  447.   {
  448.     pCounterBlock = (PERF_COUNTER_BLOCK *)((PCHAR) pInst + pInst->ByteLength);
  449.     return (PPERF_INSTANCE)((PCHAR) pCounterBlock + pCounterBlock->ByteLength);
  450.   }
  451.   else
  452.     return NULL;
  453. }
  454.  
  455. PVOID CounterData (PPERF_INSTANCE pInst, PPERF_COUNTER pCount)
  456. {
  457.   PPERF_COUNTER_BLOCK pCounterBlock;
  458.  
  459.   Log("CounterData (pInst=%p, pCount=%p)",pInst,pCount);
  460.   if (pCount && pInst)
  461.   {
  462.     pCounterBlock = (PPERF_COUNTER_BLOCK)((PCHAR)pInst + pInst->ByteLength);
  463.     return (PVOID)((PCHAR)pCounterBlock + pCount->CounterOffset);
  464.   }
  465.   else
  466.     return NULL;
  467. }
  468.  
  469. LPTSTR  InstanceName (PPERF_INSTANCE pInst)
  470. {
  471.   Log("InstanceName (pInst=%p)",pInst);
  472.   if (pInst)
  473.     return (LPTSTR) ((PCHAR) pInst + pInst->NameOffset);
  474.   else
  475.     return NULL;
  476. }
  477.  
  478. // The EnumProcs function takes a pointer to a callback function
  479. // that will be called once per process in the system providing
  480. // process EXE filename and process ID.
  481. // Callback function definition:
  482. // BOOL CALLBACK Proc( DWORD dw, LPCSTR lpstr, LPARAM lParam ) ;
  483. // 
  484. // lpProc -- Address of callback routine.
  485. // 
  486. // lParam -- A user-defined LPARAM value to be passed to
  487. //           the callback routine.
  488. BOOL WINAPI EnumProcs( PROCENUMPROC lpProc, LPARAM lParam )
  489. {
  490.   OSVERSIONINFO  osver ;
  491.   HANDLE         hSnapShot ;
  492.   PROCESSENTRY32 procentry ;
  493.   BOOL           bFlag ;
  494.  
  495.  
  496.   Log("EnumProcs start");
  497.   // Check to see if were running under Windows95 or
  498.   // Windows NT.
  499.   osver.dwOSVersionInfoSize = sizeof( osver ) ;
  500.   if( !GetVersionEx( &osver ) )
  501.   {
  502.      Log("GetVersionEx failed, EnumProcs end");
  503.      return FALSE ;
  504.   }
  505.  
  506.   // If Windows NT:
  507.   if( osver.dwPlatformId == VER_PLATFORM_WIN32_NT )
  508.   {
  509.     PPERF_INSTANCE  pInstance;
  510.     PPERF_COUNTER   pCounterProcID;
  511.     PPERF_OBJECT    pObject;
  512.     INT             InstanceIndex = 0;
  513.     PPERF_DATA      gpPerfData=NULL;
  514.     TCHAR           INDEX_PROCTHRD_OBJ[20];
  515.     DWORD           gPerfDataSize = 50*1024;
  516.     DWORD           PX_PROCESS;
  517. /*    DWORD           PX_THREAD;*/
  518.     DWORD           *pdwProcID;
  519.     char            procname[MAX_PATH];
  520.  
  521.     Log("Using NT method");
  522.     PX_PROCESS = GetTitleIdx("Process");
  523.     /*PX_THREAD  = GetTitleIdx("Thread");
  524.     wsprintf (INDEX_PROCTHRD_OBJ, TEXT("%ld %ld"), PX_PROCESS, PX_THREAD);*/
  525.     wsprintf (INDEX_PROCTHRD_OBJ, TEXT("%ld"), PX_PROCESS);
  526.     gpPerfData = RefreshPerfData (HKEY_PERFORMANCE_DATA, INDEX_PROCTHRD_OBJ, gpPerfData, &gPerfDataSize);
  527.     pObject = FindObject (gpPerfData, PX_PROCESS);
  528.     if (pObject)
  529.     {
  530.       if ((pCounterProcID = FindCounter(pObject, GetTitleIdx("ID Process"))))
  531.       {
  532.         pInstance = FirstInstance (pObject);
  533.  
  534.         while (pInstance && InstanceIndex < pObject->NumInstances)
  535.         {
  536.           pdwProcID = (DWORD *) CounterData (pInstance, pCounterProcID);
  537.           if (*pdwProcID)
  538.           {
  539.             sprintf(procname,"%S.exe",InstanceName(pInstance));
  540.             Log("procname=%s",procname);
  541.             if (!lpProc( *pdwProcID, 0, procname , lParam))
  542.             {
  543.               LocalFree(gpPerfData);
  544.               Log("EnumProcs end");
  545.               return FALSE ;
  546.             }
  547.           }
  548.           pInstance = NextInstance (pInstance);
  549.           InstanceIndex++;
  550.         }
  551.       }
  552.     }
  553.     LocalFree(gpPerfData);
  554.  
  555.  
  556.   // If Windows 95:
  557.   }
  558.   else if( osver.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS )
  559.   {
  560.  
  561.      Log("Using Win9x method");
  562.      if (hInstLib==NULL)
  563.      {
  564.        hInstLib = LoadLibraryA( "Kernel32.DLL" ) ;
  565.        if( hInstLib == NULL )
  566.           return FALSE ;
  567.  
  568.        // Get procedure addresses.
  569.        // We are linking to these functions of Kernel32
  570.        // explicitly, because otherwise a module using
  571.        // this code would fail to load under Windows NT,
  572.        // which does not have the Toolhelp32
  573.        // functions in the Kernel 32.
  574.        lpfCreateToolhelp32Snapshot=
  575.           (HANDLE(WINAPI *)(DWORD,DWORD))
  576.           GetProcAddress( hInstLib,
  577.           "CreateToolhelp32Snapshot" ) ;
  578.        lpfProcess32First=
  579.           (BOOL(WINAPI *)(HANDLE,LPPROCESSENTRY32))
  580.           GetProcAddress( hInstLib, "Process32First" ) ;
  581.        lpfProcess32Next=
  582.           (BOOL(WINAPI *)(HANDLE,LPPROCESSENTRY32))
  583.           GetProcAddress( hInstLib, "Process32Next" ) ;
  584.        lpfModule32First=
  585.           (BOOL(WINAPI *)(HANDLE,LPMODULEENTRY32))
  586.           GetProcAddress( hInstLib, "Module32First" ) ;
  587.        lpfModule32Next=
  588.           (BOOL(WINAPI *)(HANDLE,LPMODULEENTRY32))
  589.           GetProcAddress( hInstLib, "Module32Next" ) ;
  590.        if(lpfProcess32Next == NULL ||
  591.           lpfProcess32First == NULL ||
  592.           lpfModule32Next == NULL ||
  593.           lpfModule32First == NULL ||
  594.           lpfCreateToolhelp32Snapshot == NULL )
  595.        {
  596.          Log("Error loading libraries");
  597.           FreeLibrary( hInstLib );
  598.           hInstLib=NULL;
  599.           return FALSE ;
  600.        }
  601.      }
  602.  
  603.      // Get a handle to a Toolhelp snapshot of the systems
  604.      // processes.
  605.      hSnapShot = lpfCreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
  606.      if( hSnapShot == INVALID_HANDLE_VALUE )
  607.      {
  608.         Log("CreateToolhelp32Snapshot failed");
  609.         return FALSE ;
  610.      }
  611.  
  612.      // Get the first process' information.
  613.      procentry.dwSize = sizeof(PROCESSENTRY32) ;
  614.      bFlag = lpfProcess32First( hSnapShot, &procentry ) ;
  615.  
  616.      // While there are processes, keep looping.
  617.  
  618.      while( bFlag )
  619.      {
  620.        // Call the enum func with the filename and ProcID.
  621.  
  622.         MODULEENTRY32 me32 = {0}; 
  623.  
  624.         if (GetProcessModule(procentry.th32ProcessID, 
  625.                 procentry.th32ModuleID, &me32, sizeof(MODULEENTRY32)))
  626.         {
  627.            Log("szModule=%s",me32.szModule);
  628.            if(lpProc( procentry.th32ProcessID, 0,
  629.               me32.szModule, lParam ))
  630.            {
  631.              procentry.dwSize = sizeof(PROCESSENTRY32) ;
  632.              bFlag = lpfProcess32Next( hSnapShot, &procentry );
  633.            }
  634.            else
  635.            {
  636.              CloseHandle(hSnapShot);
  637.              Log("EnumProcs end");
  638.              return FALSE;
  639.            }
  640.         }     
  641.      }
  642.      CloseHandle(hSnapShot);
  643.   }
  644.   else
  645.   {
  646.     Log("EnumProcs end (Unknown OS)");
  647.      return FALSE ;
  648.   }
  649.  
  650.   Log("EnumProcs end");
  651.   return TRUE ;
  652. }
  653.  
  654. BOOL WINAPI Enum16( DWORD dwThreadId, WORD hMod16, WORD hTask16,
  655.   PSZ pszModName, PSZ pszFileName, LPARAM lpUserDefined )
  656. {
  657.   BOOL bRet ;
  658.  
  659.   EnumInfoStruct *psInfo = (EnumInfoStruct *)lpUserDefined ;
  660.  
  661.   Log("Enum16 start");
  662.   bRet = psInfo->lpProc( psInfo->dwPID, hTask16, pszFileName,
  663.      psInfo->lParam ) ;
  664.  
  665.   if(!bRet)
  666.   {
  667.      psInfo->bEnd = TRUE ;
  668.   }
  669.  
  670.   Log("Enum16 end (bRet=%d)",(int)bRet);
  671.   return !bRet;