Note that there are some explanatory texts on larger screens.

plurals
  1. POErrors calling WriteFile from visual basic .net 2010 on a named pipe
    primarykey
    data
    text
    <p>I've been banging my head on this one all day, and I just can't make sense of the various (sometimes conflicting) documentation on this. To add to the confusion, at some point during the day, this did (sort of) work - i.e. didn't throw an access violation error. But the data at the other end of the pipe was nonsense, so I suspect it only 'worked' by accident.</p> <p>I have a vb.net program (using .net 3.0 so no support for System.IO.NamedPipes :( ) which creates a named pipe and waits for another app to connect and send some data. As an 'ack', I then want the vb program to send back the total length of the message received. I'm able to create the pipe, wait for a connection and receive the message, but it barfs on trying to send the 'ack' using <code>WriteFile</code>. The (current) definition I'm using for <code>WriteFile</code> is based on the corresponding <code>ReadFile</code>, which seems to work fine:</p> <pre><code>Declare Function ReadFile Lib "kernel32" ( _ ByVal hFile As Integer, _ ByRef lpBuffer As Byte, _ ByVal nNumberOfBytesToRead As Integer, _ ByRef lpNumberOfBytesRead As Integer, _ ByVal lpOverlapped As Integer) _ As Integer Declare Function WriteFile Lib "kernel32" ( _ ByVal hFile As Long, _ ByRef lpBuffer As Byte, _ ByVal nNumberOfBytesToWrite As Integer, _ ByRef lpNumberOfBytesWritten As Integer, _ ByVal lpOverlapped As Integer) _ As Integer </code></pre> <p>The stripped down code (error checking and debug printing removed) looks like this:</p> <pre><code>Dim openMode = PIPE_ACCESS_DUPLEX Or FILE_FLAG_FIRST_PIPE_INSTANCE Dim pipeMode = PIPE_WAIT Or PIPE_TYPE_MESSAGE Or PIPE_READMODE_MESSAGE Dim res ' Result of dll calls pipeN2Q = CreateNamedPipe("\\.\pipe\N2Q", openMode, pipeMode, 10, 1024, 1024, 2000, IntPtr.Zero) res = ConnectNamedPipe(pipeN2Q, 0) Dim rxCount As Integer = 0 ' To hold the number of bytes received Dim txCount As Integer = 0 ' To hold the number of bytes sent Dim txReq As Integer = 2 ' To hold the number of bytes we're going to ask to be sent during the 'ack' Dim dataIn(256) As Byte res = ReadFile(pipeN2Q, dataIn(0), 256, rxCount, Nothing) Dim recvBuffer As String = System.Text.Encoding.ASCII.GetString(dataIn, 0, rxCount) Dim dataOut(2) As Byte dataOut(0) = 42 dataOut(1) = 43 res = WriteFile(pipeN2Q, dataOut(0), txReq, txCount, Nothing) </code></pre> <p>Once the code gets to <code>WriteFile</code>, it throws an AccessViolationException - "Attempted to read or write protected memory." I'm assuming this is complaining about the <code>dataOut</code> parameter, but it gives no further details. Things I've tried so far include:</p> <ul> <li>Changing the declaration of <code>WriteFile</code> so that <code>lpBuffer</code> is declared: <code>ByVal lpBuffer as IntPtr</code></li> <li>Allocating dataOut using <code>Marshal.AllocHGlobal(txReq)</code> and initialised using <code>Marshal.WriteInt16()</code></li> <li>Allocating a large buffer for <code>dataOut</code> (1024 bytes) and initialising them to zeros</li> </ul> <p>To be clear, the message coming from the other app is received perfectly and <code>recvBuffer</code> has the string exactly as sent. I just can't persuade WriteFile to cooperate (except once, perhaps by chance, and I haven't been able to repeat it). I'm hoping it's just something in either the declaration or the initialisation of the variables - any clues?</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload