-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathUtils.c
144 lines (122 loc) · 2.96 KB
/
Utils.c
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
#include "Driver.h"
NTSTATUS
NTAPI
SrkAsyncContextAllocate(
OUT PSRK_ASYNC_CONTEXT AsyncContext
)
{
//
// Initialize the completion event.
//
KeInitializeEvent(
&AsyncContext->CompletionEvent,
SynchronizationEvent,
FALSE
);
//
// Initialize the IRP.
//
AsyncContext->Irp = IoAllocateIrp(1, FALSE);
if (AsyncContext->Irp == NULL)
{
return STATUS_INSUFFICIENT_RESOURCES;
}
//
// SrkAsyncContextCompletionRoutine will set
// the CompletionEvent.
//
IoSetCompletionRoutine(
AsyncContext->Irp,
&SrkAsyncContextCompletionRoutine,
&AsyncContext->CompletionEvent,
TRUE,
TRUE,
TRUE
);
return STATUS_SUCCESS;
}
VOID
NTAPI
SrkAsyncContextFree(
IN PSRK_ASYNC_CONTEXT AsyncContext
)
{
//
// Free the IRP.
//
IoFreeIrp(AsyncContext->Irp);
}
VOID
NTAPI
SrkAsyncContextReset(
IN PSRK_ASYNC_CONTEXT AsyncContext
)
{
//
// If the WSK application allocated the IRP, or is reusing an IRP
// that it previously allocated, then it must set an IoCompletion
// routine for the IRP before calling a WSK function. In this
// situation, the WSK application must specify TRUE for the
// InvokeOnSuccess, InvokeOnError, and InvokeOnCancel parameters that
// are passed to the IoSetCompletionRoutine function to ensure that
// the IoCompletion routine is always called. Furthermore, the IoCompletion
// routine that is set for the IRP must always return
// STATUS_MORE_PROCESSING_REQUIRED to terminate the completion processing
// of the IRP. If the WSK application is done using the IRP after the
// IoCompletion routine has been called, then it should call the IoFreeIrp
// function to free the IRP before returning from the IoCompletion routine.
// If the WSK application does not free the IRP then it can reuse the IRP
// for a call to another WSK function.
//
// (ref: https://docs.microsoft.com/en-us/windows-hardware/drivers/network/using-irps-with-winsock-kernel-functions)
//
//
// Reset the completion event.
//
KeResetEvent(&AsyncContext->CompletionEvent);
//
// Reuse the IRP.
//
IoReuseIrp(AsyncContext->Irp, STATUS_UNSUCCESSFUL);
IoSetCompletionRoutine(
AsyncContext->Irp,
&SrkAsyncContextCompletionRoutine,
&AsyncContext->CompletionEvent,
TRUE,
TRUE,
TRUE
);
}
NTSTATUS
NTAPI
SrkAsyncContextCompletionRoutine(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PKEVENT CompletionEvent
)
{
UNREFERENCED_PARAMETER(DeviceObject);
UNREFERENCED_PARAMETER(Irp);
KeSetEvent(CompletionEvent, IO_NO_INCREMENT, FALSE);
return STATUS_MORE_PROCESSING_REQUIRED;
}
NTSTATUS
NTAPI
SrkAsyncContextWaitForCompletion(
IN PSRK_ASYNC_CONTEXT AsyncContext,
[IN,OUT] PNTSTATUS Status
)
{
if (*Status == STATUS_PENDING)
{
KeWaitForSingleObject(
&AsyncContext->CompletionEvent,
Executive,
KernelMode,
FALSE,
NULL
);
*Status = AsyncContext->Irp->IoStatus.Status;
}
return *Status;
}