vbox的更動 65698 路徑 trunk/src/VBox/HostDrivers
- 時間撮記:
- 2017-2-9 下午12:28:01 (8 年 以前)
- 檔案:
-
- 修改 1 筆資料
圖例:
- 未更動
- 新增
- 刪除
-
trunk/src/VBox/HostDrivers/VBoxNetAdp/win/VBoxNetAdp-win.cpp
r63564 r65698 20 20 #include <VBox/version.h> 21 21 #include <VBox/err.h> 22 #include <VBox/sup.h> 23 #include <VBox/intnet.h> 24 #include <VBox/intnetinline.h> 25 #include <iprt/assert.h> 22 26 #include <iprt/initterm.h> 23 #include <iprt/assert.h> 27 #include <iprt/list.h> 28 #include <iprt/net.h> 29 #include <iprt/semaphore.h> 30 #include <iprt/string.h> 31 #include <iprt/uuid.h> 24 32 25 33 #include <iprt/nt/ndis.h> … … 27 35 #include "VBoxNetAdp-win.h" 28 36 #include "VBox/VBoxNetCmn-win.h" 37 38 #define VBOXNETADP_MEM_TAG 'OHBV' 29 39 30 40 /* … … 34 44 */ 35 45 #define VBOXNETADPWIN_LINK_SPEED 1000000000ULL 46 47 #define LogError LogRel 36 48 37 49 /* Forward declarations */ … … 52 64 53 65 66 /* Packet types by destination address; used in statistics. */ 67 typedef enum { 68 kVBoxNetAdpWinPacketType_Unicast, 69 kVBoxNetAdpWinPacketType_Multicast, 70 kVBoxNetAdpWinPacketType_Broadcast, 71 kVBoxNetAdpWinPacketType_ArraySize /* Must be the last one */ 72 } VBOXNETADPWIN_PACKET_TYPE; 73 74 75 /* Miniport states as defined by NDIS. */ 76 typedef enum { 77 kVBoxNetAdpWinState_Initializing, 78 kVBoxNetAdpWinState_Paused, 79 kVBoxNetAdpWinState_Restarting, 80 kVBoxNetAdpWinState_Running, 81 kVBoxNetAdpWinState_Pausing, 82 kVBoxNetAdpWinState_32BitHack = 0x7fffffff 83 } VBOXNETADPWIN_ADAPTER_STATE; 84 85 86 /* 87 * Valid state transitions are: 88 * 1) Disconnected -> Connecting : start the worker thread, attempting to init IDC; 89 * 2) Connecting -> Disconnected : failed to start IDC init worker thread; 90 * 3) Connecting -> Connected : IDC init successful, terminate the worker; 91 * 4) Connecting -> Stopping : IDC init incomplete, but the driver is being unloaded, terminate the worker; 92 * 5) Connected -> Stopping : IDC init was successful, no worker, the driver is being unloaded; 93 * 94 * Driver terminates in either in Disconnected or in Stopping state. 95 */ 96 typedef enum { 97 kVBoxNetAdpWinIdcState_Disconnected = 0, /* Initial state */ 98 kVBoxNetAdpWinIdcState_Connecting, /* Attemping to init IDC, worker thread running */ 99 kVBoxNetAdpWinIdcState_Connected, /* Successfully connected to IDC, worker thread terminated */ 100 kVBoxNetAdpWinIdcState_Stopping /* Terminating the worker thread and disconnecting IDC */ 101 } VBOXNETADPWIN_IDC_STATE; 102 54 103 typedef struct _VBOXNETADPGLOBALS 55 104 { 56 /** ndis device */ 57 NDIS_HANDLE hDevice; 58 /** device object */ 59 PDEVICE_OBJECT pDevObj; 60 /** our miniport driver handle */ 105 /** Miniport driver handle. */ 61 106 NDIS_HANDLE hMiniportDriver; 62 /** power management capabilities, shared by all instances, do not change after init*/107 /** Power management capabilities, shared by all instances, do not change after init. */ 63 108 NDIS_PNP_CAPABILITIES PMCaps; 109 /** The INTNET trunk network interface factory. */ 110 INTNETTRUNKFACTORY TrunkFactory; 111 /** The SUPDRV component factory registration. */ 112 SUPDRVFACTORY SupDrvFactory; 113 /** The SUPDRV IDC handle (opaque struct). */ 114 SUPDRVIDCHANDLE SupDrvIDC; 115 /** IDC init thread handle. */ 116 HANDLE hInitIdcThread; 117 /** Lock protecting the following members. */ 118 NDIS_SPIN_LOCK Lock; 119 /** Lock-protected: the head of module list. */ 120 RTLISTANCHOR ListOfAdapters; 121 /** Lock-protected: The number of current factory references. */ 122 int32_t volatile cFactoryRefs; 123 /** Lock-protected: IDC initialization state. */ 124 volatile uint32_t enmIdcState; 125 /** Lock-protected: event signaled when trunk factory is not in use. */ 126 NDIS_EVENT EventUnloadAllowed; 64 127 } VBOXNETADPGLOBALS, *PVBOXNETADPGLOBALS; 65 128 … … 69 132 70 133 typedef struct _VBOXNETADP_ADAPTER { 134 /** Auxiliary member to link adapters into a list. */ 135 RTLISTNODE node; 136 /** Adapter handle for NDIS. */ 71 137 NDIS_HANDLE hAdapter; 138 /** Memory pool network buffers are allocated from. */ 139 NDIS_HANDLE hPool; 140 /** Our RJ-45 port. 141 * This is what the internal network plugs into. */ 142 INTNETTRUNKIFPORT MyPort; 143 /** The RJ-45 port on the INTNET "switch". 144 * This is what we're connected to. */ 145 PINTNETTRUNKSWPORT pSwitchPort; 146 /** Pointer to global data */ 72 147 PVBOXNETADPGLOBALS pGlobals; 148 /** Adapter state in NDIS, used for assertions only */ 149 VBOXNETADPWIN_ADAPTER_STATE volatile enmAdapterState; // @todo do we need it really? 150 /** The trunk state. */ 151 INTNETTRUNKIFSTATE volatile enmTrunkState; 152 /** Number of pending operations, when it reaches zero we signal EventIdle. */ 153 int32_t volatile cBusy; 154 /** The event that is signaled when we go idle and that pfnWaitForIdle blocks on. */ 155 NDIS_EVENT EventIdle; 156 /** MAC address of adapter. */ 73 157 RTMAC MacAddr; 158 /** Statistics: bytes received from internal network. */ 159 uint64_t au64StatsInOctets[kVBoxNetAdpWinPacketType_ArraySize]; 160 /** Statistics: packets received from internal network. */ 161 uint64_t au64StatsInPackets[kVBoxNetAdpWinPacketType_ArraySize]; 162 /** Statistics: bytes sent to internal network. */ 163 uint64_t au64StatsOutOctets[kVBoxNetAdpWinPacketType_ArraySize]; 164 /** Statistics: packets sent to internal network. */ 165 uint64_t au64StatsOutPackets[kVBoxNetAdpWinPacketType_ArraySize]; 166 /** Adapter friendly name. */ 167 char szName[1]; 74 168 } VBOXNETADP_ADAPTER; 75 169 typedef VBOXNETADP_ADAPTER *PVBOXNETADP_ADAPTER; 76 170 77 171 78 static NTSTATUS vboxNetAdpWinDevDispatch(IN PDEVICE_OBJECT pDevObj, IN PIRP pIrp) 79 { 80 RT_NOREF1(pDevObj); 81 PIO_STACK_LOCATION pIrpSl = IoGetCurrentIrpStackLocation(pIrp); 82 NTSTATUS Status = STATUS_SUCCESS; 83 84 switch (pIrpSl->MajorFunction) 85 { 86 case IRP_MJ_DEVICE_CONTROL: 87 Status = STATUS_NOT_SUPPORTED; /// @todo add/remove ioctls 88 break; 89 case IRP_MJ_CREATE: 90 case IRP_MJ_CLEANUP: 91 case IRP_MJ_CLOSE: 92 break; 93 default: 94 AssertFailed(); 95 break; 96 } 97 98 pIrp->IoStatus.Status = Status; 99 IoCompleteRequest(pIrp, IO_NO_INCREMENT); 100 101 return Status; 102 } 103 104 static NDIS_STATUS vboxNetAdpWinDevCreate(PVBOXNETADPGLOBALS pGlobals) 105 { 106 NDIS_STRING DevName, LinkName; 107 PDRIVER_DISPATCH aMajorFunctions[IRP_MJ_MAXIMUM_FUNCTION+1]; 108 NdisInitUnicodeString(&DevName, VBOXNETADP_NAME_DEVICE); 109 NdisInitUnicodeString(&LinkName, VBOXNETADP_NAME_LINK); 110 111 Assert(!pGlobals->hDevice); 112 Assert(!pGlobals->pDevObj); 113 NdisZeroMemory(aMajorFunctions, sizeof (aMajorFunctions)); 114 aMajorFunctions[IRP_MJ_CREATE] = vboxNetAdpWinDevDispatch; 115 aMajorFunctions[IRP_MJ_CLEANUP] = vboxNetAdpWinDevDispatch; 116 aMajorFunctions[IRP_MJ_CLOSE] = vboxNetAdpWinDevDispatch; 117 aMajorFunctions[IRP_MJ_DEVICE_CONTROL] = vboxNetAdpWinDevDispatch; 118 119 NDIS_DEVICE_OBJECT_ATTRIBUTES DeviceAttributes; 120 NdisZeroMemory(&DeviceAttributes, sizeof(DeviceAttributes)); 121 DeviceAttributes.Header.Type = NDIS_OBJECT_TYPE_DEVICE_OBJECT_ATTRIBUTES; 122 DeviceAttributes.Header.Revision = NDIS_DEVICE_OBJECT_ATTRIBUTES_REVISION_1; 123 DeviceAttributes.Header.Size = sizeof(DeviceAttributes); 124 DeviceAttributes.DeviceName = &DevName; 125 DeviceAttributes.SymbolicName = &LinkName; 126 DeviceAttributes.MajorFunctions = aMajorFunctions; 127 128 NDIS_STATUS Status = NdisRegisterDeviceEx(pGlobals->hMiniportDriver, 129 &DeviceAttributes, 130 &pGlobals->pDevObj, 131 &pGlobals->hDevice); 132 Log(("vboxNetAdpWinDevCreate: NdisRegisterDeviceEx returned 0x%x\n", Status)); 133 Assert(Status == NDIS_STATUS_SUCCESS); 134 return Status; 135 } 136 137 static void vboxNetAdpWinDevDestroy(PVBOXNETADPGLOBALS pGlobals) 138 { 139 Assert(pGlobals->hDevice); 140 Assert(pGlobals->pDevObj); 141 NdisDeregisterDeviceEx(pGlobals->hDevice); 142 pGlobals->hDevice = NULL; 143 pGlobals->pDevObj = NULL; 144 } 145 146 147 172 /* Port */ 173 174 #define IFPORT_2_VBOXNETADP_ADAPTER(pIfPort) \ 175 ( (PVBOXNETADP_ADAPTER)((uint8_t *)pIfPort - RT_OFFSETOF(VBOXNETADP_ADAPTER, MyPort)) ) 176 177 DECLINLINE(VBOXNETADPWIN_ADAPTER_STATE) vboxNetAdpWinGetState(PVBOXNETADP_ADAPTER pThis) 178 { 179 return (VBOXNETADPWIN_ADAPTER_STATE)ASMAtomicUoReadU32((uint32_t volatile *)&pThis->enmAdapterState); 180 } 181 182 DECLINLINE(VBOXNETADPWIN_ADAPTER_STATE) vboxNetAdpWinSetState(PVBOXNETADP_ADAPTER pThis, VBOXNETADPWIN_ADAPTER_STATE enmNewState) 183 { 184 return (VBOXNETADPWIN_ADAPTER_STATE)ASMAtomicXchgU32((uint32_t volatile *)&pThis->enmAdapterState, enmNewState); 185 } 186 187 DECLINLINE(bool) vboxNetAdpWinSetState(PVBOXNETADP_ADAPTER pThis, VBOXNETADPWIN_ADAPTER_STATE enmNewState, 188 VBOXNETADPWIN_ADAPTER_STATE enmOldState) 189 { 190 return ASMAtomicCmpXchgU32((uint32_t volatile *)&pThis->enmAdapterState, enmNewState, enmOldState); 191 } 192 193 #ifdef DEBUG 194 195 DECLHIDDEN(void) vboxNetAdpWinDumpPackets(const char *pszMsg, PNET_BUFFER_LIST pBufLists) 196 { 197 for (PNET_BUFFER_LIST pList = pBufLists; pList; pList = NET_BUFFER_LIST_NEXT_NBL(pList)) 198 { 199 for (PNET_BUFFER pBuf = NET_BUFFER_LIST_FIRST_NB(pList); pBuf; pBuf = NET_BUFFER_NEXT_NB(pBuf)) 200 { 201 Log6(("%s packet: cb=%d offset=%d", pszMsg, NET_BUFFER_DATA_LENGTH(pBuf), NET_BUFFER_DATA_OFFSET(pBuf))); 202 for (PMDL pMdl = NET_BUFFER_FIRST_MDL(pBuf); 203 pMdl != NULL; 204 pMdl = NDIS_MDL_LINKAGE(pMdl)) 205 { 206 Log6((" MDL: cb=%d", MmGetMdlByteCount(pMdl))); 207 } 208 Log6(("\n")); 209 } 210 } 211 } 212 213 DECLINLINE(const char *) vboxNetAdpWinEthTypeStr(uint16_t uType) 214 { 215 switch (uType) 216 { 217 case RTNET_ETHERTYPE_IPV4: return "IP"; 218 case RTNET_ETHERTYPE_IPV6: return "IPv6"; 219 case RTNET_ETHERTYPE_ARP: return "ARP"; 220 } 221 return "unknown"; 222 } 223 224 #define VBOXNETADP_PKTDMPSIZE 0x50 225 226 /** 227 * Dump a packet to debug log. 228 * 229 * @param cpPacket The packet. 230 * @param cb The size of the packet. 231 * @param cszText A string denoting direction of packet transfer. 232 */ 233 DECLINLINE(void) vboxNetAdpWinDumpPacket(PCINTNETSG pSG, const char *cszText) 234 { 235 uint8_t bPacket[VBOXNETADP_PKTDMPSIZE]; 236 237 uint32_t cb = pSG->cbTotal < VBOXNETADP_PKTDMPSIZE ? pSG->cbTotal : VBOXNETADP_PKTDMPSIZE; 238 IntNetSgReadEx(pSG, 0, cb, bPacket); 239 240 AssertReturnVoid(cb >= 14); 241 242 uint8_t *pHdr = bPacket; 243 uint8_t *pEnd = bPacket + cb; 244 AssertReturnVoid(pEnd - pHdr >= 14); 245 uint16_t uEthType = RT_N2H_U16(*(uint16_t*)(pHdr+12)); 246 Log2(("NetADP: %s (%d bytes), %RTmac => %RTmac, EthType=%s(0x%x)\n", 247 cszText, pSG->cbTotal, pHdr+6, pHdr, vboxNetAdpWinEthTypeStr(uEthType), uEthType)); 248 pHdr += sizeof(RTNETETHERHDR); 249 if (uEthType == RTNET_ETHERTYPE_VLAN) 250 { 251 AssertReturnVoid(pEnd - pHdr >= 4); 252 uEthType = RT_N2H_U16(*(uint16_t*)(pHdr+2)); 253 Log2((" + VLAN: id=%d EthType=%s(0x%x)\n", RT_N2H_U16(*(uint16_t*)(pHdr)) & 0xFFF, 254 vboxNetAdpWinEthTypeStr(uEthType), uEthType)); 255 pHdr += 2 * sizeof(uint16_t); 256 } 257 uint8_t uProto = 0xFF; 258 switch (uEthType) 259 { 260 case RTNET_ETHERTYPE_IPV6: 261 AssertReturnVoid(pEnd - pHdr >= 40); 262 uProto = pHdr[6]; 263 Log2((" + IPv6: %RTnaipv6 => %RTnaipv6\n", pHdr+8, pHdr+24)); 264 pHdr += 40; 265 break; 266 case RTNET_ETHERTYPE_IPV4: 267 AssertReturnVoid(pEnd - pHdr >= 20); 268 uProto = pHdr[9]; 269 Log2((" + IP: %RTnaipv4 => %RTnaipv4\n", *(uint32_t*)(pHdr+12), *(uint32_t*)(pHdr+16))); 270 pHdr += (pHdr[0] & 0xF) * 4; 271 break; 272 case RTNET_ETHERTYPE_ARP: 273 AssertReturnVoid(pEnd - pHdr >= 28); 274 AssertReturnVoid(RT_N2H_U16(*(uint16_t*)(pHdr+2)) == RTNET_ETHERTYPE_IPV4); 275 switch (RT_N2H_U16(*(uint16_t*)(pHdr+6))) 276 { 277 case 1: /* ARP request */ 278 Log2((" + ARP-REQ: who-has %RTnaipv4 tell %RTnaipv4\n", 279 *(uint32_t*)(pHdr+24), *(uint32_t*)(pHdr+14))); 280 break; 281 case 2: /* ARP reply */ 282 Log2((" + ARP-RPL: %RTnaipv4 is-at %RTmac\n", 283 *(uint32_t*)(pHdr+14), pHdr+8)); 284 break; 285 default: 286 Log2((" + ARP: unknown op %d\n", RT_N2H_U16(*(uint16_t*)(pHdr+6)))); 287 break; 288 } 289 break; 290 /* There is no default case as uProto is initialized with 0xFF */ 291 } 292 while (uProto != 0xFF) 293 { 294 switch (uProto) 295 { 296 case 0: /* IPv6 Hop-by-Hop option*/ 297 case 60: /* IPv6 Destination option*/ 298 case 43: /* IPv6 Routing option */ 299 case 44: /* IPv6 Fragment option */ 300 Log2((" + IPv6 option (%d): <not implemented>\n", uProto)); 301 uProto = pHdr[0]; 302 pHdr += pHdr[1] * 8 + 8; /* Skip to the next extension/protocol */ 303 break; 304 case 51: /* IPv6 IPsec AH */ 305 Log2((" + IPv6 IPsec AH: <not implemented>\n")); 306 uProto = pHdr[0]; 307 pHdr += (pHdr[1] + 2) * 4; /* Skip to the next extension/protocol */ 308 break; 309 case 50: /* IPv6 IPsec ESP */ 310 /* Cannot decode IPsec, fall through */ 311 Log2((" + IPv6 IPsec ESP: <not implemented>\n")); 312 uProto = 0xFF; 313 break; 314 case 59: /* No Next Header */ 315 Log2((" + IPv6 No Next Header\n")); 316 uProto = 0xFF; 317 break; 318 case 58: /* IPv6-ICMP */ 319 switch (pHdr[0]) 320 { 321 case 1: Log2((" + IPv6-ICMP: destination unreachable, code %d\n", pHdr[1])); break; 322 case 128: Log2((" + IPv6-ICMP: echo request\n")); break; 323 case 129: Log2((" + IPv6-ICMP: echo reply\n")); break; 324 default: Log2((" + IPv6-ICMP: unknown type %d, code %d\n", pHdr[0], pHdr[1])); break; 325 } 326 uProto = 0xFF; 327 break; 328 case 1: /* ICMP */ 329 switch (pHdr[0]) 330 { 331 case 0: Log2((" + ICMP: echo reply\n")); break; 332 case 8: Log2((" + ICMP: echo request\n")); break; 333 case 3: Log2((" + ICMP: destination unreachable, code %d\n", pHdr[1])); break; 334 default: Log2((" + ICMP: unknown type %d, code %d\n", pHdr[0], pHdr[1])); break; 335 } 336 uProto = 0xFF; 337 break; 338 case 6: /* TCP */ 339 Log2((" + TCP: src=%d dst=%d seq=%x ack=%x\n", 340 RT_N2H_U16(*(uint16_t*)(pHdr)), RT_N2H_U16(*(uint16_t*)(pHdr+2)), 341 RT_N2H_U32(*(uint32_t*)(pHdr+4)), RT_N2H_U32(*(uint32_t*)(pHdr+8)))); 342 uProto = 0xFF; 343 break; 344 case 17: /* UDP */ 345 Log2((" + UDP: src=%d dst=%d\n", 346 RT_N2H_U16(*(uint16_t*)(pHdr)), RT_N2H_U16(*(uint16_t*)(pHdr+2)))); 347 uProto = 0xFF; 348 break; 349 default: 350 Log2((" + Unknown: proto=0x%x\n", uProto)); 351 uProto = 0xFF; 352 break; 353 } 354 } 355 Log3(("%.*Rhxd\n", cb, bPacket)); 356 } 357 358 #else /* !DEBUG */ 359 //# define vboxNetAdpWinDumpFilterTypes(uFlags) do { } while (0) 360 //# define vboxNetAdpWinDumpOffloadSettings(p) do { } while (0) 361 //# define vboxNetAdpWinDumpSetOffloadSettings(p) do { } while (0) 362 # define vboxNetAdpWinDumpPackets(m,l) do { } while (0) 363 # define vboxNetAdpWinDumpPacket(p,t) do { } while (0) 364 #endif /* !DEBUG */ 365 366 367 DECLHIDDEN(VBOXNETADPWIN_PACKET_TYPE) vboxNetAdpWinPacketType(PINTNETSG pSG) 368 { 369 static const uint8_t g_abBcastAddr[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; 370 AssertReturn(pSG->cbTotal >= sizeof(g_abBcastAddr), kVBoxNetAdpWinPacketType_Unicast); 371 AssertReturn(pSG->cSegsUsed > 0, kVBoxNetAdpWinPacketType_Unicast); 372 AssertReturn(pSG->aSegs[0].cb >= sizeof(g_abBcastAddr), kVBoxNetAdpWinPacketType_Unicast); 373 if (!memcmp(pSG->aSegs[0].pv, g_abBcastAddr, sizeof(g_abBcastAddr))) 374 return kVBoxNetAdpWinPacketType_Broadcast; 375 if ((*(uint8_t*)pSG->aSegs[0].pv) & 1) 376 return kVBoxNetAdpWinPacketType_Multicast; 377 return kVBoxNetAdpWinPacketType_Unicast; 378 } 379 380 DECLINLINE(void) vboxNetAdpWinUpdateStats(uint64_t *pPacketStats, uint64_t *pOctetStats, PINTNETSG pSG) 381 { 382 VBOXNETADPWIN_PACKET_TYPE enmPktType = vboxNetAdpWinPacketType(pSG); 383 ASMAtomicIncU64(&pPacketStats[enmPktType]); 384 ASMAtomicAddU64(&pOctetStats[enmPktType], pSG->cbTotal); 385 } 386 387 DECLINLINE(void) vboxNetAdpWinFreeMdlChain(PMDL pMdl) 388 { 389 PMDL pMdlNext; 390 while (pMdl) 391 { 392 pMdlNext = pMdl->Next; 393 PUCHAR pDataBuf; 394 ULONG cb = 0; 395 NdisQueryMdl(pMdl, &pDataBuf, &cb, NormalPagePriority); 396 NdisFreeMdl(pMdl); 397 Log4(("vboxNetAdpWinFreeMdlChain: freed MDL 0x%p\n", pMdl)); 398 NdisFreeMemory(pDataBuf, 0, 0); 399 Log4(("vboxNetAdpWinFreeMdlChain: freed data buffer 0x%p\n", pDataBuf)); 400 pMdl = pMdlNext; 401 } 402 } 403 404 DECLHIDDEN(PNET_BUFFER_LIST) vboxNetAdpWinSGtoNB(PVBOXNETADP_ADAPTER pThis, PINTNETSG pSG) 405 { 406 AssertReturn(pSG->cSegsUsed >= 1, NULL); 407 LogFlow(("==>vboxNetAdpWinSGtoNB: segments=%d hPool=%p cb=%u\n", pSG->cSegsUsed, 408 pThis->hPool, pSG->cbTotal)); 409 AssertReturn(pThis->hPool, NULL); 410 411 412 PNET_BUFFER_LIST pBufList = NULL; 413 ULONG cbMdl = pSG->cbTotal; 414 ULONG uDataOffset = cbMdl - pSG->cbTotal; 415 PUCHAR pDataBuf = (PUCHAR)NdisAllocateMemoryWithTagPriority(pThis->hAdapter, cbMdl, 416 VBOXNETADP_MEM_TAG, NormalPoolPriority); 417 if (pDataBuf) 418 { 419 Log4(("vboxNetAdpWinSGtoNB: allocated data buffer (cb=%u) 0x%p\n", cbMdl, pDataBuf)); 420 PMDL pMdl = NdisAllocateMdl(pThis->hAdapter, pDataBuf, cbMdl); 421 if (!pMdl) 422 { 423 NdisFreeMemory(pDataBuf, 0, 0); 424 Log4(("vboxNetAdpWinSGtoNB: freed data buffer 0x%p\n", pDataBuf)); 425 LogError(("vboxNetAdpWinSGtoNB: failed to allocate an MDL (cb=%u)\n", cbMdl)); 426 LogFlow(("<==vboxNetAdpWinSGtoNB: return NULL\n")); 427 return NULL; 428 } 429 PUCHAR pDst = pDataBuf + uDataOffset; 430 for (int i = 0; i < pSG->cSegsUsed; i++) 431 { 432 NdisMoveMemory(pDst, pSG->aSegs[i].pv, pSG->aSegs[i].cb); 433 pDst += pSG->aSegs[i].cb; 434 } 435 pBufList = NdisAllocateNetBufferAndNetBufferList(pThis->hPool, 436 0 /* ContextSize */, 437 0 /* ContextBackFill */, 438 pMdl, 439 uDataOffset, 440 pSG->cbTotal); 441 if (pBufList) 442 { 443 Log4(("vboxNetAdpWinSGtoNB: allocated NBL+NB 0x%p\n", pBufList)); 444 pBufList->SourceHandle = pThis->hAdapter; 445 /** @todo Do we need to initialize anything else? */ 446 } 447 else 448 { 449 LogError(("vboxNetAdpWinSGtoNB: failed to allocate an NBL+NB\n")); 450 vboxNetAdpWinFreeMdlChain(pMdl); 451 } 452 } 453 else 454 { 455 LogError(("vboxNetAdpWinSGtoNB: failed to allocate data buffer (size=%u)\n", cbMdl)); 456 } 457 458 LogFlow(("<==vboxNetAdpWinSGtoNB: return %p\n", pBufList)); 459 return pBufList; 460 } 461 462 DECLINLINE(void) vboxNetAdpWinDestroySG(PINTNETSG pSG) 463 { 464 NdisFreeMemory(pSG, 0, 0); 465 Log4(("vboxNetAdpWinDestroySG: freed SG 0x%p\n", pSG)); 466 } 467 468 DECLINLINE(ULONG) vboxNetAdpWinCalcSegments(PNET_BUFFER pNetBuf) 469 { 470 ULONG cSegs = 0; 471 for (PMDL pMdl = NET_BUFFER_CURRENT_MDL(pNetBuf); pMdl; pMdl = NDIS_MDL_LINKAGE(pMdl)) 472 cSegs++; 473 return cSegs; 474 } 475 476 DECLHIDDEN(PINTNETSG) vboxNetAdpWinNBtoSG(PVBOXNETADP_ADAPTER pThis, PNET_BUFFER pNetBuf) 477 { 478 ULONG cbPacket = NET_BUFFER_DATA_LENGTH(pNetBuf); 479 UINT cSegs = vboxNetAdpWinCalcSegments(pNetBuf); 480 /* Allocate and initialize SG */ 481 PINTNETSG pSG = (PINTNETSG)NdisAllocateMemoryWithTagPriority(pThis->hAdapter, 482 RT_OFFSETOF(INTNETSG, aSegs[cSegs]), 483 VBOXNETADP_MEM_TAG, 484 NormalPoolPriority); 485 AssertReturn(pSG, pSG); 486 Log4(("vboxNetAdpWinNBtoSG: allocated SG 0x%p\n", pSG)); 487 IntNetSgInitTempSegs(pSG, cbPacket /*cbTotal*/, cSegs, cSegs /*cSegsUsed*/); 488 489 int rc = NDIS_STATUS_SUCCESS; 490 ULONG uOffset = NET_BUFFER_CURRENT_MDL_OFFSET(pNetBuf); 491 cSegs = 0; 492 for (PMDL pMdl = NET_BUFFER_CURRENT_MDL(pNetBuf); 493 pMdl != NULL && cbPacket > 0; 494 pMdl = NDIS_MDL_LINKAGE(pMdl)) 495 { 496 PUCHAR pSrc = (PUCHAR)MmGetSystemAddressForMdlSafe(pMdl, LowPagePriority); 497 if (!pSrc) 498 { 499 rc = NDIS_STATUS_RESOURCES; 500 break; 501 } 502 ULONG cbSrc = MmGetMdlByteCount(pMdl); 503 if (uOffset) 504 { 505 Assert(uOffset < cbSrc); 506 pSrc += uOffset; 507 cbSrc -= uOffset; 508 uOffset = 0; 509 } 510 511 if (cbSrc > cbPacket) 512 cbSrc = cbPacket; 513 514 pSG->aSegs[cSegs].pv = pSrc; 515 pSG->aSegs[cSegs].cb = cbSrc; 516 pSG->aSegs[cSegs].Phys = NIL_RTHCPHYS; 517 cSegs++; 518 cbPacket -= cbSrc; 519 } 520 521 Assert(cSegs <= pSG->cSegsAlloc); 522 523 if (RT_FAILURE(rc)) 524 { 525 vboxNetAdpWinDestroySG(pSG); 526 pSG = NULL; 527 } 528 else 529 { 530 Assert(cbPacket == 0); 531 Assert(pSG->cSegsUsed == cSegs); 532 } 533 return pSG; 534 } 535 536 DECLINLINE(bool) vboxNetAdpWinIsActive(PVBOXNETADP_ADAPTER pThis) 537 { 538 if (vboxNetAdpWinGetState(pThis) != kVBoxNetAdpWinState_Running) 539 return false; 540 if (pThis->enmTrunkState != INTNETTRUNKIFSTATE_ACTIVE) 541 return false; 542 AssertPtrReturn(pThis->pSwitchPort, false); 543 return true; 544 } 545 546 DECLHIDDEN(bool) vboxNetAdpWinForwardToIntNet(PVBOXNETADP_ADAPTER pThis, PNET_BUFFER_LIST pList, uint32_t fSrc) 547 { 548 if (!vboxNetAdpWinIsActive(pThis)) 549 { 550 LogFlow(("vboxNetAdpWinForwardToIntNet: not active\n")); 551 return false; 552 } 553 AssertReturn(pThis->pSwitchPort, false); 554 AssertReturn(pThis->pSwitchPort->pfnRecv, false); 555 LogFlow(("==>vboxNetAdpWinForwardToIntNet\n")); 556 557 if (ASMAtomicIncS32(&pThis->cBusy) == 1) 558 NdisResetEvent(&pThis->EventIdle); 559 for (PNET_BUFFER pBuf = NET_BUFFER_LIST_FIRST_NB(pList); pBuf; pBuf = NET_BUFFER_NEXT_NB(pBuf)) 560 { 561 PINTNETSG pSG = vboxNetAdpWinNBtoSG(pThis, pBuf); 562 if (pSG) 563 { 564 vboxNetAdpWinUpdateStats(pThis->au64StatsOutPackets, pThis->au64StatsOutOctets, pSG); 565 vboxNetAdpWinDumpPacket(pSG, (fSrc & INTNETTRUNKDIR_WIRE)?"intnet <-- wire":"intnet <-- host"); 566 pThis->pSwitchPort->pfnRecv(pThis->pSwitchPort, NULL, pSG, fSrc); 567 vboxNetAdpWinDestroySG(pSG); 568 } 569 } 570 if (ASMAtomicDecS32(&pThis->cBusy) == 0) 571 NdisSetEvent(&pThis->EventIdle); 572 573 return true; 574 } 575 576 577 /** 578 * @copydoc INTNETTRUNKIFPORT::pfnRetain 579 */ 580 static DECLCALLBACK(void) vboxNetAdpWinPortRetain(PINTNETTRUNKIFPORT pIfPort) 581 { 582 PVBOXNETADP_ADAPTER pThis = IFPORT_2_VBOXNETADP_ADAPTER(pIfPort); 583 RT_NOREF1(pThis); 584 LogFlow(("vboxNetAdpWinPortRetain: pThis=%p, pIfPort=%p\n", pThis, pIfPort)); 585 } 586 587 /** 588 * @copydoc INTNETTRUNKIFPORT::pfnRelease 589 */ 590 static DECLCALLBACK(void) vboxNetAdpWinPortRelease(PINTNETTRUNKIFPORT pIfPort) 591 { 592 PVBOXNETADP_ADAPTER pThis = IFPORT_2_VBOXNETADP_ADAPTER(pIfPort); 593 RT_NOREF1(pThis); 594 LogFlow(("vboxNetAdpWinPortRelease: pThis=%p, pIfPort=%p\n", pThis, pIfPort)); 595 } 596 597 /** 598 * @copydoc INTNETTRUNKIFPORT::pfnDisconnectAndRelease 599 */ 600 static DECLCALLBACK(void) vboxNetAdpWinPortDisconnectAndRelease(PINTNETTRUNKIFPORT pIfPort) 601 { 602 PVBOXNETADP_ADAPTER pThis = IFPORT_2_VBOXNETADP_ADAPTER(pIfPort); 603 604 LogFlow(("vboxNetAdpWinPortDisconnectAndRelease: pThis=%p, pIfPort=%p\n", pThis, pIfPort)); 605 /* 606 * Serious paranoia. 607 */ 608 AssertPtr(pThis); 609 Assert(pThis->MyPort.u32Version == INTNETTRUNKIFPORT_VERSION); 610 Assert(pThis->MyPort.u32VersionEnd == INTNETTRUNKIFPORT_VERSION); 611 AssertPtr(pThis->pGlobals); 612 Assert(pThis->szName[0]); 613 614 AssertPtr(pThis->pSwitchPort); 615 Assert(pThis->enmTrunkState == INTNETTRUNKIFSTATE_DISCONNECTING); 616 617 pThis->pSwitchPort = NULL; 618 } 619 620 /** 621 * @copydoc INTNETTRUNKIFPORT::pfnSetState 622 */ 623 static DECLCALLBACK(INTNETTRUNKIFSTATE) vboxNetAdpWinPortSetState(PINTNETTRUNKIFPORT pIfPort, INTNETTRUNKIFSTATE enmState) 624 { 625 PVBOXNETADP_ADAPTER pThis = IFPORT_2_VBOXNETADP_ADAPTER(pIfPort); 626 INTNETTRUNKIFSTATE enmOldTrunkState; 627 628 LogFlow(("vboxNetAdpWinPortSetState: pThis=%p, pIfPort=%p, enmState=%d\n", pThis, pIfPort, enmState)); 629 /* 630 * Input validation. 631 */ 632 AssertPtr(pThis); 633 AssertPtr(pThis->pGlobals); 634 Assert(pThis->MyPort.u32Version == INTNETTRUNKIFPORT_VERSION); 635 AssertPtrReturn(pThis->pSwitchPort, INTNETTRUNKIFSTATE_INVALID); 636 AssertReturn(enmState > INTNETTRUNKIFSTATE_INVALID && enmState < INTNETTRUNKIFSTATE_END, 637 INTNETTRUNKIFSTATE_INVALID); 638 639 enmOldTrunkState = pThis->enmTrunkState; 640 if (enmOldTrunkState != enmState) 641 ASMAtomicWriteU32((uint32_t volatile *)&pThis->enmTrunkState, enmState); 642 643 return enmOldTrunkState; 644 } 645 646 /** 647 * @copydoc INTNETTRUNKIFPORT::pfnWaitForIdle 648 */ 649 static DECLCALLBACK(int) vboxNetAdpWinPortWaitForIdle(PINTNETTRUNKIFPORT pIfPort, uint32_t cMillies) 650 { 651 PVBOXNETADP_ADAPTER pThis = IFPORT_2_VBOXNETADP_ADAPTER(pIfPort); 652 int rc; 653 654 LogFlow(("vboxNetAdpWinPortWaitForIdle: pThis=%p, pIfPort=%p, cMillies=%u\n", pThis, pIfPort, cMillies)); 655 /* 656 * Input validation. 657 */ 658 AssertPtr(pThis); 659 Assert(pThis->MyPort.u32Version == INTNETTRUNKIFPORT_VERSION); 660 AssertPtrReturn(pThis->pSwitchPort, VERR_INVALID_STATE); 661 AssertReturn(pThis->enmTrunkState == INTNETTRUNKIFSTATE_DISCONNECTING, VERR_INVALID_STATE); 662 663 rc = NdisWaitEvent(&pThis->EventIdle, cMillies) ? VINF_SUCCESS : VERR_TIMEOUT; 664 665 return rc; 666 } 667 668 /** 669 * @copydoc INTNETTRUNKIFPORT::pfnXmit 670 */ 671 static DECLCALLBACK(int) vboxNetAdpWinPortXmit(PINTNETTRUNKIFPORT pIfPort, void *pvIfData, PINTNETSG pSG, uint32_t fDst) 672 { 673 RT_NOREF1(fDst); 674 PVBOXNETADP_ADAPTER pThis = IFPORT_2_VBOXNETADP_ADAPTER(pIfPort); 675 int rc = VINF_SUCCESS; 676 677 LogFlow(("vboxNetAdpWinPortXmit: pThis=%p, pIfPort=%p, pvIfData=%p, pSG=%p, fDst=0x%x\n", pThis, pIfPort, pvIfData, pSG, fDst)); 678 RT_NOREF1(pvIfData); 679 /* 680 * Input validation. 681 */ 682 AssertPtr(pThis); 683 AssertPtr(pSG); 684 Assert(pThis->MyPort.u32Version == INTNETTRUNKIFPORT_VERSION); 685 AssertPtrReturn(pThis->pSwitchPort, VERR_INVALID_STATE); 686 687 vboxNetAdpWinDumpPacket(pSG, "intnet --> host"); 688 689 /* 690 * First of all, indicate we are busy. It is possible the trunk or the adapter 691 * will get paused or even disconnected, so we need to check the state after 692 * we have marked ourselves busy. 693 * Later, when NDIS returns all buffers, we will mark ourselves idle. 694 */ 695 if (ASMAtomicIncS32(&pThis->cBusy) == 1) 696 NdisResetEvent(&pThis->EventIdle); 697 698 if (vboxNetAdpWinIsActive(pThis)) 699 { 700 PNET_BUFFER_LIST pBufList = vboxNetAdpWinSGtoNB(pThis, pSG); 701 if (pBufList) 702 { 703 NdisMIndicateReceiveNetBufferLists(pThis->hAdapter, pBufList, NDIS_DEFAULT_PORT_NUMBER, 1, 0); 704 vboxNetAdpWinUpdateStats(pThis->au64StatsInPackets, pThis->au64StatsInOctets, pSG); 705 } 706 } 707 708 return rc; 709 } 710 711 /** 712 * @copydoc INTNETTRUNKIFPORT::pfnNotifyMacAddress 713 */ 714 static DECLCALLBACK(void) vboxNetAdpWinPortNotifyMacAddress(PINTNETTRUNKIFPORT pIfPort, void *pvIfData, PCRTMAC pMac) 715 { 716 PVBOXNETADP_ADAPTER pThis = IFPORT_2_VBOXNETADP_ADAPTER(pIfPort); 717 718 LogFlow(("vboxNetAdpWinPortNotifyMacAddress: pThis=%p, pIfPort=%p, pvIfData=%p, pMac=%p\n", pThis, pIfPort, pvIfData, pMac)); 719 RT_NOREF3(pThis, pvIfData, pMac); 720 /* 721 * Input validation. 722 */ 723 AssertPtr(pThis); 724 Assert(pThis->MyPort.u32Version == INTNETTRUNKIFPORT_VERSION); 725 726 // @todo Do we really need to handle this? 727 } 728 729 730 /** 731 * @copydoc INTNETTRUNKIFPORT::pfnConnectInterface 732 */ 733 static DECLCALLBACK(int) vboxNetAdpWinPortConnectInterface(PINTNETTRUNKIFPORT pIfPort, void *pvIf, void **ppvIfData) 734 { 735 PVBOXNETADP_ADAPTER pThis = IFPORT_2_VBOXNETADP_ADAPTER(pIfPort); 736 int rc; 737 738 LogFlow(("vboxNetAdpWinPortConnectInterface: pThis=%p, pIfPort=%p, pvIf=%p, ppvIfData=%p\n", pThis, pIfPort, pvIf, ppvIfData)); 739 RT_NOREF3(pThis, pvIf, ppvIfData); 740 /* 741 * Input validation. 742 */ 743 AssertPtr(pThis); 744 Assert(pThis->MyPort.u32Version == INTNETTRUNKIFPORT_VERSION); 745 746 rc = VINF_SUCCESS; 747 748 return rc; 749 } 750 751 752 /** 753 * @copydoc INTNETTRUNKIFPORT::pfnDisconnectInterface 754 */ 755 static DECLCALLBACK(void) vboxNetAdpWinPortDisconnectInterface(PINTNETTRUNKIFPORT pIfPort, void *pvIfData) 756 { 757 PVBOXNETADP_ADAPTER pThis = IFPORT_2_VBOXNETADP_ADAPTER(pIfPort); 758 int rc; 759 760 LogFlow(("vboxNetAdpWinPortDisconnectInterface: pThis=%p, pIfPort=%p, pvIfData=%p\n", pThis, pIfPort, pvIfData)); 761 RT_NOREF2(pThis, pvIfData); 762 /* 763 * Input validation. 764 */ 765 AssertPtr(pThis); 766 Assert(pThis->MyPort.u32Version == INTNETTRUNKIFPORT_VERSION); 767 768 rc = VINF_SUCCESS; 769 AssertRC(rc); 770 } 771 772 773 774 /** 775 * Implements the SUPDRV component factor interface query method. 776 * 777 * @returns Pointer to an interface. NULL if not supported. 778 * 779 * @param pSupDrvFactory Pointer to the component factory registration structure. 780 * @param pSession The session - unused. 781 * @param pszInterfaceUuid The factory interface id. 782 */ 783 static DECLCALLBACK(void *) vboxNetAdpWinQueryFactoryInterface(PCSUPDRVFACTORY pSupDrvFactory, PSUPDRVSESSION pSession, 784 const char *pszInterfaceUuid) 785 { 786 PVBOXNETADPGLOBALS pGlobals = (PVBOXNETADPGLOBALS)((uint8_t *)pSupDrvFactory - RT_OFFSETOF(VBOXNETADPGLOBALS, SupDrvFactory)); 787 788 /* 789 * Convert the UUID strings and compare them. 790 */ 791 RTUUID UuidReq; 792 int rc = RTUuidFromStr(&UuidReq, pszInterfaceUuid); 793 if (RT_SUCCESS(rc)) 794 { 795 if (!RTUuidCompareStr(&UuidReq, INTNETTRUNKFACTORY_UUID_STR)) 796 { 797 NdisAcquireSpinLock(&pGlobals->Lock); 798 if (pGlobals->enmIdcState == kVBoxNetAdpWinIdcState_Connected) 799 { 800 pGlobals->cFactoryRefs++; 801 NdisResetEvent(&pGlobals->EventUnloadAllowed); 802 } 803 NdisReleaseSpinLock(&pGlobals->Lock); 804 return &pGlobals->TrunkFactory; 805 } 806 #ifdef LOG_ENABLED 807 else 808 Log(("VBoxNetFlt: unknown factory interface query (%s)\n", pszInterfaceUuid)); 809 #endif 810 } 811 else 812 Log(("VBoxNetFlt: rc=%Rrc, uuid=%s\n", rc, pszInterfaceUuid)); 813 814 RT_NOREF1(pSession); 815 return NULL; 816 } 817 818 819 DECLHIDDEN(void) vboxNetAdpWinReportCapabilities(PVBOXNETADP_ADAPTER pThis) 820 { 821 if (pThis->pSwitchPort) 822 { 823 pThis->pSwitchPort->pfnReportMacAddress(pThis->pSwitchPort, &pThis->MacAddr); 824 /* Promiscuous mode makes no sense for host-only adapters, does it? */ 825 pThis->pSwitchPort->pfnReportGsoCapabilities(pThis->pSwitchPort, 0, 826 INTNETTRUNKDIR_WIRE | INTNETTRUNKDIR_HOST); 827 pThis->pSwitchPort->pfnReportNoPreemptDsts(pThis->pSwitchPort, 0 /* none */); 828 } 829 } 830 831 /** 832 * @copydoc INTNETTRUNKFACTORY::pfnCreateAndConnect 833 */ 834 static DECLCALLBACK(int) vboxNetAdpWinFactoryCreateAndConnect(PINTNETTRUNKFACTORY pIfFactory, const char *pszName, 835 PINTNETTRUNKSWPORT pSwitchPort, uint32_t fFlags, 836 PINTNETTRUNKIFPORT *ppIfPort) 837 { 838 PVBOXNETADPGLOBALS pGlobals = (PVBOXNETADPGLOBALS)((uint8_t *)pIfFactory - RT_OFFSETOF(VBOXNETADPGLOBALS, TrunkFactory)); 839 840 LogFlow(("==>vboxNetAdpWinFactoryCreateAndConnect: pszName=%p:{%s} fFlags=%#x\n", pszName, pszName, fFlags)); 841 Assert(pGlobals->cFactoryRefs > 0); 842 AssertMsgReturn(!(fFlags & ~(INTNETTRUNKFACTORY_FLAG_NO_PROMISC)), 843 ("%#x\n", fFlags), VERR_INVALID_PARAMETER); 844 845 PVBOXNETADP_ADAPTER pAdapter = NULL; 846 NdisAcquireSpinLock(&pGlobals->Lock); 847 RTListForEach(&g_VBoxNetAdpGlobals.ListOfAdapters, pAdapter, VBOXNETADP_ADAPTER, node) 848 { 849 Log(("vboxNetAdpWinFactoryCreateAndConnect: evaluating adapter=%s\n", pAdapter->szName)); 850 if (!RTStrICmp(pszName, pAdapter->szName)) 851 { 852 pAdapter->pSwitchPort = pSwitchPort; 853 *ppIfPort = &pAdapter->MyPort; 854 NdisReleaseSpinLock(&g_VBoxNetAdpGlobals.Lock); // @todo too early? adp should have been connected by the time we do this 855 Log(("vboxNetAdpWinFactoryCreateAndConnect: found matching adapter, name=%s\n", pszName)); 856 vboxNetAdpWinReportCapabilities(pAdapter); 857 // @todo I guess there is no need in vboxNetAdpWinRegisterIpAddrNotifier(pThis); 858 LogFlow(("<==vboxNetAdpWinFactoryCreateAndConnect: return VINF_SUCCESS\n")); 859 return VINF_SUCCESS; 860 } 861 } 862 NdisReleaseSpinLock(&pGlobals->Lock); 863 // @todo vboxNetAdpLogErrorEvent(IO_ERR_INTERNAL_ERROR, STATUS_SUCCESS, 6); 864 LogFlow(("<==vboxNetAdpWinFactoryCreateAndConnect: return VERR_INTNET_FLT_IF_NOT_FOUND\n")); 865 return VERR_INTNET_FLT_IF_NOT_FOUND; 866 } 867 868 869 /** 870 * @copydoc INTNETTRUNKFACTORY::pfnRelease 871 */ 872 static DECLCALLBACK(void) vboxNetAdpWinFactoryRelease(PINTNETTRUNKFACTORY pIfFactory) 873 { 874 PVBOXNETADPGLOBALS pGlobals = (PVBOXNETADPGLOBALS)((uint8_t *)pIfFactory - RT_OFFSETOF(VBOXNETADPGLOBALS, TrunkFactory)); 875 876 NdisAcquireSpinLock(&pGlobals->Lock); 877 int32_t cRefs = ASMAtomicDecS32(&pGlobals->cFactoryRefs); 878 if (cRefs == 0) 879 NdisSetEvent(&pGlobals->EventUnloadAllowed); 880 NdisReleaseSpinLock(&pGlobals->Lock); 881 Assert(cRefs >= 0); NOREF(cRefs); 882 LogFlow(("vboxNetAdpWinFactoryRelease: cRefs=%d (new)\n", cRefs)); 883 } 884 885 886 887 /* IDC */ 888 889 DECLINLINE(const char *) vboxNetAdpWinIdcStateToText(uint32_t enmState) 890 { 891 switch (enmState) 892 { 893 case kVBoxNetAdpWinIdcState_Disconnected: return "Disconnected"; 894 case kVBoxNetAdpWinIdcState_Connecting: return "Connecting"; 895 case kVBoxNetAdpWinIdcState_Connected: return "Connected"; 896 case kVBoxNetAdpWinIdcState_Stopping: return "Stopping"; 897 } 898 return "Unknown"; 899 } 900 901 static VOID vboxNetAdpWinInitIdcWorker(PVOID pvContext) 902 { 903 int rc; 904 PVBOXNETADPGLOBALS pGlobals = (PVBOXNETADPGLOBALS)pvContext; 905 906 /* 907 * Note that we break the rules here and access IDC state wihout acquiring 908 * the lock. This is ok because vboxNetAdpWinUnload will wait for this 909 * thread to terminate itself and we always use atomic access to IDC state. 910 * We check the state (while holding the lock) further when we have succeeded 911 * to connect. We cannot take the lock here and release it later as we will 912 * be holding it for too long. 913 */ 914 while (ASMAtomicReadU32(&pGlobals->enmIdcState) == kVBoxNetAdpWinIdcState_Connecting) 915 { 916 /* 917 * Establish a connection to SUPDRV and register our component factory. 918 */ 919 rc = SUPR0IdcOpen(&pGlobals->SupDrvIDC, 0 /* iReqVersion = default */, 0 /* iMinVersion = default */, NULL, NULL, NULL); 920 if (RT_SUCCESS(rc)) 921 { 922 rc = SUPR0IdcComponentRegisterFactory(&pGlobals->SupDrvIDC, &pGlobals->SupDrvFactory); 923 if (RT_SUCCESS(rc)) 924 { 925 /* 926 * At this point we should take the lock to access IDC state as 927 * we technically may now race with factory methods. 928 */ 929 NdisAcquireSpinLock(&pGlobals->Lock); 930 bool fSuccess = ASMAtomicCmpXchgU32(&pGlobals->enmIdcState, 931 kVBoxNetAdpWinIdcState_Connected, 932 kVBoxNetAdpWinIdcState_Connecting); 933 NdisReleaseSpinLock(&pGlobals->Lock); 934 if (!fSuccess) 935 { 936 /* The state has been changed (the only valid transition is to "Stopping"), undo init */ 937 rc = SUPR0IdcComponentDeregisterFactory(&pGlobals->SupDrvIDC, &pGlobals->SupDrvFactory); 938 AssertRC(rc); 939 SUPR0IdcClose(&pGlobals->SupDrvIDC); 940 Log(("vboxNetAdpWinInitIdcWorker: state change (Connecting -> %s) while initializing IDC, closed IDC, rc=0x%x\n", 941 vboxNetAdpWinIdcStateToText(ASMAtomicReadU32(&pGlobals->enmIdcState)), rc)); 942 } 943 else 944 { 945 Log(("vboxNetAdpWinInitIdcWorker: IDC state change Connecting -> Connected\n")); 946 } 947 } 948 } 949 else 950 { 951 LARGE_INTEGER WaitIn100nsUnits; 952 WaitIn100nsUnits.QuadPart = -(LONGLONG)5000000; /* 0.5 sec */ 953 KeDelayExecutionThread(KernelMode, FALSE /* non-alertable */, &WaitIn100nsUnits); 954 } 955 } 956 PsTerminateSystemThread(STATUS_SUCCESS); 957 } 958 959 960 DECLHIDDEN(int) vboxNetAdpWinStartInitIdcThread(PVBOXNETADPGLOBALS pGlobals) 961 { 962 int rc = VERR_INVALID_STATE; 963 964 /* No locking needed yet */ 965 if (ASMAtomicCmpXchgU32(&pGlobals->enmIdcState, kVBoxNetAdpWinIdcState_Connecting, kVBoxNetAdpWinIdcState_Disconnected)) 966 { 967 Log(("vboxNetAdpWinStartInitIdcThread: IDC state change Diconnected -> Connecting\n")); 968 969 NTSTATUS Status = PsCreateSystemThread(&g_VBoxNetAdpGlobals.hInitIdcThread, 970 THREAD_ALL_ACCESS, 971 NULL, 972 NULL, 973 NULL, 974 vboxNetAdpWinInitIdcWorker, 975 &g_VBoxNetAdpGlobals); 976 Log(("vboxNetAdpWinStartInitIdcThread: create IDC initialization thread, status=0x%x\n", Status)); 977 if (Status != STATUS_SUCCESS) 978 { 979 LogError(("vboxNetAdpWinStartInitIdcThread: IDC initialization failed (system thread creation, status=0x%x)\n", Status)); 980 /* 981 * We failed to init IDC and there will be no second chance. 982 */ 983 Log(("vboxNetAdpWinStartInitIdcThread: IDC state change Connecting -> Diconnected\n")); 984 ASMAtomicWriteU32(&g_VBoxNetAdpGlobals.enmIdcState, kVBoxNetAdpWinIdcState_Disconnected); 985 } 986 rc = RTErrConvertFromNtStatus(Status); 987 } 988 return rc; 989 } 990 991 992 993 /* === !!!! */ 148 994 149 995 … … 178 1024 NDIS_STATUS Status = NDIS_STATUS_SUCCESS; 179 1025 PVBOXNETADP_ADAPTER pAdapter = NULL; 1026 PVBOXNETADPGLOBALS pGlobals = &g_VBoxNetAdpGlobals; 180 1027 181 1028 LogFlow(("==>vboxNetAdpWinAllocAdapter: adapter handle=%p\n", hAdapter)); 182 1029 1030 /* Get the name */ 1031 UNICODE_STRING strUnicodeName; 1032 Status = NdisMQueryAdapterInstanceName(&strUnicodeName, hAdapter); 1033 if (Status != NDIS_STATUS_SUCCESS) 1034 { 1035 LogError(("vboxNetAdpWinAllocAdapter: NdisMQueryAdapterInstanceName failed with 0x%x\n", Status)); 1036 return Status; 1037 } 1038 1039 ANSI_STRING strAnsiName; 1040 /* We use the miniport name to associate this filter module with the netflt instance */ 1041 NTSTATUS rc = RtlUnicodeStringToAnsiString(&strAnsiName, 1042 &strUnicodeName, 1043 TRUE); 1044 if (rc != STATUS_SUCCESS) 1045 { 1046 LogError(("vboxNetAdpWinAllocAdapter: RtlUnicodeStringToAnsiString(%ls) failed with 0x%x\n", 1047 strUnicodeName, rc)); 1048 //vboxNetAdpLogErrorEvent(IO_ERR_INTERNAL_ERROR, NDIS_STATUS_FAILURE, 2); 1049 NdisFreeMemory(strUnicodeName.Buffer, 0, 0); 1050 return NDIS_STATUS_FAILURE; 1051 } 1052 NdisFreeMemory(strUnicodeName.Buffer, 0, 0); 1053 DbgPrint("vboxNetAdpWinAllocAdapter: name=%Z\n", &strAnsiName); 1054 183 1055 *ppAdapter = NULL; 184 1056 185 pAdapter = (PVBOXNETADP_ADAPTER)NdisAllocateMemoryWithTagPriority(g_VBoxNetAdpGlobals.hMiniportDriver, 186 sizeof(VBOXNETADP_ADAPTER), 187 VBOXNETADPWIN_TAG, 188 NormalPoolPriority); 1057 UINT cbAdapterWithNameExtra = sizeof(VBOXNETADP_ADAPTER) + strAnsiName.Length; 1058 pAdapter = (PVBOXNETADP_ADAPTER)NdisAllocateMemoryWithTagPriority(pGlobals->hMiniportDriver, 1059 cbAdapterWithNameExtra, 1060 VBOXNETADPWIN_TAG, 1061 NormalPoolPriority); 189 1062 if (!pAdapter) 190 1063 { 1064 RtlFreeAnsiString(&strAnsiName); 191 1065 Status = NDIS_STATUS_RESOURCES; 192 1066 Log(("vboxNetAdpWinAllocAdapter: Out of memory while allocating adapter context (size=%d)\n", sizeof(VBOXNETADP_ADAPTER))); … … 194 1068 else 195 1069 { 196 NdisZeroMemory(pAdapter, sizeof(VBOXNETADP_ADAPTER)); 1070 NdisZeroMemory(pAdapter, cbAdapterWithNameExtra); 1071 NdisMoveMemory(pAdapter->szName, strAnsiName.Buffer, strAnsiName.Length); 1072 RtlFreeAnsiString(&strAnsiName); 1073 1074 /* Allocate buffer pool */ 1075 NET_BUFFER_LIST_POOL_PARAMETERS PoolParams; 1076 NdisZeroMemory(&PoolParams, sizeof(PoolParams)); 1077 PoolParams.Header.Type = NDIS_OBJECT_TYPE_DEFAULT; 1078 PoolParams.Header.Revision = NET_BUFFER_LIST_POOL_PARAMETERS_REVISION_1; 1079 PoolParams.Header.Size = sizeof(PoolParams); 1080 PoolParams.ProtocolId = NDIS_PROTOCOL_ID_DEFAULT; 1081 PoolParams.fAllocateNetBuffer = TRUE; 1082 PoolParams.ContextSize = 0; 1083 PoolParams.PoolTag = VBOXNETADP_MEM_TAG; 1084 pAdapter->hPool = NdisAllocateNetBufferListPool(hAdapter, &PoolParams); 1085 if (!pAdapter->hPool) 1086 { 1087 LogError(("vboxNetAdpWinAllocAdapter: NdisAllocateNetBufferListPool failed\n")); 1088 NdisFreeMemory(pAdapter, 0, 0); 1089 return NDIS_STATUS_RESOURCES; 1090 } 1091 Log4(("vboxNetAdpWinAllocAdapter: allocated NBL+NB pool 0x%p\n", pAdapter->hPool)); 1092 197 1093 pAdapter->hAdapter = hAdapter; 198 pAdapter->pGlobals = &g_VBoxNetAdpGlobals; 199 /// @todo Use netadp structure instead! 200 /* Use a locally administered version of the OUI we use for the guest NICs. */ 201 pAdapter->MacAddr.au8[0] = 0x08 | 2; 202 pAdapter->MacAddr.au8[1] = 0x00; 203 pAdapter->MacAddr.au8[2] = 0x27; 204 205 pAdapter->MacAddr.au8[3] = (uIfIndex >> 16) & 0xFF; 206 pAdapter->MacAddr.au8[4] = (uIfIndex >> 8) & 0xFF; 207 pAdapter->MacAddr.au8[5] = uIfIndex & 0xFF; 208 209 /// @todo Statistics? 1094 pAdapter->MyPort.u32Version = INTNETTRUNKIFPORT_VERSION; 1095 pAdapter->MyPort.pfnRetain = vboxNetAdpWinPortRetain; 1096 pAdapter->MyPort.pfnRelease = vboxNetAdpWinPortRelease; 1097 pAdapter->MyPort.pfnDisconnectAndRelease = vboxNetAdpWinPortDisconnectAndRelease; 1098 pAdapter->MyPort.pfnSetState = vboxNetAdpWinPortSetState; 1099 pAdapter->MyPort.pfnWaitForIdle = vboxNetAdpWinPortWaitForIdle; 1100 pAdapter->MyPort.pfnXmit = vboxNetAdpWinPortXmit; 1101 pAdapter->MyPort.pfnNotifyMacAddress = vboxNetAdpWinPortNotifyMacAddress; 1102 pAdapter->MyPort.pfnConnectInterface = vboxNetAdpWinPortConnectInterface; 1103 pAdapter->MyPort.pfnDisconnectInterface = vboxNetAdpWinPortDisconnectInterface; 1104 pAdapter->MyPort.u32VersionEnd = INTNETTRUNKIFPORT_VERSION; 1105 pAdapter->pGlobals = pGlobals; 1106 pAdapter->enmAdapterState = kVBoxNetAdpWinState_Initializing; 1107 pAdapter->enmTrunkState = INTNETTRUNKIFSTATE_INACTIVE; 1108 pAdapter->cBusy = 0; 1109 NdisInitializeEvent(&pAdapter->EventIdle); 1110 NdisSetEvent(&pAdapter->EventIdle); /* We are idle initially */ 1111 1112 /* Use a locally administered version of the OUI we use for the guest NICs. */ 1113 pAdapter->MacAddr.au8[0] = 0x08 | 2; 1114 pAdapter->MacAddr.au8[1] = 0x00; 1115 pAdapter->MacAddr.au8[2] = 0x27; 1116 1117 pAdapter->MacAddr.au8[3] = (uIfIndex >> 16) & 0xFF; 1118 pAdapter->MacAddr.au8[4] = (uIfIndex >> 8) & 0xFF; 1119 pAdapter->MacAddr.au8[5] = uIfIndex & 0xFF; 1120 1121 NdisAcquireSpinLock(&pGlobals->Lock); 1122 RTListPrepend(&pGlobals->ListOfAdapters, &pAdapter->node); 1123 NdisReleaseSpinLock(&pGlobals->Lock); 210 1124 211 1125 *ppAdapter = pAdapter; … … 217 1131 DECLHIDDEN(void) vboxNetAdpWinFreeAdapter(PVBOXNETADP_ADAPTER pAdapter) 218 1132 { 1133 /* Remove from adapter chain */ 1134 NdisAcquireSpinLock(&pAdapter->pGlobals->Lock); 1135 RTListNodeRemove(&pAdapter->node); 1136 NdisReleaseSpinLock(&pAdapter->pGlobals->Lock); 1137 219 1138 NdisFreeMemory(pAdapter, 0, 0); 220 1139 } … … 316 1235 break; 317 1236 } 1237 1238 VBOXNETADPWIN_ADAPTER_STATE enmPrevState = vboxNetAdpWinSetState(pAdapter, kVBoxNetAdpWinState_Paused); 1239 RT_NOREF1(enmPrevState); 1240 Assert(enmPrevState == kVBoxNetAdpWinState_Initializing); 318 1241 } while (false); 319 1242 … … 332 1255 { 333 1256 RT_NOREF1(HaltAction); 334 PVBOXNETADP_ADAPTER p Adapter= (PVBOXNETADP_ADAPTER)MiniportAdapterContext;1257 PVBOXNETADP_ADAPTER pThis = (PVBOXNETADP_ADAPTER)MiniportAdapterContext; 335 1258 LogFlow(("==>vboxNetAdpWinHaltEx\n")); 336 /// @todo Stop something? 337 if (pAdapter) 338 vboxNetAdpWinFreeAdapter(pAdapter); 1259 AssertPtr(pThis); 1260 Assert(vboxNetAdpWinGetState(pThis) == kVBoxNetAdpWinState_Paused); 1261 /* 1262 * Check if the trunk is active which means the adapter gets disabled 1263 * while it is used by VM(s) and we need to disconnect the trunk. 1264 */ 1265 if (pThis->pSwitchPort && pThis->enmTrunkState == INTNETTRUNKIFSTATE_ACTIVE) 1266 pThis->pSwitchPort->pfnDisconnect(pThis->pSwitchPort, &pThis->MyPort, NULL); 1267 /* 1268 * Since we are already in the paused state and we have disconnected 1269 * the trunk, we can safely destroy this adapter. 1270 */ 1271 vboxNetAdpWinFreeAdapter(pThis); 339 1272 LogFlow(("<==vboxNetAdpWinHaltEx\n")); 340 1273 } … … 343 1276 IN PNDIS_MINIPORT_PAUSE_PARAMETERS MiniportPauseParameters) 344 1277 { 345 RT_NOREF2(MiniportAdapterContext, MiniportPauseParameters); 1278 RT_NOREF1(MiniportPauseParameters); 1279 PVBOXNETADP_ADAPTER pThis = (PVBOXNETADP_ADAPTER)MiniportAdapterContext; 346 1280 NDIS_STATUS Status = NDIS_STATUS_SUCCESS; 347 1281 LogFlow(("==>vboxNetAdpWinPause\n")); 1282 VBOXNETADPWIN_ADAPTER_STATE enmPrevState = vboxNetAdpWinSetState(pThis, kVBoxNetAdpWinState_Pausing); 1283 Assert(enmPrevState == kVBoxNetAdpWinState_Running); 1284 if (!NdisWaitEvent(&pThis->EventIdle, 1000 /* ms */)) 1285 { 1286 LogError(("vboxNetAdpWinPause: timed out while pausing the adapter\n")); 1287 // @todo implement NDIS_STATUS_PENDING case? probably not. 1288 } 1289 enmPrevState = vboxNetAdpWinSetState(pThis, kVBoxNetAdpWinState_Paused); 1290 Assert(enmPrevState == kVBoxNetAdpWinState_Pausing); 348 1291 LogFlow(("<==vboxNetAdpWinPause: status=0x%x\n", Status)); 349 1292 return Status; … … 353 1296 IN PNDIS_MINIPORT_RESTART_PARAMETERS MiniportRestartParameters) 354 1297 { 355 RT_NOREF2(MiniportAdapterContext, MiniportRestartParameters); 1298 RT_NOREF1(MiniportRestartParameters); 1299 PVBOXNETADP_ADAPTER pThis = (PVBOXNETADP_ADAPTER)MiniportAdapterContext; 356 1300 NDIS_STATUS Status = NDIS_STATUS_SUCCESS; 357 1301 LogFlow(("==>vboxNetAdpWinRestart\n")); 1302 VBOXNETADPWIN_ADAPTER_STATE enmPrevState = vboxNetAdpWinSetState(pThis, kVBoxNetAdpWinState_Restarting); 1303 Assert(enmPrevState == kVBoxNetAdpWinState_Paused); 1304 // @todo anything? 1305 enmPrevState = vboxNetAdpWinSetState(pThis, kVBoxNetAdpWinState_Running); 1306 Assert(enmPrevState == kVBoxNetAdpWinState_Restarting); 358 1307 LogFlow(("<==vboxNetAdpWinRestart: status=0x%x\n", Status)); 359 1308 return Status; 360 1309 } 361 1310 362 DECLHIDDEN(NDIS_STATUS) vboxNetAdpWinOidRqQuery(PVBOXNETADP_ADAPTER pAdapter, 1311 DECLINLINE(uint64_t) vboxNetAdpWinStatsTotals(uint64_t *pStats) 1312 { 1313 return pStats[kVBoxNetAdpWinPacketType_Unicast] 1314 + pStats[kVBoxNetAdpWinPacketType_Multicast] 1315 + pStats[kVBoxNetAdpWinPacketType_Broadcast]; 1316 } 1317 1318 DECLINLINE(PVOID) vboxNetAdpWinStatsU64(uint64_t *pTmp, ULONG *pcbTmp, uint64_t u64Stat) 1319 { 1320 *pcbTmp = sizeof(*pTmp); 1321 *pTmp = u64Stat; 1322 return pTmp; 1323 } 1324 1325 DECLHIDDEN(NDIS_STATUS) vboxNetAdpWinOidRqQuery(PVBOXNETADP_ADAPTER pThis, 363 1326 PNDIS_OID_REQUEST pRequest) 364 1327 { … … 395 1358 ulTmp = VBOXNETADP_MAX_FRAME_SIZE; 396 1359 break; 397 case OID_GEN_RCV_OK:398 case OID_GEN_XMIT_OK:399 u64Tmp = 0;400 pInfo = &u64Tmp;401 cbInfo = sizeof(u64Tmp);402 break;403 1360 case OID_GEN_RECEIVE_BUFFER_SPACE: 404 1361 case OID_GEN_TRANSMIT_BUFFER_SPACE: 405 1362 /// @todo Make configurable 406 1363 ulTmp = VBOXNETADP_MAX_FRAME_SIZE * 40; 1364 break; 1365 case OID_GEN_RCV_OK: 1366 pInfo = vboxNetAdpWinStatsU64(&u64Tmp, &cbInfo, vboxNetAdpWinStatsTotals(pThis->au64StatsInPackets)); 1367 break; 1368 case OID_GEN_XMIT_OK: 1369 pInfo = vboxNetAdpWinStatsU64(&u64Tmp, &cbInfo, vboxNetAdpWinStatsTotals(pThis->au64StatsOutPackets)); 407 1370 break; 408 1371 case OID_GEN_STATISTICS: … … 418 1381 pStats->Header.Revision = NDIS_STATISTICS_INFO_REVISION_1; 419 1382 pStats->Header.Size = NDIS_SIZEOF_STATISTICS_INFO_REVISION_1; 420 /// @todo We need some stats, don't we? 1383 pStats->SupportedStatistics = 1384 NDIS_STATISTICS_FLAGS_VALID_DIRECTED_FRAMES_RCV 1385 | NDIS_STATISTICS_FLAGS_VALID_MULTICAST_FRAMES_RCV 1386 | NDIS_STATISTICS_FLAGS_VALID_BROADCAST_FRAMES_RCV 1387 | NDIS_STATISTICS_FLAGS_VALID_BYTES_RCV 1388 | NDIS_STATISTICS_FLAGS_VALID_RCV_DISCARDS 1389 | NDIS_STATISTICS_FLAGS_VALID_RCV_ERROR 1390 | NDIS_STATISTICS_FLAGS_VALID_DIRECTED_FRAMES_XMIT 1391 | NDIS_STATISTICS_FLAGS_VALID_MULTICAST_FRAMES_XMIT 1392 | NDIS_STATISTICS_FLAGS_VALID_BROADCAST_FRAMES_XMIT 1393 | NDIS_STATISTICS_FLAGS_VALID_BYTES_XMIT 1394 | NDIS_STATISTICS_FLAGS_VALID_XMIT_ERROR 1395 | NDIS_STATISTICS_FLAGS_VALID_XMIT_DISCARDS 1396 | NDIS_STATISTICS_FLAGS_VALID_DIRECTED_BYTES_RCV 1397 | NDIS_STATISTICS_FLAGS_VALID_MULTICAST_BYTES_RCV 1398 | NDIS_STATISTICS_FLAGS_VALID_BROADCAST_BYTES_RCV 1399 | NDIS_STATISTICS_FLAGS_VALID_DIRECTED_BYTES_XMIT 1400 | NDIS_STATISTICS_FLAGS_VALID_MULTICAST_BYTES_XMIT 1401 | NDIS_STATISTICS_FLAGS_VALID_BROADCAST_BYTES_XMIT; 1402 1403 pStats->ifHCInOctets = vboxNetAdpWinStatsTotals(pThis->au64StatsInOctets); 1404 pStats->ifHCInUcastPkts = ASMAtomicReadU64(&pThis->au64StatsInPackets[kVBoxNetAdpWinPacketType_Unicast]); 1405 pStats->ifHCInMulticastPkts = ASMAtomicReadU64(&pThis->au64StatsInPackets[kVBoxNetAdpWinPacketType_Multicast]); 1406 pStats->ifHCInBroadcastPkts = ASMAtomicReadU64(&pThis->au64StatsInPackets[kVBoxNetAdpWinPacketType_Broadcast]); 1407 pStats->ifHCOutOctets = vboxNetAdpWinStatsTotals(pThis->au64StatsOutOctets);; 1408 pStats->ifHCOutUcastPkts = ASMAtomicReadU64(&pThis->au64StatsOutPackets[kVBoxNetAdpWinPacketType_Unicast]); 1409 pStats->ifHCOutMulticastPkts = ASMAtomicReadU64(&pThis->au64StatsOutPackets[kVBoxNetAdpWinPacketType_Multicast]); 1410 pStats->ifHCOutBroadcastPkts = ASMAtomicReadU64(&pThis->au64StatsOutPackets[kVBoxNetAdpWinPacketType_Broadcast]); 1411 pStats->ifHCInUcastOctets = ASMAtomicReadU64(&pThis->au64StatsInOctets[kVBoxNetAdpWinPacketType_Unicast]); 1412 pStats->ifHCInMulticastOctets = ASMAtomicReadU64(&pThis->au64StatsInOctets[kVBoxNetAdpWinPacketType_Multicast]); 1413 pStats->ifHCInBroadcastOctets = ASMAtomicReadU64(&pThis->au64StatsInOctets[kVBoxNetAdpWinPacketType_Broadcast]); 1414 pStats->ifHCOutUcastOctets = ASMAtomicReadU64(&pThis->au64StatsOutOctets[kVBoxNetAdpWinPacketType_Unicast]); 1415 pStats->ifHCOutMulticastOctets = ASMAtomicReadU64(&pThis->au64StatsOutOctets[kVBoxNetAdpWinPacketType_Multicast]); 1416 pStats->ifHCOutBroadcastOctets = ASMAtomicReadU64(&pThis->au64StatsOutOctets[kVBoxNetAdpWinPacketType_Broadcast]); 421 1417 break; 422 1418 } … … 433 1429 case OID_802_3_PERMANENT_ADDRESS: 434 1430 case OID_802_3_CURRENT_ADDRESS: 435 pInfo = &p Adapter->MacAddr;436 cbInfo = sizeof(p Adapter->MacAddr);1431 pInfo = &pThis->MacAddr; 1432 cbInfo = sizeof(pThis->MacAddr); 437 1433 break; 438 1434 //case OID_802_3_MULTICAST_LIST: … … 441 1437 break; 442 1438 case OID_PNP_CAPABILITIES: 443 pInfo = &p Adapter->pGlobals->PMCaps;444 cbInfo = sizeof(p Adapter->pGlobals->PMCaps);1439 pInfo = &pThis->pGlobals->PMCaps; 1440 cbInfo = sizeof(pThis->pGlobals->PMCaps); 445 1441 break; 446 1442 case OID_PNP_QUERY_POWER: … … 574 1570 LogFlow(("==>vboxNetAdpWinSendNetBufferLists\n")); 575 1571 PNET_BUFFER_LIST pNbl = NetBufferLists; 1572 vboxNetAdpWinDumpPackets("vboxNetAdpWinSendNetBufferLists: got", pNbl); 1573 1574 /* We alwast complete all send requests. */ 576 1575 for (pNbl = NetBufferLists; pNbl; pNbl = NET_BUFFER_LIST_NEXT_NBL(pNbl)) 1576 { 1577 vboxNetAdpWinForwardToIntNet(pAdapter, pNbl, INTNETTRUNKDIR_HOST); 577 1578 NET_BUFFER_LIST_STATUS(pNbl) = NDIS_STATUS_SUCCESS; 1579 } 578 1580 NdisMSendNetBufferListsComplete(pAdapter->hAdapter, NetBufferLists, 579 1581 (SendFlags & NDIS_SEND_FLAGS_DISPATCH_LEVEL) ? … … 586 1588 IN ULONG ReturnFlags) 587 1589 { 588 RT_NOREF3(MiniportAdapterContext, NetBufferLists, ReturnFlags);589 1590 LogFlow(("==>vboxNetAdpWinReturnNetBufferLists\n")); 590 Log(("vboxNetAdpWinReturnNetBufferLists: We should not be here!\n")); 1591 RT_NOREF1(ReturnFlags); 1592 PVBOXNETADP_ADAPTER pThis = (PVBOXNETADP_ADAPTER)MiniportAdapterContext; 1593 PNET_BUFFER_LIST pList = NetBufferLists; 1594 while (pList) 1595 { 1596 Assert(pList->SourceHandle == pThis->hAdapter); 1597 Assert(NET_BUFFER_LIST_FIRST_NB(pList)); 1598 Assert(NET_BUFFER_FIRST_MDL(NET_BUFFER_LIST_FIRST_NB(pList))); 1599 1600 PNET_BUFFER_LIST pNextList = NET_BUFFER_LIST_NEXT_NBL(pList); 1601 1602 vboxNetAdpWinFreeMdlChain(NET_BUFFER_FIRST_MDL(NET_BUFFER_LIST_FIRST_NB(pList))); 1603 NdisFreeNetBufferList(pList); 1604 Log4(("vboxNetLwfWinReturnNetBufferLists: freed NBL+NB+MDL+Data 0x%p\n", pList)); 1605 Assert(ASMAtomicReadS32(&pThis->cBusy) > 0); 1606 if (ASMAtomicDecS32(&pThis->cBusy) == 0) 1607 NdisSetEvent(&pThis->EventIdle); 1608 1609 pList = pNextList; 1610 } 591 1611 LogFlow(("<==vboxNetAdpWinReturnNetBufferLists\n")); 592 1612 } … … 654 1674 RT_NOREF1(DriverObject); 655 1675 LogFlow(("==>vboxNetAdpWinUnload\n")); 656 //vboxNetAdpWinDevDestroy(&g_VBoxNetAdpGlobals); 657 if (g_VBoxNetAdpGlobals.hMiniportDriver) 658 NdisMDeregisterMiniportDriver(g_VBoxNetAdpGlobals.hMiniportDriver); 659 //NdisFreeSpinLock(&g_VBoxNetAdpGlobals.Lock); 1676 PVBOXNETADPGLOBALS pGlobals = &g_VBoxNetAdpGlobals; 1677 int rc; 1678 NDIS_STATUS Status; 1679 PKTHREAD pThread = NULL; 1680 1681 /* We are about to disconnect IDC, let's make it clear so the factories will know */ 1682 NdisAcquireSpinLock(&pGlobals->Lock); 1683 uint32_t enmPrevState = ASMAtomicXchgU32(&g_VBoxNetAdpGlobals.enmIdcState, kVBoxNetAdpWinIdcState_Stopping); 1684 NdisReleaseSpinLock(&pGlobals->Lock); 1685 Log(("vboxNetAdpWinUnload: IDC state change %s -> Stopping\n", vboxNetAdpWinIdcStateToText(enmPrevState))); 1686 1687 switch (enmPrevState) 1688 { 1689 case kVBoxNetAdpWinIdcState_Disconnected: 1690 /* Have not even attempted to connect -- nothing to do. */ 1691 break; 1692 case kVBoxNetAdpWinIdcState_Stopping: 1693 /* Impossible, but another thread is alreading doing StopIdc, bail out */ 1694 LogError(("vboxNetAdpWinUnload: called in 'Stopping' state\n")); 1695 break; 1696 case kVBoxNetAdpWinIdcState_Connecting: 1697 /* the worker thread is running, let's wait for it to stop */ 1698 Status = ObReferenceObjectByHandle(g_VBoxNetAdpGlobals.hInitIdcThread, 1699 THREAD_ALL_ACCESS, NULL, KernelMode, 1700 (PVOID*)&pThread, NULL); 1701 if (Status == STATUS_SUCCESS) 1702 { 1703 KeWaitForSingleObject(pThread, Executive, KernelMode, FALSE, NULL); 1704 ObDereferenceObject(pThread); 1705 } 1706 else 1707 { 1708 LogError(("vboxNetAdpWinStopIdc: ObReferenceObjectByHandle(%p) failed with 0x%x\n", 1709 g_VBoxNetAdpGlobals.hInitIdcThread, Status)); 1710 } 1711 break; 1712 case kVBoxNetAdpWinIdcState_Connected: 1713 /* the worker succeeded in IDC init and terminated */ 1714 /* Make sure nobody uses the trunk factory. Wait half a second if needed. */ 1715 if (!NdisWaitEvent(&pGlobals->EventUnloadAllowed, 500)) 1716 LogRel(("VBoxNetAdp: unloading driver while trunk factory is in use!\n")); 1717 rc = SUPR0IdcComponentDeregisterFactory(&pGlobals->SupDrvIDC, &pGlobals->SupDrvFactory); 1718 AssertRC(rc); 1719 SUPR0IdcClose(&pGlobals->SupDrvIDC); 1720 Log(("vboxNetAdpWinUnload: closed IDC, rc=0x%x\n", rc)); 1721 break; 1722 } 1723 if (pGlobals->hMiniportDriver) 1724 NdisMDeregisterMiniportDriver(pGlobals->hMiniportDriver); 1725 NdisFreeSpinLock(&pGlobals->Lock); 660 1726 LogFlow(("<==vboxNetAdpWinUnload\n")); 1727 RTLogDestroy(RTLogRelSetDefaultInstance(NULL)); 1728 RTLogDestroy(RTLogSetDefaultInstance(NULL)); 661 1729 RTR0Term(); 662 1730 } … … 709 1777 { 710 1778 Log(("vboxNetAdpWinRegister: successfully registered miniport driver; registering device...\n")); 711 //Status = vboxNetAdpWinDevCreate(&g_VBoxNetAdpGlobals);712 //Assert(Status == STATUS_SUCCESS);713 //Log(("vboxNetAdpWinRegister: vboxNetAdpWinDevCreate() returned 0x%x\n", Status));714 1779 } 715 1780 else … … 738 1803 { 739 1804 NdisZeroMemory(&g_VBoxNetAdpGlobals, sizeof (g_VBoxNetAdpGlobals)); 740 //NdisAllocateSpinLock(&g_VBoxNetAdpGlobals.Lock); 1805 RTListInit(&g_VBoxNetAdpGlobals.ListOfAdapters); 1806 NdisAllocateSpinLock(&g_VBoxNetAdpGlobals.Lock); 1807 NdisInitializeEvent(&g_VBoxNetAdpGlobals.EventUnloadAllowed); 741 1808 //g_VBoxNetAdpGlobals.PMCaps.WakeUpCapabilities.Flags = NDIS_DEVICE_WAKE_UP_ENABLE; 742 1809 g_VBoxNetAdpGlobals.PMCaps.WakeUpCapabilities.MinMagicPacketWakeUp = NdisDeviceStateUnspecified; 743 1810 g_VBoxNetAdpGlobals.PMCaps.WakeUpCapabilities.MinPatternWakeUp = NdisDeviceStateUnspecified; 744 1811 745 Status = vboxNetAdpWinRegister(pDriverObject, pRegistryPath); 746 Assert(Status == STATUS_SUCCESS); 747 if (Status == NDIS_STATUS_SUCCESS) 748 { 749 Log(("NETADP: started successfully\n")); 750 return STATUS_SUCCESS; 751 } 752 //NdisFreeSpinLock(&g_VBoxNetAdpGlobals.Lock); 1812 /* Initialize SupDrv interface */ 1813 g_VBoxNetAdpGlobals.SupDrvFactory.pfnQueryFactoryInterface = vboxNetAdpWinQueryFactoryInterface; 1814 memcpy(g_VBoxNetAdpGlobals.SupDrvFactory.szName, "VBoxNetAdp", sizeof("VBoxNetAdp")); 1815 /* Initialize trunk factory interface */ 1816 g_VBoxNetAdpGlobals.TrunkFactory.pfnRelease = vboxNetAdpWinFactoryRelease; 1817 g_VBoxNetAdpGlobals.TrunkFactory.pfnCreateAndConnect = vboxNetAdpWinFactoryCreateAndConnect; 1818 1819 rc = vboxNetAdpWinStartInitIdcThread(&g_VBoxNetAdpGlobals); 1820 if (RT_SUCCESS(rc)) 1821 { 1822 Status = vboxNetAdpWinRegister(pDriverObject, pRegistryPath); 1823 Assert(Status == STATUS_SUCCESS); 1824 if (Status == NDIS_STATUS_SUCCESS) 1825 { 1826 Log(("NETADP: started successfully\n")); 1827 return STATUS_SUCCESS; 1828 } 1829 } 1830 else 1831 Status = NDIS_STATUS_FAILURE; 1832 NdisFreeSpinLock(&g_VBoxNetAdpGlobals.Lock); 753 1833 RTLogDestroy(RTLogRelSetDefaultInstance(NULL)); 754 1834 RTLogDestroy(RTLogSetDefaultInstance(NULL));
注意:
瀏覽 TracChangeset
來幫助您使用更動檢視器