Добавил:
Novilit
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Лабы по драйверам / lab4 / lab1_3 / lab1_3 / lab1_3
.c#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;
}