Back to index

lightning-sunbird  0.9+nobinonly
nsGlueLinkingOS2.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 6; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is Mozilla XPCOM.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Benjamin Smedberg <benjamin@smedbergs.us>
00019  *
00020  * Portions created by the Initial Developer are Copyright (C) 2005
00021  * the Initial Developer. All Rights Reserved.
00022  *
00023  * Contributor(s):
00024  *
00025  * Alternatively, the contents of this file may be used under the terms of
00026  * either the GNU General Public License Version 2 or later (the "GPL"), or
00027  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00028  * in which case the provisions of the GPL or the LGPL are applicable instead
00029  * of those above. If you wish to allow use of your version of this file only
00030  * under the terms of either the GPL or the LGPL, and not to allow others to
00031  * use your version of this file under the terms of the MPL, indicate your
00032  * decision by deleting the provisions above and replace them with the notice
00033  * and other provisions required by the GPL or the LGPL. If you do not delete
00034  * the provisions above, a recipient may use your version of this file under
00035  * the terms of any one of the MPL, the GPL or the LGPL.
00036  *
00037  * ***** END LICENSE BLOCK ***** */
00038 
00039 #include "nsGlueLinking.h"
00040 #include "nsXPCOMGlue.h"
00041 
00042 #define INCL_DOS
00043 #define INCL_DOSERRORS
00044 #include <os2.h>
00045 #include <stdlib.h>
00046 #include <stdio.h>
00047 
00048 struct DependentLib
00049 {
00050     HMODULE     libHandle;
00051     DependentLib *next;
00052 };
00053 
00054 static DependentLib *sTop;
00055 HMODULE sXULLibrary = NULLHANDLE;
00056 
00057 static void
00058 AppendDependentLib(HMODULE libHandle)
00059 {
00060     DependentLib *d = new DependentLib;
00061     if (!d)
00062         return;
00063 
00064     d->next = sTop;
00065     d->libHandle = libHandle;
00066 
00067     sTop = d;
00068 }
00069 
00070 static void
00071 ReadDependentCB(const char *aDependentLib)
00072 {
00073     CHAR pszError[_MAX_PATH];
00074     ULONG ulrc = NO_ERROR;
00075     HMODULE h;
00076 
00077     ulrc = DosLoadModule(pszError, _MAX_PATH, aDependentLib, &h);
00078 
00079     if (ulrc != NO_ERROR)
00080         return;
00081 
00082     AppendDependentLib(h);
00083 }
00084 
00085 // like strpbrk but finds the *last* char, not the first
00086 static char*
00087 ns_strrpbrk(char *string, const char *strCharSet)
00088 {
00089     char *found = NULL;
00090     for (; *string; ++string) {
00091         for (const char *search = strCharSet; *search; ++search) {
00092             if (*search == *string) {
00093                 found = string;
00094                 // Since we're looking for the last char, we save "found"       
00095                 // until we're at the end of the string. 
00096             }
00097         }
00098     }
00099 
00100     return found;
00101 }
00102 
00103 GetFrozenFunctionsFunc
00104 XPCOMGlueLoad(const char *xpcomFile)
00105 {
00106     CHAR pszError[_MAX_PATH];
00107     ULONG ulrc = NO_ERROR;
00108     HMODULE h;
00109 
00110     if (xpcomFile[0] == '.' && xpcomFile[1] == '\0') {
00111         xpcomFile = XPCOM_DLL;
00112     }
00113     else {
00114         char xpcomDir[MAXPATHLEN];
00115 
00116         _fullpath(xpcomDir, xpcomFile, sizeof(xpcomDir));
00117         char *lastSlash = ns_strrpbrk(xpcomDir, "/\\");
00118         if (lastSlash) {
00119             *lastSlash = '\0';
00120 
00121             XPCOMGlueLoadDependentLibs(xpcomDir, ReadDependentCB);
00122 
00123             snprintf(lastSlash, MAXPATHLEN - strlen(xpcomDir), "\\" XUL_DLL);
00124 
00125             DosLoadModule(pszError, _MAX_PATH, xpcomDir, &sXULLibrary);
00126         }
00127     }
00128 
00129     ulrc = DosLoadModule(pszError, _MAX_PATH, xpcomFile, &h);
00130 
00131     if (ulrc != NO_ERROR)
00132         return nsnull;
00133 
00134     AppendDependentLib(h);
00135 
00136     GetFrozenFunctionsFunc sym;
00137 
00138     ulrc = DosQueryProcAddr(h, 0, "NS_GetFrozenFunctions", (PFN*)&sym);
00139 
00140     if (ulrc != NO_ERROR)
00141         XPCOMGlueUnload();
00142 
00143     return sym;
00144 }
00145 
00146 void
00147 XPCOMGlueUnload()
00148 {
00149     while (sTop) {
00150         DosFreeModule(sTop->libHandle);
00151 
00152         DependentLib *temp = sTop;
00153         sTop = sTop->next;
00154 
00155         delete temp;
00156     }
00157 
00158     if (sXULLibrary) {
00159         DosFreeModule(sXULLibrary);
00160         sXULLibrary = nsnull;
00161     }
00162 }
00163 
00164 nsresult
00165 XPCOMGlueLoadXULFunctions(const nsDynamicFunctionLoad *symbols)
00166 {
00167     ULONG ulrc = NO_ERROR;
00168 
00169     if (!sXULLibrary)
00170         return NS_ERROR_NOT_INITIALIZED;
00171 
00172     nsresult rv = NS_OK;
00173     while (symbols->functionName) {
00174         ulrc = DosQueryProcAddr(sXULLibrary, 0, symbols->functionName, (PFN*)symbols->function);
00175 
00176         if (ulrc != NO_ERROR)
00177             rv = NS_ERROR_LOSS_OF_SIGNIFICANT_DATA;
00178 
00179         ++symbols;
00180     }
00181 
00182     return rv;
00183 }