Jump to content

Recommended Posts

..where to start. I've posted: 

now I wanna pull the data from WTSSessionInfo and WTSSessionInfoEx as described in https://docs.microsoft.com/en-us/windows/win32/api/wtsapi32/ns-wtsapi32-wtsinfoa

typedef struct _WTSINFOA {
  WTS_CONNECTSTATE_CLASS State; <--- that is an enumeration from https://docs.microsoft.com/en-us/windows/win32/api/wtsapi32/ne-wtsapi32-wts_connectstate_class
  DWORD                  SessionId;
  DWORD                  IncomingBytes;
  DWORD                  OutgoingBytes;
  DWORD                  IncomingFrames;
  DWORD                  OutgoingFrames;
  DWORD                  IncomingCompressedBytes;
  DWORD                  OutgoingCompressedBy;
  CHAR                   WinStationName[WINSTATIONNAME_LENGTH];
  CHAR                   Domain[DOMAIN_LENGTH];
  CHAR                   UserName[USERNAME_LENGTH + 1];
  LARGE_INTEGER          ConnectTime;
  LARGE_INTEGER          DisconnectTime;
  LARGE_INTEGER          LastInputTime;
  LARGE_INTEGER          LogonTime;
  LARGE_INTEGER          CurrentTime;

from the example in ListUserSessions() I get, say:

24  WTSSessionInfo _________ 0x00000000070000000D930F00229CDD00000000000000000000000000000000005244502D5463702331313700000000000000000000000000000000000000000050433032370000000000000000000000006C756973790000000000000000000000000000000000002174A0FB1B0AD70100000000000000000625AF0A200AD701AF99E5FB1B0AD701A56FBA0A200AD701
25  WTSSessionInfoEx _______ 0x01000000000000000700000000000000010000005244502D54637023313137000000000000000000000000000000000000000000006C756973790000000000000000000000000000000050433032370000000000000000000000000000000000AF99E5FB1B0AD7012174A0FB1B0AD70100000000000000000625AF0A200AD701BBBDBA0A200AD7010D930F00229CDD0000000000000000000000000000000000

My question is: how do I get the binary example above ( WTSSessionInfo ) into a struct to DllStructGetData().


Solution at https://www.autoitscript.com/forum/topic/205232-struct-_wtsinfo/?do=findComment&comment=1475912  :) 


Edited by argumentum
Link to post
Share on other sites

You can read out the binary value of WTSSessionInfo and put it to a ubyte array struct. Afterwards just create the _WTSINFOA and map it the binary string.

Something like this here:

Global $a = ListUserSessions()

$t24 = DllStructCreate("ubyte mem[" & BinaryLen(_WTSQuerySessionInformation($i, 24, 1)) / 2 & "]")
$t24.mem = _WTSQuerySessionInformation($i, 24, 1)
$tag = "int State;dword State;dword IncomingBytes;dword OutgoingBytes;dword IncomingFrames;dword OutgoingFrames;dword IncomingCompressedBytes;dword OutgoingCompressedBy;" & _
                              "ubyte WinStationName[12];ubyte Domain[3];ubyte UserName[7];int64 ConnectTime;int64 DisconnectTime;int64 LastInputTime;int64 LogonTime;int64 LogonTime"
$t = DllStructCreate($tag, DllStructGetPtr($t24))
_WinAPI_DisplayStruct($t, $tag)

You have to set the length of arrays WinStationName, Domain and UserName accordingly.


I hope it helps.

Please don't send me any personal message and ask for support! I will not reply!

Selection of finest graphical examples at Codepen.io

The own fart smells best!
Her 'sikim hıyar' diyene bir avuç tuz alıp koşma!
¯\_(ツ)_/¯  ٩(●̮̮̃•̃)۶ ٩(-̮̮̃-̃)۶ૐ

Link to post
Share on other sites

..I'm fighting with the 

CHAR                   WinStationName[WINSTATIONNAME_LENGTH];
  CHAR                   Domain[DOMAIN_LENGTH];
  CHAR                   UserName[USERNAME_LENGTH + 1];

part of it

#include <WinAPIDiag.au3>

Func Test()
    Local $d24 = "0x00000000070000000D930F00229CDD000000000000000000000000000000" & _
            "00005244502D546370233131370000000000000000000000000000000000000000005043303237" & _
            "0000000000000000000000006C756973790000000000000000000000000000000000002174A0FB" & _
    $d24 = BinaryToString($d24)

    ConsoleWrite(StringReplace($d24, Chr(0), "") & @CRLF) ; to see what strings should I find

    Local $t24 = DllStructCreate("ubyte mem[" & BinaryLen($d24) / 2 & "]")
    $t24.mem = $d24
    Local $tag = "int State;dword SessionId;dword IncomingBytes;dword OutgoingBytes;dword IncomingFrames;" & _
            "dword OutgoingFrames;dword IncomingCompressedBytes;dword OutgoingCompressedBy;ubyte WinStationName[32]" & _
            ";ubyte Domain[8];ubyte UserName[20];int64 ConnectTime;int64 DisconnectTime;int64 LastInputTime;int64 LogonTime;int64 LogonTime"
    Local $t = DllStructCreate($tag, DllStructGetPtr($t24))
    ConsoleWrite("State          = " & $t.State & @CRLF)
    ConsoleWrite("SessionId      = " & $t.SessionId & @CRLF)

;~  ConsoleWrite("+WinStationName = " & BinaryToString($t.WinStationName) & @CRLF)
;~  ConsoleWrite("+Domain         = " & BinaryToString($t.Domain) & @CRLF)
;~  ConsoleWrite("+UserName       = " & BinaryToString($t.UserName) & @CRLF)

    ConsoleWrite("-WinStationName = " & StringReplace(BinaryToString($t.WinStationName), Chr(0), "") & @CRLF)
    ConsoleWrite("-Domain         = " & StringReplace(BinaryToString($t.Domain), Chr(0), "") & @CRLF)
    ConsoleWrite("-UserName       = " & StringReplace(BinaryToString($t.UserName), Chr(0), "") & @CRLF)
    _WinAPI_DisplayStruct($t, $tag)

EndFunc   ;==>Test

..I mean, WinStationName[????], where do I get the WINSTATIONNAME_LENGTH from ! :wacko2:, lol

It' not easy. But y'all got me closer than me on my own :gathering:

Link to post
Share on other sites

Ok seems to be working well :

Local $sString = _WTSQuerySessionInformation($i, 24, 1)
Local $dData = Binary($sString)
ConsoleWrite ($dData & @CRLF)
$tByte = DllStructCreate("byte string[" & BinaryLen($dData) & "]")
DllStructSetData($tByte, 1, $dData)
Const $tagWTSINFOA = "BYTE state;DWORD SessionId;DWORD IncomingBytes;DWORD OutgoingBytes;DWORD IncomingFrames;DWORD OutgoingFrames;" & _
  "DWORD IncomingCompressedBytes;DWORD OutgoingCompressedBy;CHAR WinStationName[32];CHAR Domain[17];CHAR UserName[21];" & _
  "INT64 ConnectTime;INT64 DisconnectTime;INT64 LastInputTime;INT64 LogonTime;INT64 CurrentTime;"
$tWTSINFOA = DllStructCreate($tagWTSINFOA, DllStructGetPtr($tByte))
ConsoleWrite ($tWTSINFOA.WinStationName & @CRLF)


Link to post
Share on other sites

cool, now, how do I make .LastInputTime readable ( human readable ).
It's supposed to be the count of ns. since 1601 UTC. ( https://docs.microsoft.com/en-us/dotnet/api/system.datetime.fromfiletime?view=net-5.0 )
But I can't find the way to do it

#include <WinAPIDiag.au3>
#include <Date.au3>

Func test2() ; https://www.autoitscript.com/forum/topic/205232-solved-struct-_wtsinfo/
    Local $dData = "0x00000000070000000D930F00229CDD000000000000000000000000000000" & _
            "00005244502D546370233131370000000000000000000000000000000000000000005043303237" & _
            "0000000000000000000000006C756973790000000000000000000000000000000000002174A0FB" & _
    $dData = BinaryToString($dData)

;~  Local $dData = Binary(_WTSQuerySessionInformation($i, 24, 1))
    ConsoleWrite("=== ========================= ===" & @CRLF & StringReplace($dData, Chr(0), "") & @CRLF & "=== ========================= ===" & @CRLF)

    Local $tByte = DllStructCreate("byte string[" & BinaryLen($dData) & "]")
    Const $DOMAIN_LENGTH = 17
    Const $USERNAME_LENGTH = 20
    DllStructSetData($tByte, 1, $dData)
    Const $tagWTSINFOA = "struct;BYTE State;DWORD SessionId;DWORD IncomingBytes;DWORD OutgoingBytes;DWORD IncomingFrames;DWORD OutgoingFrames;" & _
            "DWORD IncomingCompressedBytes;DWORD OutgoingCompressedBy;CHAR WinStationName[32];CHAR Domain[17];CHAR UserName[21];" & _
            "INT64 ConnectTime;INT64 DisconnectTime;INT64 LastInputTime;INT64 LogonTime;INT64 CurrentTime;endstruct"
    Local $tWTSINFOA = DllStructCreate($tagWTSINFOA, DllStructGetPtr($tByte))

    ConsoleWrite("-State           = " & $tWTSINFOA.State & @CRLF)
    ConsoleWrite("-SessionId       = " & $tWTSINFOA.SessionId & @CRLF)
    ConsoleWrite("-WinStationName  = " & $tWTSINFOA.WinStationName & @CRLF)
    ConsoleWrite("-Domain          = " & $tWTSINFOA.Domain & @CRLF)
    ConsoleWrite("-UserName        = " & $tWTSINFOA.UserName & @CRLF)

    ; https://www.autoitscript.com/forum/topic/173626-having-trouble-converting-ad-datetime-to-readable-datetime/?do=findComment&comment=1256087
    ; @UEZ to the rescue   :)
    ConsoleWrite("-ConnectTime     = " & Systemtime2Datetime($tWTSINFOA.ConnectTime) & @CRLF)
    ConsoleWrite("-DisconnectTime  = " & Systemtime2Datetime($tWTSINFOA.DisconnectTime) & @CRLF)
    ConsoleWrite("-LastInputTime   = " & Systemtime2Datetime($tWTSINFOA.LastInputTime) & @CRLF)
    ConsoleWrite("-LogonTime       = " & Systemtime2Datetime($tWTSINFOA.LogonTime) & @CRLF)
    ConsoleWrite("-CurrentTime     = " & Systemtime2Datetime($tWTSINFOA.CurrentTime) & @CRLF)

    _WinAPI_DisplayStruct($tWTSINFOA, $tagWTSINFOA)
