(Win32 refresh) GotoURL
Mitigate some security concerns, update API calls (RegOpenKeyExW & ShellExecuteEx), support unicode natively, const correctness, etc. - not doing anything new, just updating what's here to be more modern.
This commit is contained in:
@@ -5,61 +5,100 @@
|
||||
|
||||
#include <windows.h>
|
||||
#include <shellapi.h>
|
||||
#include <string>
|
||||
#include <codecvt>
|
||||
#include <locale>
|
||||
#include <vector>
|
||||
|
||||
/* This is called from the crash handler; don't use RegistryAccess, since it's
|
||||
* not crash-conditions safe. */
|
||||
static LONG GetRegKey( HKEY key, RString subkey, LPTSTR retdata )
|
||||
static std::wstring ConvertToWString(const std::string& str)
|
||||
{
|
||||
HKEY hKey;
|
||||
LONG iRet = RegOpenKeyEx( key, subkey, 0, KEY_QUERY_VALUE, &hKey );
|
||||
|
||||
if( iRet != ERROR_SUCCESS )
|
||||
return iRet;
|
||||
|
||||
long iDataSize = MAX_PATH;
|
||||
char data[MAX_PATH];
|
||||
RegQueryValue( hKey, "emulation", data, &iDataSize );
|
||||
strcpy( retdata, data );
|
||||
RegCloseKey( hKey );
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
int size_needed = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), (int)str.size(), nullptr, 0);
|
||||
std::wstring wstrTo(size_needed, 0);
|
||||
MultiByteToWideChar(CP_UTF8, 0, str.c_str(), (int)str.size(), &wstrTo[0], size_needed);
|
||||
return wstrTo;
|
||||
}
|
||||
|
||||
bool GotoURL( RString sUrl )
|
||||
static LONG GetRegKey(HKEY key, const std::wstring& subkey, std::wstring& retdata)
|
||||
{
|
||||
// First try ShellExecute()
|
||||
intptr_t iRet = reinterpret_cast<intptr_t>(ShellExecute( nullptr, "open", sUrl, nullptr, nullptr, SW_SHOWDEFAULT ));
|
||||
HKEY hKey;
|
||||
LONG iRet = RegOpenKeyExW(key, subkey.c_str(), 0, KEY_QUERY_VALUE, &hKey);
|
||||
|
||||
// If it failed, get the .htm regkey and lookup the program
|
||||
if( iRet > 32 )
|
||||
if (iRet != ERROR_SUCCESS)
|
||||
{
|
||||
return iRet;
|
||||
}
|
||||
|
||||
DWORD iDataSize = 0;
|
||||
iRet = RegQueryValueExW(hKey, L"emulation", nullptr, nullptr, nullptr, &iDataSize);
|
||||
if (iRet != ERROR_SUCCESS)
|
||||
{
|
||||
RegCloseKey(hKey);
|
||||
return iRet;
|
||||
}
|
||||
|
||||
std::vector<wchar_t> data(iDataSize / sizeof(wchar_t));
|
||||
iRet = RegQueryValueExW(hKey, L"emulation", nullptr, nullptr, reinterpret_cast<LPBYTE>(data.data()), &iDataSize);
|
||||
if (iRet == ERROR_SUCCESS)
|
||||
{
|
||||
retdata.assign(data.begin(), data.end() - 1);
|
||||
}
|
||||
|
||||
RegCloseKey(hKey);
|
||||
return iRet;
|
||||
}
|
||||
|
||||
bool GotoURL(const RString& sUrl)
|
||||
{
|
||||
// Convert RString to std::wstring
|
||||
std::wstring iUrl = ConvertToWString(sUrl);
|
||||
|
||||
// First try ShellExecuteEx
|
||||
SHELLEXECUTEINFOW sei = { sizeof(sei) };
|
||||
sei.lpVerb = L"open";
|
||||
sei.lpFile = iUrl.c_str();
|
||||
sei.nShow = SW_SHOWDEFAULT;
|
||||
sei.fMask = SEE_MASK_FLAG_NO_UI;
|
||||
|
||||
if (ShellExecuteExW(&sei) && reinterpret_cast<intptr_t>(sei.hInstApp) > 32)
|
||||
return true;
|
||||
|
||||
char key[2*MAX_PATH];
|
||||
if( GetRegKey(HKEY_CLASSES_ROOT, ".htm", key) != ERROR_SUCCESS )
|
||||
// If it failed, get the .htm regkey and lookup the program
|
||||
std::wstring key;
|
||||
if (GetRegKey(HKEY_CLASSES_ROOT, L".htm", key) != ERROR_SUCCESS)
|
||||
return false;
|
||||
|
||||
strcpy( key, "\\shell\\open\\command" );
|
||||
key += L"\\shell\\open\\command";
|
||||
|
||||
if( GetRegKey(HKEY_CLASSES_ROOT, key, key) != ERROR_SUCCESS )
|
||||
return false;
|
||||
|
||||
char *szPos = strstr( key, "\"%1\"" );
|
||||
if( szPos == nullptr )
|
||||
size_t pos = key.find(L"\"%1\"");
|
||||
if (pos == std::wstring::npos)
|
||||
{
|
||||
// No quotes found. Check for %1 without quotes
|
||||
szPos = strstr( key, "%1" );
|
||||
if( szPos == nullptr )
|
||||
szPos = key+lstrlen(key)-1; // No parameter.
|
||||
pos = key.find(L"%1");
|
||||
if (pos == std::wstring::npos)
|
||||
pos = key.length() - 1; // No parameter.
|
||||
else
|
||||
*szPos = '\0'; // Remove the parameter
|
||||
key.erase(pos); // Remove the parameter
|
||||
}
|
||||
else
|
||||
*szPos = '\0'; // Remove the parameter
|
||||
{
|
||||
key.erase(pos); // Remove the parameter
|
||||
}
|
||||
|
||||
strcat( szPos, " " );
|
||||
strcat( szPos, sUrl );
|
||||
key += L" " + iUrl;
|
||||
|
||||
return WinExec( key, SW_SHOWDEFAULT ) > 32;
|
||||
STARTUPINFOW si = { sizeof(si) };
|
||||
PROCESS_INFORMATION pi;
|
||||
if (CreateProcessW(nullptr, &key[0], nullptr, nullptr, FALSE, 0, nullptr, nullptr, &si, &pi))
|
||||
{
|
||||
CloseHandle(pi.hProcess);
|
||||
CloseHandle(pi.hThread);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#define GOTO_URL_H
|
||||
|
||||
/** @brief Open URLs in a browser. */
|
||||
bool GotoURL( RString sUrl );
|
||||
bool GotoURL( const RString& sUrl );
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
Reference in New Issue
Block a user