root/release-kits/shared/windows/wrapper/wrapper.cpp @ 16203

Revision 16203, 11.2 KB (checked in by oranfry, 11 years ago)

made the wrapper general, so it can be used with greenstone2 or greenstone3 release kits

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        }
68    }
69   
70    for ( int i=0; i<no_chunks; i++ ) {
71   
72        //construct the chunk name
73        char chunkname[127] = {0};
74        strcpy( chunkname, basename );
75        strcat( chunkname, "_" );
76        char chunknum[5] = {0};
77        itoa( i+1, chunknum, 10 );
78        strcat( chunkname, chunknum );
79       
80        //find it
81        HRSRC hRsrc = FindResource(hModule, chunkname, type);
82        if (hRsrc == NULL ) return 1; //couldn't find the chunk
83       
84        //load it
85        HGLOBAL hGlobal = LoadResource(hModule, hRsrc);
86        if (hGlobal == NULL) return 1; //couldn't lock
87       
88        //lock it
89        BYTE* pBytes = (BYTE*) LockResource(hGlobal);
90        if (pBytes == NULL) return 1; //couldn't lock
91       
92        //put it on disk
93        DWORD dwLength = SizeofResource(hModule, hRsrc);
94        ofstream fStream(file, ios::binary | ios::out | ios::app );
95        fStream.write((char*) pBytes, dwLength);
96        fStream.close();
97       
98        //unload
99        UnlockResource(hGlobal);
100        FreeResource(hGlobal);
101       
102        //update the progress
103        set_splash_progress( i * 100 / no_chunks );
104       
105    }
106
107    return 0;
108
109}
110
111//the splash window procedure
112LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
113    switch(msg) {
114
115        case WM_CREATE: {
116            //load in the reusable resources
117            g_splash = LoadBitmap(GetModuleHandle(NULL),"SPLASH");
118            g_hfFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
119            if(g_splash == NULL) {
120                MessageBox(hwnd, "Could not load splash bitmap!", "Error", MB_OK | MB_ICONEXCLAMATION);
121            }
122           
123            //center the window automatically
124            RECT rect;
125            GetWindowRect(hwnd, &rect);
126            int x = (GetSystemMetrics(SM_CXSCREEN) - (rect.right - rect.left)) / 2;
127            int y = (GetSystemMetrics(SM_CYSCREEN) - (rect.bottom - rect.top)) / 2;
128            SetWindowPos(hwnd, HWND_TOP, x, y, 0, 0, SWP_NOSIZE);
129        }
130       
131        case WM_PAINT: {
132            // Don't use MessageBox from inside WM_PAINT
133       
134            //load in the correct resources
135            HBITMAP g_progress = NULL;
136            HBITMAP g_step = NULL;
137            char progress_res[20] = "PROGRESS_";
138            strcat( progress_res, progress );
139            char step_res[20] = "STEP_";
140            strcat( step_res, step );
141            g_progress = LoadBitmap(GetModuleHandle(NULL), progress_res );
142            g_step = LoadBitmap(GetModuleHandle(NULL), step_res );
143            if( g_progress == NULL || g_step == NULL ) {
144                MessageBox(hwnd, "Could not load an image!", "Error", MB_OK | MB_ICONEXCLAMATION);
145            }
146       
147            BITMAP bm; //holds info about the width and height
148            PAINTSTRUCT ps;
149           
150            HDC hdc = BeginPaint(hwnd, &ps);
151            HDC hdcMem = CreateCompatibleDC(hdc);
152           
153            //paint the main splash screen
154            GetObject(g_splash, sizeof(bm), &bm);
155            HBITMAP hbmOld = (HBITMAP)SelectObject(hdcMem, g_splash);
156            BitBlt(hdc, 0, 0, bm.bmWidth, bm.bmHeight, hdcMem, 0, 0, SRCCOPY);
157                       
158            //paint in the progress
159            GetObject(g_progress, sizeof(bm), &bm);
160            SelectObject(hdcMem, g_progress);
161            BitBlt(hdc, 0, 276, bm.bmWidth, bm.bmHeight, hdcMem, 0, 0, SRCCOPY);
162           
163            //paint in the step with transparency
164            GetObject(g_step, sizeof(bm), &bm);
165            SelectObject(hdcMem, g_step);
166            BitBlt(hdc, 0, 276, bm.bmWidth, bm.bmHeight, hdcMem, 0, 0, SRCPAINT);
167           
168            //print the step with text
169            RECT rcClient;
170            GetClientRect(hwnd, &rcClient);
171            //DrawText(hdc, "This is the step", -1, &rcClient, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
172           
173            //restore the hdc
174            SelectObject(hdcMem, hbmOld);
175           
176            //release resources
177            DeleteDC(hdcMem);
178            EndPaint(hwnd, &ps);
179            DeleteObject(g_progress);
180            DeleteObject(g_step);
181           
182        }
183        break;
184       
185        /*
186        case WM_LBUTTONDOWN: {
187            DeleteObject(g_splash);
188            PostQuitMessage(0);
189        }
190        break;
191        */
192       
193        case WM_CLOSE:
194            DestroyWindow(hwnd);
195            break;
196       
197        case WM_DESTROY:
198            DeleteObject(g_splash);
199            PostQuitMessage(0);
200            break;
201       
202        default:
203            return DefWindowProc(hwnd, msg, wParam, lParam);
204    }
205
206    return 0;
207
208}
209
210//function to process the window
211DWORD WINAPI ProcessWindow( LPVOID lpParam ) {
212   
213    const char g_szClassName[] = "splash";
214    WNDCLASSEX wc;
215    MSG Msg;
216
217    //Step 1: Registering the Window Class
218    wc.cbSize = sizeof(WNDCLASSEX);
219    wc.style = 0;
220    wc.lpfnWndProc = WndProc;
221    wc.cbClsExtra = 0;
222    wc.cbWndExtra = 0;
223    wc.hInstance = mainInstance;
224    wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
225    wc.hCursor = LoadCursor(NULL, IDC_ARROW);
226    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
227    wc.lpszMenuName = NULL;
228    wc.lpszClassName = g_szClassName;
229    wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
230    if(!RegisterClassEx(&wc)) {
231        MessageBox(NULL, "Window Registration Failed!", "Error!",
232        MB_ICONEXCLAMATION | MB_OK);
233        return 0;
234    }
235
236    // Step 2: Creating the Window
237    splashWnd = CreateWindowEx( WS_EX_TOOLWINDOW, g_szClassName, "", WS_POPUP | SS_BITMAP, 0, 0, 420, 300, NULL, NULL, mainInstance, NULL);
238    if( splashWnd == NULL ) {
239        MessageBox(NULL, "Window Creation Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK);
240        return 0;
241    }
242    ShowWindow(splashWnd, mainCmdShow);
243    UpdateWindow(splashWnd);
244
245    window_loaded = true;
246   
247    // Step 3: The Message Loop
248    while(GetMessage(&Msg, NULL, 0, 0) > 0) {
249        TranslateMessage(&Msg);
250        DispatchMessage(&Msg);
251    }
252    return 0;
253}
254
255int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
256   
257    const int SPOOF_TIME = 1000;
258    string command;
259    srand( time(0) );
260    mainInstance = hInstance;
261    mainCmdShow = nCmdShow;
262   
263    //start the window
264    HANDLE hThread;
265    DWORD dwThreadId, dwThrdParam = 1;
266    hThread = CreateThread(
267       NULL,                        // no security attributes
268       0,                           // use default stack size 
269       ProcessWindow,               // thread function
270       &dwThrdParam,                // argument to thread function
271       0,                           // use default creation flags
272       &dwThreadId);                // returns the thread identifier
273    if ( hThread == NULL ) {
274        return -1;
275        //ErrorExit( "CreateThread failed." );
276    }
277    CloseHandle( hThread );
278   
279    while ( !window_loaded ) {
280        Sleep( 100 );
281    }
282   
283    //create the temp folder and change to it
284    set_splash_step( "TMP" );
285    spoof_progress( SPOOF_TIME );
286    char* tmp = getenv( "TMP" );
287    char id[6]; for( int i=0; i<5; i++ ) id[i] = (char)((rand()%26) + 97); id[5] = '\0'; //id for this instance
288    string tempdir = ""; tempdir.append( tmp ); tempdir.append( "\\Greenstone-" ); tempdir.append( id );
289    _mkdir( tempdir.c_str() );
290    SetCurrentDirectory( tempdir.c_str() );
291   
292    //find java
293    //set_splash_status( hInstance, statusWnd, "STATUS_SEARCHING4J", 1000 );
294    set_splash_step( "SEARCHING" );
295    spoof_progress( SPOOF_TIME );
296    bool use_minimum = true;
297    Jvm minimum;
298    minimum.setVersionFromString( "@java.min.version@" );
299    string hint = "";
300    bool verbose = true;
301    Jvm foundJvm;
302    bool jvmFound = find( foundJvm, use_minimum, minimum, hint, verbose );
303   
304    //if the jvm was not found, try to fix it and find it
305    if ( !jvmFound ) {
306
307        //did not find a good java
308        string message = "This version of Greenstone requires java @java.min.version@ or greater, but ";
309       
310        //tell them if java is absent or just too old
311        if ( find( foundJvm, false, minimum, "", false ) ) {
312            message.append( "your java is too old.");
313        } else {
314            message.append( "java could not be found on your computer." );
315        }
316        message.append( "\n\n" );
317       
318        //is this an installer with the bundled JRE?
319        set_splash_step( "XJAVA" );
320        int extract_result = extractResource( "JAVA", "EXE", "@java.installer@" );
321
322        if ( extract_result == 0 ) {
323           
324            //yes, JRE is bundled
325            message.append( "This installer is bundled with a suitible version of java (bundled.version.java)\n");
326            message.append( "The installer program for this java will now be launched.\n" );
327            string title = "Must install java first";
328            MessageBox(NULL, message.c_str(), title.c_str(), MB_OK);
329            ShellExecute(NULL, "open", "@java.installer@", NULL, NULL, SW_SHOWNORMAL);
330            jvmFound = true; //assume the java installation went well
331           
332        } else {
333           
334            //no, JRE is not bundled
335            set_splash_step( "SEARCHING" );
336            set_splash_progress( 100 ); //we are done searching
337            message.append( "Please install java (@java.min.version@ or newer) and try again.\n" );
338            message.append( "Or, download an installer with bundled java and use that instead of this one" );
339            string title = "Installation Failed: Couldn't find java";
340            MessageBox(NULL, message.c_str(), title.c_str(), MB_OK);
341        }
342    }
343   
344   
345    //if we have found it by now, launch the installer
346    if ( jvmFound ) {
347               
348        //extract the jar
349        string jarLocation = ""; jarLocation.append( tempdir ); jarLocation.append( "\\greenstone.jar" );
350        //set_splash_status( hInstance, statusWnd, "STATUS_JAR", 0 );
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    SetCurrentDirectory("..");
381    _rmdir( tempdir.c_str() );
382
383    return 0;
384   
385}
Note: See TracBrowser for help on using the browser.