Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
183
Добавлен:
20.02.2016
Размер:
11.02 Кб
Скачать
#include "stdafx.h"
#include <ntddk.h>

PDEVICE_OBJECT pGuiDevice = NULL;
PDEVICE_OBJECT pDeviceToControl = NULL;
PDEVICE_OBJECT pFilter=NULL;
PFILE_OBJECT pGuiFileObject=NULL;
int flag=0;
int count=0;

typedef struct _DEVICE_EXTENSION
{
    PDEVICE_OBJECT TargetDeviceObject;
    PFILE_OBJECT FileObject;
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;

typedef struct _KEYBOARD_INPUT_DATA {
  USHORT UnitId;
  USHORT MakeCode;
  USHORT Flags;
  USHORT Reserved;
  ULONG  ExtraInformation;
} KEYBOARD_INPUT_DATA, *PKEYBOARD_INPUT_DATA;

char *funcs[] = {
"IRP_MJ_CREATE",                  
"IRP_MJ_CREATE_NAMED_PIPE",       
"IRP_MJ_CLOSE",       
"IRP_MJ_READ  ",      
"IRP_MJ_WRITE",     
"IRP_MJ_QUERY_INFORMATION " ,   
"IRP_MJ_SET_INFORMATION " ,  
"IRP_MJ_QUERY_EA ",   
"IRP_MJ_SET_EA  ",   
"IRP_MJ_FLUSH_BUFFERS",   
"IRP_MJ_QUERY_VOLUME_INFORMATION",
"IRP_MJ_SET_VOLUME_INFORMATION ", 
"IRP_MJ_DIRECTORY_CONTROL" ,
"IRP_MJ_FILE_SYSTEM_CONTROL", 
"IRP_MJ_DEVICE_CONTROL" ,
"IRP_MJ_INTERNAL_DEVICE_CONTROL" ,
"IRP_MJ_SHUTDOWN " ,
"IRP_MJ_LOCK_CONTROL" ,
"IRP_MJ_CLEANUP " ,
"IRP_MJ_CREATE_MAILSLOT",
"IRP_MJ_QUERY_SECURITY",
"IRP_MJ_SET_SECURITY" ,
"IRP_MJ_POWER" ,
"IRP_MJ_SYSTEM_CONTROL",
"IRP_MJ_DEVICE_CHANGE" ,
"IRP_MJ_QUERY_QUOTA " ,
"IRP_MJ_SET_QUOTA  " ,
"IRP_MJ_PNP"
};

#define FILE_DEVICE_IOCTL  0x00008301
#define IOCTL_ATTACH       CTL_CODE(FILE_DEVICE_IOCTL, 0x800, METHOD_NEITHER, FILE_ANY_ACCESS)
#define IOCTL_DEATTACH      CTL_CODE(FILE_DEVICE_IOCTL, 0x801, METHOD_NEITHER, FILE_ANY_ACCESS)

NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING  RegistryPath);
NTSTATUS FilterDrvDispatch(PDEVICE_OBJECT pDevObj, PIRP Irp);
NTSTATUS OnCreate(PDEVICE_OBJECT DeviceObject, PIRP Irp);
NTSTATUS OnClose(PDEVICE_OBJECT DeviceObject, PIRP Irp);
NTSTATUS OnRead(PDEVICE_OBJECT DeviceObject, PIRP Irp);
NTSTATUS OnControl(PDEVICE_OBJECT DeviceObject, PIRP Irp);
NTSTATUS FilterDevDispatchComplete(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context);
VOID OnDrvUnload(PDRIVER_OBJECT DriverObject);

NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING  RegistryPath)
{
	int i=0;
	UNICODE_STRING DeviceName,Win32Device;
	UNICODE_STRING DeviceToControl,Win32DeviceToControl;
	//PDEVICE_OBJECT DeviceObject = NULL;
	NTSTATUS status;
	DbgPrint("simple: DriverEntry, regpath=%ws\n", RegistryPath->Buffer);
	
	RtlInitUnicodeString(&DeviceName,L"\\Device\\GuiDevice");
	RtlInitUnicodeString(&Win32Device,L"\\DosDevices\\GuiDevice");

	RtlInitUnicodeString(&DeviceToControl,L"\\Device\\DeviceToControl");
	RtlInitUnicodeString(&Win32DeviceToControl,L"\\DosDevices\\DeviceToControl");
			

	for(i=0; i<=IRP_MJ_MAXIMUM_FUNCTION; i++)
		{
			 DriverObject->MajorFunction[i] = FilterDrvDispatch;
		}



	status = IoCreateDevice(DriverObject,sizeof(DEVICE_EXTENSION),&DeviceName,FILE_DEVICE_UNKNOWN,0,FALSE,&pGuiDevice);//при не создании хоть одного грамотно удалить все
	if (!NT_SUCCESS(status))
		return status;
	if (!pGuiDevice)
		return STATUS_UNEXPECTED_IO_ERROR;

	pGuiDevice->Flags |= 0;
	pGuiDevice->AlignmentRequirement = FILE_WORD_ALIGNMENT;
	IoCreateSymbolicLink(&Win32Device, &DeviceName);
	pGuiDevice->Flags &= ~DO_DEVICE_INITIALIZING;


	status = IoCreateDevice(DriverObject,sizeof(DEVICE_EXTENSION),&DeviceToControl,FILE_DEVICE_UNKNOWN,0,FALSE,&pDeviceToControl);//при не создании хоть одного грамотно удалить все
	if (!NT_SUCCESS(status))
		return status;
	if (!pGuiDevice)
		return STATUS_UNEXPECTED_IO_ERROR;
	

	pDeviceToControl->Flags |= 0;
	pDeviceToControl->AlignmentRequirement = FILE_WORD_ALIGNMENT;
	IoCreateSymbolicLink(&Win32DeviceToControl, &DeviceToControl);
	pDeviceToControl->Flags &= ~DO_DEVICE_INITIALIZING;

	DriverObject->DriverUnload = OnDrvUnload;
	return STATUS_SUCCESS;
}

NTSTATUS OnControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
	PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);
	NTSTATUS status = STATUS_SUCCESS;

	switch(stack->Parameters.DeviceIoControl.IoControlCode)
	{
	case IOCTL_ATTACH:
		{
			if(pFilter==0)
			{
			PDEVICE_EXTENSION devext;
			UNICODE_STRING str;
			PFILE_OBJECT pFile;
			PDEVICE_OBJECT pObj;
			void *inbuf = stack->Parameters.DeviceIoControl.Type3InputBuffer;
			DbgPrint("targetname [%x]: %ws\n",inbuf, inbuf);
			RtlInitUnicodeString(&str,(PCWSTR)inbuf);
			RtlInitUnicodeString(&str,L"\\Device\\KeyboardClass0");
			status = IoGetDeviceObjectPointer(&str,GENERIC_ALL,&pFile,&pObj);

			if(STATUS_SUCCESS!=status)
			{
				DbgPrint("err: IoGetDeviceObjectPointer return %x\n", status);
				break;
			}
			status=IoCreateDevice(DeviceObject->DriverObject,sizeof(DEVICE_EXTENSION),NULL,pObj->DeviceType,0,FALSE,&pFilter);
			if(STATUS_SUCCESS!=status)
			{
				DbgPrint("err: IoCreateDevice return %x\n", status);
				break;

			}
			if(!pFilter)
			{
				DbgPrint("err: Device NULL\n");
				status =  STATUS_UNEXPECTED_IO_ERROR;
				break;
			}
		
			DbgPrint("before:\n");
			DbgPrint(" pFilter flags = %x\n", pFilter->Flags);
			DbgPrint("    pObj flags = %x\n", pObj->Flags);

			pFilter->Flags &= ~(DO_BUFFERED_IO|DO_DIRECT_IO);
			pFilter->Flags |= pObj->Flags & (DO_BUFFERED_IO|DO_DIRECT_IO);

			pFilter->Flags&=~DO_DEVICE_INITIALIZING;

			DbgPrint("after:\n");
			DbgPrint(" pFilter flags = %x\n", pFilter->Flags);
			DbgPrint("    pObj flags = %x\n", pObj->Flags);

			devext = (PDEVICE_EXTENSION)pFilter->DeviceExtension;
			devext->TargetDeviceObject=IoAttachDeviceToDeviceStack(pFilter,pObj);
			if(!devext->TargetDeviceObject)
			{
				DbgPrint("err: TargetDeviceObject NULL\n");
				status = STATUS_UNEXPECTED_IO_ERROR;
				break;
			}
			DbgPrint("attached to device %x\n", devext->TargetDeviceObject);
			devext->FileObject=pFile;
			pGuiFileObject=stack->FileObject;
			ObReferenceObject(stack->FileObject);
			}
			break;
		}

		case IOCTL_DEATTACH:
			if(pFilter!=0)
			{
				PDEVICE_EXTENSION devext=(PDEVICE_EXTENSION)(pFilter->DeviceExtension);
				DbgPrint("DETACH from %x\n", devext->TargetDeviceObject);
				IoDetachDevice(devext->TargetDeviceObject);
				
				if(count==0)
				{
					DbgPrint("DETACH flag=%i count=i\n");
					
					if(pGuiFileObject!=NULL)
					{
						ObDereferenceObject(pGuiFileObject);
						pGuiFileObject = NULL;
					}
					ObDereferenceObject(devext->FileObject);
					IoDeleteDevice(pFilter);
					pFilter = NULL;	//
				}
				else
				{
					DbgPrint("Pending Disconnect\n");
					flag=1;
				}

			}
			else
				DbgPrint("err: DETACH NULL\n");

			break;
	}
	DbgPrint("PFilter=%x\n",pFilter);
	Irp->IoStatus.Status = status;
	Irp->IoStatus.Information = 0;
	IoCompleteRequest(Irp, IO_NO_INCREMENT);
	return status;
}

