mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-11-11 20:06:18 +01:00
Merge branch 'windows-known-folders' into 'master'
Use SHGetKnownFolderPath() on Windows Closes #2397 See merge request GNOME/glib!2089
This commit is contained in:
commit
2549187b18
122
glib/gutils.c
122
glib/gutils.c
@ -548,23 +548,20 @@ static gchar **g_user_special_dirs = NULL;
|
|||||||
#ifdef G_OS_WIN32
|
#ifdef G_OS_WIN32
|
||||||
|
|
||||||
static gchar *
|
static gchar *
|
||||||
get_special_folder (int csidl)
|
get_special_folder (REFKNOWNFOLDERID known_folder_guid_ptr)
|
||||||
{
|
{
|
||||||
wchar_t path[MAX_PATH+1];
|
wchar_t *wcp = NULL;
|
||||||
|
gchar *result = NULL;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
LPITEMIDLIST pidl = NULL;
|
|
||||||
BOOL b;
|
|
||||||
gchar *retval = NULL;
|
|
||||||
|
|
||||||
hr = SHGetSpecialFolderLocation (NULL, csidl, &pidl);
|
hr = SHGetKnownFolderPath (known_folder_guid_ptr, 0, NULL, &wcp);
|
||||||
if (hr == S_OK)
|
|
||||||
{
|
if (SUCCEEDED (hr))
|
||||||
b = SHGetPathFromIDListW (pidl, path);
|
result = g_utf16_to_utf8 (wcp, -1, NULL, NULL, NULL);
|
||||||
if (b)
|
|
||||||
retval = g_utf16_to_utf8 (path, -1, NULL, NULL, NULL);
|
CoTaskMemFree (wcp);
|
||||||
CoTaskMemFree (pidl);
|
|
||||||
}
|
return result;
|
||||||
return retval;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
@ -814,7 +811,7 @@ g_build_home_dir (void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (home_dir == NULL)
|
if (home_dir == NULL)
|
||||||
home_dir = get_special_folder (CSIDL_PROFILE);
|
home_dir = get_special_folder (&FOLDERID_Profile);
|
||||||
|
|
||||||
if (home_dir == NULL)
|
if (home_dir == NULL)
|
||||||
home_dir = get_windows_directory_root ();
|
home_dir = get_windows_directory_root ();
|
||||||
@ -1704,7 +1701,7 @@ g_build_user_data_dir (void)
|
|||||||
data_dir = g_strdup (data_dir_env);
|
data_dir = g_strdup (data_dir_env);
|
||||||
#ifdef G_OS_WIN32
|
#ifdef G_OS_WIN32
|
||||||
else
|
else
|
||||||
data_dir = get_special_folder (CSIDL_LOCAL_APPDATA);
|
data_dir = get_special_folder (&FOLDERID_LocalAppData);
|
||||||
#endif
|
#endif
|
||||||
if (!data_dir || !data_dir[0])
|
if (!data_dir || !data_dir[0])
|
||||||
{
|
{
|
||||||
@ -1730,7 +1727,7 @@ g_build_user_data_dir (void)
|
|||||||
* On Windows it follows XDG Base Directory Specification if `XDG_DATA_HOME`
|
* On Windows it follows XDG Base Directory Specification if `XDG_DATA_HOME`
|
||||||
* is defined. If `XDG_DATA_HOME` is undefined, the folder to use for local (as
|
* is defined. If `XDG_DATA_HOME` is undefined, the folder to use for local (as
|
||||||
* opposed to roaming) application data is used instead. See the
|
* opposed to roaming) application data is used instead. See the
|
||||||
* [documentation for `CSIDL_LOCAL_APPDATA`](https://msdn.microsoft.com/en-us/library/windows/desktop/bb762494%28v=vs.85%29.aspx#csidl_local_appdata).
|
* [documentation for `FOLDERID_LocalAppData`](https://docs.microsoft.com/en-us/windows/win32/shell/knownfolderid).
|
||||||
* Note that in this case on Windows it will be the same
|
* Note that in this case on Windows it will be the same
|
||||||
* as what g_get_user_config_dir() returns.
|
* as what g_get_user_config_dir() returns.
|
||||||
*
|
*
|
||||||
@ -1768,7 +1765,7 @@ g_build_user_config_dir (void)
|
|||||||
config_dir = g_strdup (config_dir_env);
|
config_dir = g_strdup (config_dir_env);
|
||||||
#ifdef G_OS_WIN32
|
#ifdef G_OS_WIN32
|
||||||
else
|
else
|
||||||
config_dir = get_special_folder (CSIDL_LOCAL_APPDATA);
|
config_dir = get_special_folder (&FOLDERID_LocalAppData);
|
||||||
#endif
|
#endif
|
||||||
if (!config_dir || !config_dir[0])
|
if (!config_dir || !config_dir[0])
|
||||||
{
|
{
|
||||||
@ -1794,7 +1791,7 @@ g_build_user_config_dir (void)
|
|||||||
* On Windows it follows XDG Base Directory Specification if `XDG_CONFIG_HOME` is defined.
|
* On Windows it follows XDG Base Directory Specification if `XDG_CONFIG_HOME` is defined.
|
||||||
* If `XDG_CONFIG_HOME` is undefined, the folder to use for local (as opposed
|
* If `XDG_CONFIG_HOME` is undefined, the folder to use for local (as opposed
|
||||||
* to roaming) application data is used instead. See the
|
* to roaming) application data is used instead. See the
|
||||||
* [documentation for `CSIDL_LOCAL_APPDATA`](https://msdn.microsoft.com/en-us/library/windows/desktop/bb762494%28v=vs.85%29.aspx#csidl_local_appdata).
|
* [documentation for `FOLDERID_LocalAppData`](https://docs.microsoft.com/en-us/windows/win32/shell/knownfolderid).
|
||||||
* Note that in this case on Windows it will be the same
|
* Note that in this case on Windows it will be the same
|
||||||
* as what g_get_user_data_dir() returns.
|
* as what g_get_user_data_dir() returns.
|
||||||
*
|
*
|
||||||
@ -1831,7 +1828,7 @@ g_build_user_cache_dir (void)
|
|||||||
cache_dir = g_strdup (cache_dir_env);
|
cache_dir = g_strdup (cache_dir_env);
|
||||||
#ifdef G_OS_WIN32
|
#ifdef G_OS_WIN32
|
||||||
else
|
else
|
||||||
cache_dir = get_special_folder (CSIDL_INTERNET_CACHE);
|
cache_dir = get_special_folder (&FOLDERID_InternetCache);
|
||||||
#endif
|
#endif
|
||||||
if (!cache_dir || !cache_dir[0])
|
if (!cache_dir || !cache_dir[0])
|
||||||
{
|
{
|
||||||
@ -1858,7 +1855,7 @@ g_build_user_cache_dir (void)
|
|||||||
* If `XDG_CACHE_HOME` is undefined, the directory that serves as a common
|
* If `XDG_CACHE_HOME` is undefined, the directory that serves as a common
|
||||||
* repository for temporary Internet files is used instead. A typical path is
|
* repository for temporary Internet files is used instead. A typical path is
|
||||||
* `C:\Documents and Settings\username\Local Settings\Temporary Internet Files`.
|
* `C:\Documents and Settings\username\Local Settings\Temporary Internet Files`.
|
||||||
* See the [documentation for `CSIDL_INTERNET_CACHE`](https://msdn.microsoft.com/en-us/library/windows/desktop/bb762494%28v=vs.85%29.aspx#csidl_internet_cache).
|
* See the [documentation for `FOLDERID_InternetCache`](https://docs.microsoft.com/en-us/windows/win32/shell/knownfolderid).
|
||||||
*
|
*
|
||||||
* The return value is cached and modifying it at runtime is not supported, as
|
* The return value is cached and modifying it at runtime is not supported, as
|
||||||
* it’s not thread-safe to modify environment variables at runtime.
|
* it’s not thread-safe to modify environment variables at runtime.
|
||||||
@ -1965,69 +1962,22 @@ load_user_special_dirs (void)
|
|||||||
static void
|
static void
|
||||||
load_user_special_dirs (void)
|
load_user_special_dirs (void)
|
||||||
{
|
{
|
||||||
typedef HRESULT (WINAPI *t_SHGetKnownFolderPath) (const GUID *rfid,
|
g_user_special_dirs[G_USER_DIRECTORY_DESKTOP] = get_special_folder (&FOLDERID_Desktop);
|
||||||
DWORD dwFlags,
|
g_user_special_dirs[G_USER_DIRECTORY_DOCUMENTS] = get_special_folder (&FOLDERID_Documents);
|
||||||
HANDLE hToken,
|
|
||||||
PWSTR *ppszPath);
|
|
||||||
t_SHGetKnownFolderPath p_SHGetKnownFolderPath;
|
|
||||||
|
|
||||||
static const GUID FOLDERID_Downloads =
|
g_user_special_dirs[G_USER_DIRECTORY_DOWNLOAD] = get_special_folder (&FOLDERID_Downloads);
|
||||||
{ 0x374de290, 0x123f, 0x4565, { 0x91, 0x64, 0x39, 0xc4, 0x92, 0x5e, 0x46, 0x7b } };
|
if (g_user_special_dirs[G_USER_DIRECTORY_DOWNLOAD] == NULL)
|
||||||
static const GUID FOLDERID_Public =
|
g_user_special_dirs[G_USER_DIRECTORY_DOWNLOAD] = get_special_folder (&FOLDERID_Desktop);
|
||||||
{ 0xDFDF76A2, 0xC82A, 0x4D63, { 0x90, 0x6A, 0x56, 0x44, 0xAC, 0x45, 0x73, 0x85 } };
|
|
||||||
|
|
||||||
wchar_t *wcp;
|
g_user_special_dirs[G_USER_DIRECTORY_MUSIC] = get_special_folder (&FOLDERID_Music);
|
||||||
|
g_user_special_dirs[G_USER_DIRECTORY_PICTURES] = get_special_folder (&FOLDERID_Pictures);
|
||||||
|
|
||||||
p_SHGetKnownFolderPath = (t_SHGetKnownFolderPath) GetProcAddress (GetModuleHandleW (L"shell32.dll"),
|
g_user_special_dirs[G_USER_DIRECTORY_PUBLIC_SHARE] = get_special_folder (&FOLDERID_Public);
|
||||||
"SHGetKnownFolderPath");
|
if (g_user_special_dirs[G_USER_DIRECTORY_PUBLIC_SHARE] == NULL)
|
||||||
|
g_user_special_dirs[G_USER_DIRECTORY_PUBLIC_SHARE] = get_special_folder (&FOLDERID_PublicDocuments);
|
||||||
|
|
||||||
g_user_special_dirs[G_USER_DIRECTORY_DESKTOP] = get_special_folder (CSIDL_DESKTOPDIRECTORY);
|
g_user_special_dirs[G_USER_DIRECTORY_TEMPLATES] = get_special_folder (&FOLDERID_Templates);
|
||||||
g_user_special_dirs[G_USER_DIRECTORY_DOCUMENTS] = get_special_folder (CSIDL_PERSONAL);
|
g_user_special_dirs[G_USER_DIRECTORY_VIDEOS] = get_special_folder (&FOLDERID_Videos);
|
||||||
|
|
||||||
if (p_SHGetKnownFolderPath == NULL)
|
|
||||||
{
|
|
||||||
g_user_special_dirs[G_USER_DIRECTORY_DOWNLOAD] = get_special_folder (CSIDL_DESKTOPDIRECTORY);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
wcp = NULL;
|
|
||||||
(*p_SHGetKnownFolderPath) (&FOLDERID_Downloads, 0, NULL, &wcp);
|
|
||||||
if (wcp)
|
|
||||||
{
|
|
||||||
g_user_special_dirs[G_USER_DIRECTORY_DOWNLOAD] = g_utf16_to_utf8 (wcp, -1, NULL, NULL, NULL);
|
|
||||||
if (g_user_special_dirs[G_USER_DIRECTORY_DOWNLOAD] == NULL)
|
|
||||||
g_user_special_dirs[G_USER_DIRECTORY_DOWNLOAD] = get_special_folder (CSIDL_DESKTOPDIRECTORY);
|
|
||||||
CoTaskMemFree (wcp);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
g_user_special_dirs[G_USER_DIRECTORY_DOWNLOAD] = get_special_folder (CSIDL_DESKTOPDIRECTORY);
|
|
||||||
}
|
|
||||||
|
|
||||||
g_user_special_dirs[G_USER_DIRECTORY_MUSIC] = get_special_folder (CSIDL_MYMUSIC);
|
|
||||||
g_user_special_dirs[G_USER_DIRECTORY_PICTURES] = get_special_folder (CSIDL_MYPICTURES);
|
|
||||||
|
|
||||||
if (p_SHGetKnownFolderPath == NULL)
|
|
||||||
{
|
|
||||||
/* XXX */
|
|
||||||
g_user_special_dirs[G_USER_DIRECTORY_PUBLIC_SHARE] = get_special_folder (CSIDL_COMMON_DOCUMENTS);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
wcp = NULL;
|
|
||||||
(*p_SHGetKnownFolderPath) (&FOLDERID_Public, 0, NULL, &wcp);
|
|
||||||
if (wcp)
|
|
||||||
{
|
|
||||||
g_user_special_dirs[G_USER_DIRECTORY_PUBLIC_SHARE] = g_utf16_to_utf8 (wcp, -1, NULL, NULL, NULL);
|
|
||||||
if (g_user_special_dirs[G_USER_DIRECTORY_PUBLIC_SHARE] == NULL)
|
|
||||||
g_user_special_dirs[G_USER_DIRECTORY_PUBLIC_SHARE] = get_special_folder (CSIDL_COMMON_DOCUMENTS);
|
|
||||||
CoTaskMemFree (wcp);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
g_user_special_dirs[G_USER_DIRECTORY_PUBLIC_SHARE] = get_special_folder (CSIDL_COMMON_DOCUMENTS);
|
|
||||||
}
|
|
||||||
|
|
||||||
g_user_special_dirs[G_USER_DIRECTORY_TEMPLATES] = get_special_folder (CSIDL_TEMPLATES);
|
|
||||||
g_user_special_dirs[G_USER_DIRECTORY_VIDEOS] = get_special_folder (CSIDL_MYVIDEO);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#else /* default is unix */
|
#else /* default is unix */
|
||||||
@ -2379,12 +2329,12 @@ g_win32_get_system_data_dirs_for_module_real (void (*address_of_function)(void))
|
|||||||
data_dirs = g_array_new (TRUE, TRUE, sizeof (char *));
|
data_dirs = g_array_new (TRUE, TRUE, sizeof (char *));
|
||||||
|
|
||||||
/* Documents and Settings\All Users\Application Data */
|
/* Documents and Settings\All Users\Application Data */
|
||||||
p = get_special_folder (CSIDL_COMMON_APPDATA);
|
p = get_special_folder (&FOLDERID_ProgramData);
|
||||||
if (p)
|
if (p)
|
||||||
g_array_append_val (data_dirs, p);
|
g_array_append_val (data_dirs, p);
|
||||||
|
|
||||||
/* Documents and Settings\All Users\Documents */
|
/* Documents and Settings\All Users\Documents */
|
||||||
p = get_special_folder (CSIDL_COMMON_DOCUMENTS);
|
p = get_special_folder (&FOLDERID_PublicDocuments);
|
||||||
if (p)
|
if (p)
|
||||||
g_array_append_val (data_dirs, p);
|
g_array_append_val (data_dirs, p);
|
||||||
|
|
||||||
@ -2531,8 +2481,8 @@ g_build_system_data_dirs (void)
|
|||||||
* the first elements in the list are the Application Data
|
* the first elements in the list are the Application Data
|
||||||
* and Documents folders for All Users. (These can be determined only
|
* and Documents folders for All Users. (These can be determined only
|
||||||
* on Windows 2000 or later and are not present in the list on other
|
* on Windows 2000 or later and are not present in the list on other
|
||||||
* Windows versions.) See documentation for CSIDL_COMMON_APPDATA and
|
* Windows versions.) See documentation for FOLDERID_ProgramData and
|
||||||
* CSIDL_COMMON_DOCUMENTS.
|
* FOLDERID_PublicDocuments.
|
||||||
*
|
*
|
||||||
* Then follows the "share" subfolder in the installation folder for
|
* Then follows the "share" subfolder in the installation folder for
|
||||||
* the package containing the DLL that calls this function, if it can
|
* the package containing the DLL that calls this function, if it can
|
||||||
@ -2587,7 +2537,7 @@ g_build_system_config_dirs (void)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
gchar *special_conf_dirs = get_special_folder (CSIDL_COMMON_APPDATA);
|
gchar *special_conf_dirs = get_special_folder (&FOLDERID_ProgramData);
|
||||||
|
|
||||||
if (special_conf_dirs)
|
if (special_conf_dirs)
|
||||||
conf_dir_vector = g_strsplit (special_conf_dirs, G_SEARCHPATH_SEPARATOR_S, 0);
|
conf_dir_vector = g_strsplit (special_conf_dirs, G_SEARCHPATH_SEPARATOR_S, 0);
|
||||||
@ -2625,7 +2575,7 @@ g_build_system_config_dirs (void)
|
|||||||
* This folder is used for application data
|
* This folder is used for application data
|
||||||
* that is not user specific. For example, an application can store
|
* that is not user specific. For example, an application can store
|
||||||
* a spell-check dictionary, a database of clip art, or a log file in the
|
* a spell-check dictionary, a database of clip art, or a log file in the
|
||||||
* CSIDL_COMMON_APPDATA folder. This information will not roam and is available
|
* FOLDERID_ProgramData folder. This information will not roam and is available
|
||||||
* to anyone using the computer.
|
* to anyone using the computer.
|
||||||
*
|
*
|
||||||
* The return value is cached and modifying it at runtime is not supported, as
|
* The return value is cached and modifying it at runtime is not supported, as
|
||||||
|
Loading…
Reference in New Issue
Block a user