VirtualBox

source: vbox/trunk/src/VBox/HostDrivers/VBoxNetFlt/win/drv/VBoxNetFltM-win.cpp@ 52618

Last change on this file since 52618 was 52618, checked in by vboxsync, 10 years ago

HostDrivers, Runtime, Devices, Additions: TSC delta measurement and other changes resulting from bumping supdrv major version. TSC delta measurement currently disabled.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 54.7 KB
Line 
1/* $Id: VBoxNetFltM-win.cpp 52618 2014-09-05 12:07:29Z vboxsync $ */
2/** @file
3 * VBoxNetFltM-win.cpp - Bridged Networking Driver, Windows Specific Code.
4 * Miniport edge
5 */
6/*
7 * Copyright (C) 2011-2014 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17#include "VBoxNetFltCmn-win.h"
18
19static const char* vboxNetFltWinMpDumpOid(ULONG oid);
20
21#ifndef VBOXNETADP
22static NDIS_STATUS vboxNetFltWinMpInitialize(OUT PNDIS_STATUS OpenErrorStatus,
23 OUT PUINT SelectedMediumIndex,
24 IN PNDIS_MEDIUM MediumArray,
25 IN UINT MediumArraySize,
26 IN NDIS_HANDLE MiniportAdapterHandle,
27 IN NDIS_HANDLE WrapperConfigurationContext)
28{
29 PVBOXNETFLTINS pNetFlt = (PVBOXNETFLTINS)NdisIMGetDeviceContext(MiniportAdapterHandle);
30 NDIS_STATUS Status = NDIS_STATUS_FAILURE;
31
32 LogFlow(("==>"__FUNCTION__": pNetFlt (0x%p)\n", pNetFlt));
33
34 pNetFlt->u.s.WinIf.hMiniport = MiniportAdapterHandle;
35 Assert(vboxNetFltWinGetOpState(&pNetFlt->u.s.WinIf.MpState) == kVBoxNetDevOpState_Initializing);
36 /* the MP state should be already set to kVBoxNetDevOpState_Initializing, just a paranoia
37 * in case NDIS for some reason calls us in some irregular way */
38 vboxNetFltWinSetOpState(&pNetFlt->u.s.WinIf.MpState, kVBoxNetDevOpState_Initializing);
39
40 NDIS_MEDIUM enmMedium = pNetFlt->u.s.WinIf.enmMedium;
41 if (enmMedium == NdisMediumWan)
42 enmMedium = NdisMedium802_3;
43
44 UINT i = 0;
45 for (; i < MediumArraySize; i++)
46 {
47 if (MediumArray[i] == enmMedium)
48 {
49 *SelectedMediumIndex = i;
50 break;
51 }
52 }
53
54 do
55 {
56 if (i != MediumArraySize)
57 {
58 NdisMSetAttributesEx(MiniportAdapterHandle, pNetFlt, 0,
59 NDIS_ATTRIBUTE_IGNORE_PACKET_TIMEOUT |
60 NDIS_ATTRIBUTE_IGNORE_REQUEST_TIMEOUT|
61 NDIS_ATTRIBUTE_INTERMEDIATE_DRIVER |
62 NDIS_ATTRIBUTE_DESERIALIZE |
63 NDIS_ATTRIBUTE_NO_HALT_ON_SUSPEND,
64 NdisInterfaceInternal /* 0 */);
65
66 pNetFlt->u.s.WinIf.MpIndicatedMediaStatus = NDIS_STATUS_MEDIA_CONNECT;
67 Assert(vboxNetFltWinGetPowerState(&pNetFlt->u.s.WinIf.MpState) == NdisDeviceStateD3);
68 vboxNetFltWinSetPowerState(&pNetFlt->u.s.WinIf.MpState, NdisDeviceStateD0);
69 Assert(pNetFlt->u.s.WinIf.MpState.OpState == kVBoxNetDevOpState_Initializing);
70 vboxNetFltWinSetOpState(&pNetFlt->u.s.WinIf.MpState, kVBoxNetDevOpState_Initialized);
71
72 Status = NDIS_STATUS_SUCCESS;
73 break;
74 }
75 else
76 {
77 Status = NDIS_STATUS_UNSUPPORTED_MEDIA;
78 }
79
80 Assert(Status != NDIS_STATUS_SUCCESS);
81 Assert(vboxNetFltWinGetPowerState(&pNetFlt->u.s.WinIf.MpState) == NdisDeviceStateD3);
82 Assert(pNetFlt->u.s.WinIf.MpState.OpState == kVBoxNetDevOpState_Initializing);
83 vboxNetFltWinSetOpState(&pNetFlt->u.s.WinIf.MpState, kVBoxNetDevOpState_Deinitialized);
84 } while (0);
85
86 NdisSetEvent(&pNetFlt->u.s.WinIf.MpInitCompleteEvent);
87
88 LogFlow(("<=="__FUNCTION__": pNetFlt (0x%p), Status (0x%x)\n", pNetFlt, Status));
89
90 *OpenErrorStatus = Status;
91
92 return Status;
93}
94
95/**
96 * process the packet send in a "passthru" mode
97 */
98static NDIS_STATUS vboxNetFltWinSendPassThru(PVBOXNETFLTINS pNetFlt, PNDIS_PACKET pPacket
99#ifdef VBOXNETFLT_NO_PACKET_QUEUE
100 , bool bNetFltActive
101#endif
102 )
103{
104 PNDIS_PACKET pMyPacket;
105 NDIS_STATUS Status = vboxNetFltWinPrepareSendPacket(pNetFlt, pPacket, &pMyPacket);
106 Assert(Status == NDIS_STATUS_SUCCESS);
107 if (Status == NDIS_STATUS_SUCCESS)
108 {
109#if !defined(VBOX_LOOPBACK_USEFLAGS) /* || defined(DEBUG_NETFLT_PACKETS) */
110# ifdef VBOXNETFLT_NO_PACKET_QUEUE
111 if (bNetFltActive)
112 vboxNetFltWinLbPutSendPacket(pNetFlt, pMyPacket, false /* bFromIntNet */);
113# else
114 /* no need for the loop enqueue & check in a passthru mode , ndis will do everything for us */
115# endif
116#endif
117 NdisSend(&Status, pNetFlt->u.s.WinIf.hBinding, pMyPacket);
118 if (Status != NDIS_STATUS_PENDING)
119 {
120 NdisIMCopySendCompletePerPacketInfo(pPacket, pMyPacket);
121#if defined(VBOXNETFLT_NO_PACKET_QUEUE) && !defined(VBOX_LOOPBACK_USEFLAGS)
122 if (bNetFltActive)
123 vboxNetFltWinLbRemoveSendPacket(pNetFlt, pMyPacket);
124#endif
125 NdisFreePacket(pMyPacket);
126 }
127 }
128 return Status;
129}
130
131#else /* defined VBOXNETADP */
132DECLHIDDEN(NDIS_STATUS) vboxNetFltWinMpDoDeinitialization(PVBOXNETFLTINS pNetFlt)
133{
134 uint64_t NanoTS = RTTimeSystemNanoTS();
135
136 Assert(vboxNetFltWinGetOpState(&pNetFlt->u.s.WinIf.MpState) == kVBoxNetDevOpState_Initialized);
137
138 RTSpinlockAcquire(pNetFlt->hSpinlock);
139 ASMAtomicUoWriteBool(&pNetFlt->fDisconnectedFromHost, true);
140 ASMAtomicUoWriteBool(&pNetFlt->fRediscoveryPending, false);
141 ASMAtomicUoWriteU64(&pNetFlt->NanoTSLastRediscovery, NanoTS);
142
143 vboxNetFltWinSetOpState(&pNetFlt->u.s.WinIf.MpState, kVBoxNetDevOpState_Deinitializing);
144
145 RTSpinlockRelease(pNetFlt->hSpinlock);
146
147 vboxNetFltWinWaitDereference(&pNetFlt->u.s.WinIf.MpState);
148
149 /* check packet pool is empty */
150 int cPPUsage = NdisPacketPoolUsage(pNetFlt->u.s.WinIf.hRecvPacketPool);
151 Assert(cPPUsage == 0);
152 /* for debugging only, ignore the err in release */
153 NOREF(cPPUsage);
154
155 vboxNetFltWinSetOpState(&pNetFlt->u.s.WinIf.MpState, kVBoxNetDevOpState_Deinitialized);
156
157 return NDIS_STATUS_SUCCESS;
158}
159
160static NDIS_STATUS vboxNetFltWinMpReadApplyConfig(PVBOXNETFLTINS pThis, NDIS_HANDLE hMiniportAdapter, NDIS_HANDLE hWrapperConfigurationContext)
161{
162 NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
163 NDIS_HANDLE hConfiguration;
164 PNDIS_CONFIGURATION_PARAMETER pParameterValue;
165 NDIS_STRING strMAC = NDIS_STRING_CONST("MAC");
166 RTMAC mac;
167
168 NdisOpenConfiguration(
169 &Status,
170 &hConfiguration,
171 hWrapperConfigurationContext);
172 Assert(Status == NDIS_STATUS_SUCCESS);
173 if (Status == NDIS_STATUS_SUCCESS)
174 {
175 do
176 {
177 int rc;
178 NDIS_CONFIGURATION_PARAMETER param;
179 WCHAR MacBuf[13];
180
181 NdisReadConfiguration(&Status,
182 &pParameterValue,
183 hConfiguration,
184 &strMAC,
185 NdisParameterString);
186// Assert(Status == NDIS_STATUS_SUCCESS);
187 if (Status == NDIS_STATUS_SUCCESS)
188 {
189
190 rc = vboxNetFltWinMACFromNdisString(&mac, &pParameterValue->ParameterData.StringData);
191 AssertRC(rc);
192 if (RT_SUCCESS(rc))
193 {
194 break;
195 }
196 }
197
198 vboxNetFltWinGenerateMACAddress(&mac);
199 param.ParameterType = NdisParameterString;
200 param.ParameterData.StringData.Buffer = MacBuf;
201 param.ParameterData.StringData.MaximumLength = sizeof(MacBuf);
202
203 rc = vboxNetFltWinMAC2NdisString(&mac, &param.ParameterData.StringData);
204 Assert(RT_SUCCESS(rc));
205 if (RT_SUCCESS(rc))
206 {
207 NdisWriteConfiguration(&Status,
208 hConfiguration,
209 &strMAC,
210 &param);
211 Assert(Status == NDIS_STATUS_SUCCESS);
212 if (Status != NDIS_STATUS_SUCCESS)
213 {
214 /* ignore the failure */
215 Status = NDIS_STATUS_SUCCESS;
216 }
217 }
218 } while (0);
219
220 NdisCloseConfiguration(hConfiguration);
221 }
222 else
223 {
224 vboxNetFltWinGenerateMACAddress(&mac);
225 }
226
227 pThis->u.s.MacAddr = mac;
228
229 return NDIS_STATUS_SUCCESS;
230}
231
232DECLHIDDEN(NDIS_STATUS) vboxNetFltWinMpDoInitialization(PVBOXNETFLTINS pNetFlt, NDIS_HANDLE hMiniportAdapter, NDIS_HANDLE hWrapperConfigurationContext)
233{
234 NDIS_STATUS Status;
235 pNetFlt->u.s.WinIf.hMiniport = hMiniportAdapter;
236
237 LogFlow(("==>"__FUNCTION__" : pNetFlt 0x%p\n", pNetFlt));
238
239 Assert(vboxNetFltWinGetOpState(&pNetFlt->u.s.WinIf.MpState) == kVBoxNetDevOpState_Deinitialized);
240 vboxNetFltWinSetOpState(&pNetFlt->u.s.WinIf.MpState, kVBoxNetDevOpState_Initializing);
241
242 vboxNetFltWinMpReadApplyConfig(pNetFlt, hMiniportAdapter, hWrapperConfigurationContext);
243
244 NdisMSetAttributesEx(hMiniportAdapter, pNetFlt,
245 0, /* CheckForHangTimeInSeconds */
246 NDIS_ATTRIBUTE_DESERIALIZE |
247 NDIS_ATTRIBUTE_NO_HALT_ON_SUSPEND,
248 NdisInterfaceInternal/* 0 */);
249
250 Assert(vboxNetFltWinGetPowerState(&pNetFlt->u.s.WinIf.MpState) == NdisDeviceStateD3);
251 vboxNetFltWinSetPowerState(&pNetFlt->u.s.WinIf.MpState, NdisDeviceStateD0);
252 Assert(vboxNetFltWinGetOpState(&pNetFlt->u.s.WinIf.MpState) == kVBoxNetDevOpState_Initializing);
253 vboxNetFltWinSetOpState(&pNetFlt->u.s.WinIf.MpState, kVBoxNetDevOpState_Initialized);
254
255 Status = NDIS_STATUS_SUCCESS;
256
257 LogFlow(("<=="__FUNCTION__" : pNetFlt 0x%p, Status 0x%x\n", pNetFlt, Status));
258
259 return Status;
260}
261
262static NDIS_STATUS vboxNetFltWinMpInitialize(OUT PNDIS_STATUS OpenErrorStatus,
263 OUT PUINT SelectedMediumIndex,
264 IN PNDIS_MEDIUM MediumArray,
265 IN UINT MediumArraySize,
266 IN NDIS_HANDLE MiniportAdapterHandle,
267 IN NDIS_HANDLE WrapperConfigurationContext)
268{
269
270 NDIS_STATUS Status = NDIS_STATUS_FAILURE;
271 UINT i = 0;
272
273 LogFlow(("==>"__FUNCTION__"\n"));
274
275 for (; i < MediumArraySize; i++)
276 {
277 if (MediumArray[i] == NdisMedium802_3)
278 {
279 *SelectedMediumIndex = i;
280 break;
281 }
282 }
283
284 if (i != MediumArraySize)
285 {
286 PDEVICE_OBJECT pPdo, pFdo;
287#define KEY_PREFIX L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Class\\"
288 UCHAR Buf[512];
289 PUCHAR pSuffix;
290 ULONG cbBuf;
291 NDIS_STRING RtlStr;
292
293 wcscpy((WCHAR*)Buf, KEY_PREFIX);
294 pSuffix = Buf + (sizeof(KEY_PREFIX)-2);
295
296 NdisMGetDeviceProperty(MiniportAdapterHandle,
297 &pPdo,
298 &pFdo,
299 NULL, //Next Device Object
300 NULL,
301 NULL);
302
303 Status = IoGetDeviceProperty (pPdo,
304 DevicePropertyDriverKeyName,
305 sizeof(Buf) - (sizeof(KEY_PREFIX)-2),
306 pSuffix,
307 &cbBuf);
308 if (Status == STATUS_SUCCESS)
309 {
310 OBJECT_ATTRIBUTES ObjAttr;
311 HANDLE hDrvKey;
312 RtlStr.Buffer=(WCHAR*)Buf;
313 RtlStr.Length=(USHORT)cbBuf - 2 + sizeof(KEY_PREFIX) - 2;
314 RtlStr.MaximumLength=sizeof(Buf);
315
316 InitializeObjectAttributes(&ObjAttr, &RtlStr, OBJ_CASE_INSENSITIVE, NULL, NULL);
317
318 Status = ZwOpenKey(&hDrvKey, KEY_READ, &ObjAttr);
319 if (Status == STATUS_SUCCESS)
320 {
321 static UNICODE_STRING NetCfgInstanceIdValue = NDIS_STRING_CONST("NetCfgInstanceId");
322// UCHAR valBuf[sizeof(KEY_VALUE_PARTIAL_INFORMATION) + RTUUID_STR_LENGTH*2 + 10];
323// ULONG cLength = sizeof(valBuf);
324#define NAME_PREFIX L"\\DEVICE\\"
325 PKEY_VALUE_PARTIAL_INFORMATION pInfo = (PKEY_VALUE_PARTIAL_INFORMATION)Buf;
326 Status = ZwQueryValueKey(hDrvKey,
327 &NetCfgInstanceIdValue,
328 KeyValuePartialInformation,
329 pInfo,
330 sizeof(Buf),
331 &cbBuf);
332 if (Status == STATUS_SUCCESS)
333 {
334 if (pInfo->Type == REG_SZ && pInfo->DataLength > 2)
335 {
336 WCHAR *pName;
337 Status = vboxNetFltWinMemAlloc((PVOID*)&pName, pInfo->DataLength + sizeof(NAME_PREFIX));
338 if (Status == STATUS_SUCCESS)
339 {
340 PVBOXNETFLTINS pNetFlt;
341 wcscpy(pName, NAME_PREFIX);
342 wcscpy(pName+(sizeof(NAME_PREFIX)-2)/2, (WCHAR*)pInfo->Data);
343 RtlStr.Buffer=pName;
344 RtlStr.Length = (USHORT)pInfo->DataLength - 2 + sizeof(NAME_PREFIX) - 2;
345 RtlStr.MaximumLength = (USHORT)pInfo->DataLength + sizeof(NAME_PREFIX);
346
347 Status = vboxNetFltWinPtInitBind(&pNetFlt, MiniportAdapterHandle, &RtlStr, WrapperConfigurationContext);
348
349 if (Status == STATUS_SUCCESS)
350 {
351 Assert(vboxNetFltWinGetOpState(&pNetFlt->u.s.WinIf.MpState) == kVBoxNetDevOpState_Initialized);
352 vboxNetFltWinSetOpState(&pNetFlt->u.s.WinIf.MpState, kVBoxNetDevOpState_Initialized);
353#if 0
354 NdisMIndicateStatus(pNetFlt->u.s.WinIf.hMiniport,
355 NDIS_STATUS_MEDIA_CONNECT,
356 (PVOID)NULL,
357 0);
358#endif
359 }
360 else
361 {
362 Assert(vboxNetFltWinGetOpState(&pNetFlt->u.s.WinIf.MpState) == kVBoxNetDevOpState_Deinitialized);
363 vboxNetFltWinSetOpState(&pNetFlt->u.s.WinIf.MpState, kVBoxNetDevOpState_Deinitialized);
364 }
365
366 vboxNetFltWinMemFree(pName);
367
368 }
369 }
370 else
371 {
372 Status = NDIS_STATUS_FAILURE;
373 }
374 }
375 }
376 }
377 }
378 else
379 {
380 Status = NDIS_STATUS_UNSUPPORTED_MEDIA;
381 }
382
383 /* TODO: */
384 *OpenErrorStatus = Status;
385
386 LogFlow(("<=="__FUNCTION__": Status (0x%x)\n", Status));
387
388 return Status;
389}
390#endif
391
392static VOID vboxNetFltWinMpSendPackets(IN NDIS_HANDLE hMiniportAdapterContext,
393 IN PPNDIS_PACKET pPacketArray,
394 IN UINT cNumberOfPackets)
395{
396 PVBOXNETFLTINS pNetFlt = (PVBOXNETFLTINS)hMiniportAdapterContext;
397 NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
398 bool bNetFltActive;
399
400 LogFlow(("==>"__FUNCTION__": pNetFlt (0x%p)\n", pNetFlt));
401
402 Assert(cNumberOfPackets);
403
404 if (vboxNetFltWinIncReferenceWinIfNetFlt(pNetFlt, cNumberOfPackets, &bNetFltActive))
405 {
406 uint32_t cAdaptRefs = cNumberOfPackets;
407 uint32_t cNetFltRefs;
408 uint32_t cPassThruRefs;
409 if (bNetFltActive)
410 {
411 cNetFltRefs = cNumberOfPackets;
412 cPassThruRefs = 0;
413 }
414 else
415 {
416 cPassThruRefs = cNumberOfPackets;
417 cNetFltRefs = 0;
418 }
419
420 for (UINT i = 0; i < cNumberOfPackets; i++)
421 {
422 PNDIS_PACKET pPacket;
423
424 pPacket = pPacketArray[i];
425
426 if (!cNetFltRefs
427#ifdef VBOXNETFLT_NO_PACKET_QUEUE
428 || !vboxNetFltWinPostIntnet(pNetFlt, pPacket, VBOXNETFLT_PACKET_SRC_HOST)
429#else
430 || (fStatus = vboxNetFltWinQuEnqueuePacket(pNetFlt, pPacket, VBOXNETFLT_PACKET_SRC_HOST)) != NDIS_STATUS_SUCCESS
431#endif
432 )
433 {
434#ifndef VBOXNETADP
435 Status = vboxNetFltWinSendPassThru(pNetFlt, pPacket
436#ifdef VBOXNETFLT_NO_PACKET_QUEUE
437 , !!cNetFltRefs
438#endif
439 );
440#else
441 if (!cNetFltRefs)
442 {
443# ifdef VBOXNETADP_REPORT_DISCONNECTED
444 Status = NDIS_STATUS_MEDIA_DISCONNECT;
445 STATISTIC_INCREASE(pNetFlt->u.s.WinIf.cTxError);
446# else
447 Status = NDIS_STATUS_SUCCESS;
448# endif
449 }
450#endif
451
452 if (Status != NDIS_STATUS_PENDING)
453 {
454 NdisMSendComplete(pNetFlt->u.s.WinIf.hMiniport, pPacket, Status);
455 }
456 else
457 {
458 cAdaptRefs--;
459 }
460 }
461 else
462 {
463#ifdef VBOXNETFLT_NO_PACKET_QUEUE
464 NdisMSendComplete(pNetFlt->u.s.WinIf.hMiniport, pPacket, NDIS_STATUS_SUCCESS);
465#else
466 cAdaptRefs--;
467 cNetFltRefs--;
468#endif
469 }
470 }
471
472 if (cNetFltRefs)
473 {
474 vboxNetFltWinDecReferenceNetFlt(pNetFlt, cNetFltRefs);
475 }
476 else if (cPassThruRefs)
477 {
478 vboxNetFltWinDecReferenceModePassThru(pNetFlt, cPassThruRefs);
479 }
480 if (cAdaptRefs)
481 {
482 vboxNetFltWinDecReferenceWinIf(pNetFlt, cAdaptRefs);
483 }
484 }
485 else
486 {
487 NDIS_HANDLE h = pNetFlt->u.s.WinIf.hMiniport;
488 Assert(0);
489 if (h)
490 {
491 for (UINT i = 0; i < cNumberOfPackets; i++)
492 {
493 PNDIS_PACKET pPacket;
494 pPacket = pPacketArray[i];
495 NdisMSendComplete(h, pPacket, NDIS_STATUS_FAILURE);
496 }
497 }
498 }
499
500 LogFlow(("<=="__FUNCTION__": pNetFlt (0x%p)\n", pNetFlt));
501}
502
503#ifndef VBOXNETADP
504static UINT vboxNetFltWinMpRequestStatePrep(PVBOXNETFLTINS pNetFlt, NDIS_STATUS *pStatus)
505{
506 Assert(!pNetFlt->u.s.WinIf.StateFlags.fRequestInfo);
507
508 if (vboxNetFltWinGetOpState(&pNetFlt->u.s.WinIf.PtState) > kVBoxNetDevOpState_Initialized /* protocol unbind in progress */
509 || vboxNetFltWinGetPowerState(&pNetFlt->u.s.WinIf.MpState) > NdisDeviceStateD0)
510 {
511 *pStatus = NDIS_STATUS_FAILURE;
512 return 0;
513 }
514
515 RTSpinlockAcquire(pNetFlt->hSpinlock);
516 Assert(!pNetFlt->u.s.WinIf.StateFlags.fRequestInfo);
517 if (vboxNetFltWinGetOpState(&pNetFlt->u.s.WinIf.PtState) > kVBoxNetDevOpState_Initialized /* protocol unbind in progress */
518 || vboxNetFltWinGetPowerState(&pNetFlt->u.s.WinIf.MpState) > NdisDeviceStateD0)
519 {
520 RTSpinlockRelease(pNetFlt->hSpinlock);
521 *pStatus = NDIS_STATUS_FAILURE;
522 return 0;
523 }
524
525 if ((vboxNetFltWinGetPowerState(&pNetFlt->u.s.WinIf.PtState) > NdisDeviceStateD0)
526 && !pNetFlt->u.s.WinIf.StateFlags.fStandBy)
527 {
528 pNetFlt->u.s.WinIf.StateFlags.fRequestInfo = VBOXNDISREQUEST_INPROGRESS | VBOXNDISREQUEST_QUEUED;
529 RTSpinlockRelease(pNetFlt->hSpinlock);
530 *pStatus = NDIS_STATUS_PENDING;
531 return VBOXNDISREQUEST_INPROGRESS | VBOXNDISREQUEST_QUEUED;
532 }
533
534 if (pNetFlt->u.s.WinIf.StateFlags.fStandBy)
535 {
536 RTSpinlockRelease(pNetFlt->hSpinlock);
537 *pStatus = NDIS_STATUS_FAILURE;
538 return 0;
539 }
540
541 pNetFlt->u.s.WinIf.StateFlags.fRequestInfo = VBOXNDISREQUEST_INPROGRESS;
542
543 RTSpinlockRelease(pNetFlt->hSpinlock);
544
545 *pStatus = NDIS_STATUS_SUCCESS;
546 return VBOXNDISREQUEST_INPROGRESS;
547}
548
549static NDIS_STATUS vboxNetFltWinMpRequestPostQuery(PVBOXNETFLTINS pNetFlt)
550{
551 if (pNetFlt->u.s.WinIf.PassDownRequest.DATA.QUERY_INFORMATION.Oid == OID_GEN_CURRENT_PACKET_FILTER && VBOXNETFLT_PROMISCUOUS_SUPPORTED(pNetFlt))
552 {
553 bool fNetFltActive;
554 const bool fWinIfActive = vboxNetFltWinReferenceWinIfNetFlt(pNetFlt, &fNetFltActive);
555
556 Assert(pNetFlt->u.s.WinIf.PassDownRequest.DATA.QUERY_INFORMATION.InformationBuffer);
557 Assert(!pNetFlt->u.s.WinIf.StateFlags.fProcessingPacketFilter);
558
559 if (fNetFltActive)
560 {
561 /* netflt is active, simply return the cached value */
562 *((PULONG)pNetFlt->u.s.WinIf.PassDownRequest.DATA.QUERY_INFORMATION.InformationBuffer) = pNetFlt->u.s.WinIf.fUpperProtocolSetFilter;
563
564 /* we've intercepted the query and completed it */
565 vboxNetFltWinMpRequestStateComplete(pNetFlt);
566
567 vboxNetFltWinDereferenceNetFlt(pNetFlt);
568 vboxNetFltWinDereferenceWinIf(pNetFlt);
569
570 return NDIS_STATUS_SUCCESS;
571 }
572 else if (fWinIfActive)
573 {
574 pNetFlt->u.s.WinIf.StateFlags.fProcessingPacketFilter = 1;
575 pNetFlt->u.s.WinIf.StateFlags.fPPFNetFlt = 0;
576 /* we're cleaning it in RequestComplete */
577 }
578 }
579
580 NDIS_STATUS Status;
581 /* issue the request */
582 NdisRequest(&Status, pNetFlt->u.s.WinIf.hBinding, &pNetFlt->u.s.WinIf.PassDownRequest);
583 if (Status != NDIS_STATUS_PENDING)
584 {
585 vboxNetFltWinPtRequestComplete(pNetFlt, &pNetFlt->u.s.WinIf.PassDownRequest, Status);
586 Status = NDIS_STATUS_PENDING;
587 }
588
589 return Status;
590}
591
592static NDIS_STATUS vboxNetFltWinMpQueryInformation(IN NDIS_HANDLE MiniportAdapterContext,
593 IN NDIS_OID Oid,
594 IN PVOID InformationBuffer,
595 IN ULONG InformationBufferLength,
596 OUT PULONG BytesWritten,
597 OUT PULONG BytesNeeded)
598{
599 PVBOXNETFLTINS pNetFlt = (PVBOXNETFLTINS)MiniportAdapterContext;
600 NDIS_STATUS Status = NDIS_STATUS_FAILURE;
601
602 LogFlow(("==>"__FUNCTION__": pNetFlt (0x%p), Oid (%s)\n", pNetFlt, vboxNetFltWinMpDumpOid(Oid)));
603
604 /* fist check if this is the oid we want to pass down */
605 switch (Oid)
606 {
607 case OID_PNP_QUERY_POWER:
608 Status = NDIS_STATUS_SUCCESS;
609 break;
610 case OID_TCP_TASK_OFFLOAD:
611 case OID_GEN_SUPPORTED_GUIDS:
612 Status = NDIS_STATUS_NOT_SUPPORTED;
613 break;
614 default:
615 {
616 /* the oid is to be passed down,
617 * check the device state if we can do it
618 * and update device state accordingly */
619 UINT uOp = vboxNetFltWinMpRequestStatePrep(pNetFlt, &Status);
620 if (uOp)
621 {
622 /* save the request info */
623 pNetFlt->u.s.WinIf.PassDownRequest.RequestType = NdisRequestQueryInformation;
624 pNetFlt->u.s.WinIf.PassDownRequest.DATA.QUERY_INFORMATION.Oid = Oid;
625 pNetFlt->u.s.WinIf.PassDownRequest.DATA.QUERY_INFORMATION.InformationBuffer = InformationBuffer;
626 pNetFlt->u.s.WinIf.PassDownRequest.DATA.QUERY_INFORMATION.InformationBufferLength = InformationBufferLength;
627 pNetFlt->u.s.WinIf.pcPDRBytesNeeded = BytesNeeded;
628 pNetFlt->u.s.WinIf.pcPDRBytesRW = BytesWritten;
629
630 /* the oid can be processed */
631 if (!(uOp & VBOXNDISREQUEST_QUEUED))
632 {
633 Status = vboxNetFltWinMpRequestPostQuery(pNetFlt);
634 }
635 }
636 break;
637 }
638 }
639
640 LogFlow(("<=="__FUNCTION__": pNetFlt (0x%p), Oid (%s), Status (0x%x)\n", pNetFlt, vboxNetFltWinMpDumpOid(Oid), Status));
641
642 return Status;
643}
644
645#endif /* ifndef VBOXNETADP*/
646
647static NDIS_STATUS vboxNetFltWinMpHandlePowerState(PVBOXNETFLTINS pNetFlt, NDIS_DEVICE_POWER_STATE enmState)
648{
649 if (vboxNetFltWinGetPowerState(&pNetFlt->u.s.WinIf.MpState) > NdisDeviceStateD0
650 && enmState != NdisDeviceStateD0)
651 {
652 /* invalid state transformation */
653 Assert(0);
654 return NDIS_STATUS_FAILURE;
655 }
656
657#ifndef VBOXNETADP
658 if (vboxNetFltWinGetPowerState(&pNetFlt->u.s.WinIf.MpState) == NdisDeviceStateD0
659 && enmState > NdisDeviceStateD0)
660 {
661 pNetFlt->u.s.WinIf.StateFlags.fStandBy = TRUE;
662 }
663
664 if (vboxNetFltWinGetPowerState(&pNetFlt->u.s.WinIf.MpState) > NdisDeviceStateD0
665 && enmState == NdisDeviceStateD0)
666 {
667 pNetFlt->u.s.WinIf.StateFlags.fStandBy = FALSE;
668 }
669#endif
670
671 vboxNetFltWinSetPowerState(&pNetFlt->u.s.WinIf.MpState, enmState);
672
673#ifndef VBOXNETADP
674 if (pNetFlt->u.s.WinIf.StateFlags.fStandBy == FALSE)
675 {
676 if (pNetFlt->u.s.WinIf.MpIndicatedMediaStatus != pNetFlt->u.s.WinIf.MpUnindicatedMediaStatus)
677 {
678 NdisMIndicateStatus(pNetFlt->u.s.WinIf.hMiniport, pNetFlt->u.s.WinIf.MpUnindicatedMediaStatus, NULL, 0);
679 NdisMIndicateStatusComplete(pNetFlt->u.s.WinIf.hMiniport);
680 pNetFlt->u.s.WinIf.MpIndicatedMediaStatus = pNetFlt->u.s.WinIf.MpUnindicatedMediaStatus;
681 }
682 }
683 else
684 {
685 pNetFlt->u.s.WinIf.MpUnindicatedMediaStatus = pNetFlt->u.s.WinIf.MpIndicatedMediaStatus;
686 }
687#endif
688
689 return NDIS_STATUS_SUCCESS;
690}
691
692#ifndef VBOXNETADP
693static NDIS_STATUS vboxNetFltWinMpRequestPostSet(PVBOXNETFLTINS pNetFlt)
694{
695 if (pNetFlt->u.s.WinIf.PassDownRequest.DATA.SET_INFORMATION.Oid == OID_GEN_CURRENT_PACKET_FILTER && VBOXNETFLT_PROMISCUOUS_SUPPORTED(pNetFlt))
696 {
697 /* need to disable cleaning promiscuous here ?? */
698 bool fNetFltActive;
699 const bool fWinIfActive = vboxNetFltWinReferenceWinIfNetFlt(pNetFlt, &fNetFltActive);
700
701 Assert(pNetFlt->u.s.WinIf.PassDownRequest.DATA.SET_INFORMATION.InformationBuffer);
702 Assert(!pNetFlt->u.s.WinIf.StateFlags.fProcessingPacketFilter);
703
704 if (fNetFltActive)
705 {
706 Assert(fWinIfActive);
707
708 /* netflt is active, update the cached value */
709 /* TODO: in case we are are not in promiscuous now, we are issuing a request.
710 * what should we do in case of a failure?
711 * i.e. should we update the fUpperProtocolSetFilter in completion routine in this case? etc. */
712 pNetFlt->u.s.WinIf.fUpperProtocolSetFilter = *((PULONG)pNetFlt->u.s.WinIf.PassDownRequest.DATA.SET_INFORMATION.InformationBuffer);
713 pNetFlt->u.s.WinIf.StateFlags.fUpperProtSetFilterInitialized = TRUE;
714
715 if (!(pNetFlt->u.s.WinIf.fOurSetFilter & NDIS_PACKET_TYPE_PROMISCUOUS))
716 {
717 pNetFlt->u.s.WinIf.fSetFilterBuffer = NDIS_PACKET_TYPE_PROMISCUOUS;
718 pNetFlt->u.s.WinIf.PassDownRequest.DATA.SET_INFORMATION.InformationBuffer = &pNetFlt->u.s.WinIf.fSetFilterBuffer;
719 pNetFlt->u.s.WinIf.PassDownRequest.DATA.SET_INFORMATION.InformationBufferLength = sizeof (pNetFlt->u.s.WinIf.fSetFilterBuffer);
720 pNetFlt->u.s.WinIf.StateFlags.fProcessingPacketFilter = 1;
721 pNetFlt->u.s.WinIf.StateFlags.fPPFNetFlt = 1;
722 /* we'll do dereferencing in request complete */
723 }
724 else
725 {
726 vboxNetFltWinDereferenceNetFlt(pNetFlt);
727 vboxNetFltWinDereferenceWinIf(pNetFlt);
728
729 /* we've intercepted the query and completed it */
730 vboxNetFltWinMpRequestStateComplete(pNetFlt);
731 return NDIS_STATUS_SUCCESS;
732 }
733 }
734 else if (fWinIfActive)
735 {
736 pNetFlt->u.s.WinIf.StateFlags.fProcessingPacketFilter = 1;
737 pNetFlt->u.s.WinIf.StateFlags.fPPFNetFlt = 0;
738 /* dereference on completion */
739 }
740 }
741
742 NDIS_STATUS Status;
743
744 NdisRequest(&Status, pNetFlt->u.s.WinIf.hBinding, &pNetFlt->u.s.WinIf.PassDownRequest);
745 if (Status != NDIS_STATUS_PENDING)
746 {
747 vboxNetFltWinPtRequestComplete(pNetFlt, &pNetFlt->u.s.WinIf.PassDownRequest, Status);
748 }
749
750 return Status;
751}
752
753DECLHIDDEN(NDIS_STATUS) vboxNetFltWinMpRequestPost(PVBOXNETFLTINS pNetFlt)
754{
755 switch (pNetFlt->u.s.WinIf.PassDownRequest.RequestType)
756 {
757 case NdisRequestQueryInformation:
758 return vboxNetFltWinMpRequestPostQuery(pNetFlt);
759 case NdisRequestSetInformation:
760 return vboxNetFltWinMpRequestPostSet(pNetFlt);
761 default:
762 AssertBreakpoint();
763 return NDIS_STATUS_FAILURE;
764 }
765}
766
767static NDIS_STATUS vboxNetFltWinMpSetInformation(IN NDIS_HANDLE MiniportAdapterContext,
768 IN NDIS_OID Oid,
769 IN PVOID InformationBuffer,
770 IN ULONG InformationBufferLength,
771 OUT PULONG BytesRead,
772 OUT PULONG BytesNeeded)
773{
774 PVBOXNETFLTINS pNetFlt = (PVBOXNETFLTINS)MiniportAdapterContext;
775 NDIS_STATUS Status = NDIS_STATUS_FAILURE;
776
777 LogFlow(("==>"__FUNCTION__": pNetFlt (0x%p), Oid (%s)\n", pNetFlt, vboxNetFltWinMpDumpOid(Oid)));
778
779 switch (Oid)
780 {
781 case OID_PNP_SET_POWER:
782 {
783 if (InformationBufferLength >= sizeof (NDIS_DEVICE_POWER_STATE))
784 {
785 NDIS_DEVICE_POWER_STATE *penmState = (NDIS_DEVICE_POWER_STATE*)InformationBuffer;
786 Status = vboxNetFltWinMpHandlePowerState(pNetFlt, *penmState);
787 }
788 else
789 {
790 Status = NDIS_STATUS_INVALID_LENGTH;
791 }
792
793 if (Status == NDIS_STATUS_SUCCESS)
794 {
795 *BytesRead = sizeof (NDIS_DEVICE_POWER_STATE);
796 *BytesNeeded = 0;
797 }
798 else
799 {
800 *BytesRead = 0;
801 *BytesNeeded = sizeof (NDIS_DEVICE_POWER_STATE);
802 }
803 break;
804 }
805 default:
806 {
807 /* the oid is to be passed down,
808 * check the device state if we can do it
809 * and update device state accordingly */
810 UINT uOp = vboxNetFltWinMpRequestStatePrep(pNetFlt, &Status);
811 if (uOp)
812 {
813 /* save the request info */
814 pNetFlt->u.s.WinIf.PassDownRequest.RequestType = NdisRequestSetInformation;
815 pNetFlt->u.s.WinIf.PassDownRequest.DATA.SET_INFORMATION.Oid = Oid;
816 pNetFlt->u.s.WinIf.PassDownRequest.DATA.SET_INFORMATION.InformationBuffer = InformationBuffer;
817 pNetFlt->u.s.WinIf.PassDownRequest.DATA.SET_INFORMATION.InformationBufferLength = InformationBufferLength;
818 pNetFlt->u.s.WinIf.pcPDRBytesNeeded = BytesNeeded;
819 pNetFlt->u.s.WinIf.pcPDRBytesRW = BytesRead;
820
821 /* the oid can be processed */
822 if (!(uOp & VBOXNDISREQUEST_QUEUED))
823 {
824 Status = vboxNetFltWinMpRequestPostSet(pNetFlt);
825 }
826 }
827 break;
828 }
829 }
830
831 LogFlow(("<=="__FUNCTION__": pNetFlt (0x%p), Oid (%s), Status (0x%x)\n", pNetFlt, vboxNetFltWinMpDumpOid(Oid), Status));
832
833 return Status;
834}
835#else
836static NDIS_OID g_vboxNetFltWinMpSupportedOids[] =
837{
838 OID_GEN_SUPPORTED_LIST,
839 OID_GEN_HARDWARE_STATUS,
840 OID_GEN_MEDIA_SUPPORTED,
841 OID_GEN_MEDIA_IN_USE,
842 OID_GEN_MAXIMUM_LOOKAHEAD,
843 OID_GEN_CURRENT_LOOKAHEAD,
844 OID_GEN_MAXIMUM_FRAME_SIZE,
845 OID_GEN_MAXIMUM_TOTAL_SIZE,
846 OID_GEN_TRANSMIT_BLOCK_SIZE,
847 OID_GEN_RECEIVE_BLOCK_SIZE,
848 OID_GEN_MAC_OPTIONS,
849 OID_GEN_LINK_SPEED,
850 OID_GEN_TRANSMIT_BUFFER_SPACE,
851 OID_GEN_RECEIVE_BUFFER_SPACE,
852 OID_GEN_VENDOR_ID,
853 OID_GEN_VENDOR_DESCRIPTION,
854 OID_GEN_VENDOR_DRIVER_VERSION,
855 OID_GEN_DRIVER_VERSION,
856 OID_GEN_MAXIMUM_SEND_PACKETS,
857 OID_GEN_MEDIA_CONNECT_STATUS,
858 OID_GEN_CURRENT_PACKET_FILTER,
859 OID_PNP_CAPABILITIES,
860 OID_PNP_QUERY_POWER,
861 OID_GEN_XMIT_OK,
862 OID_GEN_RCV_OK,
863 OID_GEN_XMIT_ERROR,
864 OID_GEN_RCV_ERROR,
865 OID_GEN_RCV_NO_BUFFER,
866 OID_GEN_RCV_CRC_ERROR,
867 OID_GEN_TRANSMIT_QUEUE_LENGTH,
868 OID_PNP_SET_POWER,
869 OID_802_3_PERMANENT_ADDRESS,
870 OID_802_3_CURRENT_ADDRESS,
871 OID_802_3_MULTICAST_LIST,
872 OID_802_3_MAC_OPTIONS,
873 OID_802_3_MAXIMUM_LIST_SIZE,
874 OID_802_3_RCV_ERROR_ALIGNMENT,
875 OID_802_3_XMIT_ONE_COLLISION,
876 OID_802_3_XMIT_MORE_COLLISIONS,
877 OID_802_3_XMIT_DEFERRED,
878 OID_802_3_XMIT_MAX_COLLISIONS,
879 OID_802_3_RCV_OVERRUN,
880 OID_802_3_XMIT_UNDERRUN,
881 OID_802_3_XMIT_HEARTBEAT_FAILURE,
882 OID_802_3_XMIT_TIMES_CRS_LOST,
883 OID_802_3_XMIT_LATE_COLLISIONS,
884};
885
886static NDIS_STATUS vboxNetFltWinMpQueryInformation(IN NDIS_HANDLE MiniportAdapterContext,
887 IN NDIS_OID Oid,
888 IN PVOID InformationBuffer,
889 IN ULONG InformationBufferLength,
890 OUT PULONG BytesWritten,
891 OUT PULONG BytesNeeded)
892{
893 /* static data */
894 static const NDIS_HARDWARE_STATUS enmHwStatus = NdisHardwareStatusReady;
895 static const NDIS_MEDIUM enmMedium = NdisMedium802_3;
896 static NDIS_PNP_CAPABILITIES PnPCaps = {0};
897 static BOOLEAN bPnPCapsInited = FALSE;
898
899 PVBOXNETFLTINS pNetFlt = (PVBOXNETFLTINS)MiniportAdapterContext;
900 NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
901 ULONG64 u64Info = 0;
902 ULONG u32Info = 0;
903 USHORT u16Info = 0;
904 /* default is 4bytes */
905 const void* pvInfo = (void*)&u32Info;
906 ULONG cbInfo = sizeof (u32Info);
907
908 LogFlow(("==>"__FUNCTION__": pNetFlt (0x%p), Oid (%s)\n", pNetFlt, vboxNetFltWinMpDumpOid(Oid)));
909
910 *BytesWritten = 0;
911 *BytesNeeded = 0;
912
913 switch (Oid)
914 {
915 case OID_GEN_SUPPORTED_LIST:
916 pvInfo = g_vboxNetFltWinMpSupportedOids;
917 cbInfo = sizeof (g_vboxNetFltWinMpSupportedOids);
918 break;
919
920 case OID_GEN_HARDWARE_STATUS:
921 pvInfo = &enmHwStatus;
922 cbInfo = sizeof (NDIS_HARDWARE_STATUS);
923 break;
924
925 case OID_GEN_MEDIA_SUPPORTED:
926 case OID_GEN_MEDIA_IN_USE:
927 pvInfo = &enmMedium;
928 cbInfo = sizeof (NDIS_MEDIUM);
929 break;
930
931 case OID_GEN_MAXIMUM_LOOKAHEAD:
932 case OID_GEN_CURRENT_LOOKAHEAD:
933 u32Info = VBOXNETADP_MAX_LOOKAHEAD_SIZE;
934 break;
935
936 case OID_GEN_MAXIMUM_FRAME_SIZE:
937 u32Info = VBOXNETADP_MAX_PACKET_SIZE - VBOXNETADP_HEADER_SIZE;
938 break;
939
940 case OID_GEN_MAXIMUM_TOTAL_SIZE:
941 case OID_GEN_TRANSMIT_BLOCK_SIZE:
942 case OID_GEN_RECEIVE_BLOCK_SIZE:
943 u32Info = VBOXNETADP_MAX_PACKET_SIZE;
944 break;
945
946 case OID_GEN_MAC_OPTIONS:
947 u32Info = NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA |
948 NDIS_MAC_OPTION_TRANSFERS_NOT_PEND |
949 NDIS_MAC_OPTION_NO_LOOPBACK;
950 break;
951
952 case OID_GEN_LINK_SPEED:
953 u32Info = VBOXNETADP_LINK_SPEED;
954 break;
955
956 case OID_GEN_TRANSMIT_BUFFER_SPACE:
957 case OID_GEN_RECEIVE_BUFFER_SPACE:
958 u32Info = VBOXNETADP_MAX_PACKET_SIZE * VBOXNETFLT_PACKET_INFO_POOL_SIZE;
959 break;
960
961 case OID_GEN_VENDOR_ID:
962 u32Info = VBOXNETADP_VENDOR_ID;
963 break;
964
965 case OID_GEN_VENDOR_DESCRIPTION:
966 pvInfo = VBOXNETADP_VENDOR_DESC;
967 cbInfo = sizeof (VBOXNETADP_VENDOR_DESC);
968 break;
969
970 case OID_GEN_VENDOR_DRIVER_VERSION:
971 u32Info = VBOXNETADP_VENDOR_DRIVER_VERSION;
972 break;
973
974 case OID_GEN_DRIVER_VERSION:
975 u16Info = (USHORT)((VBOXNETFLT_VERSION_MP_NDIS_MAJOR << 8) + VBOXNETFLT_VERSION_MP_NDIS_MINOR);
976 pvInfo = (PVOID)&u16Info;
977 cbInfo = sizeof (USHORT);
978 break;
979
980 case OID_GEN_MAXIMUM_SEND_PACKETS:
981 u32Info = VBOXNETFLT_PACKET_INFO_POOL_SIZE;
982 break;
983
984 case OID_GEN_MEDIA_CONNECT_STATUS:
985#ifdef VBOXNETADP_REPORT_DISCONNECTED
986 {
987 bool bNetFltActive;
988 bool bActive = vboxNetFltWinReferenceWinIfNetFltFromAdapt(pNetFlt, bNetFltActive);
989 if (bActive && bNetFltActive)
990 {
991 u32Info = NdisMediaStateConnected;
992 }
993 else
994 {
995 u32Info = NdisMediaStateDisconnected;
996 }
997
998 if (bActive)
999 {
1000 vboxNetFltWinDereferenceWinIf(pNetFlt);
1001 }
1002 if (bNetFltActive)
1003 {
1004 vboxNetFltWinDereferenceNetFlt(pNetFlt);
1005 }
1006 else
1007 {
1008 vboxNetFltWinDereferenceModePassThru(pNetFlt);
1009 }
1010 }
1011#else
1012 u32Info = NdisMediaStateConnected;
1013#endif
1014 break;
1015
1016 case OID_GEN_CURRENT_PACKET_FILTER:
1017 u32Info = NDIS_PACKET_TYPE_BROADCAST
1018 | NDIS_PACKET_TYPE_DIRECTED
1019 | NDIS_PACKET_TYPE_ALL_FUNCTIONAL
1020 | NDIS_PACKET_TYPE_ALL_LOCAL
1021 | NDIS_PACKET_TYPE_GROUP
1022 | NDIS_PACKET_TYPE_MULTICAST;
1023 break;
1024
1025 case OID_PNP_CAPABILITIES:
1026 if (!bPnPCapsInited)
1027 {
1028 PnPCaps.WakeUpCapabilities.MinMagicPacketWakeUp = NdisDeviceStateUnspecified;
1029 PnPCaps.WakeUpCapabilities.MinPatternWakeUp = NdisDeviceStateUnspecified;
1030 bPnPCapsInited = TRUE;
1031 }
1032 cbInfo = sizeof (NDIS_PNP_CAPABILITIES);
1033 pvInfo = &PnPCaps;
1034
1035 break;
1036
1037 case OID_PNP_QUERY_POWER:
1038 Status = NDIS_STATUS_SUCCESS;
1039 break;
1040
1041 case OID_GEN_XMIT_OK:
1042 u64Info = pNetFlt->u.s.WinIf.cTxSuccess;
1043 pvInfo = &u64Info;
1044 if (InformationBufferLength >= sizeof (ULONG64) || InformationBufferLength == 0)
1045 {
1046 cbInfo = sizeof (ULONG64);
1047 }
1048 else
1049 {
1050 cbInfo = sizeof (ULONG);
1051 }
1052 *BytesNeeded = sizeof (ULONG64);
1053 break;
1054
1055 case OID_GEN_RCV_OK:
1056 u64Info = pNetFlt->u.s.WinIf.cRxSuccess;
1057 pvInfo = &u64Info;
1058 if (InformationBufferLength >= sizeof (ULONG64) || InformationBufferLength == 0)
1059 {
1060 cbInfo = sizeof (ULONG64);
1061 }
1062 else
1063 {
1064 cbInfo = sizeof (ULONG);
1065 }
1066 *BytesNeeded = sizeof (ULONG64);
1067 break;
1068
1069 case OID_GEN_XMIT_ERROR:
1070 u32Info = pNetFlt->u.s.WinIf.cTxError;
1071 break;
1072
1073 case OID_GEN_RCV_ERROR:
1074 u32Info = pNetFlt->u.s.WinIf.cRxError;
1075 break;
1076
1077 case OID_GEN_RCV_NO_BUFFER:
1078 case OID_GEN_RCV_CRC_ERROR:
1079 u32Info = 0;
1080 break;
1081
1082 case OID_GEN_TRANSMIT_QUEUE_LENGTH:
1083 u32Info = VBOXNETFLT_PACKET_INFO_POOL_SIZE;
1084 break;
1085
1086 case OID_802_3_PERMANENT_ADDRESS:
1087 pvInfo = &pNetFlt->u.s.MacAddr;
1088 cbInfo = VBOXNETADP_ETH_ADDRESS_LENGTH;
1089 break;
1090
1091 case OID_802_3_CURRENT_ADDRESS:
1092 pvInfo = &pNetFlt->u.s.MacAddr;
1093 cbInfo = VBOXNETADP_ETH_ADDRESS_LENGTH;
1094 break;
1095
1096 case OID_802_3_MAXIMUM_LIST_SIZE:
1097 u32Info = VBOXNETADP_MAX_MCAST_LIST;
1098 break;
1099
1100 case OID_802_3_MAC_OPTIONS:
1101 case OID_802_3_RCV_ERROR_ALIGNMENT:
1102 case OID_802_3_XMIT_ONE_COLLISION:
1103 case OID_802_3_XMIT_MORE_COLLISIONS:
1104 case OID_802_3_XMIT_DEFERRED:
1105 case OID_802_3_XMIT_MAX_COLLISIONS:
1106 case OID_802_3_RCV_OVERRUN:
1107 case OID_802_3_XMIT_UNDERRUN:
1108 case OID_802_3_XMIT_HEARTBEAT_FAILURE:
1109 case OID_802_3_XMIT_TIMES_CRS_LOST:
1110 case OID_802_3_XMIT_LATE_COLLISIONS:
1111 u32Info = 0;
1112 break;
1113
1114 default:
1115 Status = NDIS_STATUS_NOT_SUPPORTED;
1116 break;
1117 }
1118
1119 if (Status == NDIS_STATUS_SUCCESS)
1120 {
1121 if (cbInfo <= InformationBufferLength)
1122 {
1123 *BytesWritten = cbInfo;
1124 if (cbInfo)
1125 NdisMoveMemory(InformationBuffer, pvInfo, cbInfo);
1126 }
1127 else
1128 {
1129 *BytesNeeded = cbInfo;
1130 Status = NDIS_STATUS_INVALID_LENGTH;
1131 }
1132 }
1133
1134
1135 LogFlow(("<=="__FUNCTION__": pNetFlt (0x%p), Oid (%s), Status (0x%x)\n", pNetFlt, vboxNetFltWinMpDumpOid(Oid), Status));
1136
1137 return Status;
1138}
1139
1140static NDIS_STATUS vboxNetFltWinMpSetInformation(IN NDIS_HANDLE MiniportAdapterContext,
1141 IN NDIS_OID Oid,
1142 IN PVOID InformationBuffer,
1143 IN ULONG InformationBufferLength,
1144 OUT PULONG BytesRead,
1145 OUT PULONG BytesNeeded)
1146{
1147 PVBOXNETFLTINS pNetFlt = (PVBOXNETFLTINS) MiniportAdapterContext;
1148 NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
1149
1150 LogFlow(("==>"__FUNCTION__": pNetFlt (0x%p), Oid (%s)\n", pNetFlt, vboxNetFltWinMpDumpOid(Oid)));
1151
1152 *BytesRead = 0;
1153 *BytesNeeded = 0;
1154
1155 switch (Oid)
1156 {
1157 case OID_802_3_MULTICAST_LIST:
1158 *BytesRead = InformationBufferLength;
1159 if (InformationBufferLength % VBOXNETADP_ETH_ADDRESS_LENGTH)
1160 {
1161 Status = NDIS_STATUS_INVALID_LENGTH;
1162 break;
1163 }
1164
1165 if (InformationBufferLength > (VBOXNETADP_MAX_MCAST_LIST * VBOXNETADP_ETH_ADDRESS_LENGTH))
1166 {
1167 Status = NDIS_STATUS_MULTICAST_FULL;
1168 *BytesNeeded = VBOXNETADP_MAX_MCAST_LIST * VBOXNETADP_ETH_ADDRESS_LENGTH;
1169 break;
1170 }
1171 break;
1172
1173 case OID_GEN_CURRENT_PACKET_FILTER:
1174 if (InformationBufferLength != sizeof (ULONG))
1175 {
1176 *BytesNeeded = sizeof (ULONG);
1177 Status = NDIS_STATUS_INVALID_LENGTH;
1178 break;
1179 }
1180
1181 *BytesRead = InformationBufferLength;
1182
1183 break;
1184
1185 case OID_GEN_CURRENT_LOOKAHEAD:
1186 if (InformationBufferLength != sizeof (ULONG)){
1187 *BytesNeeded = sizeof(ULONG);
1188 Status = NDIS_STATUS_INVALID_LENGTH;
1189 break;
1190 }
1191
1192 break;
1193
1194 case OID_PNP_SET_POWER:
1195 if (InformationBufferLength >= sizeof(NDIS_DEVICE_POWER_STATE))
1196 {
1197 NDIS_DEVICE_POWER_STATE *penmState = (NDIS_DEVICE_POWER_STATE*)InformationBuffer;
1198 Status = vboxNetFltWinMpHandlePowerState(pNetFlt, *penmState);
1199 }
1200 else
1201 {
1202 Status = NDIS_STATUS_INVALID_LENGTH;
1203 }
1204
1205 if (Status == NDIS_STATUS_SUCCESS)
1206 {
1207 *BytesRead = sizeof (NDIS_DEVICE_POWER_STATE);
1208 *BytesNeeded = 0;
1209 }
1210 else
1211 {
1212 *BytesRead = 0;
1213 *BytesNeeded = sizeof (NDIS_DEVICE_POWER_STATE);
1214 }
1215 break;
1216
1217 default:
1218 Status = NDIS_STATUS_INVALID_OID;
1219 break;
1220 }
1221
1222 LogFlow(("<=="__FUNCTION__": pNetFlt (0x%p), Oid (%s), Status (0x%x)\n", pNetFlt, vboxNetFltWinMpDumpOid(Oid), Status));
1223
1224 return Status;
1225}
1226
1227#endif
1228
1229#define VBOXNETFLTDUMP_STRCASE(_t) \
1230 case _t: return #_t;
1231#define VBOXNETFLTDUMP_STRCASE_UNKNOWN() \
1232 default: /*Assert(0);*/ return "Unknown";
1233
1234static const char* vboxNetFltWinMpDumpOid(ULONG oid)
1235{
1236 switch (oid)
1237 {
1238 VBOXNETFLTDUMP_STRCASE(OID_GEN_SUPPORTED_LIST)
1239 VBOXNETFLTDUMP_STRCASE(OID_GEN_HARDWARE_STATUS)
1240 VBOXNETFLTDUMP_STRCASE(OID_GEN_MEDIA_SUPPORTED)
1241 VBOXNETFLTDUMP_STRCASE(OID_GEN_MEDIA_IN_USE)
1242 VBOXNETFLTDUMP_STRCASE(OID_GEN_MAXIMUM_LOOKAHEAD)
1243 VBOXNETFLTDUMP_STRCASE(OID_GEN_MAXIMUM_FRAME_SIZE)
1244 VBOXNETFLTDUMP_STRCASE(OID_GEN_LINK_SPEED)
1245 VBOXNETFLTDUMP_STRCASE(OID_GEN_TRANSMIT_BUFFER_SPACE)
1246 VBOXNETFLTDUMP_STRCASE(OID_GEN_RECEIVE_BUFFER_SPACE)
1247 VBOXNETFLTDUMP_STRCASE(OID_GEN_TRANSMIT_BLOCK_SIZE)
1248 VBOXNETFLTDUMP_STRCASE(OID_GEN_RECEIVE_BLOCK_SIZE)
1249 VBOXNETFLTDUMP_STRCASE(OID_GEN_VENDOR_ID)
1250 VBOXNETFLTDUMP_STRCASE(OID_GEN_VENDOR_DESCRIPTION)
1251 VBOXNETFLTDUMP_STRCASE(OID_GEN_CURRENT_PACKET_FILTER)
1252 VBOXNETFLTDUMP_STRCASE(OID_GEN_CURRENT_LOOKAHEAD)
1253 VBOXNETFLTDUMP_STRCASE(OID_GEN_DRIVER_VERSION)
1254 VBOXNETFLTDUMP_STRCASE(OID_GEN_MAXIMUM_TOTAL_SIZE)
1255 VBOXNETFLTDUMP_STRCASE(OID_GEN_PROTOCOL_OPTIONS)
1256 VBOXNETFLTDUMP_STRCASE(OID_GEN_MAC_OPTIONS)
1257 VBOXNETFLTDUMP_STRCASE(OID_GEN_MEDIA_CONNECT_STATUS)
1258 VBOXNETFLTDUMP_STRCASE(OID_GEN_MAXIMUM_SEND_PACKETS)
1259 VBOXNETFLTDUMP_STRCASE(OID_GEN_VENDOR_DRIVER_VERSION)
1260 VBOXNETFLTDUMP_STRCASE(OID_GEN_SUPPORTED_GUIDS)
1261 VBOXNETFLTDUMP_STRCASE(OID_GEN_NETWORK_LAYER_ADDRESSES)
1262 VBOXNETFLTDUMP_STRCASE(OID_GEN_TRANSPORT_HEADER_OFFSET)
1263 VBOXNETFLTDUMP_STRCASE(OID_GEN_MACHINE_NAME)
1264 VBOXNETFLTDUMP_STRCASE(OID_GEN_RNDIS_CONFIG_PARAMETER)
1265 VBOXNETFLTDUMP_STRCASE(OID_GEN_VLAN_ID)
1266 VBOXNETFLTDUMP_STRCASE(OID_GEN_MEDIA_CAPABILITIES)
1267 VBOXNETFLTDUMP_STRCASE(OID_GEN_PHYSICAL_MEDIUM)
1268 VBOXNETFLTDUMP_STRCASE(OID_GEN_XMIT_OK)
1269 VBOXNETFLTDUMP_STRCASE(OID_GEN_RCV_OK)
1270 VBOXNETFLTDUMP_STRCASE(OID_GEN_XMIT_ERROR)
1271 VBOXNETFLTDUMP_STRCASE(OID_GEN_RCV_ERROR)
1272 VBOXNETFLTDUMP_STRCASE(OID_GEN_RCV_NO_BUFFER)
1273 VBOXNETFLTDUMP_STRCASE(OID_GEN_DIRECTED_BYTES_XMIT)
1274 VBOXNETFLTDUMP_STRCASE(OID_GEN_DIRECTED_FRAMES_XMIT)
1275 VBOXNETFLTDUMP_STRCASE(OID_GEN_MULTICAST_BYTES_XMIT)
1276 VBOXNETFLTDUMP_STRCASE(OID_GEN_MULTICAST_FRAMES_XMIT)
1277 VBOXNETFLTDUMP_STRCASE(OID_GEN_BROADCAST_BYTES_XMIT)
1278 VBOXNETFLTDUMP_STRCASE(OID_GEN_BROADCAST_FRAMES_XMIT)
1279 VBOXNETFLTDUMP_STRCASE(OID_GEN_DIRECTED_BYTES_RCV)
1280 VBOXNETFLTDUMP_STRCASE(OID_GEN_DIRECTED_FRAMES_RCV)
1281 VBOXNETFLTDUMP_STRCASE(OID_GEN_MULTICAST_BYTES_RCV)
1282 VBOXNETFLTDUMP_STRCASE(OID_GEN_MULTICAST_FRAMES_RCV)
1283 VBOXNETFLTDUMP_STRCASE(OID_GEN_BROADCAST_BYTES_RCV)
1284 VBOXNETFLTDUMP_STRCASE(OID_GEN_BROADCAST_FRAMES_RCV)
1285 VBOXNETFLTDUMP_STRCASE(OID_GEN_RCV_CRC_ERROR)
1286 VBOXNETFLTDUMP_STRCASE(OID_GEN_TRANSMIT_QUEUE_LENGTH)
1287 VBOXNETFLTDUMP_STRCASE(OID_GEN_GET_TIME_CAPS)
1288 VBOXNETFLTDUMP_STRCASE(OID_GEN_GET_NETCARD_TIME)
1289 VBOXNETFLTDUMP_STRCASE(OID_GEN_NETCARD_LOAD)
1290 VBOXNETFLTDUMP_STRCASE(OID_GEN_DEVICE_PROFILE)
1291 VBOXNETFLTDUMP_STRCASE(OID_GEN_INIT_TIME_MS)
1292 VBOXNETFLTDUMP_STRCASE(OID_GEN_RESET_COUNTS)
1293 VBOXNETFLTDUMP_STRCASE(OID_GEN_MEDIA_SENSE_COUNTS)
1294 VBOXNETFLTDUMP_STRCASE(OID_PNP_CAPABILITIES)
1295 VBOXNETFLTDUMP_STRCASE(OID_PNP_SET_POWER)
1296 VBOXNETFLTDUMP_STRCASE(OID_PNP_QUERY_POWER)
1297 VBOXNETFLTDUMP_STRCASE(OID_PNP_ADD_WAKE_UP_PATTERN)
1298 VBOXNETFLTDUMP_STRCASE(OID_PNP_REMOVE_WAKE_UP_PATTERN)
1299 VBOXNETFLTDUMP_STRCASE(OID_PNP_ENABLE_WAKE_UP)
1300 VBOXNETFLTDUMP_STRCASE(OID_802_3_PERMANENT_ADDRESS)
1301 VBOXNETFLTDUMP_STRCASE(OID_802_3_CURRENT_ADDRESS)
1302 VBOXNETFLTDUMP_STRCASE(OID_802_3_MULTICAST_LIST)
1303 VBOXNETFLTDUMP_STRCASE(OID_802_3_MAXIMUM_LIST_SIZE)
1304 VBOXNETFLTDUMP_STRCASE(OID_802_3_MAC_OPTIONS)
1305 VBOXNETFLTDUMP_STRCASE(OID_802_3_RCV_ERROR_ALIGNMENT)
1306 VBOXNETFLTDUMP_STRCASE(OID_802_3_XMIT_ONE_COLLISION)
1307 VBOXNETFLTDUMP_STRCASE(OID_802_3_XMIT_MORE_COLLISIONS)
1308 VBOXNETFLTDUMP_STRCASE(OID_802_3_XMIT_DEFERRED)
1309 VBOXNETFLTDUMP_STRCASE(OID_802_3_XMIT_MAX_COLLISIONS)
1310 VBOXNETFLTDUMP_STRCASE(OID_802_3_RCV_OVERRUN)
1311 VBOXNETFLTDUMP_STRCASE(OID_802_3_XMIT_UNDERRUN)
1312 VBOXNETFLTDUMP_STRCASE(OID_802_3_XMIT_HEARTBEAT_FAILURE)
1313 VBOXNETFLTDUMP_STRCASE(OID_802_3_XMIT_TIMES_CRS_LOST)
1314 VBOXNETFLTDUMP_STRCASE(OID_802_3_XMIT_LATE_COLLISIONS)
1315 VBOXNETFLTDUMP_STRCASE(OID_TCP_TASK_OFFLOAD)
1316 VBOXNETFLTDUMP_STRCASE(OID_TCP_TASK_IPSEC_ADD_SA)
1317 VBOXNETFLTDUMP_STRCASE(OID_TCP_TASK_IPSEC_DELETE_SA)
1318 VBOXNETFLTDUMP_STRCASE(OID_TCP_SAN_SUPPORT)
1319 VBOXNETFLTDUMP_STRCASE(OID_TCP_TASK_IPSEC_ADD_UDPESP_SA)
1320 VBOXNETFLTDUMP_STRCASE(OID_TCP_TASK_IPSEC_DELETE_UDPESP_SA)
1321 VBOXNETFLTDUMP_STRCASE_UNKNOWN()
1322 }
1323}
1324
1325DECLHIDDEN(VOID) vboxNetFltWinMpReturnPacket(IN NDIS_HANDLE hMiniportAdapterContext, IN PNDIS_PACKET pPacket)
1326{
1327 PVBOXNETFLTINS pNetFlt = (PVBOXNETFLTINS)hMiniportAdapterContext;
1328 PVBOXNETFLT_PKTRSVD_MP pInfo = (PVBOXNETFLT_PKTRSVD_MP)pPacket->MiniportReserved;
1329 PNDIS_PACKET pOrigPacket = pInfo->pOrigPacket;
1330 PVOID pBufToFree = pInfo->pBufToFree;
1331
1332 LogFlow(("==>"__FUNCTION__": pNetFlt (0x%p)\n", pNetFlt));
1333
1334 if (pOrigPacket)
1335 {
1336 /* the packet was sent from underlying miniport */
1337 NdisFreePacket(pPacket);
1338 NdisReturnPackets(&pOrigPacket, 1);
1339 }
1340 else
1341 {
1342 /* the packet was sent from IntNet or it is a packet we allocated on PtReceive for TransferData processing */
1343 vboxNetFltWinFreeSGNdisPacket(pPacket, !pBufToFree /* bFreeMem */);
1344 }
1345
1346 if (pBufToFree)
1347 {
1348 vboxNetFltWinMemFree(pBufToFree);
1349 }
1350
1351 vboxNetFltWinDereferenceWinIf(pNetFlt);
1352
1353 LogFlow(("<=="__FUNCTION__": pNetFlt (0x%p)\n", pNetFlt));
1354}
1355
1356static NDIS_STATUS vboxNetFltWinMpTransferData(OUT PNDIS_PACKET Packet,
1357 OUT PUINT BytesTransferred,
1358 IN NDIS_HANDLE hContext,
1359 IN NDIS_HANDLE MiniportReceiveContext,
1360 IN UINT ByteOffset,
1361 IN UINT BytesToTransfer)
1362{
1363#ifndef VBOXNETADP
1364 PVBOXNETFLTINS pNetFlt = (PVBOXNETFLTINS)hContext;
1365 NDIS_STATUS Status;
1366
1367 LogFlow(("==>"__FUNCTION__": pNetFlt (0x%p)\n", pNetFlt));
1368
1369 if (vboxNetFltWinGetPowerState(&pNetFlt->u.s.WinIf.PtState) != NdisDeviceStateD0
1370 || vboxNetFltWinGetPowerState(&pNetFlt->u.s.WinIf.MpState) != NdisDeviceStateD0)
1371 {
1372 LogFlow(("<=="__FUNCTION__": pNetFlt (0x%p), Status (0x%x)\n", pNetFlt, NDIS_STATUS_FAILURE));
1373 return NDIS_STATUS_FAILURE;
1374 }
1375
1376 NdisTransferData(&Status, pNetFlt->u.s.WinIf.hBinding, MiniportReceiveContext,
1377 ByteOffset, BytesToTransfer, Packet, BytesTransferred);
1378
1379 LogFlow(("<=="__FUNCTION__": pNetFlt (0x%p), Status (0x%x)\n", pNetFlt, Status));
1380 return Status;
1381#else
1382 LogFlow(("==>"__FUNCTION__": pNetFlt (0x%p)\n", hContext));
1383 /* should never be here */
1384 Assert(0);
1385 LogFlow(("<=="__FUNCTION__": pNetFlt (0x%p), Status (0x%x)\n", hContext, NDIS_STATUS_FAILURE));
1386 return NDIS_STATUS_FAILURE;
1387#endif
1388}
1389
1390static void vboxNetFltWinMpHalt(IN NDIS_HANDLE hContext)
1391{
1392 PVBOXNETFLTINS pNetFlt = (PVBOXNETFLTINS)hContext;
1393 NDIS_STATUS Status;
1394
1395 LogFlow(("==>"__FUNCTION__": pNetFlt (0x%p)\n", pNetFlt));
1396
1397#ifndef VBOXNETADP
1398 if (vboxNetFltWinGetWinIfState(pNetFlt) == kVBoxWinIfState_Disconnecting)
1399 {
1400 Assert(vboxNetFltWinGetOpState(&pNetFlt->u.s.WinIf.MpState) == kVBoxNetDevOpState_Deinitializing);
1401 vboxNetFltWinSetOpState(&pNetFlt->u.s.WinIf.MpState, kVBoxNetDevOpState_Deinitializing);
1402
1403 vboxNetFltWinPtCloseInterface(pNetFlt, &Status);
1404
1405 Assert(vboxNetFltWinGetOpState(&pNetFlt->u.s.WinIf.PtState) == kVBoxNetDevOpState_Deinitializing);
1406 vboxNetFltWinSetOpState(&pNetFlt->u.s.WinIf.PtState, kVBoxNetDevOpState_Deinitialized);
1407 vboxNetFltWinSetOpState(&pNetFlt->u.s.WinIf.MpState, kVBoxNetDevOpState_Deinitialized);
1408 }
1409 else
1410#endif
1411 {
1412 /* we're NOT called from protocolUnbinAdapter, perform a full disconnect */
1413 Assert(vboxNetFltWinGetOpState(&pNetFlt->u.s.WinIf.MpState) == kVBoxNetDevOpState_Initialized);
1414#ifndef VBOXNETADP
1415 AssertBreakpoint();
1416#endif
1417 Status = vboxNetFltWinDetachFromInterface(pNetFlt, false);
1418 Assert(Status == NDIS_STATUS_SUCCESS);
1419 }
1420
1421 LogFlow(("<=="__FUNCTION__": pNetFlt (0x%p)\n", pNetFlt));
1422}
1423
1424/**
1425 * register the miniport edge
1426 */
1427DECLHIDDEN(NDIS_STATUS) vboxNetFltWinMpRegister(PVBOXNETFLTGLOBALS_MP pGlobalsMp, PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegistryPathStr)
1428{
1429 NDIS_MINIPORT_CHARACTERISTICS MpChars;
1430
1431 NdisMInitializeWrapper(&pGlobalsMp->hNdisWrapper, pDriverObject, pRegistryPathStr, NULL);
1432
1433 NdisZeroMemory(&MpChars, sizeof (MpChars));
1434
1435 MpChars.MajorNdisVersion = VBOXNETFLT_VERSION_MP_NDIS_MAJOR;
1436 MpChars.MinorNdisVersion = VBOXNETFLT_VERSION_MP_NDIS_MINOR;
1437
1438 MpChars.HaltHandler = vboxNetFltWinMpHalt;
1439 MpChars.InitializeHandler = vboxNetFltWinMpInitialize;
1440 MpChars.QueryInformationHandler = vboxNetFltWinMpQueryInformation;
1441 MpChars.SetInformationHandler = vboxNetFltWinMpSetInformation;
1442 MpChars.TransferDataHandler = vboxNetFltWinMpTransferData;
1443 MpChars.ReturnPacketHandler = vboxNetFltWinMpReturnPacket;
1444 MpChars.SendPacketsHandler = vboxNetFltWinMpSendPackets;
1445
1446#ifndef VBOXNETADP
1447 NDIS_STATUS Status = NdisIMRegisterLayeredMiniport(pGlobalsMp->hNdisWrapper, &MpChars, sizeof (MpChars), &pGlobalsMp->hMiniport);
1448#else
1449 NDIS_STATUS Status = NdisMRegisterMiniport(pGlobalsMp->hNdisWrapper, &MpChars, sizeof (MpChars));
1450#endif
1451 Assert(Status == NDIS_STATUS_SUCCESS);
1452 if (Status == NDIS_STATUS_SUCCESS)
1453 {
1454 NdisMRegisterUnloadHandler(pGlobalsMp->hNdisWrapper, vboxNetFltWinUnload);
1455 }
1456
1457 return Status;
1458}
1459
1460/**
1461 * deregister the miniport edge
1462 */
1463DECLHIDDEN(VOID) vboxNetFltWinMpDeregister(PVBOXNETFLTGLOBALS_MP pGlobalsMp)
1464{
1465#ifndef VBOXNETADP
1466 NdisIMDeregisterLayeredMiniport(pGlobalsMp->hMiniport);
1467#endif
1468 NdisTerminateWrapper(pGlobalsMp->hNdisWrapper, NULL);
1469
1470 NdisZeroMemory(pGlobalsMp, sizeof (*pGlobalsMp));
1471}
1472
1473#ifndef VBOXNETADP
1474
1475DECLHIDDEN(NDIS_STATUS) vboxNetFltWinMpInitializeDevideInstance(PVBOXNETFLTINS pThis)
1476{
1477 NDIS_STATUS Status;
1478 Assert(vboxNetFltWinGetOpState(&pThis->u.s.WinIf.MpState) == kVBoxNetDevOpState_Deinitialized);
1479 vboxNetFltWinSetOpState(&pThis->u.s.WinIf.MpState, kVBoxNetDevOpState_Initializing);
1480
1481 Status = NdisIMInitializeDeviceInstanceEx(g_VBoxNetFltGlobalsWin.Mp.hMiniport,
1482 &pThis->u.s.WinIf.MpDeviceName,
1483 pThis);
1484 if (Status == NDIS_STATUS_SUCCESS)
1485 {
1486 if (pThis->u.s.WinIf.OpenCloseStatus == NDIS_STATUS_SUCCESS)
1487 {
1488 return NDIS_STATUS_SUCCESS;
1489 }
1490 AssertBreakpoint();
1491 vboxNetFltWinMpDeInitializeDeviceInstance(pThis, &Status);
1492 Assert(vboxNetFltWinGetOpState(&pThis->u.s.WinIf.MpState) == kVBoxNetDevOpState_Deinitialized);
1493 vboxNetFltWinSetOpState(&pThis->u.s.WinIf.MpState, kVBoxNetDevOpState_Deinitialized);
1494 return pThis->u.s.WinIf.OpenCloseStatus;
1495 }
1496
1497 Assert(vboxNetFltWinGetOpState(&pThis->u.s.WinIf.MpState) == kVBoxNetDevOpState_Deinitialized);
1498 vboxNetFltWinSetOpState(&pThis->u.s.WinIf.MpState, kVBoxNetDevOpState_Deinitialized);
1499
1500 return Status;
1501}
1502
1503DECLHIDDEN(bool) vboxNetFltWinMpDeInitializeDeviceInstance(PVBOXNETFLTINS pThis, PNDIS_STATUS pStatus)
1504{
1505 NDIS_STATUS Status;
1506
1507 if (vboxNetFltWinGetOpState(&pThis->u.s.WinIf.MpState) == kVBoxNetDevOpState_Initializing)
1508 {
1509 Status = NdisIMCancelInitializeDeviceInstance(g_VBoxNetFltGlobalsWin.Mp.hMiniport, &pThis->u.s.WinIf.MpDeviceName);
1510
1511 if (Status == NDIS_STATUS_SUCCESS)
1512 {
1513 /* we've canceled the initialization successfully */
1514 Assert(pThis->u.s.WinIf.hMiniport == NULL);
1515 Assert(vboxNetFltWinGetOpState(&pThis->u.s.WinIf.MpState) == kVBoxNetDevOpState_Deinitialized);
1516 vboxNetFltWinSetOpState(&pThis->u.s.WinIf.MpState, kVBoxNetDevOpState_Deinitialized);
1517 }
1518 else
1519 {
1520 NdisWaitEvent(&pThis->u.s.WinIf.MpInitCompleteEvent, 0);
1521 }
1522 }
1523
1524 Assert(vboxNetFltWinGetOpState(&pThis->u.s.WinIf.MpState) == kVBoxNetDevOpState_Initialized
1525 || vboxNetFltWinGetOpState(&pThis->u.s.WinIf.MpState) == kVBoxNetDevOpState_Deinitialized);
1526 if (vboxNetFltWinGetOpState(&pThis->u.s.WinIf.MpState) == kVBoxNetDevOpState_Initialized)
1527 {
1528 vboxNetFltWinSetOpState(&pThis->u.s.WinIf.MpState, kVBoxNetDevOpState_Deinitializing);
1529
1530 Status = NdisIMDeInitializeDeviceInstance(pThis->u.s.WinIf.hMiniport);
1531
1532 vboxNetFltWinSetOpState(&pThis->u.s.WinIf.MpState, kVBoxNetDevOpState_Deinitialized);
1533 if (Status != NDIS_STATUS_SUCCESS)
1534 {
1535 Status = NDIS_STATUS_FAILURE;
1536 }
1537
1538 *pStatus = Status;
1539 return true;
1540 }
1541
1542 Assert(vboxNetFltWinGetOpState(&pThis->u.s.WinIf.MpState) == kVBoxNetDevOpState_Deinitialized);
1543 vboxNetFltWinSetOpState(&pThis->u.s.WinIf.MpState, kVBoxNetDevOpState_Deinitialized);
1544
1545 *pStatus = Status;
1546 return false;
1547}
1548#endif
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette