I'm using js-ctypes here to use winapi on winxp to get a button on the task bar at buton index 1. However this line here is crashing my code: var rez = SendMessage(hToolbar, 0x417 /** TB_GETBUTTON **/, 1, aButton.address());
. How can I fix so it doesn't crash?
I'm following this tutorial here: http://w-shadow.com/blog/2006/10/01/manipulating-taskbar-buttons/
Here is copy paste code to scratchpad:
Components.utils.import("resource://gre/modules/ctypes.jsm");
var user32 = ctypes.open('user32.dll');
var kernel = ctypes.open("kernel32.dll");
var HMODULE = ctypes.uint32_t;
var HWND = ctypes.uint32_t;
var LPCTSTR = ctypes.jschar.ptr;
var LPCSTR = ctypes.char.ptr;
var LoadLibrary = kernel.declare("LoadLibraryW", ctypes.winapi_abi, HMODULE, LPCTSTR);
var GetProcAddress = kernel.declare("GetProcAddress", ctypes.winapi_abi, ctypes.void_t.ptr, HMODULE, LPCSTR);
var hUser = LoadLibrary("user32");
/* http://msdn.microsoft.com/en-us/library/windows/desktop/ms633500%28v=vs.85%29.aspx
*/
var funcPtr0 = GetProcAddress(hUser, "FindWindowExW");
var FindWindowExType = ctypes.FunctionType(ctypes.winapi_abi, ctypes.int32_t, [HWND, HWND, LPCTSTR, LPCTSTR]);
funcPtr0 = ctypes.cast(funcPtr0, FindWindowExType.ptr);
//funcPtr0(0, "Test1", "Test2", 0);
var funcPtr1 = GetProcAddress(hUser, "GetTaskmanWindow");
var GetTaskmanWindowType = ctypes.FunctionType(ctypes.winapi_abi, ctypes.int32_t, []);
funcPtr1 = ctypes.cast(funcPtr1, GetTaskmanWindowType.ptr);
var hHwnd = funcPtr1();
var hToolbar = funcPtr0(hHwnd, 0, 'ToolbarWindow32', null);
Services.wm.getMostRecentWindow(null).alert(hToolbar)
var struct_TBButton = ctypes.StructType('TBButton', [
{'iBitmap': ctypes.int},
{'idCommand': ctypes.int},
{'fbState': ctypes.unsigned_char},
{'fsStyle': ctypes.unsigned_char},
{'bReserved': ctypes.unsigned_char},
{'dwData': ctypes.unsigned_long},
{'iString': ctypes.int}
]);
var SendMessage = user32.declare('SendMessageW', ctypes.winapi_abi, ctypes.uintptr_t,
ctypes.int32_t,
ctypes.unsigned_int,
ctypes.int32_t,
ctypes.voidptr_t
);
var Count = SendMessage(hToolbar, 0x418 /** TB_BUTTONCOUNT **/, 0, ctypes.voidptr_t(0));
Services.wm.getMostRecentWindow(null).alert(Count);
var aButton = new struct_TBButton();
var rez = SendMessage(hToolbar, 0x417 /** TB_GETBUTTON **/, 1, aButton.address());
Services.wm.getMostRecentWindow(null).alert(rez);
I don't have the time/motiviation to debug this myself, but there is an apparent bug that likely causes the crashes: Your struct_TBButton
definition is wrong.
{'bReserved': ctypes.unsigned_char},
vs.
#ifdef _WIN64
BYTE bReserved[6];
#else
#if defined(_WIN32)
BYTE bReserved[2];
#endif
#endif
bReserved
should be 2 byte (unsigned chars) in a 32-bit process and 6 in a 64 bit process. (This stuff is there in the first place so that the data members are properly pointer aligned).
Also, your pointer types are wrong, which would have an effect in 64-bit processes.
Putting it all together (avoiding ArrayType
because I'm lazy):
var struct_TBButton;
if (ctypes.voidptr_t.size == 4 /* 32-bit */) {
struct_TBButton = ctypes.StructType('TBButton', [
{'iBitmap': ctypes.int},
{'idCommand': ctypes.int},
{'fbState': ctypes.unsigned_char},
{'fsStyle': ctypes.unsigned_char},
{'bReserved': ctypes.unsigned_char},
{'bReserved2': ctypes.unsigned_char},
{'dwData': ctypes.uintptr_t},
{'iString': ctypes.intptr_t}
]);
}
else if (ctypes.voidptr_t.size == 8 /* 64-bit */) {
struct_TBButton = ctypes.StructType('TBButton', [
{'iBitmap': ctypes.int},
{'idCommand': ctypes.int},
{'fbState': ctypes.unsigned_char},
{'fsStyle': ctypes.unsigned_char},
{'bReserved': ctypes.unsigned_char},
{'bReserved2': ctypes.unsigned_char},
{'bReserved3': ctypes.unsigned_char},
{'bReserved4': ctypes.unsigned_char},
{'bReserved5': ctypes.unsigned_char},
{'bReserved6': ctypes.unsigned_char},
{'dwData': ctypes.uintptr_t},
{'iString': ctypes.intptr_t}
]);
}
else {
throw new Error("wut?!");
}
console.log(struct_TBButton.size);
// 20 on 32-bit, 32 on 64-bit if I'm not mistaken
PS: The same goes for the rest of your pointer types. https://stackoverflow.com/a/18040503/484441
E.g. HWND WINAPI FindWindowEx()
== void* WINAPI FindWindowEx(...)
and not uint32_t WINAPI FindWindowEx(...)