实战EXE和SYS通信

 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; //返回成功

}

猜你喜欢

转载自blog.csdn.net/zang141588761/article/details/82750013
sys