Windows内核中如何在不同的派遣函数间进行变量传递,赋值

sharpmddr 2017-12-21 10:00:32
请问大神们,如何在两个不同的派遣函数之间进行数据交换? 小弟想做一个键盘记录的程序,使用两个派遣函数(1)DriverObject->MajorFunction[IRP_MJ_READ] = c2pDispatchRead;//在这个派遣函数中读取键盘键入的按键。(2)DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]= DeviceIoControl;//在这个派遣函数中与Ring3 的应用程序通信,将按键值发送给应用程序。 遇到的问题是:在读键盘的派遣函数的完成回调函数c2pReadComplete中保存了按键值,并同时赋值给了一个全局变量gCm,而这个全局变量在派遣函数DeviceIoControl中进行读取却变成了空值?小弟想问的是为什么会这样? 在内核中有没有什么方法在不同的派遣函数之间进行数据传递或赋值呢?谢谢大神们的解答

//部分内核程序如下:

UCHAR gCm;//全局变量用于保存键盘按下的按键值

NTSTATUS DeviceIoControl(PDEVICE_OBJECT DeviceObject, PIRP irp)
{
PIO_STACK_LOCATION irpsp;
NTSTATUS status = STATUS_SUCCESS;
ULONG inBufLength;
ULONG outBufLength;
UCHAR outbuffer = gCm;//将保存在全局变量中的按键值赋值给outbuffer.
size_t outbufferlen = strlen(outbuffer) + 1;
ULONG ret_len = 0;
UNREFERENCED_PARAMETER(DeviceObject);
PAGED_CODE();
irpsp = IoGetCurrentIrpStackLocation(irp);
inBufLength = irpsp->Parameters.DeviceIoControl.InputBufferLength;
outBufLength = irpsp->Parameters.DeviceIoControl.OutputBufferLength;
DbgPrint(("I am In Here!! In DeviceIoContrl"));
switch (irpsp->Parameters.DeviceIoControl.IoControlCode)
{
case Com_Send:
………………..
status = irp->IoStatus.Status;
IoCompleteRequest(irp, IO_NO_INCREMENT);
return status;

break;
case Com_Recv://接收应用程序发来的读数据请求,将按键值存到irp->AssociatedIrp.SystemBuffer中
RtlCopyMemory((char*)irp->AssociatedIrp.SystemBuffer, outbuffer, strlen(outbuffer) + 1);
irp->IoStatus.Information = strlen((char*)irp->AssociatedIrp.SystemBuffer) + 1;
status = irp->IoStatus.Status;
IoCompleteRequest(irp, IO_NO_INCREMENT);
return status;
break;
default:
status = STATUS_INVALID_PARAMETER;
break;
}
irp->IoStatus.Information = 0;
irp->IoStatus.Status = status;
IoCompleteRequest(irp, IO_NO_INCREMENT);
return status;
}


NTSTATUS c2pDispatchRead(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)//键盘读的派遣函数
{
NTSTATUS status = STATUS_SUCCESS;
PC2P_DEV_EXT devExt;
PIO_STACK_LOCATION currentIrpStack;
KEVENT waitEvent;
KeInitializeEvent(&waitEvent, NotificationEvent, FALSE);
if (Irp->CurrentLocation == 1)
{
ULONG ReturnedInformation = 0;
KdPrint(("Dispatch encountered bogus current location\n"));
status = STATUS_INVALID_DEVICE_REQUEST;
Irp->IoStatus.Status = status;
Irp->IoStatus.Information = ReturnedInformation;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return(status);
}
gC2pKeyCount++;
devExt =(PC2P_DEV_EXT)DeviceObject->DeviceExtension;
currentIrpStack = IoGetCurrentIrpStackLocation(Irp);
IoCopyCurrentIrpStackLocationToNext(Irp);
IoSetCompletionRoutine(Irp, c2pReadComplete,DeviceObject, TRUE, TRUE, TRUE);
return IoCallDriver(devExt->LowerDeviceObject, Irp);
}


NTSTATUS c2pReadComplete(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp,IN PVOID Context)//键盘读请求后的完成回调函数
{
PIO_STACK_LOCATION IrpSp;
ULONG buf_len = 0;
PUCHAR buf = NULL;
size_t i, numKeys;
UCHAR Outcm;
PKEYBOARD_INPUT_DATA KeyData;
IrpSp = IoGetCurrentIrpStackLocation(Irp);
if (NT_SUCCESS(Irp->IoStatus.Status))
{
buf = Irp->AssociatedIrp.SystemBuffer;
KeyData = (PKEYBOARD_INPUT_DATA)buf;
buf_len = Irp->IoStatus.Information;
numKeys = buf_len / sizeof(KEYBOARD_INPUT_DATA);
if (KeyData->Flags == KEY_BREAK)如果按键抬起
{
gCm=(UCHAR)KeyData->MakeCode;//这里将按下并抬起的按键值赋值给全局变量gCm
if (KeyData->MakeCode == CAPS_LOCK)
{
KeyData->MakeCode = LCONTROL;
}
}
}
gC2pKeyCount--;

if (Irp->PendingReturned)
{
IoMarkIrpPending(Irp);
}
return Irp->IoStatus.Status;
}


NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,IN PUNICODE_STRING RegistryPath)
{
ULONG i;
NTSTATUS status = 0;
for (i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++)
{
DriverObject->MajorFunction[i] = CreateClose;
}
DriverObject->MajorFunction[IRP_MJ_READ] = c2pDispatchRead;//在这个派遣函数中读取键盘键入的按键
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]= DeviceIoControl;//在这个派遣函数中与Ring3 的应用程序通信,将按键值发送给应用程序。
DriverObject->DriverUnload = c2pUnload;
gDriverObject = DriverObject;
status = c2pAttachDevices(DriverObject, RegistryPath);
return status;
}
...全文
551 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

21,595

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 驱动开发/核心开发
社区管理员
  • 驱动开发/核心开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