Thread overview
Windows PSAPI
Sep 06, 2008
sleek
Sep 07, 2008
Sergey Gromov
Sep 07, 2008
sleek
Re: Windows PSAPI - 3 files [1/1]
Sep 07, 2008
Sergey Gromov
Sep 07, 2008
wyverex
Sep 07, 2008
sleek
Sep 07, 2008
Sergey Gromov
Sep 07, 2008
sleek
Sep 07, 2008
torhu
Sep 08, 2008
Sergey Gromov
September 06, 2008
Hi, I'm trying to get a list of all processes running on my machine and the dlls that are in use by those processes. Windows provides the PSAPI to perform these tasks. However, the code I'm trying to run isn't working as expected. I can get the PIDs of the processes, but beyond that, weird things occur.

Can anyone offer some assistance? I have attached the code in question.

P.S.
I built psapi.lib by doing:
implib /noi /system psapi.lib c:\windows\system32\psapi.dll

Also, I'm using the "bindings" project for the psapi.d module.




September 07, 2008
sleek <cslush@gmail.com> wrote:
> Hi, I'm trying to get a list of all processes running on my machine and the dlls that are in use by those processes. Windows provides the PSAPI to perform these tasks. However, the code I'm trying to run isn't working as expected. I can get the PIDs of the processes, but beyond that, weird things occur.
> 
> Can anyone offer some assistance? I have attached the code in question.

Firstly, there are some obvious bugs:

    DWORD count;
    if (!EnumProcessModules(hProcess, hMods.ptr,
        hMods.sizeof, &count))
    {
        return;
    }

    hMods.length = count / DWORD.sizeof;

must be

    DWORD count;
    if (!EnumProcessModules(hProcess, hMods.ptr,
        hMods.length * HMODULE.sizeof, &count))
    {
        return;
    }

    hMods.length = count / HMODULE.sizeof;

But there is one more important and crucial.

The call to GetModuleFileNameExA() messes up stack.  As far as I can tell this happens because PSAPI functions are declared extern(C) in psapi.d bindings, but in fact are __stdcall.  The problem is, it's not possible to replace extern(C) with extern(Windows) because the psapi.dll functions have unmangled names, while extern(Windows) mangles them with argument stack size.  I don't have a slightest idea of how to specify mangling convention and calling convention separately in D. In C declaration looks like:

extern "C"
DWORD
WINAPI
GetModuleFileNameExA(
    HANDLE hProcess,
    HMODULE hModule,
    LPSTR lpFilename,
    DWORD nSize
    );
September 07, 2008
Sergey,

Thanks for the response. Lucky for me, I actually fixed those first couple bugs you mentioned after looking at the code a bit more. Unluckily for me, it still sounds like I'm somewhat screwed. Does anyone else out there have any info as to how I can use PSAPI from D?

"Sergey Gromov" <snake.scaly@gmail.com> wrote in message news:MPG.232e39d36d5254929896bb@news.digitalmars.com...
> sleek <cslush@gmail.com> wrote:
>> Hi, I'm trying to get a list of all processes running on my machine and
>> the
>> dlls that are in use by those processes. Windows provides the PSAPI to
>> perform these tasks. However, the code I'm trying to run isn't working as
>> expected. I can get the PIDs of the processes, but beyond that, weird
>> things
>> occur.
>>
>> Can anyone offer some assistance? I have attached the code in question.
>
> Firstly, there are some obvious bugs:
>
>    DWORD count;
>    if (!EnumProcessModules(hProcess, hMods.ptr,
>        hMods.sizeof, &count))
>    {
>        return;
>    }
>
>    hMods.length = count / DWORD.sizeof;
>
> must be
>
>    DWORD count;
>    if (!EnumProcessModules(hProcess, hMods.ptr,
>        hMods.length * HMODULE.sizeof, &count))
>    {
>        return;
>    }
>
>    hMods.length = count / HMODULE.sizeof;
>
> But there is one more important and crucial.
>
> The call to GetModuleFileNameExA() messes up stack.  As far as I can tell this happens because PSAPI functions are declared extern(C) in psapi.d bindings, but in fact are __stdcall.  The problem is, it's not possible to replace extern(C) with extern(Windows) because the psapi.dll functions have unmangled names, while extern(Windows) mangles them with argument stack size.  I don't have a slightest idea of how to specify mangling convention and calling convention separately in D. In C declaration looks like:
>
> extern "C"
> DWORD
> WINAPI
> GetModuleFileNameExA(
>    HANDLE hProcess,
>    HMODULE hModule,
>    LPSTR lpFilename,
>    DWORD nSize
>    );


