#include "stdafx.h"   //Only required for the SNARE GUI
#include <windows.h>
#include <winsvc.h>
#include <stdio.h>
#include "support.h"

//Note that these functions are self contained, since they will need to be shared
//with the "web server".

//NOTE: Retrun value of 0 = SUCCESS
//		Return value of 1 to 4 = Higher End Registry Read/Write Failure
//		Return value > 4 = Lower End Registry Read/Write Failure
//Also, return values are in binary.

int Read_Config_Registry(Reg_Config *pRegistry_struct)
{
	char strclientname[SIZE_OF_CLIENTNAME]="";
	int i_return_val = 0;
	DWORD dw_Audit = 1;
	DWORD dw_FileAudit = 1;

	//Defaults to NULL if no hostname found, or key is out of bounds.
	if(!MyGetProfileString("Config","Clientname",strclientname,SIZE_OF_CLIENTNAME)) 
	{
		strcpy(pRegistry_struct->str_ClientName,"");
		i_return_val += 1;
	} 
	else 
	{
		strncpy(pRegistry_struct->str_ClientName,strclientname,SIZE_OF_CLIENTNAME);
	}

	dw_Audit=MyGetProfileDWORD("Config","Audit",1);
	dw_FileAudit=MyGetProfileDWORD("Config","FileAudit",1);
	pRegistry_struct->dw_Audit = dw_Audit;
	pRegistry_struct->dw_FileAudit = dw_FileAudit;

	return i_return_val;
}


int Read_Objective_Registry(int i_objective_number, Reg_Objective *pRegistry_struct)
{
	HKEY hKey;
	DWORD  dw_objective_bytes = SIZE_OF_AN_OBJECTIVE, dwRegType;
	char objective_buffer[SIZE_OF_AN_OBJECTIVE]="";
	char str_objective[SIZE_OF_AN_OBJECTIVE]="";
	int i_return_val = 0,i_event_type,i_type = 0,i_event_type_log = 0;
	char str_objective_to_read[20] = "Objective",str_temp[5]=""; 
	char str_temp_pri[4]="",str_temp_evt_type[4]="",str_temp_log_type[4]="",str_temp_eventids[SIZE_OF_EVENTIDMATCH]="";
	char str_temp_usr[SIZE_OF_USERMATCH]="",str_temp_general[SIZE_OF_GENERALMATCH+2]="";
  	char str_temp_user_match_type[SIZE_OF_USER_MATCH_TYPE]="";
	long error_type=0;

	_itoa(i_objective_number,str_temp,10);
	strncat(str_objective_to_read,str_temp,sizeof(str_temp));

	//Open the registry key for READ access. 
	if ( RegOpenKeyEx(HKEY_LOCAL_MACHINE, OBJECTIVE_KEY_NAME, 0, KEY_READ,&hKey ) 
		== ERROR_SUCCESS )
	{
		error_type = RegQueryValueEx(hKey, str_objective_to_read, NULL, &dwRegType, 
		     (LPBYTE) objective_buffer, &dw_objective_bytes );
	  if ( error_type == ERROR_SUCCESS )
	  {
			//Reject any str_objective that is longer than 1056 chars
			if ((dwRegType == REG_SZ) & (dw_objective_bytes <= SIZE_OF_AN_OBJECTIVE))
				strncpy( str_objective,objective_buffer,dw_objective_bytes);
			else
			{
				//reject the str_objective and return immediately
				return (i_return_val += 1);
			}
	  }
	  else
	  {
		  //Retain this error value as 4, since the error control in the other routines
		  //look for errors in the range 1 to 3.
		  return (i_return_val += 4);
	  }

	  //Close the registry key when done
	  RegCloseKey(hKey);
	  
    }
   else
	   return (i_return_val += 2);
	


   //NOTE: This line is TAB delimited.
   //Note str_general_temp is 514 bytes to allow for the two wildcard characters
	sscanf(str_objective,"%4[^\t]\t%4[^\t]\t%4[^\t]\t%256[^\t]\t%514[^\t]\t%4[^\t]\t%256[^\n]\n",str_temp_pri,str_temp_evt_type,str_temp_log_type,str_temp_eventids,str_temp_general,str_temp_user_match_type,str_temp_usr);

	
   //Copy all the values to the struct

	//If the str_objective doesn't contain a valid criticality, assume it is 'clear'
	if (stricmp(str_temp_pri,"4") == 0)
		strncpy(pRegistry_struct->str_critic,CRITICAL_TOKEN,SIZE_OF_CRITICALITY);
	else if (stricmp(str_temp_pri,"3") == 0)
		strncpy(pRegistry_struct->str_critic,PRIORITY_TOKEN,SIZE_OF_CRITICALITY);
	else if (stricmp(str_temp_pri,"2") == 0)
		strncpy(pRegistry_struct->str_critic,WARNING_TOKEN,SIZE_OF_CRITICALITY);
	else if (stricmp(str_temp_pri,"1") == 0)
		strncpy(pRegistry_struct->str_critic,INFORMATION_TOKEN,SIZE_OF_CRITICALITY);
	else 
		strncpy(pRegistry_struct->str_critic,CLEAR_TOKEN,SIZE_OF_CRITICALITY);


	//If the str_objective doesn't contain a valid user match type, assume it is "0"
	if (stricmp(str_temp_user_match_type,"1") == 0)
	{
		strncpy(pRegistry_struct->str_user_match_type,EXCLUDE,SIZE_OF_USER_MATCH_TYPE);
		pRegistry_struct->dw_user_match_type = 1;
	}
	else 
	{
		strncpy(pRegistry_struct->str_user_match_type,INCLUDE,SIZE_OF_USER_MATCH_TYPE);
		pRegistry_struct->dw_user_match_type = 0;
	}


	//If it doesn't return with a value we can use, reject the str_objective
	i_event_type = atoi(str_temp_evt_type);
	pRegistry_struct->dw_event_type = i_event_type;
	if (i_event_type != 0)
	{
		if (i_event_type & TYPE_SUCCESS)
		{
			strncpy(pRegistry_struct->str_event_type,SUCCESS_TOKEN,SIZE_OF_EVENTLOG);
			i_type = 1;
		}
		if (i_event_type & TYPE_FAILURE)
		{
			if (i_type)
			{
				strncat(pRegistry_struct->str_event_type,",",1);
				strncat(pRegistry_struct->str_event_type,FAILURE_TOKEN,SIZE_OF_EVENTLOG);
			}
			else
				strncpy(pRegistry_struct->str_event_type,FAILURE_TOKEN,SIZE_OF_EVENTLOG);

			i_type = 1;
		}
		if (i_event_type & TYPE_INFO)
		{
			if (i_type)
			{
				strncat(pRegistry_struct->str_event_type,",",1);
				strncat(pRegistry_struct->str_event_type,INFO_TOKEN,SIZE_OF_EVENTLOG);
			}
			else
				strncpy(pRegistry_struct->str_event_type,INFO_TOKEN,SIZE_OF_EVENTLOG);
			i_type = 1;
		}
		if (i_event_type & TYPE_WARN)
		{
			if (i_type)
			{
				strncat(pRegistry_struct->str_event_type,",",1);
				strncat(pRegistry_struct->str_event_type,WARN_TOKEN,SIZE_OF_EVENTLOG);
			}
			else
				strncpy(pRegistry_struct->str_event_type,WARN_TOKEN,SIZE_OF_EVENTLOG);
			i_type = 1;
		}
		if (i_event_type & TYPE_ERROR)
		{
			if (i_type)
			{
				strncat(pRegistry_struct->str_event_type,",",1);
				strncat(pRegistry_struct->str_event_type,ERROR_TOKEN,SIZE_OF_EVENTLOG);
			}
			else
				strncpy(pRegistry_struct->str_event_type,ERROR_TOKEN,SIZE_OF_EVENTLOG);

			i_type = 1;
		}
		if (i_type == 0)
			return (i_return_val += 8);
	}
	else
		return (i_return_val += 16);


	i_type = 0;

	i_event_type_log = atoi(str_temp_log_type);
	pRegistry_struct->dw_eventlog_type = i_event_type_log;
	if (i_event_type_log != 0)
	{
		if (i_event_type_log & LOG_SEC)
		{
			strncpy(pRegistry_struct->str_eventlog_type,SECLOG_TOKEN,SIZE_OF_EVENTLOG);
			i_type = 1;
		}
		if (i_event_type_log & LOG_SYS)
		{
			if (i_type)
			{
				strncat(pRegistry_struct->str_eventlog_type,",",1);
				strncat(pRegistry_struct->str_eventlog_type,SYSLOG_TOKEN,sizeof(SYSLOG_TOKEN));
			}
			else
				strncpy(pRegistry_struct->str_eventlog_type,SYSLOG_TOKEN,SIZE_OF_EVENTLOG);

			i_type = 1;
		}
		if (i_event_type_log & LOG_APP)
		{
			if (i_type)
			{
				strncat(pRegistry_struct->str_eventlog_type,",",1);
				strncat(pRegistry_struct->str_eventlog_type,APPLOG_TOKEN,sizeof(APPLOG_TOKEN));
			}
			else
				strncpy(pRegistry_struct->str_eventlog_type,APPLOG_TOKEN,SIZE_OF_EVENTLOG);

			i_type = 1;
		}
		if (i_event_type_log & LOG_DIR)
		{
			if (i_type)
			{
				strncat(pRegistry_struct->str_eventlog_type,",",1);
				strncat(pRegistry_struct->str_eventlog_type,DIRLOG_TOKEN,sizeof(DIRLOG_TOKEN));
			}
			else
				strncpy(pRegistry_struct->str_eventlog_type,DIRLOG_TOKEN,SIZE_OF_EVENTLOG);

			i_type = 1;
		}
		if (i_event_type_log & LOG_DNS)
		{
			if (i_type)
			{
				strncat(pRegistry_struct->str_eventlog_type,",",1);
				strncat(pRegistry_struct->str_eventlog_type,DNSLOG_TOKEN,sizeof(DNSLOG_TOKEN));
			}
			else
				strncpy(pRegistry_struct->str_eventlog_type,DNSLOG_TOKEN,SIZE_OF_EVENTLOG);

			i_type = 1;
		}
		if (i_event_type_log & LOG_REP)
		{
			if (i_type)
			{
				strncat(pRegistry_struct->str_eventlog_type,",",1);
				strncat(pRegistry_struct->str_eventlog_type,REPLOG_TOKEN,sizeof(REPLOG_TOKEN));
			}
			else
				strncpy(pRegistry_struct->str_eventlog_type,REPLOG_TOKEN,SIZE_OF_EVENTLOG);

			i_type = 1;
		}
		if (i_type == 0)
			return (i_return_val += 32);
	}
	else
		return (i_return_val += 64);

	//if the event id search term is greater than 256 chars, reject the str_objective
	if (strlen(str_temp_eventids) < 257)
	{
		strncpy(pRegistry_struct->str_unformatted_eventid_match,str_temp_eventids,SIZE_OF_EVENTIDMATCH);
		if (stricmp(str_temp_eventids,LOGON_LOGOFF_EVENTS) == 0)
		{
			strncpy(pRegistry_struct->str_eventid_match,LOGONOFF_TOKEN,SIZE_OF_EVENTIDMATCH);
		}
		else if (stricmp(str_temp_eventids,RESTART_EVENTS) == 0)
		{
			strncpy(pRegistry_struct->str_eventid_match,REBOOT_TOKEN,SIZE_OF_EVENTIDMATCH);
		}
		else if (stricmp(str_temp_eventids,SECURITY_POLICY_EVENTS) == 0)
		{
			strncpy(pRegistry_struct->str_eventid_match,SECPOL_TOKEN,SIZE_OF_EVENTIDMATCH);
		}
		else if (stricmp(str_temp_eventids,USER_GROUP_ADMIN_EVENTS) == 0)
		{
			strncpy(pRegistry_struct->str_eventid_match,MANAGE_TOKEN,SIZE_OF_EVENTIDMATCH);
		}
		else if (stricmp(str_temp_eventids,USER_OF_USER_RIGHTS_EVENTS) == 0)
		{
			strncpy(pRegistry_struct->str_eventid_match,USERRIGHTS_TOKEN,SIZE_OF_EVENTIDMATCH);
		}
		else if (stricmp(str_temp_eventids,PROCESS_EVENTS) == 0)
		{
			strncpy(pRegistry_struct->str_eventid_match,PROCESS_TOKEN,SIZE_OF_EVENTIDMATCH);
		}
		else if (stricmp(str_temp_eventids,FILE_EVENTS) == 0)
		{
			strncpy(pRegistry_struct->str_eventid_match,FILE_TOKEN,SIZE_OF_EVENTIDMATCH);
		}
		else
		{
			strncpy(pRegistry_struct->str_eventid_match,str_temp_eventids,SIZE_OF_EVENTIDMATCH);
		}
	}	
	else
		return (i_return_val += 128);

	//if the user search term is greater than 256 chars, reject the str_objective
	if (sizeof(str_temp_usr) < 257)
		strncpy(pRegistry_struct->str_user_match,str_temp_usr,SIZE_OF_USERMATCH);
	else
		return (i_return_val += 256);

	//Remove the wildcard characters from the generla match temp string
	remove_wildcard_start_and_end(str_temp_general,pRegistry_struct->str_general_match,SIZE_OF_GENERALMATCH);

	//if the general search term is greater than 512 chars, reject the str_objective
	//Note that the statements below won't do much since the struct var should have been
	//throttled by the function to remove the wildcard chars
	//if (sizeof(pRegistry_struct->str_general_match) < 513)
	//	strncpy(pRegistry_struct->str_general_match,str_temp_general,SIZE_OF_GENERALMATCH);
	//else
	//	return (i_return_val += 512);
	

	return i_return_val;
}

