michael@0: /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include "SpecialSystemDirectory.h" michael@0: #include "nsString.h" michael@0: #include "nsDependentString.h" michael@0: #include "nsAutoPtr.h" michael@0: michael@0: #if defined(XP_WIN) michael@0: michael@0: #include michael@0: #include michael@0: #include michael@0: #include michael@0: #include michael@0: #include michael@0: #include michael@0: #include michael@0: #include michael@0: #include "mozilla/WindowsVersion.h" michael@0: michael@0: using mozilla::IsWin7OrLater; michael@0: michael@0: #elif defined(XP_UNIX) michael@0: michael@0: #include michael@0: #include michael@0: #include michael@0: #include michael@0: #include "prenv.h" michael@0: michael@0: #endif michael@0: michael@0: #if defined(VMS) michael@0: #include michael@0: #endif michael@0: michael@0: #ifndef MAXPATHLEN michael@0: #ifdef PATH_MAX michael@0: #define MAXPATHLEN PATH_MAX michael@0: #elif defined(MAX_PATH) michael@0: #define MAXPATHLEN MAX_PATH michael@0: #elif defined(_MAX_PATH) michael@0: #define MAXPATHLEN _MAX_PATH michael@0: #elif defined(CCHMAXPATH) michael@0: #define MAXPATHLEN CCHMAXPATH michael@0: #else michael@0: #define MAXPATHLEN 1024 michael@0: #endif michael@0: #endif michael@0: michael@0: #ifdef XP_WIN michael@0: typedef HRESULT (WINAPI* nsGetKnownFolderPath)(GUID& rfid, michael@0: DWORD dwFlags, michael@0: HANDLE hToken, michael@0: PWSTR *ppszPath); michael@0: michael@0: static nsGetKnownFolderPath gGetKnownFolderPath = nullptr; michael@0: #endif michael@0: michael@0: void StartupSpecialSystemDirectory() michael@0: { michael@0: #if defined (XP_WIN) michael@0: // SHGetKnownFolderPath is only available on Windows Vista michael@0: // so that we need to use GetProcAddress to get the pointer. michael@0: HMODULE hShell32DLLInst = GetModuleHandleW(L"shell32.dll"); michael@0: if(hShell32DLLInst) michael@0: { michael@0: gGetKnownFolderPath = (nsGetKnownFolderPath) michael@0: GetProcAddress(hShell32DLLInst, "SHGetKnownFolderPath"); michael@0: } michael@0: #endif michael@0: } michael@0: michael@0: #if defined (XP_WIN) michael@0: michael@0: static nsresult GetKnownFolder(GUID* guid, nsIFile** aFile) michael@0: { michael@0: if (!guid || !gGetKnownFolderPath) michael@0: return NS_ERROR_FAILURE; michael@0: michael@0: PWSTR path = nullptr; michael@0: gGetKnownFolderPath(*guid, 0, nullptr, &path); michael@0: michael@0: if (!path) michael@0: return NS_ERROR_FAILURE; michael@0: michael@0: nsresult rv = NS_NewLocalFile(nsDependentString(path), michael@0: true, michael@0: aFile); michael@0: michael@0: CoTaskMemFree(path); michael@0: return rv; michael@0: } michael@0: michael@0: static nsresult michael@0: GetWindowsFolder(int folder, nsIFile** aFile) michael@0: { michael@0: WCHAR path_orig[MAX_PATH + 3]; michael@0: WCHAR *path = path_orig+1; michael@0: HRESULT result = SHGetSpecialFolderPathW(nullptr, path, folder, true); michael@0: michael@0: if (!SUCCEEDED(result)) michael@0: return NS_ERROR_FAILURE; michael@0: michael@0: // Append the trailing slash michael@0: int len = wcslen(path); michael@0: if (len > 1 && path[len - 1] != L'\\') michael@0: { michael@0: path[len] = L'\\'; michael@0: path[++len] = L'\0'; michael@0: } michael@0: michael@0: return NS_NewLocalFile(nsDependentString(path, len), true, aFile); michael@0: } michael@0: michael@0: __inline HRESULT michael@0: SHLoadLibraryFromKnownFolder(REFKNOWNFOLDERID aFolderId, DWORD aMode, michael@0: REFIID riid, void **ppv) michael@0: { michael@0: *ppv = nullptr; michael@0: IShellLibrary *plib; michael@0: HRESULT hr = CoCreateInstance(CLSID_ShellLibrary, nullptr, michael@0: CLSCTX_INPROC_SERVER, michael@0: IID_PPV_ARGS(&plib)); michael@0: if (SUCCEEDED(hr)) { michael@0: hr = plib->LoadLibraryFromKnownFolder(aFolderId, aMode); michael@0: if (SUCCEEDED(hr)) { michael@0: hr = plib->QueryInterface(riid, ppv); michael@0: } michael@0: plib->Release(); michael@0: } michael@0: return hr; michael@0: } michael@0: michael@0: /* michael@0: * Check to see if we're on Win7 and up, and if so, returns the default michael@0: * save-to location for the Windows Library passed in through aFolderId. michael@0: * Otherwise falls back on pre-win7 GetWindowsFolder. michael@0: */ michael@0: static nsresult michael@0: GetLibrarySaveToPath(int aFallbackFolderId, REFKNOWNFOLDERID aFolderId, michael@0: nsIFile** aFile) michael@0: { michael@0: // Skip off checking for library support if the os is Vista or lower. michael@0: if (!IsWin7OrLater()) michael@0: return GetWindowsFolder(aFallbackFolderId, aFile); michael@0: michael@0: nsRefPtr shellLib; michael@0: nsRefPtr savePath; michael@0: HRESULT hr = michael@0: SHLoadLibraryFromKnownFolder(aFolderId, STGM_READ, michael@0: IID_IShellLibrary, getter_AddRefs(shellLib)); michael@0: michael@0: if (shellLib && michael@0: SUCCEEDED(shellLib->GetDefaultSaveFolder(DSFT_DETECT, IID_IShellItem, michael@0: getter_AddRefs(savePath)))) { michael@0: wchar_t* str = nullptr; michael@0: if (SUCCEEDED(savePath->GetDisplayName(SIGDN_FILESYSPATH, &str))) { michael@0: nsAutoString path; michael@0: path.Assign(str); michael@0: path.AppendLiteral("\\"); michael@0: nsresult rv = michael@0: NS_NewLocalFile(path, false, aFile); michael@0: CoTaskMemFree(str); michael@0: return rv; michael@0: } michael@0: } michael@0: michael@0: return GetWindowsFolder(aFallbackFolderId, aFile); michael@0: } michael@0: michael@0: /** michael@0: * Provides a fallback for getting the path to APPDATA or LOCALAPPDATA by michael@0: * querying the registry when the call to SHGetSpecialFolderPathW is unable to michael@0: * provide these paths (Bug 513958). michael@0: */ michael@0: static nsresult GetRegWindowsAppDataFolder(bool aLocal, nsIFile** aFile) michael@0: { michael@0: HKEY key; michael@0: NS_NAMED_LITERAL_STRING(keyName, michael@0: "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders"); michael@0: DWORD res = ::RegOpenKeyExW(HKEY_CURRENT_USER, keyName.get(), 0, KEY_READ, michael@0: &key); michael@0: if (res != ERROR_SUCCESS) michael@0: return NS_ERROR_FAILURE; michael@0: michael@0: WCHAR path[MAX_PATH + 2]; michael@0: DWORD type, size; michael@0: res = RegQueryValueExW(key, (aLocal ? L"Local AppData" : L"AppData"), michael@0: nullptr, &type, (LPBYTE)&path, &size); michael@0: ::RegCloseKey(key); michael@0: // The call to RegQueryValueExW must succeed, the type must be REG_SZ, the michael@0: // buffer size must not equal 0, and the buffer size be a multiple of 2. michael@0: if (res != ERROR_SUCCESS || type != REG_SZ || size == 0 || size % 2 != 0) michael@0: return NS_ERROR_FAILURE; michael@0: michael@0: // Append the trailing slash michael@0: int len = wcslen(path); michael@0: if (len > 1 && path[len - 1] != L'\\') michael@0: { michael@0: path[len] = L'\\'; michael@0: path[++len] = L'\0'; michael@0: } michael@0: michael@0: return NS_NewLocalFile(nsDependentString(path, len), true, aFile); michael@0: } michael@0: michael@0: #endif // XP_WIN michael@0: michael@0: #if defined(XP_UNIX) michael@0: static nsresult michael@0: GetUnixHomeDir(nsIFile** aFile) michael@0: { michael@0: #ifdef VMS michael@0: char *pHome; michael@0: pHome = getenv("HOME"); michael@0: if (*pHome == '/') { michael@0: return NS_NewNativeLocalFile(nsDependentCString(pHome), michael@0: true, michael@0: aFile); michael@0: } else { michael@0: return NS_NewNativeLocalFile(nsDependentCString(decc$translate_vms(pHome)), michael@0: true, michael@0: aFile); michael@0: } michael@0: #elif defined(ANDROID) michael@0: // XXX no home dir on android; maybe we should return the sdcard if present? michael@0: return NS_ERROR_FAILURE; michael@0: #else michael@0: return NS_NewNativeLocalFile(nsDependentCString(PR_GetEnv("HOME")), michael@0: true, aFile); michael@0: #endif michael@0: } michael@0: michael@0: /* michael@0: The following license applies to the xdg_user_dir_lookup function: michael@0: michael@0: Copyright (c) 2007 Red Hat, Inc. michael@0: michael@0: Permission is hereby granted, free of charge, to any person michael@0: obtaining a copy of this software and associated documentation files michael@0: (the "Software"), to deal in the Software without restriction, michael@0: including without limitation the rights to use, copy, modify, merge, michael@0: publish, distribute, sublicense, and/or sell copies of the Software, michael@0: and to permit persons to whom the Software is furnished to do so, michael@0: subject to the following conditions: michael@0: michael@0: The above copyright notice and this permission notice shall be michael@0: included in all copies or substantial portions of the Software. michael@0: michael@0: THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, michael@0: EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF michael@0: MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND michael@0: NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS michael@0: BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN michael@0: ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN michael@0: CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE michael@0: SOFTWARE. michael@0: */ michael@0: michael@0: static char * michael@0: xdg_user_dir_lookup (const char *type) michael@0: { michael@0: FILE *file; michael@0: char *home_dir, *config_home, *config_file; michael@0: char buffer[512]; michael@0: char *user_dir; michael@0: char *p, *d; michael@0: int len; michael@0: int relative; michael@0: michael@0: home_dir = getenv ("HOME"); michael@0: michael@0: if (home_dir == nullptr) michael@0: goto error; michael@0: michael@0: config_home = getenv ("XDG_CONFIG_HOME"); michael@0: if (config_home == nullptr || config_home[0] == 0) michael@0: { michael@0: config_file = (char*) malloc (strlen (home_dir) + strlen ("/.config/user-dirs.dirs") + 1); michael@0: if (config_file == nullptr) michael@0: goto error; michael@0: michael@0: strcpy (config_file, home_dir); michael@0: strcat (config_file, "/.config/user-dirs.dirs"); michael@0: } michael@0: else michael@0: { michael@0: config_file = (char*) malloc (strlen (config_home) + strlen ("/user-dirs.dirs") + 1); michael@0: if (config_file == nullptr) michael@0: goto error; michael@0: michael@0: strcpy (config_file, config_home); michael@0: strcat (config_file, "/user-dirs.dirs"); michael@0: } michael@0: michael@0: file = fopen (config_file, "r"); michael@0: free (config_file); michael@0: if (file == nullptr) michael@0: goto error; michael@0: michael@0: user_dir = nullptr; michael@0: while (fgets (buffer, sizeof (buffer), file)) michael@0: { michael@0: /* Remove newline at end */ michael@0: len = strlen (buffer); michael@0: if (len > 0 && buffer[len-1] == '\n') michael@0: buffer[len-1] = 0; michael@0: michael@0: p = buffer; michael@0: while (*p == ' ' || *p == '\t') michael@0: p++; michael@0: michael@0: if (strncmp (p, "XDG_", 4) != 0) michael@0: continue; michael@0: p += 4; michael@0: if (strncmp (p, type, strlen (type)) != 0) michael@0: continue; michael@0: p += strlen (type); michael@0: if (strncmp (p, "_DIR", 4) != 0) michael@0: continue; michael@0: p += 4; michael@0: michael@0: while (*p == ' ' || *p == '\t') michael@0: p++; michael@0: michael@0: if (*p != '=') michael@0: continue; michael@0: p++; michael@0: michael@0: while (*p == ' ' || *p == '\t') michael@0: p++; michael@0: michael@0: if (*p != '"') michael@0: continue; michael@0: p++; michael@0: michael@0: relative = 0; michael@0: if (strncmp (p, "$HOME/", 6) == 0) michael@0: { michael@0: p += 6; michael@0: relative = 1; michael@0: } michael@0: else if (*p != '/') michael@0: continue; michael@0: michael@0: if (relative) michael@0: { michael@0: user_dir = (char*) malloc (strlen (home_dir) + 1 + strlen (p) + 1); michael@0: if (user_dir == nullptr) michael@0: goto error2; michael@0: michael@0: strcpy (user_dir, home_dir); michael@0: strcat (user_dir, "/"); michael@0: } michael@0: else michael@0: { michael@0: user_dir = (char*) malloc (strlen (p) + 1); michael@0: if (user_dir == nullptr) michael@0: goto error2; michael@0: michael@0: *user_dir = 0; michael@0: } michael@0: michael@0: d = user_dir + strlen (user_dir); michael@0: while (*p && *p != '"') michael@0: { michael@0: if ((*p == '\\') && (*(p+1) != 0)) michael@0: p++; michael@0: *d++ = *p++; michael@0: } michael@0: *d = 0; michael@0: } michael@0: error2: michael@0: fclose (file); michael@0: michael@0: if (user_dir) michael@0: return user_dir; michael@0: michael@0: error: michael@0: return nullptr; michael@0: } michael@0: michael@0: static const char xdg_user_dirs[] = michael@0: "DESKTOP\0" michael@0: "DOCUMENTS\0" michael@0: "DOWNLOAD\0" michael@0: "MUSIC\0" michael@0: "PICTURES\0" michael@0: "PUBLICSHARE\0" michael@0: "TEMPLATES\0" michael@0: "VIDEOS"; michael@0: michael@0: static const uint8_t xdg_user_dir_offsets[] = { michael@0: 0, michael@0: 8, michael@0: 18, michael@0: 27, michael@0: 33, michael@0: 42, michael@0: 54, michael@0: 64 michael@0: }; michael@0: michael@0: static nsresult michael@0: GetUnixXDGUserDirectory(SystemDirectories aSystemDirectory, michael@0: nsIFile** aFile) michael@0: { michael@0: char *dir = xdg_user_dir_lookup michael@0: (xdg_user_dirs + xdg_user_dir_offsets[aSystemDirectory - michael@0: Unix_XDG_Desktop]); michael@0: michael@0: nsresult rv; michael@0: nsCOMPtr file; michael@0: if (dir) { michael@0: rv = NS_NewNativeLocalFile(nsDependentCString(dir), true, michael@0: getter_AddRefs(file)); michael@0: free(dir); michael@0: } else if (Unix_XDG_Desktop == aSystemDirectory) { michael@0: // for the XDG desktop dir, fall back to HOME/Desktop michael@0: // (for historical compatibility) michael@0: rv = GetUnixHomeDir(getter_AddRefs(file)); michael@0: if (NS_FAILED(rv)) michael@0: return rv; michael@0: michael@0: rv = file->AppendNative(NS_LITERAL_CSTRING("Desktop")); michael@0: } michael@0: else { michael@0: // no fallback for the other XDG dirs michael@0: rv = NS_ERROR_FAILURE; michael@0: } michael@0: michael@0: if (NS_FAILED(rv)) michael@0: return rv; michael@0: michael@0: bool exists; michael@0: rv = file->Exists(&exists); michael@0: if (NS_FAILED(rv)) michael@0: return rv; michael@0: if (!exists) { michael@0: rv = file->Create(nsIFile::DIRECTORY_TYPE, 0755); michael@0: if (NS_FAILED(rv)) michael@0: return rv; michael@0: } michael@0: michael@0: *aFile = nullptr; michael@0: file.swap(*aFile); michael@0: michael@0: return NS_OK; michael@0: } michael@0: #endif michael@0: michael@0: nsresult michael@0: GetSpecialSystemDirectory(SystemDirectories aSystemSystemDirectory, michael@0: nsIFile** aFile) michael@0: { michael@0: #if defined(XP_WIN) michael@0: WCHAR path[MAX_PATH]; michael@0: #else michael@0: char path[MAXPATHLEN]; michael@0: #endif michael@0: michael@0: switch (aSystemSystemDirectory) michael@0: { michael@0: case OS_CurrentWorkingDirectory: michael@0: #if defined(XP_WIN) michael@0: if (!_wgetcwd(path, MAX_PATH)) michael@0: return NS_ERROR_FAILURE; michael@0: return NS_NewLocalFile(nsDependentString(path), michael@0: true, michael@0: aFile); michael@0: #else michael@0: if(!getcwd(path, MAXPATHLEN)) michael@0: return NS_ERROR_FAILURE; michael@0: #endif michael@0: michael@0: #if !defined(XP_WIN) michael@0: return NS_NewNativeLocalFile(nsDependentCString(path), michael@0: true, michael@0: aFile); michael@0: #endif michael@0: michael@0: case OS_DriveDirectory: michael@0: #if defined (XP_WIN) michael@0: { michael@0: int32_t len = ::GetWindowsDirectoryW(path, MAX_PATH); michael@0: if (len == 0) michael@0: break; michael@0: if (path[1] == char16_t(':') && path[2] == char16_t('\\')) michael@0: path[3] = 0; michael@0: michael@0: return NS_NewLocalFile(nsDependentString(path), michael@0: true, michael@0: aFile); michael@0: } michael@0: #else michael@0: return NS_NewNativeLocalFile(nsDependentCString("/"), michael@0: true, michael@0: aFile); michael@0: michael@0: #endif michael@0: michael@0: case OS_TemporaryDirectory: michael@0: #if defined (XP_WIN) michael@0: { michael@0: DWORD len = ::GetTempPathW(MAX_PATH, path); michael@0: if (len == 0) michael@0: break; michael@0: return NS_NewLocalFile(nsDependentString(path, len), michael@0: true, michael@0: aFile); michael@0: } michael@0: #elif defined(MOZ_WIDGET_COCOA) michael@0: { michael@0: return GetOSXFolderType(kUserDomain, kTemporaryFolderType, aFile); michael@0: } michael@0: michael@0: #elif defined(XP_UNIX) michael@0: { michael@0: static const char *tPath = nullptr; michael@0: if (!tPath) { michael@0: tPath = PR_GetEnv("TMPDIR"); michael@0: if (!tPath || !*tPath) { michael@0: tPath = PR_GetEnv("TMP"); michael@0: if (!tPath || !*tPath) { michael@0: tPath = PR_GetEnv("TEMP"); michael@0: if (!tPath || !*tPath) { michael@0: tPath = "/tmp/"; michael@0: } michael@0: } michael@0: } michael@0: } michael@0: return NS_NewNativeLocalFile(nsDependentCString(tPath), michael@0: true, michael@0: aFile); michael@0: } michael@0: #else michael@0: break; michael@0: #endif michael@0: #if defined (XP_WIN) michael@0: case Win_SystemDirectory: michael@0: { michael@0: int32_t len = ::GetSystemDirectoryW(path, MAX_PATH); michael@0: michael@0: // Need enough space to add the trailing backslash michael@0: if (!len || len > MAX_PATH - 2) michael@0: break; michael@0: path[len] = L'\\'; michael@0: path[++len] = L'\0'; michael@0: michael@0: return NS_NewLocalFile(nsDependentString(path, len), michael@0: true, michael@0: aFile); michael@0: } michael@0: michael@0: case Win_WindowsDirectory: michael@0: { michael@0: int32_t len = ::GetWindowsDirectoryW(path, MAX_PATH); michael@0: michael@0: // Need enough space to add the trailing backslash michael@0: if (!len || len > MAX_PATH - 2) michael@0: break; michael@0: michael@0: path[len] = L'\\'; michael@0: path[++len] = L'\0'; michael@0: michael@0: return NS_NewLocalFile(nsDependentString(path, len), michael@0: true, michael@0: aFile); michael@0: } michael@0: michael@0: case Win_ProgramFiles: michael@0: { michael@0: return GetWindowsFolder(CSIDL_PROGRAM_FILES, aFile); michael@0: } michael@0: michael@0: case Win_HomeDirectory: michael@0: { michael@0: nsresult rv = GetWindowsFolder(CSIDL_PROFILE, aFile); michael@0: if (NS_SUCCEEDED(rv)) michael@0: return rv; michael@0: michael@0: int32_t len; michael@0: if ((len = ::GetEnvironmentVariableW(L"HOME", path, MAX_PATH)) > 0) michael@0: { michael@0: // Need enough space to add the trailing backslash michael@0: if (len > MAX_PATH - 2) michael@0: break; michael@0: michael@0: path[len] = L'\\'; michael@0: path[++len] = L'\0'; michael@0: michael@0: rv = NS_NewLocalFile(nsDependentString(path, len), michael@0: true, michael@0: aFile); michael@0: if (NS_SUCCEEDED(rv)) michael@0: return rv; michael@0: } michael@0: michael@0: len = ::GetEnvironmentVariableW(L"HOMEDRIVE", path, MAX_PATH); michael@0: if (0 < len && len < MAX_PATH) michael@0: { michael@0: WCHAR temp[MAX_PATH]; michael@0: DWORD len2 = ::GetEnvironmentVariableW(L"HOMEPATH", temp, MAX_PATH); michael@0: if (0 < len2 && len + len2 < MAX_PATH) michael@0: wcsncat(path, temp, len2); michael@0: michael@0: len = wcslen(path); michael@0: michael@0: // Need enough space to add the trailing backslash michael@0: if (len > MAX_PATH - 2) michael@0: break; michael@0: michael@0: path[len] = L'\\'; michael@0: path[++len] = L'\0'; michael@0: michael@0: return NS_NewLocalFile(nsDependentString(path, len), michael@0: true, michael@0: aFile); michael@0: } michael@0: } michael@0: case Win_Desktop: michael@0: { michael@0: return GetWindowsFolder(CSIDL_DESKTOP, aFile); michael@0: } michael@0: case Win_Programs: michael@0: { michael@0: return GetWindowsFolder(CSIDL_PROGRAMS, aFile); michael@0: } michael@0: michael@0: case Win_Downloads: michael@0: { michael@0: // Defined in KnownFolders.h. michael@0: GUID folderid_downloads = {0x374de290, 0x123f, 0x4565, {0x91, 0x64, michael@0: 0x39, 0xc4, 0x92, 0x5e, 0x46, 0x7b}}; michael@0: nsresult rv = GetKnownFolder(&folderid_downloads, aFile); michael@0: // On WinXP, there is no downloads folder, default michael@0: // to 'Desktop'. michael@0: if(NS_ERROR_FAILURE == rv) michael@0: { michael@0: rv = GetWindowsFolder(CSIDL_DESKTOP, aFile); michael@0: } michael@0: return rv; michael@0: } michael@0: michael@0: case Win_Controls: michael@0: { michael@0: return GetWindowsFolder(CSIDL_CONTROLS, aFile); michael@0: } michael@0: case Win_Printers: michael@0: { michael@0: return GetWindowsFolder(CSIDL_PRINTERS, aFile); michael@0: } michael@0: case Win_Personal: michael@0: { michael@0: return GetWindowsFolder(CSIDL_PERSONAL, aFile); michael@0: } michael@0: case Win_Favorites: michael@0: { michael@0: return GetWindowsFolder(CSIDL_FAVORITES, aFile); michael@0: } michael@0: case Win_Startup: michael@0: { michael@0: return GetWindowsFolder(CSIDL_STARTUP, aFile); michael@0: } michael@0: case Win_Recent: michael@0: { michael@0: return GetWindowsFolder(CSIDL_RECENT, aFile); michael@0: } michael@0: case Win_Sendto: michael@0: { michael@0: return GetWindowsFolder(CSIDL_SENDTO, aFile); michael@0: } michael@0: case Win_Bitbucket: michael@0: { michael@0: return GetWindowsFolder(CSIDL_BITBUCKET, aFile); michael@0: } michael@0: case Win_Startmenu: michael@0: { michael@0: return GetWindowsFolder(CSIDL_STARTMENU, aFile); michael@0: } michael@0: case Win_Desktopdirectory: michael@0: { michael@0: return GetWindowsFolder(CSIDL_DESKTOPDIRECTORY, aFile); michael@0: } michael@0: case Win_Drives: michael@0: { michael@0: return GetWindowsFolder(CSIDL_DRIVES, aFile); michael@0: } michael@0: case Win_Network: michael@0: { michael@0: return GetWindowsFolder(CSIDL_NETWORK, aFile); michael@0: } michael@0: case Win_Nethood: michael@0: { michael@0: return GetWindowsFolder(CSIDL_NETHOOD, aFile); michael@0: } michael@0: case Win_Fonts: michael@0: { michael@0: return GetWindowsFolder(CSIDL_FONTS, aFile); michael@0: } michael@0: case Win_Templates: michael@0: { michael@0: return GetWindowsFolder(CSIDL_TEMPLATES, aFile); michael@0: } michael@0: case Win_Common_Startmenu: michael@0: { michael@0: return GetWindowsFolder(CSIDL_COMMON_STARTMENU, aFile); michael@0: } michael@0: case Win_Common_Programs: michael@0: { michael@0: return GetWindowsFolder(CSIDL_COMMON_PROGRAMS, aFile); michael@0: } michael@0: case Win_Common_Startup: michael@0: { michael@0: return GetWindowsFolder(CSIDL_COMMON_STARTUP, aFile); michael@0: } michael@0: case Win_Common_Desktopdirectory: michael@0: { michael@0: return GetWindowsFolder(CSIDL_COMMON_DESKTOPDIRECTORY, aFile); michael@0: } michael@0: case Win_Common_AppData: michael@0: { michael@0: return GetWindowsFolder(CSIDL_COMMON_APPDATA, aFile); michael@0: } michael@0: case Win_Printhood: michael@0: { michael@0: return GetWindowsFolder(CSIDL_PRINTHOOD, aFile); michael@0: } michael@0: case Win_Cookies: michael@0: { michael@0: return GetWindowsFolder(CSIDL_COOKIES, aFile); michael@0: } michael@0: case Win_Appdata: michael@0: { michael@0: nsresult rv = GetWindowsFolder(CSIDL_APPDATA, aFile); michael@0: if (NS_FAILED(rv)) michael@0: rv = GetRegWindowsAppDataFolder(false, aFile); michael@0: return rv; michael@0: } michael@0: case Win_LocalAppdata: michael@0: { michael@0: nsresult rv = GetWindowsFolder(CSIDL_LOCAL_APPDATA, aFile); michael@0: if (NS_FAILED(rv)) michael@0: rv = GetRegWindowsAppDataFolder(true, aFile); michael@0: return rv; michael@0: } michael@0: case Win_Documents: michael@0: { michael@0: return GetLibrarySaveToPath(CSIDL_MYDOCUMENTS, michael@0: FOLDERID_DocumentsLibrary, michael@0: aFile); michael@0: } michael@0: case Win_Pictures: michael@0: { michael@0: return GetLibrarySaveToPath(CSIDL_MYPICTURES, michael@0: FOLDERID_PicturesLibrary, michael@0: aFile); michael@0: } michael@0: case Win_Music: michael@0: { michael@0: return GetLibrarySaveToPath(CSIDL_MYMUSIC, michael@0: FOLDERID_MusicLibrary, michael@0: aFile); michael@0: } michael@0: case Win_Videos: michael@0: { michael@0: return GetLibrarySaveToPath(CSIDL_MYVIDEO, michael@0: FOLDERID_VideosLibrary, michael@0: aFile); michael@0: } michael@0: #endif // XP_WIN michael@0: michael@0: #if defined(XP_UNIX) michael@0: case Unix_LocalDirectory: michael@0: return NS_NewNativeLocalFile(nsDependentCString("/usr/local/netscape/"), michael@0: true, michael@0: aFile); michael@0: case Unix_LibDirectory: michael@0: return NS_NewNativeLocalFile(nsDependentCString("/usr/local/lib/netscape/"), michael@0: true, michael@0: aFile); michael@0: michael@0: case Unix_HomeDirectory: michael@0: return GetUnixHomeDir(aFile); michael@0: michael@0: case Unix_XDG_Desktop: michael@0: case Unix_XDG_Documents: michael@0: case Unix_XDG_Download: michael@0: case Unix_XDG_Music: michael@0: case Unix_XDG_Pictures: michael@0: case Unix_XDG_PublicShare: michael@0: case Unix_XDG_Templates: michael@0: case Unix_XDG_Videos: michael@0: return GetUnixXDGUserDirectory(aSystemSystemDirectory, aFile); michael@0: #endif michael@0: michael@0: default: michael@0: break; michael@0: } michael@0: return NS_ERROR_NOT_AVAILABLE; michael@0: } michael@0: michael@0: #if defined (MOZ_WIDGET_COCOA) michael@0: nsresult michael@0: GetOSXFolderType(short aDomain, OSType aFolderType, nsIFile **localFile) michael@0: { michael@0: OSErr err; michael@0: FSRef fsRef; michael@0: nsresult rv = NS_ERROR_FAILURE; michael@0: michael@0: err = ::FSFindFolder(aDomain, aFolderType, kCreateFolder, &fsRef); michael@0: if (err == noErr) michael@0: { michael@0: NS_NewLocalFile(EmptyString(), true, localFile); michael@0: nsCOMPtr localMacFile(do_QueryInterface(*localFile)); michael@0: if (localMacFile) michael@0: rv = localMacFile->InitWithFSRef(&fsRef); michael@0: } michael@0: return rv; michael@0: } michael@0: #endif michael@0: