// ChecksumDlg.cpp : implementation file
//

#include "stdafx.h"
#include "Checksum.h"
#include "ChecksumDlg.h"
#include "Crc32Static.h"

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

/////////////////////////////////////////////////////////////////////////////
// CChecksumDlg dialog

CChecksumDlg::CChecksumDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CChecksumDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CChecksumDlg)
		// NOTE: the ClassWizard will add member initialization here
	//}}AFX_DATA_INIT
	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CChecksumDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CChecksumDlg)
		// NOTE: the ClassWizard will add DDX and DDV calls here
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CChecksumDlg, CDialog)
	//{{AFX_MSG_MAP(CChecksumDlg)
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CChecksumDlg message handlers

BOOL CChecksumDlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	// Set the icon for this dialog.  The framework does this automatically
	//  when the application's main window is not a dialog
	SetIcon(m_hIcon, TRUE);			// Set big icon
	SetIcon(m_hIcon, FALSE);		// Set small icon
	
	SetCheckSum("Software\\ROW\\MP-Client", "Folder", false, IDC_FOLDER, IDC_CHECKSUM, IDC_VERSION);
	SetCheckSum("Software\\ROW\\MP-Client", "TestFolder", false, IDC_FOLDER2, IDC_CHECKSUM2, IDC_VERSION2);
	SetCheckSum("Software\\ROW\\MP-Client", "BGFolder", true, IDC_FOLDER3, IDC_CHECKSUM3, IDC_VERSION3);

#ifdef _RYL_LANGUAGE
	SetWindowText("Checksum Ver. 0.80 (ROW)");
#else
	SetWindowText("Checksum Ver. 0.80 (ROW_MY)");
#endif

	return TRUE;  // return TRUE  unless you set the focus to a control
}

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CChecksumDlg::OnPaint() 
{
	if (IsIconic())
	{
		CPaintDC dc(this); // device context for painting

		SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

		// Center icon in client rectangle
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// Draw the icon
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialog::OnPaint();
	}
}

// The system calls this to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CChecksumDlg::OnQueryDragIcon()
{
	return (HCURSOR) m_hIcon;
}