int Read_Network_Registry(Reg_Network *pRegistry_struct)
{
	char str_destination[SIZE_OF_DESTINATION] = "127.0.0.1";
	DWORD dw_Destination_port = 6161, dw_Destination_port_buffer = 6161;
	DWORD dw_Syslog = 1, dw_Syslog_buffer = 1;
	DWORD dw_Syslog_Dest = 13, dw_Syslog_Dest_buffer = 13;
	int i_return_val = 0;
  

	if(!MyGetProfileString("Network","Destination",str_destination,SIZE_OF_DESTINATION)) 
	{
		strncpy(str_destination,"127.0.0.1",SIZE_OF_DESTINATION);
		i_return_val += 1;
	}

	dw_Syslog_Dest=MyGetProfileDWORD("Network","SyslogDest",13);
	dw_Syslog=MyGetProfileDWORD("Network","Syslog",0);
	dw_Destination_port=MyGetProfileDWORD("Network","DestPort",6161);
	
	if(dw_Destination_port > 65535 || dw_Destination_port < 1) 
	{
		dw_Destination_port = 6161;
		i_return_val += 4;
	}

	//Write the values to the struct
	strncpy( pRegistry_struct->str_Destination,str_destination,SIZE_OF_DESTINATION);
	pRegistry_struct->dw_SyslogDest = dw_Syslog_Dest;
	pRegistry_struct->dw_Syslog = dw_Syslog;
	pRegistry_struct->dw_DestPort = dw_Destination_port;
	return i_return_val;
}

