(十六)、IRP的同步与异步

一、IRP的同步完成与异步完成

0

1、IoMarkIrpPending

0
0
IoMarkIrpPending函数的作用就是告诉IoManager不要回收资源
 

2、FILE_FLAG_OVERLAPPED

CreateFile的倒数第二个成员
0
 
 
三环代码
// syn_asy三环代码.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <iostream>
#include <stdio.h>
#include <Windows.h>

using namespace std;


int main()
{
    HANDLE hDevice = CreateFile(TEXT("\\\\.\\MyDDKLink"),
        GENERIC_ALL,
        FILE_SHARE_READ | FILE_SHARE_WRITE,
        NULL,
        OPEN_EXISTING,
        FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
        NULL);

    if (hDevice == INVALID_HANDLE_VALUE)
    {
        printf("打开设备失败 %d\n",GetLastError());
        return -1;
    }
    DWORD dwret;
    OVERLAPPED ol = { NULL };
    for (int i = 0; i < 100; i++) {
        ReadFile(hDevice, NULL, 0, &dwret, &ol);
    }
    CloseHandle(hDevice);//在内核会触发 MJ_cleanuP 与Close派遣函数//

    getchar();
    return 0;
}
0环代码
#include <ntddk.h>

LIST_ENTRY ListHead;
VOID Unload(PDRIVER_OBJECT driver)
{
    UNICODE_STRING SymbolicLinkName = RTL_CONSTANT_STRING(L"\\??\\MyDDKLink");
    IoDeleteSymbolicLink(&SymbolicLinkName);
    IoDeleteDevice(driver->DeviceObject);

    DbgPrint("Driver Unload\n");
}

NTSTATUS Create(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
    DbgPrint("Create 成功\n");
    Irp->IoStatus.Status = STATUS_SUCCESS;
    Irp->IoStatus.Information = 0;
    
    IoCompleteRequest(Irp, IO_NO_INCREMENT);

    return STATUS_SUCCESS;
}
NTSTATUS Read(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
    DbgPrint("进入read\n"); 
    IoMarkIrpPending(Irp);

    InsertHeadList(&ListHead, &Irp->Tail.Overlay.ListEntry);//将Irp插入链表//
    //Irp->IoStatus.Status = STATUS_SUCCESS;
    //Irp->IoStatus.Information = 0;

    //IoCompleteRequest(Irp, IO_NO_INCREMENT);
    DbgPrint("离开读函数\n");  
    return STATUS_PENDING;;
}
NTSTATUS CleanUp(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
    DbgPrint("进入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);

        DbgPrint("完成Irp操作\n");
    }


    Irp->IoStatus.Status = STATUS_SUCCESS;
    Irp->IoStatus.Information = 0;

    IoCompleteRequest(Irp, IO_NO_INCREMENT);
    DbgPrint("离开CleanUp\n");
    return STATUS_SUCCESS;
}
NTSTATUS Close(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
    DbgPrint("进入Close\n");
    Irp->IoStatus.Status = STATUS_SUCCESS;
    Irp->IoStatus.Information = 0;

    IoCompleteRequest(Irp, IO_NO_INCREMENT);
    DbgPrint("离开Close\n");
    return STATUS_SUCCESS;
}
NTSTATUS DriverEntry(PDRIVER_OBJECT driver)
{
    UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\MyDDKName");
    UNICODE_STRING SymbolicLinkName = RTL_CONSTANT_STRING(L"\\??\\MyDDKLink");

    PDEVICE_OBJECT DeviceObject;
    DbgPrint("Driver Load\n");
    NTSTATUS status;
    status = IoCreateDevice(driver, 0, &DeviceName, FILE_DEVICE_UNKNOWN, 0, FALSE, &DeviceObject);

    if (!NT_SUCCESS(status))
    {
        DbgPrint("IoCreateDevice error\n");

        return status;
    }
    status = IoCreateSymbolicLink(&SymbolicLinkName, &DeviceName);
    if (!NT_SUCCESS(status))
    {
        DbgPrint("IoCreateSymbolicLink error\n");
        IoDeleteDevice(DeviceObject);
        return status;
    }
    InitializeListHead(&ListHead);
    driver->MajorFunction[IRP_MJ_CREATE] = Create;
    driver->MajorFunction[IRP_MJ_READ] = Read;
    driver->MajorFunction[IRP_MJ_CLEANUP] = CleanUp;
    driver->MajorFunction[IRP_MJ_CLOSE] = Close;

    DeviceObject->Flags |= DO_BUFFERED_IO;
    DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;




    driver->DriverUnload = Unload;

    return STATUS_SUCCESS;
}
 
