Red Gate forums :: View topic - Iphlpapi.dll -> NotifyAddrChange
Return to www.red-gate.com RSS Feed Available

Search  | Usergroups |  Profile |  Messages |  Log in  Register 
Go to product documentation
PInvoke.Net
PInvoke.Net forum

Iphlpapi.dll -> NotifyAddrChange

Search in PInvoke.Net forum
Post new topic   Reply to topic
Jump to:  
Author Message
Knox



Joined: 07 Apr 2009
Posts: 1

PostPosted: Tue Apr 07, 2009 4:06 pm    Post subject: Iphlpapi.dll -> NotifyAddrChange Reply with quote

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:

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:

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:

CNotifyAddrChange oAddrChange = new CNotifyAddrChange();
oAddrChange.AddrChangedEvent   += OnAddrChangedEvent;


3) When you are ready to shut it down, simply call Abort
Code:

oAddrChange.Abort();
Back to top
View user's profile Send private message
Brian Donahue



Joined: 23 Aug 2004
Posts: 6677

PostPosted: Wed Apr 08, 2009 9:56 am    Post subject: Reply with quote

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!
Back to top
View user's profile Send private message
Display posts from previous:   
Reply to topic All times are GMT + 1 Hour
Page 1 of 1

 
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group