VOID OnDrvUnload(PDRIVER_OBJECT DriverObject)
{
	DEVICE_OBJECT * pDeviceObj = DriverObject->DeviceObject;
	UNICODE_STRING sSymbolic;

	DbgPrint("[driver] Start OnDrvUnload");

	if(pFilter!=0)
	{
		PDEVICE_EXTENSION devext=(PDEVICE_EXTENSION)(pFilter->DeviceExtension);
		IoDetachDevice(devext->TargetDeviceObject);
	}

	while (pDeviceObj)
    {      
        DEVICE_OBJECT * pNext = pDeviceObj->NextDevice;
		DbgPrint("[driver] Deleted %x", &pDeviceObj);
        IoDeleteDevice(pDeviceObj);
        pDeviceObj = pNext;
    }

	RtlInitUnicodeString(&sSymbolic, L"\\DosDevices\\GuiDevice");
	IoDeleteSymbolicLink(&sSymbolic);
	DbgPrint("[driver] Finish OnDrvUnload");

	return;
}

NTSTATUS GuiDevDispatch(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)
{
	PIO_STACK_LOCATION stack=IoGetCurrentIrpStackLocation(Irp);
	switch(stack->MajorFunction)
	{
	case IRP_MJ_CREATE:
		{
			return OnCreate(DeviceObject,Irp);
		}
	case IRP_MJ_CLOSE:
		{
			return OnClose(DeviceObject,Irp);
		}
	case IRP_MJ_DEVICE_CONTROL:
		{
			return OnControl(DeviceObject,Irp);
		}

		case IRP_MJ_READ:
		{
			return OnRead(DeviceObject,Irp);
		}

	}
	
	Irp->IoStatus.Information=0;
	Irp->IoStatus.Status=STATUS_NOT_SUPPORTED;
	IoCompleteRequest(Irp,IO_NO_INCREMENT);	
	return Irp->IoStatus.Status;
}

NTSTATUS OnRead(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
	return STATUS_SUCCESS;
}
NTSTATUS OnCreate(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
	Irp->IoStatus.Status = STATUS_SUCCESS;
	Irp->IoStatus.Information = 0;
	IoCompleteRequest(Irp, IO_NO_INCREMENT);
	return STATUS_SUCCESS;
}
NTSTATUS OnClose(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
	Irp->IoStatus.Status = STATUS_SUCCESS;
	Irp->IoStatus.Information = 0;
	IoCompleteRequest(Irp, IO_NO_INCREMENT);
	return STATUS_SUCCESS;
}

