Sign in to follow this  
Followers 0
cojms1

Help with API call - NetRemoteTOD

10 posts in this topic

I hope someone can help with this.

I am trying to return the time from a remote server. The NetRemoteTOD function should do this. I am having a problem at the moment in

that the DllCall is not reporting any errors however there is only value being applied to the structure.

The structure should be as follows: -

DWORD tod_elapsedt
  DWORD tod_msecs
  DWORD tod_hours
  DWORD tod_mins
  DWORD tod_secs
  DWORD tod_hunds
  LONG tod_timezone
  DWORD tod_tinterval
  DWORD tod_day
  DWORD tod_month
  DWORD tod_year
  DWORD tod_weekday

The code I have at the moment is below: -

$todi_struct = DllStructCreate("dword[12]")
   $temp = ""
   $ret = DllCall("netapi32.dll", "int", "NetRemoteTOD", "wstr", $server, "ptr", DllStructGetPtr($todi_struct))
   if $ret[0] <> 0 then
      msgbox(0, "Error", $ret[0])
   else
      for $i = 1 to DllStructGetSize($todi_struct) / 4
         $temp &= $i & ":" & DllStructGetData($todi_struct, 1, $i) & @LF
      next
      msgbox(0, "Results", $temp)
   endif
   $ret = DllCall("netapi32.dll", "int", "NetApiBufferFree", "ptr", DllStructGetPtr($todi_struct))

Any help would be appreciated.

Share this post


Link to post
Share on other sites



After DllCall add this:

If @error Then _GetLastErrorMessage ("DllCall() error")


;===============================================
;    _GetLastErrorMessage($DisplayMsgBox="")
;    Format the last windows error as a string and return it
;    if $DisplayMsgBox <> "" Then it will display a message box w/ the error
;    Return        Window's error as a string
;===============================================
Func _GetLastErrorMessage ($DisplayMsgBox = "")
    Local $ret, $s
    Local $p = DllStructCreate("char[4096]")
    Local Const $FORMAT_MESSAGE_FROM_SYSTEM = 0x00001000

    If @error Then Return ""

    $ret = DllCall("Kernel32.dll", "int", "GetLastError")

    $ret = DllCall("kernel32.dll", "int", "FormatMessage", _
            "int", $FORMAT_MESSAGE_FROM_SYSTEM, _
            "ptr", 0, _
            "int", $ret[0], _
            "int", 0, _
            "ptr", DllStructGetPtr($p), _
            "int", 4096, _
            "ptr", 0)
    $s = DllStructGetData($p, 1)
    $p = 0
    If $DisplayMsgBox <> "" Then MsgBox(0, "_GetLastErrorMessage", $DisplayMsgBox & @CRLF & $s)
    Return $s
EndFunc   ;==>_GetLastErrorMessage

Share this post


Link to post
Share on other sites

@Zedna

Have added the code but @error is not being set. There is no error being returned by the DLLCall() function. The call all seems to go fine. My problem is that it seems to only populate the 1st element in the structure. All other elements return 0.

Share this post


Link to post
Share on other sites

#4 ·  Posted (edited)

@Zedna

Have added the code but @error is not being set. There is no error being returned by the DLLCall() function. The call all seems to go fine. My problem is that it seems to only populate the 1st element in the structure. All other elements return 0.

Then try this:

$todi_struct = DllStructCreate("dword;dword;dword;dword;dword;dword;dword;dword;dword;dword;dword;dword")
   $temp = ""
   $ret = DllCall("netapi32.dll", "int", "NetRemoteTOD", "wstr", $server, "ptr", DllStructGetPtr($todi_struct))
   if $ret[0] <> 0 then
      msgbox(0, "Error", $ret[0])
   else
      for $i = 1 to 12
         $temp &= $i & ":" & DllStructGetData($todi_struct, $i) & @LF
      next
      msgbox(0, "Results", $temp)
   endif
   $ret = DllCall("netapi32.dll", "int", "NetApiBufferFree", "ptr", DllStructGetPtr($todi_struct))
Edited by Zedna

Share this post


Link to post
Share on other sites

@Zedna

Unfortunately this produces the same results (only the first element get populated).

Share this post


Link to post
Share on other sites

@Zedna

Thanks for your ideas.

Share this post