September 07, 2008
sleek <cslush@gmail.com> wrote:
> Sergey,
> 
> Thanks for the response. Lucky for me, I actually fixed those first couple bugs you mentioned after looking at the code a bit more. Unluckily for me, it still sounds like I'm somewhat screwed. Does anyone else out there have any info as to how I can use PSAPI from D?

See attached.  These are the correct import library and fixed bindings.

It wasn't easy to create the library though.  First I've got Psapi.h from Microsoft Platform SDK and modified it as suggested in this article:

    http://support.microsoft.com/kb/131313

Then I went the hard way which is of no interest.  The right way is to compile the header into an obj file and then dump its symbols.  The compiler to use depends on what tools you've got handy.  I've got the complete Microsoft SDK so I used

    cl -c psapi.c
    dumpbin /symbols psapi.obj >psapi.def

Remove everything except the names, add 'LIBRARY "psapi.dll"' and 'EXPORTS' at the top, and you're almost done with the .def file. "Almost" because functions in actual DLL are not mangled, so you need to specify an internal name.  Use any regular expression tool to convert "_Anything@digits" into "_Anything@digits = Anything".  That's it.  Now use

    implib psapi psapi.def

to produce the correct import library.

I wonder if there is an easier way.

September 07, 2008
Sergey Gromov wrote:
> sleek <cslush@gmail.com> wrote:
>> Sergey,
>>
>> Thanks for the response. Lucky for me, I actually fixed those first couple bugs you mentioned after looking at the code a bit more. Unluckily for me, it still sounds like I'm somewhat screwed. Does anyone else out there have any info as to how I can use PSAPI from D?
> 
> See attached.  These are the correct import library and fixed bindings.
> 
> It wasn't easy to create the library though.  First I've got Psapi.h from Microsoft Platform SDK and modified it as suggested in this article:
> 
>     http://support.microsoft.com/kb/131313
> 
> Then I went the hard way which is of no interest.  The right way is to compile the header into an obj file and then dump its symbols.  The compiler to use depends on what tools you've got handy.  I've got the complete Microsoft SDK so I used
> 
>     cl -c psapi.c
>     dumpbin /symbols psapi.obj >psapi.def
> 
> Remove everything except the names, add 'LIBRARY "psapi.dll"' and 'EXPORTS' at the top, and you're almost done with the .def file. "Almost" because functions in actual DLL are not mangled, so you need to specify an internal name.  Use any regular expression tool to convert "_Anything@digits" into "_Anything@digits = Anything".  That's it.  Now use
> 
>     implib psapi psapi.def
> 
> to produce the correct import library.
> 
> I wonder if there is an easier way.


Always try using linkdef
http://www.dprogramming.com/linkdef.php
September 07, 2008
Sergey,

Right now you are my friggin hero! I greatly appreciate your contribution here. I just replaced the necessary pieces in my code and it now works exactly as expected! Thanks so much for the help!

"Sergey Gromov" <snake.scaly@gmail.com> wrote in message news:MPG.232e5cf6426b533d9896bc@news.digitalmars.com...
> sleek <cslush@gmail.com> wrote:
>> Sergey,
>>
>> Thanks for the response. Lucky for me, I actually fixed those first
>> couple
>> bugs you mentioned after looking at the code a bit more. Unluckily for
>> me,
>> it still sounds like I'm somewhat screwed. Does anyone else out there
>> have
>> any info as to how I can use PSAPI from D?
>
> See attached.  These are the correct import library and fixed bindings.
>
> It wasn't easy to create the library though.  First I've got Psapi.h from Microsoft Platform SDK and modified it as suggested in this article:
>
>    http://support.microsoft.com/kb/131313
>
> Then I went the hard way which is of no interest.  The right way is to compile the header into an obj file and then dump its symbols.  The compiler to use depends on what tools you've got handy.  I've got the complete Microsoft SDK so I used
>
>    cl -c psapi.c
>    dumpbin /symbols psapi.obj >psapi.def
>
> Remove everything except the names, add 'LIBRARY "psapi.dll"' and 'EXPORTS' at the top, and you're almost done with the .def file. "Almost" because functions in actual DLL are not mangled, so you need to specify an internal name.  Use any regular expression tool to convert "_Anything@digits" into "_Anything@digits = Anything".  That's it.  Now use
>
>    implib psapi psapi.def
>
> to produce the correct import library.
>
> I wonder if there is an easier way.


