| 1914 | } |
| 1915 | |
| 1916 | TFileEntry * AllocateFileEntry(TMPQArchive * ha, const char * szFileName, LCID lcLocale, LPDWORD PtrHashIndex) |
| 1917 | { |
| 1918 | TFileEntry * pFileTableEnd = ha->pFileTable + ha->dwFileTableSize; |
| 1919 | TFileEntry * pFreeEntry = NULL; |
| 1920 | TFileEntry * pFileEntry; |
| 1921 | TMPQHash * pHash = NULL; |
| 1922 | DWORD dwReservedFiles = ha->dwReservedFiles; |
| 1923 | DWORD dwFreeCount = 0; |
| 1924 | |
| 1925 | // Sanity check: File table size must be greater or equal to max file count |
| 1926 | assert(ha->dwFileTableSize >= ha->dwMaxFileCount); |
| 1927 | |
| 1928 | // If we are saving MPQ tables, we don't tale number of reserved files into account |
| 1929 | dwReservedFiles = (ha->dwFlags & MPQ_FLAG_SAVING_TABLES) ? 0 : ha->dwReservedFiles; |
| 1930 | |
| 1931 | // Now find a free entry in the file table. |
| 1932 | // Note that in the case when free entries are in the middle, |
| 1933 | // we need to use these |
| 1934 | for(pFileEntry = ha->pFileTable; pFileEntry < pFileTableEnd; pFileEntry++) |
| 1935 | { |
| 1936 | if((pFileEntry->dwFlags & MPQ_FILE_EXISTS) == 0) |
| 1937 | { |
| 1938 | // Remember the first free entry |
| 1939 | if(pFreeEntry == NULL) |
| 1940 | pFreeEntry = pFileEntry; |
| 1941 | dwFreeCount++; |
| 1942 | |
| 1943 | // If the number of free items is greater than number |
| 1944 | // of reserved items, We can add the file |
| 1945 | if(dwFreeCount > dwReservedFiles) |
| 1946 | break; |
| 1947 | } |
| 1948 | } |
| 1949 | |
| 1950 | // If the total number of free entries is less than number of reserved files, |
| 1951 | // we cannot add the file to the archive |
| 1952 | if(pFreeEntry == NULL || dwFreeCount <= dwReservedFiles) |
| 1953 | return NULL; |
| 1954 | |
| 1955 | // Initialize the file entry and set its file name |
| 1956 | memset(pFreeEntry, 0, sizeof(TFileEntry)); |
| 1957 | AllocateFileName(ha, pFreeEntry, szFileName); |
| 1958 | |
| 1959 | // If the archive has a hash table, we need to first free entry there |
| 1960 | if(ha->pHashTable != NULL) |
| 1961 | { |
| 1962 | // Make sure that the entry is not there yet |
| 1963 | assert(GetHashEntryExact(ha, szFileName, lcLocale) == NULL); |
| 1964 | |
| 1965 | // Find a free hash table entry for the name |
| 1966 | pHash = AllocateHashEntry(ha, pFreeEntry, lcLocale); |
| 1967 | if(pHash == NULL) |
| 1968 | return NULL; |
| 1969 | |
| 1970 | // Set the file index to the hash table |
| 1971 | pHash->dwBlockIndex = (DWORD)(pFreeEntry - ha->pFileTable); |
| 1972 | PtrHashIndex[0] = (DWORD)(pHash - ha->pHashTable); |
| 1973 | } |
nothing calls this directly
no test coverage detected