According to the API docs I can use GlobalAlloc to create a fixed block of memory to be shared by different processes. How can I communicate to a process I started with CreateProcess the pointer to this block of memory?
GlobalAlloc does not create a buffer that can be used by multiple processes, this is because under Win32 as opposed to Win16 there are no longer separate local and global memory heaps. To allocate memory in another process you must open it with the appropriate rights then use VirtualAllocEx to allocate shared memory in NT:
; Get the ID of the process
invoke GetWindowThreadProcessId,[hWnd],OFFSET PID
; Open the process with Virtual memory priviledges
invoke OpenProcess,PROCESS_VM_OPERATION \
+ PROCESS_VM_READ + PROCESS_VM_WRITE,0,[PID]
mov [hProcess],eax
; Create a buffer inside the process space of the other program
invoke VirtualAllocEx,eax,0,[MemSize],MEM_COMMIT,PAGE_READWRITE
mov [pMem],eax
9x, unlike NT has a shared heap. You can allocate memory on the shared heap using the ordinal export 71 from COMCTL32.DLL...
Alloc = COMCTL32.DLL:71
; Allocate memory on the shared heap
invoke Alloc, [MemSize]
mov [pMem],eax
Be sure to free the memory using the appropriate function (ordinal 73)
Free = COMCTL32.DLL:73
invoke Free, [pMem]
To pass the address to your application I would use a private message, such as WM_USER and pass it as one of the parameters.
There is another option you can use across processes and even different EXE / DLL files and that is to use memory mapped files. With the correct options they use system paging memory. About the only real limitation is they must be preset to a size which you cannot change later without closing it and creating a larger one.
There are examples in the MASM32 library on how to code a memory mapped file, its easy enough to do and very useful where you need that memory scope.
Good call Hutch,
I tend to overlook the obvious and easiest way to share data, memory mapped files. This is in effect what Windows uses when passing data in messages sent between processes. There is also the clipboard if you are not daunted by that can of worms :)
The clipboard example was where i 've seen GlobalAlloc used to transfer/share data between processes without using messages, pipes or file functions.
I see the memory mapping example now in the MASM32 examples. I again overlooked what's here the whole time
Well, the clipboard is generally a painful experience. To move binary data between apps you would generally register a new format..
invoke RegisterClipboardFormat, "MyInterprocessData"
mov [CF_Interprocess], eax
When reading you first check to see if the data is the right format and available
invoke IsClipboardFormatAvailable, [CF_Interprocess]
or eax,eax
jz >
invoke OpenClipboard, [hDlg]
invoke GetClipboardData, [CF_Interprocess]
mov [hClipData],eax
invoke GlobalLock, eax
mov [pMem], eax
; do your thing here
invoke GlobalUnlock, [hClipData]
invoke CloseClipboard
:
When sending data to the clipboard..
invoke OpenClipboard, [hDlg]
invoke EmptyClipboard ; always empty the clipboard before writing to it !!!
invoke GlobalAlloc, GMEM_FIXED, 1024
mov [hClipData], eax
; Copy your data here
invoke GlobalUnlock, [hClipData]
or eax,eax
jnz >
invoke SetClipboardData, [CF_Interprocess], [hClipData]
:
invoke CloseClipboard
Haven't actually tried any of this as I avoid the clipboard as much as I can...