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