VERSION 1.0 CLASS
BEGIN
  MultiUse = -1  'True
  Persistable = 0  'NotPersistable
  DataBindingBehavior = 0  'vbNone
  DataSourceBehavior  = 0  'vbNone
  MTSTransactionMode  = 0  'NotAnMTSObject
END
Attribute VB_Name = "clsCheckRevision"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = True
Attribute VB_PredeclaredId = False
Attribute VB_Exposed = False
'THIS MODULE IS UNFINISHED

'---------------------------------------------------------------------------------------
' Module    : clsCheckRevision
' Date      : 6/19/2004
' Author    : YobGuls
' Purpose   : The Visual Basic equivalent of Blizzard's CheckRevision() function which
'             can be found in the IX86ver?.mpq, PMACver?.mpq and XMACver?.mpq files.
'             CheckRevision() returns the product's version information to Battle.net
'             to ensure that you're running the most up-to-date version of their
'             software.
'---------------------------------------------------------------------------------------

Option Explicit

Private Declare Function GetFileTime Lib "kernel32" (ByVal hFile As Long, lpCreationTime As FILETIME, lpLastAccessTime As FILETIME, lpLastWriteTime As FILETIME) As Long
Private Declare Function FileTimeToSystemTime Lib "Kernel32.dll" (lpFileTime As FILETIME, lpSystemTime As SYSTEMTIME) As Long
Private Declare Function GetFileVersionInfoA Lib "version.dll" (ByVal lptstrFilename As String, ByVal dwHandle As Long, ByVal dwLen As Long, lpData As Any) As Long
Private Declare Function GetFileVersionInfoSizeA Lib "version.dll" (ByVal lptstrFilename As String, lpdwHandle As Long) As Long
Private Declare Function VerQueryValueA Lib "version.dll" (pBlock As Any, ByVal lpSubBlock As String, ByVal lplpBuffer As Long, puLen As Long) As Long

Private Const GENERIC_READ = &H80000000
Private Const FILE_SHARE_READ = &H1
Private Const OPEN_EXISTING = &H3
Private Const FILE_ATRIBUTE_NORMAL = &H128
Private Const INVALID_HANDLE_VALUE = &HFFFFFFFF
Private Const PAGE_READONLY = &H2
Private Const FILE_MAP_READ = &H4

Public Function CheckRevision(ByVal Executable As String, ByVal NetworkProvider As String, ByVal GeneralLibrary As String, ByVal HashCommand As String, ByRef Version As Long, ByRef Checksum As Long, ByRef ExecutableInformation As String, ByVal MPQFileName As String) As Boolean
'IX86ver7.mpq
'A=128925409 B=948711417 C=1037466657 4 A=A+S B=B+C C=C^A A=A+B
Dim clsFunctions As New clsFunctions

Dim lpszFileNames(3) As String, lpszFileName As String, s As String, arrBuffer() As Byte, cOperations(16) As String
Dim nHashFile As Integer, nVariable1(16) As Integer, nVariable2(16) As Integer, nVariable3(16) As Integer, nVariable As Integer, i As Integer, k As Integer, nHashOperations As Integer
Dim dwTotalSize As Long, dwSize As Long, j As Long, dwBytesRead As Long, dwVariables(4) As Long, dwMpqChecksumKeys(8) As Long, dwMpqKey As Long, lpdwBuffer As Long, hFile As Long, hFileMapping As Long

dwMpqChecksumKeys(0) = &HE7F4CB62
dwMpqChecksumKeys(1) = &HF6A14FFC
dwMpqChecksumKeys(2) = &HAA5504AF
dwMpqChecksumKeys(3) = &H871FCDC2
dwMpqChecksumKeys(4) = &H11BF6A18
dwMpqChecksumKeys(5) = &HC57292E6
dwMpqChecksumKeys(6) = &H7927D27E
dwMpqChecksumKeys(7) = &H2FEC8733

nHashFile = Int(Mid$(MPQFileName, 8, 1))
If nHashFile < 0 Or nHashFile > 7 Then
    Exit Function
End If
dwMpqKey = dwMpqChecksumKeys(nHashFile)
lpszFileNames(0) = Executable
lpszFileNames(1) = NetworkProvider
lpszFileNames(2) = GeneralLibrary

