On x86 compilers without fastcall, simulate it when invoking traces and un-simulate...
[wine-gecko.git] / xpcom / io / SpecialSystemDirectory.cpp
blob91067c6673221fe16cfebd12906110c14596173c
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
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/
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.
15 * The Original Code is Mozilla Communicator client code, released
16 * March 31, 1998.
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.
23 * Contributor(s):
24 * Doug Turner <dougt@netscape.com>
25 * IBM Corp.
26 * Fredrik Holmqvist <thesuckiestemail@yahoo.se>
27 * Jungshik Shin <jshin@i18nl10n.com>
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.
41 * ***** END LICENSE BLOCK ***** */
43 #include "SpecialSystemDirectory.h"
44 #include "nsString.h"
45 #include "nsDependentString.h"
47 #if defined(XP_WIN)
49 #include <windows.h>
50 #include <shlobj.h>
51 #include <stdlib.h>
52 #include <stdio.h>
53 #include <string.h>
54 #include <direct.h>
56 // These are not defined by VC6.
57 #ifndef CSIDL_LOCAL_APPDATA
58 #define CSIDL_LOCAL_APPDATA 0x001C
59 #endif
60 #ifndef CSIDL_PROGRAM_FILES
61 #define CSIDL_PROGRAM_FILES 0x0026
62 #endif
64 #elif defined(XP_OS2)
66 #define MAX_PATH _MAX_PATH
67 #define INCL_WINWORKPLACE
68 #define INCL_DOSMISC
69 #define INCL_DOSMODULEMGR
70 #define INCL_DOSPROCESS
71 #define INCL_WINSHELLDATA
72 #include <os2.h>
73 #include <stdlib.h>
74 #include <stdio.h>
75 #include "prenv.h"
77 #elif defined(XP_UNIX)
79 #include <unistd.h>
80 #include <stdlib.h>
81 #include <sys/param.h>
82 #include "prenv.h"
84 #elif defined(XP_BEOS)
86 #include <FindDirectory.h>
87 #include <fs_info.h>
88 #include <Path.h>
89 #include <unistd.h>
90 #include <stdlib.h>
91 #include <sys/param.h>
92 #include <OS.h>
93 #include <image.h>
94 #include "prenv.h"
96 #endif
98 #if defined(VMS)
99 #include <unixlib.h>
100 #endif
102 #ifndef MAXPATHLEN
103 #ifdef MAX_PATH
104 #define MAXPATHLEN MAX_PATH
105 #elif defined(_MAX_PATH)
106 #define MAXPATHLEN _MAX_PATH
107 #elif defined(CCHMAXPATH)
108 #define MAXPATHLEN CCHMAXPATH
109 #else
110 #define MAXPATHLEN 1024
111 #endif
112 #endif
114 #ifdef XP_WIN
115 typedef HRESULT (WINAPI* nsGetKnownFolderPath)(GUID& rfid,
116 DWORD dwFlags,
117 HANDLE hToken,
118 PWSTR *ppszPath);
120 static nsGetKnownFolderPath gGetKnownFolderPath = NULL;
122 static HINSTANCE gShell32DLLInst = NULL;
123 #endif
125 NS_COM void StartupSpecialSystemDirectory()
127 #if defined (XP_WIN) && !defined (WINCE)
128 // SHGetKnownFolderPath is only available on Windows Vista
129 // so that we need to use GetProcAddress to get the pointer.
130 gShell32DLLInst = LoadLibrary("Shell32.dll");
131 if(gShell32DLLInst)
133 gGetKnownFolderPath = (nsGetKnownFolderPath)
134 GetProcAddress(gShell32DLLInst, "SHGetKnownFolderPath");
136 #endif
139 NS_COM void ShutdownSpecialSystemDirectory()
141 #if defined (XP_WIN)
142 if (gShell32DLLInst)
144 FreeLibrary(gShell32DLLInst);
145 gShell32DLLInst = NULL;
146 gGetKnownFolderPath = NULL;
148 #endif
151 #if defined (XP_WIN)
153 static nsresult GetKnownFolder(GUID* guid, nsILocalFile** aFile)
155 if (!guid || !gGetKnownFolderPath)
156 return NS_ERROR_FAILURE;
158 PWSTR path = NULL;
159 gGetKnownFolderPath(*guid, 0, NULL, &path);
161 if (!path)
162 return NS_ERROR_FAILURE;
164 nsresult rv = NS_NewLocalFile(nsDependentString(path),
165 PR_TRUE,
166 aFile);
168 CoTaskMemFree(path);
169 return rv;
172 //----------------------------------------------------------------------------------------
173 static nsresult GetWindowsFolder(int folder, nsILocalFile** aFile)
174 //----------------------------------------------------------------------------------------
176 WCHAR path[MAX_PATH + 2];
177 HRESULT result = SHGetSpecialFolderPathW(NULL, path, folder, true);
179 if (!SUCCEEDED(result))
180 return NS_ERROR_FAILURE;
182 // Append the trailing slash
183 int len = wcslen(path);
184 if (len > 1 && path[len - 1] != L'\\')
186 path[len] = L'\\';
187 path[++len] = L'\0';
190 return NS_NewLocalFile(nsDependentString(path, len), PR_TRUE, aFile);
193 #endif // XP_WIN
195 #if defined (XP_BEOS)
196 static nsresult
197 GetBeOSFolder( directory_which which, dev_t volume, nsILocalFile** aFile)
199 char path[MAXPATHLEN];
200 if (volume < 0)
201 return NS_ERROR_FAILURE;
203 status_t result = find_directory(which, volume, false, path, MAXPATHLEN - 2);
204 if (result != B_OK)
205 return NS_ERROR_FAILURE;
207 int len = strlen(path);
208 if (len == 0)
209 return NS_ERROR_FAILURE;
211 if (path[len-1] != '/')
213 path[len] = '/';
214 path[len+1] = '\0';
216 return NS_NewNativeLocalFile(nsDependentCString(path), PR_TRUE, aFile);
218 #endif // XP_BEOS
220 #if defined(XP_UNIX)
221 static nsresult
222 GetUnixHomeDir(nsILocalFile** aFile)
224 #ifdef VMS
225 char *pHome;
226 pHome = getenv("HOME");
227 if (*pHome == '/') {
228 return NS_NewNativeLocalFile(nsDependentCString(pHome),
229 PR_TRUE,
230 aFile);
231 } else {
232 return NS_NewNativeLocalFile(nsDependentCString(decc$translate_vms(pHome)),
233 PR_TRUE,
234 aFile);
236 #else
237 return NS_NewNativeLocalFile(nsDependentCString(PR_GetEnv("HOME")),
238 PR_TRUE, aFile);
239 #endif
243 The following license applies to the xdg_user_dir_lookup function:
245 Copyright (c) 2007 Red Hat, Inc.
247 Permission is hereby granted, free of charge, to any person
248 obtaining a copy of this software and associated documentation files
249 (the "Software"), to deal in the Software without restriction,
250 including without limitation the rights to use, copy, modify, merge,
251 publish, distribute, sublicense, and/or sell copies of the Software,
252 and to permit persons to whom the Software is furnished to do so,
253 subject to the following conditions:
255 The above copyright notice and this permission notice shall be
256 included in all copies or substantial portions of the Software.
258 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
259 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
260 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
261 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
262 BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
263 ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
264 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
265 SOFTWARE.
268 static char *
269 xdg_user_dir_lookup (const char *type)
271 FILE *file;
272 char *home_dir, *config_home, *config_file;
273 char buffer[512];
274 char *user_dir;
275 char *p, *d;
276 int len;
277 int relative;
279 home_dir = getenv ("HOME");
281 if (home_dir == NULL)
282 goto error;
284 config_home = getenv ("XDG_CONFIG_HOME");
285 if (config_home == NULL || config_home[0] == 0)
287 config_file = (char*) malloc (strlen (home_dir) + strlen ("/.config/user-dirs.dirs") + 1);
288 if (config_file == NULL)
289 goto error;
291 strcpy (config_file, home_dir);
292 strcat (config_file, "/.config/user-dirs.dirs");
294 else
296 config_file = (char*) malloc (strlen (config_home) + strlen ("/user-dirs.dirs") + 1);
297 if (config_file == NULL)
298 goto error;
300 strcpy (config_file, config_home);
301 strcat (config_file, "/user-dirs.dirs");
304 file = fopen (config_file, "r");
305 free (config_file);
306 if (file == NULL)
307 goto error;
309 user_dir = NULL;
310 while (fgets (buffer, sizeof (buffer), file))
312 /* Remove newline at end */
313 len = strlen (buffer);
314 if (len > 0 && buffer[len-1] == '\n')
315 buffer[len-1] = 0;
317 p = buffer;
318 while (*p == ' ' || *p == '\t')
319 p++;
321 if (strncmp (p, "XDG_", 4) != 0)
322 continue;
323 p += 4;
324 if (strncmp (p, type, strlen (type)) != 0)
325 continue;
326 p += strlen (type);
327 if (strncmp (p, "_DIR", 4) != 0)
328 continue;
329 p += 4;
331 while (*p == ' ' || *p == '\t')
332 p++;
334 if (*p != '=')
335 continue;
336 p++;
338 while (*p == ' ' || *p == '\t')
339 p++;
341 if (*p != '"')
342 continue;
343 p++;
345 relative = 0;
346 if (strncmp (p, "$HOME/", 6) == 0)
348 p += 6;
349 relative = 1;
351 else if (*p != '/')
352 continue;
354 if (relative)
356 user_dir = (char*) malloc (strlen (home_dir) + 1 + strlen (p) + 1);
357 if (user_dir == NULL)
358 goto error2;
360 strcpy (user_dir, home_dir);
361 strcat (user_dir, "/");
363 else
365 user_dir = (char*) malloc (strlen (p) + 1);
366 if (user_dir == NULL)
367 goto error2;
369 *user_dir = 0;
372 d = user_dir + strlen (user_dir);
373 while (*p && *p != '"')
375 if ((*p == '\\') && (*(p+1) != 0))
376 p++;
377 *d++ = *p++;
379 *d = 0;
381 error2:
382 fclose (file);
384 if (user_dir)
385 return user_dir;
387 error:
388 return NULL;
391 static const char xdg_user_dirs[] =
392 "DESKTOP\0"
393 "DOCUMENTS\0"
394 "DOWNLOAD\0"
395 "MUSIC\0"
396 "PICTURES\0"
397 "PUBLICSHARE\0"
398 "TEMPLATES\0"
399 "VIDEOS";
401 static const PRUint8 xdg_user_dir_offsets[] = {
412 static nsresult
413 GetUnixXDGUserDirectory(SystemDirectories aSystemDirectory,
414 nsILocalFile** aFile)
416 char *dir = xdg_user_dir_lookup
417 (xdg_user_dirs + xdg_user_dir_offsets[aSystemDirectory -
418 Unix_XDG_Desktop]);
420 nsresult rv;
421 nsCOMPtr<nsILocalFile> file;
422 if (dir) {
423 rv = NS_NewNativeLocalFile(nsDependentCString(dir), PR_TRUE,
424 getter_AddRefs(file));
425 free(dir);
426 } else if (Unix_XDG_Desktop == aSystemDirectory) {
427 // for the XDG desktop dir, fall back to HOME/Desktop
428 // (for historical compatibility)
429 rv = GetUnixHomeDir(getter_AddRefs(file));
430 if (NS_FAILED(rv))
431 return rv;
433 rv = file->AppendNative(NS_LITERAL_CSTRING("Desktop"));
434 } else {
435 // no fallback for the other XDG dirs
436 rv = NS_ERROR_FAILURE;
439 if (NS_FAILED(rv))
440 return rv;
442 PRBool exists;
443 rv = file->Exists(&exists);
444 if (NS_FAILED(rv))
445 return rv;
446 if (!exists) {
447 rv = file->Create(nsIFile::DIRECTORY_TYPE, 0755);
448 if (NS_FAILED(rv))
449 return rv;
452 *aFile = nsnull;
453 file.swap(*aFile);
455 return NS_OK;
457 #endif
459 nsresult
460 GetSpecialSystemDirectory(SystemDirectories aSystemSystemDirectory,
461 nsILocalFile** aFile)
463 #if defined(XP_WIN)
464 WCHAR path[MAX_PATH];
465 #else
466 char path[MAXPATHLEN];
467 #endif
469 switch (aSystemSystemDirectory)
471 case OS_CurrentWorkingDirectory:
472 #if defined(XP_WIN)
473 if (!_wgetcwd(path, MAX_PATH))
474 return NS_ERROR_FAILURE;
475 return NS_NewLocalFile(nsDependentString(path),
476 PR_TRUE,
477 aFile);
478 #elif defined(XP_OS2)
479 if (DosQueryPathInfo( ".", FIL_QUERYFULLNAME, path, MAXPATHLEN))
480 return NS_ERROR_FAILURE;
481 #else
482 if(!getcwd(path, MAXPATHLEN))
483 return NS_ERROR_FAILURE;
484 #endif
486 #if !defined(XP_WIN)
487 return NS_NewNativeLocalFile(nsDependentCString(path),
488 PR_TRUE,
489 aFile);
490 #endif
492 case OS_DriveDirectory:
493 #if defined (XP_WIN)
495 PRInt32 len = ::GetWindowsDirectoryW(path, MAX_PATH);
496 if (len == 0)
497 break;
498 if (path[1] == PRUnichar(':') && path[2] == PRUnichar('\\'))
499 path[3] = 0;
501 return NS_NewLocalFile(nsDependentString(path),
502 PR_TRUE,
503 aFile);
505 #elif defined(XP_OS2)
507 ULONG ulBootDrive = 0;
508 char buffer[] = " :\\OS2\\";
509 DosQuerySysInfo( QSV_BOOT_DRIVE, QSV_BOOT_DRIVE,
510 &ulBootDrive, sizeof ulBootDrive);
511 buffer[0] = 'A' - 1 + ulBootDrive; // duh, 1-based index...
513 return NS_NewNativeLocalFile(nsDependentCString(buffer),
514 PR_TRUE,
515 aFile);
517 #else
518 return NS_NewNativeLocalFile(nsDependentCString("/"),
519 PR_TRUE,
520 aFile);
522 #endif
524 case OS_TemporaryDirectory:
525 #if defined (XP_WIN) && !defined (WINCE)
527 DWORD len = ::GetTempPathW(MAX_PATH, path);
528 if (len == 0)
529 break;
530 return NS_NewLocalFile(nsDependentString(path, len),
531 PR_TRUE,
532 aFile);
534 #elif defined (WINCE)
536 return NS_NewNativeLocalFile(NS_LITERAL_CSTRING("\\Temp"),
537 PR_TRUE,
538 aFile);
540 #elif defined(XP_OS2)
542 char *tPath = PR_GetEnv("TMP");
543 if (!tPath || !*tPath) {
544 tPath = PR_GetEnv("TEMP");
545 if (!tPath || !*tPath) {
546 // if an OS/2 system has neither TMP nor TEMP defined
547 // then it is severely broken, so this will never happen.
548 return NS_ERROR_UNEXPECTED;
551 nsCString tString = nsDependentCString(tPath);
552 if (tString.Find("/", PR_FALSE, 0, -1)) {
553 tString.ReplaceChar('/','\\');
555 return NS_NewNativeLocalFile(tString, PR_TRUE, aFile);
557 #elif defined(XP_MACOSX)
559 return GetOSXFolderType(kUserDomain, kTemporaryFolderType, aFile);
562 #elif defined(XP_UNIX) || defined(XP_BEOS)
564 static const char *tPath = nsnull;
565 if (!tPath) {
566 tPath = PR_GetEnv("TMPDIR");
567 if (!tPath || !*tPath) {
568 tPath = PR_GetEnv("TMP");
569 if (!tPath || !*tPath) {
570 tPath = PR_GetEnv("TEMP");
571 if (!tPath || !*tPath) {
572 tPath = "/tmp/";
577 return NS_NewNativeLocalFile(nsDependentCString(tPath),
578 PR_TRUE,
579 aFile);
581 #else
582 break;
583 #endif
584 #if defined (XP_WIN)
585 case Win_SystemDirectory:
587 PRInt32 len = ::GetSystemDirectoryW(path, MAX_PATH);
589 // Need enough space to add the trailing backslash
590 if (!len || len > MAX_PATH - 2)
591 break;
592 path[len] = L'\\';
593 path[++len] = L'\0';
595 return NS_NewLocalFile(nsDependentString(path, len),
596 PR_TRUE,
597 aFile);
600 case Win_WindowsDirectory:
602 PRInt32 len = ::GetWindowsDirectoryW(path, MAX_PATH);
604 // Need enough space to add the trailing backslash
605 if (!len || len > MAX_PATH - 2)
606 break;
608 path[len] = L'\\';
609 path[++len] = L'\0';
611 return NS_NewLocalFile(nsDependentString(path, len),
612 PR_TRUE,
613 aFile);
616 case Win_ProgramFiles:
618 return GetWindowsFolder(CSIDL_PROGRAM_FILES, aFile);
621 case Win_HomeDirectory:
623 PRInt32 len;
624 if ((len = ::GetEnvironmentVariableW(L"HOME", path, MAX_PATH)) > 0)
626 // Need enough space to add the trailing backslash
627 if (len > MAX_PATH - 2)
628 break;
630 path[len] = L'\\';
631 path[++len] = L'\0';
633 return NS_NewLocalFile(nsDependentString(path, len),
634 PR_TRUE,
635 aFile);
638 len = ::GetEnvironmentVariableW(L"HOMEDRIVE", path, MAX_PATH);
639 if (0 < len && len < MAX_PATH)
641 WCHAR temp[MAX_PATH];
642 DWORD len2 = ::GetEnvironmentVariableW(L"HOMEPATH", temp, MAX_PATH);
643 if (0 < len2 && len + len2 < MAX_PATH)
644 wcsncat(path, temp, len2);
646 len = wcslen(path);
648 // Need enough space to add the trailing backslash
649 if (len > MAX_PATH - 2)
650 break;
652 path[len] = L'\\';
653 path[++len] = L'\0';
655 return NS_NewLocalFile(nsDependentString(path, len),
656 PR_TRUE,
657 aFile);
660 case Win_Desktop:
662 return GetWindowsFolder(CSIDL_DESKTOP, aFile);
664 case Win_Programs:
666 return GetWindowsFolder(CSIDL_PROGRAMS, aFile);
669 case Win_Downloads:
671 // Defined in KnownFolders.h.
672 GUID folderid_downloads = {0x374de290, 0x123f, 0x4565, {0x91, 0x64,
673 0x39, 0xc4, 0x92, 0x5e, 0x46, 0x7b}};
674 nsresult rv = GetKnownFolder(&folderid_downloads, aFile);
675 // On WinXP and 2k, there is no downloads folder, default
676 // to 'Desktop'.
677 if(NS_ERROR_FAILURE == rv)
679 rv = GetWindowsFolder(CSIDL_DESKTOP, aFile);
681 return rv;
684 case Win_Controls:
686 return GetWindowsFolder(CSIDL_CONTROLS, aFile);
688 case Win_Printers:
690 return GetWindowsFolder(CSIDL_PRINTERS, aFile);
692 case Win_Personal:
694 return GetWindowsFolder(CSIDL_PERSONAL, aFile);
696 case Win_Favorites:
698 return GetWindowsFolder(CSIDL_FAVORITES, aFile);
700 case Win_Startup:
702 return GetWindowsFolder(CSIDL_STARTUP, aFile);
704 case Win_Recent:
706 return GetWindowsFolder(CSIDL_RECENT, aFile);
708 case Win_Sendto:
710 return GetWindowsFolder(CSIDL_SENDTO, aFile);
712 case Win_Bitbucket:
714 return GetWindowsFolder(CSIDL_BITBUCKET, aFile);
716 case Win_Startmenu:
718 return GetWindowsFolder(CSIDL_STARTMENU, aFile);
720 case Win_Desktopdirectory:
722 return GetWindowsFolder(CSIDL_DESKTOPDIRECTORY, aFile);
724 case Win_Drives:
726 return GetWindowsFolder(CSIDL_DRIVES, aFile);
728 case Win_Network:
730 return GetWindowsFolder(CSIDL_NETWORK, aFile);
732 case Win_Nethood:
734 return GetWindowsFolder(CSIDL_NETHOOD, aFile);
736 case Win_Fonts:
738 return GetWindowsFolder(CSIDL_FONTS, aFile);
740 case Win_Templates:
742 return GetWindowsFolder(CSIDL_TEMPLATES, aFile);
744 #ifndef WINCE
745 case Win_Common_Startmenu:
747 return GetWindowsFolder(CSIDL_COMMON_STARTMENU, aFile);
749 case Win_Common_Programs:
751 return GetWindowsFolder(CSIDL_COMMON_PROGRAMS, aFile);
753 case Win_Common_Startup:
755 return GetWindowsFolder(CSIDL_COMMON_STARTUP, aFile);
757 case Win_Common_Desktopdirectory:
759 return GetWindowsFolder(CSIDL_COMMON_DESKTOPDIRECTORY, aFile);
761 case Win_Printhood:
763 return GetWindowsFolder(CSIDL_PRINTHOOD, aFile);
765 case Win_Cookies:
767 return GetWindowsFolder(CSIDL_COOKIES, aFile);
769 #endif
770 case Win_Appdata:
772 return GetWindowsFolder(CSIDL_APPDATA, aFile);
775 case Win_LocalAppdata:
777 return GetWindowsFolder(CSIDL_LOCAL_APPDATA, aFile);
779 #endif // XP_WIN
781 #if defined(XP_UNIX)
782 case Unix_LocalDirectory:
783 return NS_NewNativeLocalFile(nsDependentCString("/usr/local/netscape/"),
784 PR_TRUE,
785 aFile);
786 case Unix_LibDirectory:
787 return NS_NewNativeLocalFile(nsDependentCString("/usr/local/lib/netscape/"),
788 PR_TRUE,
789 aFile);
791 case Unix_HomeDirectory:
792 return GetUnixHomeDir(aFile);
794 case Unix_XDG_Desktop:
795 case Unix_XDG_Documents:
796 case Unix_XDG_Download:
797 case Unix_XDG_Music:
798 case Unix_XDG_Pictures:
799 case Unix_XDG_PublicShare:
800 case Unix_XDG_Templates:
801 case Unix_XDG_Videos:
802 return GetUnixXDGUserDirectory(aSystemSystemDirectory, aFile);
803 #endif
805 #ifdef XP_BEOS
806 case BeOS_SettingsDirectory:
808 return GetBeOSFolder(B_USER_SETTINGS_DIRECTORY,0, aFile);
811 case BeOS_HomeDirectory:
813 return GetBeOSFolder(B_USER_DIRECTORY,0, aFile);
816 case BeOS_DesktopDirectory:
818 /* Get the user's desktop folder, which in the future may differ from the boot desktop */
819 char path[MAXPATHLEN];
820 if (find_directory(B_USER_DIRECTORY, 0, false, path, MAXPATHLEN) != B_OK )
821 break;
822 return GetBeOSFolder(B_DESKTOP_DIRECTORY, dev_for_path(path), aFile);
825 case BeOS_SystemDirectory:
827 return GetBeOSFolder(B_BEOS_DIRECTORY,0, aFile);
829 #endif
830 #ifdef XP_OS2
831 case OS2_SystemDirectory:
833 ULONG ulBootDrive = 0;
834 char buffer[] = " :\\OS2\\System\\";
835 DosQuerySysInfo( QSV_BOOT_DRIVE, QSV_BOOT_DRIVE,
836 &ulBootDrive, sizeof ulBootDrive);
837 buffer[0] = 'A' - 1 + ulBootDrive; // duh, 1-based index...
839 return NS_NewNativeLocalFile(nsDependentCString(buffer),
840 PR_TRUE,
841 aFile);
844 case OS2_OS2Directory:
846 ULONG ulBootDrive = 0;
847 char buffer[] = " :\\OS2\\";
848 DosQuerySysInfo( QSV_BOOT_DRIVE, QSV_BOOT_DRIVE,
849 &ulBootDrive, sizeof ulBootDrive);
850 buffer[0] = 'A' - 1 + ulBootDrive; // duh, 1-based index...
852 return NS_NewNativeLocalFile(nsDependentCString(buffer),
853 PR_TRUE,
854 aFile);
857 case OS2_HomeDirectory:
859 nsresult rv;
860 char *tPath = PR_GetEnv("MOZILLA_HOME");
861 char buffer[CCHMAXPATH];
862 /* If MOZILLA_HOME is not set, use GetCurrentProcessDirectory */
863 /* To ensure we get a long filename system */
864 if (!tPath || !*tPath) {
865 PPIB ppib;
866 PTIB ptib;
867 DosGetInfoBlocks( &ptib, &ppib);
868 DosQueryModuleName( ppib->pib_hmte, CCHMAXPATH, buffer);
869 *strrchr( buffer, '\\') = '\0'; // XXX DBCS misery
870 tPath = buffer;
872 rv = NS_NewNativeLocalFile(nsDependentCString(tPath),
873 PR_TRUE,
874 aFile);
876 PrfWriteProfileString(HINI_USERPROFILE, "Mozilla", "Home", tPath);
877 return rv;
880 case OS2_DesktopDirectory:
882 char szPath[CCHMAXPATH + 1];
883 BOOL fSuccess;
884 fSuccess = WinQueryActiveDesktopPathname (szPath, sizeof(szPath));
885 if (!fSuccess) {
886 // this could happen if we are running without the WPS, return
887 // the Home directory instead
888 return GetSpecialSystemDirectory(OS2_HomeDirectory, aFile);
890 int len = strlen (szPath);
891 if (len > CCHMAXPATH -1)
892 break;
893 szPath[len] = '\\';
894 szPath[len + 1] = '\0';
896 return NS_NewNativeLocalFile(nsDependentCString(szPath),
897 PR_TRUE,
898 aFile);
900 #endif
901 default:
902 break;
904 return NS_ERROR_NOT_AVAILABLE;
907 #if defined (XP_MACOSX)
908 nsresult
909 GetOSXFolderType(short aDomain, OSType aFolderType, nsILocalFile **localFile)
911 OSErr err;
912 FSRef fsRef;
913 nsresult rv = NS_ERROR_FAILURE;
915 err = ::FSFindFolder(aDomain, aFolderType, kCreateFolder, &fsRef);
916 if (err == noErr)
918 NS_NewLocalFile(EmptyString(), PR_TRUE, localFile);
919 nsCOMPtr<nsILocalFileMac> localMacFile(do_QueryInterface(*localFile));
920 if (localMacFile)
921 rv = localMacFile->InitWithFSRef(&fsRef);
923 return rv;
925 #endif