0
votes

I am trying to pass data from an x64 app to a x86 app using named pipes and overlapped I/O like what is defined here:

http://msdn.microsoft.com/en-us/library/windows/desktop/aa365603(v=vs.85).aspx

My server application's call to WriteFileEx succeeds and the structure I am sending through the pipe seems ok, however when I call ReadFile on the client side the data structure I retrieve is corrupted or different to the data that I sent, but it also successfully reads.

My client application has a unicode character set and the server's character set is 'not set', which I assume defaults to multibyte. I'm not in a position to change the server's character set to unicode.

Would this data corruption just be because I need to convert from multibyte to wide char on the client after I retrieve / read the data structure? If so is there built in helper functions that I can call on do to that?

Data structure being sent (defined identically on the server and client):

typedef struct
{
    int id;
    float vertices[VERTICES_COUNT][VERTICES_COMPONENTS];
    unsigned short indices[INDICES_COUNT];
    float texCoords[TEXTURE_COORD_COUNT][TEXTURE_COORD_COMPONENT];
    unsigned char texData[TEXTURE_SIZE];
} MESHINST, *LPMESHINST;

typedef struct
{
    OVERLAPPED oOverlap;
    HANDLE pipeInst;
    int addedCount;
    MESHINST meshes[MESH_GROUP_BUFFER];
    int removedCount;
    int removed[MESH_REMOVE_BUFFER];

} MESHGROUPINST, *LPMESHGROUPINST;

WriteFileEx call on the server:

LPMESHGROUPINST meshes = (LPMESHGROUPINST)lpOverLap;
fWrite = WriteFileEx(
    meshes->pipeInst,
    (wchar_t*)meshes,
    sizeof(MESHGROUPINST),
    (LPOVERLAPPED)meshes,
    (LPOVERLAPPED_COMPLETION_ROUTINE)CompletedWriteRoutine);

ReadFile call on the client:

(in header)

MESHGROUPINST _meshes;

(in cpp)

do
{
    _success = ReadFile(
        _pipe,
        (wchar_t*)&_meshes,
        sizeof(MESHGROUPINST),
        &_numOfBytesRead,
        NULL);
} while (!_success);
2
Traditionally you would want to pass a void pointer as the buffer. If you can't guarantee that the structure is byte for byte identical on the client and server you're going to need to serialise/deserialise it properly. - Retired Ninja
ReadFile/WriteFileEx are not affected by Unicode settings. The problem is elsewhere. It's not clear why you're casting to wchar_t* either, because both of those take void*. - Cory Nelson
The issue isn't Unicode/ANSI. The issue is 64-bit/32-bit. Your structure includes an OVERLAPPED structure and a HANDLE, both of which change size between 64-bit and 32-bit, and which @CoryNelson notes don't make sense to transfer between processes anyway. - Raymond Chen
I will factor these out of the structure that actually gets written / sent (I'll test it when I get home), and then I'll see how it goes. Thanks. - Avidius

2 Answers

1
votes

What is the type of _meshes in the ReadFile call? If it's a pointer, you'll be reading into the pointer, not the data being pointed to:

&_meshes

Should be:

_meshes

Also, it looks like you're writing process-specific HANDLE and OVERLAPPED info. Did you mean to write those?

You'll need to add more code for better help.

0
votes

You need to ensure the structure is sent and received with 1-byte packing. Use #pragma pack(1) around the struct you wish to send/receive:

#pragma pack(1)
typedef struct
{
    int id;
    float vertices[VERTICES_COUNT][VERTICES_COMPONENTS];
    unsigned short indices[INDICES_COUNT];
    float texCoords[TEXTURE_COORD_COUNT][TEXTURE_COORD_COMPONENT];
    unsigned char texData[TEXTURE_SIZE];
} MESHINST, *LPMESHINST;
#pragma pack()