Fix typo in 9b54bd30006c008b4a951331b273613d5bac3abf
[pm.git] / xpcom / io / SpecialSystemDirectory.cpp
blob8bad192d9647e9a67741c37ee7419c72b55d9a90
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "SpecialSystemDirectory.h"
8 #include "nsString.h"
9 #include "nsDependentString.h"
10 #include "nsAutoPtr.h"
12 #if defined(XP_WIN)
14 #include <windows.h>
15 #include <shlobj.h>
16 #include <stdlib.h>
17 #include <stdio.h>
18 #include <string.h>
19 #include <direct.h>
20 #include <shlobj.h>
21 #include <knownfolders.h>
22 #include <guiddef.h>
23 #include "mozilla/WindowsVersion.h"
25 using mozilla::IsWin7OrLater;
27 #elif defined(XP_UNIX)
29 #include <limits.h>
30 #include <unistd.h>
31 #include <stdlib.h>
32 #include <sys/param.h>
33 #include "prenv.h"
35 #endif
37 #if defined(VMS)
38 #include <unixlib.h>
39 #endif
41 #ifndef MAXPATHLEN
42 #ifdef PATH_MAX
43 #define MAXPATHLEN PATH_MAX
44 #elif defined(MAX_PATH)
45 #define MAXPATHLEN MAX_PATH
46 #elif defined(_MAX_PATH)
47 #define MAXPATHLEN _MAX_PATH
48 #elif defined(CCHMAXPATH)
49 #define MAXPATHLEN CCHMAXPATH
50 #else
51 #define MAXPATHLEN 1024
52 #endif
53 #endif
55 #ifdef XP_WIN
56 typedef HRESULT (WINAPI* nsGetKnownFolderPath)(GUID& rfid,
57 DWORD dwFlags,
58 HANDLE hToken,
59 PWSTR* ppszPath);
61 static nsGetKnownFolderPath gGetKnownFolderPath = nullptr;
62 #endif
64 void
65 StartupSpecialSystemDirectory()
67 #if defined (XP_WIN)
68 // SHGetKnownFolderPath is only available on Windows Vista
69 // so that we need to use GetProcAddress to get the pointer.
70 HMODULE hShell32DLLInst = GetModuleHandleW(L"shell32.dll");
71 if (hShell32DLLInst) {
72 gGetKnownFolderPath = (nsGetKnownFolderPath)
73 GetProcAddress(hShell32DLLInst, "SHGetKnownFolderPath");
75 #endif
78 #if defined (XP_WIN)
80 static nsresult
81 GetKnownFolder(GUID* aGuid, nsIFile** aFile)
83 if (!aGuid || !gGetKnownFolderPath) {
84 return NS_ERROR_FAILURE;
87 PWSTR path = nullptr;
88 gGetKnownFolderPath(*aGuid, 0, nullptr, &path);
90 if (!path) {
91 return NS_ERROR_FAILURE;
94 nsresult rv = NS_NewLocalFile(nsDependentString(path),
95 true,
96 aFile);
98 CoTaskMemFree(path);
99 return rv;
102 static nsresult
103 GetWindowsFolder(int aFolder, nsIFile** aFile)
105 WCHAR path_orig[MAX_PATH + 3];
106 WCHAR* path = path_orig + 1;
107 HRESULT result = SHGetSpecialFolderPathW(nullptr, path, aFolder, true);
109 if (!SUCCEEDED(result)) {
110 return NS_ERROR_FAILURE;
113 // Append the trailing slash
114 int len = wcslen(path);
115 if (len > 1 && path[len - 1] != L'\\') {
116 path[len] = L'\\';
117 path[++len] = L'\0';
120 return NS_NewLocalFile(nsDependentString(path, len), true, aFile);
123 __inline HRESULT
124 SHLoadLibraryFromKnownFolder(REFKNOWNFOLDERID aFolderId, DWORD aMode,
125 REFIID riid, void** ppv)
127 *ppv = nullptr;
128 IShellLibrary* plib;
129 HRESULT hr = CoCreateInstance(CLSID_ShellLibrary, nullptr,
130 CLSCTX_INPROC_SERVER,
131 IID_PPV_ARGS(&plib));
132 if (SUCCEEDED(hr)) {
133 hr = plib->LoadLibraryFromKnownFolder(aFolderId, aMode);
134 if (SUCCEEDED(hr)) {
135 hr = plib->QueryInterface(riid, ppv);
137 plib->Release();
139 return hr;
143 * Check to see if we're on Win7 and up, and if so, returns the default
144 * save-to location for the Windows Library passed in through aFolderId.
145 * Otherwise falls back on pre-win7 GetWindowsFolder.
147 static nsresult
148 GetLibrarySaveToPath(int aFallbackFolderId, REFKNOWNFOLDERID aFolderId,
149 nsIFile** aFile)
151 // Skip off checking for library support if the os is Vista or lower.
152 if (!IsWin7OrLater()) {
153 return GetWindowsFolder(aFallbackFolderId, aFile);
156 nsRefPtr<IShellLibrary> shellLib;
157 nsRefPtr<IShellItem> savePath;
158 HRESULT hr =
159 SHLoadLibraryFromKnownFolder(aFolderId, STGM_READ,
160 IID_IShellLibrary, getter_AddRefs(shellLib));
162 if (shellLib &&
163 SUCCEEDED(shellLib->GetDefaultSaveFolder(DSFT_DETECT, IID_IShellItem,
164 getter_AddRefs(savePath)))) {
165 wchar_t* str = nullptr;
166 if (SUCCEEDED(savePath->GetDisplayName(SIGDN_FILESYSPATH, &str))) {
167 nsAutoString path;
168 path.Assign(str);
169 path.Append('\\');
170 nsresult rv =
171 NS_NewLocalFile(path, false, aFile);
172 CoTaskMemFree(str);
173 return rv;
177 return GetWindowsFolder(aFallbackFolderId, aFile);
181 * Provides a fallback for getting the path to APPDATA or LOCALAPPDATA by
182 * querying the registry when the call to SHGetSpecialFolderPathW is unable to
183 * provide these paths (Bug 513958).
185 static nsresult
186 GetRegWindowsAppDataFolder(bool aLocal, nsIFile** aFile)
188 HKEY key;
189 NS_NAMED_LITERAL_STRING(keyName,
190 "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders");
191 DWORD res = ::RegOpenKeyExW(HKEY_CURRENT_USER, keyName.get(), 0, KEY_READ,
192 &key);
193 if (res != ERROR_SUCCESS) {
194 return NS_ERROR_FAILURE;
197 WCHAR path[MAX_PATH + 2];
198 DWORD type, size;
199 res = RegQueryValueExW(key, (aLocal ? L"Local AppData" : L"AppData"),
200 nullptr, &type, (LPBYTE)&path, &size);
201 ::RegCloseKey(key);
202 // The call to RegQueryValueExW must succeed, the type must be REG_SZ, the
203 // buffer size must not equal 0, and the buffer size be a multiple of 2.
204 if (res != ERROR_SUCCESS || type != REG_SZ || size == 0 || size % 2 != 0) {
205 return NS_ERROR_FAILURE;
208 // Append the trailing slash
209 int len = wcslen(path);
210 if (len > 1 && path[len - 1] != L'\\') {
211 path[len] = L'\\';
212 path[++len] = L'\0';
215 return NS_NewLocalFile(nsDependentString(path, len), true, aFile);
218 #endif // XP_WIN
220 #if defined(XP_UNIX)
221 static nsresult
222 GetUnixHomeDir(nsIFile** aFile)
224 #ifdef VMS
225 char* pHome;
226 pHome = getenv("HOME");
227 if (*pHome == '/') {
228 return NS_NewNativeLocalFile(nsDependentCString(pHome),
229 true,
230 aFile);
231 } else {
232 return NS_NewNativeLocalFile(nsDependentCString(decc$translate_vms(pHome)),
233 true,
234 aFile);
236 #elif defined(ANDROID)
237 // XXX no home dir on android; maybe we should return the sdcard if present?
238 return NS_ERROR_FAILURE;
239 #else
240 return NS_NewNativeLocalFile(nsDependentCString(PR_GetEnv("HOME")),
241 true, aFile);
242 #endif
246 The following license applies to the xdg_user_dir_lookup function:
248 Copyright (c) 2007 Red Hat, Inc.
250 Permission is hereby granted, free of charge, to any person
251 obtaining a copy of this software and associated documentation files
252 (the "Software"), to deal in the Software without restriction,
253 including without limitation the rights to use, copy, modify, merge,
254 publish, distribute, sublicense, and/or sell copies of the Software,
255 and to permit persons to whom the Software is furnished to do so,
256 subject to the following conditions:
258 The above copyright notice and this permission notice shall be
259 included in all copies or substantial portions of the Software.
261 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
262 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
263 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
264 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
265 BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
266 ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
267 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
268 SOFTWARE.
271 static char*
272 xdg_user_dir_lookup(const char* aType)
274 FILE* file;
275 char* home_dir;
276 char* config_home;
277 char* config_file;
278 char buffer[512];
279 char* user_dir;
280 char* p;
281 char* d;
282 int len;
283 int relative;
285 home_dir = getenv("HOME");
287 if (!home_dir) {
288 goto error;
291 config_home = getenv("XDG_CONFIG_HOME");
292 if (!config_home || config_home[0] == 0) {
293 config_file = (char*)malloc(strlen(home_dir) +
294 strlen("/.config/user-dirs.dirs") + 1);
295 if (!config_file) {
296 goto error;
299 strcpy(config_file, home_dir);
300 strcat(config_file, "/.config/user-dirs.dirs");
301 } else {
302 config_file = (char*)malloc(strlen(config_home) +
303 strlen("/user-dirs.dirs") + 1);
304 if (!config_file) {
305 goto error;
308 strcpy(config_file, config_home);
309 strcat(config_file, "/user-dirs.dirs");
312 file = fopen(config_file, "r");
313 free(config_file);
314 if (!file) {
315 goto error;
318 user_dir = nullptr;
319 while (fgets(buffer, sizeof(buffer), file)) {
320 /* Remove newline at end */
321 len = strlen(buffer);
322 if (len > 0 && buffer[len - 1] == '\n') {
323 buffer[len - 1] = 0;
326 p = buffer;
327 while (*p == ' ' || *p == '\t') {
328 p++;
331 if (strncmp(p, "XDG_", 4) != 0) {
332 continue;
334 p += 4;
335 if (strncmp(p, aType, strlen(aType)) != 0) {
336 continue;
338 p += strlen(aType);
339 if (strncmp(p, "_DIR", 4) != 0) {
340 continue;
342 p += 4;
344 while (*p == ' ' || *p == '\t') {
345 p++;
348 if (*p != '=') {
349 continue;
351 p++;
353 while (*p == ' ' || *p == '\t') {
354 p++;
357 if (*p != '"') {
358 continue;
360 p++;
362 relative = 0;
363 if (strncmp(p, "$HOME/", 6) == 0) {
364 p += 6;
365 relative = 1;
366 } else if (*p != '/') {
367 continue;
370 if (relative) {
371 user_dir = (char*)malloc(strlen(home_dir) + 1 + strlen(p) + 1);
372 if (!user_dir) {
373 goto error2;
376 strcpy(user_dir, home_dir);
377 strcat(user_dir, "/");
378 } else {
379 user_dir = (char*)malloc(strlen(p) + 1);
380 if (!user_dir) {
381 goto error2;
384 *user_dir = 0;
387 d = user_dir + strlen(user_dir);
388 while (*p && *p != '"') {
389 if ((*p == '\\') && (*(p + 1) != 0)) {
390 p++;
392 *d++ = *p++;
394 *d = 0;
396 error2:
397 fclose(file);
399 if (user_dir) {
400 return user_dir;
403 error:
404 return nullptr;
407 static const char xdg_user_dirs[] =
408 "DESKTOP\0"
409 "DOCUMENTS\0"
410 "DOWNLOAD\0"
411 "MUSIC\0"
412 "PICTURES\0"
413 "PUBLICSHARE\0"
414 "TEMPLATES\0"
415 "VIDEOS";
417 static const uint8_t xdg_user_dir_offsets[] = {
428 static nsresult
429 GetUnixXDGUserDirectory(SystemDirectories aSystemDirectory,
430 nsIFile** aFile)
432 char* dir = xdg_user_dir_lookup(
433 xdg_user_dirs + xdg_user_dir_offsets[aSystemDirectory - Unix_XDG_Desktop]);
435 nsresult rv;
436 nsCOMPtr<nsIFile> file;
437 if (dir) {
438 rv = NS_NewNativeLocalFile(nsDependentCString(dir), true,
439 getter_AddRefs(file));
440 free(dir);
441 } else if (Unix_XDG_Desktop == aSystemDirectory) {
442 // for the XDG desktop dir, fall back to HOME/Desktop
443 // (for historical compatibility)
444 rv = GetUnixHomeDir(getter_AddRefs(file));
445 if (NS_FAILED(rv)) {
446 return rv;
449 rv = file->AppendNative(NS_LITERAL_CSTRING("Desktop"));
450 } else {
451 // no fallback for the other XDG dirs
452 rv = NS_ERROR_FAILURE;
455 if (NS_FAILED(rv)) {
456 return rv;
459 bool exists;
460 rv = file->Exists(&exists);
461 if (NS_FAILED(rv)) {
462 return rv;
464 if (!exists) {
465 rv = file->Create(nsIFile::DIRECTORY_TYPE, 0755);
466 if (NS_FAILED(rv)) {
467 return rv;
471 *aFile = nullptr;
472 file.swap(*aFile);
474 return NS_OK;
476 #endif
478 nsresult
479 GetSpecialSystemDirectory(SystemDirectories aSystemSystemDirectory,
480 nsIFile** aFile)
482 #if defined(XP_WIN)
483 WCHAR path[MAX_PATH];
484 #else
485 char path[MAXPATHLEN];
486 #endif
488 switch (aSystemSystemDirectory) {
489 case OS_CurrentWorkingDirectory:
490 #if defined(XP_WIN)
491 if (!_wgetcwd(path, MAX_PATH)) {
492 return NS_ERROR_FAILURE;
494 return NS_NewLocalFile(nsDependentString(path),
495 true,
496 aFile);
497 #else
498 if (!getcwd(path, MAXPATHLEN)) {
499 return NS_ERROR_FAILURE;
501 #endif
503 #if !defined(XP_WIN)
504 return NS_NewNativeLocalFile(nsDependentCString(path),
505 true,
506 aFile);
507 #endif
509 case OS_DriveDirectory:
510 #if defined (XP_WIN)
512 int32_t len = ::GetWindowsDirectoryW(path, MAX_PATH);
513 if (len == 0) {
514 break;
516 if (path[1] == char16_t(':') && path[2] == char16_t('\\')) {
517 path[3] = 0;
520 return NS_NewLocalFile(nsDependentString(path),
521 true,
522 aFile);
524 #else
525 return NS_NewNativeLocalFile(nsDependentCString("/"),
526 true,
527 aFile);
529 #endif
531 case OS_TemporaryDirectory:
532 #if defined (XP_WIN)
534 DWORD len = ::GetTempPathW(MAX_PATH, path);
535 if (len == 0) {
536 break;
538 return NS_NewLocalFile(nsDependentString(path, len),
539 true,
540 aFile);
542 #elif defined(MOZ_WIDGET_COCOA)
544 return GetOSXFolderType(kUserDomain, kTemporaryFolderType, aFile);
547 #elif defined(XP_UNIX)
549 static const char* tPath = nullptr;
550 if (!tPath) {
551 tPath = PR_GetEnv("TMPDIR");
552 if (!tPath || !*tPath) {
553 tPath = PR_GetEnv("TMP");
554 if (!tPath || !*tPath) {
555 tPath = PR_GetEnv("TEMP");
556 if (!tPath || !*tPath) {
557 tPath = "/tmp/";
562 return NS_NewNativeLocalFile(nsDependentCString(tPath),
563 true,
564 aFile);
566 #else
567 break;
568 #endif
569 #if defined (XP_WIN)
570 case Win_SystemDirectory: {
571 int32_t len = ::GetSystemDirectoryW(path, MAX_PATH);
573 // Need enough space to add the trailing backslash
574 if (!len || len > MAX_PATH - 2) {
575 break;
577 path[len] = L'\\';
578 path[++len] = L'\0';
580 return NS_NewLocalFile(nsDependentString(path, len),
581 true,
582 aFile);
585 case Win_WindowsDirectory: {
586 int32_t len = ::GetWindowsDirectoryW(path, MAX_PATH);
588 // Need enough space to add the trailing backslash
589 if (!len || len > MAX_PATH - 2) {
590 break;
593 path[len] = L'\\';
594 path[++len] = L'\0';
596 return NS_NewLocalFile(nsDependentString(path, len),
597 true,
598 aFile);
601 case Win_ProgramFiles: {
602 return GetWindowsFolder(CSIDL_PROGRAM_FILES, aFile);
605 case Win_HomeDirectory: {
606 nsresult rv = GetWindowsFolder(CSIDL_PROFILE, aFile);
607 if (NS_SUCCEEDED(rv)) {
608 return rv;
611 int32_t len;
612 if ((len = ::GetEnvironmentVariableW(L"HOME", path, MAX_PATH)) > 0) {
613 // Need enough space to add the trailing backslash
614 if (len > MAX_PATH - 2) {
615 break;
618 path[len] = L'\\';
619 path[++len] = L'\0';
621 rv = NS_NewLocalFile(nsDependentString(path, len),
622 true,
623 aFile);
624 if (NS_SUCCEEDED(rv)) {
625 return rv;
629 len = ::GetEnvironmentVariableW(L"HOMEDRIVE", path, MAX_PATH);
630 if (0 < len && len < MAX_PATH) {
631 WCHAR temp[MAX_PATH];
632 DWORD len2 = ::GetEnvironmentVariableW(L"HOMEPATH", temp, MAX_PATH);
633 if (0 < len2 && len + len2 < MAX_PATH) {
634 wcsncat(path, temp, len2);
637 len = wcslen(path);
639 // Need enough space to add the trailing backslash
640 if (len > MAX_PATH - 2) {
641 break;
644 path[len] = L'\\';
645 path[++len] = L'\0';
647 return NS_NewLocalFile(nsDependentString(path, len),
648 true,
649 aFile);
652 case Win_Desktop: {
653 return GetWindowsFolder(CSIDL_DESKTOP, aFile);
655 case Win_Programs: {
656 return GetWindowsFolder(CSIDL_PROGRAMS, aFile);
659 case Win_Downloads: {
660 // Defined in KnownFolders.h.
661 GUID folderid_downloads = {
662 0x374de290, 0x123f, 0x4565,
663 { 0x91, 0x64, 0x39, 0xc4, 0x92, 0x5e, 0x46, 0x7b }
665 nsresult rv = GetKnownFolder(&folderid_downloads, aFile);
666 // On WinXP, there is no downloads folder, default
667 // to 'Desktop'.
668 if (NS_ERROR_FAILURE == rv) {
669 rv = GetWindowsFolder(CSIDL_DESKTOP, aFile);
671 return rv;
674 case Win_Controls: {
675 return GetWindowsFolder(CSIDL_CONTROLS, aFile);
677 case Win_Printers: {
678 return GetWindowsFolder(CSIDL_PRINTERS, aFile);
680 case Win_Personal: {
681 return GetWindowsFolder(CSIDL_PERSONAL, aFile);
683 case Win_Favorites: {
684 return GetWindowsFolder(CSIDL_FAVORITES, aFile);
686 case Win_Startup: {
687 return GetWindowsFolder(CSIDL_STARTUP, aFile);
689 case Win_Recent: {
690 return GetWindowsFolder(CSIDL_RECENT, aFile);
692 case Win_Sendto: {
693 return GetWindowsFolder(CSIDL_SENDTO, aFile);
695 case Win_Bitbucket: {
696 return GetWindowsFolder(CSIDL_BITBUCKET, aFile);
698 case Win_Startmenu: {
699 return GetWindowsFolder(CSIDL_STARTMENU, aFile);
701 case Win_Desktopdirectory: {
702 return GetWindowsFolder(CSIDL_DESKTOPDIRECTORY, aFile);
704 case Win_Drives: {
705 return GetWindowsFolder(CSIDL_DRIVES, aFile);
707 case Win_Network: {
708 return GetWindowsFolder(CSIDL_NETWORK, aFile);
710 case Win_Nethood: {
711 return GetWindowsFolder(CSIDL_NETHOOD, aFile);
713 case Win_Fonts: {
714 return GetWindowsFolder(CSIDL_FONTS, aFile);
716 case Win_Templates: {
717 return GetWindowsFolder(CSIDL_TEMPLATES, aFile);
719 case Win_Common_Startmenu: {
720 return GetWindowsFolder(CSIDL_COMMON_STARTMENU, aFile);
722 case Win_Common_Programs: {
723 return GetWindowsFolder(CSIDL_COMMON_PROGRAMS, aFile);
725 case Win_Common_Startup: {
726 return GetWindowsFolder(CSIDL_COMMON_STARTUP, aFile);
728 case Win_Common_Desktopdirectory: {
729 return GetWindowsFolder(CSIDL_COMMON_DESKTOPDIRECTORY, aFile);
731 case Win_Common_AppData: {
732 return GetWindowsFolder(CSIDL_COMMON_APPDATA, aFile);
734 case Win_Printhood: {
735 return GetWindowsFolder(CSIDL_PRINTHOOD, aFile);
737 case Win_Cookies: {
738 return GetWindowsFolder(CSIDL_COOKIES, aFile);
740 case Win_Appdata: {
741 nsresult rv = GetWindowsFolder(CSIDL_APPDATA, aFile);
742 if (NS_FAILED(rv)) {
743 rv = GetRegWindowsAppDataFolder(false, aFile);
745 return rv;
747 case Win_LocalAppdata: {
748 nsresult rv = GetWindowsFolder(CSIDL_LOCAL_APPDATA, aFile);
749 if (NS_FAILED(rv)) {
750 rv = GetRegWindowsAppDataFolder(true, aFile);
752 return rv;
754 #if defined(MOZ_CONTENT_SANDBOX)
755 case Win_LocalAppdataLow: {
756 // This should only really fail on versions pre-Vista, in which case this
757 // shouldn't have been used in the first place.
758 GUID localAppDataLowGuid = FOLDERID_LocalAppDataLow;
759 return GetKnownFolder(&localAppDataLowGuid, aFile);
761 #endif
762 case Win_Documents: {
763 return GetLibrarySaveToPath(CSIDL_MYDOCUMENTS,
764 FOLDERID_DocumentsLibrary,
765 aFile);
767 case Win_Pictures: {
768 return GetLibrarySaveToPath(CSIDL_MYPICTURES,
769 FOLDERID_PicturesLibrary,
770 aFile);
772 case Win_Music: {
773 return GetLibrarySaveToPath(CSIDL_MYMUSIC,
774 FOLDERID_MusicLibrary,
775 aFile);
777 case Win_Videos: {
778 return GetLibrarySaveToPath(CSIDL_MYVIDEO,
779 FOLDERID_VideosLibrary,
780 aFile);
782 #endif // XP_WIN
784 #if defined(XP_UNIX)
785 case Unix_LocalDirectory:
786 return NS_NewNativeLocalFile(nsDependentCString("/usr/local/netscape/"),
787 true,
788 aFile);
789 case Unix_LibDirectory:
790 return NS_NewNativeLocalFile(nsDependentCString("/usr/local/lib/netscape/"),
791 true,
792 aFile);
794 case Unix_HomeDirectory:
795 return GetUnixHomeDir(aFile);
797 case Unix_XDG_Desktop:
798 case Unix_XDG_Documents:
799 case Unix_XDG_Download:
800 case Unix_XDG_Music:
801 case Unix_XDG_Pictures:
802 case Unix_XDG_PublicShare:
803 case Unix_XDG_Templates:
804 case Unix_XDG_Videos:
805 return GetUnixXDGUserDirectory(aSystemSystemDirectory, aFile);
806 #endif
808 default:
809 break;
811 return NS_ERROR_NOT_AVAILABLE;
814 #if defined (MOZ_WIDGET_COCOA)
815 nsresult
816 GetOSXFolderType(short aDomain, OSType aFolderType, nsIFile** aLocalFile)
818 OSErr err;
819 FSRef fsRef;
820 nsresult rv = NS_ERROR_FAILURE;
822 err = ::FSFindFolder(aDomain, aFolderType, kCreateFolder, &fsRef);
823 if (err == noErr) {
824 NS_NewLocalFile(EmptyString(), true, aLocalFile);
825 nsCOMPtr<nsILocalFileMac> localMacFile(do_QueryInterface(*aLocalFile));
826 if (localMacFile) {
827 rv = localMacFile->InitWithFSRef(&fsRef);
830 return rv;
832 #endif