aboutsummaryrefslogtreecommitdiff
path: root/src/irp.rs
diff options
context:
space:
mode:
authorpravic <[email protected]>2016-04-12 16:39:37 +0300
committerpravic <[email protected]>2016-04-12 16:39:37 +0300
commit28ff216899e95a6a9756bcbe580f28ed8ce61228 (patch)
treebbf00e3c5f3b440db5ddb3f86b6d3a893349cee0 /src/irp.rs
parentgit ignore (diff)
downloadwinapi-kmd-rs-28ff216899e95a6a9756bcbe580f28ed8ce61228.tar.xz
winapi-kmd-rs-28ff216899e95a6a9756bcbe580f28ed8ce61228.zip
Windows Kernel-Mode library
Diffstat (limited to 'src/irp.rs')
-rw-r--r--src/irp.rs184
1 files changed, 184 insertions, 0 deletions
diff --git a/src/irp.rs b/src/irp.rs
new file mode 100644
index 0000000..8d1b390
--- /dev/null
+++ b/src/irp.rs
@@ -0,0 +1,184 @@
+//! I/O request packets (IRP).
+
+use ::NTSTATUS;
+use ::basedef::*;
+use ::event::PKEVENT;
+use ::device_object::*;
+use ::file_object::*;
+use ::basedef::IO_PRIORITY::*;
+use ::KIRQL;
+
+
+pub type PIRP = *mut IRP;
+pub type PIO_STACK_LOCATION = *mut IO_STACK_LOCATION;
+
+// NOTE: fastcall is broken: https://github.com/rust-lang/rust/issues/18086
+//extern "fastcall" { fn IofCompleteRequest(Irp: PIRP, PriorityBoost: KPRIORITY_BOOST); }
+extern "system"
+{
+ fn IoCompleteRequest(Irp: PIRP, PriorityBoost: KPRIORITY_BOOST);
+
+ // unfortunately following are macro
+ // fn IoGetCurrentIrpStackLocation(Irp: PIRP) -> PIO_STACK_LOCATION;
+ // fn IoGetNextIrpStackLocation(Irp: PIRP) -> PIO_STACK_LOCATION;
+ // fn IoSetNextIrpStackLocation(Irp: PIRP);
+ // fn IoSkipCurrentIrpStackLocation(Irp: PIRP);
+}
+
+/// `IRP` Major Function Codes.
+#[repr(u8)]
+pub enum IRP_MJ
+{
+ CREATE,
+ CREATE_NAMED_PIPE,
+ CLOSE,
+ READ,
+ WRITE,
+ QUERY_INFORMATION,
+ SET_INFORMATION,
+ QUERY_EA,
+ SET_EA,
+ FLUSH_BUFFERS,
+ QUERY_VOLUME_INFORMATION,
+ SET_VOLUME_INFORMATION,
+ DIRECTORY_CONTROL,
+ FILE_SYSTEM_CONTROL,
+ DEVICE_CONTROL,
+ INTERNAL_DEVICE_CONTROL,
+ SHUTDOWN,
+ LOCK_CONTROL,
+ CLEANUP,
+ CREATE_MAILSLOT,
+ QUERY_SECURITY,
+ SET_SECURITY,
+ POWER,
+ SYSTEM_CONTROL,
+ DEVICE_CHANGE,
+ QUERY_QUOTA,
+ SET_QUOTA,
+ PNP,
+ MAXIMUM_FUNCTION,
+}
+
+/// The `IRP` structure is a partial opaque structure that represents an I/O request packet.
+#[repr(C)]
+pub struct IRP
+{
+ pub Type: u16,
+ pub Size: u16,
+ /// Pointer to an `MDL` describing a user buffer, if the driver is using direct I/O.
+ pub MdlAddress: PVOID,
+ /// Flags word - used to remember various flags.
+ pub Flags: u32,
+ /// Pointer to a system-space buffer if the driver is using buffered I/O.
+ pub SystemBuffer: PVOID,
+ pub ThreadListEntry: LIST_ENTRY,
+ /// I/O status - final status of operation.
+ pub IoStatus: IO_STATUS_BLOCK,
+ /// Indicates the execution mode of the original requester of the operation.
+ pub RequestorMode: KPROCESSOR_MODE,
+ /// If set to `TRUE`, a driver has marked the IRP pending.
+ pub PendingReturned: bool,
+ /// Stack state information.
+ pub StackCount: i8,
+ /// Stack state information.
+ pub CurrentLocation: i8,
+ /// If set to `TRUE`, the IRP either is or should be canceled.
+ pub Cancel: bool,
+ /// Irql at which the cancel spinlock was acquired.
+ pub CancelIrql: KIRQL,
+ pub ApcEnvironment: u8,
+ /// Allocation control flags.
+ pub AllocationFlags: u8,
+ /// User parameters.
+ pub UserIosb: PIO_STATUS_BLOCK,
+ pub UserEvent: PKEVENT,
+
+ // union {
+ pub UserApcRoutine: PIO_APC_ROUTINE,
+ pub UserApcContext: PVOID,
+ // } Overlay
+
+ /// Contains the entry point for a driver-supplied `Cancel` routine to be called if the IRP is canceled.
+ pub CancelRoutine: PDRIVER_CANCEL,
+ /// Contains the address of an output buffer for `IRP_MJ_DEVICE_CONTROL`.
+ pub UserBuffer: PVOID,
+
+ /// Kernel structures.
+ // union {
+ pub Overlay: _IRP_OVERLAY,
+ // } Tail
+}
+
+/// Kernel structures for IRP.
+#[repr(C)]
+pub struct _IRP_OVERLAY
+{
+ pub DriverContext: [PVOID; 4],
+ pub Thread: PETHREAD,
+ pub AuxiliaryBuffer: PVOID,
+ pub ListEntry: LIST_ENTRY,
+ /// Current stack location.
+ pub CurrentStackLocation: PIO_STACK_LOCATION,
+ pub OriginalFileObject: PFILE_OBJECT,
+}
+
+/// I/O Stack Locations.
+#[repr(C)]
+pub struct IO_STACK_LOCATION
+{
+ /// The IRP major function code indicating the type of I/O operation to be performed.
+ pub MajorFunction: u8,
+ /// A subfunction code for `MajorFunction`.
+ pub MinorFunction: u8,
+ /// Request-type-specific values (see [DEVICE_FLAGS](../device_object/enum.DEVICE_FLAGS.html)).
+ pub Flags: u8,
+ pub Control: u8,
+
+ /// A union that depends on the major and minor IRP function code values
+ /// contained in `MajorFunction` and `MinorFunction`.
+ // union Parameters
+ pub Parameters: [PVOID; 4],
+
+ /// A pointer to the driver-created `DEVICE_OBJECT` structure
+ /// representing the target physical, logical, or virtual device for which this driver is to handle the IRP.
+ pub DeviceObject: PDEVICE_OBJECT,
+ /// A pointer to a `FILE_OBJECT` structure that represents the file object, if any, that is associated with `DeviceObject` pointer.
+ pub FileObject: PFILE_OBJECT,
+ /// The following routine is invoked depending on the flags in the above `Flags` field.
+ pub CompletionRoutine: PIO_COMPLETION_ROUTINE,
+ /// The following is used to store the address of the context parameter that should be passed to the `CompletionRoutine`.
+ pub Context: PVOID,
+}
+
+/// Parameters for `IRP_MJ_READ`.
+#[repr(C)]
+pub struct _IO_STACK_LOCATION_READ
+{
+ pub Length: u32,
+ pub Key: u32,
+ pub ByteOffset: i64,
+}
+
+
+impl IRP {
+ /// 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 }
+ }
+
+ /// 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 {
+ self.IoStatus.Status = Status;
+ unsafe { IoCompleteRequest(self, IO_NO_INCREMENT) };
+ return Status;
+ }
+}
+
+impl IO_STACK_LOCATION {
+ /// Access parameters for `IRP_MJ_READ`.
+ pub fn ParametersRead(&mut self) -> &mut _IO_STACK_LOCATION_READ {
+ unsafe { ::core::mem::transmute(&mut self.Parameters) }
+ }
+}