I am having problems porting x86 code x64.
I am having a Treeview on a dialogbox which I want to fill with all running processes.
Having the LARGEADDRESSAWARE switch NOT set the Treeview works but the information is not set inside the Treeview.
My guess it has to do with structure definitions but can't seem to figure it out.
Using the LARGEADDRESSAWARE switch the Treeview will crash.
here's my code:
Info_DialogProc Frame hWin, uMsg, wParam, lParam
cmp D[uMsg], WM_INITDIALOG
jne >> .WM_CLOSE_MESSAGE
//set icon
invoke LoadIcon, [hInstance], 90
invoke SendMessage, [hWin], WM_SETICON, ICON_SMALL, rax //set icon
//retrieve handle from treeview control
invoke GetDlgItem, [hWin], ID_DIALOG_INFO_TREEVIEW
mov [TreeViewHandle], rax
//fill our treeview with all processes running
invoke Retrieve_ProcessList, [TreeViewHandle]
.WM_CLOSE_MESSAGE:
cmp D[uMsg], WM_CLOSE
jne > .WM_COMMAND_MESSAGE
invoke EndDialog, [hWin], NULL
.WM_COMMAND_MESSAGE:
cmp D[uMsg], WM_COMMAND
jne >
:
.end:
xor rax, rax
ret
EndF
Retrieve_ProcessList Frame TreeViewHandle
//this functions shows all running processes
Local tvinsert :TV_INSERTSTRUCT
Local pe32 :PROCESSENTRY32
Local hProcessSnap :Q
Local Wow64Bool :Q
Local phandle :Q
invoke CreateToolhelp32Snapshot, TH32CS_SNAPPROCESS, 0
mov [hProcessSnap], rax
mov D[pe32.dwSize], SIZEOF PROCESSENTRY32
invoke Process32First, [hProcessSnap], offset pe32
cmp rax, 0
jnz > .store_running_process_string
.get_next_running_process
invoke Process32Next, [hProcessSnap], offset pe32
cmp rax, 0
jz >> .get_running_process_exit
.store_running_process_string
invoke OpenProcess, PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION| PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_CREATE_THREAD | PROCESS_TERMINATE, NULL,[pe32.th32ProcessID]
mov [phandle], rax
invoke IsWow64Process, rax, offset Wow64Bool
cmp B[Wow64Bool], 1
je >>
//retrieve process id and .exe name string
invoke wsprintf, offset wsprintfbuffer, '%.8d %s', [pe32.th32ProcessID], offset pe32.szExeFile
mov Q[tvinsert.hParent], NULL
mov Q[tvinsert.hInsertAfter], TVI_ROOT
mov D[tvinsert.item.mask], TVIF_TEXT
mov Q[tvinsert.item.pszText], offset wsprintfbuffer
mov D[tvinsert.item.iImage], NULL
mov D[tvinsert.item.iSelectedImage], 1
invoke SendMessage, [TreeViewHandle], TVM_INSERTITEM, 0, offset tvinsert
//invoke GetProcessImageFileName, eax, offset ImageFileName, sizeof ImageFileName //returns full device name
//invoke GetModuleFileNameEx, eax, NULL, offset ImageFileName, sizeof ImageFileName
invoke GetModuleFileNameEx, [phandle], NULL, offset FilePathBuffer, sizeof FilePathBuffer
mov Q[tvinsert.hInsertAfter], TVI_LAST
//mov Q[tvinsert.item.pszText], offset ImageFileName
mov Q[tvinsert.item.pszText], offset FilePathBuffer
invoke SendMessage, [TreeViewHandle], TVM_INSERTITEM, 0, offset tvinsert
:
jmp < .get_next_running_process
.get_running_process_exit
xor rax, rax
ret
Endf
And here are the structure definitions in Commctrl.h
#define TV_INSERTSTRUCTA TVINSERTSTRUCTA
#define TV_INSERTSTRUCTA TVINSERTSTRUCTW
TVINSERTSTRUCTA STRUCT
hParent HANDLE
hInsertAfter HANDLE
UNION
itemex TVITEMEXA
item TVITEMA
ENDUNION
ENDS
TVITEMEXA STRUCT
mask DD
hItem HANDLE
state DD
stateMask DD
pszText PTR
cchTextMax DD
iImage DD
iSelectedImage DD
cChildren DD
lParam LPARAM
iIntegral DD
uStateEx DD
#IF WINVER >= NTDDI_VISTA
hwnd HANDLE
iExpandedImage DD
#ENDIF
#IF WINVER >= NTDDI_WIN7
iReserved DD
#ENDIF
ENDS
TVITEMA STRUCT
mask DD
hItem HANDLE
state DD
stateMask DD
pszText PTR
cchTextMax DD
iImage DD
iSelectedImage DD
cChildren DD
lParam LPARAM
ENDS
Structure elements in x64 need to be aligned to their natural size.
TVITEMA STRUCT
mask DD
hItem HANDLE
...
ENDS
hItem is 8 bytes but here is aligned to 4, so everything after it is misaligned.
MASM syntax would be
TVITEMA STRUCT 8
mask DD
hItem HANDLE
...
ENDS
;or
TVITEMA STRUCT
mask DD
align1 DD
hItem HANDLE
...
ENDS
typedef struct tagTVITEMEX {
UINT mask;
HTREEITEM hItem;
UINT state;
UINT stateMask;
LPTSTR pszText;
int cchTextMax;
int iImage;
int iSelectedImage;
int cChildren;
LPARAM lParam;
int iIntegral;
#if (_WIN32_IE >= 0x0600)
UINT uStateEx;
HWND hwnd;
int iExpandedImage;
#endif
#if (NTDDI_VERSION >= NTDDI_WIN7)
int iReserved;
#endif
} TVITEMEX, *LPTVITEMEX;
So in x64 int and pointers are QWORD / DQ?
Your structs are for 32-bit?
Hi TWell,
If you want to keep LARGEADDRESSAWARE you can not use :
jmp somelabel[rax*8]
or
jmp [somelabel+rax*8]
you have to dothis:
lea rcx,somelabel
jmp QWORD PTR[rcx+rax*8]
Thanks for the answers guys,
I've found on google that the TVITEMEX structure on x86 = 60 bytes and on x64 = 80 bytes
I am trying to determine the right function defintions, here are my results so far.
Freaking code still crashes though so at the moment it's trial and error to determine the right structures.
TV_INSERTSTRUCT64 STRUCT
hParent DQ
hInsertAfter DQ
UNION
itemex TV_ITEMEX64
item TV_ITEM64
ENDUNION
ENDS
TV_ITEMEX64 STRUCT //Total size on x86 = 60 bytes on x64 = 80 bytes
mask DD // 0 - size 4
hItem DD // 4 - size 8
state DD // 8 - size 12
stateMask DD // 12 - size 16
padding2 DD // - size 20
pszText DQ // 16 --> 20 after padding (a pointer) - size 28
cchTextMax DD // 28 - size 32
iImage DD // 32 - size 36
iSelectedImage DD // 36 - size 40
cChildren DD // 40 - size 44
padding3 DD // - size 48
lParam DQ // 44 --> 48 after padding (a pointer) - size 56
iIntegral DD // 56 - size 60
#IF WINVER >= NTDDI_VISTA
uStateEx DD // 60 - size 64
hwnd DD // 64 - size 68
iExpandedImage DD // 68 - size 72
#ENDIF
#IF WINVER >= NTDDI_WIN7
iReserved DD // 72 - size 76
padding4 DD // 76 --> Total lenght before padding is 76 which is not dividable by 8 - size 80
#ENDIF
ENDS
TV_ITEM64 STRUCT //Total size 56 bytes
mask DD // 0 - size 4
hItem DD // 4 - size 8
state DD // 8 - size 12
stateMask DD // 12 - size 16
padding2 DD // - size 20
pszText DQ // 16 --> 20 after padding (a pointer) - size 28
cchTextMax DD // 28 - size 32
iImage DD // 32 - size 36
iSelectedImage DD // 36 - size 40
cChildren DD // 40 - size 44
padding3 DD // - size 48
lParam DQ // 44 --> 48 after padding (a pointer) - Total lenght is 56 which is dividable by 8 - size 56 bytes
ENDS
Although I think hItem should be a QWORD aswell following the rules that handles are 64 bit on 64 bit Windows.
Quote
I've found on google that the TVITEMEX structure on x86 = 60 bytes and on x64 = 80 bytes
Must be a world of despair,you have include who give you the correct size of the structure here:
http://masm32.com/board/index.php?topic=563.msg4563#msg4563
in commctrl.sdk DEFALIGNMASM get a defaut value,8=QWORD
Quote
TVITEMEXA STRUCT DEFALIGNMASM
imask DWORD ?
hItem XMASM ?
state DWORD ?
stateMask DWORD ?
pszText XMASM ?
cchTextMax DWORD ?
iImage DWORD ?
iSelectedImage DWORD ?
cChildren DWORD ?
lParam LPARAM ?
iIntegral DWORD ?
IF ( _WIN32_IE GE 00600h)
uStateEx DWORD ?
hwnd HWND ?
iExpandedImage DWORD ?
ENDIF
IF ( NTDDI_VERSION GE NTDDI_WIN7)
iReserved DWORD ?
ENDIF
TVITEMEXA ENDS
Hi, FlySky!
Example of Treeview with LARGEADDRESSAWARE:NO (http://masm32.com/board/index.php?topic=4190.msg47863#msg47863)