1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /* ***** BEGIN LICENSE BLOCK *****
3 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 : *
5 : * The contents of this file are subject to the Mozilla Public License Version
6 : * 1.1 (the "License"); you may not use this file except in compliance with
7 : * the License. You may obtain a copy of the License at
8 : * http://www.mozilla.org/MPL/
9 : *
10 : * Software distributed under the License is distributed on an "AS IS" basis,
11 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 : * for the specific language governing rights and limitations under the
13 : * License.
14 : *
15 : * The Original Code is Mozilla Communicator client code, released
16 : * March 31, 1998.
17 : *
18 : * The Initial Developer of the Original Code is
19 : * Netscape Communications Corporation.
20 : * Portions created by the Initial Developer are Copyright (C) 1998
21 : * the Initial Developer. All Rights Reserved.
22 : *
23 : * Contributor(s):
24 : * Doug Turner <dougt@netscape.com>
25 : * IBM Corp.
26 : * Fredrik Holmqvist <thesuckiestemail@yahoo.se>
27 : * Jungshik Shin <jshin@i18nl10n.com>
28 : *
29 : * Alternatively, the contents of this file may be used under the terms of
30 : * either of the GNU General Public License Version 2 or later (the "GPL"),
31 : * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
32 : * in which case the provisions of the GPL or the LGPL are applicable instead
33 : * of those above. If you wish to allow use of your version of this file only
34 : * under the terms of either the GPL or the LGPL, and not to allow others to
35 : * use your version of this file under the terms of the MPL, indicate your
36 : * decision by deleting the provisions above and replace them with the notice
37 : * and other provisions required by the GPL or the LGPL. If you do not delete
38 : * the provisions above, a recipient may use your version of this file under
39 : * the terms of any one of the MPL, the GPL or the LGPL.
40 : *
41 : * ***** END LICENSE BLOCK ***** */
42 :
43 : #include "SpecialSystemDirectory.h"
44 : #include "nsString.h"
45 : #include "nsDependentString.h"
46 :
47 : #if defined(XP_WIN)
48 :
49 : #include <windows.h>
50 : #include <shlobj.h>
51 : #include <stdlib.h>
52 : #include <stdio.h>
53 : #include <string.h>
54 : #include <direct.h>
55 :
56 : #elif defined(XP_OS2)
57 :
58 : #define MAX_PATH _MAX_PATH
59 : #define INCL_WINWORKPLACE
60 : #define INCL_DOSMISC
61 : #define INCL_DOSMODULEMGR
62 : #define INCL_DOSPROCESS
63 : #define INCL_WINSHELLDATA
64 : #include <os2.h>
65 : #include <stdlib.h>
66 : #include <stdio.h>
67 : #include "prenv.h"
68 :
69 : #elif defined(XP_UNIX)
70 :
71 : #include <limits.h>
72 : #include <unistd.h>
73 : #include <stdlib.h>
74 : #include <sys/param.h>
75 : #include "prenv.h"
76 :
77 : #endif
78 :
79 : #if defined(VMS)
80 : #include <unixlib.h>
81 : #endif
82 :
83 : #ifndef MAXPATHLEN
84 : #ifdef PATH_MAX
85 : #define MAXPATHLEN PATH_MAX
86 : #elif defined(MAX_PATH)
87 : #define MAXPATHLEN MAX_PATH
88 : #elif defined(_MAX_PATH)
89 : #define MAXPATHLEN _MAX_PATH
90 : #elif defined(CCHMAXPATH)
91 : #define MAXPATHLEN CCHMAXPATH
92 : #else
93 : #define MAXPATHLEN 1024
94 : #endif
95 : #endif
96 :
97 : #ifdef XP_WIN
98 : typedef HRESULT (WINAPI* nsGetKnownFolderPath)(GUID& rfid,
99 : DWORD dwFlags,
100 : HANDLE hToken,
101 : PWSTR *ppszPath);
102 :
103 : static nsGetKnownFolderPath gGetKnownFolderPath = NULL;
104 : #endif
105 :
106 1419 : void StartupSpecialSystemDirectory()
107 : {
108 : #if defined (XP_WIN)
109 : // SHGetKnownFolderPath is only available on Windows Vista
110 : // so that we need to use GetProcAddress to get the pointer.
111 : HMODULE hShell32DLLInst = GetModuleHandleW(L"shell32.dll");
112 : if(hShell32DLLInst)
113 : {
114 : gGetKnownFolderPath = (nsGetKnownFolderPath)
115 : GetProcAddress(hShell32DLLInst, "SHGetKnownFolderPath");
116 : }
117 : #endif
118 1419 : }
119 :
120 : #if defined (XP_WIN)
121 :
122 : static nsresult GetKnownFolder(GUID* guid, nsILocalFile** aFile)
123 : {
124 : if (!guid || !gGetKnownFolderPath)
125 : return NS_ERROR_FAILURE;
126 :
127 : PWSTR path = NULL;
128 : gGetKnownFolderPath(*guid, 0, NULL, &path);
129 :
130 : if (!path)
131 : return NS_ERROR_FAILURE;
132 :
133 : nsresult rv = NS_NewLocalFile(nsDependentString(path),
134 : true,
135 : aFile);
136 :
137 : CoTaskMemFree(path);
138 : return rv;
139 : }
140 :
141 : //----------------------------------------------------------------------------------------
142 : static nsresult GetWindowsFolder(int folder, nsILocalFile** aFile)
143 : //----------------------------------------------------------------------------------------
144 : {
145 : WCHAR path_orig[MAX_PATH + 3];
146 : WCHAR *path = path_orig+1;
147 : HRESULT result = SHGetSpecialFolderPathW(NULL, path, folder, true);
148 :
149 : if (!SUCCEEDED(result))
150 : return NS_ERROR_FAILURE;
151 :
152 : // Append the trailing slash
153 : int len = wcslen(path);
154 : if (len > 1 && path[len - 1] != L'\\')
155 : {
156 : path[len] = L'\\';
157 : path[++len] = L'\0';
158 : }
159 :
160 : return NS_NewLocalFile(nsDependentString(path, len), true, aFile);
161 : }
162 :
163 : /**
164 : * Provides a fallback for getting the path to APPDATA or LOCALAPPDATA by
165 : * querying the registry when the call to SHGetSpecialFolderPathW is unable to
166 : * provide these paths (Bug 513958).
167 : */
168 : static nsresult GetRegWindowsAppDataFolder(bool aLocal, nsILocalFile** aFile)
169 : {
170 : HKEY key;
171 : NS_NAMED_LITERAL_STRING(keyName,
172 : "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders");
173 : DWORD res = ::RegOpenKeyExW(HKEY_CURRENT_USER, keyName.get(), 0, KEY_READ,
174 : &key);
175 : if (res != ERROR_SUCCESS)
176 : return NS_ERROR_FAILURE;
177 :
178 : WCHAR path[MAX_PATH + 2];
179 : DWORD type, size;
180 : res = RegQueryValueExW(key, (aLocal ? L"Local AppData" : L"AppData"), NULL,
181 : &type, (LPBYTE)&path, &size);
182 : ::RegCloseKey(key);
183 : // The call to RegQueryValueExW must succeed, the type must be REG_SZ, the
184 : // buffer size must not equal 0, and the buffer size be a multiple of 2.
185 : if (res != ERROR_SUCCESS || type != REG_SZ || size == 0 || size % 2 != 0)
186 : return NS_ERROR_FAILURE;
187 :
188 : // Append the trailing slash
189 : int len = wcslen(path);
190 : if (len > 1 && path[len - 1] != L'\\')
191 : {
192 : path[len] = L'\\';
193 : path[++len] = L'\0';
194 : }
195 :
196 : return NS_NewLocalFile(nsDependentString(path, len), true, aFile);
197 : }
198 :
199 : #endif // XP_WIN
200 :
201 : #if defined(XP_UNIX)
202 : static nsresult
203 31 : GetUnixHomeDir(nsILocalFile** aFile)
204 : {
205 : #ifdef VMS
206 : char *pHome;
207 : pHome = getenv("HOME");
208 : if (*pHome == '/') {
209 : return NS_NewNativeLocalFile(nsDependentCString(pHome),
210 : true,
211 : aFile);
212 : } else {
213 : return NS_NewNativeLocalFile(nsDependentCString(decc$translate_vms(pHome)),
214 : true,
215 : aFile);
216 : }
217 : #elif defined(ANDROID)
218 : // XXX no home dir on android; maybe we should return the sdcard if present?
219 : return NS_ERROR_FAILURE;
220 : #else
221 62 : return NS_NewNativeLocalFile(nsDependentCString(PR_GetEnv("HOME")),
222 31 : true, aFile);
223 : #endif
224 : }
225 :
226 : /*
227 : The following license applies to the xdg_user_dir_lookup function:
228 :
229 : Copyright (c) 2007 Red Hat, Inc.
230 :
231 : Permission is hereby granted, free of charge, to any person
232 : obtaining a copy of this software and associated documentation files
233 : (the "Software"), to deal in the Software without restriction,
234 : including without limitation the rights to use, copy, modify, merge,
235 : publish, distribute, sublicense, and/or sell copies of the Software,
236 : and to permit persons to whom the Software is furnished to do so,
237 : subject to the following conditions:
238 :
239 : The above copyright notice and this permission notice shall be
240 : included in all copies or substantial portions of the Software.
241 :
242 : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
243 : EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
244 : MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
245 : NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
246 : BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
247 : ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
248 : CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
249 : SOFTWARE.
250 : */
251 :
252 : static char *
253 9 : xdg_user_dir_lookup (const char *type)
254 : {
255 : FILE *file;
256 : char *home_dir, *config_home, *config_file;
257 : char buffer[512];
258 : char *user_dir;
259 : char *p, *d;
260 : int len;
261 : int relative;
262 :
263 9 : home_dir = getenv ("HOME");
264 :
265 9 : if (home_dir == NULL)
266 0 : goto error;
267 :
268 9 : config_home = getenv ("XDG_CONFIG_HOME");
269 9 : if (config_home == NULL || config_home[0] == 0)
270 : {
271 9 : config_file = (char*) malloc (strlen (home_dir) + strlen ("/.config/user-dirs.dirs") + 1);
272 9 : if (config_file == NULL)
273 0 : goto error;
274 :
275 9 : strcpy (config_file, home_dir);
276 9 : strcat (config_file, "/.config/user-dirs.dirs");
277 : }
278 : else
279 : {
280 0 : config_file = (char*) malloc (strlen (config_home) + strlen ("/user-dirs.dirs") + 1);
281 0 : if (config_file == NULL)
282 0 : goto error;
283 :
284 0 : strcpy (config_file, config_home);
285 0 : strcat (config_file, "/user-dirs.dirs");
286 : }
287 :
288 9 : file = fopen (config_file, "r");
289 9 : free (config_file);
290 9 : if (file == NULL)
291 9 : goto error;
292 :
293 0 : user_dir = NULL;
294 0 : while (fgets (buffer, sizeof (buffer), file))
295 : {
296 : /* Remove newline at end */
297 0 : len = strlen (buffer);
298 0 : if (len > 0 && buffer[len-1] == '\n')
299 0 : buffer[len-1] = 0;
300 :
301 0 : p = buffer;
302 0 : while (*p == ' ' || *p == '\t')
303 0 : p++;
304 :
305 0 : if (strncmp (p, "XDG_", 4) != 0)
306 0 : continue;
307 0 : p += 4;
308 0 : if (strncmp (p, type, strlen (type)) != 0)
309 0 : continue;
310 0 : p += strlen (type);
311 0 : if (strncmp (p, "_DIR", 4) != 0)
312 0 : continue;
313 0 : p += 4;
314 :
315 0 : while (*p == ' ' || *p == '\t')
316 0 : p++;
317 :
318 0 : if (*p != '=')
319 0 : continue;
320 0 : p++;
321 :
322 0 : while (*p == ' ' || *p == '\t')
323 0 : p++;
324 :
325 0 : if (*p != '"')
326 0 : continue;
327 0 : p++;
328 :
329 0 : relative = 0;
330 0 : if (strncmp (p, "$HOME/", 6) == 0)
331 : {
332 0 : p += 6;
333 0 : relative = 1;
334 : }
335 0 : else if (*p != '/')
336 0 : continue;
337 :
338 0 : if (relative)
339 : {
340 0 : user_dir = (char*) malloc (strlen (home_dir) + 1 + strlen (p) + 1);
341 0 : if (user_dir == NULL)
342 0 : goto error2;
343 :
344 0 : strcpy (user_dir, home_dir);
345 0 : strcat (user_dir, "/");
346 : }
347 : else
348 : {
349 0 : user_dir = (char*) malloc (strlen (p) + 1);
350 0 : if (user_dir == NULL)
351 0 : goto error2;
352 :
353 0 : *user_dir = 0;
354 : }
355 :
356 0 : d = user_dir + strlen (user_dir);
357 0 : while (*p && *p != '"')
358 : {
359 0 : if ((*p == '\\') && (*(p+1) != 0))
360 0 : p++;
361 0 : *d++ = *p++;
362 : }
363 0 : *d = 0;
364 : }
365 : error2:
366 0 : fclose (file);
367 :
368 0 : if (user_dir)
369 0 : return user_dir;
370 :
371 : error:
372 9 : return NULL;
373 : }
374 :
375 : static const char xdg_user_dirs[] =
376 : "DESKTOP\0"
377 : "DOCUMENTS\0"
378 : "DOWNLOAD\0"
379 : "MUSIC\0"
380 : "PICTURES\0"
381 : "PUBLICSHARE\0"
382 : "TEMPLATES\0"
383 : "VIDEOS";
384 :
385 : static const PRUint8 xdg_user_dir_offsets[] = {
386 : 0,
387 : 8,
388 : 18,
389 : 27,
390 : 33,
391 : 42,
392 : 54,
393 : 64
394 : };
395 :
396 : static nsresult
397 9 : GetUnixXDGUserDirectory(SystemDirectories aSystemDirectory,
398 : nsILocalFile** aFile)
399 : {
400 : char *dir = xdg_user_dir_lookup
401 : (xdg_user_dirs + xdg_user_dir_offsets[aSystemDirectory -
402 9 : Unix_XDG_Desktop]);
403 :
404 : nsresult rv;
405 18 : nsCOMPtr<nsILocalFile> file;
406 9 : if (dir) {
407 0 : rv = NS_NewNativeLocalFile(nsDependentCString(dir), true,
408 0 : getter_AddRefs(file));
409 0 : free(dir);
410 9 : } else if (Unix_XDG_Desktop == aSystemDirectory) {
411 : // for the XDG desktop dir, fall back to HOME/Desktop
412 : // (for historical compatibility)
413 0 : rv = GetUnixHomeDir(getter_AddRefs(file));
414 0 : if (NS_FAILED(rv))
415 0 : return rv;
416 :
417 0 : rv = file->AppendNative(NS_LITERAL_CSTRING("Desktop"));
418 : }
419 : #if defined(MOZ_PLATFORM_MAEMO)
420 : // "MYDOCSDIR" is exported to point to "/home/user/MyDocs" in maemo.
421 : else if (Unix_XDG_Documents == aSystemDirectory) {
422 :
423 : char *myDocs = PR_GetEnv("MYDOCSDIR");
424 : if (!myDocs || !*myDocs)
425 : return NS_ERROR_FAILURE;
426 :
427 : rv = NS_NewNativeLocalFile(nsDependentCString(myDocs), true,
428 : getter_AddRefs(file));
429 : if (NS_FAILED(rv))
430 : return rv;
431 :
432 : rv = file->AppendNative(NS_LITERAL_CSTRING(".documents"));
433 : }
434 : #endif
435 : else {
436 : // no fallback for the other XDG dirs
437 9 : rv = NS_ERROR_FAILURE;
438 : }
439 :
440 9 : if (NS_FAILED(rv))
441 9 : return rv;
442 :
443 : bool exists;
444 0 : rv = file->Exists(&exists);
445 0 : if (NS_FAILED(rv))
446 0 : return rv;
447 0 : if (!exists) {
448 0 : rv = file->Create(nsIFile::DIRECTORY_TYPE, 0755);
449 0 : if (NS_FAILED(rv))
450 0 : return rv;
451 : }
452 :
453 0 : *aFile = nsnull;
454 0 : file.swap(*aFile);
455 :
456 0 : return NS_OK;
457 : }
458 : #endif
459 :
460 : nsresult
461 1492 : GetSpecialSystemDirectory(SystemDirectories aSystemSystemDirectory,
462 : nsILocalFile** aFile)
463 : {
464 : #if defined(XP_WIN)
465 : WCHAR path[MAX_PATH];
466 : #else
467 : char path[MAXPATHLEN];
468 : #endif
469 :
470 1492 : switch (aSystemSystemDirectory)
471 : {
472 : case OS_CurrentWorkingDirectory:
473 : #if defined(XP_WIN)
474 : if (!_wgetcwd(path, MAX_PATH))
475 : return NS_ERROR_FAILURE;
476 : return NS_NewLocalFile(nsDependentString(path),
477 : true,
478 : aFile);
479 : #elif defined(XP_OS2)
480 : if (DosQueryPathInfo( ".", FIL_QUERYFULLNAME, path, MAXPATHLEN))
481 : return NS_ERROR_FAILURE;
482 : #else
483 1386 : if(!getcwd(path, MAXPATHLEN))
484 0 : return NS_ERROR_FAILURE;
485 : #endif
486 :
487 : #if !defined(XP_WIN)
488 1386 : return NS_NewNativeLocalFile(nsDependentCString(path),
489 : true,
490 1386 : aFile);
491 : #endif
492 :
493 : case OS_DriveDirectory:
494 : #if defined (XP_WIN)
495 : {
496 : PRInt32 len = ::GetWindowsDirectoryW(path, MAX_PATH);
497 : if (len == 0)
498 : break;
499 : if (path[1] == PRUnichar(':') && path[2] == PRUnichar('\\'))
500 : path[3] = 0;
501 :
502 : return NS_NewLocalFile(nsDependentString(path),
503 : true,
504 : aFile);
505 : }
506 : #elif defined(XP_OS2)
507 : {
508 : ULONG ulBootDrive = 0;
509 : char buffer[] = " :\\OS2\\";
510 : DosQuerySysInfo( QSV_BOOT_DRIVE, QSV_BOOT_DRIVE,
511 : &ulBootDrive, sizeof ulBootDrive);
512 : buffer[0] = 'A' - 1 + ulBootDrive; // duh, 1-based index...
513 :
514 : return NS_NewNativeLocalFile(nsDependentCString(buffer),
515 : true,
516 : aFile);
517 : }
518 : #else
519 0 : return NS_NewNativeLocalFile(nsDependentCString("/"),
520 : true,
521 0 : aFile);
522 :
523 : #endif
524 :
525 : case OS_TemporaryDirectory:
526 : #if defined (XP_WIN)
527 : {
528 : DWORD len = ::GetTempPathW(MAX_PATH, path);
529 : if (len == 0)
530 : break;
531 : return NS_NewLocalFile(nsDependentString(path, len),
532 : true,
533 : aFile);
534 : }
535 : #elif defined(XP_OS2)
536 : {
537 : char *tPath = PR_GetEnv("TMP");
538 : if (!tPath || !*tPath) {
539 : tPath = PR_GetEnv("TEMP");
540 : if (!tPath || !*tPath) {
541 : // if an OS/2 system has neither TMP nor TEMP defined
542 : // then it is severely broken, so this will never happen.
543 : return NS_ERROR_UNEXPECTED;
544 : }
545 : }
546 : nsCString tString = nsDependentCString(tPath);
547 : if (tString.Find("/", false, 0, -1)) {
548 : tString.ReplaceChar('/','\\');
549 : }
550 : return NS_NewNativeLocalFile(tString, true, aFile);
551 : }
552 : #elif defined(MOZ_WIDGET_COCOA)
553 : {
554 : return GetOSXFolderType(kUserDomain, kTemporaryFolderType, aFile);
555 : }
556 :
557 : #elif defined(XP_UNIX)
558 : {
559 : static const char *tPath = nsnull;
560 66 : if (!tPath) {
561 66 : tPath = PR_GetEnv("TMPDIR");
562 66 : if (!tPath || !*tPath) {
563 66 : tPath = PR_GetEnv("TMP");
564 66 : if (!tPath || !*tPath) {
565 66 : tPath = PR_GetEnv("TEMP");
566 66 : if (!tPath || !*tPath) {
567 66 : tPath = "/tmp/";
568 : }
569 : }
570 : }
571 : }
572 66 : return NS_NewNativeLocalFile(nsDependentCString(tPath),
573 : true,
574 66 : aFile);
575 : }
576 : #else
577 : break;
578 : #endif
579 : #if defined (XP_WIN)
580 : case Win_SystemDirectory:
581 : {
582 : PRInt32 len = ::GetSystemDirectoryW(path, MAX_PATH);
583 :
584 : // Need enough space to add the trailing backslash
585 : if (!len || len > MAX_PATH - 2)
586 : break;
587 : path[len] = L'\\';
588 : path[++len] = L'\0';
589 :
590 : return NS_NewLocalFile(nsDependentString(path, len),
591 : true,
592 : aFile);
593 : }
594 :
595 : case Win_WindowsDirectory:
596 : {
597 : PRInt32 len = ::GetWindowsDirectoryW(path, MAX_PATH);
598 :
599 : // Need enough space to add the trailing backslash
600 : if (!len || len > MAX_PATH - 2)
601 : break;
602 :
603 : path[len] = L'\\';
604 : path[++len] = L'\0';
605 :
606 : return NS_NewLocalFile(nsDependentString(path, len),
607 : true,
608 : aFile);
609 : }
610 :
611 : case Win_ProgramFiles:
612 : {
613 : return GetWindowsFolder(CSIDL_PROGRAM_FILES, aFile);
614 : }
615 :
616 : case Win_HomeDirectory:
617 : {
618 : nsresult rv = GetWindowsFolder(CSIDL_PROFILE, aFile);
619 : if (NS_SUCCEEDED(rv))
620 : return rv;
621 :
622 : PRInt32 len;
623 : if ((len = ::GetEnvironmentVariableW(L"HOME", path, MAX_PATH)) > 0)
624 : {
625 : // Need enough space to add the trailing backslash
626 : if (len > MAX_PATH - 2)
627 : break;
628 :
629 : path[len] = L'\\';
630 : path[++len] = L'\0';
631 :
632 : rv = NS_NewLocalFile(nsDependentString(path, len),
633 : true,
634 : aFile);
635 : if (NS_SUCCEEDED(rv))
636 : return rv;
637 : }
638 :
639 : len = ::GetEnvironmentVariableW(L"HOMEDRIVE", path, MAX_PATH);
640 : if (0 < len && len < MAX_PATH)
641 : {
642 : WCHAR temp[MAX_PATH];
643 : DWORD len2 = ::GetEnvironmentVariableW(L"HOMEPATH", temp, MAX_PATH);
644 : if (0 < len2 && len + len2 < MAX_PATH)
645 : wcsncat(path, temp, len2);
646 :
647 : len = wcslen(path);
648 :
649 : // Need enough space to add the trailing backslash
650 : if (len > MAX_PATH - 2)
651 : break;
652 :
653 : path[len] = L'\\';
654 : path[++len] = L'\0';
655 :
656 : return NS_NewLocalFile(nsDependentString(path, len),
657 : true,
658 : aFile);
659 : }
660 : }
661 : case Win_Desktop:
662 : {
663 : return GetWindowsFolder(CSIDL_DESKTOP, aFile);
664 : }
665 : case Win_Programs:
666 : {
667 : return GetWindowsFolder(CSIDL_PROGRAMS, aFile);
668 : }
669 :
670 : case Win_Downloads:
671 : {
672 : // Defined in KnownFolders.h.
673 : GUID folderid_downloads = {0x374de290, 0x123f, 0x4565, {0x91, 0x64,
674 : 0x39, 0xc4, 0x92, 0x5e, 0x46, 0x7b}};
675 : nsresult rv = GetKnownFolder(&folderid_downloads, aFile);
676 : // On WinXP, there is no downloads folder, default
677 : // to 'Desktop'.
678 : if(NS_ERROR_FAILURE == rv)
679 : {
680 : rv = GetWindowsFolder(CSIDL_DESKTOP, aFile);
681 : }
682 : return rv;
683 : }
684 :
685 : case Win_Controls:
686 : {
687 : return GetWindowsFolder(CSIDL_CONTROLS, aFile);
688 : }
689 : case Win_Printers:
690 : {
691 : return GetWindowsFolder(CSIDL_PRINTERS, aFile);
692 : }
693 : case Win_Personal:
694 : {
695 : return GetWindowsFolder(CSIDL_PERSONAL, aFile);
696 : }
697 : case Win_Favorites:
698 : {
699 : return GetWindowsFolder(CSIDL_FAVORITES, aFile);
700 : }
701 : case Win_Startup:
702 : {
703 : return GetWindowsFolder(CSIDL_STARTUP, aFile);
704 : }
705 : case Win_Recent:
706 : {
707 : return GetWindowsFolder(CSIDL_RECENT, aFile);
708 : }
709 : case Win_Sendto:
710 : {
711 : return GetWindowsFolder(CSIDL_SENDTO, aFile);
712 : }
713 : case Win_Bitbucket:
714 : {
715 : return GetWindowsFolder(CSIDL_BITBUCKET, aFile);
716 : }
717 : case Win_Startmenu:
718 : {
719 : return GetWindowsFolder(CSIDL_STARTMENU, aFile);
720 : }
721 : case Win_Desktopdirectory:
722 : {
723 : return GetWindowsFolder(CSIDL_DESKTOPDIRECTORY, aFile);
724 : }
725 : case Win_Drives:
726 : {
727 : return GetWindowsFolder(CSIDL_DRIVES, aFile);
728 : }
729 : case Win_Network:
730 : {
731 : return GetWindowsFolder(CSIDL_NETWORK, aFile);
732 : }
733 : case Win_Nethood:
734 : {
735 : return GetWindowsFolder(CSIDL_NETHOOD, aFile);
736 : }
737 : case Win_Fonts:
738 : {
739 : return GetWindowsFolder(CSIDL_FONTS, aFile);
740 : }
741 : case Win_Templates:
742 : {
743 : return GetWindowsFolder(CSIDL_TEMPLATES, aFile);
744 : }
745 : case Win_Common_Startmenu:
746 : {
747 : return GetWindowsFolder(CSIDL_COMMON_STARTMENU, aFile);
748 : }
749 : case Win_Common_Programs:
750 : {
751 : return GetWindowsFolder(CSIDL_COMMON_PROGRAMS, aFile);
752 : }
753 : case Win_Common_Startup:
754 : {
755 : return GetWindowsFolder(CSIDL_COMMON_STARTUP, aFile);
756 : }
757 : case Win_Common_Desktopdirectory:
758 : {
759 : return GetWindowsFolder(CSIDL_COMMON_DESKTOPDIRECTORY, aFile);
760 : }
761 : case Win_Common_AppData:
762 : {
763 : return GetWindowsFolder(CSIDL_COMMON_APPDATA, aFile);
764 : }
765 : case Win_Printhood:
766 : {
767 : return GetWindowsFolder(CSIDL_PRINTHOOD, aFile);
768 : }
769 : case Win_Cookies:
770 : {
771 : return GetWindowsFolder(CSIDL_COOKIES, aFile);
772 : }
773 : case Win_Appdata:
774 : {
775 : nsresult rv = GetWindowsFolder(CSIDL_APPDATA, aFile);
776 : if (NS_FAILED(rv))
777 : rv = GetRegWindowsAppDataFolder(false, aFile);
778 : return rv;
779 : }
780 : case Win_LocalAppdata:
781 : {
782 : nsresult rv = GetWindowsFolder(CSIDL_LOCAL_APPDATA, aFile);
783 : if (NS_FAILED(rv))
784 : rv = GetRegWindowsAppDataFolder(true, aFile);
785 : return rv;
786 : }
787 : #endif // XP_WIN
788 :
789 : #if defined(XP_UNIX)
790 : case Unix_LocalDirectory:
791 0 : return NS_NewNativeLocalFile(nsDependentCString("/usr/local/netscape/"),
792 : true,
793 0 : aFile);
794 : case Unix_LibDirectory:
795 0 : return NS_NewNativeLocalFile(nsDependentCString("/usr/local/lib/netscape/"),
796 : true,
797 0 : aFile);
798 :
799 : case Unix_HomeDirectory:
800 31 : return GetUnixHomeDir(aFile);
801 :
802 : case Unix_XDG_Desktop:
803 : case Unix_XDG_Documents:
804 : case Unix_XDG_Download:
805 : case Unix_XDG_Music:
806 : case Unix_XDG_Pictures:
807 : case Unix_XDG_PublicShare:
808 : case Unix_XDG_Templates:
809 : case Unix_XDG_Videos:
810 9 : return GetUnixXDGUserDirectory(aSystemSystemDirectory, aFile);
811 : #endif
812 :
813 : #ifdef XP_OS2
814 : case OS2_SystemDirectory:
815 : {
816 : ULONG ulBootDrive = 0;
817 : char buffer[] = " :\\OS2\\System\\";
818 : DosQuerySysInfo( QSV_BOOT_DRIVE, QSV_BOOT_DRIVE,
819 : &ulBootDrive, sizeof ulBootDrive);
820 : buffer[0] = 'A' - 1 + ulBootDrive; // duh, 1-based index...
821 :
822 : return NS_NewNativeLocalFile(nsDependentCString(buffer),
823 : true,
824 : aFile);
825 : }
826 :
827 : case OS2_OS2Directory:
828 : {
829 : ULONG ulBootDrive = 0;
830 : char buffer[] = " :\\OS2\\";
831 : DosQuerySysInfo( QSV_BOOT_DRIVE, QSV_BOOT_DRIVE,
832 : &ulBootDrive, sizeof ulBootDrive);
833 : buffer[0] = 'A' - 1 + ulBootDrive; // duh, 1-based index...
834 :
835 : return NS_NewNativeLocalFile(nsDependentCString(buffer),
836 : true,
837 : aFile);
838 : }
839 :
840 : case OS2_HomeDirectory:
841 : {
842 : nsresult rv;
843 : char *tPath = PR_GetEnv("MOZILLA_HOME");
844 : char buffer[CCHMAXPATH];
845 : /* If MOZILLA_HOME is not set, use GetCurrentProcessDirectory */
846 : /* To ensure we get a long filename system */
847 : if (!tPath || !*tPath) {
848 : PPIB ppib;
849 : PTIB ptib;
850 : DosGetInfoBlocks( &ptib, &ppib);
851 : DosQueryModuleName( ppib->pib_hmte, CCHMAXPATH, buffer);
852 : *strrchr( buffer, '\\') = '\0'; // XXX DBCS misery
853 : tPath = buffer;
854 : }
855 : rv = NS_NewNativeLocalFile(nsDependentCString(tPath),
856 : true,
857 : aFile);
858 :
859 : PrfWriteProfileString(HINI_USERPROFILE, "Mozilla", "Home", tPath);
860 : return rv;
861 : }
862 :
863 : case OS2_DesktopDirectory:
864 : {
865 : char szPath[CCHMAXPATH + 1];
866 : BOOL fSuccess;
867 : fSuccess = WinQueryActiveDesktopPathname (szPath, sizeof(szPath));
868 : if (!fSuccess) {
869 : // this could happen if we are running without the WPS, return
870 : // the Home directory instead
871 : return GetSpecialSystemDirectory(OS2_HomeDirectory, aFile);
872 : }
873 : int len = strlen (szPath);
874 : if (len > CCHMAXPATH -1)
875 : break;
876 : szPath[len] = '\\';
877 : szPath[len + 1] = '\0';
878 :
879 : return NS_NewNativeLocalFile(nsDependentCString(szPath),
880 : true,
881 : aFile);
882 : }
883 : #endif
884 : default:
885 : break;
886 : }
887 0 : return NS_ERROR_NOT_AVAILABLE;
888 : }
889 :
890 : #if defined (MOZ_WIDGET_COCOA)
891 : nsresult
892 : GetOSXFolderType(short aDomain, OSType aFolderType, nsILocalFile **localFile)
893 : {
894 : OSErr err;
895 : FSRef fsRef;
896 : nsresult rv = NS_ERROR_FAILURE;
897 :
898 : err = ::FSFindFolder(aDomain, aFolderType, kCreateFolder, &fsRef);
899 : if (err == noErr)
900 : {
901 : NS_NewLocalFile(EmptyString(), true, localFile);
902 : nsCOMPtr<nsILocalFileMac> localMacFile(do_QueryInterface(*localFile));
903 : if (localMacFile)
904 : rv = localMacFile->InitWithFSRef(&fsRef);
905 : }
906 : return rv;
907 : }
908 : #endif
909 :
|