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

Last change on this file since 17071 was 17071, checked in by oranfry, 16 years ago

corrected an off by one which was stopping causing the wrapper to think bundled java was unavailable

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 for ( int i=0; i<no_chunks; i++ ) {
72
73 //construct the chunk name
74 char chunkname[127] = {0};
75 strcpy( chunkname, basename );
76 strcat( chunkname, "_" );
77 char chunknum[5] = {0};
78 itoa( i+1, chunknum, 10 );
79 strcat( chunkname, chunknum );
80
81 //find it
82 HRSRC hRsrc = FindResource(hModule, chunkname, type);
83 if (hRsrc == NULL ) return 1; //couldn't find the chunk
84
85 //load it
86 HGLOBAL hGlobal = LoadResource(hModule, hRsrc);
87 if (hGlobal == NULL) return 1; //couldn't lock
88
89 //lock it
90 BYTE* pBytes = (BYTE*) LockResource(hGlobal);
91 if (pBytes == NULL) return 1; //couldn't lock
92
93 //put it on disk
94 DWORD dwLength = SizeofResource(hModule, hRsrc);
95 ofstream fStream(file, ios::binary | ios::out | ios::app );
96 fStream.write((char*) pBytes, dwLength);
97 fStream.close();
98
99 //unload
100 UnlockResource(hGlobal);
101 FreeResource(hGlobal);
102
103 //update the progress
104 set_splash_progress( i * 100 / no_chunks );
105
106 }
107
108 return 0;
109
110}
111
112//the splash window procedure
113LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
114 switch(msg) {
115
116 case WM_CREATE: {
117 //load in the reusable resources
118 g_splash = LoadBitmap(GetModuleHandle(NULL),"SPLASH");
119 g_hfFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
120 if(g_splash == NULL) {
121 MessageBox(hwnd, "Could not load splash bitmap!", "Error", MB_OK | MB_ICONEXCLAMATION);
122 }
123
124 //center the window automatically
125 RECT rect;
126 GetWindowRect(hwnd, &rect);
127 int x = (GetSystemMetrics(SM_CXSCREEN) - (rect.right - rect.left)) / 2;
128 int y = (GetSystemMetrics(SM_CYSCREEN) - (rect.bottom - rect.top)) / 2;
129 SetWindowPos(hwnd, HWND_TOP, x, y, 0, 0, SWP_NOSIZE);
130 }
131
132 case WM_PAINT: {
133 // Don't use MessageBox from inside WM_PAINT
134
135 //load in the correct resources
136 HBITMAP g_progress = NULL;
137 HBITMAP g_step = NULL;
138 char progress_res[20] = "PROGRESS_";
139 strcat( progress_res, progress );
140 char step_res[20] = "STEP_";
141 strcat( step_res, step );
142 g_progress = LoadBitmap(GetModuleHandle(NULL), progress_res );
143 g_step = LoadBitmap(GetModuleHandle(NULL), step_res );
144 if( g_progress == NULL || g_step == NULL ) {
145 MessageBox(hwnd, "Could not load an image!", "Error", MB_OK | MB_ICONEXCLAMATION);
146 }
147
148 BITMAP bm; //holds info about the width and height
149 PAINTSTRUCT ps;
150
151 HDC hdc = BeginPaint(hwnd, &ps);
152 HDC hdcMem = CreateCompatibleDC(hdc);
153
154 //paint the main splash screen
155 GetObject(g_splash, sizeof(bm), &bm);
156 HBITMAP hbmOld = (HBITMAP)SelectObject(hdcMem, g_splash);
157 BitBlt(hdc, 0, 0, bm.bmWidth, bm.bmHeight, hdcMem, 0, 0, SRCCOPY);
158
159 //paint in the progress
160 GetObject(g_progress, sizeof(bm), &bm);
161 SelectObject(hdcMem, g_progress);
162 BitBlt(hdc, 0, 276, bm.bmWidth, bm.bmHeight, hdcMem, 0, 0, SRCCOPY);
163
164 //paint in the step with transparency
165 GetObject(g_step, sizeof(bm), &bm);
166 SelectObject(hdcMem, g_step);
167 BitBlt(hdc, 0, 276, bm.bmWidth, bm.bmHeight, hdcMem, 0, 0, SRCPAINT);
168
169 //print the step with text
170 RECT rcClient;
171 GetClientRect(hwnd, &rcClient);
172 //DrawText(hdc, "This is the step", -1, &rcClient, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
173
174 //restore the hdc
175 SelectObject(hdcMem, hbmOld);
176
177 //release resources
178 DeleteDC(hdcMem);
179 EndPaint(hwnd, &ps);
180 DeleteObject(g_progress);
181 DeleteObject(g_step);
182
183 }
184 break;
185
186 /*
187 case WM_LBUTTONDOWN: {
188 DeleteObject(g_splash);
189 PostQuitMessage(0);
190 }
191 break;
192 */
193
194 case WM_CLOSE:
195 DestroyWindow(hwnd);
196 break;
197
198 case WM_DESTROY:
199 DeleteObject(g_splash);
200 PostQuitMessage(0);
201 break;
202
203 default:
204 return DefWindowProc(hwnd, msg, wParam, lParam);
205 }
206
207 return 0;
208
209}
210
211//function to process the window
212DWORD WINAPI ProcessWindow( LPVOID lpParam ) {
213
214 const char g_szClassName[] = "splash";
215 WNDCLASSEX wc;
216 MSG Msg;
217
218 //Step 1: Registering the Window Class
219 wc.cbSize = sizeof(WNDCLASSEX);
220 wc.style = 0;
221 wc.lpfnWndProc = WndProc;
222 wc.cbClsExtra = 0;
223 wc.cbWndExtra = 0;
224 wc.hInstance = mainInstance;
225 wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
226 wc.hCursor = LoadCursor(NULL, IDC_ARROW);
227 wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
228 wc.lpszMenuName = NULL;
229 wc.lpszClassName = g_szClassName;
230 wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
231 if(!RegisterClassEx(&wc)) {
232 MessageBox(NULL, "Window Registration Failed!", "Error!",
233 MB_ICONEXCLAMATION | MB_OK);
234 return 0;
235 }
236
237 // Step 2: Creating the Window
238 splashWnd = CreateWindowEx( WS_EX_TOOLWINDOW, g_szClassName, "", WS_POPUP | SS_BITMAP, 0, 0, 420, 300, NULL, NULL, mainInstance, NULL);
239 if( splashWnd == NULL ) {
240 MessageBox(NULL, "Window Creation Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK);
241 return 0;
242 }
243 ShowWindow(splashWnd, mainCmdShow);
244 UpdateWindow(splashWnd);
245
246 window_loaded = true;
247
248 // Step 3: The Message Loop
249 while(GetMessage(&Msg, NULL, 0, 0) > 0) {
250 TranslateMessage(&Msg);
251 DispatchMessage(&Msg);
252 }
253 return 0;
254}
255
256int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
257
258 const int SPOOF_TIME = 1000;
259 string command;
260 srand( time(0) );
261 mainInstance = hInstance;
262 mainCmdShow = nCmdShow;
263
264 //start the window
265 HANDLE hThread;
266 DWORD dwThreadId, dwThrdParam = 1;
267 hThread = CreateThread(
268 NULL, // no security attributes
269 0, // use default stack size
270 ProcessWindow, // thread function
271 &dwThrdParam, // argument to thread function
272 0, // use default creation flags
273 &dwThreadId); // returns the thread identifier
274 if ( hThread == NULL ) {
275 return -1;
276 //ErrorExit( "CreateThread failed." );
277 }
278 CloseHandle( hThread );
279
280 while ( !window_loaded ) {
281 Sleep( 100 );
282 }
283
284 //create the temp folder and change to it
285 set_splash_step( "TMP" );
286 spoof_progress( SPOOF_TIME );
287 char* tmp = getenv( "TMP" );
288 char id[6]; for( int i=0; i<5; i++ ) id[i] = (char)((rand()%26) + 97); id[5] = '\0'; //id for this instance
289 string tempdir = ""; tempdir.append( tmp ); tempdir.append( "\\Greenstone-" ); tempdir.append( id );
290 _mkdir( tempdir.c_str() );
291 SetCurrentDirectory( tempdir.c_str() );
292
293 //find java
294 //set_splash_status( hInstance, statusWnd, "STATUS_SEARCHING4J", 1000 );
295 set_splash_step( "SEARCHING" );
296 spoof_progress( SPOOF_TIME );
297 bool use_minimum = true;
298 Jvm minimum;
299 minimum.setVersionFromString( "@java.min.version@" );
300 string hint = "";
301 bool verbose = true;
302 Jvm foundJvm;
303 bool jvmFound = find( foundJvm, use_minimum, minimum, hint, verbose );
304
305 //if the jvm was not found, try to fix it and find it
306 if ( !jvmFound ) {
307
308 //did not find a good java
309 string message = "This version of Greenstone requires java @java.min.version@ or greater, but ";
310
311 //tell them if java is absent or just too old
312 if ( find( foundJvm, false, minimum, "", false ) ) {
313 message.append( "your java is too old.");
314 } else {
315 message.append( "java could not be found on your computer." );
316 }
317 message.append( "\n\n" );
318
319 //is this an installer with the bundled JRE?
320 set_splash_step( "XJAVA" );
321 int extract_result = extractResource( "JAVA", "EXE", "@java.installer@" );
322
323 if ( extract_result == 0 ) {
324
325 //yes, JRE is bundled
326 message.append( "This installer is bundled with a suitible version of java (@bundled.version.java@)\n");
327 message.append( "The installer program for this java will now be launched.\n" );
328 string title = "Must install java first";
329 MessageBox(NULL, message.c_str(), title.c_str(), MB_OK);
330 ShellExecute(NULL, "open", "@java.installer@", NULL, NULL, SW_SHOWNORMAL);
331 jvmFound = true; //assume the java installation went well
332
333 } else {
334
335 //no, JRE is not bundled
336 set_splash_step( "SEARCHING" );
337 set_splash_progress( 100 ); //we are done searching
338 message.append( "Please install java (@java.min.version@ or newer) and try again.\n" );
339 message.append( "Or, download an installer with bundled java and use that instead of this one" );
340 string title = "Installation Failed: Couldn't find java";
341 MessageBox(NULL, message.c_str(), title.c_str(), MB_OK);
342 }
343 }
344
345
346 //if we have found it by now, launch the installer
347 if ( jvmFound ) {
348
349 //extract the jar
350 string jarLocation = ""; jarLocation.append( tempdir ); jarLocation.append( "\\greenstone.jar" );
351 //set_splash_status( hInstance, statusWnd, "STATUS_JAR", 0 );
352
353 set_splash_step( "XJAR" );
354 extractResource( "JAR", "JAR", (char*) jarLocation.c_str() );
355
356 //launch the jar
357 set_splash_step( "LAUNCHING" );
358 spoof_progress( SPOOF_TIME );
359 string cmd = "\"";
360 cmd.append( foundJvm.getWinExecutable() );
361 cmd.append( "\" -jar greenstone.jar" );
362
363 //hide splash screen
364 ShowWindow(splashWnd, SW_HIDE);
365
366 //run the jar
367 int launch_exit_code = process( cmd, true );
368
369 //report how it went
370 if ( launch_exit_code != 0 ) {
371 string title = "Installation Error";
372 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.";
373 MessageBox(NULL, message.c_str(), title.c_str(), MB_OK);
374 }
375 }
376
377 //clean up the temp directory
378 _unlink("greenstone.jar");
379 _unlink("ant.install.log");
380 _unlink("@java.installer@");
381 SetCurrentDirectory("..");
382 _rmdir( tempdir.c_str() );
383
384 return 0;
385
386}
Note: See TracBrowser for help on using the repository browser.