Line data Source code
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/. */
6 :
7 : #include "SpecialSystemDirectory.h"
8 : #include "nsString.h"
9 : #include "nsDependentString.h"
10 : #include "nsAutoPtr.h"
11 :
12 : #if defined(XP_WIN)
13 :
14 : #include <windows.h>
15 : #include <stdlib.h>
16 : #include <stdio.h>
17 : #include <string.h>
18 : #include <direct.h>
19 : #include <shlobj.h>
20 : #include <knownfolders.h>
21 : #include <guiddef.h>
22 :
23 : #elif defined(XP_UNIX)
24 :
25 : #include <limits.h>
26 : #include <unistd.h>
27 : #include <stdlib.h>
28 : #include <sys/param.h>
29 : #include "prenv.h"
30 : #if defined(MOZ_WIDGET_COCOA)
31 : #include "CocoaFileUtils.h"
32 : #endif
33 :
34 : #endif
35 :
36 : #ifndef MAXPATHLEN
37 : #ifdef PATH_MAX
38 : #define MAXPATHLEN PATH_MAX
39 : #elif defined(MAX_PATH)
40 : #define MAXPATHLEN MAX_PATH
41 : #elif defined(_MAX_PATH)
42 : #define MAXPATHLEN _MAX_PATH
43 : #elif defined(CCHMAXPATH)
44 : #define MAXPATHLEN CCHMAXPATH
45 : #else
46 : #define MAXPATHLEN 1024
47 : #endif
48 : #endif
49 :
50 : #if defined (XP_WIN)
51 :
52 : static nsresult
53 : GetKnownFolder(GUID* aGuid, nsIFile** aFile)
54 : {
55 : if (!aGuid) {
56 : return NS_ERROR_FAILURE;
57 : }
58 :
59 : PWSTR path = nullptr;
60 : SHGetKnownFolderPath(*aGuid, 0, nullptr, &path);
61 :
62 : if (!path) {
63 : return NS_ERROR_FAILURE;
64 : }
65 :
66 : nsresult rv = NS_NewLocalFile(nsDependentString(path),
67 : true,
68 : aFile);
69 :
70 : CoTaskMemFree(path);
71 : return rv;
72 : }
73 :
74 : static nsresult
75 : GetWindowsFolder(int aFolder, nsIFile** aFile)
76 : {
77 : WCHAR path_orig[MAX_PATH + 3];
78 : WCHAR* path = path_orig + 1;
79 : HRESULT result = SHGetSpecialFolderPathW(nullptr, path, aFolder, true);
80 :
81 : if (!SUCCEEDED(result)) {
82 : return NS_ERROR_FAILURE;
83 : }
84 :
85 : // Append the trailing slash
86 : int len = wcslen(path);
87 : if (len > 1 && path[len - 1] != L'\\') {
88 : path[len] = L'\\';
89 : path[++len] = L'\0';
90 : }
91 :
92 : return NS_NewLocalFile(nsDependentString(path, len), true, aFile);
93 : }
94 :
95 : #if WINVER < 0x0601
96 : __inline HRESULT
97 : SHLoadLibraryFromKnownFolder(REFKNOWNFOLDERID aFolderId, DWORD aMode,
98 : REFIID riid, void** ppv)
99 : {
100 : *ppv = nullptr;
101 : IShellLibrary* plib;
102 : HRESULT hr = CoCreateInstance(CLSID_ShellLibrary, nullptr,
103 : CLSCTX_INPROC_SERVER,
104 : IID_PPV_ARGS(&plib));
105 : if (SUCCEEDED(hr)) {
106 : hr = plib->LoadLibraryFromKnownFolder(aFolderId, aMode);
107 : if (SUCCEEDED(hr)) {
108 : hr = plib->QueryInterface(riid, ppv);
109 : }
110 : plib->Release();
111 : }
112 : return hr;
113 : }
114 : #endif
115 :
116 : /*
117 : * Return the default save-to location for the Windows Library passed in
118 : * through aFolderId.
119 : */
120 : static nsresult
121 : GetLibrarySaveToPath(int aFallbackFolderId, REFKNOWNFOLDERID aFolderId,
122 : nsIFile** aFile)
123 : {
124 : RefPtr<IShellLibrary> shellLib;
125 : RefPtr<IShellItem> savePath;
126 : HRESULT hr =
127 : SHLoadLibraryFromKnownFolder(aFolderId, STGM_READ,
128 : IID_IShellLibrary, getter_AddRefs(shellLib));
129 :
130 : if (shellLib &&
131 : SUCCEEDED(shellLib->GetDefaultSaveFolder(DSFT_DETECT, IID_IShellItem,
132 : getter_AddRefs(savePath)))) {
133 : wchar_t* str = nullptr;
134 : if (SUCCEEDED(savePath->GetDisplayName(SIGDN_FILESYSPATH, &str))) {
135 : nsAutoString path;
136 : path.Assign(str);
137 : path.Append('\\');
138 : nsresult rv =
139 : NS_NewLocalFile(path, false, aFile);
140 : CoTaskMemFree(str);
141 : return rv;
142 : }
143 : }
144 :
145 : return GetWindowsFolder(aFallbackFolderId, aFile);
146 : }
147 :
148 : /**
149 : * Provides a fallback for getting the path to APPDATA or LOCALAPPDATA by
150 : * querying the registry when the call to SHGetSpecialFolderPathW is unable to
151 : * provide these paths (Bug 513958).
152 : */
153 : static nsresult
154 : GetRegWindowsAppDataFolder(bool aLocal, nsIFile** aFile)
155 : {
156 : HKEY key;
157 : LPCWSTR keyName =
158 : L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders";
159 : DWORD res = ::RegOpenKeyExW(HKEY_CURRENT_USER, keyName, 0, KEY_READ,
160 : &key);
161 : if (res != ERROR_SUCCESS) {
162 : return NS_ERROR_FAILURE;
163 : }
164 :
165 : WCHAR path[MAX_PATH + 2];
166 : DWORD type, size;
167 : res = RegQueryValueExW(key, (aLocal ? L"Local AppData" : L"AppData"),
168 : nullptr, &type, (LPBYTE)&path, &size);
169 : ::RegCloseKey(key);
170 : // The call to RegQueryValueExW must succeed, the type must be REG_SZ, the
171 : // buffer size must not equal 0, and the buffer size be a multiple of 2.
172 : if (res != ERROR_SUCCESS || type != REG_SZ || size == 0 || size % 2 != 0) {
173 : return NS_ERROR_FAILURE;
174 : }
175 :
176 : // Append the trailing slash
177 : int len = wcslen(path);
178 : if (len > 1 && path[len - 1] != L'\\') {
179 : path[len] = L'\\';
180 : path[++len] = L'\0';
181 : }
182 :
183 : return NS_NewLocalFile(nsDependentString(path, len), true, aFile);
184 : }
185 :
186 : #endif // XP_WIN
187 :
188 : #if defined(XP_UNIX)
189 : static nsresult
190 1 : GetUnixHomeDir(nsIFile** aFile)
191 : {
192 : #if defined(ANDROID)
193 : // XXX no home dir on android; maybe we should return the sdcard if present?
194 : return NS_ERROR_FAILURE;
195 : #else
196 2 : return NS_NewNativeLocalFile(nsDependentCString(PR_GetEnv("HOME")),
197 2 : true, aFile);
198 : #endif
199 : }
200 :
201 : /*
202 : The following license applies to the xdg_user_dir_lookup function:
203 :
204 : Copyright (c) 2007 Red Hat, Inc.
205 :
206 : Permission is hereby granted, free of charge, to any person
207 : obtaining a copy of this software and associated documentation files
208 : (the "Software"), to deal in the Software without restriction,
209 : including without limitation the rights to use, copy, modify, merge,
210 : publish, distribute, sublicense, and/or sell copies of the Software,
211 : and to permit persons to whom the Software is furnished to do so,
212 : subject to the following conditions:
213 :
214 : The above copyright notice and this permission notice shall be
215 : included in all copies or substantial portions of the Software.
216 :
217 : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
218 : EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
219 : MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
220 : NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
221 : BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
222 : ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
223 : CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
224 : SOFTWARE.
225 : */
226 :
227 : static char*
228 1 : xdg_user_dir_lookup(const char* aType)
229 : {
230 : FILE* file;
231 : char* home_dir;
232 : char* config_home;
233 : char* config_file;
234 : char buffer[512];
235 : char* user_dir;
236 : char* p;
237 : char* d;
238 : int len;
239 : int relative;
240 :
241 1 : home_dir = getenv("HOME");
242 :
243 1 : if (!home_dir) {
244 0 : goto error;
245 : }
246 :
247 1 : config_home = getenv("XDG_CONFIG_HOME");
248 1 : if (!config_home || config_home[0] == 0) {
249 1 : config_file = (char*)malloc(strlen(home_dir) +
250 1 : strlen("/.config/user-dirs.dirs") + 1);
251 1 : if (!config_file) {
252 0 : goto error;
253 : }
254 :
255 1 : strcpy(config_file, home_dir);
256 1 : strcat(config_file, "/.config/user-dirs.dirs");
257 : } else {
258 0 : config_file = (char*)malloc(strlen(config_home) +
259 0 : strlen("/user-dirs.dirs") + 1);
260 0 : if (!config_file) {
261 0 : goto error;
262 : }
263 :
264 0 : strcpy(config_file, config_home);
265 0 : strcat(config_file, "/user-dirs.dirs");
266 : }
267 :
268 1 : file = fopen(config_file, "r");
269 1 : free(config_file);
270 1 : if (!file) {
271 0 : goto error;
272 : }
273 :
274 1 : user_dir = nullptr;
275 31 : while (fgets(buffer, sizeof(buffer), file)) {
276 : /* Remove newline at end */
277 15 : len = strlen(buffer);
278 15 : if (len > 0 && buffer[len - 1] == '\n') {
279 15 : buffer[len - 1] = 0;
280 : }
281 :
282 15 : p = buffer;
283 15 : while (*p == ' ' || *p == '\t') {
284 0 : p++;
285 : }
286 :
287 15 : if (strncmp(p, "XDG_", 4) != 0) {
288 7 : continue;
289 : }
290 8 : p += 4;
291 8 : if (strncmp(p, aType, strlen(aType)) != 0) {
292 7 : continue;
293 : }
294 1 : p += strlen(aType);
295 1 : if (strncmp(p, "_DIR", 4) != 0) {
296 0 : continue;
297 : }
298 1 : p += 4;
299 :
300 1 : while (*p == ' ' || *p == '\t') {
301 0 : p++;
302 : }
303 :
304 1 : if (*p != '=') {
305 0 : continue;
306 : }
307 1 : p++;
308 :
309 1 : while (*p == ' ' || *p == '\t') {
310 0 : p++;
311 : }
312 :
313 1 : if (*p != '"') {
314 0 : continue;
315 : }
316 1 : p++;
317 :
318 1 : relative = 0;
319 1 : if (strncmp(p, "$HOME/", 6) == 0) {
320 1 : p += 6;
321 1 : relative = 1;
322 0 : } else if (*p != '/') {
323 0 : continue;
324 : }
325 :
326 1 : if (relative) {
327 1 : user_dir = (char*)malloc(strlen(home_dir) + 1 + strlen(p) + 1);
328 1 : if (!user_dir) {
329 0 : goto error2;
330 : }
331 :
332 1 : strcpy(user_dir, home_dir);
333 1 : strcat(user_dir, "/");
334 : } else {
335 0 : user_dir = (char*)malloc(strlen(p) + 1);
336 0 : if (!user_dir) {
337 0 : goto error2;
338 : }
339 :
340 0 : *user_dir = 0;
341 : }
342 :
343 1 : d = user_dir + strlen(user_dir);
344 19 : while (*p && *p != '"') {
345 9 : if ((*p == '\\') && (*(p + 1) != 0)) {
346 0 : p++;
347 : }
348 9 : *d++ = *p++;
349 : }
350 1 : *d = 0;
351 : }
352 : error2:
353 1 : fclose(file);
354 :
355 1 : if (user_dir) {
356 1 : return user_dir;
357 : }
358 :
359 : error:
360 0 : return nullptr;
361 : }
362 :
363 : static const char xdg_user_dirs[] =
364 : "DESKTOP\0"
365 : "DOCUMENTS\0"
366 : "DOWNLOAD\0"
367 : "MUSIC\0"
368 : "PICTURES\0"
369 : "PUBLICSHARE\0"
370 : "TEMPLATES\0"
371 : "VIDEOS";
372 :
373 : static const uint8_t xdg_user_dir_offsets[] = {
374 : 0,
375 : 8,
376 : 18,
377 : 27,
378 : 33,
379 : 42,
380 : 54,
381 : 64
382 : };
383 :
384 : static nsresult
385 1 : GetUnixXDGUserDirectory(SystemDirectories aSystemDirectory,
386 : nsIFile** aFile)
387 : {
388 1 : char* dir = xdg_user_dir_lookup(
389 2 : xdg_user_dirs + xdg_user_dir_offsets[aSystemDirectory - Unix_XDG_Desktop]);
390 :
391 : nsresult rv;
392 2 : nsCOMPtr<nsIFile> file;
393 1 : if (dir) {
394 2 : rv = NS_NewNativeLocalFile(nsDependentCString(dir), true,
395 3 : getter_AddRefs(file));
396 1 : free(dir);
397 0 : } else if (Unix_XDG_Desktop == aSystemDirectory) {
398 : // for the XDG desktop dir, fall back to HOME/Desktop
399 : // (for historical compatibility)
400 0 : rv = GetUnixHomeDir(getter_AddRefs(file));
401 0 : if (NS_FAILED(rv)) {
402 0 : return rv;
403 : }
404 :
405 0 : rv = file->AppendNative(NS_LITERAL_CSTRING("Desktop"));
406 : } else {
407 : // no fallback for the other XDG dirs
408 0 : rv = NS_ERROR_FAILURE;
409 : }
410 :
411 1 : if (NS_FAILED(rv)) {
412 0 : return rv;
413 : }
414 :
415 : bool exists;
416 1 : rv = file->Exists(&exists);
417 1 : if (NS_FAILED(rv)) {
418 0 : return rv;
419 : }
420 1 : if (!exists) {
421 0 : rv = file->Create(nsIFile::DIRECTORY_TYPE, 0755);
422 0 : if (NS_FAILED(rv)) {
423 0 : return rv;
424 : }
425 : }
426 :
427 1 : *aFile = nullptr;
428 1 : file.swap(*aFile);
429 :
430 1 : return NS_OK;
431 : }
432 : #endif
433 :
434 : nsresult
435 4 : GetSpecialSystemDirectory(SystemDirectories aSystemSystemDirectory,
436 : nsIFile** aFile)
437 : {
438 : #if defined(XP_WIN)
439 : WCHAR path[MAX_PATH];
440 : #else
441 : char path[MAXPATHLEN];
442 : #endif
443 :
444 4 : switch (aSystemSystemDirectory) {
445 : case OS_CurrentWorkingDirectory:
446 : #if defined(XP_WIN)
447 : if (!_wgetcwd(path, MAX_PATH)) {
448 : return NS_ERROR_FAILURE;
449 : }
450 : return NS_NewLocalFile(nsDependentString(path),
451 : true,
452 : aFile);
453 : #else
454 1 : if (!getcwd(path, MAXPATHLEN)) {
455 0 : return NS_ERROR_FAILURE;
456 : }
457 : #endif
458 :
459 : #if !defined(XP_WIN)
460 2 : return NS_NewNativeLocalFile(nsDependentCString(path),
461 : true,
462 1 : aFile);
463 : #endif
464 :
465 : case OS_DriveDirectory:
466 : #if defined (XP_WIN)
467 : {
468 : int32_t len = ::GetWindowsDirectoryW(path, MAX_PATH);
469 : if (len == 0) {
470 : break;
471 : }
472 : if (path[1] == char16_t(':') && path[2] == char16_t('\\')) {
473 : path[3] = 0;
474 : }
475 :
476 : return NS_NewLocalFile(nsDependentString(path),
477 : true,
478 : aFile);
479 : }
480 : #else
481 0 : return NS_NewNativeLocalFile(nsDependentCString("/"),
482 : true,
483 0 : aFile);
484 :
485 : #endif
486 :
487 : case OS_TemporaryDirectory:
488 : #if defined (XP_WIN)
489 : {
490 : DWORD len = ::GetTempPathW(MAX_PATH, path);
491 : if (len == 0) {
492 : break;
493 : }
494 : return NS_NewLocalFile(nsDependentString(path, len),
495 : true,
496 : aFile);
497 : }
498 : #elif defined(MOZ_WIDGET_COCOA)
499 : {
500 : return GetOSXFolderType(kUserDomain, kTemporaryFolderType, aFile);
501 : }
502 :
503 : #elif defined(XP_UNIX)
504 : {
505 : static const char* tPath = nullptr;
506 1 : if (!tPath) {
507 1 : tPath = PR_GetEnv("TMPDIR");
508 1 : if (!tPath || !*tPath) {
509 1 : tPath = PR_GetEnv("TMP");
510 1 : if (!tPath || !*tPath) {
511 1 : tPath = PR_GetEnv("TEMP");
512 1 : if (!tPath || !*tPath) {
513 1 : tPath = "/tmp/";
514 : }
515 : }
516 : }
517 : }
518 2 : return NS_NewNativeLocalFile(nsDependentCString(tPath),
519 : true,
520 1 : aFile);
521 : }
522 : #else
523 : break;
524 : #endif
525 : #if defined (XP_WIN)
526 : case Win_SystemDirectory: {
527 : int32_t len = ::GetSystemDirectoryW(path, MAX_PATH);
528 :
529 : // Need enough space to add the trailing backslash
530 : if (!len || len > MAX_PATH - 2) {
531 : break;
532 : }
533 : path[len] = L'\\';
534 : path[++len] = L'\0';
535 :
536 : return NS_NewLocalFile(nsDependentString(path, len),
537 : true,
538 : aFile);
539 : }
540 :
541 : case Win_WindowsDirectory: {
542 : int32_t len = ::GetWindowsDirectoryW(path, MAX_PATH);
543 :
544 : // Need enough space to add the trailing backslash
545 : if (!len || len > MAX_PATH - 2) {
546 : break;
547 : }
548 :
549 : path[len] = L'\\';
550 : path[++len] = L'\0';
551 :
552 : return NS_NewLocalFile(nsDependentString(path, len),
553 : true,
554 : aFile);
555 : }
556 :
557 : case Win_ProgramFiles: {
558 : return GetWindowsFolder(CSIDL_PROGRAM_FILES, aFile);
559 : }
560 :
561 : case Win_HomeDirectory: {
562 : nsresult rv = GetWindowsFolder(CSIDL_PROFILE, aFile);
563 : if (NS_SUCCEEDED(rv)) {
564 : return rv;
565 : }
566 :
567 : int32_t len;
568 : if ((len = ::GetEnvironmentVariableW(L"HOME", path, MAX_PATH)) > 0) {
569 : // Need enough space to add the trailing backslash
570 : if (len > MAX_PATH - 2) {
571 : break;
572 : }
573 :
574 : path[len] = L'\\';
575 : path[++len] = L'\0';
576 :
577 : rv = NS_NewLocalFile(nsDependentString(path, len),
578 : true,
579 : aFile);
580 : if (NS_SUCCEEDED(rv)) {
581 : return rv;
582 : }
583 : }
584 :
585 : len = ::GetEnvironmentVariableW(L"HOMEDRIVE", path, MAX_PATH);
586 : if (0 < len && len < MAX_PATH) {
587 : WCHAR temp[MAX_PATH];
588 : DWORD len2 = ::GetEnvironmentVariableW(L"HOMEPATH", temp, MAX_PATH);
589 : if (0 < len2 && len + len2 < MAX_PATH) {
590 : wcsncat(path, temp, len2);
591 : }
592 :
593 : len = wcslen(path);
594 :
595 : // Need enough space to add the trailing backslash
596 : if (len > MAX_PATH - 2) {
597 : break;
598 : }
599 :
600 : path[len] = L'\\';
601 : path[++len] = L'\0';
602 :
603 : return NS_NewLocalFile(nsDependentString(path, len),
604 : true,
605 : aFile);
606 : }
607 : }
608 : case Win_Desktop: {
609 : return GetWindowsFolder(CSIDL_DESKTOP, aFile);
610 : }
611 : case Win_Programs: {
612 : return GetWindowsFolder(CSIDL_PROGRAMS, aFile);
613 : }
614 :
615 : case Win_Downloads: {
616 : // Defined in KnownFolders.h.
617 : GUID folderid_downloads = {
618 : 0x374de290, 0x123f, 0x4565,
619 : { 0x91, 0x64, 0x39, 0xc4, 0x92, 0x5e, 0x46, 0x7b }
620 : };
621 : nsresult rv = GetKnownFolder(&folderid_downloads, aFile);
622 : // On WinXP, there is no downloads folder, default
623 : // to 'Desktop'.
624 : if (NS_ERROR_FAILURE == rv) {
625 : rv = GetWindowsFolder(CSIDL_DESKTOP, aFile);
626 : }
627 : return rv;
628 : }
629 :
630 : case Win_Controls: {
631 : return GetWindowsFolder(CSIDL_CONTROLS, aFile);
632 : }
633 : case Win_Printers: {
634 : return GetWindowsFolder(CSIDL_PRINTERS, aFile);
635 : }
636 : case Win_Personal: {
637 : return GetWindowsFolder(CSIDL_PERSONAL, aFile);
638 : }
639 : case Win_Favorites: {
640 : return GetWindowsFolder(CSIDL_FAVORITES, aFile);
641 : }
642 : case Win_Startup: {
643 : return GetWindowsFolder(CSIDL_STARTUP, aFile);
644 : }
645 : case Win_Recent: {
646 : return GetWindowsFolder(CSIDL_RECENT, aFile);
647 : }
648 : case Win_Sendto: {
649 : return GetWindowsFolder(CSIDL_SENDTO, aFile);
650 : }
651 : case Win_Bitbucket: {
652 : return GetWindowsFolder(CSIDL_BITBUCKET, aFile);
653 : }
654 : case Win_Startmenu: {
655 : return GetWindowsFolder(CSIDL_STARTMENU, aFile);
656 : }
657 : case Win_Desktopdirectory: {
658 : return GetWindowsFolder(CSIDL_DESKTOPDIRECTORY, aFile);
659 : }
660 : case Win_Drives: {
661 : return GetWindowsFolder(CSIDL_DRIVES, aFile);
662 : }
663 : case Win_Network: {
664 : return GetWindowsFolder(CSIDL_NETWORK, aFile);
665 : }
666 : case Win_Nethood: {
667 : return GetWindowsFolder(CSIDL_NETHOOD, aFile);
668 : }
669 : case Win_Fonts: {
670 : return GetWindowsFolder(CSIDL_FONTS, aFile);
671 : }
672 : case Win_Templates: {
673 : return GetWindowsFolder(CSIDL_TEMPLATES, aFile);
674 : }
675 : case Win_Common_Startmenu: {
676 : return GetWindowsFolder(CSIDL_COMMON_STARTMENU, aFile);
677 : }
678 : case Win_Common_Programs: {
679 : return GetWindowsFolder(CSIDL_COMMON_PROGRAMS, aFile);
680 : }
681 : case Win_Common_Startup: {
682 : return GetWindowsFolder(CSIDL_COMMON_STARTUP, aFile);
683 : }
684 : case Win_Common_Desktopdirectory: {
685 : return GetWindowsFolder(CSIDL_COMMON_DESKTOPDIRECTORY, aFile);
686 : }
687 : case Win_Common_AppData: {
688 : return GetWindowsFolder(CSIDL_COMMON_APPDATA, aFile);
689 : }
690 : case Win_Printhood: {
691 : return GetWindowsFolder(CSIDL_PRINTHOOD, aFile);
692 : }
693 : case Win_Cookies: {
694 : return GetWindowsFolder(CSIDL_COOKIES, aFile);
695 : }
696 : case Win_Appdata: {
697 : nsresult rv = GetWindowsFolder(CSIDL_APPDATA, aFile);
698 : if (NS_FAILED(rv)) {
699 : rv = GetRegWindowsAppDataFolder(false, aFile);
700 : }
701 : return rv;
702 : }
703 : case Win_LocalAppdata: {
704 : nsresult rv = GetWindowsFolder(CSIDL_LOCAL_APPDATA, aFile);
705 : if (NS_FAILED(rv)) {
706 : rv = GetRegWindowsAppDataFolder(true, aFile);
707 : }
708 : return rv;
709 : }
710 : #if defined(MOZ_CONTENT_SANDBOX)
711 : case Win_LocalAppdataLow: {
712 : GUID localAppDataLowGuid = FOLDERID_LocalAppDataLow;
713 : return GetKnownFolder(&localAppDataLowGuid, aFile);
714 : }
715 : #endif
716 : case Win_Documents: {
717 : return GetLibrarySaveToPath(CSIDL_MYDOCUMENTS,
718 : FOLDERID_DocumentsLibrary,
719 : aFile);
720 : }
721 : case Win_Pictures: {
722 : return GetLibrarySaveToPath(CSIDL_MYPICTURES,
723 : FOLDERID_PicturesLibrary,
724 : aFile);
725 : }
726 : case Win_Music: {
727 : return GetLibrarySaveToPath(CSIDL_MYMUSIC,
728 : FOLDERID_MusicLibrary,
729 : aFile);
730 : }
731 : case Win_Videos: {
732 : return GetLibrarySaveToPath(CSIDL_MYVIDEO,
733 : FOLDERID_VideosLibrary,
734 : aFile);
735 : }
736 : #endif // XP_WIN
737 :
738 : #if defined(XP_UNIX)
739 : case Unix_LocalDirectory:
740 0 : return NS_NewNativeLocalFile(nsDependentCString("/usr/local/netscape/"),
741 : true,
742 0 : aFile);
743 : case Unix_LibDirectory:
744 0 : return NS_NewNativeLocalFile(nsDependentCString("/usr/local/lib/netscape/"),
745 : true,
746 0 : aFile);
747 :
748 : case Unix_HomeDirectory:
749 1 : return GetUnixHomeDir(aFile);
750 :
751 : case Unix_XDG_Desktop:
752 : case Unix_XDG_Documents:
753 : case Unix_XDG_Download:
754 : case Unix_XDG_Music:
755 : case Unix_XDG_Pictures:
756 : case Unix_XDG_PublicShare:
757 : case Unix_XDG_Templates:
758 : case Unix_XDG_Videos:
759 1 : return GetUnixXDGUserDirectory(aSystemSystemDirectory, aFile);
760 : #endif
761 :
762 : default:
763 0 : break;
764 : }
765 0 : return NS_ERROR_NOT_AVAILABLE;
766 : }
767 :
768 : #if defined (MOZ_WIDGET_COCOA)
769 : nsresult
770 : GetOSXFolderType(short aDomain, OSType aFolderType, nsIFile** aLocalFile)
771 : {
772 : nsresult rv = NS_ERROR_FAILURE;
773 :
774 : if (aFolderType == kTemporaryFolderType) {
775 : NS_NewLocalFile(EmptyString(), true, aLocalFile);
776 : nsCOMPtr<nsILocalFileMac> localMacFile(do_QueryInterface(*aLocalFile));
777 : if (localMacFile) {
778 : rv = localMacFile->InitWithCFURL(
779 : CocoaFileUtils::GetTemporaryFolderCFURLRef());
780 : }
781 : return rv;
782 : }
783 :
784 : OSErr err;
785 : FSRef fsRef;
786 : err = ::FSFindFolder(aDomain, aFolderType, kCreateFolder, &fsRef);
787 : if (err == noErr) {
788 : NS_NewLocalFile(EmptyString(), true, aLocalFile);
789 : nsCOMPtr<nsILocalFileMac> localMacFile(do_QueryInterface(*aLocalFile));
790 : if (localMacFile) {
791 : rv = localMacFile->InitWithFSRef(&fsRef);
792 : }
793 : }
794 : return rv;
795 : }
796 : #endif
797 :
|