[NDIS]
authorCameron Gutman <aicommander@gmail.com>
Fri, 23 Jul 2010 16:34:35 +0000 (16:34 +0000)
committerCameron Gutman <aicommander@gmail.com>
Fri, 23 Jul 2010 16:34:35 +0000 (16:34 +0000)
- Verify that each adapter has been initialized before passing it to the protocol's BindAdapter function
- Also verify that each adapter has not already been bound to the protocol
- Miniport drivers can now function without a reboot (needed to use 3rd-party NIC drivers on the live CD)

svn path=/trunk/; revision=48212

reactos/drivers/network/ndis/include/protocol.h
reactos/drivers/network/ndis/ndis/miniport.c
reactos/drivers/network/ndis/ndis/protocol.c

index 171ecb6..a2fd528 100644 (file)
@@ -71,6 +71,6 @@ proSendPacketToMiniport(PLOGICAL_ADAPTER Adapter, PNDIS_PACKET Packet);
 
 VOID
 NTAPI
 
 VOID
 NTAPI
-ndisBindMiniportsToProtocol(OUT PNDIS_STATUS Status, IN PNDIS_PROTOCOL_CHARACTERISTICS ProtocolCharacteristics);
+ndisBindMiniportsToProtocol(OUT PNDIS_STATUS Status, IN PPROTOCOL_BINDING Protocol);
 
 /* EOF */
 
 /* EOF */
index b1ca384..bfe4123 100644 (file)
@@ -2064,7 +2064,7 @@ NdisIPnPStartDevice(
   {
       ProtocolBinding = CONTAINING_RECORD(CurrentEntry, PROTOCOL_BINDING, ListEntry);
 
   {
       ProtocolBinding = CONTAINING_RECORD(CurrentEntry, PROTOCOL_BINDING, ListEntry);
 
-      ndisBindMiniportsToProtocol(&NdisStatus, &ProtocolBinding->Chars);
+      ndisBindMiniportsToProtocol(&NdisStatus, ProtocolBinding);
 
       CurrentEntry = CurrentEntry->Flink;
   }
 
       CurrentEntry = CurrentEntry->Flink;
   }
index 3817391..f41017b 100644 (file)
@@ -865,9 +865,39 @@ NdisOpenAdapter(
   *Status = NDIS_STATUS_SUCCESS;
 }
 
   *Status = NDIS_STATUS_SUCCESS;
 }
 
+PADAPTER_BINDING
+NTAPI
+LocateAdapterBindingByName(IN PPROTOCOL_BINDING ProtocolBinding, IN PNDIS_STRING AdapterName)
+{
+    PLIST_ENTRY CurrentEntry;
+    PADAPTER_BINDING AdapterBinding;
+    KIRQL OldIrql;
+
+    KeAcquireSpinLock(&ProtocolBinding->Lock, &OldIrql);
+
+    CurrentEntry = ProtocolBinding->AdapterListHead.Flink;
+
+    while (CurrentEntry != &ProtocolBinding->AdapterListHead)
+    {
+         AdapterBinding = CONTAINING_RECORD(CurrentEntry, ADAPTER_BINDING, ProtocolListEntry);
+
+         if (RtlCompareUnicodeString(AdapterName, &AdapterBinding->Adapter->NdisMiniportBlock.MiniportName, TRUE) == 0)
+         {
+             KeReleaseSpinLock(&ProtocolBinding->Lock, OldIrql);
+             return AdapterBinding;
+         }
+
+         CurrentEntry = CurrentEntry->Flink;
+    }
+
+    KeReleaseSpinLock(&ProtocolBinding->Lock, OldIrql);
+
+    return NULL;
+}
+
 VOID
 NTAPI
 VOID
 NTAPI
