VirtualBox

source: vbox/trunk/src/VBox/HostDrivers/VBoxNetAdp/win/VBoxNetAdp-win.cpp@ 62564

Last change on this file since 62564 was 62490, checked in by vboxsync, 8 years ago

(C) 2016

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 28.0 KB
Line 
1/* $Id: VBoxNetAdp-win.cpp 62490 2016-07-22 18:41:49Z vboxsync $ */
2/** @file
3 * VBoxNetAdp-win.cpp - NDIS6 Host-only Networking Driver, Windows-specific code.
4 */
5/*
6 * Copyright (C) 2014-2016 Oracle Corporation
7 *
8 * This file is part of VirtualBox Open Source Edition (OSE), as
9 * available from http://www.virtualbox.org. This file is free software;
10 * you can redistribute it and/or modify it under the terms of the GNU
11 * General Public License (GPL) as published by the Free Software
12 * Foundation, in version 2 as it comes in the "COPYING" file of the
13 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
14 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
15 */
16
17#define LOG_GROUP LOG_GROUP_NET_ADP_DRV
18
19#include <VBox/log.h>
20#include <VBox/version.h>
21#include <VBox/err.h>
22#include <iprt/initterm.h>
23#include <iprt/assert.h>
24
25RT_C_DECLS_BEGIN
26#include <ndis.h>
27RT_C_DECLS_END
28
29#include "VBoxNetAdp-win.h"
30#include "VBox/VBoxNetCmn-win.h"
31
32/*
33 * By default the link speed reported to be 1Gbps. We may wish to lower
34 * it to 100Mbps to work around issues with multi-cast traffic on the host.
35 * See @bugref{6379}.
36 */
37#define VBOXNETADPWIN_LINK_SPEED 1000000000ULL
38
39/* Forward declarations */
40MINIPORT_INITIALIZE vboxNetAdpWinInitializeEx;
41MINIPORT_HALT vboxNetAdpWinHaltEx;
42MINIPORT_UNLOAD vboxNetAdpWinUnload;
43MINIPORT_PAUSE vboxNetAdpWinPause;
44MINIPORT_RESTART vboxNetAdpWinRestart;
45MINIPORT_OID_REQUEST vboxNetAdpWinOidRequest;
46MINIPORT_SEND_NET_BUFFER_LISTS vboxNetAdpWinSendNetBufferLists;
47MINIPORT_RETURN_NET_BUFFER_LISTS vboxNetAdpWinReturnNetBufferLists;
48MINIPORT_CANCEL_SEND vboxNetAdpWinCancelSend;
49MINIPORT_CHECK_FOR_HANG vboxNetAdpWinCheckForHangEx;
50MINIPORT_RESET vboxNetAdpWinResetEx;
51MINIPORT_DEVICE_PNP_EVENT_NOTIFY vboxNetAdpWinDevicePnPEventNotify;
52MINIPORT_SHUTDOWN vboxNetAdpWinShutdownEx;
53MINIPORT_CANCEL_OID_REQUEST vboxNetAdpWinCancelOidRequest;
54
55
56typedef struct _VBOXNETADPGLOBALS
57{
58 /** ndis device */
59 NDIS_HANDLE hDevice;
60 /** device object */
61 PDEVICE_OBJECT pDevObj;
62 /** our miniport driver handle */
63 NDIS_HANDLE hMiniportDriver;
64 /** power management capabilities, shared by all instances, do not change after init */
65 NDIS_PNP_CAPABILITIES PMCaps;
66} VBOXNETADPGLOBALS, *PVBOXNETADPGLOBALS;
67
68/* win-specific global data */
69VBOXNETADPGLOBALS g_VBoxNetAdpGlobals;
70
71
72typedef struct _VBOXNETADP_ADAPTER {
73 NDIS_HANDLE hAdapter;
74 PVBOXNETADPGLOBALS pGlobals;
75 RTMAC MacAddr;
76} VBOXNETADP_ADAPTER;
77typedef VBOXNETADP_ADAPTER *PVBOXNETADP_ADAPTER;
78
79
80static NTSTATUS vboxNetAdpWinDevDispatch(IN PDEVICE_OBJECT pDevObj, IN PIRP pIrp)
81{
82 PIO_STACK_LOCATION pIrpSl = IoGetCurrentIrpStackLocation(pIrp);;
83 NTSTATUS Status = STATUS_SUCCESS;
84
85 switch (pIrpSl->MajorFunction)
86 {
87 case IRP_MJ_DEVICE_CONTROL:
88 Status = STATUS_NOT_SUPPORTED; // TODO: add/remove ioctls
89 break;
90 case IRP_MJ_CREATE:
91 case IRP_MJ_CLEANUP:
92 case IRP_MJ_CLOSE:
93 break;
94 default:
95 Assert(0);
96 break;
97 }
98
99 pIrp->IoStatus.Status = Status;
100 IoCompleteRequest(pIrp, IO_NO_INCREMENT);
101
102 return Status;
103}
104
105static NDIS_STATUS vboxNetAdpWinDevCreate(PVBOXNETADPGLOBALS pGlobals)
106{
107 NDIS_STRING DevName, LinkName;
108 PDRIVER_DISPATCH aMajorFunctions[IRP_MJ_MAXIMUM_FUNCTION+1];
109 NdisInitUnicodeString(&DevName, VBOXNETADP_NAME_DEVICE);
110 NdisInitUnicodeString(&LinkName, VBOXNETADP_NAME_LINK);
111
112 Assert(!pGlobals->hDevice);
113 Assert(!pGlobals->pDevObj);
114 NdisZeroMemory(aMajorFunctions, sizeof (aMajorFunctions));
115 aMajorFunctions[IRP_MJ_CREATE] = vboxNetAdpWinDevDispatch;
116 aMajorFunctions[IRP_MJ_CLEANUP] = vboxNetAdpWinDevDispatch;
117 aMajorFunctions[IRP_MJ_CLOSE] = vboxNetAdpWinDevDispatch;
118 aMajorFunctions[IRP_MJ_DEVICE_CONTROL] = vboxNetAdpWinDevDispatch;
119
120 NDIS_DEVICE_OBJECT_ATTRIBUTES DeviceAttributes;
121 NdisZeroMemory(&DeviceAttributes, sizeof(DeviceAttributes));
122 DeviceAttributes.Header.Type = NDIS_OBJECT_TYPE_DEVICE_OBJECT_ATTRIBUTES;
123 DeviceAttributes.Header.Revision = NDIS_DEVICE_OBJECT_ATTRIBUTES_REVISION_1;
124 DeviceAttributes.Header.Size = sizeof(DeviceAttributes);
125 DeviceAttributes.DeviceName = &DevName;
126 DeviceAttributes.SymbolicName = &LinkName;
127 DeviceAttributes.MajorFunctions = aMajorFunctions;
128
129 NDIS_STATUS Status = NdisRegisterDeviceEx(pGlobals->hMiniportDriver,
130 &DeviceAttributes,
131 &pGlobals->pDevObj,
132 &pGlobals->hDevice);
133 Log(("vboxNetAdpWinDevCreate: NdisRegisterDeviceEx returned 0x%x\n", Status));
134 Assert(Status == NDIS_STATUS_SUCCESS);
135 return Status;
136}
137
138static void vboxNetAdpWinDevDestroy(PVBOXNETADPGLOBALS pGlobals)
139{
140 Assert(pGlobals->hDevice);
141 Assert(pGlobals->pDevObj);
142 NdisDeregisterDeviceEx(pGlobals->hDevice);
143 pGlobals->hDevice = NULL;
144 pGlobals->pDevObj = NULL;
145}
146
147
148
149
150
151NDIS_OID g_SupportedOids[] =
152{
153 OID_GEN_CURRENT_LOOKAHEAD,
154 OID_GEN_CURRENT_PACKET_FILTER,
155 OID_GEN_INTERRUPT_MODERATION,
156 OID_GEN_LINK_PARAMETERS,
157 OID_GEN_MAXIMUM_TOTAL_SIZE,
158 OID_GEN_RCV_OK,
159 OID_GEN_RECEIVE_BLOCK_SIZE,
160 OID_GEN_RECEIVE_BUFFER_SPACE,
161 OID_GEN_STATISTICS,
162 OID_GEN_TRANSMIT_BLOCK_SIZE,
163 OID_GEN_TRANSMIT_BUFFER_SPACE,
164 OID_GEN_VENDOR_DESCRIPTION,
165 OID_GEN_VENDOR_DRIVER_VERSION,
166 OID_GEN_VENDOR_ID,
167 OID_GEN_XMIT_OK,
168 OID_802_3_PERMANENT_ADDRESS,
169 OID_802_3_CURRENT_ADDRESS,
170 OID_802_3_MULTICAST_LIST,
171 OID_802_3_MAXIMUM_LIST_SIZE,
172 OID_PNP_CAPABILITIES,
173 OID_PNP_QUERY_POWER,
174 OID_PNP_SET_POWER
175};
176
177DECLHIDDEN(NDIS_STATUS) vboxNetAdpWinAllocAdapter(NDIS_HANDLE hAdapter, PVBOXNETADP_ADAPTER *ppAdapter, ULONG uIfIndex)
178{
179 NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
180 PVBOXNETADP_ADAPTER pAdapter = NULL;
181
182 LogFlow(("==>vboxNetAdpWinAllocAdapter: adapter handle=%p\n", hAdapter));
183
184 *ppAdapter = NULL;
185
186 pAdapter = (PVBOXNETADP_ADAPTER)NdisAllocateMemoryWithTagPriority(g_VBoxNetAdpGlobals.hMiniportDriver,
187 sizeof(VBOXNETADP_ADAPTER),
188 VBOXNETADPWIN_TAG,
189 NormalPoolPriority);
190 if (!pAdapter)
191 {
192 Status = NDIS_STATUS_RESOURCES;
193 Log(("vboxNetAdpWinAllocAdapter: Out of memory while allocating adapter context (size=%d)\n", sizeof(VBOXNETADP_ADAPTER)));
194 }
195 else
196 {
197 NdisZeroMemory(pAdapter, sizeof(VBOXNETADP_ADAPTER));
198 pAdapter->hAdapter = hAdapter;
199 pAdapter->pGlobals = &g_VBoxNetAdpGlobals;
200 // TODO: Use netadp structure instead!
201 /* Use a locally administered version of the OUI we use for the guest NICs. */
202 pAdapter->MacAddr.au8[0] = 0x08 | 2;
203 pAdapter->MacAddr.au8[1] = 0x00;
204 pAdapter->MacAddr.au8[2] = 0x27;
205
206 pAdapter->MacAddr.au8[3] = (uIfIndex >> 16) & 0xFF;
207 pAdapter->MacAddr.au8[4] = (uIfIndex >> 8) & 0xFF;
208 pAdapter->MacAddr.au8[5] = uIfIndex & 0xFF;
209
210 //TODO: Statistics?
211
212 *ppAdapter = pAdapter;
213 }
214 LogFlow(("<==vboxNetAdpWinAllocAdapter: status=0x%x\n", Status));
215 return Status;
216}
217
218DECLHIDDEN(void) vboxNetAdpWinFreeAdapter(PVBOXNETADP_ADAPTER pAdapter)
219{
220 NdisFreeMemory(pAdapter, 0, 0);
221}
222
223DECLINLINE(NDIS_MEDIA_CONNECT_STATE) vboxNetAdpWinGetConnectState(PVBOXNETADP_ADAPTER pAdapter)
224{
225 return MediaConnectStateConnected;
226}
227
228
229DECLHIDDEN(NDIS_STATUS) vboxNetAdpWinInitializeEx(IN NDIS_HANDLE NdisMiniportHandle,
230 IN NDIS_HANDLE MiniportDriverContext,
231 IN PNDIS_MINIPORT_INIT_PARAMETERS MiniportInitParameters)
232{
233 PVBOXNETADP_ADAPTER pAdapter = NULL;
234 NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
235
236 LogFlow(("==>vboxNetAdpWinInitializeEx: miniport=0x%x\n", NdisMiniportHandle));
237
238 do
239 {
240 NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES RAttrs = {0};
241 NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES GAttrs = {0};
242
243 Status = vboxNetAdpWinAllocAdapter(NdisMiniportHandle, &pAdapter, MiniportInitParameters->IfIndex);
244 if (Status != NDIS_STATUS_SUCCESS)
245 {
246 Log(("vboxNetAdpWinInitializeEx: Failed to allocate the adapter context with 0x%x\n", Status));
247 break;
248 }
249
250 RAttrs.Header.Type = NDIS_OBJECT_TYPE_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES;
251 RAttrs.Header.Size = NDIS_SIZEOF_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES_REVISION_1;
252 RAttrs.Header.Revision = NDIS_MINIPORT_ADAPTER_REGISTRATION_ATTRIBUTES_REVISION_1;
253 RAttrs.MiniportAdapterContext = pAdapter;
254 RAttrs.AttributeFlags = VBOXNETADPWIN_ATTR_FLAGS; // NDIS_MINIPORT_ATTRIBUTES_NDIS_WDM
255 RAttrs.CheckForHangTimeInSeconds = VBOXNETADPWIN_HANG_CHECK_TIME;
256 RAttrs.InterfaceType = NdisInterfaceInternal;
257
258 Status = NdisMSetMiniportAttributes(NdisMiniportHandle,
259 (PNDIS_MINIPORT_ADAPTER_ATTRIBUTES)&RAttrs);
260 if (Status != NDIS_STATUS_SUCCESS)
261 {
262 Log(("vboxNetAdpWinInitializeEx: NdisMSetMiniportAttributes(registration) failed with 0x%x\n", Status));
263 break;
264 }
265
266 // TODO: Registry?
267
268 // TODO: WDM stack?
269
270 // TODO: DPC?
271
272 GAttrs.Header.Type = NDIS_OBJECT_TYPE_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES;
273 GAttrs.Header.Size = NDIS_SIZEOF_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES_REVISION_1;
274 GAttrs.Header.Revision = NDIS_MINIPORT_ADAPTER_GENERAL_ATTRIBUTES_REVISION_1;
275
276 GAttrs.MediaType = NdisMedium802_3;
277 GAttrs.PhysicalMediumType = NdisPhysicalMediumUnspecified;
278 GAttrs.MtuSize = 1500; //TODO
279 GAttrs.MaxXmitLinkSpeed = VBOXNETADPWIN_LINK_SPEED;
280 GAttrs.XmitLinkSpeed = VBOXNETADPWIN_LINK_SPEED;
281 GAttrs.MaxRcvLinkSpeed = VBOXNETADPWIN_LINK_SPEED;
282 GAttrs.RcvLinkSpeed = VBOXNETADPWIN_LINK_SPEED;
283 GAttrs.MediaConnectState = vboxNetAdpWinGetConnectState(pAdapter);
284 GAttrs.MediaDuplexState = MediaDuplexStateFull;
285 GAttrs.LookaheadSize = 1500; //TODO
286 GAttrs.MacOptions = VBOXNETADP_MAC_OPTIONS;
287 GAttrs.SupportedPacketFilters = VBOXNETADP_SUPPORTED_FILTERS;
288 GAttrs.MaxMulticastListSize = 32; //TODO
289
290 GAttrs.MacAddressLength = ETH_LENGTH_OF_ADDRESS;
291 Assert(GAttrs.MacAddressLength == sizeof(pAdapter->MacAddr));
292 memcpy(GAttrs.PermanentMacAddress, pAdapter->MacAddr.au8, GAttrs.MacAddressLength);
293 memcpy(GAttrs.CurrentMacAddress, pAdapter->MacAddr.au8, GAttrs.MacAddressLength);
294
295 GAttrs.RecvScaleCapabilities = NULL;
296 GAttrs.AccessType = NET_IF_ACCESS_BROADCAST;
297 GAttrs.DirectionType = NET_IF_DIRECTION_SENDRECEIVE;
298 GAttrs.ConnectionType = NET_IF_CONNECTION_DEDICATED;
299 GAttrs.IfType = IF_TYPE_ETHERNET_CSMACD;
300 GAttrs.IfConnectorPresent = false;
301 GAttrs.SupportedStatistics = VBOXNETADPWIN_SUPPORTED_STATISTICS;
302 GAttrs.SupportedPauseFunctions = NdisPauseFunctionsUnsupported;
303 GAttrs.DataBackFillSize = 0;
304 GAttrs.ContextBackFillSize = 0;
305 GAttrs.SupportedOidList = g_SupportedOids;
306 GAttrs.SupportedOidListLength = sizeof(g_SupportedOids);
307 GAttrs.AutoNegotiationFlags = NDIS_LINK_STATE_DUPLEX_AUTO_NEGOTIATED;
308 GAttrs.PowerManagementCapabilities = &g_VBoxNetAdpGlobals.PMCaps;
309
310 Status = NdisMSetMiniportAttributes(NdisMiniportHandle,
311 (PNDIS_MINIPORT_ADAPTER_ATTRIBUTES)&GAttrs);
312 if (Status != NDIS_STATUS_SUCCESS)
313 {
314 Log(("vboxNetAdpWinInitializeEx: NdisMSetMiniportAttributes(general) failed with 0x%x\n", Status));
315 break;
316 }
317 } while (false);
318
319 if (Status != NDIS_STATUS_SUCCESS)
320 {
321 if (pAdapter)
322 vboxNetAdpWinFreeAdapter(pAdapter);
323 }
324
325 LogFlow(("<==vboxNetAdpWinInitializeEx: status=0x%x\n", Status));
326 return Status;
327}
328
329DECLHIDDEN(VOID) vboxNetAdpWinHaltEx(IN NDIS_HANDLE MiniportAdapterContext,
330 IN NDIS_HALT_ACTION HaltAction)
331{
332 PVBOXNETADP_ADAPTER pAdapter = (PVBOXNETADP_ADAPTER)MiniportAdapterContext;
333 LogFlow(("==>vboxNetAdpWinHaltEx\n"));
334 // TODO: Stop something?
335 if (pAdapter)
336 vboxNetAdpWinFreeAdapter(pAdapter);
337 LogFlow(("<==vboxNetAdpWinHaltEx\n"));
338}
339
340DECLHIDDEN(NDIS_STATUS) vboxNetAdpWinPause(IN NDIS_HANDLE MiniportAdapterContext,
341 IN PNDIS_MINIPORT_PAUSE_PARAMETERS MiniportPauseParameters)
342{
343 NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
344 LogFlow(("==>vboxNetAdpWinPause\n"));
345 LogFlow(("<==vboxNetAdpWinPause: status=0x%x\n", Status));
346 return Status;
347}
348
349DECLHIDDEN(NDIS_STATUS) vboxNetAdpWinRestart(IN NDIS_HANDLE MiniportAdapterContext,
350 IN PNDIS_MINIPORT_RESTART_PARAMETERS MiniportRestartParameters)
351{
352 NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
353 LogFlow(("==>vboxNetAdpWinRestart\n"));
354 LogFlow(("<==vboxNetAdpWinRestart: status=0x%x\n", Status));
355 return Status;
356}
357
358DECLHIDDEN(NDIS_STATUS) vboxNetAdpWinOidRqQuery(PVBOXNETADP_ADAPTER pAdapter,
359 PNDIS_OID_REQUEST pRequest)
360{
361 NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
362 struct _NDIS_OID_REQUEST::_REQUEST_DATA::_QUERY *pQuery = &pRequest->DATA.QUERY_INFORMATION;
363
364 LogFlow(("==>vboxNetAdpWinOidRqQuery\n"));
365
366 uint64_t u64Tmp = 0;
367 ULONG ulTmp = 0;
368 PVOID pInfo = &ulTmp;
369 ULONG cbInfo = sizeof(ulTmp);
370
371 switch (pQuery->Oid)
372 {
373 case OID_GEN_INTERRUPT_MODERATION:
374 {
375 PNDIS_INTERRUPT_MODERATION_PARAMETERS pParams =
376 (PNDIS_INTERRUPT_MODERATION_PARAMETERS)pQuery->InformationBuffer;
377 cbInfo = NDIS_SIZEOF_INTERRUPT_MODERATION_PARAMETERS_REVISION_1;
378 if (cbInfo > pQuery->InformationBufferLength)
379 break;
380 pParams->Header.Type = NDIS_OBJECT_TYPE_DEFAULT;
381 pParams->Header.Revision = NDIS_INTERRUPT_MODERATION_PARAMETERS_REVISION_1;
382 pParams->Header.Size = NDIS_SIZEOF_INTERRUPT_MODERATION_PARAMETERS_REVISION_1;
383 pParams->Flags = 0;
384 pParams->InterruptModeration = NdisInterruptModerationNotSupported;
385 pInfo = NULL; /* Do not copy */
386 break;
387 }
388 case OID_GEN_MAXIMUM_TOTAL_SIZE:
389 case OID_GEN_RECEIVE_BLOCK_SIZE:
390 case OID_GEN_TRANSMIT_BLOCK_SIZE:
391 ulTmp = VBOXNETADP_MAX_FRAME_SIZE;
392 break;
393 case OID_GEN_RCV_OK:
394 case OID_GEN_XMIT_OK:
395 u64Tmp = 0;
396 pInfo = &u64Tmp;
397 cbInfo = sizeof(u64Tmp);
398 break;
399 case OID_GEN_RECEIVE_BUFFER_SPACE:
400 case OID_GEN_TRANSMIT_BUFFER_SPACE:
401 // TODO: Make configurable
402 ulTmp = VBOXNETADP_MAX_FRAME_SIZE * 40;
403 break;
404 case OID_GEN_STATISTICS:
405 {
406 PNDIS_STATISTICS_INFO pStats =
407 (PNDIS_STATISTICS_INFO)pQuery->InformationBuffer;
408 cbInfo = NDIS_SIZEOF_STATISTICS_INFO_REVISION_1;
409 if (cbInfo > pQuery->InformationBufferLength)
410 break;
411 pInfo = NULL; /* Do not copy */
412 memset(pStats, 0, cbInfo);
413 pStats->Header.Type = NDIS_OBJECT_TYPE_DEFAULT;
414 pStats->Header.Revision = NDIS_STATISTICS_INFO_REVISION_1;
415 pStats->Header.Size = NDIS_SIZEOF_STATISTICS_INFO_REVISION_1;
416 // TODO: We need some stats, don't we?
417 break;
418 }
419 case OID_GEN_VENDOR_DESCRIPTION:
420 pInfo = VBOXNETADP_VENDOR_NAME;
421 cbInfo = sizeof(VBOXNETADP_VENDOR_NAME);
422 break;
423 case OID_GEN_VENDOR_DRIVER_VERSION:
424 ulTmp = (VBOXNETADP_VERSION_NDIS_MAJOR << 16) | VBOXNETADP_VERSION_NDIS_MINOR;
425 break;
426 case OID_GEN_VENDOR_ID:
427 ulTmp = VBOXNETADP_VENDOR_ID;
428 break;
429 case OID_802_3_PERMANENT_ADDRESS:
430 case OID_802_3_CURRENT_ADDRESS:
431 pInfo = &pAdapter->MacAddr;
432 cbInfo = sizeof(pAdapter->MacAddr);
433 break;
434 //case OID_802_3_MULTICAST_LIST:
435 case OID_802_3_MAXIMUM_LIST_SIZE:
436 ulTmp = VBOXNETADP_MCAST_LIST_SIZE;
437 break;
438 case OID_PNP_CAPABILITIES:
439 pInfo = &pAdapter->pGlobals->PMCaps;
440 cbInfo = sizeof(pAdapter->pGlobals->PMCaps);
441 break;
442 case OID_PNP_QUERY_POWER:
443 pInfo = NULL; /* Do not copy */
444 cbInfo = 0;
445 break;
446 default:
447 Status = NDIS_STATUS_NOT_SUPPORTED;
448 break;
449 }
450
451 if (Status == NDIS_STATUS_SUCCESS)
452 {
453 if (cbInfo > pQuery->InformationBufferLength)
454 {
455 pQuery->BytesNeeded = cbInfo;
456 Status = NDIS_STATUS_BUFFER_TOO_SHORT;
457 }
458 else
459 {
460 if (pInfo)
461 NdisMoveMemory(pQuery->InformationBuffer, pInfo, cbInfo);
462 pQuery->BytesWritten = cbInfo;
463 }
464 }
465
466 LogFlow(("<==vboxNetAdpWinOidRqQuery: status=0x%x\n", Status));
467 return Status;
468}
469
470DECLHIDDEN(NDIS_STATUS) vboxNetAdpWinOidRqSet(PVBOXNETADP_ADAPTER pAdapter,
471 PNDIS_OID_REQUEST pRequest)
472{
473 NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
474 struct _NDIS_OID_REQUEST::_REQUEST_DATA::_SET *pSet = &pRequest->DATA.SET_INFORMATION;
475
476 LogFlow(("==>vboxNetAdpWinOidRqSet\n"));
477
478 switch (pSet->Oid)
479 {
480 case OID_GEN_CURRENT_LOOKAHEAD:
481 if (pSet->InformationBufferLength != sizeof(ULONG))
482 {
483 pSet->BytesNeeded = sizeof(ULONG);
484 Status = NDIS_STATUS_INVALID_LENGTH;
485 break;
486 }
487 // TODO: For the time being we simply ignore lookahead settings.
488 pSet->BytesRead = sizeof(ULONG);
489 Status = NDIS_STATUS_SUCCESS;
490 break;
491
492 case OID_GEN_CURRENT_PACKET_FILTER:
493 if (pSet->InformationBufferLength != sizeof(ULONG))
494 {
495 pSet->BytesNeeded = sizeof(ULONG);
496 Status = NDIS_STATUS_INVALID_LENGTH;
497 break;
498 }
499 // TODO: For the time being we simply ignore packet filter settings.
500 pSet->BytesRead = pSet->InformationBufferLength;
501 Status = NDIS_STATUS_SUCCESS;
502 break;
503
504 case OID_GEN_INTERRUPT_MODERATION:
505 pSet->BytesNeeded = 0;
506 pSet->BytesRead = 0;
507 Status = NDIS_STATUS_INVALID_DATA;
508 break;
509
510 case OID_PNP_SET_POWER:
511 if (pSet->InformationBufferLength < sizeof(NDIS_DEVICE_POWER_STATE))
512 {
513 Status = NDIS_STATUS_INVALID_LENGTH;
514 break;
515 }
516 pSet->BytesRead = sizeof(NDIS_DEVICE_POWER_STATE);
517 Status = NDIS_STATUS_SUCCESS;
518 break;
519
520 default:
521 Status = NDIS_STATUS_NOT_SUPPORTED;
522 break;
523 }
524
525 LogFlow(("<==vboxNetAdpWinOidRqSet: status=0x%x\n", Status));
526 return Status;
527}
528
529DECLHIDDEN(NDIS_STATUS) vboxNetAdpWinOidRequest(IN NDIS_HANDLE MiniportAdapterContext,
530 IN PNDIS_OID_REQUEST NdisRequest)
531{
532 NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
533 PVBOXNETADP_ADAPTER pAdapter = (PVBOXNETADP_ADAPTER)MiniportAdapterContext;
534 LogFlow(("==>vboxNetAdpWinOidRequest\n"));
535 vboxNetCmnWinDumpOidRequest(__FUNCTION__, NdisRequest);
536
537 switch (NdisRequest->RequestType)
538 {
539#if 0
540 case NdisRequestMethod:
541 Status = vboxNetAdpWinOidRqMethod(pAdapter, NdisRequest);
542 break;
543#endif
544
545 case NdisRequestSetInformation:
546 Status = vboxNetAdpWinOidRqSet(pAdapter, NdisRequest);
547 break;
548
549 case NdisRequestQueryInformation:
550 case NdisRequestQueryStatistics:
551 Status = vboxNetAdpWinOidRqQuery(pAdapter, NdisRequest);
552 break;
553
554 default:
555 Status = NDIS_STATUS_NOT_SUPPORTED;
556 break;
557 }
558 LogFlow(("<==vboxNetAdpWinOidRequest: status=0x%x\n", Status));
559 return Status;
560}
561
562DECLHIDDEN(VOID) vboxNetAdpWinSendNetBufferLists(IN NDIS_HANDLE MiniportAdapterContext,
563 IN PNET_BUFFER_LIST NetBufferLists,
564 IN NDIS_PORT_NUMBER PortNumber,
565 IN ULONG SendFlags)
566{
567 PVBOXNETADP_ADAPTER pAdapter = (PVBOXNETADP_ADAPTER)MiniportAdapterContext;
568 LogFlow(("==>vboxNetAdpWinSendNetBufferLists\n"));
569 PNET_BUFFER_LIST pNbl = NetBufferLists;
570 for (pNbl = NetBufferLists; pNbl; pNbl = NET_BUFFER_LIST_NEXT_NBL(pNbl))
571 NET_BUFFER_LIST_STATUS(pNbl) = NDIS_STATUS_SUCCESS;
572 NdisMSendNetBufferListsComplete(pAdapter->hAdapter, NetBufferLists,
573 (SendFlags & NDIS_SEND_FLAGS_DISPATCH_LEVEL) ?
574 NDIS_SEND_COMPLETE_FLAGS_DISPATCH_LEVEL : 0);
575 LogFlow(("<==vboxNetAdpWinSendNetBufferLists\n"));
576}
577
578DECLHIDDEN(VOID) vboxNetAdpWinReturnNetBufferLists(IN NDIS_HANDLE MiniportAdapterContext,
579 IN PNET_BUFFER_LIST NetBufferLists,
580 IN ULONG ReturnFlags)
581{
582 PVBOXNETADP_ADAPTER pAdapter = (PVBOXNETADP_ADAPTER)MiniportAdapterContext;
583 LogFlow(("==>vboxNetAdpWinReturnNetBufferLists\n"));
584 Log(("vboxNetAdpWinReturnNetBufferLists: We should not be here!\n"));
585 LogFlow(("<==vboxNetAdpWinReturnNetBufferLists\n"));
586}
587
588DECLHIDDEN(VOID) vboxNetAdpWinCancelSend(IN NDIS_HANDLE MiniportAdapterContext,
589 IN PVOID CancelId)
590{
591 PVBOXNETADP_ADAPTER pAdapter = (PVBOXNETADP_ADAPTER)MiniportAdapterContext;
592 LogFlow(("==>vboxNetAdpWinCancelSend\n"));
593 Log(("vboxNetAdpWinCancelSend: We should not be here!\n"));
594 LogFlow(("<==vboxNetAdpWinCancelSend\n"));
595}
596
597
598DECLHIDDEN(BOOLEAN) vboxNetAdpWinCheckForHangEx(IN NDIS_HANDLE MiniportAdapterContext)
599{
600 PVBOXNETADP_ADAPTER pAdapter = (PVBOXNETADP_ADAPTER)MiniportAdapterContext;
601 LogFlow(("==>vboxNetAdpWinCheckForHangEx\n"));
602 LogFlow(("<==vboxNetAdpWinCheckForHangEx return false\n"));
603 return FALSE;
604}
605
606DECLHIDDEN(NDIS_STATUS) vboxNetAdpWinResetEx(IN NDIS_HANDLE MiniportAdapterContext,
607 OUT PBOOLEAN AddressingReset)
608{
609 NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
610 LogFlow(("==>vboxNetAdpWinResetEx\n"));
611 LogFlow(("<==vboxNetAdpWinResetEx: status=0x%x\n", Status));
612 return Status;
613}
614
615DECLHIDDEN(VOID) vboxNetAdpWinDevicePnPEventNotify(IN NDIS_HANDLE MiniportAdapterContext,
616 IN PNET_DEVICE_PNP_EVENT NetDevicePnPEvent)
617{
618 PVBOXNETADP_ADAPTER pAdapter = (PVBOXNETADP_ADAPTER)MiniportAdapterContext;
619 LogFlow(("==>vboxNetAdpWinDevicePnPEventNotify\n"));
620 Log(("vboxNetAdpWinDevicePnPEventNotify: PnP event=%d\n", NetDevicePnPEvent->DevicePnPEvent));
621 LogFlow(("<==vboxNetAdpWinDevicePnPEventNotify\n"));
622}
623
624
625DECLHIDDEN(VOID) vboxNetAdpWinShutdownEx(IN NDIS_HANDLE MiniportAdapterContext,
626 IN NDIS_SHUTDOWN_ACTION ShutdownAction)
627{
628 PVBOXNETADP_ADAPTER pAdapter = (PVBOXNETADP_ADAPTER)MiniportAdapterContext;
629 LogFlow(("==>vboxNetAdpWinShutdownEx\n"));
630 Log(("vboxNetAdpWinShutdownEx: action=%d\n", ShutdownAction));
631 LogFlow(("<==vboxNetAdpWinShutdownEx\n"));
632}
633
634DECLHIDDEN(VOID) vboxNetAdpWinCancelOidRequest(IN NDIS_HANDLE MiniportAdapterContext,
635 IN PVOID RequestId)
636{
637 PVBOXNETADP_ADAPTER pAdapter = (PVBOXNETADP_ADAPTER)MiniportAdapterContext;
638 LogFlow(("==>vboxNetAdpWinCancelOidRequest\n"));
639 Log(("vboxNetAdpWinCancelOidRequest: req id=%p\n", RequestId));
640 LogFlow(("<==vboxNetAdpWinCancelOidRequest\n"));
641}
642
643
644
645DECLHIDDEN(VOID) vboxNetAdpWinUnload(IN PDRIVER_OBJECT DriverObject)
646{
647 LogFlow(("==>vboxNetAdpWinUnload\n"));
648 //vboxNetAdpWinDevDestroy(&g_VBoxNetAdpGlobals);
649 if (g_VBoxNetAdpGlobals.hMiniportDriver)
650 NdisMDeregisterMiniportDriver(g_VBoxNetAdpGlobals.hMiniportDriver);
651 //NdisFreeSpinLock(&g_VBoxNetAdpGlobals.Lock);
652 LogFlow(("<==vboxNetAdpWinUnload\n"));
653 RTR0Term();
654}
655
656
657/**
658 * register the miniport driver
659 */
660DECLHIDDEN(NDIS_STATUS) vboxNetAdpWinRegister(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegistryPathStr)
661{
662 NDIS_MINIPORT_DRIVER_CHARACTERISTICS MChars;
663
664 NdisZeroMemory(&MChars, sizeof (MChars));
665
666 MChars.Header.Type = NDIS_OBJECT_TYPE_MINIPORT_DRIVER_CHARACTERISTICS;
667 MChars.Header.Size = sizeof(NDIS_MINIPORT_DRIVER_CHARACTERISTICS);
668 MChars.Header.Revision = NDIS_MINIPORT_DRIVER_CHARACTERISTICS_REVISION_1;
669
670 MChars.MajorNdisVersion = VBOXNETADP_VERSION_NDIS_MAJOR;
671 MChars.MinorNdisVersion = VBOXNETADP_VERSION_NDIS_MINOR;
672
673 MChars.MajorDriverVersion = VBOXNETADP_VERSION_MAJOR;
674 MChars.MinorDriverVersion = VBOXNETADP_VERSION_MINOR;
675
676 MChars.InitializeHandlerEx = vboxNetAdpWinInitializeEx;
677 MChars.HaltHandlerEx = vboxNetAdpWinHaltEx;
678 MChars.UnloadHandler = vboxNetAdpWinUnload;
679 MChars.PauseHandler = vboxNetAdpWinPause;
680 MChars.RestartHandler = vboxNetAdpWinRestart;
681 MChars.OidRequestHandler = vboxNetAdpWinOidRequest;
682 MChars.SendNetBufferListsHandler = vboxNetAdpWinSendNetBufferLists;
683 MChars.ReturnNetBufferListsHandler = vboxNetAdpWinReturnNetBufferLists;
684 MChars.CancelSendHandler = vboxNetAdpWinCancelSend;
685 MChars.CheckForHangHandlerEx = vboxNetAdpWinCheckForHangEx;
686 MChars.ResetHandlerEx = vboxNetAdpWinResetEx;
687 MChars.DevicePnPEventNotifyHandler = vboxNetAdpWinDevicePnPEventNotify;
688 MChars.ShutdownHandlerEx = vboxNetAdpWinShutdownEx;
689 MChars.CancelOidRequestHandler = vboxNetAdpWinCancelOidRequest;
690
691 NDIS_STATUS Status;
692 g_VBoxNetAdpGlobals.hMiniportDriver = NULL;
693 Log(("vboxNetAdpWinRegister: registering miniport driver...\n"));
694 Status = NdisMRegisterMiniportDriver(pDriverObject,
695 pRegistryPathStr,
696 (NDIS_HANDLE)&g_VBoxNetAdpGlobals,
697 &MChars,
698 &g_VBoxNetAdpGlobals.hMiniportDriver);
699 Assert(Status == STATUS_SUCCESS);
700 if (Status == STATUS_SUCCESS)
701 {
702 Log(("vboxNetAdpWinRegister: successfully registered miniport driver; registering device...\n"));
703 //Status = vboxNetAdpWinDevCreate(&g_VBoxNetAdpGlobals);
704 //Assert(Status == STATUS_SUCCESS);
705 //Log(("vboxNetAdpWinRegister: vboxNetAdpWinDevCreate() returned 0x%x\n", Status));
706 }
707 else
708 {
709 Log(("ERROR! vboxNetAdpWinRegister: failed to register miniport driver, status=0x%x", Status));
710 }
711 return Status;
712}
713
714
715RT_C_DECLS_BEGIN
716
717NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject, IN PUNICODE_STRING pRegistryPath);
718
719RT_C_DECLS_END
720
721NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject, IN PUNICODE_STRING pRegistryPath)
722{
723 NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
724 int rc;
725
726
727 rc = RTR0Init(0);
728 AssertRC(rc);
729 if (RT_SUCCESS(rc))
730 {
731 NdisZeroMemory(&g_VBoxNetAdpGlobals, sizeof (g_VBoxNetAdpGlobals));
732 //NdisAllocateSpinLock(&g_VBoxNetAdpGlobals.Lock);
733 //g_VBoxNetAdpGlobals.PMCaps.WakeUpCapabilities.Flags = NDIS_DEVICE_WAKE_UP_ENABLE;
734 g_VBoxNetAdpGlobals.PMCaps.WakeUpCapabilities.MinMagicPacketWakeUp = NdisDeviceStateUnspecified;
735 g_VBoxNetAdpGlobals.PMCaps.WakeUpCapabilities.MinPatternWakeUp = NdisDeviceStateUnspecified;
736
737 Status = vboxNetAdpWinRegister(pDriverObject, pRegistryPath);
738 Assert(Status == STATUS_SUCCESS);
739 if (Status == NDIS_STATUS_SUCCESS)
740 {
741 Log(("NETADP: started successfully\n"));
742 return STATUS_SUCCESS;
743 }
744 //NdisFreeSpinLock(&g_VBoxNetAdpGlobals.Lock);
745 RTLogDestroy(RTLogRelSetDefaultInstance(NULL));
746 RTLogDestroy(RTLogSetDefaultInstance(NULL));
747
748 RTR0Term();
749 }
750 else
751 {
752 Status = NDIS_STATUS_FAILURE;
753 }
754
755 return Status;
756}
757
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