⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tnamebreakerdlg1.cpp

📁 mpq文件的格式就是一种压缩格式
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/*****************************************************************************/
/* TNameBreakerDlg1.cpp                   Copyright (c) Ladislav Zezula 2003 */
/*---------------------------------------------------------------------------*/
/* Dialog for brute-force name detecting - User interface part               */
/*---------------------------------------------------------------------------*/
/*   Date    Ver   Who  Comment                                              */
/* --------  ----  ---  -------                                              */
/* 12.04.03  1.00  Lad  The first version of TNameBreakerDlg.cpp             */
/*****************************************************************************/

#include "stdafx.h"
#include <Mmsystem.h>

#include "TNameBreakerDlg.h"
#include "TBreakOptsDlg.h"
#include "THexViewer.h"

#pragma comment(lib, "Winmm.lib")

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

//-----------------------------------------------------------------------------
// TNameBreakerDlg dialog

BEGIN_MESSAGE_MAP(TNameBreakerDlg, CDialog)
	//{{AFX_MSG_MAP(TNameBreakerDlg)
	ON_WM_SIZE()
	ON_WM_CONTEXTMENU()
	ON_NOTIFY(LVN_COLUMNCLICK, IDC_FILELIST, OnColumnClick)
	ON_WM_TIMER()
	ON_BN_CLICKED(IDC_CLOSE, OnCloseClick)
	ON_WM_CLOSE()
    ON_NOTIFY(LVN_DELETEITEM, IDC_FILELIST, OnDeleteItem)
    ON_MESSAGE(WM_LOADARCHIVE, OnLoadArchive)
	ON_NOTIFY(NM_DBLCLK, IDC_FILELIST, OnFileListDblClk)
    ON_MESSAGE(WM_NAMEFOUND, OnNameFound)
    ON_MESSAGE(WM_WORKCOMPLETE, OnWorkComplete)
	ON_BN_CLICKED(IDC_SAVELIST, OnSaveList)
	ON_COMMAND(ID_PREVUNKNOWN, OnPrevUnknown)
	ON_COMMAND(ID_NEXTUNKNOWN, OnNextUnknown)
	ON_COMMAND(ID_HEXVIEW, OnHexView)
    ON_BN_CLICKED(IDC_DETECT, OnDetect)
	ON_COMMAND(ID_DETECT, OnDetect)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()


TNameBreakerDlg::TNameBreakerDlg(CWnd* pParent /*=NULL*/)
	: CDialog(TNameBreakerDlg::IDD, pParent)
{
    memset(&m_dto, NULL, sizeof(TDetectOptions));
    m_dwStartTime = 0;
    m_pHashTable  = NULL;
    m_pFolderList = new CPtrList;
    m_pExtList    = new CPtrList;
    m_hThread     = NULL;
    m_pFont       = NULL;
    m_nDetected   = 0;
    m_dwUnknowns  = 0;
    m_nTimer      = 0;
    m_bMinimized  = FALSE;
    m_nOldShow    = SW_SHOWNORMAL;

    // Initial sorting
    m_uSortColumn = 0;
    m_bAscending  = TRUE;
    m_bInTimer    = FALSE;
}

TNameBreakerDlg::~TNameBreakerDlg()
{
    // Remove list view font
    if(m_pFont != NULL)
    {
        m_pFont->Detach();
        delete m_pFont;
    }

    // Free the folder list and extension list
    FreeStringList(m_pFolderList);
    FreeStringList(m_pExtList);

    // Free the hash table
    if(m_pHashTable != NULL)
    {
        delete m_pHashTable;
        m_pHashTable = NULL;
    }
}

void TNameBreakerDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(TNameBreakerDlg)
	DDX_Control(pDX, IDC_FILELIST, m_FileList);
	//}}AFX_DATA_MAP
}

