Author | Message | Time |
---|---|---|
BreW | The following code works just fine when extracting anything from starcraft maps, but SFileOpenArchive seems to fail when trying to extract anything else (for example, ExtraWork dlls, unless they don't have (listfile)s) and files within internal directories. Can anyone see what seems to be the problem? [code] void ExtractMPQ(char *filename, char *toget) { HMODULE hLibStorm = LoadLibrary("Storm.dll"); FILE *file; char *asdf; unsigned long hMPQ, hMPQFile, filesize, highdword; unsigned long SFileDestroy = (unsigned long)GetProcAddress(hLibStorm, MAKEINTRESOURCE(262)); unsigned long SFileSetLocale = (unsigned long)GetProcAddress(hLibStorm, MAKEINTRESOURCE(272)); unsigned long SFileOpenArchive = (unsigned long)GetProcAddress(hLibStorm, MAKEINTRESOURCE(266)); unsigned long SFileOpenFileEx = (unsigned long)GetProcAddress(hLibStorm, MAKEINTRESOURCE(268)); unsigned long SFileGetFileSize = (unsigned long)GetProcAddress(hLibStorm, MAKEINTRESOURCE(265)); unsigned long SFileReadFile = (unsigned long)GetProcAddress(hLibStorm, MAKEINTRESOURCE(269)); unsigned long SFileCloseFile = (unsigned long)GetProcAddress(hLibStorm, MAKEINTRESOURCE(253)); unsigned long SFileCloseArchive = (unsigned long)GetProcAddress(hLibStorm, MAKEINTRESOURCE(252)); __asm { push 'enUS' call SFileSetLocale test eax, eax jz errored call SFileDestroy test eax, eax jz errored lea eax, [hMPQ] push eax push 0 push 0 mov eax, filename push eax call SFileOpenArchive test eax, eax jz errored lea eax, [hMPQFile] push eax push 0 push toget push hMPQ call SFileOpenFileEx test eax, eax jz errored lea eax, [highdword] push eax push hMPQFile call SFileGetFileSize mov filesize, eax cmp eax, -1 je errored push eax call malloc pop ecx mov asdf, eax push 0 push 0 push filesize push eax push hMPQFile call SFileReadFile test eax, eax jz errored push '\\' push toget call strchr add esp, 8 mov ecx, toget test eax, eax jz over mov ecx, eax inc ecx over: mov highdword, 'bw' lea eax, [highdword] push eax push ecx call fopen mov file, eax add esp, 8 push eax push filesize push 1 push asdf call fwrite add esp, 10h push file call fclose pop ecx push asdf call free pop ecx push hMPQFile call SFileCloseFile test eax, eax jz errored push hMPQ call SFileCloseArchive test eax, eax jz errored push hLibStorm call dword ptr [FreeLibrary] } return; errored: AddChat(vbRed, "ExtractMPQ Failed!"); return; } ... ExtractMPQ("C:\\Documents and Settings\\Owner\\Desktop\\IX86Mindsight.mpq", "(listfile)"); [/code] | March 25, 2008, 1:10 AM |
Barabajagal | If it's any help, here's my VB code which seems to work just fine: [code]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 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 On Error GoTo Erred SFileDestroy SFileOpenArchive SettingsFolder & "\Tmp\MPQs\" & strArchive, 0, 0, hMPQ SFileOpenFileEx hMPQ, strFile, 0, hFile If hFile <> 0 Then 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 &H0 If dwBytes <> lngSize Then ExtractFromMPQ = "MPQ Corrupt (" & dwBytes & " / " & lngSize & ")" GoTo Failed End If If LenB(Dir$(SettingsFolder & "\Tmp\MPQs\" & strFile)) > 0 Then Kill SettingsFolder & "\Tmp\MPQs\" & strFile hOutput = CreateFileA(SettingsFolder & "\Tmp\MPQs\" & strFile, &H40000000, &H2, ByVal 0&, &H2, ByVal 0&, ByVal 0&) WriteFile hOutput, szBuffer(0), lngSize, dwBytes, ByVal &H0 CloseHandle hOutput If dwBytes <> lngSize Then ExtractFromMPQ = "DLL Corrupt (" & dwBytes & " / " & lngSize & ")" GoTo Failed End If SFileCloseFile hFile SFileCloseArchive hMPQ SetFileTimeInfo SettingsFolder & "\Tmp\MPQs\" & strFile, GetFileTimeInfo(SettingsFolder & "\Tmp\MPQs\" & strArchive), GetFileTimeInfo(SettingsFolder & "\Tmp\MPQs\" & strArchive), GetFileTimeInfo(SettingsFolder & "\Tmp\MPQs\" & strArchive) ExtractFromMPQ = "OK" Else ExtractFromMPQ = "MPQ not authentic" End If Else ExtractFromMPQ = "Could not find " & strFile & " in " & strArchive End If SFileDestroy Exit Function Failed: If hFile <> 0 Then SFileCloseFile hFile If hMPQ <> 0 Then SFileCloseArchive hMPQ Exit Function Erred: ExtractFromMPQ = Err.Description GoTo Failed End Function[/code] | March 25, 2008, 5:59 PM |
BreW | Actually, now that I look at it today, my own works just fine as well... mmm, idk. So, better question: How would I get at those files inside of an internal directory? Would I have to call another storm function to change the current directory or something? Passing the raw filename and path to the lib doesn't seem to work. | March 25, 2008, 7:56 PM |
Barabajagal | I... never got that far. But if I had to guess, I'd say SFileSetBasePath. | March 25, 2008, 10:30 PM |
BreW | Hm, I wonder what the params are for that? I guess i'll check what battle.snp does... EDIT** Oops! I just realized, since when would battle.snp need that functionality? Hmm, i guess i'll check starcraft.exe. EDIT*** Well, starcraft.exe doesn't call it either. Apparently it passes the filename just like that? [code] .text:004CC3A4 loc_4CC3A4: ; CODE XREF: sub_4CC320+5A .text:004CC3A4 push 104h .text:004CC3A9 push offset aStareditScenar ; "staredit\\scenario.chk" .text:004CC3AE lea ecx, [ebp+var_20C] .text:004CC3B4 push ecx .text:004CC3B5 call SStrNCpy .text:004CC3BA .text:004CC3BA loc_4CC3BA: ; CODE XREF: sub_4CC320+82 .text:004CC3BA push 88Bh .text:004CC3BF push offset aStarcraftSw_66 ; "Starcraft\\SWAR\\lang\\maphdr.cpp" .text:004CC3C4 push 1 .text:004CC3C6 push 0 .text:004CC3C8 lea edx, [ebp+var_20C] .text:004CC3CE push edx ; effectively contains staredit\scenario.chk .text:004CC3CF xor ecx, ecx .text:004CC3D1 lea eax, [ebp+var_4] .text:004CC3D4 call loc_4D2940 .text:004D2940 push ebp .text:004D2941 mov ebp, esp .text:004D2943 push ecx .text:004D2944 push ebx .text:004D2945 push esi .text:004D2946 mov esi, [ebp+8] .text:004D2949 mov ebx, eax .text:004D294B lea eax, [ebp-4] .text:004D294E push eax ; phFile .text:004D294F push ecx ; "int" .text:004D2950 push esi ; filename .text:004D2951 push 0 ; hArchive .text:004D2953 call SFileOpenFileEx [/code] ...and look at that. all of my mpq archive extracting woes are gone. | March 26, 2008, 12:34 AM |
Barabajagal | double backslash ftw. I'll have to make a note of that, just in case... | March 26, 2008, 1:51 AM |
NicoQwertyu | [quote author=Andy link=topic=17407.msg177272#msg177272 date=1206496284] double backslash ftw. I'll have to make a note of that, just in case... [/quote] AFAIK the double backslash is a language specific rule; you don't need to worry about it with VB. | March 26, 2008, 3:23 AM |
UserLoser | [quote author=brew link=topic=17407.msg177266#msg177266 date=1206475019] Actually, now that I look at it today, my own works just fine as well... mmm, idk. So, better question: How would I get at those files inside of an internal directory? Would I have to call another storm function to change the current directory or something? Passing the raw filename and path to the lib doesn't seem to work. [/quote] keep in mind your project in whatever IDE you're using might not have the same running location ('current directory') as your files so you have to include the whole path (or a part of it) | March 26, 2008, 8:20 PM |
Hex | this program uses Storm Library and SFMPQ Library. Programmed in VC++ 6.0 Unused Unprotector 2 Source code. Link: http://sunrub.dothome.co.kr/Unused_Unprotector_2_source.zip | April 28, 2008, 6:48 AM |