DriverGen Example

Back to DFC Information page...
------------------------- MyDriver.h -----------------------------------
/////////////////////////////////////////////////
// MyDriver.h
//
// Interface definition of CMyDevice class.
//
// This header is private to the driver and should not be 
// included in user-mode applications.

#ifndef MYDRIVER_H
#define MYDRIVER_H

/////////////////////////////////////////////////
// CMyDevice device class

class CMyDevice : public CDevice
{
public:
	CMyDevice();

	NTSTATUS Initialize();
	NTSTATUS DispatchDeviceControl(CIrp* pIrp);
	VOID StartIo(CIrp* pIrp);
	BOOLEAN OnInterrupt(PKINTERRUPT pInterrupt);
	VOID DpcForIsr(PKDPC pDpc, CIrp* pIrp, PVOID pContext);

protected:
	CPortRange m_ports;
	ULONG m_nBase;
	CInterrupt<CMyDevice> m_interrupt;
};

#endif // ifndef MYDRIVER_H
------------------------- MyDriver.cpp ----------------------------------
/////////////////////////////////////////////////
// MyDriver.cpp
//
// DriverEntry routine and implementation of CMyDevice class.

#ifdef DFC_WIN
	// Include DFC headers for VxD build
	#include "Windfc.h"
	#include "Lcode.h"
#else
	// Include DFC headers for NT driver build
	#include "Dfc.h"
	#include "MyDrlog.h"
#endif
#include "MyDriver.h"
#include "MyDrintr.h"

/////////////////// DriverEntry()
//
// This is the entry point for the driver module. We create a driver
// instance to initialize the module and create device objects.

extern "C"
NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject,
	IN PUNICODE_STRING pRegistryPath)
{
	CIsaDriver<CMyDevice>* pDriver = new CIsaDriver<CMyDevice>;
	NTSTATUS status = STATUS_SUCCESS;

	TRACE("Entering DriverEntry\n");

	if (!pDriver)
	{
		status = STATUS_NO_MEMORY;
		DfcLogError(pDriverObject, IO_ERR_INSUFFICIENT_RESOURCES, status);
	}
	else
	{
		// Iterate registry configurations and create device objects
		status = pDriver->OnEntry(pDriverObject, pRegistryPath);

		// Fail driver load if not able to create any devices
		if (pDriver->m_nDevices == 0)
		{
			TRACE("No devices created.\n");
			status = STATUS_NO_SUCH_DEVICE;
		}
		delete pDriver;
	}

	return status;
}

//////////////////// CMyDevice()

CMyDevice::CMyDevice()
{
	AddResource(&m_ports);
	AddResource(&m_interrupt);

	// TODO: Initialize other device members...
}

/////////////////// Initialize()

NTSTATUS CMyDevice::Initialize()
{
	// Call base class Initialize to initialize resources
	NTSTATUS status = CDevice::Initialize();
	if (!NT_SUCCESS(status))
		return status;

	// Save port base for inp and outp
	m_nBase = m_ports.GetBase();

	// TODO: Initialize your hardware...

	return status;
}

/////////////////// DispatchDeviceControl()
//
// Dispatch routine for DeviceIoControl requests.

NTSTATUS CMyDevice::DispatchDeviceControl(CIrp* pIrp)
{
	NTSTATUS status;
	ULONG cbRet = 0;

	switch (pIrp->GetControlCode())
	{
	case IOCTL_TEST:
		status = STATUS_PENDING;
		break;
	default:
		status = STATUS_NOT_IMPLEMENTED;
		break;
	}

	if (status == STATUS_PENDING)
	{
		pIrp->MarkPending();
		StartPacket(pIrp);
	}
	else
		pIrp->Complete(status, cbRet);

	return status;
}

/////////////////// StartIo()
//
// Starts processing of a request.

VOID CMyDevice::StartIo(CIrp* pIrp)
{
	NTSTATUS status = STATUS_SUCCESS;
	ULONG cbRet = 0;

	if (DfcIrpCancelled(pIrp))
	{
		TRACE("Returning from StartIo with cancelled IRP %x.", pIrp);
		return;
	}

	switch (pIrp->GetMajorFunction())
	{
	case IRP_MJ_READ:
	case IRP_MJ_WRITE:
	case IRP_MJ_DEVICE_CONTROL:
		// Switch pIrp->GetControlCode()
		break;
	default:
		break;
	}

	if (status != STATUS_PENDING)
	{
		StartNextPacket();
		pIrp->Complete(status, cbRet);
	}
}

//////////////////// OnInterrupt()
//
// Interrupt service routine for device.
//
// Returns TRUE if our device triggered the interrupt; else returns FALSE.

BOOLEAN CMyDevice::OnInterrupt(PKINTERRUPT pInterrupt)
{
	// TODO: Stop device from interrupting and call RequestDpc to complete
	// interrupt processing in the device DpcForIsr routine
	return TRUE;
}

/////////////////// DpcForIsr()
//
// Deferred procedure call for device ISR.

VOID CMyDevice::DpcForIsr(PKDPC pDpc, CIrp* pIrp, PVOID pContext)
{
	if (pIrp)
	{
		if (DfcIrpCancelled(pIrp))
		{
			TRACE("Returning from DpcForIsr with cancelled IRP %x.",pIrp);
			return;
		}

		// TODO: Complete any lengthy interrupt processing

		pIrp->Complete();
	}
}
Back to DFC Information page...

Home | Products | Support | Order | Press