source: release-kits/wirk3/wrapper/wrapper.cpp@ 15689

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

new resource scheme for wirk3 wrapper

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