带有node-ffi

时间:2017-03-23 11:54:55

标签: winapi kernel32 node-ffi

我正在尝试使用node-ffi与win32 api FormatMessageA接口但是我似乎无法获得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

我知道函数成功,因为它返回57但是我无法获得包含我需要的错误字符串的lpBuffer值。

1 个答案:

答案 0 :(得分:1)

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

  • FORMAT_MESSAGE_ALLOCATE_BUFFER说明:
      

    lpBuffer参数是LPTSTR指针;您必须将指针强制转换为LPTSTR(例如(LPTSTR)&lpBuffer)

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

    // 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的指针),实际上是一个指针LPTSTR(指向TCHAR的双指针) cast ed to LPTSTR

那,翻译在 JS (我没有经验),意味着:

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

注意:根据同一页面,当LocalFree不再需要时,应使用FormatMessage释放缓冲区(有意义,因为LocalFree分配内存对于它 - 这就是它需要成为双指针的原因)。再一次,不知道这将如何在 JS 中转换(我知道应该在uchar *(解除引用)缓冲区上调用lpBuffer,而不是直接在each={ items })。