September 07, 2008
Another great tip. Thanks, I'll look into this one next time I need to create a custom lib file.

"wyverex" <wyverex.cypher@gmail.com> wrote in message news:ga18jq$1h5m$1@digitalmars.com...
> Sergey Gromov wrote:
>> sleek <cslush@gmail.com> wrote:
>>> Sergey,
>>>
>>> Thanks for the response. Lucky for me, I actually fixed those first couple bugs you mentioned after looking at the code a bit more. Unluckily for me, it still sounds like I'm somewhat screwed. Does anyone else out there have any info as to how I can use PSAPI from D?
>>
>> See attached.  These are the correct import library and fixed bindings.
>>
>> It wasn't easy to create the library though.  First I've got Psapi.h from Microsoft Platform SDK and modified it as suggested in this article:
>>
>>     http://support.microsoft.com/kb/131313
>>
>> Then I went the hard way which is of no interest.  The right way is to compile the header into an obj file and then dump its symbols.  The compiler to use depends on what tools you've got handy.  I've got the complete Microsoft SDK so I used
>>
>>     cl -c psapi.c
>>     dumpbin /symbols psapi.obj >psapi.def
>>
>> Remove everything except the names, add 'LIBRARY "psapi.dll"' and 'EXPORTS' at the top, and you're almost done with the .def file. "Almost" because functions in actual DLL are not mangled, so you need to specify an internal name.  Use any regular expression tool to convert "_Anything@digits" into "_Anything@digits = Anything".  That's it.  Now use
>>
>>     implib psapi psapi.def
>>
>> to produce the correct import library.
>>
>> I wonder if there is an easier way.
>
>
> Always try using linkdef http://www.dprogramming.com/linkdef.php


September 07, 2008
wyverex <wyverex.cypher@gmail.com> wrote:
> Always try using linkdef http://www.dprogramming.com/linkdef.php

What a nice tool.  I wish it were mentioned somewhere in D docs concerning the DLL usage.
September 07, 2008
Sergey Gromov wrote:
> The call to GetModuleFileNameExA() messes up stack.  As far as I can tell this happens because PSAPI functions are declared extern(C) in psapi.d bindings, but in fact are __stdcall.  The problem is, it's not possible to replace extern(C) with extern(Windows) because the psapi.dll functions have unmangled names, while extern(Windows) mangles them with argument stack size.  I don't have a slightest idea of how to specify mangling convention and calling convention separately in D. In C declaration looks like:

Using coffimplib with a psapi.lib taken from the M$ platform SDK will probably work.  The stdcall mangling is present in the .lib file, but not the .dll.  I didn't test the resulting OMF lib file, but the names are correctly mangled, "_GetModuleFileNameExA@16" and so on.

http://ftp.digitalmars.com/coffimplib.zip
September 08, 2008
torhu <no@spam.invalid> wrote:
> Sergey Gromov wrote:
> > The call to GetModuleFileNameExA() messes up stack.  As far as I can tell this happens because PSAPI functions are declared extern(C) in psapi.d bindings, but in fact are __stdcall.  The problem is, it's not possible to replace extern(C) with extern(Windows) because the psapi.dll functions have unmangled names, while extern(Windows) mangles them with argument stack size.  I don't have a slightest idea of how to specify mangling convention and calling convention separately in D. In C declaration looks like:
> 
> Using coffimplib with a psapi.lib taken from the M$ platform SDK will probably work.  The stdcall mangling is present in the .lib file, but not the .dll.  I didn't test the resulting OMF lib file, but the names are correctly mangled, "_GetModuleFileNameExA@16" and so on.
> 
> http://ftp.digitalmars.com/coffimplib.zip

Thank you, this is another fine tool that works.