diff options
Diffstat (limited to 'other-licenses/nsis/Contrib/WebBrowser/CustomFunctions.cpp')
-rw-r--r-- | other-licenses/nsis/Contrib/WebBrowser/CustomFunctions.cpp | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/other-licenses/nsis/Contrib/WebBrowser/CustomFunctions.cpp b/other-licenses/nsis/Contrib/WebBrowser/CustomFunctions.cpp new file mode 100644 index 0000000000..4ad004b841 --- /dev/null +++ b/other-licenses/nsis/Contrib/WebBrowser/CustomFunctions.cpp @@ -0,0 +1,75 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0.If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +#include "WebBrowser.h" +#include "exdll.h" + +extern WebBrowser* gBrowser; +void Init(HWND hWndParent, int string_size, TCHAR* variables, + stack_t** stacktop, extra_parameters* extra); + +static void CustomFunctionWrapper(void* NSISFunctionAddr, VARIANT jsArg, + VARIANT* retVal) { + // Marshal the argument passed to the JavaScript function onto the NSIS stack. + switch (jsArg.vt) { + case VT_BSTR: + pushstring(jsArg.bstrVal); + break; + case VT_I4: { + TCHAR intArgStr[32] = _T(""); + _itot_s(jsArg.intVal, intArgStr, 10); + pushstring(intArgStr); + break; + } + case VT_BOOL: + pushstring(jsArg.boolVal == VARIANT_TRUE ? _T("1") : _T("0")); + break; + default: + // No other argument types supported. + pushstring(_T("")); + break; + } + + // Call the NSIS function. + int rv = g_executeCodeSegment((int)NSISFunctionAddr, nullptr); + + // Retrieve the return value from the NSIS stack. + TCHAR* nsisRetval = + (TCHAR*)HeapAlloc(GetProcessHeap(), 0, g_stringsize * sizeof(TCHAR)); + popstring(nsisRetval); + + // Pass the return value back to JavaScript, if it asked for one. + if (retVal) { + VariantInit(retVal); + retVal->vt = VT_BSTR; + retVal->bstrVal = SysAllocString(nsisRetval); + } + + HeapFree(GetProcessHeap(), 0, nsisRetval); +} + +PLUGINFUNCTION(RegisterCustomFunction) { + if (!gBrowser) { + Init(hWndParent, string_size, variables, stacktop, extra); + } + + TCHAR* funcAddrStr = + (TCHAR*)HeapAlloc(GetProcessHeap(), 0, g_stringsize * sizeof(TCHAR)); + popstring(funcAddrStr); + + TCHAR* funcName = + (TCHAR*)HeapAlloc(GetProcessHeap(), 0, g_stringsize * sizeof(TCHAR)); + popstring(funcName); + + if (gBrowser && funcAddrStr && funcName) { + // Apparently GetFunctionAddress returnes a 1-indexed offset, but + // ExecuteCodeSegment expects a 0-indexed one. Or something. + uintptr_t funcAddr = static_cast<uintptr_t>(_ttoi64(funcAddrStr)) - 1; + gBrowser->AddCustomFunction(funcName, CustomFunctionWrapper, + (void*)funcAddr); + } + + HeapFree(GetProcessHeap(), 0, funcName); + HeapFree(GetProcessHeap(), 0, funcAddrStr); +} |