www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Windows PSAPI

reply "sleek" <cslush gmail.com> writes:
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. 
Sep 06 2008
parent reply Sergey Gromov <snake.scaly gmail.com> writes:
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 );
Sep 07 2008
next sibling parent reply "sleek" <cslush gmail.com> writes:
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 );

Sep 07 2008
parent reply Sergey Gromov <snake.scaly gmail.com> writes:
Content-Type: text/plain; charset="iso-8859-15"
Content-Transfer-Encoding: 7bit

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.
Sep 07 2008
next sibling parent reply wyverex <wyverex.cypher gmail.com> writes:
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
Sep 07 2008
next sibling parent "sleek" <cslush gmail.com> writes:
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

Sep 07 2008
prev sibling parent Sergey Gromov <snake.scaly gmail.com> writes:
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.
Sep 07 2008
prev sibling parent "sleek" <cslush gmail.com> writes:
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.

Sep 07 2008
prev sibling parent reply torhu <no spam.invalid> writes:
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
Sep 07 2008
parent Sergey Gromov <snake.scaly gmail.com> writes:
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.
Sep 08 2008