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

Last change on this file since 19009 was 19009, checked in by oranfry, 13 years ago

going back to using the TMP dir for temp files so that installation from CD works

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