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

Last change on this file since 17905 was 17905, checked in by max, 12 years ago

Now extracts in the hidden folder in the current directory instead of the temp folder.

File size: 10.8 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, 276, 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 // Now we are generating temporary files in a folder inside the current directory,
293 // instead of creating this folder in the system Temp directory(referenced by TMP)
294 // And we make this folder hidden
295 char* tmp = NULL; //char* tmp = getenv( "TMP" );
296 tmp = _getcwd(tmp, 1000);
297 char id[6]; for( int i=0; i<5; i++ ) id[i] = (char)((rand()%26) + 97); id[5] = '\0'; //id for this instance
298 string tempdir = ""; tempdir.append( tmp ); tempdir.append( "\\Greenstone-" ); tempdir.append( id );
299 const char* tmpdir = tempdir.c_str();
300 _mkdir( tmpdir );
301 SetFileAttributes(tmpdir, FILE_ATTRIBUTE_HIDDEN);
302 SetCurrentDirectory(tmpdir);
303 delete tmp; // deallocate memory
304
305 //rip out java archive if it is bundled
306 set_splash_step( "XJAVA" );
307 int javaIsBundled = (extractResource( "JAVA", "EXE", "@java.installer@" ) == 0);
308 if ( javaIsBundled ) {
309 process( "@java.installer@", false );
310 }
311
312 //find java
313 set_splash_step( "SEARCHING" );
314 spoof_progress( SPOOF_TIME );
315 bool use_minimum = true;
316 Jvm minimum;
317 minimum.setVersionFromString( "@java.min.version@" );
318 string phint = "@java.extracted@";
319 string hint = "";
320 bool verbose = true;
321 Jvm foundJvm;
322 bool jvmFound = find( foundJvm, use_minimum, minimum, phint, hint, verbose );
323
324 //if the jvm was not found, try to fix it and find it
325 if ( !jvmFound ) {
326
327 //did not find a good java
328 string message = "This version of Greenstone requires java @java.min.version@ or greater, but ";
329
330 //tell them if java is absent or just too old
331 if ( find( foundJvm, false, minimum, "", "", false ) ) {
332 message.append( "your java is too old.");
333 } else {
334 message.append( "java could not be found on your computer." );
335 }
336 message.append( "\n" );
337
338 string title = "Installation Failed: Couldn't find java";
339 MessageBox(NULL, message.c_str(), title.c_str(), MB_OK);
340
341 //if java was found, carry on
342 } else {
343
344 //extract the jar
345 string jarLocation = ""; jarLocation.append( tempdir ); jarLocation.append( "\\greenstone.jar" );
346
347 set_splash_step( "XJAR" );
348 extractResource( "JAR", "JAR", (char*) jarLocation.c_str() );
349
350 //launch the jar
351 set_splash_step( "LAUNCHING" );
352 spoof_progress( SPOOF_TIME );
353 string cmd = "\"";
354 cmd.append( foundJvm.getWinExecutable() );
355 cmd.append( "\" -jar greenstone.jar" );
356
357 //hide splash screen
358 ShowWindow(splashWnd, SW_HIDE);
359
360 //run the jar
361 int launch_exit_code = process( cmd, true );
362
363 //report how it went
364 if ( launch_exit_code != 0 ) {
365 string title = "Installation Error";
366 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.";
367 MessageBox(NULL, message.c_str(), title.c_str(), MB_OK);
368 }
369 }
370
371 //clean up the temp directory
372 _unlink( "greenstone.jar" );
373 _unlink( "ant.install.log" );
374 _unlink( "@java.installer@" );
375 process( "cmd.exe /c rd /s /q @java.extracted@", false );
376 SetCurrentDirectory( ".." );
377 _rmdir( tempdir.c_str() );
378
379 return 0;
380
381}
Note: See TracBrowser for help on using the repository browser.