-ndisBindMiniportsToProtocol(OUT PNDIS_STATUS Status, IN PNDIS_PROTOCOL_CHARACTERISTICS ProtocolCharacteristics)
+ndisBindMiniportsToProtocol(OUT PNDIS_STATUS Status, IN PPROTOCOL_BINDING Protocol)
 {
   /*
    * bind the protocol to all of its miniports
 {
   /*
    * bind the protocol to all of its miniports
@@ -883,6 +913,7 @@ ndisBindMiniportsToProtocol(OUT PNDIS_STATUS Status, IN PNDIS_PROTOCOL_CHARACTER
     WCHAR *DataPtr;
     HANDLE DriverKeyHandle = NULL;
     PKEY_VALUE_PARTIAL_INFORMATION KeyInformation = NULL;
     WCHAR *DataPtr;
     HANDLE DriverKeyHandle = NULL;
     PKEY_VALUE_PARTIAL_INFORMATION KeyInformation = NULL;
+    PNDIS_PROTOCOL_CHARACTERISTICS ProtocolCharacteristics = &Protocol->Chars;
 
     RegistryPathStr = ExAllocatePoolWithTag(PagedPool, sizeof(SERVICES_KEY) + ProtocolCharacteristics->Name.Length + sizeof(LINKAGE_KEY), NDIS_TAG + __LINE__);
     if(!RegistryPathStr)
 
     RegistryPathStr = ExAllocatePoolWithTag(PagedPool, sizeof(SERVICES_KEY) + ProtocolCharacteristics->Name.Length + sizeof(LINKAGE_KEY), NDIS_TAG + __LINE__);
     if(!RegistryPathStr)
@@ -952,6 +983,9 @@ ndisBindMiniportsToProtocol(OUT PNDIS_STATUS Status, IN PNDIS_PROTOCOL_CHARACTER
       }
   }
 
       }
   }
 
+  /* Assume success for now */
+  *Status = NDIS_STATUS_SUCCESS;
+
   for (DataPtr = (WCHAR *)KeyInformation->Data;
        *DataPtr != 0;
        DataPtr += wcslen(DataPtr) + 1)
   for (DataPtr = (WCHAR *)KeyInformation->Data;
        *DataPtr != 0;
        DataPtr += wcslen(DataPtr) + 1)
@@ -965,6 +999,20 @@ ndisBindMiniportsToProtocol(OUT PNDIS_STATUS Status, IN PNDIS_PROTOCOL_CHARACTER
 
       RtlInitUnicodeString(&DeviceName, DataPtr);      /* we know this is 0-term */
 
 
       RtlInitUnicodeString(&DeviceName, DataPtr);      /* we know this is 0-term */
 
+      /* Make sure the adapter has started */
+      if (!MiniLocateDevice(&DeviceName))
+      {
+          /* It wasn't in the global miniport list, so skip the bind entry */
+          continue;
+      }
+
+      /* Make sure this device isn't already bound to this protocol */
+      if (LocateAdapterBindingByName(Protocol, &DeviceName))
+      {
+          /* It was already in this protocol's bound adapter list, so skip the bind entry */
+          continue;
+      }
+
       /*
        * RegistryPath should be:
        *     \Registry\Machine\System\CurrentControlSet\Services\Nic1\Parameters\Tcpip
       /*
        * RegistryPath should be:
        *     \Registry\Machine\System\CurrentControlSet\Services\Nic1\Parameters\Tcpip
@@ -1011,7 +1059,6 @@ ndisBindMiniportsToProtocol(OUT PNDIS_STATUS Status, IN PNDIS_PROTOCOL_CHARACTER
         }
     }
 
         }
     }
 
-   *Status = NDIS_STATUS_SUCCESS;
    ExFreePool(KeyInformation);
 }
 
    ExFreePool(KeyInformation);
 }
 
@@ -1111,7 +1158,7 @@ NdisRegisterProtocol(
 
   *NdisProtocolHandle = Protocol;
 
 
   *NdisProtocolHandle = Protocol;
 
-  ndisBindMiniportsToProtocol(Status, &Protocol->Chars);
+  ndisBindMiniportsToProtocol(Status, Protocol);
 
   /* Should we only send this if ndisBindMiniportsToProtocol succeeds? */
   PnPEvent = ProSetupPnPEvent(NetEventBindsComplete, NULL, 0);
 
   /* Should we only send this if ndisBindMiniportsToProtocol succeeds? */
   PnPEvent = ProSetupPnPEvent(NetEventBindsComplete, NULL, 0);
@@ -1252,10 +1299,9 @@ VOID
 NTAPI
 NdisReEnumerateProtocolBindings(IN NDIS_HANDLE NdisProtocolHandle)
 {
 NTAPI
 NdisReEnumerateProtocolBindings(IN NDIS_HANDLE NdisProtocolHandle)
 {
-    PPROTOCOL_BINDING Protocol = NdisProtocolHandle;
     NDIS_STATUS NdisStatus;
 
     NDIS_STATUS NdisStatus;
 
-    ndisBindMiniportsToProtocol(&NdisStatus, &Protocol->Chars);
+    ndisBindMiniportsToProtocol(&NdisStatus, NdisProtocolHandle);
 }
 
 
 }