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

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

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

File size: 11.0 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
[16079]16HFONT g_hfFont = NULL; //the main splash bitmap
[15689]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;
[15023]23
[15689]24void set_splash_step( char* new_step ) {
25 strcpy( step, new_step );
26 InvalidateRect(splashWnd, NULL, FALSE);
27 UpdateWindow(splashWnd);
[15023]28}
29
[15689]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}
[15023]38
[15689]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
[16079]48int extractResource( const char * basename, const char * type, char * file ) {
[15689]49
[15023]50 HMODULE hModule = GetModuleHandle(NULL);
[15689]51 set_splash_progress( 0 );
[15023]52
[16079]53 int no_chunks;
54 bool chunk_available = true;
55 for ( no_chunks = 0; chunk_available; no_chunks++ ) {
[15023]56
[15689]57 //construct the chunk name
58 char chunkname[127] = {0};
59 strcpy( chunkname, basename );
60 strcat( chunkname, "_" );
61 char chunknum[5] = {0};
[16079]62 itoa( no_chunks+1, chunknum, 10 );
63 strcat( chunkname, chunknum );
64
65 if ( FindResource(hModule, chunkname, type) == NULL ) {
66 chunk_available = false;
[17071]67 break;
[16079]68 }
69 }
70
[17307]71 if ( no_chunks == 0 ) {
72 return 1;
73 }
74
[16079]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};
[15689]82 itoa( i+1, chunknum, 10 );
83 strcat( chunkname, chunknum );
84
[16079]85 //find it
[15689]86 HRSRC hRsrc = FindResource(hModule, chunkname, type);
[16079]87 if (hRsrc == NULL ) return 1; //couldn't find the chunk
[15689]88
89 //load it
90 HGLOBAL hGlobal = LoadResource(hModule, hRsrc);
91 if (hGlobal == NULL) return 1; //couldn't lock
[16079]92
93 //lock it
[15689]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 }
[15023]111
112 return 0;
113
114}
115
[15689]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");
[16079]123 g_hfFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
[15689]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);
[17982]166 BitBlt(hdc, 0, 270, bm.bmWidth, bm.bmHeight, hdcMem, 0, 0, SRCCOPY);
[15689]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
[16079]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
[15689]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
[15813]190 /*
[15689]191 case WM_LBUTTONDOWN: {
192 DeleteObject(g_splash);
193 PostQuitMessage(0);
194 }
195 break;
[15813]196 */
[15689]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
[15095]213}
214
[15689]215//function to process the window
216DWORD WINAPI ProcessWindow( LPVOID lpParam ) {
217
218 const char g_szClassName[] = "splash";
219 WNDCLASSEX wc;
220 MSG Msg;
[15095]221
[15689]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 }
[15095]240
[15689]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;
[15023]251
[15689]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) {
[15023]261
[15689]262 const int SPOOF_TIME = 1000;
263 string command;
264 srand( time(0) );
265 mainInstance = hInstance;
266 mainCmdShow = nCmdShow;
[15095]267
[15689]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 );
[17905]291
[19009]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" );
[15689]297 char id[6]; for( int i=0; i<5; i++ ) id[i] = (char)((rand()%26) + 97); id[5] = '\0'; //id for this instance
[16203]298 string tempdir = ""; tempdir.append( tmp ); tempdir.append( "\\Greenstone-" ); tempdir.append( id );
[17905]299 const char* tmpdir = tempdir.c_str();
[18032]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 }
[19009]306 //SetFileAttributes(tmpdir, FILE_ATTRIBUTE_HIDDEN);
[17905]307 SetCurrentDirectory(tmpdir);
308 delete tmp; // deallocate memory
[17271]309
310 //rip out java archive if it is bundled
311 set_splash_step( "XJAVA" );
[17307]312 int javaIsBundled = (extractResource( "JAVA", "EXE", "@java.installer@" ) == 0);
[17271]313 if ( javaIsBundled ) {
[17342]314 process( "@java.installer@", false );
[17271]315 }
316
[15689]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@" );
[17307]323 string phint = "@java.extracted@";
324 string hint = "";
[15689]325 bool verbose = true;
326 Jvm foundJvm;
[18246]327 bool jvmFound = find( foundJvm, use_minimum, minimum, false, false, phint, hint, verbose );
[15689]328
[15095]329 //if the jvm was not found, try to fix it and find it
330 if ( !jvmFound ) {
[15689]331
[15095]332 //did not find a good java
[16203]333 string message = "This version of Greenstone requires java @java.min.version@ or greater, but ";
[15023]334
[15095]335 //tell them if java is absent or just too old
[18246]336 if ( find( foundJvm, false, minimum, false, false, "", "", false ) ) {
[15689]337 message.append( "your java is too old.");
[15095]338 } else {
[15689]339 message.append( "java could not be found on your computer." );
[15095]340 }
[17271]341 message.append( "\n" );
[15095]342
[17271]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 {
[15689]348
349 //extract the jar
[17919]350 string jarLocation = "greenstone.jar";
[17961]351
[15689]352 set_splash_step( "XJAR" );
[16079]353 extractResource( "JAR", "JAR", (char*) jarLocation.c_str() );
[17271]354
[15689]355 //launch the jar
356 set_splash_step( "LAUNCHING" );
357 spoof_progress( SPOOF_TIME );
358 string cmd = "\"";
359 cmd.append( foundJvm.getWinExecutable() );
[17271]360 cmd.append( "\" -jar greenstone.jar" );
[15689]361
362 //hide splash screen
363 ShowWindow(splashWnd, SW_HIDE);
364
365 //run the jar
366 int launch_exit_code = process( cmd, true );
367
[15146]368 //report how it went
[15689]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);
[15023]373 }
374 }
[15025]375
[15689]376 //clean up the temp directory
[17342]377 _unlink( "greenstone.jar" );
378 _unlink( "ant.install.log" );
379 _unlink( "@java.installer@" );
[17385]380 process( "cmd.exe /c rd /s /q @java.extracted@", false );
[17342]381 SetCurrentDirectory( ".." );
[15689]382 _rmdir( tempdir.c_str() );
[15095]383
[15689]384 return 0;
[15023]385
[15095]386}
Note: See TracBrowser for help on using the repository browser.