~ubuntu-branches/ubuntu/precise/kompozer/precise

« back to all changes in this revision

Viewing changes to mozilla/tools/preloader/preloader.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Anthony Yarusso
  • Date: 2007-08-27 01:11:03 UTC
  • Revision ID: james.westby@ubuntu.com-20070827011103-2jgf4s6532gqu2ka
Tags: upstream-0.7.10
ImportĀ upstreamĀ versionĀ 0.7.10

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 
2
/* ***** BEGIN LICENSE BLOCK *****
 
3
 * Version: NPL 1.1/GPL 2.0/LGPL 2.1
 
4
 *
 
5
 * The contents of this file are subject to the Netscape Public License
 
6
 * Version 1.1 (the "License"); you may not use this file except in
 
7
 * compliance with the License. You may obtain a copy of the License at
 
8
 * http://www.mozilla.org/NPL/
 
9
 *
 
10
 * Software distributed under the License is distributed on an "AS IS" basis,
 
11
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 
12
 * for the specific language governing rights and limitations under the
 
13
 * License.
 
14
 *
 
15
 * The Original Code is mozilla.org code.
 
16
 *
 
17
 * The Initial Developer of the Original Code is 
 
18
 * Netscape Communications Corporation.
 
19
 * Portions created by the Initial Developer are Copyright (C) 1998
 
20
 * the Initial Developer. All Rights Reserved.
 
21
 *
 
22
 * Contributor(s):
 
23
 *
 
24
 * Alternatively, the contents of this file may be used under the terms of
 
25
 * either the GNU General Public License Version 2 or later (the "GPL"), or 
 
26
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 
27
 * in which case the provisions of the GPL or the LGPL are applicable instead
 
28
 * of those above. If you wish to allow use of your version of this file only
 
29
 * under the terms of either the GPL or the LGPL, and not to allow others to
 
30
 * use your version of this file under the terms of the NPL, indicate your
 
31
 * decision by deleting the provisions above and replace them with the notice
 
32
 * and other provisions required by the GPL or the LGPL. If you do not delete
 
33
 * the provisions above, a recipient may use your version of this file under
 
34
 * the terms of any one of the NPL, the GPL or the LGPL.
 
35
 *
 
36
 * ***** END LICENSE BLOCK ***** */
 
37
 
 
38
/****************************************************************************
 
39
 
 
40
  Module Notes:
 
41
  =============
 
42
 
 
43
  Overview:
 
44
    This little win32 application knows how to load the modules for
 
45
    intalled version netscape and mozilla browsers. It preloads these
 
46
    modules in order to make overall startup time seem faster to our
 
47
    end users. 
 
48
 
 
49
  Notes:
 
50
    We assume that this preloader is stored with the mozilla/netscape
 
51
    install somewhere, and that a link to that file is stored in either 
 
52
    the CURRENT_USER startup folder or the ALL_USERS startup folder. 
 
53
    If it's get's put somewhere else (like DEFAULT_USERS) then the 
 
54
    code we use to remove ourselves from the startup folder needs to 
 
55
    be adjusted accordingly.
 
56
 
 
57
 
 
58
  Who       When      What Changed
 
59
  ==================================================================
 
60
  rickg   03.15.01    Version 1.0 of the preloader; proof of concept. 
 
61
 
 
62
  rickg   04.16.01    changed code to use system-tray API's directly
 
63
  rickg   04.17.01    added menu code to system tray to allow user to disable us
 
64
  rickg   04.18.01    added code to auto-remove the preloader from startup folder
 
65
  rickg   04.18.01    switched strings to resource files for easier localization.
 
66
  rickg   04.23.01    added code to prevent multiple instances
 
67
  rickg   04.23.01    added code to prevent preloader operation if browser is already running
 
68
  rickg   04.23.01    added code to display unique icon (ugly yellow) if browser is already running.
 
69
  rickg   04.23.01    added code to get/set "tuning" config settings from config dialog 
 
70
  rickg   04.24.01    added code to get/set "tuning" settings from registry
 
71
  rickg   04.24.01    added accelerators to menu, and changed tooltip    
 
72
  rickg   04.24.01    moved more strings to resource file
 
73
  rickg   04.24.01    hooked up "tuning" config settings for gModulePercent and gFrequencyPercent
 
74
  rickg   04.27.01    hooked up "tuning" config settings for gEntryPercent
 
75
  rickg   04.27.01    added a new config setting that specifies which browser instance to preload
 
76
 
 
77
 ****************************************************************************/
 
78
 
 
79
 
 
80
//additional includes
 
81
#include "resrc1.h"
 
82
#include <atlbase.h>
 
83
#include <windows.h>
 
84
#include <commctrl.h>
 
85
#include <stdio.h>
 
86
 
 
87
//trayicon notification message
 
88
#define WM_TRAY   WM_USER+0x100+5
 
89
 
 
90
static  NOTIFYICONDATA gTrayData = {0,0,0,0,0,0,0};
 
91
static  HWND gMainWindow=0;
 
92
static  HICON gCheckIcons[2] = {0,0};
 
93
static  HICON gBrowserRunningIcon = {0};
 
94
 
 
95
static  const int kLoadTimerID = 2;
 
96
static  const int kPingModuleTimerID = 3;
 
97
 
 
98
static  char  gExePath[1024]={0};   //used to keep a path to our executable...
 
99
static  const char* thePathSep="\\";
 
100
static  const char* gBrowserWindowName=0;
 
101
static  const char *gRegKey=0;
 
102
static  const char *gRegSubKey=0;
 
103
 
 
104
static  HINSTANCE gMainInst=0;      //application main instance handle
 
105
static  int gModulePercent = 100;   //This tells us the percent of modules to load (default value)
 
106
static  int gEntryPercent  = 50;    //Tells us the % of entry points per module (default value)
 
107
static  int gFrequencyPercent = 50; //Tells us relative frequency to call entry points (default value)
 
108
 
 
109
/***********************************************************
 
110
  call this to change the icon shown for our tray app 
 
111
 ***********************************************************/
 
112
void SetTrayIcon(const HICON hIcon){
 
113
  gTrayData.hIcon=hIcon;
 
114
  Shell_NotifyIcon(NIM_MODIFY, &gTrayData);
 
115
}
 
116
 
 
117
/***********************************************************
 
118
  call this to change the tooltip shown for our tray app
 
119
 ***********************************************************/
 
120
void SetTrayToolTip(const char *aTip){
 
121
  if(aTip) {
 
122
    if(!gTrayData.szTip[0])  //if previously no tooltip
 
123
      gTrayData.uFlags=gTrayData.uFlags | NIF_TIP;
 
124
    strcpy(gTrayData.szTip, aTip);
 
125
  }
 
126
  else gTrayData.uFlags=NIF_ICON | NIF_MESSAGE;
 
127
  Shell_NotifyIcon(NIM_MODIFY, &gTrayData);
 
128
}
 
129
 
 
130
/***********************************************************
 
131
  call this to init and display the tray app.
 
132
 ***********************************************************/
 
133
void ShowTrayApp(bool aVisible) {
 
134
 
 
135
  if(aVisible) {
 
136
    gTrayData.cbSize=sizeof(NOTIFYICONDATA);
 
137
    gTrayData.hWnd=gMainWindow;
 
138
    gTrayData.uID=IDI_CHECK;  //our tray ID
 
139
    gTrayData.uFlags= NIF_ICON | NIF_MESSAGE | NIF_TIP;
 
140
    gTrayData.uCallbackMessage=WM_TRAY; //send a WM_TRAY message when users clicks in our tray window
 
141
    gTrayData.hIcon=gCheckIcons[0]; //init our default icon
 
142
  
 
143
    Shell_NotifyIcon(NIM_ADD, &gTrayData); //now show our tray icon
 
144
 
 
145
    char theTip[256];
 
146
    if(LoadString(gMainInst,IDS_TOOLTIP,theTip,sizeof(theTip))){
 
147
      SetTrayToolTip(theTip);  
 
148
    }
 
149
    else SetTrayToolTip("Click to configure moz-preloader");
 
150
    SetTrayIcon(gCheckIcons[0]);
 
151
  }
 
152
  else {
 
153
    Shell_NotifyIcon(NIM_DELETE, &gTrayData);
 
154
  }
 
155
}
 
