/* 
 * Bhrama Client-Server Interface 0.3
 * (c)1999 CindyG
 *
 * bhrama.c: Interface implementation
 */

#define WIN32_LEAN_AND_MEAN
#define STRICT
#include <windows.h>
#include "bhrama_internal.h"

// --------------------------------------------------------------------------
// FUNCTION: bhrama_getserverhandle()
// DESCRIPT: 
// --------------------------------------------------------------------------

HWND bhrama_getserverhandle()
{
	/* todo: start server if not found? */
	return FindWindow(NULL, BHRAMA_SERVER_ID);
}

// --------------------------------------------------------------------------
// FUNCTION: bhrama_ipc()
// DESCRIPT: 
// --------------------------------------------------------------------------

BOOL bhrama_ipc(DWORD pid, DWORD function, PBHRAMA_IPC_STRUCT bhrama)
{
	HWND pdserver = bhrama_getserverhandle();

	if (pdserver)
	{
		COPYDATASTRUCT bhrama_cd;

		bhrama->version = BHRAMA_VERSION;
		bhrama->pid     = pid;
		
		bhrama_cd.dwData = function;
		bhrama_cd.cbData = sizeof(BHRAMA_IPC_STRUCT);
		bhrama_cd.lpData = (PVOID)bhrama;
	
		SendMessage(pdserver, WM_COPYDATA, (WPARAM)NULL, (LPARAM)&bhrama_cd);
		return TRUE;
	}
	return FALSE;
}

// --------------------------------------------------------------------------
// FUNCTION: bhrama_query()
// DESCRIPT: 
// --------------------------------------------------------------------------

BOOL bhrama_query(DWORD pid)
{
	BHRAMA_IPC_STRUCT bhrama;
	ZeroMemory(&bhrama, sizeof(bhrama));

	// todo: no specs available yet

	return bhrama_ipc(pid, BHRAMA_QUERY_PID, &bhrama);
}

// --------------------------------------------------------------------------
// FUNCTION: bhrama_dump()
// DESCRIPT: 
// --------------------------------------------------------------------------

BOOL bhrama_dump(DWORD pid, DWORD eip, DWORD delay, DWORD import, DWORD options)
{
	BHRAMA_IPC_STRUCT bhrama;
	ZeroMemory(&bhrama, sizeof(bhrama));

	bhrama.dump.eip                   = eip;
	bhrama.dump.delay                 = delay;
	bhrama.dump.internal_predump      = (options & BHRAMA_PREDUMP_AUTODUMP) ? 1 : 0;
	bhrama.dump.delayed_predump       = (delay != 0) ? 1 : 0;
	bhrama.dump.ignore_faults         = (options & BHRAMA_TRACE_RANGECHECK) ? 1 : 0;
	bhrama.dump.no_eip_confirm        = (options & BHRAMA_TRACE_AUTOEIP) ? 0 : 1;
	bhrama.dump.no_layer_confirm      = (options & BHRAMA_TRACE_AUTOLAYER) ? 0 : 1;
	bhrama.dump.trace_api             = (options & BHRAMA_TRACE_TRACEAPI) ? 1 : 0;
	bhrama.dump.recompute_object_size = (options & BHRAMA_RESTORE_AUTOOBJ) ? 1 : 0;
	bhrama.dump.optimize_pe           = (options & BHRAMA_RESTORE_SHRINKPE) ? 1 : 0;
	bhrama.dump.rebuild_relocations   = (options & BHRAMA_RESTORE_RELOC) ? 1 : 0;
	bhrama.dump.rebuild_header        = (options & BHRAMA_RESTORE_HEADER) ? 1 : 0;
	bhrama.dump.rebuild_import        = (BYTE)import;
	bhrama.dump.force_raw_mode        = (options & BHRAMA_LOADER_RAWMODE) ? 1 : 0;
	bhrama.dump.merge_code            = (options & BHRAMA_LOADER_MERGECODE) ? 1 : 0;
	bhrama.dump.check_header          = (options & BHRAMA_LOADER_CHECKHEADER) ? 1 : 0;
	bhrama.dump.show_disassembly      = (options & BHRAMA_MISC_SHOWDISASM) ? 1 : 0;

	return bhrama_ipc(pid, BHRAMA_DUMP_PID, &bhrama);
}

// --------------------------------------------------------------------------
// FUNCTION: bhrama_dumppart()
// DESCRIPT: 
// --------------------------------------------------------------------------

BOOL bhrama_dumppart(DWORD pid, DWORD start, DWORD length)
{
	BHRAMA_IPC_STRUCT bhrama;
	ZeroMemory(&bhrama, sizeof(bhrama));

	bhrama.dumppart.start  = start;
	bhrama.dumppart.length = length;

	return bhrama_ipc(pid, BHRAMA_DUMP_PID_PART, &bhrama);
}