summaryrefslogtreecommitdiff
path: root/pos/drivers/MagneticStripeReader/Device.cpp
blob: 85932fb262ac26647b303fa28161181170ad0d91 (plain)
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 magnetic stripe reader 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 Magnetic Stripe Reader so that the device can be enumerated
    status = WdfDeviceCreateDeviceInterface(
        device,
        &GUID_DEVINTERFACE_POS_MSR,
        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;
}