0
在该实验中Read派遣函数的IRP被放入到链表中,同时挂起,当派遣函数CleanUp运行的时候才被重新运行
 

二、取消IRP

 
0
IoSetCancelRoutine
0
VOID
(*PDRIVER_CANCEL)(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
);
代码(这是一份错误的代码,怎么运行怎么蓝屏,我不是很理解)
0环代码
#include <ntddk.h>

LIST_ENTRY ListHead;
VOID Unload(PDRIVER_OBJECT driver)
{
    UNICODE_STRING SymbolicLinkName = RTL_CONSTANT_STRING(L"\\??\\MyDDKLink");
    IoDeleteSymbolicLink(&SymbolicLinkName);
    IoDeleteDevice(driver->DeviceObject);

    DbgPrint("Driver Unload\n");
}

NTSTATUS Create(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
    DbgPrint("Create 成功\n");
    Irp->IoStatus.Status = STATUS_SUCCESS;
    Irp->IoStatus.Information = 0;

    IoCompleteRequest(Irp, IO_NO_INCREMENT);

    return STATUS_SUCCESS;
}
VOID CancelRoutine(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
)
{
    DbgPrint("进入取消函数\n");
    Irp->IoStatus.Status = STATUS_CANCELLED;
    Irp->IoStatus.Information = 0;
    IoCompleteRequest(Irp, IO_NO_INCREMENT);

    DbgPrint("离开取消函数\n");
}

NTSTATUS Read(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
    DbgPrint("进入read\n");

    IoSetCancelRoutine(Irp, CancelRoutine);
    IoMarkIrpPending(Irp);

    
    //InsertHeadList(&ListHead, &Irp->Tail.Overlay.ListEntry);//将Irp插入链表//
    //Irp->IoStatus.Status = STATUS_SUCCESS;
    //Irp->IoStatus.Information = 0;

    //IoCompleteRequest(Irp, IO_NO_INCREMENT);
    DbgPrint("离开读函数\n");
    return STATUS_PENDING;
}
NTSTATUS CleanUp(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
    DbgPrint("进入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);

        DbgPrint("完成Irp操作\n");
    }


    Irp->IoStatus.Status = STATUS_SUCCESS;
    Irp->IoStatus.Information = 0;

    IoCompleteRequest(Irp, IO_NO_INCREMENT);
    DbgPrint("离开CleanUp\n");
    return STATUS_SUCCESS;
}
NTSTATUS Close(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
    DbgPrint("进入Close\n");
    Irp->IoStatus.Status = STATUS_SUCCESS;
    Irp->IoStatus.Information = 0;

    IoCompleteRequest(Irp, IO_NO_INCREMENT);
    DbgPrint("离开Close\n");
    return STATUS_SUCCESS;
}
NTSTATUS DriverEntry(PDRIVER_OBJECT driver)
{
    NTSTATUS status;
    UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\MyDDKName");
    UNICODE_STRING SymbolicLinkName = RTL_CONSTANT_STRING(L"\\??\\MyDDKLink");

    PDEVICE_OBJECT DeviceObject;
    DbgPrint("Driver Load\n");

    status = IoCreateDevice(driver, 0, &DeviceName, FILE_DEVICE_UNKNOWN, 0, FALSE, &DeviceObject);

    if (!NT_SUCCESS(status))
    {
        DbgPrint("IoCreateDevice error\n");

        return status;
    }
    status = IoCreateSymbolicLink(&SymbolicLinkName, &DeviceName);
    if (!NT_SUCCESS(status))
    {
        DbgPrint("IoCreateSymbolicLink error\n");
        IoDeleteDevice(DeviceObject);
        return status;
    }
    InitializeListHead(&ListHead);
    driver->MajorFunction[IRP_MJ_CREATE] = Create;
    driver->MajorFunction[IRP_MJ_READ] = Read;
    driver->MajorFunction[IRP_MJ_CLEANUP] = CleanUp;
    driver->MajorFunction[IRP_MJ_CLOSE] = Close;

    DeviceObject->Flags |= DO_BUFFERED_IO;
    DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;




    driver->DriverUnload = Unload;

    return STATUS_SUCCESS;
}
 

三、StartIo

StartIo主要任务就是将并行的Irp进行串行处理
IoStartPacket
0
 
0
 
 
DRIVER_STARTIO DriverStartio;
void DriverStartio(
[in, out] _DEVICE_OBJECT *DeviceObject,
[in, out] _IRP *Irp
)
{...}
 
 
IoStartNextPacket
0
 
