Click here to Skip to main content
15,894,017 members
Articles / Desktop Programming / MFC

Communication between GUI Application and Device Driver

Rate me:
Please Sign up or sign in to vote.
4.83/5 (29 votes)
26 Mar 20022 min read 278.1K   5.7K   121  
An article on Communication between GUI Application and Device Driver

#include <ntddk.h>
#include "CommDriver.h"
#include "..\include\IoControl.h"


PVOID	gpEventObject = NULL;

/*
Response to CreateFile
*/
NTSTATUS CommDriver_Create(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
    )
{
	NTSTATUS status = STATUS_SUCCESS;

	DbgPrint("CommDriver_Create\n");

	Irp->IoStatus.Status = STATUS_SUCCESS;
	Irp->IoStatus.Information = 0;
	IoCompleteRequest(Irp, IO_NO_INCREMENT);

	return status;
}

/*
Response to CloseHandle
*/
NTSTATUS CommDriver_Close(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
    )
{
	NTSTATUS status = STATUS_SUCCESS;

	DbgPrint("CommDriver_Close\n");

	Irp->IoStatus.Status = STATUS_SUCCESS;
	Irp->IoStatus.Information = 0;
	IoCompleteRequest(Irp, IO_NO_INCREMENT);

	return status;
}

/*
Resonse to DeviceIoControl
*/
NTSTATUS CommDriver_IoControl(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
    )
{
	NTSTATUS					status = STATUS_SUCCESS;
	ULONG						controlCode;
	PIO_STACK_LOCATION			irpStack;
	HANDLE						hEvent;
	OBJECT_HANDLE_INFORMATION	objHandleInfo;
	LONG*						outBuf;

	irpStack = IoGetCurrentIrpStackLocation(Irp);
	controlCode = irpStack->Parameters.DeviceIoControl.IoControlCode;
	
	switch(controlCode)
	{
	case IO_REFERENCE_EVENT:
		hEvent = (HANDLE) irpStack->Parameters.DeviceIoControl.Type3InputBuffer;
		status = ObReferenceObjectByHandle(
				hEvent,
				GENERIC_ALL,
				NULL,
				KernelMode,
				&gpEventObject,
				&objHandleInfo);
		if(status != STATUS_SUCCESS)
		{
			DbgPrint("ObReferenceObjectByHandle failed! status = %x\n", status);
			break;
		}
		DbgPrint("Referenct object sussfully!\n");
		break;
		
	case IO_DEREFERENCE_EVENT:
		if(gpEventObject)
			ObDereferenceObject(gpEventObject);
		DbgPrint("Dereferenct object sussfully!\n");
		break;

	case IO_SET_EVENT:
		KeSetEvent(gpEventObject,
			0,
			FALSE);
		DbgPrint("KeSetEvent sussfully!\n");
		break;
		
	case IO_CLEAR_EVENT:
		KeClearEvent(gpEventObject);
		DbgPrint("KeClearEvent sussfully!\n");
		break;
	
	case IO_QUERY_EVENT_STATE:
		DbgPrint("in KeReadStateEvent !\n");
		outBuf = (LONG*) Irp->UserBuffer;
		*outBuf = KeReadStateEvent(gpEventObject);
		DbgPrint("KeReadStateEvent sussfully!\n");
		
		Irp->IoStatus.Status = STATUS_SUCCESS;
		Irp->IoStatus.Information = sizeof(LONG);
		IoCompleteRequest(Irp, IO_NO_INCREMENT);
		return status;

	default:
		break;
	}

	Irp->IoStatus.Status = STATUS_SUCCESS;
	Irp->IoStatus.Information = 0;
	IoCompleteRequest(Irp, IO_NO_INCREMENT);

	return status;
}


void CommDriver_Unload(
    IN PDRIVER_OBJECT DriverObject
    )
{
	UNICODE_STRING	SymbolicName;

	RtlInitUnicodeString(&SymbolicName, COMM_DRIVER_WIN32_DEV_NAME);
	IoDeleteSymbolicLink(&SymbolicName);

	IoDeleteDevice(DriverObject->DeviceObject);
}

NTSTATUS DriverEntry( 
    IN PDRIVER_OBJECT DriverObject, 
    IN PUNICODE_STRING RegistryPath 
    )
{
	NTSTATUS		status = STATUS_SUCCESS;
	UNICODE_STRING	DeviceName;
	UNICODE_STRING	SymbolicName;

	/* Driver unload routine */
	DriverObject->DriverUnload = CommDriver_Unload;

	/* Initialize major functions */
	DriverObject->MajorFunction[IRP_MJ_CREATE] = CommDriver_Create;
	DriverObject->MajorFunction[IRP_MJ_CLOSE] = CommDriver_Close;
	DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = CommDriver_IoControl;

	/* Initizlize device name and symbolic name */
	RtlInitUnicodeString(&DeviceName, COMM_DRIVER_DEV_NAME);
	RtlInitUnicodeString(&SymbolicName, COMM_DRIVER_WIN32_DEV_NAME);

	/*
	Create a communication object, 
	GUI application can open the device and communicate with this kernel module.
	*/
	status = IoCreateDevice(
			DriverObject,
			sizeof(COMM_DRIVER_EXT),
			&DeviceName,
			FILE_DEVICE_UNKNOWN,
			0,
			TRUE,
			&DriverObject->DeviceObject
			);
	if(status != STATUS_SUCCESS)
	{
		DbgPrint("IoCreateDevice failed\n");
		return status;
	}
	
	/* Create symbilic link */
	status = IoCreateSymbolicLink(&SymbolicName, &DeviceName);
	if(status != STATUS_SUCCESS)
	{
		DbgPrint("IoCreateSymbolicLink failed\n");
		return status;
	}
	
	DbgPrint("Exit DriverEntry\n");

	return  status;
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions