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
|
#include <pch.h>
#include "File.h"
#include "PosEvents.h"
#include "Ioctl.h"
#include "IoRead.h"
/*
** Driver TODO: Complete the implementation of EvtDriverDeviceAdd for your specific device.
**
** WDF calls this callback when a device instance is added to the driver. Good drivers will do a lot of
** work here to set up everything necessary, such as adding callbacks for PNP power state changes.
** This function defines an IO queue for handling DeviceIoControl and file read requests, both of which are
** important to the POS barcode scanner model.
**
** Note that this is not a complete device add implementation, as the PNP power callbacks are not handled.
** Additionally, driver writers may wish to set up additional queues to serialize device property requests
** (see Ioctl.cpp for more info).
*/
NTSTATUS EvtDriverDeviceAdd(_In_ WDFDRIVER /* UnusedDriver */, _Inout_ PWDFDEVICE_INIT DeviceInit)
{
NTSTATUS status = STATUS_SUCCESS;
WDF_FILEOBJECT_CONFIG fileConfig;
WDF_OBJECT_ATTRIBUTES deviceAttributes;
WDF_OBJECT_ATTRIBUTES fileAttributes;
WDFDEVICE device;
// Handle file events
WDF_FILEOBJECT_CONFIG_INIT(
&fileConfig,
EvtDeviceFileCreate,
EvtFileClose,
WDF_NO_EVENT_CALLBACK
);
WDF_OBJECT_ATTRIBUTES_INIT(&fileAttributes);
WdfDeviceInitSetFileObjectConfig(
DeviceInit,
&fileConfig,
&fileAttributes
);
// Create Device
WDF_OBJECT_ATTRIBUTES_INIT(&deviceAttributes);
status = WdfDeviceCreate(
&DeviceInit,
&deviceAttributes,
&device
);
if (!NT_SUCCESS(status))
{
return status;
}
// Create a device interface for POS Barcode Scanner so that the device can be enumerated
status = WdfDeviceCreateDeviceInterface(
device,
&GUID_DEVINTERFACE_POS_SCANNER,
NULL
);
if (!NT_SUCCESS(status))
{
return status;
}
// Initialize the POS library
POS_CX_ATTRIBUTES posCxAttributes;
POS_CX_ATTRIBUTES_INIT(&posCxAttributes);
posCxAttributes.EvtDeviceOwnershipChange = EvtDeviceOwnershipChange;
status = PosCxInit(device, &posCxAttributes);
if (!NT_SUCCESS(status))
{
return status;
}
// Set up an IO queue to handle DeviceIoControl and ReadFile
WDF_IO_QUEUE_CONFIG queueConfig;
WDF_OBJECT_ATTRIBUTES attributes;
WDFQUEUE queue;
WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(&queueConfig, WdfIoQueueDispatchSequential);
queueConfig.EvtIoDeviceControl = EvtIoDeviceControl;
queueConfig.EvtIoRead = EvtIoRead;
// Call us in PASSIVE_LEVEL
WDF_OBJECT_ATTRIBUTES_INIT(&attributes);
attributes.ExecutionLevel = WdfExecutionLevelPassive;
status = WdfIoQueueCreate(
device,
&queueConfig,
&attributes,
&queue
);
return status;
}
|