取消函数会首先获取一个自旋锁,如果当前Irp不等于提供的Irp,就需要我们释放系统发取消自旋锁,参考:
0环代码
#include <ntddk.h>

LIST_ENTRY ListHead;
VOID Unload(PDRIVER_OBJECT driver)
{
    UNICODE_STRING SymbolicLinkName = RTL_CONSTANT_STRING(L"\\??\\MyDDKLink");
    IoDeleteSymbolicLink(&SymbolicLinkName);
    IoDeleteDevice(driver->DeviceObject);

    DbgPrint("Driver Unload\n");
}

NTSTATUS Create(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
    DbgPrint("Create 成功\n");
    Irp->IoStatus.Status = STATUS_SUCCESS;
    Irp->IoStatus.Information = 0;

    IoCompleteRequest(Irp, IO_NO_INCREMENT);

    return STATUS_SUCCESS;
}


void DriverStartio(
   struct _DEVICE_OBJECT *DeviceObject,
   struct _IRP *Irp
)
{
    LARGE_INTEGER timeout = RtlConvertLongToLargeInteger(-10 * 100 * 1000);
    DbgPrint("进入StartIo\n");
    KeDelayExecutionThread(KernelMode, FALSE, &timeout);
    Irp->IoStatus.Status = STATUS_SUCCESS;
    Irp->IoStatus.Information = 0;

    IoCompleteRequest(Irp, IO_NO_INCREMENT);
    IoStartNextPacket(DeviceObject, TRUE);
    DbgPrint("离开StartIo\n");
}
VOID CancelRoutine(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
)
{
    DbgPrint("进入取消函数\n");
    Irp->IoStatus.Status = STATUS_CANCELLED;
    Irp->IoStatus.Information = 0;
    IoCompleteRequest(Irp, IO_NO_INCREMENT);



    DbgPrint("离开取消函数\n");
}

NTSTATUS Read(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
    DbgPrint("进入read\n");

    //IoSetCancelRoutine(Irp, CancelRoutine);
    IoMarkIrpPending(Irp);

    IoStartPacket(DeviceObject, Irp, NULL, CancelRoutine);//将并行Irp串行处理// 将100个Irp自动插入一个链表中,串形处理//
    
    //InsertHeadList(&ListHead, &Irp->Tail.Overlay.ListEntry);//将Irp插入链表//
    //Irp->IoStatus.Status = STATUS_SUCCESS;
    //Irp->IoStatus.Information = 0;

    //IoCompleteRequest(Irp, IO_NO_INCREMENT);
    DbgPrint("离开读函数\n");
    return STATUS_PENDING;
}
NTSTATUS CleanUp(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
    DbgPrint("进入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);

        DbgPrint("完成Irp操作\n");
    }


    Irp->IoStatus.Status = STATUS_SUCCESS;
    Irp->IoStatus.Information = 0;

    IoCompleteRequest(Irp, IO_NO_INCREMENT);
    DbgPrint("离开CleanUp\n");
    return STATUS_SUCCESS;
}
NTSTATUS Close(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
    DbgPrint("进入Close\n");
    Irp->IoStatus.Status = STATUS_SUCCESS;
    Irp->IoStatus.Information = 0;

    IoCompleteRequest(Irp, IO_NO_INCREMENT);
    DbgPrint("离开Close\n");
    return STATUS_SUCCESS;
}
NTSTATUS DriverEntry(PDRIVER_OBJECT driver)
{
    NTSTATUS status;
    UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\MyDDKName");
    UNICODE_STRING SymbolicLinkName = RTL_CONSTANT_STRING(L"\\??\\MyDDKLink");

    PDEVICE_OBJECT DeviceObject;
    DbgPrint("Driver Load\n");

    status = IoCreateDevice(driver, 0, &DeviceName, FILE_DEVICE_UNKNOWN, 0, FALSE, &DeviceObject);

    if (!NT_SUCCESS(status))
    {
        DbgPrint("IoCreateDevice error\n");

        return status;
    }
    status = IoCreateSymbolicLink(&SymbolicLinkName, &DeviceName);
    if (!NT_SUCCESS(status))
    {
        DbgPrint("IoCreateSymbolicLink error\n");
        IoDeleteDevice(DeviceObject);
        return status;
    }
    InitializeListHead(&ListHead);
    driver->DriverStartIo = DriverStartio;
    driver->MajorFunction[IRP_MJ_CREATE] = Create;
    driver->MajorFunction[IRP_MJ_READ] = Read;
    driver->MajorFunction[IRP_MJ_CLEANUP] = CleanUp;
    driver->MajorFunction[IRP_MJ_CLOSE] = Close;

    DeviceObject->Flags |= DO_BUFFERED_IO;
    DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;




    driver->DriverUnload = Unload;

    return STATUS_SUCCESS;
}
3环代码
// syn_asy三环代码.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <iostream>
#include <stdio.h>
#include <Windows.h>