156
 
 
157
//********************************************************************
 
158
 
 
159
 
 
160
static bool  gUseFullModuleList = false;
 
161
 
 
162
 
 
163
//this enum distinguishes version of netscape (and mozilla).
 
164
enum eAppVersion {eNetscape65, eNetscape60, eMozilla, eNetscapePre60, eUserPath,eUnknownVersion,eAutoDetect};
 
165
 
 
166
static eAppVersion  gAppVersion=eNetscape65;
 
167
 
 
168
//Constants for my DLL loader to use...
 
169
static char gMozPath[2048]= {0};
 
170
static char gUserPath[2048]= {0};
 
171
static int  gPreloadJava = 1;
 
172
 
 
173
static char gMozModuleList[4096] = {0};
 
174
static char* gModuleCP = gMozModuleList;
 
175
static int  gModuleCount=0;
 
176
static int gMozPathLen=0;
 
177
static int gUserPathLen=0;
 
178
 
 
179
static const char *theMozPath=0;
 
180
static int  gDLLIndex=0;
 
181
 
 
182
 
 
183
/*********************************************************
 
184
  This counts the number of unique modules in the given
 
185
  list of modules, by counting semicolons.
 
186
 *********************************************************/
 
187
int CountModules(char*&aModuleList) {
 
188
  char *cp=aModuleList;
 
189
  
 
190
  int count=0;
 
191
 
 
192
  while(*cp) {
 
193
    if(*cp) {
 
194
      count++;
 
195
    }
 
196
    char *theSemi=strchr(cp,';');
 
197
    if(theSemi) {
 
198
      cp=theSemi+1; //skip the semi
 
199
    }
 
200
  }
 
201
  return count;
 
202
}
 
203
 
 
204
 
 
205
/*********************************************************
 
206
  This list describes the set of modules for NS6.0
 
207
  XXX This data should really live in a string table too.
 
208
 *********************************************************/
 
209
int Get60ModuleList(char*&aModuleList) {
 
210
  
 
211
  static char* theModuleList = 
 
212
 
 
213
    "nspr4;plds4;plc4;mozreg;xpcom;img3250;zlib;" \
 
214
 
 
215
    "gkgfxwin;gkwidget;" \
 
216
 
 
217
    "components\\gkparser;" \
 
218
    "jpeg3250;" \
 
219
    "js3250;" \
 
220
    "jsj3250;" \
 
221
    "jsdom;" \
 
222
    "components\\jsloader;" \
 
223
 
 
224
    "components\\activation;" \
 
225
    "components\\appcomps;" \
 
226
    "components\\addrbook;" \
 
227
    "components\\appshell;" \
 
228
    "components\\caps;" \
 
229
    "components\\chardet;" \
 
230
    "components\\chrome;" \
 
231
    "components\\cookie;" \
 
232
    "components\\docshell;" \
 
233
    "components\\editor;" \
 
234
    "components\\gkhtml;" \
 
235
    "components\\gkplugin;" \
 
236
    "components\\gkview;" \
 
237
    "gkwidget;" \
 
238
    "components\\jar50;" \
 
239
    "components\\lwbrk;" \
 
240
    "mozreg;" \
 
241
    "components\\necko;" \
 
242
    "components\\nsgif;" \
 
243
    "components\\nslocale;" \
 
244
    "components\\nsprefm;" \
 
245
    "components\\profile;" \
 
246
    "components\\psmglue;" \
 
247
    "components\\rdf;" \
 
248
    "components\\shistory;" \
 
249
    "components\\strres;" \
 
250
    "components\\txmgr;" \
 
251
    "components\\txtsvc;" \
 
252
    "components\\ucharuti;" \
 
253
    "components\\uconv;" \
 
254
    "components\\ucvlatin;" \
 
255
    "components\\ucvcn;" \
 
256
    "components\\ucvja;" \
 
257
    "components\\urildr;" \
 
258
    "components\\wallet;" \
 
259
    "components\\xpc3250;" \
 
260
    "components\\xpinstal;" \
 
261
    "components\\xppref32;" \
 
262
    "components\\mozbrwsr;" \
 
263
    "components\\nsjpg;" \
 
264
    "components\\oji;" \
 
265
 
 
266
    "msgbsutl;" \
 
267
    "components\\mork;" \
 
268
    "components\\msglocal;" \
 
269
 
 
270
    "xprt;" \
 
271
    "xptl;" \
 
272
    "xpcs;";
 
273
 
 
274
  strcpy(aModuleList,theModuleList);
 
275
  return CountModules(theModuleList);
 
276
}
 
277
 
 
278
/*********************************************************
 
279
  This list describes the set of modules for NS6.5
 
280
  XXX This data should really live in a string table too.
 
281
 *********************************************************/
 
282
int Get65ModuleList(char *&aModuleList) {
 
283
  static char* theModuleList = 
 
284
 
 
285
  "nspr4;plds4;plc4;mozreg;xpcom;img3250;zlib;" \
 
286
 
 
287
  "gkgfxwin;gkwidget;" \
 
288
 
 
289
  "components\\gkparser;" \
 
290
  "jpeg3250;" \
 
291
  "js3250;" \
 
292
  "jsj3250;" \
 
293
  "jsdom;" \
 
294
  "components\\jsloader;" \
 
295
 
 
296
  "components\\activation;" \
 
297
  "components\\addrbook;" \
 
298
  "components\\appcomps;" \
 
299
  "components\\appshell;" \
 
300
  "components\\embedcomponents;"
 
301
  "components\\caps;" \
 
302
  "components\\chardet;" \
 
303
  "components\\chrome;" \
 
304
  "components\\cookie;" \
 
305
  "components\\docshell;" \
 
306
  "components\\editor;" \
 
307
  "components\\gkplugin;" \
 
308
  "components\\gkview;" \
 
309
  "gkwidget;" \
 
310
  "gfx2;" \
 
311
  "components\\jar50;" \
 
312
  "components\\lwbrk;" \
 
313
  "components\\necko;" \
 
314
  "components\\nsgif;" \
 
315
  "components\\nslocale;" \
 
316
  "components\\nsprefm;" \
 
317
  "components\\profile;" \
 
318
  "components\\psmglue;" \
 
319
  "components\\rdf;" \
 
320
  "components\\shistory;" \
 
321
  "components\\strres;" \
 
322
  "components\\txmgr;" \
 
323
  "components\\txtsvc;" \
 
324
  "components\\ucharuti;" \
 
325
  "components\\uconv;" \
 
326
  "components\\ucvlatin;" \
 
327
  "components\\ucvcn;" \
 
328
  "components\\ucvja;" \
 
329
  "components\\urildr;" \
 
330
  "components\\wallet;" \
 
331
  "components\\xpc3250;" \
 
332
  "components\\xpinstal;" \
 
333
  "components\\xppref32;" \
 
334
  "components\\xmlextras;" \
 
335
 
 
336
  "components\\gklayout;" \
 
337
  "components\\gkcontent;" \
 
338
  "components\\mozbrwsr;" \
 
339
  "components\\nsjpg;" \
 
340
  "components\\oji;" \
 
341
 
 
342
  "msgbsutl;" \
 
343
  "components\\mork;" \
 
344
  "components\\msglocal;" \
 
345
 
 
346
  "xprt;" \
 
347
  "xptl;" \
 
348
  "xpcs;";
 
349
 
 
350
  strcpy(aModuleList,theModuleList);
 
351
  return CountModules(theModuleList);
 
352
}
 
353
 
 
354
 
 
355
/*********************************************************
 
356
  ...
 
357
 *********************************************************/
 
358
static char gKeyBuffer[512]={0};
 
359
static char gSubKeyBuffer[128]={0};
 
