Author Topic: Sharing data between 32- and 64-bit applications  (Read 5765 times)

jj2007

  • Member
  • *****
  • Posts: 13957
  • Assembly is fun ;-)
    • MasmBasic
Sharing data between 32- and 64-bit applications
« on: October 28, 2016, 11:19:40 AM »
Here is a simple server-client pair, where server is a 32-bit console application:

include \masm32\MasmBasic\MasmBasic.inc      ; download
  Init
  Let esi="{\rtf1\ansi This is \b bold \b0 text}"      ; the client understands RTF, too ;)
  .Repeat
      Let esi=Input$("Type the text to send, or Esc & Return to exit: ", esi)
      SendData "Hello World64", esi
  .Until !Len(esi)
EndOfCode


The server uses SendData (about 160k max). At the receiving end, a simple handler sets the text to a RichEdit control:
Code: [Select]
  Case_ WM_COPYDATA
jinvoke SetWindowText, hEdit, wmcd$()

The client can be built as 32- or 64-bit application, using ML/ML64/HJWasm/AsmC:
Code: [Select]
include \Masm32\MasmBasic\Res\JBasic.inc ; hit F6 to build this program
.data ; OPT_64 1 ; 0=32-bit, 1=64-bit assembly
wcx WNDCLASSEX <WNDCLASSEX, CS_HREDRAW or CS_VREDRAW or CS_OWNDC, WndProc, 0, 0, 1, 2, 3, COLOR_BTNFACE+1, 0, txClass, SIZE_P>
txClass db "JBasicGUI", 0 ; OPT_Assembler ML ; try HJWasm or AsmC, too
hEdit SIZE_P ? ; the handle to the edit control is a pointer, 32 or 64 bits wide
Init
WinMain proc
LOCAL msg:MSG
  wc equ [rbx.WNDCLASSEX] ; we use an equate for better readability
  lea rbx, wcx
  mov wc.hInstance, rv(GetModuleHandle, 0)
  mov wc.hIcon, rv(LoadIcon, rax, IDI_APPLICATION) ; click on the first Rsrc bookmark to change the icon
  mov wc.hIconSm, rax ; the rv macro returns results in rax
  mov wc.hCursor, rv(LoadCursor, NULL, IDC_ARROW) ; get a cursor
  jinvoke RegisterClassEx, rbx ; the window class needs to be registered
  wsStyle=WS_OVERLAPPED or WS_VISIBLE or WS_CLIPCHILDREN or WS_SYSMENU
  jinvoke CreateWindowEx, WS_EX_TOPMOST, wc.lpszClassName, Chr$("Hello World64"), wsStyle, 300+320*@64, 127, 700, 600, NULL, rv(LoadMenu, wc.hInstance, 100), wc.hInstance, NULL
  msgLoop: jinvoke TranslateMessage, addr msg ; translates virtual-key messages into character messages
jinvoke DispatchMessage, addr msg ; dispatches a message to a window procedure
jinvoke GetMessage, addr msg, 0, 0, 0 ; retrieve a message from the queue, and return a BOOL
mcs inc eax : shr eax, 1 : jne msgLoop ; quit if GetMessage returned 0 (exit OK) or -1 (error)
  jinvoke ExitProcess, msg.wParam
WinMain endp
wmcd$ macro
  mov rax, lParam
  EXITM <[rax.COPYDATASTRUCT.lpData]>
ENDM
WndProc proc <cb cs> uses rsi rdi rbx hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
  Switch_ uMsg
  Case_ WM_COPYDATA
jinvoke SetWindowText, hEdit, wmcd$()
  Case_ WM_CREATE
reStyle=WS_VISIBLE or WS_CHILD or ES_MULTILINE or WS_VSCROLL or WS_HSCROLL or ES_AUTOHSCROLL or ES_AUTOVSCROLL or ES_NOHIDESEL
jinvoke LoadLibrary, Chr$("RichEd20") ; we want to add a RichEdit control
mov hEdit, rv(CreateWindowEx, WS_EX_CLIENTEDGE, Chr$("RichEdit20A"), NULL, reStyle, 3, 3, 700-12, 600-30, hWnd, 111, wcx.hInstance, NULL)
jinvoke SendMessage, hEdit, EM_SETTARGETDEVICE, 0, 0 ; word wrap on
jinvoke SendMessage, hEdit, EM_EXLIMITTEXT, 0, -1 ; no limit
jinvoke SendMessage, hEdit, WM_SETFONT, rv(GetStockObject, ANSI_FIXED_FONT), 0
jinvoke SetWindowText, hEdit, Str$(Chr$("This program was built with", 13, 10, @AsmUsed$(1), " in %i-bit mode", 13, 10), jBits)
  Case_ WM_DESTROY
