Skip to content

Instantly share code, notes, and snippets.

@yajd
Last active August 29, 2015 14:02
Show Gist options
  • Save yajd/e49b49b4d5c3887889b9 to your computer and use it in GitHub Desktop.
Save yajd/e49b49b4d5c3887889b9 to your computer and use it in GitHub Desktop.
_ff-addon-snippet-GetTaskmanWindowCTypes - Using js-ctypes to access the taskbar of WinXP. May be useful in Win7 as well.
Components.utils.import("resource://gre/modules/ctypes.jsm");
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 FindWindowExW = GetProcAddress(hUser, "FindWindowExW");
var FindWindowExType = ctypes.FunctionType(ctypes.winapi_abi, ctypes.int32_t, [HWND, HWND, LPCTSTR, LPCTSTR]);
FindWindowExW = ctypes.cast(FindWindowExW, FindWindowExType.ptr);
//funcPtr0(0, "Test1", "Test2", 0);
var GetTaskmanWindow = GetProcAddress(hUser, "GetTaskmanWindow");
var GetTaskmanWindowType = ctypes.FunctionType(ctypes.winapi_abi, ctypes.int32_t, []);
GetTaskmanWindow = ctypes.cast(GetTaskmanWindow, GetTaskmanWindowType.ptr);
var hHwnd = GetTaskmanWindow();
var hToolbar = FindWindowExW(hHwnd, 0, 'ToolbarWindow32', null);
alert(hToolbar)
var SendMessage = GetProcAddress(hUser, "SendMessage");
var SendMessageType = ctypes.FunctionType(ctypes.winapi_abi, ctypes.uintptr_t, [ctypes.int32_t, ctypes.unsigned_int, ctypes.int32_t, ctypes.voidptr_t]);
SendMessage = ctypes.cast(SendMessage, SendMessageType.ptr);
var Count = SendMessage(hToolbar, 0x418 /** TB_BUTTONCOUNT **/, 0, ctypes.voidptr_t(0));
Services.wm.getMostRecentWindow(null).alert(Count);
/*
var funcPtr = GetProcAddress(hUser, "GetTaskmanWindow");
// Now we have a pointer to a function, let's cast it to the right type
var GetTaskmanWindowType = ctypes.FunctionType(ctypes.winapi_abi, ctypes.int32_t, [HWND, LPCTSTR, LPCTSTR, ctypes.uint32_t]);
funcPtr = ctypes.cast(funcPtr, GetTaskmanWindowType.ptr);
funcPtr(0, "Test1", "Test2", 0);
*/
var funcPtr = GetProcAddress(hUser, "MessageBoxW");
// Now we have a pointer to a function, let's cast it to the right type
var MessageBoxType = ctypes.FunctionType(ctypes.winapi_abi, ctypes.int32_t, [HWND, LPCTSTR, LPCTSTR, ctypes.uint32_t]);
funcPtr = ctypes.cast(funcPtr, MessageBoxType.ptr);
funcPtr(0, "Test1", "Test2", 0);
@Noitidart
Copy link

TB_GETBUTTON and other constants from: https://github.com/health901/AHK/blob/d9018af348e69796272021ef5f188ba85ad32cb8/TrayIcon.ahk#L33

    ;<commctrl.h>
;#define WM_USER 0x400
;#define TB_HIDEBUTTON (WM_USER+4) 0x404
;#define TB_GETBUTTON (WM_USER+23) 0x417
;#define TB_BUTTONCOUNT (WM_USER+24) 0x418
;#define TB_GETBUTTONTEXTA (WM_USER+45)0X42D
;#define TB_GETBUTTONTEXTW (WM_USER+75)
WM_USER=0x400
TB_HIDEBUTTON:=WM_USER+4
TB_GETBUTTON:=WM_USER+23
TB_BUTTONCOUNT:=WM_USER+24
TB_GETBUTTONTEXTA:=WM_USER+45
TB_GETBUTTONTEXTW:=WM_USER+75

@Noitidart
Copy link

TBBUTTON structure fixed and also converted away from kernel and GetProcAddress and FunctionType. However this code is still crashing if I try the var rez = SendMessage(hToolbar, 0x417 /** TB_GETBUTTON **/, 1, aButton.address());.

Components.utils.import("resource://gre/modules/ctypes.jsm");

var user32 = ctypes.open('user32.dll');
var HMODULE = ctypes.uint32_t;
var HWND = ctypes.uint32_t;
var LPCTSTR = ctypes.jschar.ptr;
var LPCSTR = ctypes.char.ptr;

