#pragma once

//#define _WIN32_WINNT 0x0400
#define _WIN32_DCOM

#include <stdio.h>
#include <tchar.h>
#include <Windows.h>
#include <WbemIdl.h>
#include <WbemCli.h>


#include "..\Runtime\Runtime.h"

#include "..\common\uthash_runtime.h"

#include "../common/debug.h"

typedef struct _Sink {
	IWbemObjectSinkVtbl * lpVtbl;
	PRUNTIME pRuntime;
	LONG m_lRef;
	BOOL bDone;
} Sink;


HRESULT STDMETHODCALLTYPE SinkQueryInterface(IWbemObjectSink *, REFIID riid, void** ppv);

ULONG STDMETHODCALLTYPE SinkAddRef(IWbemObjectSink *);

ULONG STDMETHODCALLTYPE SinkRelease(IWbemObjectSink *);

HRESULT STDMETHODCALLTYPE SinkIndicateDeletion(IWbemObjectSink *, long lObjectCount, IWbemClassObject** apObjArray);

HRESULT STDMETHODCALLTYPE SinkIndicateCreation(IWbemObjectSink *, long lObjectCount, IWbemClassObject** apObjArray);

HRESULT STDMETHODCALLTYPE SinkSetStatus(__RPC__in IWbemObjectSink *, LONG lFlags, HRESULT hResult, BSTR strParam, IWbemClassObject __RPC_FAR *pObjParam);

//static const IWbemObjectSinkVtbl SinkSo_Vtbl = {
//	SinkSoQueryInterface,
//	AddRef,
//	Release,
//	SinkSoIndicate,
//	NULL	// SetStatus
//};


void start_process_creation_callback(PRUNTIME pRuntime);
void start_process_deletion_callback(PRUNTIME pRuntime);
void get_process_list(PRUNTIME pRuntime);

void* process_addwatch(PRUNTIME pRuntime, void *(*callback)(PMONITOR_THREAD_PARAMETERS), void *args, int flags, ...);
void* process_delwatch(PRUNTIME pRuntime, void *entry);

void monitored_process_dump(PRUNTIME pRuntime);

void monitor_process_start(PRUNTIME pRuntime);

typedef struct _PROCESS_LIST_ELEMENT {
	LPSTR strProcessName;
	DWORD dwProcessId;
	DWORD dwNumberOfInstances;
	UT_hash_handle hh;
} PROCESS_LIST_ELEMENT, *PPROCESS_LIST_ELEMENT;


typedef struct _MONITORED_PROCESS {
	LPTHREAD_START_ROUTINE callback;
	void *args;
	int flags;
	LPSTR name;
	UT_hash_handle hh;
} MONITORED_PROCESS, *PMONITORED_PROCESS;