title: WriteFileEx completion routine succeeds, but bytes transferred is incorrect
body: <p>I'm communicating between two processes on different machines via a pipe, using IO completion routines.</p>
  
  <p>Occasionally, when the completion routine for WriteFileEx gets called, the completion routine parameter dwErrorCode is 0 (i.e. no error), GetOverlappedResult returns true (i.e. no error), but dwNumberOfBytesTransfered does not match nNumberOfBytesToWrite in the call to WriteFileEx. I only see this on the client end of the pipe however.</p>
  
  <p>If the number of bytes transferred does not match the number of bytes that was requested to transfer, how can this be deemed a success?</p>
  
  <p>This is how the client's handle to the pipe is created:</p>
  
  <pre><code>mHPipe = CreateFile(pipeName,                 // pipe name 
                      GENERIC_READ |            // read and write access 
                      GENERIC_WRITE, 
                      0,                        // no sharing 
                      NULL,                     // default security attributes
                      OPEN_EXISTING,            // opens existing pipe 
                      FILE_FLAG_OVERLAPPED |    // overlapped
                      FILE_FLAG_WRITE_THROUGH,  // write through mode
                      NULL);                    // no template file 
  
  // do some checking...
  
  // The pipe connected; change to message-read mode. 
  DWORD dwMode = PIPE_READMODE_MESSAGE; 
  BOOL fSuccess = SetNamedPipeHandleState(mHPipe,   // pipe handle 
                                          &amp;dwMode,  // new pipe mode 
                                          NULL,     // don't set maximum bytes 
                                          NULL);    // don't set maximum time 
  </code></pre>
  
  <p>Can anyone see why this would happen?</p>
  
  <p>Thanks</p>
  
  <p><strong>EDIT:</strong></p>
  
  <p>The relevant WriteFileEx code is as follows:</p>
  
  <pre><code>void WINAPI CompletedWriteRoutine(DWORD dwErrorCode, DWORD dwNumberOfBytesTransfered, LPOVERLAPPED lpOverLap)
  {
    BOOL fWrite = FALSE;
    LPPIPEINST lpPipeInst = (LPPIPEINST)lpOverLap;
  
    //
    // !  99.9% of the time, dwNumberOfBytesTransfered == lpPipeInst-&gt;cbDataSize
    //    but 0.1% of the time, they do not match
    //
  
    // Some stuff
  
    // Copy next message to send
    memcpy_s(lpPipeInst-&gt;chData, sizeof(lpPipeInst-&gt;chData), pMsg-&gt;msg, pMsg-&gt;size);
    lpPipeInst-&gt;cbDataSize = pMsg-&gt;size;
  
    // Some other stuff
  
    fWrite = WriteFileEx(lpPipeInst-&gt;hPipeInst,
                         lpPipeInst-&gt;chData,
                         lpPipeInst-&gt;cbDataSize,
                         (LPOVERLAPPED) lpPipeInst,
                         (LPOVERLAPPED_COMPLETION_ROUTINE)CompletedWriteRoutine);
  
    // Some other, other stuff
  }
  </code></pre>
  
  <p>Where LPPIPEINST is declared as:</p>
  
  <pre><code>typedef struct 
  { 
    OVERLAPPED oOverlap;      // must remain first item
    HANDLE hPipeInst;
    TCHAR chData[BUFSIZE];
    DWORD cbDataSize;
  } PIPEINST, *LPPIPEINST;
  </code></pre>
  
  <p>And the initial call to CompletedWriteRoutine is given the lpOverlap parameter declared thusly:</p>
  
  <pre><code>PIPEINST pipeInstWrite        = {0};
  pipeInstWrite.hPipeInst       = client.getPipeHandle();
  pipeInstWrite.oOverlap.hEvent = hEvent[eventWriteComplete];
  </code></pre>
  
  <p><strong>EDIT:</strong></p>
  
  <p>After trying re-initializing the overlapped structure as Harry suggested, I noticed something peculiar.
  I <code>memset</code> the <code>OVERLAPPED</code> structure to zero before each <code>WriteFileEx</code>, and roughly 1/5000 completion routine callbacks, the <code>cbWritten</code> parameter and the <code>OVERLAPPED</code> structure's <code>InternalHigh</code> member was now set to the size of the previous message, instead of the most recent message. I added some logging to file on both the client and server ends of the pipe inside the completion routines, and the data sent and received at both ends was an exact match (and the correct, expected data). This then unveiled that in the time taken to write the data to a file, the <code>InternalHigh</code> member in the <code>OVERLAPPED</code> structure had changed to now reflect the size of the message I was expecting (<code>cbWritten</code> remains the old message size). I removed the file logging, and am now able to reproduce the issue like clockwork with this code:</p>
  
  <pre><code>void WINAPI CompletedWriteRoutine(DWORD dwErr, DWORD cbWritten, LPOVERLAPPED lpOverLap)
  {
    LPPIPEINST lpPipeInst = (LPPIPEINST)lpOverLap;
  
    // Completion routine says it wrote the amount of data from the previous callback
    if (cbWritten != lpPipeInst-&gt;cbDataSize)
    {
      // Roughly 1 in 5000 callbacks ends up in here
  
      OVERLAPPED ovl1 = lpPipeInst-&gt;oOverlap; // Contains size of previous message, i.e. cbWritten
      Sleep(100);
      OVERLAPPED ovl2 = lpPipeInst-&gt;oOverlap; // Contains size of most recent message, i.e lpPipeInst-&gt;cbDataSize
    }
    ...
  }
  </code></pre>
  
  <p>It seems that sometimes, the completion routine is being called before the <code>OVERLAPPED</code> structure and the completion routine input parameter is updated. I'm using <code>MsgWaitForMultipleObjectsEx(eventLast, hEvent, INFINITE, QS_POSTMESSAGE, MWMO_ALERTABLE);</code> for the completion routines to be called on Windows 7 64 bit.</p>
  
  <p><a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms684139%28v=vs.85%29.aspx" rel="nofollow">This MSDN page</a> says:</p>
  
  <blockquote>
    <p>"The system does not use the OVERLAPPED structure after the completion routine is called, so the completion routine can deallocate the memory used by the overlapped structure."</p>
  </blockquote>
  
  <p>...so apparently, what this code can reproduce should never happen?</p>
  
  <p>Is this a WINAPI bug?</p>