/* http://msdn.microsoft.com/en-us/library/windows/desktop/ms633500%28v=vs.85%29.aspx
*/
var FindWindowEx = user32.declare('FindWindowExW', ctypes.winapi_abi, ctypes.int32_t, HWND, HWND, LPCTSTR, LPCTSTR);
ctypes.FunctionType(ctypes.winapi_abi, ctypes.int32_t, [HWND, HWND, LPCTSTR, LPCTSTR]);

var GetTaskmanWindow = user32.declare('GetTaskmanWindow', ctypes.winapi_abi, ctypes.int32_t);
var hHwnd = GetTaskmanWindow();

var hToolbar = FindWindowEx(hHwnd, 0, 'ToolbarWindow32', null);
Services.wm.getMostRecentWindow(null).alert(hToolbar)

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 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("should never get here as process has to be either 32bit or 64bit");
}
console.log(struct_TBButton.size); // 20 on 32-bit, 32 on 64-bit
//var aButton = new struct_TBButton();
//var rez = SendMessage(hToolbar, 0x417 /** TB_GETBUTTON **/, 1, aButton.address());
//Services.wm.getMostRecentWindow(null).alert(rez);

@yajd
Copy link
Author

yajd commented Jun 19, 2014

README

Rev2

  • Renamed funcPtr# to actual function names
  • Added SendMessage
  • Added count line
  • Untested
  • I'm thinking maybe if I do it with this GetProcAddress method then I won't have to do what @nmaier suggested at ask.m.o to avoid the WinXP crash. I don't know, test it first. If not then get back to work on the @nmaier method: https://gist.github.com/yajd/01616e237e743a7a560d

@Noitidart
Copy link

combining nmaiers ask.m.o method and my cleaned up of funcPtr# version here

Cu.import("resource://gre/modules/ctypes.jsm");

var kernel32 = ctypes.open('kernel32.dll');
var user32 = ctypes.open('user32.dll');

/* http://msdn.microsoft.com/en-us/library/windows/desktop/ms633500%28v=vs.85%29.aspx
* HWND WINAPI FindWindowEx(
* __in_opt_  HWND hwndParent,
* __in_opt_  HWND hwndChildAfter,
* __in_opt_  LPCTSTR lpszClass,
* __in_opt_  LPCTSTR lpszWindow
* );
*/
var FindWindowEx = user32.declare('FindWindowExW', ctypes.winapi_abi, ctypes.voidptr_t, // HWND
  ctypes.voidptr_t, // HWND
  ctypes.voidptr_t, // HWND
  ctypes.jschar.ptr, // LPCTSTR
  ctypes.jschar.ptr // LPCTSTR
);

/* UNDOCUMENTED
* HWND WINAPI GetTaskmanWindow(
* );
*/
var GetTaskmanWindow = user32.declare('GetTaskmanWindow', ctypes.winapi_abi, ctypes.voidptr_t // HWND
);

/* http://msdn.microsoft.com/en-us/library/windows/desktop/ms644950%28v=vs.85%29.aspx
* LRESULT WINAPI SendMessage(
* __in HWND hWnd,
* __in UINT Msg,
* __in WPARAM wParam,
* __in LPARAM lParam
* );
*/
var SendMessage = user32.declare('SendMessageW', ctypes.winapi_abi, ctypes.uintptr_t, // LRESULT
  ctypes.voidptr_t, // HWND
  ctypes.unsigned_int, // UINT
  ctypes.int32_t, // WPARAM
  ctypes.voidptr_t // LPARAM
);


var hHwnd = GetTaskmanWindow();
var hToolbar = FindWindowEx(hHwnd, ctypes.voidptr_t(0), 'ToolbarWindow32', null);
Services.wm.getMostRecentWindow(null).alert(hToolbar);


var Count = SendMessage(hToolbar, 0x418 /** TB_BUTTONCOUNT **/, 0, ctypes.voidptr_t(0));
Services.wm.getMostRecentWindow(null).alert(Count);


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("should never get here as process has to be either 32bit or 64bit");
}
console.log(struct_TBButton.size); // 20 on 32-bit, 32 on 64-bit
//var aButton = new struct_TBButton();
//var rez = SendMessage(hToolbar, 0x417 /** TB_GETBUTTON **/, 1, aButton.address());
//Services.wm.getMostRecentWindow(null).alert(rez);


