////////////////////////////////////////////////////////
// File Name: SignatureValidation.cpp
//
//  Abstract: Implements signature validation class.
//
////////////////////////////////////////////////////////

#if !defined(AFX_SIGNATUREVALIDATION_H__24B730C3_AA62_11D2_A66B_00105A1CF3A4__INCLUDED_)
#define AFX_SIGNATUREVALIDATION_H__24B730C3_AA62_11D2_A66B_00105A1CF3A4__INCLUDED_

#include "XMLSignatureVerifier.h"
#include "CompressionManager.h"
#include "CompressedFileImp.h"

const TCHAR DirectorySeparatorChar = '\\';
const TCHAR AltDirectorySeparatorChar = '/';
const TCHAR VolumeSeparatorChar = ':';

CATLString NormalizePath(const CATLString& Path);

class CSingleFileSignatureValidation : public CXMLSignatureCallback
{
public:
	CSingleFileSignatureValidation(CompressedFileSharedPtr spCompressedFile, const CATLString& WorkingFolder) 
		: m_spCompressedFile(spCompressedFile), m_WorkingFolder(WorkingFolder) 
	{}

	virtual bool XMLFileMatch(const CATLString& FileName)
	{
		return NormalizePath(m_spCompressedFile->GetFileName()) == NormalizePath(FileName);
	}

	virtual bool XMLFileOpen(const CATLString& FileName, HANDLE& pFileHandle)
	{
		bool RetVal = false;
		CATLString FilePath;

		if(NormalizePath(m_spCompressedFile->GetFileName()) == NormalizePath(FileName))
		{
			FilePath = m_WorkingFolder + m_spCompressedFile->GetFileName();
			if(m_spCompressedFile->Extract(_bstr_t(FilePath)))
			{
				pFileHandle = CreateFile(FilePath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);	

				if(pFileHandle != INVALID_HANDLE_VALUE)
				{
					RetVal = true;
				}
			}
		}

		return RetVal;
	}

	virtual bool XMLFileRead(HANDLE FileHandle, BYTE* pbuffer, int Length, DWORD& BytesRead)
	{
		bool RetVal = false;
		BOOL ReadResponse;

		BytesRead = -1;

		if(FileHandle)
		{
			ReadResponse = ReadFile(FileHandle, pbuffer, Length, &BytesRead, NULL);

			if(ReadResponse)
			{
				RetVal = true;
			}
		}

		return RetVal;
	}

	virtual bool CustomxmlFileClose(HANDLE FileHandle)
	{
		bool RetVal = false;

		if(CloseHandle(FileHandle))
		{
			RetVal = true;
		}

		return RetVal;
	}

	CompressedFileSharedPtr m_spCompressedFile;
	CATLString m_WorkingFolder;
};

class CSignatureValidation : public CXMLSignatureCallback
{
public:
	CSignatureValidation(CCompressedFileCollection* pCurrentFilePackage, const CATLString& WorkingFolder) 
		: m_pCurrentFilePackage(pCurrentFilePackage), m_WorkingFolder(WorkingFolder) 
	{}

	virtual bool XMLFileMatch(const CATLString& FileName)
	{
		bool RetVal = false;
		int CompressedFileCount = m_pCurrentFilePackage->GetCount();
		CCompressedFile* pCompressedFile = nullptr;

		for(int i = 0; i < CompressedFileCount && !RetVal; i++)
		{
			pCompressedFile = m_pCurrentFilePackage->GetCompressedFile(i);

			if(NormalizePath(pCompressedFile->GetFileName()) == NormalizePath(FileName))
			{
				RetVal = true;
			}

			pCompressedFile->Release();
			pCompressedFile = nullptr;
		}

		return RetVal;
	}

	virtual bool XMLFileOpen(const CATLString& FileName, HANDLE& pFileHandle)
	{
		bool RetVal = false;

		int CompressedFileCount = m_pCurrentFilePackage->GetCount();
		CCompressedFile* pCompressedFile = nullptr;
		CATLString FilePath;

		for(int i = 0; i < CompressedFileCount && !RetVal; i++)
		{
			pCompressedFile = m_pCurrentFilePackage->GetCompressedFile(i);

			if(NormalizePath(pCompressedFile->GetFileName()) == NormalizePath(FileName))
			{
				FilePath = m_WorkingFolder + pCompressedFile->GetFileName();
				if(pCompressedFile->Extract(_bstr_t(FilePath)))
				{
					pFileHandle = CreateFile(FilePath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);	

					if(pFileHandle != INVALID_HANDLE_VALUE)
					{
						RetVal = true;
					}
				}
			}

			pCompressedFile->Release();
			pCompressedFile = nullptr;
		}

		return RetVal;
	}

	virtual bool XMLFileRead(HANDLE FileHandle, BYTE* pbuffer, int Length, DWORD& BytesRead)
	{
		bool RetVal = false;
		BOOL ReadResponse;

		BytesRead = -1;

		if(FileHandle)
		{
			ReadResponse = ReadFile(FileHandle, pbuffer, Length, &BytesRead, NULL);

			if(ReadResponse)
			{
				RetVal = true;
			}
		}

		return RetVal;
	}

	virtual bool CustomxmlFileClose(HANDLE FileHandle)
	{
		bool RetVal = false;

		if(CloseHandle(FileHandle))
		{
			RetVal = true;
		}

		return RetVal;
	}

	CCompressedFileCollection* m_pCurrentFilePackage;
	CATLString m_WorkingFolder;
};

#endif