int Read_Remote_Registry(Reg_Remote *pRegistry_struct)
{
	char str_restrictip[SIZE_OF_RESTRICTIP] = "127.0.0.1";
	char str_password[SIZE_OF_PASSWORD] = "password";
	DWORD dw_webport = 8080, dw_webport_buffer = 8080;
	DWORD dw_allow = 0, dw_allow_buffer = 0, dw_password = 0;
	DWORD dw_restrict = 0, dw_restrict_buffer = 0;
	DWORD dw_webportchange = 0, dw_webportchange_buffer = 0;
	int i_return_val = 0;
    
	if(!MyGetProfileString("Remote","RestrictIP",str_restrictip,SIZE_OF_RESTRICTIP)) 
	{
		strncpy(str_restrictip,"127.0.0.1",SIZE_OF_RESTRICTIP);
		i_return_val += 1;
	}

	dw_allow=MyGetProfileDWORD("Remote","Allow",0);
	dw_password=MyGetProfileDWORD("Remote","AccessKey",0);
	dw_webport=MyGetProfileDWORD("Remote","WebPort",80);
	
	if(dw_webport > 65535 || dw_webport < 1) 
	{
		dw_webport = 80;
		i_return_val += 2;
	}
	
	dw_restrict=MyGetProfileDWORD("Remote","Restrict",1);
	dw_webportchange=MyGetProfileDWORD("Remote","WebPortChange",0);

	if(!MyGetProfileString("Remote","AccessKeySet",str_password,SIZE_OF_PASSWORD)) 
	{
		strncpy(str_password,"",SIZE_OF_PASSWORD);
		i_return_val += 4;
	}

	   
   //Copy all the values into the structure
   strncpy( pRegistry_struct->str_Password,str_password,SIZE_OF_PASSWORD);
   strncpy( pRegistry_struct->str_RestrictIP,str_restrictip,SIZE_OF_RESTRICTIP);
   pRegistry_struct->dw_Restrict = dw_restrict;
   pRegistry_struct->dw_WebPortChange = dw_webportchange;
   pRegistry_struct->dw_Allow = dw_allow;
   pRegistry_struct->dw_WebPort = dw_webport;
   pRegistry_struct->dw_Password = dw_password;

   //Return the error code
   return i_return_val;
}

int Write_Config_Registry(Reg_Config *pRegistry_struct)
{
	HKEY hKey;
	DWORD dwDisp, dwBytesReturned = 100; 
	int i_return_val = 0;
	char str_clientnamebuffer[SIZE_OF_CLIENTNAME]="";
    
	//Open the registry key for ALL access. 
	if ( RegOpenKeyEx(HKEY_LOCAL_MACHINE, CONFIG_KEY_NAME, 0, KEY_ALL_ACCESS,&hKey ) 
		!= ERROR_SUCCESS )
	{
		//The registry key does not exist and was thus unable to be opened.
		//Try and create it.
		if (RegCreateKeyEx(HKEY_LOCAL_MACHINE, CONFIG_KEY_NAME,0,REG_NONE,
					       REG_OPTION_NON_VOLATILE,KEY_ALL_ACCESS,
						   NULL,&hKey,&dwDisp) != ERROR_SUCCESS)
		{
		//The registry key was unable to be created. Return.
			i_return_val += 2;
			return i_return_val;
		}
	}
		
	//Now attempt to set the registry values

	//No error checking required on this Reg Value
	strncpy(str_clientnamebuffer,pRegistry_struct->str_ClientName,SIZE_OF_CLIENTNAME);
	if ( RegSetValueEx(hKey, "Clientname",0,REG_SZ,
			  (CONST BYTE *) str_clientnamebuffer,strlen(str_clientnamebuffer)) 
			  != ERROR_SUCCESS )
		i_return_val += 4;
				
	//If Audit is out of bounds, then it becomes 1
	if ((pRegistry_struct->dw_Audit < 0) | (pRegistry_struct->dw_Audit > 1))
		pRegistry_struct->dw_Audit = 1;
	if ( RegSetValueEx(hKey, "Audit",0,REG_DWORD,
			  (CONST BYTE *) &pRegistry_struct->dw_Audit,
			  sizeof(pRegistry_struct->dw_Audit))
			  != ERROR_SUCCESS )
		i_return_val += 8;

	//If FileAudit is out of bounds, then it becomes 1
	if ((pRegistry_struct->dw_FileAudit < 0) | (pRegistry_struct->dw_FileAudit > 1))
		pRegistry_struct->dw_FileAudit = 1;
	if ( RegSetValueEx(hKey, "FileAudit",0,REG_DWORD,
			  (CONST BYTE *) &pRegistry_struct->dw_FileAudit,
			  sizeof(pRegistry_struct->dw_FileAudit))
			  != ERROR_SUCCESS )
		i_return_val += 16;

	//Close the registry key when done
	RegCloseKey(hKey);

	return i_return_val;
}

int Write_Network_Registry(Reg_Network *pRegistry_struct)
{
	HKEY hKey;
	DWORD dwDisp, dwBytesReturned = 100; 
	int i_return_val = 0;
	char str_destination[SIZE_OF_DESTINATION]="";
    
	//Open the registry key for ALL access. 
	if ( RegOpenKeyEx(HKEY_LOCAL_MACHINE, NETWORK_KEY_NAME, 0, KEY_ALL_ACCESS,&hKey ) 
		!= ERROR_SUCCESS )
	{
		//The registry key does not exist and was thus unable to be opened.
		//Try and create it.
		if (RegCreateKeyEx(HKEY_LOCAL_MACHINE, NETWORK_KEY_NAME,0,REG_NONE,
					       REG_OPTION_NON_VOLATILE,KEY_ALL_ACCESS,
						   NULL,&hKey,&dwDisp) != ERROR_SUCCESS)
		{
		//The registry key was unable to be created. Return.
			i_return_val += 2;
			return i_return_val;
		}
	}
		
	//Now attempt to set the registry values

	// Write out the hostname (if set)
	if(strlen(pRegistry_struct->str_Destination) > 1) {
		strncpy(str_destination,pRegistry_struct->str_Destination,SIZE_OF_DESTINATION);
	} else {
		strncpy(str_destination,"",SIZE_OF_DESTINATION);
	}
	if ( RegSetValueEx(hKey, "Destination",0,REG_SZ,
			  (CONST BYTE *) str_destination,strlen(str_destination)) 
			  != ERROR_SUCCESS )
		i_return_val += 4;
		
	//If DestPort is out of bounds, then it becomes 6161
	if ((pRegistry_struct->dw_DestPort < 1) | (pRegistry_struct->dw_DestPort > 65535))
		pRegistry_struct->dw_DestPort = 6161;

	if ( RegSetValueEx(hKey, "DestPort",0,REG_DWORD,
			  (CONST BYTE *) &pRegistry_struct->dw_DestPort,
			  sizeof(pRegistry_struct->dw_DestPort))
			  != ERROR_SUCCESS )
		i_return_val += 8;

	//If Syslog is out of bounds, then it becomes 1
	if ((pRegistry_struct->dw_Syslog < 0) | (pRegistry_struct->dw_Syslog > 1))
		pRegistry_struct->dw_Syslog = 1;
	if ( RegSetValueEx(hKey, "Syslog",0,REG_DWORD,
			  (CONST BYTE *) &pRegistry_struct->dw_Syslog,
			  sizeof(pRegistry_struct->dw_Syslog))
			  != ERROR_SUCCESS )
		i_return_val += 16;

	//No error checking for the Syslog catgeory and criticality
	if ( RegSetValueEx(hKey, "SyslogDest",0,REG_DWORD,
			  (CONST BYTE *) &pRegistry_struct->dw_SyslogDest,
			  sizeof(pRegistry_struct->dw_SyslogDest))
			  != ERROR_SUCCESS )
		i_return_val += 32;
		

	//Close the registry key when done
	RegCloseKey(hKey);

	return i_return_val;
}