EndFunc   ;==>test2

Func Systemtime2Datetime($INT64) ; https://www.autoitscript.com/forum/topic/173626-having-trouble-converting-ad-datetime-to-readable-datetime/?do=findComment&comment=1256087
    If StringLen($INT64) < 8 Then Return SetError(1, 0, "")
    Return _DateAdd("s", StringTrimRight($INT64, 7), "1601/01/01 00:00:00")

solved :) 
Thanks @UEZ and @Nine

PS: @Nhardel, here is your answer too ;) 

Edited by argumentum
Link to post
Share on other sites

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
  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By InunoTaishou
      Struggling a bit to get this GDI+ function converted to AutoIt.
      #include <GDIPlus.au3> _GDIPlus_Startup() Global $hImage = _GDIPlus_ImageLoadFromFile("F:\DCIM\Camera\20170515_111804.jpg") Global $tBufferSize = DllStructCreate("uint") Global $tProperties = DllStructCreate("uint") _GDIPlus_GetPropertySize($hImage, $tBufferSize, $tProperties) Global $tAllItems = DllStructCreate("struct;char[" & DllStructGetData($tBufferSize, 1) & "];endstruct") _GDIPlus_GetAllPropertyItems($hImage, $tBufferSize, $tProperties, $tPropertyItem) _GDIPlus_ImageDispose($hImage) _GDIPlus_Shutdown() Func _GDIPlus_GetAllPropertyItems(ByRef $hImage, Const $tTotalBufferSize, Const $tNumProperties, ByRef $tAllItems) If (Not IsDllStruct($tPropertyItem)) Then Return SetError(-1, 0, "") Local $aResult = DllCall($__g_hGDIPDll, "int", "GdipGetAllPropertyItems", "hwnd", $hImage, "unit", DllStructGetData($tTotalBufferSize, 1), "uint", DllStructGetData($tNumProperties, 1), "ptr", DllStructGetPtr($tAllItems)) If (@error) Then Return SetError(@error, @extended, ConsoleWrite("@Error = " & @error & @LF)) If ($aResult[0]) Then Return SetError($aResult[0], @extended, "") Return $aResult[0] EndFunc ;==>_GDIPlus_GetAllPropertyItems Func _GDIPlus_GetPropertySize(Const ByRef $hImage, ByRef $tTotalBufferSize, ByRef $tNumProperties) If (Not IsDllStruct($tTotalBufferSize)) Then Return SetError(-1, 0, "") If (Not IsDllStruct($tNumProperties)) Then Return SetError(-2, 0, "") Local $aResult = DllCall($__g_hGDIPDll, "uint", "GdipGetPropertySize", "hwnd", $hImage, "uint_ptr", DllStructGetPtr($tTotalBufferSize), "uint_ptr", DllStructGetPtr($tNumProperties)) If (@error) Then Return SetError(@error, @extended, "") If ($aResult[0]) Then Return SetError($aResult[0], 0, "") Return $aResult[0] EndFunc ;==>_GDIPlus_GetPropertySize Got the GetPropertySize function to work, gives me the correct buffer size and the property count, but I cannot figure out how to get the struct for the all items.
      Function on MSDN:
      Struct needed:
      PropertyItem class:
      Found other topics about this function in other languages where they used a blank string as the buffer, so I tried using a char array, which doesn't work. Just cannot figure out how to create the struct buffer to hold the data.
    • By Skysnake
      bool SMSAPI_sendsms( const LPSMSAPI_NETWORKCONFIGURATION lpNetConfig, const LPSMSAPI_ACCOUNTINFO lpAccInfo, const LPSMSAPI_MESSAGEINFO lpMsgInfo, LPSMSAPI_RESPONSEINFO lpResponseInfo); How does one call this in an AutoIt DllCall() - I do not see "const" conversions and how does one insert the pointers?
    • By Skysnake
      I can not program.  What I am trying to do is make a little AutoIt Desktop SMS sender that uses BulkSMS upstream.  BulkSMS provides services in the UK, USA, Europe and South Africa.  BulkSMS provides several options (a) create string and plug it into browser and send via HTTP, ugly but it works; (b) a DLL called smstxt32.dll which supports a few functions to do this in a typical Windows Desktop application.  They provide examples in C, PHP, Python etc.  I do not understand any of those.  I attach several files.
      The BulkSMS home page is located here: www.BulkSMS.com
      You can create a free account which allows five free credits to experiment with. So you can try to send the SMSes for free initially.
      The file "BulkSMS Win32 API ver 1006a.zip" contains a .doc help file and the smstxt32.dll file.
       BulkSMS Win32 API ver 1006a.zip
      The file BulkSMS.au3 is my attempt.
      My BulkSMS.au3 attempts to create the required structs for use with the DLL.  I think I do manage, but do not understand anything about pointers.  Then I attempt to actually send the SMS using the following DLLCALL
      Local $res = DllCall($__g_hDll_BulkSMS, _ ; name of DLL "BOOL", _ ; return type "SMSAPI_sendsms", _ ; function "LONG", _ ; type1 $gSMSAPI_NETWORKCONFIGURATION, _ ; param1 "LONG", _ ; type2 $gSMSAPI_ACCOUNTINFO, _ ; param2 "LONG", _ ; type3 $gSMSAPI_MESSAGEINFO, _ ; param3 "LONG", _ ; type4 $gSMSAPI_RESPONSEINFO _ ; param4 )This is based on the following example from the included help file, 
      bool SMSAPI_sendsms( const LPSMSAPI_NETWORKCONFIGURATION lpNetConfig, const LPSMSAPI_ACCOUNTINFO lpAccInfo, const LPSMSAPI_MESSAGEINFO lpMsgInfo, LPSMSAPI_RESPONSEINFO lpResponseInfo);According to the AutoIt Helpfile, there are conversions to comparable data types.  However, I do not see a "const" so I do not know what do with that.  Also, the C example shows the use of "long pointers." What would this be in AutoIt?
      Thank you
      BulkSMS Win32 API ver 1006a.zip
    • By swieru
      I am trying to write very basic script to use COM object. It is a specific object allowed to communication with software on the industrial controller.
      I can create reference to a COM object by function ObjCreate. Thanks to ObjectName function I can read all information about object. Problem is that, I can trigger (only) one method of this object, named Disconnect().
      When I want to use the other method instead of Disconnect(), for example, ReadValueN I have problem with arguments for this method. I tryed many variants, combinations, without positive result. My error monitoring function (for COM errors) reports: "Bad variable types" or "Type mismath".
      I studied many examples, many documentations but I have no idea how it should be.
      Below is description for method, data etc based on OLE/ COM Object Viewer.
      long ReadValueN( [in] long TARGET_id, [in] PARAM_DEF* pParamDef, [out] BUFFER* pResBuffer);typedef struct tagPARAM_DEF{ unsigned char Param1; unsigned char Param2; unsigned char Param3; unsigned char ParamT[8]; short Number; unsigned char ValueF; unsigned char ValueD; } PARAM_DEF; typedef struct tagBUFFER{ unsigned char BuffA1; unsigned char BuffA2; unsigned char BuffA3; unsigned char BuffTable[256]; } BUFFER;$structParamDef = DllStructCreate("byte; byte; byte; byte[8]; short; byte; byte") $structBuffer = DllStructCreate("byte; byte; byte; byte[256]") $response = $myObject.ReadValueN(0, DllStructGetPtr($structParamDef), DllStructGetPtr($structBuffer)) ;$response = $myObject.Disconnect() ; is workingCould someone write me what is wrong and how it should be? And especially - why?
      thanks in advanced
    • By UEZ
      I'm trying to understand following code which I want to convert to Autoit:


      VOID Example_RedEyeSetParameters(HDC hdc) { Graphics graphics(hdc); Image myImage(L"RedEyePhoto.jpg"); REAL srcWidth = (REAL)myImage.GetWidth(); REAL srcHeight = (REAL)myImage.GetHeight(); RectF srcRect(0.0f, 0.0f, srcWidth, srcHeight); Matrix myMatrix(1.0f, 0.0f, 0.0f, 1.0f, 300.0f, 20.0f); RECT redAreas[2] = {40, 10, 55, 30, 110, 20, 125, 40}; RedEyeCorrectionParams myRedEyeCorParams; myRedEyeCorParams.numberOfAreas = 2; myRedEyeCorParams.areas = redAreas; RedEyeCorrection myRedEyeCor; myRedEyeCor.SetParameters(&myRedEyeCorParams); // Draw the image with no change. graphics.DrawImage(&myImage, 20.0, 20.0, srcWidth, srcHeight); // Draw the image with the red eye correction. graphics.DrawImage(&myImage, &srcRect, &myMatrix, &myRedEyeCor, NULL, UnitPixel); }
      I made something like this here

      Global $tRECT1 = DllStructCreate("long left;long top;long right;long buttom") DllStructSetData($tRECT1, "left", 55) DllStructSetData($tRECT1, "top", 69) DllStructSetData($tRECT1, "right", 68) DllStructSetData($tRECT1, "buttom", 81) Global $pRECT1 = DllStructGetPtr($tRECT1) Global $tRECT2 = DllStructCreate("long left;long top;long right;long buttom") DllStructSetData($tRECT2, "left", 159) DllStructSetData($tRECT2, "top", 68) DllStructSetData($tRECT2, "right", 172) DllStructSetData($tRECT2, "buttom", 81) Global $pRECT2 = DllStructGetPtr($tRECT2) Global Const $tagREDEYECORRECTIONPARAMS = "uint numberOfAreas;int areas[2]" Global $tRedEye = DllStructCreate($tagREDEYECORRECTIONPARAMS) Global Const $pRedEye = DllStructGetPtr($tRedEye) DllStructSetData($tRedEye, "numberOfAreas", 2) DllStructSetData($tRedEye, "areas", $tRECT1, 1) DllStructSetData($tRedEye, "areas", $tRECT2, 2) $hEffect = _GDIPlus_EffectCreate($GDIP_REDEYECORRECTIONEFFECT) ConsoleWrite(_GDIPlus_EffectsSetParameters($hEffect, $pRedEye) & " / " & @error & @LF)
      but it is not working - return code 8, error code 2.

      I'm an absolute C++ noob and I hope somebody can help here.

  • Create New...