jinvoke PostQuitMessage, NULL
  Endsw_
  mcs jinvoke DefWindowProc, hWnd, uMsg, wParam, lParam : ret
WndProc endp
EndOfCode ; OPT_Icon Eye

mabdelouahab

  • Member
  • ****
  • Posts: 537
Re: Sharing data between 32- and 64-bit applications
« Reply #1 on: October 28, 2016, 06:02:14 PM »
Good idea jj2007  :t
For me I use COM LocalServers

MichaelW

  • Global Moderator
  • Member
  • *****
  • Posts: 1196
Re: Sharing data between 32- and 64-bit applications
« Reply #2 on: October 29, 2016, 04:20:42 AM »
The 160K max was determined by test, or is it documented somewhere?
Well Microsoft, here’s another nice mess you’ve gotten us into.

jj2007

  • Member
  • *****
  • Posts: 13957
  • Assembly is fun ;-)
    • MasmBasic
Re: Sharing data between 32- and 64-bit applications
« Reply #3 on: October 29, 2016, 07:26:06 AM »
160k is the limit of the internal MasmBasic circulary buffer. SendData was not meant for big strings; but you are right that it should be documented :bgrin:

hutch--

  • Administrator
  • Member
  • ******
  • Posts: 10583
  • Mnemonic Driven API Grinder
    • The MASM32 SDK
Re: Sharing data between 32- and 64-bit applications
« Reply #4 on: October 29, 2016, 08:23:50 AM »
Has anyone tried memory mapped files yet. I know you can use TCP/IP like some of the databases do, the other comment is whether messaging works across the 32/64 bit boundary, IE: SendMessage HWND_BROADCAST with private messages for example. I will get around to testing this stuff but I have too much to do at the moment.
hutch at movsd dot com
http://www.masm32.com    :biggrin:  :skrewy:

mabdelouahab

  • Member
  • ****
  • Posts: 537
Re: Sharing data between 32- and 64-bit applications
« Reply #5 on: October 29, 2016, 09:28:43 AM »
Has anyone tried memory mapped files yet. I know you can use TCP/IP like some of the databases do, the other comment is whether messaging works across the 32/64 bit boundary, IE: SendMessage HWND_BROADCAST with private messages for example. I will get around to testing this stuff but I have too much to do at the moment.
Easy
Run the 32bit app, then run the 64bit app, press Ok (MessageBox), and see what happens to the 32bit app
32bit:
Code: [Select]
include masm32rt.inc
.data
lpFileMapping dd 0
lpBaseAddr dd 0
.code
Start:
invoke CreateFileMapping,INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, NULL, 1024, chr$("Sh3264.333")
.if eax
mov lpFileMapping,eax
invoke MapViewOfFile,lpFileMapping, FILE_MAP_ALL_ACCESS , NULL, NULL, NULL
.if eax
mov lpBaseAddr,eax
printf("\n Value = 144 \n Wait while Value = 64.\n")
mov edi,lpBaseAddr
mov dword ptr [edi],144
@@:
mov eax,dword ptr [edi]
cmp eax,64
jne @B

printf("\n Now Value = 64 \n")
invoke UnmapViewOfFile,lpBaseAddr
.endif
invoke CloseHandle,lpFileMapping
.endif
inkey
exit
End Start
64bit:
Code: [Select]
include X64.inc
include win64.inc
Include_lib kernel32
Include_lib user32
Include_lib msvcrt
  .data
lpFileMapping dq 0
lpBaseAddr dq 0
  .code

main proc
.invoke OpenFileMapping,FILE_MAP_ALL_ACCESS, FALSE, "Sh3264.333"
.if RAX
mov lpFileMapping,RAX
.invoke MapViewOfFile,lpFileMapping, FILE_MAP_ALL_ACCESS , NULL, NULL, NULL
.if RAX
mov lpBaseAddr,RAX
mov RDI,lpBaseAddr
.invoke vc_printf ,"Value =%d",dword ptr [RDI]
.invoke MessageBox,0,"Any Key To set Value = 64",0,0
mov RDI,lpBaseAddr
mov dword ptr [RDI],64
.invoke UnmapViewOfFile,lpBaseAddr
.endif
.invoke CloseHandle,lpFileMapping
.endif
.invoke ExitProcess,0
main endp
end 


jj2007

  • Member
  • *****
  • Posts: 13957
  • Assembly is fun ;-)
    • MasmBasic
Re: Sharing data between 32- and 64-bit applications
« Reply #6 on: October 29, 2016, 10:07:01 AM »
the other comment is whether messaging works across the 32/64 bit boundary

The SendData macro uses the WM_COPYDATA message.