#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;
}