首页 > WinDriver > WD-驱动之间交互(read IRP传递示例)
2013十二月13

WD-驱动之间交互(read IRP传递示例)

随手示例,驱动A与B之间的readfile 传递

注意点:

1.A中必须实现IRP_MJ_CREATE返回SUCCESS,不然CreateFile会失败的,返回错误1

2.IRP_MJ_READ在A中再IoCallDriver传到B,要注意,必须使用A的IO堆栈(IO_STACK_LOCATION),因为它里面包含了IRP_MJ_READ这些信息,驱动是靠它来分发到B的Read处理函数的,所以可以使用IoCopyCurrentIrpStackLocationToNext或IoSkipCurrentIrpStackLocation,不然 就不知道分发到哪去了

3.IoGetDeviceObjectPointer可以直接通过设备名获得驱动句柄,这比较给力!

代码如下:

test:

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
int main()
{
	HANDLE hDevice =
		CreateFile("\\.\DDKTestDevice",
		GENERIC_READ ¦ GENERIC_WRITE,
		0,		// share mode none
		NULL,	// no security
		OPEN_EXISTING,
		FILE_ATTRIBUTE_NORMAL,
		NULL );		// no template
 
	if (INVALID_HANDLE_VALUE == hDevice)
	{
		printf("Fail to open device with err:%dn", GetLastError());
		getchar();
		return 1;
	}
 
	UCHAR buffer[10] = {0};
	ULONG ulRead = 0;
	ReadFile(hDevice, buffer, 10, &ulRead, 0);
 
	printf("start...n");
	CloseHandle(hDevice);
	printf("end...n");
 
	getchar();
	return 0;
}

A:

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
#include "Driver.h"
 
 
extern "C" NTSTATUS DriverEntry(
								PDRIVER_OBJECT pDriverObject,
								PUNICODE_STRING pRegistryPath)
{
	NTSTATUS ntstatus = STATUS_SUCCESS;
 
	pDriverObject->DriverUnload = DDKTestUnload;
	pDriverObject->MajorFunction[IRP_MJ_READ] = DDKTestRead;
	pDriverObject->MajorFunction[IRP_MJ_CREATE] = DDKTestCreate;
 
	UNICODE_STRING DeviceName;
	RtlInitUnicodeString(&DeviceName, L"\Device\MyDDKDeviceA");
 
	PDEVICE_OBJECT DeviceObject = NULL;
	PFILE_OBJECT FileObject = NULL;
 
	ntstatus = IoGetDeviceObjectPointer(&DeviceName, FILE_ALL_ACCESS,
		&FileObject, &DeviceObject);
	if (!NT_SUCCESS(ntstatus))
	{
		KdPrint(("IoGetDeviceObjectPointer err:0x%08xn", ntstatus));
		return ntstatus;
	}
 
	// 创建驱动设备对象
	ntstatus = CreateDevice(pDriverObject);
	if (!NT_SUCCESS(ntstatus))
	{
		// 将引用计数减一
		ObDereferenceObject(FileObject);
		KdPrint(("CreateDevice err:0x%08xn", ntstatus));
		return ntstatus;
	}
 
	PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION)pDriverObject->DeviceObject->DeviceExtension;
 
	//得到当前创建的驱动
	PDEVICE_OBJECT FilterDeviceObject = pdx->pDevice;
 
	// 挂接
	PDEVICE_OBJECT TargetDevice = IoAttachDeviceToDeviceStack(FilterDeviceObject, DeviceObject);
 
	// 记录下一层驱动
	pdx->TargetDevice = TargetDevice;
	if (!TargetDevice)
	{
		// 引用计数减1
		ObDereferenceObject(FileObject);
 
		// 删除当前设备对象
		IoDeleteDevice(FilterDeviceObject);
 
		return STATUS_INSUFFICIENT_RESOURCES;
 
	}
 
	// 设置设备类型
	FilterDeviceObject->DeviceType = TargetDevice->DeviceType;
 
	// 设置设备对象标记
	FilterDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
	FilterDeviceObject->Flags ¦= ( TargetDevice->Flags & ( DO_DIRECT_IO ¦
		DO_BUFFERED_IO));
 
	// 引用计数减1
	ObDereferenceObject( FileObject );
 
	return ntstatus;
 
};
 
NTSTATUS DDKTestCreate(IN PDEVICE_OBJECT pDevObj,
						IN PIRP pIrp)
{
	KdPrint(("DriverB:Enter B HelloDDKCreaten"));
	NTSTATUS ntStatus = STATUS_SUCCESS;
 
	// 完成IRP
	pIrp->IoStatus.Status = ntStatus;
	pIrp->IoStatus.Information = 0;	// bytes xfered
	IoCompleteRequest( pIrp, IO_NO_INCREMENT );
 
	return ntStatus;
}
 
