www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 1695] New: Calling some functions out of PSAPI.dll corrupts stack

reply d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=1695

           Summary: Calling some functions out of PSAPI.dll corrupts stack
           Product: D
           Version: 2.007
          Platform: PC
        OS/Version: Windows
            Status: NEW
          Severity: critical
          Priority: P2
         Component: DMD
        AssignedTo: bugzilla digitalmars.com
        ReportedBy: mail tobias-wassermann.de


1. Generate a lib with implib: implib /noi /system psapi.lib
C:\windows\system32\psapi.lib

2. Compile the following code with dmd ProcessFinder.d -L+psapi/noi

import std.stdio;
import std.c.windows.windows;

extern (Windows) HANDLE OpenProcess(uint dwDesiredAccess, BOOL bInheritHandle,
uint dwProcessId);    

extern (C) 
{
  BOOL EnumProcesses(DWORD* pProcessIds, DWORD cb, DWORD* pBytesReturned);
  DWORD GetModuleFileNameExA(HANDLE hProcess, HMODULE hModule, char* fileName,
uint size);  
  DWORD GetProcessImageFileNameA(HANDLE hProcess, LPSTR lpImageFileName, DWORD
nSize);
}

void main(char[][] args)
{
  uint[256] processIds;
  uint byteCount;
  char[] processFileName;
  int ret = EnumProcesses(processIds.ptr, processIds.length*uint.sizeof,
&byteCount);
  if(ret!=0)
  {
    for(uint i=0; i<processIds.length && i<byteCount/uint.sizeof; i++)
    {
      if(processIds[i]==0)
        continue;
      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 = GetProcessImageFileNameA(hProcess, processFileName.ptr,
processFileName.length);
        namelength = GetModuleFileNameExA(hProcess, cast(HMODULE)0,
processFileName.ptr, processFileName.length);
        processFileName.length = namelength;
        writefln("=> %s", processFileName);        
        CloseHandle(hProcess);
      }
    }
  }
}

So what will happen? With commented out GetModuleFileNameExA()-call you will
get a list of correct process id's:

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

If you use GetModuleFileNameExA() the list will be incorrect:

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.

3. After calling GetModuleFileNameExA() the stack will be corrupted, the
processIds-Array will be incorrect, if you comment out this call, all works
fine. The same behaviour if you call GetProcessImageFileNameA()

Strange thing: If you port the code to C and compile against DMC - same
problem! If you compile it with Microsoft Visual C++, you can also use
GetModuleFileNameExA() and GetProcessImageFileNameA() without any problems.
Seems to be an implib-issue?

See also the "Windows API: Strange behaviour after calling
GetModuleFileNameExA" entries within the digitalmars.D-newsgroup


-- 
Nov 27 2007
parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=1695


bugzilla digitalmars.com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
         Resolution|                            |INVALID




------- Comment #1 from bugzilla digitalmars.com  2007-12-30 00:55 -------
The problem is declaring Windows API functions as being extern(C). They should
be extern(Windows). Stack corruption is the result of incorrectly declaring
what function calling convention to use.


-- 
Dec 29 2007