source: release-kits/shared/windows/wrapper/wrapper.cpp@ 19587

Last change on this file since 19587 was 19587, checked in by oranfry, 12 years ago

keep track of original directory installer was run from

File size: 11.3 KB
Line 
1#include <windows.h>
2
3#include <fstream>
4#include <iostream>
5#include <conio.h>
6#include <string>
7#include <time.h>
8#include <shellapi.h>
9#include <direct.h>
10#include "libsearch4j.h"
11
12using namespace std;
13
14//globals
15HBITMAP g_splash = NULL; //the main splash bitmap
16HFONT g_hfFont = NULL; //the main splash bitmap
17char step[10] = "TMP"; //the current step
18char progress[4] = "0"; //progress in the current step
19HWND splashWnd;
20HINSTANCE mainInstance;
21int mainCmdShow;
22bool window_loaded = false;
23
24void set_splash_step( char* new_step ) {
25 strcpy( step, new_step );
26 InvalidateRect(splashWnd, NULL, FALSE);
27 UpdateWindow(splashWnd);
28}
29
30void set_splash_progress( int percent_progress ) {
31 percent_progress = ( percent_progress / 10 ) * 10;
32 char p[4] = {0};
33 strcpy( progress, itoa( percent_progress, p, 10 ) );
34 InvalidateRect(splashWnd, NULL, FALSE);
35 //RedrawWindow(splashWnd, NULL, NULL, RDW_INVALIDATE | RDW_ERASE | RDW_ERASENOW | RDW_UPDATENOW | RDW_INTERNALPAINT);
36 UpdateWindow(splashWnd);
37}
38
39void spoof_progress( int interval ) {
40 int tenPercentWait = interval / 11;
41 for ( int i=0; i <= 100; i+=10 ) {
42 set_splash_progress( i );
43 Sleep( tenPercentWait );
44 }
45}
46
47//extracts a resource in chunks
48int extractResource( const char * basename, const char * type, char * file ) {
49
50 HMODULE hModule = GetModuleHandle(NULL);
51 set_splash_progress( 0 );
52
53 int no_chunks;
54 bool chunk_available = true;
55 for ( no_chunks = 0; chunk_available; no_chunks++ ) {
56
57 //construct the chunk name
58 char chunkname[127] = {0};
59 strcpy( chunkname, basename );
60 strcat( chunkname, "_" );
61 char chunknum[5] = {0};
62 itoa( no_chunks+1, chunknum, 10 );
63 strcat( chunkname, chunknum );
64
65 if ( FindResource(hModule, chunkname, type) == NULL ) {
66 chunk_available = false;
67 break;
68 }
69 }
70
71 if ( no_chunks == 0 ) {
72 return 1;
73 }
74
75 for ( int i=0; i<no_chunks; i++ ) {
76
77 //construct the chunk name
78 char chunkname[127] = {0};
79 strcpy( chunkname, basename );
80 strcat( chunkname, "_" );
81 char chunknum[5] = {0};
82 itoa( i+1, chunknum, 10 );
83 strcat( chunkname, chunknum );
84
85 //find it
86 HRSRC hRsrc = FindResource(hModule, chunkname, type);
87 if (hRsrc == NULL ) return 1; //couldn't find the chunk
88
89 //load it
90 HGLOBAL hGlobal = LoadResource(hModule, hRsrc);
91 if (hGlobal == NULL) return 1; //couldn't lock
92
93 //lock it
94 BYTE* pBytes = (BYTE*) LockResource(hGlobal);
95 if (pBytes == NULL) return 1; //couldn't lock
96
97 //put it on disk
98 DWORD dwLength = SizeofResource(hModule, hRsrc);
99 ofstream fStream(file, ios::binary | ios::out | ios::app );
100 fStream.write((char*) pBytes, dwLength);
101 fStream.close();
102
103 //unload
104 UnlockResource(hGlobal);
105 FreeResource(hGlobal);
106
107 //update the progress
108 set_splash_progress( i * 100 / no_chunks );
109
110 }
111
112 return 0;
113
114}
115
116//the splash window procedure
117LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
118 switch(msg) {
119
120 case WM_CREATE: {
121 //load in the reusable resources
122 g_splash = LoadBitmap(GetModuleHandle(NULL),"SPLASH");
123 g_hfFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
124 if(g_splash == NULL) {
125 MessageBox(hwnd, "Could not load splash bitmap!", "Error", MB_OK | MB_ICONEXCLAMATION);
126 }
127
128 //center the window automatically
129 RECT rect;
130 GetWindowRect(hwnd, &rect);
131 int x = (GetSystemMetrics(SM_CXSCREEN) - (rect.right - rect.left)) / 2;
132 int y = (GetSystemMetrics(SM_CYSCREEN) - (rect.bottom - rect.top)) / 2;
133 SetWindowPos(hwnd, HWND_TOP, x, y, 0, 0, SWP_NOSIZE);
134 }
135
136 case WM_PAINT: {
137 // Don't use MessageBox from inside WM_PAINT
138
139 //load in the correct resources
140 HBITMAP g_progress = NULL;
141 HBITMAP g_step = NULL;
142 char progress_res[20] = "PROGRESS_";
143 strcat( progress_res, progress );
144 char step_res[20] = "STEP_";
145 strcat( step_res, step );
146 g_progress = LoadBitmap(GetModuleHandle(NULL), progress_res );
147 g_step = LoadBitmap(GetModuleHandle(NULL), step_res );
148 if( g_progress == NULL || g_step == NULL ) {
149 //MessageBox(hwnd, "Could not load an image!", "Error", MB_OK | MB_ICONEXCLAMATION);
150 }
151
152 BITMAP bm; //holds info about the width and height
153 PAINTSTRUCT ps;
154
155 HDC hdc = BeginPaint(hwnd, &ps);
156 HDC hdcMem = CreateCompatibleDC(hdc);
157
158 //paint the main splash screen
159 GetObject(g_splash, sizeof(bm), &bm);
160 HBITMAP hbmOld = (HBITMAP)SelectObject(hdcMem, g_splash);
161 BitBlt(hdc, 0, 0, bm.bmWidth, bm.bmHeight, hdcMem, 0, 0, SRCCOPY);
162
163 //paint in the progress
164 GetObject(g_progress, sizeof(bm), &bm);
165 SelectObject(hdcMem, g_progress);
166 BitBlt(hdc, 0, 270, bm.bmWidth, bm.bmHeight, hdcMem, 0, 0, SRCCOPY);
167
168 //paint in the step with transparency
169 GetObject(g_step, sizeof(bm), &bm);
170 SelectObject(hdcMem, g_step);
171 BitBlt(hdc, 0, 276, bm.bmWidth, bm.bmHeight, hdcMem, 0, 0, SRCPAINT);
172
173 //print the step with text
174 RECT rcClient;
175 GetClientRect(hwnd, &rcClient);
176 //DrawText(hdc, "This is the step", -1, &rcClient, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
177
178 //restore the hdc
179 SelectObject(hdcMem, hbmOld);
180
181 //release resources
182 DeleteDC(hdcMem);
183 EndPaint(hwnd, &ps);
184 DeleteObject(g_progress);
185 DeleteObject(g_step);
186
187 }
188 break;
189
190 /*
191 case WM_LBUTTONDOWN: {
192 DeleteObject(g_splash);
193 PostQuitMessage(0);
194 }
195 break;
196 */
197
198 case WM_CLOSE:
199 DestroyWindow(hwnd);
200 break;
201
202 case WM_DESTROY:
203 DeleteObject(g_splash);
204 PostQuitMessage(0);
205 break;
206
207 default:
208 return DefWindowProc(hwnd, msg, wParam, lParam);
209 }
210
211 return 0;
212
213}
214
215//function to process the window
216DWORD WINAPI ProcessWindow( LPVOID lpParam ) {
217
218 const char g_szClassName[] = "splash";
219 WNDCLASSEX wc;
220 MSG Msg;
221
222 //Step 1: Registering the Window Class
223 wc.cbSize = sizeof(WNDCLASSEX);
224 wc.style = 0;
225 wc.lpfnWndProc = WndProc;
226 wc.cbClsExtra = 0;
227 wc.cbWndExtra = 0;
228 wc.hInstance = mainInstance;
229 wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
230 wc.hCursor = LoadCursor(NULL, IDC_ARROW);
231 wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
232 wc.lpszMenuName = NULL;
233 wc.lpszClassName = g_szClassName;
234 wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
235 if(!RegisterClassEx(&wc)) {
236 MessageBox(NULL, "Window Registration Failed!", "Error!",
237 MB_ICONEXCLAMATION | MB_OK);
238 return 0;
239 }
240
241 // Step 2: Creating the Window
242 splashWnd = CreateWindowEx( WS_EX_TOOLWINDOW, g_szClassName, "", WS_POPUP | SS_BITMAP, 0, 0, 420, 300, NULL, NULL, mainInstance, NULL);
243 if( splashWnd == NULL ) {
244 MessageBox(NULL, "Window Creation Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK);
245 return 0;
246 }
247 ShowWindow(splashWnd, mainCmdShow);
248 UpdateWindow(splashWnd);
249
250 window_loaded = true;
251
252 // Step 3: The Message Loop
253 while(GetMessage(&Msg, NULL, 0, 0) > 0) {
254 TranslateMessage(&Msg);
255 DispatchMessage(&Msg);
256 }
257 return 0;
258}
259
260int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
261
262 const int SPOOF_TIME = 1000;
263 string command;
264 srand( time(0) );
265 mainInstance = hInstance;
266 mainCmdShow = nCmdShow;
267
268 //start the window
269 HANDLE hThread;
270 DWORD dwThreadId, dwThrdParam = 1;
271 hThread = CreateThread(
272 NULL, // no security attributes
273 0, // use default stack size
274 ProcessWindow, // thread function
275 &dwThrdParam, // argument to thread function
276 0, // use default creation flags
277 &dwThreadId); // returns the thread identifier
278 if ( hThread == NULL ) {
279 return -1;
280 //ErrorExit( "CreateThread failed." );
281 }
282 CloseHandle( hThread );
283
284 while ( !window_loaded ) {
285 Sleep( 100 );
286 }
287
288 //create the temp folder and change to it
289 set_splash_step( "TMP" );
290 spoof_progress( SPOOF_TIME );
291
292 //get the original working directory
293 char* owd = _getcwd(NULL, 1024);
294
295 //using the users TMP directory for temp files rather than the current directory so
296 //installation from cdrom works
297 char* tmp = getenv( "TMP" );
298 char id[6]; for( int i=0; i<5; i++ ) id[i] = (char)((rand()%26) + 97); id[5] = '\0'; //id for this instance
299 string tempdir = ""; tempdir.append( tmp ); tempdir.append( "\\Greenstone-" ); tempdir.append( id );
300 const char* tmpdir = tempdir.c_str();
301 if ( _mkdir( tmpdir ) != 0 ) {
302 string title = "Failed to create the temp folder.";
303 string message = "Failed to create the temp folder.\nPlease set the environment variable TMP to a folder you have permission to write to.";
304 ShowWindow(splashWnd, SW_HIDE); //hide splash screen
305 MessageBox(NULL, message.c_str(), title.c_str(), MB_OK);
306 return -1;
307 }
308 //SetFileAttributes(tmpdir, FILE_ATTRIBUTE_HIDDEN);
309 SetCurrentDirectory(tmpdir);
310 delete tmp; // deallocate memory
311
312 //rip out java archive if it is bundled
313 set_splash_step( "XJAVA" );
314 int javaIsBundled = (extractResource( "JAVA", "EXE", "@java.installer@" ) == 0);
315 if ( javaIsBundled ) {
316 process( "@java.installer@", false );
317 }
318
319 //find java
320 set_splash_step( "SEARCHING" );
321 spoof_progress( SPOOF_TIME );
322 bool use_minimum = true;
323 Jvm minimum;
324 minimum.setVersionFromString( "@java.min.version@" );
325 string phint = "@java.extracted@";
326 string hint = "";
327 bool verbose = true;
328 Jvm foundJvm;
329 bool jvmFound = find( foundJvm, use_minimum, minimum, false, false, phint, hint, verbose );
330
331 //if the jvm was not found, try to fix it and find it
332 if ( !jvmFound ) {
333
334 //did not find a good java
335 string message = "This version of Greenstone requires java @java.min.version@ or greater, but ";
336
337 //tell them if java is absent or just too old
338 if ( find( foundJvm, false, minimum, false, false, "", "", false ) ) {
339 message.append( "your java is too old.");
340 } else {
341 message.append( "java could not be found on your computer." );
342 }
343 message.append( "\n" );
344
345 string title = "Installation Failed: Couldn't find java";
346 ShowWindow(splashWnd, SW_HIDE); //hide splash screen
347 MessageBox(NULL, message.c_str(), title.c_str(), MB_OK);
348
349 //if java was found, carry on
350 } else {
351
352 //extract the jar
353 string jarLocation = "greenstone.jar";
354
355 set_splash_step( "XJAR" );
356 extractResource( "JAR", "JAR", (char*) jarLocation.c_str() );
357
358 //launch the jar
359 set_splash_step( "LAUNCHING" );
360 spoof_progress( SPOOF_TIME );
361 string cmd = "\"";
362 cmd.append( foundJvm.getWinExecutable() );
363 cmd.append( "\" \"-Dorig.dir=" );
364 cmd.append( owd );
365 cmd.append( "\" -jar greenstone.jar" );
366
367
368 //hide splash screen
369 ShowWindow(splashWnd, SW_HIDE);
370
371 //run the jar
372 int launch_exit_code = process( cmd, true );
373
374 //report how it went
375 if ( launch_exit_code != 0 ) {
376 string title = "Installation Error";
377 string message = "The installation exited with an error. Java may not be installed properly, or the installation may have been interrupted partway through. Please try again.";
378 ShowWindow(splashWnd, SW_HIDE); //hide splash screen
379 MessageBox(NULL, message.c_str(), title.c_str(), MB_OK);
380 }
381 }
382
383 //clean up the temp directory
384 _unlink( "greenstone.jar" );
385 _unlink( "ant.install.log" );
386 _unlink( "@java.installer@" );
387 process( "cmd.exe /c rd /s /q @java.extracted@", false );
388 SetCurrentDirectory( ".." );
389 _rmdir( tempdir.c_str() );
390
391 delete owd;
392
393 return 0;
394
395}
Note: See TracBrowser for help on using the repository browser.