VirtualBox

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

Last change on this file since 79846 was 76553, checked in by vboxsync, 6 years ago

scm --update-copyright-year

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