Link to post
Share on other sites

After DllCall add this:

If @error Then _GetLastErrorMessage ("DllCall() error")
;===============================================
;    _GetLastErrorMessage($DisplayMsgBox="")
;    Format the last windows error as a string and return it
;    if $DisplayMsgBox <> "" Then it will display a message box w/ the error
;    Return        Window's error as a string
;===============================================
Func _GetLastErrorMessage ($DisplayMsgBox = "")
    Local $ret, $s
    Local $p = DllStructCreate("char[4096]")
    Local Const $FORMAT_MESSAGE_FROM_SYSTEM = 0x00001000

    If @error Then Return ""

    $ret = DllCall("Kernel32.dll", "int", "GetLastError")

    $ret = DllCall("kernel32.dll", "int", "FormatMessage", _
            "int", $FORMAT_MESSAGE_FROM_SYSTEM, _
            "ptr", 0, _
            "int", $ret[0], _
            "int", 0, _
            "ptr", DllStructGetPtr($p), _
            "int", 4096, _
            "ptr", 0)
    $s = DllStructGetData($p, 1)
    $p = 0
    If $DisplayMsgBox <> "" Then MsgBox(0, "_GetLastErrorMessage", $DisplayMsgBox & @CRLF & $s)
    Return $s
EndFunc   ;==>_GetLastErrorMessage

Is there anyone who worked with delphi and show me hints to execute my dll with Autoit ?

Nothing worked ! and not getting error evnthough i run Then _GetLastErrorMessage Procedure !

Share this post


Link to post
Share on other sites

Spent a while scratching my head on this too. Problem is that NetRemoteTOD does not populate the structure you supply a pointer to, with the TIME_OF_DAY_INFO data you're expecting. It populates this with a pointer to the data that you're expecting. Hence why only the first element of the structure appears to be populated (its populated with the pointer rather than actual TOD data)...

You need to create a structure receive the pointer into, then use that in DllStructCreate to form the structure around the memory with the useful data in...

;Remote server to query
$svr = "hostname"

;TIME_OF_DAY_INFO Structure definition
; http://msdn.microsoft.com/en-us/library/aa370959(VS.85).aspx
$struct = "dword elapsedt;dword msecs;dword hours;dword mins;dword secs;dword hunds;long timezone;"
$struct &= "dword tinterval;dword day;dword month;dword year;dword weekday"

;Will contain pointer to TIME_OF_DAY_INFO result
$Buf = DllStructCreate("long")

$hdlDLL = DllOpen("Netapi32.dll")
If $hdlDLL = -1 Then
    MsgBox(0, "DEBUG", "DllOpen failed!")
    Exit
EndIf

$result = DllCall($hdlDLL, "dword", "NetRemoteTOD", "wstr", $svr, "ptr", DllStructGetPtr($Buf))
If @error Then
    MsgBox(0, "DEBUG", "DllCall() failed with error " & @error)
    Exit
EndIf

;Form structure using pointer to data from DllCall
$TIME_OF_DAY_INFO = DllStructCreate($struct, DllStructGetData($Buf, 1))
If @error Then
    MsgBox(0, "DEBUG", "DllStructCreate() failed with error " & @error)
    Exit
EndIf

MsgBox(0, "Full Result", "Elapsed: " & DllStructGetData($TIME_OF_DAY_INFO, "elapsedt") & @CRLF & _
                            "Msec: " & DllStructGetData($TIME_OF_DAY_INFO, "msecs") & @CRLF & _
                            "Hour: " & DllStructGetData($TIME_OF_DAY_INFO, "hours") & @CRLF & _
                            "Mins: " & DllStructGetData($TIME_OF_DAY_INFO, "mins") & @CRLF & _
                            "Secs: " & DllStructGetData($TIME_OF_DAY_INFO, "secs") & @CRLF & _
                            "Hund: " & DllStructGetData($TIME_OF_DAY_INFO, "hunds") & @CRLF & _
                            "Tzne: " & DllStructGetData($TIME_OF_DAY_INFO, "timezone") & @CRLF & _
                            "Tint: " & DllStructGetData($TIME_OF_DAY_INFO, "tinterval") & @CRLF & _
                            "Day : " & DllStructGetData($TIME_OF_DAY_INFO, "day") & @CRLF & _
                            "Mont: " & DllStructGetData($TIME_OF_DAY_INFO, "month") & @CRLF & _
                            "Year: " & DllStructGetData($TIME_OF_DAY_INFO, "year") & @CRLF & _
                            "Wkdy: " & DllStructGetData($TIME_OF_DAY_INFO, "weekday"))

