VirtualBox

Changeset 71235 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Mar 6, 2018 11:09:36 AM (7 years ago)
Author:
vboxsync
Message:

NetLwf/Win: (bugref:7933) Fixed module structure corruption that was causing VERR_INTNET_FLT_IF_NOT_FOUND. Offload config buffers are allocated dynamically now.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/HostDrivers/VBoxNetFlt/win/drv/VBoxNetLwf-win.cpp

    r69500 r71235  
    178178    /** MAC address of underlying adapter */
    179179    RTMAC MacAddr;
     180    /** Size of offload config structure */
     181    USHORT cbOffloadConfig;
    180182    /** Saved offload configuration */
    181     NDIS_OFFLOAD SavedOffloadConfig;
     183    PNDIS_OFFLOAD pSavedOffloadConfig;
     184    /** Temporary buffer for disabling offload configuration */
     185    PNDIS_OFFLOAD pDisabledOffloadConfig;
    182186    /** the cloned request we have passed down */
    183187    PNDIS_OID_REQUEST pPendingRequest;
     
    9991003}
    10001004
    1001 static void vboxNetLwfWinUpdateSavedOffloadConfig(PVBOXNETLWF_MODULE pModuleCtx, PNDIS_OFFLOAD pOffload)
    1002 {
    1003     pModuleCtx->SavedOffloadConfig = *pOffload;
    1004     pModuleCtx->fOffloadConfigValid = true;
    1005 }
    1006 
    1007 #ifdef VBOXNETLWF_FIXED_SIZE_POOLS
    1008 static void vboxNetLwfWinFreePools(PVBOXNETLWF_MODULE pModuleCtx, int cPools)
    1009 {
    1010     for (int i = 0; i < cPools; ++i)
    1011     {
    1012         if (pModuleCtx->hPool[i])
    1013         {
    1014             NdisFreeNetBufferListPool(pModuleCtx->hPool[i]);
    1015             Log4(("vboxNetLwfWinAttach: freeed NBL+NB pool 0x%p\n", pModuleCtx->hPool[i]));
    1016         }
    1017     }
    1018 }
    1019 #endif /* VBOXNETLWF_FIXED_SIZE_POOLS */
    1020 
    1021 DECLARE_GLOBAL_CONST_UNICODE_STRING(g_strHostOnlyMiniportName, L"VirtualBox Host-Only");
    1022 
    1023 static NDIS_STATUS vboxNetLwfWinAttach(IN NDIS_HANDLE hFilter, IN NDIS_HANDLE hDriverCtx,
    1024                                        IN PNDIS_FILTER_ATTACH_PARAMETERS pParameters)
    1025 {
    1026     LogFlow(("==>vboxNetLwfWinAttach: filter=%p\n", hFilter));
    1027 
    1028     PVBOXNETLWFGLOBALS pGlobals = (PVBOXNETLWFGLOBALS)hDriverCtx;
    1029     if (!pGlobals)
    1030     {
    1031         vboxNetLwfLogErrorEvent(IO_ERR_INTERNAL_ERROR, NDIS_STATUS_FAILURE, 1);
    1032         return NDIS_STATUS_FAILURE;
    1033     }
    1034 
    1035     /*
    1036      * We need a copy of NDIS_STRING structure as we are going to modify length
    1037      * of the base miniport instance name since RTL does not support comparing
    1038      * first n characters of two strings. We check if miniport names start with
    1039      * "Virtual Host-Only" to detect host-only adapters. It is a waste of resources
    1040      * to bind our filter to host-only adapters since they now operate independently.
    1041      */
    1042     NDIS_STRING strTruncatedInstanceName = *pParameters->BaseMiniportInstanceName; /* Do not copy data, only the structure itself */
    1043     strTruncatedInstanceName.Length = g_strHostOnlyMiniportName.Length; /* Truncate instance name */
    1044     if (RtlEqualUnicodeString(&strTruncatedInstanceName, &g_strHostOnlyMiniportName, TRUE /* Case insensitive */))
    1045     {
    1046         DbgPrint("vboxNetLwfWinAttach: won't attach to %wZ\n", pParameters->BaseMiniportInstanceName);
    1047         return NDIS_STATUS_FAILURE;
    1048     }
    1049 
    1050     ANSI_STRING strMiniportName;
    1051     /* We use the miniport name to associate this filter module with the netflt instance */
    1052     NTSTATUS rc = RtlUnicodeStringToAnsiString(&strMiniportName,
    1053                                                pParameters->BaseMiniportName,
    1054                                                TRUE);
    1055     if (rc != STATUS_SUCCESS)
    1056     {
    1057         LogError(("vboxNetLwfWinAttach: RtlUnicodeStringToAnsiString(%ls) failed with 0x%x\n",
    1058              pParameters->BaseMiniportName, rc));
    1059         vboxNetLwfLogErrorEvent(IO_ERR_INTERNAL_ERROR, NDIS_STATUS_FAILURE, 2);
    1060         return NDIS_STATUS_FAILURE;
    1061     }
    1062     DbgPrint("vboxNetLwfWinAttach: friendly name=%wZ\n", pParameters->BaseMiniportInstanceName);
    1063     DbgPrint("vboxNetLwfWinAttach: name=%Z\n", &strMiniportName);
    1064 
    1065     UINT cbModuleWithNameExtra = sizeof(VBOXNETLWF_MODULE) + strMiniportName.Length;
    1066     PVBOXNETLWF_MODULE pModuleCtx = (PVBOXNETLWF_MODULE)NdisAllocateMemoryWithTagPriority(hFilter,
    1067                                                                       cbModuleWithNameExtra,
    1068                                                                       VBOXNETLWF_MEM_TAG,
    1069                                                                       LowPoolPriority);
    1070     if (!pModuleCtx)
    1071     {
    1072         LogError(("vboxNetLwfWinAttach: Failed to allocate module context for %ls\n", pParameters->BaseMiniportName));
    1073         RtlFreeAnsiString(&strMiniportName);
    1074         vboxNetLwfLogErrorEvent(IO_ERR_INSUFFICIENT_RESOURCES, NDIS_STATUS_RESOURCES, 3);
    1075         return NDIS_STATUS_RESOURCES;
    1076     }
    1077     Log4(("vboxNetLwfWinAttach: allocated module context 0x%p\n", pModuleCtx));
    1078 
    1079     NdisZeroMemory(pModuleCtx, cbModuleWithNameExtra);
    1080     NdisMoveMemory(pModuleCtx->szMiniportName, strMiniportName.Buffer, strMiniportName.Length);
    1081     RtlFreeAnsiString(&strMiniportName);
    1082 
    1083     pModuleCtx->hWorkItem = NdisAllocateIoWorkItem(g_VBoxNetLwfGlobals.hFilterDriver);
    1084     if (!pModuleCtx->hWorkItem)
    1085     {
    1086         LogError(("vboxNetLwfWinAttach: Failed to allocate work item for %ls\n",
    1087                 pParameters->BaseMiniportName));
    1088         NdisFreeMemory(pModuleCtx, 0, 0);
    1089         vboxNetLwfLogErrorEvent(IO_ERR_INSUFFICIENT_RESOURCES, NDIS_STATUS_RESOURCES, 4);
    1090         return NDIS_STATUS_RESOURCES;
    1091     }
    1092 
    1093     Assert(pParameters->MacAddressLength == sizeof(RTMAC));
    1094     NdisMoveMemory(&pModuleCtx->MacAddr, pParameters->CurrentMacAddress, RT_MIN(sizeof(RTMAC), pParameters->MacAddressLength));
    1095     if (pParameters->DefaultOffloadConfiguration)
    1096         vboxNetLwfWinUpdateSavedOffloadConfig(pModuleCtx, pParameters->DefaultOffloadConfiguration);
    1097 
    1098     pModuleCtx->pGlobals  = pGlobals;
    1099     pModuleCtx->hFilter   = hFilter;
    1100     vboxNetLwfWinChangeState(pModuleCtx, LwfState_Attaching);
    1101     /* Initialize transmission mutex and events */
    1102     NDIS_INIT_MUTEX(&pModuleCtx->InTransmit);
    1103 #ifdef VBOXNETLWF_SYNC_SEND
    1104     KeInitializeEvent(&pModuleCtx->EventWire, SynchronizationEvent, FALSE);
    1105     KeInitializeEvent(&pModuleCtx->EventHost, SynchronizationEvent, FALSE);
    1106 #else /* !VBOXNETLWF_SYNC_SEND */
    1107     NdisInitializeEvent(&pModuleCtx->EventSendComplete);
    1108     pModuleCtx->cPendingBuffers = 0;
    1109 #endif /* !VBOXNETLWF_SYNC_SEND */
    1110 
    1111 #ifdef VBOXNETLWF_FIXED_SIZE_POOLS
    1112     for (int i = 0; i < RT_ELEMENTS(g_cbPool); ++i)
    1113     {
    1114         /* Allocate buffer pools */
    1115         NET_BUFFER_LIST_POOL_PARAMETERS PoolParams;
    1116         NdisZeroMemory(&PoolParams, sizeof(PoolParams));
    1117         PoolParams.Header.Type = NDIS_OBJECT_TYPE_DEFAULT;
    1118         PoolParams.Header.Revision = NET_BUFFER_LIST_POOL_PARAMETERS_REVISION_1;
    1119         PoolParams.Header.Size = sizeof(PoolParams);
    1120         PoolParams.ProtocolId = NDIS_PROTOCOL_ID_DEFAULT;
    1121         PoolParams.fAllocateNetBuffer = TRUE;
    1122         PoolParams.ContextSize = 0; /** @todo Do we need to consider underlying drivers? I think not. */
    1123         PoolParams.PoolTag = VBOXNETLWF_MEM_TAG;
    1124         PoolParams.DataSize = g_cbPool[i];
    1125         pModuleCtx->hPool[i] = NdisAllocateNetBufferListPool(hFilter, &PoolParams);
    1126         if (!pModuleCtx->hPool[i])
    1127         {
    1128             LogError(("vboxNetLwfWinAttach: NdisAllocateNetBufferListPool failed\n"));
    1129             vboxNetLwfWinFreePools(pModuleCtx, i);
    1130             NdisFreeIoWorkItem(pModuleCtx->hWorkItem);
    1131             NdisFreeMemory(pModuleCtx, 0, 0);
    1132             vboxNetLwfLogErrorEvent(IO_ERR_INSUFFICIENT_RESOURCES, NDIS_STATUS_RESOURCES, 7);
    1133             return NDIS_STATUS_RESOURCES;
    1134         }
    1135         Log4(("vboxNetLwfWinAttach: allocated NBL+NB pool (data size=%u) 0x%p\n",
    1136               PoolParams.DataSize, pModuleCtx->hPool[i]));
    1137     }
    1138 #else /* !VBOXNETLWF_FIXED_SIZE_POOLS */
    1139     /* Allocate buffer pools */
    1140     NET_BUFFER_LIST_POOL_PARAMETERS PoolParams;
    1141     NdisZeroMemory(&PoolParams, sizeof(PoolParams));
    1142     PoolParams.Header.Type = NDIS_OBJECT_TYPE_DEFAULT;
    1143     PoolParams.Header.Revision = NET_BUFFER_LIST_POOL_PARAMETERS_REVISION_1;
    1144     PoolParams.Header.Size = sizeof(PoolParams);
    1145     PoolParams.ProtocolId = NDIS_PROTOCOL_ID_DEFAULT;
    1146     PoolParams.fAllocateNetBuffer = TRUE;
    1147     PoolParams.ContextSize = 0; /** @todo Do we need to consider underlying drivers? I think not. */
    1148     PoolParams.PoolTag = VBOXNETLWF_MEM_TAG;
    1149     pModuleCtx->hPool = NdisAllocateNetBufferListPool(hFilter, &PoolParams);
    1150     if (!pModuleCtx->hPool)
    1151     {
    1152         LogError(("vboxNetLwfWinAttach: NdisAllocateNetBufferListPool failed\n"));
    1153         NdisFreeIoWorkItem(pModuleCtx->hWorkItem);
    1154         NdisFreeMemory(pModuleCtx, 0, 0);
    1155         vboxNetLwfLogErrorEvent(IO_ERR_INSUFFICIENT_RESOURCES, NDIS_STATUS_RESOURCES, 7);
    1156         return NDIS_STATUS_RESOURCES;
    1157     }
    1158     Log4(("vboxNetLwfWinAttach: allocated NBL+NB pool 0x%p\n", pModuleCtx->hPool));
    1159 #endif /* !VBOXNETLWF_FIXED_SIZE_POOLS */
    1160 
    1161     NDIS_FILTER_ATTRIBUTES Attributes;
    1162     NdisZeroMemory(&Attributes, sizeof(Attributes));
    1163     Attributes.Header.Revision = NDIS_FILTER_ATTRIBUTES_REVISION_1;
    1164     Attributes.Header.Size = sizeof(Attributes);
    1165     Attributes.Header.Type = NDIS_OBJECT_TYPE_FILTER_ATTRIBUTES;
    1166     Attributes.Flags = 0;
    1167     NDIS_STATUS Status = NdisFSetAttributes(hFilter, pModuleCtx, &Attributes);
    1168     if (Status != NDIS_STATUS_SUCCESS)
    1169     {
    1170         LogError(("vboxNetLwfWinAttach: NdisFSetAttributes failed with 0x%x\n", Status));
    1171 #ifdef VBOXNETLWF_FIXED_SIZE_POOLS
    1172         vboxNetLwfWinFreePools(pModuleCtx, RT_ELEMENTS(g_cbPool));
    1173 #else /* !VBOXNETLWF_FIXED_SIZE_POOLS */
    1174         NdisFreeNetBufferListPool(pModuleCtx->hPool);
    1175         Log4(("vboxNetLwfWinAttach: freed NBL+NB pool 0x%p\n", pModuleCtx->hPool));
    1176 #endif /* !VBOXNETLWF_FIXED_SIZE_POOLS */
    1177         NdisFreeIoWorkItem(pModuleCtx->hWorkItem);
    1178         NdisFreeMemory(pModuleCtx, 0, 0);
    1179         vboxNetLwfLogErrorEvent(IO_ERR_INTERNAL_ERROR, NDIS_STATUS_RESOURCES, 5);
    1180         return NDIS_STATUS_RESOURCES;
    1181     }
    1182     /* Insert into module chain */
    1183     NdisAcquireSpinLock(&pGlobals->Lock);
    1184     RTListPrepend(&pGlobals->listModules, &pModuleCtx->node);
    1185     NdisReleaseSpinLock(&pGlobals->Lock);
    1186 
    1187     vboxNetLwfWinChangeState(pModuleCtx, LwfState_Paused);
    1188 
    1189     /// @todo Somehow the packet filter is 0 at this point: Status = vboxNetLwfWinGetPacketFilter(pModuleCtx);
    1190     /// @todo We actually update it later in status handler, perhaps we should not do anything here.
    1191 
    1192     LogFlow(("<==vboxNetLwfWinAttach: Status = 0x%x\n", Status));
    1193     return Status;
    1194 }
    1195 
    1196 static VOID vboxNetLwfWinDetach(IN NDIS_HANDLE hModuleCtx)
    1197 {
    1198     LogFlow(("==>vboxNetLwfWinDetach: module=%p\n", hModuleCtx));
    1199     PVBOXNETLWF_MODULE pModuleCtx = (PVBOXNETLWF_MODULE)hModuleCtx;
    1200     vboxNetLwfWinChangeState(pModuleCtx, LwfState_Detached, LwfState_Paused);
    1201 
    1202     /* Remove from module chain */
    1203     NdisAcquireSpinLock(&pModuleCtx->pGlobals->Lock);
    1204     RTListNodeRemove(&pModuleCtx->node);
    1205     NdisReleaseSpinLock(&pModuleCtx->pGlobals->Lock);
    1206 
    1207     PVBOXNETFLTINS pNetFltIns = pModuleCtx->pNetFlt; /// @todo Atomic?
    1208     if (pNetFltIns && vboxNetFltTryRetainBusyNotDisconnected(pNetFltIns))
    1209     {
    1210         /*
    1211          * Set hModuleCtx to null now in order to prevent filter restart,
    1212          * OID requests and other stuff associated with NetFlt deactivation.
    1213          */
    1214         pNetFltIns->u.s.WinIf.hModuleCtx = NULL;
    1215         /* Notify NetFlt that we are going down */
    1216         pNetFltIns->pSwitchPort->pfnDisconnect(pNetFltIns->pSwitchPort, &pNetFltIns->MyPort, vboxNetFltPortReleaseBusy);
    1217         /* We do not 'release' netflt instance since it has been done by pfnDisconnect */
    1218     }
    1219     pModuleCtx->pNetFlt = NULL;
    1220 
    1221     /*
    1222      * We have to make sure that all NET_BUFFER_LIST structures have been freed by now, but
    1223      * it does not require us to do anything here since it has already been taken care of
    1224      * by vboxNetLwfWinPause().
    1225      */
    1226 #ifdef VBOXNETLWF_FIXED_SIZE_POOLS
    1227     vboxNetLwfWinFreePools(pModuleCtx, RT_ELEMENTS(g_cbPool));
    1228 #else /* !VBOXNETLWF_FIXED_SIZE_POOLS */
    1229     if (pModuleCtx->hPool)
    1230     {
    1231         NdisFreeNetBufferListPool(pModuleCtx->hPool);
    1232         Log4(("vboxNetLwfWinDetach: freed NBL+NB pool 0x%p\n", pModuleCtx->hPool));
    1233     }
    1234 #endif /* !VBOXNETLWF_FIXED_SIZE_POOLS */
    1235     NdisFreeIoWorkItem(pModuleCtx->hWorkItem);
    1236     NdisFreeMemory(hModuleCtx, 0, 0);
    1237     Log4(("vboxNetLwfWinDetach: freed module context 0x%p\n", pModuleCtx));
    1238     LogFlow(("<==vboxNetLwfWinDetach\n"));
    1239 }
    1240 
    1241 
    1242 static NDIS_STATUS vboxNetLwfWinPause(IN NDIS_HANDLE hModuleCtx, IN PNDIS_FILTER_PAUSE_PARAMETERS pParameters)
    1243 {
    1244     RT_NOREF1(pParameters);
    1245     LogFlow(("==>vboxNetLwfWinPause: module=%p\n", hModuleCtx));
    1246     PVBOXNETLWF_MODULE pModuleCtx = (PVBOXNETLWF_MODULE)hModuleCtx;
    1247     vboxNetLwfWinChangeState(pModuleCtx, LwfState_Pausing, LwfState_Running);
    1248     /* Wait for pending send/indication operations to complete. */
    1249     NDIS_WAIT_FOR_MUTEX(&pModuleCtx->InTransmit);
    1250 #ifndef VBOXNETLWF_SYNC_SEND
    1251     NdisWaitEvent(&pModuleCtx->EventSendComplete, 1000 /* ms */);
    1252 #endif /* !VBOXNETLWF_SYNC_SEND */
    1253     vboxNetLwfWinChangeState(pModuleCtx, LwfState_Paused, LwfState_Pausing);
    1254     NDIS_RELEASE_MUTEX(&pModuleCtx->InTransmit);
    1255     LogFlow(("<==vboxNetLwfWinPause\n"));
    1256     return NDIS_STATUS_SUCCESS; /* Failure is not an option */
    1257 }
    1258 
    1259 
    1260 static void vboxNetLwfWinIndicateOffload(PVBOXNETLWF_MODULE pModuleCtx, PNDIS_OFFLOAD pOffload)
    1261 {
    1262     Log5(("vboxNetLwfWinIndicateOffload: offload config changed to:\n"));
    1263     vboxNetLwfWinDumpOffloadSettings(pOffload);
    1264     NDIS_STATUS_INDICATION OffloadingIndication;
    1265     NdisZeroMemory(&OffloadingIndication, sizeof(OffloadingIndication));
    1266     OffloadingIndication.Header.Type = NDIS_OBJECT_TYPE_STATUS_INDICATION;
    1267     OffloadingIndication.Header.Revision = NDIS_STATUS_INDICATION_REVISION_1;
    1268     OffloadingIndication.Header.Size = NDIS_SIZEOF_STATUS_INDICATION_REVISION_1;
    1269     OffloadingIndication.SourceHandle = pModuleCtx->hFilter;
    1270     OffloadingIndication.StatusCode = NDIS_STATUS_TASK_OFFLOAD_CURRENT_CONFIG;
    1271     OffloadingIndication.StatusBuffer = pOffload;
    1272     OffloadingIndication.StatusBufferSize = sizeof(NDIS_OFFLOAD);
    1273     NdisFIndicateStatus(pModuleCtx->hFilter, &OffloadingIndication);
    1274 }
    1275 
    1276 
    1277 static NDIS_STATUS vboxNetLwfWinRestart(IN NDIS_HANDLE hModuleCtx, IN PNDIS_FILTER_RESTART_PARAMETERS pParameters)
    1278 {
    1279     RT_NOREF1(pParameters);
    1280     LogFlow(("==>vboxNetLwfWinRestart: module=%p\n", hModuleCtx));
    1281     PVBOXNETLWF_MODULE pModuleCtx = (PVBOXNETLWF_MODULE)hModuleCtx;
    1282     vboxNetLwfWinChangeState(pModuleCtx, LwfState_Restarting, LwfState_Paused);
    1283     vboxNetLwfWinChangeState(pModuleCtx, LwfState_Running, LwfState_Restarting);
    1284     NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
    1285     LogFlow(("<==vboxNetLwfWinRestart: Status = 0x%x\n", Status));
    1286     return Status;
    1287 }
    1288 
    1289 
    1290 static void vboxNetLwfWinDestroySG(PINTNETSG pSG)
    1291 {
    1292     NdisFreeMemory(pSG, 0, 0);
    1293     Log4(("vboxNetLwfWinDestroySG: freed SG 0x%p\n", pSG));
    1294 }
    1295 
    1296 DECLINLINE(ULONG) vboxNetLwfWinCalcSegments(PNET_BUFFER pNetBuf)
    1297 {
    1298     ULONG cSegs = 0;
    1299     for (PMDL pMdl = NET_BUFFER_CURRENT_MDL(pNetBuf); pMdl; pMdl = NDIS_MDL_LINKAGE(pMdl))
    1300         cSegs++;
    1301     return cSegs;
    1302 }
    1303 
    1304 DECLINLINE(void) vboxNetLwfWinFreeMdlChain(PMDL pMdl)
    1305 {
    1306 #ifndef VBOXNETLWF_FIXED_SIZE_POOLS
    1307     PMDL pMdlNext;
    1308     while (pMdl)
    1309     {
    1310         pMdlNext = pMdl->Next;
    1311 # ifndef VBOXNETLWF_SYNC_SEND
    1312         PUCHAR pDataBuf;
    1313         ULONG cb = 0;
    1314         NdisQueryMdl(pMdl, &pDataBuf, &cb, NormalPagePriority);
    1315 # endif /* !VBOXNETLWF_SYNC_SEND */
    1316         NdisFreeMdl(pMdl);
    1317         Log4(("vboxNetLwfWinFreeMdlChain: freed MDL 0x%p\n", pMdl));
    1318 # ifndef VBOXNETLWF_SYNC_SEND
    1319         NdisFreeMemory(pDataBuf, 0, 0);
    1320         Log4(("vboxNetLwfWinFreeMdlChain: freed data buffer 0x%p\n", pDataBuf));
    1321 # endif /* !VBOXNETLWF_SYNC_SEND */
    1322         pMdl = pMdlNext;
    1323     }
    1324 #else  /* VBOXNETLWF_FIXED_SIZE_POOLS */
    1325     RT_NOREF1(pMdl);
    1326 #endif /* VBOXNETLWF_FIXED_SIZE_POOLS */
    1327 }
    1328 
    1329 /** @todo
    1330  * 1) Copy data from SG to MDL (if we decide to complete asynchronously).
    1331  * 2) Provide context/backfill space. Nobody does it, should we?
    1332  * 3) We always get a single segment from intnet. Simplify?
    1333  */
    1334 static PNET_BUFFER_LIST vboxNetLwfWinSGtoNB(PVBOXNETLWF_MODULE pModule, PINTNETSG pSG)
    1335 {
    1336     AssertReturn(pSG->cSegsUsed >= 1, NULL);
    1337     LogFlow(("==>vboxNetLwfWinSGtoNB: segments=%d hPool=%p cb=%u\n", pSG->cSegsUsed,
    1338              pModule->hPool, pSG->cbTotal));
    1339     AssertReturn(pModule->hPool, NULL);
    1340 
    1341 #ifdef VBOXNETLWF_SYNC_SEND
    1342     PINTNETSEG pSeg = pSG->aSegs;
    1343     PMDL pMdl = NdisAllocateMdl(pModule->hFilter, pSeg->pv, pSeg->cb);
    1344     if (!pMdl)
    1345     {
    1346         LogError(("vboxNetLwfWinSGtoNB: failed to allocate an MDL\n"));
    1347         LogFlow(("<==vboxNetLwfWinSGtoNB: return NULL\n"));
    1348         return NULL;
    1349     }
    1350     Log4(("vboxNetLwfWinSGtoNB: allocated Mdl 0x%p\n", pMdl));
    1351     PMDL pMdlCurr = pMdl;
    1352     for (int i = 1; i < pSG->cSegsUsed; i++)
    1353     {
    1354         pSeg = &pSG->aSegs[i];
    1355         pMdlCurr->Next = NdisAllocateMdl(pModule->hFilter, pSeg->pv, pSeg->cb);
    1356         if (!pMdlCurr->Next)
    1357         {
    1358             LogError(("vboxNetLwfWinSGtoNB: failed to allocate an MDL\n"));
    1359             /* Tear down all MDL we chained so far */
    1360             vboxNetLwfWinFreeMdlChain(pMdl);
    1361             return NULL;
    1362         }
    1363         pMdlCurr = pMdlCurr->Next;
    1364         Log4(("vboxNetLwfWinSGtoNB: allocated Mdl 0x%p\n", pMdlCurr));
    1365     }
    1366     PNET_BUFFER_LIST pBufList = NdisAllocateNetBufferAndNetBufferList(pModule->hPool,
    1367                                                                       0 /* ContextSize */,
    1368                                                                       0 /* ContextBackFill */,
    1369                                                                       pMdl,
    1370                                                                       0 /* DataOffset */,
    1371                                                                       pSG->cbTotal);
    1372     if (pBufList)
    1373     {
    1374         Log4(("vboxNetLwfWinSGtoNB: allocated NBL+NB 0x%p\n", pBufList));
    1375         pBufList->SourceHandle = pModule->hFilter;
    1376         /** @todo Do we need to initialize anything else? */
    1377     }
    1378     else
    1379     {
    1380         LogError(("vboxNetLwfWinSGtoNB: failed to allocate an NBL+NB\n"));
    1381         vboxNetLwfWinFreeMdlChain(pMdl);
    1382     }
    1383 #else /* !VBOXNETLWF_SYNC_SEND */
    1384 
    1385 # ifdef VBOXNETLWF_FIXED_SIZE_POOLS
    1386     int iPool = 0;
    1387     ULONG cbFrame = VBOXNETLWF_MAX_FRAME_SIZE(pSG->cbTotal);
    1388     /* Let's find the appropriate pool first */
    1389     for (iPool = 0; iPool < RT_ELEMENTS(g_cbPool); ++iPool)
    1390         if (cbFrame <= g_cbPool[iPool])
    1391             break;
    1392     if (iPool >= RT_ELEMENTS(g_cbPool))
    1393     {
    1394         LogError(("vboxNetLwfWinSGtoNB: frame is too big (%u > %u), drop it.\n", cbFrame, g_cbPool[RT_ELEMENTS(g_cbPool)-1]));
    1395         LogFlow(("<==vboxNetLwfWinSGtoNB: return NULL\n"));
    1396         return NULL;
    1397     }
    1398     PNET_BUFFER_LIST pBufList = NdisAllocateNetBufferList(pModule->hPool[iPool],
    1399                                                           0 /** @todo ContextSize */,
    1400                                                           0 /** @todo ContextBackFill */);
    1401     if (!pBufList)
    1402     {
    1403         LogError(("vboxNetLwfWinSGtoNB: failed to allocate netbuffer (cb=%u) from pool %d\n", cbFrame, iPool));
    1404         LogFlow(("<==vboxNetLwfWinSGtoNB: return NULL\n"));
    1405         return NULL;
    1406     }
    1407     const ULONG cbAlignmentMask = sizeof(USHORT) - 1; /* Microsoft LB/FO provider expects packets to be aligned at word boundary. */
    1408     ULONG cbAlignedFrame = (pSG->cbTotal + cbAlignmentMask) & ~cbAlignmentMask;
    1409     Assert(cbAlignedFrame >= pSG->cbTotal);
    1410     Assert(cbFrame >= cbAlignedFrame);
    1411     NET_BUFFER *pBuffer = NET_BUFFER_LIST_FIRST_NB(pBufList);
    1412     NDIS_STATUS Status = NdisRetreatNetBufferDataStart(pBuffer, cbAlignedFrame, 0 /** @todo DataBackfill */, NULL);
    1413     if (Status == NDIS_STATUS_SUCCESS)
    1414     {
    1415         uint8_t *pDst = (uint8_t*)NdisGetDataBuffer(pBuffer, pSG->cbTotal, NULL, 1, 0);
    1416         if (pDst)
    1417         {
    1418             for (int i = 0; i < pSG->cSegsUsed; i++)
    1419             {
    1420                 NdisMoveMemory(pDst, pSG->aSegs[i].pv, pSG->aSegs[i].cb);
    1421                 pDst += pSG->aSegs[i].cb;
    1422             }
    1423             if (cbAlignedFrame > pSG->cbTotal)
    1424             {
    1425                 Log4(("vboxNetLwfWinSGtoNB: padding %d-byte packet with %d zero bytes", pSG->cbTotal, cbAlignedFrame - pSG->cbTotal));
    1426                 NdisZeroMemory(pDst, cbAlignedFrame - pSG->cbTotal);
    1427             }
    1428             Log4(("vboxNetLwfWinSGtoNB: allocated NBL+NB 0x%p\n", pBufList));
    1429             pBufList->SourceHandle = pModule->hFilter;
    1430         }
    1431         else
    1432         {
    1433             LogError(("vboxNetLwfWinSGtoNB: failed to obtain the buffer pointer (size=%u)\n", pSG->cbTotal));
    1434             NdisAdvanceNetBufferDataStart(pBuffer, cbAlignedFrame, false, NULL); /** @todo why bother? */
    1435             NdisFreeNetBufferList(pBufList);
    1436             pBufList = NULL;
    1437         }
    1438     }
    1439     else
    1440     {
    1441         LogError(("vboxNetLwfWinSGtoNB: NdisRetreatNetBufferDataStart failed with 0x%x (size=%u)\n", Status, pSG->cbTotal));
    1442         NdisFreeNetBufferList(pBufList);
    1443         pBufList = NULL;
    1444     }
    1445 # else /* !VBOXNETLWF_FIXED_SIZE_POOLS */
    1446     PNET_BUFFER_LIST pBufList = NULL;
    1447     ULONG cbMdl = VBOXNETLWF_MAX_FRAME_SIZE(pSG->cbTotal);
    1448     ULONG uDataOffset = cbMdl - pSG->cbTotal;
    1449     PUCHAR pDataBuf = (PUCHAR)NdisAllocateMemoryWithTagPriority(pModule->hFilter, cbMdl,
    1450                                                                 VBOXNETLWF_MEM_TAG, NormalPoolPriority);
    1451     if (pDataBuf)
    1452     {
    1453         Log4(("vboxNetLwfWinSGtoNB: allocated data buffer (cb=%u) 0x%p\n", cbMdl, pDataBuf));
    1454         PMDL pMdl = NdisAllocateMdl(pModule->hFilter, pDataBuf, cbMdl);
    1455         if (!pMdl)
    1456         {
    1457             NdisFreeMemory(pDataBuf, 0, 0);
    1458             Log4(("vboxNetLwfWinSGtoNB: freed data buffer 0x%p\n", pDataBuf));
    1459             LogError(("vboxNetLwfWinSGtoNB: failed to allocate an MDL (cb=%u)\n", cbMdl));
    1460             LogFlow(("<==vboxNetLwfWinSGtoNB: return NULL\n"));
    1461             return NULL;
    1462         }
    1463         PUCHAR pDst = pDataBuf + uDataOffset;
    1464         for (int i = 0; i < pSG->cSegsUsed; i++)
    1465         {
    1466             NdisMoveMemory(pDst, pSG->aSegs[i].pv, pSG->aSegs[i].cb);
    1467             pDst += pSG->aSegs[i].cb;
    1468         }
    1469         pBufList = NdisAllocateNetBufferAndNetBufferList(pModule->hPool,
    1470                                                          0 /* ContextSize */,
    1471                                                          0 /* ContextBackFill */,
    1472                                                          pMdl,
    1473                                                          uDataOffset,
    1474                                                          pSG->cbTotal);
    1475         if (pBufList)
    1476         {
    1477             Log4(("vboxNetLwfWinSGtoNB: allocated NBL+NB 0x%p\n", pBufList));
    1478             pBufList->SourceHandle = pModule->hFilter;
    1479             /** @todo Do we need to initialize anything else? */
    1480         }
    1481         else
    1482         {
    1483             LogError(("vboxNetLwfWinSGtoNB: failed to allocate an NBL+NB\n"));
    1484             vboxNetLwfWinFreeMdlChain(pMdl);
    1485         }
    1486     }
    1487     else
    1488     {
    1489         LogError(("vboxNetLwfWinSGtoNB: failed to allocate data buffer (size=%u)\n", cbMdl));
    1490     }
    1491 # endif /* !VBOXNETLWF_FIXED_SIZE_POOLS */
    1492 
    1493 #endif /* !VBOXNETLWF_SYNC_SEND */
    1494     LogFlow(("<==vboxNetLwfWinSGtoNB: return %p\n", pBufList));
    1495     return pBufList;
    1496 }
    1497 
    1498 static PINTNETSG vboxNetLwfWinNBtoSG(PVBOXNETLWF_MODULE pModule, PNET_BUFFER pNetBuf)
    1499 {
    1500     ULONG cbPacket = NET_BUFFER_DATA_LENGTH(pNetBuf);
    1501     UINT cSegs = vboxNetLwfWinCalcSegments(pNetBuf);
    1502     /* Allocate and initialize SG */
    1503     PINTNETSG pSG = (PINTNETSG)NdisAllocateMemoryWithTagPriority(pModule->hFilter,
    1504                                                                  RT_OFFSETOF(INTNETSG, aSegs[cSegs]),
    1505                                                                  VBOXNETLWF_MEM_TAG,
    1506                                                                  NormalPoolPriority);
    1507     AssertReturn(pSG, pSG);
    1508     Log4(("vboxNetLwfWinNBtoSG: allocated SG 0x%p\n", pSG));
    1509     IntNetSgInitTempSegs(pSG, cbPacket /*cbTotal*/, cSegs, cSegs /*cSegsUsed*/);
    1510 
    1511     int rc = NDIS_STATUS_SUCCESS;
    1512     ULONG uOffset = NET_BUFFER_CURRENT_MDL_OFFSET(pNetBuf);
    1513     cSegs = 0;
    1514     for (PMDL pMdl = NET_BUFFER_CURRENT_MDL(pNetBuf);
    1515          pMdl != NULL && cbPacket > 0;
    1516          pMdl = NDIS_MDL_LINKAGE(pMdl))
    1517     {
    1518         PUCHAR pSrc = (PUCHAR)MmGetSystemAddressForMdlSafe(pMdl, LowPagePriority);
    1519         if (!pSrc)
    1520         {
    1521             rc = NDIS_STATUS_RESOURCES;
    1522             break;
    1523         }
    1524         ULONG cbSrc = MmGetMdlByteCount(pMdl);
    1525         if (uOffset)
    1526         {
    1527             Assert(uOffset < cbSrc);
    1528             pSrc  += uOffset;
    1529             cbSrc -= uOffset;
    1530             uOffset = 0;
    1531         }
    1532 
    1533         if (cbSrc > cbPacket)
    1534             cbSrc = cbPacket;
    1535 
    1536         pSG->aSegs[cSegs].pv = pSrc;
    1537         pSG->aSegs[cSegs].cb = cbSrc;
    1538         pSG->aSegs[cSegs].Phys = NIL_RTHCPHYS;
    1539         cSegs++;
    1540         cbPacket -= cbSrc;
    1541     }
    1542 
    1543     Assert(cSegs <= pSG->cSegsAlloc);
    1544 
    1545     if (RT_FAILURE(rc))
    1546     {
    1547         vboxNetLwfWinDestroySG(pSG);
    1548         pSG = NULL;
    1549     }
    1550     else
    1551     {
    1552         Assert(cbPacket == 0);
    1553         Assert(pSG->cSegsUsed == cSegs);
    1554     }
    1555     return pSG;
    1556 }
    1557 
    15581005static void vboxNetLwfWinDisableOffloading(PNDIS_OFFLOAD pOffloadConfig)
    15591006{
     
    15761023    pOffloadConfig->LsoV2.IPv6.IpExtensionHeadersSupported            = NDIS_OFFLOAD_NOT_SUPPORTED;
    15771024    pOffloadConfig->LsoV2.IPv6.TcpOptionsSupported                    = NDIS_OFFLOAD_NOT_SUPPORTED;
     1025}
     1026
     1027static void vboxNetLwfWinUpdateSavedOffloadConfig(PVBOXNETLWF_MODULE pModuleCtx, PNDIS_OFFLOAD pOffload)
     1028{
     1029    if (pModuleCtx->cbOffloadConfig < pOffload->Header.Size)
     1030    {
     1031        vboxNetLwfLogErrorEvent(IO_ERR_INTERNAL_ERROR, STATUS_SUCCESS, 10);
     1032        return;
     1033    }
     1034
     1035    NdisMoveMemory(pModuleCtx->pSavedOffloadConfig, pOffload, pOffload->Header.Size);
     1036    NdisMoveMemory(pModuleCtx->pDisabledOffloadConfig, pOffload, pOffload->Header.Size);
     1037    vboxNetLwfWinDisableOffloading(pModuleCtx->pDisabledOffloadConfig);
     1038    pModuleCtx->fOffloadConfigValid = true;
     1039}
     1040
     1041#ifdef VBOXNETLWF_FIXED_SIZE_POOLS
     1042static void vboxNetLwfWinFreePools(PVBOXNETLWF_MODULE pModuleCtx, int cPools)
     1043{
     1044    for (int i = 0; i < cPools; ++i)
     1045    {
     1046        if (pModuleCtx->hPool[i])
     1047        {
     1048            NdisFreeNetBufferListPool(pModuleCtx->hPool[i]);
     1049            Log4(("vboxNetLwfWinFreePools: freed NBL+NB pool 0x%p\n", pModuleCtx->hPool[i]));
     1050        }
     1051    }
     1052}
     1053#endif /* VBOXNETLWF_FIXED_SIZE_POOLS */
     1054
     1055
     1056static void vboxNetLwfWinFreeModuleResources(PVBOXNETLWF_MODULE pModuleCtx)
     1057{
     1058#ifdef VBOXNETLWF_FIXED_SIZE_POOLS
     1059    vboxNetLwfWinFreePools(pModuleCtx, RT_ELEMENTS(g_cbPool));
     1060#else /* !VBOXNETLWF_FIXED_SIZE_POOLS */
     1061    if (pModuleCtx->hPool)
     1062    {
     1063        NdisFreeNetBufferListPool(pModuleCtx->hPool);
     1064        Log4(("vboxNetLwfWinFreeModuleResources: freed NBL+NB pool 0x%p\n", pModuleCtx->hPool));
     1065    }
     1066#endif /* !VBOXNETLWF_FIXED_SIZE_POOLS */
     1067    if (pModuleCtx->pDisabledOffloadConfig)
     1068        NdisFreeMemory(pModuleCtx->pDisabledOffloadConfig, 0, 0);
     1069    if (pModuleCtx->pSavedOffloadConfig)
     1070        NdisFreeMemory(pModuleCtx->pSavedOffloadConfig, 0, 0);
     1071    if (pModuleCtx->hWorkItem)
     1072        NdisFreeIoWorkItem(pModuleCtx->hWorkItem);
     1073    NdisFreeMemory(pModuleCtx, 0, 0);
     1074}
     1075
     1076
     1077DECLARE_GLOBAL_CONST_UNICODE_STRING(g_strHostOnlyMiniportName, L"VirtualBox Host-Only");
     1078
     1079static NDIS_STATUS vboxNetLwfWinAttach(IN NDIS_HANDLE hFilter, IN NDIS_HANDLE hDriverCtx,
     1080                                       IN PNDIS_FILTER_ATTACH_PARAMETERS pParameters)
     1081{
     1082    LogFlow(("==>vboxNetLwfWinAttach: filter=%p\n", hFilter));
     1083
     1084    PVBOXNETLWFGLOBALS pGlobals = (PVBOXNETLWFGLOBALS)hDriverCtx;
     1085    if (!pGlobals)
     1086    {
     1087        vboxNetLwfLogErrorEvent(IO_ERR_INTERNAL_ERROR, NDIS_STATUS_FAILURE, 1);
     1088        return NDIS_STATUS_FAILURE;
     1089    }
     1090
     1091    /*
     1092     * We need a copy of NDIS_STRING structure as we are going to modify length
     1093     * of the base miniport instance name since RTL does not support comparing
     1094     * first n characters of two strings. We check if miniport names start with
     1095     * "Virtual Host-Only" to detect host-only adapters. It is a waste of resources
     1096     * to bind our filter to host-only adapters since they now operate independently.
     1097     */
     1098    NDIS_STRING strTruncatedInstanceName = *pParameters->BaseMiniportInstanceName; /* Do not copy data, only the structure itself */
     1099    strTruncatedInstanceName.Length = g_strHostOnlyMiniportName.Length; /* Truncate instance name */
     1100    if (RtlEqualUnicodeString(&strTruncatedInstanceName, &g_strHostOnlyMiniportName, TRUE /* Case insensitive */))
     1101    {
     1102        DbgPrint("vboxNetLwfWinAttach: won't attach to %wZ\n", pParameters->BaseMiniportInstanceName);
     1103        return NDIS_STATUS_FAILURE;
     1104    }
     1105
     1106    ANSI_STRING strMiniportName;
     1107    /* We use the miniport name to associate this filter module with the netflt instance */
     1108    NTSTATUS rc = RtlUnicodeStringToAnsiString(&strMiniportName,
     1109                                               pParameters->BaseMiniportName,
     1110                                               TRUE);
     1111    if (rc != STATUS_SUCCESS)
     1112    {
     1113        LogError(("vboxNetLwfWinAttach: RtlUnicodeStringToAnsiString(%ls) failed with 0x%x\n",
     1114             pParameters->BaseMiniportName, rc));
     1115        vboxNetLwfLogErrorEvent(IO_ERR_INTERNAL_ERROR, NDIS_STATUS_FAILURE, 2);
     1116        return NDIS_STATUS_FAILURE;
     1117    }
     1118    DbgPrint("vboxNetLwfWinAttach: friendly name=%wZ\n", pParameters->BaseMiniportInstanceName);
     1119    DbgPrint("vboxNetLwfWinAttach: name=%Z\n", &strMiniportName);
     1120
     1121    UINT cbModuleWithNameExtra = sizeof(VBOXNETLWF_MODULE) + strMiniportName.Length;
     1122    PVBOXNETLWF_MODULE pModuleCtx = (PVBOXNETLWF_MODULE)NdisAllocateMemoryWithTagPriority(hFilter,
     1123                                                                      cbModuleWithNameExtra,
     1124                                                                      VBOXNETLWF_MEM_TAG,
     1125                                                                      LowPoolPriority);
     1126    if (!pModuleCtx)
     1127    {
     1128        LogError(("vboxNetLwfWinAttach: Failed to allocate module context for %ls\n", pParameters->BaseMiniportName));
     1129        RtlFreeAnsiString(&strMiniportName);
     1130        vboxNetLwfLogErrorEvent(IO_ERR_INSUFFICIENT_RESOURCES, NDIS_STATUS_RESOURCES, 3);
     1131        return NDIS_STATUS_RESOURCES;
     1132    }
     1133    Log4(("vboxNetLwfWinAttach: allocated module context 0x%p\n", pModuleCtx));
     1134
     1135    NdisZeroMemory(pModuleCtx, cbModuleWithNameExtra);
     1136    NdisMoveMemory(pModuleCtx->szMiniportName, strMiniportName.Buffer, strMiniportName.Length);
     1137    RtlFreeAnsiString(&strMiniportName);
     1138
     1139    pModuleCtx->hWorkItem = NdisAllocateIoWorkItem(g_VBoxNetLwfGlobals.hFilterDriver);
     1140    if (!pModuleCtx->hWorkItem)
     1141    {
     1142        LogError(("vboxNetLwfWinAttach: Failed to allocate work item for %ls\n",
     1143                pParameters->BaseMiniportName));
     1144        NdisFreeMemory(pModuleCtx, 0, 0);
     1145        vboxNetLwfLogErrorEvent(IO_ERR_INSUFFICIENT_RESOURCES, NDIS_STATUS_RESOURCES, 4);
     1146        return NDIS_STATUS_RESOURCES;
     1147    }
     1148
     1149    Assert(pParameters->MacAddressLength == sizeof(RTMAC));
     1150    NdisMoveMemory(&pModuleCtx->MacAddr, pParameters->CurrentMacAddress, RT_MIN(sizeof(RTMAC), pParameters->MacAddressLength));
     1151
     1152    pModuleCtx->cbOffloadConfig = sizeof(NDIS_OFFLOAD) * 2; /* Best guess to accomodate future expansion. */
     1153    /* Get the exact size, if possible. */
     1154    if (pParameters->DefaultOffloadConfiguration)
     1155        pModuleCtx->cbOffloadConfig = pParameters->DefaultOffloadConfiguration->Header.Size;
     1156    else
     1157        vboxNetLwfLogErrorEvent(IO_ERR_INTERNAL_ERROR, STATUS_SUCCESS, 8);
     1158   
     1159    pModuleCtx->pSavedOffloadConfig =
     1160        (PNDIS_OFFLOAD)NdisAllocateMemoryWithTagPriority(hFilter, pModuleCtx->cbOffloadConfig,
     1161                                                         VBOXNETLWF_MEM_TAG, LowPoolPriority);
     1162    pModuleCtx->pDisabledOffloadConfig =
     1163        (PNDIS_OFFLOAD)NdisAllocateMemoryWithTagPriority(hFilter, pModuleCtx->cbOffloadConfig,
     1164                                                         VBOXNETLWF_MEM_TAG, LowPoolPriority);
     1165    if (!pModuleCtx->pSavedOffloadConfig || !pModuleCtx->pDisabledOffloadConfig)
     1166    {
     1167        LogError(("vboxNetLwfWinAttach: Failed to allocate offload config buffers for %ls\n",
     1168                pParameters->BaseMiniportName));
     1169        vboxNetLwfWinFreeModuleResources(pModuleCtx);
     1170        vboxNetLwfLogErrorEvent(IO_ERR_INSUFFICIENT_RESOURCES, NDIS_STATUS_RESOURCES, 9);
     1171        return NDIS_STATUS_RESOURCES;
     1172    }
     1173
     1174    if (pParameters->DefaultOffloadConfiguration)
     1175        vboxNetLwfWinUpdateSavedOffloadConfig(pModuleCtx, pParameters->DefaultOffloadConfiguration);
     1176    else
     1177    {
     1178        NdisZeroMemory(pModuleCtx->pDisabledOffloadConfig, pModuleCtx->cbOffloadConfig);
     1179        pModuleCtx->pDisabledOffloadConfig->Header.Type = NDIS_OBJECT_TYPE_OFFLOAD;
     1180        pModuleCtx->pDisabledOffloadConfig->Header.Revision = NDIS_OFFLOAD_REVISION_1;
     1181        pModuleCtx->pDisabledOffloadConfig->Header.Size = NDIS_SIZEOF_NDIS_OFFLOAD_REVISION_1;
     1182    }
     1183
     1184    pModuleCtx->pGlobals  = pGlobals;
     1185    pModuleCtx->hFilter   = hFilter;
     1186    vboxNetLwfWinChangeState(pModuleCtx, LwfState_Attaching);
     1187    /* Initialize transmission mutex and events */
     1188    NDIS_INIT_MUTEX(&pModuleCtx->InTransmit);
     1189#ifdef VBOXNETLWF_SYNC_SEND
     1190    KeInitializeEvent(&pModuleCtx->EventWire, SynchronizationEvent, FALSE);
     1191    KeInitializeEvent(&pModuleCtx->EventHost, SynchronizationEvent, FALSE);
     1192#else /* !VBOXNETLWF_SYNC_SEND */
     1193    NdisInitializeEvent(&pModuleCtx->EventSendComplete);
     1194    pModuleCtx->cPendingBuffers = 0;
     1195#endif /* !VBOXNETLWF_SYNC_SEND */
     1196
     1197#ifdef VBOXNETLWF_FIXED_SIZE_POOLS
     1198    for (int i = 0; i < RT_ELEMENTS(g_cbPool); ++i)
     1199    {
     1200        /* Allocate buffer pools */
     1201        NET_BUFFER_LIST_POOL_PARAMETERS PoolParams;
     1202        NdisZeroMemory(&PoolParams, sizeof(PoolParams));
     1203        PoolParams.Header.Type = NDIS_OBJECT_TYPE_DEFAULT;
     1204        PoolParams.Header.Revision = NET_BUFFER_LIST_POOL_PARAMETERS_REVISION_1;
     1205        PoolParams.Header.Size = sizeof(PoolParams);
     1206        PoolParams.ProtocolId = NDIS_PROTOCOL_ID_DEFAULT;
     1207        PoolParams.fAllocateNetBuffer = TRUE;
     1208        PoolParams.ContextSize = 0; /** @todo Do we need to consider underlying drivers? I think not. */
     1209        PoolParams.PoolTag = VBOXNETLWF_MEM_TAG;
     1210        PoolParams.DataSize = g_cbPool[i];
     1211        pModuleCtx->hPool[i] = NdisAllocateNetBufferListPool(hFilter, &PoolParams);
     1212        if (!pModuleCtx->hPool[i])
     1213        {
     1214            LogError(("vboxNetLwfWinAttach: NdisAllocateNetBufferListPool failed\n"));
     1215            vboxNetLwfWinFreeModuleResources(pModuleCtx);
     1216            vboxNetLwfLogErrorEvent(IO_ERR_INSUFFICIENT_RESOURCES, NDIS_STATUS_RESOURCES, 7);
     1217            return NDIS_STATUS_RESOURCES;
     1218        }
     1219        Log4(("vboxNetLwfWinAttach: allocated NBL+NB pool (data size=%u) 0x%p\n",
     1220              PoolParams.DataSize, pModuleCtx->hPool[i]));
     1221    }
     1222#else /* !VBOXNETLWF_FIXED_SIZE_POOLS */
     1223    /* Allocate buffer pools */
     1224    NET_BUFFER_LIST_POOL_PARAMETERS PoolParams;
     1225    NdisZeroMemory(&PoolParams, sizeof(PoolParams));
     1226    PoolParams.Header.Type = NDIS_OBJECT_TYPE_DEFAULT;
     1227    PoolParams.Header.Revision = NET_BUFFER_LIST_POOL_PARAMETERS_REVISION_1;
     1228    PoolParams.Header.Size = sizeof(PoolParams);
     1229    PoolParams.ProtocolId = NDIS_PROTOCOL_ID_DEFAULT;
     1230    PoolParams.fAllocateNetBuffer = TRUE;
     1231    PoolParams.ContextSize = 0; /** @todo Do we need to consider underlying drivers? I think not. */
     1232    PoolParams.PoolTag = VBOXNETLWF_MEM_TAG;
     1233    pModuleCtx->hPool = NdisAllocateNetBufferListPool(hFilter, &PoolParams);
     1234    if (!pModuleCtx->hPool)
     1235    {
     1236        LogError(("vboxNetLwfWinAttach: NdisAllocateNetBufferListPool failed\n"));
     1237        vboxNetLwfWinFreeModuleResources(pModuleCtx);
     1238        vboxNetLwfLogErrorEvent(IO_ERR_INSUFFICIENT_RESOURCES, NDIS_STATUS_RESOURCES, 7);
     1239        return NDIS_STATUS_RESOURCES;
     1240    }
     1241    Log4(("vboxNetLwfWinAttach: allocated NBL+NB pool 0x%p\n", pModuleCtx->hPool));
     1242#endif /* !VBOXNETLWF_FIXED_SIZE_POOLS */
     1243
     1244    NDIS_FILTER_ATTRIBUTES Attributes;
     1245    NdisZeroMemory(&Attributes, sizeof(Attributes));
     1246    Attributes.Header.Revision = NDIS_FILTER_ATTRIBUTES_REVISION_1;
     1247    Attributes.Header.Size = sizeof(Attributes);
     1248    Attributes.Header.Type = NDIS_OBJECT_TYPE_FILTER_ATTRIBUTES;
     1249    Attributes.Flags = 0;
     1250    NDIS_STATUS Status = NdisFSetAttributes(hFilter, pModuleCtx, &Attributes);
     1251    if (Status != NDIS_STATUS_SUCCESS)
     1252    {
     1253        LogError(("vboxNetLwfWinAttach: NdisFSetAttributes failed with 0x%x\n", Status));
     1254        vboxNetLwfWinFreeModuleResources(pModuleCtx);
     1255        vboxNetLwfLogErrorEvent(IO_ERR_INTERNAL_ERROR, NDIS_STATUS_RESOURCES, 5);
     1256        return NDIS_STATUS_RESOURCES;
     1257    }
     1258    /* Insert into module chain */
     1259    NdisAcquireSpinLock(&pGlobals->Lock);
     1260    RTListPrepend(&pGlobals->listModules, &pModuleCtx->node);
     1261    NdisReleaseSpinLock(&pGlobals->Lock);
     1262
     1263    vboxNetLwfWinChangeState(pModuleCtx, LwfState_Paused);
     1264
     1265    /// @todo Somehow the packet filter is 0 at this point: Status = vboxNetLwfWinGetPacketFilter(pModuleCtx);
     1266    /// @todo We actually update it later in status handler, perhaps we should not do anything here.
     1267
     1268    LogFlow(("<==vboxNetLwfWinAttach: Status = 0x%x\n", Status));
     1269    return Status;
     1270}
     1271
     1272static VOID vboxNetLwfWinDetach(IN NDIS_HANDLE hModuleCtx)
     1273{
     1274    LogFlow(("==>vboxNetLwfWinDetach: module=%p\n", hModuleCtx));
     1275    PVBOXNETLWF_MODULE pModuleCtx = (PVBOXNETLWF_MODULE)hModuleCtx;
     1276    vboxNetLwfWinChangeState(pModuleCtx, LwfState_Detached, LwfState_Paused);
     1277
     1278    /* Remove from module chain */
     1279    NdisAcquireSpinLock(&pModuleCtx->pGlobals->Lock);
     1280    RTListNodeRemove(&pModuleCtx->node);
     1281    NdisReleaseSpinLock(&pModuleCtx->pGlobals->Lock);
     1282
     1283    PVBOXNETFLTINS pNetFltIns = pModuleCtx->pNetFlt; /// @todo Atomic?
     1284    if (pNetFltIns && vboxNetFltTryRetainBusyNotDisconnected(pNetFltIns))
     1285    {
     1286        /*
     1287         * Set hModuleCtx to null now in order to prevent filter restart,
     1288         * OID requests and other stuff associated with NetFlt deactivation.
     1289         */
     1290        pNetFltIns->u.s.WinIf.hModuleCtx = NULL;
     1291        /* Notify NetFlt that we are going down */
     1292        pNetFltIns->pSwitchPort->pfnDisconnect(pNetFltIns->pSwitchPort, &pNetFltIns->MyPort, vboxNetFltPortReleaseBusy);
     1293        /* We do not 'release' netflt instance since it has been done by pfnDisconnect */
     1294    }
     1295    pModuleCtx->pNetFlt = NULL;
     1296
     1297    /*
     1298     * We have to make sure that all NET_BUFFER_LIST structures have been freed by now, but
     1299     * it does not require us to do anything here since it has already been taken care of
     1300     * by vboxNetLwfWinPause().
     1301     */
     1302    vboxNetLwfWinFreeModuleResources(pModuleCtx);
     1303    Log4(("vboxNetLwfWinDetach: freed module context 0x%p\n", pModuleCtx));
     1304    LogFlow(("<==vboxNetLwfWinDetach\n"));
     1305}
     1306
     1307
     1308static NDIS_STATUS vboxNetLwfWinPause(IN NDIS_HANDLE hModuleCtx, IN PNDIS_FILTER_PAUSE_PARAMETERS pParameters)
     1309{
     1310    RT_NOREF1(pParameters);
     1311    LogFlow(("==>vboxNetLwfWinPause: module=%p\n", hModuleCtx));
     1312    PVBOXNETLWF_MODULE pModuleCtx = (PVBOXNETLWF_MODULE)hModuleCtx;
     1313    vboxNetLwfWinChangeState(pModuleCtx, LwfState_Pausing, LwfState_Running);
     1314    /* Wait for pending send/indication operations to complete. */
     1315    NDIS_WAIT_FOR_MUTEX(&pModuleCtx->InTransmit);
     1316#ifndef VBOXNETLWF_SYNC_SEND
     1317    NdisWaitEvent(&pModuleCtx->EventSendComplete, 1000 /* ms */);
     1318#endif /* !VBOXNETLWF_SYNC_SEND */
     1319    vboxNetLwfWinChangeState(pModuleCtx, LwfState_Paused, LwfState_Pausing);
     1320    NDIS_RELEASE_MUTEX(&pModuleCtx->InTransmit);
     1321    LogFlow(("<==vboxNetLwfWinPause\n"));
     1322    return NDIS_STATUS_SUCCESS; /* Failure is not an option */
     1323}
     1324
     1325
     1326static void vboxNetLwfWinIndicateOffload(PVBOXNETLWF_MODULE pModuleCtx, PNDIS_OFFLOAD pOffload)
     1327{
     1328    Log5(("vboxNetLwfWinIndicateOffload: offload config changed to:\n"));
     1329    vboxNetLwfWinDumpOffloadSettings(pOffload);
     1330    NDIS_STATUS_INDICATION OffloadingIndication;
     1331    NdisZeroMemory(&OffloadingIndication, sizeof(OffloadingIndication));
     1332    OffloadingIndication.Header.Type = NDIS_OBJECT_TYPE_STATUS_INDICATION;
     1333    OffloadingIndication.Header.Revision = NDIS_STATUS_INDICATION_REVISION_1;
     1334    OffloadingIndication.Header.Size = NDIS_SIZEOF_STATUS_INDICATION_REVISION_1;
     1335    OffloadingIndication.SourceHandle = pModuleCtx->hFilter;
     1336    OffloadingIndication.StatusCode = NDIS_STATUS_TASK_OFFLOAD_CURRENT_CONFIG;
     1337    OffloadingIndication.StatusBuffer = pOffload;
     1338    OffloadingIndication.StatusBufferSize = sizeof(NDIS_OFFLOAD);
     1339    NdisFIndicateStatus(pModuleCtx->hFilter, &OffloadingIndication);
     1340}
     1341
     1342
     1343static NDIS_STATUS vboxNetLwfWinRestart(IN NDIS_HANDLE hModuleCtx, IN PNDIS_FILTER_RESTART_PARAMETERS pParameters)
     1344{
     1345    RT_NOREF1(pParameters);
     1346    LogFlow(("==>vboxNetLwfWinRestart: module=%p\n", hModuleCtx));
     1347    PVBOXNETLWF_MODULE pModuleCtx = (PVBOXNETLWF_MODULE)hModuleCtx;
     1348    vboxNetLwfWinChangeState(pModuleCtx, LwfState_Restarting, LwfState_Paused);
     1349    vboxNetLwfWinChangeState(pModuleCtx, LwfState_Running, LwfState_Restarting);
     1350    NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
     1351    LogFlow(("<==vboxNetLwfWinRestart: Status = 0x%x\n", Status));
     1352    return Status;
     1353}
     1354
     1355
     1356static void vboxNetLwfWinDestroySG(PINTNETSG pSG)
     1357{
     1358    NdisFreeMemory(pSG, 0, 0);
     1359    Log4(("vboxNetLwfWinDestroySG: freed SG 0x%p\n", pSG));
     1360}
     1361
     1362DECLINLINE(ULONG) vboxNetLwfWinCalcSegments(PNET_BUFFER pNetBuf)
     1363{
     1364    ULONG cSegs = 0;
     1365    for (PMDL pMdl = NET_BUFFER_CURRENT_MDL(pNetBuf); pMdl; pMdl = NDIS_MDL_LINKAGE(pMdl))
     1366        cSegs++;
     1367    return cSegs;
     1368}
     1369
     1370DECLINLINE(void) vboxNetLwfWinFreeMdlChain(PMDL pMdl)
     1371{
     1372#ifndef VBOXNETLWF_FIXED_SIZE_POOLS
     1373    PMDL pMdlNext;
     1374    while (pMdl)
     1375    {
     1376        pMdlNext = pMdl->Next;
     1377# ifndef VBOXNETLWF_SYNC_SEND
     1378        PUCHAR pDataBuf;
     1379        ULONG cb = 0;
     1380        NdisQueryMdl(pMdl, &pDataBuf, &cb, NormalPagePriority);
     1381# endif /* !VBOXNETLWF_SYNC_SEND */
     1382        NdisFreeMdl(pMdl);
     1383        Log4(("vboxNetLwfWinFreeMdlChain: freed MDL 0x%p\n", pMdl));
     1384# ifndef VBOXNETLWF_SYNC_SEND
     1385        NdisFreeMemory(pDataBuf, 0, 0);
     1386        Log4(("vboxNetLwfWinFreeMdlChain: freed data buffer 0x%p\n", pDataBuf));
     1387# endif /* !VBOXNETLWF_SYNC_SEND */
     1388        pMdl = pMdlNext;
     1389    }
     1390#else  /* VBOXNETLWF_FIXED_SIZE_POOLS */
     1391    RT_NOREF1(pMdl);
     1392#endif /* VBOXNETLWF_FIXED_SIZE_POOLS */
     1393}
     1394
     1395/** @todo
     1396 * 1) Copy data from SG to MDL (if we decide to complete asynchronously).
     1397 * 2) Provide context/backfill space. Nobody does it, should we?
     1398 * 3) We always get a single segment from intnet. Simplify?
     1399 */
     1400static PNET_BUFFER_LIST vboxNetLwfWinSGtoNB(PVBOXNETLWF_MODULE pModule, PINTNETSG pSG)
     1401{
     1402    AssertReturn(pSG->cSegsUsed >= 1, NULL);
     1403    LogFlow(("==>vboxNetLwfWinSGtoNB: segments=%d hPool=%p cb=%u\n", pSG->cSegsUsed,
     1404             pModule->hPool, pSG->cbTotal));
     1405    AssertReturn(pModule->hPool, NULL);
     1406
     1407#ifdef VBOXNETLWF_SYNC_SEND
     1408    PINTNETSEG pSeg = pSG->aSegs;
     1409    PMDL pMdl = NdisAllocateMdl(pModule->hFilter, pSeg->pv, pSeg->cb);
     1410    if (!pMdl)
     1411    {
     1412        LogError(("vboxNetLwfWinSGtoNB: failed to allocate an MDL\n"));
     1413        LogFlow(("<==vboxNetLwfWinSGtoNB: return NULL\n"));
     1414        return NULL;
     1415    }
     1416    Log4(("vboxNetLwfWinSGtoNB: allocated Mdl 0x%p\n", pMdl));
     1417    PMDL pMdlCurr = pMdl;
     1418    for (int i = 1; i < pSG->cSegsUsed; i++)
     1419    {
     1420        pSeg = &pSG->aSegs[i];
     1421        pMdlCurr->Next = NdisAllocateMdl(pModule->hFilter, pSeg->pv, pSeg->cb);
     1422        if (!pMdlCurr->Next)
     1423        {
     1424            LogError(("vboxNetLwfWinSGtoNB: failed to allocate an MDL\n"));
     1425            /* Tear down all MDL we chained so far */
     1426            vboxNetLwfWinFreeMdlChain(pMdl);
     1427            return NULL;
     1428        }
     1429        pMdlCurr = pMdlCurr->Next;
     1430        Log4(("vboxNetLwfWinSGtoNB: allocated Mdl 0x%p\n", pMdlCurr));
     1431    }
     1432    PNET_BUFFER_LIST pBufList = NdisAllocateNetBufferAndNetBufferList(pModule->hPool,
     1433                                                                      0 /* ContextSize */,
     1434                                                                      0 /* ContextBackFill */,
     1435                                                                      pMdl,
     1436                                                                      0 /* DataOffset */,
     1437                                                                      pSG->cbTotal);
     1438    if (pBufList)
     1439    {
     1440        Log4(("vboxNetLwfWinSGtoNB: allocated NBL+NB 0x%p\n", pBufList));
     1441        pBufList->SourceHandle = pModule->hFilter;
     1442        /** @todo Do we need to initialize anything else? */
     1443    }
     1444    else
     1445    {
     1446        LogError(("vboxNetLwfWinSGtoNB: failed to allocate an NBL+NB\n"));
     1447        vboxNetLwfWinFreeMdlChain(pMdl);
     1448    }
     1449#else /* !VBOXNETLWF_SYNC_SEND */
     1450
     1451# ifdef VBOXNETLWF_FIXED_SIZE_POOLS
     1452    int iPool = 0;
     1453    ULONG cbFrame = VBOXNETLWF_MAX_FRAME_SIZE(pSG->cbTotal);
     1454    /* Let's find the appropriate pool first */
     1455    for (iPool = 0; iPool < RT_ELEMENTS(g_cbPool); ++iPool)
     1456        if (cbFrame <= g_cbPool[iPool])
     1457            break;
     1458    if (iPool >= RT_ELEMENTS(g_cbPool))
     1459    {
     1460        LogError(("vboxNetLwfWinSGtoNB: frame is too big (%u > %u), drop it.\n", cbFrame, g_cbPool[RT_ELEMENTS(g_cbPool)-1]));
     1461        LogFlow(("<==vboxNetLwfWinSGtoNB: return NULL\n"));
     1462        return NULL;
     1463    }
     1464    PNET_BUFFER_LIST pBufList = NdisAllocateNetBufferList(pModule->hPool[iPool],
     1465                                                          0 /** @todo ContextSize */,
     1466                                                          0 /** @todo ContextBackFill */);
     1467    if (!pBufList)
     1468    {
     1469        LogError(("vboxNetLwfWinSGtoNB: failed to allocate netbuffer (cb=%u) from pool %d\n", cbFrame, iPool));
     1470        LogFlow(("<==vboxNetLwfWinSGtoNB: return NULL\n"));
     1471        return NULL;
     1472    }
     1473    const ULONG cbAlignmentMask = sizeof(USHORT) - 1; /* Microsoft LB/FO provider expects packets to be aligned at word boundary. */
     1474    ULONG cbAlignedFrame = (pSG->cbTotal + cbAlignmentMask) & ~cbAlignmentMask;
     1475    Assert(cbAlignedFrame >= pSG->cbTotal);
     1476    Assert(cbFrame >= cbAlignedFrame);
     1477    NET_BUFFER *pBuffer = NET_BUFFER_LIST_FIRST_NB(pBufList);
     1478    NDIS_STATUS Status = NdisRetreatNetBufferDataStart(pBuffer, cbAlignedFrame, 0 /** @todo DataBackfill */, NULL);
     1479    if (Status == NDIS_STATUS_SUCCESS)
     1480    {
     1481        uint8_t *pDst = (uint8_t*)NdisGetDataBuffer(pBuffer, pSG->cbTotal, NULL, 1, 0);
     1482        if (pDst)
     1483        {
     1484            for (int i = 0; i < pSG->cSegsUsed; i++)
     1485            {
     1486                NdisMoveMemory(pDst, pSG->aSegs[i].pv, pSG->aSegs[i].cb);
     1487                pDst += pSG->aSegs[i].cb;
     1488            }
     1489            if (cbAlignedFrame > pSG->cbTotal)
     1490            {
     1491                Log4(("vboxNetLwfWinSGtoNB: padding %d-byte packet with %d zero bytes", pSG->cbTotal, cbAlignedFrame - pSG->cbTotal));
     1492                NdisZeroMemory(pDst, cbAlignedFrame - pSG->cbTotal);
     1493            }
     1494            Log4(("vboxNetLwfWinSGtoNB: allocated NBL+NB 0x%p\n", pBufList));
     1495            pBufList->SourceHandle = pModule->hFilter;
     1496        }
     1497        else
     1498        {
     1499            LogError(("vboxNetLwfWinSGtoNB: failed to obtain the buffer pointer (size=%u)\n", pSG->cbTotal));
     1500            NdisAdvanceNetBufferDataStart(pBuffer, cbAlignedFrame, false, NULL); /** @todo why bother? */
     1501            NdisFreeNetBufferList(pBufList);
     1502            pBufList = NULL;
     1503        }
     1504    }
     1505    else
     1506    {
     1507        LogError(("vboxNetLwfWinSGtoNB: NdisRetreatNetBufferDataStart failed with 0x%x (size=%u)\n", Status, pSG->cbTotal));
     1508        NdisFreeNetBufferList(pBufList);
     1509        pBufList = NULL;
     1510    }
     1511# else /* !VBOXNETLWF_FIXED_SIZE_POOLS */
     1512    PNET_BUFFER_LIST pBufList = NULL;
     1513    ULONG cbMdl = VBOXNETLWF_MAX_FRAME_SIZE(pSG->cbTotal);
     1514    ULONG uDataOffset = cbMdl - pSG->cbTotal;
     1515    PUCHAR pDataBuf = (PUCHAR)NdisAllocateMemoryWithTagPriority(pModule->hFilter, cbMdl,
     1516                                                                VBOXNETLWF_MEM_TAG, NormalPoolPriority);
     1517    if (pDataBuf)
     1518    {
     1519        Log4(("vboxNetLwfWinSGtoNB: allocated data buffer (cb=%u) 0x%p\n", cbMdl, pDataBuf));
     1520        PMDL pMdl = NdisAllocateMdl(pModule->hFilter, pDataBuf, cbMdl);
     1521        if (!pMdl)
     1522        {
     1523            NdisFreeMemory(pDataBuf, 0, 0);
     1524            Log4(("vboxNetLwfWinSGtoNB: freed data buffer 0x%p\n", pDataBuf));
     1525            LogError(("vboxNetLwfWinSGtoNB: failed to allocate an MDL (cb=%u)\n", cbMdl));
     1526            LogFlow(("<==vboxNetLwfWinSGtoNB: return NULL\n"));
     1527            return NULL;
     1528        }
     1529        PUCHAR pDst = pDataBuf + uDataOffset;
     1530        for (int i = 0; i < pSG->cSegsUsed; i++)
     1531        {
     1532            NdisMoveMemory(pDst, pSG->aSegs[i].pv, pSG->aSegs[i].cb);
     1533            pDst += pSG->aSegs[i].cb;
     1534        }
     1535        pBufList = NdisAllocateNetBufferAndNetBufferList(pModule->hPool,
     1536                                                         0 /* ContextSize */,
     1537                                                         0 /* ContextBackFill */,
     1538                                                         pMdl,
     1539                                                         uDataOffset,
     1540                                                         pSG->cbTotal);
     1541        if (pBufList)
     1542        {
     1543            Log4(("vboxNetLwfWinSGtoNB: allocated NBL+NB 0x%p\n", pBufList));
     1544            pBufList->SourceHandle = pModule->hFilter;
     1545            /** @todo Do we need to initialize anything else? */
     1546        }
     1547        else
     1548        {
     1549            LogError(("vboxNetLwfWinSGtoNB: failed to allocate an NBL+NB\n"));
     1550            vboxNetLwfWinFreeMdlChain(pMdl);
     1551        }
     1552    }
     1553    else
     1554    {
     1555        LogError(("vboxNetLwfWinSGtoNB: failed to allocate data buffer (size=%u)\n", cbMdl));
     1556    }
     1557# endif /* !VBOXNETLWF_FIXED_SIZE_POOLS */
     1558
     1559#endif /* !VBOXNETLWF_SYNC_SEND */
     1560    LogFlow(("<==vboxNetLwfWinSGtoNB: return %p\n", pBufList));
     1561    return pBufList;
     1562}
     1563
     1564static PINTNETSG vboxNetLwfWinNBtoSG(PVBOXNETLWF_MODULE pModule, PNET_BUFFER pNetBuf)
     1565{
     1566    ULONG cbPacket = NET_BUFFER_DATA_LENGTH(pNetBuf);
     1567    UINT cSegs = vboxNetLwfWinCalcSegments(pNetBuf);
     1568    /* Allocate and initialize SG */
     1569    PINTNETSG pSG = (PINTNETSG)NdisAllocateMemoryWithTagPriority(pModule->hFilter,
     1570                                                                 RT_OFFSETOF(INTNETSG, aSegs[cSegs]),
     1571                                                                 VBOXNETLWF_MEM_TAG,
     1572                                                                 NormalPoolPriority);
     1573    AssertReturn(pSG, pSG);
     1574    Log4(("vboxNetLwfWinNBtoSG: allocated SG 0x%p\n", pSG));
     1575    IntNetSgInitTempSegs(pSG, cbPacket /*cbTotal*/, cSegs, cSegs /*cSegsUsed*/);
     1576
     1577    int rc = NDIS_STATUS_SUCCESS;
     1578    ULONG uOffset = NET_BUFFER_CURRENT_MDL_OFFSET(pNetBuf);
     1579    cSegs = 0;
     1580    for (PMDL pMdl = NET_BUFFER_CURRENT_MDL(pNetBuf);
     1581         pMdl != NULL && cbPacket > 0;
     1582         pMdl = NDIS_MDL_LINKAGE(pMdl))
     1583    {
     1584        PUCHAR pSrc = (PUCHAR)MmGetSystemAddressForMdlSafe(pMdl, LowPagePriority);
     1585        if (!pSrc)
     1586        {
     1587            rc = NDIS_STATUS_RESOURCES;
     1588            break;
     1589        }
     1590        ULONG cbSrc = MmGetMdlByteCount(pMdl);
     1591        if (uOffset)
     1592        {
     1593            Assert(uOffset < cbSrc);
     1594            pSrc  += uOffset;
     1595            cbSrc -= uOffset;
     1596            uOffset = 0;
     1597        }
     1598
     1599        if (cbSrc > cbPacket)
     1600            cbSrc = cbPacket;
     1601
     1602        pSG->aSegs[cSegs].pv = pSrc;
     1603        pSG->aSegs[cSegs].cb = cbSrc;
     1604        pSG->aSegs[cSegs].Phys = NIL_RTHCPHYS;
     1605        cSegs++;
     1606        cbPacket -= cbSrc;
     1607    }
     1608
     1609    Assert(cSegs <= pSG->cSegsAlloc);
     1610
     1611    if (RT_FAILURE(rc))
     1612    {
     1613        vboxNetLwfWinDestroySG(pSG);
     1614        pSG = NULL;
     1615    }
     1616    else
     1617    {
     1618        Assert(cbPacket == 0);
     1619        Assert(pSG->cSegsUsed == cSegs);
     1620    }
     1621    return pSG;
    15781622}
    15791623
     
    23712415        /* Disable offloading temporarily by indicating offload config change. */
    23722416        /** @todo Be sure to revise this when implementing offloading support! */
    2373         NDIS_OFFLOAD OffloadConfig;
    2374         if (pModuleCtx->fOffloadConfigValid)
    2375         {
    2376             OffloadConfig = pModuleCtx->SavedOffloadConfig;
    2377             vboxNetLwfWinDisableOffloading(&OffloadConfig);
    2378         }
    2379         else
    2380         {
    2381             DbgPrint("VBoxNetLwf: no saved offload config to modify for %s\n", pModuleCtx->szMiniportName);
    2382             NdisZeroMemory(&OffloadConfig, sizeof(OffloadConfig));
    2383             OffloadConfig.Header.Type = NDIS_OBJECT_TYPE_OFFLOAD;
    2384             OffloadConfig.Header.Revision = NDIS_OFFLOAD_REVISION_1;
    2385             OffloadConfig.Header.Size = NDIS_SIZEOF_NDIS_OFFLOAD_REVISION_1;
    2386         }
    2387         vboxNetLwfWinIndicateOffload(pModuleCtx, &OffloadConfig);
     2417        vboxNetLwfWinIndicateOffload(pModuleCtx, pModuleCtx->pDisabledOffloadConfig);
    23882418        Log(("vboxNetLwfWinToggleOffloading: set offloading off\n"));
    23892419    }
     
    23932423        if (pModuleCtx->fOffloadConfigValid)
    23942424        {
    2395             vboxNetLwfWinIndicateOffload(pModuleCtx, &pModuleCtx->SavedOffloadConfig);
     2425            vboxNetLwfWinIndicateOffload(pModuleCtx, pModuleCtx->pSavedOffloadConfig);
    23962426            Log(("vboxNetLwfWinToggleOffloading: restored offloading config\n"));
    23972427        }
Note: See TracChangeset for help on using the changeset viewer.

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