• Welcome to Valhalla Legends Archive.
 

[VB] CheckRevision

Started by Joe[x86], April 14, 2005, 10:45 PM

Previous topic - Next topic

Joe[x86]

Not sure if this should go in the VB Programming forum. Please move it if it should.

Hdx and I are working on writing a VisualBasic CheckRevision() function. If anyone is interested in suggesting stuff or testing, or would like more information or something, feel free to ask. Here it is, as of right now.

Public Function checkRevision( _  '// This is the CheckRevision function used for 0x51.
versionString As String, _        '// Checksum Formula recieved in 0x50.
mpqNum As Integer, _              '// MPQ Number recieved in 0x50.
Product As String) As Long        '// Product to use.

      'START JOES CODE
          '// Sample formula -- A=602362906 B=5284658 C=149279165 4 A=A+S B=B^C C=C^A A=A^B
          '// TODO - Joe: Define hash codes, define files.

          Dim A As Long, B As Long, C As Long, S As Long, Splt() as String, O1 as String
          Dim O2 as String, Dim O3 as String

          A = CLng(Mid(Splt(0), 3))
          B = CLng(Mid(Splt(1), 3))
          C = CLng(Mid(Splt(2), 3))

          O1 = Mid(Splt(4), 4, 1)
          O2 = Mid(Splt(5), 4, 1)
          O2 = Mid(Splt(6), 4, 1)
      'END JOES CODE

      'START HDX'S CODE     
      A = A ^ hashCodes(mpqNum)

      For I = 0 To UBound(strFiles)
          intFile = FreeFile
          Open strFiles(I) For Binary Access Read As #intFile
              RoundedSize = CDbl((LOF(intFile) / 1024) * 1024)

          For J = 0 To RoundedSize Step 4
              strTmpData = Space(4)
              Get #intFile, J + 1, strTmpData
              S = GetDWORD(strTmpData)

              Select Case op1
                  Case "^": A = A ^ S
                  Case "-": A = A - S
                  Case "+": A = A + S
              End Select

              Select Case op2
                  Case "^": B = B ^ C
                  Case "-": B = B - C
                  Case "+": B = B + C
              End Select

              Select Case op3
                  Case "^": C = C ^ A
                  Case "-": C = C - A
                  Case "+": C = C + A
              End Select

              Select Case op4
                  Case "^": A = A ^ B
                  Case "-": A = A - B
                  Case "+": A = A + B
              End Select
          Next J
      Close #intFile
      Next I
  checkRevision = C
  '// END HDX'S CODE
End Function
Quote from: brew on April 25, 2007, 07:33 PM
that made me feel like a total idiot. this entire thing was useless.

MyndFyre

A couple comments, and take them with a grain of salt, as it's late and I might just be completely missing something.

1.) The Splt array seems to be unassigned.  You declare it, and then immediately use it:

'Declare it:
          Dim A As Long, B As Long, C As Long, S As Long, Splt() as String, O1 as String
' Use it
          A = CLng(Mid(Splt(0), 3))

Is this intended?  I would think it would generate a compile-time error.

2.) I can't remember, but does VB support the ^ operator?  I thought it didn't support *any* symbolic bitwise operators -- I thought that appropriate bitwise operators were:

A = A And B
B = B Or C
C = C Xor S

If that's the case you'll need to revise code that uses the ^ operator.  I'm too lazy to look it up right now.

Actually, the ^ operator is valid, but it means exponentiation.  See this page for more information.

3.) You repeat defining O2:

          O2 = Mid(Splt(5), 4, 1)
          O2 = Mid(Splt(6), 4, 1)

Not being picky, just saving you that runtime debugging frustration later :)

Otherwise I think you've got a good start.
QuoteEvery generation of humans believed it had all the answers it needed, except for a few mysteries they assumed would be solved at any moment. And they all believed their ancestors were simplistic and deluded. What are the odds that you are the first generation of humans who will understand reality?

After 3 years, it's on the horizon.  The new JinxBot, and BN#, the managed Battle.net Client library.

Quote from: chyea on January 16, 2009, 05:05 PM
You've just located global warming.

UserLoser.

Correct me if I'm wrong, but wouldn't:

((Integer * 1024) / 1024) return the same value as Integer..?

MyndFyre

#3
Quote from: UserLoser on April 15, 2005, 02:06 PM
Correct me if I'm wrong, but wouldn't:

((Integer * 1024) / 1024) return the same value as Integer..?

Assuming you didn't have overflow, yes, but I don't see that expression in his code.  You want either

((Integer / 1024) * 1024)

or:

Integer - (Integer % 1024)