using namespace std;


int main()
{
    HANDLE hDevice = CreateFile(TEXT("\\\\.\\MyDDKLink"),
        GENERIC_ALL,
        FILE_SHARE_READ | FILE_SHARE_WRITE,
        NULL,
        OPEN_EXISTING,
        FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
        NULL);

    if (hDevice == INVALID_HANDLE_VALUE)
    {
        printf("打开设备失败 %d\n", GetLastError());
        return -1;
    }
    DWORD dwret;
    OVERLAPPED ol = { NULL };
    for (int i = 0; i < 100; i++) {
        ReadFile(hDevice, NULL, 0, &dwret, &ol);
    }
    CloseHandle(hDevice);//在内核会触发 MJ_cleanuP 与Close派遣函数//

    getchar();
    return 0;
}
 
0
 
 

四、自定义StartIo

迷迷糊糊的,毛啊   //代码好像写的有点问题。。。
#include <ntddk.h>

LIST_ENTRY ListHead;
KDEVICE_QUEUE DeviceQueue;
VOID Unload(PDRIVER_OBJECT driver)
{
    UNICODE_STRING SymbolicLinkName = RTL_CONSTANT_STRING(L"\\??\\MyDDKLink");
    IoDeleteSymbolicLink(&SymbolicLinkName);
    IoDeleteDevice(driver->DeviceObject);

    DbgPrint("Driver Unload\n");
}

NTSTATUS Create(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
    DbgPrint("Create 成功\n");
    Irp->IoStatus.Status = STATUS_SUCCESS;
    Irp->IoStatus.Information = 0;

    IoCompleteRequest(Irp, IO_NO_INCREMENT);

    return STATUS_SUCCESS;
}


void DriverStartio(
   struct _DEVICE_OBJECT *DeviceObject,
   struct _IRP *Irp
)
{
    LARGE_INTEGER timeout = RtlConvertLongToLargeInteger(-10 * 100 * 1000);
    if (DeviceObject->CurrentIrp != Irp) {
        IoReleaseCancelSpinLock(Irp->Cancel);
        return;
    }
    DbgPrint("进入StartIo\n");
    KeDelayExecutionThread(KernelMode, FALSE, &timeout);
    Irp->IoStatus.Status = STATUS_SUCCESS;
    Irp->IoStatus.Information = 0;

    IoCompleteRequest(Irp, IO_NO_INCREMENT);
    IoStartNextPacket(DeviceObject, TRUE);
    DbgPrint("离开StartIo\n");
}
VOID CancelRoutine(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
)
{
    DbgPrint("进入取消函数\n");
    Irp->IoStatus.Status = STATUS_CANCELLED;
    Irp->IoStatus.Information = 0;
    IoCompleteRequest(Irp, IO_NO_INCREMENT);



    DbgPrint("离开取消函数\n");
}