int TNameBreakerDlg::RunBreaker(const char * szMpqName, const char * szFileList, const char * szDirs, const char * szExts, int nItem)
{
    m_strMpqName  = szMpqName;
    m_strFileList = szFileList;
    if(szDirs != NULL && szExts != NULL)
    {
        m_strDirs = szDirs;
        m_strExts = szExts;
        m_nItem = nItem;
    }
    DoModal();
    return 0;
}

//-----------------------------------------------------------------------------
// Protected functions

TNameInfo * TNameBreakerDlg::CreateDetectInfo(DWORD dwIndex, int dwHashIndex, int dwCodeName1, int dwCodeName2, int lcLocale, int dwSeed, int dwFileSize, const char * szExt, const char * szFileName)
{
    TNameInfo * pInfo = new TNameInfo;

    memset(pInfo, 0, sizeof(TNameInfo));
    pInfo->dwIndex = dwIndex;
    SetDetectInfo(pInfo, dwHashIndex, dwCodeName1, dwCodeName2, lcLocale, dwSeed, dwFileSize, szExt, szFileName);
    return pInfo;
}

BOOL TNameBreakerDlg::SetDetectInfo(TNameInfo * pInfo, int dwHashIndex, int dwCodeName1, int dwCodeName2, int lcLocale, int dwSeed, int dwFileSize, const char * szExt, const char * szFileName)
{
    BOOL bResult = FALSE;

    if(dwHashIndex != -1)
    {
        pInfo->dwHashIndex = (DWORD)dwHashIndex;
        pInfo->dwFlags |= DTI_HASH_INDEX;
    }

    if(dwCodeName1 != -1 && dwCodeName2 != -1)
    {
        pInfo->dwCodeName1 = (DWORD)dwCodeName1;
        pInfo->dwCodeName2 = (DWORD)dwCodeName2;
        pInfo->dwFlags |= DTI_CODENAMES;
    }

    if(lcLocale != -1)
    {
        pInfo->lcLocale = lcLocale;
        pInfo->dwFlags |= DTI_LOCALE;
    }

    if(dwSeed != -1)
    {
        pInfo->dwSeed = dwSeed;
        pInfo->dwFlags |= DTI_SEED;
    }

    if(dwFileSize != -1)
    {
        pInfo->dwFileSize = dwFileSize;
        pInfo->dwFlags |= DTI_FILESIZE;
    }

    if(szExt != NULL)
    {
        strcpy(pInfo->szExt, szExt);
        pInfo->dwFlags |= DTI_EXTENSION;
    }

    if(szFileName != NULL && (pInfo->dwFlags & DTI_FILENAME) == 0)
    {
        strcpy(pInfo->szFullName, szFileName);
        strcpy(pInfo->szExt, GetFileExt(szFileName)); 
        pInfo->szPlainName = GetPlainName(pInfo->szFullName);
        pInfo->dwFlags |= (DTI_EXTENSION | DTI_FILENAME);
        bResult = TRUE;
    }
    return bResult;
}

void TNameBreakerDlg::UpdateItemLabels(int nIndex, TNameInfo * pInfo)
{
    char szUnknown[32] = "";
    char szDeleted[32] = "";
    char szText[32] = "";

    LoadString(AfxGetResourceHandle(), IDS_UNKNOWN, szUnknown, sizeof(szUnknown)-1);
    LoadString(AfxGetResourceHandle(), IDS_DELETED, szDeleted, sizeof(szDeleted)-1);

    sprintf(szText, "%08lX", pInfo->dwHashIndex);
    strcpy(szText, (pInfo->dwHashIndex < 0xFFFFFFFE) ? szText : szDeleted);
    m_FileList.SetItemText(nIndex, 1, (pInfo->dwFlags & DTI_HASH_INDEX) ? szText : szUnknown);

    sprintf(szText, "%08lX", pInfo->dwCodeName1);
    strcpy(szText, (pInfo->dwCodeName1 < 0xFFFFFFFE) ? szText : szDeleted);
    m_FileList.SetItemText(nIndex, 2, (pInfo->dwFlags & DTI_CODENAME1) ? szText : szUnknown);

    sprintf(szText, "%08lX", pInfo->dwCodeName2);
    strcpy(szText, (pInfo->dwCodeName2 < 0xFFFFFFFE) ? szText : szDeleted);
    m_FileList.SetItemText(nIndex, 3, (pInfo->dwFlags & DTI_CODENAME2) ? szText : szUnknown);

    sprintf(szText, "%08lX", pInfo->dwSeed);
    m_FileList.SetItemText(nIndex, 4, (pInfo->dwFlags & DTI_SEED) ? szText : szUnknown);

    sprintf(szText, "%9u", pInfo->dwFileSize);
    m_FileList.SetItemText(nIndex, 5, (pInfo->dwFlags & DTI_FILESIZE) ? szText : szUnknown);

    if(pInfo->dwFlags & DTI_EXTENSION)
        m_FileList.SetItemText(nIndex, 6, pInfo->szExt);

    if(pInfo->dwFlags & DTI_FILENAME) 
        m_FileList.SetItemText(nIndex, 7, pInfo->szFullName);
}

