sergi
sergi

Reputation: 137

Shared Memory Interface between Windows 64 bits and 32 bits

I need to write code in Windows 7 (64 bits) that executes a 32-bits program that has a Shared Memory Interface (SMI). More precisely, the program I am coding writes into the SMI and the 32-bits program reads from this SMI.

The first problem that I have is that I don't have access to the source code of the 32-bit program, problem that can't be solved. The second problem is that the SMI stores the address of the information that is written. This pointed is stored as a based pointer using the following code:

gpSharedBlock->m_pData[uiDataPointer] = (char __based(gpSharedBlock)*)pData;

Were pData is a pointer to the data we are writing, and gpSharedBlock->m_pData[i] points to the i^th element stored.

Probably from here you have already noticed the problem; a pointer in W32 is 4 bytes while a pointer in W64 is 8 bytes. Then, since the value stored is a 64 bit pointer, the value finally read by the 32-bits program is not the desired one.

My question is: is there a way to do a translation of the 64-bit address to a 32-bit address such that the program that is running reads the correct information?

I have read about WOW64, and I suppose that the W32 program is running under it, but I don't know how to take advantage of that. Any ideas?

Upvotes: 2

Views: 1302

Answers (1)

Remy Lebeau
Remy Lebeau

Reputation: 595412

A __based pointer is a numeric offset from another pointer. It is effectively a virtual pointer interpretted at runtime.

A pointer is 8 bytes in 64-bit, so to be compatible with the 32-bit program, you will have to declare the pointer members of the SharedBlock type in your 64-bit code to use 4-bit integers instead of pointers, eg:

struct sSharedBlock
{
    int32_t m_pData[...];
};

pData is __based on gpSharedBlock, so the value of pData is a relative offset from the value of gpSharedBlock. Use that fact to determine the actual byte offset of your data block relative to the gpSharedBlock memory block, and then store that offset value into m_pData[] as an integer. That is what the SMI memory block is actually expecting anyway - an offset, not a real pointer. The __based keyword is just a fancy way of handling offsets using pointers without doing the offset calculations manually in code.

The original code is effectively the same as the following without needing the __based keyword:

gpSharedBlock->m_pData[uiDataPointer] = (int32_t) ( ((char*)pData) - ((char*)gpSharedBlock) );

Upvotes: 5

Related Questions