360
static char gWinNameBuffer[128]={0};     //this is the expected browser name.
 
361
 
 
362
void GetPathFromRegistry(eAppVersion aVersion, const char *&aKey, const char *&aSubkey, char *&aModuleList, int &aSize) {
 
363
  
 
364
  switch(aVersion) { 
 
365
  
 
366
    case eMozilla:
 
367
 
 
368
      aKey=(LoadString(gMainInst,IDS_MOZ_KEY,gKeyBuffer,sizeof(gKeyBuffer))) ? gKeyBuffer : "Software\\Mozilla.org\\Mozilla\\0.8 (en)\\Main"; 
 
369
 
 
370
      aSubkey = (LoadString(gMainInst,IDS_SUBKEY_INSTALL,gSubKeyBuffer,sizeof(gSubKeyBuffer))) ? gSubKeyBuffer : "Install Directory";
 
371
 
 
372
      gBrowserWindowName = (LoadString(gMainInst,IDS_MOZ_WINDOWNAME,gWinNameBuffer,sizeof(gWinNameBuffer))) ? gWinNameBuffer: "- Mozilla";
 
373
 
 
374
      aSize=Get65ModuleList(aModuleList);
 
375
 
 
376
      break;
 
377
    
 
378
    case eNetscape65:
 
379
 
 
380
      aKey=(LoadString(gMainInst,IDS_NS65_KEY,gKeyBuffer,sizeof(gKeyBuffer))) ? gKeyBuffer : "Software\\Netscape\\Netscape 6\\6.5 (en)\\Main"; 
 
381
 
 
382
      aSubkey = (LoadString(gMainInst,IDS_SUBKEY_INSTALL,gSubKeyBuffer,sizeof(gSubKeyBuffer))) ? gSubKeyBuffer : "Install Directory";
 
383
 
 
384
      gBrowserWindowName = (LoadString(gMainInst,IDS_NS_WINDOWNAME,gWinNameBuffer,sizeof(gWinNameBuffer))) ? gWinNameBuffer: "- Netstacpe 6";
 
385
 
 
386
      aSize=Get65ModuleList(aModuleList);
 
387
 
 
388
      break;
 
389
    
 
390
    case eNetscape60:
 
391
 
 
392
      aKey=(LoadString(gMainInst,IDS_NS60_KEY,gKeyBuffer,sizeof(gKeyBuffer))) ? gKeyBuffer : "Software\\Netscape\\Netscape 6\\6.0 (en)\\Main"; 
 
393
 
 
394
      aSubkey = (LoadString(gMainInst,IDS_SUBKEY_PATH,gSubKeyBuffer,sizeof(gSubKeyBuffer))) ? gSubKeyBuffer : "Path";
 
395
 
 
396
      gBrowserWindowName = (LoadString(gMainInst,IDS_NS_WINDOWNAME,gWinNameBuffer,sizeof(gWinNameBuffer))) ? gWinNameBuffer: "- Netstacpe 6";
 
397
 
 
398
      aSize=Get60ModuleList(aModuleList);
 
399
 
 
400
      break;
 
401
 
 
402
    case eNetscapePre60:
 
403
 
 
404
      aKey=(LoadString(gMainInst,IDS_PRE60_KEY,gKeyBuffer,sizeof(gKeyBuffer))) ? gKeyBuffer : "Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\netscp6.exe"; 
 
405
 
 
406
      aSubkey = (LoadString(gMainInst,IDS_SUBKEY_PATH,gSubKeyBuffer,sizeof(gSubKeyBuffer))) ? gSubKeyBuffer : "Path";
 
407
 
 
408
      gBrowserWindowName = (LoadString(gMainInst,IDS_NS_WINDOWNAME,gWinNameBuffer,sizeof(gWinNameBuffer))) ? gWinNameBuffer: "- Netstacpe 6";
 
409
 
 
410
      aSize=Get60ModuleList(aModuleList);
 
411
 
 
412
      break;
 
413
 
 
414
    case eUserPath:
 
415
      aKey  = 0;
 
416
      aSubkey= 0;
 
417
      strcpy(gMozPath,gUserPath);
 
418
 
 
419
      aSize=Get65ModuleList(aModuleList);
 
420
 
 
421
      gBrowserWindowName = (LoadString(gMainInst,IDS_MOZ_WINDOWNAME,gWinNameBuffer,sizeof(gWinNameBuffer))) ? gWinNameBuffer: "- Mozilla";
 
422
 
 
423
      break;
 
424
 
 
425
    case eUnknownVersion:
 
426
      break;
 
427
  }
 
428
}
 
429
 
 
430
/*********************************************************
 
431
  Get the path to the netscape6 browser via the registry...
 
432
 *********************************************************/
 
433
bool GetMozillaRegistryInfo(eAppVersion &aVersion) {
 
434
 
 
435
  //first we try to get the registry info based on the command line settings.
 
436
  //if that fails, we try others.
 
437
 
 
438
  bool found=false;
 
439
  LONG theOpenResult = 1; //any non-zero will do to initialize this...
 
440
 
 
441
  if ( aVersion == eUserPath) {
 
442
    found=true;
 
443
  }  
 
444
 
 
445
  while((ERROR_SUCCESS!=theOpenResult) && (aVersion<eUnknownVersion)) {
 
446
     
 
447
    GetPathFromRegistry(aVersion,gRegKey,gRegSubKey,gModuleCP,gModuleCount);
 
448
 
 
449
    CRegKey theRegKey;
 
450
 
 
451
    if((eUserPath!=aVersion) && (gRegKey)) {
 
452
      theOpenResult=theRegKey.Open(HKEY_LOCAL_MACHINE,gRegKey,KEY_QUERY_VALUE);
 
453
 
 
454
      if(ERROR_SUCCESS==theOpenResult) {
 
455
        DWORD theSize=1024;
 
456
 
 
457
        theRegKey.QueryValue(gMozPath,gRegSubKey,&theSize);
 
458
 
 
459
        if((ERROR_SUCCESS==theOpenResult) && (aVersion!=eUserPath)) {
 
460
 
 
461
          theSize=1024;
 
462
          char theCachedModuleList[1024] = {0};
 
463
 
 
464
          theRegKey.QueryValue(theCachedModuleList,"Modules",&theSize);
 
465
 
 
466
          if(theCachedModuleList[0]) {
 
467
            strcpy(gMozModuleList,theCachedModuleList);
 
468
          }
 
469
          else {
 
470
            theRegKey.Create(HKEY_LOCAL_MACHINE,gRegKey);
 
471
            theRegKey.SetValue( HKEY_LOCAL_MACHINE, gRegKey, gMozModuleList, "Modules");
 
472
          }
 
473
        }
 
474
 
 
475
        found=true;
 
476
        break;
 
477
      }
 
478
    }
 
479
    aVersion=eAppVersion(int(aVersion)+1);
 
480
    
 
481
  } //while
 
482
 
 
483
  gMozPathLen=strlen(gMozPath);
 
484
  gModuleCP = gMozModuleList;
 
485
 
 
486
  return found;
 
487
}
 
488
 
 
489
 
 
490
/*********************************************************
 
491
  Extract the "next" module name from our module name list.
 
492
  XXX The module names should come from string resources.
 
493
 *********************************************************/
 
494
void GetNextModuleName(char* aName) {
 
495
  //scan ahead to find the next ';' or the end of the string...
 
496
  bool done=false;
 
497
  char theChar=0;
 
498
 
 
499
  aName[0]=0;
 
500
 
 
501
  char *theCP=gModuleCP;
 
502
 
 
503
  while(*theCP) {
 
504
    theChar=*theCP;
 
505
    if(';'==theChar)
 
506
      break;
 
507
    else theCP++;
 
508
  }
 
509
 
 
510
  if(theCP!=gModuleCP) {
 
511
    size_t theSize=theCP-gModuleCP;
 
512
    strncpy(aName,gModuleCP,theSize);
 
513
    aName[theSize]=0;
 
514
    gModuleCP=theCP;
 
515
    while(';'==*gModuleCP)
 
516
      gModuleCP++;
 
517
  }
 
518
 
 
519
}
 
