• windows 驱动与内核调试 学习2


    前言

    我们知道我们驱动存在的意义往往是用于驱动硬件,而一个硬件读写大多数操作系统都是为文件io。既然是文件那么必然涉及到文件打开,读写等。我们看看在内核驱动该如何实现这些逻辑操作。

    
    //驱动被加载的时候会调用此函数
    NTSTATUS
    DriverEntry(
    	_In_ struct _DRIVER_OBJECT* DriverObject,
    	_In_ PUNICODE_STRING    RegistryPath
    )
    {
    	//如果你没有用到参数需要告诉系统。
    	UNREFERENCED_PARAMETER(RegistryPath);
    	//打印信息
    	DbgPrint("hello  drive loaded");
    	//触发一个断点
    	//DbgBreakPoint();
    	//驱动卸载回调注册
    	DriverObject->DriverUnload = myUnload;
    
    
    	//设置一个驱动映射的文件名称,RtlInitUnicodeString是一个便捷创建内核UNICODE_STRING函数
    	UNICODE_STRING ustrDevName;
    	//使用工具函数创建一个名叫MytestDriver驱动文件
    	RtlInitUnicodeString(&ustrDevName, L"\\Device\\MytestDriver");
    	//用于保存创建结果
    	PDEVICE_OBJECT  pDevObj = NULL;
    	
    	//IoCreateDevice用于创建一个DEVICE_OBJECT对象
    	auto ret = IoCreateDevice(DriverObject, 0, &ustrDevName, FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN, FALSE, &pDevObj);
    
    
    	if (NT_SUCCESS(ret))
    	{
    	//
    		DbgPrint("IoCreateDevice 成功 %p\r\n", ret);
    	}
    	else {
    		DbgPrint("IoCreateDevice 失败\r\n");
    		return STATUS_FAIL_CHECK;
    	}
    
    	//这里便是注册驱动文件读写相关回调
    	//注册一个创建文件回调
    	DriverObject->MajorFunction[IRP_MJ_CREATE] = DispatchCreate;
    	//注册文件关闭
    	DriverObject->MajorFunction[IRP_MJ_CLOSE] = DispatchClose;
    	//读取
    	DriverObject->MajorFunction[IRP_MJ_READ] = DispatchRead;
    	//写入
    	DriverObject->MajorFunction[IRP_MJ_WRITE] = DispatchWrite;
    	//控制相关 其实也可以使用写入代替 但是为了职责分明额外多一个回调
    	DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchControl;
    
    	return STATUS_SUCCESS;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53

    当函数卸载的时候一定要记得删除驱动文件哦

    //这个函数被注册用于驱动卸载调用
    VOID myUnload(
    	struct _DRIVER_OBJECT* DriverObject
    ) {
    	UNREFERENCED_PARAMETER(DriverObject);
    
    	DbgPrint("hello  drive unloaded");
    
    	PDEVICE_OBJECT DeviceObject = DriverObject->DeviceObject;
    
    	if (DriverObject->DeviceObject !=NULL)
    	{
    		DbgPrint("驱动文件不为空执行删除");
    		IoDeleteDevice(DeviceObject);
    	}
    }
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    我们贴出完成相关代码

    
    #include 
    
    //这个函数被注册用于驱动卸载调用
    VOID myUnload(
    	struct _DRIVER_OBJECT* DriverObject
    ) {
    	UNREFERENCED_PARAMETER(DriverObject);
    
    	DbgPrint("hello  drive unloaded");
    
    	PDEVICE_OBJECT DeviceObject = DriverObject->DeviceObject;
    
    	if (DriverObject->DeviceObject !=NULL)
    	{
    		DbgPrint("驱动文件不为空执行删除");
    		IoDeleteDevice(DeviceObject);
    	}
    }
    
    
    
    NTSTATUS
    DispatchCreate(
    	_In_ struct _DEVICE_OBJECT* DeviceObject,
    	_Inout_ struct _IRP* Irp
    ) {
    	UNREFERENCED_PARAMETER(Irp);
    	UNREFERENCED_PARAMETER(DeviceObject);
    	return STATUS_SUCCESS;
    }
    NTSTATUS
    DispatchClose(
    	_In_ struct _DEVICE_OBJECT* DeviceObject,
    	_Inout_ struct _IRP* Irp
    ) {
    	UNREFERENCED_PARAMETER(Irp);
    	UNREFERENCED_PARAMETER(DeviceObject);
    	return STATUS_SUCCESS;
    }
    
    NTSTATUS
    DispatchRead(
    	_In_ struct _DEVICE_OBJECT* DeviceObject,
    	_Inout_ struct _IRP* Irp
    ) {
    	UNREFERENCED_PARAMETER(Irp);
    	UNREFERENCED_PARAMETER(DeviceObject);
    	return STATUS_SUCCESS;
    }
    NTSTATUS
    DispatchWrite(
    	_In_ struct _DEVICE_OBJECT* DeviceObject,
    	_Inout_ struct _IRP* Irp
    ) {
    	UNREFERENCED_PARAMETER(Irp);
    	UNREFERENCED_PARAMETER(DeviceObject);
    	return STATUS_SUCCESS;
    }
    
    NTSTATUS
    DispatchControl(
    	_In_ struct _DEVICE_OBJECT* DeviceObject,
    	_Inout_ struct _IRP* Irp
    ) {
    	UNREFERENCED_PARAMETER(Irp);
    	UNREFERENCED_PARAMETER(DeviceObject);
    	return STATUS_SUCCESS;
    }
    
    
    //驱动被加载的时候会调用此函数
    NTSTATUS
    DriverEntry(
    	_In_ struct _DRIVER_OBJECT* DriverObject,
    	_In_ PUNICODE_STRING    RegistryPath
    )
    {
    	//如果你没有用到参数需要告诉系统。
    	UNREFERENCED_PARAMETER(RegistryPath);
    	//打印信息
    	DbgPrint("hello  drive loaded");
    	//触发一个断点
    	//DbgBreakPoint();
    	//驱动卸载回调注册
    	DriverObject->DriverUnload = myUnload;
    
    
    	DriverObject->MajorFunction[IRP_MJ_CREATE] = DispatchCreate;
    	DriverObject->MajorFunction[IRP_MJ_CLOSE] = DispatchClose;
    	DriverObject->MajorFunction[IRP_MJ_READ] = DispatchRead;
    	DriverObject->MajorFunction[IRP_MJ_WRITE] = DispatchWrite;
    	DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchControl;
    
    
    	UNICODE_STRING ustrDevName;
    	RtlInitUnicodeString(&ustrDevName, L"\\Device\\MytestDriver");
    	PDEVICE_OBJECT  pDevObj = NULL;
    	auto ret = IoCreateDevice(DriverObject, 0, &ustrDevName, FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN, FALSE, &pDevObj);
    
    
    	if (NT_SUCCESS(ret))
    	{
    		DbgPrint("IoCreateDevice 成功 %p\r\n", ret);
    	}
    	else {
    		DbgPrint("IoCreateDevice 失败\r\n");
    		return STATUS_FAIL_CHECK;
    	}
    
    
    	return STATUS_SUCCESS;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113

    我们利用工具将驱动文件进行加载
    在这里插入图片描述
    然后我们在利用winobj查看我们注册驱动文件

    在这里插入图片描述
    我们最后执行卸载操作。
    在这里插入图片描述
    上面的注册驱动文件不能在ring3 进行文件读写,如果你期望ring3也可以驱动需要额外注册一个另一个映射名(符号链接 )
    相关代码如下

    	UNICODE_STRING symbolDevName;
    	RtlInitUnicodeString(&symbolDevName, L"\\DosDevices\\MytestDriver");
    	ret = IoCreateSymbolicLink(&symbolDevName, &ustrDevName);
    	if (NT_SUCCESS(ret))
    	{
    		DbgPrint("IoCreateSymbolicLink 成功 \r\n");
    	}
    	else {
    		DbgPrint("IoCreateSymbolicLink 失败%d\r\n", ret);
    
    		IoDeleteDevice(pDevObj);
    
    		return STATUS_FAIL_CHECK;
    	}
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    同样我们加载驱动
    在这里插入图片描述

    在这里插入图片描述
    再卸载的时候同样记得要删除。

    #include 
    
    
    
    //这个函数被注册用于驱动卸载调用
    VOID myUnload(
    	struct _DRIVER_OBJECT* DriverObject
    ) {
    	UNREFERENCED_PARAMETER(DriverObject);
    
    	DbgPrint("hello  drive unloaded");
    
    	PDEVICE_OBJECT DeviceObject = DriverObject->DeviceObject;
    
    	if (DriverObject->DeviceObject != NULL)
    	{
    		DbgPrint("驱动文件不为空执行删除");
    		IoDeleteDevice(DeviceObject);
    
    
    		UNICODE_STRING symbolDevName;
    		RtlInitUnicodeString(&symbolDevName, L"\\DosDevices\\MytestDriver");
    		IoDeleteSymbolicLink(&symbolDevName);
    	}
    }
    
    
    
    //驱动被加载的时候会调用此函数
    NTSTATUS
    DriverEntry(
    	_In_ struct _DRIVER_OBJECT* DriverObject,
    	_In_ PUNICODE_STRING    RegistryPath
    )
    {
    	//如果你没有用到参数需要告诉系统。
    	UNREFERENCED_PARAMETER(RegistryPath);
    	//打印信息
    	DbgPrint("hello  drive loaded");
    	//触发一个断点
    	//DbgBreakPoint();
    	//驱动卸载回调注册
    	DriverObject->DriverUnload = myUnload;
    
    
    	DriverObject->MajorFunction[IRP_MJ_CREATE] = DispatchCreate;
    	DriverObject->MajorFunction[IRP_MJ_CLOSE] = DispatchClose;
    	DriverObject->MajorFunction[IRP_MJ_READ] = DispatchRead;
    	DriverObject->MajorFunction[IRP_MJ_WRITE] = DispatchWrite;
    	DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchControl;
    
    
    	UNICODE_STRING ustrDevName;
    	RtlInitUnicodeString(&ustrDevName, L"\\Device\\MytestDriver");
    	PDEVICE_OBJECT  pDevObj = NULL;
    	auto ret = IoCreateDevice(DriverObject, 0, &ustrDevName, FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN, FALSE, &pDevObj);
    
    
    
    
    	if (NT_SUCCESS(ret))
    	{
    		DbgPrint("IoCreateDevice 成功 \r\n");
    	}
    	else {
    		DbgPrint("IoCreateDevice 失败 %d\r\n", ret);
    		return STATUS_FAIL_CHECK;
    	}
    
    
    	UNICODE_STRING symbolDevName;
    	RtlInitUnicodeString(&symbolDevName, L"\\DosDevices\\MytestDriver");
    	ret = IoCreateSymbolicLink(&symbolDevName, &ustrDevName);
    	if (NT_SUCCESS(ret))
    	{
    		DbgPrint("IoCreateSymbolicLink 成功 \r\n");
    	}
    	else {
    		DbgPrint("IoCreateSymbolicLink 失败%d\r\n", ret);
    
    		IoDeleteDevice(pDevObj);
    
    		return STATUS_FAIL_CHECK;
    	}
    
    	return STATUS_SUCCESS;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87

    微软IRP设计

    以下来自微软官方的一个设计架构图
    在这里插入图片描述
    具体可参阅
    (2) End-User I/O Requests and File Objects

    微软使用IRP设计用于应用层和驱动层传递数据,并且驱动可以进行继续分层处理(比如文件系统驱动 可能有多个驱动 1级驱动提供读写 2级别提供特定大小的缓存功能的读写)。

    我们现在完善上文驱动读写操作

    NTSTATUS
    DispatchRead(
    	_In_ struct _DEVICE_OBJECT* DeviceObject,
    	_Inout_ struct _IRP* Irp
    ) {
    	DbgPrint("DispatchRead");
    
    	UNREFERENCED_PARAMETER(DeviceObject);
    
    	//因为分层驱动的设计,所以需要从Irp获取当前层级的参数
    	PIO_STACK_LOCATION	pIrp = IoGetCurrentIrpStackLocation(Irp);
    	//上册指定缓存区长度
    	ULONG nLength = pIrp->Parameters.Read.Length;
    
    	DbgPrint("DispatchRead buffer:%s bytes:%d", Irp->UserBuffer, nLength);
    	//拷贝缓冲区
    	memcpy(Irp->UserBuffer,"helloread",10);
    	
    	//通知上册成功写入
    	Irp->IoStatus.Status = STATUS_SUCCESS;
    	//通知上层写入的大小
    	Irp->IoStatus.Information = 10;
    	//回调给io处理器完成请求
    	IoCompleteRequest(Irp, IO_NO_INCREMENT);
    
    
    	return STATUS_SUCCESS;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    其他读写操作类似就不再举例

    #include 
    
    
    
    //这个函数被注册用于驱动卸载调用
    VOID myUnload(
    	struct _DRIVER_OBJECT* DriverObject
    ) {
    	UNREFERENCED_PARAMETER(DriverObject);
    
    	DbgPrint("hello  drive unloaded");
    
    	PDEVICE_OBJECT DeviceObject = DriverObject->DeviceObject;
    
    	if (DriverObject->DeviceObject != NULL)
    	{
    		DbgPrint("驱动文件不为空执行删除");
    		IoDeleteDevice(DeviceObject);
    
    
    		UNICODE_STRING symbolDevName;
    		RtlInitUnicodeString(&symbolDevName, L"\\DosDevices\\MytestDriver");
    		IoDeleteSymbolicLink(&symbolDevName);
    	}
    }
    
    
    
    NTSTATUS
    DispatchCreate(
    	_In_ struct _DEVICE_OBJECT* DeviceObject,
    	_Inout_ struct _IRP* Irp
    ) {
    	UNREFERENCED_PARAMETER(Irp);
    	UNREFERENCED_PARAMETER(DeviceObject);
    	DbgPrint("DispatchCreate");
    
    	return STATUS_SUCCESS;
    }
    NTSTATUS
    DispatchClose(
    	_In_ struct _DEVICE_OBJECT* DeviceObject,
    	_Inout_ struct _IRP* Irp
    ) {
    	DbgPrint("DispatchClose");
    
    	UNREFERENCED_PARAMETER(Irp);
    	UNREFERENCED_PARAMETER(DeviceObject);
    	return STATUS_SUCCESS;
    }
    
    NTSTATUS
    DispatchRead(
    	_In_ struct _DEVICE_OBJECT* DeviceObject,
    	_Inout_ struct _IRP* Irp
    ) {
    	DbgPrint("DispatchRead");
    
    	UNREFERENCED_PARAMETER(DeviceObject);
    
    
    	PIO_STACK_LOCATION	pIrp = IoGetCurrentIrpStackLocation(Irp);
    	ULONG nLength = pIrp->Parameters.Read.Length;
    
    	DbgPrint("DispatchRead buffer:%s bytes:%d", Irp->UserBuffer, nLength);
    	memcpy(Irp->UserBuffer,"helloread",10);
    
    	Irp->IoStatus.Status = STATUS_SUCCESS;
    	Irp->IoStatus.Information = 10;
    	IoCompleteRequest(Irp, IO_NO_INCREMENT);
    
    
    	return STATUS_SUCCESS;
    }
    NTSTATUS
    DispatchWrite(
    	_In_ struct _DEVICE_OBJECT* DeviceObject,
    	_Inout_ struct _IRP* Irp
    ) {
    	DbgPrint("DispatchWrite");
    	UNREFERENCED_PARAMETER(DeviceObject);
    
    
    	PIO_STACK_LOCATION	pIrp = IoGetCurrentIrpStackLocation(Irp);
    	ULONG nLength = pIrp->Parameters.Write.Length;
    
    	DbgPrint("DispatchWrite buffer:%s bytes:%d", Irp->UserBuffer, nLength);
    
    	Irp->IoStatus.Status = STATUS_SUCCESS;
    	Irp->IoStatus.Information = 6;
    	IoCompleteRequest(Irp, IO_NO_INCREMENT);
    
    	return STATUS_SUCCESS;
    }
    
    NTSTATUS
    DispatchControl(
    	_In_ struct _DEVICE_OBJECT* DeviceObject,
    	_Inout_ struct _IRP* Irp
    ) {
    	DbgPrint("DispatchControl");
    
    	UNREFERENCED_PARAMETER(Irp);
    	UNREFERENCED_PARAMETER(DeviceObject);
    	return STATUS_SUCCESS;
    }
    
    
    //驱动被加载的时候会调用此函数
    NTSTATUS
    DriverEntry(
    	_In_ struct _DRIVER_OBJECT* DriverObject,
    	_In_ PUNICODE_STRING    RegistryPath
    )
    {
    	//如果你没有用到参数需要告诉系统。
    	UNREFERENCED_PARAMETER(RegistryPath);
    	//打印信息
    	DbgPrint("hello  drive loaded");
    	//触发一个断点
    	//DbgBreakPoint();
    	//驱动卸载回调注册
    	DriverObject->DriverUnload = myUnload;
    
    
    	DriverObject->MajorFunction[IRP_MJ_CREATE] = DispatchCreate;
    	DriverObject->MajorFunction[IRP_MJ_CLOSE] = DispatchClose;
    	DriverObject->MajorFunction[IRP_MJ_READ] = DispatchRead;
    	DriverObject->MajorFunction[IRP_MJ_WRITE] = DispatchWrite;
    	DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchControl;
    
    
    	UNICODE_STRING ustrDevName;
    	RtlInitUnicodeString(&ustrDevName, L"\\Device\\MytestDriver");
    	PDEVICE_OBJECT  pDevObj = NULL;
    	auto ret = IoCreateDevice(DriverObject, 0, &ustrDevName, FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN, FALSE, &pDevObj);
    
    
    
    
    	if (NT_SUCCESS(ret))
    	{
    		DbgPrint("IoCreateDevice 成功 \r\n");
    	}
    	else {
    		DbgPrint("IoCreateDevice 失败 %d\r\n", ret);
    		return STATUS_FAIL_CHECK;
    	}
    
    
    	UNICODE_STRING symbolDevName;
    	RtlInitUnicodeString(&symbolDevName, L"\\DosDevices\\MytestDriver");
    	ret = IoCreateSymbolicLink(&symbolDevName, &ustrDevName);
    	if (NT_SUCCESS(ret))
    	{
    		DbgPrint("IoCreateSymbolicLink 成功 \r\n");
    	}
    	else {
    		DbgPrint("IoCreateSymbolicLink 失败%d\r\n", ret);
    
    		IoDeleteDevice(pDevObj);
    
    		return STATUS_FAIL_CHECK;
    	}
    
    	return STATUS_SUCCESS;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167

    最后写一个应用层代码进行读写

    // InvotationDevApp.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
    //
    
    #include 
    #include
    #include
    int main()
    {
    	std::cout << "Hello World!\n";
    
    
    	HANDLE hFile;
    	hFile = CreateFile("\\\\\?\\MytestDriver",
    		GENERIC_WRITE | GENERIC_READ,
    		0,
    		NULL,
    		OPEN_EXISTING,
    		FILE_ATTRIBUTE_NORMAL,
    		NULL
    	);
    	if (hFile == INVALID_HANDLE_VALUE)
    	{
    		std::cout << "INVALID_HANDLE_VALUE  "<< GetLastError()<<"\n";
    
    		return EXIT_FAILURE;
    	}
    
    	std::cout << "open ok\n";
    	DWORD dwBytes = 0;
    	if (WriteFile(hFile, "hello", 6, &dwBytes, NULL))
    	{
    		std::cout << "write ok " << dwBytes << std::endl;
    	}
    	else {
    		std::cout << "write failure " << dwBytes << std::endl;
    	}
    
    	DWORD drBytes = 0;
    	char szBuffer[120];
    	if (ReadFile(hFile, szBuffer, sizeof szBuffer, &drBytes, NULL))
    	{
    		std::cout << "read ok  " << drBytes << " "<< szBuffer << std::endl;
    	}
    	else {
    		std::cout << "read failure " << std::endl;
    	}
    
    
    	CloseHandle(hFile);
    	system("pause");
    	return EXIT_SUCCESS;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53

    在这里插入图片描述

    reference

    (1) a simple demo for WDM driver

    (2) End-User I/O Requests and File Objects

  • 相关阅读:
    A Survey on Explainable Artificial Intelligence (XAI): Toward Medical XAI学习笔记
    华为云云耀云服务器L实例评测|部署个人在线电子书库 calibre
    小程序微信支付API?小程序获取手机号?
    Could the Earth be swallowed by a black hole?
    一面锦旗一个故事——百华真情暖人心,职工感恩送锦旗
    Nginx学习与实战 · 解决net::ERR_CONTENT_LENGTH_MISMATCH 206问题
    线性回归详解
    图解Java对象在Heap内存中的分配过程
    Git详解(持续更新)
    io流简单介绍
  • 原文地址:https://blog.csdn.net/qfanmingyiq/article/details/127586460