| /************************************************************** |
| * |
| * 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; |
| } |