November 26, 2007
Hi all,

I have the following code, including some functions out of the psapi.dll (generated a lib with implib /noi /system psapi.lib C:\windows\system32\psapi.lib):

extern (Windows)
{
  HANDLE OpenProcess(uint dwDesiredAccess, BOOL bInheritHandle, uint dwProcessId);
  BOOL CloseHandle(HANDLE hHandle);
}
extern (C)
{
  BOOL EnumProcesses(DWORD* pProcessIds, DWORD cb, DWORD* pBytesReturned);
  uint GetModuleFileNameExA(HANDLE hProcess, HMODULE hModule, LPTSTR fileName, uint size);
}

void main(char[][] args) {
 ...
 uint[256] processIds;
 int ret = EnumProcesses(&processIds[0], processIds.length * uint.sizeof, &byteCount);
 ...
 for(uint i=0; i<processIds.length && i<byteCount/uint.sizeof; i++) {
   uint pid =  processIds[i];
   writefln("Process #%d - PID: %d", i, pid);
   HANDLE hProcess = OpenProcess(0x410 /* QueryInformation | VMRead */, false, pid);
   if(cast(int)hProcess>0)
     CloseHandle(hProcess);
 }
}

Running this code works fine. I'll get a list like:

Process #1 - PID: 4
Process #2 - PID: 780
Process #3 - PID: 836
...

But now I'll change the for-loop:

for(uint i=0; i<processIds.length && i<byteCount/uint.sizeof; i++)
{
  uint pid =  processIds[i];
  writefln("Process #%d - PID: %d", i, pid);
  HANDLE hProcess = OpenProcess(0x410 /* QueryInformation | VMRead */, false, pid);
  if(cast(int)hProcess>0)
  {
    processFileName.length = 300;
    uint namelength = 0;
    namelength = GetModuleFileNameExA(hProcess, cast(HMODULE)null, processFileName.ptr, processFileName.length);
    CloseHandle(hProcess);
  }
}

With the call of GetModuleFileNameExA() my process id list will be corrupted, I'll get something like this:

Process #1 - PID: 4
Process #2 - PID: 780
Process #3 - PID: 836
Process #4 - PID: 4298544
Process #6 - PID: 1244976
Process #7 - PID: 4202711
Process #8 - PID: 1040
Process #9 - PID: 1288
Process #10 - PID: 1332

Process #4 to Process #8: These are invalid process id's - processes with these id doesn't exist, the next real id is 1288.

I don't know why this happens, looking to the MSDN it gives me the following function header:

DWORD GetModuleFileNameEx(
  HANDLE hProcess,
  HMODULE hModule,
  LPTSTR lpFilename,
  DWORD nSize
);

So I think, my declaration within D should be correct:

uint GetModuleFileNameExA(HANDLE hProcess, HMODULE hModule, LPTSTR fileName, uint size);

Do anybody have any suggestions?

Thanks,

Tobias
November 26, 2007
How have you declared processFileName?  Perhaps "char[] processFileName;"?  Is it declared in main right next to processIds?