-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathNetworking.c
238 lines (183 loc) · 5.92 KB
/
Networking.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
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
#include "Driver.h"
//#include "wsk.h"
extern WSK_CLIENT_DISPATCH WskAppDispatch;
extern WSK_REGISTRATION WskRegistration;
extern WSK_PROVIDER_NPI wskProviderNpi;
extern BOOLEAN WskProviderNpiInitialized;
NTSTATUS WskInit()
{
NTSTATUS status;
WSK_CLIENT_NPI wskClientNpi;
// Register the WSK application
wskClientNpi.ClientContext = NULL;
wskClientNpi.Dispatch = &WskAppDispatch;
status = WskRegister(&wskClientNpi, &WskRegistration);
if (!NT_SUCCESS(status))
{
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_TRACE_LEVEL, "WskRegister failed %d", status);
return status;
}
return WskInitNpi();
}
// WSK application routine that waits for WSK subsystem
// to become ready and captures the WSK Provider NPI
NTSTATUS
WskInitNpi()
{
NTSTATUS status;
// WskCaptureProviderNPI() must be called at PASSIVE_LEVEL IRQL
PAGED_CODE()
// Capture the WSK Provider NPI. If WSK subsystem is not ready yet,
// wait until it becomes ready.
status = WskCaptureProviderNPI(
&WskRegistration, // must have been initialized with WskRegister
WSK_INFINITE_WAIT,
&wskProviderNpi
);
if (!NT_SUCCESS(status)) {
// The WSK Provider NPI could not be captured.
if (status == STATUS_NOINTERFACE) {
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_TRACE_LEVEL, "WSK application's requested version is not supported");
}
else if (status == STATUS_DEVICE_NOT_READY) {
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_TRACE_LEVEL, "WskDeregister was invoked in another thread thereby causing WskCaptureProviderNPI to be canceled.");
}
else {
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_TRACE_LEVEL, "Some other unexpected failure has occurred");
}
return status;
}
WskProviderNpiInitialized = TRUE;
return status;
}
// WSK application routine that releases the WSK Provider NPI
// and deregisters the WSK application
VOID WskCleanup()
{
// Release the WSK Provider NPI
if (WskProviderNpiInitialized) {
WskReleaseProviderNPI(&wskProviderNpi);
WskProviderNpiInitialized = FALSE;
}
// Deregister the WSK application
WskDeregister(&WskRegistration);
}
NTSTATUS SrkGetAddrInfo(IN PUNICODE_STRING NodeName,
IN PUNICODE_STRING ServiceName,
IN PADDRINFOEXW Hints,
OUT PADDRINFOEXW* Result)
{
NTSTATUS Status;
//
// Allocate async context.
//
SRK_ASYNC_CONTEXT AsyncContext;
Status = KspAsyncContextAllocate(&AsyncContext);
if (!NT_SUCCESS(Status))
{
return Status;
}
//
// Call the WSK API.
//
Status = wskProviderNpi.Dispatch->WskGetAddressInfo(
wskProviderNpi.Client, // Client
NodeName, // NodeName
ServiceName, // ServiceName
0, // NameSpace
NULL, // Provider
Hints, // Hints
Result, // Result
NULL, // OwningProcess
NULL, // OwningThread
AsyncContext.Irp // Irp
);
SrkAsyncContextWaitForCompletion(&AsyncContext, &Status);
//
// Free the async context.
//
SrkAsyncContextFree(&AsyncContext);
return Status;
}
// WSK application routine that creates a WSK socket
NTSTATUS WskCreateSocketAndConnect(
IN PADDRINFOEXW RemoteAddrInfo,
OUT PWSK_SOCKET Socket
)
{
NTSTATUS Status;
SOCKADDR_IN LocalAddress, RemoteAddr;
RemoteAddr = *(struct sockaddr_in*)RemoteAddrInfo->ai_addr;
RemoteAddr.sin_port = SYMBOL_SERVER_REMOTE_PORT;
LocalAddress.sin_family = AF_INET;
LocalAddress.sin_addr.s_addr = INADDR_ANY;
//
// Allocate async context.
//
SRK_ASYNC_CONTEXT AsyncContext;
Status = KspAsyncContextAllocate(&AsyncContext);
if (!NT_SUCCESS(Status))
{
return Status;
}
//
// Call the WSK API.
//
wskProviderNpi.Dispatch->WskSocketConnect(
wskProviderNpi.Client,RemoteAddrInfo->ai_socktype,RemoteAddrInfo->ai_protocol,&LocalAddress, &RemoteAddr, NULL, NULL, NULL, NULL,NULL, NULL,AsyncContext.Irp);
SrkAsyncContextWaitForCompletion(&AsyncContext, &Status);
if (!NT_SUCCESS(Status))
{
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_TRACE_LEVEL, "WskSocketConnect failed %d", Status);
goto Cleanup;
}
Socket = (PWSK_SOCKET)AsyncContext.Irp->IoStatus.Information;
//
// Free the async context.
//
SrkAsyncContextFree(&AsyncContext);
Cleanup:
return Status;
}
NTSTATUS WskSendReceiveData(PWSK_SOCKET Socket, PWSK_BUF SendBuf, PWSK_BUF RecvBuf)
{
NTSTATUS Status;
WSK_PROVIDER_CONNECTION_DISPATCH ConnDispatch = *((WSK_PROVIDER_CONNECTION_DISPATCH*)Socket->Dispatch);
if (ConnDispatch.WskSend == NULL || ConnDispatch.WskReceive == NULL)
{
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_TRACE_LEVEL, "%s: The WSK_SOCKET does NOT contain the Send\Recv functions.", __func__);
goto Cleanup;
}
//
// Allocate async context.
//
SRK_ASYNC_CONTEXT AsyncContext;
Status = KspAsyncContextAllocate(&AsyncContext);
if (!NT_SUCCESS(Status))
{
return Status;
}
//
// Call the WSK API.
//
Status = ConnDispatch.WskSend(Socket, SendBuf, WSK_FLAG_NODELAY, &AsyncContext);
SrkAsyncContextWaitForCompletion(&AsyncContext, &Status);
if (!NT_SUCCESS(Status))
{
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_TRACE_LEVEL, "%s: WskSend failed %d", __func__, Status);
goto Cleanup;
}
SrkAsyncContextReset(&AsyncContext);
Status = ConnDispatch.WskReceive(Socket, RecvBuf, WSK_FLAG_WAITALL, &AsyncContext);
if (!NT_SUCCESS(Status))
{
DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_TRACE_LEVEL, "%s: WskReceive failed %d", __func__, Status);
goto Cleanup;
}
//
// Free the async context.
//
SrkAsyncContextFree(&AsyncContext);
Cleanup:
return Status;
}