/// <summary> /// Initiates a worker thread to listen for reports of device /// changes. Listeners can register for notification of these /// changes, which the thread will send. /// </summary> public void StartStatusMonitoring() { if (!Active) { // Create a point-to-point message queue to get the // notifications. mq = new PointToPointMsgQueue( null, // unnamed 25, DEVDETAIL.MAX_DEVDETAIL_SIZE, true, 0); // Start monitoring thread. mqt = new ThreadEx(new ThreadStart(this.StatusThread)); mqt.Start(); } }
/// <summary> /// Initiates a worker thread to listen for NDIS-reported /// changes to the status of the adapter. Listeners can /// register for notification of these changes, which the /// thread will send. /// </summary> public void StartStatusMonitoring() { if (!Active) { // Create a point-to-point message queue to get the // notifications. mq = new PointToPointMsgQueue( null, // unnamed 25, NDISUIO_DEVICE_NOTIFICATION.Size, true, 0); // Start monitoring thread. mqt = new ThreadEx(new ThreadStart(this.StatusThread)); mqt.Start(); } }
internal void StatusThread() { // Ask the system to notify our message queue when devices of // the indicated class are added or removed. IntPtr h = RequestDeviceNotifications( devClass.ToGuid().ToByteArray(), mq.Handle, fAll); // Wait for the queue to be signaled. When it is, decode // the message and call any listeners for it. If the // queue closes suddenly, that's our cue to exit, shutting // down notifications before we leave. PointToPointMsgQueue q = mq; while (mq != null) // Check the global object here. { // Wait. On return, true indicates that the queue is // signaled; false is a chance to check whether we should // exit. if (q.Wait(-1)) { // Read the event data. int bytes = 0; PointToPointMsgQueueFlags readFlags = 0; DEVDETAIL devDetail = new DEVDETAIL(); if (q.ReadMsgQueue(devDetail.getBytes(), DEVDETAIL.MAX_DEVDETAIL_SIZE, ref bytes, -1, ref readFlags)) { // Handle the event. OnDeviceNotification(new DeviceNotificationArgs( devDetail.guidDevClass, devDetail.fAttached, devDetail.szName)); } } else { System.Diagnostics.Debug.WriteLine(this, "mq is null in monitoring thread. Exiting..."); } } System.Diagnostics.Debug.WriteLine(this, "exiting DeviceStatusMonitor thread."); // Stop notifications to us. StopDeviceNotifications(h); }
/// <summary> /// Stops the worker thread which monitors for changes of status /// of the adapter. This must be done, if monitoring has been /// started, before the object is destroyed. /// </summary> public void StopStatusMonitoring() { if (Active) { if (mq != null) { // Close the point-to-point message queue. This should // cause any waits on it to return, allowing the thread // to exit. PointToPointMsgQueue q = mq; mq = null; q.Close(); // Wait for the monitoring thread to exit. mqt.Join(5000); mqt = null; } } }
/// <summary> /// Stops the worker thread which monitors for changes of status /// of the adapter. This must be done, if monitoring has been /// started, before the object is destroyed. /// </summary> public void StopStatusMonitoring() { if ( Active ) { if ( mq != null ) { // Close the point-to-point message queue. This should // cause any waits on it to return, allowing the thread // to exit. PointToPointMsgQueue q = mq; mq = null; q.Close(); // Wait for the monitoring thread to exit. mqt.Join( 5000 ); mqt = null; } } }
/// <summary> /// Initiates a worker thread to listen for reports of device /// changes. Listeners can register for notification of these /// changes, which the thread will send. /// </summary> public void StartStatusMonitoring() { if ( !Active ) { // Create a point-to-point message queue to get the // notifications. mq = new PointToPointMsgQueue( null, // unnamed 25, DEVDETAIL.MAX_DEVDETAIL_SIZE, true, 0 ); // Start monitoring thread. mqt = new ThreadEx( new ThreadStart( this.StatusThread ) ); mqt.Start(); } }
internal void StatusThread() { // Ask NDISUIO to send us notification messages for our // adapter. IntPtr ndisAccess = FileEx.CreateFile( NDISUIOPInvokes.NDISUIO_DEVICE_NAME, FileAccess.All, FileShare.None, FileCreateDisposition.OpenExisting, NDISUIOPInvokes.FILE_ATTRIBUTE_NORMAL | NDISUIOPInvokes.FILE_FLAG_OVERLAPPED); if ((int)ndisAccess == FileEx.InvalidHandle) { return; } NDISUIO_REQUEST_NOTIFICATION ndisRequestNotification = new NDISUIO_REQUEST_NOTIFICATION(); ndisRequestNotification.hMsgQueue = mq.Handle; ndisRequestNotification.dwNotificationTypes = NDISUIOPInvokes.NDISUIO_NOTIFICATION_MEDIA_SPECIFIC_NOTIFICATION | NDISUIOPInvokes.NDISUIO_NOTIFICATION_MEDIA_CONNECT | NDISUIOPInvokes.NDISUIO_NOTIFICATION_MEDIA_DISCONNECT | NDISUIOPInvokes.NDISUIO_NOTIFICATION_BIND | NDISUIOPInvokes.NDISUIO_NOTIFICATION_UNBIND; UInt32 xcount = 0; if (!NDISUIOPInvokes.DeviceIoControl(ndisAccess, NDISUIOPInvokes.IOCTL_NDISUIO_REQUEST_NOTIFICATION, ndisRequestNotification.getBytes(), NDISUIO_REQUEST_NOTIFICATION.Size, null, 0, ref xcount, IntPtr.Zero)) { System.Diagnostics.Debug.WriteLine(this, "Error in DeviceIoControl to request notifications!"); } // Each notification will be of this type. NDISUIO_DEVICE_NOTIFICATION ndisDeviceNotification = new NDISUIO_DEVICE_NOTIFICATION(); // Wait for the queue to be signaled. When it is, decode // the message and call any listeners for it. If the // queue closes suddenly, that's our cue to exit, shutting // down NDISUIO notifications before we leave. PointToPointMsgQueue q = mq; while (mq != null) // Check the global object here. { // Wait. On return, true indicates that the queue is // signaled; false is a chance to check whether we should // exit. if (q.Wait(-1)) { // Read the event data. int bytes = 0; PointToPointMsgQueueFlags readFlags = 0; if (q.ReadMsgQueue(ndisDeviceNotification.getBytes(), NDISUIO_DEVICE_NOTIFICATION.Size, ref bytes, -1, ref readFlags)) { // Handle the event. OnAdapterNotification(new AdapterNotificationArgs( ndisDeviceNotification.ptcDeviceName, (NdisNotificationType)ndisDeviceNotification.dwNotificationType)); } } else { System.Diagnostics.Debug.WriteLine(this, "mq is null in monitoring thread. Exiting..."); } } System.Diagnostics.Debug.WriteLine(this, "exiting AdapterStatusMonitor thread."); if (!NDISUIOPInvokes.DeviceIoControl(ndisAccess, NDISUIOPInvokes.IOCTL_NDISUIO_CANCEL_NOTIFICATION, null, 0, null, 0, ref xcount, IntPtr.Zero)) { System.Diagnostics.Debug.WriteLine(this, "Error in DeviceIoControl to stop notifications!"); // ???? } // Don't forget to close our handle to NDISUIO. FileEx.CloseHandle(ndisAccess); }