VirtualBox

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

Last change on this file since 65512 was 63564, checked in by vboxsync, 9 years ago

scm: cleaning up todos

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

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