IIRC the second is more efficient, because integral division can take a long time.

You also might be able to get it faster by left-shifting (without carry) by 22 and then right-shifting it back 22 -- I believe that will fill the upper 22 bits with 0s and leave the remaining lower 10 bits as they were.

Or you could just bitwise AND it with 0x3ff, IIRC.

And on that note, should you just use a Long instead of a Double to hold the file size?  I don't think that any of Blizz's files go bigger than 2gb -- at least, not the ones you're CheckRevisioning.
QuoteEvery generation of humans believed it had all the answers it needed, except for a few mysteries they assumed would be solved at any moment. And they all believed their ancestors were simplistic and deluded. What are the odds that you are the first generation of humans who will understand reality?

After 3 years, it's on the horizon.  The new JinxBot, and BN#, the managed Battle.net Client library.

Quote from: chyea on January 16, 2009, 05:05 PM
You've just located global warming.

UserLoser.

Quote from: MyndFyre on April 15, 2005, 02:15 PM
Assuming you didn't have overflow, yes, but I don't see that expression in his code.  You want either

RoundedSize = CDbl((LOF(intFile) / 1024) * 1024)

According to all my tests, it returns the same value.  What's the point of doing / 1024 * 1024 is what I'm wanting to know

Adron

Quote from: UserLoser on April 15, 2005, 02:25 PM
Quote from: MyndFyre on April 15, 2005, 02:15 PM
Assuming you didn't have overflow, yes, but I don't see that expression in his code.  You want either

RoundedSize = CDbl((LOF(intFile) / 1024) * 1024)

According to all my tests, it returns the same value.  What's the point of doing / 1024 * 1024 is what I'm wanting to know

You should do \ 1024 then * 1024...

Adron

Quote from: MyndFyre on April 15, 2005, 02:15 PM

Integer - (Integer % 1024)

IIRC the second is more efficient, because integral division can take a long time.

I'll just point out that % implies integral division.

You do save a multiplication though.

OnlyMeat

#7
With modern processors there isn't a performance gain doing shifts in place of multiplications/divisions anymore.

I simply did this in my vb 6.0 checkrevision implementation.


        ' Round file size
        lFileSize = Round(GetFileSize(hFile, ByVal 0&) / 1024) * 1024


I store the result in a long (which in vb 6 is 32 bits) and worked just fine.

Joe[x86]

MyndFyre, thanks for reminding me to fill Splt with stuff, and for reminding me about Xor. I'll just have to replace the ^ with Xor's, so I don't screw myself up big time.

UserLoser: I was wondering that myself. Thats in the Hdx's Code section, and I'll have to talk to him and find out what the hell he was thinking.
Quote from: brew on April 25, 2007, 07:33 PM
that made me feel like a total idiot. this entire thing was useless.

Adron

Quote from: OnlyMeat on April 15, 2005, 02:47 PM

        ' Round file size
        lFileSize = Round(GetFileSize(hFile, ByVal 0&) / 1024) * 1024


I store the result in a long (which in vb 6 is 32 bits) and worked just fine.

I'm not so sure that works reliably. Maybe it just works 50% of the cases?

Hdx

#10
#1, the ((I / 1024) * 1024) was suposto round the size to the nerest MB, but I accedently did / insted of \ :/
As for the ^ This was already descused in the original topic -.- the one i started.
Also Joe, PLEASE stop taking my code and posts from one site, and posting them on another site saying its a team project between the two of us!, I mearly wanted the input of some people on Quikness forums. Not here -.- (no offence all, but I would of posted it here myself, if i wanted help from everyone here, I like smaller forums over big ones)

Now Here is the current code:
Private hashCodes(0 To 7) As Long
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (ByRef destination As Any, ByRef Source As Any, ByVal numbytes As Long)

Private Sub SetVars()
    hashCodes(0) = &HE7F4CB62
    hashCodes(1) = &HF6A14FFC
    hashCodes(2) = &HAA5504AF
    hashCodes(3) = &H871FCDC2
    hashCodes(4) = &H11BF6A18
    hashCodes(5) = &HC57292E6
    hashCodes(6) = &H7927D27E
    hashCodes(7) = &H2FEC8733
End Sub

Public Function GetDWORD(Data As String) As Long
    Dim lReturn As Long
    Call CopyMemory(lReturn, ByVal Data, 4)
    GetDWORD = lReturn
End Function

