(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 <windows.h>
|
||||||
#include <shellapi.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
|
static std::wstring ConvertToWString(const std::string& str)
|
||||||
* not crash-conditions safe. */
|
|
||||||
static LONG GetRegKey( HKEY key, RString subkey, LPTSTR retdata )
|
|
||||||
{
|
{
|
||||||
HKEY hKey;
|
int size_needed = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), (int)str.size(), nullptr, 0);
|
||||||
LONG iRet = RegOpenKeyEx( key, subkey, 0, KEY_QUERY_VALUE, &hKey );
|
std::wstring wstrTo(size_needed, 0);
|
||||||
|
MultiByteToWideChar(CP_UTF8, 0, str.c_str(), (int)str.size(), &wstrTo[0], size_needed);
|
||||||
if( iRet != ERROR_SUCCESS )
|
return wstrTo;
|
||||||
return iRet;
|
|
||||||
|
|
||||||
long iDataSize = MAX_PATH;
|
|
||||||
char data[MAX_PATH];
|
|
||||||
RegQueryValue( hKey, "emulation", data, &iDataSize );
|
|
||||||
strcpy( retdata, data );
|
|
||||||
RegCloseKey( hKey );
|
|
||||||
|
|
||||||
return ERROR_SUCCESS;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GotoURL( RString sUrl )
|
static LONG GetRegKey(HKEY key, const std::wstring& subkey, std::wstring& retdata)
|
||||||
{
|
{
|
||||||
// First try ShellExecute()
|
HKEY hKey;
|
||||||
intptr_t iRet = reinterpret_cast<intptr_t>(ShellExecute( nullptr, "open", sUrl, nullptr, nullptr, SW_SHOWDEFAULT ));
|
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 != ERROR_SUCCESS)
|
||||||
if( iRet > 32 )
|
{
|
||||||
|
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;
|
return true;
|
||||||
|
|
||||||
char key[2*MAX_PATH];
|
// If it failed, get the .htm regkey and lookup the program
|
||||||
if( GetRegKey(HKEY_CLASSES_ROOT, ".htm", key) != ERROR_SUCCESS )
|
std::wstring key;
|
||||||
|
if (GetRegKey(HKEY_CLASSES_ROOT, L".htm", key) != ERROR_SUCCESS)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
strcpy( key, "\\shell\\open\\command" );
|
key += L"\\shell\\open\\command";
|
||||||
|
|
||||||
if( GetRegKey(HKEY_CLASSES_ROOT, key, key) != ERROR_SUCCESS )
|
if( GetRegKey(HKEY_CLASSES_ROOT, key, key) != ERROR_SUCCESS )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
char *szPos = strstr( key, "\"%1\"" );
|
size_t pos = key.find(L"\"%1\"");
|
||||||
if( szPos == nullptr )
|
if (pos == std::wstring::npos)
|
||||||
{
|
{
|
||||||
// No quotes found. Check for %1 without quotes
|
// No quotes found. Check for %1 without quotes
|
||||||
szPos = strstr( key, "%1" );
|
pos = key.find(L"%1");
|
||||||
if( szPos == nullptr )
|
if (pos == std::wstring::npos)
|
||||||
szPos = key+lstrlen(key)-1; // No parameter.
|
pos = key.length() - 1; // No parameter.
|
||||||
else
|
else
|
||||||
*szPos = '\0'; // Remove the parameter
|
key.erase(pos); // Remove the parameter
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
*szPos = '\0'; // Remove the parameter
|
{
|
||||||
|
key.erase(pos); // Remove the parameter
|
||||||
|
}
|
||||||
|
|
||||||
strcat( szPos, " " );
|
key += L" " + iUrl;
|
||||||
strcat( szPos, sUrl );
|
|
||||||
|
|
||||||
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
|
#define GOTO_URL_H
|
||||||
|
|
||||||
/** @brief Open URLs in a browser. */
|
/** @brief Open URLs in a browser. */
|
||||||
bool GotoURL( RString sUrl );
|
bool GotoURL( const RString& sUrl );
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user