diff --git a/UsbDk/Irp.cpp b/UsbDk/Irp.cpp new file mode 100644 index 0000000..c3388ca --- /dev/null +++ b/UsbDk/Irp.cpp @@ -0,0 +1,67 @@ +#include "Irp.h" + +CIrp::~CIrp() +{ + if (m_Irp != NULL) + { + Destroy(); + } +} + +VOID CIrp::Destroy() +{ + ASSERT(m_Irp != NULL); + ASSERT(m_TargetDevice != NULL); + + IoFreeIrp(m_Irp); + m_Irp = NULL; + + ObDereferenceObject(m_TargetDevice); + m_TargetDevice = NULL; +} + +NTSTATUS CIrp::Create(PDEVICE_OBJECT TargetDevice) +{ + m_TargetDevice = TargetDevice; + ObReferenceObject(m_TargetDevice); + + m_Irp = IoAllocateIrp(TargetDevice->StackSize, FALSE); + + if (m_Irp != NULL) + { + m_Irp->IoStatus.Status = STATUS_NOT_SUPPORTED; + return STATUS_SUCCESS; + } + + return STATUS_INSUFFICIENT_RESOURCES; +} + +NTSTATUS CIrp::SynchronousCompletion(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context) +{ + UNREFERENCED_PARAMETER(DeviceObject); + UNREFERENCED_PARAMETER(Irp); + + ASSERT(Context != NULL); + + KeSetEvent(static_cast(Context), IO_NO_INCREMENT, FALSE); + + return STATUS_MORE_PROCESSING_REQUIRED; +} + +NTSTATUS CIrp::SendSynchronously() +{ + KEVENT event; + + KeInitializeEvent(&event, SynchronizationEvent, FALSE); + + IoSetCompletionRoutine(m_Irp, SynchronousCompletion, &event, + TRUE, TRUE, TRUE); + + auto status = IoCallDriver(m_TargetDevice, m_Irp); + if (status == STATUS_PENDING) { + KeWaitForSingleObject(&event, Executive, KernelMode, FALSE, NULL); + status = m_Irp->IoStatus.Status; + } + + return status; +} diff --git a/UsbDk/Irp.h b/UsbDk/Irp.h new file mode 100644 index 0000000..4c336dd --- /dev/null +++ b/UsbDk/Irp.h @@ -0,0 +1,33 @@ +#pragma once + +#include "ntddk.h" +#include "Alloc.h" +#include "MemoryBuffer.h" + +class CIrp : public CAllocatable +{ +public: + CIrp() {}; + ~CIrp(); + + NTSTATUS Create(PDEVICE_OBJECT TargetDevice); + VOID Destroy(); + NTSTATUS SendSynchronously(); + + template + VOID Configure(ConfiguratorT Configurator) + { Configurator(IoGetNextIrpStackLocation(m_Irp)); } + + template + VOID ReadResult(ReaderT Reader) + { Reader(m_Irp->IoStatus.Information); } + + CIrp(const CIrp&) = delete; + CIrp& operator= (const CIrp&) = delete; + +private: + static NTSTATUS SynchronousCompletion(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context); + + PIRP m_Irp = NULL; + PDEVICE_OBJECT m_TargetDevice = NULL; +}; diff --git a/UsbDk/UsbDk.vcxproj b/UsbDk/UsbDk.vcxproj index 35723a6..10cad38 100644 --- a/UsbDk/UsbDk.vcxproj +++ b/UsbDk/UsbDk.vcxproj @@ -55,6 +55,7 @@ + @@ -64,6 +65,7 @@ + diff --git a/UsbDk/UsbDk.vcxproj.filters b/UsbDk/UsbDk.vcxproj.filters index a3a7ba2..697a141 100644 --- a/UsbDk/UsbDk.vcxproj.filters +++ b/UsbDk/UsbDk.vcxproj.filters @@ -46,6 +46,9 @@ Header Files + + Header Files + @@ -66,5 +69,8 @@ Source Files + + Source Files + \ No newline at end of file