mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-15 23:20:36 +01:00
Dep/CascLib: Update to ladislav-zezula/CascLib@0a05c59eb8
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
#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, "CascLibDAS.lib") // Debug 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, "CascLibDUD.lib") // Debug 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, "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
|
||||
#else
|
||||
#pragma comment(lib, "CascLibRAS.lib") // Release Ansi CRT-LIB version
|
||||
#endif
|
||||
#else
|
||||
#ifdef _DLL
|
||||
#pragma comment(lib, "CascLibRUD.lib") // Release Unicode CRT-DLL version
|
||||
#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;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,24 +324,50 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// 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
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -165,6 +165,14 @@ void CASC_FREE(T *& ptr)
|
||||
ptr = NULL;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// 32-bit ROL
|
||||
|
||||
inline DWORD Rol32(DWORD dwValue, DWORD dwRolCount)
|
||||
{
|
||||
return (dwValue << dwRolCount) | (dwValue >> (32 - dwRolCount));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Big endian number manipulation
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
ULONGLONG ByteOffset = (pByteOffset != NULL) ? *pByteOffset : pStream->Base.File.FilePos;
|
||||
|
||||
// Update the byte offset
|
||||
pStream->Base.File.FilePos = ByteOffset;
|
||||
|
||||
// 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)
|
||||
{
|
||||
SetLastError(errno);
|
||||
return false;
|
||||
}
|
||||
pStream->Base.File.FilePos = ByteOffset;
|
||||
}
|
||||
ssize_t bytes_read;
|
||||
|
||||
// Perform the read operation
|
||||
if(dwBytesToRead != 0)
|
||||
{
|
||||
bytes_read = read((intptr_t)pStream->Base.File.hFile, pvBuffer, (size_t)dwBytesToRead);
|
||||
if(bytes_read == -1)
|
||||
// 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;
|
||||
}
|
||||
|
||||
dwBytesRead = (DWORD)(size_t)bytes_read;
|
||||
// Perform the read operation
|
||||
if (dwBytesToRead != 0)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
#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
|
||||
ULONGLONG ByteOffset = (pByteOffset != NULL) ? *pByteOffset : pStream->Base.File.FilePos;
|
||||
|
||||
// Update the byte offset
|
||||
pStream->Base.File.FilePos = ByteOffset;
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
|
||||
@@ -62,7 +62,7 @@ recastnavigation (Recast is state of the art navigation mesh construction toolse
|
||||
|
||||
CascLib (An open-source implementation of library for reading CASC storage from Blizzard games since 2014)
|
||||
https://github.com/ladislav-zezula/CascLib
|
||||
Version: b91f87c770c78340dcd96df970e55b5c0469e884
|
||||
Version: 0a05c59eb8a3eab1bc5471f43934cd5f992f0aca
|
||||
|
||||
rapidjson (A fast JSON parser/generator for C++ with both SAX/DOM style API http://rapidjson.org/)
|
||||
https://github.com/miloyip/rapidjson
|
||||
|
||||
@@ -1425,7 +1425,7 @@ uint32 GetInstalledLocalesMask()
|
||||
try
|
||||
{
|
||||
boost::filesystem::path const storage_dir(boost::filesystem::canonical(input_path) / "Data");
|
||||
CASC::StorageHandle storage = CASC::OpenStorage(storage_dir, 0, CONF_Product);
|
||||
CASC::StorageHandle storage = CASC::OpenStorage(storage_dir, CASC_LOCALE_ALL_WOW, CONF_Product);
|
||||
if (!storage)
|
||||
return false;
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ u_map_fcc MverMagic = { { 'R','E','V','M' } };
|
||||
|
||||
ChunkedFile::ChunkedFile()
|
||||
{
|
||||
data = 0;
|
||||
data = nullptr;
|
||||
data_size = 0;
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ ChunkedFile::~ChunkedFile()
|
||||
bool ChunkedFile::loadFile(CASC::StorageHandle const& mpq, std::string const& fileName, bool log)
|
||||
{
|
||||
free();
|
||||
CASC::FileHandle file = CASC::OpenFile(mpq, fileName.c_str(), CASC_LOCALE_ALL, log);
|
||||
CASC::FileHandle file = CASC::OpenFile(mpq, fileName.c_str(), CASC_LOCALE_ALL_WOW, log);
|
||||
if (!file)
|
||||
return false;
|
||||
|
||||
@@ -63,7 +63,7 @@ bool ChunkedFile::loadFile(CASC::StorageHandle const& mpq, std::string const& fi
|
||||
bool ChunkedFile::loadFile(CASC::StorageHandle const& mpq, uint32 fileDataId, std::string const& description, bool log)
|
||||
{
|
||||
free();
|
||||
CASC::FileHandle file = CASC::OpenFile(mpq, fileDataId, CASC_LOCALE_ALL, log);
|
||||
CASC::FileHandle file = CASC::OpenFile(mpq, fileDataId, CASC_LOCALE_ALL_WOW, log);
|
||||
if (!file)
|
||||
return false;
|
||||
|
||||
@@ -104,13 +104,13 @@ bool ChunkedFile::prepareLoadedData()
|
||||
|
||||
void ChunkedFile::free()
|
||||
{
|
||||
for (auto chunk : chunks)
|
||||
for (auto& chunk : chunks)
|
||||
delete chunk.second;
|
||||
|
||||
chunks.clear();
|
||||
|
||||
delete[] data;
|
||||
data = 0;
|
||||
data = nullptr;
|
||||
data_size = 0;
|
||||
}
|
||||
|
||||
@@ -171,12 +171,12 @@ FileChunk* ChunkedFile::GetChunk(std::string const& name)
|
||||
if (std::distance(range.first, range.second) == 1)
|
||||
return range.first->second;
|
||||
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
FileChunk::~FileChunk()
|
||||
{
|
||||
for (auto subchunk : subchunks)
|
||||
for (auto& subchunk : subchunks)
|
||||
delete subchunk.second;
|
||||
|
||||
subchunks.clear();
|
||||
@@ -215,5 +215,5 @@ FileChunk* FileChunk::GetSubChunk(std::string const& name)
|
||||
if (std::distance(range.first, range.second) == 1)
|
||||
return range.first->second;
|
||||
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ CASCFile::CASCFile(CASC::StorageHandle const& casc, const char* filename, bool w
|
||||
pointer(0),
|
||||
size(0)
|
||||
{
|
||||
CASC::FileHandle file = CASC::OpenFile(casc, filename, CASC_LOCALE_ALL, false);
|
||||
CASC::FileHandle file = CASC::OpenFile(casc, filename, CASC_LOCALE_ALL_WOW, false);
|
||||
if (!file)
|
||||
{
|
||||
if (warnNoExist || GetLastError() != ERROR_FILE_NOT_FOUND)
|
||||
@@ -43,7 +43,7 @@ CASCFile::CASCFile(CASC::StorageHandle const& casc, uint32 fileDataId, std::stri
|
||||
pointer(0),
|
||||
size(0)
|
||||
{
|
||||
CASC::FileHandle file = CASC::OpenFile(casc, fileDataId, CASC_LOCALE_ALL, false);
|
||||
CASC::FileHandle file = CASC::OpenFile(casc, fileDataId, CASC_LOCALE_ALL_WOW, false);
|
||||
if (!file)
|
||||
{
|
||||
if (warnNoExist || GetLastError() != ERROR_FILE_NOT_FOUND)
|
||||
|
||||
@@ -72,7 +72,7 @@ enum ModelTypes : uint32
|
||||
bool GetHeaderMagic(std::string const& fileName, uint32* magic)
|
||||
{
|
||||
*magic = 0;
|
||||
CASC::FileHandle file = CASC::OpenFile(CascStorage, fileName.c_str(), CASC_LOCALE_ALL);
|
||||
CASC::FileHandle file = CASC::OpenFile(CascStorage, fileName.c_str(), CASC_LOCALE_ALL_WOW);
|
||||
if (!file)
|
||||
return false;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user