Win32 api 使用 node-ffi 格式化消息

Win32 api format message with node-ffi

我正在尝试使用 node-ffi 与 win32 接口 api FormatMessageA 但是我似乎无法获取 out lpBuffer 参数,这里是一段代码来展示我已经尝试过的内容

   'use strict';

   const ref = require('ref');
   const ffi = require('ffi');

   const Kernel32 = ffi.Library('Kernel32.dll', {
       FormatMessageA: ['ulong', [
           'ulong', //flags 
           'void *', 
           'ulong', //status number
           'ulong', //language 
           'uchar *',
           'ulong',
           'void *'
       ]]
   });


   const FORMAT_MESSAGE_FROM_SYSTEM = 0x1000;
   const FORMAT_MESSAGE_ALLOCATE_BUFFER = 0x100;
   const FORMAT_MESSAGE_IGNORE_INSERTS = 0x200;

   const lpBuffer = ref.alloc('uchar *'); 

   const result = Kernel32.FormatMessageA(
       FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS,
       null, 
       0x80090300, //error code
       0,
       lpBuffer,
       0, 
       null
   );

   console.log(result); //prints 57 bytes

我知道函数是成功的 returns 57 但是我无法获得包含我需要的错误字符串的 lpBuffer 值。

正如我在 1st 评论中所述,根据 [MSDN] FormatMessage function:

  • FORMAT_MESSAGE_ALLOCATE_BUFFER 说明:

    The lpBuffer parameter is a pointer to an LPTSTR; you must cast the pointer to an LPTSTR (for example, (LPTSTR)&lpBuffer).

  • 页面底部的(2nd)示例:

    // Some code (not relevant for this problem)
    LPWSTR pBuffer = NULL;
    // Some more code (still not relevant)
    FormatMessage(FORMAT_MESSAGE_FROM_STRING |
                  FORMAT_MESSAGE_ALLOCATE_BUFFER,
                  pMessage, 
                  0,
                  0,
                  (LPWSTR)&pBuffer,
    // The rest of the code (not relevant)
    

dwFlags 参数由 FORMAT_MESSAGE_ALLOCATE_BUFFER 组成时,函数期望 lpBuffer 参数是 LPTSTR(指向 TCHAR 的指针) , 实际上是 pointer to LPTSTR (double pointer to TCHAR) cast ed to LPTSTR .

那,翻译成 JS(我没有经验),意思是:

const lpBuffer = ref.alloc('uchar **');

注意:根据同一页,缓冲区应该在不再需要时使用LocalFree释放(有道理,因为FormatMessage分配它的内存 - 这就是为什么它需要是一个双指针)。同样,不知道这将如何在 JS 中转换(我所知道的是 LocalFree 应该在 uchar *(取消引用)缓冲区上调用,而不是直接在 lpBuffer).