void TNameBreakerDlg::InsertFolderAndExt(const char * szFullName)
{
    POSITION pos;
    char * szNewStr = NULL;
    char szFolder[MAX_PATH];
    char szExt[MAX_PATH];

    // Get the folder and the extension
    strcpy(szFolder, szFullName);
    *GetPlainName(szFolder) = 0;
    strcpy(szExt, GetFileExt(szFullName));

    // Search the folders list.
    szNewStr = NULL;
    pos = m_pFolderList->GetHeadPosition();
    while(pos != NULL)
    {
        szNewStr = (char *)m_pFolderList->GetNext(pos);
        if(!stricmp(szNewStr, szFolder))
            break;
        szNewStr = NULL;
    }

    // If the folder was not found there, create new and insert it
    if(szNewStr == NULL)
    {
        szNewStr = new char[strlen(szFolder) + 1];
        strcpy(szNewStr, szFolder);
        m_pFolderList->AddTail(szNewStr);
    }

    // Now search the extensions
    szNewStr = NULL;
    pos = m_pExtList->GetHeadPosition();
    while(pos != NULL)
    {
        szNewStr = (char *)m_pExtList->GetNext(pos);
        if(!stricmp(szNewStr, szExt))
            break;
        szNewStr = NULL;
    }

    // If the extension was not found there, insert it
    if(szNewStr == NULL)
    {
        szNewStr = new char[strlen(szExt) + 1];
        strcpy(szNewStr, szExt);
        m_pExtList->AddTail(szNewStr);
    }
}

// Finds list view item with specified file index
int TNameBreakerDlg::FindItemByFileIndex(DWORD dwFileIndex)
{
    TNameInfo * pData = NULL;
    int nItems = m_FileList.GetItemCount();

    // Find the item which belongs to that file index
    for(int i = 0; i < nItems; i++)
    {
        pData = (TNameInfo *)m_FileList.GetItemData(i);

        if(pData->dwIndex == dwFileIndex)
            return i;
    }

    // No such name file, do nothing
    return -1;
}

