/*==LICENSE==*

CyanWorlds.com Engine - MMOG client, server and tools
Copyright (C) 2011  Cyan Worlds, Inc.

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.

You can contact Cyan Worlds, Inc. by email legal@cyan.com
 or by snail mail at:
      Cyan Worlds, Inc.
      14617 N Newport Hwy
      Mead, WA   99021

*==LICENSE==*/
/*****************************************************************************
*
*	$/Plasma20/Sources/Plasma/NucleusLib/pnCrashExe/pnCreTools.cpp
*	
***/

#include "../Pch.h"
#pragma	hdrstop


//============================================================================
namespace Crash	{
//============================================================================


/*****************************************************************************
*
*   Internal functions
*
***/

//===========================================================================
static BOOL MYIMAGEAPI iSymGetModuleInfo (
	HANDLE,
	DWORD,
	IMAGEHLP_MODULE * ModuleInfo
) {
	ZEROPTR(ModuleInfo);
	return false;
}

//===========================================================================
static BOOL MYIMAGEAPI iStackWalk (
	DWORD,
	HANDLE,
	HANDLE,
	LPSTACKFRAME,
	LPVOID,
	PREAD_PROCESS_MEMORY_ROUTINE,
	PFUNCTION_TABLE_ACCESS_ROUTINE,
	PGET_MODULE_BASE_ROUTINE,
	PTRANSLATE_ADDRESS_ROUTINE
) {
	return false;
}

//===========================================================================
static LPVOID MYIMAGEAPI iSymFunctionTableAccess (
	HANDLE,
	DWORD
) {
	return nil;
}

//===========================================================================
static DWORD MYIMAGEAPI iSymGetModuleBase (
	HANDLE,  
	DWORD
) {
	return 0;
}

//===========================================================================
static BOOL MYIMAGEAPI iSymGetSymFromAddr (
	HANDLE,
	DWORD,
	LPDWORD Displacement,       
	PIMAGEHLP_SYMBOL Symbol  
) {
	*Displacement = 0;
	ZEROPTR(Symbol);
	return false;
}


/*****************************************************************************
*
*	CImageHelp
*
***/

//============================================================================
CImageHelp::CImageHelp (HINSTANCE instance)
:	m_libInst(nil),
	m_process(nil)
{
	// get program directory and filename
	if (!GetModuleFileNameA(instance, m_appPath, arrsize(m_appPath)))
		m_appPath[0] = 0;
	if (nil !=	(m_appName = StrChrR(m_appPath,	'\\')))
		*m_appName++ = '\0';
	else
		m_appName =	m_appPath;

	// initialize symbols
	for	(;;) {
		if (nil ==	(m_libInst = LoadLibrary("ImageHlp.dll")))
			break;

		// initialize symbols for this process
		BOOL (MYIMAGEAPI * SymInitialize)(HANDLE hProcess, char	* path,	BOOL fInvade);
		* (FARPROC *) &SymInitialize = GetProcAddress(m_libInst, "SymInitialize");
		if (!SymInitialize)
			break;

		HANDLE hProcess	= GetCurrentProcess();
		if (!SymInitialize(hProcess, m_appPath,	false))
			break;

		// import functions
		FARPROC	proc;
		#define	BIND(x)	* (FARPROC *) &(x) = ((proc	= GetProcAddress(m_libInst,	#x)) !=	nil) ?	proc : (FARPROC) i##x
		BIND(SymGetModuleInfo);
		BIND(StackWalk);
		BIND(SymFunctionTableAccess);
		BIND(SymGetModuleBase);
		BIND(SymGetSymFromAddr);
		#undef BIND

		// success
		m_process =	hProcess;
		return;
	}

	// failure!
	if (m_libInst) {
		FreeLibrary(m_libInst);
		m_libInst =	nil;
	}

	#define	INIT(x)	x =	i##x
	INIT(SymGetModuleInfo);
	INIT(StackWalk);
	INIT(SymFunctionTableAccess);
	INIT(SymGetModuleBase);
	INIT(SymGetSymFromAddr);
	#undef INIT
}

//============================================================================
CImageHelp::~CImageHelp () {
	if (m_process) {
		BOOL (MYIMAGEAPI * SymCleanup)(HANDLE hProcess);
		* (FARPROC *) &SymCleanup = GetProcAddress(m_libInst, "SymCleanup");
		if (SymCleanup)
			SymCleanup(m_process);
		m_process = 0;
	}

	if (m_libInst) {
		FreeLibrary(m_libInst);
		m_libInst = 0;
	}
}



//============================================================================
} // namespace Crash
//============================================================================