Various improvements to known_folder() function.

This commit is contained in:
LoRd_MuldeR 2019-05-13 20:14:08 +02:00
parent 9a898f5d49
commit 60d17ef37e
8 changed files with 131 additions and 76 deletions

View File

@ -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 &amp;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>

View File

@ -156,9 +156,9 @@ MUTILS_API const char *&#160;</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 &amp;&#160;</td><td class="memItemRight" valign="bottom"><b>running_on_wine</b> (void)</td></tr>
<tr class="separator:aa9b386b6e44ec9584a01ff9a8612f573"><td class="memSeparator" colspan="2">&#160;</td></tr>
<tr class="memitem:ab76cf63d91b34f34f50f218563cf6c75"><td class="memItemLeft" align="right" valign="top"><a id="ab76cf63d91b34f34f50f218563cf6c75"></a>
MUTILS_API const QString &amp;&#160;</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">&#160;</td></tr>
<tr class="memitem:a8316cd86318a055ca7e4d953803f86ba"><td class="memItemLeft" align="right" valign="top"><a id="a8316cd86318a055ca7e4d953803f86ba"></a>
MUTILS_API const QString &amp;&#160;</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">&#160;</td></tr>
<tr class="memitem:a186c34bfd3d6256af637635009faf4ea"><td class="memItemLeft" align="right" valign="top"><a id="a186c34bfd3d6256af637635009faf4ea"></a>
MUTILS_API QDate&#160;</td><td class="memItemRight" valign="bottom"><b>current_date</b> (void)</td></tr>
<tr class="separator:a186c34bfd3d6256af637635009faf4ea"><td class="memSeparator" colspan="2">&#160;</td></tr>

View File

@ -186,9 +186,9 @@ MUTILS_API const char *&#160;</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 &amp;&#160;</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">&#160;</td></tr>
<tr class="memitem:ab76cf63d91b34f34f50f218563cf6c75"><td class="memItemLeft" align="right" valign="top"><a id="ab76cf63d91b34f34f50f218563cf6c75"></a>
MUTILS_API const QString &amp;&#160;</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">&#160;</td></tr>
<tr class="memitem:a8316cd86318a055ca7e4d953803f86ba"><td class="memItemLeft" align="right" valign="top"><a id="a8316cd86318a055ca7e4d953803f86ba"></a>
MUTILS_API const QString &amp;&#160;</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">&#160;</td></tr>
<tr class="memitem:a186c34bfd3d6256af637635009faf4ea"><td class="memItemLeft" align="right" valign="top"><a id="a186c34bfd3d6256af637635009faf4ea"></a>
MUTILS_API QDate&#160;</td><td class="memItemRight" valign="bottom"><b>MUtils::OS::current_date</b> (void)</td></tr>
<tr class="separator:a186c34bfd3d6256af637635009faf4ea"><td class="memSeparator" colspan="2">&#160;</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

View File

@ -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);

View File

@ -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())