annotate Windows/WindowsNamedPipe.cs @ 110:5e717aac4c1d

Improvements in RemotingManager (close event) and Windows Named Pipe (accept time-out)
author Ivo Smits <Ivo@UCIS.nl>
date Fri, 07 Nov 2014 18:33:34 +0100
parents ec222fb577dd
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
55
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1 ???using System;
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
2 using System.ComponentModel;
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
3 using System.IO;
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
4 using System.Runtime.InteropServices;
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
5 using System.Threading;
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
6 using Microsoft.Win32.SafeHandles;
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
7 using UCIS.Util;
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
8
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
9 namespace UCIS.Windows {
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
10 public class WindowsNamedPipe : PacketStream {
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
11 delegate Byte[] ReadPacketDelegate();
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
12 ReadPacketDelegate ReadPacketDelegateInstance = null;
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
13 SafeFileHandle PipeHandle;
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
14
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
15 [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
16 static extern SafeFileHandle CreateFile(string lpFileName, uint dwDesiredAccess, [MarshalAs(UnmanagedType.U4)] FileShare dwShareMode, IntPtr lpSecurityAttributes, [MarshalAs(UnmanagedType.U4)] FileMode dwCreationDisposition, UInt32 dwFlagsAndAttributes, IntPtr hTemplateFile);
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
17 [DllImport("kernel32.dll", SetLastError = true)]
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
18 static extern unsafe bool ReadFile(SafeFileHandle hFile, Byte* lpBuffer, uint nNumberOfBytesToRead, out uint lpNumberOfBytesRead, NativeOverlapped* lpOverlapped);
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
19 [DllImport("kernel32.dll", SetLastError = true)]
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
20 static extern unsafe bool WriteFile(SafeFileHandle hFile, Byte* lpBuffer, uint nNumberOfBytesToWrite, out uint lpNumberOfBytesWritten, NativeOverlapped* lpOverlapped);
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
21 [DllImport("kernel32.dll", SetLastError = true)]
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
22 static extern unsafe bool GetOverlappedResult(SafeFileHandle hFile, NativeOverlapped* lpOverlapped, out uint lpNumberOfBytesTransferred, Boolean bWait);
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
23 [DllImport("kernel32.dll", SetLastError = true)]
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
24 static extern bool SetNamedPipeHandleState(SafeFileHandle hNamedPipe, ref UInt32 lpMode, IntPtr lpMaxCollectionCount, IntPtr lpCollectDataTimeout);
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
25 [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Ansi)]
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
26 static extern SafeFileHandle CreateNamedPipe([MarshalAs(UnmanagedType.LPStr)] String lpName, UInt32 dwOpenMode, UInt32 dwPipeMode, UInt32 nMaxInstances, UInt32 nOutBufferSize, UInt32 nInBufferSize, UInt32 nDefaultTimeOut, IntPtr lpSecurityAttributes);
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
27 [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
28 static extern unsafe bool ConnectNamedPipe(SafeFileHandle hNamedPipe, NativeOverlapped* lpOverlapped);
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
29 [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
30 static extern unsafe bool GetNamedPipeInfo(SafeFileHandle hNamedPipe, out UInt32 lpFlags, IntPtr lpOutBufferSize, IntPtr lpInBufferSize, IntPtr lpMaxInstances);
110
5e717aac4c1d Improvements in RemotingManager (close event) and Windows Named Pipe (accept time-out)
Ivo Smits <Ivo@UCIS.nl>
parents: 55
diff changeset
31 [DllImport("kernel32.dll")]
5e717aac4c1d Improvements in RemotingManager (close event) and Windows Named Pipe (accept time-out)
Ivo Smits <Ivo@UCIS.nl>
parents: 55
diff changeset
32 [return: MarshalAs(UnmanagedType.Bool)]
5e717aac4c1d Improvements in RemotingManager (close event) and Windows Named Pipe (accept time-out)
Ivo Smits <Ivo@UCIS.nl>
parents: 55
diff changeset
33 static extern bool CancelIo(SafeFileHandle hFile);
55
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
34
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
35 const UInt32 PIPE_ACCESS_DUPLEX = 0x00000003;
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
36 const UInt32 FILE_FLAG_OVERLAPPED = 0x40000000;
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
37 const UInt32 PIPE_TYPE_BYTE = 0x00000000;
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
38 const UInt32 PIPE_TYPE_MESSAGE = 0x00000004;
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
39 const UInt32 PIPE_READMODE_BYTE = 0x00000000;
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
40 const UInt32 PIPE_READMODE_MESSAGE = 0x00000002;
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
41
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
42 public int InitialMessageBufferSize { get; set; }
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
43
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
44 private WindowsNamedPipe(SafeFileHandle handle) {
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
45 InitialMessageBufferSize = 1024;
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
46 this.PipeHandle = handle;
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
47 }
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
48 public static WindowsNamedPipe Create(String name, Boolean messageMode, uint maxClients, uint readBuffer, uint writeBuffer, uint defaultTimeout) {
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
49 SafeFileHandle handle = CreateNamedPipe(name, PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
50 messageMode ? (PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE) : (PIPE_TYPE_BYTE | PIPE_READMODE_BYTE),
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
51 maxClients, writeBuffer, readBuffer, defaultTimeout, IntPtr.Zero);
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
52 if (handle.IsInvalid) throw new Win32Exception(Marshal.GetLastWin32Error());
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
53 return new WindowsNamedPipe(handle);
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
54 }
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
55 public static WindowsNamedPipe Connect(String name) {
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
56 SafeFileHandle handle = CreateFile(name, 0x40000000 | 0x80000000, FileShare.None, IntPtr.Zero, FileMode.Open, 0x40000000, IntPtr.Zero);
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
57 if (handle.IsInvalid) throw new Win32Exception(Marshal.GetLastWin32Error());
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
58 UInt32 flags;
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
59 if (!GetNamedPipeInfo(handle, out flags, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero)) throw new Win32Exception(Marshal.GetLastWin32Error());
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
60 UInt32 lpMode = (flags & PIPE_TYPE_MESSAGE) != 0 ? PIPE_READMODE_MESSAGE : PIPE_READMODE_BYTE;
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
61 if (!SetNamedPipeHandleState(handle, ref lpMode, IntPtr.Zero, IntPtr.Zero)) throw new Win32Exception(Marshal.GetLastWin32Error());
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
62 return new WindowsNamedPipe(handle);
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
63 }
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
64
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
65 public unsafe void WaitForClient() {
110
5e717aac4c1d Improvements in RemotingManager (close event) and Windows Named Pipe (accept time-out)
Ivo Smits <Ivo@UCIS.nl>
parents: 55
diff changeset
66 WaitForClient(-1);
5e717aac4c1d Improvements in RemotingManager (close event) and Windows Named Pipe (accept time-out)
Ivo Smits <Ivo@UCIS.nl>
parents: 55
diff changeset
67 }
5e717aac4c1d Improvements in RemotingManager (close event) and Windows Named Pipe (accept time-out)
Ivo Smits <Ivo@UCIS.nl>
parents: 55
diff changeset
68 public unsafe void WaitForClient(int millisecondsTimeout) {
55
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
69 uint nread;
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
70 using (ManualResetEvent evt = new ManualResetEvent(false)) {
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
71 NativeOverlapped overlapped = new NativeOverlapped();
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
72 overlapped.EventHandle = evt.SafeWaitHandle.DangerousGetHandle();
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
73 if (!ConnectNamedPipe(PipeHandle, &overlapped)) {
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
74 int err = Marshal.GetLastWin32Error();
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
75 if (err != 997) throw new Win32Exception(err);
110
5e717aac4c1d Improvements in RemotingManager (close event) and Windows Named Pipe (accept time-out)
Ivo Smits <Ivo@UCIS.nl>
parents: 55
diff changeset
76 if (!evt.WaitOne(millisecondsTimeout)) {
5e717aac4c1d Improvements in RemotingManager (close event) and Windows Named Pipe (accept time-out)
Ivo Smits <Ivo@UCIS.nl>
parents: 55
diff changeset
77 CancelIo(PipeHandle);
5e717aac4c1d Improvements in RemotingManager (close event) and Windows Named Pipe (accept time-out)
Ivo Smits <Ivo@UCIS.nl>
parents: 55
diff changeset
78 throw new TimeoutException("The operation timed out");
5e717aac4c1d Improvements in RemotingManager (close event) and Windows Named Pipe (accept time-out)
Ivo Smits <Ivo@UCIS.nl>
parents: 55
diff changeset
79 }
55
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
80 if (!GetOverlappedResult(PipeHandle, &overlapped, out nread, false)) throw new Win32Exception(Marshal.GetLastWin32Error());
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
81 }
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
82 }
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
83 }
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
84
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
85 private unsafe int ReadInternal(Byte[] buffer, int offset, int count, out int error) {
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
86 if (offset < 0 || offset + count > buffer.Length) throw new ArgumentOutOfRangeException("offset", "Specified buffer is outside of array bounds");
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
87 uint nread;
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
88 using (ManualResetEvent evt = new ManualResetEvent(false)) {
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
89 NativeOverlapped overlapped = new NativeOverlapped();
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
90 overlapped.EventHandle = evt.SafeWaitHandle.DangerousGetHandle();
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
91 fixed (Byte* bufferptr = buffer) {
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
92 if (ReadFile(PipeHandle, bufferptr + offset, (uint)count, out nread, &overlapped)) {
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
93 error = 0;
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
94 } else {
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
95 error = Marshal.GetLastWin32Error();
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
96 if (error == 997) {
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
97 evt.WaitOne();
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
98 if (GetOverlappedResult(PipeHandle, &overlapped, out nread, false)) {
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
99 error = 0;
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
100 } else {
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
101 error = Marshal.GetLastWin32Error();
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
102 }
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
103 }
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
104 }
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
105 return (int)nread;
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
106 }
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
107 }
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
108 }
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
109 public override unsafe int Read(byte[] buffer, int offset, int count) {
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
110 int error;
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
111 int nread = ReadInternal(buffer, offset, count, out error);
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
112 if (error == 109) return 0;
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
113 if (error == 0) return nread;
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
114 throw new Win32Exception(error);
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
115 }
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
116 public override unsafe void Write(byte[] buffer, int offset, int count) {
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
117 if (offset < 0 || offset + count > buffer.Length) throw new ArgumentOutOfRangeException("offset", "Specified buffer is outside of array bounds");
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
118 uint nread;
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
119 using (ManualResetEvent evt = new ManualResetEvent(false)) {
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
120 NativeOverlapped overlapped = new NativeOverlapped();
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
121 overlapped.EventHandle = evt.SafeWaitHandle.DangerousGetHandle();
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
122 fixed (Byte* bufferptr = buffer) {
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
123 if (!WriteFile(PipeHandle, bufferptr + offset, (uint)count, out nread, &overlapped)) {
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
124 int err = Marshal.GetLastWin32Error();
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
125 if (err != 997) throw new Win32Exception(err);
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
126 evt.WaitOne();
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
127 if (!GetOverlappedResult(PipeHandle, &overlapped, out nread, false)) throw new Win32Exception(Marshal.GetLastWin32Error());
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
128 }
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
129 }
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
130 }
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
131 if (nread != count) throw new IOException("Not all data could be written");
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
132 }
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
133 public override void Close() {
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
134 base.Close();
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
135 PipeHandle.Close();
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
136 }
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
137
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
138 public unsafe override byte[] ReadPacket() {
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
139 int offset = 0;
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
140 Byte[] buffer = new Byte[InitialMessageBufferSize];
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
141 while (true) {
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
142 int error;
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
143 int nread = ReadInternal(buffer, offset, buffer.Length - offset, out error);
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
144 offset += nread;
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
145 if (error == 109) {
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
146 return null;
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
147 } else if (error == 0) {
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
148 if (offset != buffer.Length) Array.Resize(ref buffer, offset);
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
149 return buffer;
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
150 } else if (error == 234) {
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
151 offset = buffer.Length;
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
152 Array.Resize(ref buffer, buffer.Length * 2);
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
153 } else {
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
154 throw new Win32Exception(error);
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
155 }
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
156 }
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
157 }
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
158 public override IAsyncResult BeginReadPacket(AsyncCallback callback, object state) {
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
159 if (ReadPacketDelegateInstance == null) ReadPacketDelegateInstance = (ReadPacketDelegate)ReadPacket;
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
160 return ReadPacketDelegateInstance.BeginInvoke(callback, state);
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
161 }
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
162 public override byte[] EndReadPacket(IAsyncResult asyncResult) {
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
163 return ReadPacketDelegateInstance.EndInvoke(asyncResult);
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
164 }
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
165
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
166 public override bool CanRead {
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
167 get { return !PipeHandle.IsClosed; }
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
168 }
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
169 public override bool CanWrite {
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
170 get { return !PipeHandle.IsClosed; }
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
171 }
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
172
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
173 public override void Flush() { }
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
174 public override bool CanSeek { get { return false; } }
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
175
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
176 public override long Length { get { throw new NotSupportedException(); } }
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
177 public override long Position {
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
178 get { throw new NotSupportedException(); }
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
179 set { throw new NotSupportedException(); }
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
180 }
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
181
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
182 public override long Seek(long offset, System.IO.SeekOrigin origin) { throw new NotSupportedException(); }
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
183
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
184 public override void SetLength(long value) { throw new NotSupportedException(); }
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
185
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
186 }
ec222fb577dd Added Windows Named Pipe stream wrapper
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
187 }