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:

           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

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

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

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:

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