int Write_Remote_Registry(Reg_Remote *pRegistry_struct)
{
	HKEY hKey;
	DWORD dwDisp, dwBytesReturned = 100; 
	int i_return_val = 0;
	char str_restrictip[SIZE_OF_RESTRICTIP]="";
	char str_password[SIZE_OF_PASSWORD]="";
    
	//Open the registry key for ALL access. 
	if ( RegOpenKeyEx(HKEY_LOCAL_MACHINE, REMOTE_KEY_NAME, 0, KEY_ALL_ACCESS,&hKey ) 
		!= ERROR_SUCCESS )
	{
		//The registry key does not exist and was thus unable to be opened.
		//Try and create it.
		if (RegCreateKeyEx(HKEY_LOCAL_MACHINE, REMOTE_KEY_NAME,0,REG_NONE,
					       REG_OPTION_NON_VOLATILE,KEY_ALL_ACCESS,
						   NULL,&hKey,&dwDisp) != ERROR_SUCCESS)
		{
		//The registry key was unable to be created. Return.
			i_return_val += 2;
			return i_return_val;
		}
	}
		
	//Now attempt to set the registry values

	//No error checking required on this Reg Value
	strncpy(str_restrictip,pRegistry_struct->str_RestrictIP,SIZE_OF_RESTRICTIP);
	if ( RegSetValueEx(hKey, "RestrictIP",0,REG_SZ,
			  (CONST BYTE *) str_restrictip,strlen(str_restrictip)) 
			  != ERROR_SUCCESS )
		i_return_val += 4;
		
	//If WebPort is out of bounds, then it becomes 8080
	if ((pRegistry_struct->dw_WebPort < 1) | (pRegistry_struct->dw_WebPort > 65535))
		pRegistry_struct->dw_WebPort = 8080;

	if ( RegSetValueEx(hKey, "WebPort",0,REG_DWORD,
			  (CONST BYTE *) &pRegistry_struct->dw_WebPort,
			  sizeof(pRegistry_struct->dw_WebPort))
			  != ERROR_SUCCESS )
		i_return_val += 8;

	//If Allow is out of bounds, then it becomes 0, the default
	if ((pRegistry_struct->dw_Allow < 0) | (pRegistry_struct->dw_Allow > 1))
		pRegistry_struct->dw_Allow = 0;

	if ( RegSetValueEx(hKey, "Allow",0,REG_DWORD,
			  (CONST BYTE *) &pRegistry_struct->dw_Allow,
			  sizeof(pRegistry_struct->dw_Allow))
			  != ERROR_SUCCESS )
		i_return_val += 16;

	//If Password is out of bounds, then it becomes 0, the default
	if ((pRegistry_struct->dw_Password < 0) | (pRegistry_struct->dw_Password > 1))
		pRegistry_struct->dw_Password = 0;

	if ( RegSetValueEx(hKey, "AccessKey",0,REG_DWORD,
			  (CONST BYTE *) &pRegistry_struct->dw_Password,
			  sizeof(pRegistry_struct->dw_Password))
			  != ERROR_SUCCESS )
		i_return_val += 256;


	//If Restrict is out of bounds, then it becomes 0, the default
	if ((pRegistry_struct->dw_Restrict < 0) | (pRegistry_struct->dw_Restrict > 1))
		pRegistry_struct->dw_Restrict = 0;

	if ( RegSetValueEx(hKey, "Restrict",0,REG_DWORD,
			  (CONST BYTE *) &pRegistry_struct->dw_Restrict,
			  sizeof(pRegistry_struct->dw_Restrict))
			  != ERROR_SUCCESS )
		i_return_val += 32;

	//If WebPortChange is out of bounds, then it becomes 0, the default
	if ((pRegistry_struct->dw_WebPortChange < 0) | (pRegistry_struct->dw_WebPortChange > 1))
		pRegistry_struct->dw_WebPortChange = 0;

	if ( RegSetValueEx(hKey, "WebPortChange",0,REG_DWORD,
			  (CONST BYTE *) &pRegistry_struct->dw_WebPortChange,
			  sizeof(pRegistry_struct->dw_WebPortChange))
			  != ERROR_SUCCESS )
		i_return_val += 64;
		
	//No error checking required on this Reg Value
	strncpy(str_password,pRegistry_struct->str_Password,SIZE_OF_PASSWORD);
	if ( RegSetValueEx(hKey, "AccessKeySet",0,REG_SZ,
			  (CONST BYTE *) str_password,strlen(str_password)) 
			  != ERROR_SUCCESS )
		i_return_val += 128;

	//Close the registry key when done
	RegCloseKey(hKey);

	return i_return_val;
}