520
 
 
521
/****************************************************************
 
522
  The following types are fraudulent. They're just here so 
 
523
  we can write up calls entry points in each module.
 
524
 ****************************************************************/
 
525
 
 
526
const  int        gMaxDLLCount=256;
 
527
const  int        gMaxProcCount=512;
 
528
static HINSTANCE  gInstances[gMaxDLLCount];
 
529
static long*      gFuncTable[gMaxDLLCount][gMaxProcCount];
 
530
static int        gDLLCount=0;
 
531
static int        gMaxEntryIndex=0;
 
532
 
 
533
 
 
534
/****************************************************************
 
535
  This helper function is called by LoadModule. We separated this
 
536
  stuff out so we can use the same code to load java modules 
 
537
  that aren't in the mozilla directory. 
 
538
 ****************************************************************/
 
539
HINSTANCE LoadModuleFromPath(const char* aPath) {
 
540
 
 
541
  HINSTANCE theInstance=gInstances[gDLLCount++]=LoadLibrary(aPath);
 
542
 
 
543
    //we'll constrain the steprate to the range 1..20.
 
544
  static double kPercent=(100-gEntryPercent)/100.0;
 
545
  static const int kEntryStepRate=1+int(20*kPercent);
 
546
  int theEntryCount=0;
 
547
 
 
548
  if(theInstance) {
 
549
    //let's get addresses throughout the module, skipping by the rate of kEntryStepRate.
 
550
    for(int theEntryPoint=0;theEntryPoint<gMaxProcCount;theEntryPoint++){
 
551
      long *entry=(long*)::GetProcAddress(theInstance,MAKEINTRESOURCE(1+(kEntryStepRate*theEntryPoint)));
 
552
      if(entry) {
 
553
        gFuncTable[gDLLCount-1][theEntryCount++]=entry;
 
554
      }
 
555
      else {
 
556
        break;
 
557
      }
 
558
    }
 
559
    if(theEntryCount>gMaxEntryIndex)
 
560
      gMaxEntryIndex=theEntryCount; //we track the highest index we find.
 
561
  }
 
562
 
 
563
  return theInstance;
 
564
}
 
565
 
 
566
 
 
567
/****************************************************************
 
568
  Call this once for each module you want to preload.
 
569
  We use gEntryPercent to determine what percentage of entry 
 
570
  p oints to acquire (we will always get at least 1, and we'll
 
571
  skip at most 20 entry points at a time).
 
572
 ****************************************************************/
 
573
HINSTANCE LoadModule(const char* aName) {
 
574
 
 
575
  //we operate on gMozPath directly to avoid an unnecessary string copy.
 
576
  //when we're done with this method, we reset gMozpath to it's original value for reuse.
 
577
 
 
578
  strcat(gMozPath,aName);
 
579
  strcat(gMozPath,".dll");
 
580
 
 
581
  HINSTANCE theInstance = LoadModuleFromPath(gMozPath);
 
582
 
 
583
  gMozPath[gMozPathLen]=0;
 
584
  return theInstance;
 
585
}
 
586
 
 
587
 
 
588
BOOL CALLBACK EnumWindowsProc(HWND hwnd,LPARAM lParam ) {
 
589
 
 
590
  char buf[256]={0};
 
591
  if(GetWindowText(hwnd,buf,sizeof(buf))){
 
592
    if(strstr(buf,gBrowserWindowName)) {
 
593
      return FALSE; //stop iterating now...
 
594
    }
 
595
  }
 
596
  return TRUE;
 
597
}
 
598
 
 
599
/****************************************************************
 
600
  Call this to detect whether the browser is running.
 
601
  We cache the result to speed up this function (by preventing
 
602
  subsuquent searches of top level windows).
 
603
 ****************************************************************/
 
604
bool BrowserIsRunning() {
 
605
  static bool gBrowserIsRunning=false;
 
606
  
 
607
  if(!gBrowserIsRunning) {
 
608
    if(!EnumWindows(EnumWindowsProc,0)) {
 
609
      gBrowserIsRunning=true;
 
610
    }
 
611
  }
 
612
 
 
613
  return gBrowserIsRunning;
 
614
}
 
615
 
 
616
/****************************************************************
 
617
  This function get's called repeatedly to call on a timer,
 
618
  and it calls GetProcAddr() to keep modules from paging.
 
619
 
 
620
  NOTE: This method uses gFrequencyPercent to determine how much
 
621
  work to do each time it gets called.
 
622
 
 
623
 ****************************************************************/
 
624
VOID CALLBACK KeepAliveTimerProc(HWND hwnd, UINT uMsg, UINT idEvent, DWORD dwTime  ) {
 
625
 
 
626
  //let's go see if mozilla is running.
 
627
  //if so, then bail out without pinging modules...
 
628
  
 
629
  if(BrowserIsRunning()) {
 
630
    return;
 
631
  }
 
632
 
 
633
  static bool theTimerIsRunning=false;
 
634
  static int  theCurrentModule=0;
 
635
  static int  theCurrentProc=0;
 
636
 
 
637
  if(!theTimerIsRunning) { //ignore other timer calls till we're done.
 
638
    theTimerIsRunning=true;
 
639
 
 
640
      //constrain the step to 1..gDLLCount
 
641
    static const double kPercent=gFrequencyPercent/100.0;
 
642
    static const int kMaxSteps=1+int(3*gDLLCount*kPercent);
 
643
 
 
644
    int count=0;
 
645
 
 
646
    //this version iterates the entry points in each module before moving to the next module
 
647
 
 
648
    while(count<kMaxSteps) {
 
649
 
 
650
      volatile long *p=(long*)gFuncTable[theCurrentModule][theCurrentProc];
 
651
      count++;
 
652
      if (p) {
 
653
        if (*p && p){  
 
654
        //don't actually invoke it, just cause it to load into memory...
 
655
        //note that modules have different number of entry points.
 
656
        //so not all modules have an entry point at theCurrentProc index.
 
657
          int x=10;
 
658
        }
 
659
      }
 
660
 
 
661
#define _DEPTH_FIRST
 
662
#ifdef _DEPTH_FIRST
 
663
      
 
664
      if(theCurrentModule >= gDLLCount) {
 
665
        theCurrentModule = 0;
 
666
        theCurrentProc = (theCurrentProc>=gMaxEntryIndex) ? 0 : theCurrentProc+1;
 
667
      }
 
668
      else {
 
669
        theCurrentModule++;
 
670
      }
 
671
 
 
672
#else //breadth first...
 
673
 
 
674
      if(theCurrentProc >= gMaxEntryIndex) {
 
675
        theCurrentProc=0;
 
676
        theCurrentModule = (theCurrentModule>=gDLLCount) ? 0 : theCurrentModule+1;
 
677
      }
 
678
      else {
 
679
        theCurrentProc++;
 
680
      }
 
681
 
 
682
#endif
 
683
 
 
684
    }
 
685
 
 
686
    theTimerIsRunning=false;
 
687
  }
 
688
}
 
689
 
 
690
 
 
691
/****************************************************************
 
692
  This gets called repeatedly by a windows timer, and loads
 
693
  the modules that it gets from the modulelist (see top of this file).
 
694
 
 
695
  This routine has been updated to account for the gModulesPercent
 
696
  setting (1-100). We'll load modules until we cross over this 
 
697
  percentage.
 
698
 ****************************************************************/
 
