use crate::ioctl;
use wdk::println;
use wdk_sys::{
call_unsafe_wdf_function_binding, NTSTATUS, STATUS_SUCCESS,
WDFDEVICE, WDFDEVICE_INIT, WDFDRIVER, WDFQUEUE,
WDF_IO_QUEUE_CONFIG, WDF_NO_OBJECT_ATTRIBUTES,
};
pub const DEVICE_INTERFACE_GUID: wdk_sys::GUID = wdk_sys::GUID {
Data1: 0x12345678,
Data2: 0x1234,
Data3: 0x1234,
Data4: [0x12, 0x34, 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC],
};
#[unsafe(no_mangle)]
pub unsafe extern "C" fn evt_device_add(
_driver: WDFDRIVER,
device_init: *mut WDFDEVICE_INIT,
) -> NTSTATUS {
println!("[Leviathan] Device add callback invoked");
match unsafe { create_device(device_init) } {
Ok(device) => {
println!("[Leviathan] Device created successfully");
if let Err(status) = unsafe { create_io_queue(device) } {
println!("[Leviathan] Failed to create I/O queue: {:#x}", status);
return status;
}
if let Err(status) = unsafe { register_device_interface(device) } {
println!("[Leviathan] Failed to register device interface: {:#x}", status);
return status;
}
STATUS_SUCCESS
}
Err(status) => {
println!("[Leviathan] Device creation failed: {:#x}", status);
status
}
}
}
unsafe fn create_device(device_init: *mut WDFDEVICE_INIT) -> Result<WDFDEVICE, NTSTATUS> {
let mut device: WDFDEVICE = core::ptr::null_mut();
unsafe {
call_unsafe_wdf_function_binding!(
WdfDeviceInitSetIoType,
device_init,
wdk_sys::_WDF_DEVICE_IO_TYPE::WdfDeviceIoBuffered
);
}
let status = unsafe {
call_unsafe_wdf_function_binding!(
WdfDeviceCreate,
&mut (device_init as *mut _),
WDF_NO_OBJECT_ATTRIBUTES,
&mut device
)
};
if status != STATUS_SUCCESS {
return Err(status);
}
Ok(device)
}
unsafe fn create_io_queue(device: WDFDEVICE) -> Result<WDFQUEUE, NTSTATUS> {
let mut queue_config = WDF_IO_QUEUE_CONFIG {
Size: core::mem::size_of::<WDF_IO_QUEUE_CONFIG>() as u32,
PowerManaged: wdk_sys::_WDF_TRI_STATE::WdfUseDefault,
DefaultQueue: true as u8,
DispatchType: wdk_sys::_WDF_IO_QUEUE_DISPATCH_TYPE::WdfIoQueueDispatchSequential,
EvtIoDefault: None,
EvtIoRead: Some(ioctl::evt_io_read),
EvtIoWrite: Some(ioctl::evt_io_write),
EvtIoDeviceControl: Some(ioctl::evt_io_device_control),
EvtIoStop: None,
EvtIoResume: None,
EvtIoInternalDeviceControl: None,
EvtIoCanceledOnQueue: None,
AllowZeroLengthRequests: false as u8,
Settings: unsafe { core::mem::zeroed() },
Driver: core::ptr::null_mut(),
};
let mut queue: WDFQUEUE = core::ptr::null_mut();
let status = unsafe {
call_unsafe_wdf_function_binding!(
WdfIoQueueCreate,
device,
&mut queue_config,
WDF_NO_OBJECT_ATTRIBUTES,
&mut queue
)
};
if status != STATUS_SUCCESS {
return Err(status);
}
Ok(queue)
}
unsafe fn register_device_interface(device: WDFDEVICE) -> Result<(), NTSTATUS> {
let status = unsafe {
call_unsafe_wdf_function_binding!(
WdfDeviceCreateDeviceInterface,
device,
&DEVICE_INTERFACE_GUID,
core::ptr::null()
)
};
if status != STATUS_SUCCESS {
return Err(status);
}
println!("[Leviathan] Device interface registered");
Ok(())
}