Iphlpapi.dll -> NotifyAddrChange

Announcements and discussion for PInvoke

Moderators: Luke Jefferson, Robert

Iphlpapi.dll -> NotifyAddrChange

Postby Knox » Tue Apr 07, 2009 4:06 pm

I'm not sure how to add a new wiki page, and there isn't one for the NotifyAddrChange function of the Iphlpapi.dll. I am fairly new to .NET C# programming, and it took me a while to figure out how to properly use this call. I figured I would post up what I have here to help any others who might be having trouble with it.

Code: Select all
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Runtime.InteropServices;

namespace Iphlpapi
{
   public class CNotifyAddrChange
   {
      public event EventHandler<EventArgs>      AddrChangedEvent   = null;
      
      protected Thread                     TheThread         { get; set; }

      protected enum EEvents
      {
         AddrChange,
         Abort,

         Count,
      }
      protected AutoResetEvent[] m_aoEvents;
      
      [DllImport(\"Iphlpapi.dll\", SetLastError = true)]
      public static extern UInt32 NotifyAddrChange(ref IntPtr Handle, ref NativeOverlapped overlapped);

      public CNotifyAddrChange()
      {
         TheThread      = null;

         m_aoEvents = new AutoResetEvent[(int)EEvents.Count]
         {
            new AutoResetEvent(false),   // AddrChangeEvent
            new AutoResetEvent(false),   // AbortEvent
         };
         
         Start();
      }

      ~CcpNotifyAddrChange()
      {
         Abort();
      }

      protected AutoResetEvent AddrChangeEvent
      {
         get
         {
            return m_aoEvents[(int)EEvents.AddrChange];
         }
      }

      protected AutoResetEvent AbortEvent
      {
         get
         {
            return m_aoEvents[(int)EEvents.Abort];
         }
      }
      
      public void Start()
      {
         Abort();
         
         TheThread      = new Thread(new ThreadStart(ThreadProc));

         TheThread.Name    = \"NotifyAddrChange\";
         TheThread.Start();
      }
      
      public void Abort()
      {
         if( (TheThread != null) && TheThread.IsAlive )
         {
            AbortEvent.Set();
            
            TheThread.Join();
         }
      }

      public void ThreadProc()
      {
         try
         {
            NativeOverlapped            oOverlapped      = new NativeOverlapped();
            IntPtr                     pnHandle      = IntPtr.Zero;
            oOverlapped.EventHandle                     = AddrChangeEvent.SafeWaitHandle.DangerousGetHandle();
            
            while(true)
            {
               if(NotifyAddrChange(ref pnHandle, ref oOverlapped) == 997) // 997 == ERROR_IO_PENDING
               {
                  if (WaitHandle.WaitAny(m_aoEvents) == (Int32)EEvents.AddrChange)
                  {
                     EventHandler<EventArgs>   oHandler   = AddrChangedEvent;
                     if(oHandler != null)
                     {
                        oHandler(this, null);
                     }
                  }
                  else
                  {
                     // The abort event was triggered
                     break;
                  }
               }
               else
               {
                  // Handle the error
                  break;
               }
            }
         }
         catch (System.Exception oException)
         {
            // Handle the error
         }
      }
   }
}


How to use:

1) Create the event handler function that you want called when an address changes
Code: Select all
public void OnAddrChangedEvent(object sender, EventArgs e)
{
   try
   {
      // Do whatever it is you need to do when an address changes
   }
   catch (System.Exception oException)
   {
      // Handle the error
   }
}


2) Create the object within the scope you want it to run and assign your event handler.
Code: Select all
CNotifyAddrChange oAddrChange = new CNotifyAddrChange();
oAddrChange.AddrChangedEvent   += OnAddrChangedEvent;


3) When you are ready to shut it down, simply call Abort
Code: Select all
oAddrChange.Abort();
Knox
 
Posts: 1
Joined: Tue Apr 07, 2009 3:14 pm

Postby Brian Donahue » Wed Apr 08, 2009 9:56 am

Hi,

It's easy to create a page for a new function in the PInvoke wiki. Just click the text box at the top of each page that says navigate or create a new function and enter Iphlpapi.NotifyAddrChange.

The only time you would need administrator help would be when you need to add a new module to the wiki. I pick these requests up when moderating the forum and add new modules when requested.

Hope this helps!
Brian Donahue
 
Posts: 6668
Joined: Mon Aug 23, 2004 10:48 am


Return to PInvoke.Net

Who is online

Users browsing this forum: No registered users and 1 guest