WDF驱动和3环通信

#ifndef CTL_CODE_H_89749_9961731
#define CTL_CODE_H_89749_9961731

#define CTL_BUFFERED CTL_CODE(FILE_DEVICE_UNKNOWN,0x850,METHOD_BUFFERED,FILE_ANY_ACCESS)

//METHOD_OUT_DIRECT 该方式既可以使用输入缓冲区.也可以使用输出缓冲区
#define CTL_DIRECT   CTL_CODE(FILE_DEVICE_UNKNOWN,0x851,METHOD_OUT_DIRECT,FILE_ANY_ACCESS)
#endif

此驱动为支持PNP的驱动
采用METHOD_BUFFERED方式通信时,获取的输入缓冲区可以当成输出缓冲区使用,直接写入值就可以返回给3环
而METHOD_OUT_DIRECT通信方式,输入缓冲区和输出缓冲区是不一样的,需要单独获取,才能给3环返回值

#include "Queue.h"
#include "IOCTL.h"
#include "Device.h"
#include <ntstatus.h>
//I/O内部设备控制
VOID EvtIoDeviceControl(
	_In_ WDFQUEUE Queue,
	_In_ WDFREQUEST Request,
	_In_ size_t OutputBufferLength,
	_In_ size_t InputBufferLength,
	_In_  ULONG IoControlCode
	)
{
	KdPrint(("有io请求\n"));
	PULONG Buffer = NULL;
	size_t Length = 0;

	switch (IoControlCode)
	{
	case CTL_BUFFERED:
		KdPrint(("进入CTL_BUFFERED方式处理请求\n"));

		//获取缓冲区
		WdfRequestRetrieveInputBuffer(Request, 1,&Buffer,&Length );
		if (*Buffer==0x13)
		{
			WdfRequestRetrieveOutputBuffer(Request, 1, &Buffer, &Length);
			*Buffer = 5;
			WdfRequestCompleteWithInformation(Request, STATUS_SUCCESS, 4);
			return;
		}
		else
		{
			*Buffer = 0x500;
			WdfRequestCompleteWithInformation(Request, STATUS_SUCCESS, 4);
		}

		break;
	case CTL_DIRECT:

		//获取缓冲区
		KdPrint(("进入CTL_DIRECT方式处理请求\n"));

		//获取缓冲区
		WdfRequestRetrieveInputBuffer(Request, 1, &Buffer, &Length);
		if (*Buffer == 0x13)
		{
			WdfRequestRetrieveOutputBuffer(Request, 1, &Buffer, &Length);
			*Buffer = 5;
			WdfRequestCompleteWithInformation(Request, STATUS_SUCCESS, 4);
			return;
		}
		else
		{
			WdfRequestRetrieveOutputBuffer(Request, 1, &Buffer, &Length);
			*Buffer = 0x500;
			WdfRequestCompleteWithInformation(Request, STATUS_SUCCESS, 4);
		}

		break;
	default:
		WdfRequestCompleteWithInformation(Request, STATUS_INVALID_PARAMETER, 0);
	}

}

// WDFuser.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include<windows.h>
#include <stdio.h>
#include <InitGuid.h>
#include <SetupAPI.h>
#include "IOCTL.h"
#pragma comment(lib,"SetupAPI.lib")

DEFINE_GUID(WDF_GUID, 0xb184f9a, 0xe875, 0x49c2, 0xb0, 0xdc, 0xcf, 0x58, 0xa8, 0x56, 0x1f, 0x8e);

//使用VS的生成GUID工具,选择第二种方式生成。

PWCHAR GetDeviceViaInterface(const GUID* pGuid)
{
	//SetupDiGetClassDevs 通过GUID找到对应的设备接口
	HDEVINFO info = SetupDiGetClassDevs(pGuid,
		NULL,	//总线类型 虚拟设备不用管这个值
		NULL, 	//父窗口
		DIGCF_PRESENT |  //设备在系统中
		DIGCF_INTERFACEDEVICE); //查找的是接口
	if (info == INVALID_HANDLE_VALUE)
	{
		printf("No HDEVINFO available for this GUID\n");
		return NULL;
	}

	// Get interface data for the requested instance
	SP_INTERFACE_DEVICE_DATA IfData;
	IfData.cbSize = sizeof(IfData);
	//枚举设备接口  一个驱动设备可以创建多个接口 插入一个相同设备就会创建一个设备接口.
	// i 指定了多个设备中的其中一个设备序号 如果没有这个序号就会枚举失败

		if (!SetupDiEnumDeviceInterfaces(info, NULL, pGuid, 0, &IfData))
		{
			SetupDiDestroyDeviceInfoList(info);
			return NULL;
		}
		DWORD ReqLen;
		//获取指定接口的详细信息 主要是获得ReqLen
		SetupDiGetDeviceInterfaceDetail(info, &IfData, NULL, 0, &ReqLen, NULL);

		//分配符号链接名长度的内存
		PSP_INTERFACE_DEVICE_DETAIL_DATA IfDetail = (PSP_INTERFACE_DEVICE_DETAIL_DATA)(new char[ReqLen]);
		if (IfDetail == NULL)
		{
			SetupDiDestroyDeviceInfoList(info);
			return NULL;
		}

		// Get symbolic link name
		IfDetail->cbSize = sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA);
		if (!SetupDiGetDeviceInterfaceDetail(info, &IfData, IfDetail, ReqLen, NULL, NULL))
		{
			SetupDiDestroyDeviceInfoList(info);
			delete IfDetail;
			return NULL;
		}
		printf("Symbolic link is %S\n", IfDetail->DevicePath);
		return IfDetail->DevicePath;
}



int _tmain(int argc, _TCHAR* argv[])
{
	PWCHAR pInterfaceLink = GetDeviceViaInterface(&WDF_GUID);

	// Open file
	HANDLE hDevice = CreateFile(pInterfaceLink,
	GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE,
	FILE_SHARE_READ | FILE_SHARE_WRITE,
	NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
	if (hDevice == INVALID_HANDLE_VALUE)
	{
		printf("设备接口打开失败,ErrorCode=%x", GetLastError());
		return false;
	}

	/*
	delete ifDetail;
	SetupDiDestroyDeviceInfoList(info);
	*/
	DWORD dwRet = 0;
	CHAR InBuffer[10] = { '5','3' };
	DWORD InBufferSize = 10;
	UCHAR OutBuffer[10] = { 0 };
	DWORD OutBufferSize = 10;


	DeviceIoControl(hDevice, CTL_CONVERT, InBuffer, InBufferSize,OutBuffer ,OutBufferSize, &dwRet, 0);
	CloseHandle(hDevice);
	if(dwRet>0)
	{
		printf("OutBuffer=%x\n  返回的字节数=%x", *(PUCHAR)OutBuffer,dwRet);
	}
	
	getchar();
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值