Share this post


Link to post
Share on other sites

You don't need the extra DLLStruct for the Pointer and you should free the Buffer when you are finished:

;Remote server to query
$svr = @ComputerName

;TIME_OF_DAY_INFO Structure definition
; http://msdn.microsoft.com/en-us/library/aa370959(VS.85).aspx
Global Const $tagTIME_OF_DAY_INFO = _
  "DWORD todElapsedt;" & _
  "DWORD todMsecs;" & _
  "DWORD todHours;" & _
  "DWORD todMins;" & _
  "DWORD todSecs;" & _
  "DWORD todHunds;" & _
  "LONG  todTimezone;" & _
  "DWORD todTinterval;" & _
  "DWORD todDay;" & _
  "DWORD todMonth;" & _
  "DWORD todYear;" & _
  "DWORD todWeekday;"

$hdlDLL = DllOpen("Netapi32.dll")
If $hdlDLL = -1 Then
    MsgBox(0, "DEBUG", "DllOpen failed!")
    Exit
EndIf

$result = DllCall($hdlDLL, "dword", "NetRemoteTOD", "wstr", $svr, "ptr*", 0)
If @error Then
    MsgBox(0, "DEBUG", "DllCall() failed with error " & @error)
    Exit
ElseIf $result[0]<>0 Then
    MsgBox(0, "DEBUG", "NetRemoteTOD failed with error " & $result[0])
    Exit
EndIf

$Pointer = $result[2]

;Form structure using pointer to data from DllCall
$TIME_OF_DAY_INFO = DllStructCreate($tagTIME_OF_DAY_INFO, $Pointer)
If @error Then
    MsgBox(0, "DEBUG", "DllStructCreate() failed with error " & @error)
    Exit
EndIf

MsgBox(0, "Full Result", "Elapsed: " & DllStructGetData($TIME_OF_DAY_INFO, "todElapsedt") & @CRLF & _
                            "Msec: " & DllStructGetData($TIME_OF_DAY_INFO, "todsecs") & @CRLF & _
                            "Hour: " & DllStructGetData($TIME_OF_DAY_INFO, "todhours") & @CRLF & _
                            "Mins: " & DllStructGetData($TIME_OF_DAY_INFO, "todmins") & @CRLF & _
                            "Secs: " & DllStructGetData($TIME_OF_DAY_INFO, "todsecs") & @CRLF & _
                            "Hund: " & DllStructGetData($TIME_OF_DAY_INFO, "todhunds") & @CRLF & _
                            "Tzne: " & DllStructGetData($TIME_OF_DAY_INFO, "todtimezone") & @CRLF & _
                            "Tint: " & DllStructGetData($TIME_OF_DAY_INFO, "todtinterval") & @CRLF & _
                            "Day : " & DllStructGetData($TIME_OF_DAY_INFO, "todday") & @CRLF & _
                            "Mont: " & DllStructGetData($TIME_OF_DAY_INFO, "todmonth") & @CRLF & _
                            "Year: " & DllStructGetData($TIME_OF_DAY_INFO, "todyear") & @CRLF & _
                            "Wkdy: " & DllStructGetData($TIME_OF_DAY_INFO, "todweekday"))

; free buffer
DllCall($hdlDLL,"int","NetApiBufferFree", "ptr", $Pointer)

*GERMAN* [note: you are not allowed to remove author / modified info from my UDFs]My UDFs:[_SetImageBinaryToCtrl] [_TaskDialog] [AutoItObject] [Animated GIF (GDI+)] [ClipPut for Image] [FreeImage] [GDI32 UDFs] [GDIPlus Progressbar] [Hotkey-Selector] [Multiline Inputbox] [MySQL without ODBC] [RichEdit UDFs] [SpeechAPI Example] [WinHTTP]UDFs included in AutoIt: FTP_Ex (as FTPEx), _WinAPI_SetLayeredWindowAttributes

Share this post


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
Sign in to follow this  
Followers 0