unsigned long  CChecksumDlg::CheckOCTREE()
{
	unsigned long dwCrc = 0, dwTemp = 0;
    HANDLE              hSrch;
    WIN32_FIND_DATA     wfd;
    BOOL                bResult = TRUE;

	char strScriptPath[MAX_PATH];
	sprintf(strScriptPath, "%s\\OCTREE\\*.OCT", m_strClientPath);

	hSrch = FindFirstFile(strScriptPath, &wfd);

	int iCount = 0;

    while (bResult)
    {
        if(wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
        {
			;
        }
        else
        {
			sprintf(strScriptPath, "%s\\OCTREE\\%s", m_strClientPath, wfd.cFileName);

			dwTemp = 0;
			if(CCrc32Static::FileCrc32Assembly(strScriptPath, dwTemp) != NO_ERROR)
			{
				;
			}
			dwCrc = dwCrc ^ dwTemp;
			iCount++;
        }

        bResult = FindNextFile(hSrch, &wfd);
    }
    FindClose(hSrch);

	return dwCrc;
}

bool CChecksumDlg::SetCheckSum(const char* szRegKey, const char* szRegValue, bool bBattleServer, 
							   unsigned long dwViewPathID, unsigned long dwViewCheckSumID, unsigned long dwViewVersionID)
{
	HKEY hMPClientReg;
	unsigned long dwReadType = 0, dwReadLens = 256;
	unsigned long dwReadType1 = 0, dwReadLens1 = 256;
	unsigned long dwReadType2 = 0, dwReadLens2 = 256;
	char strScriptPath[MAX_PATH];
	unsigned long dwCrc[20], dwVer, dwTemp;
	unsigned long m_dwVersion;
	CWnd *lpWnd;
	char strCheckSum[20];
	char szErrMsg[MAX_PATH];

	ZeroMemory(dwCrc, sizeof(unsigned long)*20);

	if ( RegOpenKeyEx(HKEY_LOCAL_MACHINE, szRegKey, 0, KEY_READ, &hMPClientReg) == ERROR_SUCCESS &&
		RegQueryValueEx(hMPClientReg, szRegValue, 0, &dwReadType2, (LPBYTE)m_strClientPath, &dwReadLens2) == ERROR_SUCCESS )
	{
		sprintf(strScriptPath, "%s\\Client.exe", m_strClientPath);
		if (CCrc32Static::FileCrc32Assembly(strScriptPath, dwCrc[0]) != NO_ERROR)
		{
			MessageBox("Client.exe가 없습니다.", "Checksum 확인", MB_OK);
			return false;
		}

		// 옥트리 체크섬 검사
		dwTemp = CheckOCTREE();
		dwCrc[0] = dwCrc[0] ^ dwTemp;

#ifdef _RYL_LANGUAGE
		// 랭귀지 설정
		int iMaxLanguage = 7;
		TCHAR szLanguage[7][32] = { _T("ENG"), _T("CHS"), _T("JPN"), _T("KOR"), _T("PRT"), _T("SPN"), _T("POL") };

		//////////////////////////////////////////////////////////////////////////////
		// MUI
		for(int i = 0; i < iMaxLanguage; ++i)
		{
			sprintf(strScriptPath, "%s\\Language\\%s\\NPCScript.mcf", m_strClientPath, szLanguage[i]);
			if (CCrc32Static::FileCrc32Assembly(strScriptPath, dwTemp) != NO_ERROR)
			{
				sprintf(szErrMsg, "%s가 없습니다.", strScriptPath);
				MessageBox(szErrMsg, "Checksum 확인", MB_OK);
				return false;
			}
			dwCrc[1] = dwCrc[1]^dwTemp;

			if (true == bBattleServer)
			{
				sprintf(strScriptPath, "%s\\Language\\%s\\BGItemScript.gsf", m_strClientPath, szLanguage[i]);
			}
			else
			{
				sprintf(strScriptPath, "%s\\Language\\%s\\ItemScript.gsf", m_strClientPath, szLanguage[i]);
			}

			if (CCrc32Static::FileCrc32Assembly(strScriptPath, dwTemp) != NO_ERROR)
			{
				sprintf(szErrMsg, "%s가 없습니다.", strScriptPath);
				MessageBox(szErrMsg, "Checksum 확인", MB_OK);
				return false;
			}
			dwCrc[2] = dwCrc[2]^dwTemp;

			sprintf(strScriptPath, "%s\\Language\\%s\\SkillScript.gsf", m_strClientPath, szLanguage[i]);
			if (CCrc32Static::FileCrc32Assembly(strScriptPath, dwTemp) != NO_ERROR)
			{
				sprintf(szErrMsg, "%s가 없습니다.", strScriptPath);
				MessageBox(szErrMsg, "Checksum 확인", MB_OK);
				return false;
			}
			dwCrc[3] = dwCrc[3]^dwTemp;

			sprintf(strScriptPath, "%s\\Language\\%s\\MonsterProtoType.gsf", m_strClientPath, szLanguage[i]);
			if (CCrc32Static::FileCrc32Assembly(strScriptPath, dwTemp) != NO_ERROR)
			{
				sprintf(szErrMsg, "%s가 없습니다.", strScriptPath);
				MessageBox(szErrMsg, "Checksum 확인", MB_OK);
				return false;
			}
			dwCrc[4] = dwCrc[4]^dwTemp;

			sprintf(strScriptPath, "%s\\Language\\%s\\Quest.mcf", m_strClientPath, szLanguage[i]);
			if (CCrc32Static::FileCrc32Assembly(strScriptPath, dwTemp) != NO_ERROR)
			{
				sprintf(szErrMsg, "%s가 없습니다.", strScriptPath);
				MessageBox(szErrMsg, "Checksum 확인", MB_OK);
				return false;
			}
			dwCrc[5] = dwCrc[5]^dwTemp;

		}
		//////////////////////////////////////////////////////////////////////////////
#else
		sprintf(strScriptPath, "%s\\NPCScript.mcf", m_strClientPath);
		if (CCrc32Static::FileCrc32Assembly(strScriptPath, dwCrc[1]) != NO_ERROR)
		{
			sprintf(szErrMsg, "%s가 없습니다.", strScriptPath);
			MessageBox(szErrMsg, "Checksum 확인", MB_OK);
			return false;
		}

		if (true == bBattleServer)
		{
			sprintf(strScriptPath, "%s\\BGItemScript.gsf", m_strClientPath);
		}
		else
		{
			sprintf(strScriptPath, "%s\\ItemScript.gsf", m_strClientPath);
		}

		if (CCrc32Static::FileCrc32Assembly(strScriptPath, dwCrc[2]) != NO_ERROR)
		{
			sprintf(szErrMsg, "%s가 없습니다.", strScriptPath);
			MessageBox(szErrMsg, "Checksum 확인", MB_OK);
			return false;
		}

		sprintf(strScriptPath, "%s\\SkillScript.gsf", m_strClientPath);
		if (CCrc32Static::FileCrc32Assembly(strScriptPath, dwCrc[3]) != NO_ERROR)
		{
			sprintf(szErrMsg, "%s가 없습니다.", strScriptPath);
			MessageBox(szErrMsg, "Checksum 확인", MB_OK);
			return false;
		}

		sprintf(strScriptPath, "%s\\MonsterProtoType.gsf", m_strClientPath);
		if (CCrc32Static::FileCrc32Assembly(strScriptPath, dwCrc[4]) != NO_ERROR)
		{
			sprintf(szErrMsg, "%s가 없습니다.", strScriptPath);
			MessageBox(szErrMsg, "Checksum 확인", MB_OK);
			return false;
		}

		sprintf(strScriptPath, "%s\\Quest.mcf", m_strClientPath);
		if (CCrc32Static::FileCrc32Assembly(strScriptPath, dwCrc[5]) != NO_ERROR)
		{
			sprintf(szErrMsg, "%s가 없습니다.", strScriptPath);
			MessageBox(szErrMsg, "Checksum 확인", MB_OK);
			return false;
		}
#endif
		sprintf(strScriptPath, "%s\\Script1.gsf", m_strClientPath);
		if (CCrc32Static::FileCrc32Assembly(strScriptPath, dwCrc[6]) != NO_ERROR)
		{
			sprintf(szErrMsg, "%s가 없습니다.", strScriptPath);
			MessageBox(szErrMsg, "Checksum 확인", MB_OK);
			return false;
		}

		sprintf(strScriptPath, "%s\\Character\\Data\\ChrEvent.eds", m_strClientPath);
		if (CCrc32Static::FileCrc32Assembly(strScriptPath, dwCrc[7]) != NO_ERROR)
		{
			sprintf(szErrMsg, "%s가 없습니다.", strScriptPath);
			MessageBox(szErrMsg, "Checksum 확인", MB_OK);
			return false;
		}

		sprintf(strScriptPath, "%s\\Chemical.gsf", m_strClientPath);
		if (CCrc32Static::FileCrc32Assembly(strScriptPath, dwCrc[8]) != NO_ERROR)
		{
			sprintf(szErrMsg, "%s가 없습니다.", strScriptPath);
			MessageBox(szErrMsg, "Checksum 확인", MB_OK);
			return false;
		}

		sprintf(strScriptPath, "%s\\SpeacialCompensation.gsf", m_strClientPath);
		if (CCrc32Static::FileCrc32Assembly(strScriptPath, dwCrc[9]) != NO_ERROR)
		{
			sprintf(szErrMsg, "%s가 없습니다.", strScriptPath);
			MessageBox(szErrMsg, "Checksum 확인", MB_OK);
			return false;
		}

		sprintf(strScriptPath, "%s\\zone1.z3s", m_strClientPath);
		if (CCrc32Static::FileCrc32Assembly(strScriptPath, dwTemp) != NO_ERROR)
		{
			sprintf(szErrMsg, "%s가 없습니다.", strScriptPath);
			MessageBox(szErrMsg, "Checksum 확인", MB_OK);
			return false;
		}
		dwCrc[10] = dwCrc[10]^dwTemp;

		sprintf(strScriptPath, "%s\\zone2.z3s", m_strClientPath);
		if (CCrc32Static::FileCrc32Assembly(strScriptPath, dwTemp) != NO_ERROR)
		{
			sprintf(szErrMsg, "%s가 없습니다.", strScriptPath);
			MessageBox(szErrMsg, "Checksum 확인", MB_OK);
			return false;
		}
		dwCrc[10] = dwCrc[10]^dwTemp;

		sprintf(strScriptPath, "%s\\zone4.z3s", m_strClientPath);
		if (CCrc32Static::FileCrc32Assembly(strScriptPath, dwTemp) != NO_ERROR)
		{
			sprintf(szErrMsg, "%s가 없습니다.", strScriptPath);
			MessageBox(szErrMsg, "Checksum 확인", MB_OK);
			return false;
		}
		dwCrc[10] = dwCrc[10]^dwTemp;

		sprintf(strScriptPath, "%s\\zone5.z3s", m_strClientPath);
		if (CCrc32Static::FileCrc32Assembly(strScriptPath, dwTemp) != NO_ERROR)
		{
			sprintf(szErrMsg, "%s가 없습니다.", strScriptPath);
			MessageBox(szErrMsg, "Checksum 확인", MB_OK);
			return false;
		}
		dwCrc[10] = dwCrc[10]^dwTemp;

		sprintf(strScriptPath, "%s\\zone8.z3s", m_strClientPath);
		if (CCrc32Static::FileCrc32Assembly(strScriptPath, dwTemp) != NO_ERROR)
		{
			sprintf(szErrMsg, "%s가 없습니다.", strScriptPath);
			MessageBox(szErrMsg, "Checksum 확인", MB_OK);
			return false;
		}
		dwCrc[10] = dwCrc[10]^dwTemp;

		sprintf(strScriptPath, "%s\\zone12.z3s", m_strClientPath);
		if (CCrc32Static::FileCrc32Assembly(strScriptPath, dwTemp) != NO_ERROR)
		{
			sprintf(szErrMsg, "%s가 없습니다.", strScriptPath);
			MessageBox(szErrMsg, "Checksum 확인", MB_OK);
			return false;
		}
		dwCrc[10] = dwCrc[10]^dwTemp;

		sprintf(strScriptPath, "%s\\zone16.z3s", m_strClientPath);
		if (CCrc32Static::FileCrc32Assembly(strScriptPath, dwTemp) != NO_ERROR)
		{
			sprintf(szErrMsg, "%s가 없습니다.", strScriptPath);
			MessageBox(szErrMsg, "Checksum 확인", MB_OK);
			return false;
		}
		dwCrc[10] = dwCrc[10]^dwTemp;
/*
		sprintf(strScriptPath, "%s\\GameGuard.des", m_strClientPath);
		if (CCrc32Static::FileCrc32Assembly(strScriptPath, dwCrc[11]) != NO_ERROR)
		{
			sprintf(szErrMsg, "%s가 없습니다.", strScriptPath);
			MessageBox(szErrMsg, "Checksum 확인", MB_OK);
			return false;
		}
*/
		sprintf(strScriptPath, "%s\\MineralVein8.gsf", m_strClientPath);
		if (CCrc32Static::FileCrc32Assembly(strScriptPath, dwCrc[11]) != NO_ERROR)
		{
			sprintf(szErrMsg, "%s가 없습니다.", strScriptPath);
			MessageBox(szErrMsg, "Checksum 확인", MB_OK);
			return false;
		}

/*

		sprintf(strScriptPath, "%s\\MineralVein16.gsf", m_strClientPath);
		if (CCrc32Static::FileCrc32Assembly(strScriptPath, dwCrc[12]) != NO_ERROR)
		{
			sprintf(szErrMsg, "%s가 없습니다.", strScriptPath);
			MessageBox(szErrMsg, "Checksum 확인", MB_OK);
			return false;
		}
*/
		m_dwVersion = dwCrc[0] ^ dwCrc[1];
		m_dwVersion = m_dwVersion ^ dwCrc[2];
		m_dwVersion = m_dwVersion ^ dwCrc[3];
		m_dwVersion = m_dwVersion ^ dwCrc[4];
		m_dwVersion = m_dwVersion ^ dwCrc[5];
		m_dwVersion = m_dwVersion ^ dwCrc[6];
		m_dwVersion = m_dwVersion ^ dwCrc[7];
		m_dwVersion = m_dwVersion ^ dwCrc[8];
		m_dwVersion = m_dwVersion ^ dwCrc[9];
		m_dwVersion = m_dwVersion ^ dwCrc[10];
		m_dwVersion = m_dwVersion ^ dwCrc[11];
//		m_dwVersion = m_dwVersion ^ dwCrc[12];
	} 
	else
	{
		char szErrMsg[MAX_PATH];
		sprintf(szErrMsg, "%s - %s 에 표기된 위치에 있는 클라이언트가 설치되지 않았습니다.", szRegKey, szRegValue);
		MessageBox(szErrMsg, "Checksum 확인", MB_OK);
		return false;
	}

	RegCloseKey(hMPClientReg);

	lpWnd = GetDlgItem(dwViewPathID);
	lpWnd->SetWindowText(m_strClientPath);

	sprintf(strCheckSum, "0x%08x", m_dwVersion);
	lpWnd = GetDlgItem(dwViewCheckSumID);
	lpWnd->SetWindowText(strCheckSum);

	sprintf(strScriptPath, "%s\\VersionInfo.dat", m_strClientPath);
	FILE* fp = fopen(strScriptPath, "r");
	fscanf(fp, "%d", &dwVer);
	fclose(fp);

	sprintf(strCheckSum, "%d", dwVer);
	lpWnd = GetDlgItem(dwViewVersionID);
	lpWnd->SetWindowText(strCheckSum);

	return true;
}
