Process crash when repeatly call NodeJS native module

282 Views Asked by At

I want to changes the parent window of the specified child window by calling native modules in NodeJS16.(electron 22.)

CPP code:

#include <napi.h>
#include <windows.h>
#include <winuser.h>

using namespace Napi;

class ContextData
{
private:
    HWND hWnd_;
    LPDWORD lpdwProcessId_;
    Function &cb_;

public:
    ContextData(Function &cb, HWND hWnd, LPDWORD lpdwProcessId) : cb_(cb), hWnd_(hWnd), lpdwProcessId_(lpdwProcessId) {}
    HWND hWnd()
    {
        return hWnd_;
    }
    LPDWORD lpdwProcessId()
    {
        return lpdwProcessId_;
    }
    Function &cb()
    {
        return cb_;
    }
    static BOOL CALLBACK EnumChildProc(HWND hWnd, LPARAM callbackLParam)
    {
        ContextData *lParam = (ContextData *)callbackLParam;

        LPDWORD pid;
        GetWindowThreadProcessId(hWnd, (LPDWORD)pid);

        uint32_t childWindowPid = *(uint32_t *)pid;
        printf("childWindowPid is: %d\n", childWindowPid);

        uint32_t targetWindowPid = *(uint32_t *)(lParam->lpdwProcessId());
        printf("targetWindowPid is: %d\n", targetWindowPid);

        if (childWindowPid == targetWindowPid)
        {
            printf("find successfully\n");
            SetParent(hWnd, lParam->hWnd());
            (lParam->cb()).Call({});
            return FALSE;
        }

        return TRUE;
    }
};

static void Method(const CallbackInfo &info)
{
    Env env = info.Env();

    if (info.Length() < 3)
    {
        TypeError::New(env, "Wrong number of arguments")
            .ThrowAsJavaScriptException();
        return;
    }

    if (!info[0].IsBuffer())
    {
        TypeError::New(env, "hwnd must be buffer")
            .ThrowAsJavaScriptException();
        return;
    }

    if (!info[1].IsNumber())
    {
        TypeError::New(env, "pid must be number")
            .ThrowAsJavaScriptException();
        return;
    }

    if (!info[2].IsFunction())
    {
        TypeError::New(env, "cb must be function")
            .ThrowAsJavaScriptException();
        return;
    }

    // parent window's hWnd
    Buffer<void *> handle = info[0].As<Buffer<void *>>();
    HWND hWnd = static_cast<HWND>(*reinterpret_cast<void **>(handle.Data()));

    // child process identifier
    uint32_t pid = info[1].As<Number>().Uint32Value();
    LPDWORD lpdwProcessId = reinterpret_cast<LPDWORD>(&pid);

    // callback
    Function cb = info[2].As<Function>();
    ContextData context(cb, hWnd, lpdwProcessId);

    EnumChildWindows(hWnd, ContextData::EnumChildProc, (LPARAM)(&context));
    return;
}

Object Init(Env env, Object exports)
{
    exports.Set(String::New(env, "SetParentNapi"),
                Function::New(env, Method));
    return exports;
}

NODE_API_MODULE(addon, Init)

JS code:

  const controller = new AbortController()

  try {
    // eslint-disable-next-line @typescript-eslint/no-unused-vars
    for await (const _value of setInterval(5000, undefined, {
      signal: controller.signal,
    })) {
      SetParentNapi(buffer, pid, () => {
        log4js.info('SetParent success!')
        controller.abort()
      })
    }
  } catch (error) {
    if (controller.signal.aborted) {
      log4js.debug('timeout aborted!')
      return
    }

    log4js.error(error)
  }

If SetParentNapi executes ok, it would print out message like following:

childWindowPid is: 6872                                                                                                          
targetWindowPid is: 8324                                                                                                         
childWindowPid is: 8324
targetWindowPid is: 8324
find successfully

Every seems ok, but if I try to comment out the following code in JS,

controller.abort()

to force calling native modules repeatedly, the app crash.

[20464:1231/223445.713:ERROR:crashpad_client_win.cc(844)] not connected

Process finished with exit code -36861

Why it happened, how can I fix it?

0

There are 0 best solutions below