NTSTATUS CreateDevice (IN PDRIVER_OBJECT pDriverObject)
{
 
	NTSTATUS ntstatus = STATUS_SUCCESS;
 
	// 创建设备名称
	UNICODE_STRING devName;
	RtlInitUnicodeString(&devName, L"\Device\DDKTestDevice");
 
	// 创建设备
	PDEVICE_OBJECT pDevObj;
	ntstatus = IoCreateDevice(pDriverObject,
		sizeof(DEVICE_EXTENSION),
		&devName,
		FILE_DEVICE_UNKNOWN,
		0, TRUE,
		&pDevObj);
	if (!NT_SUCCESS(ntstatus))
	{
		KdPrint(("err:0x%8xn", ntstatus));
		return ntstatus;
	}
 
	pDevObj->Flags ¦= DO_DIRECT_IO;
	PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)pDevObj->DeviceExtension;
	pDevExt->pDevice = pDevObj;
 
 
	//创建符号链接
	UNICODE_STRING symLinkName;
	RtlInitUnicodeString(&symLinkName,L"\??\DDKTestDevice");
	pDevExt->ustrSymLinkName = symLinkName;
	ntstatus = IoCreateSymbolicLink( &symLinkName,&devName );
	if (!NT_SUCCESS(ntstatus))
	{
		IoDeleteDevice(pDevObj);
		return ntstatus;
	}
 
	return ntstatus;
}
 
NTSTATUS DDKTestRead(IN PDEVICE_OBJECT pDevObj,
					  IN PIRP pIrp)
{
	NTSTATUS ntstatus = STATUS_SUCCESS;
 
	PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION)pDevObj->DeviceExtension;
 
	IoCopyCurrentIrpStackLocationToNext(pIrp);
	ntstatus = IoCallDriver(pdx->TargetDevice, pIrp);
	return ntstatus;
}
 
 
VOID DDKTestUnload (IN PDRIVER_OBJECT pDriverObject)
{
	KdPrint(("[DDKTestUnload] startn"));
 
	PDEVICE_OBJECT pNextObj = pDriverObject->DeviceObject;
	while (NULL != pNextObj)
	{
		PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)pNextObj->DeviceExtension;
		pNextObj = pNextObj->NextDevice;
 
		// 从设备栈中弹出
		IoDetachDevice(pDevExt->TargetDevice);
 
		// 删除符号链接
		UNICODE_STRING pLinkName = pDevExt->ustrSymLinkName;
		IoDeleteSymbolicLink(&pLinkName);
 
		// 删除该设备对象
		IoDeleteDevice(pDevExt->pDevice);
	}
 
	KdPrint(("[DDKTestUnload] endn"));
}

B:

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
#include "Driver.h"
 
#pragma INITCODE
extern "C" NTSTATUS DriverEntry (
			IN PDRIVER_OBJECT pDriverObject,
			IN PUNICODE_STRING pRegistryPath	)
{
	NTSTATUS status;
	KdPrint(("DriverA:Enter A DriverEntryn"));
 
	//注册其他驱动调用函数入口
	pDriverObject->DriverUnload = HelloDDKUnload;
	pDriverObject->MajorFunction[IRP_MJ_CREATE] = HelloDDKCreate;
	pDriverObject->MajorFunction[IRP_MJ_CLOSE] = HelloDDKClose;
	pDriverObject->MajorFunction[IRP_MJ_WRITE] = HelloDDKDispatchRoutine;
	pDriverObject->MajorFunction[IRP_MJ_READ] = HelloDDKRead;
 
	//创建驱动设备对象
	status = CreateDevice(pDriverObject);
 
	KdPrint(("DriverA:Leave A DriverEntryn"));
	return status;
}
 
NTSTATUS CreateDevice (
		IN PDRIVER_OBJECT	pDriverObject)
{
	NTSTATUS status;
	PDEVICE_OBJECT pDevObj;
	PDEVICE_EXTENSION pDevExt;
 
	//创建设备名称
	UNICODE_STRING devName;
	RtlInitUnicodeString(&devName,L"\Device\MyDDKDeviceA");
 
	//创建设备
	status = IoCreateDevice( pDriverObject,
						sizeof(DEVICE_EXTENSION),
						&(UNICODE_STRING)devName,
						FILE_DEVICE_UNKNOWN,
						0, TRUE,
						&pDevObj );
	if (!NT_SUCCESS(status))
		return status;
 
	pDevObj->Flags ¦= DO_DIRECT_IO;
	pDevExt = (PDEVICE_EXTENSION)pDevObj->DeviceExtension;
	pDevExt->pDevice = pDevObj;
	pDevExt->ustrDeviceName = devName;
 
	//创建符号链接
	UNICODE_STRING symLinkName;
	RtlInitUnicodeString(&symLinkName,L"\??\HelloDDKA");
	pDevExt->ustrSymLinkName = symLinkName;
	status = IoCreateSymbolicLink( &symLinkName,&devName );
	if (!NT_SUCCESS(status))
	{
		IoDeleteDevice( pDevObj );
		return status;
	}
	return STATUS_SUCCESS;
}
 
