diff options
author | Shauren <shauren.trinity@gmail.com> | 2017-08-17 17:31:02 +0200 |
---|---|---|
committer | Shauren <shauren.trinity@gmail.com> | 2017-08-17 17:31:02 +0200 |
commit | 3f3991362848d80721dc8f4607518a9e451b60ad (patch) | |
tree | c82ad06fef28508be3e2847f7ad643cf26bd55d1 /dep/CascLib | |
parent | 43d268d75c8b5afae94983f19363ac0e484e4afb (diff) |
Dep/CascLib: Update to ladislav-zezula/CascLib@fb9442155352b36e56b74a6c0d265b3b62d20e3a
Diffstat (limited to 'dep/CascLib')
-rw-r--r-- | dep/CascLib/CMakeLists.txt | 1 | ||||
-rw-r--r-- | dep/CascLib/src/CascCommon.h | 2 | ||||
-rw-r--r-- | dep/CascLib/src/CascDecrypt.cpp | 53 | ||||
-rw-r--r-- | dep/CascLib/src/CascFiles.cpp | 1 | ||||
-rw-r--r-- | dep/CascLib/src/CascLib.h | 3 | ||||
-rw-r--r-- | dep/CascLib/src/CascOpenStorage.cpp | 32 | ||||
-rw-r--r-- | dep/CascLib/src/CascPort.h | 1 | ||||
-rw-r--r-- | dep/CascLib/src/CascReadFile.cpp | 2 | ||||
-rw-r--r-- | dep/CascLib/src/CascRootFile_Mndx.cpp | 15 | ||||
-rw-r--r-- | dep/CascLib/src/CascRootFile_SC1.cpp | 216 |
10 files changed, 289 insertions, 37 deletions
diff --git a/dep/CascLib/CMakeLists.txt b/dep/CascLib/CMakeLists.txt index 3c3755a2590..a649d33016a 100644 --- a/dep/CascLib/CMakeLists.txt +++ b/dep/CascLib/CMakeLists.txt @@ -32,6 +32,7 @@ set(SRC_FILES src/CascRootFile_Diablo3.cpp src/CascRootFile_Mndx.cpp src/CascRootFile_Ovr.cpp + src/CascRootFile_SC1.cpp src/CascRootFile_WoW6.cpp ) diff --git a/dep/CascLib/src/CascCommon.h b/dep/CascLib/src/CascCommon.h index e7a9d6b5464..e38094171b8 100644 --- a/dep/CascLib/src/CascCommon.h +++ b/dep/CascLib/src/CascCommon.h @@ -45,6 +45,7 @@ #define CASC_GAME_DIABLO3 0x00030000 // Diablo 3 since PTR 2.2.0 #define CASC_GAME_OVERWATCH 0x00040000 // Overwatch since PTR 24919 #define CASC_GAME_STARCRAFT2 0x00050000 // Starcraft II - Legacy of the Void, since build 38996 +#define CASC_GAME_STARCRAFT1 0x00060000 // Starcraft 1 (remastered) #define CASC_GAME_MASK 0xFFFF0000 // Mask for getting game ID #define CASC_INDEX_COUNT 0x10 @@ -345,6 +346,7 @@ int RootHandler_CreateMNDX(TCascStorage * hs, LPBYTE pbRootFile, DWORD cbRootFil int RootHandler_CreateDiablo3(TCascStorage * hs, LPBYTE pbRootFile, DWORD cbRootFile); int RootHandler_CreateOverwatch(TCascStorage * hs, LPBYTE pbRootFile, DWORD cbRootFile); int RootHandler_CreateWoW6(TCascStorage * hs, LPBYTE pbRootFile, DWORD cbRootFile, DWORD dwLocaleMask); +int RootHandler_CreateSC1(TCascStorage * hs, LPBYTE pbRootFile, DWORD cbRootFile); //----------------------------------------------------------------------------- // Dumping CASC data structures diff --git a/dep/CascLib/src/CascDecrypt.cpp b/dep/CascLib/src/CascDecrypt.cpp index 4cf93f2854c..7e721c2c73c 100644 --- a/dep/CascLib/src/CascDecrypt.cpp +++ b/dep/CascLib/src/CascDecrypt.cpp @@ -58,29 +58,34 @@ static CASC_ENCRYPTION_KEY CascKeys[] = { 0xCAE3FAC925F20402ULL, { 0x98, 0xB7, 0x8E, 0x87, 0x74, 0xBF, 0x27, 0x50, 0x93, 0xCB, 0x1B, 0x5F, 0xC7, 0x14, 0x51, 0x1B } }, // (included in game) { 0x061581CA8496C80CULL, { 0xDA, 0x2E, 0xF5, 0x05, 0x2D, 0xB9, 0x17, 0x38, 0x0B, 0x8A, 0xA6, 0xEF, 0x7A, 0x5F, 0x8E, 0x6A } }, // { 0xBE2CB0FAD3698123ULL, { 0x90, 0x2A, 0x12, 0x85, 0x83, 0x6C, 0xE6, 0xDA, 0x58, 0x95, 0x02, 0x0D, 0xD6, 0x03, 0xB0, 0x65 } }, // - { 0x57A5A33B226B8E0AULL, { 0xFD, 0xFC, 0x35, 0xC9, 0x9B, 0x9D, 0xB1, 0x1A, 0x32, 0x62, 0x60, 0xCA, 0x24, 0x6A, 0xCB, 0x41 } }, // 1.1.0.0.30200 (Ana) - { 0x42B9AB1AF5015920ULL, { 0xC6, 0x87, 0x78, 0x82, 0x3C, 0x96, 0x4C, 0x6F, 0x24, 0x7A, 0xCC, 0x0F, 0x4A, 0x25, 0x84, 0xF8 } }, // 1.2.0.1.30684 (Summer Games) + { 0x57A5A33B226B8E0AULL, { 0xFD, 0xFC, 0x35, 0xC9, 0x9B, 0x9D, 0xB1, 0x1A, 0x32, 0x62, 0x60, 0xCA, 0x24, 0x6A, 0xCB, 0x41 } }, // 1.1.0.0.30200 Ana + { 0x42B9AB1AF5015920ULL, { 0xC6, 0x87, 0x78, 0x82, 0x3C, 0x96, 0x4C, 0x6F, 0x24, 0x7A, 0xCC, 0x0F, 0x4A, 0x25, 0x84, 0xF8 } }, // 1.2.0.1.30684 Summer Games { 0x4F0FE18E9FA1AC1AULL, { 0x89, 0x38, 0x1C, 0x74, 0x8F, 0x65, 0x31, 0xBB, 0xFC, 0xD9, 0x77, 0x53, 0xD0, 0x6C, 0xC3, 0xCD } }, // 1.2.0.1.30684 { 0x7758B2CF1E4E3E1BULL, { 0x3D, 0xE6, 0x0D, 0x37, 0xC6, 0x64, 0x72, 0x35, 0x95, 0xF2, 0x7C, 0x5C, 0xDB, 0xF0, 0x8B, 0xFA } }, // 1.2.0.1.30684 - { 0xE5317801B3561125ULL, { 0x7D, 0xD0, 0x51, 0x19, 0x9F, 0x84, 0x01, 0xF9, 0x5E, 0x4C, 0x03, 0xC8, 0x84, 0xDC, 0xEA, 0x33 } }, // 1.4.0.2.32143 (Halloween Terror) - { 0x16B866D7BA3A8036ULL, { 0x13, 0x95, 0xE8, 0x82, 0xBF, 0x25, 0xB4, 0x81, 0xF6, 0x1A, 0x4D, 0x62, 0x11, 0x41, 0xDA, 0x6E } }, // 1.4.1.0.31804 (Bastion Blizzcon 2016 skin) - { 0x11131FFDA0D18D30ULL, { 0xC3, 0x2A, 0xD1, 0xB8, 0x25, 0x28, 0xE0, 0xA4, 0x56, 0x89, 0x7B, 0x3C, 0xE1, 0xC2, 0xD2, 0x7E } }, // 1.5.0.1.32795 (Sombra) - { 0xCAC6B95B2724144AULL, { 0x73, 0xE4, 0xBE, 0xA1, 0x45, 0xDF, 0x2B, 0x89, 0xB6, 0x5A, 0xEF, 0x02, 0xF8, 0x3F, 0xA2, 0x60 } }, // 1.5.0.1.32795 (Ecopoint: Antarctica) - { 0xB7DBC693758A5C36ULL, { 0xBC, 0x3A, 0x92, 0xBF, 0xE3, 0x02, 0x51, 0x8D, 0x91, 0xCC, 0x30, 0x79, 0x06, 0x71, 0xBF, 0x10 } }, // 1.5.0.1.32795 (Genji Oni skin) - { 0x90CA73B2CDE3164BULL, { 0x5C, 0xBF, 0xF1, 0x1F, 0x22, 0x72, 0x0B, 0xAC, 0xC2, 0xAE, 0x6A, 0xAD, 0x8F, 0xE5, 0x33, 0x17 } }, // 1.6.1.0.33236 (Oasis map) + { 0xE5317801B3561125ULL, { 0x7D, 0xD0, 0x51, 0x19, 0x9F, 0x84, 0x01, 0xF9, 0x5E, 0x4C, 0x03, 0xC8, 0x84, 0xDC, 0xEA, 0x33 } }, // 1.4.0.2.32143 Halloween Terror + { 0x16B866D7BA3A8036ULL, { 0x13, 0x95, 0xE8, 0x82, 0xBF, 0x25, 0xB4, 0x81, 0xF6, 0x1A, 0x4D, 0x62, 0x11, 0x41, 0xDA, 0x6E } }, // 1.4.1.0.31804 Bastion Blizzcon 2016 skin + { 0x11131FFDA0D18D30ULL, { 0xC3, 0x2A, 0xD1, 0xB8, 0x25, 0x28, 0xE0, 0xA4, 0x56, 0x89, 0x7B, 0x3C, 0xE1, 0xC2, 0xD2, 0x7E } }, // 1.5.0.1.32795 Sombra + { 0xCAC6B95B2724144AULL, { 0x73, 0xE4, 0xBE, 0xA1, 0x45, 0xDF, 0x2B, 0x89, 0xB6, 0x5A, 0xEF, 0x02, 0xF8, 0x3F, 0xA2, 0x60 } }, // 1.5.0.1.32795 Ecopoint: Antarctica + { 0xB7DBC693758A5C36ULL, { 0xBC, 0x3A, 0x92, 0xBF, 0xE3, 0x02, 0x51, 0x8D, 0x91, 0xCC, 0x30, 0x79, 0x06, 0x71, 0xBF, 0x10 } }, // 1.5.0.1.32795 Genji Oni skin + { 0x90CA73B2CDE3164BULL, { 0x5C, 0xBF, 0xF1, 0x1F, 0x22, 0x72, 0x0B, 0xAC, 0xC2, 0xAE, 0x6A, 0xAD, 0x8F, 0xE5, 0x33, 0x17 } }, // 1.6.1.0.33236 Oasis map { 0x6DD3212FB942714AULL, { 0xE0, 0x2C, 0x16, 0x43, 0x60, 0x2E, 0xC1, 0x6C, 0x3A, 0xE2, 0xA4, 0xD2, 0x54, 0xA0, 0x8F, 0xD9 } }, // 1.6.1.0.33236 - { 0x11DDB470ABCBA130ULL, { 0x66, 0x19, 0x87, 0x66, 0xB1, 0xC4, 0xAF, 0x75, 0x89, 0xEF, 0xD1, 0x3A, 0xD4, 0xDD, 0x66, 0x7A } }, // 1.6.1.0.33236 (Winter Wonderland) + { 0x11DDB470ABCBA130ULL, { 0x66, 0x19, 0x87, 0x66, 0xB1, 0xC4, 0xAF, 0x75, 0x89, 0xEF, 0xD1, 0x3A, 0xD4, 0xDD, 0x66, 0x7A } }, // 1.6.1.0.33236 Winter Wonderland { 0x5BEF27EEE95E0B4BULL, { 0x36, 0xBC, 0xD2, 0xB5, 0x51, 0xFF, 0x1C, 0x84, 0xAA, 0x3A, 0x39, 0x94, 0xCC, 0xEB, 0x03, 0x3E } }, // - { 0x9359B46E49D2DA42ULL, { 0x17, 0x3D, 0x65, 0xE7, 0xFC, 0xAE, 0x29, 0x8A, 0x93, 0x63, 0xBD, 0x6A, 0xA1, 0x89, 0xF2, 0x00 } }, // (Diablo's 20th anniversary) - { 0x1A46302EF8896F34ULL, { 0x80, 0x29, 0xAD, 0x54, 0x51, 0xD4, 0xBC, 0x18, 0xE9, 0xD0, 0xF5, 0xAC, 0x44, 0x9D, 0xC0, 0x55 } }, // 1.7.0.2.34156 (Year of the Rooster) - { 0x693529F7D40A064CULL, { 0xCE, 0x54, 0x87, 0x3C, 0x62, 0xDA, 0xA4, 0x8E, 0xFF, 0x27, 0xFC, 0xC0, 0x32, 0xBD, 0x07, 0xE3 } }, // 1.8.0.0.34470 - { 0x388B85AEEDCB685DULL, { 0xD9, 0x26, 0xE6, 0x59, 0xD0, 0x4A, 0x09, 0x6B, 0x24, 0xC1, 0x91, 0x51, 0x07, 0x6D, 0x37, 0x9A } }, // 1.8.0.0.34470 - { 0xE218F69AAC6C104DULL, { 0xF4, 0x3D, 0x12, 0xC9, 0x4A, 0x9A, 0x52, 0x84, 0x97, 0x97, 0x1F, 0x1C, 0xBE, 0x41, 0xAD, 0x4D } }, // 1.9.0.0.34986 - { 0xF432F0425363F250ULL, { 0xBA, 0x69, 0xF2, 0xB3, 0x3C, 0x27, 0x68, 0xF5, 0xF2, 0x9B, 0xFE, 0x78, 0xA5, 0xA1, 0xFA, 0xD5 } }, // 1.10.0.0.35455 cmf - { 0x061D52F86830B35DULL, { 0xD7, 0x79, 0xF9, 0xC6, 0xCC, 0x9A, 0x4B, 0xE1, 0x03, 0xA4, 0xE9, 0x0A, 0x73, 0x38, 0xF7, 0x93 } }, // 1.10.0.0.35455 cmf + { 0x9359B46E49D2DA42ULL, { 0x17, 0x3D, 0x65, 0xE7, 0xFC, 0xAE, 0x29, 0x8A, 0x93, 0x63, 0xBD, 0x6A, 0xA1, 0x89, 0xF2, 0x00 } }, // Diablo's 20th anniversary + { 0x1A46302EF8896F34ULL, { 0x80, 0x29, 0xAD, 0x54, 0x51, 0xD4, 0xBC, 0x18, 0xE9, 0xD0, 0xF5, 0xAC, 0x44, 0x9D, 0xC0, 0x55 } }, // 1.7.0.2.34156 Year of the Rooster + { 0x693529F7D40A064CULL, { 0xCE, 0x54, 0x87, 0x3C, 0x62, 0xDA, 0xA4, 0x8E, 0xFF, 0x27, 0xFC, 0xC0, 0x32, 0xBD, 0x07, 0xE3 } }, // 1.8.0.0.34470 CTF Maps + { 0x388B85AEEDCB685DULL, { 0xD9, 0x26, 0xE6, 0x59, 0xD0, 0x4A, 0x09, 0x6B, 0x24, 0xC1, 0x91, 0x51, 0x07, 0x6D, 0x37, 0x9A } }, // 1.8.0.0.34470 Numbani Update (Doomfist teaser) + { 0xE218F69AAC6C104DULL, { 0xF4, 0x3D, 0x12, 0xC9, 0x4A, 0x9A, 0x52, 0x84, 0x97, 0x97, 0x1F, 0x1C, 0xBE, 0x41, 0xAD, 0x4D } }, // 1.9.0.0.34986 Orisa + { 0xF432F0425363F250ULL, { 0xBA, 0x69, 0xF2, 0xB3, 0x3C, 0x27, 0x68, 0xF5, 0xF2, 0x9B, 0xFE, 0x78, 0xA5, 0xA1, 0xFA, 0xD5 } }, // 1.10.0.0.35455 Uprising + { 0x061D52F86830B35DULL, { 0xD7, 0x79, 0xF9, 0xC6, 0xCC, 0x9A, 0x4B, 0xE1, 0x03, 0xA4, 0xE9, 0x0A, 0x73, 0x38, 0xF7, 0x93 } }, // 1.10.0.0.35455 D.Va Officer Skin (HotS Nexus Challenge 2) { 0x1275C84CF113EF65ULL, { 0xCF, 0x58, 0xB6, 0x93, 0x3E, 0xAF, 0x98, 0xAF, 0x53, 0xE7, 0x6F, 0x84, 0x26, 0xCC, 0x7E, 0x6C } }, // { 0xD9C7C7AC0F14C868ULL, { 0x3A, 0xFD, 0xF6, 0x8E, 0x3A, 0x5D, 0x63, 0xBA, 0xBA, 0x1E, 0x68, 0x21, 0x88, 0x3F, 0x06, 0x7D } }, // - // {0xBD4E42661A432951ULL, {0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??}}, // 1.11.0.0.36376 (Unknown event) + { 0xBD4E42661A432951ULL, { 0x6D, 0xE8, 0xE2, 0x8C, 0x85, 0x11, 0x64, 0x4D, 0x55, 0x95, 0xFC, 0x45, 0xE5, 0x35, 0x14, 0x72 } }, // 1.11.0.0.36376 Anniversary event + { 0xC43CB14355249451ULL, { 0x0E, 0xA2, 0xB4, 0x4F, 0x96, 0xA2, 0x69, 0xA3, 0x86, 0x85, 0x6D, 0x04, 0x9A, 0x3D, 0xEC, 0x86 } }, // 1.12.0.0.37104 Horizon Lunar Colony + { 0xE6D914F8E4744953ULL, { 0xC8, 0x47, 0x7C, 0x28, 0x9D, 0xCE, 0x66, 0xD9, 0x13, 0x65, 0x07, 0xA3, 0x3A, 0xA3, 0x33, 0x01 } }, // 1.13.0.0.37646 Doomfist + { 0x5694C503F8C80178ULL, { 0x7F, 0x4C, 0xF1, 0xC1, 0xFB, 0xBA, 0xD9, 0x2B, 0x18, 0x43, 0x36, 0xD6, 0x77, 0xEB, 0xF9, 0x37 } }, // 1.13.0.0.37646 Doomfist + // { 0x21DBFD65F3E54269ULL, {0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??}}, // 1.13.0.0.37646 Summer Games 2017 + // { 0x27ABA5F88DD8D078ULL, {0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??}}, // 1.13.0.0.37646 // Streamed WoW keys { 0xFA505078126ACB3EULL, { 0xBD, 0xC5, 0x18, 0x62, 0xAB, 0xED, 0x79, 0xB2, 0xDE, 0x48, 0xC8, 0xE7, 0xE6, 0x6C, 0x62, 0x00 } }, // 15 WOW-20740patch7.0.1_Beta @@ -113,15 +118,17 @@ static CASC_ENCRYPTION_KEY CascKeys[] = { 0x460C92C372B2A166ULL, { 0x94, 0x6D, 0x56, 0x59, 0xF2, 0xFA, 0xF3, 0x27, 0xC0, 0xB7, 0xEC, 0x82, 0x8B, 0x74, 0x8A, 0xDB } }, // 74 WOW-21952patch7.0.3_Beta Stormheim Alliance cinematic (legion_g_a_sth) { 0x8165D801CCA11962ULL, { 0xCD, 0x0C, 0x0F, 0xFA, 0xAD, 0x93, 0x63, 0xEC, 0x14, 0xDD, 0x25, 0xEC, 0xDD, 0x2A, 0x5B, 0x62 } }, // 75 WOW-21952patch7.0.3_Beta Stormheim Horde cinematic (legion_g_h_sth) { 0xA3F1C999090ADAC9ULL, { 0xB7, 0x2F, 0xEF, 0x4A, 0x01, 0x48, 0x8A, 0x88, 0xFF, 0x02, 0x28, 0x0A, 0xA0, 0x7A, 0x92, 0xBB } }, // 81 WOW-22578patch7.1.0_PTR Firecat Mount - // {0x18AFDF5191923610ULL, {0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??}}, // 82 WOW-22578patch7.1.0_PTR - // {0x3C258426058FBD93ULL, {0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??}}, // 91 WOW-23436patch7.2.0_PTR - // {0x094E9A0474876B98ULL, {0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??}}, // 92 WOW-23910patch7.2.5_PTR + // {0x18AFDF5191923610ULL, {0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x?? } }, // 82 WOW-22578patch7.1.0_PTR + // {0x3C258426058FBD93ULL, {0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x?? } }, // 91 WOW-23436patch7.2.0_PTR + { 0x094E9A0474876B98ULL, { 0xE5, 0x33, 0xBB, 0x6D, 0x65, 0x72, 0x7A, 0x58, 0x32, 0x68, 0x0D, 0x62, 0x0B, 0x0B, 0xC1, 0x0B } }, // 92 WOW-23910patch7.2.5_PTR { 0x3DB25CB86A40335EULL, { 0x02, 0x99, 0x0B, 0x12, 0x26, 0x0C, 0x1E, 0x9F, 0xDD, 0x73, 0xFE, 0x47, 0xCB, 0xAB, 0x70, 0x24 } }, // 93 WOW-23789patch7.2.0_PTR { 0x0DCD81945F4B4686ULL, { 0x1B, 0x78, 0x9B, 0x87, 0xFB, 0x3C, 0x92, 0x38, 0xD5, 0x28, 0x99, 0x7B, 0xFA, 0xB4, 0x41, 0x86 } }, // 94 WOW-23789patch7.2.0_PTR - // {0x486A2A3A2803BE89ULL, {0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??}}, // 95 WOW-23789patch7.2.0_PTR + { 0x486A2A3A2803BE89ULL, { 0x32, 0x67, 0x9E, 0xA7, 0xB0, 0xF9, 0x9E, 0xBF, 0x4F, 0xA1, 0x70, 0xE8, 0x47, 0xEA, 0x43, 0x9A } }, // 95 WOW-23789patch7.2.0_PTR + // { 0x71F69446AD848E06ULL, { 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x?? } }, // 97 WOW-24473patch7.3.0_PTR + // { 0x211FCD1265A928E9ULL, { 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x?? } }, // 98 WOW-24473patch7.3.0_PTR { 0x0ADC9E327E42E98CULL, { 0x01, 0x7B, 0x34, 0x72, 0xC1, 0xDE, 0xE3, 0x04, 0xFA, 0x0B, 0x2F, 0xF8, 0xE5, 0x3F, 0xF7, 0xD6 } }, // 99 WOW-23910patch7.2.5_PTR - // { 0x71F69446AD848E06ULL, { 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x?? } }, // 97 WOW-24473patch7.3.0_PTR - // { 0x211FCD1265A928E9ULL, { 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x?? } }, // 98 WOW-24473patch7.3.0_PTR + // { 0xBAE9F621B60174F1ULL, { 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x?? } }, // 100 WOW-24473patch7.3.0_PTR + // { 0x34DE1EEADC97115EULL, { 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x?? } }, // 101 WOW-24473patch7.3.0_PTR { 0, { 0 } } }; diff --git a/dep/CascLib/src/CascFiles.cpp b/dep/CascLib/src/CascFiles.cpp index d17d1bc0204..3132992db4c 100644 --- a/dep/CascLib/src/CascFiles.cpp +++ b/dep/CascLib/src/CascFiles.cpp @@ -58,6 +58,7 @@ static const TGameIdString GameIds[] = {"Diablo3", 0x07, CASC_GAME_DIABLO3}, // Diablo III BETA 2.2.0 {"Prometheus", 0x0A, CASC_GAME_OVERWATCH}, // Overwatch BETA since build 24919 {"SC2", 0x03, CASC_GAME_STARCRAFT2}, // Starcraft II - Legacy of the Void + {"Starcraft1", 0x0A, CASC_GAME_STARCRAFT1}, // Starcraft 1 (remake) {NULL, 0, 0}, }; diff --git a/dep/CascLib/src/CascLib.h b/dep/CascLib/src/CascLib.h index a297e3cd458..272d4b4ad4d 100644 --- a/dep/CascLib/src/CascLib.h +++ b/dep/CascLib/src/CascLib.h @@ -108,6 +108,7 @@ typedef enum _CASC_STORAGE_INFO_CLASS CascStorageFeatures, CascStorageGameInfo, CascStorageGameBuild, + CascStorageInstalledLocales, CascStorageInfoClassMax } CASC_STORAGE_INFO_CLASS, *PCASC_STORAGE_INFO_CLASS; @@ -126,7 +127,7 @@ typedef struct _CASC_FIND_DATA char * szPlainName; // Plain name of the found file BYTE EncodingKey[MD5_HASH_SIZE]; // Encoding key DWORD dwLocaleFlags; // Locale flags (WoW only) - DWORD dwFileDataId; // File data ID (WoW only) + DWORD dwFileDataId; // File data ID (WoW only) DWORD dwFileSize; // Size of the file } CASC_FIND_DATA, *PCASC_FIND_DATA; diff --git a/dep/CascLib/src/CascOpenStorage.cpp b/dep/CascLib/src/CascOpenStorage.cpp index 398dfb62960..ec277f67c13 100644 --- a/dep/CascLib/src/CascOpenStorage.cpp +++ b/dep/CascLib/src/CascOpenStorage.cpp @@ -121,6 +121,29 @@ static bool IsIndexFileName_V2(const TCHAR * szFileName) _tcsicmp(szFileName + 0x0A, _T(".idx")) == 0); } +static bool IsRootFile_Starcraft1(LPBYTE pbFileData, DWORD cbFileData) +{ + LPBYTE pbFileEnd = pbFileData + cbFileData; + LPBYTE pbHashName; + LPBYTE pbHashEnd; + + // Skip the file name + while(pbFileData < pbFileEnd && pbFileData[0] != '|') + pbFileData++; + if(pbFileData[0] != '|') + return false; + + // Then, a MD5 must follow + pbHashName = pbHashEnd = pbFileData + 1; + while(pbHashEnd < pbFileEnd && pbHashEnd[0] != 0x0A) + pbHashEnd++; + if(pbHashEnd[0] != 0x0A) + return false; + + // The length must be exactly 32 characters + return ((pbHashEnd - pbHashName) == 32); +} + static bool IsCascIndexHeader_V1(LPBYTE pbFileData, DWORD cbFileData) { PFILE_INDEX_HEADER_V1 pIndexHeader = (PFILE_INDEX_HEADER_V1)pbFileData; @@ -913,7 +936,10 @@ static int LoadRootFile(TCascStorage * hs, DWORD dwLocaleMask) break; default: - nError = RootHandler_CreateWoW6(hs, pbRootFile, cbRootFile, dwLocaleMask); + if(IsRootFile_Starcraft1(pbRootFile, cbRootFile)) + nError = RootHandler_CreateSC1(hs, pbRootFile, cbRootFile); + else + nError = RootHandler_CreateWoW6(hs, pbRootFile, cbRootFile, dwLocaleMask); break; } } @@ -1123,6 +1149,10 @@ bool WINAPI CascGetStorageInfo( dwInfoValue = hs->dwBuildNumber; break; + case CascStorageInstalledLocales: + dwInfoValue = hs->dwDefaultLocale; + break; + default: SetLastError(ERROR_INVALID_PARAMETER); return false; diff --git a/dep/CascLib/src/CascPort.h b/dep/CascLib/src/CascPort.h index d1d556df17b..7b5a2535381 100644 --- a/dep/CascLib/src/CascPort.h +++ b/dep/CascLib/src/CascPort.h @@ -153,6 +153,7 @@ typedef LONG * PLONG; typedef DWORD * PDWORD; typedef BYTE * LPBYTE; + typedef char * LPSTR; #ifdef PLATFORM_32BIT #define _LZMA_UINT32_IS_ULONG diff --git a/dep/CascLib/src/CascReadFile.cpp b/dep/CascLib/src/CascReadFile.cpp index 76227449461..1b13e873f02 100644 --- a/dep/CascLib/src/CascReadFile.cpp +++ b/dep/CascLib/src/CascReadFile.cpp @@ -494,7 +494,7 @@ bool WINAPI CascReadFile(HANDLE hFile, void * pvBuffer, DWORD dwBytesToRead, PDW if(nError == ERROR_SUCCESS && hf->FilePointer >= hf->FileSize) { *pdwBytesRead = 0; - return ERROR_SUCCESS; + return true; } // Find the file frame where to read from diff --git a/dep/CascLib/src/CascRootFile_Mndx.cpp b/dep/CascLib/src/CascRootFile_Mndx.cpp index 1c193ea9498..20e3c86e3a6 100644 --- a/dep/CascLib/src/CascRootFile_Mndx.cpp +++ b/dep/CascLib/src/CascRootFile_Mndx.cpp @@ -91,14 +91,6 @@ typedef struct _CASC_ROOT_ENTRY_MNDX } CASC_ROOT_ENTRY_MNDX, *PCASC_ROOT_ENTRY_MNDX; //----------------------------------------------------------------------------- -// Testing functions prototypes - -#if defined(_DEBUG) && defined(_X86_) && defined(CASCLIB_TEST) -extern "C" bool _cdecl sub_1958B00_x86(TFileNameDatabase * pDB, TMndxFindResult * pStruct1C); -void TestMndxRootFile(PCASC_MNDX_INFO pMndxInfo); -#endif - -//----------------------------------------------------------------------------- // Local variables unsigned char table_1BA1818[0x800] = @@ -3345,8 +3337,9 @@ int RootHandler_CreateMNDX(TCascStorage * hs, LPBYTE pbRootFile, DWORD cbRootFil // Unit tests #if defined(_DEBUG) && defined(_X86_) && defined(CASCLIB_TEST) - +/* extern "C" { + bool _cdecl sub_1958B00_x86(TFileNameDatabase * pDB, TMndxFindResult * pStruct1C); DWORD _cdecl sub_19573D0_x86(TFileNameDatabase * pDB, DWORD arg_0, DWORD arg_4); DWORD _cdecl sub_1957EF0_x86(TFileNameDatabase * pDB, TMndxFindResult * pStruct1C); bool _cdecl sub_1959460_x86(TFileNameDatabase * pDB, TMndxFindResult * pStruct1C); @@ -3390,7 +3383,7 @@ static int sub_1956CE0_x86(TFileNameDatabasePtr * pDatabasePtr, TMndxFindResult *pbFindResult = sub_1959460_x86(pDatabasePtr->pDB, pStruct1C); return nError; } -/* + static void TestFileSearch_SubStrings(PMAR_FILE pMarFile, char * szFileName, size_t nLength) { TMndxFindResult Struct1C_1; @@ -3437,7 +3430,6 @@ static void TestFileSearch_SubStrings(PMAR_FILE pMarFile, char * szFileName, siz nLength--; } } -*/ static void TestFindPackage(PMAR_FILE pMarFile, const char * szPackageName) { @@ -3621,4 +3613,5 @@ void TestMndxRootFile(PCASC_MNDX_INFO pMndxInfo) ListFile_Free(pvListFile); } } +*/ #endif // defined(_DEBUG) && defined(_X86_) && defined(CASCLIB_TEST) diff --git a/dep/CascLib/src/CascRootFile_SC1.cpp b/dep/CascLib/src/CascRootFile_SC1.cpp new file mode 100644 index 00000000000..76c7756ea23 --- /dev/null +++ b/dep/CascLib/src/CascRootFile_SC1.cpp @@ -0,0 +1,216 @@ +/*****************************************************************************/ +/* CascRootFile_SC1.cpp Copyright (c) Ladislav Zezula 2017 */ +/*---------------------------------------------------------------------------*/ +/* Support for loading Starcraft 1 ROOT file */ +/*---------------------------------------------------------------------------*/ +/* Date Ver Who Comment */ +/* -------- ---- --- ------- */ +/* 28.10.15 1.00 Lad The first version of CascRootFile_SC1.cpp */ +/*****************************************************************************/ + +#define __CASCLIB_SELF__ +#include "CascLib.h" +#include "CascCommon.h" + +//----------------------------------------------------------------------------- +// Structure definitions for Overwatch root file + +typedef struct _CASC_FILE_ENTRY +{ + ENCODING_KEY EncodingKey; // Encoding key + ULONGLONG FileNameHash; // File name hash + DWORD dwFileName; // Offset of the file name in the name cache +} CASC_FILE_ENTRY, *PCASC_FILE_ENTRY; + +struct TRootHandler_SC1 : public TRootHandler +{ + // Linear global list of file entries + DYNAMIC_ARRAY FileTable; + + // Linear global list of names + DYNAMIC_ARRAY FileNames; + + // Global map of FileName -> FileEntry + PCASC_MAP pRootMap; +}; + +//----------------------------------------------------------------------------- +// Local functions + +static int InsertFileEntry( + TRootHandler_SC1 * pRootHandler, + const char * szFileName, + LPBYTE pbEncodingKey) +{ + PCASC_FILE_ENTRY pFileEntry; + size_t nLength = strlen(szFileName); + + // Attempt to insert the file name to the global buffer + szFileName = (char *)Array_Insert(&pRootHandler->FileNames, szFileName, nLength + 1); + if(szFileName == NULL) + return ERROR_NOT_ENOUGH_MEMORY; + + // Attempt to insert the entry to the array of file entries + pFileEntry = (PCASC_FILE_ENTRY)Array_Insert(&pRootHandler->FileTable, NULL, 1); + if(pFileEntry == NULL) + return ERROR_NOT_ENOUGH_MEMORY; + + // Fill the file entry + pFileEntry->EncodingKey = *(PENCODING_KEY)pbEncodingKey; + pFileEntry->FileNameHash = CalcFileNameHash(szFileName); + pFileEntry->dwFileName = (DWORD)Array_IndexOf(&pRootHandler->FileNames, szFileName); + + // Insert the file entry to the map + assert(Map_FindObject(pRootHandler->pRootMap, &pFileEntry->FileNameHash, NULL) == NULL); + Map_InsertObject(pRootHandler->pRootMap, pFileEntry, &pFileEntry->FileNameHash); + return ERROR_SUCCESS; +} + +//----------------------------------------------------------------------------- +// Implementation of Overwatch root file + +static int SC1Handler_Insert( + TRootHandler_SC1 * pRootHandler, + const char * szFileName, + LPBYTE pbEncodingKey) +{ + return InsertFileEntry(pRootHandler, szFileName, pbEncodingKey); +} + +static LPBYTE SC1Handler_Search(TRootHandler_SC1 * pRootHandler, TCascSearch * pSearch, PDWORD /* PtrFileSize */, PDWORD /* PtrLocaleFlags */, PDWORD /* PtrFileDataId */) +{ + PCASC_FILE_ENTRY pFileEntry; + + // Are we still inside the root directory range? + while(pSearch->IndexLevel1 < pRootHandler->FileTable.ItemCount) + { + // Retrieve the file item + pFileEntry = (PCASC_FILE_ENTRY)Array_ItemAt(&pRootHandler->FileTable, pSearch->IndexLevel1); + + // Prepare the pointer to the next search + pSearch->IndexLevel1++; + + char *filename = (char *)Array_ItemAt(&pRootHandler->FileNames, pFileEntry->dwFileName); + if (CheckWildCard(filename, pSearch->szMask)) { + strcpy(pSearch->szFileName, filename); + return pFileEntry->EncodingKey.Value; + } + } + + // No more entries + return NULL; +} + +static void SC1Handler_EndSearch(TRootHandler_SC1 * /* pRootHandler */, TCascSearch * /* pSearch */) +{ + // Do nothing +} + +static LPBYTE SC1Handler_GetKey(TRootHandler_SC1 * pRootHandler, const char * szFileName) +{ + ULONGLONG FileNameHash = CalcFileNameHash(szFileName); + + return (LPBYTE)Map_FindObject(pRootHandler->pRootMap, &FileNameHash, NULL); +} + +static DWORD SC1Handler_GetFileId(TRootHandler_SC1 * /* pRootHandler */, const char * /* szFileName */) +{ + // Not implemented for Overwatch + return 0; +} + +static void SC1Handler_Close(TRootHandler_SC1 * pRootHandler) +{ + if(pRootHandler != NULL) + { + // Free the file map + if(pRootHandler->pRootMap) + Map_Free(pRootHandler->pRootMap); + pRootHandler->pRootMap = NULL; + + // Free the array of the file names and file items + Array_Free(&pRootHandler->FileTable); + Array_Free(&pRootHandler->FileNames); + + // Free the root file itself + CASC_FREE(pRootHandler); + } +} + +//----------------------------------------------------------------------------- +// Public functions + +int RootHandler_CreateSC1(TCascStorage * hs, LPBYTE pbRootFile, DWORD cbRootFile) +{ + TRootHandler_SC1 * pRootHandler; + ENCODING_KEY KeyBuffer; + QUERY_KEY EncodingKey = {KeyBuffer.Value, MD5_HASH_SIZE}; + void * pTextFile; + size_t nLength; + char szOneLine[0x200]; + char szFileName[MAX_PATH+1]; + DWORD dwFileCountMax = (DWORD)hs->pEncodingMap->TableSize; + int nFileNameIndex; + int nError = ERROR_SUCCESS; + + // Allocate the root handler object + hs->pRootHandler = pRootHandler = CASC_ALLOC(TRootHandler_SC1, 1); + if(pRootHandler == NULL) + return ERROR_NOT_ENOUGH_MEMORY; + + // Fill-in the handler functions + memset(pRootHandler, 0, sizeof(TRootHandler_SC1)); + pRootHandler->Insert = (ROOT_INSERT)SC1Handler_Insert; + pRootHandler->Search = (ROOT_SEARCH)SC1Handler_Search; + pRootHandler->EndSearch = (ROOT_ENDSEARCH)SC1Handler_EndSearch; + pRootHandler->GetKey = (ROOT_GETKEY)SC1Handler_GetKey; + pRootHandler->Close = (ROOT_CLOSE)SC1Handler_Close; + pRootHandler->GetFileId = (ROOT_GETFILEID)SC1Handler_GetFileId; + + // Fill-in the flags + pRootHandler->dwRootFlags |= ROOT_FLAG_HAS_NAMES; + + // Allocate the linear array of file entries + nError = Array_Create(&pRootHandler->FileTable, CASC_FILE_ENTRY, 0x10000); + if(nError != ERROR_SUCCESS) + return nError; + + // Allocate the buffer for the file names + nError = Array_Create(&pRootHandler->FileNames, char, 0x10000); + if(nError != ERROR_SUCCESS) + return nError; + + // Create map of ROOT_ENTRY -> FileEntry + pRootHandler->pRootMap = Map_Create(dwFileCountMax, sizeof(ULONGLONG), FIELD_OFFSET(CASC_FILE_ENTRY, FileNameHash)); + if(pRootHandler->pRootMap == NULL) + return ERROR_NOT_ENOUGH_MEMORY; + + // Parse the ROOT file + pTextFile = ListFile_FromBuffer(pbRootFile, cbRootFile); + if(pTextFile != NULL) + { + // Parse the next lines + while((nLength = ListFile_GetNextLine(pTextFile, szOneLine, _maxchars(szOneLine))) > 0) + { + LPSTR szEncodingKey; + BYTE EncodingKey[MD5_HASH_SIZE]; + + szEncodingKey = strchr(szOneLine, _T('|')); + if(szEncodingKey != NULL) + { + // Split the name and encoding key + *szEncodingKey++ = 0; + + // Insert the entry to the map + ConvertStringToBinary(szEncodingKey, MD5_STRING_SIZE, EncodingKey); + InsertFileEntry(pRootHandler, szOneLine, EncodingKey); + } + } + + // Free the listfile + ListFile_Free(pTextFile); + } + + // Succeeded + return nError; +} |