win10驱动开发19——IRP同步

这篇文章代码有问题可以参靠这篇
这篇文章

#include <windows.h>
#include <stdio.h>

void LpoverlappedCompletionRoutine(
	__in     DWORD dwErrorCode,
	__in      DWORD dwNumberOfBytesTransfered,
	__out  LPOVERLAPPED lpOverlapped
)
{
	printf("已经完成了读操作\n");
}
//同步
VOID Syn() 
{
	HANDLE hFile = CreateFile(TEXT("test.txt"),
		GENERIC_ALL,
		FILE_SHARE_READ | FILE_SHARE_WRITE,
		NULL,
		OPEN_ALWAYS,//存在打开不存在创建打开
		FILE_ATTRIBUTE_NORMAL ,
		NULL);
	if (hFile == INVALID_HANDLE_VALUE)
	{
		printf("文件打开失败%d\n", GetLastError());
	}
	DWORD dwret;
	WriteFile(hFile, "这是同步操作", strlen("这是同步操作"), &dwret, NULL);
	CloseHandle(hFile);
}
//异步
VOID Asy()
{
	HANDLE hFile = CreateFile(TEXT("test.txt"),
		GENERIC_ALL,
		FILE_SHARE_READ | FILE_SHARE_WRITE,
		NULL,
		OPEN_ALWAYS,//存在打开不存在创建打开
		FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,//加上就是一部
		NULL);
	if (hFile == INVALID_HANDLE_VALUE)
	{
		printf("文件打开失败%d\n", GetLastError());
	}
	DWORD dwret;
	OVERLAPPED ol = {NULL};
	ol.hEvent = CreateEvent(NULL,FALSE,FALSE,NULL);
	WriteFile(hFile, "这是异步操作", strlen("这是异步操作"), &dwret, &ol);
	WaitForSingleObject(ol.hEvent, INFINITE);
	char Buffer[1024] = { 0 };
	ReadFileEx(hFile, Buffer, sizeof(Buffer), &ol, LpoverlappedCompletionRoutine);
	SleepEx(INFINITE, TRUE);
	printf("%s\n", Buffer);
	printf("结束\n");
	CloseHandle(hFile);
}
int main()
{
	Syn();
	Asy();
}

在这里插入图片描述
内核层

#include <ntddk.h>   

LIST_ENTRY listHead;

VOID Unload(IN PDRIVER_OBJECT pDriverObject)
{
	UNICODE_STRING SymbolicLinkName = RTL_CONSTANT_STRING(L"\\??\\HelloDDK");
	IoDeleteSymbolicLink(&SymbolicLinkName);//删除连接
	IoDeleteDevice(pDriverObject->DeviceObject);//释放驱动对象
	//驱动卸载的时候显示
	KdPrint(("Goodbye driver\n"));
}

NTSTATUS Create(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 Read(IN PDEVICE_OBJECT deviceObject, IN PIRP Irp)
{
	KdPrint(("进入Read\n"));
	if (Irp->PendingReturned)
	{
		//这段代码不知道怎么进来
		IoMarkIrpPending(Irp);//保证irp不会释放
		InsertHeadList(&listHead, &Irp->Tail.Overlay.ListEntry);
	}
	else 
	{
		Irp->IoStatus.Status = STATUS_SUCCESS;//设置返回状态,告诉操作是成功还是失败
		Irp->IoStatus.Information = 0;
		IoCompleteRequest(Irp, IO_NO_INCREMENT);
		KdPrint(("else\n"));
	}
	KdPrint(("离开Read\n"));
	return STATUS_SUCCESS;
}

NTSTATUS Cleanup(IN PDEVICE_OBJECT deviceObject, IN PIRP Irp)
{
	KdPrint(("进入Cleanup\n"));
	while (!IsListEmpty(&listHead))
	{
		PLIST_ENTRY pEntry = RemoveHeadList(&listHead);
		PIRP pendingIrp=CONTAINING_RECORD(pEntry, IRP, Tail.Overlay.ListEntry);
		pendingIrp->IoStatus.Status = STATUS_SUCCESS;//设置返回状态,告诉操作是成功还是失败
		pendingIrp->IoStatus.Information = 0;
		IoCompleteRequest(pendingIrp, IO_NO_INCREMENT);
	}
	Irp->IoStatus.Status = STATUS_SUCCESS;//设置返回状态,告诉操作是成功还是失败
	Irp->IoStatus.Information = 0;
	IoCompleteRequest(Irp, IO_NO_INCREMENT);
	KdPrint(("离开Cleanup\n"));
	return STATUS_SUCCESS;
}

NTSTATUS Close(IN PDEVICE_OBJECT deviceObject, IN PIRP Irp)
{
	KdPrint(("进入Close\n"));
	Irp->IoStatus.Status = STATUS_SUCCESS;//设置返回状态,告诉操作是成功还是失败
	Irp->IoStatus.Information = 0;
	IoCompleteRequest(Irp, IO_NO_INCREMENT);//是不改变
	KdPrint(("离开Close\n"));
	return STATUS_SUCCESS;
}

NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath
)
{
	KdPrint(("hello driver\n"));
	UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\HelloDDK");
	UNICODE_STRING SymbolicLinkName = RTL_CONSTANT_STRING(L"\\??\\HelloDDK");
	NTSTATUS status;
	PDEVICE_OBJECT DeviceObject;
	DriverObject->DriverUnload = Unload;
	DriverObject->MajorFunction[IRP_MJ_CREATE] = Create;
	DriverObject->MajorFunction[IRP_MJ_READ] = Read;
	DriverObject->MajorFunction[IRP_MJ_CLEANUP] = Cleanup;
	DriverObject->MajorFunction[IRP_MJ_CLOSE] = Close;
	status = IoCreateDevice(DriverObject, 0, &DeviceName, FILE_DEVICE_UNKNOWN, 0, FALSE, &DeviceObject);
	if (!NT_SUCCESS(status))
	{
		KdPrint(("创建设备失败%x\n", status));
		return status;
	}
	status = IoCreateSymbolicLink(&SymbolicLinkName, &DeviceName);
	if (!NT_SUCCESS(status))
	{
		KdPrint(("符号连接创建失败%x\n", status));
		IoDeleteDevice(DeviceObject);
		return status;
	}
	DeviceObject->Flags |= DO_BUFFERED_IO; //
	DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
	InitializeListHead(&listHead);
	return STATUS_SUCCESS;
}

应用层

#include <windows.h>
#include <stdio.h>
#include <winioctl.h>
int main()
{
	HANDLE hDevice = CreateFile(TEXT("\\\\.\\HelloDDK"),
		GENERIC_ALL,
		FILE_SHARE_READ | FILE_SHARE_WRITE,
		NULL,
		OPEN_EXISTING,
		FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED,//FILE_FLAG_OVERLAPPED 代表异步  FILE_ATTRIBUTE_NORMAL代表同步
		NULL
	);
	if (hDevice == INVALID_HANDLE_VALUE)
	{
		printf("设备打开失败%d\n", GetLastError());
		return -1;
	}
	DWORD dwRet;
	//注意异步操作必须加 OVERLAPPED ol = { NULL }标识 否则不是异步操作将会一直等待上一个ReadFile完成才执行下一个ReadFile
	OVERLAPPED ol = { NULL };
	for (int i=0;i<2;i++)
	{
		ReadFile(hDevice, NULL, 0, &dwRet, &ol);
	}
	CloseHandle(hDevice);
	return 0;
}

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值