#pragma PAGEDCODE
VOID HelloDDKUnload (IN PDRIVER_OBJECT pDriverObject)
{
	PDEVICE_OBJECT	pNextObj;
	KdPrint(("DriverA:Enter A DriverUnloadn"));
	pNextObj = pDriverObject->DeviceObject;
	while (pNextObj != NULL)
	{
		PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)
			pNextObj->DeviceExtension;
 
		//删除符号链接
		UNICODE_STRING pLinkName = pDevExt->ustrSymLinkName;
		IoDeleteSymbolicLink(&pLinkName);
		pNextObj = pNextObj->NextDevice;
		IoDeleteDevice( pDevExt->pDevice );
	}
	KdPrint(("DriverA:Leave A DriverUnloadn"));
}
 
#pragma PAGEDCODE
NTSTATUS HelloDDKRead(IN PDEVICE_OBJECT pDevObj,
								 IN PIRP pIrp)
{
	KdPrint(("DriverA:Enter A HelloDDKReadn"));
	NTSTATUS status = STATUS_SUCCESS;
 
	PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(pIrp);
 
	ULONG totalLength;
	PVOID virtualAddress;
	if (!pIrp->MdlAddress)
	{
		status = STATUS_UNSUCCESSFUL;
		totalLength = 0;
		goto HelloDDKRead_EXIT;
	}
 
	virtualAddress = MmGetMdlVirtualAddress(pIrp->MdlAddress);
	totalLength = MmGetMdlByteCount(pIrp->MdlAddress);
 
	RtlFillMemory(virtualAddress,totalLength,0xFF);
 
	KdPrint(("DriverA:virtualAddress:%xn",virtualAddress));
	KdPrint(("DriverA:totalLength:%dn",totalLength));
 
HelloDDKRead_EXIT:
	// 完成IRP
	pIrp->IoStatus.Status = status;
	pIrp->IoStatus.Information = totalLength;	//bytes xfered
	IoCompleteRequest( pIrp, IO_NO_INCREMENT );
	KdPrint(("DriverA:Leave A HelloDDKReadn"));
	return status;
}
 
NTSTATUS HelloDDKDispatchRoutine(IN PDEVICE_OBJECT pDevObj,
								 IN PIRP pIrp)
{
	KdPrint(("DriverA:Enter A HelloDDKDispatchRoutinen"));
	NTSTATUS status = STATUS_SUCCESS;
	// 完成IRP
	pIrp->IoStatus.Status = status;
	pIrp->IoStatus.Information = 0;	// bytes xfered
	IoCompleteRequest( pIrp, IO_NO_INCREMENT );
	KdPrint(("DriverA:Leave A HelloDDKDispatchRoutinen"));
	return status;
}
 
#pragma PAGEDCODE
NTSTATUS HelloDDKCreate(IN PDEVICE_OBJECT pDevObj,
								 IN PIRP pIrp)
{
	KdPrint(("DriverA:Enter A HelloDDKCreaten"));
	NTSTATUS status = STATUS_SUCCESS;
	// 完成IRP
	pIrp->IoStatus.Status = status;
	pIrp->IoStatus.Information = 0;	// bytes xfered
	IoCompleteRequest( pIrp, IO_NO_INCREMENT );
	KdPrint(("DriverA:Leave A HelloDDKCreaten"));
	return status;
}
 
#pragma PAGEDCODE
NTSTATUS HelloDDKClose(IN PDEVICE_OBJECT pDevObj,
								 IN PIRP pIrp)
{
	KdPrint(("DriverA:Enter A HelloDDKClosen"));
	NTSTATUS status = STATUS_SUCCESS;
	// 完成IRP
	pIrp->IoStatus.Status = status;
	pIrp->IoStatus.Information = 0;	// bytes xfered
	IoCompleteRequest( pIrp, IO_NO_INCREMENT );
	KdPrint(("DriverA:Leave A HelloDDKClosen"));
	return status;
}


























文章作者:hgy413
本文地址:https://hgy413.com/105.html
版权所有 © 转载时必须以链接形式注明作者和原始出处!

本文的评论功能被关闭了.