Bug 470455 - test_database_sync_embed_visits.js leaks, r=sdwilsh
[wine-gecko.git] / xpcom / glue / standalone / nsGlueLinkingWin.cpp
blob46257b566eeae4d759b380277e7b61bdc42be1d1
1 /* -*- Mode: C++; tab-width: 6; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
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.
15 * The Original Code is Mozilla XPCOM.
17 * The Initial Developer of the Original Code is
18 * Benjamin Smedberg <benjamin@smedbergs.us>
20 * Portions created by the Initial Developer are Copyright (C) 2005
21 * the Initial Developer. All Rights Reserved.
23 * Contributor(s):
25 * Alternatively, the contents of this file may be used under the terms of
26 * either the GNU General Public License Version 2 or later (the "GPL"), or
27 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
28 * in which case the provisions of the GPL or the LGPL are applicable instead
29 * of those above. If you wish to allow use of your version of this file only
30 * under the terms of either the GPL or the LGPL, and not to allow others to
31 * use your version of this file under the terms of the MPL, indicate your
32 * decision by deleting the provisions above and replace them with the notice
33 * and other provisions required by the GPL or the LGPL. If you do not delete
34 * the provisions above, a recipient may use your version of this file under
35 * the terms of any one of the MPL, the GPL or the LGPL.
37 * ***** END LICENSE BLOCK ***** */
39 #include "nsGlueLinking.h"
40 #include "nsXPCOMGlue.h"
42 #include "nsStringAPI.h"
43 #include <windows.h>
44 #include <stdlib.h>
45 #include <stdio.h>
46 #include <tchar.h>
48 struct DependentLib
50 HINSTANCE libHandle;
51 DependentLib *next;
54 static DependentLib *sTop;
55 HINSTANCE sXULLibrary;
57 static void
58 AppendDependentLib(HINSTANCE libHandle)
60 DependentLib *d = new DependentLib;
61 if (!d)
62 return;
64 d->next = sTop;
65 d->libHandle = libHandle;
67 sTop = d;
70 static void
71 ReadDependentCB(const char *aDependentLib)
74 HINSTANCE h =
75 LoadLibraryExW(NS_ConvertUTF8toUTF16(aDependentLib).get(), NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
76 if (!h)
77 return;
79 AppendDependentLib(h);
82 // like strpbrk but finds the *last* char, not the first
83 static char*
84 ns_strrpbrk(char *string, const char *strCharSet)
86 char *found = NULL;
87 for (; *string; ++string) {
88 for (const char *search = strCharSet; *search; ++search) {
89 if (*search == *string) {
90 found = string;
91 // Since we're looking for the last char, we save "found"
92 // until we're at the end of the string.
97 return found;
99 // like strpbrk but finds the *last* char, not the first
100 static wchar_t*
101 ns_wcspbrk(wchar_t *string, const wchar_t *strCharSet)
103 wchar_t *found = NULL;
104 for (; *string; ++string) {
105 for (const wchar_t *search = strCharSet; *search; ++search) {
106 if (*search == *string) {
107 found = string;
108 // Since we're looking for the last char, we save "found"
109 // until we're at the end of the string.
114 return found;
117 bool ns_isRelPath(wchar_t* path)
119 #ifdef WINCE
120 if (path[0] == '\\')
121 return false;
122 #else
123 if (path[1] == ':')
124 return false;
125 #endif
126 return true;
130 GetFrozenFunctionsFunc
131 XPCOMGlueLoad(const char *aXpcomFile)
133 wchar_t xpcomFile[MAXPATHLEN];
134 MultiByteToWideChar(CP_ACP, 0, aXpcomFile,-1,
135 xpcomFile, MAXPATHLEN);
138 if (xpcomFile[0] == '.' && xpcomFile[1] == '\0') {
139 wcscpy(xpcomFile, LXPCOM_DLL);
141 else {
142 wchar_t xpcomDir[MAXPATHLEN];
144 if (ns_isRelPath(xpcomFile))
146 _wfullpath(xpcomDir, xpcomFile, sizeof(xpcomDir)/sizeof(wchar_t));
148 else
150 wcscpy(xpcomDir, xpcomFile);
152 wchar_t *lastSlash = ns_wcspbrk(xpcomDir, L"/\\");
153 if (lastSlash) {
154 *lastSlash = '\0';
155 char xpcomDir_narrow[MAXPATHLEN];
156 WideCharToMultiByte(CP_ACP, 0, xpcomDir,-1,
157 xpcomDir_narrow, MAX_PATH, NULL, NULL);
159 XPCOMGlueLoadDependentLibs(xpcomDir_narrow, ReadDependentCB);
161 _snwprintf(lastSlash, MAXPATHLEN - wcslen(xpcomDir), L"\\" LXUL_DLL);
162 sXULLibrary =
163 LoadLibraryExW(xpcomDir, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
165 #ifdef DEBUG
166 if (!sXULLibrary)
168 LPVOID lpMsgBuf;
169 FormatMessage(
170 FORMAT_MESSAGE_ALLOCATE_BUFFER |
171 FORMAT_MESSAGE_FROM_SYSTEM |
172 FORMAT_MESSAGE_IGNORE_INSERTS,
173 NULL,
174 GetLastError(),
175 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
176 (LPTSTR) &lpMsgBuf,
178 NULL
180 wprintf(L"Error loading xul.dll: %s\n", lpMsgBuf);
182 #endif //DEBUG
185 HINSTANCE h =
186 LoadLibraryExW(xpcomFile, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
189 if (!h)
191 #ifdef DEBUG
192 LPVOID lpMsgBuf;
193 FormatMessage(
194 FORMAT_MESSAGE_ALLOCATE_BUFFER |
195 FORMAT_MESSAGE_FROM_SYSTEM |
196 FORMAT_MESSAGE_IGNORE_INSERTS,
197 NULL,
198 GetLastError(),
199 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
200 (LPTSTR) &lpMsgBuf,
202 NULL
204 wprintf(L"Error loading xpcom.dll: %s\n", lpMsgBuf);
205 #endif
206 return nsnull;
209 AppendDependentLib(h);
211 GetFrozenFunctionsFunc sym =
212 (GetFrozenFunctionsFunc) GetProcAddress(h, "NS_GetFrozenFunctions");
214 if (!sym)
215 XPCOMGlueUnload();
217 return sym;
220 void
221 XPCOMGlueUnload()
223 while (sTop) {
224 FreeLibrary(sTop->libHandle);
226 DependentLib *temp = sTop;
227 sTop = sTop->next;
229 delete temp;
232 if (sXULLibrary) {
233 FreeLibrary(sXULLibrary);
234 sXULLibrary = nsnull;
238 nsresult
239 XPCOMGlueLoadXULFunctions(const nsDynamicFunctionLoad *symbols)
241 if (!sXULLibrary)
242 return NS_ERROR_NOT_INITIALIZED;
244 nsresult rv = NS_OK;
245 while (symbols->functionName) {
246 *symbols->function =
247 (NSFuncPtr) GetProcAddress(sXULLibrary, symbols->functionName);
248 if (!*symbols->function)
249 rv = NS_ERROR_LOSS_OF_SIGNIFICANT_DATA;
251 ++symbols;
254 return rv;