Skip to content

Commit

Permalink
win: fix delay-load hook for electron 4
Browse files Browse the repository at this point in the history
PR-URL: #1566
Reviewed-By: Refael Ackermann <[email protected]>
  • Loading branch information
adill authored and rvagg committed Apr 24, 2019
1 parent 6f5a408 commit d3b2122
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 9 deletions.
4 changes: 3 additions & 1 deletion addon.gypi
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
'variables' : {
'node_engine_include_dir%': 'deps/v8/include',
'node_host_binary%': 'node'
},
'target_defaults': {
'type': 'loadable_module',
Expand Down Expand Up @@ -70,12 +71,13 @@
# is named node.exe, iojs.exe, or something else.
'conditions': [
[ 'OS=="win"', {
'defines': [ 'HOST_BINARY=\"<(node_host_binary)<(EXECUTABLE_SUFFIX)\"', ],
'sources': [
'<(node_gyp_dir)/src/win_delay_load_hook.cc',
],
'msvs_settings': {
'VCLinkerTool': {
'DelayLoadDLLs': [ 'iojs.exe', 'node.exe' ],
'DelayLoadDLLs': [ '<(node_host_binary)<(EXECUTABLE_SUFFIX)' ],
# Don't print a linker warning when no imports from either .exe
# are used.
'AdditionalOptions': [ '/ignore:4199' ],
Expand Down
11 changes: 5 additions & 6 deletions src/win_delay_load_hook.cc
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
/*
* When this file is linked to a DLL, it sets up a delay-load hook that
* intervenes when the DLL is trying to load 'node.exe' or 'iojs.exe'
* dynamically. Instead of trying to locate the .exe file it'll just return
* a handle to the process image.
* intervenes when the DLL is trying to load the host executable
* dynamically. Instead of trying to locate the .exe file it'll just
* return a handle to the process image.
*
* This allows compiled addons to work when node.exe or iojs.exe is renamed.
* This allows compiled addons to work when the host executable is renamed.
*/

#ifdef _MSC_VER
Expand All @@ -23,8 +23,7 @@ static FARPROC WINAPI load_exe_hook(unsigned int event, DelayLoadInfo* info) {
if (event != dliNotePreLoadLibrary)
return NULL;

if (_stricmp(info->szDll, "iojs.exe") != 0 &&
_stricmp(info->szDll, "node.exe") != 0)
if (_stricmp(info->szDll, HOST_BINARY) != 0)
return NULL;

m = GetModuleHandle(NULL);
Expand Down
35 changes: 33 additions & 2 deletions test/test-addon.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,19 @@ var test = require('tape')
var path = require('path')
var fs = require('graceful-fs')
var child_process = require('child_process')
var os = require('os')
var addonPath = path.resolve(__dirname, 'node_modules', 'hello_world')
var nodeGyp = path.resolve(__dirname, '..', 'bin', 'node-gyp.js')
var execFileSync = child_process.execFileSync || require('./process-exec-sync')
var execFile = child_process.execFile

function runHello() {
function runHello(hostProcess) {
if (!hostProcess) {
hostProcess = process.execPath
}
var testCode = "console.log(require('hello_world').hello())"
return execFileSync(process.execPath, ['-e', testCode], { cwd: __dirname }).toString()
console.log('running ', hostProcess);
return execFileSync(hostProcess, ['-e', testCode], { cwd: __dirname }).toString()
}

function getEncoding() {
Expand Down Expand Up @@ -111,3 +116,29 @@ test('build simple addon in path with non-ascii characters', function (t) {
proc.stdout.setEncoding('utf-8')
proc.stderr.setEncoding('utf-8')
})

test('addon works with renamed host executable', function (t) {
// No `fs.copyFileSync` before node8.
if (process.version.substr(1).split('.')[0] < 8) {
t.skip("skipping test for old node version");
t.end();
return;
}

t.plan(3)

var notNodePath = path.join(os.tmpdir(), 'notnode' + path.extname(process.execPath))
fs.copyFileSync(process.execPath, notNodePath)

var cmd = [nodeGyp, 'rebuild', '-C', addonPath, '--loglevel=verbose']
var proc = execFile(process.execPath, cmd, function (err, stdout, stderr) {
var logLines = stderr.toString().trim().split(/\r?\n/)
var lastLine = logLines[logLines.length-1]
t.strictEqual(err, null)
t.strictEqual(lastLine, 'gyp info ok', 'should end in ok')
t.strictEqual(runHello(notNodePath).trim(), 'world')
fs.unlinkSync(notNodePath)
})
proc.stdout.setEncoding('utf-8')
proc.stderr.setEncoding('utf-8')
})

0 comments on commit d3b2122

Please sign in to comment.