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
failPath(wchar_t * pszAppTitle,wchar_t * pszMsg)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
fail()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
getVirtualBaseAddress(wchar_t * pszFilePath)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
checkImageVirtualBaseAddress(wchar_t * pszFilePath,LPVOID lpVBA)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
getBrandPath(wchar_t * pszPath)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
WinMain(HINSTANCE hInst,HINSTANCE,LPSTR,int)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