PxPlus User Forum

Twitter Twitter Twitter

Author Topic: using dll()  (Read 1306 times)

thenewguy

  • Member
  • **
  • Posts: 15
    • View Profile
using dll()
« on: July 20, 2020, 10:15:06 AM »
Hi all,

I'm still trying to wrap my brain around the usage of the dll() function.

I've managed to get a result using some of the examples in documentation, but then attempting to apply that to my own needs, I keep just getting a 0 back, which to me means I'm doing something wrong.

So, I'm trying to use Kernel32 -> OpenProcess

The link above says the format is:

Code: [Select]
HANDLE OpenProcess(
  DWORD dwDesiredAccess,
  BOOL  bInheritHandle,
  DWORD dwProcessId
);

For dwDesiredAccess, you're supposed to use the Process Security and Access Rights list. So if I wanted to get, for example PROCESS_TERMINATE rights, I would use 0x0001.
My understanding of how to pass that along is:
Code: [Select]
a$ = swp(bin(1,4))
For bInheritHandle I just gave it a 0, for FALSE.

For dwProcessId, I got the process ID of a Notepad window that I had opened (so i should definitely have rights to PROCESS_TERMINATE): 40364, but since it's looking for a DWORD, I did the bin/swap thing:
Code: [Select]
b$ = swp(bin(40364,4))
but then:

Code: [Select]
output = dll("Kernel32","OpenProcess",a$,0,b$)
output = 0 every time.

Does anyone have any idea what I might be doing wrong here?

Mike King

  • Diamond Member
  • *****
  • Posts: 3811
  • Mike King
    • View Profile
    • BBSysco Consulting
Re: using dll()
« Reply #1 on: July 20, 2020, 10:30:39 AM »
Okay -- Using the DLL function requires you to understand the difference between passing data by reference (i.e. a pointer to the data/value) and passing the actual data value.  All parameters passed to the DLL are passed on the stack and that consists of a series of 32/64 bit values so its important to get these right.

Generally if you are calling a DLL function:
  • if you are asked to pass a simple value such as a number or bit mask they want it passed by value.
  • if you are passing a string or structure they want the value passed by reference which is a pointer to the data.
Okay -- So looking at the OpenProcess function it wants 3 values a DWORD with the Access requested, an indicator if you want it Inherted, and a DWORD with the Process ID.  All of these are simple values/bit masks so all need to be passed as values.

This means, given the values you requested the DLL method call would be:

sts = DLL("Kernel32","OpenProcess", 1, 0, 40364)

PxPlus will place these value in the stack and call the specified function.

If you need to pass a pointer to a structure or buffer to a string or such, you create a string to contain the values and simply put the string name in the DLL call in order to have its addressed passed.

It should also be noted that on Windows, functions that work with text often have two definitions, one definition passing 8-BIT ASCII data and one passing 16-Bit Unicode (wide) characters.  For example the FindWindow function actually exists as FindWindowA -- where you can pass a sting containing ASCII data or FindWindowW -- where you can pass a string containing 16 Bit UNICODE.  For the most part, when calling these functions from PxPlus you want the ASCII (xxxxA) function.

Lastly, remember when passing strings, that the functions often want Null terminated strings; that is a string whose last character is $00$ so make sure to add this to the end of whatever string you pass or if receiving a string only use the data up the $00$ byte.
« Last Edit: July 20, 2020, 05:46:53 PM by Mike King »
Mike King
President - BBSysco Consulting
eMail: mike.king@bbsysco.com

thenewguy

  • Member
  • **
  • Posts: 15
    • View Profile
Re: using dll()
« Reply #2 on: July 20, 2020, 10:48:08 AM »
Ah! I know the difference between passing by reference and passing by value but I didn't know the details you posted about how to tell the program which one you're giving it. That WORKED!!

Quick follow up question though, regarding the access rights page, the process-specific rights all have hex values that I at least understand (0x0080, 0x0002, 0x0001), but the "standard access rights" all have values like 0x00010000L, 0x00020000L, etc. Those (afaik) are not standard hex numbers. I'm not sure how I would convert those to decimal to pass them in.

I really appreciate the (very fast!) assistance!

Mike King

  • Diamond Member
  • *****
  • Posts: 3811
  • Mike King
    • View Profile
    • BBSysco Consulting
Re: using dll()
« Reply #3 on: July 20, 2020, 11:32:26 AM »
Actually 0x0001 and 0x00000001L are the same value.  The 'L' at the end tells the compilers that its a 'long' which used to be required when we had 16 Bit OS'es.  Now a long is 64 Bits so it would be 0x0000000000000001L.

Now for values such as 0x00010000L the easiest way to get the numeric value is to provide the value a HEX string and pass it to the DEC function as in DEC($00010000$)
Mike King
President - BBSysco Consulting
eMail: mike.king@bbsysco.com

thenewguy

  • Member
  • **
  • Posts: 15
    • View Profile
Re: using dll()
« Reply #4 on: July 20, 2020, 11:33:32 AM »
Brilliant. Thank you!