There is a good SO Q/A session on the general use of WM_COPYDATA
messages here, and a 'discussion' about whether or not this will work between apps of different 32/64-bitness here. However, the latter seems to be focussed on possible misuse of the 'data pointer' being passed. So, I'm raising a new question here.
I am working on getting two Windows apps to communicate/synchronize with each other and, as a first-round approach, I'm using Windows Messaging to implement this. Everything seems OK for now … but I'm using the WM_COPYDATA
message to pass info between the apps.
My question: Is this approach guaranteed to be safe when the two apps have different (32/64) bitness? I've done some tests using the code below with all four possible combinations of 32 vs 64 builds between 'client' and 'server', and all work as expected; but is this just because I'm getting 'lucky' results (from possible undefined behaviour), or does the WOW64 system (especially when server is 64-bit and client is 32) take care of all the necessary marshalling?
If anyone can confirm that it is guaranteed to work, I would very much appreciate an 'official' link/reference confirming that.
Shared header file:
static const WPARAM nmIdFilePath = 0x00001100;
struct nmLockInfoType {
char filePathID[1024];
// More elements will be added later!
};
static const nmLockInfoType nmLockInfoDefault = {
"<<<Uninitialised Image Data Path>>>",
//...
};
extern nmLockInfoType nmLockInfo; // MUST be provided by each app!
///nmLockInfoType nmLockInfo = nmLockInfoDefault; // Use this code to instatiate it (once, somewhere)!
Server program code (inside the handler for a RegisterWindowMessage(L"HANDSHAKE");
message):
//...
COPYDATASTRUCT cds;
cds.dwData = nmIdFilePath; // Pre-defined ID
cds.cbData = sizeof(nmLockInfoType);
cds.lpData = &nmLockInfo; // Pre-defined structure (see above)
//...
// Send a copy of the "Welcome Pack" data structure to the client app ...
::SendMessage(clientLock, WM_COPYDATA, WPARAM(m_hWnd), LPARAM(&cds)); // "clientLock is the HWND of the client app's MainWnd
Client Program code:
BOOL MyFrame::OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct)
{
switch (pCopyDataStruct->dwData)
{
case nmIdFilePath:
memcpy(&nmLockInfo, pCopyDataStruct->lpData, pCopyDataStruct->cbData);
return nmsSucceeded; // This is NON_ZERO so evaluates to TRUE
// Other cases here ...
}
return CMDIFrameWnd::OnCopyData(pWnd, pCopyDataStruct);
}
I'm particularly concerned about the case when the client is 32-bit but the server is 64-bit; in such a case, it would be sending a 64-bit data address to a 32-bit app (albeit, a WOW64 app). Does the in-built 'marshalling' handle this in WOW64 situations?