| 886 | // Adds a file to the archive |
| 887 | |
| 888 | bool WINAPI SFileAddFileEx( |
| 889 | HANDLE hMpq, |
| 890 | const TCHAR * szFileName, |
| 891 | const char * szArchivedName, |
| 892 | DWORD dwFlags, |
| 893 | DWORD dwCompression, // Compression of the first sector |
| 894 | DWORD dwCompressionNext) // Compression of next sectors |
| 895 | { |
| 896 | ULONGLONG FileSize = 0; |
| 897 | ULONGLONG FileTime = 0; |
| 898 | TFileStream * pStream = NULL; |
| 899 | HANDLE hMpqFile = NULL; |
| 900 | LPBYTE pbFileData = NULL; |
| 901 | DWORD dwBytesRemaining = 0; |
| 902 | DWORD dwBytesToRead; |
| 903 | DWORD dwSectorSize = 0x1000; |
| 904 | DWORD dwChannels = 0; |
| 905 | bool bIsAdpcmCompression = false; |
| 906 | bool bIsFirstSector = true; |
| 907 | DWORD dwErrCode = ERROR_SUCCESS; |
| 908 | |
| 909 | // Check parameters |
| 910 | if(hMpq == NULL || szFileName == NULL || *szFileName == 0) |
| 911 | { |
| 912 | SetLastError(ERROR_INVALID_PARAMETER); |
| 913 | return false; |
| 914 | } |
| 915 | |
| 916 | // Open added file |
| 917 | pStream = FileStream_OpenFile(szFileName, STREAM_FLAG_READ_ONLY | STREAM_PROVIDER_FLAT | BASE_PROVIDER_FILE); |
| 918 | if(pStream == NULL) |
| 919 | return false; |
| 920 | |
| 921 | // Files bigger than 4GB cannot be added to MPQ |
| 922 | FileStream_GetTime(pStream, &FileTime); |
| 923 | FileStream_GetSize(pStream, &FileSize); |
| 924 | if(FileSize >> 32) |
| 925 | dwErrCode = ERROR_DISK_FULL; |
| 926 | |
| 927 | // Allocate data buffer for reading from the source file |
| 928 | if(dwErrCode == ERROR_SUCCESS) |
| 929 | { |
| 930 | dwBytesRemaining = (DWORD)FileSize; |
| 931 | pbFileData = STORM_ALLOC(BYTE, dwSectorSize); |
| 932 | if(pbFileData == NULL) |
| 933 | dwErrCode = ERROR_NOT_ENOUGH_MEMORY; |
| 934 | } |
| 935 | |
| 936 | // Deal with various combination of compressions |
| 937 | if(dwErrCode == ERROR_SUCCESS) |
| 938 | { |
| 939 | // When the compression for next blocks is set to default, |
| 940 | // we will copy the compression for the first sector |
| 941 | if(dwCompressionNext == MPQ_COMPRESSION_NEXT_SAME) |
| 942 | dwCompressionNext = dwCompression; |
| 943 | |
| 944 | // If the caller wants ADPCM compression, we make sure |
| 945 | // that the first sector is not compressed with lossy compression |