Lookup can parse hex numbers

git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@7253 212acab6-be3b-0410-9dea-997c60f758d6
This commit is contained in:
anders_k 2021-01-19 03:31:07 +00:00
parent c076ace51e
commit b7acb6a79e
4 changed files with 38 additions and 29 deletions

View file

@ -34,16 +34,19 @@ template<class T> static LPWSTR SmartStrTToW(T*Src, LPWSTR Dst, UINT cch)
return (StrTToW(Src, Dst, cch), Dst); return (StrTToW(Src, Dst, cch), Dst);
} }
#define StrToSInt StrBase10ToSInt #define StrBase10ToSInt(s) StrToSInt((s), 10)
template<class T> static int WINAPI StrBase10ToSInt(const T*str) template<class T> static int WINAPI StrToSInt(const T*Str, UINT Base = 0)
{ {
unsigned int v = 0, neg = 0, c, i = 0, base = 10; if (Base && !(*Str >= '0' && *Str <= '9') && *Str != '-') return 0; // Don't allow leading space
if (str[i] == '-') ++neg, ++i; int v, succ;
for (; (c = str[i]) >= T('0') && c <= T('9'); ++i) c -= T('0'), v *= base, v += c; if (sizeof(*Str) > 1)
return neg ? (int) v * -1 : v; succ = StrToIntExW((WCHAR*) Str, Base != 10 ? STIF_SUPPORT_HEX : STIF_DEFAULT, &v);
else
succ = StrToIntExA((CHAR *) Str, Base != 10 ? STIF_SUPPORT_HEX : STIF_DEFAULT, &v);
return succ ? v : 0; // Not full base support, we only need 10 and 16
} }
template<class T> static ULARGE_INTEGER WINAPI PathParseIconLocationEx(T*Path) template<class T> static ULARGE_INTEGER PathParseIconLocationEx(T*Path)
{ {
ULARGE_INTEGER li; ULARGE_INTEGER li;
int idx = 0; int idx = 0;
@ -130,7 +133,6 @@ template<class I, class O> static HKEY ParseRegPath(I*In, O*&Path, O*&Name)
return (Path = const_cast<O*>(pp), Name = const_cast<O*>(pn), hKey); return (Path = const_cast<O*>(pp), Name = const_cast<O*>(pn), hKey);
} }
HRESULT (WINAPI*g_SHLIS)(LPCWSTR s, LPWSTR o, UINT cch, PVOID*ppvReserved);
HRESULT (WINAPI*g_RLMSOld)(HKEY hKey, LPCWSTR pszValue, LPWSTR pszOutBuf, DWORD cbOutBuf); HRESULT (WINAPI*g_RLMSOld)(HKEY hKey, LPCWSTR pszValue, LPWSTR pszOutBuf, DWORD cbOutBuf);
static LSTATUS WINAPI RegLoadMUIStringFallbackW(HKEY hKey, LPCWSTR Name, LPWSTR Out, DWORD cbOutBuf, LPDWORD pcbData, DWORD Flags, LPCSTR pszDirectory) static LSTATUS WINAPI RegLoadMUIStringFallbackW(HKEY hKey, LPCWSTR Name, LPWSTR Out, DWORD cbOutBuf, LPDWORD pcbData, DWORD Flags, LPCSTR pszDirectory)
@ -154,6 +156,7 @@ enum { LM_SHGLN, LM_SHLIS, LM_RLMS, LM_PPIL, LM_FMTMSG };
LPCSTR g_ModeLbl[] = { "Path:", "Path:", "Registry:", "Path:", "[Path,]Number:" }; LPCSTR g_ModeLbl[] = { "Path:", "Path:", "Registry:", "Path:", "[Path,]Number:" };
struct DIALOGDATA { struct DIALOGDATA {
HRESULT (WINAPI*SHLIS)(LPCWSTR s, LPWSTR o, UINT cch, PVOID*ppvReserved);
HRESULT (WINAPI*SHGLN)(PCWSTR p, PWSTR m, UINT cch, int*rid); HRESULT (WINAPI*SHGLN)(PCWSTR p, PWSTR m, UINT cch, int*rid);
LSTATUS (WINAPI*RLMS)(HKEY hKey, LPCWSTR pszValue, LPWSTR pszOutBuf, DWORD cbOutBuf, LPDWORD pcbData, DWORD Flags, LPCSTR pszDirectory); LSTATUS (WINAPI*RLMS)(HKEY hKey, LPCWSTR pszValue, LPWSTR pszOutBuf, DWORD cbOutBuf, LPDWORD pcbData, DWORD Flags, LPCSTR pszDirectory);
int (WINAPI*PPIL)(LPTSTR p); int (WINAPI*PPIL)(LPTSTR p);
@ -183,9 +186,9 @@ static INT_PTR CALLBACK LookupDlgProc(HWND hDlg, UINT Msg, WPARAM WParam, LPARAM
pDD->hExtra = GetDlgItem(hDlg, IDC_LUEXTRATEXT); pDD->hExtra = GetDlgItem(hDlg, IDC_LUEXTRATEXT);
pDD->hOutTxt = GetDlgItem(hDlg, IDC_LUOUTPUTTEXT); pDD->hOutTxt = GetDlgItem(hDlg, IDC_LUOUTPUTTEXT);
pDD->hOutIco = CreateWindowEx(WS_EX_TRANSPARENT, _T("STATIC"), 0, WS_CHILD|WS_VISIBLE|SS_ICON|SS_CENTERIMAGE|SS_REALSIZECONTROL, 0, 0, 0, 0, pDD->hOutTxt, 0, 0, 0); pDD->hOutIco = CreateWindowEx(WS_EX_TRANSPARENT, _T("STATIC"), 0, WS_CHILD|WS_VISIBLE|SS_ICON|SS_CENTERIMAGE|SS_REALSIZECONTROL, 0, 0, 0, 0, pDD->hOutTxt, 0, 0, 0);
if (pDD->SHGLN) AddComboStringWithData(pDD->hMode, "SHGetLocalizedName", LM_SHGLN); if (pDD->SHLIS) AddComboStringWithData(pDD->hMode, "SHLoadIndirectString", LM_SHLIS);
if (g_SHLIS) AddComboStringWithData(pDD->hMode, "SHLoadIndirectString", LM_SHLIS);
if (pDD->RLMS) AddComboStringWithData(pDD->hMode, "RegLoadMUIString", LM_RLMS); if (pDD->RLMS) AddComboStringWithData(pDD->hMode, "RegLoadMUIString", LM_RLMS);
if (pDD->SHGLN) AddComboStringWithData(pDD->hMode, "SHGetLocalizedName", LM_SHGLN);
if (pDD->PPIL) AddComboStringWithData(pDD->hMode, "PathParseIconLocation", LM_PPIL); if (pDD->PPIL) AddComboStringWithData(pDD->hMode, "PathParseIconLocation", LM_PPIL);
AddComboStringWithData(pDD->hMode, "FormatMessage", LM_FMTMSG); AddComboStringWithData(pDD->hMode, "FormatMessage", LM_FMTMSG);
SNDMSG(pDD->hExtra, EM_LIMITTEXT, COUNTOF(buf), 0); SNDMSG(pDD->hExtra, EM_LIMITTEXT, COUNTOF(buf), 0);
@ -270,7 +273,7 @@ static INT_PTR CALLBACK LookupDlgProc(HWND hDlg, UINT Msg, WPARAM WParam, LPARAM
{ {
WCHAR is[COUNTOF(buf)], os[MAX_PATH], *pis; WCHAR is[COUNTOF(buf)], os[MAX_PATH], *pis;
pis = SmartStrTToW(buf, is, COUNTOF(is)); pis = SmartStrTToW(buf, is, COUNTOF(is));
hr = g_SHLIS(pis, os, COUNTOF(os), NULL); hr = pDD->SHLIS(pis, os, COUNTOF(os), NULL);
if (FAILED(hr)) goto die_hr; if (FAILED(hr)) goto die_hr;
AppendText(pDD->hOutTxt, os); AppendText(pDD->hOutTxt, os);
} }
@ -321,7 +324,6 @@ static INT_PTR CALLBACK LookupDlgProc(HWND hDlg, UINT Msg, WPARAM WParam, LPARAM
if (!FormatMessage(flags, hMod, hr, 0, buf, COUNTOF(buf), NULL)) badmsgmod: if (!FormatMessage(flags, hMod, hr, 0, buf, COUNTOF(buf), NULL)) badmsgmod:
{ {
hr = GetLastError(); hr = GetLastError();
AppendText(pDD->hOutTxt, "(Could not find message) ");
goto die_hr; goto die_hr;
} }
if (hMod) FreeLibrary(hMod); if (hMod) FreeLibrary(hMod);
@ -339,18 +341,18 @@ static INT_PTR CALLBACK LookupDlgProc(HWND hDlg, UINT Msg, WPARAM WParam, LPARAM
INT_PTR ShowLookupDialog(HWND hOwner) INT_PTR ShowLookupDialog(HWND hOwner)
{ {
DIALOGDATA dd; DIALOGDATA dd;
(FARPROC&) dd.SHGLN = GetSysProcAddr("SHELL32", "SHGetLocalizedName"); (FARPROC&) dd.SHLIS = GetSysProcAddr("SHLWAPI", "SHLoadIndirectString"); // WXP+
(FARPROC&) g_SHLIS = GetSysProcAddr("SHLWAPI", (LPCSTR) 487); (FARPROC&) dd.SHGLN = GetSysProcAddr("SHELL32", "SHGetLocalizedName"); // WVista+
(FARPROC&) dd.RLMS = GetSysProcAddr("ADVAPI32", "RegLoadMUIStringW"); // Note: RegLoadMUIStringA always returns ERROR_CALL_NOT_IMPLEMENTED (FARPROC&) dd.RLMS = GetSysProcAddr("ADVAPI32", "RegLoadMUIStringW"); // WVista+ Note: RegLoadMUIStringA always returns ERROR_CALL_NOT_IMPLEMENTED
if (!dd.RLMS && ((FARPROC&) g_RLMSOld = GetSysProcAddr("SHLWAPI", (LPCSTR) 439))) dd.RLMS = RegLoadMUIStringFallbackW; if (!dd.RLMS && ((FARPROC&) g_RLMSOld = GetSysProcAddr("SHLWAPI", (LPCSTR) 439))) dd.RLMS = RegLoadMUIStringFallbackW; // W98SE+,IE5+
(FARPROC&) dd.PPIL = (FARPROC&) dd.PPIL =
#ifdef _WIN64 #ifdef _WIN64
(FARPROC) PathParseIconLocation; (FARPROC) PathParseIconLocation;
#else #else
GetSysProcAddr("SHLWAPI", sizeof(TCHAR) == 1 ? "PathParseIconLocationA" : "PathParseIconLocationW"); GetSysProcAddr("SHLWAPI", sizeof(TCHAR) == 1 ? "PathParseIconLocationA" : "PathParseIconLocationW"); // W95OSR2+,IE3.1+
if (!dd.PPIL || (SupportsWNT4() || IsWin9598ME())) if (!dd.PPIL || (SupportsWNT4() || IsWin9598ME()))
{ {
(FARPROC&) dd.PPIL = GetSysProcAddr("SHELL32", (LPCSTR) 249); // PathParseIconLocationT (FARPROC&) dd.PPIL = GetSysProcAddr("SHELL32", (LPCSTR) 249); // WNT4+ PathParseIconLocationT
if (sizeof(TCHAR) == 1) (FARPROC&) dd.PPIL = (FARPROC) PathParseIconLocationFallback<CHAR>; if (sizeof(TCHAR) == 1) (FARPROC&) dd.PPIL = (FARPROC) PathParseIconLocationFallback<CHAR>;
} }
#endif #endif

View file

@ -39,8 +39,8 @@
#define SupportsW95() ( FALSE && SupportsW9X() && !DpiAwarePerMonitor() ) #define SupportsW95() ( FALSE && SupportsW9X() && !DpiAwarePerMonitor() )
#define SupportsW2000() ( sizeof(void*) == 4 ) #define SupportsW2000() ( sizeof(void*) == 4 )
static bool IsWin9598ME() { return SupportsW9X() && (int) GetVersion() < 0; } static inline bool IsWin9598ME() { return SupportsW9X() && (int) GetVersion() < 0; }
static bool IsWin95() { return SupportsW95() && (GetVersion() & (0x8000FFFF & ~0x0300)) == 0x80000004; } static inline bool IsWin95() { return SupportsW95() && (GetVersion() & (0x8000FFFF & ~0x0300)) == 0x80000004; }
// Defines // Defines
#define NSIS_URL "https://nsis.sourceforge.io/" #define NSIS_URL "https://nsis.sourceforge.io/"

View file

@ -281,11 +281,11 @@ STYLE DS_SETFONT | DS_FIXEDSYS | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSM
CAPTION "Lookup" CAPTION "Lookup"
FONT 8, "MS Shell Dlg", 0, 0, 0x0 FONT 8, "MS Shell Dlg", 0, 0, 0x0
BEGIN BEGIN
CONTROL "Source", -1, BUTTON, BS_GROUPBOX | WS_CHILD | WS_VISIBLE, 7, 7, 285, 65 GROUPBOX "Source", 0, 7, 7, 285, 65
CONTROL "", IDC_LUMODE, COMBOBOX, CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 16, 20, 268, 114 COMBOBOX IDC_LUMODE, 16, 20, 268, 114, CBS_DROPDOWNLIST | CBS_HASSTRINGS | WS_CHILD | WS_VISIBLE | WS_TABSTOP
CONTROL "", IDC_LUEXTRALABEL, STATIC, SS_LEFT | WS_CHILD | WS_VISIBLE | WS_GROUP, 16, 38, 268, 10 CONTROL "", IDC_LUEXTRALABEL, "Static", SS_LEFT | WS_CHILD | WS_VISIBLE | WS_GROUP, 16, 38, 268, 10
CONTROL "", IDC_LUEXTRATEXT, EDIT, ES_LEFT | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP, 16, 50, 268, 14 CONTROL "", IDC_LUEXTRATEXT, "Edit", ES_LEFT | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP, 16, 50, 268, 14
CONTROL "", IDC_LUOUTPUTTEXT, EDIT, ES_LEFT | ES_MULTILINE | ES_AUTOVSCROLL | ES_READONLY | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_VSCROLL | WS_TABSTOP, 7, 80, 286, 60 CONTROL "", IDC_LUOUTPUTTEXT, "Edit", ES_LEFT | ES_MULTILINE | ES_AUTOVSCROLL | ES_READONLY | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_VSCROLL | WS_TABSTOP, 7, 80, 286, 60
END END
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////

View file

@ -95,9 +95,16 @@ static BOOL GetLogicalWindowRect(HWND hWnd, RECT&Rect, HWND hWndCaller)
} }
static HWND GetParentWindow(HWND hWnd) static HWND GetParentWindow(HWND hWnd)
{
HWND r = GetParent(hWnd); // Parent or owner
return r != GetWindow(hWnd, GW_OWNER) ? r : NULL;
}
static HWND GetAncestorRoot(HWND hWnd)
{ {
HWND hParent = GetAncestor(hWnd, GA_PARENT); // Parent but NOT owner. if (!SupportsWNT4() && !SupportsW95()) return GetAncestor(hWnd, GA_ROOT);
return hParent == GetParent(hWnd) ? hParent : NULL; // Filter away GetDesktopWindow(). for (HWND hTmp; (hTmp = GetParentWindow(hWnd)); ) hWnd = hTmp;
return hWnd;
} }
typedef struct _DIALOGDATA { typedef struct _DIALOGDATA {
@ -319,7 +326,7 @@ static INT_PTR CALLBACK SpyDlgProc(HWND hDlg, UINT Msg, WPARAM WParam, LPARAM LP
break; break;
pDD->hWndTarget = hWnd; pDD->hWndTarget = hWnd;
if (GetAncestor(hWnd, GA_ROOT) == hDlg) if (GetAncestorRoot(hWnd) == hDlg)
hWnd = 0; hWnd = 0;
ShowWindowInfo(hDlg, hWnd); ShowWindowInfo(hDlg, hWnd);
@ -336,7 +343,7 @@ static INT_PTR CALLBACK SpyDlgProc(HWND hDlg, UINT Msg, WPARAM WParam, LPARAM LP
SetWindowPos(pDD->hWndOutline, HWND_BOTTOM, -32767, -32767, 1, 1, SWP_SHOWWINDOW|SWP_NOCOPYBITS|SWP_NOACTIVATE|SWP_NOOWNERZORDER); // MSDN says LogicalToPhysicalPoint requires a visible window SetWindowPos(pDD->hWndOutline, HWND_BOTTOM, -32767, -32767, 1, 1, SWP_SHOWWINDOW|SWP_NOCOPYBITS|SWP_NOACTIVATE|SWP_NOOWNERZORDER); // MSDN says LogicalToPhysicalPoint requires a visible window
RECT r; RECT r;
GetPhysicalWindowRect(pDD->hWndTarget, r, hDlg), PhysicalToLogical(pDD->hWndOutline, r, hDlg); GetPhysicalWindowRect(pDD->hWndTarget, r, hDlg), PhysicalToLogical(pDD->hWndOutline, r, hDlg);
if (GetAncestor(pDD->hWndTarget, GA_ROOT) != hDlg) if (GetAncestorRoot(pDD->hWndTarget) != hDlg)
{ {
SetWindowPos(pDD->hWndOutline, HWND_TOPMOST, r.left, r.top, r.right - r.left, r.bottom - r.top, SWP_HIDEWINDOW|SWP_NOCOPYBITS|SWP_NOACTIVATE|SWP_NOOWNERZORDER); SetWindowPos(pDD->hWndOutline, HWND_TOPMOST, r.left, r.top, r.right - r.left, r.bottom - r.top, SWP_HIDEWINDOW|SWP_NOCOPYBITS|SWP_NOACTIVATE|SWP_NOOWNERZORDER);
ShowWindow(pDD->hWndOutline, SW_SHOW); // To avoid a small Windows redraw bug, don't show the window until after it has the correct size ShowWindow(pDD->hWndOutline, SW_SHOW); // To avoid a small Windows redraw bug, don't show the window until after it has the correct size