public static IAsyncDvcChannel Open(string channelName, WTS_CHANNEL_OPTION option = WTS_CHANNEL_OPTION.DYNAMIC) { ValidateChannelName(channelName); DvcServerChannel result = null; // Open sfh in a CER since it can't be in a dispose block since lifetime is transferred to DynamicVirtualServerChannel RuntimeHelpers.PrepareConstrainedRegions(); try { /* CER */ } finally { SafeFileHandle pFile = null; var sfh = WTSVirtualChannelOpenEx(WTS_CURRENT_SESSION, channelName, option); try { WtsAllocSafeHandle pBuffer = null; try { int cbReturned; if (!WTSVirtualChannelQuery(sfh, WTS_VIRTUAL_CLASS.FileHandle, out pBuffer, out cbReturned) || cbReturned < IntPtr.Size) { throw new Win32Exception(); } pFile = new SafeFileHandle(Marshal.ReadIntPtr(pBuffer.DangerousGetHandle()), false); } finally { pBuffer?.Dispose(); } if (pFile.IsInvalid) { throw new InvalidOperationException("WTSVirtualChannelQuery WTS_VIRTUAL_CLASS.FileHandle returned invalid handle"); } // create result = new DvcServerChannel(sfh, new FileStream(pFile, FileAccess.ReadWrite, bufferSize: 32 * 1024 * 1024, isAsync: true)); } finally { if (result == null) { sfh.Dispose(); } } } return(result); }
public static extern WtsVitrualChannelSafeHandle WTSVirtualChannelOpenEx( int sessionId, // channel name is always ASCII [MarshalAs(UnmanagedType.LPStr)] string channelName, WTS_CHANNEL_OPTION options);