Created
September 1, 2019 11:11
-
-
Save LuoZijun/095937109781ea7a85473894ac51eb3d to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#![allow(non_camel_case_types, unused_variables, non_snake_case)] | |
pub type c_void = (); | |
pub type ULONG = u64; | |
pub type LONG = i64; | |
pub type HANDLE = *mut c_void; | |
pub type TUN_RING_PTR = *mut u8; | |
pub const TUN_RING_DEFAULT_CAPACITY: usize = 8388608; // 2**23 = 8MB | |
pub const TUN_RING_LEN: usize = std::mem::size_of::<TUN_RING_HEADER>() + TUN_RING_DEFAULT_CAPACITY + 0x10000; | |
#[repr(C)] | |
pub struct TUN_RING_HEADER { | |
pub Head: ULONG, | |
pub Tail: ULONG, | |
pub Alertable: LONG, // Bool | |
} | |
pub struct TUN_RING { | |
inner: Vec<u8>, | |
} | |
impl TUN_RING { | |
pub fn new(header: TUN_RING_HEADER) -> Self { | |
let size = TUN_RING_LEN; | |
let mut inner = Vec::with_capacity(size); | |
inner.resize(size, 0u8); | |
let header_len = std::mem::size_of::<TUN_RING_HEADER>(); | |
let header_ptr = &header as *const TUN_RING_HEADER as *const u8; | |
let header_bytes = unsafe { std::slice::from_raw_parts(header_ptr, header_len) }; | |
(&mut inner[..header_len]).copy_from_slice(header_bytes); | |
Self { inner } | |
} | |
pub fn as_ptr(&self) -> *const u8 { | |
self.inner.as_ptr() | |
} | |
pub fn as_mut_ptr(&mut self) -> *mut u8 { | |
self.inner.as_mut_ptr() | |
} | |
pub fn header(&self) -> &TUN_RING_HEADER { | |
let header_len = std::mem::size_of::<TUN_RING_HEADER>(); | |
let header_bytes = &self.inner[..header_len]; | |
unsafe { std::mem::transmute::<*const u8, &TUN_RING_HEADER>(header_bytes.as_ptr()) } | |
} | |
pub fn head(&self) -> ULONG { | |
self.header().Head | |
} | |
pub fn tail(&self) -> ULONG { | |
self.header().Tail | |
} | |
pub fn alertable(&self) -> LONG { | |
self.header().Alertable | |
} | |
} | |
pub struct TUN_REGISTER_RING { | |
pub RingSize: ULONG, | |
pub Ring: TUN_RING_PTR, // *mut TUN_RING | |
pub TailMoved: HANDLE, | |
} | |
pub struct TUN_REGISTER_RINGS { | |
pub Send: TUN_REGISTER_RING, | |
pub Receive: TUN_REGISTER_RING, | |
} | |
// for (;;) { | |
// TUN_PACKET *Next = PopFromRing(Rings->Send.Ring); | |
// if (!Next) { | |
// Rings->Send.Ring->Alertable = TRUE; | |
// Next = PopFromRing(Rings->Send.Ring); | |
// if (!Next) { | |
// WaitForSingleObject(Rings->Send.TailMoved, INFINITE); | |
// Rings->Send.Ring->Alertable = FALSE; | |
// continue; | |
// } | |
// Rings->Send.Ring->Alertable = FALSE; | |
// ResetEvent(Rings->Send.TailMoved); | |
// } | |
// SendToClientProgram(Next); | |
// } | |
fn main() { | |
let mut a = TUN_RING::new(TUN_RING_HEADER { Head: 100, Tail: 200, Alertable: 1}); | |
let mut b = TUN_RING::new(TUN_RING_HEADER { Head: 100, Tail: 200, Alertable: 1}); | |
let a_ptr = a.as_mut_ptr(); | |
let b_ptr = b.as_mut_ptr(); | |
// NOTE: 如果有必要 | |
// std::mem::forget(a); | |
// std::mem::forget(b); | |
let register = TUN_REGISTER_RINGS { | |
Send: TUN_REGISTER_RING { | |
RingSize: 100, | |
Ring: a_ptr, | |
TailMoved: std::ptr::null_mut::<()>() as HANDLE, | |
}, | |
Receive: TUN_REGISTER_RING { | |
RingSize: 100, | |
Ring: b_ptr, | |
TailMoved: std::ptr::null_mut::<()>() as HANDLE, | |
}, | |
}; | |
let f = || -> *mut u8 { | |
unreachable!() | |
}; | |
// NOTE: 从 C 代码那边接收 TUN_RING 指针 | |
let ring_ptr = f(); | |
let ring_inner = unsafe { Vec::from_raw_parts(ring_ptr, TUN_RING_LEN, TUN_RING_LEN) }; | |
let ring = TUN_RING { inner: ring_inner }; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment