Back to index

lightning-sunbird  0.9+nobinonly
mozturbo.cpp
Go to the documentation of this file.
00001  /* ***** BEGIN LICENSE BLOCK *****
00002  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00003  *
00004  * The contents of this file are subject to the Mozilla Public License
00005  * Version 1.1 (the "License"); you may not use this file except in
00006  * compliance with the License. You may obtain a copy of the License at
00007  * http://www.mozilla.org/MPL/
00008  *
00009  * Software distributed under the License is distributed on an "AS IS"
00010  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
00011  * License for the specific language governing rights and limitations
00012  * under the License.
00013  *
00014  * The Original Code is OS/2 specific turbo mode
00015  *
00016  * The Initial Developer of the Original Code is IBM Corporation. 
00017  * Portions created by IBM Corporation are Copyright (C) 2002
00018  * IBM Corporation. All Rights Reserved.
00019  *
00020  * Contributor(s):
00021  *   IBM Corp.
00022  *
00023  * Alternatively, the contents of this file may be used under the terms of
00024  * either the GNU General Public License Version 2 or later (the "GPL"), or 
00025  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00026  * in which case the provisions of the GPL or the LGPL are applicable instead
00027  * of those above. If you wish to allow use of your version of this file only
00028  * under the terms of either the GPL or the LGPL, and not to allow others to
00029  * use your version of this file under the terms of the MPL, indicate your
00030  * decision by deleting the provisions above and replace them with the notice
00031  * and other provisions required by the GPL or the LGPL. If you do not delete
00032  * the provisions above, a recipient may use your version of this file under
00033  * the terms of any one of the MPL, the GPL or the LGPL.
00034  *
00035  * ***** END LICENSE BLOCK ***** */
00036 
00037 /*******************************************************************************
00038 This program implements a module preloader for the OS/2 version of the SeaMonkey
00039 Web Browser.
00040 
00041 The way this is implemented is by loading each DLL using DosLoadModule and then
00042 querying the first ordinal (entry point) using DosQueryProcAddr. This entry point
00043 is then accessed so that its memory becomes paged in and resident in memory.
00044 Once this is done, the program suspends execution by waiting on a named
00045 semaphore so the modules are held in memory.
00046 
00047 The list of module names was determined by loading SeaMonkey and then
00048 seeing which DLLs were in use at that time.
00049 *******************************************************************************/
00050 
00051 #define INCL_DOS
00052 #define INCL_DOSERRORS
00053 #include <os2.h>
00054 #include <stdio.h>
00055 #include <string.h>
00056 
00057 /* Older versions of the toolkit, as well as GCC do not have this - from bsedos.h */
00058 extern "C" {
00059    APIRET APIENTRY  DosQueryModFromEIP(HMODULE *phMod,
00060                                         ULONG *pObjNum,
00061                                         ULONG BuffLen,
00062                                         PCHAR pBuff,
00063                                         ULONG *pOffset,
00064                                         ULONG Address);
00065 }
00066 
00067 /* BIN directory */
00068 char *bindir[] = {
00069  "GKGFX.DLL",
00070  "JSJ.DLL",
00071  "MOZJS.DLL",
00072  "MOZZ.DLL",
00073  "MSGBSUTL.DLL",
00074  "NSPR4.DLL",
00075  "PLC4.DLL",
00076  "PLDS4.DLL",
00077  "XPCOM.DLL",
00078  "XPCOMCOR.DLL",
00079  "XPCOMCT.DLL",
00080  0
00081  };
00082 
00083 /* COMPONENTS directory */
00084 char *compdir[] = {
00085  "APPCOMPS.DLL",
00086  "APPSHELL.DLL",
00087  "CAPS.DLL",
00088  "CHROME.DLL",
00089  "COOKIE.DLL",
00090  "DOCSHELL.DLL",
00091  "EDITOR.DLL",
00092  "EMBEDCMP.DLL",
00093  "GFX_OS2.DLL",
00094  "GKLAYOUT.DLL",
00095  "GKPARSER.DLL",
00096  "GKPLUGIN.DLL",
00097  "I18N.DLL",
00098  "IMGLIB2.DLL",
00099  "JAR50.DLL",
00100  "MAILNEWS.DLL",
00101  "MORK.DLL",
00102  "MOZUCONV.DLL",
00103  "MSGNEWS.DLL",
00104  "NECKO.DLL",
00105  "OJI.DLL",
00106  "PIPBOOT.DLL",
00107  "PREF.DLL",
00108  "PROFILE.DLL",
00109  "RDF.DLL",
00110  "TXMGR.DLL",
00111  "TYPAHEAD.DLL",
00112  "WDGTOS2.DLL",
00113  "WEBBRWSR.DLL",
00114  "XPCOMCTC.DLL",
00115  "XPCONECT.DLL",
00116  0,
00117  };
00118 
00119 #define SEMNAME "\\SEM32\\MOZTURBO\\MOZTURBO"
00120 
00121 void ForceModuleLoad(HMODULE hmodule);
00122 
00123 int main(int argc, char *argv[]) {
00124 
00125   int do_load,do_unload,do_help,do_path;
00126   do_load=do_unload=do_help=do_path=0;
00127 
00128   char basepath[CCHMAXPATH];
00129 
00130   if (argc == 1)
00131     do_help = 1;
00132   else {
00133     for (int i=1; i < argc; i++) {
00134       if (strnicmp(argv[i],"-l", 2) == 0)
00135         do_load = 1;
00136       else if (strnicmp(argv[i],"-u", 2) == 0)
00137         do_unload = 1;
00138       else if (strnicmp(argv[i],"-h", 2) == 0) 
00139         do_help = 1;
00140       else if (strnicmp(argv[i],"-?", 2) == 0)
00141         do_help = 1;
00142       else if (strnicmp(argv[i],"-p", 2) == 0) {
00143         if (argc > i+1) {
00144           strcpy(basepath, argv[i+1]);
00145           if (basepath[strlen(basepath)] !='\\') {
00146             strcat(basepath, "\\");
00147           }
00148         do_path = 1;
00149         } else {
00150           do_help = 1;
00151         }
00152       }
00153     }
00154   }
00155 
00156 
00157   if (do_help) {
00158     printf("%s for OS/2 preloader\n"\
00159            "\n"\
00160            "Usage: %s [-h] [-l | -u] [-p path]\n"\
00161            "       -h display this help\n"\
00162            "       -l load modules\n"\
00163            "       -u unload modules\n"\
00164            "       -p specify fully qualified path to directory where EXE is located\n",
00165            MOZ_APP_DISPLAYNAME, argv[0]);
00166     return(1);
00167   }
00168 
00169   if (do_unload) {
00170     HEV hev = NULLHANDLE;
00171     if (DosOpenEventSem(SEMNAME, &hev) == NO_ERROR) {
00172       if (DosPostEventSem(hev) == NO_ERROR) {
00173         if (DosCloseEventSem(hev) == NO_ERROR) {
00174           return(0);
00175         }
00176       }
00177     }
00178     printf("%s for OS/2 preloader is not running\n", MOZ_APP_DISPLAYNAME);
00179     return(1);
00180   }
00181 
00182   if (do_path == 0) {
00183     /* Get the name of this EXE and use its location as the path */
00184     HMODULE hmodule;
00185     DosQueryModFromEIP(&hmodule, NULL, 0, NULL, NULL, (ULONG)ForceModuleLoad);
00186     DosQueryModuleName(hmodule, CCHMAXPATH, basepath);
00187     char *pchar = strrchr(basepath, '\\');
00188     pchar++;
00189     *pchar = '\0';
00190   }
00191 
00192   if (do_load) {
00193     ULONG ulCurMaxFH;
00194     LONG ulReqFH = 40;
00195     DosSetRelMaxFH(&ulReqFH, &ulCurMaxFH);
00196 
00197     HEV hev;
00198     if (DosCreateEventSem(SEMNAME, &hev, DC_SEM_SHARED, FALSE) != NO_ERROR) {
00199       printf("%s for OS/2 preloader is already running\n", MOZ_APP_DISPLAYNAME);
00200       return(1);
00201     }
00202 
00203     /* Add directory where EXE is located to LIBPATH */
00204     DosSetExtLIBPATH(basepath, BEGIN_LIBPATH);
00205 
00206     /* loop through list loading named modules */
00207     char filepath[CCHMAXPATH];
00208     HMODULE hmod;
00209 
00210     int i = 0, nummodules = 0;
00211     while (bindir[i]) {
00212       strcpy(filepath,basepath);
00213       strcat(filepath,bindir[i]);
00214    
00215       if (DosLoadModule(NULL, 0, filepath, &hmod) == NO_ERROR) {
00216         ForceModuleLoad(hmod);
00217         nummodules++;
00218       }
00219       i++;
00220     }
00221 
00222     i = 0;
00223     while (compdir[i]) {
00224       strcpy(filepath, basepath);
00225       strcat(filepath, "COMPONENTS\\");
00226       strcat(filepath, compdir[i]);
00227 
00228       if (DosLoadModule(NULL, 0, filepath, &hmod) == NO_ERROR) {
00229         ForceModuleLoad(hmod);
00230         nummodules++;
00231       }
00232       i++;
00233     }
00234    
00235     if (nummodules > 0) {
00236       if (DosWaitEventSem(hev, SEM_INDEFINITE_WAIT) != NO_ERROR) {
00237         printf("DosWaitEventSem failed\n");
00238         return(1);
00239       }
00240 
00241       if (DosCloseEventSem(hev) != NO_ERROR) {
00242         printf("DosCloseEventSem failed\n");
00243         return(1);
00244       }
00245     } else {
00246       printf("No modules available to load\n");
00247     }
00248   }
00249 
00250  return(0);
00251 }
00252 
00253 /* This function forces a module load by accessing the code pointed */
00254 /* to by the first entry point in a module */
00255 void ForceModuleLoad(HMODULE hmodule)
00256 {
00257   /* DosQueryMem */
00258   unsigned long memsize=0;
00259   unsigned long memend=0;
00260   unsigned long memflags=0;
00261   /* DosQueryProcAddr */
00262   PFN modaddr;
00263 
00264   volatile unsigned char cpybuf;
00265   unsigned int base=0;
00266   unsigned char* baseptr=0;
00267 
00268   if (DosQueryProcAddr(hmodule,1,0,&modaddr) == NO_ERROR) {
00269     /* calc 64K aligned addr previous to entry point */
00270     base=(( (unsigned long)modaddr) & 0xFFFF0000);
00271    
00272     /* get size and flags for this memory area */
00273     memsize=0x0fffffff;
00274     DosQueryMem((void*)base,&memsize,&memflags);
00275    
00276     /* if not first page of object, back off addr and retry */
00277     while (memflags < PAG_BASE) {
00278       base=base - PAG_BASE;
00279       memsize=0x0fffffff;
00280       DosQueryMem((void*)base,&memsize,&memflags);
00281     }
00282   
00283     /* finally, now loop through object pages, force page-in */
00284     memend=base+memsize;
00285     while(base<memend) {
00286       baseptr=(unsigned char*)base;
00287       cpybuf=*baseptr;
00288       base+=4096;
00289     }
00290   }
00291 }
00292