// SSOInstallLogic.cpp : Defines the initialization routines for the DLL.
//

#include "stdafx.h"
#include "SSOInstallLogic.h"
#include <string>
using namespace std;
#ifdef _DEBUG
#define new DEBUG_NEW
#endif

//
//TODO: If this DLL is dynamically linked against the MFC DLLs,
//		any functions exported from this DLL which call into
//		MFC must have the AFX_MANAGE_STATE macro added at the
//		very beginning of the function.
//
//		For example:
//
//		extern "C" BOOL PASCAL EXPORT ExportedFunction()
//		{
//			AFX_MANAGE_STATE(AfxGetStaticModuleState());
//			// normal function body here
//		}
//
//		It is very important that this macro appear in each
//		function, prior to any calls into MFC.  This means that
//		it must appear as the first statement within the 
//		function, even before any object variable declarations
//		as their constructors may generate calls into the MFC
//		DLL.
//
//		Please see MFC Technical Notes 33 and 58 for additional
//		details.
//


// CSSOInstallLogicApp

BEGIN_MESSAGE_MAP(CSSOInstallLogicApp, CWinApp)
END_MESSAGE_MAP()


// CSSOInstallLogicApp construction

CSSOInstallLogicApp::CSSOInstallLogicApp()
{
	// TODO: add construction code here,
	// Place all significant initialization in InitInstance
}


// The one and only CSSOInstallLogicApp object

CSSOInstallLogicApp theApp;


// CSSOInstallLogicApp initialization

BOOL CSSOInstallLogicApp::InitInstance()
{
	CWinApp::InitInstance();

	return TRUE;
}

LONG AddGinaSSOasActive(HKEY a_hKey)
{
	WCHAR* lszCustomGinaValue = L"GinaSSO.dll";
	DWORD l_dwCustomGinaValueSize = (DWORD)wcslen(lszCustomGinaValue );	
	LONG l_RetVal = RegSetValueEx(a_hKey,L"GinaDll",0,REG_SZ,(LPBYTE)lszCustomGinaValue ,l_dwCustomGinaValueSize*2);
	return l_RetVal;
}
UINT __stdcall Unchain( MSIHANDLE hModule )
{
	//1. see if there was a custom Gina before GinaSSO
	LONG returnStatus;
	HKEY hOriginalKey;
	HKEY hKey;
	WCHAR lszOriginalCustomGinaValue[MAX_PATH];
	DWORD dwSize=MAX_PATH;
	DWORD dwType=REG_SZ;
	DWORD l_dwSize = MAX_PATH;
	DWORD l_dwOutSize = MAX_PATH;
	WCHAR* l_pwstrStoringKeybuf = new WCHAR[l_dwSize];
	UINT res = MsiGetProperty(hModule ,MSI_CUSTOM_ACTION_DATA_PROPERTY_NAME,l_pwstrStoringKeybuf,&l_dwSize); 
	wstring 	l_strStoringKeybuf = L"SOFTWARE\\";
	l_strStoringKeybuf = l_strStoringKeybuf+ l_pwstrStoringKeybuf+ L"\\SSO";
	returnStatus = RegOpenKeyEx(HKEY_LOCAL_MACHINE, l_strStoringKeybuf.c_str(), 0L,  KEY_ALL_ACCESS, 
								&hOriginalKey);
	if (returnStatus == ERROR_SUCCESS)
	{
		returnStatus = RegQueryValueEx(hOriginalKey, ORIGINAL_CUSTOM_GINA_REGISTY_VALUE_NAME, 
			NULL, &dwType,(LPBYTE)&lszOriginalCustomGinaValue, &dwSize);
	}
	//2. if yes- restore it under winlogon\GinaDll
	if (returnStatus == ERROR_SUCCESS && (wcscmp(lszOriginalCustomGinaValue,L"")!=0))
	{
		returnStatus = RegOpenKeyEx(HKEY_LOCAL_MACHINE, CUSTOM_GINA_REGISTY_PATH, 0L,  KEY_ALL_ACCESS, &hKey);
		returnStatus = RegSetValueEx(hKey,L"GinaDll",0,REG_SZ,(LPBYTE)lszOriginalCustomGinaValue ,dwSize);
		RegCloseKey(hKey);
		//delete save key is done by uninstall automatically
		RegCloseKey(hOriginalKey);
	}
	else
	{
		//2a. if no - delete winlogon\GinaDll value
		returnStatus = RegOpenKeyEx(HKEY_LOCAL_MACHINE, CUSTOM_GINA_REGISTY_PATH, 0L,  KEY_ALL_ACCESS, &hKey);
		returnStatus = RegDeleteValue(hKey,L"GinaDll");
		RegCloseKey(hKey);
	}
	return returnStatus ;
}
UINT __stdcall ChainCustomGinas ( MSIHANDLE hModule )
{
	//1. read custom gina key
	WCHAR lszOriginalCustomGinaValue[MAX_PATH];
    HKEY hKey;
    LONG returnStatus;
    DWORD dwType=REG_SZ;
    DWORD dwSize=MAX_PATH;
    returnStatus = RegOpenKeyEx(HKEY_LOCAL_MACHINE, CUSTOM_GINA_REGISTY_PATH, 0L,  KEY_ALL_ACCESS, &hKey);
    if (returnStatus == ERROR_SUCCESS)
    {
		returnStatus = RegQueryValueEx(hKey, CUSTOM_GINA_REGISTY_VALUE_NAME, NULL, &dwType,(LPBYTE)&lszOriginalCustomGinaValue, &dwSize);
		if (returnStatus != ERROR_SUCCESS)
		{
			//no original custom gina installed
			AddGinaSSOasActive(hKey);
			RegCloseKey(hKey);
			return ERROR_SUCCESS ;
		}
    }
	else
	{
		//smth wrong with registry/windows installation
		MessageBox(NULL,L"Can't istall custom Gina - check windows installation",L"Qumranet",MB_OK);
		return returnStatus;
	}
	AddGinaSSOasActive(hKey);
    RegCloseKey(hKey);

	//2. store its value under the manufacturer key - original custom gina - only if the porevious one is not Qumranet's
	if(wcscmp(lszOriginalCustomGinaValue,L"GinaSSO.dll")!=0)
	{
		DWORD l_dwSize = MAX_PATH;
		WCHAR* l_pwstrStoringKeybuf = new WCHAR[l_dwSize];
		UINT res = MsiGetProperty(hModule ,MSI_CUSTOM_ACTION_DATA_PROPERTY_NAME,l_pwstrStoringKeybuf,&l_dwSize); 
		wstring 	l_strStoringKeybuf = L"SOFTWARE\\";
		l_strStoringKeybuf = l_strStoringKeybuf+ l_pwstrStoringKeybuf+ L"\\SSO";
		if (returnStatus == ERROR_SUCCESS)
		{
			returnStatus = RegOpenKeyEx(HKEY_LOCAL_MACHINE, l_strStoringKeybuf.c_str(), 0L,  KEY_ALL_ACCESS, &hKey);
			returnStatus = RegSetValueEx(hKey,ORIGINAL_CUSTOM_GINA_REGISTY_VALUE_NAME,0,REG_SZ,(LPBYTE)&lszOriginalCustomGinaValue,dwSize);
			RegCloseKey(hKey);
		}
	}
    return returnStatus ;
}