/************************************************************************************************************
Methods:
1. Delete()		delete the specified branch from registry
2. Get()		get the specified value from specified branch
3. GetAll()		get list of specified branch
4. Set()		set the value to specified branch

Properties:
1. PutEntry()		the registry value to be processed
2. GetErrorReason() reports any errors that occur during the request
3. GetIsError()		returns 1 if any error occur during the request otherwise 0
4. PutSort()		sorts query column data (case-insensitive). sorts on entry, type, and value columns as text.
					valid values are
					Entry_ASC (default)
					Entry_DESC 
					Type_ASC 
					Type_DESC 
					Value_ASC 
					Value_DESC
5. PutType()		the type of data you want to process. valid values are 
					Any 
					String 
					DWORD 
					Key
6. PutValue()		the data value to be set
************************************************************************************************************/

/***********************************/
/*include all required header files*/
/***********************************/
#include <stdio.h>
#include <conio.h>

/***********************************************************************/
/*import AdvRegistry COM library here to get its methods and properties*/
/***********************************************************************/
#import "C:\AdvRegistry.dll" no_namespace

/*************************/
/*prototype for functions*/
/*************************/
void Delete();//Delete function
void Get();//Get function
void GetAll();//GetAll function
void Set();//Set function

/**************/
/*main program*/
/**************/
void main(void)
{
	char Ch;
	do
	{
		printf("\r\nDelete	[D]");
		printf("\r\nGet	[G]");
		printf("\r\nGetAll	[A]");
		printf("\r\nSet	[S]");
		printf("\r\nQuit	[Q]");
		printf("\r\n\r\nEnter Choice = ");
		scanf("%c", &Ch);
		getchar();
		Ch = toupper(Ch);
		switch (Ch)
		{
			case 'D':Delete();break;//call Delete function
			case 'G':Get();break;//call Get function
			case 'A':GetAll();break;//call GetAll function
			case 'S':Set();break;//call Set function
			case 'Q':printf("\r\nGood Bye\r\n");break;
			default: printf("\r\nError: Please enter valid choice\r\n");
		}
	}
	while (Ch != 'Q');
}

/******************************************************************/
/*Delete function: The function is used to delete registry entries*/
/******************************************************************/
void Delete()
{
	char m_Branch[256], m_Entry[256];//define charecter buffer of 256 to read branch name and entry name
	printf("\r\nEnter Branch Name = ");
	gets(m_Branch);//read branch name
	printf("\r\nEnter Entry Name = ");
	gets(m_Entry);//read entry name
	try//for COM library call, try...catch is used to handle exceptions
	{
		IRegistryPtr obj;//take smart pointer object obj for COM library
		CoInitialize(NULL);//Initializes the COM library on the current thread
		obj = IRegistryPtr("AdvRegistry.Registry");
		obj->PutEntry(m_Entry);//set entry property
		HRESULT hr = obj->Delete(m_Branch);//call Delete method of COM library
		if (!SUCCEEDED(hr))//if COM call is not successfull then display error message and return
		{
			printf("\r\nError: %s\r\n", (char*)obj->GetErrorReason());//display error message
			return;
		}
		//call GetIsError() property of COM library and check its value, if its value is 1, then
		//GetErrorReason() property of COM will contain error message, for which this error occured
		if (obj->GetIsError() == 1)
			printf("\r\nError: %s\r\n", (char*)obj->GetErrorReason());//display error message
		else
			printf("\r\nSuccessfully Deleted\r\n");//display successfull message
	}
	catch (_com_error &error)//catch exception here
	{
		printf(TEXT("%S[%X]"), error.ErrorMessage(), error.Error());//display error message
	}
}

/*****************************************************************/
/*Get function: The function is used to get registry entry values*/
/*****************************************************************/
void Get()
{
	char m_Branch[256], m_Entry[256], m_Type[256];//define charecter buffer of 256 to read branch name, entry name and type
	printf("\r\nEnter Branch Name = ");
	gets(m_Branch);//read branch name
	printf("\r\nEnter Entry Name = ");
	gets(m_Entry);//read entry name
	printf("\r\nEnter Type = ");
	gets(m_Type);//read type name
	try//for COM library call, try...catch is used to handle exceptions
	{
		IRegistryPtr obj;//take smart pointer object obj for COM library
		CoInitialize(NULL);//Initializes the COM library on the current thread
		obj = IRegistryPtr("AdvRegistry.Registry");
		obj->PutEntry(m_Entry);//set entry property
		obj->PutType(m_Type);//set type property
		IDispatch* p = obj->Get(m_Branch);//call Get method of COM library
		//call GetIsError() property of COM library and check its value, if its value is 1, then
		//GetErrorReason() property of COM will contain error message, for which this error occured
		if (obj->GetIsError() == 1)
			printf("\r\nError: %s\r\n", (char*)obj->GetErrorReason());//display error message
		else
		{
			printf("\r\nSuccessfully Get\r\n");//display successfull message
			IGetPtr getobj;
			p->QueryInterface(IID_IDispatch,(void**)&getobj);//call query interface
			printf("\r\nValue = %s\r\n", (char*)getobj->GetValue());
		}
	}
	catch (_com_error &error)//catch exception here
	{
		printf(TEXT("%S[%X]"), error.ErrorMessage(), error.Error());//display error message
	}
}