VOID MyStartIo(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{

    LARGE_INTEGER timeout = RtlConvertLongToLargeInteger(-10 * 3000 * 100);
    PIRP CurrentIrp = Irp;
    PKDEVICE_QUEUE_ENTRY QueueEntry = NULL;
    DbgPrint("进入MyStartIo\n");

    while (TRUE)
    {
        CurrentIrp->IoStatus.Status = STATUS_SUCCESS;
        CurrentIrp->IoStatus.Information = 0;
        IoCompleteRequest(CurrentIrp, IO_NO_INCREMENT);

        QueueEntry = KeRemoveDeviceQueue(&DeviceQueue);

        if (QueueEntry == NULL)
        {
            break;
        }
        CurrentIrp = CONTAINING_RECORD(QueueEntry, IRP, Tail.Overlay.DeviceQueueEntry);
        KeDelayExecutionThread(KernelMode, FALSE, &timeout);
    }

    DbgPrint("离开MyStartIo\n");
}
NTSTATUS Read(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
    DbgPrint("进入read\n");

    //IoSetCancelRoutine(Irp, CancelRoutine);
    IoMarkIrpPending(Irp);


    if (!KeInsertDeviceQueue(&DeviceQueue, &Irp->Tail.Overlay.DeviceQueueEntry))
    {
        MyStartIo(DeviceObject,Irp);
    }

    //IoStartPacket(DeviceObject, Irp, NULL, CancelRoutine);//将并行Irp串行处理// 将100个Irp自动插入一个链表中,串形处理//
    
    //InsertHeadList(&ListHead, &Irp->Tail.Overlay.ListEntry);//将Irp插入链表//
    //Irp->IoStatus.Status = STATUS_SUCCESS;
    //Irp->IoStatus.Information = 0;

    //IoCompleteRequest(Irp, IO_NO_INCREMENT);
    DbgPrint("离开读函数\n");
    return STATUS_PENDING;
}
NTSTATUS CleanUp(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
    DbgPrint("进入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);

        DbgPrint("完成Irp操作\n");
    }


    Irp->IoStatus.Status = STATUS_SUCCESS;
    Irp->IoStatus.Information = 0;

    IoCompleteRequest(Irp, IO_NO_INCREMENT);
    DbgPrint("离开CleanUp\n");
    return STATUS_SUCCESS;
}
NTSTATUS Close(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
    DbgPrint("进入Close\n");
    Irp->IoStatus.Status = STATUS_SUCCESS;
    Irp->IoStatus.Information = 0;

    IoCompleteRequest(Irp, IO_NO_INCREMENT);
    DbgPrint("离开Close\n");
    return STATUS_SUCCESS;
}
NTSTATUS DriverEntry(PDRIVER_OBJECT driver)
{
    NTSTATUS status;
    UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\MyDDKName");
    UNICODE_STRING SymbolicLinkName = RTL_CONSTANT_STRING(L"\\??\\MyDDKLink");

    PDEVICE_OBJECT DeviceObject;
    DbgPrint("Driver Load\n");

    status = IoCreateDevice(driver, 0, &DeviceName, FILE_DEVICE_UNKNOWN, 0, FALSE, &DeviceObject);

    if (!NT_SUCCESS(status))
    {
        DbgPrint("IoCreateDevice error\n");

        return status;
    }
    status = IoCreateSymbolicLink(&SymbolicLinkName, &DeviceName);
    if (!NT_SUCCESS(status))
    {
        DbgPrint("IoCreateSymbolicLink error\n");
        IoDeleteDevice(DeviceObject);
        return status;
    }
    InitializeListHead(&ListHead);
    KeInitializeDeviceQueue(&DeviceQueue);

    driver->DriverStartIo = DriverStartio;
    driver->MajorFunction[IRP_MJ_CREATE] = Create;
    driver->MajorFunction[IRP_MJ_READ] = Read;
    driver->MajorFunction[IRP_MJ_CLEANUP] = CleanUp;
    driver->MajorFunction[IRP_MJ_CLOSE] = Close;

    DeviceObject->Flags |= DO_BUFFERED_IO;
    DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;




    driver->DriverUnload = Unload;

    return STATUS_SUCCESS;
}

 

// syn_asy三环代码.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <iostream>
#include <stdio.h>
#include <Windows.h>

using namespace std;
DWORD WINAPI ThreadProc(PVOID Context)
{
    DWORD dwRet;
    HANDLE hDevice = *(PHANDLE)Context;
    OVERLAPPED ol = { NULL };
    ol.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);

    ReadFile(hDevice, NULL, 0, &dwRet, &ol);
    //Sleep(3000);
    //SetEvent(ol.hEvent);
    WaitForSingleObject(hDevice, INFINITE);
    printf("完成!!!\n");
    return 0;
}

int main()
{
    HANDLE hDevice = CreateFile(TEXT("\\\\.\\MyDDKLink"),
        GENERIC_ALL,
        FILE_SHARE_READ | FILE_SHARE_WRITE,
        NULL,
        OPEN_EXISTING,
        FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
        NULL);

    if (hDevice == INVALID_HANDLE_VALUE)
    {
        printf("打开设备失败 %d\n", GetLastError());
        return -1;
    }

   
    for (int i = 0; i < 100; i++)
    {
        CreateThread(NULL, 0, ThreadProc, &hDevice, 0, NULL);
    }
    while (true)
    {
        Sleep(2000);
    }
    CloseHandle(hDevice);//在内核会触发 MJ_cleanuP 与Close派遣函数//

    getchar();
    return 0;
}

 

posted @ 2022-04-12 16:43  TLSN  阅读(253)  评论(0编辑  收藏  举报