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

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

cdrom wrapper needs to use temp dir, so basing it off web wrapper after all

File size: 11.9 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
11using namespace std;
12
13#ifdef WEB
14#include "libsearch4j.h"
15#endif
16
17//globals
18HBITMAP g_splash = NULL; //the main splash bitmap
19HFONT g_hfFont = NULL; //the main splash bitmap
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;
26
27void set_splash_step( char* new_step ) {
28 strcpy( step, new_step );
29 InvalidateRect(splashWnd, NULL, FALSE);
30 UpdateWindow(splashWnd);
31}
32
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}
41
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
51int extractResource( const char * basename, const char * type, char * file ) {
52
53 HMODULE hModule = GetModuleHandle(NULL);
54 set_splash_progress( 0 );
55
56 int no_chunks;
57 bool chunk_available = true;
58 for ( no_chunks = 0; chunk_available; no_chunks++ ) {
59
60 //construct the chunk name
61 char chunkname[127] = {0};
62 strcpy( chunkname, basename );
63 strcat( chunkname, "_" );
64 char chunknum[5] = {0};
65 itoa( no_chunks+1, chunknum, 10 );
66 strcat( chunkname, chunknum );
67
68 if ( FindResource(hModule, chunkname, type) == NULL ) {
69 chunk_available = false;
70 break;
71 }
72 }
73
74 if ( no_chunks == 0 ) {
75 return 1;
76 }
77
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};
85 itoa( i+1, chunknum, 10 );
86 strcat( chunkname, chunknum );
87
88 //find it
89 HRSRC hRsrc = FindResource(hModule, chunkname, type);
90 if (hRsrc == NULL ) return 1; //couldn't find the chunk
91
92 //load it
93 HGLOBAL hGlobal = LoadResource(hModule, hRsrc);
94 if (hGlobal == NULL) return 1; //couldn't lock
95
96 //lock it
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 }
114
115 return 0;
116
117}
118
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");
126 g_hfFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
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 ) {
152 //MessageBox(hwnd, "Could not load an image!", "Error", MB_OK | MB_ICONEXCLAMATION);
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);
169 BitBlt(hdc, 0, 270, bm.bmWidth, bm.bmHeight, hdcMem, 0, 0, SRCCOPY);
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
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
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
193 /*
194 case WM_LBUTTONDOWN: {
195 DeleteObject(g_splash);
196 PostQuitMessage(0);
197 }
198 break;
199 */
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
216}
217
218//function to process the window
219DWORD WINAPI ProcessWindow( LPVOID lpParam ) {
220
221 const char g_szClassName[] = "splash";
222 WNDCLASSEX wc;
223 MSG Msg;
224
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 }
243
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;
254
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) {
264
265 const int SPOOF_TIME = 1000;
266 string command;
267 srand( time(0) );
268 mainInstance = hInstance;
269 mainCmdShow = nCmdShow;
270
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 );
294
295 //get the original working directory
296 char* owd = _getcwd(NULL, 1024);
297
298 //using the users TMP directory for temp files rather than the current directory so
299 //installation from cdrom works
300 char* tmp = getenv( "TMP" );
301 char id[6]; for( int i=0; i<5; i++ ) id[i] = (char)((rand()%26) + 97); id[5] = '\0'; //id for this instance
302 string tempdir = ""; tempdir.append( tmp ); tempdir.append( "\\Greenstone-" ); tempdir.append( id );
303 const char* tmpdir = tempdir.c_str();
304 if ( _mkdir( tmpdir ) != 0 ) {
305 string title = "Failed to create the temp folder.";
306 string message = "Failed to create the temp folder.\nPlease set the environment variable TMP to a folder you have permission to write to.";
307 ShowWindow(splashWnd, SW_HIDE); //hide splash screen
308 MessageBox(NULL, message.c_str(), title.c_str(), MB_OK);
309 return -1;
310 }
311 //SetFileAttributes(tmpdir, FILE_ATTRIBUTE_HIDDEN);
312 SetCurrentDirectory(tmpdir);
313 delete tmp; // deallocate memory
314
315 #ifdef WEB
316 //rip out java archive if it is bundled
317 set_splash_step( "XJAVA" );
318 int javaIsBundled = (extractResource( "JAVA", "EXE", "@java.installer@" ) == 0);
319 if ( javaIsBundled ) {
320 process( "@java.installer@", false );
321 }
322
323 //find java
324 set_splash_step( "SEARCHING" );
325 spoof_progress( SPOOF_TIME );
326 bool use_minimum = true;
327 Jvm minimum;
328 minimum.setVersionFromString( "@java.min.version@" );
329 string phint = "@java.extracted@";
330 string hint = "";
331 bool verbose = true;
332 Jvm foundJvm;
333 bool jvmFound = find( foundJvm, use_minimum, minimum, false, false, phint, hint, verbose );
334
335 //if the jvm was not found, try to fix it and find it
336 if ( !jvmFound ) {
337
338 //did not find a good java
339 string message = "This version of Greenstone requires java @java.min.version@ or greater, but ";
340
341 //tell them if java is absent or just too old
342 if ( find( foundJvm, false, minimum, false, false, "", "", false ) ) {
343 message.append( "your java is too old.");
344 } else {
345 message.append( "java could not be found on your computer." );
346 }
347 message.append( "\n" );
348
349 string title = "Installation Failed: Couldn't find java";
350 ShowWindow(splashWnd, SW_HIDE); //hide splash screen
351 MessageBox(NULL, message.c_str(), title.c_str(), MB_OK);
352
353 //if java was found, carry on
354 } else {
355
356 //extract the jar
357 string jarLocation = "greenstone.jar";
358
359 set_splash_step( "XJAR" );
360 extractResource( "JAR", "JAR", (char*) jarLocation.c_str() );
361
362 //launch the jar
363 set_splash_step( "LAUNCHING" );
364 spoof_progress( SPOOF_TIME );
365 string cmd = "\"";
366 cmd.append( foundJvm.getWinExecutable() );
367 cmd.append( "\" \"-Dorig.dir=" );
368 cmd.append( owd );
369 cmd.append( "\" -jar greenstone.jar" );
370
371
372 //hide splash screen
373 ShowWindow(splashWnd, SW_HIDE);
374
375 //run the jar
376 int launch_exit_code = process( cmd, true );
377
378 //report how it went
379 if ( launch_exit_code != 0 ) {
380 string title = "Installation Error";
381 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.";
382 ShowWindow(splashWnd, SW_HIDE); //hide splash screen
383 MessageBox(NULL, message.c_str(), title.c_str(), MB_OK);
384 }
385 }
386
387 #endif
388
389 #ifdef CDROM
390
391 //ask if they want to install, then do it if so
392 int choice = MessageBox(NULL, "Install Greenstone?", "Greenstone", MB_OKCANCEL | MB_ICONQUESTION );
393 if ( choice == IDOK ) {
394
395 //launch the jar
396 set_splash_step( "LAUNCHING" );
397 spoof_progress( SPOOF_TIME );
398 string cmd = "\"";
399 cmd.append( owd );
400 cmd.append( "\\Java\\Windows\\jre\\bin\\java.exe\" \"-Dorig.dir=" );
401 cmd.append( owd );
402 cmd.append( "\" -jar greenstone.jar" );
403
404 //hide splash screen
405 ShowWindow(splashWnd, SW_HIDE);
406
407 //run the jar
408 int launch_exit_code = process( cmd, false );
409 }
410
411 #endif
412
413 //clean up the temp directory
414 _unlink( "greenstone.jar" );
415 _unlink( "ant.install.log" );
416 _unlink( "@java.installer@" );
417 process( "cmd.exe /c rd /s /q @java.extracted@", false );
418 SetCurrentDirectory( ".." );
419 _rmdir( tempdir.c_str() );
420
421 delete owd;
422
423 return 0;
424
425}
Note: See TracBrowser for help on using the repository browser.