diff options
| author | pravic <[email protected]> | 2016-04-28 23:29:31 +0300 |
|---|---|---|
| committer | pravic <[email protected]> | 2016-04-28 23:29:31 +0300 |
| commit | 60f48d27f3d0a87020e6b196d7d4a99f1eebd6ed (patch) | |
| tree | c321204059c13b68ba76dd444afd15a439ea3add /src | |
| parent | small updates for samples (diff) | |
| download | winapi-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.rs | 76 | ||||
| -rw-r--r-- | src/device_object.rs | 22 | ||||
| -rw-r--r-- | src/irp.rs | 72 | ||||
| -rw-r--r-- | src/object.rs | 5 | ||||
| -rw-r--r-- | src/string.rs | 3 | ||||
| -rw-r--r-- | src/types.rs | 1 |
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>; @@ -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. |