int Write_Objective_Registry(int i_objective_number, Reg_Objective *pRegistry_struct)
{
	HKEY hKey;
	DWORD dwDisp, dwBytesReturned = 100,i_AlertType = 0,i_EventType = 0;
	DWORD i_EventLogType = 0;
	int i_return_val = 0;
	char str_UserMatch[SIZE_OF_USERMATCH]="", str_EventIDMatch[SIZE_OF_EVENTIDMATCH]="";
	char str_GeneralMatch[SIZE_OF_GENERALMATCH],str_Alert[2] = "1";
	char str_event_log[SIZE_OF_EVENTLOG]="",str_event_type[SIZE_OF_EVENTLOG]="";
	char str_objective[SIZE_OF_AN_OBJECTIVE] = "";
	char str_objective_to_read[20] = "Objective",str_temp[10]=""; 
	char str_user_match_type[SIZE_OF_USER_MATCH_TYPE];
	char str_GeneralMatchPlusTwo[SIZE_OF_GENERALMATCH+2];

	_itoa(i_objective_number,str_temp,10);
	strncat(str_objective_to_read,str_temp,sizeof(str_objective_to_read) - strlen(str_objective_to_read));


	//Attempt to set the registry values
		if (stricmp(pRegistry_struct->str_critic,CRITICAL_TOKEN) == 0)
			strncpy(str_Alert,"4",SIZE_OF_CRITICALITY);
		else if (stricmp(pRegistry_struct->str_critic,PRIORITY_TOKEN) == 0)
			strncpy(str_Alert,"3",SIZE_OF_CRITICALITY);
		else if (stricmp(pRegistry_struct->str_critic,WARNING_TOKEN) == 0)
			strncpy(str_Alert,"2",SIZE_OF_CRITICALITY);
		else if (stricmp(pRegistry_struct->str_critic,INFORMATION_TOKEN) == 0)
			strncpy(str_Alert,"1",SIZE_OF_CRITICALITY);
		else 
			strncpy(str_Alert,"0",SIZE_OF_CRITICALITY);

		if (strstr(pRegistry_struct->str_event_type,SUCCESS_TOKEN) != NULL)
			i_EventType += TYPE_SUCCESS;
		if (strstr(pRegistry_struct->str_event_type,FAILURE_TOKEN) != NULL)
			i_EventType += TYPE_FAILURE;
		if (strstr(pRegistry_struct->str_event_type,INFO_TOKEN) != NULL)
			i_EventType += TYPE_INFO;
		if (strstr(pRegistry_struct->str_event_type,WARN_TOKEN) != NULL)
			i_EventType += TYPE_WARN;
		if (strstr(pRegistry_struct->str_event_type,ERROR_TOKEN) != NULL)
			i_EventType += TYPE_ERROR;
		_itoa(i_EventType,str_event_type,10);

		if (strstr(pRegistry_struct->str_eventlog_type,SECLOG_TOKEN) != NULL)
			i_EventLogType += LOG_SEC;
		if (strstr(pRegistry_struct->str_eventlog_type,SYSLOG_TOKEN) != NULL)
			i_EventLogType += LOG_SYS;
		if (strstr(pRegistry_struct->str_eventlog_type,APPLOG_TOKEN) != NULL)
			i_EventLogType += LOG_APP;
		if (strstr(pRegistry_struct->str_eventlog_type,DIRLOG_TOKEN) != NULL)
			i_EventLogType += LOG_DIR;
		if (strstr(pRegistry_struct->str_eventlog_type,DNSLOG_TOKEN) != NULL)
			i_EventLogType += LOG_DNS;
		if (strstr(pRegistry_struct->str_eventlog_type,REPLOG_TOKEN) != NULL)
			i_EventLogType += LOG_REP;
		_itoa(i_EventLogType,str_event_log,10);

		if (strstr(pRegistry_struct->str_user_match_type,EXCLUDE) != NULL)
			strncpy(str_user_match_type,"1",SIZE_OF_USER_MATCH_TYPE);
		else
			strncpy(str_user_match_type,"0",SIZE_OF_USER_MATCH_TYPE);

		if (stricmp(pRegistry_struct->str_eventid_match,LOGONOFF_TOKEN) == 0)
			strncpy(str_EventIDMatch,LOGON_LOGOFF_EVENTS,SIZE_OF_EVENTIDMATCH);
		else if (stricmp(pRegistry_struct->str_eventid_match,FILE_TOKEN) == 0)
			strncpy(str_EventIDMatch,FILE_EVENTS,SIZE_OF_EVENTIDMATCH);
		else if (stricmp(pRegistry_struct->str_eventid_match,PROCESS_TOKEN) == 0)
			strncpy(str_EventIDMatch,PROCESS_EVENTS,SIZE_OF_EVENTIDMATCH);
		else if (stricmp(pRegistry_struct->str_eventid_match,USERRIGHTS_TOKEN) == 0)
			strncpy(str_EventIDMatch,USER_OF_USER_RIGHTS_EVENTS,SIZE_OF_EVENTIDMATCH);
		else if (stricmp(pRegistry_struct->str_eventid_match,MANAGE_TOKEN) == 0)
			strncpy(str_EventIDMatch,USER_GROUP_ADMIN_EVENTS,SIZE_OF_EVENTIDMATCH);
		else if (stricmp(pRegistry_struct->str_eventid_match,SECPOL_TOKEN) == 0)
			strncpy(str_EventIDMatch,SECURITY_POLICY_EVENTS,SIZE_OF_EVENTIDMATCH);
		else if (stricmp(pRegistry_struct->str_eventid_match,REBOOT_TOKEN) == 0)
			strncpy(str_EventIDMatch,RESTART_EVENTS,SIZE_OF_EVENTIDMATCH);
		else
		{
			//Need to make sure the length is limited
			strncpy(str_EventIDMatch,pRegistry_struct->str_eventid_match,SIZE_OF_EVENTIDMATCH);
		}
		

		//Need to make sure the length is limited
		strncpy(str_UserMatch,pRegistry_struct->str_user_match,SIZE_OF_USERMATCH);

		//Need to make sure the length is limited
		strncpy(str_GeneralMatch,pRegistry_struct->str_general_match,SIZE_OF_GENERALMATCH);

		//This is to add a "*" character to the start and end of the general string
		add_wildcard_start_and_end(str_GeneralMatch,str_GeneralMatchPlusTwo,SIZE_OF_GENERALMATCH+2);
		
		//form the str_objective
		strncpy(str_objective,str_Alert,strlen(str_Alert));
		strncat(str_objective,OBJECTIVE_DELIMITER,strlen(OBJECTIVE_DELIMITER));
		strncat(str_objective,str_event_type,strlen(str_event_type));
		strncat(str_objective,OBJECTIVE_DELIMITER,strlen(OBJECTIVE_DELIMITER));
		strncat(str_objective,str_event_log,strlen(str_event_log));
		strncat(str_objective,OBJECTIVE_DELIMITER,strlen(OBJECTIVE_DELIMITER));
		strncat(str_objective,str_EventIDMatch,strlen(str_EventIDMatch));
		strncat(str_objective,OBJECTIVE_DELIMITER,strlen(OBJECTIVE_DELIMITER));
		strncat(str_objective,str_GeneralMatchPlusTwo,strlen(str_GeneralMatchPlusTwo));
		strncat(str_objective,OBJECTIVE_DELIMITER,strlen(OBJECTIVE_DELIMITER));
		strncat(str_objective,str_user_match_type,strlen(str_user_match_type));
		strncat(str_objective,OBJECTIVE_DELIMITER,strlen(OBJECTIVE_DELIMITER));
		strncat(str_objective,str_UserMatch,strlen(str_UserMatch));
		

	//Open the registry key for ALL access. 
	if ( RegOpenKeyEx(HKEY_LOCAL_MACHINE, OBJECTIVE_KEY_NAME, 0, KEY_ALL_ACCESS,&hKey ) 
		!= ERROR_SUCCESS )
	{
		//The registry key does not exist and was thus unable to be opened.
		//Try and create it.
		if (RegCreateKeyEx(HKEY_LOCAL_MACHINE, OBJECTIVE_KEY_NAME,0,REG_NONE,
					       REG_OPTION_NON_VOLATILE,KEY_ALL_ACCESS,
						   NULL,&hKey,&dwDisp) != ERROR_SUCCESS)
		{
		//The registry key was unable to be created. Return.
			i_return_val += 2;
			return i_return_val;
		}
	}

	//No error checking required on this Reg Value
	//strncpy(str_buffer,pRegistry_struct->str_RestrictIP,1024);
	
	if ( RegSetValueEx(hKey, str_objective_to_read,0,REG_SZ,
			  (CONST BYTE *) str_objective,strlen(str_objective)) 
			  != ERROR_SUCCESS )
		i_return_val += 4;
		

	//Close the registry key when done
	RegCloseKey(hKey);

	return i_return_val;
}


int Recreate_Objective_Key()
{
	HKEY hKey;
	DWORD dwDisp; 
	int i_return_val = 0;
    
	//Delete the "Objective" Registry Key 
	if ( RegDeleteKey(HKEY_LOCAL_MACHINE, OBJECTIVE_KEY_NAME) != ERROR_SUCCESS )
	{
		//The registry key could not be deleted
		i_return_val += 1;
	}
	if (RegCreateKeyEx(HKEY_LOCAL_MACHINE, OBJECTIVE_KEY_NAME,0,REG_NONE,
					       REG_OPTION_NON_VOLATILE,KEY_ALL_ACCESS,
						   NULL,&hKey,&dwDisp) != ERROR_SUCCESS)
	{
		//The registry key was unable to be created. Return.
		i_return_val += 2;
	}
		

	//Close the registry key when done
	RegCloseKey(hKey);

	return i_return_val;
}


int Delete_Objective(int i_objective_number)
{
	HKEY hKey;
	int i_return_val = 0;
	char str_objective_to_delete[20] = "Objective",str_temp[10]=""; 
    
	_itoa(i_objective_number,str_temp,10);
	strncat(str_objective_to_delete,str_temp,sizeof(str_objective_to_delete) - strlen(str_objective_to_delete));

	//Open the registry key for ALL access. 
	if ( RegOpenKeyEx(HKEY_LOCAL_MACHINE, OBJECTIVE_KEY_NAME, 0, KEY_ALL_ACCESS,&hKey ) != ERROR_SUCCESS )
			return i_return_val += 1;

	if ( RegDeleteValue(hKey, str_objective_to_delete) != ERROR_SUCCESS )
		i_return_val += 2;
		
	//Close the registry key when done
	RegCloseKey(hKey);

	return i_return_val;
}


