/// <summary> /// Lists all available remote access capable devices. /// </summary> /// <returns>A new collection of <see cref="DotRas.RasDevice"/> objects.</returns> public ReadOnlyCollection<RasDevice> GetDevices() { ReadOnlyCollection<RasDevice> retval = null; int size = Marshal.SizeOf(typeof(NativeMethods.RASDEVINFO)); StructBufferedPInvokeParams info = new StructBufferedPInvokeParams(); info.BufferSize = new IntPtr(size); info.Count = IntPtr.Zero; bool retry = false; do { NativeMethods.RASDEVINFO device = new NativeMethods.RASDEVINFO(); device.size = size; try { info.Address = Marshal.AllocHGlobal(info.BufferSize); Marshal.StructureToPtr(device, info.Address, true); int ret = SafeNativeMethods.Instance.EnumDevices(info); if (ret == NativeMethods.ERROR_BUFFER_TOO_SMALL) { retry = true; } else if (ret == NativeMethods.SUCCESS) { retry = false; NativeMethods.RASDEVINFO[] devices = Utilities.CreateArrayOfType<NativeMethods.RASDEVINFO>(info.Address, size, info.Count.ToInt32()); RasDevice[] tempArray = null; if (devices == null || devices.Length == 0) { tempArray = new RasDevice[0]; } else { tempArray = new RasDevice[devices.Length]; for (int index = 0; index < devices.Length; index++) { NativeMethods.RASDEVINFO current = devices[index]; tempArray[index] = RasDevice.Create( current.name, current.type); } } retval = new ReadOnlyCollection<RasDevice>(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 GetDevicesTest() { NativeMethods.RASDEVINFO[] expected = new NativeMethods.RASDEVINFO[] { new NativeMethods.RASDEVINFO() { name = "WAN Miniport (PPTP)", type = NativeMethods.RASDT_Vpn }, new NativeMethods.RASDEVINFO() { name = "WAN Miniport (L2TP)", type = NativeMethods.RASDT_Vpn }, new NativeMethods.RASDEVINFO() { name = "POTS Modem", type = NativeMethods.RASDT_Modem } }; IntPtr expectedSize = new IntPtr(Marshal.SizeOf(typeof(NativeMethods.RASDEVINFO)) * expected.Length); StructBufferedPInvokeMock<StructBufferedPInvokeParams, NativeMethods.RASDEVINFO> target = new StructBufferedPInvokeMock<StructBufferedPInvokeParams, NativeMethods.RASDEVINFO>(); target.Result = expected; Mock<ISafeNativeMethods> mock = new Mock<ISafeNativeMethods>(); SafeNativeMethods.Instance = mock.Object; mock.Setup(o => o.EnumDevices(It.Is<StructBufferedPInvokeParams>(i => i.BufferSize != expectedSize))).Callback((StructBufferedPInvokeParams value) => { target.Execute(value); }).Returns(NativeMethods.ERROR_BUFFER_TOO_SMALL); mock.Setup(o => o.EnumDevices(It.Is<StructBufferedPInvokeParams>(i => i.BufferSize == expectedSize))).Callback((StructBufferedPInvokeParams value) => { target.Execute(value); }).Returns(NativeMethods.SUCCESS); ReadOnlyCollection<RasDevice> actual = RasHelper.Instance.GetDevices(); Assert.AreEqual(expected.Length, actual.Count); for (int index = 0; index < expected.Length; index++) { Assert.AreEqual(expected[index].name, actual[index].Name); Assert.IsTrue(string.Equals(expected[index].type, actual[index].DeviceType.ToString(), StringComparison.CurrentCultureIgnoreCase)); } }