NTSTATUS FilterDevDispatch(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)
{
	PDEVICE_EXTENSION devext;
	NTSTATUS NtStatus;

	PIO_STACK_LOCATION CurStack = IoGetCurrentIrpStackLocation(Irp);
   
	PIO_STACK_LOCATION NextStack = IoGetNextIrpStackLocation(Irp);
	DbgPrint(" FilterDrvDispatch: %s\n", funcs[CurStack->MajorFunction]);
	*NextStack = *CurStack;
	
	devext = (PDEVICE_EXTENSION)(DeviceObject->DeviceExtension);
   
	DbgPrint("  Sending to device %x\n", devext->TargetDeviceObject);

	DbgPrint(" pFilter flags = %x\n", DeviceObject->Flags);

	IoSetCompletionRoutine(Irp, FilterDevDispatchComplete, pFilter, TRUE, TRUE, TRUE);
	count++;
	NtStatus = IoCallDriver(devext->TargetDeviceObject, Irp);
	DbgPrint("  IoCallDriver return %x\n", NtStatus);
	DbgPrint("---\n");
	return NtStatus;
}

NTSTATUS FilterDrvDispatch(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)
{
	NTSTATUS ntStatus;
    PIO_STACK_LOCATION CurStack = IoGetCurrentIrpStackLocation(Irp);
	if(pGuiDevice==DeviceObject)
	   ntStatus = GuiDevDispatch(DeviceObject, Irp);
	else
	   ntStatus = FilterDevDispatch(DeviceObject, Irp);
return ntStatus;
}

NTSTATUS FilterDevDispatchComplete(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context)
{
   PIO_STACK_LOCATION CurStack = IoGetCurrentIrpStackLocation(Irp);
   ULONG buf_size=CurStack->Parameters.Read.Length;
   PKEYBOARD_INPUT_DATA buf;
   PDEVICE_EXTENSION devext = (PDEVICE_EXTENSION)pFilter->DeviceExtension;
	DbgPrint("FILTER_COMPLETE\n");
	DbgPrint("  %s\n",funcs[CurStack->MajorFunction]);
	if(Irp->PendingReturned)
	{
		IoMarkIrpPending(Irp);
	}

	if(CurStack->MajorFunction==IRP_MJ_READ)
	{

		if(DeviceObject->Flags&DO_BUFFERED_IO)
		{	
			buf = (PKEYBOARD_INPUT_DATA)Irp->AssociatedIrp.SystemBuffer;
		}
		else 
		if(DeviceObject->Flags&DO_DIRECT_IO)
		{
			buf=(PKEYBOARD_INPUT_DATA)MmGetSystemAddressForMdl(Irp->MdlAddress);
		}
		else
		{
			buf = (PKEYBOARD_INPUT_DATA)Irp->UserBuffer;
		}
		DbgPrint("  scancode=%x\n",buf->MakeCode);
	}


	count--;
	if((flag==1)&&(count==0))
	{
		ObDereferenceObject(devext->FileObject);
		ObDereferenceObject(pGuiFileObject);
		IoDeleteDevice(pFilter);
		pFilter = NULL;
		flag=0;
		DbgPrint("DeReference in Complete\n");
	}
	DbgPrint("count=%d,flag=%d---\n",count,flag);
    return STATUS_SUCCESS;
}
Соседние файлы в папке lab1_3
  • #
    20.02.2016882 б181buildchk_wxp_x86.log
  • #
    20.02.201676 б181buildchk_wxp_x86.wrn
  • #
    20.02.201611.02 Кб183lab1_3.c
  • #
    20.02.20167.52 Mб181lab1_3.ncb
  • #
    20.02.2016147 б181lab1_3.reg
  • #
    20.02.2016877 б181lab1_3.sln
  • #
    20.02.201616.9 Кб181lab1_3.suo
  • #
    20.02.20162.99 Кб181lab1_3.vcproj