699
VOID CALLBACK LoadModuleTimerProc(HWND hwnd, UINT uMsg, UINT idEvent,DWORD dwTime) {
 
700
 
 
701
  static bool theTimerIsRunning=false;
 
702
  static int  gTrayIconIndex = 0;
 
703
 
 
704
  if(!theTimerIsRunning) {
 
705
    theTimerIsRunning=true;
 
706
 
 
707
      //gDLLCount is the number of modules loaded so far
 
708
      //gModuleCount is the total number of modules we know about
 
709
      //gModulePercent is the total % of modules we're being asked to load (config setting)
 
710
 
 
711
    double theMaxPercentToLoad=gModulePercent/100.0;
 
712
 
 
713
      //we'll only load more modules if haven't loaded the max percentage of modules
 
714
      //based on the configuration UI (stored in gModulePercent).
 
715
 
 
716
    const int theModulePerCallCount = 3; // specifies how many modules to load per timer callback.
 
717
    bool  done=false;
 
718
 
 
719
    for(int theModuleIndex=0;theModuleIndex<theModulePerCallCount;theModuleIndex++) {
 
720
 
 
721
      SetTrayIcon(gCheckIcons[gTrayIconIndex]);
 
722
 
 
723
      gTrayIconIndex = (gTrayIconIndex==1) ? 0 : gTrayIconIndex+1; //this toggles the preloader icon to show activity...
 
724
 
 
725
      char theDLLName[512];
 
726
      GetNextModuleName(theDLLName);
 
727
 
 
728
      if(theDLLName[0]) {
 
729
        if(gDLLCount/(gModuleCount*1.0)<=theMaxPercentToLoad) {
 
730
          HINSTANCE theInstance=LoadModule(theDLLName);
 
731
        }
 
732
        else done=true;
 
733
      }
 
734
      else done=true;
 
735
 
 
736
      if(done) {
 
737
 
 
738
          //if they've asked us to preload java, then do so here...
 
739
        if(gPreloadJava) {
 
740
 
 
741
          char kJavaRegStr[512] = {0};
 
742
          if(LoadString(gMainInst,IDS_JAVAREGSTR,kJavaRegStr,sizeof(kJavaRegStr))){
 
743
 
 
744
            CRegKey theRegKey;
 
745
 
 
746
            LONG theOpenResult=theRegKey.Open(HKEY_LOCAL_MACHINE,kJavaRegStr,KEY_QUERY_VALUE);
 
747
            if(ERROR_SUCCESS==theOpenResult) {
 
748
 
 
749
              char kJavaRegPath[128] = {0};
 
750
              if(LoadString(gMainInst,IDS_JAVAREGPATH,kJavaRegPath,sizeof(kJavaRegPath))){
 
751
 
 
752
                char thePath[1024] = {0};
 
753
                DWORD theSize=sizeof(thePath);
 
754
                theRegKey.QueryValue(thePath,kJavaRegPath,&theSize);
 
755
 
 
756
                if(thePath) {
 
757
                  //here we go; let's load java and awt...
 
758
                  char theTempPath[1024]={0};
 
759
 
 
760
                  sprintf(theTempPath,"%s\\hotspot\\jvm.dll",thePath);
 
761
                  LoadModuleFromPath(theTempPath);
 
762
 
 
763
                  sprintf(theTempPath,"%s\\verify.dll",thePath);
 
764
                  LoadModuleFromPath(theTempPath);
 
765
 
 
766
                  sprintf(theTempPath,"%s\\jpins32.dll",thePath);
 
767
                  LoadModuleFromPath(theTempPath);
 
768
 
 
769
                  sprintf(theTempPath,"%s\\jpishare.dll",thePath);
 
770
                  LoadModuleFromPath(theTempPath);
 
771
 
 
772
                  sprintf(theTempPath,"%s\\NPOJI600.dll",thePath);
 
773
                  LoadModuleFromPath(theTempPath);
 
774
 
 
775
                  sprintf(theTempPath,"%s\\java.dll",thePath);
 
776
                  LoadModuleFromPath(theTempPath);
 
777
 
 
778
                  sprintf(theTempPath,"%s\\awt.dll",thePath);
 
779
                  LoadModuleFromPath(theTempPath);
 
780
 
 
781
                }
 
782
              }
 
783
            }
 
784
          }
 
785
 
 
786
        }
 
787
 
 
788
        KillTimer(gMainWindow,kLoadTimerID);     
 
789
        SetTrayIcon(gCheckIcons[1]);
 
790
    
 
791
        //now make a new timer that calls GetProcAddr()...
 
792
        //we take gFrequencyPercent into account. We assume a timer range (min..max) of ~1second.
 
793
 
 
794
        int theFreq=50+(100-gFrequencyPercent)*10;
 
795
 
 
796
        UINT result=SetTimer(gMainWindow,kPingModuleTimerID,theFreq,KeepAliveTimerProc);
 
797
        return; //bail out    
 
798
      }
 
799
    }
 
800
 
 
801
    theTimerIsRunning=false;
 
802
  }
 
803
}
 
804
 
 
805
/****************************************
 
806
  we support the following args:
 
807
    -f(+/-) : use FULL module list (not really supported yet)
 
808
    -m : use mozilla installation
 
809
    -n : use netscape installation (this is the default)
 
810
    -p : use the given path (use this when you're running from a debug build rather than an installed version)
 
811
 ****************************************/
 
812
void ParseArgs(LPSTR &CmdLineArgs,eAppVersion &anAppVersion) {
 
813
 
 
814
  const char* cp=CmdLineArgs;
 
815
  
 
816
  while(*cp) {
 
817
    char theChar=*cp;
 
818
    if(('-'==theChar) || ('/'==theChar)){
 
819
      //we found a valid command, go get it...
 
820
      ++cp;
 
821
      char theCmd=*cp;
 
822
 
 
823
      switch(theCmd) {
 
824
        case 'n':
 
825
        case 'N':
 
826
          anAppVersion=eNetscape65;
 
827
          break;
 
828
 
 
829
        case 'm':
 
830
        case 'M':
 
831
          anAppVersion=eMozilla;
 
832
          break;
 
833
 
 
834
        case 'f':
 
835
        case 'F':
 
836
          ++cp;          
 
837
          if('+'==*cp) {
 
838
            gUseFullModuleList=true;
 
839
          }
 
840
          break;
 
841
 
 
842
        case 'p':
 
843
        case 'P':
 
844
          cp++; //skip over the command, then get the install path the user wants us to use.
 
845
          anAppVersion=eUserPath;
 
846
          while(*cp) {              //skip whitespace...
 
847
            if(' '!=*cp)
 
848
              break;
 
849
            cp++;
 
850
          }
 
851
            //now eat the path
 
852
          gMozPathLen=gUserPathLen=0;
 
853
          if('"'==*cp) { // Allow spaces in the path ie "C:\Program Files"
 
854
            cp++; // skip the "
 
855
            while(*cp) {
 
856
              if('"'!=*cp) {
 
857
                gUserPath[gUserPathLen++]=*cp;
 
858
              }
 
859
              cp++;
 
860
            }
 
861
          }
 
862
          else {
 
863
            while(*cp) {
 
864
              if(' '!=*cp) {
 
865
                gUserPath[gUserPathLen++]=*cp;
 
866
              }
 
867
              cp++;
 
868
            }
 
869
          }
 
870
          if(gUserPath[gUserPathLen-1]!= '\\') // make sure there's a \ on the end. 
 
871
            gUserPath[gUserPathLen++] = '\\';
 
872
          gUserPath[gUserPathLen]=0;
 
873
          continue;
 
874
          break;
 
875
        default:
 
876
          break;
 
877
      }
 
878
    }
 
879
    cp++; 
 
880
  }
 
881
 
 
882
}
 
883
 
 
884
/*********************************************************
 
885
  This is the event loop controller for our diable 
 
886
  dialog box UI.
 
887
 *********************************************************/
 
