Jump to content

Recommended Posts

Posted (edited)

Good morning Forums :bye:
In these days, I am working on a project that involved me to use some Windows APIs to obtain some information about Terminal Servers.
I'm doing this using wtsapi32.dll in a VBA Project, but, the lack of knowledge about few things threated in the articles make this quite difficult to
implement and understand at the same time.
The most difficult thing I'm facing is "translating" C/C++ functions or struct in VBA when pointers are used, or pointers of pointers, and so on.
Since VBA seems to not have a pointer type, to make those functions work I need to implement other functions taken from other DLLs, and this confuses me a lot.
For example, starting from this code, I splitted all the functions and all the definitions to understand why they are there, and why I need to use them.
At the end, I've found out that the code I was going to implement starting from the functions provided in the Microsoft Docs won't be ever be able to work without some supplementary functions which are not mentioned anywhere.
So, I was wondering if someone would please point me out to a good and practical exaplanation about pointers (in general) or specifically for VBA, because I need to use them quite often in these days, and I'd like to understand what I am doing.
Thanks in advance.

Best Regards and Stay at home 🏡
 

Edited by FrancescoDiMuro

Click here to see my signature:

  Reveal hidden contents

 

Posted (edited)

Good afternoon @Danyfirex :)
I looked at the links you provided to me, and they have been really helpful about the topic, but, I have a question I can't find an answer for.
Let me show you some code:

  Reveal hidden contents

If you run this function on your PC, you'd probably note that the value of lngBytes is not the lenght in Bytes of the information returned, but the lenght in characters of that, and I've found it strange since in the documentation about WTSQuerySessionInformationA() it says that pBytes stores the lenght in Bytes of the information returned.
Said that, let's see the PointerToStringA() function:

  Reveal hidden contents

From here too, I am a little confused.
Since a string in VBA is a pointer to a BSTR data type, couldn't I get the lenght of the string returned by WTSQuerySessionInformationA taking the 4 Bytes data before the start of the string content?
Practically, no, but why?
Then, when I ReDim the Bytes array, shouldn't I use the lenght of the string in characters * the number of Bytes of each character in a VB String (2 Bytes)?
Here too, the answer is "Practically no", but I tried to modify the above code to what "theory says", and the app crashes.
I am asking these questions just to "completely" understand what's going on when strings and pointers are used in VB.

Here it is the Wtsapi32 Module:

  Reveal hidden contents

Could you (or anyone) please answer me, even with an example, to those questions?

EDIT: Added a string test.

  Reveal hidden contents

P.S.: To the reader:

  Reveal hidden contents

Thanks in advance :)

Edited by FrancescoDiMuro
Added string test

Click here to see my signature:

  Reveal hidden contents

 

Posted

Hello. 

  Quote

Since a string in VBA is a pointer to a BSTR data type, couldn't I get the length of the string returned by WTSQuerySessionInformationA taking the 4 Bytes data before the start of the string content?

Expand  

yes You can get the length of a string from the BSTR structure But It's not the right/correct way. But using WTSQuerySessionInformationA you will get the length in lngBytes in bytes. So If you use WTSQuerySessionInformationW You will get lngBytes * 2

  Quote

Then, when I ReDim the Bytes array, shouldn't I use the lenght of the string in characters * the number of Bytes of each character in a VB String (2 Bytes)?
Here too, the answer is "Practically no", but I tried to modify the above code to what "theory says", and the app crashes.
I am asking these questions just to "completely" understand what's going on when strings and pointers are used in VB.

Expand  

 

It's correct you can use the lngBytes for redim and subtract 2,  (1 for NULL Char at the end of the string and the other because vba array bound starts from 0.) It's what lstrlenA does.

in your code you could do this instead using PointerToStringA.

Dim aByteArray() As Byte
ReDim aByteArray(lngBytes - 2)
CopyMemory aByteArray(0), ByVal lngBuffer, lngBytes - 1
Dim sStr As String
sStr = StrConv(aByteArray, vbUnicode)

 

Saludos

 

 

Posted
  On 4/19/2020 at 4:00 PM, Danyfirex said:

So If you use WTSQuerySessionInformationW You will get lngBytes * 2

Expand  

Now it is much clearer.

I didn't know the difference between A (ANSI) and W (Wide Char or Unicode).

By default, I saw that VBA uses ANSI format for strings, so better to use all the functions and structures with the final "A" in order to don't have any problem of conversion from/to Unicode format.

Is it a Wise choice? :D

I'm gonna read some articles about ANSI and Unicode to understand the difference.

For the code you posted, I will try ASAP and let you know the results.

As always, thanks dear @Danyfirex :)

P.S.: your dog looks amazing!

Click here to see my signature:

  Reveal hidden contents

 

Posted

Good morning :)
I just tested the WTSOpenServerW, and, even if it returns a Long variable, it doesn't work when used with WTSQuerySessionInformationW; I had to use 0& when calling WTSQuerySessionInformationW, but seems that it loads a little bit more then the *A functions (~1 second more).
The discussion about A and W is not very clear on these functions.
I have to study more, but, for now, I think that I'm going to use A functions and structures, even if they are stangely faster than then W ones.

Click here to see my signature:

  Reveal hidden contents

 

Posted

The reason that You don't get working the Wide version is because You'll need to copy the Unicode string directly to your vba string. Like this way.

 

Dim sStr As String
sStr = String((lngBytes / 2) - 1, vbNullChar)
CopyMemory ByVal StrPtr(sStr), ByVal lngBuffer, lngBytes - 2

Saludos

Posted

@Danyfirex
Thanks for the reply as always.

The part that it's not working is the one with WTSQuerySessionInformationW() function, which is returning 0.
To get the handle of the Server, I used WTSOpenServerW, which takes a string as input, and it does return an handle, so, the problem seems to be (and practically too) with WTSQuerySessionInformationW() function.
I feel quite confident with Bytes array and CopyMemory for now.
Later I am going to test these functions in a big environment, and try to catch the LogonTime of the Session.
There are a lot of things that I'm learning right now, and I feel quite confused about all of these information, and even a bit struggled.
 

Click here to see my signature:

  Reveal hidden contents

 

Posted

Hello. W API works correctly for me. Let me know your result when you do your tests.

 

Saludos

Posted (edited)

Hey @Danyfirex :)
I finally got the *W functions working.
The error was on the function WTSOpenServerW(), which takes as "in parameter" a pointer to a Wide String, and so, I had to convert the string parameter in Unicode:

  Reveal hidden contents

But, this lead me to make another question...
Why did I have to convert the string in Unicode, if VBA handles the string in Unicode format natively?
Because I modified the StringFromPointerW() function like this:

  Reveal hidden contents

and you can see that I'm assigning the value of Byte array directly to the function return's value, so, how strings in VBA are handled?
Did you have to pass an Unicode string as parameter of WTSOpenServerW() in order to have it working, and how did you handle the obtainment of the value of the string from the pointer?
Thank you and have a good day :)

Best Regards.

Edited by FrancescoDiMuro

Click here to see my signature:

  Reveal hidden contents

 

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...