/**************************************************************
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
 *************************************************************/



#include "precompiled_desktop.hxx"

#define  UNICODE    1
#define _UNICODE    1

#ifndef _WINDOWS_
#	define WIN32_LEAN_AND_MEAN
#if defined _MSC_VER
#pragma warning(push, 1)
#endif
#	include <windows.h>
#	include <shellapi.h>
#	include <wchar.h>
#if defined _MSC_VER
#pragma warning(pop)
#endif
#endif

#include "Resource.h"
#include <time.h>
#include "sal/config.h"
#include "tools/pathutils.hxx"

const DWORD PE_Signature = 0x00004550;

#define MY_LENGTH(s)		(sizeof (s) / sizeof *(s) - 1)
#define MY_STRING(s)		(s), MY_LENGTH(s)
#define MAX_STR_CAPTION		256
#define MAX_TEXT_LENGTH     1024

static void failPath(wchar_t* pszAppTitle, wchar_t* pszMsg)
{
    MessageBoxW(NULL, pszMsg, pszAppTitle, MB_OK | MB_ICONERROR);
    TerminateProcess(GetCurrentProcess(), 255);
}

static void fail()
{
    LPWSTR buf = NULL;
    FormatMessageW(
        FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL,
        GetLastError(), 0, reinterpret_cast< LPWSTR >(&buf), 0, NULL);
    MessageBoxW(NULL, buf, NULL, MB_OK | MB_ICONERROR);
    LocalFree(buf);
    TerminateProcess(GetCurrentProcess(), 255);
}

static LPVOID getVirtualBaseAddress( wchar_t* pszFilePath )
{
    HANDLE                hFile;
    HANDLE                hFileMapping;
    LPVOID				  lpFileBase = 0;
    PIMAGE_DOS_HEADER     lpDosHeader;
	PIMAGE_NT_HEADERS     lpNTHeader;

    hFile = CreateFile(pszFilePath,
					   GENERIC_READ, FILE_SHARE_READ, NULL,
                       OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,
					   0);

    if ( hFile == INVALID_HANDLE_VALUE )
    {
        return NULL;
	}

    hFileMapping = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
    if ( hFileMapping == 0 )
    {
		CloseHandle(hFile);
        return NULL;
	}

    lpFileBase = MapViewOfFile(hFileMapping, FILE_MAP_READ, 0, 0, 0);
    if ( lpFileBase == 0 )
    {
        CloseHandle(hFileMapping);
        CloseHandle(hFile);
        return NULL;
    }

    lpDosHeader = (PIMAGE_DOS_HEADER)lpFileBase;
    if ( lpDosHeader->e_magic == IMAGE_DOS_SIGNATURE )
    {
		lpNTHeader = (PIMAGE_NT_HEADERS)((char*)lpDosHeader + lpDosHeader->e_lfanew);
		if (lpNTHeader->Signature == PE_Signature )
			lpFileBase = reinterpret_cast<LPVOID>( lpNTHeader->OptionalHeader.ImageBase );
	}

	UnmapViewOfFile(lpFileBase);
    CloseHandle(hFileMapping);
    CloseHandle(hFile);

	return lpFileBase;
}

static bool checkImageVirtualBaseAddress(wchar_t* pszFilePath, LPVOID lpVBA)
{
	LPVOID lpImageVBA = getVirtualBaseAddress(pszFilePath);
	if ( lpImageVBA == lpVBA )
		return true;
	else
		return false;
}

static wchar_t* getBrandPath(wchar_t * pszPath)
{
    DWORD n = GetModuleFileNameW(NULL, pszPath, MAX_PATH);
    if (n == 0 || n >= MAX_PATH) {
        exit(EXIT_FAILURE);
    }
    return tools::filename(pszPath);
}

extern "C" int APIENTRY WinMain( HINSTANCE hInst, HINSTANCE, LPSTR, int )
{
    wchar_t* pAppTitle = new wchar_t[ MAX_STR_CAPTION ];
			 pAppTitle[0]  = '\0';
	LoadString( hInst, IDS_APP_TITLE, pAppTitle, MAX_STR_CAPTION );

    wchar_t* pTextServer = new wchar_t[ MAX_TEXT_LENGTH ];
			 pTextServer[0]  = '\0';
	LoadString( hInst, IDS_MSG_OPTIMIZED_FOR_SERVER, pTextServer, MAX_TEXT_LENGTH );

    wchar_t* pTextClient = new wchar_t[ MAX_TEXT_LENGTH ];
			 pTextClient[0]  = '\0';
	LoadString( hInst, IDS_MSG_OPTIMIZED_FOR_CLIENT, pTextClient, MAX_TEXT_LENGTH );

    wchar_t* pTextNoInstallation = new wchar_t[ MAX_TEXT_LENGTH ];
			 pTextNoInstallation[0]  = '\0';
	LoadString( hInst, IDS_MSG_NO_INSTALLATION_FOUND, pTextNoInstallation, MAX_TEXT_LENGTH );

	LPVOID  VBA = (void*)0x10000000;
	wchar_t path[MAX_PATH];

	wchar_t * pathEnd = getBrandPath(path);

	if (tools::buildPath(path, path, pathEnd, MY_STRING(L"libxml2.dll")) == NULL)
		fail();
	bool bFast = checkImageVirtualBaseAddress(path, VBA);

	if (tools::buildPath(path, path, pathEnd, MY_STRING(L"..\\basis-link")) == NULL)
		fail();
	pathEnd = tools::resolveLink(path);

	if (pathEnd == NULL)
		failPath(pAppTitle, pTextNoInstallation);

	if (tools::buildPath(path, path, pathEnd, MY_STRING(L"\\program\\vclmi.dll")) == NULL)
		fail();
	bFast &= checkImageVirtualBaseAddress(path, VBA);

	if (tools::buildPath(path, path, pathEnd, MY_STRING(L"\\ure-link")) == NULL)
		fail();
	pathEnd = tools::resolveLink(path);

	if (pathEnd == NULL)
		failPath(pAppTitle, pTextNoInstallation);

	if (tools::buildPath(path, path, pathEnd, MY_STRING(L"\\bin\\sal3.dll")) == NULL)
		fail();
	bFast &= checkImageVirtualBaseAddress(path, VBA);

	const wchar_t* pOutput = pTextClient;
	if (!bFast)
		pOutput = pTextServer;

	MessageBoxW( NULL, pOutput, pAppTitle, MB_OK );

	return 0;
}
