Create a gist now

Instantly share code, notes, and snippets.

_ff-addon-getTxtForCode - Gets WinAPI error text for a code. [js-ctypes][winapi]
function getTxtForCode(aErrorCode) {
Cu.import('resource://gre/modules/ctypes.jsm');
let kernel = ctypes.open('kernel32');
const IFDEF_UNICODE = true;
// types for FormatMessage
let DWORD = ctypes.uint32_t;
let LPCVOID = ctypes.voidptr_t;
let CHAR = ctypes.char;
let WCHAR = ctypes.jschar;
let LPSTR = CHAR.ptr;
let LPWSTR = WCHAR.ptr;
let LPTSTR = IFDEF_UNICODE ? LPWSTR : LPSTR;
// types for LocalFree
let PVOID = ctypes.voidptr_t;
let HANDLE = PVOID;
let HLOCAL = HANDLE;
// const for FormatMessage
const FORMAT_MESSAGE_ALLOCATE_BUFFER = 0x00000100;
const FORMAT_MESSAGE_FROM_SYSTEM = 0x00001000;
const FORMAT_MESSAGE_IGNORE_INSERTS = 0x00000200;
// const for MAKELANGID
const LANG_NEUTRAL = 0; // https://msdn.microsoft.com/en-us/library/cc230847.aspx
const SUBLANG_DEFAULT = 1;
let va_list = ctypes.voidptr_t; // i didnt bother as i pass null anyways, but details are here - https://github.com/wine-mirror/wine/blob/e2ebc0dc23f0fa04ea79cefc9e3d2faf189a6bf7/include/windef.h#L102
let FormatMessage = kernel.declare(IFDEF_UNICODE ? 'FormatMessageW' : 'FormatMessageA', ctypes.winapi_abi,
DWORD, // return
DWORD, // dwFlags
LPCVOID, //lpSource
DWORD, // dwMessageId
DWORD, // dwLanguageId
LPTSTR, // lpBuffer
DWORD, // nSize
va_list // *Arguments
);
let LocalFree = kernel.declare('LocalFree', ctypes.winapi_abi,
HLOCAL, // return
HLOCAL // hMem
);
// MACRO: https://github.com/wine-mirror/wine/blob/b1ee60f22fbd6b854c3810a89603458ec0585369/include/winnt.h#L2180
// #define MAKELANGID(p, s) ((((WORD)(s))<<10) | (WORD)(p))
let MAKELANGID = (p, s) => ((((s))<<10) | (p));
let bufptr = LPTSTR();
let bufptrptr = ctypes.cast(bufptr.address(), LPTSTR);
console.log('bufptr:', bufptr.toString(), 'bufptr.address():', bufptr.address().toString());
console.log('bufptrptr:', bufptrptr.toString(), 'bufptrptr.address():', bufptrptr.address().toString());
let bufsize = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS, null, aErrorCode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), bufptrptr, 0, null);
console.log('bufsize:', bufsize.toString(), 'bufptr:', bufptr.toString(), 'bufptr.address():', bufptr.address().toString());
let the_error_txt;
if (bufptr.isNull()) {
console.error('Failed FormatMessage. Error:', ctypes.winLastError);
} else {
console.log('Number of characters in bufptr:', bufsize);
the_error_txt = bufptr.readString();
let freed = LocalFree(bufptr);
console.log('freed:', freed.toString());
if (!freed.isNull()) {
console.error('Failed to free from heap! Error:', ctypes.winLastError);
}
}
kernel.close();
return the_error_txt;
}
getTxtForCode(0);
@Noitidart
Owner

README

Rev1

  • Works
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment