mirror of
https://github.com/roytam1/palemoon27.git
synced 2026-05-26 14:30:27 +00:00
8a0a002cf2
- Bug 1148708: Add missing 'override' annotations in DocAccessibleChild.h. rs=ehsan (d606358545)
- Bug 1210408 - make nsMaiInterfaceAction work with proxies, r=tbsaunde (f7c819c6ae)
- Bug 1210407 - teach nsMaiInterfaceTable to use proxies, r=tbsaunde (4ca4f10b5f)
- bug 1185157 make sure we don't send an event to a destroyed ipc document r=billm (23acf53f75)
- bug 1214864 - make SetCarretOffset() async r=davidb (e3079e9b2d)
- missing of Bug 1139972 - IPC Proxy for charAt, r=tbsaunde (e9593ed752)
- bug 1191598 - Pass MOZ_CURRENT_PROJECT in environment when running post-build automation steps for universal mac builds. r=gps (fc342c6ced)
- Bug 1164596 - Add mach android-emulator command; r=ahal (afeb9b27d1)
- Bug 1223149 - Add basic usage documentation for mach build; r=glandium (bfb802d175)
- Bug 1182301 - Improve 'mach build' notifications. r=gps (2c65a122d1)
- Bug 1184696 - Add clobber targets to |mach clobber|; Ability to clobber compiled python files, r=gps (35d8be292e)
- Bug 1117958 - Allow any debugging options to the run or gtest mach subcommands to automatically enable debugging. r=gps (32f986af4b)
- Bug 1180081 - Properly rebuild gtest/libxul before running gtests. r=gps (80db9a3d49)
- Bug 1171647, part 1 - Define a new function to convert the mode to a string. r=njn (61ad16f5ba)
- Bug 1171647, part 2 - Remove redundant assertion for dark matter mode. r=njn (b5ac9519f3)
- Bug 1058178, part 1 - Implement DMD heap scanning mode. r=njn (60e1079536)
- Bug 1058178, part 2 - Implement address clamping analysis for DMD scan logs. r=njn (45c0326b93)
- Bug 1102388 - Fix DMD static constructor ordering dependency. r=mccr8 (59b87897a1)
- Bug 1128705 - Don't redefine PAGE_SIZE in DMD if it's already defined. r=erahm (49216348ee)
- Bug 1179042 - Add a script for analyzing memory blocks using a heap scan DMD log. r=njn DONTBUILD (1c08d2d66e)
- Bug 1207245 - part 6 - rename nsRefPtr<T> to RefPtr<T>; r=ehsan; a=Tomcat (1c999d139b)
- Bug 1158772 - fix non-idiomatic memset call in nsDeque.cpp; r=erahm (de6b555245)
- Bug 1199400 - Part 1: Use CheckedInt when growing nsDeque capacity. r=froydnj (dfdf6814a3)
- Bug 1199400 - Part 0: Remove unused nsDequeIterator. r=froydnj (38d69d7f47)
- Bug 1199400 - Part 2: Add tests for possible nsDeque corner cases. r=froydnj (931baff195)
- Bug 1201997 - Part 1 - Converted compiled test to gtest for nsDeque class. Added tests to test untested methods. r=froydn (e893916651)
- Bug 1201997 - Part 2 - Removing unused methods from the nsDeque class. r=froydn (41595a90ac)
- Bug 1201997 - Part 3 - Make internally used methods private. r=froydn (8cd3afd96f)
- Bug 1201997 - Part 4 - Change size and offset variables to size_t.r=froydn (73eabc8d60)
- Bug 1215140 P1 Add an nsIConsoleReportCollector interface to support navigation channel logging. r=bz (8a41535e2b)
- Bug 1215140 P2 Make HttpBaseChannel implement nsIConsoleReportCollector. r=bz (75fca301f2)
- Bug 1197679 - If nsUnknownDecoder is involved in e10s DivertToParent can break. r=jduell (5d94a12504)
- Bug 1178991 - smartptr for http converter r=hurley (8e7fbc8443)
- bug 366559 - patch 2, fix nsHTTPCompressConv indentation r=bagder (ba762da587)
- bug 366559 - patch 3, fix nsHTTPCompressConv bracing style r=bagder (54195ab451)
- bits of bug 366559 - patch 7, content-encoding brotli for http (f0b4051022)
- Bug 1205112 - Make PushEvent.data nullable. r=mt,smaug (775db32856)
- Bug 1193414 - SharedWorkers thread should be kept alive also when the SharedWorker object is CCed, r=khuey (b77ea8125c)
- Bug 1206520: Add about:config prefs to enable throwing on asm.js validation failures; r=bz (c42126665d)
- Bug 1193414 - Telemetry for SharedWorker spawning. r=bkelly (77984b7bcc)
- Bug 1205676 - Enable WPT service-worker/unregister-then-register-new-script.https.html in e10s, r=nsm (ec24939cf6)
- Bug 1193133 - Throw when calling postMessage from a Service Worker dom object with no global. r=bkelly (526dcacfab)
- Bug 1181871 P1 Only enforce Cache Context shared data destruction on target thread after init. r=ehsan (cdbf3ed3a8)
- Bug 1181871 P2 Fix ServiceWorkerManager usage of stack-based ErrorResult. r=ehsan (c449195d90)
- minor cleanup and missing bit of 1198230 (02f459db05)
- Bug 1143717 - Implement the ServiceWorkerMessageEvent interface. r=baku (027b3465f2)
- fix misspatch (708eee4e84)
- Bug 1188545 - Disentangle service workers from shared workers and refactor event dispatching code into a separate class. r=nsm,mrbkap (fb5b5341c9)
- Bug 1205228 - Change PackagedAppVerifier to notify the verification result asynchronously. r=valentin. (9edda0fa00)
- Bug 1178518 - Packaged App Utils. r=valentin (f60f3b7a93)
- Bug 1213150 - Part 1: Add a nsContentUtils::IsNonSubresourceRequest helper; r=jdm (b509cc3cc9)
- Bug 1213150 - Part 2: Rework ShouldPrepareForIntercept() in terms of subresource requests; r=jdm (2e92fe8780)
- Bug 1213150 - Part 3: Remove nsIInterceptedChannel.isNavigation; r=jdm (becf1cc12f)
- Bug 1213150 follow-up: fix build bustage (8d73d6ca73)
- Bug 1198394 - Part 1: Allow interception of HSTS upgraded connections in non-e10s mode; r=mcmanus (f504c5be08)
- Bug 1198394 - Part 2: Add a test for interception of HSTS upgraded connections; r=jdm (054e984eef)
- Bug 1187011 - Don't allow response body with null body status. r=bkelly (b1860741d1)
- missing bit of 1140788 (29d319712e)
- Bug 1213436 - Reject core dumps with node IDs that don't fit in an IEEE 754 double; r=sfink (3c1f6fdda0)
- Bug 1211006 - Add Debugger.Source.prototype.canonicalId; r=ejpbruel (eef7b79fce)
- Bug 1199218 - Implement JS::ubi::Node::size for js::LazyScript referents; r=sfink (098a48d240)
- Bug 1220031 - Add JS::ubi::Node::scriptFilename; r=sfink (6b824ae680)
- Bug 1143575. Remove unused MediaQueue::Empty. r=cpearce (de737f3433)
- Bug 1209933 - Make sure all parent runtime pointers are the topmost parent, r=billm. (fe824d967d)
- Bug 1197012 - Fix ThrowTypeError in Notification. r=mccr8 (0b1a097526)
- Bug 1197893 - Check the number of arguments for ThrowTypeError() and ThrowRangeError() at compile time. r=peterv (d98c7d78a0)
- Bug 1142083 - Add test for IDN Unicode domain redirect. r=mcmanus (0c8961fe17)
- Bug 1187159 - Add mochitest for loading packaged apps (iframe+fetch+mozapp) r=jduell (ce90ea561b)
- Bug 1186290 - Notify TabParent to switch process when loading a signed package. r=honzab, r=kanru. (c58a14554a)
- fix (15e2df75eb)
- Bug 1206124 P1 Fix "same-origin" CORS credentials in FetchDriver. r=ehsan (fae1bb6ab3)
- Bug 1206124 P2 Test fetch() with credentials and redirects. r=ehsan (ffc6254112)
- Bug 1211751: Remove nsIChannelEventSink-forwarding from EventSource and FetchDriver. It's never needed. r=smaug (adafe5737a)
- Bug 1212433 Fail fetch() calls that require preflight and also redirect. r=sicking a=abillings (c0d6742b9e)
- Bug 1193128 - Fix base64 decoding when fetching data URIs. r=baku (80bafa291a)
- Bug 1195167 part 1: Let necko handle all protocols. r=bkelly (bb932b0ada)
- Bug 1195167 part 2: Remove redundant aCORSFlag argument and instead use mCORSFlagEverSet. r=bkelly (beadafcad0)
- Bug 1195167 part 3: Remove more scheme-specific handling from FetchDriver. r=bkelly (d00b38db9e)
- Bug 1195167 part 4: Remove FetchDriver::BasicFetch since it is empty. r=bkelly (c5ed097267)
- Bug 1210413 P2 Test CORS credentials on cross-origin redirects. r=sicking a=dveditz (b4eeb8aac0)
- Bug 1210413 P1 Propagate new channel load flags from child to parent on redirect. r=jduell a=dveditz (8b329af4fa)
- Bug 1195167 part 5: Make FetchDriver use AsyncOpen2. r=bkelly (cc217c4cc1)
- Bug 1195167 part 6: Some code simplification since necko handles fetch recursion. r=bkelly (f3b6da2262)
- Bug 1195167: Followup to fix test which I forgot to change (81e7439a2e)
- Bug 1215746: Remove RequestMode::Cors_with_forced_preflight. r=bkelly (0336e812b6)
- Bug 1211000: Move CORS preflight logic from nsCORSListenerProxy to nsCORSPreflightListener. r=ehsan (bf2f71cf22)
- missing bit of Bug 1211443 - Drop scheduled update if decoder initialization isn't done yet. r=jya (f6bc074e33)
- Bug 1182571: Fix nsILoadInfo->GetContentPolicyType API to be less ambigious. Audit and fix all users of it. r=ckerschb (5af6fa7442)
- fix (e40c8e7625)
- Bug 1173811 - Part 1: Propagate the response URL to intercepted channels when necessary (non-e10s). r=mayhemer,bkelly (26f4f13c28)
- Bug 1173811 - Part 2: Propagate the response URL to intercepted channels when necessary (e10s). r=mayhemer,bkelly (a603fe1df2)
- Bug 1154309 - Add New Resource Timing Fields r=bz,hurley (1d14eb6bef)
- Bug 1175685 - add OriginAttribute to LoadInfo. r=jonas, r=ckerschb, r=michal (a5d18bb637)
- Bug 1175685 - add OriginAttribute to LoadInfo. r=jonas, r=ckerschb, r=michal (fb07d2c8aa)
- Bug 1212904 P1 Add a LoadTainting enumeration. r=jduell (a1db8a3e99)
- Bug 1212904 P2 Add LoadTainting information to nsILoadInfo. r=jduell (2482e5e334)
- Bug 1221151 - use [infallible] in nsILoadInfo.idl instead of manual %{C++ blocks; r=jduell (aae73129b6)
- Bug 1045891 - CSP 2 child-src implementation r=ckerschb (792920aeb9)
- Bug 1219931 - CSP: Don't allow removing a policy (r=sicking) (9daaab4186)
- Bug 1208661 - Dump client-side layer textures. r=BenWa (1f2d17d515)
834 lines
21 KiB
C++
834 lines
21 KiB
C++
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
#include "SpecialSystemDirectory.h"
|
|
#include "nsString.h"
|
|
#include "nsDependentString.h"
|
|
#include "nsAutoPtr.h"
|
|
|
|
#if defined(XP_WIN)
|
|
|
|
#include <windows.h>
|
|
#include <shlobj.h>
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <direct.h>
|
|
#include <shlobj.h>
|
|
#include <knownfolders.h>
|
|
#include <guiddef.h>
|
|
#include "mozilla/WindowsVersion.h"
|
|
|
|
using mozilla::IsWin7OrLater;
|
|
|
|
#elif defined(XP_UNIX)
|
|
|
|
#include <limits.h>
|
|
#include <unistd.h>
|
|
#include <stdlib.h>
|
|
#include <sys/param.h>
|
|
#include "prenv.h"
|
|
|
|
#endif
|
|
|
|
#if defined(VMS)
|
|
#include <unixlib.h>
|
|
#endif
|
|
|
|
#ifndef MAXPATHLEN
|
|
#ifdef PATH_MAX
|
|
#define MAXPATHLEN PATH_MAX
|
|
#elif defined(MAX_PATH)
|
|
#define MAXPATHLEN MAX_PATH
|
|
#elif defined(_MAX_PATH)
|
|
#define MAXPATHLEN _MAX_PATH
|
|
#elif defined(CCHMAXPATH)
|
|
#define MAXPATHLEN CCHMAXPATH
|
|
#else
|
|
#define MAXPATHLEN 1024
|
|
#endif
|
|
#endif
|
|
|
|
#ifdef XP_WIN
|
|
typedef HRESULT (WINAPI* nsGetKnownFolderPath)(GUID& rfid,
|
|
DWORD dwFlags,
|
|
HANDLE hToken,
|
|
PWSTR* ppszPath);
|
|
|
|
static nsGetKnownFolderPath gGetKnownFolderPath = nullptr;
|
|
#endif
|
|
|
|
void
|
|
StartupSpecialSystemDirectory()
|
|
{
|
|
#if defined (XP_WIN)
|
|
// SHGetKnownFolderPath is only available on Windows Vista
|
|
// so that we need to use GetProcAddress to get the pointer.
|
|
HMODULE hShell32DLLInst = GetModuleHandleW(L"shell32.dll");
|
|
if (hShell32DLLInst) {
|
|
gGetKnownFolderPath = (nsGetKnownFolderPath)
|
|
GetProcAddress(hShell32DLLInst, "SHGetKnownFolderPath");
|
|
}
|
|
#endif
|
|
}
|
|
|
|
#if defined (XP_WIN)
|
|
|
|
static nsresult
|
|
GetKnownFolder(GUID* aGuid, nsIFile** aFile)
|
|
{
|
|
if (!aGuid || !gGetKnownFolderPath) {
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
|
|
PWSTR path = nullptr;
|
|
gGetKnownFolderPath(*aGuid, 0, nullptr, &path);
|
|
|
|
if (!path) {
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
|
|
nsresult rv = NS_NewLocalFile(nsDependentString(path),
|
|
true,
|
|
aFile);
|
|
|
|
CoTaskMemFree(path);
|
|
return rv;
|
|
}
|
|
|
|
static nsresult
|
|
GetWindowsFolder(int aFolder, nsIFile** aFile)
|
|
{
|
|
WCHAR path_orig[MAX_PATH + 3];
|
|
WCHAR* path = path_orig + 1;
|
|
HRESULT result = SHGetSpecialFolderPathW(nullptr, path, aFolder, true);
|
|
|
|
if (!SUCCEEDED(result)) {
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
|
|
// Append the trailing slash
|
|
int len = wcslen(path);
|
|
if (len > 1 && path[len - 1] != L'\\') {
|
|
path[len] = L'\\';
|
|
path[++len] = L'\0';
|
|
}
|
|
|
|
return NS_NewLocalFile(nsDependentString(path, len), true, aFile);
|
|
}
|
|
|
|
__inline HRESULT
|
|
SHLoadLibraryFromKnownFolder(REFKNOWNFOLDERID aFolderId, DWORD aMode,
|
|
REFIID riid, void** ppv)
|
|
{
|
|
*ppv = nullptr;
|
|
IShellLibrary* plib;
|
|
HRESULT hr = CoCreateInstance(CLSID_ShellLibrary, nullptr,
|
|
CLSCTX_INPROC_SERVER,
|
|
IID_PPV_ARGS(&plib));
|
|
if (SUCCEEDED(hr)) {
|
|
hr = plib->LoadLibraryFromKnownFolder(aFolderId, aMode);
|
|
if (SUCCEEDED(hr)) {
|
|
hr = plib->QueryInterface(riid, ppv);
|
|
}
|
|
plib->Release();
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
/*
|
|
* Check to see if we're on Win7 and up, and if so, returns the default
|
|
* save-to location for the Windows Library passed in through aFolderId.
|
|
* Otherwise falls back on pre-win7 GetWindowsFolder.
|
|
*/
|
|
static nsresult
|
|
GetLibrarySaveToPath(int aFallbackFolderId, REFKNOWNFOLDERID aFolderId,
|
|
nsIFile** aFile)
|
|
{
|
|
// Skip off checking for library support if the os is Vista or lower.
|
|
if (!IsWin7OrLater()) {
|
|
return GetWindowsFolder(aFallbackFolderId, aFile);
|
|
}
|
|
|
|
RefPtr<IShellLibrary> shellLib;
|
|
RefPtr<IShellItem> savePath;
|
|
HRESULT hr =
|
|
SHLoadLibraryFromKnownFolder(aFolderId, STGM_READ,
|
|
IID_IShellLibrary, getter_AddRefs(shellLib));
|
|
|
|
if (shellLib &&
|
|
SUCCEEDED(shellLib->GetDefaultSaveFolder(DSFT_DETECT, IID_IShellItem,
|
|
getter_AddRefs(savePath)))) {
|
|
wchar_t* str = nullptr;
|
|
if (SUCCEEDED(savePath->GetDisplayName(SIGDN_FILESYSPATH, &str))) {
|
|
nsAutoString path;
|
|
path.Assign(str);
|
|
path.Append('\\');
|
|
nsresult rv =
|
|
NS_NewLocalFile(path, false, aFile);
|
|
CoTaskMemFree(str);
|
|
return rv;
|
|
}
|
|
}
|
|
|
|
return GetWindowsFolder(aFallbackFolderId, aFile);
|
|
}
|
|
|
|
/**
|
|
* Provides a fallback for getting the path to APPDATA or LOCALAPPDATA by
|
|
* querying the registry when the call to SHGetSpecialFolderPathW is unable to
|
|
* provide these paths (Bug 513958).
|
|
*/
|
|
static nsresult
|
|
GetRegWindowsAppDataFolder(bool aLocal, nsIFile** aFile)
|
|
{
|
|
HKEY key;
|
|
NS_NAMED_LITERAL_STRING(keyName,
|
|
"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders");
|
|
DWORD res = ::RegOpenKeyExW(HKEY_CURRENT_USER, keyName.get(), 0, KEY_READ,
|
|
&key);
|
|
if (res != ERROR_SUCCESS) {
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
|
|
WCHAR path[MAX_PATH + 2];
|
|
DWORD type, size;
|
|
res = RegQueryValueExW(key, (aLocal ? L"Local AppData" : L"AppData"),
|
|
nullptr, &type, (LPBYTE)&path, &size);
|
|
::RegCloseKey(key);
|
|
// The call to RegQueryValueExW must succeed, the type must be REG_SZ, the
|
|
// buffer size must not equal 0, and the buffer size be a multiple of 2.
|
|
if (res != ERROR_SUCCESS || type != REG_SZ || size == 0 || size % 2 != 0) {
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
|
|
// Append the trailing slash
|
|
int len = wcslen(path);
|
|
if (len > 1 && path[len - 1] != L'\\') {
|
|
path[len] = L'\\';
|
|
path[++len] = L'\0';
|
|
}
|
|
|
|
return NS_NewLocalFile(nsDependentString(path, len), true, aFile);
|
|
}
|
|
|
|
#endif // XP_WIN
|
|
|
|
#if defined(XP_UNIX)
|
|
static nsresult
|
|
GetUnixHomeDir(nsIFile** aFile)
|
|
{
|
|
#ifdef VMS
|
|
char* pHome;
|
|
pHome = getenv("HOME");
|
|
if (*pHome == '/') {
|
|
return NS_NewNativeLocalFile(nsDependentCString(pHome),
|
|
true,
|
|
aFile);
|
|
} else {
|
|
return NS_NewNativeLocalFile(nsDependentCString(decc$translate_vms(pHome)),
|
|
true,
|
|
aFile);
|
|
}
|
|
#elif defined(ANDROID)
|
|
// XXX no home dir on android; maybe we should return the sdcard if present?
|
|
return NS_ERROR_FAILURE;
|
|
#else
|
|
return NS_NewNativeLocalFile(nsDependentCString(PR_GetEnv("HOME")),
|
|
true, aFile);
|
|
#endif
|
|
}
|
|
|
|
/*
|
|
The following license applies to the xdg_user_dir_lookup function:
|
|
|
|
Copyright (c) 2007 Red Hat, Inc.
|
|
|
|
Permission is hereby granted, free of charge, to any person
|
|
obtaining a copy of this software and associated documentation files
|
|
(the "Software"), to deal in the Software without restriction,
|
|
including without limitation the rights to use, copy, modify, merge,
|
|
publish, distribute, sublicense, and/or sell copies of the Software,
|
|
and to permit persons to whom the Software is furnished to do so,
|
|
subject to the following conditions:
|
|
|
|
The above copyright notice and this permission notice shall be
|
|
included in all copies or substantial portions of the Software.
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
|
BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
|
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
SOFTWARE.
|
|
*/
|
|
|
|
static char*
|
|
xdg_user_dir_lookup(const char* aType)
|
|
{
|
|
FILE* file;
|
|
char* home_dir;
|
|
char* config_home;
|
|
char* config_file;
|
|
char buffer[512];
|
|
char* user_dir;
|
|
char* p;
|
|
char* d;
|
|
int len;
|
|
int relative;
|
|
|
|
home_dir = getenv("HOME");
|
|
|
|
if (!home_dir) {
|
|
goto error;
|
|
}
|
|
|
|
config_home = getenv("XDG_CONFIG_HOME");
|
|
if (!config_home || config_home[0] == 0) {
|
|
config_file = (char*)malloc(strlen(home_dir) +
|
|
strlen("/.config/user-dirs.dirs") + 1);
|
|
if (!config_file) {
|
|
goto error;
|
|
}
|
|
|
|
strcpy(config_file, home_dir);
|
|
strcat(config_file, "/.config/user-dirs.dirs");
|
|
} else {
|
|
config_file = (char*)malloc(strlen(config_home) +
|
|
strlen("/user-dirs.dirs") + 1);
|
|
if (!config_file) {
|
|
goto error;
|
|
}
|
|
|
|
strcpy(config_file, config_home);
|
|
strcat(config_file, "/user-dirs.dirs");
|
|
}
|
|
|
|
file = fopen(config_file, "r");
|
|
free(config_file);
|
|
if (!file) {
|
|
goto error;
|
|
}
|
|
|
|
user_dir = nullptr;
|
|
while (fgets(buffer, sizeof(buffer), file)) {
|
|
/* Remove newline at end */
|
|
len = strlen(buffer);
|
|
if (len > 0 && buffer[len - 1] == '\n') {
|
|
buffer[len - 1] = 0;
|
|
}
|
|
|
|
p = buffer;
|
|
while (*p == ' ' || *p == '\t') {
|
|
p++;
|
|
}
|
|
|
|
if (strncmp(p, "XDG_", 4) != 0) {
|
|
continue;
|
|
}
|
|
p += 4;
|
|
if (strncmp(p, aType, strlen(aType)) != 0) {
|
|
continue;
|
|
}
|
|
p += strlen(aType);
|
|
if (strncmp(p, "_DIR", 4) != 0) {
|
|
continue;
|
|
}
|
|
p += 4;
|
|
|
|
while (*p == ' ' || *p == '\t') {
|
|
p++;
|
|
}
|
|
|
|
if (*p != '=') {
|
|
continue;
|
|
}
|
|
p++;
|
|
|
|
while (*p == ' ' || *p == '\t') {
|
|
p++;
|
|
}
|
|
|
|
if (*p != '"') {
|
|
continue;
|
|
}
|
|
p++;
|
|
|
|
relative = 0;
|
|
if (strncmp(p, "$HOME/", 6) == 0) {
|
|
p += 6;
|
|
relative = 1;
|
|
} else if (*p != '/') {
|
|
continue;
|
|
}
|
|
|
|
if (relative) {
|
|
user_dir = (char*)malloc(strlen(home_dir) + 1 + strlen(p) + 1);
|
|
if (!user_dir) {
|
|
goto error2;
|
|
}
|
|
|
|
strcpy(user_dir, home_dir);
|
|
strcat(user_dir, "/");
|
|
} else {
|
|
user_dir = (char*)malloc(strlen(p) + 1);
|
|
if (!user_dir) {
|
|
goto error2;
|
|
}
|
|
|
|
*user_dir = 0;
|
|
}
|
|
|
|
d = user_dir + strlen(user_dir);
|
|
while (*p && *p != '"') {
|
|
if ((*p == '\\') && (*(p + 1) != 0)) {
|
|
p++;
|
|
}
|
|
*d++ = *p++;
|
|
}
|
|
*d = 0;
|
|
}
|
|
error2:
|
|
fclose(file);
|
|
|
|
if (user_dir) {
|
|
return user_dir;
|
|
}
|
|
|
|
error:
|
|
return nullptr;
|
|
}
|
|
|
|
static const char xdg_user_dirs[] =
|
|
"DESKTOP\0"
|
|
"DOCUMENTS\0"
|
|
"DOWNLOAD\0"
|
|
"MUSIC\0"
|
|
"PICTURES\0"
|
|
"PUBLICSHARE\0"
|
|
"TEMPLATES\0"
|
|
"VIDEOS";
|
|
|
|
static const uint8_t xdg_user_dir_offsets[] = {
|
|
0,
|
|
8,
|
|
18,
|
|
27,
|
|
33,
|
|
42,
|
|
54,
|
|
64
|
|
};
|
|
|
|
static nsresult
|
|
GetUnixXDGUserDirectory(SystemDirectories aSystemDirectory,
|
|
nsIFile** aFile)
|
|
{
|
|
char* dir = xdg_user_dir_lookup(
|
|
xdg_user_dirs + xdg_user_dir_offsets[aSystemDirectory - Unix_XDG_Desktop]);
|
|
|
|
nsresult rv;
|
|
nsCOMPtr<nsIFile> file;
|
|
if (dir) {
|
|
rv = NS_NewNativeLocalFile(nsDependentCString(dir), true,
|
|
getter_AddRefs(file));
|
|
free(dir);
|
|
} else if (Unix_XDG_Desktop == aSystemDirectory) {
|
|
// for the XDG desktop dir, fall back to HOME/Desktop
|
|
// (for historical compatibility)
|
|
rv = GetUnixHomeDir(getter_AddRefs(file));
|
|
if (NS_FAILED(rv)) {
|
|
return rv;
|
|
}
|
|
|
|
rv = file->AppendNative(NS_LITERAL_CSTRING("Desktop"));
|
|
} else {
|
|
// no fallback for the other XDG dirs
|
|
rv = NS_ERROR_FAILURE;
|
|
}
|
|
|
|
if (NS_FAILED(rv)) {
|
|
return rv;
|
|
}
|
|
|
|
bool exists;
|
|
rv = file->Exists(&exists);
|
|
if (NS_FAILED(rv)) {
|
|
return rv;
|
|
}
|
|
if (!exists) {
|
|
rv = file->Create(nsIFile::DIRECTORY_TYPE, 0755);
|
|
if (NS_FAILED(rv)) {
|
|
return rv;
|
|
}
|
|
}
|
|
|
|
*aFile = nullptr;
|
|
file.swap(*aFile);
|
|
|
|
return NS_OK;
|
|
}
|
|
#endif
|
|
|
|
nsresult
|
|
GetSpecialSystemDirectory(SystemDirectories aSystemSystemDirectory,
|
|
nsIFile** aFile)
|
|
{
|
|
#if defined(XP_WIN)
|
|
WCHAR path[MAX_PATH];
|
|
#else
|
|
char path[MAXPATHLEN];
|
|
#endif
|
|
|
|
switch (aSystemSystemDirectory) {
|
|
case OS_CurrentWorkingDirectory:
|
|
#if defined(XP_WIN)
|
|
if (!_wgetcwd(path, MAX_PATH)) {
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
return NS_NewLocalFile(nsDependentString(path),
|
|
true,
|
|
aFile);
|
|
#else
|
|
if (!getcwd(path, MAXPATHLEN)) {
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
#endif
|
|
|
|
#if !defined(XP_WIN)
|
|
return NS_NewNativeLocalFile(nsDependentCString(path),
|
|
true,
|
|
aFile);
|
|
#endif
|
|
|
|
case OS_DriveDirectory:
|
|
#if defined (XP_WIN)
|
|
{
|
|
int32_t len = ::GetWindowsDirectoryW(path, MAX_PATH);
|
|
if (len == 0) {
|
|
break;
|
|
}
|
|
if (path[1] == char16_t(':') && path[2] == char16_t('\\')) {
|
|
path[3] = 0;
|
|
}
|
|
|
|
return NS_NewLocalFile(nsDependentString(path),
|
|
true,
|
|
aFile);
|
|
}
|
|
#else
|
|
return NS_NewNativeLocalFile(nsDependentCString("/"),
|
|
true,
|
|
aFile);
|
|
|
|
#endif
|
|
|
|
case OS_TemporaryDirectory:
|
|
#if defined (XP_WIN)
|
|
{
|
|
DWORD len = ::GetTempPathW(MAX_PATH, path);
|
|
if (len == 0) {
|
|
break;
|
|
}
|
|
return NS_NewLocalFile(nsDependentString(path, len),
|
|
true,
|
|
aFile);
|
|
}
|
|
#elif defined(MOZ_WIDGET_COCOA)
|
|
{
|
|
return GetOSXFolderType(kUserDomain, kTemporaryFolderType, aFile);
|
|
}
|
|
|
|
#elif defined(XP_UNIX)
|
|
{
|
|
static const char* tPath = nullptr;
|
|
if (!tPath) {
|
|
tPath = PR_GetEnv("TMPDIR");
|
|
if (!tPath || !*tPath) {
|
|
tPath = PR_GetEnv("TMP");
|
|
if (!tPath || !*tPath) {
|
|
tPath = PR_GetEnv("TEMP");
|
|
if (!tPath || !*tPath) {
|
|
tPath = "/tmp/";
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return NS_NewNativeLocalFile(nsDependentCString(tPath),
|
|
true,
|
|
aFile);
|
|
}
|
|
#else
|
|
break;
|
|
#endif
|
|
#if defined (XP_WIN)
|
|
case Win_SystemDirectory: {
|
|
int32_t len = ::GetSystemDirectoryW(path, MAX_PATH);
|
|
|
|
// Need enough space to add the trailing backslash
|
|
if (!len || len > MAX_PATH - 2) {
|
|
break;
|
|
}
|
|
path[len] = L'\\';
|
|
path[++len] = L'\0';
|
|
|
|
return NS_NewLocalFile(nsDependentString(path, len),
|
|
true,
|
|
aFile);
|
|
}
|
|
|
|
case Win_WindowsDirectory: {
|
|
int32_t len = ::GetWindowsDirectoryW(path, MAX_PATH);
|
|
|
|
// Need enough space to add the trailing backslash
|
|
if (!len || len > MAX_PATH - 2) {
|
|
break;
|
|
}
|
|
|
|
path[len] = L'\\';
|
|
path[++len] = L'\0';
|
|
|
|
return NS_NewLocalFile(nsDependentString(path, len),
|
|
true,
|
|
aFile);
|
|
}
|
|
|
|
case Win_ProgramFiles: {
|
|
return GetWindowsFolder(CSIDL_PROGRAM_FILES, aFile);
|
|
}
|
|
|
|
case Win_HomeDirectory: {
|
|
nsresult rv = GetWindowsFolder(CSIDL_PROFILE, aFile);
|
|
if (NS_SUCCEEDED(rv)) {
|
|
return rv;
|
|
}
|
|
|
|
int32_t len;
|
|
if ((len = ::GetEnvironmentVariableW(L"HOME", path, MAX_PATH)) > 0) {
|
|
// Need enough space to add the trailing backslash
|
|
if (len > MAX_PATH - 2) {
|
|
break;
|
|
}
|
|
|
|
path[len] = L'\\';
|
|
path[++len] = L'\0';
|
|
|
|
rv = NS_NewLocalFile(nsDependentString(path, len),
|
|
true,
|
|
aFile);
|
|
if (NS_SUCCEEDED(rv)) {
|
|
return rv;
|
|
}
|
|
}
|
|
|
|
len = ::GetEnvironmentVariableW(L"HOMEDRIVE", path, MAX_PATH);
|
|
if (0 < len && len < MAX_PATH) {
|
|
WCHAR temp[MAX_PATH];
|
|
DWORD len2 = ::GetEnvironmentVariableW(L"HOMEPATH", temp, MAX_PATH);
|
|
if (0 < len2 && len + len2 < MAX_PATH) {
|
|
wcsncat(path, temp, len2);
|
|
}
|
|
|
|
len = wcslen(path);
|
|
|
|
// Need enough space to add the trailing backslash
|
|
if (len > MAX_PATH - 2) {
|
|
break;
|
|
}
|
|
|
|
path[len] = L'\\';
|
|
path[++len] = L'\0';
|
|
|
|
return NS_NewLocalFile(nsDependentString(path, len),
|
|
true,
|
|
aFile);
|
|
}
|
|
}
|
|
case Win_Desktop: {
|
|
return GetWindowsFolder(CSIDL_DESKTOP, aFile);
|
|
}
|
|
case Win_Programs: {
|
|
return GetWindowsFolder(CSIDL_PROGRAMS, aFile);
|
|
}
|
|
|
|
case Win_Downloads: {
|
|
// Defined in KnownFolders.h.
|
|
GUID folderid_downloads = {
|
|
0x374de290, 0x123f, 0x4565,
|
|
{ 0x91, 0x64, 0x39, 0xc4, 0x92, 0x5e, 0x46, 0x7b }
|
|
};
|
|
nsresult rv = GetKnownFolder(&folderid_downloads, aFile);
|
|
// On WinXP, there is no downloads folder, default
|
|
// to 'Desktop'.
|
|
if (NS_ERROR_FAILURE == rv) {
|
|
rv = GetWindowsFolder(CSIDL_DESKTOP, aFile);
|
|
}
|
|
return rv;
|
|
}
|
|
|
|
case Win_Controls: {
|
|
return GetWindowsFolder(CSIDL_CONTROLS, aFile);
|
|
}
|
|
case Win_Printers: {
|
|
return GetWindowsFolder(CSIDL_PRINTERS, aFile);
|
|
}
|
|
case Win_Personal: {
|
|
return GetWindowsFolder(CSIDL_PERSONAL, aFile);
|
|
}
|
|
case Win_Favorites: {
|
|
return GetWindowsFolder(CSIDL_FAVORITES, aFile);
|
|
}
|
|
case Win_Startup: {
|
|
return GetWindowsFolder(CSIDL_STARTUP, aFile);
|
|
}
|
|
case Win_Recent: {
|
|
return GetWindowsFolder(CSIDL_RECENT, aFile);
|
|
}
|
|
case Win_Sendto: {
|
|
return GetWindowsFolder(CSIDL_SENDTO, aFile);
|
|
}
|
|
case Win_Bitbucket: {
|
|
return GetWindowsFolder(CSIDL_BITBUCKET, aFile);
|
|
}
|
|
case Win_Startmenu: {
|
|
return GetWindowsFolder(CSIDL_STARTMENU, aFile);
|
|
}
|
|
case Win_Desktopdirectory: {
|
|
return GetWindowsFolder(CSIDL_DESKTOPDIRECTORY, aFile);
|
|
}
|
|
case Win_Drives: {
|
|
return GetWindowsFolder(CSIDL_DRIVES, aFile);
|
|
}
|
|
case Win_Network: {
|
|
return GetWindowsFolder(CSIDL_NETWORK, aFile);
|
|
}
|
|
case Win_Nethood: {
|
|
return GetWindowsFolder(CSIDL_NETHOOD, aFile);
|
|
}
|
|
case Win_Fonts: {
|
|
return GetWindowsFolder(CSIDL_FONTS, aFile);
|
|
}
|
|
case Win_Templates: {
|
|
return GetWindowsFolder(CSIDL_TEMPLATES, aFile);
|
|
}
|
|
case Win_Common_Startmenu: {
|
|
return GetWindowsFolder(CSIDL_COMMON_STARTMENU, aFile);
|
|
}
|
|
case Win_Common_Programs: {
|
|
return GetWindowsFolder(CSIDL_COMMON_PROGRAMS, aFile);
|
|
}
|
|
case Win_Common_Startup: {
|
|
return GetWindowsFolder(CSIDL_COMMON_STARTUP, aFile);
|
|
}
|
|
case Win_Common_Desktopdirectory: {
|
|
return GetWindowsFolder(CSIDL_COMMON_DESKTOPDIRECTORY, aFile);
|
|
}
|
|
case Win_Common_AppData: {
|
|
return GetWindowsFolder(CSIDL_COMMON_APPDATA, aFile);
|
|
}
|
|
case Win_Printhood: {
|
|
return GetWindowsFolder(CSIDL_PRINTHOOD, aFile);
|
|
}
|
|
case Win_Cookies: {
|
|
return GetWindowsFolder(CSIDL_COOKIES, aFile);
|
|
}
|
|
case Win_Appdata: {
|
|
nsresult rv = GetWindowsFolder(CSIDL_APPDATA, aFile);
|
|
if (NS_FAILED(rv)) {
|
|
rv = GetRegWindowsAppDataFolder(false, aFile);
|
|
}
|
|
return rv;
|
|
}
|
|
case Win_LocalAppdata: {
|
|
nsresult rv = GetWindowsFolder(CSIDL_LOCAL_APPDATA, aFile);
|
|
if (NS_FAILED(rv)) {
|
|
rv = GetRegWindowsAppDataFolder(true, aFile);
|
|
}
|
|
return rv;
|
|
}
|
|
#if defined(MOZ_CONTENT_SANDBOX)
|
|
case Win_LocalAppdataLow: {
|
|
// This should only really fail on versions pre-Vista, in which case this
|
|
// shouldn't have been used in the first place.
|
|
GUID localAppDataLowGuid = FOLDERID_LocalAppDataLow;
|
|
return GetKnownFolder(&localAppDataLowGuid, aFile);
|
|
}
|
|
#endif
|
|
case Win_Documents: {
|
|
return GetLibrarySaveToPath(CSIDL_MYDOCUMENTS,
|
|
FOLDERID_DocumentsLibrary,
|
|
aFile);
|
|
}
|
|
case Win_Pictures: {
|
|
return GetLibrarySaveToPath(CSIDL_MYPICTURES,
|
|
FOLDERID_PicturesLibrary,
|
|
aFile);
|
|
}
|
|
case Win_Music: {
|
|
return GetLibrarySaveToPath(CSIDL_MYMUSIC,
|
|
FOLDERID_MusicLibrary,
|
|
aFile);
|
|
}
|
|
case Win_Videos: {
|
|
return GetLibrarySaveToPath(CSIDL_MYVIDEO,
|
|
FOLDERID_VideosLibrary,
|
|
aFile);
|
|
}
|
|
#endif // XP_WIN
|
|
|
|
#if defined(XP_UNIX)
|
|
case Unix_LocalDirectory:
|
|
return NS_NewNativeLocalFile(nsDependentCString("/usr/local/netscape/"),
|
|
true,
|
|
aFile);
|
|
case Unix_LibDirectory:
|
|
return NS_NewNativeLocalFile(nsDependentCString("/usr/local/lib/netscape/"),
|
|
true,
|
|
aFile);
|
|
|
|
case Unix_HomeDirectory:
|
|
return GetUnixHomeDir(aFile);
|
|
|
|
case Unix_XDG_Desktop:
|
|
case Unix_XDG_Documents:
|
|
case Unix_XDG_Download:
|
|
case Unix_XDG_Music:
|
|
case Unix_XDG_Pictures:
|
|
case Unix_XDG_PublicShare:
|
|
case Unix_XDG_Templates:
|
|
case Unix_XDG_Videos:
|
|
return GetUnixXDGUserDirectory(aSystemSystemDirectory, aFile);
|
|
#endif
|
|
|
|
default:
|
|
break;
|
|
}
|
|
return NS_ERROR_NOT_AVAILABLE;
|
|
}
|
|
|
|
#if defined (MOZ_WIDGET_COCOA)
|
|
nsresult
|
|
GetOSXFolderType(short aDomain, OSType aFolderType, nsIFile** aLocalFile)
|
|
{
|
|
OSErr err;
|
|
FSRef fsRef;
|
|
nsresult rv = NS_ERROR_FAILURE;
|
|
|
|
err = ::FSFindFolder(aDomain, aFolderType, kCreateFolder, &fsRef);
|
|
if (err == noErr) {
|
|
NS_NewLocalFile(EmptyString(), true, aLocalFile);
|
|
nsCOMPtr<nsILocalFileMac> localMacFile(do_QueryInterface(*aLocalFile));
|
|
if (localMacFile) {
|
|
rv = localMacFile->InitWithFSRef(&fsRef);
|
|
}
|
|
}
|
|
return rv;
|
|
}
|
|
#endif
|
|
|