Public Function checkRevision(ByVal versionString As String, ByRef strFiles() As String, ByVal mpqNum As Integer) As Integer

        Dim tok As New clsStringTokenizer
        Call tok.SetVals(versionString, Space(1))
       
        Dim A As Long, B As Long, C As Long, S As Long
        A = Val(tok.getNextToken(3))
        B = Val(tok.getNextToken(3))
        C = Val(tok.getNextToken(3))

        tok.getNextToken
        Dim Formula As String, I As Integer, intFile As Integer, RoundedSize As Double, J As Double
        Dim op1 As String, op2 As String, op3 As String, op4 As String, strTmpData As String

        op1 = Mid(tok.getNextToken, 4, 1)
        op2 = Mid(tok.getNextToken, 4, 1)
        op3 = Mid(tok.getNextToken, 4, 1)
        op4 = Mid(tok.getNextToken, 4, 1)
       
        A = A Xor hashCodes(mpqNum)

        For I = 0 To UBound(strFiles)
            intFile = FreeFile
            Open strFiles(I) For Binary Access Read As #intFile
                RoundedSize = CDbl((LOF(intFile) \ 1024) * 1024)

            For J = 0 To RoundedSize Step 4
                strTmpData = Space(4)
                Get #intFile, J + 1, strTmpData
                S = GetDWORD(strTmpData)

                Select Case op1
                    Case "^": A = Moduls(A Xor S)
                    Case "-": A = Moduls(A - S)
                    Case "+": A = Moduls(A + S)
                End Select

                Select Case op2
                    Case "^": B = Moduls(B Xor C)
                    Case "-": B = Moduls(B - C)
                    Case "+": B = Moduls(B + C)
                End Select

                Select Case op3
                    Case "^": C = Moduls(C Xor A)
                    Case "-": C = Moduls(C - A)
                    Case "+": C = Moduls(C + A)
                End Select

                Select Case op4
                    Case "^": A = Moduls(A Xor B)
                    Case "-": A = Moduls(A - B)
                    Case "+": A = Moduls(A + B)
                End Select
            Next J
        Close #intFile
        Next I
    checkRevision = C
    End Function
   
Private Function Moduls(intOne As Long) As Long
    Moduls = CLng(intOne Mod &HFFFFFFFF)
End Function

Private Sub Form_Load()
    Call SetVars
    Dim blah(0 To 2) As String
    blah(0) = "E:\JBLS\W2BN\Warcraft II BNE.exe"
    blah(2) = "E:\JBLS\W2BN\battle.snp"
    blah(1) = "E:\JBLS\W2BN\storm.dll"
Call checkRevision("A=602362906 B=5284658 C=149279165 4 A=A+S B=B^C C=C^A A=A^B", blah, 3)
End Sub

Moduls() Was suggested by both Joe, Fool, And iago. As a way to prevent overflows. But it always returns zero :/

Now does the opertation thet B.net sends refer to all Bitwise opertations (Xor, Or, And, Etc...) or there mathmatical counterparts? (+, -, /, \, ^, *, etc...)

^ was explaind to mean Xor, and so could it be assumed that + means And, and - means Or? If so it always returns zero (not using Moduls()) with no overflows.
~-~(HDX)~-~

PS: This is a strait port of iago's java code.
Also who deleyted my last post. Please don't do it again. It is varry annoying. Thanks.

Proud host of the JBLS server www.JBLS.org.
JBLS.org Status:
JBLS/BNLS Server Status

UserLoser.

Quote from: Adron on April 15, 2005, 02:29 PM
Quote from: UserLoser on April 15, 2005, 02:25 PM
Quote from: MyndFyre on April 15, 2005, 02:15 PM
Assuming you didn't have overflow, yes, but I don't see that expression in his code.  You want either

RoundedSize = CDbl((LOF(intFile) / 1024) * 1024)

According to all my tests, it returns the same value.  What's the point of doing / 1024 * 1024 is what I'm wanting to know

You should do \ 1024 then * 1024...

That seems correct.  I wanted to know why he was doing it the other way

Joe[x86]

Private Sub SetVars()
    hashCodes(0) = &HE7F4CB62
    hashCodes(1) = &HF6A14FFC
    hashCodes(2) = &HAA5504AF
    hashCodes(3) = &H871FCDC2
    hashCodes(4) = &H11BF6A18
    hashCodes(5) = &HC57292E6
    hashCodes(6) = &H7927D27E
    hashCodes(7) = &H2FEC8733
End Sub


