Mercurial > hg > ucis.core
annotate Windows/WindowsNamedPipe.cs @ 111:df53bdd49507 default tip
Merge
author | Ivo Smits <Ivo@UCIS.nl> |
---|---|
date | Fri, 07 Nov 2014 18:37:39 +0100 |
parents | 5e717aac4c1d |
children |
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 } |