diff options
author | Shauren <shauren.trinity@gmail.com> | 2020-05-07 14:39:40 +0200 |
---|---|---|
committer | Shauren <shauren.trinity@gmail.com> | 2020-05-07 14:39:40 +0200 |
commit | ea812fec1153280b94d2fff8bdefd678e86bddeb (patch) | |
tree | cd7d75fc98ab6cc2c975fe4db9be67ccb87f40c1 /dep/CascLib | |
parent | dfdabdb97bdd776da4add3cd4f19cf5793160abf (diff) |
Dep/CascLib: Update to ladislav-zezula/CascLib@0a05c59eb8a3eab1bc5471f43934cd5f992f0aca
Diffstat (limited to 'dep/CascLib')
-rw-r--r-- | dep/CascLib/src/CascCommon.h | 5 | ||||
-rw-r--r-- | dep/CascLib/src/CascDecrypt.cpp | 287 | ||||
-rw-r--r-- | dep/CascLib/src/CascDumpData.cpp | 2 | ||||
-rw-r--r-- | dep/CascLib/src/CascFiles.cpp | 72 | ||||
-rw-r--r-- | dep/CascLib/src/CascFindFile.cpp | 2 | ||||
-rw-r--r-- | dep/CascLib/src/CascIndexFiles.cpp | 84 | ||||
-rw-r--r-- | dep/CascLib/src/CascLib.h | 70 | ||||
-rw-r--r-- | dep/CascLib/src/CascOpenStorage.cpp | 68 | ||||
-rw-r--r-- | dep/CascLib/src/CascPort.h | 61 | ||||
-rw-r--r-- | dep/CascLib/src/CascReadFile.cpp | 24 | ||||
-rw-r--r-- | dep/CascLib/src/DllMain.rc | 8 | ||||
-rw-r--r-- | dep/CascLib/src/common/Common.cpp | 50 | ||||
-rw-r--r-- | dep/CascLib/src/common/Common.h | 39 | ||||
-rw-r--r-- | dep/CascLib/src/common/Csv.cpp | 2 | ||||
-rw-r--r-- | dep/CascLib/src/common/Csv.h | 2 | ||||
-rw-r--r-- | dep/CascLib/src/common/Directory.cpp | 6 | ||||
-rw-r--r-- | dep/CascLib/src/common/FileStream.cpp | 238 | ||||
-rw-r--r-- | dep/CascLib/src/common/FileStream.h | 9 | ||||
-rw-r--r-- | dep/CascLib/src/common/FileTree.cpp | 8 | ||||
-rw-r--r-- | dep/CascLib/src/common/ListFile.cpp | 2 | ||||
-rw-r--r-- | dep/CascLib/src/common/ListFile.h | 2 | ||||
-rw-r--r-- | dep/CascLib/src/md5/md5.cpp | 86 |
22 files changed, 791 insertions, 336 deletions
diff --git a/dep/CascLib/src/CascCommon.h b/dep/CascLib/src/CascCommon.h index 7700c782cbf..8ef9d557a51 100644 --- a/dep/CascLib/src/CascCommon.h +++ b/dep/CascLib/src/CascCommon.h @@ -207,7 +207,7 @@ typedef struct _CASC_FILE_FRAME CONTENT_KEY FrameHash; // MD5 hash of the file frame ULONGLONG StartOffset; // Starting offset of the file span ULONGLONG EndOffset; // Ending offset of the file span - DWORD DataFileOffset; // Offset in the data file (data.###) + ULONGLONG DataFileOffset; // Offset in the data file (data.###) DWORD EncodedSize; // Encoded size of the frame DWORD ContentSize; // Content size of the frame } CASC_FILE_FRAME, *PCASC_FILE_FRAME; @@ -275,6 +275,7 @@ struct TCascStorage // Class members PCASC_OPEN_STORAGE_ARGS pArgs; // Open storage arguments. Only valid during opening the storage + CASC_LOCK StorageLock; // Lock for multi-threaded operations LPCTSTR szIndexFormat; // Format of the index file name LPTSTR szCodeName; // On local storage, this select a product in a multi-product storage. For online storage, this selects a product @@ -285,6 +286,7 @@ struct TCascStorage LPTSTR szCdnServers; // Multi-SZ list of CDN servers LPTSTR szCdnPath; // Remote CDN sub path for the product LPSTR szRegion; // Product region. Only when "versions" is used as storage root file + LPSTR szBuildKey; // Product build key, aka MD5 of the build file DWORD dwDefaultLocale; // Default locale, read from ".build.info" DWORD dwBuildNumber; // Product build number DWORD dwRefCount; // Number of references @@ -330,7 +332,6 @@ struct TCascStorage CASC_ARRAY ExtraKeysList; // List additional encryption keys CASC_MAP EncryptionKeys; // Map of encryption keys ULONGLONG LastFailKeyName; // The value of the encryption key that recently was NOT found. - }; struct TCascFile diff --git a/dep/CascLib/src/CascDecrypt.cpp b/dep/CascLib/src/CascDecrypt.cpp index 308be6cab46..ccce1fc0a5b 100644 --- a/dep/CascLib/src/CascDecrypt.cpp +++ b/dep/CascLib/src/CascDecrypt.cpp @@ -48,8 +48,8 @@ static CASC_ENCRYPTION_KEY CascKeys[] = // { 0xD0CAE11366CEEA83ULL, { 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x?? }}, // 1.12.3.2609 (build 45364) // Warcraft III Reforged beta (build) - { 0x6E4296823E7D561EULL, { 0xC0, 0xBF, 0xA2, 0x94, 0x3A, 0xC3, 0xE9, 0x22, 0x86, 0xE4, 0x44, 0x3E, 0xE3, 0x56, 0x0D, 0x65 }}, // Build 13369 - { 0xE04D60E31DDEBF63ULL, { 0x26, 0x3D, 0xB5, 0xC4, 0x02, 0xDA, 0x8D, 0x4D, 0x68, 0x63, 0x09, 0xCB, 0x2E, 0x32, 0x54, 0xD0 }}, // Build 13445 + { 0x6E4296823E7D561EULL, { 0xC0, 0xBF, 0xA2, 0x94, 0x3A, 0xC3, 0xE9, 0x22, 0x86, 0xE4, 0x44, 0x3E, 0xE3, 0x56, 0x0D, 0x65 }}, // 1.32.0.13369 Base content (Beta Week 0) + { 0xE04D60E31DDEBF63ULL, { 0x26, 0x3D, 0xB5, 0xC4, 0x02, 0xDA, 0x8D, 0x4D, 0x68, 0x63, 0x09, 0xCB, 0x2E, 0x32, 0x54, 0xD0 }}, // 1.32.0.13445 Base content (Beta Week 1) // Overwatch { 0xFB680CB6A8BF81F3ULL, { 0x62, 0xD9, 0x0E, 0xFA, 0x7F, 0x36, 0xD7, 0x1C, 0x39, 0x8A, 0xE2, 0xF1, 0xFE, 0x37, 0xBD, 0xB9 } }, // 0.8.0.24919_retailx64 (hardcoded) @@ -222,7 +222,7 @@ static CASC_ENCRYPTION_KEY CascKeys[] = { 0x14C4257E557B49A1ULL, { 0x06, 0x4A, 0x97, 0x09, 0xF4, 0x2D, 0x50, 0xCB, 0x5F, 0x8B, 0x94, 0xBC, 0x1A, 0xCF, 0xDD, 0x5D } }, // 242 WOW-28440patch8.1.0_PTR dor cinematic { 0x1254E65319C6EEFFULL, { 0x79, 0xD2, 0xB3, 0xD1, 0xCC, 0xB0, 0x15, 0x47, 0x4E, 0x71, 0x58, 0x81, 0x38, 0x64, 0xB8, 0xE6 } }, // 243 WOW-28440patch8.1.0_PTR akt cinematic { 0xC8753773ADF1174CULL, { 0x1E, 0x0E, 0x37, 0xD4, 0x2E, 0xE5, 0xCE, 0x5E, 0x80, 0x67, 0xF0, 0x39, 0x4B, 0x09, 0x05, 0xF2 } }, // 244 WOW-28938patch8.1.5_PTR Obsidian Worldbreaker mount & Lil' Nefarian pet -// { 0x2170BCAA9FA96E22ULL, { 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x?? } }, // 245 WOW-28938patch8.1.5_PTR alpaca mount + { 0x2170BCAA9FA96E22ULL, { 0x6D, 0xDA, 0x6D, 0x48, 0xD7, 0x2D, 0xC8, 0x00, 0x5D, 0xB9, 0xDC, 0x15, 0x36, 0x8D, 0x35, 0xBC } }, // 245 WOW-28938patch8.1.5_PTR baby alpaca pet // { 0x75485627AA225F4DULL, { 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x?? } }, // 246 WOW-28938patch8.1.5_PTR fdid 2741546, 2741548, 2741549 { 0x08717B15BF3C7955ULL, { 0x4B, 0x06, 0xBF, 0x9D, 0x17, 0x66, 0x3C, 0xEB, 0x33, 0x12, 0xEA, 0x3C, 0x69, 0xFB, 0xC5, 0xDD } }, // 248 WOW-29220patch8.1.5_PTR inv_encrypted20.blp (fdid 2823166) // { 0xD19DCF7ACA8D96D6ULL, { 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x?? } }, // 249 WOW-30080patch8.2.0_PTR starts at fdid 2843110, 10 files @@ -233,35 +233,296 @@ static CASC_ENCRYPTION_KEY CascKeys[] = { 0x6A026290FBDB3754ULL, { 0x3D, 0x2D, 0x62, 0x08, 0x50, 0xA6, 0x76, 0x5D, 0xD5, 0x91, 0x22, 0x4F, 0x60, 0x5B, 0x94, 0x9A } }, // 255 WOW-30080patch8.2.0_PTR BlizzCon 2019 - Wendigo transmog set { 0xCF72FD04608D36EDULL, { 0xA0, 0xA8, 0x89, 0x97, 0x6D, 0x02, 0xFA, 0x8D, 0x00, 0xF7, 0xAF, 0x00, 0x17, 0xAD, 0x72, 0x1F } }, // 257 WOW-30262patch8.2.0_PTR Azshara Warbringer cinematic (5 files) { 0x17F07C2E3A45DB3DULL, { 0x6D, 0x38, 0x86, 0xBD, 0xB9, 0x1E, 0x71, 0x5A, 0xE7, 0x18, 0x2D, 0x9F, 0x3A, 0x08, 0xF2, 0xC9 } }, // 258 WOW-30262patch8.2.0_PTR Solesa Naksu Nazjatar phase (34 files) -// { 0xDFAB5841B87802B5ULL, { 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x?? } }, // 259 WOW-31337patch8.2.5_PTR starts at fdid 3016206, 8 files, 3016206 is a creature + { 0xDFAB5841B87802B5ULL, { 0xF3, 0x7E, 0x96, 0xED, 0x8A, 0x1F, 0x8D, 0x85, 0x2F, 0x07, 0x5D, 0xDE, 0x37, 0xC7, 0x13, 0x27 } }, // 259 WOW-31337patch8.2.5_PTR Ratmount2 Flying Rat Mount { 0xC050FA06BB0538F6ULL, { 0xC5, 0x52, 0xF5, 0xD0, 0xB7, 0x22, 0x31, 0x50, 0x2D, 0x25, 0x47, 0x31, 0x4E, 0x60, 0x15, 0xF7 } }, // 260 WOW-30495patch8.2.0_PTR Crossroads cinematic (5 files) { 0xAB5CDD3FC321831FULL, { 0xE1, 0x38, 0x4F, 0x5B, 0x06, 0xEB, 0xBC, 0xD3, 0x33, 0x69, 0x5A, 0xA6, 0xFF, 0xC6, 0x83, 0x18 } }, // 261 WOW-30495patch8.2.0_PTR Azshara kill cinematic (5 files) { 0xA7B7D1F12395040EULL, { 0x36, 0xAD, 0x3B, 0x31, 0x27, 0x3F, 0x1E, 0xBC, 0xEE, 0x85, 0x20, 0xAA, 0xA7, 0x4B, 0x12, 0xF2 } }, // 262 WOW-30495patch8.2.0_PTR Nazjatar intro cinematics (9 files) { 0x83A2AB72DD8AE992ULL, { 0x02, 0x3C, 0xFF, 0x06, 0x2B, 0x19, 0xA5, 0x29, 0xB9, 0xF1, 0x4F, 0x9B, 0x7A, 0xAA, 0xC5, 0xBB } }, // 263 WOW-31337patch8.2.5_PTR 8.2.5 War Campaign scenario/models { 0xBEAF567CC45362F0ULL, { 0x8B, 0xD3, 0xED, 0x79, 0x24, 0x05, 0xD9, 0xEE, 0x74, 0x2B, 0xF6, 0xAF, 0xA9, 0x44, 0x57, 0x8A } }, // 264 WOW-31337patch8.2.5_PTR 8.2.5 War Campaign quests/vo { 0x7BB3A77FD8D14783ULL, { 0x4C, 0x94, 0xE3, 0x60, 0x9C, 0xFE, 0x0A, 0x82, 0x00, 0x0A, 0x0B, 0xD4, 0x60, 0x69, 0xAC, 0x6F } }, // 265 WOW-31337patch8.2.5_PTR 8.2.5 War Campaign epilogue quests - { 0x8F4098E2470FE0C8ULL, { 0xAA, 0x71, 0x8D, 0x1F, 0x1A, 0x23, 0x07, 0x8D, 0x49, 0xAD, 0x0C, 0x60, 0x6A, 0x72, 0xF3, 0xD5 } }, // 266 WOW-31337patch8.2.5_PTR 8.2.5 War Campaign epilogue in-game cinematic -// { 0x6AC5C837A2027A6BULL, { 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x?? } }, // 267 WOW-31337patch8.2.5_PTR starts at fdid 3037834, 263 files, 3037834 & 3040716 are creatures + { 0x8F4098E2470FE0C8ULL, { 0xAA, 0x71, 0x8D, 0x1F, 0x1A, 0x23, 0x07, 0x8D, 0x49, 0xAD, 0x0C, 0x60, 0x6A, 0x72, 0xF3, 0xD5 } }, // 266 WOW-31337patch8.2.5_PTR 8.2.5 War Campaign epilogue in-game cinematic5 + { 0x6AC5C837A2027A6BULL, { 0xB0, 0xB7, 0xCE, 0x09, 0x17, 0x63, 0xD1, 0x5E, 0x7F, 0x69, 0xA8, 0xE2, 0x34, 0x2C, 0xDD, 0x7C } }, // 267 WOW-31337patch8.2.5_PTR Shadowlands CE rewards { 0x302AAD8B1F441D95ULL, { 0x24, 0xB8, 0x64, 0x38, 0xCF, 0x02, 0x53, 0x86, 0x49, 0xE5, 0xBA, 0x67, 0x2F, 0xD5, 0x99, 0x3A } }, // 271 WOW-31337patch8.2.5_PTR RaF mounts & armor // { 0x5C909F00088734B9ULL, { 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x?? } }, // 272 WOW-31337patch8.2.5_PTR Unused in 8.2.5 -// { 0xF785977C76DE9C77ULL, { 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x?? } }, // 273 WOW-31337patch8.2.5_PTR starts at fdid 3071600, 313 files, Winter Veil? -// { 0x1CDAF3931871BEC3ULL, { 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x?? } }, // 275 WOW-31337patch8.2.5_PTR unknown toy/achievement, 28 files + { 0xF785977C76DE9C77ULL, { 0x7F, 0x3C, 0x19, 0x51, 0xF5, 0x28, 0x3A, 0x18, 0xC1, 0xC6, 0xD4, 0x5B, 0x68, 0x67, 0xB5, 0x1A } }, // 273 WOW-31337patch8.2.5_PTR Starts at fdid 3071600, 313 files, Winter Veil? + { 0x1CDAF3931871BEC3ULL, { 0x66, 0xB4, 0xD3, 0x4A, 0x3A, 0xF3, 0x0E, 0x5E, 0xB7, 0xF4, 0x14, 0xF6, 0xC3, 0x0A, 0xAF, 0x4F } }, // 275 WOW-31337patch8.2.5_PTR Winter Veil 2019 toy/achievement (28 files) { 0x814E1AB43F3F9345ULL, { 0xB6, 0x5E, 0x2A, 0x63, 0xA1, 0x16, 0xAA, 0x25, 0x1F, 0xA5, 0xD7, 0xB0, 0xBA, 0xAB, 0xF7, 0x78 } }, // 276 WOW-31599patch8.2.5_PTR The Negotiation cinematic (5 files) { 0x1FBE97A317FFBEFAULL, { 0xBD, 0x71, 0xF7, 0x8D, 0x43, 0x11, 0x7C, 0x68, 0x72, 0x4B, 0xB6, 0xE0, 0xD9, 0x57, 0x7E, 0x08 } }, // 277 WOW-31599patch8.2.5_PTR Reckoning cinematic (5 files) +// { 0x30581F81528FB27CULL, { 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x?? } }, // 278 WOW-32044patch8.3.0_PTR Contains creature that uses monkey sounds // { 0x4287F49A5BB366DAULL, { 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x?? } }, // 279 WOW-31599patch8.2.5_PTR Unused in 8.2.5 + { 0xD134F430A45C1CF2ULL, { 0x54, 0x3D, 0xA7, 0x84, 0xD4, 0xBD, 0x24, 0x28, 0xCF, 0xB5, 0xEB, 0xFE, 0xBA, 0x76, 0x2A, 0x90 } }, // 280 WOW-32044patch8.3.0_PTR Encrypted map w/ Icecrown assets, Darion Mograine VO // { 0x01C82EE0725EDA3AULL, { 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x?? } }, // 281 WOW-31812patch8.2.5_PTR Unused in 8.2.5 // { 0x04C0C50B5BE0CC78ULL, { 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x?? } }, // 282 WOW-31812patch8.2.5_PTR Unused in 8.2.5 // { 0xA26FD104489B3DE5ULL, { 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x?? } }, // 283 WOW-31812patch8.2.5_PTR Unused in 8.2.5 +// { 0xEA6C3B8F210A077FULL, { 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x?? } }, // 284 WOW-32044patch8.3.0_PTR 18 files, 3159888 is a creature that uses gronn sounds, likely a mount +// { 0x4A738212694AD0B6ULL, { 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x?? } }, // 285 WOW-32044patch8.3.0_PTR Unused in 32044 +// { 0x2A430C60DDCC75FFULL, { 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x?? } }, // 286 WOW-32044patch8.3.0_PTR 254 files, appears to be items + { 0x0A096FB251CFF471ULL, { 0x05, 0xC7, 0x59, 0x12, 0xEC, 0xFF, 0x04, 0x0F, 0x85, 0xFB, 0x46, 0x97, 0xC9, 0x9C, 0x77, 0x03 } }, // 287 WOW-32414patch8.3.0_PTR In-game scene & VO +// { 0x205AFFCDFBA639CBULL, { 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x?? } }, // 288 WOW-32414patch8.3.0_PTR + { 0x32B62CF10571971FULL, { 0x18, 0xB8, 0x3F, 0xDD, 0x5E, 0x4B, 0x39, 0x7F, 0xB8, 0x9B, 0xB5, 0x72, 0x46, 0x75, 0xCC, 0xBA } }, // 289 WOW-32489patch8.3.0_PTR In-game Wrathion scene +// { 0xB408D6CDE8E0D4C1ULL, { 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x?? } }, // 290 WOW-33978patch9.0.1_Beta + { 0x1DBE03EF5A0059E1ULL, { 0xD6, 0x3B, 0x26, 0x3C, 0xB1, 0xC7, 0xE8, 0x56, 0x23, 0xCC, 0x42, 0x58, 0x79, 0xCC, 0x59, 0x2D } }, // 294 WOW-32489patch8.3.0_PTR Cinematic + { 0x29D08CEA080FDB84ULL, { 0x06, 0x51, 0x32, 0xA6, 0x42, 0x8B, 0x19, 0xDF, 0xCB, 0x2B, 0x68, 0x94, 0x8B, 0xE9, 0x58, 0xF5 } }, // 295 WOW-32489patch8.3.0_PTR Cinematic + { 0x3FE91B3FD7F18B37ULL, { 0xC9, 0x13, 0xB1, 0xC2, 0x0D, 0xAE, 0xC8, 0x04, 0xE9, 0xF8, 0xD3, 0x52, 0x7F, 0x2A, 0x05, 0xF7 } }, // 296 WOW-32489patch8.3.0_PTR Cinematic +// { 0xF7BECC6682B9EF36ULL, { 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x?? } }, // 297 WOW-33978patch9.0.1_Beta +// { 0xDCB5C5DC78520BD6ULL, { 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x?? } }, // 298 WOW-33978patch9.0.1_Beta +// { 0x566DF4A5A9E3341FULL, { 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x?? } }, // 299 WOW-33978patch9.0.1_Beta +// { 0x9183F8AAA603704DULL, { 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x?? } }, // 300 WOW-33978patch9.0.1_Beta +// { 0x856D38B447512C51ULL, { 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x?? } }, // 301 WOW-33978patch9.0.1_Beta +// { 0x1D0614B43A9D6DF9ULL, { 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x??, 0x?? } }, // 302 WOW-33978patch9.0.1_Beta + { 0x00179EB433442A73ULL, { 0xD4, 0x1D, 0x69, 0x4C, 0x0D, 0xF8, 0x63, 0x10, 0x5C, 0x53, 0x49, 0xFD, 0x4F, 0xFB, 0xC2, 0x56 } }, // WOW-33978patch9.0.1_Beta + { 0x033DBFE564685CF6ULL, { 0xA1, 0xE3, 0xB2, 0x4B, 0xFE, 0x85, 0x78, 0xC0, 0x3D, 0x0F, 0xCC, 0x7F, 0x19, 0xE6, 0xD0, 0x69 } }, // WOW-33978patch9.0.1_Beta + { 0x05EC085870DF2AF0ULL, { 0x31, 0xE6, 0xAB, 0x03, 0xA0, 0x9E, 0x68, 0xC8, 0xFB, 0x55, 0xBF, 0x19, 0x5E, 0x1F, 0x1B, 0x99 } }, // WOW-33978patch9.0.1_Beta + { 0x0626C885AF0EEF65ULL, { 0x55, 0x7E, 0xC9, 0x97, 0xAD, 0x64, 0x62, 0x1C, 0xFE, 0x2B, 0x3D, 0x79, 0xA5, 0xB7, 0x50, 0x65 } }, // WOW-33978patch9.0.1_Beta + { 0x070994B8FE881897ULL, { 0xA5, 0x4A, 0x65, 0x23, 0x5D, 0x6D, 0x64, 0x87, 0x27, 0x7C, 0x36, 0x10, 0xBA, 0x84, 0xAB, 0xF5 } }, // WOW-33978patch9.0.1_Beta + { 0x0811E03FCFB84903ULL, { 0x6E, 0x56, 0x77, 0x05, 0x1E, 0xE0, 0x92, 0xA5, 0x7C, 0xF6, 0x56, 0xE1, 0xC5, 0x00, 0x2F, 0xFC } }, // WOW-33978patch9.0.1_Beta + { 0x0993C8311127F20EULL, { 0xE9, 0x53, 0xC3, 0x57, 0x4C, 0x3E, 0xE5, 0x43, 0xD9, 0xF5, 0x52, 0xED, 0xC8, 0x2F, 0x20, 0xE9 } }, // WOW-33978patch9.0.1_Beta + { 0x0A5E25A024FBA6B1ULL, { 0xBB, 0x8F, 0x7B, 0x18, 0x15, 0x09, 0xA9, 0x31, 0x7B, 0xE1, 0x59, 0x26, 0x34, 0x62, 0xF2, 0x8D } }, // WOW-33978patch9.0.1_Beta + { 0x0C15F03D0FE27E48ULL, { 0x74, 0x33, 0x79, 0x1B, 0xF3, 0x45, 0x89, 0xEB, 0x64, 0x32, 0x99, 0x7E, 0x10, 0xA2, 0x54, 0x22 } }, // WOW-33978patch9.0.1_Beta + { 0x0C2D617E60368120ULL, { 0x94, 0xB8, 0x12, 0x27, 0x1D, 0x6D, 0xE6, 0xC3, 0x18, 0x14, 0x40, 0xD0, 0xAA, 0x27, 0x65, 0x3D } }, // WOW-33978patch9.0.1_Beta + { 0x0C49BD78283973B0ULL, { 0x34, 0xB5, 0xBC, 0x69, 0xC1, 0x2A, 0xA3, 0x7A, 0xD7, 0x12, 0x9B, 0x7E, 0x28, 0xC1, 0xDA, 0x58 } }, // WOW-33978patch9.0.1_Beta + { 0x0CA696AE84A34281ULL, { 0x9E, 0x0C, 0xBF, 0x53, 0x20, 0x5A, 0x20, 0x64, 0x3A, 0x92, 0x30, 0xE9, 0x4E, 0xCB, 0x0E, 0x3E } }, // WOW-33978patch9.0.1_Beta + { 0x0D069101292C9EF9ULL, { 0x11, 0x6A, 0x8D, 0x4C, 0x1B, 0xA6, 0x65, 0xE1, 0x55, 0x52, 0xCA, 0x69, 0xCD, 0x7C, 0xB3, 0x67 } }, // WOW-33978patch9.0.1_Beta + { 0x0DE2CF914415467AULL, { 0xAF, 0x90, 0xC0, 0x00, 0x65, 0x47, 0xCA, 0x72, 0x72, 0x34, 0xC7, 0xAF, 0xA3, 0xAB, 0xA8, 0xA7 } }, // WOW-33978patch9.0.1_Beta + { 0x0DFACE33557D5092ULL, { 0x61, 0x54, 0x99, 0x41, 0x94, 0x26, 0x6E, 0xEF, 0x93, 0xD7, 0x5F, 0x2C, 0x23, 0xEA, 0x52, 0xB5 } }, // WOW-33978patch9.0.1_Beta + { 0x0FC6144903CFC12BULL, { 0x3B, 0x15, 0xF8, 0x9E, 0x91, 0x2F, 0xE4, 0x3D, 0x89, 0x64, 0x3D, 0xCB, 0xA9, 0x45, 0xE5, 0xCD } }, // WOW-33978patch9.0.1_Beta + { 0x100C57C7D8B42E58ULL, { 0x24, 0xF7, 0x54, 0x23, 0x09, 0x73, 0x46, 0xC7, 0x92, 0x7F, 0x14, 0x51, 0x93, 0xB6, 0xD5, 0xFE } }, // WOW-33978patch9.0.1_Beta + { 0x1108F594E9F5BCB7ULL, { 0x47, 0x80, 0xC7, 0xB3, 0x7A, 0x42, 0xFA, 0x64, 0xD4, 0x90, 0xFB, 0xB6, 0xDE, 0xE9, 0x30, 0xDC } }, // WOW-33978patch9.0.1_Beta + { 0x13DA86340D87FEB9ULL, { 0x55, 0x24, 0xD9, 0x49, 0x18, 0x52, 0x37, 0x1F, 0x19, 0x15, 0xCC, 0x1F, 0xDF, 0xD0, 0x53, 0xD1 } }, // WOW-33978patch9.0.1_Beta + { 0x141A5383D3AEEB59ULL, { 0xD5, 0xDF, 0xE7, 0x38, 0x99, 0xD2, 0x86, 0xE3, 0x02, 0x2F, 0xAC, 0xAD, 0x3E, 0x70, 0x4B, 0xE3 } }, // WOW-33978patch9.0.1_Beta + { 0x1423888694CDE5FCULL, { 0xE7, 0xFA, 0x1C, 0xD3, 0x4A, 0xEA, 0xB1, 0xB6, 0x1B, 0x0A, 0x6C, 0x9E, 0xA6, 0xA9, 0x04, 0x08 } }, // WOW-33978patch9.0.1_Beta + { 0x153616FF38D5E460ULL, { 0x0A, 0x94, 0x08, 0xA4, 0x9A, 0x1C, 0xE0, 0x5B, 0x90, 0x30, 0x4D, 0x01, 0x7D, 0xE7, 0x58, 0x92 } }, // WOW-33978patch9.0.1_Beta + { 0x15D5A13976DCBD05ULL, { 0xD1, 0x7D, 0x19, 0xEE, 0x14, 0xF7, 0xDD, 0x88, 0x0F, 0x0E, 0xF6, 0xCE, 0x64, 0x44, 0x54, 0xBE } }, // WOW-33978patch9.0.1_Beta + { 0x15FA2DA0B33C39EEULL, { 0xA2, 0x94, 0x10, 0xBB, 0x93, 0x1D, 0xA3, 0xE7, 0x84, 0x85, 0x96, 0xFB, 0xA7, 0x7F, 0x50, 0x37 } }, // WOW-33978patch9.0.1_Beta + { 0x17ABC9D27E24B4D7ULL, { 0xFA, 0x41, 0x45, 0x70, 0x62, 0x60, 0x5A, 0x17, 0x3D, 0x10, 0xFB, 0x90, 0xE0, 0x77, 0x9A, 0x44 } }, // WOW-33978patch9.0.1_Beta + { 0x188E37F5AB501082ULL, { 0xE5, 0x66, 0x96, 0x36, 0x09, 0x3C, 0xE1, 0xB8, 0x99, 0x75, 0x6B, 0xE6, 0x9B, 0x8C, 0x2C, 0x58 } }, // WOW-33978patch9.0.1_Beta + { 0x18C32E5601F89AC3ULL, { 0xC8, 0x64, 0x03, 0x2D, 0x3E, 0x9D, 0xA9, 0x29, 0xF9, 0xFE, 0xC6, 0xE5, 0xB5, 0x38, 0x94, 0xA1 } }, // WOW-33978patch9.0.1_Beta + { 0x1A16C07D5F35124FULL, { 0x34, 0xAB, 0xF6, 0xA4, 0x68, 0x69, 0xE0, 0x0C, 0xBB, 0x83, 0x94, 0x7C, 0xFD, 0x6A, 0x39, 0x47 } }, // WOW-33978patch9.0.1_Beta + { 0x1A4F317C88C93C04ULL, { 0xFF, 0x16, 0x9D, 0x5A, 0xB8, 0x13, 0x5D, 0x38, 0xEC, 0x92, 0xFE, 0xAB, 0xEE, 0x0E, 0x39, 0x7B } }, // WOW-33978patch9.0.1_Beta + { 0x1ABF6A7265BBC7AFULL, { 0x9E, 0x12, 0x7C, 0xE7, 0x16, 0x69, 0x1C, 0x50, 0xB5, 0xD4, 0x95, 0x9D, 0xAD, 0xA8, 0xEB, 0xEC } }, // WOW-33978patch9.0.1_Beta + { 0x1BD281160FB552FDULL, { 0xEA, 0x57, 0x6F, 0x20, 0xAA, 0x9A, 0xF5, 0x8A, 0x76, 0xF4, 0xB8, 0x43, 0xF5, 0x3A, 0x8E, 0x5D } }, // WOW-33978patch9.0.1_Beta + { 0x1BE9A4EEC5B455C5ULL, { 0xBA, 0xFC, 0x5C, 0xC3, 0x9B, 0xDD, 0xC1, 0xD8, 0x02, 0xBA, 0x07, 0x46, 0x41, 0x42, 0x7D, 0x68 } }, // WOW-33978patch9.0.1_Beta + { 0x1DCF36E171124EFCULL, { 0xC6, 0x59, 0x7A, 0xA9, 0x76, 0x98, 0x8B, 0xD4, 0xCF, 0x57, 0xB8, 0x33, 0x04, 0xDA, 0x19, 0x34 } }, // WOW-33978patch9.0.1_Beta + { 0x1E47BD8DB4D6032FULL, { 0x0F, 0x81, 0x0C, 0x27, 0xE9, 0x10, 0xA5, 0xFF, 0xD1, 0x47, 0x79, 0x27, 0xE2, 0x40, 0x64, 0x59 } }, // WOW-33978patch9.0.1_Beta + { 0x1FB4F1C56721C87EULL, { 0x64, 0x8C, 0x26, 0x55, 0xE0, 0xAF, 0x50, 0xF4, 0x26, 0xC5, 0xCD, 0x2C, 0x4F, 0xD2, 0x21, 0xE7 } }, // WOW-33978patch9.0.1_Beta + { 0x225902F0EC8BF0FCULL, { 0x09, 0x81, 0x25, 0xBC, 0x75, 0x9E, 0x47, 0xA4, 0x4F, 0x46, 0x7E, 0xCC, 0x28, 0x48, 0x07, 0x47 } }, // WOW-33978patch9.0.1_Beta + { 0x225EADE089BA38D8ULL, { 0xFD, 0x5D, 0x6A, 0x9A, 0xDA, 0x76, 0xC7, 0x06, 0x7A, 0x83, 0xBF, 0x5E, 0x56, 0x92, 0xC6, 0xC3 } }, // WOW-33978patch9.0.1_Beta + { 0x22EE6101A078F310ULL, { 0xEC, 0x43, 0x74, 0x15, 0xFA, 0x5B, 0xC5, 0x98, 0x79, 0xBB, 0xAA, 0x5C, 0x5F, 0xF3, 0x6A, 0xCD } }, // WOW-33978patch9.0.1_Beta + { 0x23457E4AB5352E38ULL, { 0xEE, 0x3F, 0xDC, 0xA7, 0x8B, 0x42, 0xC0, 0x75, 0x03, 0xEF, 0x98, 0x86, 0xF9, 0x8B, 0xB0, 0x28 } }, // WOW-33978patch9.0.1_Beta + { 0x236B38CBE43FC318ULL, { 0x14, 0x89, 0xB7, 0x05, 0x62, 0xD5, 0x6A, 0x60, 0x76, 0x00, 0xFA, 0xA8, 0x0A, 0x5A, 0xFD, 0xEF } }, // WOW-33978patch9.0.1_Beta + { 0x264DB70A1A6CC720ULL, { 0x94, 0x88, 0x48, 0x13, 0x6B, 0xDD, 0x11, 0xD9, 0x95, 0xF3, 0xC4, 0x16, 0x9B, 0x8A, 0x9C, 0xAF } }, // WOW-33978patch9.0.1_Beta + { 0x2678A2608A95FAAEULL, { 0xDB, 0x72, 0x2D, 0x47, 0x18, 0xB8, 0xB2, 0xC3, 0x13, 0x17, 0xB8, 0x43, 0xF6, 0x2D, 0x5F, 0xA8 } }, // WOW-33978patch9.0.1_Beta + { 0x27683B8282673916ULL, { 0x9A, 0x06, 0x02, 0xC6, 0x62, 0x4A, 0xD2, 0xB1, 0x85, 0x18, 0x7C, 0x8B, 0xD7, 0xAF, 0x81, 0x7A } }, // WOW-33978patch9.0.1_Beta + { 0x278A558C1E4C9789ULL, { 0x7C, 0xCF, 0xEE, 0xF6, 0x2E, 0xD5, 0x65, 0x60, 0xFD, 0x12, 0x94, 0xBB, 0x79, 0x7E, 0xC0, 0x0C } }, // WOW-33978patch9.0.1_Beta + { 0x29C4474FA5A650C2ULL, { 0xB4, 0x5A, 0x3E, 0x43, 0xB8, 0x18, 0x52, 0xD2, 0x69, 0x70, 0x0D, 0x11, 0xCA, 0xAA, 0x52, 0x74 } }, // WOW-33978patch9.0.1_Beta + { 0x29E553202112D688ULL, { 0xBB, 0x29, 0xC4, 0x2B, 0x23, 0xD1, 0x0E, 0xBE, 0x4E, 0xC7, 0x33, 0xC0, 0x4F, 0xB1, 0x9E, 0x0C } }, // WOW-33978patch9.0.1_Beta + { 0x2A50EBBA4B44FBF5ULL, { 0x7F, 0x1F, 0xA1, 0x12, 0x4C, 0xC3, 0xF4, 0x70, 0xAD, 0x48, 0x30, 0xB6, 0xD6, 0xA1, 0xF5, 0x13 } }, // WOW-33978patch9.0.1_Beta + { 0x2AFA1E90F5548DADULL, { 0x76, 0x6F, 0x2A, 0x52, 0x49, 0x29, 0xD9, 0x97, 0x83, 0x5D, 0xAE, 0x83, 0xC9, 0xB3, 0xDF, 0x4B } }, // WOW-33978patch9.0.1_Beta + { 0x2CDD202075F2BB7BULL, { 0x8B, 0x78, 0x02, 0x28, 0xAD, 0x85, 0xC5, 0xB0, 0x26, 0x53, 0xB9, 0x0E, 0x6A, 0x98, 0x28, 0x44 } }, // WOW-33978patch9.0.1_Beta + { 0x2D5511A1586B85BDULL, { 0x3A, 0x2A, 0x7A, 0x6B, 0x63, 0xE6, 0xA7, 0x0E, 0x26, 0x52, 0xDB, 0x45, 0x1C, 0x80, 0xA8, 0x78 } }, // WOW-33978patch9.0.1_Beta + { 0x2D6ADB0D7D20DA8FULL, { 0x39, 0x5C, 0xD9, 0xDF, 0xCF, 0x86, 0xA5, 0xF5, 0x53, 0x1A, 0x1C, 0xA3, 0xDE, 0x43, 0x96, 0x04 } }, // WOW-33978patch9.0.1_Beta + { 0x323E310D6BD63AC9ULL, { 0x52, 0x19, 0xD6, 0xB2, 0x0E, 0x8E, 0xA3, 0xF9, 0x72, 0xFD, 0x85, 0xD3, 0x55, 0xD3, 0x30, 0xD8 } }, // WOW-33978patch9.0.1_Beta + { 0x337A168A21969F6CULL, { 0x67, 0x03, 0x67, 0x8A, 0x02, 0x29, 0x4E, 0x8E, 0x8B, 0xCF, 0xC4, 0x23, 0xF0, 0xFF, 0xF9, 0x35 } }, // WOW-33978patch9.0.1_Beta + { 0x33801621A7C885FDULL, { 0x93, 0xBE, 0xD4, 0x71, 0xDD, 0x0C, 0xF9, 0x02, 0xA3, 0xA2, 0x43, 0xD8, 0xA3, 0x44, 0x11, 0xC5 } }, // WOW-33978patch9.0.1_Beta + { 0x34487D8CF061757AULL, { 0x33, 0x26, 0x12, 0x28, 0xE6, 0x94, 0xDD, 0x95, 0x9A, 0xC9, 0xA6, 0x8B, 0x73, 0x6F, 0x6A, 0xF3 } }, // WOW-33978patch9.0.1_Beta + { 0x35FC62C0E25BFA2CULL, { 0x69, 0x0D, 0x5E, 0xC1, 0xE5, 0x6A, 0xA0, 0x50, 0x49, 0x5B, 0x7B, 0xAE, 0x51, 0x3C, 0xAB, 0xCF } }, // WOW-33978patch9.0.1_Beta + { 0x3692291361CDD66BULL, { 0x87, 0x81, 0x36, 0x91, 0xB2, 0xFA, 0xEA, 0xBC, 0x9A, 0x28, 0x26, 0x5B, 0xE0, 0x3F, 0xAE, 0x7E } }, // WOW-33978patch9.0.1_Beta + { 0x38138436341EB55EULL, { 0xCD, 0x0D, 0xF8, 0x43, 0x30, 0x6C, 0x37, 0xB5, 0x17, 0x68, 0x91, 0xFC, 0x56, 0xDF, 0x7D, 0x57 } }, // WOW-33978patch9.0.1_Beta + { 0x390336A9AC1ADBD3ULL, { 0xF1, 0x93, 0xE1, 0xAC, 0x0A, 0x1C, 0x80, 0x93, 0xF2, 0x31, 0x82, 0x47, 0xF1, 0xED, 0xC6, 0xA4 } }, // WOW-33978patch9.0.1_Beta + { 0x41A0F110F49EB86AULL, { 0xDF, 0x50, 0xC9, 0x44, 0xB4, 0x2E, 0xF1, 0x6B, 0x4E, 0x6F, 0xA3, 0xE3, 0xF2, 0x8E, 0x70, 0xF7 } }, // WOW-33978patch9.0.1_Beta + { 0x41BDEA4884539B22ULL, { 0x14, 0xC6, 0xE1, 0xA2, 0xC0, 0xBB, 0xCF, 0x1E, 0x6D, 0x21, 0xA2, 0x1F, 0x39, 0xD5, 0x51, 0xCA } }, // WOW-33978patch9.0.1_Beta + { 0x41E698459DAD7101ULL, { 0xBF, 0xE8, 0x76, 0x01, 0x16, 0x60, 0xAD, 0x32, 0xA5, 0x72, 0x7E, 0x48, 0x9F, 0x83, 0x64, 0x68 } }, // WOW-33978patch9.0.1_Beta + { 0x4223772617A3212AULL, { 0xC4, 0x09, 0x63, 0x17, 0x1B, 0x49, 0x6B, 0xB7, 0x65, 0xA5, 0x6E, 0xC3, 0xF2, 0x2D, 0xD6, 0x48 } }, // WOW-33978patch9.0.1_Beta + { 0x422ABA4AE3E43AC5ULL, { 0xA0, 0xAE, 0x8D, 0xA9, 0x66, 0x39, 0x3F, 0x20, 0x60, 0x12, 0xA6, 0x1A, 0xE8, 0x19, 0xBD, 0xEA } }, // WOW-33978patch9.0.1_Beta + { 0x429E445F8823DE47ULL, { 0xCB, 0x10, 0x47, 0x34, 0xDC, 0x4A, 0xDE, 0x45, 0x4A, 0x7A, 0x1A, 0x17, 0x96, 0x42, 0x3B, 0x21 } }, // WOW-33978patch9.0.1_Beta + { 0x43855C4ABC59CD03ULL, { 0x91, 0xA3, 0x74, 0xB1, 0xE8, 0xCF, 0xE4, 0x6D, 0x2B, 0x82, 0xC7, 0x69, 0x52, 0x2D, 0x7F, 0xAF } }, // WOW-33978patch9.0.1_Beta + { 0x44324FEB63BAD71BULL, { 0xBA, 0xA7, 0xA3, 0x31, 0x1F, 0x36, 0xD3, 0xF6, 0xC1, 0x58, 0x9F, 0xBF, 0x34, 0xF1, 0x63, 0xAF } }, // WOW-33978patch9.0.1_Beta + { 0x445C444DDCB144D0ULL, { 0xE1, 0x1F, 0x30, 0x61, 0x10, 0xA2, 0x47, 0xAC, 0x08, 0x7E, 0x44, 0x66, 0xE8, 0x50, 0x5A, 0xC2 } }, // WOW-33978patch9.0.1_Beta + { 0x4570E5C612AD4680ULL, { 0xC7, 0x5A, 0x72, 0x40, 0xBF, 0x08, 0x89, 0xBD, 0xB5, 0x0D, 0xB2, 0x14, 0x7C, 0xAE, 0xC2, 0x9F } }, // WOW-33978patch9.0.1_Beta + { 0x463B8AC09861DBF2ULL, { 0x85, 0x14, 0x8A, 0x61, 0x6B, 0x3D, 0x2C, 0x0F, 0x3B, 0x50, 0x22, 0xB8, 0x71, 0xE4, 0xAB, 0x2F } }, // WOW-33978patch9.0.1_Beta + { 0x46B9652048C5B9EBULL, { 0x42, 0xAD, 0x0B, 0xE5, 0x4B, 0xCF, 0xED, 0x59, 0x75, 0xC3, 0x5B, 0xC8, 0x00, 0xF6, 0x94, 0x4B } }, // WOW-33978patch9.0.1_Beta + { 0x477AF884E1779F04ULL, { 0x81, 0xE7, 0x36, 0x61, 0x9B, 0x2A, 0xA8, 0xD3, 0xBE, 0xB3, 0x80, 0x01, 0x8C, 0x04, 0xC0, 0x97 } }, // WOW-33978patch9.0.1_Beta + { 0x49E4DB410ACD71E4ULL, { 0xEC, 0xAD, 0x54, 0xE4, 0xCC, 0x6A, 0xE5, 0xA2, 0xB1, 0xCD, 0xFC, 0x94, 0xDC, 0xC4, 0xA7, 0xE0 } }, // WOW-33978patch9.0.1_Beta + { 0x4BA04135745B0C77ULL, { 0x48, 0xAC, 0x8F, 0x63, 0xF9, 0xF6, 0xD4, 0xFC, 0x7B, 0xBE, 0xF2, 0xF8, 0x97, 0x40, 0xB7, 0x3F } }, // WOW-33978patch9.0.1_Beta + { 0x4C3638A33B225E20ULL, { 0x85, 0xB3, 0x19, 0x7B, 0x10, 0x55, 0x03, 0xD9, 0xBC, 0x11, 0x76, 0xA6, 0xCE, 0x90, 0xB2, 0x1B } }, // WOW-33978patch9.0.1_Beta + { 0x4CA3E38A5F339D85ULL, { 0x65, 0xDA, 0x28, 0xD6, 0x97, 0xE8, 0x2F, 0x7F, 0xB3, 0x26, 0x98, 0xF5, 0xDC, 0x13, 0xFE, 0x67 } }, // WOW-33978patch9.0.1_Beta + { 0x4D356B23BBB63ABFULL, { 0x5B, 0x31, 0xF5, 0xD4, 0x37, 0x18, 0x20, 0xE0, 0x86, 0xD1, 0x59, 0x1F, 0x20, 0x96, 0x3C, 0x6F } }, // WOW-33978patch9.0.1_Beta + { 0x4D81CA32AF4851B8ULL, { 0x2F, 0xAF, 0x21, 0x8D, 0x81, 0x0A, 0x5D, 0x2C, 0x5B, 0xCD, 0x6E, 0xBE, 0x7A, 0xF6, 0x7C, 0x66 } }, // WOW-33978patch9.0.1_Beta + { 0x4E8FD51F7FDCB494ULL, { 0x6F, 0x19, 0x66, 0x48, 0xE9, 0xE0, 0xBD, 0x75, 0xC4, 0xC9, 0x63, 0x21, 0x4F, 0xBF, 0x43, 0x53 } }, // WOW-33978patch9.0.1_Beta + { 0x4F29CD1DBFF6A704ULL, { 0x19, 0xF0, 0x45, 0x81, 0x27, 0x1E, 0xB2, 0x56, 0xF1, 0x05, 0x34, 0xE5, 0x0C, 0x82, 0x9D, 0x30 } }, // WOW-33978patch9.0.1_Beta + { 0x50BDE6C6B138D920ULL, { 0x86, 0x3D, 0xE7, 0xEA, 0x7E, 0xDE, 0x52, 0x18, 0xCE, 0x92, 0x86, 0x36, 0x0D, 0xD5, 0x4C, 0xE3 } }, // WOW-33978patch9.0.1_Beta + { 0x51C45371AA62A30DULL, { 0x80, 0x29, 0x74, 0xB8, 0x2D, 0x99, 0x83, 0xCD, 0x78, 0xB6, 0x65, 0x33, 0x20, 0xD3, 0xDA, 0xA5 } }, // WOW-33978patch9.0.1_Beta + { 0x53422759826BCE28ULL, { 0x46, 0x7F, 0x7B, 0xB8, 0x45, 0xB5, 0x0A, 0xBE, 0x1B, 0x0B, 0xD7, 0x18, 0x95, 0xFD, 0x78, 0x38 } }, // WOW-33978patch9.0.1_Beta + { 0x54E0E8C0E9A4CEE7ULL, { 0x41, 0x8D, 0x3F, 0xA2, 0xCB, 0xA3, 0xD9, 0x72, 0x29, 0x36, 0x1E, 0x2D, 0xE7, 0x96, 0x79, 0x28 } }, // WOW-33978patch9.0.1_Beta + { 0x550AB6D42C0118D3ULL, { 0xBF, 0x50, 0x7B, 0x7E, 0xAC, 0x67, 0x29, 0x55, 0x0E, 0x87, 0xBD, 0x44, 0x4B, 0xB7, 0x0F, 0x35 } }, // WOW-33978patch9.0.1_Beta + { 0x577E78AECCE3D388ULL, { 0x19, 0x6B, 0x59, 0x45, 0x39, 0x36, 0x4E, 0xCC, 0xFF, 0xD9, 0x2E, 0x71, 0xD9, 0x19, 0x30, 0x20 } }, // WOW-33978patch9.0.1_Beta + { 0x587E8D3EB9594F4AULL, { 0x0E, 0xDE, 0x7A, 0x2C, 0x7B, 0xE8, 0xA1, 0x9A, 0x98, 0x73, 0x88, 0xC3, 0xF6, 0x04, 0x67, 0x55 } }, // WOW-33978patch9.0.1_Beta + { 0x591C8211EE53BFDBULL, { 0x46, 0xA6, 0x19, 0xF7, 0xA6, 0xC4, 0xE0, 0xCE, 0x54, 0x2B, 0xB1, 0xA9, 0xE4, 0x71, 0x3F, 0x34 } }, // WOW-33978patch9.0.1_Beta + { 0x597B3EA295C88FA7ULL, { 0x2D, 0x36, 0x4A, 0xE4, 0xD4, 0x6C, 0xEF, 0x42, 0x2A, 0x6F, 0x53, 0x1D, 0x9B, 0x1A, 0x7A, 0xD2 } }, // WOW-33978patch9.0.1_Beta + { 0x59CBA5A49554EB2FULL, { 0x4B, 0x5F, 0xF9, 0xC6, 0x7E, 0x02, 0x1C, 0x5E, 0x2A, 0xA3, 0xB0, 0x5A, 0xC9, 0xE0, 0x50, 0x96 } }, // WOW-33978patch9.0.1_Beta + { 0x5B1A3C7FC9D58D21ULL, { 0xA4, 0x8B, 0xA8, 0xE3, 0x19, 0x20, 0x7B, 0x2C, 0x04, 0xE8, 0x2B, 0x25, 0xC0, 0xF3, 0xC1, 0x49 } }, // WOW-33978patch9.0.1_Beta + { 0x5B256C6230E168FFULL, { 0x89, 0xF3, 0x1D, 0x0F, 0xA3, 0x81, 0xD7, 0x23, 0x55, 0x56, 0x6B, 0x01, 0x24, 0xB8, 0xE1, 0xF2 } }, // WOW-33978patch9.0.1_Beta + { 0x5B657AE4D191AAFBULL, { 0xF8, 0x84, 0xAA, 0xC1, 0xE2, 0xAB, 0x1C, 0x41, 0x3F, 0x7B, 0xAD, 0xDD, 0x14, 0x9D, 0x09, 0x61 } }, // WOW-33978patch9.0.1_Beta + { 0x5B93089CD9316EFEULL, { 0x95, 0x76, 0x53, 0xD3, 0x4A, 0xBF, 0x29, 0x88, 0x46, 0xFF, 0x56, 0x04, 0xC1, 0xEB, 0x06, 0xD0 } }, // WOW-33978patch9.0.1_Beta + { 0x5C172612CB60DEF2ULL, { 0xF5, 0x10, 0xBF, 0xEF, 0xFF, 0x2F, 0x87, 0x0B, 0x08, 0x93, 0x1B, 0x62, 0x52, 0x6F, 0x01, 0xFE } }, // WOW-33978patch9.0.1_Beta + { 0x5E6EB3F5C47183FFULL, { 0x73, 0xEC, 0xB7, 0xAE, 0x15, 0x19, 0xE3, 0x9C, 0xC8, 0xBB, 0xD8, 0xF9, 0x90, 0xF3, 0xAC, 0xFB } }, // WOW-33978patch9.0.1_Beta + { 0x5E7181FBA91F3766ULL, { 0x2F, 0x6A, 0xAB, 0xDC, 0x38, 0x9E, 0xA1, 0x0A, 0x11, 0xA9, 0xF1, 0x83, 0x58, 0x04, 0xF8, 0x6C } }, // WOW-33978patch9.0.1_Beta + { 0x5E7B9DCD0092888BULL, { 0x6F, 0xE5, 0xA1, 0x40, 0x39, 0x93, 0xAE, 0x2A, 0x22, 0xA4, 0xF1, 0xAD, 0x31, 0x14, 0x4D, 0xAB } }, // WOW-33978patch9.0.1_Beta + { 0x5F1C8C3CFABDC578ULL, { 0xEA, 0x5A, 0x36, 0x31, 0x46, 0x09, 0xC6, 0x70, 0x84, 0xDB, 0x63, 0xCF, 0xF7, 0x87, 0xDF, 0xCA } }, // WOW-33978patch9.0.1_Beta + { 0x62EDE4DE7880CC68ULL, { 0xEA, 0xAA, 0x8D, 0x5C, 0x76, 0xEA, 0x95, 0x76, 0x31, 0x52, 0xAE, 0x50, 0x3C, 0xF5, 0x67, 0x45 } }, // WOW-33978patch9.0.1_Beta + { 0x637AD198DBD985ECULL, { 0xA8, 0x31, 0xE0, 0x85, 0xC7, 0xA0, 0x98, 0x45, 0x57, 0xE7, 0x97, 0x30, 0x5C, 0xB2, 0xA2, 0x63 } }, // WOW-33978patch9.0.1_Beta + { 0x6444A004E5F352B9ULL, { 0x76, 0x8A, 0x1C, 0x07, 0x02, 0x50, 0xD1, 0x70, 0x95, 0x02, 0x3D, 0xBD, 0xBD, 0x02, 0x3B, 0xC7 } }, // WOW-33978patch9.0.1_Beta + { 0x649F6483822B8C3EULL, { 0xDB, 0xD9, 0x35, 0x20, 0x0A, 0x22, 0xE7, 0x89, 0x75, 0x89, 0x40, 0xE9, 0x1E, 0x1C, 0xFC, 0xAE } }, // WOW-33978patch9.0.1_Beta + { 0x650E0558CFE68DBDULL, { 0xE4, 0x98, 0x29, 0x4E, 0x3A, 0x2C, 0xB7, 0xF1, 0x0B, 0x0F, 0x1A, 0xC8, 0x98, 0xF3, 0x79, 0xB6 } }, // WOW-33978patch9.0.1_Beta + { 0x667C9AD6F57610C7ULL, { 0xF7, 0xF9, 0x8E, 0xFE, 0x5D, 0xB2, 0x27, 0x92, 0x8F, 0x97, 0x02, 0x85, 0x20, 0xD9, 0x7F, 0xC3 } }, // WOW-33978patch9.0.1_Beta + { 0x67AD32C6DFF4B640ULL, { 0x03, 0x32, 0x11, 0xB8, 0x92, 0xF5, 0x2C, 0xBE, 0x56, 0x10, 0x51, 0xEB, 0xAA, 0xC8, 0xCE, 0x2F } }, // WOW-33978patch9.0.1_Beta + { 0x6870068DF23BA71BULL, { 0x58, 0x97, 0x6C, 0xEA, 0xF5, 0xE2, 0xAB, 0x19, 0x38, 0x01, 0xD7, 0x13, 0xAB, 0xEC, 0x60, 0x5B } }, // WOW-33978patch9.0.1_Beta + { 0x69CADB492EBF739EULL, { 0x63, 0xA4, 0x2B, 0xB5, 0x28, 0x05, 0x0C, 0x59, 0x47, 0x73, 0x5C, 0x18, 0x36, 0x60, 0x5C, 0x95 } }, // WOW-33978patch9.0.1_Beta + { 0x6B20D9D506B930E6ULL, { 0xA4, 0x2E, 0xEC, 0xB7, 0x63, 0xC8, 0x79, 0xC3, 0x9C, 0xFC, 0xC3, 0x82, 0x0C, 0xC0, 0x57, 0x13 } }, // WOW-33978patch9.0.1_Beta + { 0x6BF0360FC30A1651ULL, { 0x7A, 0x69, 0xDC, 0x9A, 0x2E, 0xF9, 0x6E, 0x9E, 0xFA, 0x1F, 0x4E, 0xE3, 0x75, 0x44, 0xD0, 0x60 } }, // WOW-33978patch9.0.1_Beta + { 0x6C3380DB72AFCF88ULL, { 0xC5, 0xED, 0xF5, 0x55, 0xCE, 0x52, 0xF6, 0x71, 0x7B, 0x38, 0x28, 0x1C, 0x1B, 0x46, 0xCC, 0xDC } }, // WOW-33978patch9.0.1_Beta + { 0x6CEAD213E31A6F01ULL, { 0x1D, 0x26, 0x3C, 0xFB, 0x4B, 0xD4, 0xDE, 0x9E, 0xBF, 0x59, 0xB1, 0x28, 0x7E, 0x39, 0x7F, 0xFE } }, // WOW-33978patch9.0.1_Beta + { 0x6D6AD51EAA144766ULL, { 0x3E, 0xDD, 0x69, 0x0A, 0x09, 0x18, 0xA4, 0x2B, 0x49, 0xCB, 0xE2, 0x14, 0xBC, 0x90, 0x5D, 0x22 } }, // WOW-33978patch9.0.1_Beta + { 0x6E92CDCE4FEA3B27ULL, { 0xE9, 0x88, 0x05, 0xA6, 0xB0, 0xD4, 0xEA, 0x3C, 0x28, 0x0A, 0x4E, 0xF4, 0x9A, 0xE5, 0x10, 0x11 } }, // WOW-33978patch9.0.1_Beta + { 0x6EA6B9E529B29CC8ULL, { 0x7D, 0x8F, 0xE7, 0x88, 0xCA, 0x9A, 0xF0, 0x7F, 0x99, 0xC3, 0xDC, 0xA6, 0x1E, 0x1F, 0xBA, 0xC7 } }, // WOW-33978patch9.0.1_Beta + { 0x72337416FD82C794ULL, { 0xF4, 0x78, 0x2D, 0x77, 0xEA, 0xDA, 0x33, 0x0A, 0x2D, 0xD1, 0x78, 0x9D, 0x64, 0x7F, 0x27, 0xBF } }, // WOW-33978patch9.0.1_Beta + { 0x725E3CA857E0D99FULL, { 0x91, 0xD3, 0xAB, 0xCC, 0xDE, 0xE7, 0x20, 0xF4, 0xBA, 0xD5, 0xB9, 0x0E, 0xFA, 0xB9, 0x04, 0xFC } }, // WOW-33978patch9.0.1_Beta + { 0x747A16FD3A3F6970ULL, { 0x16, 0x26, 0xFE, 0x4D, 0x37, 0x25, 0xE1, 0xD1, 0x7D, 0xEE, 0xE1, 0xC2, 0xDF, 0xEE, 0x85, 0xD4 } }, // WOW-33978patch9.0.1_Beta + { 0x75BD0F89A7DF7076ULL, { 0x9A, 0x4F, 0x51, 0xF7, 0xDB, 0x21, 0xD0, 0x49, 0x32, 0xAF, 0x81, 0x86, 0x42, 0xCC, 0x7B, 0xEC } }, // WOW-33978patch9.0.1_Beta + { 0x75E2B6A4145B00DBULL, { 0xE0, 0x9B, 0x5A, 0x79, 0xB5, 0xFB, 0xAD, 0xE1, 0x9D, 0x1D, 0x97, 0x9B, 0x2C, 0x32, 0xE4, 0xB7 } }, // WOW-33978patch9.0.1_Beta + { 0x77F0A6FE6BE42E62ULL, { 0x35, 0xBA, 0xB9, 0x29, 0x81, 0xF6, 0x04, 0xEF, 0x4C, 0x3C, 0x22, 0x53, 0xC0, 0x3D, 0x36, 0xCE } }, // WOW-33978patch9.0.1_Beta + { 0x7810113EF44E92B2ULL, { 0xA2, 0x18, 0x6B, 0x58, 0x6A, 0xE6, 0x86, 0xF3, 0xE1, 0x57, 0x9F, 0xFA, 0x9D, 0xDF, 0x17, 0x03 } }, // WOW-33978patch9.0.1_Beta + { 0x78B7C378F1424152ULL, { 0xDF, 0x20, 0xB3, 0xFA, 0x41, 0x5B, 0x16, 0x25, 0xAA, 0x7D, 0x82, 0x22, 0x61, 0x2F, 0x75, 0xA0 } }, // WOW-33978patch9.0.1_Beta + { 0x79383B3295AA93C4ULL, { 0xEF, 0xDE, 0x6A, 0xEB, 0xDA, 0x6A, 0xBE, 0xD6, 0x5B, 0x2F, 0xE9, 0x1F, 0x33, 0x95, 0xDA, 0x4E } }, // WOW-33978patch9.0.1_Beta + { 0x7AD23E997C77CBEBULL, { 0x05, 0x6F, 0x35, 0x4E, 0xA0, 0x86, 0x41, 0x26, 0x53, 0x44, 0x33, 0x6C, 0xEF, 0x0C, 0xDB, 0x8D } }, // WOW-33978patch9.0.1_Beta + { 0x7C86AE10DE9A2D24ULL, { 0x7B, 0x0A, 0x70, 0xD0, 0xD1, 0x6E, 0xA7, 0x34, 0x5B, 0xFF, 0xDD, 0x56, 0xF6, 0x5E, 0xA2, 0x7F } }, // WOW-33978patch9.0.1_Beta + { 0x7CD6AC9BD4B6C2F1ULL, { 0x20, 0xE7, 0x93, 0x06, 0x6B, 0x7D, 0x48, 0x94, 0x6B, 0xCE, 0x64, 0xA1, 0x6E, 0x72, 0x31, 0xD7 } }, // WOW-33978patch9.0.1_Beta + { 0x7E1F1D367C75D4E3ULL, { 0x37, 0x15, 0xB8, 0x5F, 0x6E, 0xCD, 0xBD, 0x3B, 0x1D, 0x85, 0x89, 0x60, 0x22, 0x53, 0xDC, 0x75 } }, // WOW-33978patch9.0.1_Beta + { 0x7E4C540FC51875ECULL, { 0x36, 0x71, 0xFC, 0xCE, 0xDF, 0xF2, 0x7D, 0x9F, 0x46, 0x3F, 0x6A, 0x5B, 0xED, 0xE5, 0xE2, 0x2D } }, // WOW-33978patch9.0.1_Beta + { 0x7E766271DF1A2F90ULL, { 0x2C, 0xEC, 0x2B, 0x76, 0xCF, 0x05, 0x63, 0x4D, 0xFB, 0xC4, 0xCB, 0x1F, 0xB9, 0x8C, 0xBC, 0x4F } }, // WOW-33978patch9.0.1_Beta + { 0x7F7D6EDEF8F5BCFCULL, { 0xF1, 0xD5, 0x9F, 0xEC, 0x5C, 0xB7, 0x4B, 0x2E, 0x66, 0x38, 0x00, 0xB7, 0xDA, 0xBF, 0x32, 0x16 } }, // WOW-33978patch9.0.1_Beta + { 0x801FD0E0D505C316ULL, { 0x91, 0x30, 0x64, 0x6A, 0xD7, 0x52, 0x44, 0xBB, 0x44, 0x5B, 0x66, 0x88, 0xA5, 0x00, 0x7B, 0x5C } }, // WOW-33978patch9.0.1_Beta + { 0x8281CFAEB6AE6182ULL, { 0xC3, 0x25, 0x34, 0xB1, 0x97, 0x5C, 0x71, 0x07, 0xB6, 0x38, 0xD4, 0x77, 0x94, 0xA9, 0xF3, 0xF2 } }, // WOW-33978patch9.0.1_Beta + { 0x834E863E91A946E0ULL, { 0xFF, 0xC4, 0x7E, 0x87, 0xFA, 0xD8, 0x8A, 0x87, 0x24, 0xE2, 0xCF, 0x3E, 0xAE, 0xE1, 0xAA, 0x06 } }, // WOW-33978patch9.0.1_Beta + { 0x85B1F0C5AFA7684AULL, { 0x7A, 0x29, 0xDC, 0xA9, 0x90, 0xAA, 0x0A, 0x7D, 0xF1, 0x99, 0x4E, 0xAF, 0x00, 0x04, 0x54, 0xB8 } }, // WOW-33978patch9.0.1_Beta + { 0x85CB9DF9FC580C0EULL, { 0xD1, 0x70, 0xBC, 0xFC, 0x13, 0xB1, 0xA2, 0x18, 0x5C, 0x4F, 0xE1, 0x3C, 0x5F, 0x55, 0x5E, 0x2D } }, // WOW-33978patch9.0.1_Beta + { 0x867D98DC263C7AE1ULL, { 0xD6, 0xC5, 0xAE, 0x41, 0x33, 0xA0, 0xD3, 0x2F, 0x6A, 0x33, 0x39, 0x19, 0xC9, 0x95, 0xC2, 0x9F } }, // WOW-33978patch9.0.1_Beta + { 0x86ACAF9277898823ULL, { 0xE6, 0x3D, 0xFD, 0x69, 0x16, 0xBD, 0xDE, 0x96, 0x32, 0x63, 0x3B, 0x25, 0x5B, 0xEE, 0x73, 0x10 } }, // WOW-33978patch9.0.1_Beta + { 0x87413DE10A58AB14ULL, { 0x0B, 0x08, 0x32, 0x50, 0x17, 0x72, 0x9F, 0xD1, 0xBF, 0x2B, 0xA6, 0xC9, 0xEC, 0x03, 0xB0, 0x91 } }, // WOW-33978patch9.0.1_Beta + { 0x8831955158E50488ULL, { 0x12, 0x5E, 0x99, 0x2B, 0x50, 0xDD, 0x3C, 0x1D, 0x9B, 0xD5, 0xA4, 0x7D, 0xCA, 0xD7, 0x4F, 0x63 } }, // WOW-33978patch9.0.1_Beta + { 0x8A34D884566690F3ULL, { 0xD7, 0x7E, 0x4B, 0x5D, 0x2D, 0x5F, 0x2A, 0x07, 0xD1, 0xB7, 0x4C, 0x77, 0x2C, 0x7B, 0x9E, 0x1D } }, // WOW-33978patch9.0.1_Beta + { 0x8AA33E951B061C6CULL, { 0x45, 0xF8, 0xA8, 0x73, 0x94, 0x61, 0xA1, 0x5B, 0x5E, 0xEC, 0xDB, 0x8E, 0xD6, 0xD6, 0x68, 0x20 } }, // WOW-33978patch9.0.1_Beta + { 0x8AB2DCD201956FF5ULL, { 0xF4, 0x91, 0x31, 0x04, 0x7B, 0x25, 0xA7, 0xD3, 0x00, 0x67, 0xC7, 0xCB, 0x31, 0xF4, 0xB7, 0xC8 } }, // WOW-33978patch9.0.1_Beta + { 0x8AFF128B2C44402FULL, { 0x09, 0x28, 0x59, 0x7D, 0xDA, 0x06, 0x1C, 0xCA, 0x27, 0x72, 0x63, 0x9B, 0x18, 0x15, 0x3B, 0xBA } }, // WOW-33978patch9.0.1_Beta + { 0x929399E254952F89ULL, { 0x76, 0x23, 0x36, 0xB5, 0x0C, 0xBB, 0x8C, 0xBF, 0xA6, 0xEC, 0x6F, 0xF2, 0x97, 0x00, 0x96, 0x40 } }, // WOW-33978patch9.0.1_Beta + { 0x93A98F82D5B5FA3DULL, { 0x9A, 0x84, 0x56, 0x3A, 0xC7, 0xF1, 0x9E, 0x66, 0xAC, 0x4F, 0x63, 0x34, 0x6D, 0x58, 0xCB, 0xBC } }, // WOW-33978patch9.0.1_Beta + { 0x9440B38F8FC83801ULL, { 0xF2, 0x35, 0xB5, 0x29, 0x24, 0x61, 0xAD, 0xD2, 0xCD, 0x58, 0x27, 0x5F, 0xDA, 0xBF, 0x2D, 0x91 } }, // WOW-33978patch9.0.1_Beta + { 0x953B60DFAAD53C53ULL, { 0x0F, 0xFD, 0xE3, 0x48, 0xDB, 0xBF, 0x68, 0x28, 0x10, 0x38, 0x61, 0xE7, 0xC2, 0x02, 0xEE, 0x03 } }, // WOW-33978patch9.0.1_Beta + { 0x96CDB729EF5FF4D8ULL, { 0x9D, 0x5C, 0xD0, 0x16, 0x7D, 0xA6, 0x0B, 0x4A, 0x5D, 0x5B, 0x7E, 0xB1, 0x0F, 0x1F, 0x44, 0x02 } }, // WOW-33978patch9.0.1_Beta + { 0x96D55B6111ADB046ULL, { 0x7D, 0x8B, 0x9D, 0x2B, 0x57, 0x88, 0xCF, 0x14, 0x94, 0xE1, 0xBE, 0x73, 0xA3, 0x2A, 0x0A, 0xEB } }, // WOW-33978patch9.0.1_Beta + { 0x994C40C879819D41ULL, { 0x88, 0xA3, 0x28, 0x44, 0xB2, 0x2E, 0xB1, 0xE8, 0x36, 0x2B, 0x72, 0x8A, 0xE5, 0x1F, 0x66, 0x63 } }, // WOW-33978patch9.0.1_Beta + { 0x9A4F5BC0D2DF3E7CULL, { 0x27, 0x5D, 0x03, 0x60, 0xE8, 0x11, 0xEE, 0x2F, 0x3E, 0xB3, 0xBC, 0xCA, 0x96, 0xFA, 0x39, 0x88 } }, // WOW-33978patch9.0.1_Beta + { 0x9BB64D7C24F7F570ULL, { 0xA5, 0xF5, 0x27, 0xB1, 0x2A, 0x7C, 0x54, 0x49, 0x01, 0x30, 0x1F, 0x0C, 0xC4, 0xF7, 0x5A, 0xC6 } }, // WOW-33978patch9.0.1_Beta + { 0x9CAE05184985E6FAULL, { 0x7D, 0x79, 0xCA, 0x06, 0x09, 0xB2, 0xA9, 0xF5, 0x2C, 0x17, 0xB4, 0x91, 0xB2, 0x2F, 0xF2, 0x95 } }, // WOW-33978patch9.0.1_Beta + { 0x9DE3C22E44D3D817ULL, { 0x2A, 0xD1, 0x8A, 0xE6, 0x65, 0x74, 0xB1, 0x78, 0x4A, 0x9B, 0x52, 0xC4, 0xE4, 0x5C, 0x47, 0x0C } }, // WOW-33978patch9.0.1_Beta + { 0x9E10A1C6E2156E96ULL, { 0xA1, 0x4F, 0x9D, 0x5B, 0x4B, 0x8E, 0x6F, 0xFC, 0x17, 0x33, 0x48, 0xA8, 0x16, 0x89, 0x88, 0x2D } }, // WOW-33978patch9.0.1_Beta + { 0x9E84167C7BCCAECFULL, { 0xBB, 0x28, 0xC7, 0x41, 0x89, 0x32, 0x7B, 0xEC, 0x53, 0xC1, 0xF1, 0xD9, 0x0D, 0x62, 0xBD, 0xA6 } }, // WOW-33978patch9.0.1_Beta + { 0xA1651FBBB33533C8ULL, { 0xAB, 0x1E, 0x3D, 0x12, 0x8C, 0x6E, 0xC9, 0x4E, 0x6C, 0x7E, 0x0B, 0xAB, 0x3F, 0xF9, 0x6B, 0x54 } }, // WOW-33978patch9.0.1_Beta + { 0xA1F082630668B975ULL, { 0xA0, 0xC9, 0xAB, 0x98, 0x7F, 0x54, 0x4D, 0xAD, 0x86, 0x73, 0x5E, 0xEC, 0x3A, 0xB7, 0x0C, 0xBC } }, // WOW-33978patch9.0.1_Beta + { 0xA2A3787CEE9A05EEULL, { 0x2F, 0xAA, 0x35, 0x7F, 0x63, 0xC7, 0x2E, 0x74, 0x9B, 0x42, 0x3E, 0x45, 0xA7, 0x21, 0xE5, 0x49 } }, // WOW-33978patch9.0.1_Beta + { 0xA6D012ADD54A30CEULL, { 0x22, 0xE1, 0x30, 0x2E, 0xEB, 0xD9, 0x98, 0xCB, 0x7F, 0x05, 0xBC, 0xAF, 0x1D, 0x85, 0x39, 0xC6 } }, // WOW-33978patch9.0.1_Beta + { 0xA7E2CEFD0280FD3AULL, { 0x08, 0x90, 0x89, 0x66, 0x8F, 0xD4, 0xF2, 0xCA, 0x94, 0xE0, 0x28, 0xCE, 0x0E, 0x8F, 0x0E, 0xAD } }, // WOW-33978patch9.0.1_Beta + { 0xA8E1094D80B82D21ULL, { 0x8F, 0xA8, 0xB2, 0xEE, 0x12, 0xF4, 0x5E, 0xD0, 0xF2, 0x40, 0x1C, 0x03, 0x3B, 0x32, 0x43, 0x8C } }, // WOW-33978patch9.0.1_Beta + { 0xAA15EAD581169812ULL, { 0x60, 0xAA, 0x2D, 0x1C, 0xB7, 0xC2, 0x92, 0x84, 0xDD, 0x63, 0x6E, 0x35, 0x77, 0xAF, 0x3E, 0xFD } }, // WOW-33978patch9.0.1_Beta + { 0xAA3EB38B572073F9ULL, { 0xE5, 0xBC, 0x7A, 0x03, 0x54, 0xB6, 0x45, 0x39, 0xCA, 0x59, 0xB6, 0x78, 0x70, 0x3C, 0xE4, 0x72 } }, // WOW-33978patch9.0.1_Beta + { 0xAA7119519C968451ULL, { 0x57, 0x84, 0xAC, 0xD6, 0x7A, 0xAD, 0xFF, 0xA5, 0xA3, 0x50, 0x84, 0xC8, 0xB7, 0x97, 0x4B, 0x7E } }, // WOW-33978patch9.0.1_Beta + { 0xAAAD5C17B34A935FULL, { 0xB0, 0x95, 0x4F, 0x6A, 0x29, 0x14, 0x19, 0x10, 0x81, 0x00, 0x93, 0x49, 0xAF, 0x44, 0x43, 0xC3 } }, // WOW-33978patch9.0.1_Beta + { 0xABA6C1AFDB427F54ULL, { 0x29, 0x75, 0xC6, 0x9D, 0xA6, 0x14, 0xC3, 0xFF, 0x32, 0xEE, 0xC3, 0xFE, 0xD8, 0x47, 0x29, 0xDE } }, // WOW-33978patch9.0.1_Beta + { 0xADC58189215E1C48ULL, { 0x1F, 0xFB, 0xD3, 0xB8, 0xE6, 0x2A, 0x10, 0x24, 0x92, 0xDC, 0x30, 0x73, 0x21, 0x16, 0xF1, 0x62 } }, // WOW-33978patch9.0.1_Beta + { 0xAFEE51897035872EULL, { 0xF0, 0x85, 0xEA, 0xBC, 0x11, 0xE2, 0x92, 0xD2, 0x0C, 0x77, 0x8B, 0x6D, 0x89, 0x2A, 0xBD, 0x1E } }, // WOW-33978patch9.0.1_Beta + { 0xAFFFA5791F73520AULL, { 0xA9, 0x67, 0xF2, 0xF4, 0x7E, 0x7C, 0xC0, 0x05, 0xCB, 0x8D, 0x7E, 0x92, 0x84, 0x78, 0x15, 0x8E } }, // WOW-33978patch9.0.1_Beta + { 0xB032F43502EDFA5AULL, { 0x4B, 0x0E, 0xF7, 0x9E, 0x47, 0x2D, 0x00, 0x2F, 0x8E, 0x71, 0x7E, 0xED, 0x75, 0xB0, 0x3E, 0x69 } }, // WOW-33978patch9.0.1_Beta + { 0xB23472311441BF43ULL, { 0x3E, 0xE4, 0x12, 0x48, 0xB9, 0x9B, 0xF6, 0xA1, 0x7E, 0xF9, 0x63, 0xC2, 0xD6, 0x88, 0x7B, 0xF5 } }, // WOW-33978patch9.0.1_Beta + { 0xB4582D7E642035F5ULL, { 0xCA, 0x5B, 0x90, 0xA2, 0x8C, 0x7D, 0xAE, 0xF5, 0xAC, 0x8B, 0xA2, 0x6A, 0x3B, 0x7E, 0xB2, 0x6F } }, // WOW-33978patch9.0.1_Beta + { 0xB46B23A8B047E71AULL, { 0x5F, 0xD3, 0xB3, 0xE6, 0xFF, 0x1B, 0xEB, 0x79, 0x6B, 0x13, 0xA0, 0x44, 0x7C, 0x8C, 0x9E, 0xCE } }, // WOW-33978patch9.0.1_Beta + { 0xB62985BE1B0E820CULL, { 0x7B, 0xCB, 0x7A, 0x3A, 0x7A, 0x7F, 0xE6, 0x72, 0xD7, 0xBB, 0x8D, 0xAB, 0x4C, 0x32, 0x66, 0xCA } }, // WOW-33978patch9.0.1_Beta + { 0xB76D3CD9FA80EF23ULL, { 0x43, 0x2F, 0xDE, 0xF3, 0x70, 0xE6, 0x84, 0x73, 0xCE, 0xB7, 0x5B, 0xE4, 0x80, 0x28, 0x71, 0x49 } }, // WOW-33978patch9.0.1_Beta + { 0xB881ACD9C433C39BULL, { 0x41, 0x5B, 0xEC, 0x80, 0x13, 0x4B, 0x91, 0xEB, 0xA7, 0xA8, 0x94, 0xE8, 0x11, 0x1F, 0x16, 0xED } }, // WOW-33978patch9.0.1_Beta + { 0xB8F711CD1BCCCB5AULL, { 0x06, 0x8D, 0xA8, 0x49, 0x5F, 0x4F, 0x87, 0x05, 0x08, 0xDF, 0xAF, 0xCE, 0xFA, 0xB3, 0x4F, 0x6C } }, // WOW-33978patch9.0.1_Beta + { 0xBA2586D5321809C9ULL, { 0x37, 0x08, 0xFF, 0xBC, 0xD5, 0xDE, 0x8B, 0xA1, 0x1E, 0x7A, 0xE2, 0xF2, 0x10, 0x88, 0xF5, 0xE0 } }, // WOW-33978patch9.0.1_Beta + { 0xBB56A0BAE42B0A58ULL, { 0x36, 0xF6, 0x57, 0xC6, 0x27, 0x16, 0xEA, 0x72, 0xEB, 0x46, 0x44, 0x6C, 0xD3, 0x6E, 0xF0, 0x81 } }, // WOW-33978patch9.0.1_Beta + { 0xBBC9FAFBFB8A476EULL, { 0xDF, 0x8F, 0x45, 0x6C, 0xE6, 0xF4, 0x2B, 0x83, 0x29, 0xD6, 0xAB, 0x75, 0x44, 0x5E, 0x93, 0x47 } }, // WOW-33978patch9.0.1_Beta + { 0xBDE676123BBB010AULL, { 0x9A, 0x68, 0x26, 0xB6, 0x35, 0x2B, 0xF4, 0x47, 0xC5, 0x52, 0x6F, 0x3D, 0x80, 0xB2, 0xA4, 0x2A } }, // WOW-33978patch9.0.1_Beta + { 0xBE78B15D2D2FFC28ULL, { 0x18, 0x63, 0x5E, 0xA1, 0xEA, 0x0D, 0x52, 0xA8, 0x04, 0x34, 0x5D, 0x74, 0x2E, 0x47, 0xE7, 0xFF } }, // WOW-33978patch9.0.1_Beta + { 0xBF0DA6AAE66E25A0ULL, { 0xFB, 0x2D, 0xEA, 0x41, 0xD6, 0x00, 0xF3, 0x95, 0xB4, 0x1F, 0x1D, 0x21, 0x9C, 0x2F, 0xDE, 0x4D } }, // WOW-33978patch9.0.1_Beta + { 0xBF26C727BFC92EAFULL, { 0x5E, 0xD5, 0x02, 0xEE, 0xFB, 0x92, 0x1A, 0x27, 0xC1, 0x83, 0x6A, 0x8E, 0x5E, 0x4A, 0x15, 0x92 } }, // WOW-33978patch9.0.1_Beta + { 0xBF874CF500A50632ULL, { 0x87, 0xB9, 0x5B, 0xE0, 0x9C, 0xEE, 0x36, 0xDC, 0x91, 0x43, 0x04, 0x70, 0x95, 0x2E, 0xF3, 0x26 } }, // WOW-33978patch9.0.1_Beta + { 0xBF87DE9EFBA3E7E7ULL, { 0x2A, 0x2C, 0x1E, 0x9A, 0xCA, 0x4F, 0xCD, 0x01, 0xF8, 0xF6, 0x40, 0x66, 0x76, 0x70, 0x63, 0x79 } }, // WOW-33978patch9.0.1_Beta + { 0xC132034A5F2F7E10ULL, { 0x27, 0x3B, 0xA2, 0x00, 0x5D, 0x7C, 0xDE, 0xDD, 0xB1, 0x67, 0x5C, 0x8C, 0x0F, 0x74, 0x1B, 0x7A } }, // WOW-33978patch9.0.1_Beta + { 0xC16F60A6BAD360C0ULL, { 0xBB, 0x8E, 0xF0, 0x39, 0x32, 0xAC, 0x38, 0xC6, 0xCE, 0x11, 0xFE, 0x67, 0x96, 0xEB, 0xBD, 0xEC } }, // WOW-33978patch9.0.1_Beta + { 0xC2BCD68E7A2AE4AFULL, { 0x89, 0x48, 0x11, 0x50, 0x8B, 0x28, 0xE9, 0x0B, 0xFA, 0xB0, 0x28, 0x4D, 0xA2, 0x3E, 0xE5, 0x06 } }, // WOW-33978patch9.0.1_Beta + { 0xC312DAF915B31117ULL, { 0xDA, 0xB0, 0x06, 0x6B, 0x4F, 0x8C, 0xD0, 0x79, 0x54, 0x8C, 0xE7, 0x52, 0x88, 0x4E, 0x19, 0x49 } }, // WOW-33978patch9.0.1_Beta + { 0xC63B911BD06869D3ULL, { 0xCB, 0x82, 0xD1, 0x56, 0x11, 0xA0, 0x96, 0xAA, 0xD6, 0xB2, 0xD9, 0x48, 0x8A, 0x87, 0x93, 0x9A } }, // WOW-33978patch9.0.1_Beta + { 0xC65443D5AB354639ULL, { 0xA9, 0x85, 0x72, 0x55, 0xBB, 0x6E, 0x5A, 0x75, 0xFA, 0x9A, 0xFE, 0xC8, 0xDA, 0xC2, 0xB0, 0x7A } }, // WOW-33978patch9.0.1_Beta + { 0xC8167C2D20426AD8ULL, { 0xF4, 0xF7, 0x7B, 0x2C, 0xA8, 0x36, 0xA4, 0xF9, 0xBE, 0x53, 0x61, 0x6E, 0xC6, 0x2D, 0x61, 0x84 } }, // WOW-33978patch9.0.1_Beta + { 0xC88BB3653C3C964FULL, { 0x7B, 0x61, 0xCA, 0x6E, 0x9C, 0x98, 0x29, 0xF2, 0xF4, 0x52, 0xD2, 0x17, 0x37, 0xD9, 0xD7, 0x23 } }, // WOW-33978patch9.0.1_Beta + { 0xC926C2CBE0DFF9BEULL, { 0x9D, 0x29, 0x47, 0x37, 0xAB, 0x13, 0xC3, 0x6B, 0x02, 0xEC, 0x0E, 0x0B, 0x77, 0x65, 0x7B, 0x13 } }, // WOW-33978patch9.0.1_Beta + { 0xC9A159E7B047AE82ULL, { 0xE4, 0x3C, 0x35, 0x49, 0xE6, 0x0E, 0xB1, 0x2C, 0x49, 0xF9, 0xE9, 0x57, 0x38, 0x61, 0xA5, 0xE0 } }, // WOW-33978patch9.0.1_Beta + { 0xC9F63551DC0A7DD3ULL, { 0xAA, 0xD6, 0xE9, 0xB5, 0x71, 0x97, 0x1E, 0x0A, 0xE9, 0x21, 0x22, 0xE9, 0x77, 0x28, 0x96, 0xDC } }, // WOW-33978patch9.0.1_Beta + { 0xC9FDAB91F9DABA18ULL, { 0x02, 0x5D, 0xF3, 0x9D, 0x8B, 0xF6, 0x32, 0xE6, 0x8B, 0x0A, 0x4E, 0x74, 0xC1, 0x44, 0x2A, 0x24 } }, // WOW-33978patch9.0.1_Beta + { 0xCA9C5B912FFBCAC7ULL, { 0xAF, 0xEE, 0xA5, 0xF1, 0x64, 0xC4, 0x0C, 0xF3, 0x84, 0x98, 0xD8, 0xBC, 0x5A, 0x0C, 0x6B, 0x8F } }, // WOW-33978patch9.0.1_Beta + { 0xCB4D2A3F81E1794EULL, { 0x12, 0x0C, 0x6B, 0x4A, 0x25, 0x41, 0xB5, 0xA9, 0x79, 0x81, 0x0C, 0x35, 0x38, 0x8C, 0x56, 0xF1 } }, // WOW-33978patch9.0.1_Beta + { 0xCBBACF102B89411FULL, { 0xE0, 0x4C, 0x71, 0x77, 0x15, 0xB0, 0x06, 0x11, 0xAC, 0x7E, 0xA9, 0x7D, 0x0B, 0x45, 0xAA, 0x0C } }, // WOW-33978patch9.0.1_Beta + { 0xD0C5486A7AD05CF9ULL, { 0x54, 0x84, 0xBE, 0x9C, 0xB3, 0x7D, 0xE9, 0x51, 0x12, 0xA1, 0x8B, 0x60, 0x52, 0xC5, 0xA7, 0xE5 } }, // WOW-33978patch9.0.1_Beta + { 0xD362C01C25B71B50ULL, { 0x08, 0xFB, 0x22, 0xF6, 0xA9, 0x52, 0x2A, 0x48, 0xCA, 0x24, 0x79, 0xCD, 0xED, 0x66, 0xA1, 0x75 } }, // WOW-33978patch9.0.1_Beta + { 0xD3CD986A5533AE96ULL, { 0x56, 0x70, 0x8F, 0x30, 0x77, 0xB7, 0x24, 0x88, 0x10, 0xC7, 0xB8, 0x7E, 0xDA, 0xCF, 0x25, 0xC2 } }, // WOW-33978patch9.0.1_Beta + { 0xD628DFD6FD4C4629ULL, { 0x30, 0x0F, 0x61, 0x98, 0xF8, 0xD3, 0x4F, 0x71, 0x81, 0x11, 0x61, 0x52, 0x13, 0x31, 0x4E, 0x07 } }, // WOW-33978patch9.0.1_Beta + { 0xD843A7FFCE96C7AEULL, { 0x08, 0xF1, 0xDE, 0x2D, 0x96, 0xEB, 0x99, 0x9C, 0x89, 0xA1, 0xD4, 0xE3, 0xBD, 0x22, 0x34, 0x3D } }, // WOW-33978patch9.0.1_Beta + { 0xD8EDA6A4C2799AFCULL, { 0x82, 0xD9, 0x7B, 0x8F, 0x98, 0x6A, 0xF1, 0x57, 0x66, 0xC8, 0x9F, 0x61, 0x1C, 0x14, 0x68, 0x88 } }, // WOW-33978patch9.0.1_Beta + { 0xDB37969AE172E0A2ULL, { 0xE0, 0x71, 0xBF, 0xF3, 0x31, 0x7D, 0x6F, 0xCC, 0x61, 0x12, 0xE8, 0xCB, 0xF0, 0x4B, 0x9E, 0x84 } }, // WOW-33978patch9.0.1_Beta + { 0xDBD4F370AE374627ULL, { 0x0D, 0x78, 0x08, 0xF6, 0x29, 0xBE, 0x2E, 0x0B, 0xE2, 0x80, 0x73, 0x1F, 0x9C, 0xCD, 0x51, 0xAE } }, // WOW-33978patch9.0.1_Beta + { 0xDC692CF534CF6094ULL, { 0xA6, 0x41, 0xD3, 0x32, 0xCE, 0x02, 0xCF, 0x14, 0x71, 0x42, 0x9F, 0xA3, 0x5B, 0x9C, 0xC2, 0x2A } }, // WOW-33978patch9.0.1_Beta + { 0xDE7D8C810DEBCCBBULL, { 0x39, 0xBD, 0x23, 0xF7, 0xBA, 0x29, 0x73, 0xCF, 0x57, 0x36, 0xE8, 0xA4, 0xD1, 0x37, 0xA2, 0x59 } }, // WOW-33978patch9.0.1_Beta + { 0xDFDBE74EFD0C1D9AULL, { 0x80, 0xA6, 0x40, 0x5D, 0xCA, 0x4A, 0xDB, 0x58, 0x04, 0xDF, 0xF3, 0x9E, 0x25, 0xAA, 0x6A, 0xF0 } }, // WOW-33978patch9.0.1_Beta + { 0xE186FB75B0C94A7CULL, { 0x9F, 0x7B, 0x27, 0xC6, 0xD8, 0x4C, 0x80, 0x59, 0xEF, 0xD8, 0x81, 0x56, 0x0C, 0x84, 0xFB, 0xF2 } }, // WOW-33978patch9.0.1_Beta + { 0xE26933D3B03457B8ULL, { 0xE4, 0xE9, 0x79, 0x3A, 0x4B, 0x0F, 0xFA, 0x09, 0xC6, 0x9A, 0x2F, 0xB3, 0xC4, 0x86, 0xE4, 0x5C } }, // WOW-33978patch9.0.1_Beta + { 0xE2D4CD545D19C5B3ULL, { 0x5F, 0x4D, 0xC6, 0x65, 0x17, 0xB5, 0x26, 0xCF, 0x48, 0x18, 0xDD, 0xDA, 0x50, 0xAE, 0xD6, 0x2A } }, // WOW-33978patch9.0.1_Beta + { 0xE321D1E0F5FD72D1ULL, { 0x39, 0x7A, 0xB9, 0x76, 0xC9, 0xFF, 0x03, 0x78, 0x37, 0xF9, 0x26, 0x00, 0xBE, 0x75, 0x4C, 0x63 } }, // WOW-33978patch9.0.1_Beta + { 0xE50F70F06A579FCCULL, { 0xE2, 0xB1, 0x53, 0x8D, 0x2C, 0x14, 0xAD, 0x00, 0xC9, 0xF2, 0xB1, 0xFE, 0x56, 0xC1, 0xF0, 0xD2 } }, // WOW-33978patch9.0.1_Beta + { 0xE6DE529515D5322EULL, { 0x1D, 0x58, 0x84, 0x6A, 0x1C, 0x87, 0x1B, 0xA0, 0x8C, 0x2E, 0xCD, 0x7B, 0x32, 0xFA, 0xCA, 0x41 } }, // WOW-33978patch9.0.1_Beta + { 0xE6F58B08B45D7A12ULL, { 0x18, 0xF3, 0x4D, 0xA5, 0xA6, 0x91, 0xF6, 0xAA, 0xF1, 0xF9, 0xA7, 0x05, 0xB6, 0x56, 0xE0, 0x1F } }, // WOW-33978patch9.0.1_Beta + { 0xE7357F7B88B8338DULL, { 0x9B, 0xAC, 0x5D, 0x21, 0x9C, 0xE7, 0x19, 0x84, 0xCB, 0xD6, 0xBE, 0x98, 0xE7, 0x2A, 0xB8, 0x3C } }, // WOW-33978patch9.0.1_Beta + { 0xE8F494F7E371D157ULL, { 0x4E, 0x2C, 0xDA, 0xA4, 0x18, 0x44, 0x03, 0x48, 0xE4, 0x39, 0x99, 0x5D, 0x64, 0x28, 0x4B, 0x73 } }, // WOW-33978patch9.0.1_Beta + { 0xE995E22AF7111D57ULL, { 0x33, 0xE8, 0xD6, 0x3D, 0xF4, 0xA8, 0xCE, 0x36, 0xD1, 0x88, 0xEC, 0x07, 0x22, 0x09, 0xD1, 0x84 } }, // WOW-33978patch9.0.1_Beta + { 0xEA9589F00A338035ULL, { 0xEC, 0xCB, 0x9C, 0xA5, 0x7C, 0xA0, 0x30, 0x33, 0x9B, 0x2D, 0xBA, 0x74, 0x5B, 0x5C, 0x14, 0x9B } }, // WOW-33978patch9.0.1_Beta + { 0xEAC344DACB040496ULL, { 0x51, 0x22, 0xD6, 0x18, 0x1F, 0x79, 0x71, 0x9A, 0x81, 0x7B, 0xBF, 0x84, 0xA2, 0xB5, 0x7B, 0xA1 } }, // WOW-33978patch9.0.1_Beta + { 0xEB5B9AA992D0582BULL, { 0x3A, 0xC4, 0xA8, 0x0F, 0x38, 0x66, 0x3F, 0xB3, 0xAD, 0xEB, 0x1C, 0xE5, 0x5E, 0xD3, 0xC1, 0x4D } }, // WOW-33978patch9.0.1_Beta + { 0xEB824892D843D365ULL, { 0x39, 0x4F, 0xCE, 0x26, 0x76, 0x68, 0x05, 0xA7, 0x68, 0x14, 0xB2, 0x5B, 0x4B, 0x72, 0xB4, 0xD8 } }, // WOW-33978patch9.0.1_Beta + { 0xEC434CD731FF1D6EULL, { 0x84, 0xC4, 0x3B, 0x20, 0xA6, 0x33, 0x66, 0x82, 0xB5, 0xAA, 0x1D, 0x7C, 0xFA, 0x00, 0xDA, 0xE3 } }, // WOW-33978patch9.0.1_Beta + { 0xED4548400C6CD9B3ULL, { 0xDD, 0xAE, 0x53, 0x8A, 0x39, 0x59, 0x16, 0x11, 0xBF, 0x1D, 0x2E, 0xEE, 0x97, 0x34, 0xF8, 0xDD } }, // WOW-33978patch9.0.1_Beta + { 0xED85FA32ABE4D31AULL, { 0xC9, 0x35, 0xBB, 0xCB, 0x24, 0x70, 0xF2, 0x97, 0xEA, 0x61, 0xF8, 0x66, 0x9D, 0xE7, 0x38, 0x10 } }, // WOW-33978patch9.0.1_Beta + { 0xEDB14BC9682C3EC7ULL, { 0x07, 0x63, 0x2A, 0xA3, 0x73, 0xD5, 0x08, 0xD9, 0x94, 0x81, 0x64, 0x6E, 0xF5, 0x2C, 0x6F, 0x21 } }, // WOW-33978patch9.0.1_Beta + { 0xEFD8CF7039C9E3ABULL, { 0x6B, 0xA7, 0x1A, 0xEC, 0x7C, 0xF7, 0xED, 0x83, 0xE7, 0xD4, 0x7A, 0x47, 0xE1, 0xAA, 0x97, 0x58 } }, // WOW-33978patch9.0.1_Beta + { 0xEFF36C5D384458ADULL, { 0x9F, 0x0B, 0x12, 0x0C, 0x9D, 0x86, 0xB5, 0x9B, 0x2C, 0x8B, 0x5E, 0xB0, 0x6C, 0xE0, 0x33, 0xC2 } }, // WOW-33978patch9.0.1_Beta + { 0xF04AF4C9E8BD1063ULL, { 0x62, 0xDB, 0x73, 0x69, 0x77, 0x96, 0x60, 0xE4, 0xAC, 0x83, 0xB1, 0xAF, 0x77, 0xCD, 0x86, 0x0A } }, // WOW-33978patch9.0.1_Beta + { 0xF0C135866D740895ULL, { 0x44, 0xAD, 0xC9, 0xAC, 0xBE, 0xD5, 0x0F, 0x49, 0x0A, 0xD8, 0xD5, 0xEE, 0xA8, 0x13, 0xDB, 0x69 } }, // WOW-33978patch9.0.1_Beta + { 0xF399E2091BB4EB3DULL, { 0xC3, 0x8C, 0x68, 0x01, 0x59, 0xE6, 0x3F, 0x03, 0x65, 0xFF, 0x10, 0xC6, 0xB4, 0x8C, 0xF6, 0xBC } }, // WOW-33978patch9.0.1_Beta + { 0xF4941ADAEFD62B50ULL, { 0x4E, 0x37, 0xCC, 0x48, 0xF5, 0x1E, 0x3B, 0x5F, 0x73, 0xCC, 0xD7, 0x41, 0x90, 0x91, 0xE3, 0xB6 } }, // WOW-33978patch9.0.1_Beta + { 0xF4A0D7C6BE16E9E6ULL, { 0xB9, 0x6B, 0x07, 0x4E, 0x60, 0xBB, 0x6B, 0x0C, 0x3F, 0xFD, 0x1F, 0xBC, 0x87, 0x77, 0x36, 0x7C } }, // WOW-33978patch9.0.1_Beta + { 0xF5BC79A1093D4297ULL, { 0xE1, 0x18, 0x0A, 0x55, 0xA6, 0x7B, 0x29, 0xAC, 0xDA, 0x9B, 0x6A, 0x3A, 0x70, 0x4C, 0x90, 0x27 } }, // WOW-33978patch9.0.1_Beta + { 0xF88CD79C16ED40C1ULL, { 0xED, 0x5B, 0xC5, 0xBF, 0x5D, 0x1E, 0xD1, 0x69, 0x51, 0x9F, 0x85, 0x9F, 0x4C, 0xEB, 0xAB, 0xA9 } }, // WOW-33978patch9.0.1_Beta + { 0xF9B971BF3BAE0F5FULL, { 0x41, 0x6A, 0x38, 0x03, 0x5B, 0xAD, 0xD4, 0xC2, 0x7A, 0x14, 0xF1, 0xE8, 0x74, 0xB1, 0x0F, 0xFC } }, // WOW-33978patch9.0.1_Beta + { 0xFA6C85CFB99D0738ULL, { 0x41, 0xFA, 0x48, 0x6B, 0x2F, 0xEB, 0x68, 0xFB, 0x96, 0x64, 0xD4, 0x22, 0xAA, 0xF1, 0x71, 0x38 } }, // WOW-33978patch9.0.1_Beta + { 0xFB90D71D100E9595ULL, { 0xB7, 0xA7, 0x6E, 0x35, 0x33, 0x75, 0x11, 0xB4, 0xA2, 0x6E, 0xE9, 0xBE, 0x0E, 0xCA, 0xD3, 0xD0 } }, // WOW-33978patch9.0.1_Beta + { 0xFD06442092131C5EULL, { 0x3E, 0x55, 0xE1, 0x47, 0xB6, 0x53, 0xB5, 0xF9, 0xE6, 0x8E, 0xAB, 0x44, 0x90, 0x8F, 0xBD, 0xC1 } }, // WOW-33978patch9.0.1_Beta + { 0xFD0BA919048A69AAULL, { 0x66, 0xE4, 0x75, 0xF4, 0x60, 0x26, 0xB0, 0x91, 0xAD, 0xD4, 0xA3, 0xE1, 0xBC, 0x61, 0x96, 0x91 } }, // WOW-33978patch9.0.1_Beta + { 0xFF08D3B90FB93B8CULL, { 0xD4, 0x27, 0x97, 0x22, 0xFB, 0x8B, 0xDD, 0x2A, 0xA8, 0xB3, 0xA4, 0xC7, 0x4E, 0xFD, 0x44, 0xCA } }, // WOW-33978patch9.0.1_Beta + { 0xFF7C9A1B789D0D42ULL, { 0xA9, 0xEC, 0x27, 0x53, 0x3B, 0x7D, 0x9D, 0xB1, 0xE2, 0x39, 0xEC, 0x68, 0x8B, 0xA6, 0x53, 0xF4 } }, // WOW-33978patch9.0.1_Beta }; //----------------------------------------------------------------------------- // Local functions -static DWORD Rol32(DWORD dwValue, DWORD dwRolCount) -{ - return (dwValue << dwRolCount) | (dwValue >> (32 - dwRolCount)); -} - static void Initialize(PCASC_SALSA20 pState, LPBYTE pbKey, DWORD cbKeyLength, LPBYTE pbVector) { const char * szConstants = (cbKeyLength == 32) ? szKeyConstant32 : szKeyConstant16; diff --git a/dep/CascLib/src/CascDumpData.cpp b/dep/CascLib/src/CascDumpData.cpp index 40e791f7a15..e29ad66bf63 100644 --- a/dep/CascLib/src/CascDumpData.cpp +++ b/dep/CascLib/src/CascDumpData.cpp @@ -25,7 +25,7 @@ int CaptureDownloadTag(CASC_DOWNLOAD_HEADER & DlHeader, CASC_TAG_ENTRY1 & DlTag, //----------------------------------------------------------------------------- // Local functions -static char * StringFromLPTSTR(const TCHAR * szString, char * szBuffer, size_t cchBuffer) +static char * StringFromLPTSTR(LPCTSTR szString, char * szBuffer, size_t cchBuffer) { char * szSaveBuffer = szBuffer; char * szBufferEnd = szBuffer + cchBuffer - 1; diff --git a/dep/CascLib/src/CascFiles.cpp b/dep/CascLib/src/CascFiles.cpp index f47b8316693..c1a9e648c72 100644 --- a/dep/CascLib/src/CascFiles.cpp +++ b/dep/CascLib/src/CascFiles.cpp @@ -27,7 +27,7 @@ typedef DWORD (*PARSE_VARIABLE)(TCascStorage * hs, const char * szVariableName, struct TBuildFileInfo { - const TCHAR * szFileName; + LPCTSTR szFileName; CBLD_TYPE BuildFileType; }; @@ -45,7 +45,7 @@ static const TBuildFileInfo BuildTypes[] = {NULL, CascBuildNone} }; -static const TCHAR * DataDirs[] = +static LPCTSTR DataDirs[] = { _T("data") _T(PATH_SEP_STRING) _T("casc"), // Overwatch _T("data"), // TACT casc (for Linux systems) @@ -494,23 +494,17 @@ static int LoadQueryKey(const CASC_CSV_COLUMN & Column, QUERY_KEY & Key) static void SetProductCodeName(TCascStorage * hs, LPCSTR szCodeName) { - TCHAR szCodeNameT[0x40]; - if(hs->szCodeName == NULL && szCodeName != NULL) { - CascStrCopy(szCodeNameT, _countof(szCodeNameT), szCodeName); - hs->szCodeName = CascNewStr(szCodeNameT); + hs->szCodeName = CascNewStrA2T(szCodeName); } } static DWORD GetDefaultCdnPath(TCascStorage * hs, const CASC_CSV_COLUMN & Column) { - TCHAR szCdnPath[MAX_PATH]; - if(hs->szCdnPath == NULL && Column.nLength != 0) { - CascStrCopy(szCdnPath, _countof(szCdnPath), Column.szValue); - hs->szCdnPath = CascNewStr(szCdnPath); + hs->szCdnPath = CascNewStrA2T(Column.szValue); } return ERROR_SUCCESS; @@ -544,8 +538,6 @@ static DWORD GetDefaultLocaleMask(TCascStorage * hs, const CASC_CSV_COLUMN & Col static DWORD ParseFile_CDNS(TCascStorage * hs, CASC_CSV & Csv) { const char * szWantedRegion = hs->szRegion; - TCHAR szCdnServers[MAX_PATH]; - TCHAR szCdnPath[MAX_PATH]; size_t nLineCount; // Fix the region @@ -562,12 +554,10 @@ static DWORD ParseFile_CDNS(TCascStorage * hs, CASC_CSV & Csv) if(!strcmp(Csv[i]["Name!STRING:0"].szValue, szWantedRegion)) { // Save the list of CDN servers - CascStrCopy(szCdnServers, _countof(szCdnServers), Csv[i]["Hosts!STRING:0"].szValue); - hs->szCdnServers = CascNewStr(szCdnServers); + hs->szCdnServers = CascNewStrA2T(Csv[i]["Hosts!STRING:0"].szValue); // Save the CDN subpath - CascStrCopy(szCdnPath, _countof(szCdnPath), Csv[i]["Path!STRING:0"].szValue); - hs->szCdnPath = CascNewStr(szCdnPath); + hs->szCdnPath = CascNewStrA2T(Csv[i]["Path!STRING:0"].szValue); // Check and return result return (hs->szCdnServers && hs->szCdnPath) ? ERROR_SUCCESS : ERROR_BAD_FORMAT; @@ -698,7 +688,7 @@ static DWORD ParseFile_BuildInfo(TCascStorage * hs, CASC_CSV & Csv) static DWORD ParseFile_VersionsDb(TCascStorage * hs, CASC_CSV & Csv) { size_t nLineCount = Csv.GetLineCount(); - DWORD dwErrCode; + DWORD dwErrCode = ERROR_SUCCESS; // Find the active config for (size_t i = 0; i < nLineCount; i++) @@ -723,7 +713,15 @@ static DWORD ParseFile_VersionsDb(TCascStorage * hs, CASC_CSV & Csv) } // Verify all variables - return (hs->CdnBuildKey.pbData != NULL && hs->CdnConfigKey.pbData != NULL) ? ERROR_SUCCESS : ERROR_BAD_FORMAT; + if(hs->CdnBuildKey.pbData != NULL && hs->CdnConfigKey.pbData != NULL) + { + // If we have manually given build key, override the value + if(hs->szBuildKey != NULL) + dwErrCode = ConvertStringToBinary(hs->szBuildKey, MD5_STRING_SIZE, hs->CdnBuildKey.pbData); + return dwErrCode; + } + + return ERROR_BAD_FORMAT; } } @@ -860,9 +858,9 @@ static DWORD ParseFile_CdnBuild(TCascStorage * hs, void * pvListFile) return dwErrCode; } -static DWORD CheckDataDirectory(TCascStorage * hs, TCHAR * szDirectory) +static DWORD CheckDataDirectory(TCascStorage * hs, LPTSTR szDirectory) { - TCHAR * szDataPath; + LPTSTR szDataPath; DWORD dwErrCode = ERROR_FILE_NOT_FOUND; // Try all known subdirectories @@ -888,7 +886,7 @@ static DWORD CheckDataDirectory(TCascStorage * hs, TCHAR * szDirectory) return dwErrCode; } -static DWORD LoadCsvFile(TCascStorage * hs, const TCHAR * szFileName, PARSECSVFILE PfnParseProc, bool bHasHeader) +static DWORD LoadCsvFile(TCascStorage * hs, LPCTSTR szFileName, PARSECSVFILE PfnParseProc, bool bHasHeader) { CASC_CSV Csv(0x40, bHasHeader); DWORD dwErrCode; @@ -899,9 +897,9 @@ static DWORD LoadCsvFile(TCascStorage * hs, const TCHAR * szFileName, PARSECSVFI return dwErrCode; } -static const TCHAR * ExtractCdnServerName(TCHAR * szServerName, size_t cchServerName, const TCHAR * szCdnServers) +static LPCTSTR ExtractCdnServerName(LPTSTR szServerName, size_t cchServerName, LPCTSTR szCdnServers) { - const TCHAR * szSeparator; + LPCTSTR szSeparator; if(szCdnServers[0] != 0) { @@ -982,9 +980,9 @@ static void CreateRemoteAndLocalPath(TCascStorage * hs, CASC_CDN_DOWNLOAD & Cdns LocalPath.AppendString(CdnsInfo.szExtension, false); } -static DWORD ForcePathExist(const TCHAR * szFileName, bool bIsFileName) +static DWORD ForcePathExist(LPCTSTR szFileName, bool bIsFileName) { - TCHAR * szLocalPath; + LPTSTR szLocalPath; size_t nIndex; bool bFirstSeparator = false; DWORD dwErrCode = ERROR_NOT_ENOUGH_MEMORY; @@ -1046,6 +1044,21 @@ static DWORD ForcePathExist(const TCHAR * szFileName, bool bIsFileName) return dwErrCode; } +static bool FileAlreadyExists(LPCTSTR szFileName) +{ + TFileStream * pStream; + ULONGLONG FileSize = 0; + + // The file open must succeed and also must be of non-zero size + if((pStream = FileStream_OpenFile(szFileName, 0)) != NULL) + { + FileStream_GetSize(pStream, &FileSize); + FileStream_Close(pStream); + } + + return (FileSize != 0); +} + static DWORD DownloadFile( LPCTSTR szRemoteName, LPCTSTR szLocalName, @@ -1118,7 +1131,7 @@ static DWORD DownloadFileFromCDN2(TCascStorage * hs, CASC_CDN_DOWNLOAD & CdnsInf CreateRemoteAndLocalPath(hs, CdnsInfo, RemotePath, LocalPath); // Check whether the local file exists - if((CdnsInfo.Flags & CASC_CDN_FORCE_DOWNLOAD) || (_taccess(LocalPath, 0) == -1)) + if((CdnsInfo.Flags & CASC_CDN_FORCE_DOWNLOAD) || !FileAlreadyExists(LocalPath)) { // Make sure that the path exists dwErrCode = ForcePathExist(LocalPath, true); @@ -1267,10 +1280,10 @@ DWORD GetFileSpanInfo(PCASC_CKEY_ENTRY pCKeyEntry, PULONGLONG PtrContentSize, PU // Checks whether there is a ".build.info" or ".build.db". // If yes, the function sets "szDataPath" and "szIndexPath" // in the storage structure and returns ERROR_SUCCESS -DWORD CheckGameDirectory(TCascStorage * hs, TCHAR * szDirectory) +DWORD CheckGameDirectory(TCascStorage * hs, LPTSTR szDirectory) { TFileStream * pStream; - TCHAR * szBuildFile; + LPTSTR szBuildFile; DWORD dwErrCode = ERROR_FILE_NOT_FOUND; // Try to find any of the root files used in the history @@ -1504,8 +1517,7 @@ LPBYTE LoadFileToMemory(LPCTSTR szFileName, DWORD * pcbFileData) DWORD cbFileData = 0; // Open the stream for read-only access and read the file - // Note that this fails when the game is running (sharing violation). - pStream = FileStream_OpenFile(szFileName, STREAM_FLAG_READ_ONLY | STREAM_PROVIDER_FLAT | BASE_PROVIDER_FILE); + pStream = FileStream_OpenFile(szFileName, STREAM_FLAG_READ_ONLY | STREAM_FLAG_WRITE_SHARE | STREAM_PROVIDER_FLAT | BASE_PROVIDER_FILE); if(pStream != NULL) { // Retrieve the file size diff --git a/dep/CascLib/src/CascFindFile.cpp b/dep/CascLib/src/CascFindFile.cpp index f33541f07d0..9694ae5e878 100644 --- a/dep/CascLib/src/CascFindFile.cpp +++ b/dep/CascLib/src/CascFindFile.cpp @@ -138,7 +138,7 @@ static bool DoStorageSearch_CKey(TCascSearch * pSearch, PCASC_FIND_DATA pFindDat { // Locate the n-th CKey entry. pCKeyEntry = (PCASC_CKEY_ENTRY)hs->CKeyArray.ItemAt(pSearch->nFileIndex++); -// BREAK_ON_XKEY3(pCKeyEntry->CKey, 0x2B, 0xfc, 0xe4); + //BREAK_ON_XKEY3(pCKeyEntry->CKey, 0x2B, 0xfc, 0xe4); // Only report files that are unreferenced by the ROOT handler if(pCKeyEntry->IsFile() && pCKeyEntry->RefCount == 0) diff --git a/dep/CascLib/src/CascIndexFiles.cpp b/dep/CascLib/src/CascIndexFiles.cpp index eddbdb67b0d..bfcee15330b 100644 --- a/dep/CascLib/src/CascIndexFiles.cpp +++ b/dep/CascLib/src/CascIndexFiles.cpp @@ -28,7 +28,7 @@ typedef bool (*EKEY_ENTRY_CALLBACK)(TCascStorage * hs, CASC_INDEX_HEADER & InHea // Local functions // "data.iXY" -static bool IsIndexFileName_V1(const TCHAR * szFileName) +static bool IsIndexFileName_V1(LPCTSTR szFileName) { // Check if the name looks like a valid index file return (_tcslen(szFileName) == 8 && @@ -36,7 +36,7 @@ static bool IsIndexFileName_V1(const TCHAR * szFileName) _tcsspn(szFileName + 6, szAllowedHexChars) == 2); } -static bool IsIndexFileName_V2(const TCHAR * szFileName) +static bool IsIndexFileName_V2(LPCTSTR szFileName) { // Check if the name looks like a valid index file return (_tcslen(szFileName) == 14 && @@ -116,7 +116,7 @@ static bool IndexDirectory_OnFileFound( return true; } -static TCHAR * CreateIndexFileName(TCascStorage * hs, DWORD IndexValue, DWORD IndexVersion) +static LPTSTR CreateIndexFileName(TCascStorage * hs, DWORD IndexValue, DWORD IndexVersion) { TCHAR szPlainName[0x40]; @@ -167,6 +167,7 @@ static LPBYTE CaptureGuardedBlock2(LPBYTE pbFileData, LPBYTE pbFileEnd, size_t E PFILE_INDEX_GUARDED_BLOCK pBlock = (PFILE_INDEX_GUARDED_BLOCK)pbFileData; LPBYTE pbEntryPtr; size_t EntryCount; + unsigned int HashBlizzGet = 0; unsigned int HashHigh = 0; unsigned int HashLow = 0; @@ -177,7 +178,10 @@ static LPBYTE CaptureGuardedBlock2(LPBYTE pbFileData, LPBYTE pbFileEnd, size_t E if (pBlock->BlockSize == 0 || (pbFileData + sizeof(FILE_INDEX_GUARDED_BLOCK) + pBlock->BlockSize) > pbFileEnd) return NULL; - // Compute the hash entry-by-entry + // + // Verify the hash from the Blizzard Downloader + // + pbEntryPtr = pbFileData + sizeof(FILE_INDEX_GUARDED_BLOCK); EntryCount = pBlock->BlockSize / EntryLength; for (size_t i = 0; i < EntryCount; i++) @@ -187,13 +191,39 @@ static LPBYTE CaptureGuardedBlock2(LPBYTE pbFileData, LPBYTE pbFileEnd, size_t E } // Verify hash - if (HashHigh != pBlock->BlockHash) - return NULL; + if (HashHigh == pBlock->BlockHash) + { + // Give the output + if (PtrBlockSize != NULL) + PtrBlockSize[0] = pBlock->BlockSize; + return (LPBYTE)(pBlock + 1); + } - // Give the output - if (PtrBlockSize != NULL) - PtrBlockSize[0] = pBlock->BlockSize; - return (LPBYTE)(pBlock + 1); + // + // Verify the hash from the Blizzget tool, which calculates the hash differently + // https://github.com/d07RiV/blizzget/blob/master/src/ngdp.cpp + // Function void DataStorage::writeIndex() + // + + pbEntryPtr = pbFileData + sizeof(FILE_INDEX_GUARDED_BLOCK); + EntryCount = pBlock->BlockSize / EntryLength; + for (size_t i = 0; i < EntryCount; i++) + { + HashBlizzGet = hashlittle(pbEntryPtr, EntryLength, HashBlizzGet); + pbEntryPtr += EntryLength; + } + + // Verify hash + if (HashBlizzGet == pBlock->BlockHash) + { + // Give the output + if (PtrBlockSize != NULL) + PtrBlockSize[0] = pBlock->BlockSize; + return (LPBYTE)(pBlock + 1); + } + + // Hash mismatch + return NULL; } // Third method of checking a guarded block; There is 32-bit hash, followed by EKey entry @@ -286,8 +316,11 @@ static DWORD LoadIndexItems(TCascStorage * hs, CASC_INDEX_HEADER & InHeader, EKE while((pbEKeyEntry + EntryLength) <= pbEKeyEnd) { - // DOWNLOAD in HOTS - //BREAK_ON_XKEY3(EKeyEntry.EKey, 0x09, 0xF3, 0xCD); + // ENCODING, DOWNLOAD, ROOT in Warcraft III Reforged build 14481 + BREAK_ON_XKEY3(pbEKeyEntry, 0xcd, 0x3b, 0xd8); + BREAK_ON_XKEY3(pbEKeyEntry, 0xdb, 0xfa, 0x35); + BREAK_ON_XKEY3(pbEKeyEntry, 0x5c, 0xe8, 0x48); + if(!PfnEKeyEntry(hs, InHeader, pbEKeyEntry)) return ERROR_INDEX_PARSING_DONE; @@ -487,17 +520,17 @@ static bool InsertEncodingEKeyToMap(TCascStorage * hs, CASC_INDEX_HEADER &, LPBY return true; } -static DWORD ProcessLocalIndexFiles(TCascStorage * hs, EKEY_ENTRY_CALLBACK PfnEKeyEntry) +static DWORD ProcessLocalIndexFiles(TCascStorage * hs, EKEY_ENTRY_CALLBACK PfnEKeyEntry, DWORD dwIndexCount) { DWORD dwErrCode = ERROR_SUCCESS; // Load each index file - for(DWORD i = 0; i < CASC_INDEX_COUNT; i++) + for(DWORD i = 0; i < dwIndexCount; i++) { CASC_INDEX & IndexFile = hs->IndexFiles[i]; // Inform the user about what we are doing - if(InvokeProgressCallback(hs, "Loading index files", NULL, i, CASC_INDEX_COUNT)) + if(InvokeProgressCallback(hs, "Loading index files", NULL, i, dwIndexCount)) { dwErrCode = ERROR_CANCELLED; break; @@ -520,6 +553,7 @@ static DWORD ProcessLocalIndexFiles(TCascStorage * hs, EKEY_ENTRY_CALLBACK PfnEK static DWORD LoadLocalIndexFiles(TCascStorage * hs) { ULONGLONG TotalSize = 0; + DWORD dwIndexCount = 0; DWORD dwErrCode; // Inform the user about what we are doing @@ -529,6 +563,10 @@ static DWORD LoadLocalIndexFiles(TCascStorage * hs) // Perform the directory scan if((dwErrCode = ScanIndexDirectory(hs->szIndexPath, IndexDirectory_OnFileFound, hs)) == ERROR_SUCCESS) { + // If no index file was found, we cannot load anything + if(hs->szIndexFormat == NULL) + return ERROR_FILE_NOT_FOUND; + // Load each index file for(DWORD i = 0; i < CASC_INDEX_COUNT; i++) { @@ -541,16 +579,28 @@ static DWORD LoadLocalIndexFiles(TCascStorage * hs) // WoW6 actually reads THE ENTIRE file to memory. Verified on Mac build (x64). if((IndexFile.pbFileData = LoadFileToMemory(IndexFile.szFileName, &cbFileData)) == NULL) - return ERROR_NOT_ENOUGH_MEMORY; + { + // Storages downloaded by Blizzget tool don't have all index files present + if((dwErrCode = GetLastError()) == ERROR_FILE_NOT_FOUND) + { + dwErrCode = ERROR_SUCCESS; + break; + } + + return dwErrCode; + } + + // Add to the total size of the index files IndexFile.cbFileData = cbFileData; TotalSize += cbFileData; + dwIndexCount++; } // Build the map of EKey -> IndexEKeyEntry dwErrCode = hs->IndexEKeyMap.Create((size_t)(TotalSize / sizeof(FILE_EKEY_ENTRY)), CASC_EKEY_SIZE, 0); if(dwErrCode == ERROR_SUCCESS) { - dwErrCode = ProcessLocalIndexFiles(hs, InsertEncodingEKeyToMap); + dwErrCode = ProcessLocalIndexFiles(hs, InsertEncodingEKeyToMap, dwIndexCount); } } diff --git a/dep/CascLib/src/CascLib.h b/dep/CascLib/src/CascLib.h index 8bf515abca9..b9a3ef7de0d 100644 --- a/dep/CascLib/src/CascLib.h +++ b/dep/CascLib/src/CascLib.h @@ -34,41 +34,43 @@ extern "C" { // // X - D for Debug version, R for Release version // Y - A for ANSI version, U for Unicode version -// Z - S for static-linked CRT library, D for multithreaded DLL CRT library +// Z - S for static-linked CRT library, D for dynamic CRT library (dll) // -#if defined(_MSC_VER) && !defined(__CASCLIB_SELF__) && !defined(CASCLIB_NO_AUTO_LINK_LIBRARY) - #ifdef _DEBUG // DEBUG VERSIONS - #ifndef _UNICODE - #ifdef _DLL - #pragma comment(lib, "CascLibDAD.lib") // Debug Ansi CRT-DLL version - #else - #pragma comment(lib, "CascLibDAS.lib") // Debug Ansi CRT-LIB version - #endif - #else - #ifdef _DLL - #pragma comment(lib, "CascLibDUD.lib") // Debug Unicode CRT-DLL version - #else - #pragma comment(lib, "CascLibDUS.lib") // Debug Unicode CRT-LIB version - #endif - #endif - #else // RELEASE VERSIONS - #ifndef _UNICODE - #ifdef _DLL - #pragma comment(lib, "CascLibRAD.lib") // Release Ansi CRT-DLL version +#if defined(_MSC_VER) && !defined(__CASCLIB_SELF__) && !defined(CASCLIB_NO_AUTO_LINK_LIBRARY) + #ifndef WDK_BUILD + #ifdef _DEBUG // DEBUG VERSIONS + #ifndef _UNICODE + #ifdef _DLL + #pragma comment(lib, "CascLibDAD.lib") // Debug Ansi CRT-DLL version + #else + #pragma comment(lib, "CascLibDAS.lib") // Debug Ansi CRT-LIB version + #endif #else - #pragma comment(lib, "CascLibRAS.lib") // Release Ansi CRT-LIB version + #ifdef _DLL + #pragma comment(lib, "CascLibDUD.lib") // Debug Unicode CRT-DLL version + #else + #pragma comment(lib, "CascLibDUS.lib") // Debug Unicode CRT-LIB version + #endif #endif - #else - #ifdef _DLL - #pragma comment(lib, "CascLibRUD.lib") // Release Unicode CRT-DLL version + #else // RELEASE VERSIONS + #ifndef _UNICODE + #ifdef _DLL + #pragma comment(lib, "CascLibRAD.lib") // Release Ansi CRT-DLL version + #else + #pragma comment(lib, "CascLibRAS.lib") // Release Ansi CRT-LIB version + #endif #else - #pragma comment(lib, "CascLibRUS.lib") // Release Unicode CRT-LIB version + #ifdef _DLL + #pragma comment(lib, "CascLibRUD.lib") // Release Unicode CRT-DLL version + #else + #pragma comment(lib, "CascLibRUS.lib") // Release Unicode CRT-LIB version + #endif #endif #endif #endif - #endif + //----------------------------------------------------------------------------- // Defines @@ -159,7 +161,7 @@ typedef enum _CASC_STORAGE_INFO_CLASS // Returns the total file count, including the offline files CascStorageTotalFileCount, - + CascStorageFeatures, // Returns the features flag CascStorageInstalledLocales, // Not supported CascStorageProduct, // Gives CASC_STORAGE_PRODUCT @@ -187,7 +189,7 @@ typedef enum _CASC_NAME_TYPE CascNameDataId, // Name created from file data id (FILE%08X.dat) CascNameCKey, // Name created as string representation of CKey CascNameEKey // Name created as string representation of EKey -} CASC_NAME_TYPE, *PCASC_NAME_TYPE; +} CASC_NAME_TYPE, *PCASC_NAME_TYPE; // Structure for SFileFindFirstFile and SFileFindNextFile typedef struct _CASC_FIND_DATA @@ -195,7 +197,7 @@ typedef struct _CASC_FIND_DATA // Full name of the found file. In case when this is CKey/EKey, // this will be just string representation of the key stored in 'FileKey' char szFileName[MAX_PATH]; - + // Content key. This is present if the CASC_FEATURE_ROOT_CKEY is present BYTE CKey[MD5_HASH_SIZE]; @@ -213,7 +215,7 @@ typedef struct _CASC_FIND_DATA // File data ID. Only valid if the storage supports file data IDs, otherwise CASC_INVALID_ID DWORD dwFileDataId; - + // Locale flags. Only valid if the storage supports locale flags, otherwise CASC_INVALID_ID DWORD dwLocaleFlags; @@ -246,7 +248,7 @@ typedef struct _CASC_STORAGE_TAGS CASC_STORAGE_TAG Tags[1]; // Array of CASC tags -} CASC_STORAGE_TAGS, *PCASC_STORAGE_TAGS; +} CASC_STORAGE_TAGS, *PCASC_STORAGE_TAGS; typedef struct _CASC_STORAGE_PRODUCT { @@ -333,10 +335,12 @@ typedef struct _CASC_OPEN_STORAGE_ARGS // Any additional member from here on must be checked for availability using the ExtractVersionedArgument function. // Example: // - // DWORD dwMyExtraMember = 0; - // ExtractVersionedArgument(pArgs, offsetof(CASC_OPEN_STORAGE_ARGS, dwMyExtraMember), &dwMyExtraMember); + // LPCTSTR szBuildKey = NULL; + // ExtractVersionedArgument(pArgs, offsetof(CASC_OPEN_STORAGE_ARGS, szBuildId), &szBuildKey); // + LPCTSTR szBuildKey; // If non-null, this will specify a build key (aka MD5 of build config that is different that current online version) + } CASC_OPEN_STORAGE_ARGS, *PCASC_OPEN_STORAGE_ARGS; //----------------------------------------------------------------------------- diff --git a/dep/CascLib/src/CascOpenStorage.cpp b/dep/CascLib/src/CascOpenStorage.cpp index aab10d2c88a..d48ae50342f 100644 --- a/dep/CascLib/src/CascOpenStorage.cpp +++ b/dep/CascLib/src/CascOpenStorage.cpp @@ -14,6 +14,10 @@ #include "CascLib.h" #include "CascCommon.h" +#ifdef INTERLOCKED_NOT_SUPPORTED +#pragma error Interlocked operations are not supported on this architecture. Multi-threaded access to CASC storages will not work properly. +#endif + //----------------------------------------------------------------------------- // Local defines @@ -23,15 +27,21 @@ //----------------------------------------------------------------------------- // DEBUG functions -//#define CHECKED_KEY "2a378c" +#define CHECKED_KEY {0x00, 0x00, 0x0F, 0x84} #if defined(_DEBUG) && defined(CHECKED_KEY) inline bool CheckForXKey(LPBYTE XKey) { - BYTE CheckedKey[4]; - ConvertStringToBinary(CHECKED_KEY, 6, CheckedKey); - return (XKey[0] == CheckedKey[0] && XKey[1] == CheckedKey[1] && XKey[2] == CheckedKey[2]); + BYTE CheckedKey[] = CHECKED_KEY; + + for(size_t i = 0; i < _countof(CheckedKey); i++) + { + if(XKey[i] != CheckedKey[i]) + return false; + } + + return true; } #define BREAK_ON_WATCHED(XKey) if(CheckForXKey((LPBYTE)XKey)) { __debugbreak(); } @@ -54,14 +64,19 @@ TCascStorage::TCascStorage() szRootPath = szDataPath = szIndexPath = szBuildFile = szCdnServers = szCdnPath = szCodeName = NULL; szIndexFormat = NULL; szRegion = NULL; - + szBuildKey = NULL; + memset(DataFiles, 0, sizeof(DataFiles)); memset(IndexFiles, 0, sizeof(IndexFiles)); + CascInitLock(StorageLock); + dwDefaultLocale = 0; dwBuildNumber = 0; dwFeatures = 0; BuildFileType = CascBuildNone; + LastFailKeyName = 0; LocalFiles = TotalFiles = EKeyEntries = EKeyLength = FileOffsetBits = 0; + pArgs = NULL; } TCascStorage::~TCascStorage() @@ -81,6 +96,9 @@ TCascStorage::~TCascStorage() // Cleanup space occupied by index files FreeIndexFiles(this); + // Cleanup the lock + CascFreeLock(StorageLock); + // Free the file paths CASC_FREE(szDataPath); CASC_FREE(szRootPath); @@ -90,6 +108,7 @@ TCascStorage::~TCascStorage() CASC_FREE(szCdnPath); CASC_FREE(szCodeName); CASC_FREE(szRegion); + CASC_FREE(szBuildKey); // Free the blobs FreeCascBlob(&CdnConfigKey); @@ -105,12 +124,15 @@ TCascStorage::~TCascStorage() TCascStorage * TCascStorage::AddRef() { + // Need this to be atomic to make multi-threaded file opens work CascInterlockedIncrement(&dwRefCount); return this; } TCascStorage * TCascStorage::Release() { + // If the reference count reached zero, we close the archive + // Need this to be atomic to make multi-threaded file opens work if(CascInterlockedDecrement(&dwRefCount) == 0) { delete this; @@ -362,8 +384,6 @@ static DWORD InitCKeyArray(TCascStorage * hs) if(dwErrCode != ERROR_SUCCESS) return dwErrCode; - // Insert the entry of ENCODING file. This is vital for its opening and loading - InsertCKeyEntry(hs, hs->EncodingCKey); return ERROR_SUCCESS; } @@ -433,9 +453,10 @@ static int LoadEncodingManifest(TCascStorage * hs) if(InvokeProgressCallback(hs, "Loading ENCODING manifest", NULL, 0, 0)) return ERROR_CANCELLED; - // Fill-in the information from the index entry + // Fill-in the information from the index entry and insert it to the file tree if(!CopyEKeyEntry(hs, &CKeyEntry)) return ERROR_FILE_NOT_FOUND; + InsertCKeyEntry(hs, CKeyEntry); // Load the entire encoding file to memory pbEncodingFile = LoadInternalFileToMemory(hs, &hs->EncodingCKey, &cbEncodingFile); @@ -809,7 +830,9 @@ static bool InsertWellKnownFile(TCascStorage * hs, const char * szFileName, CASC // Insert the key to the root handler. Note that the file can already be referenced // ("index" vs "vfs-root" in Warcraft III storages) hs->pRootHandler->Insert(szFileName, pCKeyEntry); - pCKeyEntry->Flags |= (CASC_CE_IN_BUILD | dwFlags); + + // Copy some flags + pCKeyEntry->Flags |= (dwFlags | CASC_CE_IN_BUILD); return true; } } @@ -823,7 +846,7 @@ static bool InsertWellKnownFile(TCascStorage * hs, const char * szFileName, CASC if(pCKeyEntry != NULL) { hs->pRootHandler->Insert(szFileName, pCKeyEntry); - pCKeyEntry->Flags |= (CASC_CE_IN_BUILD | dwFlags); + pCKeyEntry->Flags |= (dwFlags | CASC_CE_IN_BUILD); return true; } } @@ -1123,7 +1146,7 @@ static DWORD LoadCascStorage(TCascStorage * hs, PCASC_OPEN_STORAGE_ARGS pArgs) { LPCTSTR szCodeName = NULL; LPCTSTR szRegion = NULL; - char szRegionA[0x40]; + LPCTSTR szBuildKey = NULL; DWORD dwLocaleMask = 0; DWORD dwErrCode = ERROR_SUCCESS; @@ -1131,18 +1154,19 @@ static DWORD LoadCascStorage(TCascStorage * hs, PCASC_OPEN_STORAGE_ARGS pArgs) hs->pArgs = pArgs; // Extract optional arguments - ExtractVersionedArgument(pArgs, offsetof(CASC_OPEN_STORAGE_ARGS, dwLocaleMask), &dwLocaleMask); + ExtractVersionedArgument(pArgs, FIELD_OFFSET(CASC_OPEN_STORAGE_ARGS, dwLocaleMask), &dwLocaleMask); // Extract the product code name - if(ExtractVersionedArgument(pArgs, offsetof(CASC_OPEN_STORAGE_ARGS, szCodeName), &szCodeName) && szCodeName != NULL) + if(ExtractVersionedArgument(pArgs, FIELD_OFFSET(CASC_OPEN_STORAGE_ARGS, szCodeName), &szCodeName) && szCodeName != NULL) hs->szCodeName = CascNewStr(szCodeName); // Extract the region (optional) - if(ExtractVersionedArgument(pArgs, offsetof(CASC_OPEN_STORAGE_ARGS, szRegion), &szRegion) && szRegion != NULL) - { - CascStrCopy(szRegionA, _countof(szRegionA), szRegion); - hs->szRegion = CascNewStr(szRegionA); - } + if(ExtractVersionedArgument(pArgs, FIELD_OFFSET(CASC_OPEN_STORAGE_ARGS, szRegion), &szRegion) && szRegion != NULL) + hs->szRegion = CascNewStrT2A(szRegion); + + // Extract the build key (optional) + if(ExtractVersionedArgument(pArgs, FIELD_OFFSET(CASC_OPEN_STORAGE_ARGS, szBuildKey), &szBuildKey) && szBuildKey != NULL) + hs->szBuildKey = CascNewStrT2A(szBuildKey); // For online storages, we need to load CDN servers if ((dwErrCode == ERROR_SUCCESS) && (hs->dwFeatures & CASC_FEATURE_ONLINE)) @@ -1271,6 +1295,7 @@ static LPTSTR ParseOpenParams(LPCTSTR szParams, PCASC_OPEN_STORAGE_ARGS pArgs) pArgs->szLocalPath = szParamsCopy; pArgs->szCodeName = NULL; pArgs->szRegion = NULL; + pArgs->szBuildKey = NULL; // Find the first ":". This will indicate the end of local path and also begin of product code if((szSeparator = _tcschr(szPlainName, _T(':'))) != NULL) @@ -1284,6 +1309,13 @@ static LPTSTR ParseOpenParams(LPCTSTR szParams, PCASC_OPEN_STORAGE_ARGS pArgs) { pArgs->szRegion = szSeparator + 1; szSeparator[0] = 0; + + // Try again. If found, it is a build key (MD5 of a build file) + if((szSeparator = _tcschr(szSeparator + 1, _T(':'))) != NULL) + { + pArgs->szBuildKey = szSeparator + 1; + szSeparator[0] = 0; + } } } } diff --git a/dep/CascLib/src/CascPort.h b/dep/CascLib/src/CascPort.h index 9f401f80b2e..8a296505c7e 100644 --- a/dep/CascLib/src/CascPort.h +++ b/dep/CascLib/src/CascPort.h @@ -37,11 +37,11 @@ #define WIN32_LEAN_AND_MEAN #endif -//#pragma warning(disable:4995) // warning C4995: 'sprintf': name was marked as #pragma deprecated + // Suppress definitions of `min` and `max` macros by <windows.h>: + #define NOMINMAX 1 #include <tchar.h> #include <assert.h> - #include <intrin.h> // Support for intrinsic functions #include <ctype.h> #include <io.h> #include <stdio.h> @@ -63,14 +63,21 @@ #define URL_SEP_CHAR '/' #define PATH_SEP_CHAR '\\' #define PATH_SEP_STRING "\\" - - #pragma intrinsic(memcmp, memcpy) #define PLATFORM_WINDOWS #define PLATFORM_DEFINED // The platform is known now #endif +#if _MSC_VER >= 1500 + #include <intrin.h> // Support for intrinsic functions + #pragma intrinsic(memcmp, memcpy) +#endif + +#ifndef FIELD_OFFSET +#define FIELD_OFFSET(type, field) ((LONG)(size_t)&(((type *)0)->field)) +#endif + //----------------------------------------------------------------------------- // Defines for Mac @@ -93,6 +100,7 @@ #include <wchar.h> #include <cassert> #include <errno.h> + #include <pthread.h> // Support for PowerPC on Max OS X #if (__ppc__ == 1) || (__POWERPC__ == 1) || (_ARCH_PPC == 1) @@ -111,11 +119,10 @@ #define URL_SEP_CHAR '/' #define PATH_SEP_CHAR '/' #define PATH_SEP_STRING "/" - + #define PLATFORM_MAC #define PLATFORM_DEFINED // The platform is known now - #define FIELD_OFFSET(t,f) offsetof(t,f) #endif //----------------------------------------------------------------------------- @@ -138,16 +145,16 @@ #include <wchar.h> #include <assert.h> #include <errno.h> + #include <pthread.h> #define URL_SEP_CHAR '/' #define PATH_SEP_CHAR '/' #define PATH_SEP_STRING "/" - + #define PLATFORM_LITTLE_ENDIAN #define PLATFORM_LINUX #define PLATFORM_DEFINED - #define FIELD_OFFSET(t,f) offsetof(t,f) #endif //----------------------------------------------------------------------------- @@ -270,9 +277,9 @@ #endif #ifndef _countof -#define _countof(x) (sizeof(x) / sizeof(x[0])) +#define _countof(x) (sizeof(x) / sizeof(x[0])) #endif - + //----------------------------------------------------------------------------- // Swapping functions @@ -317,25 +324,51 @@ //----------------------------------------------------------------------------- // Interlocked operations -inline DWORD CascInterlockedIncrement(PDWORD PtrValue) +inline DWORD CascInterlockedIncrement(DWORD * PtrValue) { #ifdef PLATFORM_WINDOWS return (DWORD)InterlockedIncrement((LONG *)(PtrValue)); +#elif defined(__GNUC__) + return __sync_add_and_fetch(PtrValue, 1); #else - return ++PtrValue[0]; + #define INTERLOCKED_NOT_SUPPORTED + return ++(*PtrValue); #endif } -inline DWORD CascInterlockedDecrement(PDWORD PtrValue) +inline DWORD CascInterlockedDecrement(DWORD * PtrValue) { #ifdef PLATFORM_WINDOWS return (DWORD)InterlockedDecrement((LONG *)(PtrValue)); +#elif defined(__GNUC__) + return __sync_sub_and_fetch(PtrValue, 1); #else - return --PtrValue[0]; + return --(*PtrValue); #endif } //----------------------------------------------------------------------------- +// Lock functions + +#ifdef PLATFORM_WINDOWS + +typedef RTL_CRITICAL_SECTION CASC_LOCK; +#define CascInitLock(Lock) InitializeCriticalSection(&Lock); +#define CascFreeLock(Lock) DeleteCriticalSection(&Lock); +#define CascLock(Lock) EnterCriticalSection(&Lock); +#define CascUnlock(Lock) LeaveCriticalSection(&Lock); + +#else + +typedef pthread_mutex_t CASC_LOCK; +#define CascInitLock(Lock) pthread_mutex_init(&Lock, NULL); +#define CascFreeLock(Lock) pthread_mutex_destroy(&Lock); +#define CascLock(Lock) pthread_mutex_lock(&Lock); +#define CascUnlock(Lock) pthread_mutex_unlock(&Lock); + +#endif + +//----------------------------------------------------------------------------- // Forbidden functions, do not use #ifdef __CASCLIB_SELF__ diff --git a/dep/CascLib/src/CascReadFile.cpp b/dep/CascLib/src/CascReadFile.cpp index aa2a718198c..5bfc4f654a0 100644 --- a/dep/CascLib/src/CascReadFile.cpp +++ b/dep/CascLib/src/CascReadFile.cpp @@ -40,7 +40,10 @@ static DWORD OpenDataStream(TCascFile * hf, PCASC_FILE_SPAN pFileSpan, PCASC_CKE { DWORD dwArchiveIndex = pFileSpan->ArchiveIndex; - // If the file is not open yet, do it + // Lock the storage to make the operation thread-safe + CascLock(hs->StorageLock); + + // If the data archive is not open yet, open it now. if(hs->DataFiles[dwArchiveIndex] == NULL) { // Prepare the name of the data file @@ -53,6 +56,9 @@ static DWORD OpenDataStream(TCascFile * hf, PCASC_FILE_SPAN pFileSpan, PCASC_CKE hs->DataFiles[dwArchiveIndex] = pStream; } + // Unlock the storage + CascUnlock(hs->StorageLock); + // Return error or success pFileSpan->pStream = hs->DataFiles[dwArchiveIndex]; return (pFileSpan->pStream != NULL) ? ERROR_SUCCESS : ERROR_FILE_NOT_FOUND; @@ -257,7 +263,7 @@ static LPBYTE CaptureBlteFileFrame(CASC_FILE_FRAME & Frame, LPBYTE pbFramePtr, L return pbFramePtr + sizeof(BLTE_FRAME); } -static DWORD LoadSpanFrames(PCASC_FILE_SPAN pFileSpan, PCASC_CKEY_ENTRY pCKeyEntry, DWORD DataFileOffset, LPBYTE pbFramePtr, LPBYTE pbFrameEnd, size_t cbHeaderSize) +static DWORD LoadSpanFrames(PCASC_FILE_SPAN pFileSpan, PCASC_CKEY_ENTRY pCKeyEntry, ULONGLONG DataFileOffset, LPBYTE pbFramePtr, LPBYTE pbFrameEnd, size_t cbHeaderSize) { PCASC_FILE_FRAME pFrames = NULL; DWORD ContentSize = 0; @@ -420,8 +426,8 @@ static DWORD LoadEncodedHeaderAndSpanFrames(PCASC_FILE_SPAN pFileSpan, PCASC_CKE // Load the array of frame headers if (dwErrCode == ERROR_SUCCESS) { - assert((DWORD)(ReadOffset + cbHeaderSize) > (DWORD)ReadOffset); - dwErrCode = LoadSpanFrames(pFileSpan, pCKeyEntry, (DWORD)(ReadOffset + cbHeaderSize), pbEncodedBuffer + cbHeaderSize, pbEncodedBuffer + cbEncodedBuffer, cbHeaderSize); + assert((ReadOffset + cbHeaderSize) > ReadOffset); + dwErrCode = LoadSpanFrames(pFileSpan, pCKeyEntry, ReadOffset + cbHeaderSize, pbEncodedBuffer + cbHeaderSize, pbEncodedBuffer + cbEncodedBuffer, cbHeaderSize); } } else @@ -821,7 +827,6 @@ static DWORD ReadFile_FrameCached(TCascFile * hf, LPBYTE pbBuffer, ULONGLONG Sta PCASC_CKEY_ENTRY pCKeyEntry = hf->pCKeyEntry; PCASC_FILE_SPAN pFileSpan = hf->pFileSpan; PCASC_FILE_FRAME pFileFrame = NULL; - ULONGLONG ByteOffset; LPBYTE pbSaveBuffer = pbBuffer; LPBYTE pbEncoded = NULL; LPBYTE pbDecoded = NULL; @@ -876,8 +881,7 @@ static DWORD ReadFile_FrameCached(TCascFile * hf, LPBYTE pbBuffer, ULONGLONG Sta } // Load the frame to the encoded buffer - ByteOffset = pFileFrame->DataFileOffset; - if(FileStream_Read(pFileSpan->pStream, &ByteOffset, pbEncoded, pFileFrame->EncodedSize)) + if(FileStream_Read(pFileSpan->pStream, &pFileFrame->DataFileOffset, pbEncoded, pFileFrame->EncodedSize)) { ULONGLONG EndOfCopy = CASCLIB_MIN(pFileFrame->EndOffset, EndOffset); DWORD dwBytesToCopy = (DWORD)(EndOfCopy - StartOffset); @@ -1143,7 +1147,7 @@ bool WINAPI CascSetFilePointer64(HANDLE hFile, LONGLONG DistanceToMove, PULONGLO } // Do not allow the file pointer to move to negative values - if((FilePosition = FilePosition + DistanceToMove) < 0) + if((LONGLONG)(FilePosition = FilePosition + DistanceToMove) < 0) FilePosition = 0; hf->FilePointer = FilePosition; } @@ -1269,6 +1273,8 @@ bool WINAPI CascReadFile(HANDLE hFile, void * pvBuffer, DWORD dwBytesToRead, PDW if(PtrBytesRead != NULL) PtrBytesRead[0] = 0; hf->FilePointer = SaveFilePointer; - return false; + + // If 0 bytes were requested, it's actually a success + return (dwBytesToRead == 0); } } diff --git a/dep/CascLib/src/DllMain.rc b/dep/CascLib/src/DllMain.rc index a6243d2540b..7007a24ab65 100644 --- a/dep/CascLib/src/DllMain.rc +++ b/dep/CascLib/src/DllMain.rc @@ -25,8 +25,8 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL // VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,50,0,181 - PRODUCTVERSION 1,50,0,181 + FILEVERSION 1,50,0,197 + PRODUCTVERSION 1,50,0,197 FILEFLAGSMASK 0x17L #ifdef _DEBUG FILEFLAGS 0x1L @@ -42,12 +42,12 @@ BEGIN BLOCK "040504b0" BEGIN VALUE "FileDescription", "CascLib library for reading Blizzard CASC storages" - VALUE "FileVersion", "1, 50, 0, 181\0" + VALUE "FileVersion", "1, 50, 0, 197\0" VALUE "InternalName", "CascLib" VALUE "LegalCopyright", "Copyright (c) 2014 - 2019 Ladislav Zezula" VALUE "OriginalFilename", "CascLib.dll" VALUE "ProductName", "CascLib" - VALUE "ProductVersion", "1, 50, 0, 181\0" + VALUE "ProductVersion", "1, 50, 0, 197\0" END END BLOCK "VarFileInfo" diff --git a/dep/CascLib/src/common/Common.cpp b/dep/CascLib/src/common/Common.cpp index 1fc6cc977b4..c16323e0f5e 100644 --- a/dep/CascLib/src/common/Common.cpp +++ b/dep/CascLib/src/common/Common.cpp @@ -356,6 +356,44 @@ wchar_t * CascNewStr(const wchar_t * szString, size_t nCharsToReserve) return szNewString; } +LPSTR CascNewStrT2A(LPCTSTR szString, size_t nCharsToReserve) +{ + LPSTR szNewString = NULL; + size_t nLength; + + if(szString != NULL) + { + nLength = _tcslen(szString); + szNewString = CASC_ALLOC<char>(nLength + nCharsToReserve + 1); + if(szNewString != NULL) + { + CascStrCopy(szNewString, nLength + nCharsToReserve + 1, szString, nLength); +// szNewString[nLength] = 0; + } + } + + return szNewString; +} + +LPTSTR CascNewStrA2T(LPCSTR szString, size_t nCharsToReserve) +{ + LPTSTR szNewString = NULL; + size_t nLength; + + if(szString != NULL) + { + nLength = strlen(szString); + szNewString = CASC_ALLOC<TCHAR>(nLength + nCharsToReserve + 1); + if(szNewString != NULL) + { + CascStrCopy(szNewString, nLength + nCharsToReserve + 1, szString, nLength); +// szNewString[nLength] = 0; + } + } + + return szNewString; +} + //----------------------------------------------------------------------------- // String merging @@ -387,7 +425,7 @@ LPTSTR GetLastPathPart(LPTSTR szWorkPath) return NULL; } -bool CutLastPathPart(TCHAR * szWorkPath) +bool CutLastPathPart(LPTSTR szWorkPath) { // Get the last part of the path szWorkPath = GetLastPathPart(szWorkPath); @@ -482,7 +520,7 @@ ULONGLONG CalcFileNameHash(const char * szFileName) return CalcNormNameHash(szNormName, nLength); } -int ConvertDigitToInt32(const TCHAR * szString, PDWORD PtrValue) +DWORD ConvertDigitToInt32(LPCTSTR szString, PDWORD PtrValue) { BYTE Digit; @@ -494,7 +532,7 @@ int ConvertDigitToInt32(const TCHAR * szString, PDWORD PtrValue) return (Digit > 0x0F) ? ERROR_BAD_FORMAT : ERROR_SUCCESS; } -int ConvertStringToInt08(const char * szString, PDWORD PtrValue) +DWORD ConvertStringToInt08(LPCSTR szString, PDWORD PtrValue) { BYTE DigitOne = AsciiToUpperTable_BkSlash[szString[0]] - '0'; BYTE DigitTwo = AsciiToUpperTable_BkSlash[szString[1]] - '0'; @@ -510,7 +548,7 @@ int ConvertStringToInt08(const char * szString, PDWORD PtrValue) return (DigitOne <= 0x0F && DigitTwo <= 0x0F) ? ERROR_SUCCESS : ERROR_BAD_FORMAT; } -int ConvertStringToInt32(const TCHAR * szString, size_t nMaxDigits, PDWORD PtrValue) +DWORD ConvertStringToInt32(LPCTSTR szString, size_t nMaxDigits, PDWORD PtrValue) { // The number of digits must be even assert((nMaxDigits & 0x01) == 0); @@ -545,8 +583,8 @@ int ConvertStringToInt32(const TCHAR * szString, size_t nMaxDigits, PDWORD PtrVa } // Converts string blob to binary blob. -int ConvertStringToBinary( - const char * szString, +DWORD ConvertStringToBinary( + LPCSTR szString, size_t nMaxDigits, LPBYTE pbBinary) { diff --git a/dep/CascLib/src/common/Common.h b/dep/CascLib/src/common/Common.h index ddf8e136c9b..0037293f53d 100644 --- a/dep/CascLib/src/common/Common.h +++ b/dep/CascLib/src/common/Common.h @@ -166,6 +166,14 @@ void CASC_FREE(T *& ptr) } //----------------------------------------------------------------------------- +// 32-bit ROL + +inline DWORD Rol32(DWORD dwValue, DWORD dwRolCount) +{ + return (dwValue << dwRolCount) | (dwValue >> (32 - dwRolCount)); +} + +//----------------------------------------------------------------------------- // Big endian number manipulation inline DWORD ConvertBytesToInteger_2(LPBYTE ValueAsBytes) @@ -246,18 +254,18 @@ inline ULONGLONG ConvertBytesToInteger_5(LPBYTE ValueAsBytes) inline void ConvertIntegerToBytes_4(DWORD Value, LPBYTE ValueAsBytes) { - ValueAsBytes[0] = (Value >> 0x18) & 0xFF; - ValueAsBytes[1] = (Value >> 0x10) & 0xFF; - ValueAsBytes[2] = (Value >> 0x08) & 0xFF; - ValueAsBytes[3] = (Value >> 0x00) & 0xFF; + ValueAsBytes[0] = (BYTE)((Value >> 0x18) & 0xFF); + ValueAsBytes[1] = (BYTE)((Value >> 0x10) & 0xFF); + ValueAsBytes[2] = (BYTE)((Value >> 0x08) & 0xFF); + ValueAsBytes[3] = (BYTE)((Value >> 0x00) & 0xFF); } inline void ConvertIntegerToBytes_4_LE(DWORD Value, LPBYTE ValueAsBytes) { - ValueAsBytes[0] = (Value >> 0x00) & 0xFF; - ValueAsBytes[1] = (Value >> 0x08) & 0xFF; - ValueAsBytes[2] = (Value >> 0x10) & 0xFF; - ValueAsBytes[3] = (Value >> 0x18) & 0xFF; + ValueAsBytes[0] = (BYTE)((Value >> 0x00) & 0xFF); + ValueAsBytes[1] = (BYTE)((Value >> 0x08) & 0xFF); + ValueAsBytes[2] = (BYTE)((Value >> 0x10) & 0xFF); + ValueAsBytes[3] = (BYTE)((Value >> 0x18) & 0xFF); } // Faster than memset(Buffer, 0, 0x10) @@ -313,14 +321,17 @@ size_t CascStrPrintf(wchar_t * buffer, size_t nCount, const wchar_t * format, .. //----------------------------------------------------------------------------- // String allocation -char * CascNewStr(const char * szString, size_t nCharsToReserve = 0); +char * CascNewStr(const char * szString, size_t nCharsToReserve = 0); wchar_t * CascNewStr(const wchar_t * szString, size_t nCharsToReserve = 0); +LPSTR CascNewStrT2A(LPCTSTR szString, size_t nCharsToReserve = 0); +LPTSTR CascNewStrA2T(LPCSTR szString, size_t nCharsToReserve = 0); + size_t CombinePath(LPTSTR szBuffer, size_t nMaxChars, char chSeparator, va_list argList); size_t CombinePath(LPTSTR szBuffer, size_t nMaxChars, char chSeparator, ...); LPTSTR CombinePath(LPCTSTR szPath, LPCTSTR szSubDir); LPTSTR GetLastPathPart(LPTSTR szWorkPath); -bool CutLastPathPart(TCHAR * szWorkPath); +bool CutLastPathPart(LPTSTR szWorkPath); size_t NormalizeFileName_UpperBkSlash(char * szNormName, const char * szFileName, size_t cchMaxChars); size_t NormalizeFileName_LowerSlash(char * szNormName, const char * szFileName, size_t cchMaxChars); @@ -328,10 +339,10 @@ size_t NormalizeFileName_LowerSlash(char * szNormName, const char * szFileName, ULONGLONG CalcNormNameHash(const char * szNormName, size_t nLength); ULONGLONG CalcFileNameHash(const char * szFileName); -int ConvertDigitToInt32(const TCHAR * szString, PDWORD PtrValue); -int ConvertStringToInt08(const char * szString, PDWORD PtrValue); -int ConvertStringToInt32(const TCHAR * szString, size_t nMaxDigits, PDWORD PtrValue); -int ConvertStringToBinary(const char * szString, size_t nMaxDigits, LPBYTE pbBinary); +DWORD ConvertDigitToInt32(LPCTSTR szString, PDWORD PtrValue); +DWORD ConvertStringToInt08(LPCSTR szString, PDWORD PtrValue); +DWORD ConvertStringToInt32(LPCTSTR szString, size_t nMaxDigits, PDWORD PtrValue); +DWORD ConvertStringToBinary(LPCSTR szString, size_t nMaxDigits, LPBYTE pbBinary); //----------------------------------------------------------------------------- // Conversion from binary array to string. The caller must ensure that diff --git a/dep/CascLib/src/common/Csv.cpp b/dep/CascLib/src/common/Csv.cpp index c665fc00c4c..818973e9603 100644 --- a/dep/CascLib/src/common/Csv.cpp +++ b/dep/CascLib/src/common/Csv.cpp @@ -185,7 +185,7 @@ CASC_CSV::~CASC_CSV() m_szCsvFile = NULL; } -DWORD CASC_CSV::Load(const TCHAR * szFileName) +DWORD CASC_CSV::Load(LPCTSTR szFileName) { DWORD cbFileData = 0; DWORD dwErrCode = ERROR_SUCCESS; diff --git a/dep/CascLib/src/common/Csv.h b/dep/CascLib/src/common/Csv.h index 394eab1e2f0..2fcee847703 100644 --- a/dep/CascLib/src/common/Csv.h +++ b/dep/CascLib/src/common/Csv.h @@ -70,7 +70,7 @@ class CASC_CSV ~CASC_CSV(); DWORD Load(LPBYTE pbData, size_t cbData); - DWORD Load(const TCHAR * szFileName); + DWORD Load(LPCTSTR szFileName); bool LoadNextLine(); const CASC_CSV_COLUMN & operator[](const char * szColumnName) const; diff --git a/dep/CascLib/src/common/Directory.cpp b/dep/CascLib/src/common/Directory.cpp index 387ca3a8ea4..57c7d552733 100644 --- a/dep/CascLib/src/common/Directory.cpp +++ b/dep/CascLib/src/common/Directory.cpp @@ -15,7 +15,7 @@ //----------------------------------------------------------------------------- // Public functions -bool DirectoryExists(const TCHAR * szDirectory) +bool DirectoryExists(LPCTSTR szDirectory) { #ifdef PLATFORM_WINDOWS @@ -38,7 +38,7 @@ bool DirectoryExists(const TCHAR * szDirectory) return false; } -bool MakeDirectory(const TCHAR * szDirectory) +bool MakeDirectory(LPCTSTR szDirectory) { #ifdef PLATFORM_WINDOWS @@ -60,7 +60,7 @@ int ScanIndexDirectory( #ifdef PLATFORM_WINDOWS WIN32_FIND_DATA wf; - TCHAR * szSearchMask; + LPTSTR szSearchMask; HANDLE hFind; // Prepare the search mask diff --git a/dep/CascLib/src/common/FileStream.cpp b/dep/CascLib/src/common/FileStream.cpp index ab591a2e3f1..350b0540cf4 100644 --- a/dep/CascLib/src/common/FileStream.cpp +++ b/dep/CascLib/src/common/FileStream.cpp @@ -89,7 +89,7 @@ static bool BaseFile_Create(TFileStream * pStream) return true; } -static bool BaseFile_Open(TFileStream * pStream, const TCHAR * szFileName, DWORD dwStreamFlags) +static bool BaseFile_Open(TFileStream * pStream, LPCTSTR szFileName, DWORD dwStreamFlags) { #ifdef PLATFORM_WINDOWS { @@ -160,66 +160,72 @@ static bool BaseFile_Read( void * pvBuffer, // Pointer to data to be read DWORD dwBytesToRead) // Number of bytes to read from the file { - ULONGLONG ByteOffset = (pByteOffset != NULL) ? *pByteOffset : pStream->Base.File.FilePos; DWORD dwBytesRead = 0; // Must be set by platform-specific code -#ifdef PLATFORM_WINDOWS + // Synchronize the access to the TFileStream structure + CascLock(pStream->Lock); { - // Note: We no longer support Windows 9x. - // Thus, we can use the OVERLAPPED structure to specify - // file offset to read from file. This allows us to skip - // one system call to SetFilePointer - - // Update the byte offset - pStream->Base.File.FilePos = ByteOffset; + ULONGLONG ByteOffset = (pByteOffset != NULL) ? *pByteOffset : pStream->Base.File.FilePos; - // Read the data - if(dwBytesToRead != 0) +#ifdef PLATFORM_WINDOWS { - OVERLAPPED Overlapped; + // Note: We no longer support Windows 9x. + // Thus, we can use the OVERLAPPED structure to specify + // file offset to read from file. This allows us to skip + // one system call to SetFilePointer - Overlapped.OffsetHigh = (DWORD)(ByteOffset >> 32); - Overlapped.Offset = (DWORD)ByteOffset; - Overlapped.hEvent = NULL; - if(!ReadFile(pStream->Base.File.hFile, pvBuffer, dwBytesToRead, &dwBytesRead, &Overlapped)) - return false; + // Update the byte offset + pStream->Base.File.FilePos = ByteOffset; + + // Read the data + if (dwBytesToRead != 0) + { + OVERLAPPED Overlapped; + + Overlapped.OffsetHigh = (DWORD)(ByteOffset >> 32); + Overlapped.Offset = (DWORD)ByteOffset; + Overlapped.hEvent = NULL; + if (!ReadFile(pStream->Base.File.hFile, pvBuffer, dwBytesToRead, &dwBytesRead, &Overlapped)) + return false; + } } - } #endif #if defined(PLATFORM_MAC) || defined(PLATFORM_LINUX) - { - ssize_t bytes_read; - - // If the byte offset is different from the current file position, - // we have to update the file position - if(ByteOffset != pStream->Base.File.FilePos) { - if(lseek64((intptr_t)pStream->Base.File.hFile, (off64_t)(ByteOffset), SEEK_SET) == (off64_t)-1) + ssize_t bytes_read; + + // If the byte offset is different from the current file position, + // we have to update the file position + if (ByteOffset != pStream->Base.File.FilePos) { - SetLastError(errno); - return false; + if (lseek64((intptr_t)pStream->Base.File.hFile, (off64_t)(ByteOffset), SEEK_SET) == (off64_t)-1) + { + SetLastError(errno); + return false; + } + pStream->Base.File.FilePos = ByteOffset; } - pStream->Base.File.FilePos = ByteOffset; - } - // Perform the read operation - if(dwBytesToRead != 0) - { - bytes_read = read((intptr_t)pStream->Base.File.hFile, pvBuffer, (size_t)dwBytesToRead); - if(bytes_read == -1) + // Perform the read operation + if (dwBytesToRead != 0) { - SetLastError(errno); - return false; - } + bytes_read = read((intptr_t)pStream->Base.File.hFile, pvBuffer, (size_t)dwBytesToRead); + if (bytes_read == -1) + { + SetLastError(errno); + return false; + } - dwBytesRead = (DWORD)(size_t)bytes_read; + dwBytesRead = (DWORD)(size_t)bytes_read; + } } - } #endif - // Increment the current file position by number of bytes read - pStream->Base.File.FilePos = ByteOffset + dwBytesRead; + // Increment the current file position by number of bytes read + pStream->Base.File.FilePos = ByteOffset + dwBytesRead; + } + CascUnlock(pStream->Lock); // If the number of bytes read doesn't match to required amount, return false // However, Blizzard's CASC handlers read encoded data so that if less than expected @@ -249,67 +255,73 @@ static bool BaseFile_Read( static bool BaseFile_Write(TFileStream * pStream, ULONGLONG * pByteOffset, const void * pvBuffer, DWORD dwBytesToWrite) { - ULONGLONG ByteOffset = (pByteOffset != NULL) ? *pByteOffset : pStream->Base.File.FilePos; DWORD dwBytesWritten = 0; // Must be set by platform-specific code -#ifdef PLATFORM_WINDOWS + // Synchronize the access to the TFileStream structure + CascLock(pStream->Lock); { - // Note: We no longer support Windows 9x. - // Thus, we can use the OVERLAPPED structure to specify - // file offset to read from file. This allows us to skip - // one system call to SetFilePointer - - // Update the byte offset - pStream->Base.File.FilePos = ByteOffset; + ULONGLONG ByteOffset = (pByteOffset != NULL) ? *pByteOffset : pStream->Base.File.FilePos; - // Read the data - if(dwBytesToWrite != 0) +#ifdef PLATFORM_WINDOWS { - OVERLAPPED Overlapped; + // Note: We no longer support Windows 9x. + // Thus, we can use the OVERLAPPED structure to specify + // file offset to read from file. This allows us to skip + // one system call to SetFilePointer - Overlapped.OffsetHigh = (DWORD)(ByteOffset >> 32); - Overlapped.Offset = (DWORD)ByteOffset; - Overlapped.hEvent = NULL; - if(!WriteFile(pStream->Base.File.hFile, pvBuffer, dwBytesToWrite, &dwBytesWritten, &Overlapped)) - return false; + // Update the byte offset + pStream->Base.File.FilePos = ByteOffset; + + // Read the data + if (dwBytesToWrite != 0) + { + OVERLAPPED Overlapped; + + Overlapped.OffsetHigh = (DWORD)(ByteOffset >> 32); + Overlapped.Offset = (DWORD)ByteOffset; + Overlapped.hEvent = NULL; + if (!WriteFile(pStream->Base.File.hFile, pvBuffer, dwBytesToWrite, &dwBytesWritten, &Overlapped)) + return false; + } } - } #endif #if defined(PLATFORM_MAC) || defined(PLATFORM_LINUX) - { - ssize_t bytes_written; - - // If the byte offset is different from the current file position, - // we have to update the file position - if(ByteOffset != pStream->Base.File.FilePos) { - if(lseek64((intptr_t)pStream->Base.File.hFile, (off64_t)(ByteOffset), SEEK_SET) == (off64_t)-1) + ssize_t bytes_written; + + // If the byte offset is different from the current file position, + // we have to update the file position + if (ByteOffset != pStream->Base.File.FilePos) + { + if (lseek64((intptr_t)pStream->Base.File.hFile, (off64_t)(ByteOffset), SEEK_SET) == (off64_t)-1) + { + SetLastError(errno); + return false; + } + pStream->Base.File.FilePos = ByteOffset; + } + + // Perform the read operation + bytes_written = write((intptr_t)pStream->Base.File.hFile, pvBuffer, (size_t)dwBytesToWrite); + if (bytes_written == -1) { SetLastError(errno); return false; } - pStream->Base.File.FilePos = ByteOffset; - } - // Perform the read operation - bytes_written = write((intptr_t)pStream->Base.File.hFile, pvBuffer, (size_t)dwBytesToWrite); - if(bytes_written == -1) - { - SetLastError(errno); - return false; + dwBytesWritten = (DWORD)(size_t)bytes_written; } - - dwBytesWritten = (DWORD)(size_t)bytes_written; - } #endif - // Increment the current file position by number of bytes read - pStream->Base.File.FilePos = ByteOffset + dwBytesWritten; + // Increment the current file position by number of bytes read + pStream->Base.File.FilePos = ByteOffset + dwBytesWritten; - // Also modify the file size, if needed - if(pStream->Base.File.FilePos > pStream->Base.File.FileSize) - pStream->Base.File.FileSize = pStream->Base.File.FilePos; + // Also modify the file size, if needed + if(pStream->Base.File.FilePos > pStream->Base.File.FileSize) + pStream->Base.File.FileSize = pStream->Base.File.FilePos; + } + CascUnlock(pStream->Lock); if(dwBytesWritten != dwBytesToWrite) SetLastError(ERROR_DISK_FULL); @@ -383,12 +395,8 @@ static bool BaseFile_GetPos(TFileStream * pStream, ULONGLONG * pByteOffset) static bool BaseFile_Replace(TFileStream * pStream, TFileStream * pNewStream) { #ifdef PLATFORM_WINDOWS - // Delete the original stream file. Don't check the result value, - // because if the file doesn't exist, it would fail - DeleteFile(pStream->szFileName); - // Rename the new file to the old stream's file - return (bool)MoveFile(pNewStream->szFileName, pStream->szFileName); + return (bool)MoveFileEx(pNewStream->szFileName, pStream->szFileName, MOVEFILE_COPY_ALLOWED | MOVEFILE_REPLACE_EXISTING); #endif #if defined(PLATFORM_MAC) || defined(PLATFORM_LINUX) @@ -405,19 +413,24 @@ static bool BaseFile_Replace(TFileStream * pStream, TFileStream * pNewStream) static void BaseFile_Close(TFileStream * pStream) { - if(pStream->Base.File.hFile != INVALID_HANDLE_VALUE) + // Synchronize the access to multiple threads + CascLock(pStream->Lock); { + if(pStream->Base.File.hFile != INVALID_HANDLE_VALUE) + { #ifdef PLATFORM_WINDOWS - CloseHandle(pStream->Base.File.hFile); + CloseHandle(pStream->Base.File.hFile); #endif #if defined(PLATFORM_MAC) || defined(PLATFORM_LINUX) - close((intptr_t)pStream->Base.File.hFile); + close((intptr_t)pStream->Base.File.hFile); #endif - } + } - // Also invalidate the handle - pStream->Base.File.hFile = INVALID_HANDLE_VALUE; + // Also invalidate the handle + pStream->Base.File.hFile = INVALID_HANDLE_VALUE; + } + CascUnlock(pStream->Lock); } // Initializes base functions for the disk file @@ -436,7 +449,7 @@ static void BaseFile_Init(TFileStream * pStream) //----------------------------------------------------------------------------- // Local functions - base memory-mapped file support -static bool BaseMap_Open(TFileStream * pStream, const TCHAR * szFileName, DWORD dwStreamFlags) +static bool BaseMap_Open(TFileStream * pStream, LPCTSTR szFileName, DWORD dwStreamFlags) { #ifdef PLATFORM_WINDOWS @@ -584,7 +597,7 @@ static void BaseMap_Init(TFileStream * pStream) //----------------------------------------------------------------------------- // Local functions - base HTTP file support -static const TCHAR * BaseHttp_ExtractServerName(const TCHAR * szFileName, TCHAR * szServerName) +static LPCTSTR BaseHttp_ExtractServerName(LPCTSTR szFileName, LPTSTR szServerName) { // Check for HTTP if(!_tcsnicmp(szFileName, _T("http://"), 7)) @@ -607,7 +620,7 @@ static const TCHAR * BaseHttp_ExtractServerName(const TCHAR * szFileName, TCHAR return szFileName; } -static bool BaseHttp_Open(TFileStream * pStream, const TCHAR * szFileName, DWORD dwStreamFlags) +static bool BaseHttp_Open(TFileStream * pStream, LPCTSTR szFileName, DWORD dwStreamFlags) { #ifdef PLATFORM_WINDOWS @@ -1018,13 +1031,13 @@ static STREAM_INIT StreamBaseInit[4] = // The stream structure is created as flat block, variable length // The file name is placed after the end of the stream structure data static TFileStream * AllocateFileStream( - const TCHAR * szFileName, + LPCTSTR szFileName, size_t StreamSize, DWORD dwStreamFlags) { TFileStream * pMaster = NULL; TFileStream * pStream; - const TCHAR * szNextFile = szFileName; + LPCTSTR szNextFile = szFileName; size_t FileNameSize; // Sanity check @@ -1063,10 +1076,13 @@ static TFileStream * AllocateFileStream( pStream->dwFlags = dwStreamFlags; // Initialize the file name - pStream->szFileName = (TCHAR *)((BYTE *)pStream + StreamSize); + pStream->szFileName = (LPTSTR)((BYTE *)pStream + StreamSize); memcpy(pStream->szFileName, szFileName, FileNameSize); pStream->szFileName[FileNameSize / sizeof(TCHAR)] = 0; + // Initialize the stream lock + CascInitLock(pStream->Lock); + // Initialize the stream functions StreamBaseInit[dwStreamFlags & 0x03](pStream); } @@ -1367,7 +1383,7 @@ static bool FlatStream_CreateMirror(TBlockStream * pStream) return true; } -static TFileStream * FlatStream_Open(const TCHAR * szFileName, DWORD dwStreamFlags) +static TFileStream * FlatStream_Open(LPCTSTR szFileName, DWORD dwStreamFlags) { TBlockStream * pStream; ULONGLONG ByteOffset = 0; @@ -1788,7 +1804,7 @@ static bool PartStream_CreateMirror(TBlockStream * pStream) return true; } -static TFileStream * PartStream_Open(const TCHAR * szFileName, DWORD dwStreamFlags) +static TFileStream * PartStream_Open(LPCTSTR szFileName, DWORD dwStreamFlags) { TBlockStream * pStream; @@ -1898,13 +1914,6 @@ static const char * AuthCodeArray[] = NULL }; -static DWORD Rol32(DWORD dwValue, DWORD dwRolCount) -{ - DWORD dwShiftRight = 32 - dwRolCount; - - return (dwValue << dwRolCount) | (dwValue >> dwShiftRight); -} - static void CreateKeyFromAuthCode( LPBYTE pbKeyBuffer, const char * szAuthCode) @@ -2105,7 +2114,7 @@ static bool EncrStream_BlockRead( return true; } -static TFileStream * EncrStream_Open(const TCHAR * szFileName, DWORD dwStreamFlags) +static TFileStream * EncrStream_Open(LPCTSTR szFileName, DWORD dwStreamFlags) { TEncryptedStream * pStream; @@ -2232,14 +2241,14 @@ static void Block4Stream_Close(TBlockStream * pStream) return; } -static TFileStream * Block4Stream_Open(const TCHAR * szFileName, DWORD dwStreamFlags) +static TFileStream * Block4Stream_Open(LPCTSTR szFileName, DWORD dwStreamFlags) { TBaseProviderData * NewBaseArray = NULL; ULONGLONG RemainderBlock; ULONGLONG BlockCount; ULONGLONG FileSize; TBlockStream * pStream; - TCHAR * szNameBuff; + LPTSTR szNameBuff; size_t nNameLength; DWORD dwBaseFiles = 0; DWORD dwBaseFlags; @@ -2458,7 +2467,7 @@ TFileStream * FileStream_OpenFile( * * \a pStream Pointer to an open stream */ -const TCHAR * FileStream_GetFileName(TFileStream * pStream) +LPCTSTR FileStream_GetFileName(TFileStream * pStream) { assert(pStream != NULL); return pStream->szFileName; @@ -2754,6 +2763,9 @@ void FileStream_Close(TFileStream * pStream) else if(pStream->BaseClose != NULL) pStream->BaseClose(pStream); + // Free the stream lock + CascFreeLock(pStream->Lock); + // Free the stream itself CASC_FREE(pStream); } diff --git a/dep/CascLib/src/common/FileStream.h b/dep/CascLib/src/common/FileStream.h index e934cca062f..acd0683a596 100644 --- a/dep/CascLib/src/common/FileStream.h +++ b/dep/CascLib/src/common/FileStream.h @@ -48,7 +48,7 @@ typedef bool (*STREAM_CREATE)( typedef bool (*STREAM_OPEN)( struct TFileStream * pStream, // Pointer to an unopened stream - const TCHAR * szFileName, // Pointer to file name to be open + LPCTSTR szFileName, // Pointer to file name to be open DWORD dwStreamFlags // Stream flags ); @@ -205,11 +205,12 @@ struct TFileStream STREAM_CLOSE BaseClose; // Pointer to function closing the stream // Base provider data (file size, file position) - TBaseProviderData Base; + TBaseProviderData Base; // Stream information, like size or current position + CASC_LOCK Lock; // For multi-threaded synchronization // Stream provider data TFileStream * pMaster; // Master stream (e.g. MPQ on a web server) - TCHAR * szFileName; // File name (self-relative pointer) + LPTSTR szFileName; // File name (self-relative pointer) ULONGLONG StreamSize; // Stream size (can be less than file size) ULONGLONG StreamPos; // Stream position @@ -249,7 +250,7 @@ struct TEncryptedStream : public TBlockStream TFileStream * FileStream_CreateFile(LPCTSTR szFileName, DWORD dwStreamFlags); TFileStream * FileStream_OpenFile(LPCTSTR szFileName, DWORD dwStreamFlags); -const TCHAR * FileStream_GetFileName(TFileStream * pStream); +LPCTSTR FileStream_GetFileName(TFileStream * pStream); size_t FileStream_Prefix(LPCTSTR szFileName, DWORD * pdwProvider); bool FileStream_SetCallback(TFileStream * pStream, STREAM_DOWNLOAD_CALLBACK pfnCallback, void * pvUserData); diff --git a/dep/CascLib/src/common/FileTree.cpp b/dep/CascLib/src/common/FileTree.cpp index ceb578cf578..6a44940bd8a 100644 --- a/dep/CascLib/src/common/FileTree.cpp +++ b/dep/CascLib/src/common/FileTree.cpp @@ -293,13 +293,7 @@ PCASC_FILE_NODE CASC_FILE_TREE::InsertByName(PCASC_CKEY_ENTRY pCKeyEntry, const assert(szFileName != NULL && szFileName[0] != 0); assert(pCKeyEntry != NULL); - //char szCKey[MD5_STRING_SIZE+1]; - //char szEKey[MD5_STRING_SIZE+1]; - //StringFromBinary(pCKeyEntry->CKey, MD5_HASH_SIZE, szCKey); - //StringFromBinary(pCKeyEntry->EKey, MD5_HASH_SIZE, szEKey); - //printf("%s\t%s\t%s\n", szCKey, szEKey, szFileName); - - //BREAK_ON_XKEY3(pCKeyEntry->EKey, 0x03, 0xDC, 0x7D); + //BREAK_ON_XKEY3(pCKeyEntry->EKey, 0x00, 0x00, 0x0F); // Calculate the file name hash FileNameHash = CalcFileNameHash(szFileName); diff --git a/dep/CascLib/src/common/ListFile.cpp b/dep/CascLib/src/common/ListFile.cpp index bcca8b7177a..a284ef2db10 100644 --- a/dep/CascLib/src/common/ListFile.cpp +++ b/dep/CascLib/src/common/ListFile.cpp @@ -121,7 +121,7 @@ static int ListFile_GetFileDataId(PLISTFILE_CACHE pCache, PDWORD PtrFileDataId) //----------------------------------------------------------------------------- // Functions for parsing an external listfile -void * ListFile_OpenExternal(const TCHAR * szListFile) +void * ListFile_OpenExternal(LPCTSTR szListFile) { PLISTFILE_CACHE pCache = NULL; TFileStream * pStream; diff --git a/dep/CascLib/src/common/ListFile.h b/dep/CascLib/src/common/ListFile.h index 1333b52c2b5..7710b269cef 100644 --- a/dep/CascLib/src/common/ListFile.h +++ b/dep/CascLib/src/common/ListFile.h @@ -14,7 +14,7 @@ //----------------------------------------------------------------------------- // Functions for parsing an external listfile -void * ListFile_OpenExternal(const TCHAR * szListFile); +void * ListFile_OpenExternal(LPCTSTR szListFile); void * ListFile_FromBuffer(LPBYTE pbBuffer, DWORD cbBuffer); bool ListFile_VerifyMD5(void * pvListFile, LPBYTE pbHashMD5); size_t ListFile_GetNextLine(void * pvListFile, const char ** pszLineBegin, const char ** pszLineEnd); diff --git a/dep/CascLib/src/md5/md5.cpp b/dep/CascLib/src/md5/md5.cpp index b6cc49db42b..688269953a0 100644 --- a/dep/CascLib/src/md5/md5.cpp +++ b/dep/CascLib/src/md5/md5.cpp @@ -36,11 +36,11 @@ */ #ifndef HAVE_OPENSSL - + #include <string.h> - + #include "md5.h" - + /* * The basic MD5 functions. * @@ -53,7 +53,7 @@ #define H(x, y, z) (((x) ^ (y)) ^ (z)) #define H2(x, y, z) ((x) ^ ((y) ^ (z))) #define I(x, y, z) ((y) ^ ((x) | ~(z))) - + /* * The MD5 transformation for all four rounds. */ @@ -61,7 +61,7 @@ (a) += f((b), (c), (d)) + (x) + (t); \ (a) = (((a) << (s)) | (((a) & 0xffffffff) >> (32 - (s)))); \ (a) += (b); - + /* * SET reads 4 input bytes in little-endian byte order and stores them in a * properly aligned word in host byte order. @@ -102,20 +102,20 @@ static const void *body(MD5_CTX *ctx, const void *data, unsigned long size) const unsigned char *ptr; MD5_u32plus a, b, c, d; MD5_u32plus saved_a, saved_b, saved_c, saved_d; - + ptr = (const unsigned char *)data; - + a = ctx->a; b = ctx->b; c = ctx->c; d = ctx->d; - + do { saved_a = a; saved_b = b; saved_c = c; saved_d = d; - + /* Round 1 */ STEP(F, a, b, c, d, SET(0), 0xd76aa478, 7) STEP(F, d, a, b, c, SET(1), 0xe8c7b756, 12) @@ -133,7 +133,7 @@ static const void *body(MD5_CTX *ctx, const void *data, unsigned long size) STEP(F, d, a, b, c, SET(13), 0xfd987193, 12) STEP(F, c, d, a, b, SET(14), 0xa679438e, 17) STEP(F, b, c, d, a, SET(15), 0x49b40821, 22) - + /* Round 2 */ STEP(G, a, b, c, d, GET(1), 0xf61e2562, 5) STEP(G, d, a, b, c, GET(6), 0xc040b340, 9) @@ -151,7 +151,7 @@ static const void *body(MD5_CTX *ctx, const void *data, unsigned long size) STEP(G, d, a, b, c, GET(2), 0xfcefa3f8, 9) STEP(G, c, d, a, b, GET(7), 0x676f02d9, 14) STEP(G, b, c, d, a, GET(12), 0x8d2a4c8a, 20) - + /* Round 3 */ STEP(H, a, b, c, d, GET(5), 0xfffa3942, 4) STEP(H2, d, a, b, c, GET(8), 0x8771f681, 11) @@ -169,7 +169,7 @@ static const void *body(MD5_CTX *ctx, const void *data, unsigned long size) STEP(H2, d, a, b, c, GET(12), 0xe6db99e5, 11) STEP(H, c, d, a, b, GET(15), 0x1fa27cf8, 16) STEP(H2, b, c, d, a, GET(2), 0xc4ac5665, 23) - + /* Round 4 */ STEP(I, a, b, c, d, GET(0), 0xf4292244, 6) STEP(I, d, a, b, c, GET(7), 0x432aff97, 10) @@ -187,20 +187,20 @@ static const void *body(MD5_CTX *ctx, const void *data, unsigned long size) STEP(I, d, a, b, c, GET(11), 0xbd3af235, 10) STEP(I, c, d, a, b, GET(2), 0x2ad7d2bb, 15) STEP(I, b, c, d, a, GET(9), 0xeb86d391, 21) - + a += saved_a; b += saved_b; c += saved_c; d += saved_d; - + ptr += 64; } while (size -= 64); - + ctx->a = a; ctx->b = b; ctx->c = c; ctx->d = d; - + return ptr; } @@ -210,81 +210,81 @@ void MD5_Init(MD5_CTX *ctx) ctx->b = 0xefcdab89; ctx->c = 0x98badcfe; ctx->d = 0x10325476; - + ctx->lo = 0; ctx->hi = 0; } - + void MD5_Update(MD5_CTX *ctx, const void *data, unsigned long size) { MD5_u32plus saved_lo; unsigned long used, available; - + saved_lo = ctx->lo; if ((ctx->lo = (saved_lo + size) & 0x1fffffff) < saved_lo) ctx->hi++; ctx->hi += size >> 29; - + used = saved_lo & 0x3f; - + if (used) { available = 64 - used; - + if (size < available) { memcpy(&ctx->buffer[used], data, size); return; } - + memcpy(&ctx->buffer[used], data, available); data = (const unsigned char *)data + available; size -= available; body(ctx, ctx->buffer, 64); } - + if (size >= 64) { data = body(ctx, data, size & ~(unsigned long)0x3f); size &= 0x3f; } - + memcpy(ctx->buffer, data, size); } - -#define OUT(dst, src) \ + +#define PUT_VALUE32(dst, src) \ (dst)[0] = (unsigned char)(src); \ (dst)[1] = (unsigned char)((src) >> 8); \ (dst)[2] = (unsigned char)((src) >> 16); \ (dst)[3] = (unsigned char)((src) >> 24); - + void MD5_Final(unsigned char *result, MD5_CTX *ctx) { unsigned long used, available; - + used = ctx->lo & 0x3f; - + ctx->buffer[used++] = 0x80; - + available = 64 - used; - + if (available < 8) { memset(&ctx->buffer[used], 0, available); body(ctx, ctx->buffer, 64); used = 0; available = 64; } - + memset(&ctx->buffer[used], 0, available - 8); - + ctx->lo <<= 3; - OUT(&ctx->buffer[56], ctx->lo) - OUT(&ctx->buffer[60], ctx->hi) - + PUT_VALUE32(&ctx->buffer[56], ctx->lo) + PUT_VALUE32(&ctx->buffer[60], ctx->hi) + body(ctx, ctx->buffer, 64); - - OUT(&result[0], ctx->a) - OUT(&result[4], ctx->b) - OUT(&result[8], ctx->c) - OUT(&result[12], ctx->d) - + + PUT_VALUE32(&result[0], ctx->a) + PUT_VALUE32(&result[4], ctx->b) + PUT_VALUE32(&result[8], ctx->c) + PUT_VALUE32(&result[12], ctx->d) + memset(ctx, 0, sizeof(*ctx)); } |