/// <summary> /// Retrieves a read-only list of active connections. /// </summary> /// <returns>A new read-only collection of <see cref="DotRas.RasConnection"/> objects, or an empty collection if no active connections were found.</returns> public ReadOnlyCollection<RasConnection> GetActiveConnections() { ReadOnlyCollection<RasConnection> retval = null; int size = Marshal.SizeOf(typeof(NativeMethods.RASCONN)); StructBufferedPInvokeParams info = new StructBufferedPInvokeParams(); info.BufferSize = new IntPtr(size); info.Count = IntPtr.Zero; bool retry = false; do { NativeMethods.RASCONN conn = new NativeMethods.RASCONN(); conn.size = size; try { info.Address = Marshal.AllocHGlobal(info.BufferSize); Marshal.StructureToPtr(conn, info.Address, true); int ret = SafeNativeMethods.Instance.EnumConnections(info); if (ret == NativeMethods.ERROR_BUFFER_TOO_SMALL) { retry = true; } else if (ret == NativeMethods.SUCCESS) { retry = false; NativeMethods.RASCONN[] connections = Utilities.CreateArrayOfType<NativeMethods.RASCONN>( info.Address, size, info.Count.ToInt32()); RasConnection[] tempArray = null; if (connections == null || connections.Length == 0) { tempArray = new RasConnection[0]; } else { tempArray = new RasConnection[connections.Length]; for (int index = 0; index < connections.Length; index++) { NativeMethods.RASCONN current = connections[index]; RasConnection item = new RasConnection(); item.Handle = new RasHandle(current.handle, current.subEntryId > 1); item.EntryName = current.entryName; item.Device = RasDevice.Create(current.deviceName, current.deviceType); item.PhoneBookPath = current.phoneBook; item.SubEntryId = current.subEntryId; item.EntryId = current.entryId; #if (WINXP || WIN2K8 || WIN7 || WIN8) item.SessionId = current.sessionId; Utilities.SetRasConnectionOptions(item, current.connectionOptions); #endif #if (WIN2K8 || WIN7 || WIN8) item.CorrelationId = current.correlationId; #endif tempArray[index] = item; } } retval = new ReadOnlyCollection<RasConnection>(tempArray); } else { ThrowHelper.ThrowRasException(ret); } } catch (EntryPointNotFoundException) { ThrowHelper.ThrowNotSupportedException(Resources.Exception_NotSupportedOnPlatform); } finally { if (info.Address != IntPtr.Zero) { Marshal.FreeHGlobal(info.Address); } } } while (retry); return retval; }
public void GetActiveConnectionsTest() { NativeMethods.RASCONN[] expected = new NativeMethods.RASCONN[] { new NativeMethods.RASCONN() { deviceName = "WAN Miniport (PPTP)", deviceType = NativeMethods.RASDT_Vpn, entryId = Guid.NewGuid(), entryName = "Test VPN Entry", handle = new IntPtr(1), phoneBook = "C:\\Test.pbk", subEntryId = 0, #if (WINXP || WIN2K8 || WIN7 || WIN8) sessionId = Luid.Empty, #endif #if (WIN2K8 || WIN7 || WIN8) correlationId = Guid.NewGuid() #endif }, new NativeMethods.RASCONN() { deviceName = "Standard POTS Modem", deviceType = NativeMethods.RASDT_Modem, entryId = Guid.NewGuid(), entryName = "Test Modem Entry", handle = new IntPtr(2), phoneBook = "C:\\Test.pbk", subEntryId = 0, #if (WINXP || WIN2K8 || WIN7 || WIN8) sessionId = Luid.Empty, #endif #if (WIN2K8 || WIN7 || WIN8) correlationId = Guid.NewGuid() #endif } }; IntPtr expectedSize = new IntPtr(Marshal.SizeOf(typeof(NativeMethods.RASCONN)) * expected.Length); StructBufferedPInvokeMock<StructBufferedPInvokeParams, NativeMethods.RASCONN> target = new StructBufferedPInvokeMock<StructBufferedPInvokeParams, NativeMethods.RASCONN>(); target.Result = expected; Mock<ISafeNativeMethods> mock = new Mock<ISafeNativeMethods>(); SafeNativeMethods.Instance = mock.Object; mock.Setup(o => o.EnumConnections(It.Is<StructBufferedPInvokeParams>(i => i.BufferSize != expectedSize))).Callback((StructBufferedPInvokeParams info) => { target.Execute(info); }).Returns(NativeMethods.ERROR_BUFFER_TOO_SMALL); mock.Setup(o => o.EnumConnections(It.Is<StructBufferedPInvokeParams>(i => i.BufferSize == expectedSize))).Callback((StructBufferedPInvokeParams info) => { target.Execute(info); }).Returns(NativeMethods.SUCCESS); ReadOnlyCollection<RasConnection> actual = RasHelper.Instance.GetActiveConnections(); Assert.AreEqual(expected.Length, actual.Count); for (int index = 0; index < expected.Length; index++) { NativeMethods.RASCONN objA = expected[index]; RasConnection objB = actual[index]; Assert.AreEqual(objA.deviceName, objB.Device.Name); Assert.IsTrue(string.Equals(objA.deviceType, objB.Device.DeviceType.ToString(), StringComparison.CurrentCultureIgnoreCase)); Assert.AreEqual(objA.entryId, objB.EntryId); Assert.AreEqual(objA.entryName, objB.EntryName); Assert.AreEqual(objA.handle, objB.Handle.DangerousGetHandle()); Assert.AreEqual(objA.phoneBook, objB.PhoneBookPath); Assert.AreEqual(objA.subEntryId, objB.SubEntryId); #if (WINXP || WIN2K8 || WIN7 || WIN8) Assert.AreEqual(objA.sessionId, objB.SessionId); #endif #if (WIN2K8 || WIN7 || WIN8) Assert.AreEqual(objA.correlationId, objB.CorrelationId); #endif } }