| 2025 | } |
| 2026 | |
| 2027 | static bool MpqeStream_DetectFileKey(TEncryptedStream * pStream) |
| 2028 | { |
| 2029 | ULONGLONG ByteOffset = 0; |
| 2030 | BYTE EncryptedHeader[MPQE_CHUNK_SIZE]; |
| 2031 | BYTE FileHeader[MPQE_CHUNK_SIZE]; |
| 2032 | |
| 2033 | // Read the first file chunk |
| 2034 | if(pStream->BaseRead(pStream, &ByteOffset, EncryptedHeader, sizeof(EncryptedHeader))) |
| 2035 | { |
| 2036 | // We just try all known keys one by one |
| 2037 | for(int i = 0; AuthCodeArray[i] != NULL; i++) |
| 2038 | { |
| 2039 | // Prepare they decryption key from game serial number |
| 2040 | CreateKeyFromAuthCode(pStream->Key, AuthCodeArray[i]); |
| 2041 | |
| 2042 | // Try to decrypt with the given key |
| 2043 | memcpy(FileHeader, EncryptedHeader, MPQE_CHUNK_SIZE); |
| 2044 | DecryptFileChunk((LPDWORD)FileHeader, pStream->Key, ByteOffset, MPQE_CHUNK_SIZE); |
| 2045 | |
| 2046 | // We check the decrypted data |
| 2047 | // All known encrypted MPQs have header at the begin of the file, |
| 2048 | // so we check for MPQ signature there. |
| 2049 | if(FileHeader[0] == 'M' && FileHeader[1] == 'P' && FileHeader[2] == 'Q') |
| 2050 | { |
| 2051 | // Update the stream size |
| 2052 | pStream->StreamSize = pStream->Base.File.FileSize; |
| 2053 | |
| 2054 | // Fill the block information |
| 2055 | pStream->BlockSize = MPQE_CHUNK_SIZE; |
| 2056 | pStream->BlockCount = (DWORD)(pStream->Base.File.FileSize + MPQE_CHUNK_SIZE - 1) / MPQE_CHUNK_SIZE; |
| 2057 | pStream->IsComplete = 1; |
| 2058 | return true; |
| 2059 | } |
| 2060 | } |
| 2061 | } |
| 2062 | |
| 2063 | // Key not found, sorry |
| 2064 | return false; |
| 2065 | } |
| 2066 | |
| 2067 | static bool MpqeStream_BlockRead( |
| 2068 | TEncryptedStream * pStream, |
no test coverage detected