diff --git a/src/adapter.rs b/src/adapter.rs index e304ac0..56193a7 100644 --- a/src/adapter.rs +++ b/src/adapter.rs @@ -69,7 +69,7 @@ impl Adapter { let name_utf16: Vec<_> = name.encode_utf16().chain(std::iter::once(0)).collect(); let tunnel_type_utf16: Vec = tunnel_type.encode_utf16().chain(std::iter::once(0)).collect(); - let guid = match guid { + let mut guid = match guid { Some(guid) => guid, None => { let mut guid: GUID = unsafe { std::mem::zeroed() }; @@ -88,6 +88,14 @@ impl Adapter { } let luid = crate::ffi::alias_to_luid(name)?; let index = crate::ffi::luid_to_index(&luid)?; + let real_guid = util::win_guid_to_u128(&crate::ffi::luid_to_guid(&luid)?); + if guid != real_guid { + let real_guid_s = util::guid_to_win_style_string(&GUID::from_u128(real_guid))?; + let guid_s = util::guid_to_win_style_string(&GUID::from_u128(guid))?; + let (major, minor, build) = util::get_windows_version()?; + log::warn!("Windows {major}.{minor}.{build} internal bug cause the GUID mismatch: Expected {guid_s}, got {real_guid_s}"); + guid = real_guid; + } Ok(Arc::new(Adapter { adapter: UnsafeHandle(result), wintun: wintun.clone(), diff --git a/src/util.rs b/src/util.rs index 8f87907..f37b2a9 100644 --- a/src/util.rs +++ b/src/util.rs @@ -43,6 +43,18 @@ pub fn get_wintun_bin_pattern_path() -> std::io::Result { Ok(dll_path.into()) } +// +// WINAPI VOID RtlGetNtVersionNumbers (DWORD *MajorVersion, DWORD *MinorVersion, DWORD *BuildNumber); +// +pub(crate) fn get_windows_version() -> Result<(u32, u32, u32), libloading::Error> { + let library = unsafe { ::libloading::Library::new("ntdll")? }; + type TheFn = unsafe extern "system" fn(*mut u32, *mut u32, *mut u32); + let func: TheFn = unsafe { library.get(b"RtlGetNtVersionNumbers\0").map(|sym| *sym)? }; + let (mut major, mut minor, mut build) = (0, 0, 0); + unsafe { func(&mut major, &mut minor, &mut build) }; + Ok((major, minor, build)) +} + pub(crate) const fn win_guid_to_u128(guid: &GUID) -> u128 { let data4_u64 = u64::from_be_bytes(guid.data4); ((guid.data1 as u128) << 96) | ((guid.data2 as u128) << 80) | ((guid.data3 as u128) << 64) | (data4_u64 as u128)