s = HashCommand
i = 1
While Len(s) > 0
    Dim tmpData As String
    tmpData = Mid$(s, 1, 1)
    If IsNumeric(tmpData) = False Then
        nVariable = CInt(Asc(UCase(tmpData)) - &H41)
    Else
        nHashOperations = CInt(Asc(tmpData) - &H30)
        s = Mid$(s, InStr(s, " ") + 1)
        If (s = vbNullString) Then
            Exit Function
        End If
        GoTo Break1
    End If
    If Mid$(s, i + 1, 1) = "=" Then
        i = i + 2
    End If
    dwVariables(nVariable) = CDbl(Mid$(s, i, InStr(Mid$(s, i), " ")))
    s = Mid$(s, InStr(s, " ") + 1)
    If (s = vbNullString) Then
        Exit Function
    End If
    i = 1
Wend

Break1:

For i = 0 To nHashOperations - 1
    tmpData = Mid$(s, 1, 1)
    If IsNumeric(tmpData) = True Then
        Exit Function
    End If
    nVariable1(i) = Asc(UCase$(tmpData)) - &H41
    If Mid$(s, 2, 1) = "=" Then
        s = Mid$(s, 3)
    End If
    tmpData = Mid$(s, 1, 1)
    If Asc(UCase$(tmpData)) = &H53 Then
        nVariable2(i) = 3
    Else
        nVariable2(i) = Asc(UCase$(tmpData)) - &H41
        cOperations(i) = Asc(Mid$(s, 2, 1))
        s = Mid$(s, 3)
    End If
    tmpData = Mid$(s, 1, 1)
    If Asc(UCase$(tmpData)) = &H53 Then
        nVariable3(i) = 3
    Else
        nVariable3(i) = Asc(UCase$(tmpData)) - &H41
        s = Mid$(s, InStr(s, " ") + 1)
    End If
    If s = vbNullString Then
        GoTo Break2
    End If
    s = Mid$(s, 3)
Next i

Break2:

dwVariables(0) = dwVariables(0) Xor dwMpqKey

For i = 0 To 3 Step 1
    Open lpszFileNames(i) For Binary Access Read As #1
        ReDim arrBuffer(0 To LOF(1))
        Get #1, , arrBuffer
    Close #1
    dwSize = (FileLen(lpszFileNames(i)) / 1024) * 1024
    For j = 0 To (dwSize / 4) Step 1
        dwVariables(3) = arrBuffer(j)
        Debug.Print dwVariables(nVariable2(k)) & ":" & dwVariables(nVariable3(k))
        For k = 0 To nHashOperations Step 1
            Select Case cOperations(k)
                Case Asc("+")
                    dwVariables(nVariable1(k)) = dwVariables(nVariable2(k)) + dwVariables(nVariable3(k))
                Case Asc("-")
                    dwVariables(nVariable1(k)) = dwVariables(nVariable2(k)) - dwVariables(nVariable3(k))
                Case Asc("^")
                    dwVariables(nVariable1(k)) = dwVariables(nVariable2(k)) ^ dwVariables(nVariable3(k))
                Case Else
                    Exit Function
            End Select
        Next k
    Next j
Next i

lpszFileName = lpszFileNames(0)
dwSize = GetFileVersionInfoSizeA(lpszFileName, dwBytesRead)
'lpbBuffer = (LPBYTE) VirtualAlloc(NULL, dwSize, MEM_COMMIT, PAGE_READWRITE);
'if (lpbBuffer == NULL)
'   return FALSE;
'if (GetFileVersionInfo(lpszFileName, NULL, dwSize, lpbBuffer) == FALSE)
'   return FALSE;
'if (VerQueryValue(lpbBuffer, "\\", (LPVOID *) &ffi, (PUINT) &dwSize) == FALSE)
'   return FALSE;
'*lpdwVersion = ((HIWORD(ffi->dwProductVersionMS) & 0xFF) << 24) | ((LOWORD(ffi->dwProductVersionMS) & 0xFF) << 16) | ((HIWORD(ffi->dwProductVersionLS) & 0xFF) << 8) | (LOWORD(ffi->dwProductVersionLS) & 0xFF);
'VirtualFree(lpbBuffer, 0lu, MEM_RELEASE);
's = (char *) &lpszFileName[strlen(lpszFileName)-1];
'while (*s != '\\' && s > (char *) lpszFileName)
'   s--;
's++;
'sprintf(lpExeInfoString, "%s %02u/%02u/%02u %02u:%02u:%02u %lu", s, st.wMonth, st.wDay, st.wYear % 100, st.wHour, st.wMinute, st.wSecond, dwTotalSize);

Checksum = dwVariables(2)
CheckRevision = True
End Function
