📄 slistfile.cpp
字号:
for(;;)
{
if(pHash->dwName1 != dwName1 && pHash->dwName2 != dwName2 && pHash->dwBlockIndex < LISTFILE_ENTRY_DELETED)
{
dwName1 = pHash->dwName1;
dwName2 = pHash->dwName2;
pNode = ha->pListFile[pHash - ha->pHashTable];
if((DWORD_PTR)pNode < LISTFILE_ENTRY_DELETED)
{
memcpy(szBuffer, pNode->szFileName, pNode->nLength);
szBuffer[pNode->nLength + 0] = 0x0D;
szBuffer[pNode->nLength + 1] = 0x0A;
WriteFile(hFile, szBuffer, (DWORD)(pNode->nLength + 2), &dwTransferred, NULL);
}
}
if(++pHash >= pHashEnd)
pHash = ha->pHashTable;
if(pHash == pHash0)
break;
}
// Write the listfile name (if not already there)
if(GetHashEntry(ha, LISTFILE_NAME) == NULL)
{
nLength = strlen(LISTFILE_NAME);
memcpy(szBuffer, LISTFILE_NAME, nLength);
szBuffer[nLength + 0] = 0x0D;
szBuffer[nLength + 1] = 0x0A;
WriteFile(hFile, szBuffer, (DWORD)(nLength + 2), &dwTransferred, NULL);
}
// Add the listfile into the archive.
SFileSetLocale(LANG_NEUTRAL);
nError = AddFileToArchive(ha, hFile, LISTFILE_NAME, MPQ_FILE_COMPRESS_PKWARE | MPQ_FILE_ENCRYPTED | MPQ_FILE_REPLACEEXISTING, 0, SFILE_TYPE_DATA, NULL);
}
// Close the temporary file. This will delete it too.
if(hFile != INVALID_HANDLE_VALUE)
CloseHandle(hFile);
lcLocale = lcSave;
return nError;
}
//-----------------------------------------------------------------------------
// File functions
// Adds a listfile into the MPQ archive.
// Note that the function does not remove the
// TODO: Test for archives > 4GB
int WINAPI SFileAddListFile(HANDLE hMpq, const char * szListFile)
{
TListFileCache * pCache = NULL;
TMPQArchive * ha = (TMPQArchive *)hMpq;
HANDLE hListFile = NULL;
char szFileName[MAX_PATH + 1];
DWORD dwSearchScope = SFILE_OPEN_LOCAL_FILE;
DWORD dwCacheSize = 0;
DWORD dwFileSize = 0;
size_t nLength = 0;
int nError = ERROR_SUCCESS;
// If the szListFile is NULL, it means we have to open internal listfile
if(szListFile == NULL)
{
szListFile = LISTFILE_NAME;
dwSearchScope = SFILE_OPEN_FROM_MPQ;
}
// Open the local/internal listfile
if(nError == ERROR_SUCCESS)
{
if(!SFileOpenFileEx((HANDLE)ha, szListFile, dwSearchScope, &hListFile))
nError = GetLastError();
}
if(nError == ERROR_SUCCESS)
{
dwCacheSize =
dwFileSize = SFileGetFileSize(hListFile, NULL);
// Try to allocate memory for the complete file. If it fails,
// load the part of the file
pCache = (TListFileCache *)ALLOCMEM(char, (sizeof(TListFileCache) + dwCacheSize));
if(pCache == NULL)
{
dwCacheSize = LISTFILE_CACHE_SIZE;
pCache = (TListFileCache *)ALLOCMEM(char, sizeof(TListFileCache) + dwCacheSize);
}
if(pCache == NULL)
nError = ERROR_NOT_ENOUGH_MEMORY;
}
if(nError == ERROR_SUCCESS)
{
// Initialize the file cache
memset(pCache, 0, sizeof(TListFileCache));
pCache->hFile = hListFile;
pCache->dwFileSize = dwFileSize;
pCache->dwBuffSize = dwCacheSize;
pCache->dwFilePos = 0;
// Fill the cache
SFileReadFile(hListFile, pCache->Buffer, pCache->dwBuffSize, &pCache->dwBuffSize, NULL);
// Initialize the pointers
pCache->pBegin =
pCache->pPos = &pCache->Buffer[0];
pCache->pEnd = pCache->pBegin + pCache->dwBuffSize;
// Load the node tree
while((nLength = ReadLine(pCache, szFileName, sizeof(szFileName) - 1)) > 0)
SListFileAddNode(ha, szFileName);
// Add well-known names
// Sometimes, they are not in listfile, but they exist in the archive
SListFileAddNode(ha, LISTFILE_NAME);
SListFileAddNode(ha, SIGNATURE_NAME);
SListFileAddNode(ha, ATTRIBUTES_NAME);
}
// Cleanup & exit
if(pCache != NULL)
SListFileFindClose((HANDLE)pCache);
return nError;
}
//-----------------------------------------------------------------------------
// Passing through the listfile
// TODO: Test for archives > 4GB
HANDLE SListFileFindFirstFile(HANDLE hMpq, const char * szListFile, const char * szMask, SFILE_FIND_DATA * lpFindFileData)
{
TListFileCache * pCache = NULL;
TMPQArchive * ha = (TMPQArchive *)hMpq;
HANDLE hListFile = NULL;
DWORD dwSearchScope = SFILE_OPEN_LOCAL_FILE;
DWORD dwCacheSize = 0;
DWORD dwFileSize = 0;
size_t nLength = 0;
int nError = ERROR_SUCCESS;
// Initialize the structure with zeros
memset(lpFindFileData, 0, sizeof(SFILE_FIND_DATA));
// If the szListFile is NULL, it means we have to open internal listfile
if(szListFile == NULL)
{
szListFile = LISTFILE_NAME;
dwSearchScope = SFILE_OPEN_FROM_MPQ;
}
// Open the local/internal listfile
if(nError == ERROR_SUCCESS)
{
if(!SFileOpenFileEx((HANDLE)ha, szListFile, dwSearchScope, &hListFile))
nError = GetLastError();
}
if(nError == ERROR_SUCCESS)
{
dwCacheSize =
dwFileSize = SFileGetFileSize(hListFile, NULL);
// Try to allocate memory for the complete file. If it fails,
// load the part of the file
pCache = (TListFileCache *)ALLOCMEM(char, sizeof(TListFileCache) + dwCacheSize);
if(pCache == NULL)
{
dwCacheSize = LISTFILE_CACHE_SIZE;
pCache = (TListFileCache *)ALLOCMEM(char, sizeof(TListFileCache) + dwCacheSize);
}
if(pCache == NULL)
nError = ERROR_NOT_ENOUGH_MEMORY;
}
if(nError == ERROR_SUCCESS)
{
// Initialize the file cache
memset(pCache, 0, sizeof(TListFileCache));
pCache->hFile = hListFile;
pCache->dwFileSize = dwFileSize;
pCache->dwBuffSize = dwCacheSize;
pCache->dwFilePos = 0;
if(szMask != NULL)
{
pCache->szMask = ALLOCMEM(char, strlen(szMask) + 1);
strcpy(pCache->szMask, szMask);
}
// Fill the cache
SFileReadFile(hListFile, pCache->Buffer, pCache->dwBuffSize, &pCache->dwBuffSize, NULL);
// Initialize the pointers
pCache->pBegin =
pCache->pPos = &pCache->Buffer[0];
pCache->pEnd = pCache->pBegin + pCache->dwBuffSize;
for(;;)
{
// Read the (next) line
nLength = ReadLine(pCache, lpFindFileData->cFileName, sizeof(lpFindFileData->cFileName));
if(nLength == 0)
{
nError = ERROR_NO_MORE_FILES;
break;
}
// If some mask entered, check it
if(CheckWildCard(lpFindFileData->cFileName, pCache->szMask))
break;
}
}
// Cleanup & exit
if(nError != ERROR_SUCCESS)
{
memset(lpFindFileData, 0, sizeof(SFILE_FIND_DATA));
SListFileFindClose((HANDLE)pCache);
pCache = NULL;
SetLastError(nError);
}
return (HANDLE)pCache;
}
// TODO: Test for archives > 4GB
BOOL SListFileFindNextFile(HANDLE hFind, SFILE_FIND_DATA * lpFindFileData)
{
TListFileCache * pCache = (TListFileCache *)hFind;
size_t nLength;
BOOL bResult = FALSE;
int nError = ERROR_SUCCESS;
for(;;)
{
// Read the (next) line
nLength = ReadLine(pCache, lpFindFileData->cFileName, sizeof(lpFindFileData->cFileName));
if(nLength == 0)
{
nError = ERROR_NO_MORE_FILES;
break;
}
// If some mask entered, check it
if(CheckWildCard(lpFindFileData->cFileName, pCache->szMask))
{
bResult = TRUE;
break;
}
}
if(nError != ERROR_SUCCESS)
SetLastError(nError);
return bResult;
}
// TODO: Test for archives > 4GB
BOOL SListFileFindClose(HANDLE hFind)
{
TListFileCache * pCache = (TListFileCache *)hFind;
if(pCache != NULL)
{
if(pCache->hFile != NULL)
SFileCloseFile(pCache->hFile);
if(pCache->szMask != NULL)
FREEMEM(pCache->szMask);
FREEMEM(pCache);
return TRUE;
}
return FALSE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -