// DotNetAppLauncher.cpp : Defines the entry point for the application.
//

#include "stdafx.h"
#include "DotNetAppLauncher.h"

#include "..\\..\\..\\..\\BoxedAppSDK\\include\\BoxedAppSDK.h"
#pragma comment(lib, "..\\..\\..\\..\\BoxedAppSDK\\lib\\bxsdk32.lib")

#include <mscoree.h>
#include <atlbase.h>

#include <string>
typedef std::basic_string<TCHAR> tstring;

// Load resource helper
void LoadResourceHelper( /* in */ LPCTSTR lpszName, 
                         /* in */ LPCTSTR lpszType, 
                         /* out */ LPVOID& lpData, 
                         /* out */ DWORD& dwSize)
{
    HMODULE hModule = GetModuleHandle(NULL);
    HRSRC hResInfo = FindResource(hModule, lpszName, lpszType);
    HGLOBAL hResData = LoadResource(hModule, hResInfo);
    lpData = LockResource(hResData);
    dwSize = SizeofResource(hModule, hResInfo);
}

void CreateVirtualFileFromResource(LPCTSTR szVirtualPath, LPCTSTR szResName, LPCTSTR szResType)
{
	DWORD temp;

	LPVOID pData;
	DWORD dwSize;

	LoadResourceHelper(szResName, szResType, pData, dwSize);

	ATLASSERT(NULL != pData);

	HANDLE hFile = BoxedAppSDK_CreateVirtualFile(szVirtualPath, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_NEW, 0, NULL);
	WriteFile(hFile, pData, dwSize, &temp, NULL);
	CloseHandle(hFile);
}

int APIENTRY _tWinMain(HINSTANCE hInstance,
                       HINSTANCE hPrevInstance,
                       LPTSTR lpCmdLine,
                       int nCmdShow)
{
	CoInitialize(NULL);

	BoxedAppSDK_Init();

	tstring strDotNetRoot = _T("C:\\DotNet");

	{
		DWORD dwDisposition;
		HKEY hKey__DotNet;
		LONG lRes = 
		BoxedAppSDK_CreateVirtualRegKey(
			HKEY_LOCAL_MACHINE, 
			_T("SOFTWARE\\Microsoft\\.NETFramework"), 
			0, 
			NULL, 
			REG_OPTION_NON_VOLATILE, 
			KEY_ALL_ACCESS, 
			NULL, 
			&hKey__DotNet, 
			&dwDisposition);
		{
			LPCTSTR szValue = _T("C:\\DotNet\\");
			RegSetValueEx(hKey__DotNet, _T("InstallRoot"), 0, REG_SZ, (CONST BYTE*)szValue, (lstrlen(szValue) + 1) * sizeof(TCHAR));
		}

		lRes = 
		BoxedAppSDK_CreateVirtualRegKey(
			HKEY_LOCAL_MACHINE, 
			_T("COMPONENTS\\Winners\\x86_policy.8.0.microsoft.vc80.crt_1fc8b3b9a1e18e3b_none_e8a8ec119a3821e7"), 
			0, 
			NULL, 
			REG_OPTION_NON_VOLATILE, 
			KEY_ALL_ACCESS, 
			NULL, 
			&hKey__DotNet, 
			&dwDisposition);
		{
			LPCTSTR szValue = _T("8.0");
			RegSetValueEx(hKey__DotNet, _T(""), 0, REG_SZ, (CONST BYTE*)szValue, (lstrlen(szValue) + 1) * sizeof(TCHAR));
		}
		lRes = 
		BoxedAppSDK_CreateVirtualRegKey(
			HKEY_LOCAL_MACHINE, 
			_T("COMPONENTS\\Winners\\x86_policy.8.0.microsoft.vc80.crt_1fc8b3b9a1e18e3b_none_e8a8ec119a3821e7\\8.0"), 
			0, 
			NULL, 
			REG_OPTION_NON_VOLATILE, 
			KEY_ALL_ACCESS, 
			NULL, 
			&hKey__DotNet, 
			&dwDisposition);
		{
			LPCTSTR szValue = _T("8.0.50727.1434");
			RegSetValueEx(hKey__DotNet, _T(""), 0, REG_SZ, (CONST BYTE*)szValue, (lstrlen(szValue) + 1) * sizeof(TCHAR));

			BYTE value[] = { 1 };
			RegSetValueEx(hKey__DotNet, _T("8.0.50727.1434"), 0, REG_BINARY, (CONST BYTE*)value, sizeof(value));
		}
		RegCloseKey(hKey__DotNet);

		lRes = 
		BoxedAppSDK_CreateVirtualRegKey(
			HKEY_LOCAL_MACHINE, 
			_T("COMPONENTS\\Winners\\x86_microsoft.vc80.crt_1fc8b3b9a1e18e3b_none_bcc8f3fc9457ed28"), 
			0, 
			NULL, 
			REG_OPTION_NON_VOLATILE, 
			KEY_ALL_ACCESS, 
			NULL, 
			&hKey__DotNet, 
			&dwDisposition);
		{
			LPCTSTR szValue = _T("8.0");
			RegSetValueEx(hKey__DotNet, _T(""), 0, REG_SZ, (CONST BYTE*)szValue, (lstrlen(szValue) + 1) * sizeof(TCHAR));
		}
		lRes = 
		BoxedAppSDK_CreateVirtualRegKey(
			HKEY_LOCAL_MACHINE, 
			_T("COMPONENTS\\Winners\\x86_microsoft.vc80.crt_1fc8b3b9a1e18e3b_none_bcc8f3fc9457ed28\\8.0"), 
			0, 
			NULL, 
			REG_OPTION_NON_VOLATILE, 
			KEY_ALL_ACCESS, 
			NULL, 
			&hKey__DotNet, 
			&dwDisposition);
		{
			LPCTSTR szValue = _T("8.0.50727.1434");
			RegSetValueEx(hKey__DotNet, _T(""), 0, REG_SZ, (CONST BYTE*)szValue, (lstrlen(szValue) + 1) * sizeof(TCHAR));

			BYTE value[] = { 1 };
			RegSetValueEx(hKey__DotNet, _T("8.0.50727.1434"), 0, REG_BINARY, (CONST BYTE*)value, sizeof(value));
		}
		RegCloseKey(hKey__DotNet);

		lRes = 
		BoxedAppSDK_CreateVirtualRegKey(
			HKEY_LOCAL_MACHINE, 
			_T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\SideBySide\\Winners\\x86_policy.8.0.microsoft.vc80.crt_1fc8b3b9a1e18e3b_none_e8a8ec119a3821e7"), 
			0, 
			NULL, 
			REG_OPTION_NON_VOLATILE, 
			KEY_ALL_ACCESS, 
			NULL, 
			&hKey__DotNet, 
			&dwDisposition);
		{
			LPCTSTR szValue = _T("8.0");
			RegSetValueEx(hKey__DotNet, _T(""), 0, REG_SZ, (CONST BYTE*)szValue, (lstrlen(szValue) + 1) * sizeof(TCHAR));
		}
		RegCloseKey(hKey__DotNet);
		lRes = 
		BoxedAppSDK_CreateVirtualRegKey(
			HKEY_LOCAL_MACHINE, 
			_T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\SideBySide\\Winners\\x86_policy.8.0.microsoft.vc80.crt_1fc8b3b9a1e18e3b_none_e8a8ec119a3821e7\\8.0"), 
			0, 
			NULL, 
			REG_OPTION_NON_VOLATILE, 
			KEY_ALL_ACCESS, 
			NULL, 
			&hKey__DotNet, 
			&dwDisposition);
		{
			LPCTSTR szValue = _T("8.0.50727.1434");
			RegSetValueEx(hKey__DotNet, _T(""), 0, REG_SZ, (CONST BYTE*)szValue, (lstrlen(szValue) + 1) * sizeof(TCHAR));

			BYTE value[] = { 1 };
			RegSetValueEx(hKey__DotNet, _T("8.0.50727.1434"), 0, REG_BINARY, (CONST BYTE*)value, sizeof(value));
		}
		RegCloseKey(hKey__DotNet);

		lRes = 
		BoxedAppSDK_CreateVirtualRegKey(
			HKEY_LOCAL_MACHINE, 
			_T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\SideBySide\\Winners\\x86_microsoft.vc80.crt_1fc8b3b9a1e18e3b_none_bcc8f3fc9457ed28"), 
			0, 
			NULL, 
			REG_OPTION_NON_VOLATILE, 
			KEY_ALL_ACCESS, 
			NULL, 
			&hKey__DotNet, 
			&dwDisposition);
		RegCloseKey(hKey__DotNet);		
		lRes = 
		BoxedAppSDK_CreateVirtualRegKey(
			HKEY_LOCAL_MACHINE, 
			_T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\SideBySide\\Winners\\x86_microsoft.vc80.crt_1fc8b3b9a1e18e3b_none_bcc8f3fc9457ed28\\8.0"), 
			0, 
			NULL, 
			REG_OPTION_NON_VOLATILE, 
			KEY_ALL_ACCESS, 
			NULL, 
			&hKey__DotNet, 
			&dwDisposition);
		{
			LPCTSTR szValue = _T("8.0.50727.1434");
			RegSetValueEx(hKey__DotNet, _T(""), 0, REG_SZ, (CONST BYTE*)szValue, (lstrlen(szValue) + 1) * sizeof(TCHAR));

			BYTE value[] = { 1 };
			RegSetValueEx(hKey__DotNet, _T("8.0.50727.1434"), 0, REG_BINARY, (CONST BYTE*)value, sizeof(value));
		}
		RegCloseKey(hKey__DotNet);

		lRes = 
		BoxedAppSDK_CreateVirtualRegKey(
			HKEY_LOCAL_MACHINE, 
			_T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\SideBySide\\Winners\\x86_microsoft.vc80.crt_1fc8b3b9a1e18e3b_none_bcc8f3fc9457ed28"), 
			0, 
			NULL, 
			REG_OPTION_NON_VOLATILE, 
			KEY_ALL_ACCESS, 
			NULL, 
			&hKey__DotNet, 
			&dwDisposition);
		RegCloseKey(hKey__DotNet);		
		lRes = 
		BoxedAppSDK_CreateVirtualRegKey(
			HKEY_LOCAL_MACHINE, 
			_T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\SideBySide\\Winners\\x86_microsoft.vc80.crt_1fc8b3b9a1e18e3b_none_bcc8f3fc9457ed28\\8.0"), 
			0, 
			NULL, 
			REG_OPTION_NON_VOLATILE, 
			KEY_ALL_ACCESS, 
			NULL, 
			&hKey__DotNet, 
			&dwDisposition);
		{
			LPCTSTR szValue = _T("8.0.50727.1434");
			RegSetValueEx(hKey__DotNet, _T(""), 0, REG_SZ, (CONST BYTE*)szValue, (lstrlen(szValue) + 1) * sizeof(TCHAR));

			BYTE value[] = { 1 };
			RegSetValueEx(hKey__DotNet, _T("8.0.50727.1434"), 0, REG_BINARY, (CONST BYTE*)value, sizeof(value));
		}
		RegCloseKey(hKey__DotNet);
	}

	TCHAR szWinDir[MAX_PATH] = { 0 };
	GetWindowsDirectory(szWinDir, MAX_PATH);
	tstring strWinDir = szWinDir;

	TCHAR szSystemDir[1024] = { 0 };
	GetSystemDirectory(szSystemDir, MAX_PATH);
	tstring strSystemDir = szSystemDir;

	struct SFileResInfo
	{
		tstring strVirtualPath;
		LPCTSTR szResName;
	};

	const SFileResInfo ResInfo[] = 
	{
		{ strSystemDir + _T("\\mscoree.dll"), _T("mscoree.dll") }, 

		{ strDotNetRoot + _T("\\v2.0.50727\\mscorjit.dll"), _T("mscorjit.dll") }, 

		{ strDotNetRoot + _T("\\v2.0.50727\\mscorwks.dll"), _T("mscorwks.dll") }, 

		{ strWinDir + _T("\\WinSxS\\x86_Microsoft.Windows.Common-Controls_6595b64144ccf1df_6.0.2600.2982_x-ww_ac3f9c03\\comctl32.dll"), _T("comctl32.dll") }, 
		{ strSystemDir + _T("\\comctl32.dll"), _T("comctl32.dll") }, 

		{ strWinDir + _T("\\WinSxS\\x86_Microsoft.VC80.CRT_1fc8b3b9a1e18e3b_8.0.50727.1433_x-ww_5cf844d2\\msvcr80.dll"), _T("msvcr80.dll") }, 
		{ strSystemDir + _T("\\msvcr80.dll"), _T("msvcr80.dll") }, 
		{ strDotNetRoot + _T("\\v2.0.50727\\msvcr80.dll"), _T("msvcr80.dll") }, 

		{ strWinDir + _T("\\assembly\\GAC_MSIL\\System.Windows.Forms\\2.0.0.0__b77a5c561934e089\\System.Windows.Forms.dll"), _T("System.Windows.Forms.dll") }, 

		{ strWinDir + _T("\\assembly\\GAC_32\\mscorlib\\2.0.0.0__b77a5c561934e089\\mscorlib.dll"), _T("mscorlib.dll") }, 

		{ strDotNetRoot + _T("\\v2.0.50727\\mscorrc.dll"), _T("mscorrc.dll") }, 

		{ strWinDir + _T("\\assembly\\GAC_32\\mscorlib\\2.0.0.0__b77a5c561934e089\\sorttbls.nlp"), _T("sorttbls.nlp") }, 
		{ strWinDir + _T("\\assembly\\GAC_32\\mscorlib\\2.0.0.0__b77a5c561934e089\\sortkey.nlp"), _T("sortkey.nlp") }, 

		{ strDotNetRoot + _T("\\v2.0.50727\\System.dll"), _T("System.dll") }, 

		{ strDotNetRoot + _T("\\v2.0.50727\\System.Data.dll"), _T("System.Data.dll") }, 
		{ strDotNetRoot + _T("\\v2.0.50727\\System.Drawing.dll"), _T("System.Drawing.dll") }, 

		{ strDotNetRoot + _T("\\v2.0.50727\\Culture.dll"), _T("Culture.dll") }, 

		{ strWinDir + _T("\\assembly\\GAC_MSIL\\System\\2.0.0.0__b77a5c561934e089\\System.dll"), _T("System.dll") }, 
		{ strWinDir + _T("\\assembly\\GAC_MSIL\\System.Drawing\\2.0.0.0__b03f5f7f11d50a3a\\System.Drawing.dll"), _T("System.Drawing.dll") }, 

		{ strDotNetRoot + _T("\\v2.0.50727\\Accessibility.dll"), _T("Accessibility.dll") }, 
		{ strWinDir + _T("\\assembly\\GAC_MSIL\\Accessibility\\2.0.0.0__b03f5f7f11d50a3a\\Accessibility.dll"), _T("Accessibility.dll") }, 

		{ strSystemDir + _T("\\GdiPlus.dll"), _T("GdiPlus.dll") }, 

		{ strWinDir + _T("\\WinSxS\\Manifests\\x86_Microsoft.VC80.CRT_1fc8b3b9a1e18e3b_8.0.50727.1433_x-ww_5cf844d2.manifest"), _T("x86_Microsoft.VC80.CRT_1fc8b3b9a1e18e3b_8.0.50727.1433_x-ww_5cf844d2.manifest") }, 

		{ _T("C:\\AppLauncher.dll"), _T("AppLauncher.dll") }, 
		{ _T("C:\\WindowsApplication1.exe"), _T("WindowsApplication1.exe") }, 

		{ strWinDir + _T("\\WinSxS\\Policies\\x86_policy.8.0.Microsoft.VC80.CRT_1fc8b3b9a1e18e3b_x-ww_77c24773\\8.0.50727.1433.cat"), _T("_8_0_50727_1433_cat") }, 
		{ strWinDir + _T("\\WinSxS\\Policies\\x86_policy.8.0.Microsoft.VC80.CRT_1fc8b3b9a1e18e3b_x-ww_77c24773\\8.0.50727.1433.policy"), _T("_8_0_50727_1433_policy") }, 
		{ strWinDir + _T("\\WinSxS\\Policies\\x86_policy.8.0.Microsoft.VC80.CRT_1fc8b3b9a1e18e3b_x-ww_77c24773\\8.0.50727.163.cat"), _T("_8_0_50727_163_cat") }, 
		{ strWinDir + _T("\\WinSxS\\Policies\\x86_policy.8.0.Microsoft.VC80.CRT_1fc8b3b9a1e18e3b_x-ww_77c24773\\8.0.50727.163.policy"), _T("_8_0_50727_163_policy") }, 
		{ strWinDir + _T("\\WinSxS\\Policies\\x86_policy.8.0.Microsoft.VC80.CRT_1fc8b3b9a1e18e3b_x-ww_77c24773\\8.0.50727.42.cat"), _T("_8_0_50727_42_cat") }, 
		{ strWinDir + _T("\\WinSxS\\Policies\\x86_policy.8.0.Microsoft.VC80.CRT_1fc8b3b9a1e18e3b_x-ww_77c24773\\8.0.50727.42.policy"), _T("_8_0_50727_42_policy") }, 
		{ strWinDir + _T("\\WinSxS\\Policies\\x86_policy.8.0.Microsoft.VC80.CRT_1fc8b3b9a1e18e3b_x-ww_77c24773\\8.0.50727.762.cat"), _T("_8_0_50727_762_cat") }, 
		{ strWinDir + _T("\\WinSxS\\Policies\\x86_policy.8.0.Microsoft.VC80.CRT_1fc8b3b9a1e18e3b_x-ww_77c24773\\8.0.50727.762.policy"), _T("_8_0_50727_762_policy") }, 

		{ strWinDir + _T("\\WinSxS\\Manifests\\x86_policy.8.0.microsoft.vc80.crt_1fc8b3b9a1e18e3b_8.0.50727.1434_none_516c10c30f4aae68.manifest"), _T("x86_policy.8.0.microsoft.vc80.crt_1fc8b3b9a1e18e3b_8.0.50727.1434_none_516c10c30f4aae68.manifest_") }, 
		{ strWinDir + _T("\\WinSxS\\Manifests\\x86_microsoft.vc80.crt_1fc8b3b9a1e18e3b_8.0.50727.1434_none_d08b6002442c891f.manifest"), _T("x86_microsoft.vc80.crt_1fc8b3b9a1e18e3b_8.0.50727.1434_none_d08b6002442c891f.manifest_") }, 
		
		{ strWinDir + _T("\\WinSxS\\x86_microsoft.vc80.crt_1fc8b3b9a1e18e3b_8.0.50727.1434_none_d08b6002442c891f\\msvcr80.dll"), _T("msvcr80.dll") }, 

	};

	for (int i = 0; i < sizeof(ResInfo) / sizeof(ResInfo[0]); i++)
		CreateVirtualFileFromResource(ResInfo[i].strVirtualPath.c_str(), ResInfo[i].szResName, _T("BIN"));

	HMODULE hMSCoree = LoadLibrary((strSystemDir + _T("\\mscoree.dll")).c_str());

	typedef HRESULT (__stdcall *P_CorBindToRuntimeEx)(LPCWSTR pwszVersion, LPCWSTR pwszBuildFlavor, DWORD startupFlags, REFCLSID rclsid, REFIID riid, LPVOID FAR *ppv);
	P_CorBindToRuntimeEx pCorBindToRuntimeEx = (P_CorBindToRuntimeEx)GetProcAddress(hMSCoree, "CorBindToRuntimeEx");

	ICLRRuntimeHost* pCLRRuntimeHost = NULL;
	pCorBindToRuntimeEx(L"v2.0.50727", NULL, 0, CLSID_CLRRuntimeHost, IID_ICLRRuntimeHost, (void**)&pCLRRuntimeHost);

	pCLRRuntimeHost->Start();

	DWORD nRetValue;
	pCLRRuntimeHost->ExecuteInDefaultAppDomain(
		L"C:\\AppLauncher.dll", 
		L"AppLauncher.Launcher", 
		L"Launch", 
		L"C:\\WindowsApplication1.exe", 
		&nRetValue);

	pCLRRuntimeHost->Stop();

	pCLRRuntimeHost->Release();

	FreeLibrary(hMSCoree);

	CoUninitialize();

	BoxedAppSDK_Exit();

	return 0;
}
