aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorpravic <[email protected]>2016-04-28 23:29:31 +0300
committerpravic <[email protected]>2016-04-28 23:29:31 +0300
commit60f48d27f3d0a87020e6b196d7d4a99f1eebd6ed (patch)
treec321204059c13b68ba76dd444afd15a439ea3add /src
parentsmall updates for samples (diff)
downloadwinapi-kmd-rs-60f48d27f3d0a87020e6b196d7d4a99f1eebd6ed.tar.xz
winapi-kmd-rs-60f48d27f3d0a87020e6b196d7d4a99f1eebd6ed.zip
km updates for Winsock network drivers WIP
Diffstat (limited to 'src')
-rw-r--r--src/basedef.rs76
-rw-r--r--src/device_object.rs22
-rw-r--r--src/irp.rs72
-rw-r--r--src/object.rs5
-rw-r--r--src/string.rs3
-rw-r--r--src/types.rs1
6 files changed, 171 insertions, 8 deletions
diff --git a/src/basedef.rs b/src/basedef.rs
index fb8dfbb..d8e779b 100644
--- a/src/basedef.rs
+++ b/src/basedef.rs
@@ -16,12 +16,32 @@ pub enum km_void {
__variant2,
}
+pub type CHAR = i8;
+pub type CCHAR = i8;
+pub type USHORT = u16;
+pub type CSHORT = i16;
+pub type ULONG = u32;
+
pub type VOID = km_void;
pub type PVOID = *mut VOID;
pub type PCVOID = *const VOID;
+pub type SIZE_T = usize;
+
+pub type ULONG_PTR = usize;
+pub type PEPROCESS = PVOID;
pub type PETHREAD = PVOID;
+pub type PSECURITY_DESCRIPTOR = PVOID;
+
+pub type PGUID = PVOID;
+pub type PCGUID = PCVOID;
+
+pub type PSTR = *mut u8;
+pub type PWSTR = *mut u16;
+pub type PCSTR = *const u8;
+pub type PCWSTR = *const u16;
+
pub type PIO_APC_ROUTINE = Option<extern "system" fn (ApcContext: PCVOID, IoStatusBlock: *const IO_STATUS_BLOCK, Reserved: u32)>;
@@ -29,11 +49,8 @@ extern "system"
{
pub fn KeGetCurrentIrql() -> KIRQL;
pub fn KeRaiseIrqlToDpcLevel() -> KIRQL;
- pub fn KfLowerIrql(NewIrql: KIRQL) -> KIRQL;
- pub fn KfRaiseIrql(NewIrql: KIRQL) -> KIRQL;
}
-
/// Doubly linked list structure.
#[repr(C)]
pub struct LIST_ENTRY
@@ -44,6 +61,7 @@ pub struct LIST_ENTRY
/// Spin Lock.
#[repr(C)]
+#[derive(Default)]
pub struct KSPIN_LOCK
{
pub lock: usize,
@@ -63,14 +81,29 @@ pub struct DISPATCHER_HEADER
/// An I/O status block.
#[repr(C)]
+#[derive(Default, Clone, Copy)]
pub struct IO_STATUS_BLOCK
{
+ /// Completion status.
pub Status: ::NTSTATUS,
+ /// Request-dependent value.
pub Information: usize,
}
pub type PIO_STATUS_BLOCK = *mut IO_STATUS_BLOCK;
+impl IO_STATUS_BLOCK {
+ /// Return integer value for `Information` field.
+ pub fn as_size(&self) -> usize {
+ self.Information
+ }
+
+ /// Return the pointer of specified object type.
+ pub fn as_ptr<T>(&self) -> *const T {
+ unsafe { ::core::mem::transmute(self.Information) }
+ }
+}
+
/// Processor modes.
#[repr(u8)]
@@ -90,3 +123,40 @@ pub mod IO_PRIORITY {
pub const IO_DISK_INCREMENT: KPRIORITY_BOOST = 1;
pub const EVENT_INCREMENT: KPRIORITY_BOOST = 1;
}
+
+pub type KPRIORITY = IO_PRIORITY::KPRIORITY_BOOST;
+
+/// Memory Descriptor List (MDL)
+#[repr(C)]
+pub struct MDL
+{
+ Next: *mut MDL,
+ Size: i16,
+ MdlFlags: i16,
+ Process: PEPROCESS,
+ MappedSystemVa: PVOID,
+ StartVa: PVOID,
+ ByteCount: u32,
+ ByteOffset: u32,
+}
+
+pub type PMDL = *mut MDL;
+
+#[repr(i16)]
+pub enum MDL_FLAGS {
+ MDL_MAPPED_TO_SYSTEM_VA = 0x0001,
+ MDL_PAGES_LOCKED = 0x0002,
+ MDL_SOURCE_IS_NONPAGED_POOL = 0x0004,
+ MDL_ALLOCATED_FIXED_SIZE = 0x0008,
+ MDL_PARTIAL = 0x0010,
+ MDL_PARTIAL_HAS_BEEN_MAPPED = 0x0020,
+ MDL_IO_PAGE_READ = 0x0040,
+ MDL_WRITE_OPERATION = 0x0080,
+ MDL_PARENT_MAPPED_SYSTEM_VA = 0x0100,
+ MDL_LOCK_HELD = 0x0200,
+ MDL_SCATTER_GATHER_VA = 0x0400,
+ MDL_IO_SPACE = 0x0800,
+ MDL_NETWORK_HEADER = 0x1000,
+ MDL_MAPPING_CAN_FAIL = 0x2000,
+ MDL_ALLOCATED_MUST_SUCCEED = 0x4000,
+}
diff --git a/src/device_object.rs b/src/device_object.rs
index f4cbf39..b475f8f 100644
--- a/src/device_object.rs
+++ b/src/device_object.rs
@@ -2,7 +2,7 @@
use ::{NTSTATUS, UNICODE_STRING};
use ::driver_object::DRIVER_OBJECT;
-use ::irp::{IRP, PIRP};
+use ::irp::{IRP};
use ::dpc::KDPC;
use ::event::KEVENT;
use ::object::*;
@@ -41,6 +41,15 @@ pub enum DEVICE_FLAGS {
DO_XIP = 0x00020000
}
+/// `IoCompletion` routine result.
+#[repr(u32)]
+pub enum IO_COMPLETION_ROUTINE_RESULT {
+ // STATUS_SUCCESS
+ ContinueCompletion = 0,
+ // STATUS_MORE_PROCESSING_REQUIRED
+ StopCompletion = 0xC0000016,
+}
+
/// The `DEVICE_OBJECT` structure is used by the operating system to represent a device object.
#[repr(C)]
pub struct DEVICE_OBJECT
@@ -72,6 +81,13 @@ pub struct DEVICE_OBJECT
pub Reserved: *const u8,
}
+impl DEVICE_OBJECT {
+ /// Return a reference to driver-defined data structure.
+ pub fn extension<T>(&mut self) -> &mut T {
+ unsafe { &mut *(self.DeviceExtension as *mut T) }
+ }
+}
+
/// Device object extension structure.
#[repr(C)]
pub struct DEVOBJ_EXTENSION
@@ -92,8 +108,8 @@ pub struct DEVOBJ_EXTENSION
pub type PDEVICE_OBJECT = *mut DEVICE_OBJECT;
-pub type PDRIVER_CANCEL = Option<extern "system" fn (DeviceObject: PDEVICE_OBJECT, Irp: PIRP)>;
+pub type PDRIVER_CANCEL = Option<extern "system" fn (DeviceObject: &mut DEVICE_OBJECT, Irp: &mut IRP)>;
pub type PDRIVER_DISPATCH = Option<extern "system" fn (DeviceObject: &mut DEVICE_OBJECT, Irp: &mut IRP) -> NTSTATUS>;
-pub type PIO_COMPLETION_ROUTINE = Option<extern "system" fn (DeviceObject: PDEVICE_OBJECT, Irp: PIRP, Context: PVOID) -> NTSTATUS>;
+pub type PIO_COMPLETION_ROUTINE = Option<extern "system" fn (DeviceObject: &mut DEVICE_OBJECT, Irp: &mut IRP, Context: PVOID) -> IO_COMPLETION_ROUTINE_RESULT>;
diff --git a/src/irp.rs b/src/irp.rs
index 8d1b390..5e00e24 100644
--- a/src/irp.rs
+++ b/src/irp.rs
@@ -18,6 +18,12 @@ extern "system"
{
fn IoCompleteRequest(Irp: PIRP, PriorityBoost: KPRIORITY_BOOST);
+ pub fn IoAllocateIrp(StackSize: CCHAR, ChargeQuota: bool) -> PIRP;
+ pub fn IoFreeIrp(Irp: PIRP);
+ pub fn IoReuseIrp(Irp: PIRP, Status: NTSTATUS);
+ pub fn IoInitializeIrp(Irp: PIRP, PacketSize: USHORT, StackSize: CCHAR);
+ pub fn IoMakeAssociatedIrp(Irp: PIRP, StackSize: CCHAR) -> PIRP;
+
// unfortunately following are macro
// fn IoGetCurrentIrpStackLocation(Irp: PIRP) -> PIO_STACK_LOCATION;
// fn IoGetNextIrpStackLocation(Irp: PIRP) -> PIO_STACK_LOCATION;
@@ -26,27 +32,46 @@ extern "system"
}
/// `IRP` Major Function Codes.
+///
+/// For information about these requests, see
+/// [IRP Major Function Codes](https://msdn.microsoft.com/en-us/library/windows/hardware/ff548603%28v=vs.85%29.aspx).
#[repr(u8)]
pub enum IRP_MJ
{
+ /// The operating system sends this request to open a handle to a file object or device object.
CREATE,
CREATE_NAMED_PIPE,
+ /// Indicates that the last handle of the file object that is associated with the target device object
+ /// has been closed and released. All outstanding I/O requests have been completed or canceled.
+ /// See also `CLEANUP`.
CLOSE,
+ /// A user-mode application or Win32 component has requested a data transfer from the device.
+ /// Or a higher-level driver has created and set up the read IRP.
READ,
+ /// A user-mode application or Win32 component has requested a data transfer to the device.
+ /// Or a higher-level driver has created and set up the write IRP.
WRITE,
QUERY_INFORMATION,
SET_INFORMATION,
QUERY_EA,
SET_EA,
+ /// Indicates that the driver should flush the device's cache or its internal buffer,
+ /// or, possibly, should discard the data in its internal buffer.
FLUSH_BUFFERS,
QUERY_VOLUME_INFORMATION,
SET_VOLUME_INFORMATION,
DIRECTORY_CONTROL,
FILE_SYSTEM_CONTROL,
+ /// An user-mode thread has called the Microsoft Win32 `DeviceIoControl` function, or a higher-level kernel-mode driver has set up the request.
DEVICE_CONTROL,
+ /// Some driver calls either `IoBuildDeviceIoControlRequest` or `IoAllocateIrp` to create a request.
INTERNAL_DEVICE_CONTROL,
+ /// Indicates that a file system driver is sending notice that the system is being shut down.
SHUTDOWN,
LOCK_CONTROL,
+ /// Indicates that the last handle for a file object that is associated with the target device object has been closed
+ /// (but, due to outstanding I/O requests, might not have been released).
+ /// See also `CLOSE`.
CLEANUP,
CREATE_MAILSLOT,
QUERY_SECURITY,
@@ -123,6 +148,11 @@ pub struct _IRP_OVERLAY
pub OriginalFileObject: PFILE_OBJECT,
}
+pub const SL_PENDING_RETURNED: u8 = 0x01;
+pub const SL_INVOKE_ON_CANCEL: u8 = 0x20;
+pub const SL_INVOKE_ON_SUCCESS: u8 = 0x40;
+pub const SL_INVOKE_ON_ERROR: u8 = 0x80;
+
/// I/O Stack Locations.
#[repr(C)]
pub struct IO_STACK_LOCATION
@@ -133,6 +163,7 @@ pub struct IO_STACK_LOCATION
pub MinorFunction: u8,
/// Request-type-specific values (see [DEVICE_FLAGS](../device_object/enum.DEVICE_FLAGS.html)).
pub Flags: u8,
+ /// Stack location control flags.
pub Control: u8,
/// A union that depends on the major and minor IRP function code values
@@ -162,11 +193,28 @@ pub struct _IO_STACK_LOCATION_READ
impl IRP {
+ pub fn new(StackSize: i8) -> PIRP {
+ unsafe { IoAllocateIrp(StackSize, false) }
+ }
+
+ pub fn with_quota(StackSize: i8) -> PIRP {
+ unsafe { IoAllocateIrp(StackSize, true) }
+ }
+
+ pub fn free(&mut self) {
+ unsafe { IoFreeIrp(self) };
+ }
+
/// Returns a pointer to the caller's stack location in the given `IRP`.
pub fn get_current_stack_location(&mut self) -> &mut IO_STACK_LOCATION {
unsafe { &mut *self.Overlay.CurrentStackLocation }
}
+ /// Returns a pointer to the next-lower-level driver's I/O stack location.
+ pub fn get_next_stack_location(&mut self) -> &mut IO_STACK_LOCATION {
+ unsafe { &mut *self.Overlay.CurrentStackLocation.offset(-1) }
+ }
+
/// Indicates that the caller has completed all processing for a given I/O request
/// and is returning the given IRP to the I/O manager.
pub fn complete_request(&mut self, Status: NTSTATUS) -> NTSTATUS {
@@ -174,6 +222,30 @@ impl IRP {
unsafe { IoCompleteRequest(self, IO_NO_INCREMENT) };
return Status;
}
+
+ /// Registers an `IoCompletion` routine, which will be called when the next-lower-level driver
+ /// has completed the requested operation for the given IRP.
+ pub fn set_completion(&mut self, CompletionRoutine: PIO_COMPLETION_ROUTINE, Context: PVOID,
+ InvokeOnSuccess: bool, InvokeOnError: bool, InvokeOnCancel: bool)
+ {
+ let mut lower = self.get_next_stack_location();
+ lower.CompletionRoutine = CompletionRoutine;
+ lower.Context = Context;
+ lower.Control = 0;
+ if InvokeOnSuccess {
+ lower.Control |= SL_INVOKE_ON_SUCCESS;
+ }
+ if InvokeOnError {
+ lower.Control |= SL_INVOKE_ON_ERROR;
+ }
+ if InvokeOnCancel {
+ lower.Control |= SL_INVOKE_ON_CANCEL;
+ }
+ }
+
+ pub fn set_unconditional_completion(&mut self, CompletionRoutine: PIO_COMPLETION_ROUTINE, Context: PVOID) {
+ self.set_completion(CompletionRoutine, Context, true, true, true)
+ }
}
impl IO_STACK_LOCATION {
diff --git a/src/object.rs b/src/object.rs
index ab34aeb..b57b8d4 100644
--- a/src/object.rs
+++ b/src/object.rs
@@ -3,7 +3,12 @@
use ::basedef::*;
use ::device_object::PDEVICE_OBJECT;
use ::irp::IRP;
+use ::status::NTSTATUS;
+extern "system"
+{
+ pub fn KeWaitForSingleObject(Object: PVOID, WaitReason: u32, WaitMode: KPROCESSOR_MODE, Alertable: bool, Timeout: Option<&i64>) -> NTSTATUS;
+}
#[repr(C)]
pub struct WAIT_CONTEXT_BLOCK
diff --git a/src/string.rs b/src/string.rs
index 252dbe6..251b9cb 100644
--- a/src/string.rs
+++ b/src/string.rs
@@ -70,7 +70,8 @@ pub type UnicodeString = UNICODE_STRING;
pub type CONST_UNICODE_STRING = UNICODE_STRING;
pub type CONST_ANSI_STRING = ANSI_STRING;
-
+pub type PUNICODE_STRING = *mut UNICODE_STRING;
+pub type PCUNICODE_STRING = *const UNICODE_STRING;
extern "system"
{
diff --git a/src/types.rs b/src/types.rs
deleted file mode 100644
index f7e3838..0000000
--- a/src/types.rs
+++ /dev/null
@@ -1 +0,0 @@
-//! Kernel types.