888
BOOL CALLBACK DisableDialogProc(HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam) {
 
889
 
 
890
  switch(Msg) {
 
891
 
 
892
    case WM_INITDIALOG:
 
893
      {
 
894
        RECT cr1,cr2;
 
895
 
 
896
          //The rect code below is used to put our dialog right by the taskbar.
 
897
          //It makes it's presence more obvious to the user.
 
898
 
 
899
        HWND theTopWnd=GetDesktopWindow();
 
900
        GetClientRect(theTopWnd,&cr1);
 
901
        GetClientRect(hwnd,&cr2);
 
902
        int w=cr2.right-cr2.left;
 
903
        int h=cr2.bottom-cr2.top;
 
904
 
 
905
        SetWindowPos(hwnd,HWND_TOP,cr1.right-(w+50),cr1.bottom-(h+70),0,0,SWP_NOSIZE);
 
906
        return TRUE;
 
907
      }
 
908
  
 
909
    case WM_COMMAND:
 
910
      switch(LOWORD(wParam)) {
 
911
        case IDOK:
 
912
          EndDialog(hwnd,1);
 
913
          break;
 
914
        case IDCANCEL:
 
915
          EndDialog(hwnd,0);
 
916
          return TRUE;
 
917
          break;
 
918
        default:
 
919
          break;
 
920
      }//switch
 
921
    default:
 
922
      break;
 
923
  }
 
924
  
 
925
  return FALSE;
 
926
}
 
927
 
 
928
/*********************************************************
 
929
  This is the event loop controller for our performance
 
930
  conifuration dialog box UI.
 
931
 *********************************************************/
 
932
BOOL CALLBACK ConfigureDialogProc(HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam) {
 
933
 
 
934
  int x=0;
 
935
 
 
936
  switch(Msg) {
 
937
 
 
938
    case WM_INITDIALOG:
 
939
      {
 
940
        RECT cr1,cr2;
 
941
 
 
942
          //The rect code below is used to put our dialog right by the taskbar.
 
943
          //It makes it's presence more obvious to the user.
 
944
 
 
945
        HWND theTopWnd=GetDesktopWindow();
 
946
        GetClientRect(theTopWnd,&cr1);
 
947
        GetClientRect(hwnd,&cr2);
 
948
        int w=cr2.right-cr2.left;
 
949
        int h=cr2.bottom-cr2.top;
 
950
 
 
951
 
 
952
        /*---------------------------------------------------------------
 
953
          Add members to our list control...
 
954
         ---------------------------------------------------------------*/
 
955
 
 
956
        HWND theListCtrl=GetDlgItem(hwnd,IDC_PRELOAD);
 
957
 
 
958
        SendMessage(theListCtrl, CB_RESETCONTENT, 0, 0);
 
959
        SendMessage(theListCtrl, CB_ADDSTRING, 0, (LPARAM)"Auto"); 
 
960
        SendMessage(theListCtrl, CB_ADDSTRING, 0, (LPARAM)"Mozilla"); 
 
961
        SendMessage(theListCtrl, CB_ADDSTRING, 0, (LPARAM)"Netscape-6.0"); 
 
962
        SendMessage(theListCtrl, CB_ADDSTRING, 0, (LPARAM)"Netscape-6.5"); 
 
963
        SendMessage(theListCtrl, CB_ADDSTRING, 0, (LPARAM)"Pre-Netscape-6.0"); 
 
964
        SendMessage(theListCtrl, CB_ADDSTRING, 0, (LPARAM)"User-defined"); 
 
965
        
 
966
        int theSel=0;
 
967
        switch(gAppVersion) {
 
968
          case eNetscape65: theSel=3; break;
 
969
          case eNetscape60: theSel=2; break;
 
970
          case eMozilla:    theSel=1; break;
 
971
          case eNetscapePre60:  theSel=4; break;
 
972
          case eUserPath:   theSel=5; break;
 
973
          default:
 
974
            break;
 
975
        }
 
976
        
 
977
        SendMessage(theListCtrl, CB_SETCURSEL, (WPARAM)theSel, 0);
 
978
 
 
979
        /*---------------------------------------------------------------
 
980
          Set the text of our edit control...
 
981
         ---------------------------------------------------------------*/
 
982
 
 
983
        HWND theEditCtrl=GetDlgItem(hwnd,IDC_EDIT1);
 
984
        SendMessage(theEditCtrl, WM_CLEAR, 0, 0); 
 
985
        SendMessage(theEditCtrl, EM_REPLACESEL, 0, (LPARAM)gMozPath); 
 
986
 
 
987
        /*---------------------------------------------------------------
 
988
          Set the state of our JAVA checkbox...
 
989
         ---------------------------------------------------------------*/
 
990
 
 
991
        HWND theJavaCheckBox =GetDlgItem(hwnd,IDC_JAVA);
 
992
        SendMessage(theJavaCheckBox, BM_SETCHECK, gPreloadJava, 0); 
 
993
 
 
994
        /*---------------------------------------------------------------
 
995
          add code here to set the range of our sliders...
 
996
         ---------------------------------------------------------------*/
 
997
 
 
998
        HWND theSlider=GetDlgItem(hwnd,IDC_MODULES);
 
999
        gModulePercent = SendMessage(theSlider, TBM_SETPOS, (BOOL)TRUE, (LONG)gModulePercent); 
 
1000
 
 
1001
        theSlider=GetDlgItem(hwnd,IDC_ENTRIES);
 
1002
        gEntryPercent = SendMessage(theSlider, TBM_SETPOS, (BOOL)TRUE, (LONG)gEntryPercent); 
 
1003
 
 
1004
        theSlider=GetDlgItem(hwnd,IDC_FREQUENCY);
 
1005
        gFrequencyPercent = SendMessage(theSlider, TBM_SETPOS, (BOOL)TRUE, (LONG)gFrequencyPercent); 
 
1006
        
 
1007
        SetWindowPos(hwnd,HWND_TOP,cr1.right-(w+50),cr1.bottom-(h+70),0,0,SWP_NOSIZE);
 
1008
        return TRUE;
 
1009
      }
 
1010
 
 
1011
    case WM_COMMAND:
 
1012
      switch(LOWORD(wParam)) {
 
1013
 
 
1014
        case IDOK:
 
1015
 
 
1016
          {
 
1017
            HWND theSlider=GetDlgItem(hwnd,IDC_MODULES);
 
1018
            gModulePercent = SendMessage(theSlider, TBM_GETPOS, 0, 0); 
 
1019
 
 
1020
            theSlider=GetDlgItem(hwnd,IDC_ENTRIES);
 
1021
            gEntryPercent = SendMessage(theSlider, TBM_GETPOS, 0, 0); 
 
1022
 
 
1023
            theSlider=GetDlgItem(hwnd,IDC_FREQUENCY);
 
1024
            gFrequencyPercent = SendMessage(theSlider, TBM_GETPOS, 0, 0); 
 
1025
 
 
1026
            theSlider=GetDlgItem(hwnd,IDC_JAVA);
 
1027
            gPreloadJava = (int)SendMessage(theSlider, BM_GETCHECK, 0, 0); 
 
1028
 
 
1029
            EndDialog(hwnd,1);
 
1030
 
 
1031
            //and now, let's save the configuration settings...
 
1032
 
 
1033
            CRegKey theRegKey;
 
1034
 
 
1035
            LONG theOpenResult=theRegKey.Open(HKEY_LOCAL_MACHINE,gRegKey,KEY_QUERY_VALUE);
 
1036
            if(ERROR_SUCCESS!=theOpenResult) {
 
1037
              theRegKey.Create(HKEY_LOCAL_MACHINE,gRegKey);
 
1038
            }
 
1039
 
 
1040
            char theSettings[128];
 
1041
            sprintf(theSettings,"%i %i %i %i %s",gModulePercent,gEntryPercent,gFrequencyPercent,gPreloadJava,gUserPath);
 
1042
            theRegKey.SetValue( HKEY_LOCAL_MACHINE, gRegKey, theSettings, "Settings");
 
1043
          }
 
1044
          
 
1045
          break;
 
1046
 
 
1047
        case IDCANCEL:
 
1048
          EndDialog(hwnd,0);
 
1049
          return TRUE;
 
1050
          break;
 
1051
 
 
1052
        default:
 
1053
          break;
 
1054
      }//switch
 
1055
    default:
 
1056
      break;
 
1057
  }
 
1058
  
 
1059
  return FALSE;
 
1060
}
 
