WinBatch Tech Support Home

Database Search

If you can't find the information using the categories below, post a question over in our WinBatch Tech Support Forum.

TechHome

ADSI
plus

Can't find the information you are looking for here? Then leave a message over on our WinBatch Tech Support Forum.

Convert Qword


Question:

I really suck in hex/dec/bin conversions and need some help solving the following coding issue. I'm doing a RegQueryQWord on a key that has the following value in RegEdit:
1c85ddf2c25c2d0 (hex)
128455802479821520 (dec)
Using RegQueryQWord in Winbatch I get:
D0 C2 25 2C DF 5D C8 01
What would be the easiest way to get the QWord value converted into the decimal value?

Answer:

Here is some sample code. Note that you get a string that *looks* like a decimal number back. However WinBatch cannot understand this number. If you are going to try to modify the number, you MUST use the HugeMath extender *ONLY*

#DefineFunction Hex2Dec(hex)
   str="0123456789ABCDEF"
   hex=StrTrim(StrUpper(hex))
   hexlen=StrLen(hex)
   dec=0
   for x=1 to hexlen
       dec=(dec*16) + StrIndex(str,strsub(hex,x,1),0,@fwdscan) -1
   next
   return(dec)
#EndFunction

AddExtender("wwhug34i.dll")
qworddata="D0 C2 25 2C DF 5D C8 01"  ;<- low byte first list as RegQWordGet returns 


QDecimalResult=0

count=ItemCount(qworddata," ")

for index = count to 1 by -1
 QDecimalResult = huge_Multiply(QDecimalResult,256)
 byte=ItemExtract(index,qworddata," ")
 byte=Hex2Dec(byte)
 QDecimalResult= huge_Add(QDecimalResult, byte)
next

Message(qWordData,QDecimalResult)
Or
AddExtender("wwhug34i.dll")

#DefineFunction QWord2Dec(QWord)
HexStr = StrReplace(QWord," ","")
f = 1
v = 0
For i = 1 To StrLen(HexStr)
   For j = 1 To 0 By -1
      a = StrSub(HexStr,i + j,1)
      If !IsInt(a) Then a = Char2Num(a) - 55
      v = huge_Add(v,huge_Multiply(f,a))
      f = huge_Multiply(f,16)
   Next
   i = i + 1
Next
Return v
#EndFunction

QWord = "D0 C2 25 2C DF 5D C8 01"
Pause(QWord,QWord2Dec(QWord))

User Reply:

The QWord value is acutally the date Vista Windows Backup succeeded the last time to make a backup. It's stored at HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsBackup\Status[LastSuccess].

Using some sample code from the Winbatch tech database and together with your code I'm now able to convert that number to a valid ymdhms date. That saves me a lot of headaches.

The only issue that I have now is that I don't have the huge math extender added to my compiled executable and I'm already at 9 extenders loaded. Is there any chance for a future update that would allow converting a QWord date to a ymdhms date like you do with the ADSI dates? That would help alot since those QWord dates seem to be more common these days.

Answer:

; No extender approach to converting a little endian hex string to a WIL data.
; (Intended as an example only and not complete by any means.)

; Converts a high/low quadword to WIL time.
; (Script paraphrase of a c++ class member in the ADSI extender.)

#DefineFunction ADSITimeToYmdHms(_nHighPart, _nLowPart)

   FileTime   = BinaryAlloc(8)
   FileTime2  = BinaryAlloc(8)
   SystemTime = BinaryAlloc(16)

   BinaryPoke4(FileTime,0,_nLowPart)
   BinaryPoke4(FileTime,4,_nHighPart)
   BinaryEodSet(SystemTime,16)

   hDll = DllLoad(DirWindows(1):"kernel32.dll")  ; Keep snow++ happy.
   flag = DllCall(hDll,long:"FileTimeToLocalFileTime", lpbinary:FileTime, lpbinary:FileTime2)
   flag = DllCall(hDll,long:"FileTimeToSystemTime", lpbinary:FileTime2, lpbinary:SystemTime)
   DllFree(hDll)

   year   = BinaryPeek2(SystemTime,0)
   month  = StrFixLeft(BinaryPeek2(SystemTime,2),0,2)
   day    = StrFixLeft(BinaryPeek2(SystemTime,6),0,2)
   hour   = StrFixLeft(BinaryPeek2(SystemTime,8),0,2)
   minute = StrFixLeft(BinaryPeek2(SystemTime,10),0,2)
   second = StrFixLeft(BinaryPeek2(SystemTime,12),0,2)
   BinaryFree(FileTime)
   BinaryFree(FileTime2)
   BinaryFree(SystemTime)
   ymdhms = StrCat(year,":",month,":",day,":",hour,":",minute,":",second)

   Return (ymdhms)
#EndFunction


; Converts hex string byte to a decimal integer.
#DefineFunction HexByteToDec(_sHexByte)
   _sHexByte = StrUpper(_sHexByte)
   nHexOff   = 55
   nByte     = 0
   For i = 1 To 2
      cNybble = StrSub(_sHexByte, i, 1)
       If !IsInt(cNybble) Then cNybble = Char2Num(cNybble) - nHexOff
      nByte = (nByte << 4) | cNybble
   Next
    Return nByte
#EndFunction

; Parses high/low decimal integers from an input of a little endian
; hex string quadword.
#DefineFunction QWord2HighLow( _sHexLittleEndian, _pdwHighPart, _pdwLowPart)
   _sHexLittleEndian = StrUpper(_sHexLittleEndian)
   nTotalBytes       = ItemCount(_sHexLittleEndian, " ")

   If nTotalBytes >= 4 Then nBytes = 4
   Else nBytes = nTotalBytes

   dwPart = 0
   For i = nBytes To 1  By -1
      cByte  = ItemExtract(i,_sHexLittleEndian," ")
      dwPart = (dwPart<<8) | HexByteToDec(cByte)
   Next
   *_pdwLowPart  = dwPart

   dwPart = 0
   nbytes = nBytes + 1
   For i = nTotalBytes To nbytes  By -1
      cByte  = ItemExtract(i,_sHexLittleEndian," ")
      dwPart = (dwPart<<8) | HexByteToDec(cByte)
   Next
   *_pdwHighPart = dwPart
   Return 0
#EndFunction

sQuadHex = "D0 C2 25 2C DF 5D C8 01"

QWord2HighLow(sQuadHex, &dwHighPart, &dwLowPart)
Date = ADSITimeToYmdHms(dwHighPart, dwLowPart)

Message(sQuadHex,Date)
Exit

Article ID:   W17364
File Created: 2008:04:10:15:08:24
Last Updated: 2008:04:10:15:08:24