1 /* -*- Mode: C++; tab-width: 4; 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
15 * The Original Code is Mozilla Communicator client code, released
18 * The Initial Developer of the Original Code is
19 * Netscape Communications Corporation.
20 * Portions created by the Initial Developer are Copyright (C) 2000
21 * the Initial Developer. All Rights Reserved.
24 * Conrad Carlen <conrad@ingress.com>
26 * Alternatively, the contents of this file may be used under the terms of
27 * either the GNU General Public License Version 2 or later (the "GPL"), or
28 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29 * in which case the provisions of the GPL or the LGPL are applicable instead
30 * of those above. If you wish to allow use of your version of this file only
31 * under the terms of either the GPL or the LGPL, and not to allow others to
32 * use your version of this file under the terms of the MPL, indicate your
33 * decision by deleting the provisions above and replace them with the notice
34 * and other provisions required by the GPL or the LGPL. If you do not delete
35 * the provisions above, a recipient may use your version of this file under
36 * the terms of any one of the MPL, the GPL or the LGPL.
38 * ***** END LICENSE BLOCK ***** */
40 #include "winEmbedFileLocProvider.h"
41 #include "nsAppDirectoryServiceDefs.h"
42 #include "nsDirectoryServiceDefs.h"
43 #include "nsILocalFile.h"
45 #include "nsXPIDLString.h"
53 // WARNING: These hard coded names need to go away. They need to
54 // come from localizable resources
55 #define APP_REGISTRY_NAME NS_LITERAL_CSTRING("registry.dat")
57 #define PROFILE_ROOT_DIR_NAME NS_LITERAL_CSTRING("Profiles")
58 #define DEFAULTS_DIR_NAME NS_LITERAL_CSTRING("defaults")
59 #define DEFAULTS_PREF_DIR_NAME NS_LITERAL_CSTRING("pref")
60 #define DEFAULTS_PROFILE_DIR_NAME NS_LITERAL_CSTRING("profile")
61 #define RES_DIR_NAME NS_LITERAL_CSTRING("res")
62 #define CHROME_DIR_NAME NS_LITERAL_CSTRING("chrome")
63 #define PLUGINS_DIR_NAME NS_LITERAL_CSTRING("plugins")
64 #define SEARCH_DIR_NAME NS_LITERAL_CSTRING("searchplugins")
65 #define COMPONENTS_DIR_NAME NS_LITERAL_CSTRING("components")
67 //*****************************************************************************
68 // winEmbedFileLocProvider::Constructor/Destructor
69 //*****************************************************************************
71 winEmbedFileLocProvider::winEmbedFileLocProvider(const char* productDirName
)
73 strncpy(mProductDirName
, productDirName
, sizeof(mProductDirName
) - 1);
74 mProductDirName
[sizeof(mProductDirName
) - 1] = '\0';
77 winEmbedFileLocProvider::~winEmbedFileLocProvider()
82 //*****************************************************************************
83 // winEmbedFileLocProvider::nsISupports
84 //*****************************************************************************
86 NS_IMPL_ISUPPORTS1(winEmbedFileLocProvider
, nsIDirectoryServiceProvider
)
88 //*****************************************************************************
89 // winEmbedFileLocProvider::nsIDirectoryServiceProvider
90 //*****************************************************************************
93 winEmbedFileLocProvider::GetFile(const char *prop
, PRBool
*persistent
, nsIFile
**_retval
)
95 nsCOMPtr
<nsILocalFile
> localFile
;
96 nsresult rv
= NS_ERROR_FAILURE
;
99 *persistent
= PR_TRUE
;
101 if (nsCRT::strcmp(prop
, NS_APP_APPLICATION_REGISTRY_DIR
) == 0)
103 rv
= GetProductDirectory(getter_AddRefs(localFile
));
105 else if (nsCRT::strcmp(prop
, NS_APP_APPLICATION_REGISTRY_FILE
) == 0)
107 rv
= GetProductDirectory(getter_AddRefs(localFile
));
108 if (NS_SUCCEEDED(rv
))
109 rv
= localFile
->AppendNative(APP_REGISTRY_NAME
);
111 else if (nsCRT::strcmp(prop
, NS_APP_DEFAULTS_50_DIR
) == 0)
113 rv
= CloneMozBinDirectory(getter_AddRefs(localFile
));
114 if (NS_SUCCEEDED(rv
))
115 rv
= localFile
->AppendRelativeNativePath(DEFAULTS_DIR_NAME
);
117 else if (nsCRT::strcmp(prop
, NS_APP_PREF_DEFAULTS_50_DIR
) == 0)
119 rv
= CloneMozBinDirectory(getter_AddRefs(localFile
));
120 if (NS_SUCCEEDED(rv
)) {
121 rv
= localFile
->AppendRelativeNativePath(DEFAULTS_DIR_NAME
);
122 if (NS_SUCCEEDED(rv
))
123 rv
= localFile
->AppendRelativeNativePath(DEFAULTS_PREF_DIR_NAME
);
126 else if (nsCRT::strcmp(prop
, NS_APP_PROFILE_DEFAULTS_NLOC_50_DIR
) == 0 ||
127 nsCRT::strcmp(prop
, NS_APP_PROFILE_DEFAULTS_50_DIR
) == 0)
129 rv
= CloneMozBinDirectory(getter_AddRefs(localFile
));
130 if (NS_SUCCEEDED(rv
)) {
131 rv
= localFile
->AppendRelativeNativePath(DEFAULTS_DIR_NAME
);
132 if (NS_SUCCEEDED(rv
))
133 rv
= localFile
->AppendRelativeNativePath(DEFAULTS_PROFILE_DIR_NAME
);
136 else if (nsCRT::strcmp(prop
, NS_APP_USER_PROFILES_ROOT_DIR
) == 0)
138 rv
= GetDefaultUserProfileRoot(getter_AddRefs(localFile
));
140 else if (nsCRT::strcmp(prop
, NS_APP_RES_DIR
) == 0)
142 rv
= CloneMozBinDirectory(getter_AddRefs(localFile
));
143 if (NS_SUCCEEDED(rv
))
144 rv
= localFile
->AppendRelativeNativePath(RES_DIR_NAME
);
146 else if (nsCRT::strcmp(prop
, NS_APP_CHROME_DIR
) == 0)
148 rv
= CloneMozBinDirectory(getter_AddRefs(localFile
));
149 if (NS_SUCCEEDED(rv
))
150 rv
= localFile
->AppendRelativeNativePath(CHROME_DIR_NAME
);
152 else if (nsCRT::strcmp(prop
, NS_APP_PLUGINS_DIR
) == 0)
154 rv
= CloneMozBinDirectory(getter_AddRefs(localFile
));
155 if (NS_SUCCEEDED(rv
))
156 rv
= localFile
->AppendRelativeNativePath(PLUGINS_DIR_NAME
);
158 else if (nsCRT::strcmp(prop
, NS_APP_SEARCH_DIR
) == 0)
160 rv
= CloneMozBinDirectory(getter_AddRefs(localFile
));
161 if (NS_SUCCEEDED(rv
))
162 rv
= localFile
->AppendRelativeNativePath(SEARCH_DIR_NAME
);
164 //---------------------------------------------------------------
165 // Note that by returning a valid localFile's for NS_GRE_DIR and
166 // NS_GRE_COMPONENT_DIR your app is indicating to XPCOM that
167 // it found an GRE version with which it's compatible with and
168 // it intends to be "run against" that GRE
170 // Please see http://www.mozilla.org/projects/embedding/MRE.html
171 // for more info. on GRE
172 //---------------------------------------------------------------
173 else if (nsCRT::strcmp(prop
, NS_GRE_DIR
) == 0)
175 rv
= GetGreDirectory(getter_AddRefs(localFile
));
177 else if (nsCRT::strcmp(prop
, NS_GRE_COMPONENT_DIR
) == 0)
179 rv
= GetGreDirectory(getter_AddRefs(localFile
));
180 if (NS_SUCCEEDED(rv
))
181 rv
= localFile
->AppendRelativeNativePath(COMPONENTS_DIR_NAME
);
184 if (localFile
&& NS_SUCCEEDED(rv
))
185 return localFile
->QueryInterface(NS_GET_IID(nsIFile
), (void**)_retval
);
190 // Get the location of the GRE version we're compatible with from
193 static char * GetGreLocationFromRegistry()
197 DWORD dwLength
= _MAX_PATH
* sizeof(char);
199 char keyValue
[_MAX_PATH
+ 1];
200 char *pGreLocation
= NULL
;
202 // A couple of key points here:
203 // 1. Note the usage of the "Software\\Mozilla\\GRE" subkey - this allows
204 // us to have multiple versions of GREs on the same machine by having
205 // subkeys such as 1.0, 1.1, 2.0 etc. under it.
206 // 2. In this sample below we're looking for the location of GRE version 1.3
207 // i.e. we're compatible with GRE 1.3 and we're trying to find it's install
210 // Please see http://www.mozilla.org/projects/embedding/MRE.html for
213 strcpy(szKey
, "Software\\Mozilla\\GRE\\" MOZILLA_VERSION
);
215 if (::RegOpenKeyEx(HKEY_LOCAL_MACHINE
, szKey
, 0, KEY_QUERY_VALUE
, &hRegKey
) == ERROR_SUCCESS
)
217 if ((rc
= ::RegQueryValueEx(hRegKey
, "GreHome", NULL
, NULL
, (BYTE
*)keyValue
, &dwLength
))==ERROR_SUCCESS
)
219 pGreLocation
= ::strdup(keyValue
);
220 ::RegCloseKey(hRegKey
);
227 // Create and return the location of the GRE the application is
228 // currently using, if any, via the |aLocalFile| param
230 // If an embedding application is written to use an GRE it determines
231 // the compatible GRE's location by looking in the Windows registry
232 // In this case GetGreDirectory() creates a new localFile based on the
233 // GRE path it just read from the registry
235 // If the embedding application is not using an GRE and is running in
236 // a "regular" embedding scenario GetGreDirectory() simply returns a
237 // failure code indicating to the caller to fallback to a non-GRE
238 // based operation - which is the default mode of operation.
240 // Please see http://www.mozilla.org/projects/embedding/MRE.html for
241 // more information on the Mozilla Runtime Environment(GRE) and for
242 // the actual registry key whichs contains the GRE path, if any.
244 NS_METHOD
winEmbedFileLocProvider::GetGreDirectory(nsILocalFile
**aLocalFile
)
246 NS_ENSURE_ARG_POINTER(aLocalFile
);
247 nsresult rv
= NS_ERROR_FAILURE
;
249 // Get the path of the GRE which is compatible with our embedding application
252 char *pGreDir
= GetGreLocationFromRegistry();
255 nsCOMPtr
<nsILocalFile
> tempLocal
;
256 rv
= NS_NewNativeLocalFile(nsDependentCString(pGreDir
), TRUE
, getter_AddRefs(tempLocal
));
260 *aLocalFile
= tempLocal
;
261 NS_ADDREF(*aLocalFile
);
271 NS_METHOD
winEmbedFileLocProvider::CloneMozBinDirectory(nsILocalFile
**aLocalFile
)
273 NS_ENSURE_ARG_POINTER(aLocalFile
);
276 if (!mMozBinDirectory
)
278 // Get the mozilla bin directory
279 // 1. Check the directory service first for NS_XPCOM_CURRENT_PROCESS_DIR
280 // This will be set if a directory was passed to NS_InitXPCOM
281 // 2. If that doesn't work, set it to be the current process directory
283 nsCOMPtr
<nsIProperties
> directoryService
=
284 do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID
, &rv
);
288 rv
= directoryService
->Get(NS_XPCOM_CURRENT_PROCESS_DIR
, NS_GET_IID(nsIFile
), getter_AddRefs(mMozBinDirectory
));
290 rv
= directoryService
->Get(NS_OS_CURRENT_PROCESS_DIR
, NS_GET_IID(nsIFile
), getter_AddRefs(mMozBinDirectory
));
296 nsCOMPtr
<nsIFile
> aFile
;
297 rv
= mMozBinDirectory
->Clone(getter_AddRefs(aFile
));
301 nsCOMPtr
<nsILocalFile
> lfile
= do_QueryInterface (aFile
);
303 return NS_ERROR_FAILURE
;
305 NS_IF_ADDREF(*aLocalFile
= lfile
);
310 //----------------------------------------------------------------------------------------
311 // GetProductDirectory - Gets the directory which contains the application data folder
313 // WIN : <Application Data folder on user's machine>\Mozilla
314 //----------------------------------------------------------------------------------------
315 NS_METHOD
winEmbedFileLocProvider::GetProductDirectory(nsILocalFile
**aLocalFile
)
317 NS_ENSURE_ARG_POINTER(aLocalFile
);
321 nsCOMPtr
<nsILocalFile
> localDir
;
323 nsCOMPtr
<nsIProperties
> directoryService
=
324 do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID
, &rv
);
325 if (NS_FAILED(rv
)) return rv
;
326 rv
= directoryService
->Get(NS_WIN_APPDATA_DIR
, NS_GET_IID(nsILocalFile
), getter_AddRefs(localDir
));
327 if (NS_SUCCEEDED(rv
))
328 rv
= localDir
->Exists(&exists
);
329 if (NS_FAILED(rv
) || !exists
)
331 // On some Win95 machines, NS_WIN_APPDATA_DIR does not exist - revert to NS_WIN_WINDOWS_DIR
333 rv
= directoryService
->Get(NS_WIN_WINDOWS_DIR
, NS_GET_IID(nsILocalFile
), getter_AddRefs(localDir
));
335 if (NS_FAILED(rv
)) return rv
;
337 rv
= localDir
->AppendRelativeNativePath(nsDependentCString(mProductDirName
));
338 if (NS_FAILED(rv
)) return rv
;
339 rv
= localDir
->Exists(&exists
);
340 if (NS_SUCCEEDED(rv
) && !exists
)
341 rv
= localDir
->Create(nsIFile::DIRECTORY_TYPE
, 0775);
342 if (NS_FAILED(rv
)) return rv
;
344 *aLocalFile
= localDir
;
345 NS_ADDREF(*aLocalFile
);
351 //----------------------------------------------------------------------------------------
352 // GetDefaultUserProfileRoot - Gets the directory which contains each user profile dir
354 // WIN : <Application Data folder on user's machine>\Mozilla\Users50
355 //----------------------------------------------------------------------------------------
356 NS_METHOD
winEmbedFileLocProvider::GetDefaultUserProfileRoot(nsILocalFile
**aLocalFile
)
358 NS_ENSURE_ARG_POINTER(aLocalFile
);
362 nsCOMPtr
<nsILocalFile
> localDir
;
364 rv
= GetProductDirectory(getter_AddRefs(localDir
));
365 if (NS_FAILED(rv
)) return rv
;
367 // These 3 platforms share this part of the path - do them as one
368 rv
= localDir
->AppendRelativeNativePath(PROFILE_ROOT_DIR_NAME
);
369 if (NS_FAILED(rv
)) return rv
;
370 rv
= localDir
->Exists(&exists
);
371 if (NS_SUCCEEDED(rv
) && !exists
)
372 rv
= localDir
->Create(nsIFile::DIRECTORY_TYPE
, 0775);
373 if (NS_FAILED(rv
)) return rv
;
375 *aLocalFile
= localDir
;
376 NS_ADDREF(*aLocalFile
);