Last active
August 29, 2015 14:02
-
-
Save Noitidart/1fc56b28be82d45a245d to your computer and use it in GitHub Desktop.
_ff-addon-snippet-GetHandleFromTBB - I'm trying to get handle from tbb then later on I'll get window class and then make separate groups of Firefox based on separate class becase each profile of Firefox has different window class (learned from that icon apply technique).
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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/ms633539%28v=vs.85%29.aspx | |
* BOOL WINAPI SetForegroundWindow( | |
* __in HWND hWnd | |
* ); | |
*/ | |
var SetForegroundWindow = user32.declare('SetForegroundWindow', ctypes.winapi_abi, ctypes.bool, //BOOL | |
ctypes.voidptr_t // HWND | |
); | |
/* http://msdn.microsoft.com/en-us/library/ms633539%28v=vs.85%29.aspx | |
* int WINAPI GetClassName( | |
* __in_ HWND hWnd, | |
* __out_ LPTSTR lpClassName, | |
* __in_ int nMaxCount | |
* ); | |
*/ | |
var GetClassName = user32.declare('GetClassNameW', ctypes.winapi_abi, ctypes.int, // int | |
ctypes.voidptr_t, // HWND | |
ctypes.jschar.ptr, // LPTSTR | |
ctypes.int // int | |
); | |
/* http://msdn.microsoft.com/en-us/library/windows/desktop/ms633571%28v=vs.85%29.aspx | |
* LRESULT WINAPI CallWindowProc( | |
* __in_ WNDPROC lpPrevWndFunc, | |
* __in_ HWND hWnd, | |
* __in_ UINT Msg, | |
* __in_ WPARAM wParam, | |
* __in_ LPARAM lParam | |
* ); | |
*/ | |
var CallWindowProc = user32.declare('CallWindowProcW', ctypes.winapi_abi, ctypes.size_t, // LRESULT | |
ctypes.voidptr_t, // WNDPROC | |
ctypes.voidptr_t, // HWND | |
ctypes.unsigned_int, // UINT | |
ctypes.int32_t, // WPARAM | |
ctypes.voidptr_t // LPARAM | |
); | |
function TurnButtonIntoGroup(hToolbar, ButtonCommand, GroupTitle) { //returns bool //ButtonCommand:longint; const GroupTitle:string | |
var rez; | |
var went; | |
var SourceGroup; | |
var SourceGroupCommand; | |
var ButtonIndex; //longint | |
var aButton = new struct_TBButton(); | |
var HaveBehind; //:boolean; | |
ButtonIndex = CallWindowProc(OldWndProc, hToolbar, TB_COMMANDTOINDEX, ButtonCommand, 0); | |
if (ButtonIndex < 0) { | |
console.error('ButtonIndex = ', ButtonIndex, 'This is less than 0 so exit'); | |
return; | |
} | |
//Check if there's another button after this one. | |
//fillchar(aButton,sizeof(aButton),0); | |
var rez = CallWindowProc(OldWndProc, hToolbar, TB_GETBUTTON, ButtonIndex+1, aButton.address()); | |
if (rez != 0 && !(aButton.fsStyle & BTNS_DROPDOWN)) { | |
HaveBehind = true; | |
} else { | |
HaveBehind = false; | |
} | |
var went = 0; | |
while (went == 0 || aButton.fsStyle & BTNS_DROPDOWN || rez == 0) { | |
var SourceGroup = ButtonIndex; | |
var SourceGroupCommand = 0; | |
var repeat; | |
var rez = CallWindowProc(OldWndProc, hToolbar, TB_GETBUTTON, ButtonIndex - went, aButton.address()); | |
went++; | |
} | |
if (rez != 0) { | |
SourceGroup = ButtonIndex - went + 1; | |
SourceGroupCommand = aButton.idCommand; | |
} | |
if (HaveBehind) { | |
CopyTBGroup(SourceGroup, ButtonIndex + 1); | |
} | |
if (SourceGroup < ButtonIndex - 1) { | |
//Make a new hidden group before this. | |
SourceGroupCommand = CopyTBGroup(SourceGroup, ButtonIndex); | |
SourceGroup = ButtonIndex; | |
} | |
SetTBButtonTitle(SourceGroup, GroupTitle); | |
inc(MyLastCommand); | |
SetTBGroupFile(SourceGroup,'Custom Group '+inttostr(MyLastCommand)); | |
SetTBButtonBitmap(SourceGroupCommand,AppFolder+'someicon.ico'); | |
CallWindowProc(OldWndProc,hToolbar,TB_HIDEBUTTON,SourceButtonCommand,integer(true)); | |
CallWindowProc(OldWndProc,hToolbar,TB_HIDEBUTTON,SourceGroupCommand,integer(false)); | |
UpdateToolbarParent; | |
} | |
function CopyTBGroup(FromIndex, ToIndex) { //returns integer | |
var aButton = new struct_TBButton(); | |
var StrBuf = '?'; //PWideChar; // note: need to ask mbhai | |
var StrBufA = '?'; //PAnsiChar; // note: need to ask mbhai | |
var aString = '?'; //string; // note: need to ask mbhai | |
var OldSize = '?'; //cardinal; // note: need to ask mbhai | |
MyLastCommand++; | |
if (MyLastCommand >= MAXINT - 10) { | |
MyLastCommand = CommandOffset | |
} | |
OldSize = CallWindowProc(OldWndProc, hToolbar, TB_GETBUTTONSIZE, 0, 0); | |
CallWindowProc(OldWndProc, hToolbar, TB_GETBUTTON, FromIndex, aButton.address()); | |
aButton.idCommand = MyLastCommand; | |
aButton.fsState = TBSTATE_ENABLED || TBSTATE_HIDDEN; | |
//Copy the internal data. | |
StrBuf = VirtualAlloc(null , TDataArray.size, MEM_COMMIT, PAGE_READWRITE); //can i use virtualAllocEx here instead? | |
Move(aButton.dwData,StrBuf,TDataArray.size); //Move((aButton.dwData)^,StrBuf^,sizeof(TDataArray)); | |
aButton.dwData = StrBuf; | |
//Copy filename. | |
//StrBuf = VirtualAlloc(null ,Max_Path*2+1,MEM_COMMIT,PAGE_READWRITE); note: ask mbhai | |
//Move(pointer(PDataArray(aButton.dwData)^[5])^, StrBuf^, Max_Path*2+1); //Move(pointer(PDataArray(aButton.dwData)^[5])^, StrBuf^, Max_Path*2+1); //note: i got the memmove function made | |
//PDataArray(aButton.dwData)^[5]:=cardinal(StrBuf); note: ask mbhai | |
//Copy button name. | |
StrBuf = PWideChar(aButton.iString); | |
aString = StrBuf; | |
StrBufA = VirtualAlloc(null,aString.length + 1, MEM_COMMIT, PAGE_READWRITE); | |
StrPCopy(StrBufA, aString); | |
aButton.iString = StrBufA; | |
//Insert a button. | |
CallWindowProc(OldWndProc, hToolbar, TB_SETBUTTONSIZE, 0, OldSize); | |
var Count = SendMessage(hToolbar, TB_BUTTONCOUNT, 0, 0); | |
if (ToIndex < Count) { | |
//Insert before the specified index. | |
CallWindowProc(OldWndProc, hToolbar, TB_INSERTBUTTON, ToIndex, aButton.address()); | |
} else { | |
//Just add it as the last button. | |
CallWindowProc(OldWndProc, hToolbar, TB_ADDBUTTONS, 1, aButton.address()); | |
} | |
} | |
function SetTBGroupFile(hToolbar, GroupIndex, NewFile) { //GroupIndex:integer,;const NewFile:String | |
var aButton = new struct_TBButton(); | |
var rez; | |
var StrBuf = '?'; // PWideChar note: need to ask mbhai | |
var rez = CallWindowProc(OldWndProc, hToolbar, TB_GETBUTTON, GroupIndex, aButton.address()); | |
if (!rez) { | |
return; | |
} | |
var StrBuf = VirtualAlloc(null, NewFile.length*2+2, MEM_COMMIT, PAGE_READWRITE); | |
//StringToWideChar(NewFile,StrBuf,Length(NewFile)); // can skip in ctypes? i think its a cast | |
//PDataArray(aButton.dwData)^[5]:=cardinal(StrBuf); //i dont understand this, but cardinal is ctypes.uint32_t | |
} | |
/* http://msdn.microsoft.com/en-us/library/windows/desktop/ms633510%28v=vs.85%29.aspx | |
* HWND WINAPI GetParent( | |
* __in_ HWND hWnd | |
* ); | |
*/ | |
var GetParent = user32.declare('GetWindowRect', ctypes.winapi_abi, ctypes.voidptr_t, // HWND | |
ctypes.voidptr_t // HWND | |
); | |
/* http://msdn.microsoft.com/en-us/library/windows/desktop/dd162897%28v=vs.85%29.aspx | |
* typedef struct _RECT { | |
* LONG left; | |
* LONG top; | |
* LONG right; | |
* LONG bottom; | |
* } RECT, *PRECT; | |
*/ | |
var struct_RECT = ctypes.StructType('RECT', [ | |
{top: ctypes.long}, | |
{left: ctypes.long}, | |
{bottom: ctypes.long}, | |
{right: ctypes.long} | |
]); | |
/* http://msdn.microsoft.com/en-us/library/windows/desktop/dd162897%28v=vs.85%29.aspx | |
* typedef struct tagPOINT { | |
* LONG x; | |
* LONG y; | |
* } POINT, *PPOINT; | |
*/ | |
var struct_TAGPOINT = ctypes.StructType('tagPOINT', [ | |
{x: ctypes.long}, | |
{y: ctypes.long} | |
]); | |
/* http://msdn.microsoft.com/en-us/library/windows/desktop/ms633519%28v=vs.85%29.aspx | |
* BOOL WINAPI GetWindowRect( | |
* __in_ HWND hWnd, | |
* __out_ LPRECT lpRect | |
* ); | |
*/ | |
var GetWindowRect = user32.declare('GetWindowRect', ctypes.winapi_abi, ctypes.bool, // BOOL | |
ctypes.voidptr_t, // HWND | |
struct_RECT.ptr // LPRECT | |
); | |
/* http://msdn.microsoft.com/en-us/library/windows/desktop/dd162952%28v=vs.85%29.aspx | |
* BOOL ScreenToClient( | |
* __in_ HWND hWnd, | |
* __in_ LPPOINT lpPoint | |
* ); | |
*/ | |
var ScreenToClient = user32.declare('ScreenToClient', ctypes.winapi_abi, ctypes.bool, // BOOL | |
ctypes.voidptr_t, // HWND | |
struct_TAGPOINT.ptr // LPPOINT | |
); | |
/* http://msdn.microsoft.com/en-us/library/windows/desktop/ms633545%28v=vs.85%29.aspx | |
* BOOL WINAPI SetWindowPos( | |
* __in_ HWND hWnd, | |
* __in_opt_ HWND hWndInsertAfter, | |
* __in_ int X, | |
* __in_ int Y, | |
* __in_ int cx, | |
* __in_ int cy, | |
* __in_ UINT uFlags | |
* ); | |
*/ | |
var SetWindowPos = user32.declare('SetWindowPos', ctypes.winapi_abi, ctypes.bool, // BOOL | |
ctypes.voidptr_t, // HWND | |
ctypes.voidptr_t, // HWND | |
ctypes.int, // int | |
ctypes.int, // int | |
ctypes.int, // int | |
ctypes.int, // int | |
ctypes.unsigned_int // UINT | |
); | |
var SWP_NOOWNERZORDER = 0x0200; | |
var SWP_FRAMECHANGED = 0x0020; | |
/* | |
Procedure UpdateToolbarParent; | |
var | |
aRect:TRect; | |
punkts1:TPoint; | |
aParent,aBar:cardinal; | |
begin | |
//get the parent of taskman window | |
aBar:=TaskmanWindow; | |
GetWindowRect(aBar, aRect); | |
aParent:=GetParent(aBar); | |
punkts1.X:=aRect.Left; | |
Punkts1.Y:=aRect.Top; | |
ScreenToClient(aParent, punkts1); | |
if punkts1.X<0 then punkts1.X:=0; | |
if punkts1.y<0 then punkts1.y:=0; | |
//set it to exactly the same position and size | |
SetWindowPos(aBar, HWND_TOP, punkts1.X, punkts1.Y, abs(aRect.Right – aRect.Left), abs(arect.Bottom – aRect.Top), SWP_NOOWNERZORDER or SWP_FRAMECHANGED); //these flags are important! | |
end; | |
*/ | |
//Sometimes, if you do something that changes the number of visible buttons (hide some, create a new button, etc) the size of new buttons will be wrong. Algorithm to resize the buttons == UpdateToolbarParent | |
function UpdateToolbarParent(hToolbar) { | |
var aRect = new struct_RECT(); | |
var punkts1 = new struct_TAGPOINT(); | |
var aParent; // HWND | |
var aBar = hToolbar; | |
var rez = GetWindowRect(aBar, aRect.address()); | |
if (!rez) { | |
throw new Error('failed on GetWindowRect'); | |
} | |
var aParent = GetParent(aBar); | |
punkts1.x = aRect.left; | |
punkts1.y = aRect.top; | |
var rez = ScreenToClient(aParent, punkts1.address()); | |
if (!rez) { | |
throw new Error('error on ScreenToClient'); | |
} | |
punkts1.x = punkts1.x < 0 ? 0 : punkts1.x; | |
punkts1.y = punkts1.y < 0 ? 0 : punkts1.y; | |
//set it to exactly the same position and size | |
// note: i have to ask whiteShadow what is `HWND_TOP` | |
var rez = SetWindowPos(aBar, HWND_TOP, punkts1.x, punkts1.y, Math.abs(aRect.right - aRect.left), Math.abs(aRect.bottom - aRect.top), SWP_NOOWNERZORDER | SWP_FRAMECHANGED); | |
if (!rez) { | |
throw new Error('error on SetWindowPos'); | |
} | |
} | |
/* 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.voidptr_t.size == 8 ? ctypes.int64_t : ctypes.long, // LRESULT | |
ctypes.voidptr_t, // HWND | |
ctypes.unsigned_int, // UINT | |
ctypes.int32_t, // WPARAM | |
ctypes.voidptr_t // LPARAM | |
); | |
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 TB_HIDEBUTTON = 0x404; | |
var TB_GETBUTTON = 0x417; | |
var TB_BUTTONCOUNT = 0x418; | |
var TB_COMMANDTOINDEX = 0x419; | |
var TB_GETBUTTONTEXTA = 0x42D; | |
var TB_GETBUTTONTEXTW = 0x44B; | |
var TB_GETBUTTONSIZE = 0x43A; | |
var TB_SETBUTTONSIZE = 0x41F; | |
var TB_INSERTBUTTON = 0x415; | |
var TB_ADDBUTTONS = 0x414; | |
var TBSTATE_CHECKED = 0x01; | |
var TBSTATE_PRESSED = 0x02; | |
var TBSTATE_ENABLED = 0x04; | |
var TBSTATE_HIDDEN = 0x08; | |
var TBSTATE_INDETERMINATE = 0x10; | |
var TBSTATE_WRAP = 0x20; | |
var TBSTATE_ELLIPSES = 0x40; | |
var TBSTATE_MARKED = 0x80; | |
var BTNS_DROPDOWN = 0x0008; | |
/* 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.voidptr_t, //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.voidptr_t, //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 | |
); | |
/*realloc_t class. | |
*I'm not going to make an actual declaration, | |
*because im lazy | |
*just stick the functions here | |
*/ | |
var PROCESS_VM_READ = 0x0010 | |
var PROCESS_VM_WRITE = 0x0020; | |
var PROCESS_VM_OPERATION = 0x0008; | |
var MEM_COMMIT = 0x1000; | |
var MEM_RESERVE = 0x2000; | |
var MEM_RELEASE = 0x8000; | |
var PAGE_READWRITE = 0x04; | |
var FALSE = 0; | |
var TRUE = 1; | |
var proc; | |
var buffers = []; /*MAP={output of virtualMallocEX, size}*/ | |
function ralloc_constr(hwnd) { | |
var pid = ctypes.cast(ctypes.voidptr_t(0), ctypes.unsigned_long); | |
var rez = GetWindowThreadProcessId(hwnd, pid.address()); | |
if (!rez) { | |
console.warn('dang, no dice on GetWindowThreadProcessId'); | |
} | |
proc = OpenProcess(PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_VM_OPERATION, FALSE, pid); | |
if (!proc) { | |
console.warn('no open for me!'); | |
} | |
} | |
function ralloc_alloc(size) { | |
var ret_address = VirtualAllocEx(proc, ctypes.voidptr_t(0), size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); | |
buffers.push([ret_address, size]); | |
return ret_address; | |
} | |
function ralloc_free(address) { | |
var found_addr; | |
for (var i = 0; i < buffers.length; i++) { | |
if (buffers[i][0] == address) { | |
found_addr = buffers[i] | |
break; | |
} | |
} | |
if (!found_addr) { | |
return null; | |
} | |
var rez = VirtualFreeEx(proc, found_addr[0], found_addr[1], MEM_RELEASE); | |
return rez; | |
} | |
/*local must be array as we need it passed as reference for one reason. readprocessmemory returns to that*/ | |
function ralloc_read(remote_address, local_buffer) { | |
var found_addr; | |
for (var i = 0; i < buffers.length; i++) { | |
if (buffers[i][0] == remote_address) { | |
found_addr = buffers[i] | |
break; | |
} | |
} | |
if (!found_addr) { | |
return null; | |
} | |
/*using the found remote address(found_addr[0]), | |
*i read size bytes (found_addr[1]) into my local_buffer*/ | |
//console.info('found_addr[0]', found_addr[0].toString()); | |
var rez = ReadProcessMemory(proc, found_addr[0], local_buffer, found_addr[1], 0); | |
return rez; | |
} | |
function ralloc_write(remote_address, local_buffer) { | |
var found_addr; | |
for (var i = 0; i < buffers.length; i++) { | |
if (buffers[i][0] == remote_address) { | |
found_addr = buffers[i] | |
break; | |
} | |
} | |
if (!found_addr) { | |
return null; | |
} | |
/*using the found remote address(found_addr[0]), | |
*write size bytes (found_addr[1]) from local_buffer to the remote address*/ | |
var rez = WriteProcessMemory(proc, found_addr[0], local_buffer, found_addr[1], 0) | |
return rez; | |
} | |
/* END realloc_t class */ | |
///int main() | |
var me = Services.wm.getMostRecentWindow(null); | |
function main() { | |
var hHwnd = GetTaskmanWindow(); | |
if (!hHwnd) { | |
console.error('Failed to get GetTaskmanWindow!'); | |
return; | |
} | |
var hToolbar = FindWindowEx(hHwnd, ctypes.voidptr_t(0), 'ToolbarWindow32', null); | |
if (!hToolbar) { | |
console.error('Failed to get toolbar window!'); | |
return; | |
} | |
ralloc_constr(hToolbar); | |
var Count = SendMessage(hToolbar, TB_BUTTONCOUNT, 0, ctypes.voidptr_t(0)); | |
Services.wm.getMostRecentWindow(null).alert('Count of taskbar buttons = ' + Count); | |
for (var i = 0; i < Count; i++) { | |
var remote_tbb = ralloc_alloc(struct_TBButton.size); | |
var rez = SendMessage(hToolbar, TB_GETBUTTON, i, ctypes.voidptr_t(remote_tbb)); | |
if (!rez) { | |
console.error('Failed on SendMessage of TB_GETBUTTON'); | |
me.alert('Failed on SendMessage of TB_GETBUTTON = ' + rez); | |
return false; | |
} | |
var local_tbb = new struct_TBButton(); | |
var retRead = ralloc_read(remote_tbb, local_tbb.address()); | |
var freed = ralloc_free(remote_tbb); | |
console.log('freed', freed); | |
console.info('local_tbb ' + i, local_tbb); | |
for (var n in local_tbb) { | |
console.log(n, local_tbb[n]); | |
try { | |
console.log('toString', n, local_tbb[n].toString()); | |
} catch (ignore) {} | |
} | |
console.info('is button hidden? = ', (local_tbb.fbState & TBSTATE_HIDDEN)); | |
//start get window handle | |
var remote_hwnd_ptr = new ctypes.voidptr_t(local_tbb.dwData); | |
var local_hwnd = new ctypes.voidptr_t(); | |
// Important: pass the address of |handle|, not |handle| itself. | |
var hwndRead = ReadProcessMemory(proc, remote_hwnd_ptr, local_hwnd.address(), ctypes.voidptr_t.size, 0); | |
console.log('hwndRead = ', hwndRead); | |
if (!hwndRead) { | |
throw new Error('Failed to read window handle'); | |
} else { | |
console.log('SUCCESS local_hwnd = ', local_hwnd, local_hwnd.toString(), uneval(local_hwnd)); | |
if (local_hwnd.toString().indexOf('UInt64("0x0")') > -1) { | |
console.log('has no handle it is 0 local_hwnd.toString() = ', local_hwnd.toString()); | |
} else { | |
var fored = SetForegroundWindow(local_hwnd); | |
console.log('win fored = ', fored); | |
var wndClassBuf = new new ctypes.ArrayType(ctypes.jschar, 255); | |
var wndClassRet = GetClassName(local_hwnd, wndClassBuf, 255); | |
console.log('wndClassRet=', wndClassRet); | |
console.log('wndClassBuf=', wndClassBuf, wndClassBuf.toString(), wndClassBuf.readString()); | |
//var PID = new ctypes.uint32_t; //DWORD; | |
var PID = ctypes.cast(ctypes.voidptr_t(0), ctypes.unsigned_long); | |
GetWindowThreadProcessId(local_hwnd, PID.address()); | |
console.log('PID=', PID, PID.toString()); | |
if (confirm('act on this?')) { | |
return; | |
} | |
} | |
} | |
//end get window handle | |
//start get button text | |
// var chars = SendMessage(hToolbar, TB_GETBUTTONTEXTW, local_tbb.idCommand, ctypes.voidptr_t(0)); //chars holds length of characters the button text is | |
// console.log('chars=', chars, chars.toString(), uneval(chars)); | |
// if (chars && ctypes.Int64.compare(chars, ctypes.Int64('0')) > 0) { | |
// var charsCastedSoItWorksWith_VirtualAllocEx = ctypes.voidptr_t.size == 8 ? ctypes.cast(ctypes.voidptr_t(chars), ctypes.uint64_t) : ctypes.cast(ctypes.voidptr_t(chars), ctypes.unsigned_long); | |
// var remote_buf = ralloc_alloc(charsCastedSoItWorksWith_VirtualAllocEx); | |
// var charsRe = SendMessage(hToolbar, TB_GETBUTTONTEXTW, local_tbb.idCommand, ctypes.voidptr_t(remote_buf)); //chars holds length of characters the button text is | |
// console.log('charsRe=', charsRe); | |
// var local_buf = ctypes.jschar.array()(chars); //WCHAR_T | |
// var retRead = ralloc_read(remote_buf, local_buf.address()); | |
// console.log('retRead=', retRead); | |
// var freed = ralloc_free(remote_buf); | |
// console.log('freed=', freed); | |
// console.log('Button Text = ', local_buf, local_buf.toString(), local_buf.readString()); | |
// } else { | |
// console.log('Button Text = NONE'); | |
// } | |
//end get button text | |
me.alert('done i = ' + i); | |
} | |
} | |
main(); |
I find this code of ctypes interesting: https://github.com/nightwing/foximirror/blob/f40afb12beb512fb1d453afa028bc94c53f9326b/ctypes.js#L126
why does he do new new
, thats new
twice...
function SearchPD(hwnd, lParam) {
var result = true;
var buf = new new ctypes.ArrayType(ctypes.jschar, 255);
GetClassName(hwnd, buf, 255);
ans.push([buf.readString(),hwnd])
return true
if (buf.readString() == 'TMainForm') {
var PID = new DWORD;
GetWindowThreadProcessId(hwnd, PID.address());
var PName = ProcessFileName(PID.address().contents);
if (PName.toLowerCase() == 'pdownloadmanager.exe') {
LPARAM.ptr(lParam).contents = hwnd;
result = false;
}
}
return result;
}
A ton of TB_*
constants available here: https://github.com/aBothe/fxLib/blob/cf619d974856fa5929b9c8238066cdd941981258/src/fx/controls/toolbar.d#L177
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
README
Rev1
Rev2
Gets handle, but interesting this is, I get it after I do
ralloc_free
, maybe my free function doesn't work?Code that gets the handle:
Note that group buttons always have handle of
ctypes.voidptr_t(ctypes.UInt64("0x0"))
regardless of hidden or not (Recall that it is hidden it is not grouped)I tried to make this code detect a
0x0
handle with compare but I couldn't figure it out. I tried the following:Rev3
SetClassLongPtr
it only applies per profile, so I have to figure out how to get that class that is unique to each profile.Rev4
SetClassLongPtr
also takes into consideration the pid, so I now get that in this rev.Rev6
This work was actually done on June 29, 2014
Moved
main
to bottom of all codeUtter basic no thinking translated WhiteShadow's
TurnButtonIntoGroup
andCopyTBGroup
functionsBrought in
CallWindowProc
WinAPI functionBrought in some more needed
TB
constantsThis work led to to question for WhiteShadow:
Rev7
SetTBGroupFile
andUpdateToolbarParent
functionsQuestions that came up
Brought over a bunch of WinAPI functions and new structures for
RECT
andtagPOINT
as was needed for the translationmain
runs on copy pasting to scratchpad, as of now main still isn't using the translated functions yet, it's just going through the buttons and asking if you want to act on it, if i click yes then it just exits. But plan to make it move that button over to a new group if click yes.