CustomFunctions.cpp (2383B)
1 // This Source Code Form is subject to the terms of the Mozilla Public 2 // License, v. 2.0.If a copy of the MPL was not distributed with this 3 // file, You can obtain one at http://mozilla.org/MPL/2.0/. 4 5 #include "WebBrowser.h" 6 #include "exdll.h" 7 8 extern WebBrowser* gBrowser; 9 void Init(HWND hWndParent, int string_size, TCHAR* variables, 10 stack_t** stacktop, extra_parameters* extra); 11 12 static void CustomFunctionWrapper(void* NSISFunctionAddr, VARIANT jsArg, 13 VARIANT* retVal) { 14 // Marshal the argument passed to the JavaScript function onto the NSIS stack. 15 switch (jsArg.vt) { 16 case VT_BSTR: 17 pushstring(jsArg.bstrVal); 18 break; 19 case VT_I4: { 20 TCHAR intArgStr[32] = _T(""); 21 _itot_s(jsArg.intVal, intArgStr, 10); 22 pushstring(intArgStr); 23 break; 24 } 25 case VT_BOOL: 26 pushstring(jsArg.boolVal == VARIANT_TRUE ? _T("1") : _T("0")); 27 break; 28 default: 29 // No other argument types supported. 30 pushstring(_T("")); 31 break; 32 } 33 34 // Call the NSIS function. 35 int rv = g_executeCodeSegment((int)NSISFunctionAddr, nullptr); 36 37 // Retrieve the return value from the NSIS stack. 38 TCHAR* nsisRetval = 39 (TCHAR*)HeapAlloc(GetProcessHeap(), 0, g_stringsize * sizeof(TCHAR)); 40 popstring(nsisRetval); 41 42 // Pass the return value back to JavaScript, if it asked for one. 43 if (retVal) { 44 VariantInit(retVal); 45 retVal->vt = VT_BSTR; 46 retVal->bstrVal = SysAllocString(nsisRetval); 47 } 48 49 HeapFree(GetProcessHeap(), 0, nsisRetval); 50 } 51 52 PLUGINFUNCTION(RegisterCustomFunction) { 53 if (!gBrowser) { 54 Init(hWndParent, string_size, variables, stacktop, extra); 55 } 56 57 TCHAR* funcAddrStr = 58 (TCHAR*)HeapAlloc(GetProcessHeap(), 0, g_stringsize * sizeof(TCHAR)); 59 popstring(funcAddrStr); 60 61 TCHAR* funcName = 62 (TCHAR*)HeapAlloc(GetProcessHeap(), 0, g_stringsize * sizeof(TCHAR)); 63 popstring(funcName); 64 65 if (gBrowser && funcAddrStr && funcName) { 66 // Apparently GetFunctionAddress returnes a 1-indexed offset, but 67 // ExecuteCodeSegment expects a 0-indexed one. Or something. 68 uintptr_t funcAddr = static_cast<uintptr_t>(_ttoi64(funcAddrStr)) - 1; 69 gBrowser->AddCustomFunction(funcName, CustomFunctionWrapper, 70 (void*)funcAddr); 71 } 72 73 HeapFree(GetProcessHeap(), 0, funcName); 74 HeapFree(GetProcessHeap(), 0, funcAddrStr); 75 }