/*
int Restart_Service() 
{

	STARTUPINFO StartupInfo;  // pointer to STARTUPINFO
	PROCESS_INFORMATION ProcessInformation,ProcessInformation2;  // pointer to PROCESS_INFORMATION
	SECURITY_ATTRIBUTES saAttr;
	HANDLE h_readInPipe, h_writeInPipe, h_readOutPipe, h_writeOutPipe;
	DWORD dw_bytes,dw_return_result,dw_error=0;
	char str_buffer[1024]="";

	//Create the pipe that will be used to read from the process
	//Also need to create a pipe that the process will write to
	saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
	saAttr.bInheritHandle = TRUE;
	saAttr.lpSecurityDescriptor = NULL;

    if (!CreatePipe(&h_readInPipe,  &h_writeInPipe, &saAttr, 0))
		dw_error += 256;
    if (!CreatePipe(&h_readOutPipe, &h_writeOutPipe, &saAttr, 0))
		dw_error += 512;

	StartupInfo.cb = sizeof(STARTUPINFO);
	StartupInfo.hStdOutput = h_writeOutPipe; 
	StartupInfo.hStdInput = h_readInPipe;  
	StartupInfo.hStdError = h_writeOutPipe;
	StartupInfo.lpTitle = NULL;
	StartupInfo.cbReserved2 = 0;
	StartupInfo.lpReserved2 = NULL;
	StartupInfo.lpReserved = NULL;
	//This must be in the defintion, or the process **__WILL NOT__** run from the toolbar.
	//STDHANDLES must be also specified.
	StartupInfo.lpDesktop = NULL;
	StartupInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW | STARTF_FORCEONFEEDBACK;


	//If I can't run this process, then something is wrong.
	//You must set the 5th value to TRUE....or it won't work properly with the handles...
	//Create a process to STOP the SNARE service. 
	if (CreateProcess(NULL,"net stop snare",NULL,NULL,TRUE,
		NORMAL_PRIORITY_CLASS,NULL,NULL,
		&StartupInfo,&ProcessInformation))
	{
		//Wait for up to 5 seconds for process to terminate
		dw_return_result = WaitForSingleObject(ProcessInformation.hProcess, 10000);
		if ((dw_return_result == WAIT_FAILED) || (dw_return_result == WAIT_TIMEOUT))
			dw_error += 1;		
		else
		{
			if (ReadFile(h_readOutPipe, str_buffer, 1024, &dw_bytes, NULL) != 0)
			{
				if (strstr(str_buffer,"stopped successfully") == NULL)
					dw_error += 2;		
			}
			else
				dw_error += 4;		
		}
	}
	else
		dw_error += 8;		


	//Now try and restart it
	if (CreateProcess(NULL,"net start snare",NULL,NULL,TRUE,
		NORMAL_PRIORITY_CLASS,NULL,NULL,
		&StartupInfo,&ProcessInformation2))
	{
		//Wait for up to 5 seconds for process to terminate
		dw_return_result = WaitForSingleObject(ProcessInformation2.hProcess, 10000);
		if ((dw_return_result == WAIT_FAILED) || (dw_return_result == WAIT_TIMEOUT))
			dw_error += 16;		
		else
		{
			if (ReadFile(h_readOutPipe, str_buffer, 1024, &dw_bytes, NULL) != 0)
			{
				if (strstr(str_buffer,"started successfully") == NULL)
					dw_error += 32;

			}
			else
				dw_error += 64;
		}
	}
	else
		dw_error += 128;
	
	CloseHandle(h_readInPipe);
	CloseHandle(h_writeInPipe);

    CloseHandle(h_readOutPipe);
	CloseHandle(h_writeOutPipe);

	return dw_error;
} */


int Restart_Service() 
{
	int returncode=0;
	returncode += Stop_Service();
	returncode += Start_Service();
	return(returncode);
}

int Stop_Service()
{
	SERVICE_STATUS ssStatus;
    DWORD dwStartTime;
    DWORD dwTimeout=30000; // 30 seconds
	SC_HANDLE hSCM;
	SC_HANDLE schService;

	dwStartTime = GetTickCount();

    // Open the SCM database
    hSCM = OpenSCManager( NULL, NULL, SC_MANAGER_CONNECT );
    if ( !hSCM ) {
		return(1);
	}
 
    schService = OpenService( 
        hSCM,          // SCM database 
        "Snare",          // service name
        SERVICE_ALL_ACCESS); 
 
    if (schService == NULL) 
    { 
        CloseServiceHandle(hSCM);
		return(1); 
    }
 

	if (!ControlService(schService,SERVICE_CONTROL_STOP,&ssStatus ) ) {
		CloseServiceHandle(schService);
		CloseServiceHandle(hSCM);
		return(1);
	}

    // Wait for the service to stop
	while ( ssStatus.dwCurrentState != SERVICE_STOPPED ) 
    {
		Sleep( ssStatus.dwWaitHint );
        if ( !QueryServiceStatus( schService, &ssStatus ) ) {
			CloseServiceHandle(schService);
			CloseServiceHandle(hSCM);

			return(1);
		}

		if ( ssStatus.dwCurrentState == SERVICE_STOPPED )
			break;

        if ( GetTickCount() - dwStartTime > dwTimeout ) {
			CloseServiceHandle(schService);
			CloseServiceHandle(hSCM);

			return(1);
		}
	}

	CloseServiceHandle(schService);
	CloseServiceHandle(hSCM);

	return(0);
}


// UP TO HERE - REDREDRED
int Start_Service()
{
	SERVICE_STATUS ssStatus;
    DWORD dwOldCheckPoint; 
    DWORD dwStartTickCount;
    DWORD dwWaitTime;
    DWORD dwStatus;

	SC_HANDLE hSCM;
	SC_HANDLE schService;

    // Open the SCM database
    hSCM = OpenSCManager( NULL, NULL, SC_MANAGER_CONNECT );
    if ( !hSCM ) {
		return(2);
	}
 
    schService = OpenService( 
        hSCM,          // SCM database 
        "Snare",          // service name
        SERVICE_ALL_ACCESS); 
 
    if (schService == NULL) 
    {
		CloseServiceHandle(hSCM);
        return(2); 
    }
 
    if (!StartService(
            schService,  // handle to service 
            0,           // number of arguments 
            NULL) )      // no arguments 
    {
		// Excellent - Service started.
		CloseServiceHandle(schService);
		CloseServiceHandle(hSCM);

        return(0); 
    }
 
    // Check the status until the service is no longer start pending. 
 
    if (!QueryServiceStatus( 
            schService,   // handle to service 
            &ssStatus) )  // address of status information structure
    {
		CloseServiceHandle(schService);
		CloseServiceHandle(hSCM);
		return(2);
    }
 
    // Save the tick count and initial checkpoint.

    dwStartTickCount = GetTickCount();
    dwOldCheckPoint = ssStatus.dwCheckPoint;

    while (ssStatus.dwCurrentState == SERVICE_START_PENDING) 
    { 
        // Do not wait longer than the wait hint. A good interval is 
        // one tenth the wait hint, but no less than 1 second and no 
        // more than 10 seconds. 
 
        dwWaitTime = ssStatus.dwWaitHint / 10;

        if( dwWaitTime < 1000 )
            dwWaitTime = 1000;
        else if ( dwWaitTime > 10000 )
            dwWaitTime = 10000;

        Sleep( dwWaitTime );

        // Check the status again. 
 
        if (!QueryServiceStatus( 
                schService,   // handle to service 
                &ssStatus) )  // address of structure
            break; 
 
        if ( ssStatus.dwCheckPoint > dwOldCheckPoint ) {
            // The service is making progress.
            dwStartTickCount = GetTickCount();
            dwOldCheckPoint = ssStatus.dwCheckPoint;
        } else {
            if(GetTickCount()-dwStartTickCount > ssStatus.dwWaitHint)
            {
                // No progress made within the wait hint
                break;
            }
        }
    } 

    if (ssStatus.dwCurrentState == SERVICE_RUNNING) 
    {
		// Service started.
        dwStatus = 0;
    } else { 
        dwStatus = 2;
    }
 
	CloseServiceHandle(schService);
	CloseServiceHandle(hSCM);

    return dwStatus;
}


