Valhalla Legends Forums Archive | Battle.net Bot Development | FILETIME Structures and Battle.net

AuthorMessageTime
bethra
Ok, I have a question on FILETIME Structures and how they are sent and recieved in BNCS packets.

FILETIME Structures have two members that are both a DWORD and are named dwLowDateTime and dwHighDateTime.

When I send/recieve a packet to/from Battle.net that has a FILETIME structure in it, the FILETIME Structure would be basically be a string of 8 bytes with the first 4 bytes the DWORD dwLowDateTime, followed by the DWORD dwHighDateTime as the last 4 bytes?

For example, if I had a FILETIME Structure with the member dwLowDateTime as 0x50 and the member dwHighDateTime as 0x51, then if I were to send it in a packet, it would look like this in hex:
[quote]
50 00 00 00 51 00 00 00
[/quote]

Is this correct?

Thank you for your time.  This is kind of a noob question.
January 2, 2006, 6:45 PM
LoRd
FILETIMEs are not dwords nor are they strings.  They're single 8 byte structures and they should be treated as such.
January 2, 2006, 7:19 PM
bethra
Ok.

So In VB6, if I recieve these 8 bytes in a packet from BNCS, then I have now idea how I would be able to convert it as a string into a FILETIME structure...

I have a FILETIME structure as a Type... End Type.
[code]
Public Type FILETIME
dwLowDateTime As Long
dwHighDateTime As Long
End Type
[/code]
January 2, 2006, 8:12 PM
LoRd
CopyMemory()
January 2, 2006, 8:29 PM
bethra
Yes, after doing more experimenting I've concluded that I am correct...

What I did was:
1.  Get the FILETIME structure for a file that existed on my PC.
2.  Convert that FILETIME structure into a string by calling a function that uses CopyMemory for the conversion and returns the string.
3.  Display the hex output of the string.
4.  Convert the returned string back into a FILETIME structure by calling a function that creates a FILETIME structure and sets the member dwLowDateTime to the first 4 bytes of the passed string and the member dwHighDateTime to the next 4 bytes of the passed string, returns the created FILETIME structure.
5.  Convert the returned FILETIME structure created in step 4 into a SYSTEMTIME structure using a declared kernel.dll API function.
6.  Check the members of the returned SYSTEMTIME structure so that I can easily verify that the Year, Month, Day, Hour, Minute, Second, etc. are the same as the file on my PC that I used.

So I concluded that the first 4 bytes of a 8 byte FILETIME structure is definitely the member dwLowDateTime and the next 4 bytes are the member dwHighDateTime.
January 2, 2006, 10:54 PM
LoRd
[code]Dim ft as FILETIME

Call CopyMemory(ft, data, 8)
[/code]

So much simpler.
January 2, 2006, 11:01 PM
bethra
I originally tried that code, however something weird happens with that code.

Here is the code:
[code]
'Declare the FILETIME structure
Private Type FILETIME
    dwLowDateTime As Long
    dwHighDateTime As Long
End Type

'Fires when button btnDebug is clicked
Private Sub btnDebug_Click()
    Dim str$
    Dim ft1 As FILETIME, ft2 As FILETIME, ft3 As FILETIME
   
    'Set the FILETIME structure member's values
    ft1.dwLowDateTime = &H50
    ft1.dwHighDateTime = &H51
   
    'Convert FILETIME structure to string and display output
    str = FtToStr(ft1)
    Debug.Print "FtToStr() converted FILETIME structure into string:" & vbNewLine
    Debug.Print DebugOutput(str) & vbNewLine
   
    'Testing my way
    ft2 = StrToFt(str)
    Debug.Print "StrToFt() returned FILETIME structure with members:"
    Debug.Print "dwLowDateTime = " & Hex(ft2.dwLowDateTime)
    Debug.Print "dwHighDateTime = " & Hex(ft2.dwHighDateTime) & vbNewLine
   
    'Testing Lord[nK]'s way
    ft3 = StrToFt2(str)
    Debug.Print "StrToFt2() returned FILETIME structure with members:"
    Debug.Print "dwLowDateTime = " & Hex(ft3.dwLowDateTime)
    Debug.Print "dwHighDateTime = " & Hex(ft3.dwHighDateTime) & vbNewLine
End Sub

'A function that converts a FILETIME structure to a String
Public Function FtToStr$(ft As FILETIME)
    Dim result As String * 8
    CopyMemory ByVal result, ft, 8
    FtToStr = result
End Function

'A function that converts a String to FILETIME structure
Private Function StrToFt(ByVal str$) As FILETIME
    Dim ft As FILETIME

    'StrToLng() is a function I wrote to convert a 4 character string into it's
    'Long numerical representation
    ft.dwLowDateTime = StrToLng(StrReverse(Mid(str, 1, 4)))
    ft.dwHighDateTime = StrToLng(StrReverse(Mid(str, 5)))
   
    StrToFt = ft
End Function

'A function that converts a String to FILETIME structure (Doesn't seem to work)
Private Function StrToFt2(ByVal str$) As FILETIME
    Dim ft As FILETIME

    CopyMemory ft, str, 8
   
    StrToFt2 = ft
End Function
[/code]

The output of the code after clicking button btnDebug 4 times:
[quote]
FtToStr() converted FILETIME structure into string:

50 00 00 00 51 00 00 00                          P...Q...........

StrToFt() returned FILETIME structure with members:
dwLowDateTime = 50
dwHighDateTime = 51

StrToFt2() returned FILETIME structure with members:
dwLowDateTime = 1CF53C
dwHighDateTime = 0

FtToStr() converted FILETIME structure into string:

50 00 00 00 51 00 00 00                          P...Q...........

StrToFt() returned FILETIME structure with members:
dwLowDateTime = 50
dwHighDateTime = 51

StrToFt2() returned FILETIME structure with members:
dwLowDateTime = 249EB4
dwHighDateTime = 0

FtToStr() converted FILETIME structure into string:

50 00 00 00 51 00 00 00                          P...Q...........

StrToFt() returned FILETIME structure with members:
dwLowDateTime = 50
dwHighDateTime = 51

StrToFt2() returned FILETIME structure with members:
dwLowDateTime = 24A09C
dwHighDateTime = 0

FtToStr() converted FILETIME structure into string:

50 00 00 00 51 00 00 00                          P...Q...........

StrToFt() returned FILETIME structure with members:
dwLowDateTime = 50
dwHighDateTime = 51

StrToFt2() returned FILETIME structure with members:
dwLowDateTime = 24B384
dwHighDateTime = 0
[/quote]

Odd... I originally tried Lord[nK]'s code for the converting a String into a FILETIME structure using CopyMemory, but found that I don't get the right values when I check each of the two FILETIME structure's members.

Since all I'm doing is converting a FILETIME structure to a String and then converting that String back to a FILETIME structure, the values for members dwLowDateTime and dwHighDateTime in the FILETIME structure returned by StrToFt2() SHOULD be 0x50 and 0x51, respectively.

StrToFt() does what it is expected... but StrToFt2() does not.
January 2, 2006, 11:38 PM
JoeTheOdd
[code]Public Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (pDest As Any, pSrc As Any, ByVal ByteLen As Long)

Public Type LongLong
    dwLo As Long
    dwHi As Long
End Type

Public Function GetQWORD(s As String) As Integer
    Dim rVal As LongLong
    CopyMemory rVal, ByVal s, 8
    GetQWORD = rVal
End Function[/code]
January 4, 2006, 2:00 AM

Search