/*********************************************************************/
/*GetAll function: The function is used to get registry entry listing*/
/*********************************************************************/
void GetAll()
{
	char m_Branch[256], m_Sort[256], m_Type[256];//define charecter buffer of 256 to read branch name, sort criteria and type
	printf("\r\nEnter Branch Name = ");
	gets(m_Branch);//read branch name
	printf("\r\nEnter Type = ");
	gets(m_Type);//read type name
	printf("\r\nEnter Sort Criteria = ");
	gets(m_Sort);//read sort citeria name
	try//for COM library call, try...catch is used to handle exceptions
	{
		IRegistryPtr obj;//take smart pointer object obj for COM library
		CoInitialize(NULL);//Initializes the COM library on the current thread
		obj = IRegistryPtr("AdvRegistry.Registry");
		obj->PutType(m_Type);//set type property
		obj->PutSort(m_Sort);//set sort criteria property
		_variant_t pVal = obj->GetAll(m_Branch);//call GetAll method of COM library
		//call GetIsError() property of COM library and check its value, if its value is 1, then
		//GetErrorReason() property of COM will contain error message, for which this error occured
		if (obj->GetIsError() == 1)
		{
			printf("\r\nError: %s\r\n", (char*)obj->GetErrorReason());//display error message
		}
		else
		{
			printf("\r\nSuccessfully GetAll\r\n");//display successfull message
			IDispatch* p = pVal.pdispVal;//IDispatch object is assigned VARIANT object
			IGetAllPtr getallobj;//take GetAll interface object
			p->QueryInterface(IID_IDispatch,(void**)&getallobj);//call query interface
			long count = getallobj->GetCount();//get number of nodes
			for (int j = 1; j <= count; j++)//loop over each node
			{
				_variant_t retVal = getallobj->GetItem(j);//get node item
				IDispatch* pp = retVal.pdispVal;//IDispatch object is assigned VARIANT object
				IGetAllEntriesPtr getallentriesobj;//take GetAllEntries interface object
				pp->QueryInterface(IID_IDispatch,(void**)&getallentriesobj);//call query interface
				printf("\r\n%s | %s | %s\r\n", (char*)getallentriesobj->GetEntry(),
					(char*)getallentriesobj->GetType(),(char*)getallentriesobj->GetValue());//format data
			}
			printf("\r\n");
		}
	}
	catch (_com_error &error)//catch exception here
	{
		printf(TEXT("%S[%X]"), error.ErrorMessage(), error.Error());//display error message
	}
}

/****************************************************************/
/*Set function: The function is used to set registry entry value*/
/****************************************************************/
void Set()
{
	char m_Branch[256], m_Entry[256], m_Type[256], m_Value[256];//define charecter buffer of 256 to read branch name, entry name, type and value
	printf("\r\nEnter Branch Name = ");
	gets(m_Branch);//read branch name
	printf("\r\nEnter Entry Name = ");
	gets(m_Entry);//read entry name
	printf("\r\nEnter Type = ");
	gets(m_Type);//read type name
	printf("\r\nEnter Value = ");
	gets(m_Value);//read sort citeria name
	try//for COM library call, try...catch is used to handle exceptions
	{
		IRegistryPtr obj;//take smart pointer object obj for COM library
		CoInitialize(NULL);//Initializes the COM library on the current thread
		obj = IRegistryPtr("AdvRegistry.Registry");
		obj->PutEntry(m_Entry);//set entry property
		obj->PutType(m_Type);//set type property
		obj->PutValue(m_Value);//set value property
		HRESULT hr = obj->Set(m_Branch);//call Set method of COM library
		if (!SUCCEEDED(hr))//if COM call is not successfull then display error message and return
		{
			printf("\r\nError: %s\r\n", (char*)obj->GetErrorReason());//display error message
			return;
		}
		//call GetIsError() property of COM library and check its value, if its value is 1, then
		//GetErrorReason() property of COM will contain error message, for which this error occured
		if (obj->GetIsError() == 1)
			printf("\r\nError: %s\r\n", (char*)obj->GetErrorReason());//display error message
		else
			printf("\r\nSuccessfully Set\r\n");//display successfull message
	}
	catch (_com_error &error)//catch exception here
	{
		printf(TEXT("%S[%X]"), error.ErrorMessage(), error.Error());//display error message
	}
}
