A、用户层传入数据-EXE部分代码
B、驱动层接收数据并处理-SYS部分代码
C、驱动层返回数据至用户层
D、用户层获得处理结果
A、用户层传入数据EXE部分代码
//#include <winioctl.h>
#define add_code CTL_CODE(FILE_DEVICE_UNKNOWN, 0x800, METHOD_BUFFERED,FILE_ANY_ACCESS)
#define sub_code CTL_CODE(FILE_DEVICE_UNKNOWN, 0x801, METHOD_BUFFERED,FILE_ANY_ACCESS)
int port[2],bufret;
DWORD dwWrite;
int add(HANDLE hDevice,int a,int b)
{
port[0]=a;
port[1]=b;
DeviceIoControl(hDevice, add_code , &port, 8, &bufret, 4, &dwWrite, NULL);
return bufret;
}
///////主要代码如下
{ //CreateFile hDevice
HANDLE hDevice =
CreateFile("\\\\.\\My_DriverLinkName", //\\??\My_DriverLinkName
GENERIC_READ | GENERIC_WRITE,
0, // share mode none
NULL, // no security
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL ); // no template
printf("start\n");
if (hDevice == INVALID_HANDLE_VALUE)
{
printf("获取驱动句柄失败: %s with Win32 error code: %d\n","MyDriver", GetLastError() );
getchar();
return -1;
}
//add_code
int a=55;
int b=33;
int r= add(hDevice,a,b);
printf("%d+%d=%d\n",a,b,r);
getchar();
return 0;
}
1、修改符号链接
RtlInitUnicodeString(&symLinkName,L"\\??\\My_DriverLinkName");
2、
B、驱动层接收数据并处理SYS部分代码
NTSTATUS ddk_DispatchRoutine_CONTROL(IN PDEVICE_OBJECT pDevobj,IN PIRP pIrp )
{ //
ULONG info;
//得到当前栈指针
PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(pIrp);
ULONG mf=stack->MajorFunction;//区分IRP
switch (mf)
{
case IRP_MJ_DEVICE_CONTROL:
{ KdPrint(("Enter myDriver_DeviceIOControl\n"));
NTSTATUS status = STATUS_SUCCESS;
//得到输入缓冲区大小
ULONG cbin = stack->Parameters.DeviceIoControl.InputBufferLength;
//得到输出缓冲区大小
ULONG cbout = stack->Parameters.DeviceIoControl.OutputBufferLength;
//得到IOCTL码
ULONG code = stack->Parameters.DeviceIoControl.IoControlCode;
switch (code)
{
case add_code:
{
int a,b;
KdPrint(("add_code 1111111111111111111\n"));
//缓冲区方式IOCTL
//获取缓冲区数据 a,b
int * InputBuffer = (int*)pIrp->AssociatedIrp.SystemBuffer;
_asm
{
mov eax,InputBuffer
mov ebx,[eax]
mov a,ebx
mov ebx,[eax+4]
mov b,ebx
}
KdPrint(("a=%d,b=%d \n", a,b));
a=a+b;
//C、驱动层返回数据至用户层
//操作输出缓冲区
int* OutputBuffer = (int*)pIrp->AssociatedIrp.SystemBuffer;
_asm
{
mov eax,a
mov ebx,OutputBuffer
mov [ebx],eax //bufferet=a+b
}
KdPrint(("a+b=%d \n",a));
//设置实际操作输出缓冲区长度
info = 4;
}
case sub_code:
{
break;
}
}//end code switch
break;
}
case IRP_MJ_CREATE:
{
break;
}
case IRP_MJ_CLOSE:
{
break;
}
case IRP_MJ_READ:
{
break;
}
}
//对相应的IPR进行处理
pIrp->IoStatus.Information=info;//设置操作的字节数为0,这里无实际意义
pIrp->IoStatus.Status=STATUS_SUCCESS;//返回成功
IoCompleteRequest(pIrp,IO_NO_INCREMENT);//指示完成此IRP
KdPrint(("离开派遣函数\n"));//调试信息
return STATUS_SUCCESS; //返回成功
}