// Write a DWORD to the registry
BOOL MyWriteProfileDWORD(LPCTSTR lpszSection, LPCTSTR lpszEntry, DWORD nValue)
{
	HKEY hSecKey = MyGetSectionKey(lpszSection);
	if (hSecKey == NULL)
		return TRUE;
	LONG lResult = RegSetValueEx(hSecKey, lpszEntry, NULL, REG_DWORD,
		(LPBYTE)&nValue, sizeof(nValue));
	RegCloseKey(hSecKey);
	return lResult == ERROR_SUCCESS;
}

// Get a DWORD from the registry
DWORD MyGetProfileDWORD(LPCTSTR lpszSection, LPCTSTR lpszEntry, DWORD nDefault)
{
	HKEY hSecKey = MyGetSectionKey(lpszSection);
	if (hSecKey == NULL)
		return nDefault;
	DWORD dwValue;
	DWORD dwType;
	DWORD dwCount = sizeof(DWORD);
	LONG lResult = RegQueryValueEx(hSecKey, (LPTSTR)lpszEntry, NULL, &dwType,
		(LPBYTE)&dwValue, &dwCount);
	RegCloseKey(hSecKey);
	if (lResult == ERROR_SUCCESS)
	{
		return dwValue;
	}
	return nDefault;
}

// Write a string to the registry
BOOL MyWriteProfileString(LPCTSTR lpszSection, LPCTSTR lpszEntry, LPCTSTR lpszString)
{
	HKEY hSecKey = MyGetSectionKey(lpszSection);
	if (hSecKey == NULL)
		return TRUE;
	LONG lResult = RegSetValueEx(hSecKey, lpszEntry, NULL, REG_SZ,
		(unsigned char *)lpszString, strlen(lpszString)+1);
//		(unsigned char *)lpszString, (strlen(lpszString)+1) * sizeof(LPCTSTR));
	RegCloseKey(hSecKey);
	return lResult == ERROR_SUCCESS;
}

// Get a string from the registry
BOOL MyGetProfileString(LPCTSTR lpszSection, LPCTSTR lpszEntry, LPCTSTR lpszString, DWORD dwStringBuffer)
{
	HKEY hSecKey = MyGetSectionKey(lpszSection);
	if (hSecKey == NULL)
		return TRUE;
	DWORD dwSize = dwStringBuffer;
	DWORD dwType;
	LONG lResult = RegQueryValueEx(hSecKey, (LPCTSTR)lpszEntry, NULL, &dwType,
		(LPBYTE)lpszString, &dwSize);
	RegCloseKey(hSecKey);
	return lResult == ERROR_SUCCESS;
}

// Get the setion registry key
HKEY MyGetSectionKey(LPCTSTR lpszSection)
{
	HKEY hSectionKey = NULL;
	HKEY hAppKey = MyGetServiceRegistryKey();
	if (hAppKey == NULL)
		return NULL;
	
	DWORD dw;
	RegCreateKeyEx(hAppKey, lpszSection, 0, REG_NONE,
		REG_OPTION_NON_VOLATILE, KEY_WRITE|KEY_READ, NULL,
		&hSectionKey, &dw);
	RegCloseKey(hAppKey);
	return hSectionKey;
}

HKEY MyGetServiceRegistryKey()
{
	// Store the information within the InterSect Alliance high level key.
	char m_sServiceName[256]="InterSect Alliance";
	
	HKEY hServicesKey = NULL;
	HKEY hParametersKey = NULL;
	HKEY hAppKey = NULL;
	
	if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE", 0, KEY_WRITE|KEY_READ,
		&hServicesKey) == ERROR_SUCCESS)
	{
		DWORD dw;
		if (RegCreateKeyEx(hServicesKey, m_sServiceName, 0, REG_NONE,
			REG_OPTION_NON_VOLATILE, KEY_WRITE|KEY_READ, NULL,
			&hAppKey, &dw) == ERROR_SUCCESS)
		{
			RegCreateKeyEx(hAppKey, "AuditService", 0, REG_NONE,
				REG_OPTION_NON_VOLATILE, KEY_WRITE|KEY_READ, NULL,
				&hParametersKey, &dw);
		}
	}
	if (hServicesKey != NULL)
		RegCloseKey(hServicesKey);
	if (hAppKey != NULL)
		RegCloseKey(hAppKey);
	
	return hParametersKey;
}

int add_wildcard_start_and_end(char *source, char *dest, int length)
{
	//This routine is simply to add the wildcard "*" to the start and
	//end of a string

      int count=0;
      char *copyofdest;
      copyofdest=dest;

      if(!source || !dest) 
		  return(1);
	  else
	  {	
		  if(count < length)
		  {
			  *dest='*';
			  dest++;
			  count++;
		  }
	  }


      while(*source) 
	  {
		if(count < length)
		{ 
			*dest=*source; 
			dest++; 
			count++; 
		}
		source++;
	  }

      if((count+2) < length)
	  {
		  *dest='*';
		  dest++;
		  *dest='\0';
	  }


	  dest=copyofdest;

      return(0);
}

int remove_wildcard_start_and_end(char *source, char *dest, int length)
{
	//This routine is simply to remove the wildcard "*" to the start and
	//end of a string

      int count=0;
      char *copyofdest;
      copyofdest=dest;

      if(!source || !dest) 
		  return(1);

	  if (*source == '*')
	  {
		  source++;
		  if(count < length)
		  {
			  *dest = *source;
			  dest++;
			  count++;
			  source++;
		  }
	  }

	  while(*source)
	  {
		  if(count < length)
		  {
			  *dest = *source;
			  dest++;
			  count++;
		  }
		  source++;
	  }

	  source--;
	  dest--;
	  count--;
	  if (*source == '*')
	  {
		  if(count < length)
		  {
			  *dest = '\0';
			  dest++;
			  count++;
		  }
	  }



	  dest=copyofdest;

      return(0);
}


void read_event(char *str_buffer,char *SourceName,char *SIDType,char *EventLogType,
				char *ExpandedString,char *DataString,char *ComputerName,char *UserName,
				char *CategoryString,char *DateTime,char *Criticality,char *System,
				char *null,char *EventID)
{
	
	if(str_buffer[0]=='<') 
	{
		// SYSLOG. Slightly different header structure.
		sscanf(str_buffer,"%256[^ ] %256[^ ] %256[^ ] %256[^ ] %256[^\t]\t%2[^\t]\t%100[^\t]\t%256[^\t]\t%100[^\t]\t%10[^\t]\t%100[^\t]\t%256[^\t]\t%100[^\t]\t%50[^\t]\t%256[^\t]\t%256[^\t]\t%1024[^\t]\t%1024s",null,null,null,System,null,Criticality,SourceName,null,DateTime,EventID,SourceName,UserName,SIDType,EventLogType,ComputerName,CategoryString,ExpandedString,DataString);
	} 
	else 
	{
		// WARNING: If the buffer sizes of any of these change, there is a potential for buffer overflow!
		sscanf(str_buffer,"%256[^\t]\t%256[^\t]\t%2[^\t]\t%100[^\t]\t%256[^\t]\t%100[^\t]\t%10[^\t]\t%100[^\t]\t%256[^\t]\t%100[^\t]\t%50[^\t]\t%256[^\t]\t%256[^\t]\t%1024[^\t]\t%1024s",System,null,Criticality,SourceName,null,DateTime,EventID,SourceName,UserName,SIDType,EventLogType,ComputerName,CategoryString,ExpandedString,DataString);
	}

	return;
}

