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
).
我正在尝试使用 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 anLPTSTR
; you must cast the pointer to anLPTSTR
(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
).