You want to look at the nodes in
/sys/class/net/
I experimented with mine:
Wire Plugged in:
eth0/carrier:1
eth0/operstate:unknown
Wire Removed:
eth0/carrier:0
eth0/operstate:down
Wire Plugged in Again:
eth0/carrier:1
eth0/operstate:up
Side Trick: harvesting all properties at once the easy way:
grep "" eth0/*
This forms a nice list of key:value
pairs.
I realize I'm answering my own question here, but it was actually a question asked of via email, and I actually spent quite a while finding the answer, so I'm posting it here.
So the general answer for how this is detected is that you have to call down into the NDIS driver via an IOCTL and tell it that you're interested in notifications. This is done with the IOCTL_NDISUIO_REQUEST_NOTIFICATION value (the docs say this is not supported in WinMo, but the docs are wrong). Of course receiving the notifications isn't so straightforward - you son't just get some nice callback. Instead you have to spin up a point to point message queue and send that in to the IOCTL call, along with a mask of which specific notifications you want. Then, when something changes (like the cable is pulled) you'll get an NDISUIO_DEVICE_NOTIFICATION structure (again MSDN incorrectly says this is CE-only) on the queue, which you can then parse to find the adapter that had the event and what the exact event is.
From a managed code perspective, this is actually a lot of code to have to write - CreateFile to open NDIS, all of the queueing APIs, the structures for the notifications, etc. Fortunately, I'd already been down this road and had added it to the Smart Device Framework already. So if you're using the SDF, getting the notifications looks like this:
public partial class TestForm : Form
{
public TestForm()
{
InitializeComponent();
this.Disposed += new EventHandler(TestForm_Disposed);
AdapterStatusMonitor.NDISMonitor.AdapterNotification +=
new AdapterNotificationEventHandler(NDISMonitor_AdapterNotification);
AdapterStatusMonitor.NDISMonitor.StartStatusMonitoring();
}
void TestForm_Disposed(object sender, EventArgs e)
{
AdapterStatusMonitor.NDISMonitor.StopStatusMonitoring();
}
void NDISMonitor_AdapterNotification(object sender,
AdapterNotificationArgs e)
{
string @event = string.Empty;
switch (e.NotificationType)
{
case NdisNotificationType.NdisMediaConnect:
@event = "Media Connected";
break;
case NdisNotificationType.NdisMediaDisconnect:
@event = "Media Disconnected";
break;
case NdisNotificationType.NdisResetStart:
@event = "Resetting";
break;
case NdisNotificationType.NdisResetEnd:
@event = "Done resetting";
break;
case NdisNotificationType.NdisUnbind:
@event = "Unbind";
break;
case NdisNotificationType.NdisBind:
@event = "Bind";
break;
default:
return;
}
if (this.InvokeRequired)
{
this.Invoke(new EventHandler(delegate
{
eventList.Items.Add(string.Format(
"Adapter '{0}' {1}", e.AdapterName, @event));
}));
}
else
{
eventList.Items.Add(string.Format(
"Adapter '{0}' {1}", e.AdapterName, @event));
}
}
}
Best Answer
The easiest way is to use OpenNETCF's SDF and look at the OpenNETCF.Net.NetworkInformation.NetworkInterfaceWatcher class, which will raise events when NDIS sends out notifications (like MEDIA_CONNECT and MEDIA_DISCONNECT).
You can do the same work without the SDF, of course. It involves onening the NDIS driver directly and calling IOCTL_NDISUIO_REQUEST_NOTIFICATION with a P2P message queue handle. It's not overly difficult, but there's a lot you have to get right for it to work and not leak.