• Welcome to Valhalla Legends Archive.
 

[VB6] MPQ Extraction... I think.

Started by RealityRipple, October 27, 2006, 02:36 PM

Previous topic - Next topic

RealityRipple

Recently, users of my bot have been getting Windows crash errors, which I eventually linked to the With object shortcut. Removing all of those, the crash mostly disappeared (still one when connecting on d1 for some people... I'm working on that). However, the users are now unable to extract the ver-iX86-#.dll from the MPQ. Before I go off and break things even more, I want to make sure this code works for other people. It works fine for me... but I'd appreciate if someone else confirmed this should work:
Option Explicit
Private Type OVERLAPPED
    Internal     As Long
    InternalHigh As Long
    offset       As Long
    OffsetHigh   As Long
    hEvent       As Long
End Type
Private Declare Function SFileCloseArchive Lib "Storm.dll" Alias "#252" (ByVal hMPQ As Long) As Boolean
Private Declare Function SFileCloseFile Lib "Storm.dll" Alias "#253" (ByVal hFile As Long) As Boolean
Private Declare Function SFileDestroy Lib "Storm.dll" Alias "#262" () As Boolean
Private Declare Function SFileGetFileSize Lib "Storm.dll" Alias "#265" (ByVal hFile As Long, ByRef lpFileSizeHigh As Long) As Long
Private Declare Function SFileOpenArchive Lib "Storm.dll" Alias "#266" (ByVal lpFileName As String, ByVal dwPriority As Long, ByVal dwFlags As Long, ByRef hMPQ As Long) As Boolean
Private Declare Function SFileOpenFileEx Lib "Storm.dll" Alias "#268" (ByVal hMPQ As Long, ByVal lpFileName As String, ByVal dwSearchScope As Long, ByRef hFile As Long) As Boolean
Private Declare Function SFileReadFile Lib "Storm.dll" Alias "#269" (ByVal hFile As Long, lpBuffer As Byte, ByVal nNumberOfBYTEsToRead As Long, ByRef lpNumberOfBYTEsRead As Long, lpOverlapped As OVERLAPPED) As Boolean
Private Declare Function SFileSetLocale Lib "Storm.dll" Alias "#272" (ByVal nNewLocale As Long) As Long
Private Declare Function SFileAuthenticateArchive Lib "Storm.dll" Alias "#251" (ByVal hMPQ As Long, ByRef dwAuthenticationStatus As Long) As Boolean
Private Declare Function WriteFile Lib "kernel32" (ByVal hFile As Long, lpBuffer As Any, ByVal nNumberOfBytesToWrite As Long, lpNumberOfBytesWritten As Long, lpOverlapped As OVERLAPPED) As Long
Public Function ExtractFromMPQ(ByVal strArchive As String, ByVal strFile As String) As String
Dim hMPQ       As Long
Dim hFile      As Long
Dim hOutput    As Long
Dim lngSize    As Long
Dim dwBytes    As Long
Dim szBuffer() As Byte
Dim Status     As Long
Dim Overlap    As OVERLAPPED
    SFileDestroy
    SFileSetLocale GetRegionDWord
    SFileOpenArchive App.Path & "\MPQs\" & strArchive, 0, 0, hMPQ
    SFileOpenFileEx hMPQ, strFile, 0, hFile
    SFileAuthenticateArchive hMPQ, Status
    If Status = &H0 Or Status = &H1 Or Status = &H5 Then
        lngSize = SFileGetFileSize(hFile, 0)
        ReDim szBuffer(0 To lngSize)
        SFileReadFile hFile, szBuffer(0), lngSize, dwBytes, Overlap
        If dwBytes <> lngSize Then
            ExtractFromMPQ = "MPQ Corrupt (" & dwBytes & " / " & lngSize & ")"
            GoTo Failed
        End If
        If Dir$(App.Path & "\MPQs\" & strFile) <> vbNullString Then Kill App.Path & "\MPQs\" & strFile
        hOutput = CreateFile(App.Path & "\MPQs\" & strFile, &H40000000, &H2, ByVal 0&, &H2, ByVal 0&, ByVal 0&)
        WriteFile hOutput, szBuffer(0), lngSize, dwBytes, Overlap
        CloseHandle hOutput
        If dwBytes <> lngSize Then
            ExtractFromMPQ = "DLL Corrupt (" & dwBytes & " / " & lngSize & ")"
            GoTo Failed
        End If
        SFileCloseFile hFile
        SFileCloseArchive hMPQ
        SetFileTimeInfo App.Path & "\MPQs\" & strFile, GetFileTimeInfo(App.Path & "\MPQs\" & strArchive), GetFileTimeInfo(App.Path & "\MPQs\" & strArchive), GetFileTimeInfo(App.Path & "\MPQs\" & strArchive)
        ExtractFromMPQ = "OK"
    Else
        ExtractFromMPQ = "MPQ not authentic"
    End If
    Exit Function
Failed:
    If hFile <> 0 Then SFileCloseFile hFile
    If hMPQ <> 0 Then SFileCloseArchive hMPQ
End Function


Am I doing anything that would cause problems here? One user is getting the DLL Corrupt error, the other just gets a DLL of zero bytes. Any help on this matter would be appreciated.

Edit: CreateFile and CloseHandle are defined elsewhere in my EXE, they're not missing.
Edit#2: I've tested this with WAR3's storm, STAR's storm, and SSHR's storm. All work for me, none work for the users with problems.

Hero

SSPN = ?

And I'll test it in a second.

RealityRipple

#2
Sorry, that should be SSHR, not SSPN. I'm a bit tired... working on it all night.

Edited the code a bit:

Option Explicit
Private Declare Function SFileCloseArchive Lib "Storm.dll" Alias "#252" (ByVal hMPQ As Long) As Boolean
Private Declare Function SFileCloseFile Lib "Storm.dll" Alias "#253" (ByVal hFile As Long) As Boolean
Private Declare Function SFileDestroy Lib "Storm.dll" Alias "#262" () As Boolean
Private Declare Function SFileGetFileSize Lib "Storm.dll" Alias "#265" (ByVal hFile As Long, ByRef lpFileSizeHigh As Long) As Long
Private Declare Function SFileOpenArchive Lib "Storm.dll" Alias "#266" (ByVal lpFileName As String, ByVal dwPriority As Long, ByVal dwFlags As Long, ByRef hMPQ As Long) As Boolean
Private Declare Function SFileOpenFileEx Lib "Storm.dll" Alias "#268" (ByVal hMPQ As Long, ByVal lpFileName As String, ByVal dwSearchScope As Long, ByRef hFile As Long) As Boolean
Private Declare Function SFileReadFile Lib "Storm.dll" Alias "#269" (ByVal hFile As Long, lpBuffer As Byte, ByVal nNumberOfBYTEsToRead As Long, ByRef lpNumberOfBYTEsRead As Long, lpOverlapped As Long) As Boolean
Private Declare Function SFileAuthenticateArchive Lib "Storm.dll" Alias "#251" (ByVal hMPQ As Long, ByRef dwAuthenticationStatus As Long) As Boolean
Private Declare Function WriteFile Lib "kernel32" (ByVal hFile As Long, lpBuffer As Any, ByVal nNumberOfBytesToWrite As Long, lpNumberOfBytesWritten As Long, lpOverlapped As Long) As Long
Dim hMPQ       As Long
Dim hFile      As Long
Dim hOutput    As Long
Dim lngSize    As Long
Dim dwBytes    As Long
Dim szBuffer() As Byte
Dim Status     As Long
    SFileDestroy
    SFileOpenArchive App.Path & "\MPQs\" & strArchive, 0, 0, hMPQ
    SFileOpenFileEx hMPQ, strFile, 0, hFile
    SFileAuthenticateArchive hMPQ, Status
    If Status = &H0 Or Status = &H1 Or Status = &H5 Then
        lngSize = SFileGetFileSize(hFile, 0)
        ReDim szBuffer(0 To lngSize)
        SFileReadFile hFile, szBuffer(0), lngSize, dwBytes, ByVal 0&
        If dwBytes <> lngSize Then
            ExtractFromMPQ = "MPQ Corrupt (" & dwBytes & " / " & lngSize & ")"
            GoTo Failed
        End If
        If Dir$(App.Path & "\MPQs\" & strFile) <> vbNullString Then Kill App.Path & "\MPQs\" & strFile
        hOutput = CreateFile(App.Path & "\MPQs\" & strFile, &H40000000, &H2, ByVal 0&, &H2, ByVal 0&, ByVal 0&)
        WriteFile hOutput, szBuffer(0), lngSize, dwBytes, ByVal 0&
        CloseHandle hOutput
        If dwBytes <> lngSize Then
            ExtractFromMPQ = "DLL Corrupt (" & dwBytes & " / " & lngSize & ")"
            GoTo Failed
        End If
        SFileCloseFile hFile
        SFileCloseArchive hMPQ
        SetFileTimeInfo App.Path & "\MPQs\" & strFile, GetFileTimeInfo(App.Path & "\MPQs\" & strArchive), GetFileTimeInfo(App.Path & "\MPQs\" & strArchive), GetFileTimeInfo(App.Path & "\MPQs\" & strArchive)
        ExtractFromMPQ = "OK"
    Else
        ExtractFromMPQ = "MPQ not authentic"
    End If
    Exit Function
Failed:
    If hFile <> 0 Then SFileCloseFile hFile
    If hMPQ <> 0 Then SFileCloseArchive hMPQ
End Function


Removed SetLocale, since it seems completely useless here. Got rid of Overlapped as l2k-Shadow's post (which seems to have disappeared) recommended.

topaz

RLY...?

RealityRipple

Ya, I had to fix the With Packet issue that caused a windows crash on some computers. Took 2 days to find out what caused it, 2 hours to replace them all correctly, and it still crashes on d1 clients sometimes. I spent the rest of the night looking over all the code in my program, testing different versions of different files, uploading (on dial up) new files so other people could download them, get errors, and try to tell me what went wrong. Fixing a problem you don't have, can't recreate, and can't get a good debug on is hell.

Kp

Quote from: RealityRipple on October 27, 2006, 05:57 PM
Ya, I had to fix the With Packet issue that caused a windows crash on some computers. Took 2 days to find out what caused it, 2 hours to replace them all correctly, and it still crashes on d1 clients sometimes. I spent the rest of the night looking over all the code in my program, testing different versions of different files, uploading (on dial up) new files so other people could download them, get errors, and try to tell me what went wrong. Fixing a problem you don't have, can't recreate, and can't get a good debug on is hell.

Am I reading this correctly that a "With Packet { blah } End Width" construct in Visual Basic was causing people's computers to BSoD?

Why's it take two hours to clean that all up?  You should be able to write some quick macros in your favorite text editor to automate most of it.

As for fixing: welcome to software development. :)
[19:20:23] (BotNet) <[vL]Kp> Any idiot can make a bot with CSB, and many do!

RealityRipple

Not BSOD. Just a windows crash message... Windows 9x's "illegal operation" or NT/XP's  "Report Error" message. But ya, that's what was causing it. I'm not a fan of automatic stuff... I prefer to do things manually. And thanks -.-

RealityRipple

Well, it seems to have disappeared. Probably the removal of overlapped. How odd...

NetNX

Quote from: Kp on October 27, 2006, 07:08 PM
Quote from: RealityRipple on October 27, 2006, 05:57 PM
Ya, I had to fix the With Packet issue that caused a windows crash on some computers. Took 2 days to find out what caused it, 2 hours to replace them all correctly, and it still crashes on d1 clients sometimes. I spent the rest of the night looking over all the code in my program, testing different versions of different files, uploading (on dial up) new files so other people could download them, get errors, and try to tell me what went wrong. Fixing a problem you don't have, can't recreate, and can't get a good debug on is hell.

Am I reading this correctly that a "With Packet { blah } End Width" construct in Visual Basic was causing people's computers to BSoD?

Why's it take two hours to clean that all up?  You should be able to write some quick macros in your favorite text editor to automate most of it.

As for fixing: welcome to software development. :)

Well i assume that i assume ripple chat is his creation... a few weeks ago i happened to see a copy of that source on bnetweb if this is his bot i can understand why he would have problems correcting these mistakes.

MyndFyre

I see you're using Storm.  It's my understanding that the Storm library has memory leaks and the such that make it impractical to use.  I highly recommend using SFMPQ.dll, written by a guy called ShadowFlare.  This is what I use in my 2.0 beta of MBNCSUtil.

If you Google for SFMPQ, you'll find it.  His homepage is called "ShadowFlare's realm".
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.

topaz

Quote from: MyndFyre[vL] on November 01, 2006, 11:26 AM
I see you're using Storm.  It's my understanding that the Storm library has memory leaks and the such that make it impractical to use.  I highly recommend using SFMPQ.dll, written by a guy called ShadowFlare.  This is what I use in my 2.0 beta of MBNCSUtil.

If you Google for SFMPQ, you'll find it.  His homepage is called "ShadowFlare's realm".

IIRC, the memory leaks only occur when you call checkrevision
RLY...?

Ersan

What else would you use this for...

topaz

Quote from: Ersan on November 03, 2006, 03:30 PM
What else would you use this for...

There are like two hundredfjfja billion other files available in the MPQs, mostly modals/images. You can use SFmpq to generate a list of them.
RLY...?