int TNameBreakerDlg::LoadArchive(const char * szMpqName, const char * szFileList)
{
    TMPQBlock * pBlockTable = NULL;
    TMPQHash * pHashTable = NULL;
    TNameInfo * pInfo = NULL;
    TMPQHash * pHash = NULL;
    HANDLE hMpq = NULL;
    HANDLE hFile = NULL;
    char  szFileName[MAX_PATH] = "";
    DWORD dwHashTableSize = 0;
    DWORD dwHashIndex;
    DWORD dwName1;
    DWORD dwName2;
    LCID  lcLocale;
    DWORD dwSeed;
    DWORD dwFileSize;
    DWORD dwFiles = 0;
    DWORD dwFile = 0;
    int nError = ERROR_SUCCESS;

    // Clear the list view
    m_FileList.DeleteAllItems();
    m_dwHashIndexMask = 0;

    // Load the archive
    if(nError == ERROR_SUCCESS)
    {
        if(!SFileOpenArchive(szMpqName, 0, 0, &hMpq))
            nError = GetLastError();
    }

    // Copy the hash table from the archive
    if(nError == ERROR_SUCCESS)
    {                   
        pBlockTable     = (TMPQBlock *)SFileGetFileInfo(hMpq, SFILE_INFO_BLOCK_TABLE);
        pHashTable      = (TMPQHash *)SFileGetFileInfo(hMpq, SFILE_INFO_HASH_TABLE);
        dwHashTableSize = SFileGetFileInfo(hMpq, SFILE_INFO_HASH_TABLE_SIZE);

        if(pHashTable != NULL && dwHashTableSize != 0xFFFFFFFF)
        {
            m_pHashTable = new TMPQHash[dwHashTableSize];
            memcpy(m_pHashTable, pHashTable, sizeof(TMPQHash) * dwHashTableSize);
            m_pHashEnd = m_pHashTable + dwHashTableSize;
        }
    }

    // Load all items from the archive
    if(nError == ERROR_SUCCESS)
    {
        // Disable redrawing
        m_FileList.SetRedraw(FALSE);

        // Fill all items
        m_dwHashIndexMask = SFileGetFileInfo(hMpq, SFILE_INFO_HASH_TABLE_SIZE) - 1;
        m_dwUnknowns = dwFiles = SFileGetFileInfo(hMpq, SFILE_INFO_BLOCK_TABLE_SIZE);

        for(dwFile = 0; dwFile < dwFiles; dwFile++)
        {
            TNameInfo * pInfo = CreateDetectInfo(dwFile, -1, -1, -1, -1, -1, -1, NULL, NULL);
            LVITEM lvitem;
            char szText[16];

            ZeroMemory(&lvitem, sizeof(LV_ITEM));
            sprintf(szText, "%u", dwFile);
            lvitem.mask    = LVIF_TEXT | LVIF_PARAM;
            lvitem.iItem   = (int)dwFile;
            lvitem.pszText = szText;
            lvitem.lParam  = (LPARAM)pInfo;
            m_FileList.InsertItem(&lvitem);

            UpdateItemLabels(dwFile, pInfo);
        }

        // Enable redrawing and redraw
        m_FileList.SetRedraw(TRUE);
        m_FileList.Invalidate(TRUE);
    }

    // Set the deleted ones
    if(nError == ERROR_SUCCESS)
    {
        TMPQBlock * pBlock = (TMPQBlock *)SFileGetFileInfo(hMpq, SFILE_INFO_BLOCK_TABLE);

        for(DWORD i = 0; i < dwFiles; i++)
        {
            if((pBlock[i].dwFlags & MPQ_FILE_EXISTS) == 0)
            {
                pInfo = (TNameInfo *)m_FileList.GetItemData(i);
                
                SetDetectInfo(pInfo, 0xFFFFFFFE, 0xFFFFFFFE, 0xFFFFFFFE, -1, -1, -1, NULL, NULL);
                UpdateItemLabels(i, pInfo);
                m_dwUnknowns--;
            }
        }
    }

    // Load the names from the filelist "regular way"
    if(nError == ERROR_SUCCESS)
    {
        SFILE_FIND_DATA wf;
        HANDLE hFind = SFileFindFirstFile(hMpq, "*", &wf, szFileList);
        BOOL bResult = TRUE;

        while(hFind != NULL && bResult == TRUE)
        {
            SFileSetLocale(wf.lcLocale);
            if(SFileOpenFileEx(hMpq, wf.cFileName, 0, &hFile))
            {
                pHash   = m_pHashTable + SFileGetFileInfo(hFile, SFILE_INFO_HASH_INDEX);
                dwName1 = pHash->dwName1;
                dwName2 = pHash->dwName2;
                dwFileSize = SFileGetFileSize(hFile, NULL);
                dwSeed  = SFileGetFileInfo(hFile, SFILE_INFO_SEED_UNFIXED);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -