VirtualBox

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

Last change on this file was 106061, checked in by vboxsync, 3 weeks ago

Copyright year updates by scm.

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