5 use windows
::Win32
::Foundation
::ERROR_INVALID_HANDLE
; 
   6 use windows
::Win32
::Foundation
::ERROR_INVALID_PARAMETER
; 
   7 use windows
::Win32
::Foundation
::ERROR_NOT_ENOUGH_MEMORY
; 
   8 use windows
::Win32
::Foundation
::NO_ERROR
; 
   9 use windows
::Win32
::NetworkManagement
::IpHelper
::CancelMibChangeNotify2
; 
  10 use windows
::Win32
::NetworkManagement
::IpHelper
::MIB_NOTIFICATION_TYPE
; 
  11 use windows
::Win32
::NetworkManagement
::IpHelper
::MIB_UNICASTIPADDRESS_ROW
; 
  13     Foundation
::{BOOLEAN
, HANDLE
}, 
  14     NetworkManagement
::IpHelper
::NotifyUnicastIpAddressChange
, 
  15     Networking
::WinSock
::AF_UNSPEC
, 
  22 pub struct WatchState 
{ 
  23     /// The last result that we captured, for diffing 
  26     cb
: Box
<dyn 
FnMut(Update
) + '
static>, 
  29 pub struct WatchHandle 
{ 
  31     _state
: Pin
<Box
<Mutex
<WatchState
>>>, 
  34 impl Drop 
for WatchHandle 
{ 
  37             let _ 
= CancelMibChangeNotify2(self.hnd
); 
  42 pub(crate) fn watch_interfaces
<F
: FnMut(Update
) + '
static>( 
  44 ) -> Result
<WatchHandle
, Error
> { 
  45     let state 
= Box
::pin(Mutex
::new(WatchState 
{ 
  46         prev_list
: List
::default(), 
  47         cb
: Box
::new(callback
), 
  49     let state_ctx 
= &*state
.as_ref() as *const _ 
as *const c_void
; 
  51     let mut hnd 
= HANDLE
::default(); 
  53         NotifyUnicastIpAddressChange( 
  63             // Trigger an initial update. 
  64             // This is allowed to race with true updates because it 
  65             // will always calculate a diff and discard no-ops. 
  66             handle_notif(&mut *state
.lock().unwrap
()); 
  67             // Then return the handle 
  68             Ok(WatchHandle 
{ hnd
, _state
: state 
}) 
  70         ERROR_INVALID_HANDLE 
=> Err(Error
::Internal
), 
  71         ERROR_INVALID_PARAMETER 
=> Err(Error
::Internal
), 
  72         ERROR_NOT_ENOUGH_MEMORY 
=> Err(Error
::Internal
), 
  73         _ 
=> Err(Error
::Internal
), // TODO: Use FormatMessage and get real error 
  77 unsafe extern "system" fn notif( 
  79     _row
: *const MIB_UNICASTIPADDRESS_ROW
, 
  80     _notification_type
: MIB_NOTIFICATION_TYPE
, 
  82     let state_ptr 
= ctx 
as *const Mutex
<WatchState
>; 
  84         let state_guard 
= &mut *state_ptr
.as_ref().unwrap
().lock().unwrap
(); 
  85         handle_notif(state_guard
); 
  89 fn handle_notif(state
: &mut WatchState
) { 
  90     let Ok(new_list
) = crate::list
::list_interfaces() else { 
  93     if new_list 
== state
.prev_list 
{ 
  97         interfaces
: new_list
.0.clone(), 
  98         diff
: new_list
.diff_from(&state
.prev_list
), 
 101     state
.prev_list 
= new_list
;