FoxPro Programming
Accessing pointer returned by WTSAPI32
Gravatar is a globally recognized avatar based on your email address. Accessing pointer returned by WTSAPI32
  Raymond
  All
  Mar 13, 2020 @ 08:57pm

I am calling WTSQuerySessionInformationA in WTSAPI32. The result is returned as a pointer. I am probably not declaring it correctly or just confused as how to access the value or sometimes a structure depending on the requested WTSInfoClass. (I have only done simple API calls where the result buffer contains the actual values.)

#DEFINE WTS_CURRENT_SERVER 0
#DEFINE WTS_CURRENT_SESSION -1
#DEFINE WTSSessionId 4
#DEFINE WTSClientName 10
#DEFINE WTSClientAddress 14

DECLARE INTEGER WTSQuerySessionInformationA;
	IN WTSAPI32.DLL;
	INTEGER hServer,;
	INTEGER SessionId,;
	INTEGER WTSInfoClass,;
	STRING @ppBuffer,;
	INTEGER @pBytesReturned

lcBuffer = SPACE(4)
lnBufferSize = 0
lnRetval = WTSQuerySessionInformationA(WTS_CURRENT_SERVER_HANDLE,;
WTS_CURRENT_SESSION,;
WTSClientAddress,;
@lcBuffer,@lnBufferSize )

lcBuffer always contains 4 chars (pointer) and lnBufferSize will vary based on what is requested...

WTSSessionId returns 4.

WTSClientName returns 8.

WTSClientAddress returns 24 which is a structure (integer and 20 chars)

It all seems to work, and makes sense, but I am just brain dead on how to get it setup correctly to access the result.

Thanks for any guidance.

Gravatar is a globally recognized avatar based on your email address. re: Accessing pointer returned by WTSAPI32
  Rick Strahl
  Raymond
  Mar 14, 2020 @ 01:45pm

The struct buffer that comes back should contain a string (along with some funky characters) and you should be able to read the string data as an offset with SUBSTR() - offsetting for the pre-amble with the size for the string data. If the string is Unicode you may have to to strip off the double byte extra null characters.

+++ Rick ---

Gravatar is a globally recognized avatar based on your email address. re: Accessing pointer returned by WTSAPI32
  Raymond
  Rick Strahl
  Mar 14, 2020 @ 03:32pm

Thanks Rick. I am not being clear as to what I am seeing.

In the example, lcBuffer and lnBufferSize are passed by reference. The API returns a numeric value in lnBufferSize which indicates the size of the result. However, the result is stored in separate memory allocated by the API. The 4 byte value returned in lcBuffer points to that allocated memory. I can see and access these 4 bytes, but I am unclear as to how to take that value (address) and access the information stored at that address.

Gravatar is a globally recognized avatar based on your email address. re: Accessing pointer returned by WTSAPI32
  Rick Strahl
  Raymond
  Mar 15, 2020 @ 12:42am

Ah Ok you need to de-reference the pointer returned...

You can use:

lcBuffer = SYS(2600,lnPointer,1024)

to get the data from the pointer. Then you can parse the data as described previously.

+++ Rick --

Gravatar is a globally recognized avatar based on your email address. re: Accessing pointer returned by WTSAPI32
  Raymond
  Rick Strahl
  Mar 15, 2020 @ 11:29am

Well, that didn't seem to work either.

I suspect that the API is returning a 64 bit address and I probably just can't get there from here. I think I will shift gears and try calling powershell and extracting the info that way.

Thanks for your attempt. Your the best.

Stay well.

Gravatar is a globally recognized avatar based on your email address. re: Accessing pointer returned by WTSAPI32
  Rick Strahl
  Raymond
  Mar 16, 2020 @ 04:56am

Your types aren't quite right. The pointer should be a number. I tried this but it still looks like the pointer that is returned is not to the right memory location for the data:

CLEAR
#DEFINE WTS_CURRENT_SERVER_HANDLE 0
#DEFINE WTS_CURRENT_SESSION -1
#DEFINE WTSSessionId 4
#DEFINE WTSClientName 10
#DEFINE WTSClientAddress 14

DECLARE INTEGER WTSQuerySessionInformationA;
	IN WTSAPI32.DLL;
	INTEGER hServer,;
	INTEGER SessionId,;
	INTEGER WTSInfoClass,;
	INTEGER @ppBuffer,;
	INTEGER @pBytesReturned

lnPointer = 0

lnBufferSize = 0
lnRetval = WTSQuerySessionInformationA(WTS_CURRENT_SERVER_HANDLE,;
WTS_CURRENT_SESSION,;
WTSClientAddress,;
@lnPointer,@lnBufferSize )
? lnBufferSize
? lnPointer

lcRes = SYS(2600,lnPointer,lnBufferSize)
? lcRes

+++ Rick ---

© 1996-2020