// return 0 for failure
// return 1 for file
// return 2 for directory
int validate_file_or_directory(char *filename)
{
	if(!filename)				return(FALSE);
	if(strlen(filename) < 3)	return(FALSE); // Must be at least "C:\"
	if(!((filename[0] >= 'a' && filename[0] <= 'z') || (filename[0] >= 'A' && filename[0] <= 'Z'))) {
		return(FALSE);
	}
	if(filename[1] != ':')		return(FALSE);
	if(filename[2] != '\\')		return(FALSE);

	// Ok, anything else is fair game.
	DWORD Attributes;
	Attributes=GetFileAttributes(filename);
	if(Attributes == 0xFFFFFFFF) {
		// File or directory does not exist
		return(FALSE);
	}
	if(Attributes & FILE_ATTRIBUTE_DIRECTORY) {
		return(2);
	}

	return(1);
}


// Don't set audit on c:\winnt\system32\msaudite.dll
void WalkPathAndSet(char *dir, PSECURITY_DESCRIPTOR NewSD)
{
	char path[MAX_PATH];
	
	WIN32_FIND_DATA fd;
	// first the files
	HANDLE hFind;
	BOOL more;
	BOOL set=1;
	
	// MAKE SURE that we don't set audit on msaudite.dll
	// if(is msaudite.dll as last path element
	if(strlen(dir) > 12) {
		if(!strcmpi("msaudite.dll",&dir[strlen(dir)-strlen("msaudite.dll")])) {
			char tempdir[256];
			ExpandEnvironmentStrings("%SystemRoot%\\system32\\msaudite.dll",tempdir,256);
			if(!strcmpi(dir,tempdir)) {
				// Dont set attributes
				set=0;
			}
		}
	}
	
	if(set)
	{
		SetFileSecurity(dir,SACL_SECURITY_INFORMATION|SE_SACL_AUTO_INHERIT_REQ|SE_SACL_AUTO_INHERITED,NewSD);
	}
	
	hFind = FindFirstFile(dir,&fd);
	if(hFind == INVALID_HANDLE_VALUE)
		return;
	if(!(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
		return;
		
	_snprintf(path,MAX_PATH,"%s\\*",dir);

	// Set for the current path.
	
	hFind = FindFirstFile(path,&fd);
	more = (hFind!=INVALID_HANDLE_VALUE);

	while(more) {
		_snprintf(path,MAX_PATH,"%s\\%s",dir,fd.cFileName);
		
		if(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
			if(fd.cFileName[0]!='.') {
				WalkPathAndSet(path,NewSD);
			}
		} else {
			// MAKE SURE that we don't set audit on msaudite.dll
			// if(is msaudite.dll as last path element
			set=1;
			if(strlen(path) > 12) {
				if(!strcmpi("msaudite.dll",&path[strlen(path)-strlen("msaudite.dll")])) {
					char tempdir[256];
					ExpandEnvironmentStrings("%SystemRoot%\\system32\\msaudite.dll",tempdir,256);
					if(!strcmpi(path,tempdir)) {
						// Dont set attributes
						set=0;
					}
				}
			}
			if(set) {
				SetFileSecurity(path,SACL_SECURITY_INFORMATION|SE_SACL_AUTO_INHERIT_REQ|SE_SACL_AUTO_INHERITED,NewSD);
			}
		}
		more=FindNextFile(hFind,&fd);
	}
	FindClose(hFind);
}


BOOL EnableSecurityName() {

   // A process that tries to read or write a SACL needs
   // to have and enable the SE_SECURITY_NAME privilege.
   
   LUID   SecurityNameValue;
   HANDLE hToken;
   TOKEN_PRIVILEGES tp;

   if (!OpenProcessToken(GetCurrentProcess(),
         TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) {
      return FALSE;
   }

   if (!LookupPrivilegeValue(NULL, SE_SECURITY_NAME,
         &SecurityNameValue)) {
      return FALSE;
   }

   tp.PrivilegeCount = 1;
   tp.Privileges[0].Luid = SecurityNameValue;
   tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

   if (!AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(tp),
         NULL, NULL)) {
      return FALSE;
   }

   return TRUE;
}

BOOL AddEveryoneAceToFileSacl(char * strFileName,
      DWORD dwAccessMask) {

   BOOL  bReturn   = FALSE;
   PSID  psidWorld = NULL;
   PACL  pNewACL   = NULL;
   DWORD dwNewACLSize;
   UCHAR NewSD[SECURITY_DESCRIPTOR_MIN_LENGTH];

   SID_IDENTIFIER_AUTHORITY authWorld = SECURITY_WORLD_SID_AUTHORITY;

   __try {

      // Build the "Everyone" SID
      if (!AllocateAndInitializeSid(&authWorld, 1, SECURITY_WORLD_RID,
            0, 0, 0, 0, 0, 0, 0, &psidWorld)) {
         __leave;
      }

      // Initialize new SD
      if (!InitializeSecurityDescriptor(&NewSD,
            SECURITY_DESCRIPTOR_REVISION)) {
         __leave;
      }

      // Compute size needed for the new ACL
      dwNewACLSize = sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) 
            + GetLengthSid(psidWorld) - sizeof(DWORD);
 
      // Allocate memory for new ACL
      pNewACL = (PACL) HeapAlloc(GetProcessHeap(), 0, dwNewACLSize);
      if (!pNewACL) {
         __leave;
      }

      // Initialize the new ACL
      if (!InitializeAcl(pNewACL, dwNewACLSize, ACL_REVISION2)) {
         __leave;
      }
 
	  // _WIN32_WINNT >= 0x0500
		if(IsNT5()) {
			// WIN2k PRO and Above
			// Add the audit ACE to the new SACL
			if (!AddAuditAccessAceEx(pNewACL, ACL_REVISION2,
				CONTAINER_INHERIT_ACE | FAILED_ACCESS_ACE_FLAG | INHERITED_ACE | OBJECT_INHERIT_ACE | SUCCESSFUL_ACCESS_ACE_FLAG,
				dwAccessMask, psidWorld, TRUE /* Audit Success */,
					TRUE /* Audit Failure */)) {
				__leave;
			}
		} else {
			// WINDOWS NT
			// Add the audit ACE to the new SACL
			if (!AddAuditAccessAce(pNewACL, ACL_REVISION2,
				dwAccessMask, psidWorld, TRUE /* Audit Success */,
				TRUE /* Audit Failure */)) {
					__leave;
			}
		}


      // Add the SACL to the new SD
      if (!SetSecurityDescriptorSacl(&NewSD, TRUE, pNewACL, FALSE)) {
         __leave;
      }

		// Set the security on the service using the new SD

		WalkPathAndSet(strFileName,&NewSD);
	  

      bReturn = TRUE;
   }

   __finally
   {
      // Free the allocated SID.
      if (psidWorld) FreeSid(psidWorld);

      // Free the memory allocated for the new ACL.
      if (pNewACL) HeapFree(GetProcessHeap(), 0, pNewACL);
   }

   return bReturn;
}

BOOL IsNT5(void) {
	DWORD winVer;
	BOOL returncode=FALSE;
	winVer=GetVersion();
	if(winVer<0x80000000) {
		OSVERSIONINFO *osvi;
		osvi=(OSVERSIONINFO *)malloc(sizeof(OSVERSIONINFO));
		if(osvi!=NULL) {
			memset(osvi,0,sizeof(OSVERSIONINFO));
			osvi->dwOSVersionInfoSize=sizeof(OSVERSIONINFO);
			GetVersionEx(osvi);
			if(osvi->dwMajorVersion>=5) {
				returncode=TRUE;
			}
			free(osvi);
		}
	}
	return(returncode);
}