1061
 
 
1062
/*********************************************************
 
1063
  The user asked us to disable the preloader. So we'll try
 
1064
  to remove ourselves from both the current user start
 
1065
  menu and ALL-USERS start menu.
 
1066
 
 
1067
  This ASSUMES that the installer put us into the startup
 
1068
  folder using a shortcut to our current exe name.
 
1069
 
 
1070
  So, if the exe is called "preloader.exe", then we assume
 
1071
  that the installer put us into the startup folder as:
 
1072
 
 
1073
  "shortcut to preloader.exe.lnk".
 
1074
 *********************************************************/
 
1075
void RemoveFromStartupFolder() {
 
1076
  
 
1077
  //Using the name of our running application, let's derive the
 
1078
  //name of the link to it in the startup folder.
 
1079
 
 
1080
  char theAppName[128]={0};
 
1081
  char theFilename[128]={0};
 
1082
  char theFullPath[1024]={0};
 
1083
 
 
1084
  const char *theLastSep=strrchr(gExePath,thePathSep[0]);
 
1085
 
 
1086
  if(theLastSep) {
 
1087
    theLastSep++; //skip the slash
 
1088
 
 
1089
    char prefix[512]={0};
 
1090
    
 
1091
    if(LoadString(gMainInst,IDS_STARTUP_FOLDER_PREFIX,prefix,sizeof(prefix))){
 
1092
      
 
1093
      char suffix[512]={0};
 
1094
    
 
1095
      if(LoadString(gMainInst,IDS_STARTUP_FOLDER_SUFFIX,suffix,sizeof(suffix))){
 
1096
        strcpy(theFilename,prefix);
 
1097
        strcat(theFilename,theLastSep);
 
1098
        strcat(theFilename,suffix);
 
1099
      }
 
1100
    
 
1101
    }
 
1102
  }
 
1103
 
 
1104
  if(theFilename) { //dont try if you can't get a reasonable guess to the path in the startup folder.
 
1105
  
 
1106
    //-----------------------------------------------------------------------------
 
1107
    //first, let's try to remove ourselves from the current users's startup folder...
 
1108
    //-----------------------------------------------------------------------------
 
1109
 
 
1110
    char theUserKey[256]={0};
 
1111
    if(LoadString(gMainInst,IDS_STARTUP_FOLDER_KEY,theUserKey,sizeof(theUserKey))) {
 
1112
 
 
1113
      CRegKey theRegKey;
 
1114
 
 
1115
      LONG theOpenResult=theRegKey.Open(HKEY_CURRENT_USER,theUserKey,KEY_QUERY_VALUE);
 
1116
 
 
1117
      if(ERROR_SUCCESS==theOpenResult) {
 
1118
    
 
1119
        DWORD theSize=sizeof(theFullPath);
 
1120
 
 
1121
        char theSubKey[128]={0};
 
1122
        
 
1123
        if(LoadString(gMainInst,IDS_STARTUP_FOLDER_SUBKEY1,theSubKey,sizeof(theSubKey))) {
 
1124
         
 
1125
          theRegKey.QueryValue(theFullPath,theSubKey,&theSize);
 
1126
          if(theFullPath) {
 
1127
 
 
1128
            //Now let's construct a complete path to our preloader.exe.lnk.
 
1129
 
 
1130
            strcat(theFullPath,thePathSep);
 
1131
            strcat(theFullPath,theFilename);
 
1132
 
 
1133
            //Ask the OS to remove us from the startup folder...
 
1134
 
 
1135
            DeleteFile(theFullPath);
 
1136
          }
 
1137
        }
 
1138
      }
 
1139
    }
 
1140
 
 
1141
    //-----------------------------------------------------------------------------
 
1142
    //Next, let's try to remove ourselves from ALL_USERS startup folder...
 
1143
    //-----------------------------------------------------------------------------
 
1144
 
 
1145
    CRegKey theRegKey2;
 
1146
 
 
1147
    LONG theOpenResult=theRegKey2.Open(HKEY_LOCAL_MACHINE,theUserKey,KEY_QUERY_VALUE);
 
1148
 
 
1149
    if(ERROR_SUCCESS==theOpenResult) {
 
1150
  
 
1151
      DWORD theSize=sizeof(theFullPath);
 
1152
 
 
1153
      char theSubKey[128]={0};
 
1154
      
 
1155
      if(LoadString(gMainInst,IDS_STARTUP_FOLDER_SUBKEY2,theSubKey,sizeof(theSubKey))) {
 
1156
       
 
1157
        theRegKey2.QueryValue(theFullPath,theSubKey,&theSize);
 
1158
        if(theFullPath) {
 
1159
 
 
1160
          //Now let's construct a complete path to our preloader.exe.lnk.
 
1161
 
 
1162
          strcat(theFullPath,thePathSep);
 
1163
          strcat(theFullPath,theFilename);
 
1164
 
 
1165
          //Ask the OS to remove us from the startup folder...
 
1166
 
 
1167
          DeleteFile(theFullPath);
 
1168
        }
 
1169
      }
 
1170
    }
 
1171
 
 
1172
  }
 
1173
}
 
1174
 
 
1175
 
 
1176
/*********************************************************
 
1177
  
 
1178
 *********************************************************/
 
1179
LRESULT CALLBACK WindowFunc(HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam) {
 
1180
 
 
1181
  static HMENU hPopup=0;           //menu handle
 
1182
  static int   gState=0;
 
1183
  static bool  gConfigDialogShowing=false;
 
1184
 
 
1185
  switch(Msg) {
 
1186
 
 
1187
    case WM_CREATE: 
 
1188
      //initialize icons
 
1189
 
 
1190
      gCheckIcons[0]=LoadIcon(gMainInst, MAKEINTRESOURCE(IDI_CHECK));
 
1191
      gCheckIcons[1]=LoadIcon(gMainInst, MAKEINTRESOURCE(IDI_CHECK1));
 
1192
      gBrowserRunningIcon = LoadIcon(gMainInst, MAKEINTRESOURCE(IDI_BROWSERRUNNING));
 
1193
 
 
1194
      //initialize popup menu
 
1195
      hPopup=LoadMenu(gMainInst, MAKEINTRESOURCE(IDR_MENU1));
 
1196
 
 
1197
      gMainWindow=hwnd;
 
1198
      ShowTrayApp(true); //now display our app in the system tray
 
1199
 
 
1200
      break;
 
1201
 
 
1202
    //notification from trayicon received
 
1203
    case WM_TRAY:
 
1204
 
 
1205
      //if right mouse button pressed
 
1206
      if(lParam == WM_RBUTTONDOWN && (!gConfigDialogShowing)) {
 
1207
        POINT pt;
 
1208
        GetCursorPos(&pt);  //get cursor position
 
1209
        SetForegroundWindow(hwnd);  //set window to foreground
 
1210
        //display popup menu
 
1211
        BOOL bRes=TrackPopupMenu(GetSubMenu(hPopup, 0), TPM_BOTTOMALIGN | TPM_RIGHTALIGN | TPM_RIGHTBUTTON,
 
1212
                                 pt.x, pt.y, 0, hwnd, 0);
 
1213
        //send dummy message to window
 
1214
        SendMessage(hwnd, WM_NULL, 0, 0);
 
1215
      }
 
1216
      break;
 
1217
 
 
1218
    //notification from menu received
 
1219
    case WM_COMMAND:
 
1220
 
 
1221
      switch(LOWORD(wParam)) {
 
1222
 
 
1223
        case IDM_CONFIGURE:
 
1224
          {
 
1225
            if(!gConfigDialogShowing) {
 
1226
              gConfigDialogShowing=true;
 
1227
              if(DialogBox(gMainInst,MAKEINTRESOURCE(IDD_PERFORMANCE),hwnd,ConfigureDialogProc)) {
 
1228
              }
 
1229
              gConfigDialogShowing=false;
 
1230
            }
 
1231
          }
 
1232
          break;
 
1233
 
 
1234
        case IDM_REMOVE:
 
1235
          //show them the disable preloader dialog. If they say yes, remove ourselves from
 
1236
          //the start menu (if that's where we were launched from) and quit.
 
1237
          //now fall through on purpose...
 
1238
          if(DialogBox(gMainInst,MAKEINTRESOURCE(DISABLE),hwnd,DisableDialogProc)) {
 
1239
            //a non-zero result means we are supposed to kill the preloader 
 
1240
            //and remove it from the startup folder.
 
1241
 
 
1242
            RemoveFromStartupFolder();
 
1243
            //now fall thru...
 
1244
 
 
1245
          }
 
1246
          else break;
 
1247
                
 
1248
        case IDM_EXIT:
 
1249
          DestroyWindow(hwnd);
 
1250
          break;
 
1251
 
 
1252
        //change icon in system tray; why bother?
 
1253
        case IDM_CHANGE:
 
1254
          if(!gState) {
 
1255
            gState=1;
 
1256
          } 
 
1257
          else {
 
1258
            gState=0;
 
1259
          }
 
1260
          break;
 
1261
      }
 
1262
      break;
 
1263
 
 
1264
    //exit application
 
1265
    case WM_DESTROY:
 
1266
      //release used resources
 
1267
 
 
1268
      ShowTrayApp(false);
 
1269
 
 
1270
      DestroyIcon(gCheckIcons[0]);
 
1271
      DestroyIcon(gCheckIcons[1]);
 
1272
 
 
1273
      DestroyMenu(hPopup);
 
1274
      PostQuitMessage(0);
 
1275
      break;
 
1276
 
 
1277
    default:
 
1278
      return DefWindowProc(hwnd, Msg, wParam, lParam);
 
1279
  }
 
1280
  return 0;
 
1281
}
 
