Various improvements to known_folder() function.
This commit is contained in:
parent
9a898f5d49
commit
60d17ef37e
@ -73,7 +73,7 @@ $(function() {
|
||||
<div class="ttc" id="_hash_8h_html_aa9e34ac422f4e52061cb8908f922fe17"><div class="ttname"><a href="../../d2/dad/_hash_8h.html#aa9e34ac422f4e52061cb8908f922fe17">MUtils::Hash::HASH_BLAKE2_512</a></div><div class="ttdeci">static const quint16 HASH_BLAKE2_512</div><div class="ttdoc">Hash algorithm identifier. </div><div class="ttdef"><b>Definition:</b> Hash.h:42</div></div>
|
||||
<div class="ttc" id="_hash_8h_html_af80dfb1569816fab7ab5ed32e6386458"><div class="ttname"><a href="../../d2/dad/_hash_8h.html#af80dfb1569816fab7ab5ed32e6386458">MUtils::Hash::HASH_KECCAK_384</a></div><div class="ttdeci">static const quint16 HASH_KECCAK_384</div><div class="ttdoc">Hash algorithm identifier. </div><div class="ttdef"><b>Definition:</b> Hash.h:45</div></div>
|
||||
<div class="ttc" id="namespace_m_utils_html"><div class="ttname"><a href="../../d3/da6/namespace_m_utils.html">MUtils</a></div><div class="ttdoc">Global MUtils namespace. </div><div class="ttdef"><b>Definition:</b> CPUFeatures.h:37</div></div>
|
||||
<div class="ttc" id="_global_8h_html_a8e7b4857b78f9749233e5abc96534ca8"><div class="ttname"><a href="../../d5/d3b/_global_8h.html#a8e7b4857b78f9749233e5abc96534ca8">MUTILS_NO_COPY</a></div><div class="ttdeci">#define MUTILS_NO_COPY(CLASS)</div><div class="ttdoc">Disables copy constructor and assignment operator in the specified class. This macro should be used i...</div><div class="ttdef"><b>Definition:</b> Global.h:422</div></div>
|
||||
<div class="ttc" id="_global_8h_html_a8e7b4857b78f9749233e5abc96534ca8"><div class="ttname"><a href="../../d5/d3b/_global_8h.html#a8e7b4857b78f9749233e5abc96534ca8">MUTILS_NO_COPY</a></div><div class="ttdeci">#define MUTILS_NO_COPY(CLASS)</div><div class="ttdoc">Disables copy constructor and assignment operator in the specified class. This macro should be used i...</div><div class="ttdef"><b>Definition:</b> Global.h:418</div></div>
|
||||
<div class="ttc" id="_hash_8h_html_a330b73d6927d6cd95892712f9396f40e"><div class="ttname"><a href="../../d2/dad/_hash_8h.html#a330b73d6927d6cd95892712f9396f40e">MUtils::Hash::create</a></div><div class="ttdeci">MUTILS_API Hash * create(const quint16 &hashId, const char *const key=NULL)</div><div class="ttdoc">Create instance of a hash function. </div></div>
|
||||
<div class="ttc" id="class_m_utils_1_1_hash_1_1_hash_html"><div class="ttname"><a href="../../da/db0/class_m_utils_1_1_hash_1_1_hash.html">MUtils::Hash::Hash</a></div><div class="ttdoc">This abstract class specifies the generic interface for all support hash algorithms. </div><div class="ttdef"><b>Definition:</b> Hash.h:57</div></div>
|
||||
<div class="ttc" id="_hash_8h_html_ae38cda07e425eb7c745492215a48ae08"><div class="ttname"><a href="../../d2/dad/_hash_8h.html#ae38cda07e425eb7c745492215a48ae08">MUtils::Hash::HASH_KECCAK_256</a></div><div class="ttdeci">static const quint16 HASH_KECCAK_256</div><div class="ttdoc">Hash algorithm identifier. </div><div class="ttdef"><b>Definition:</b> Hash.h:44</div></div>
|
||||
|
@ -156,9 +156,9 @@ MUTILS_API const char * </td><td class="memItemRight" valign="bottom"><b>os
|
||||
<tr class="memitem:aa9b386b6e44ec9584a01ff9a8612f573"><td class="memItemLeft" align="right" valign="top"><a id="aa9b386b6e44ec9584a01ff9a8612f573"></a>
|
||||
MUTILS_API const bool & </td><td class="memItemRight" valign="bottom"><b>running_on_wine</b> (void)</td></tr>
|
||||
<tr class="separator:aa9b386b6e44ec9584a01ff9a8612f573"><td class="memSeparator" colspan="2"> </td></tr>
|
||||
<tr class="memitem:ab76cf63d91b34f34f50f218563cf6c75"><td class="memItemLeft" align="right" valign="top"><a id="ab76cf63d91b34f34f50f218563cf6c75"></a>
|
||||
MUTILS_API const QString & </td><td class="memItemRight" valign="bottom"><b>known_folder</b> (<a class="el" href="../../d2/df4/namespace_m_utils_1_1_o_s.html#a62a1b72ba9a7accee438d19212785e54">known_folder_t</a> folder_id)</td></tr>
|
||||
<tr class="separator:ab76cf63d91b34f34f50f218563cf6c75"><td class="memSeparator" colspan="2"> </td></tr>
|
||||
<tr class="memitem:a8316cd86318a055ca7e4d953803f86ba"><td class="memItemLeft" align="right" valign="top"><a id="a8316cd86318a055ca7e4d953803f86ba"></a>
|
||||
MUTILS_API const QString & </td><td class="memItemRight" valign="bottom"><b>known_folder</b> (const <a class="el" href="../../d2/df4/namespace_m_utils_1_1_o_s.html#a62a1b72ba9a7accee438d19212785e54">known_folder_t</a> folder_id)</td></tr>
|
||||
<tr class="separator:a8316cd86318a055ca7e4d953803f86ba"><td class="memSeparator" colspan="2"> </td></tr>
|
||||
<tr class="memitem:a186c34bfd3d6256af637635009faf4ea"><td class="memItemLeft" align="right" valign="top"><a id="a186c34bfd3d6256af637635009faf4ea"></a>
|
||||
MUTILS_API QDate </td><td class="memItemRight" valign="bottom"><b>current_date</b> (void)</td></tr>
|
||||
<tr class="separator:a186c34bfd3d6256af637635009faf4ea"><td class="memSeparator" colspan="2"> </td></tr>
|
||||
|
@ -186,9 +186,9 @@ MUTILS_API const char * </td><td class="memItemRight" valign="bottom"><b>MU
|
||||
<tr class="memitem:aa9b386b6e44ec9584a01ff9a8612f573"><td class="memItemLeft" align="right" valign="top"><a id="aa9b386b6e44ec9584a01ff9a8612f573"></a>
|
||||
MUTILS_API const bool & </td><td class="memItemRight" valign="bottom"><b>MUtils::OS::running_on_wine</b> (void)</td></tr>
|
||||
<tr class="separator:aa9b386b6e44ec9584a01ff9a8612f573"><td class="memSeparator" colspan="2"> </td></tr>
|
||||
<tr class="memitem:ab76cf63d91b34f34f50f218563cf6c75"><td class="memItemLeft" align="right" valign="top"><a id="ab76cf63d91b34f34f50f218563cf6c75"></a>
|
||||
MUTILS_API const QString & </td><td class="memItemRight" valign="bottom"><b>MUtils::OS::known_folder</b> (known_folder_t folder_id)</td></tr>
|
||||
<tr class="separator:ab76cf63d91b34f34f50f218563cf6c75"><td class="memSeparator" colspan="2"> </td></tr>
|
||||
<tr class="memitem:a8316cd86318a055ca7e4d953803f86ba"><td class="memItemLeft" align="right" valign="top"><a id="a8316cd86318a055ca7e4d953803f86ba"></a>
|
||||
MUTILS_API const QString & </td><td class="memItemRight" valign="bottom"><b>MUtils::OS::known_folder</b> (const known_folder_t folder_id)</td></tr>
|
||||
<tr class="separator:a8316cd86318a055ca7e4d953803f86ba"><td class="memSeparator" colspan="2"> </td></tr>
|
||||
<tr class="memitem:a186c34bfd3d6256af637635009faf4ea"><td class="memItemLeft" align="right" valign="top"><a id="a186c34bfd3d6256af637635009faf4ea"></a>
|
||||
MUTILS_API QDate </td><td class="memItemRight" valign="bottom"><b>MUtils::OS::current_date</b> (void)</td></tr>
|
||||
<tr class="separator:a186c34bfd3d6256af637635009faf4ea"><td class="memSeparator" colspan="2"> </td></tr>
|
||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -162,7 +162,7 @@ namespace MUtils
|
||||
MUTILS_API const bool &running_on_wine(void);
|
||||
|
||||
//Get known Folder
|
||||
MUTILS_API const QString &known_folder(known_folder_t folder_id);
|
||||
MUTILS_API const QString &known_folder(const known_folder_t folder_id);
|
||||
|
||||
//Current Date & Time
|
||||
MUTILS_API QDate current_date(void);
|
||||
|
@ -690,43 +690,131 @@ const bool &MUtils::OS::running_on_wine(void)
|
||||
static QReadWriteLock g_known_folders_lock;
|
||||
static QScopedPointer<QHash<size_t, QString>> g_known_folders_data;
|
||||
|
||||
typedef HRESULT (WINAPI *SHGetKnownFolderPath_t)(const GUID &rfid, DWORD dwFlags, HANDLE hToken, PWSTR *ppszPath);
|
||||
typedef HRESULT (WINAPI *SHGetFolderPath_t) (HWND hwndOwner, int nFolder, HANDLE hToken, DWORD dwFlags, LPWSTR pszPath);
|
||||
typedef HRESULT (WINAPI *SHGetKnownFolderPathProc)(const GUID &rfid, DWORD dwFlags, HANDLE hToken, PWSTR *ppszPath);
|
||||
typedef HRESULT (WINAPI *SHGetFolderPathProc)(HWND hwndOwner, int nFolder, HANDLE hToken, DWORD dwFlags, LPWSTR pszPath);
|
||||
|
||||
const QString &MUtils::OS::known_folder(known_folder_t folder_id)
|
||||
static const struct
|
||||
{
|
||||
typedef enum { KF_FLAG_CREATE = 0x00008000 } kf_flags_t;
|
||||
|
||||
struct
|
||||
{
|
||||
const int csidl;
|
||||
const GUID guid;
|
||||
INT32 csidl;
|
||||
GUID kfuid;
|
||||
}
|
||||
static s_folders[] =
|
||||
s_known_folders_lut[] =
|
||||
{
|
||||
{ 0x001a, {0x3EB685DB,0x65F9,0x4CF6,{0xA0,0x3A,0xE3,0xEF,0x65,0x72,0x9F,0x3D}} }, //CSIDL_APPDATA
|
||||
{ 0x001c, {0xF1B32785,0x6FBA,0x4FCF,{0x9D,0x55,0x7B,0x8E,0x7F,0x15,0x70,0x91}} }, //CSIDL_LOCAL_APPDATA
|
||||
{ 0x001A, { 0x3EB685DB, 0x65F9, 0x4CF6, { 0xA0, 0x3A, 0xE3, 0xEF, 0x65, 0x72, 0x9F, 0x3D } } }, //CSIDL_APPDATA
|
||||
{ 0x001C, { 0xF1B32785, 0x6FBA, 0x4FCF, { 0x9D, 0x55, 0x7B, 0x8E, 0x7F, 0x15, 0x70, 0x91 } } }, //CSIDL_LOCAL_APPDATA
|
||||
{ 0x0028, { 0x5E6C858F, 0x0E22, 0x4760, { 0x9A, 0xFE, 0xEA, 0x33, 0x17, 0xB6, 0x71, 0x73 } } }, //CSIDL_PROFILE
|
||||
{ 0x0026, {0x905e63b6,0xc1bf,0x494e,{0xb2,0x9c,0x65,0xb7,0x32,0xd3,0xd2,0x1a}} }, //CSIDL_PROGRAM_FILES
|
||||
{ 0x0026, { 0x905E63B6, 0xC1BF, 0x494E, { 0xB2, 0x9C, 0x65, 0xB7, 0x32, 0xD3, 0xD2, 0x1A } } }, //CSIDL_PROGRAM_FILES
|
||||
{ 0x0025, { 0x1AC14E77, 0x02E7, 0x4E5D, { 0xB7, 0x44, 0x2E, 0xB1, 0xAE, 0x51, 0x98, 0xB7 } } }, //CSIDL_SYSTEM_FOLDER
|
||||
{ 0x0024, { 0xF38BF404, 0x1D43, 0x42F2, { 0x93, 0x05, 0x67, 0xDE, 0x0B, 0x28, 0xFC, 0x23 } } }, //CSIDL_WINDOWS_FOLDER
|
||||
};
|
||||
|
||||
size_t folderId = size_t(-1);
|
||||
static QString known_folder_fallback(const size_t folderId)
|
||||
{
|
||||
static const DWORD s_shgfpTypes[3] =
|
||||
{
|
||||
0, /*SHGFP_TYPE_CURRENT*/
|
||||
1, /*SHGFP_TYPE_DEFAULT*/
|
||||
MAXDWORD
|
||||
};
|
||||
|
||||
static const INT32 s_shgfpFlags[3] =
|
||||
{
|
||||
0x0000, /*No extra flags*/
|
||||
0x8000, /*SHGFP_FLAG_CREATE*/
|
||||
MAXINT32
|
||||
};
|
||||
|
||||
const SHGetFolderPathProc getFolderPath = MUtils::Win32Utils::resolve<SHGetFolderPathProc>(QLatin1String("shell32"), QLatin1String("SHGetFolderPathW"));
|
||||
if (getFolderPath)
|
||||
{
|
||||
QVector<WCHAR> pathBuffer(MAX_PATH);
|
||||
for (size_t i = 0; s_shgfpTypes[i] != MAXDWORD; ++i)
|
||||
{
|
||||
for (size_t j = 0; s_shgfpFlags[j] != MAXINT32; ++j)
|
||||
{
|
||||
if (getFolderPath(NULL, s_known_folders_lut[folderId].csidl | s_shgfpFlags[j], NULL, s_shgfpTypes[i], pathBuffer.data()) == S_OK)
|
||||
{
|
||||
//MessageBoxW(0, path, L"SHGetFolderPathW", MB_TOPMOST);
|
||||
const QDir folderPathTemp = QDir(QDir::fromNativeSeparators(MUTILS_QSTR(pathBuffer.data())));
|
||||
if (folderPathTemp.exists())
|
||||
{
|
||||
return folderPathTemp.canonicalPath();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return QString(); /*failed!*/
|
||||
}
|
||||
|
||||
static QString known_folder_detect(const size_t folderId)
|
||||
{
|
||||
typedef enum
|
||||
{
|
||||
KF_FLAG_DEFAULT = 0x00000000,
|
||||
KF_FLAG_DEFAULT_PATH = 0x00000400,
|
||||
KF_FLAG_CREATE = 0x00008000
|
||||
}
|
||||
kf_flag_t;
|
||||
|
||||
static const DWORD s_kfFlags[5] =
|
||||
{
|
||||
KF_FLAG_DEFAULT,
|
||||
KF_FLAG_CREATE,
|
||||
KF_FLAG_DEFAULT_PATH,
|
||||
KF_FLAG_DEFAULT_PATH | KF_FLAG_CREATE,
|
||||
MAXDWORD
|
||||
};
|
||||
|
||||
const SHGetKnownFolderPathProc getKnownFolderPath = MUtils::Win32Utils::resolve<SHGetKnownFolderPathProc>(QLatin1String("shell32"), QLatin1String("SHGetKnownFolderPath"));
|
||||
if (getKnownFolderPath)
|
||||
{
|
||||
for (size_t i = 0; s_kfFlags[i] != MAXDWORD; ++i)
|
||||
{
|
||||
WCHAR* path = NULL;
|
||||
if (getKnownFolderPath(s_known_folders_lut[folderId].kfuid, s_kfFlags[i], NULL, &path) == S_OK)
|
||||
{
|
||||
//MessageBoxW(0, path, L"SHGetKnownFolderPath", MB_TOPMOST);
|
||||
const QDir folderPathTemp = QDir(QDir::fromNativeSeparators(MUTILS_QSTR(path)));
|
||||
CoTaskMemFree(path);
|
||||
if (folderPathTemp.exists())
|
||||
{
|
||||
return folderPathTemp.canonicalPath();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return known_folder_fallback(folderId); /*fallback!*/
|
||||
}
|
||||
|
||||
static size_t known_folder_decode(const MUtils::OS::known_folder_t folder_id)
|
||||
{
|
||||
switch (folder_id)
|
||||
{
|
||||
case FOLDER_ROAMING_DATA: folderId = 0; break;
|
||||
case FOLDER_LOCALAPPDATA: folderId = 1; break;
|
||||
case FOLDER_USER_PROFILE: folderId = 2; break;
|
||||
case FOLDER_PROGRAMFILES: folderId = 3; break;
|
||||
case FOLDER_SYSTEMFOLDER: folderId = 4; break;
|
||||
case FOLDER_SYSTROOT_DIR: folderId = 5; break;
|
||||
case MUtils::OS::FOLDER_ROAMING_DATA: return 0U;
|
||||
case MUtils::OS::FOLDER_LOCALAPPDATA: return 1U;
|
||||
case MUtils::OS::FOLDER_USER_PROFILE: return 2U;
|
||||
case MUtils::OS::FOLDER_PROGRAMFILES: return 3U;
|
||||
case MUtils::OS::FOLDER_SYSTEMFOLDER: return 4U;
|
||||
case MUtils::OS::FOLDER_SYSTROOT_DIR: return 5U;
|
||||
default:
|
||||
qWarning("Invalid 'known' folder was requested!");
|
||||
return SIZE_MAX;
|
||||
}
|
||||
}
|
||||
|
||||
const QString &MUtils::OS::known_folder(const known_folder_t folder_id)
|
||||
{
|
||||
//Map to numeric id
|
||||
const size_t folderId = known_folder_decode(folder_id);
|
||||
if (folderId == SIZE_MAX)
|
||||
{
|
||||
return Internal::g_empty;
|
||||
}
|
||||
|
||||
//Obtain read lock
|
||||
QReadLocker readLock(&g_known_folders_lock);
|
||||
|
||||
//Already in cache?
|
||||
@ -757,41 +845,8 @@ const QString &MUtils::OS::known_folder(known_folder_t folder_id)
|
||||
g_known_folders_data.reset(new QHash<size_t, QString>());
|
||||
}
|
||||
|
||||
QString folderPath;
|
||||
|
||||
//Try SHGetKnownFolderPath() first!
|
||||
if(const SHGetKnownFolderPath_t known_folders_fpGetKnownFolderPath = MUtils::Win32Utils::resolve<SHGetKnownFolderPath_t>(QLatin1String("shell32"), QLatin1String("SHGetKnownFolderPath")))
|
||||
{
|
||||
WCHAR *path = NULL;
|
||||
if(known_folders_fpGetKnownFolderPath(s_folders[folderId].guid, KF_FLAG_CREATE, NULL, &path) == S_OK)
|
||||
{
|
||||
//MessageBoxW(0, path, L"SHGetKnownFolderPath", MB_TOPMOST);
|
||||
const QDir folderTemp = QDir(QDir::fromNativeSeparators(MUTILS_QSTR(path)));
|
||||
if(folderTemp.exists())
|
||||
{
|
||||
folderPath = folderTemp.canonicalPath();
|
||||
}
|
||||
CoTaskMemFree(path);
|
||||
}
|
||||
}
|
||||
|
||||
//Fall back to SHGetFolderPathW()
|
||||
if (folderPath.isEmpty())
|
||||
{
|
||||
if (const SHGetFolderPath_t known_folders_fpGetFolderPath = MUtils::Win32Utils::resolve<SHGetFolderPath_t>(QLatin1String("shell32"), QLatin1String("SHGetFolderPathW")))
|
||||
{
|
||||
QScopedArrayPointer<WCHAR> path(new WCHAR[4096]);
|
||||
if (known_folders_fpGetFolderPath(NULL, s_folders[folderId].csidl | CSIDL_FLAG_CREATE, NULL, NULL, path.data()) == S_OK)
|
||||
{
|
||||
//MessageBoxW(0, path, L"SHGetFolderPathW", MB_TOPMOST);
|
||||
const QDir folderTemp = QDir(QDir::fromNativeSeparators(MUTILS_QSTR(path.data())));
|
||||
if (folderTemp.exists())
|
||||
{
|
||||
folderPath = folderTemp.canonicalPath();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//Detect path now!
|
||||
const QString folderPath = known_folder_detect(folderId);
|
||||
|
||||
//Update cache
|
||||
if (!folderPath.isEmpty())
|
||||
|
Loading…
Reference in New Issue
Block a user