[6076] | 1 | /* $Id: GetVBoxUserHomeDirectory.cpp 98103 2023-01-17 14:15:46Z vboxsync $ */
|
---|
[1] | 2 | /** @file
|
---|
[68538] | 3 | * MS COM / XPCOM Abstraction Layer - GetVBoxUserHomeDirectory.
|
---|
[1] | 4 | */
|
---|
| 5 |
|
---|
| 6 | /*
|
---|
[98103] | 7 | * Copyright (C) 2005-2023 Oracle and/or its affiliates.
|
---|
[1] | 8 | *
|
---|
[96407] | 9 | * This file is part of VirtualBox base platform packages, as
|
---|
| 10 | * available from https://www.virtualbox.org.
|
---|
| 11 | *
|
---|
| 12 | * This program is free software; you can redistribute it and/or
|
---|
| 13 | * modify it under the terms of the GNU General Public License
|
---|
| 14 | * as published by the Free Software Foundation, in version 3 of the
|
---|
| 15 | * License.
|
---|
| 16 | *
|
---|
| 17 | * This program is distributed in the hope that it will be useful, but
|
---|
| 18 | * WITHOUT ANY WARRANTY; without even the implied warranty of
|
---|
| 19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
---|
| 20 | * General Public License for more details.
|
---|
| 21 | *
|
---|
| 22 | * You should have received a copy of the GNU General Public License
|
---|
| 23 | * along with this program; if not, see <https://www.gnu.org/licenses>.
|
---|
| 24 | *
|
---|
| 25 | * SPDX-License-Identifier: GPL-3.0-only
|
---|
[1] | 26 | */
|
---|
| 27 |
|
---|
[69241] | 28 |
|
---|
[68538] | 29 | /*********************************************************************************************************************************
|
---|
| 30 | * Header Files *
|
---|
| 31 | *********************************************************************************************************************************/
|
---|
| 32 | #define LOG_GROUP LOG_GROUP_MAIN
|
---|
[79904] | 33 | #include <VBox/com/utils.h>
|
---|
[1] | 34 |
|
---|
[68538] | 35 | #include <iprt/env.h>
|
---|
| 36 | #include <iprt/dir.h>
|
---|
[2976] | 37 | #include <iprt/param.h>
|
---|
| 38 | #include <iprt/path.h>
|
---|
[2672] | 39 | #include <iprt/string.h>
|
---|
[2976] | 40 |
|
---|
[2672] | 41 | #include <VBox/err.h>
|
---|
[68538] | 42 | #include <VBox/log.h>
|
---|
[2672] | 43 |
|
---|
[68538] | 44 |
|
---|
| 45 |
|
---|
| 46 | /*********************************************************************************************************************************
|
---|
| 47 | * Global Variables *
|
---|
| 48 | *********************************************************************************************************************************/
|
---|
[44563] | 49 | #if !defined(RT_OS_DARWIN) && !defined(RT_OS_WINDOWS)
|
---|
[59228] | 50 | char g_szXdgConfigHome[RTPATH_MAX] = "";
|
---|
[44563] | 51 | #endif
|
---|
| 52 |
|
---|
| 53 | /**
|
---|
| 54 | * Possible locations for the VirtualBox user configuration folder,
|
---|
| 55 | * listed from oldest (as in legacy) to newest. These can be either
|
---|
| 56 | * absolute or relative to the home directory. We use the first entry
|
---|
| 57 | * of the list which corresponds to a real folder on storage, or
|
---|
| 58 | * create a folder corresponding to the last in the list (the least
|
---|
| 59 | * legacy) if none do.
|
---|
| 60 | */
|
---|
[59228] | 61 | const char * const g_apcszUserHome[] =
|
---|
[68538] | 62 | {
|
---|
[3668] | 63 | #ifdef RT_OS_DARWIN
|
---|
[68538] | 64 | "Library/VirtualBox",
|
---|
[44545] | 65 | #elif defined RT_OS_WINDOWS
|
---|
[68538] | 66 | ".VirtualBox",
|
---|
[2976] | 67 | #else
|
---|
[68538] | 68 | ".VirtualBox", g_szXdgConfigHome,
|
---|
[7418] | 69 | #endif
|
---|
[68538] | 70 | };
|
---|
[2976] | 71 |
|
---|
| 72 |
|
---|
[1] | 73 | namespace com
|
---|
| 74 | {
|
---|
| 75 |
|
---|
[68538] | 76 | static int composeHomePath(char *aDir, size_t aDirLen, const char *pcszBase)
|
---|
[2672] | 77 | {
|
---|
[44545] | 78 | int vrc;
|
---|
| 79 | if (RTPathStartsWithRoot(pcszBase))
|
---|
| 80 | vrc = RTStrCopy(aDir, aDirLen, pcszBase);
|
---|
| 81 | else
|
---|
| 82 | {
|
---|
| 83 | /* compose the config directory (full path) */
|
---|
| 84 | /** @todo r=bird: RTPathUserHome doesn't necessarily return a
|
---|
| 85 | * full (abs) path like the comment above seems to indicate. */
|
---|
| 86 | vrc = RTPathUserHome(aDir, aDirLen);
|
---|
| 87 | if (RT_SUCCESS(vrc))
|
---|
| 88 | vrc = RTPathAppend(aDir, aDirLen, pcszBase);
|
---|
| 89 | }
|
---|
| 90 | return vrc;
|
---|
| 91 | }
|
---|
| 92 |
|
---|
[42385] | 93 | int GetVBoxUserHomeDirectory(char *aDir, size_t aDirLen, bool fCreateDir)
|
---|
[2976] | 94 | {
|
---|
[21878] | 95 | AssertReturn(aDir, VERR_INVALID_POINTER);
|
---|
| 96 | AssertReturn(aDirLen > 0, VERR_BUFFER_OVERFLOW);
|
---|
[3387] | 97 |
|
---|
[2976] | 98 | /* start with null */
|
---|
[3387] | 99 | *aDir = 0;
|
---|
[2976] | 100 |
|
---|
[25944] | 101 | char szTmp[RTPATH_MAX];
|
---|
| 102 | int vrc = RTEnvGetEx(RTENV_DEFAULT, "VBOX_USER_HOME", szTmp, sizeof(szTmp), NULL);
|
---|
| 103 | if (RT_SUCCESS(vrc) || vrc == VERR_ENV_VAR_NOT_FOUND)
|
---|
[2976] | 104 | {
|
---|
[44545] | 105 | bool fFound = false;
|
---|
[21878] | 106 | if (RT_SUCCESS(vrc))
|
---|
[2976] | 107 | {
|
---|
[25944] | 108 | /* get the full path name */
|
---|
| 109 | vrc = RTPathAbs(szTmp, aDir, aDirLen);
|
---|
| 110 | }
|
---|
| 111 | else
|
---|
| 112 | {
|
---|
[44545] | 113 | #if !defined(RT_OS_WINDOWS) && !defined(RT_OS_DARWIN)
|
---|
[59228] | 114 | vrc = RTEnvGetEx(RTENV_DEFAULT, "XDG_CONFIG_HOME", g_szXdgConfigHome, sizeof(g_szXdgConfigHome), NULL);
|
---|
| 115 | if (RT_SUCCESS(vrc))
|
---|
| 116 | vrc = RTPathAppend(g_szXdgConfigHome, sizeof(g_szXdgConfigHome), "VirtualBox");
|
---|
[68096] | 117 | AssertMsg(vrc == VINF_SUCCESS || vrc == VERR_ENV_VAR_NOT_FOUND, ("%Rrc\n", vrc));
|
---|
[59228] | 118 | if (RT_FAILURE_NP(vrc))
|
---|
| 119 | vrc = RTStrCopy(g_szXdgConfigHome, sizeof(g_szXdgConfigHome), ".config/VirtualBox");
|
---|
[44545] | 120 | #endif
|
---|
[59228] | 121 | for (unsigned i = 0; i < RT_ELEMENTS(g_apcszUserHome); ++i)
|
---|
[44545] | 122 | {
|
---|
[59228] | 123 | vrc = composeHomePath(aDir, aDirLen, g_apcszUserHome[i]);
|
---|
[53834] | 124 | if ( RT_SUCCESS(vrc)
|
---|
| 125 | && RTDirExists(aDir))
|
---|
[44545] | 126 | {
|
---|
| 127 | fFound = true;
|
---|
| 128 | break;
|
---|
| 129 | }
|
---|
| 130 | }
|
---|
[2976] | 131 | }
|
---|
[25944] | 132 |
|
---|
| 133 | /* ensure the home directory exists */
|
---|
[21878] | 134 | if (RT_SUCCESS(vrc))
|
---|
[44545] | 135 | if (!fFound && fCreateDir)
|
---|
[39926] | 136 | vrc = RTDirCreateFullPath(aDir, 0700);
|
---|
[2976] | 137 | }
|
---|
| 138 |
|
---|
| 139 | return vrc;
|
---|
| 140 | }
|
---|
| 141 |
|
---|
[5658] | 142 | } /* namespace com */
|
---|