- Merge aicom-network-fixes up to r36740
[reactos.git] / reactos / drivers / network / tcpip / datalink / lan.c
index 1355c00..35a5797 100644 (file)
@@ -201,6 +201,8 @@ VOID STDCALL ProtocolOpenAdapterComplete(
 
     TI_DbgPrint(DEBUG_DATALINK, ("Called.\n"));
 
+    Adapter->NdisStatus = Status;
+
     KeSetEvent(&Adapter->Event, 0, FALSE);
 }
 
@@ -235,7 +237,13 @@ VOID STDCALL ProtocolResetComplete(
  *     Status         = Status of the operation
  */
 {
-    TI_DbgPrint(MID_TRACE, ("Called.\n"));
+    PLAN_ADAPTER Adapter = (PLAN_ADAPTER)BindingContext;
+
+    TI_DbgPrint(DEBUG_DATALINK, ("Called.\n"));
+
+    Adapter->NdisStatus = Status;
+
+    KeSetEvent(&Adapter->Event, 0, FALSE);
 }
 
 
@@ -298,32 +306,32 @@ VOID LanReceiveWorker( PVOID Context ) {
     Packet = WorkItem->Packet;
     Adapter = WorkItem->Adapter;
     BytesTransferred = WorkItem->BytesTransferred;
-    
+
     IPPacket.NdisPacket = Packet;
-    
+
     NdisGetFirstBufferFromPacket(Packet,
                                 &NdisBuffer,
                                 &IPPacket.Header,
                                 &IPPacket.ContigSize,
                                 &IPPacket.TotalSize);
-    
+
     IPPacket.ContigSize = IPPacket.TotalSize = BytesTransferred;
     /* Determine which upper layer protocol that should receive
        this packet and pass it to the correct receive handler */
-    
+
     TI_DbgPrint(MID_TRACE,
                ("ContigSize: %d, TotalSize: %d, BytesTransferred: %d\n",
                 IPPacket.ContigSize, IPPacket.TotalSize,
                 BytesTransferred));
-    
+
     PacketType = PC(IPPacket.NdisPacket)->PacketType;
     IPPacket.Position = 0;
-    
+
     TI_DbgPrint
        (DEBUG_DATALINK,
         ("Ether Type = %x ContigSize = %d Total = %d\n",
          PacketType, IPPacket.ContigSize, IPPacket.TotalSize));
-    
+
     switch (PacketType) {
     case ETYPE_IPv4:
     case ETYPE_IPv6:
@@ -336,7 +344,7 @@ VOID LanReceiveWorker( PVOID Context ) {
     default:
        break;
     }
-    
+
     FreeNdisPacket( Packet );
 }
 
@@ -485,18 +493,9 @@ NDIS_STATUS STDCALL ProtocolReceive(
     }
     else
     {
-       if (NdisStatus == NDIS_STATUS_SUCCESS)
-        {
-           ASSERT(PacketSize <= Adapter->MTU);
-
-            NdisTransferData(&NdisStatus, Adapter->NdisHandle,
-                             MacReceiveContext, 0, PacketSize,
-                            NdisPacket, &BytesTransferred);
-        }
-        else
-        {
-            BytesTransferred = 0;
-        }
+        NdisTransferData(&NdisStatus, Adapter->NdisHandle,
+                         MacReceiveContext, 0, PacketSize,
+                        NdisPacket, &BytesTransferred);
     }
     TI_DbgPrint(DEBUG_DATALINK, ("Calling complete\n"));
 
@@ -526,19 +525,44 @@ VOID STDCALL ProtocolReceiveComplete(
 
 VOID STDCALL ProtocolStatus(
     NDIS_HANDLE BindingContext,
-    NDIS_STATUS GenerelStatus,
+    NDIS_STATUS GeneralStatus,
     PVOID StatusBuffer,
     UINT StatusBufferSize)
 /*
  * FUNCTION: Called by NDIS when the underlying driver has changed state
  * ARGUMENTS:
  *     BindingContext   = Pointer to a device context (LAN_ADAPTER)
- *     GenerelStatus    = A generel status code
+ *     GeneralStatus    = A general status code
  *     StatusBuffer     = Pointer to a buffer with medium-specific data
  *     StatusBufferSize = Number of bytes in StatusBuffer
  */
 {
+    PLAN_ADAPTER Adapter = BindingContext;
+
     TI_DbgPrint(DEBUG_DATALINK, ("Called.\n"));
+
+    switch(GeneralStatus)
+    {
+      case NDIS_STATUS_MEDIA_CONNECT:
+         DbgPrint("NDIS_STATUS_MEDIA_CONNECT\n");
+         break;
+
+      case NDIS_STATUS_MEDIA_DISCONNECT:
+         DbgPrint("NDIS_STATUS_MEDIA_DISCONNECT\n");
+         break;
+
+      case NDIS_STATUS_RESET_START:
+         Adapter->State = LAN_STATE_RESETTING;
+         break;
+
+      case NDIS_STATUS_RESET_END:
+         Adapter->State = LAN_STATE_STARTED;
+         break;
+
+      default:
+         DbgPrint("Unhandled status: %x", GeneralStatus);
+         break;
+    }
 }
 
 
@@ -597,8 +621,8 @@ VOID LANTransmit(
     PETH_HEADER EHeader;
     PCHAR Data;
     UINT Size;
-    KIRQL OldIrql;
     PLAN_ADAPTER Adapter = (PLAN_ADAPTER)Context;
+    KIRQL OldIrql;
 
     TI_DbgPrint(DEBUG_DATALINK,
                ("Called( NdisPacket %x, Offset %d, Adapter %x )\n",
@@ -677,7 +701,7 @@ VOID LANTransmit(
 
        TcpipAcquireSpinLock( &Adapter->Lock, &OldIrql );
        TI_DbgPrint(MID_TRACE, ("NdisSend\n"));
-        NdisSend(&NdisStatus, Adapter->NdisHandle, NdisPacket);
+       NdisSend(&NdisStatus, Adapter->NdisHandle, NdisPacket);
        TI_DbgPrint(MID_TRACE, ("NdisSend %s\n",
                                NdisStatus == NDIS_STATUS_PENDING ?
                                "Pending" : "Complete"));
@@ -841,29 +865,43 @@ static NTSTATUS FindDeviceDescForAdapter( PUNICODE_STRING Name,
         ExAllocatePool(NonPagedPool, sizeof(KEY_BASIC_INFORMATION));
     ULONG KbioLength = sizeof(KEY_BASIC_INFORMATION), ResultLength;
 
+    if( !Kbio ) return STATUS_INSUFFICIENT_RESOURCES;
+
     RtlInitUnicodeString
         (&EnumKeyName, CCS_ROOT L"\\Control\\Class\\" TCPIP_GUID);
 
     Status = OpenRegistryKey( &EnumKeyName, &EnumKey );
 
-    if( !NT_SUCCESS(Status) )
+    if( !NT_SUCCESS(Status) ) {
         TI_DbgPrint(DEBUG_DATALINK,("Couldn't open Enum key %wZ: %x\n",
                                     &EnumKeyName, Status));
+        ExFreePool( Kbio );
+        return Status;
+    }
 
     for( i = 0; NT_SUCCESS(Status); i++ ) {
         Status = ZwEnumerateKey( EnumKey, i, KeyBasicInformation,
                                  Kbio, KbioLength, &ResultLength );
 
-        if( Status == STATUS_BUFFER_TOO_SMALL ) {
+        if( Status == STATUS_BUFFER_TOO_SMALL || Status == STATUS_BUFFER_OVERFLOW ) {
             ExFreePool( Kbio );
             KbioLength = ResultLength;
             Kbio = ExAllocatePool( NonPagedPool, KbioLength );
+            if( !Kbio ) {
+                TI_DbgPrint(DEBUG_DATALINK,("Failed to allocate memory\n"));
+                NtClose( EnumKey );
+                return STATUS_NO_MEMORY;
+            }
 
             Status = ZwEnumerateKey( EnumKey, i, KeyBasicInformation,
                                      Kbio, KbioLength, &ResultLength );
 
-            TI_DbgPrint(DEBUG_DATALINK,("Couldn't enum key child %d\n", i));
-            return Status;
+            if( !NT_SUCCESS(Status) ) {
+                TI_DbgPrint(DEBUG_DATALINK,("Couldn't enum key child %d\n", i));
+                NtClose( EnumKey );
+                ExFreePool( Kbio );
+                return Status;
+            }
         }
 
         if( NT_SUCCESS(Status) ) {
@@ -875,6 +913,7 @@ static NTSTATUS FindDeviceDescForAdapter( PUNICODE_STRING Name,
                 ( &EnumKeyName, &TargetKeyName, Name, DeviceDesc );
             if( NT_SUCCESS(Status) ) {
                 NtClose( EnumKey );
+                ExFreePool( Kbio );
                 return Status;
             } else Status = STATUS_SUCCESS;
         }
@@ -883,6 +922,7 @@ static NTSTATUS FindDeviceDescForAdapter( PUNICODE_STRING Name,
     RtlInitUnicodeString( DeviceDesc, L"" );
     AppendUnicodeString( DeviceDesc, &TargetKeyName, FALSE );
     NtClose( EnumKey );
+    ExFreePool( Kbio );
     return STATUS_UNSUCCESSFUL;
 }
 
@@ -1193,11 +1233,6 @@ NDIS_STATUS LANRegisterAdapter(
     /* Convert returned link speed to bps (it is in 100bps increments) */
     IF->Speed = Speed * 100L;
 
-    /* Add adapter to the adapter list */
-    ExInterlockedInsertTailList(&AdapterListHead,
-                                &IF->ListEntry,
-                                &AdapterListLock);
-
     /* Bind adapter to IP layer */
     if( !BindAdapter(IF, RegistryPath) ) {
        TI_DbgPrint(DEBUG_DATALINK,("denying adapter %wZ (BindAdapter)\n", AdapterName));
@@ -1205,6 +1240,11 @@ NDIS_STATUS LANRegisterAdapter(
        return NDIS_STATUS_NOT_ACCEPTED;
     }
 
+    /* Add adapter to the adapter list */
+    ExInterlockedInsertTailList(&AdapterListHead,
+                                &IF->ListEntry,
+                                &AdapterListLock);
+
     TI_DbgPrint(DEBUG_DATALINK, ("Leaving.\n"));
 
     return NDIS_STATUS_SUCCESS;
@@ -1253,7 +1293,7 @@ NDIS_STATUS LANUnregisterAdapter(
 
     FreeAdapter(Adapter);
 
-    return NDIS_STATUS_SUCCESS;
+    return NdisStatus;
 }