[FFI newbie] Windows process info from Squeak
"Boris Gärtner"
Boris.Gaertner at gmx.net
Thu Feb 2 15:11:52 UTC 2006
"Valdas Bucinskas" <valdas.bucinskas at ipsistemos.lt> wrote:
> Hello,
>
> Wow, your examples are really interesting and helps incredibly much.
> I modified your your last example slightly, incorporating RAMs used by the
> process. And then tried to find the .exe that calls the process. It
> appears,
> the method GetModuleBaseName from psapi.dll should be used, which is
> described in
>
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/perfmon/bas
> e/getmodulebasename.asp.
> It gives the method declaration is
> DWORD GetModuleBaseName(
> HANDLE hProcess,
> HMODULE hModule,
> LPTSTR lpBaseName,
> DWORD nSize
> );
> What I miss now is the knowledge, how do I convert types from c++ like
> into
> Sueak ones. I guess hProcess corresponds to Win32Handle, lpBaseName
> corresponds to char*, and nSize corresponds to long. GetModuleBaseName
> returns long.
> 1. But what does hModule correspond to?
> My guess
> <apicall: long 'GetModuleBaseName' (Win32Handle Win32Handle char* long)
> module: 'psapi.dll'>
almost correct, but the name of the function is
'GetModuleBaseNameA'
where the last character stands for ASCII.
A DLL contents viewer helps a lot to find out such details,
I use this one: http://www.nirsoft.net/utils/dll_export_viewer.html
> throughs Error 13, which is 'The data is invalid.'
> 2. Should a class similar to Win32Handle be created in order to hModule
> typecasting work?
No, that is not needed, hModule is a handle, Win32Handle is the right
choice.
No please try this:
1. add this api method to Win32Window:
apiGetModuleBaseName: hProcess module: hModule into: lpString bufferSize:
size
<apicall: long 'GetModuleBaseNameA' (Win32Handle Win32Handle char* long)
module: 'psapi.dll'>
^self externalCallFailed
2. Ensure that you open the process handle with access rights 16r410 (this
is
PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, the access
right alone PROCESS_QUERY_INFORMATION does not allow you tho read the name)
(The processes System, Idle and some others will not tell you their
names anyway)
3. Do something like this:
handleArray do: [:idx |
processHandle := interface getProcessHandleWithAccessRights: 16r410
inherit: true processId: idx.
processHandle notNil
ifTrue:
[ | buffer processName cnt |
buffer := ByteArray new: 80.
interface apiGetModuleBaseName: processHandle
module: nil into: buffer bufferSize: 80.
processName := WriteStream on: (String new: 80).
cnt := 1.
[i <= 80 and: [(buffer at: cnt) ~= 0]]
whileTrue:
[processName nextPut: (Character value: (buffer at: cnt)).
cnt := cnt + 1].
processName := processName contents.
oc add:
(Array with: idx
with: (interface apiGetGuiResources: processHandle
type: 0)
with: (interface apiGetGuiResources: processHandle
type: 1)
with: processName).
interface closeHandle: processHandle.
]
].
When you have to provide buffers that are filled with some information,
it is always a good choice to use ByteArrays of suitable size. You
can always convert a ByteArray into a number or into a string.
Hope this helps,
Boris
More information about the Squeak-dev
mailing list
|