1282
 
 
1283
 
 
1284
/*********************************************************
 
1285
  Main 
 
1286
 *********************************************************/
 
1287
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpszArgs,int nWinMode){
 
1288
 
 
1289
  memset(gFuncTable,0,sizeof(gFuncTable)); //init this to empty ptr's for good housekeeping...
 
1290
   
 
1291
  ::CreateMutex(NULL, FALSE, "YourMutexName");
 
1292
  if (GetLastError()  == ERROR_ALREADY_EXISTS ) {
 
1293
    //Bail out if we already have one instance running.
 
1294
    exit(0);
 
1295
  }
 
1296
 
 
1297
  WNDCLASS WinClass;
 
1298
 
 
1299
  static char theClassName[128];
 
1300
  if(!LoadString(hInstance,IDS_CLASSNAME,theClassName,sizeof(theClassName)))
 
1301
    strcpy(theClassName,"MozPreloader"); //as a backup; just being paranoid.
 
1302
 
 
1303
  //register window class
 
1304
  WinClass.hInstance=hInstance;
 
1305
 
 
1306
  //---------------------------------------------------------------
 
1307
  //  We hang on to the app name in case they disable us.
 
1308
  //  We'll remove a .lnk entry of this name from the startup folder.
 
1309
  //---------------------------------------------------------------
 
1310
 
 
1311
  GetModuleFileName(hInstance,gExePath,sizeof(gExePath)); //remember where we were run from in case we get disabled. 
 
1312
 
 
1313
 
 
1314
  //---------------------------------------------------------------
 
1315
  //  Now let's init and register our window class...
 
1316
  //---------------------------------------------------------------
 
1317
 
 
1318
  gMainInst=hInstance;
 
1319
  WinClass.lpszClassName=theClassName;  //specify class name
 
1320
  WinClass.lpfnWndProc=WindowFunc;    //specify callback function
 
1321
  WinClass.style=0;
 
1322
  WinClass.hIcon=LoadIcon(NULL, IDI_APPLICATION); //specify icon
 
1323
  WinClass.hCursor=LoadCursor(NULL, IDC_ARROW);   //specify cursor
 
1324
  WinClass.lpszMenuName=0;
 
1325
  WinClass.cbClsExtra=0;
 
1326
  WinClass.cbWndExtra=0;
 
1327
  WinClass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH); //specify window background
 
1328
 
 
1329
  if(!RegisterClass(&WinClass))
 
1330
    return 0;
 
1331
 
 
1332
  //create window
 
1333
  HWND hwnd=CreateWindow(theClassName,0,WS_OVERLAPPEDWINDOW,10,10,10,10,HWND_DESKTOP,NULL,hInstance,NULL);
 
1334
  gMainWindow=hwnd;
 
1335
 
 
1336
  //hide window
 
1337
  ShowWindow(hwnd, SW_HIDE);
 
1338
 
 
1339
  //---------------------------------------------------------------
 
1340
  //  Now let's grab the module settings info...
 
1341
  //---------------------------------------------------------------
 
1342
 
 
1343
  bool useDebugModuleList=false;
 
1344
  
 
1345
  ParseArgs(lpszArgs,gAppVersion);
 
1346
 
 
1347
  if(GetMozillaRegistryInfo(gAppVersion)) {
 
1348
 
 
1349
    SetTrayIcon(gBrowserRunningIcon); //by default.
 
1350
 
 
1351
    //---------------------------------------------------------------
 
1352
    //  Now let's grab the config settings (if they happen to exist)
 
1353
    //---------------------------------------------------------------
 
1354
 
 
1355
    CRegKey theRegKey;
 
1356
 
 
1357
    LONG theOpenResult=theRegKey.Open(HKEY_LOCAL_MACHINE,gRegKey,KEY_QUERY_VALUE);
 
1358
    if(ERROR_SUCCESS==theOpenResult) {
 
1359
 
 
1360
      const int theSize=1024;
 
1361
      DWORD size=theSize;
 
1362
      char theSettings[theSize] = {0};
 
1363
 
 
1364
      theOpenResult=theRegKey.QueryValue(theSettings,"Settings",&size);
 
1365
      if(ERROR_SUCCESS==theOpenResult) {
 
1366
        //now let's decode the settings from the string
 
1367
        char *cp=theSettings;
 
1368
        
 
1369
        gModulePercent = atoi(cp);
 
1370
        cp=strchr(cp,' '); //skip ahead to the next space...
 
1371
        cp++; //and step over it
 
1372
 
 
1373
        gEntryPercent = atoi(cp);
 
1374
 
 
1375
        cp=strchr(cp,' '); //skip ahead to the next space...
 
1376
        if(cp) {
 
1377
          cp++; //and step over it
 
1378
          gFrequencyPercent = atoi(cp);
 
1379
        }
 
1380
 
 
1381
        cp=strchr(cp,' '); //skip ahead to the next space...
 
1382
        if(cp) {
 
1383
          cp++; //and step over it
 
1384
          gPreloadJava = atoi(cp);
 
1385
        }
 
1386
 
 
1387
 
 
1388
        if(!gUserPath[0]) { //dont override something they provide at the 
 
1389
          if(cp){
 
1390
            cp=strchr(cp,'['); //seek to the separator for the pathname (optional)
 
1391
            if(cp && *cp) {
 
1392
              char *endcp=strchr(cp,']'); //now grab the (optional) user defined path...
 
1393
              if(endcp) {
 
1394
                strcpy(gUserPath,cp);
 
1395
              }
 
1396
            }
 
1397
          }
 
1398
        }
 
1399
      }
 
1400
    }
 
1401
 
 
1402
    //---------------------------------------------------------------
 
1403
    //  And start the timer...
 
1404
    //---------------------------------------------------------------
 
1405
 
 
1406
    if(!BrowserIsRunning()) {
 
1407
      SetTimer(hwnd,kLoadTimerID,50,LoadModuleTimerProc); //don't bother with the preloader if the browser is already up...
 
1408
    }
 
1409
 
 
1410
  }
 
1411
 
 
1412
  //start message pump
 
1413
  MSG WinMsg;
 
1414
  while(GetMessage(&WinMsg, NULL, 0, 0)) {
 
1415
    TranslateMessage(&WinMsg);
 
1416
    DispatchMessage(&WinMsg);
 
1417
  }
 
1418
 
 
1419
  return WinMsg.wParam;
 
1420
}
 
1421