I suggest just space-delimiting them, and then calling them using Split(Hashcodes, Space(1)(MPQNum).
Quote from: brew on April 25, 2007, 07:33 PM
that made me feel like a total idiot. this entire thing was useless.

UserLoser.

Quote from: Joex86] link=topic=11286.msg108723#msg108723 date=1113617931]
Private Sub SetVars()
    hashCodes(0) = &HE7F4CB62
    hashCodes(1) = &HF6A14FFC
    hashCodes(2) = &HAA5504AF
    hashCodes(3) = &H871FCDC2
    hashCodes(4) = &H11BF6A18
    hashCodes(5) = &HC57292E6
    hashCodes(6) = &H7927D27E
    hashCodes(7) = &H2FEC8733
End Sub


I suggest just space-delimiting them, and then calling them using Split(Hashcodes, Space(1)(MPQNum).

Why!?

Joe[x86]

No initiation sub needs to be called beforehand.

CRev() Initiated..
M(A) = -5091265
M(B) = 5284658
M(C) = 15061445
M(A) = -5091265
M(A) = -5091265
M(B) = 5284658
M(C) = 15061445
M(A) = -5091265
M(A) = -5091265
M(B) = 5284658
M(C) = 15061445
M(A) = -5091265
CRev() = 15061445


GG.
I lowered the mod to &HFFFFFF, because I don't remember if it was actually &HFFFFFFFF in the first place, and it works now. Not sure if it returned the correct value, but atleast it returned.

Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" _
    (ByRef destination As Any, ByRef Source As Any, ByVal numbytes As Long)

Private Const HashCodes As String = "&HE7F4CB62 &HF6A14FFC &HAA5504AF " _
    & "&H871FCDC2 &H11BF6A18 &HC57292E6 &H7927D27E &H2FEC8733"

Public Function GetDWORD(Data As String) As Long
    Dim lReturn As Long
    Call CopyMemory(lReturn, ByVal Data, 4)
    GetDWORD = lReturn
End Function

Public Function checkRevision(ByVal versionString As String, ByRef strFiles() As String, ByVal mpqNum As Integer) As Currency
    '// Sample formula -- A=602362906 B=5284658 C=149279165 4 A=A+S B=B^C C=C^A A=A^B
   
    Dim I1 As Integer, I2 As Integer, ToAdd As Long

    Dim A As Currency, B As Currency, C As Currency, Splt() As String, O1 As String
    Dim O2 As String, O3 As String, O4 As String, sTmpData As String
   
    Splt = Split(versionString, " ")
   
    A = CLng(Mid(Splt(0), 3))
    B = CLng(Mid(Splt(1), 3))
    C = CLng(Mid(Splt(2), 3))
   
    O1 = Mid(Splt(4), 4, 1)
    O2 = Mid(Splt(5), 4, 1)
    O3 = Mid(Splt(6), 4, 1)

    Debug.Print "CRev() Initiated.."

    A = A Xor Split(HashCodes, " ")(mpqNum - 1)

    For I1 = LBound(strFiles) To UBound(strFiles)
        intFile = FreeFile
        Open strFiles(I) For Binary Access Read As #intFile
        RoundedSize = LOF(intFile) - (LOF(intFile) Mod 4) 'RoundedSize = CDbl((LOF(intFile) \ 1024) * 1024)
        For I2 = 0 To RoundedSize Step 4
            strTmpData = Space(4)
            Get #intFile, I2 + 1, strTmpData
            ToAdd = GetDWORD(CStr(strTmpData))

            Select Case op1
                Case "^": A = A Xor ToAdd
                Case "-": A = A - S
                Case "+": A = A + S
            End Select
            Debug.Print "M(A) = " & M(A)
            A = M(A)

            Select Case op2
                Case "^": B = B Xor ToAdd
                Case "-": B = B - C
                Case "+": B = B + C
            End Select
            Debug.Print "M(B) = " & M(B)
            B = M(B)

            Select Case op3
                Case "^": C = C Xor ToAdd
                Case "-": C = C - A
                Case "+": C = C + A
            End Select
            Debug.Print "M(C) = " & M(C)
            C = M(C)

            Select Case op4
                Case "^": A = A Xor ToAdd
                Case "-": A = A - B
                Case "+": A = A + B
            End Select
            Debug.Print "M(A) = " & M(A)
            A = M(A)
           
        Next I2
        Close #intFile
    Next I1
   
    Debug.Print "CRev() = " & C
   
    checkRevision = C
End Function

Public Function M(l As Currency) As Currency

    'Dim l2 As Long
    'l2 = l
   
    'While l2 > &HFFFFFFFF
    '    l2 = l2 - &HFFFFFFFF
    'Wend
   
    'M = l2
    '// @Above: How slow can such simple code get?
   
    M = l Mod &HFFFFFF
End Function
Quote from: brew on April 25, 2007, 07:33 PM
that made me feel like a total idiot. this entire thing was useless.