1*2722ceddSAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 3*2722ceddSAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4*2722ceddSAndrew Rist * or more contributor license agreements. See the NOTICE file 5*2722ceddSAndrew Rist * distributed with this work for additional information 6*2722ceddSAndrew Rist * regarding copyright ownership. The ASF licenses this file 7*2722ceddSAndrew Rist * to you under the Apache License, Version 2.0 (the 8*2722ceddSAndrew Rist * "License"); you may not use this file except in compliance 9*2722ceddSAndrew Rist * with the License. You may obtain a copy of the License at 10cdf0e10cSrcweir * 11*2722ceddSAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12cdf0e10cSrcweir * 13*2722ceddSAndrew Rist * Unless required by applicable law or agreed to in writing, 14*2722ceddSAndrew Rist * software distributed under the License is distributed on an 15*2722ceddSAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*2722ceddSAndrew Rist * KIND, either express or implied. See the License for the 17*2722ceddSAndrew Rist * specific language governing permissions and limitations 18*2722ceddSAndrew Rist * under the License. 19cdf0e10cSrcweir * 20*2722ceddSAndrew Rist *************************************************************/ 21*2722ceddSAndrew Rist 22*2722ceddSAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir #include "precompiled_desktop.hxx" 25cdf0e10cSrcweir 26cdf0e10cSrcweir #define UNICODE 1 27cdf0e10cSrcweir #define _UNICODE 1 28cdf0e10cSrcweir 29cdf0e10cSrcweir #ifndef _WINDOWS_ 30cdf0e10cSrcweir # define WIN32_LEAN_AND_MEAN 31cdf0e10cSrcweir #if defined _MSC_VER 32cdf0e10cSrcweir #pragma warning(push, 1) 33cdf0e10cSrcweir #endif 34cdf0e10cSrcweir # include <windows.h> 35cdf0e10cSrcweir # include <shellapi.h> 36cdf0e10cSrcweir # include <wchar.h> 37cdf0e10cSrcweir #if defined _MSC_VER 38cdf0e10cSrcweir #pragma warning(pop) 39cdf0e10cSrcweir #endif 40cdf0e10cSrcweir #endif 41cdf0e10cSrcweir 42cdf0e10cSrcweir #include "Resource.h" 43cdf0e10cSrcweir #include <time.h> 44cdf0e10cSrcweir #include "sal/config.h" 45cdf0e10cSrcweir #include "tools/pathutils.hxx" 46cdf0e10cSrcweir 47cdf0e10cSrcweir const DWORD PE_Signature = 0x00004550; 48cdf0e10cSrcweir 49cdf0e10cSrcweir #define MY_LENGTH(s) (sizeof (s) / sizeof *(s) - 1) 50cdf0e10cSrcweir #define MY_STRING(s) (s), MY_LENGTH(s) 51cdf0e10cSrcweir #define MAX_STR_CAPTION 256 52cdf0e10cSrcweir #define MAX_TEXT_LENGTH 1024 53cdf0e10cSrcweir 54cdf0e10cSrcweir static void failPath(wchar_t* pszAppTitle, wchar_t* pszMsg) 55cdf0e10cSrcweir { 56cdf0e10cSrcweir MessageBoxW(NULL, pszMsg, pszAppTitle, MB_OK | MB_ICONERROR); 57cdf0e10cSrcweir TerminateProcess(GetCurrentProcess(), 255); 58cdf0e10cSrcweir } 59cdf0e10cSrcweir 60cdf0e10cSrcweir static void fail() 61cdf0e10cSrcweir { 62cdf0e10cSrcweir LPWSTR buf = NULL; 63cdf0e10cSrcweir FormatMessageW( 64cdf0e10cSrcweir FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, 65cdf0e10cSrcweir GetLastError(), 0, reinterpret_cast< LPWSTR >(&buf), 0, NULL); 66cdf0e10cSrcweir MessageBoxW(NULL, buf, NULL, MB_OK | MB_ICONERROR); 67cdf0e10cSrcweir LocalFree(buf); 68cdf0e10cSrcweir TerminateProcess(GetCurrentProcess(), 255); 69cdf0e10cSrcweir } 70cdf0e10cSrcweir 71cdf0e10cSrcweir static LPVOID getVirtualBaseAddress( wchar_t* pszFilePath ) 72cdf0e10cSrcweir { 73cdf0e10cSrcweir HANDLE hFile; 74cdf0e10cSrcweir HANDLE hFileMapping; 75cdf0e10cSrcweir LPVOID lpFileBase = 0; 76cdf0e10cSrcweir PIMAGE_DOS_HEADER lpDosHeader; 77cdf0e10cSrcweir PIMAGE_NT_HEADERS lpNTHeader; 78cdf0e10cSrcweir 79cdf0e10cSrcweir hFile = CreateFile(pszFilePath, 80cdf0e10cSrcweir GENERIC_READ, FILE_SHARE_READ, NULL, 81cdf0e10cSrcweir OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 82cdf0e10cSrcweir 0); 83cdf0e10cSrcweir 84cdf0e10cSrcweir if ( hFile == INVALID_HANDLE_VALUE ) 85cdf0e10cSrcweir { 86cdf0e10cSrcweir return NULL; 87cdf0e10cSrcweir } 88cdf0e10cSrcweir 89cdf0e10cSrcweir hFileMapping = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL); 90cdf0e10cSrcweir if ( hFileMapping == 0 ) 91cdf0e10cSrcweir { 92cdf0e10cSrcweir CloseHandle(hFile); 93cdf0e10cSrcweir return NULL; 94cdf0e10cSrcweir } 95cdf0e10cSrcweir 96cdf0e10cSrcweir lpFileBase = MapViewOfFile(hFileMapping, FILE_MAP_READ, 0, 0, 0); 97cdf0e10cSrcweir if ( lpFileBase == 0 ) 98cdf0e10cSrcweir { 99cdf0e10cSrcweir CloseHandle(hFileMapping); 100cdf0e10cSrcweir CloseHandle(hFile); 101cdf0e10cSrcweir return NULL; 102cdf0e10cSrcweir } 103cdf0e10cSrcweir 104cdf0e10cSrcweir lpDosHeader = (PIMAGE_DOS_HEADER)lpFileBase; 105cdf0e10cSrcweir if ( lpDosHeader->e_magic == IMAGE_DOS_SIGNATURE ) 106cdf0e10cSrcweir { 107cdf0e10cSrcweir lpNTHeader = (PIMAGE_NT_HEADERS)((char*)lpDosHeader + lpDosHeader->e_lfanew); 108cdf0e10cSrcweir if (lpNTHeader->Signature == PE_Signature ) 109cdf0e10cSrcweir lpFileBase = reinterpret_cast<LPVOID>( lpNTHeader->OptionalHeader.ImageBase ); 110cdf0e10cSrcweir } 111cdf0e10cSrcweir 112cdf0e10cSrcweir UnmapViewOfFile(lpFileBase); 113cdf0e10cSrcweir CloseHandle(hFileMapping); 114cdf0e10cSrcweir CloseHandle(hFile); 115cdf0e10cSrcweir 116cdf0e10cSrcweir return lpFileBase; 117cdf0e10cSrcweir } 118cdf0e10cSrcweir 119cdf0e10cSrcweir static bool checkImageVirtualBaseAddress(wchar_t* pszFilePath, LPVOID lpVBA) 120cdf0e10cSrcweir { 121cdf0e10cSrcweir LPVOID lpImageVBA = getVirtualBaseAddress(pszFilePath); 122cdf0e10cSrcweir if ( lpImageVBA == lpVBA ) 123cdf0e10cSrcweir return true; 124cdf0e10cSrcweir else 125cdf0e10cSrcweir return false; 126cdf0e10cSrcweir } 127cdf0e10cSrcweir 128cdf0e10cSrcweir static wchar_t* getBrandPath(wchar_t * pszPath) 129cdf0e10cSrcweir { 130cdf0e10cSrcweir DWORD n = GetModuleFileNameW(NULL, pszPath, MAX_PATH); 131cdf0e10cSrcweir if (n == 0 || n >= MAX_PATH) { 132cdf0e10cSrcweir exit(EXIT_FAILURE); 133cdf0e10cSrcweir } 134cdf0e10cSrcweir return tools::filename(pszPath); 135cdf0e10cSrcweir } 136cdf0e10cSrcweir 137cdf0e10cSrcweir extern "C" int APIENTRY WinMain( HINSTANCE hInst, HINSTANCE, LPSTR, int ) 138cdf0e10cSrcweir { 139cdf0e10cSrcweir wchar_t* pAppTitle = new wchar_t[ MAX_STR_CAPTION ]; 140cdf0e10cSrcweir pAppTitle[0] = '\0'; 141cdf0e10cSrcweir LoadString( hInst, IDS_APP_TITLE, pAppTitle, MAX_STR_CAPTION ); 142cdf0e10cSrcweir 143cdf0e10cSrcweir wchar_t* pTextServer = new wchar_t[ MAX_TEXT_LENGTH ]; 144cdf0e10cSrcweir pTextServer[0] = '\0'; 145cdf0e10cSrcweir LoadString( hInst, IDS_MSG_OPTIMIZED_FOR_SERVER, pTextServer, MAX_TEXT_LENGTH ); 146cdf0e10cSrcweir 147cdf0e10cSrcweir wchar_t* pTextClient = new wchar_t[ MAX_TEXT_LENGTH ]; 148cdf0e10cSrcweir pTextClient[0] = '\0'; 149cdf0e10cSrcweir LoadString( hInst, IDS_MSG_OPTIMIZED_FOR_CLIENT, pTextClient, MAX_TEXT_LENGTH ); 150cdf0e10cSrcweir 151cdf0e10cSrcweir wchar_t* pTextNoInstallation = new wchar_t[ MAX_TEXT_LENGTH ]; 152cdf0e10cSrcweir pTextNoInstallation[0] = '\0'; 153cdf0e10cSrcweir LoadString( hInst, IDS_MSG_NO_INSTALLATION_FOUND, pTextNoInstallation, MAX_TEXT_LENGTH ); 154cdf0e10cSrcweir 155cdf0e10cSrcweir LPVOID VBA = (void*)0x10000000; 156cdf0e10cSrcweir wchar_t path[MAX_PATH]; 157cdf0e10cSrcweir 158cdf0e10cSrcweir wchar_t * pathEnd = getBrandPath(path); 159cdf0e10cSrcweir 160cdf0e10cSrcweir if (tools::buildPath(path, path, pathEnd, MY_STRING(L"libxml2.dll")) == NULL) 161cdf0e10cSrcweir fail(); 162cdf0e10cSrcweir bool bFast = checkImageVirtualBaseAddress(path, VBA); 163cdf0e10cSrcweir 164cdf0e10cSrcweir if (tools::buildPath(path, path, pathEnd, MY_STRING(L"..\\basis-link")) == NULL) 165cdf0e10cSrcweir fail(); 166cdf0e10cSrcweir pathEnd = tools::resolveLink(path); 167cdf0e10cSrcweir 168cdf0e10cSrcweir if (pathEnd == NULL) 169cdf0e10cSrcweir failPath(pAppTitle, pTextNoInstallation); 170cdf0e10cSrcweir 171cdf0e10cSrcweir if (tools::buildPath(path, path, pathEnd, MY_STRING(L"\\program\\vclmi.dll")) == NULL) 172cdf0e10cSrcweir fail(); 173cdf0e10cSrcweir bFast &= checkImageVirtualBaseAddress(path, VBA); 174cdf0e10cSrcweir 175cdf0e10cSrcweir if (tools::buildPath(path, path, pathEnd, MY_STRING(L"\\ure-link")) == NULL) 176cdf0e10cSrcweir fail(); 177cdf0e10cSrcweir pathEnd = tools::resolveLink(path); 178cdf0e10cSrcweir 179cdf0e10cSrcweir if (pathEnd == NULL) 180cdf0e10cSrcweir failPath(pAppTitle, pTextNoInstallation); 181cdf0e10cSrcweir 182cdf0e10cSrcweir if (tools::buildPath(path, path, pathEnd, MY_STRING(L"\\bin\\sal3.dll")) == NULL) 183cdf0e10cSrcweir fail(); 184cdf0e10cSrcweir bFast &= checkImageVirtualBaseAddress(path, VBA); 185cdf0e10cSrcweir 186cdf0e10cSrcweir const wchar_t* pOutput = pTextClient; 187cdf0e10cSrcweir if (!bFast) 188cdf0e10cSrcweir pOutput = pTextServer; 189cdf0e10cSrcweir 190cdf0e10cSrcweir MessageBoxW( NULL, pOutput, pAppTitle, MB_OK ); 191cdf0e10cSrcweir 192cdf0e10cSrcweir return 0; 193cdf0e10cSrcweir } 194