/* http://msdn.microsoft.com/en-us/library/windows/desktop/ms684320%28v=vs.85%29.aspx
* HANDLE WINAPI OpenProcess(
* __in_  DWORD dwDesiredAccess,
* __in_  BOOL bInheritHandle,
* __in_  DWORD dwProcessId
* );
*/
var OpenProcess = kernel32.declare('OpenProcess', ctypes.winapi_abi, ctypes.voidptr_t, //HANDLE
    ctypes.unsigned_long, //DWORD
    ctypes.bool, //BOOL
    ctypes.unsigned_long //DWORD
);

/* http://msdn.microsoft.com/en-us/library/windows/desktop/aa366890%28v=vs.85%29.aspx
* LPVOID WINAPI VirtualAllocEx(
* __in_      HANDLE hProcess,
* __in_opt_  LPVOID lpAddress,
* __in_      SIZE_T dwSize,
* __in_      DWORD flAllocationType,
* __in_      DWORD flProtect
* );
*/
var VirtualAllocEx = kernel32.declare('VirtualAllocEx', ctypes.winapi_abi, ctypes.voidptr_t, //LPVOID
    ctypes.voidptr_t, //HANDLE
    ctypes.voidptr_t, //LPVOID
    ctypes.voidptr_t.size == 8 ? ctypes.uint64_t : ctypes.unsigned_long, //SIZE_T
    ctypes.unsigned_long, //DWORD
    ctypes.unsigned_long //DWORD
);

/* http://msdn.microsoft.com/en-us/library/windows/desktop/ms681674%28v=vs.85%29.aspx
* BOOL WINAPI WriteProcessMemory(
* __in_   HANDLE hProcess,
* __in_   LPVOID lpBaseAddress,
* __in_   LPCVOID lpBuffer,
* __in_   SIZE_T nSize,
* __out_  SIZE_T *lpNumberOfBytesWritten
* );
*/
var WriteProcessMemory = kernel32.declare('WriteProcessMemory', ctypes.winapi_abi, ctypes.bool, //BOOL
    ctypes.voidptr_t, //HANDLE
    ctypes.voidptr_t, //LPVOID
    ctypes.char.ptr, //LPCVOID
    ctypes.voidptr_t.size == 8 ? ctypes.uint64_t : ctypes.unsigned_long, //SIZE_T
    ctypes.voidptr_t.size == 8 ? ctypes.uint64_t : ctypes.unsigned_long //SIZE_T
);

/* http://msdn.microsoft.com/en-us/library/windows/desktop/ms680553%28v=vs.85%29.aspx
* BOOL WINAPI ReadProcessMemory(
* __in_   HANDLE hProcess,
* __in_   LPCVOID lpBaseAddress,
* __out_  LPVOID lpBuffer,
* __in_   SIZE_T nSize,
* __out_  SIZE_T *lpNumberOfBytesRead
* );
*/
var ReadProcessMemory = kernel32.declare('ReadProcessMemory', ctypes.winapi_abi, ctypes.bool, //BOOL
    ctypes.voidptr_t, //HANDLE
    ctypes.char.ptr, //LPCVOID
    ctypes.voidptr_t, //LPVOID
    ctypes.voidptr_t.size == 8 ? ctypes.uint64_t : ctypes.unsigned_long, //SIZE_T
    ctypes.voidptr_t.size == 8 ? ctypes.uint64_t : ctypes.unsigned_long //SIZE_T
);

/* http://msdn.microsoft.com/en-us/library/windows/desktop/aa366894%28v=vs.85%29.aspx
* BOOL WINAPI VirtualFreeEx(
* __in_  HANDLE hProcess,
* __in_  LPVOID lpAddress,
* __in_  SIZE_T dwSize,
* __in_  DWORD dwFreeType
* );
*/
var VirtualFreeEx = kernel32.declare('VirtualFreeEx', ctypes.winapi_abi, ctypes.bool, //BOOL
    ctypes.voidptr_t, //HANDLE
    ctypes.voidptr_t, //LPVOID
    ctypes.voidptr_t.size == 8 ? ctypes.uint64_t : ctypes.unsigned_long, //SIZE_T
    ctypes.unsigned_long //DWORD
);

/* http://msdn.microsoft.com/en-us/library/windows/desktop/ms633522%28v=vs.85%29.aspx
* DWORD WINAPI GetWindowThreadProcessId(
* __in_       HWND hWnd,
* __out_opt_  LPDWORD lpdwProcessId
* );
*/
var GetWindowThreadProcessId = user32.declare('GetWindowThreadProcessId', ctypes.winapi_abi, ctypes.unsigned_long, //DWORD
    ctypes.voidptr_t, //HWND
    ctypes.unsigned_long.ptr //LPDWORD
);

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