vlc/src/win32/dirs-uap.c

350 lines
11 KiB
C

/*****************************************************************************
* dirs.c: directories configuration
*****************************************************************************
* Copyright (C) 2001-2010 VLC authors and VideoLAN
* Copyright © 2007-2012 Rémi Denis-Courmont
*
* Authors: Gildas Bazin <gbazin@videolan.org>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#define COBJMACROS
#define INITGUID
#ifndef UNICODE
#define UNICODE
#endif
#include <vlc_common.h>
#include <vlc_configuration.h>
#include "../config/configuration.h"
#include <vlc_charset.h>
#include <assert.h>
#include <winstring.h>
#include <roapi.h>
#define WIDL_using_Windows_Storage
#include <windows.storage.h>
#ifndef IStorageItem_get_Path
typedef __x_ABI_CWindows_CStorage_CIStorageFolder IStorageFolder;
typedef __x_ABI_CWindows_CStorage_CIStorageItem IStorageItem;
typedef __x_ABI_CWindows_CStorage_CIKnownFoldersStatics IKnownFoldersStatics;
typedef __x_ABI_CWindows_CStorage_CIApplicationDataStatics IApplicationDataStatics;
typedef __x_ABI_CWindows_CStorage_CIApplicationData IApplicationData;
typedef __x_ABI_CWindows_CStorage_CIApplicationData2 IApplicationData2;
#define IID_IStorageItem IID___x_ABI_CWindows_CStorage_CIStorageItem
#define IID_IKnownFoldersStatics IID___x_ABI_CWindows_CStorage_CIKnownFoldersStatics
#define IID_IApplicationDataStatics IID___x_ABI_CWindows_CStorage_CIApplicationDataStatics
#define IID_IApplicationData2 IID___x_ABI_CWindows_CStorage_CIApplicationData2
#define IKnownFoldersStatics_get_DocumentsLibrary(a,f) __x_ABI_CWindows_CStorage_CIKnownFoldersStatics_get_DocumentsLibrary(a,f)
#define IKnownFoldersStatics_get_MusicLibrary(a,f) __x_ABI_CWindows_CStorage_CIKnownFoldersStatics_get_MusicLibrary(a,f)
#define IKnownFoldersStatics_get_PicturesLibrary(a,f) __x_ABI_CWindows_CStorage_CIKnownFoldersStatics_get_PicturesLibrary(a,f)
#define IKnownFoldersStatics_get_VideosLibrary(a,f) __x_ABI_CWindows_CStorage_CIKnownFoldersStatics_get_VideosLibrary(a,f)
#define IStorageItem_get_Path(a,f) __x_ABI_CWindows_CStorage_CIStorageItem_get_Path(a,f)
#define IStorageItem_Release(a) __x_ABI_CWindows_CStorage_CIStorageItem_Release(a)
#define IStorageFolder_Release(a) __x_ABI_CWindows_CStorage_CIStorageFolder_Release(a)
#define IStorageFolder_QueryInterface(a,i,v) __x_ABI_CWindows_CStorage_CIStorageFolder_QueryInterface(a,i,v)
#define IKnownFoldersStatics_Release(a) __x_ABI_CWindows_CStorage_CIKnownFoldersStatics_Release(a)
#define IApplicationDataStatics_get_Current(a,f) __x_ABI_CWindows_CStorage_CIApplicationDataStatics_get_Current(a,f)
#define IApplicationData_get_LocalFolder(a,f) __x_ABI_CWindows_CStorage_CIApplicationData_get_LocalFolder(a,f)
#define IApplicationDataStatics_Release(a) __x_ABI_CWindows_CStorage_CIApplicationDataStatics_Release(a)
#define IApplicationData_Release(a) __x_ABI_CWindows_CStorage_CIApplicationData_Release(a)
#define IApplicationData_QueryInterface(a,i,v) __x_ABI_CWindows_CStorage_CIApplicationData_QueryInterface(a,i,v)
#define IApplicationData2_get_LocalCacheFolder(a,f) __x_ABI_CWindows_CStorage_CIApplicationData2_get_LocalCacheFolder(a,f)
#define IApplicationData2_Release(a) __x_ABI_CWindows_CStorage_CIApplicationData2_Release(a)
#endif
static char * GetFolderName(IStorageFolder *folder)
{
HRESULT hr;
void *pv;
IStorageItem *item;
hr = IStorageFolder_QueryInterface(folder, &IID_IStorageItem, &pv);
if (FAILED(hr))
return NULL;
item = pv;
char *result = NULL;
HSTRING path;
hr = IStorageItem_get_Path(item, &path);
if (SUCCEEDED(hr))
{
PCWSTR pszPathTemp = WindowsGetStringRawBuffer(path, NULL);
result = FromWide(pszPathTemp);
WindowsDeleteString(path);
}
IStorageItem_Release(item);
IStorageFolder_Release(folder);
return result;
}
static char *config_GetShellDir(vlc_userdir_t csidl)
{
HRESULT hr;
IStorageFolder *folder = NULL;
void *pv;
IKnownFoldersStatics *knownFoldersStatics = NULL;
static const WCHAR *className = L"Windows.Storage.KnownFolders";
const UINT32 clen = wcslen(className);
HSTRING hClassName = NULL;
HSTRING_HEADER header;
hr = WindowsCreateStringReference(className, clen, &header, &hClassName);
if (FAILED(hr))
goto end_other;
hr = RoGetActivationFactory(hClassName, &IID_IKnownFoldersStatics, &pv);
if (FAILED(hr))
goto end_other;
if (!pv) {
hr = E_FAIL;
goto end_other;
}
knownFoldersStatics = pv;
switch (csidl) {
case VLC_HOME_DIR:
hr = IKnownFoldersStatics_get_DocumentsLibrary(knownFoldersStatics, &folder);
break;
case VLC_MUSIC_DIR:
hr = IKnownFoldersStatics_get_MusicLibrary(knownFoldersStatics, &folder);
break;
case VLC_PICTURES_DIR:
hr = IKnownFoldersStatics_get_PicturesLibrary(knownFoldersStatics, &folder);
break;
case VLC_VIDEOS_DIR:
hr = IKnownFoldersStatics_get_VideosLibrary(knownFoldersStatics, &folder);
break;
default: vlc_assert_unreachable();
}
end_other:
if (knownFoldersStatics)
IKnownFoldersStatics_Release(knownFoldersStatics);
if( FAILED(hr) || folder == NULL )
return NULL;
return GetFolderName(folder);
}
static char *config_GetDataDir(void)
{
const char *path = getenv ("VLC_DATA_PATH");
return (path != NULL) ? strdup (path) : NULL;
}
char *config_GetSysPath(vlc_sysdir_t type, const char *filename)
{
char *dir = NULL;
switch (type)
{
case VLC_PKG_DATA_DIR:
dir = config_GetDataDir();
break;
case VLC_PKG_LIB_DIR:
case VLC_PKG_LIBEXEC_DIR:
case VLC_SYSDATA_DIR:
return NULL;
case VLC_LOCALE_DIR:
dir = config_GetSysPath(VLC_PKG_DATA_DIR, "locale");
break;
default:
vlc_assert_unreachable();
}
if (unlikely(dir == NULL))
return NULL;
if (filename == NULL)
return dir;
char *path;
if (unlikely(asprintf(&path, "%s\\%s", dir, filename) == -1))
path = NULL;
free(dir);
return path;
}
static char *config_GetAppDir (void)
{
char *psz_dir = NULL;
HRESULT hr;
IStorageFolder *folder = NULL;
void *pv;
IApplicationDataStatics *appDataStatics = NULL;
IApplicationData *appData = NULL;
static const WCHAR *className = L"Windows.Storage.ApplicationData";
const UINT32 clen = wcslen(className);
HSTRING hClassName = NULL;
HSTRING_HEADER header;
hr = WindowsCreateStringReference(className, clen, &header, &hClassName);
if (FAILED(hr))
goto end_appdata;
hr = RoGetActivationFactory(hClassName, &IID_IApplicationDataStatics, &pv);
if (FAILED(hr))
goto end_appdata;
if (!pv) {
hr = E_FAIL;
goto end_appdata;
}
appDataStatics = pv;
hr = IApplicationDataStatics_get_Current(appDataStatics, &appData);
if (FAILED(hr))
goto end_appdata;
if (!appData) {
hr = E_FAIL;
goto end_appdata;
}
hr = IApplicationData_get_LocalFolder(appData, &folder);
if( SUCCEEDED(hr) && folder != NULL )
{
char *psz_parent = GetFolderName(folder);
if (psz_parent == NULL
|| asprintf (&psz_dir, "%s\\vlc", psz_parent) == -1)
psz_dir = NULL;
free(psz_parent);
}
end_appdata:
if (appDataStatics)
IApplicationDataStatics_Release(appDataStatics);
if (appData)
IApplicationData_Release(appData);
return psz_dir;
}
#ifdef HAVE___X_ABI_CWINDOWS_CSTORAGE_CIAPPLICATIONDATA2
static char *config_GetCacheDir (void)
{
HRESULT hr;
IStorageFolder *folder = NULL;
void *pv;
IApplicationDataStatics *appDataStatics = NULL;
IApplicationData *appData = NULL;
IApplicationData2 *appData2 = NULL;
static const WCHAR *className = L"Windows.Storage.ApplicationData";
const UINT32 clen = wcslen(className);
HSTRING hClassName = NULL;
HSTRING_HEADER header;
hr = WindowsCreateStringReference(className, clen, &header, &hClassName);
if (FAILED(hr))
goto end_appdata;
hr = RoGetActivationFactory(hClassName, &IID_IApplicationDataStatics, &pv);
if (FAILED(hr))
goto end_appdata;
if (!pv) {
hr = E_FAIL;
goto end_appdata;
}
appDataStatics = pv;
hr = IApplicationDataStatics_get_Current(appDataStatics, &appData);
if (FAILED(hr))
goto end_appdata;
if (!appData) {
hr = E_FAIL;
goto end_appdata;
}
IApplicationData_QueryInterface(appData, &IID_IApplicationData2, &pv);
if (!pv) {
hr = E_FAIL;
goto end_appdata;
}
appData2 = pv;
hr = IApplicationData2_get_LocalCacheFolder(appData2, &folder);
end_appdata:
if (appDataStatics)
IApplicationDataStatics_Release(appDataStatics);
if (appData2)
IApplicationData2_Release(appData2);
if (appData)
IApplicationData_Release(appData);
if( FAILED(hr) || folder == NULL )
return NULL;
return GetFolderName(folder);
}
#else
static inline char *config_GetCacheDir(void)
{
return config_GetAppDir();
}
#endif // HAVE___X_ABI_CWINDOWS_CSTORAGE_CIAPPLICATIONDATA2
char *platform_GetUserDir (vlc_userdir_t type)
{
switch (type)
{
case VLC_HOME_DIR:
case VLC_DESKTOP_DIR:
case VLC_DOWNLOAD_DIR:
case VLC_TEMPLATES_DIR:
case VLC_PUBLICSHARE_DIR:
case VLC_DOCUMENTS_DIR:
return config_GetShellDir (VLC_HOME_DIR);
case VLC_CONFIG_DIR:
case VLC_USERDATA_DIR:
return config_GetAppDir ();
case VLC_CACHE_DIR:
return config_GetCacheDir ();
case VLC_MUSIC_DIR:
return config_GetShellDir (VLC_MUSIC_DIR);
case VLC_SNAPSHOTS_DIR: // FIXME GetFolderForUserAsync / UserDataPath
case VLC_PICTURES_DIR:
return config_GetShellDir (VLC_PICTURES_DIR);
case VLC_VIDEOS_DIR:
return config_GetShellDir (VLC_VIDEOS_DIR);
default:
vlc_assert_unreachable ();
}
}