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

Last change on this file since 19848 was 19848, checked in by oranfry, 15 years ago

changes that went in for the 2.82cd release

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