Use DriverDesc in the registry as the adapter name since the ndis name OID
seems generally unimplemented.  What a pain.
Modified: trunk/reactos/drivers/net/tcpip/datalink/lan.c
Modified: trunk/reactos/drivers/net/tcpip/include/info.h
Modified: trunk/reactos/drivers/net/tcpip/include/tcpip.h

Modified: trunk/reactos/drivers/net/tcpip/datalink/lan.c
--- trunk/reactos/drivers/net/tcpip/datalink/lan.c	2005-04-14 22:41:48 UTC (rev 14623)
+++ trunk/reactos/drivers/net/tcpip/datalink/lan.c	2005-04-15 00:48:25 UTC (rev 14624)
@@ -18,6 +18,9 @@
 UINT LanReceiveWorkerCalled = 0;
 BOOLEAN LanReceiveWorkerBusy = FALSE;
 
+#define CCS_ROOT L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet"
+#define TCPIP_GUID L"{4D36E972-E325-11CE-BFC1-08002BE10318}"
+
 #define NGFP(_Packet)                                             \
     {                                                             \
         PVOID _Header;                                            \
@@ -331,21 +334,21 @@
 	IPPacket.Position = 0;
 
 	TI_DbgPrint
-		(DEBUG_DATALINK,
-		 ("Ether Type = %x ContigSize = %d Total = %d\n",
-		  PacketType, IPPacket.ContigSize, IPPacket.TotalSize));
+            (DEBUG_DATALINK,
+             ("Ether Type = %x ContigSize = %d Total = %d\n",
+              PacketType, IPPacket.ContigSize, IPPacket.TotalSize));
 	
         switch (PacketType) {
-            case ETYPE_IPv4:
-            case ETYPE_IPv6:
-		TI_DbgPrint(MID_TRACE,("Received IP Packet\n"));
-                IPReceive(Adapter->Context, &IPPacket);
-                break;
-            case ETYPE_ARP:
-		TI_DbgPrint(MID_TRACE,("Received ARP Packet\n"));
-                ARPReceive(Adapter->Context, &IPPacket);
-            default:
-                break;
+        case ETYPE_IPv4:
+        case ETYPE_IPv6:
+            TI_DbgPrint(MID_TRACE,("Received IP Packet\n"));
+            IPReceive(Adapter->Context, &IPPacket);
+            break;
+        case ETYPE_ARP:
+            TI_DbgPrint(MID_TRACE,("Received ARP Packet\n"));
+            ARPReceive(Adapter->Context, &IPPacket);
+        default:
+            break;
         }
 
 	FreeNdisPacket( Packet );
@@ -599,10 +602,10 @@
  *     SystemSpecific2: Unused & must not be touched
  */
 {
-	/* XXX confirm that this is still true, or re-word the following comment */
-	/* we get to ignore BindContext because we will never pend an operation with NDIS */
-	TI_DbgPrint(DEBUG_DATALINK, ("Called with registry path %wZ for %wZ\n", SystemSpecific1, DeviceName));
-	*Status = LANRegisterAdapter(DeviceName, SystemSpecific1);
+    /* XXX confirm that this is still true, or re-word the following comment */
+    /* we get to ignore BindContext because we will never pend an operation with NDIS */
+    TI_DbgPrint(DEBUG_DATALINK, ("Called with registry path %wZ for %wZ\n", SystemSpecific1, DeviceName));
+    *Status = LANRegisterAdapter(DeviceName, SystemSpecific1);
 }
 
 
@@ -664,25 +667,25 @@
             RtlCopyMemory(EHeader->SrcAddr, Adapter->HWAddress, IEEE_802_ADDR_LENGTH);
 
             switch (Type) {
-                case LAN_PROTO_IPv4:
-                    EHeader->EType = ETYPE_IPv4;
-                    break;
-                case LAN_PROTO_ARP:
-                    EHeader->EType = ETYPE_ARP;
-                    break;
-                case LAN_PROTO_IPv6:
-                    EHeader->EType = ETYPE_IPv6;
-                    break;
-                default:
+            case LAN_PROTO_IPv4:
+                EHeader->EType = ETYPE_IPv4;
+                break;
+            case LAN_PROTO_ARP:
+                EHeader->EType = ETYPE_ARP;
+                break;
+            case LAN_PROTO_IPv6:
+                EHeader->EType = ETYPE_IPv6;
+                break;
+            default:
 #ifdef DBG
-                    /* Should not happen */
-                    TI_DbgPrint(MIN_TRACE, ("Unknown LAN protocol.\n"));
+                /* Should not happen */
+                TI_DbgPrint(MIN_TRACE, ("Unknown LAN protocol.\n"));
 
-                    ProtocolSendComplete((NDIS_HANDLE)Context,
-                                         NdisPacket,
-                                         NDIS_STATUS_FAILURE);
+                ProtocolSendComplete((NDIS_HANDLE)Context,
+                                     NdisPacket,
+                                     NDIS_STATUS_FAILURE);
 #endif
-                    return;
+                return;
             }
             break;
 
@@ -729,7 +732,7 @@
     NTSTATUS Status;
     
     InitializeObjectAttributes(&Attributes, RegistryPath, OBJ_CASE_INSENSITIVE, 0, 0);
-    Status = ZwOpenKey(RegHandle, GENERIC_READ, &Attributes);
+    Status = ZwOpenKey(RegHandle, KEY_ALL_ACCESS, &Attributes);
     return Status;
 }
 
@@ -811,7 +814,7 @@
     TI_DbgPrint(MIN_TRACE, ("Information DataLength: 0x%x\n", Information->DataLength));
     
     UnicodeString.Buffer = (PWCHAR)&Information->Data;
-    UnicodeString.Length = Information->DataLength;
+    UnicodeString.Length = Information->DataLength - sizeof(WCHAR);
     UnicodeString.MaximumLength = Information->DataLength;
  
     String->Buffer = 
@@ -826,34 +829,163 @@
     return STATUS_SUCCESS;
 }
 
-static VOID GetSimpleAdapterNameFromRegistryPath
-( PUNICODE_STRING TargetString,
-  PUNICODE_STRING RegistryPath ) {
-    PWCHAR i, LastSlash = NULL;
-    UINT NewStringLength = 0;
+/* 
+ * Utility to copy and append two unicode strings.
+ *
+ * IN OUT PUNICODE_STRING ResultFirst -> First string and result
+ * IN     PUNICODE_STRING Second      -> Second string to append
+ * IN     BOOL            Deallocate  -> TRUE: Deallocate First string before
+ *                                       overwriting.
+ *
+ * Returns NTSTATUS.
+ */
 
-    for( i = RegistryPath->Buffer; 
-	 i < RegistryPath->Buffer + 
-	     (RegistryPath->Length / sizeof(WCHAR));
-	 i++ ) if( *i == '\\' ) LastSlash = i;
+NTSTATUS NTAPI AppendUnicodeString(PUNICODE_STRING ResultFirst,
+				   PUNICODE_STRING Second,
+				   BOOL Deallocate) {
+    NTSTATUS Status;
+    UNICODE_STRING Ustr = *ResultFirst;
+    PWSTR new_string = ExAllocatePoolWithTag
+        (PagedPool,
+         (ResultFirst->Length + Second->Length + sizeof(WCHAR)), TAG_STRING);
+    if( !new_string ) {
+	return STATUS_NO_MEMORY;
+    }
+    memcpy( new_string, ResultFirst->Buffer, ResultFirst->Length );
+    memcpy( new_string + ResultFirst->Length / sizeof(WCHAR),
+	    Second->Buffer, Second->Length );
+    if( Deallocate ) RtlFreeUnicodeString(ResultFirst);
+    ResultFirst->Length = Ustr.Length + Second->Length;
+    ResultFirst->MaximumLength = ResultFirst->Length;
+    new_string[ResultFirst->Length / sizeof(WCHAR)] = 0;
+    Status = RtlCreateUnicodeString(ResultFirst,new_string) ? 
+	STATUS_SUCCESS : STATUS_NO_MEMORY;
+    ExFreePool(new_string);
+    return Status;
+}
 
-    if( LastSlash ) LastSlash++; else LastSlash = RegistryPath->Buffer;
+static NTSTATUS CheckForDeviceDesc( PUNICODE_STRING EnumKeyName,
+                                    PUNICODE_STRING TargetKeyName,
+                                    PUNICODE_STRING ShortName,
+                                    PUNICODE_STRING OutName ) {
+    UNICODE_STRING RootDevice = { 0 }, LinkageKeyName = { 0 };
+    UNICODE_STRING DescKeyName = { 0 }, Linkage = { 0 };
+    UNICODE_STRING BackSlash = { 0 };
+    HANDLE DescKey = NULL, LinkageKey = NULL;
+    NTSTATUS Status;
 
-    NewStringLength = RegistryPath->MaximumLength - 
-	((LastSlash - RegistryPath->Buffer) * sizeof(WCHAR));
+    TI_DbgPrint(DEBUG_DATALINK,("EnumKeyName %wZ\n", EnumKeyName));
 
-    TargetString->Buffer = 
-	(PWCHAR)exAllocatePool( NonPagedPool, NewStringLength );
+    RtlInitUnicodeString(&BackSlash, L"\\");
+    RtlInitUnicodeString(&Linkage, L"\\Linkage");
 
-    if( !TargetString->Buffer ) {
-	TargetString->Length = TargetString->MaximumLength = 0;
-	return;
+    RtlInitUnicodeString(&DescKeyName, L"");
+    AppendUnicodeString( &DescKeyName, EnumKeyName, FALSE );
+    AppendUnicodeString( &DescKeyName, &BackSlash, TRUE );
+    AppendUnicodeString( &DescKeyName, TargetKeyName, TRUE );
+
+    RtlInitUnicodeString(&LinkageKeyName, L"");
+    AppendUnicodeString( &LinkageKeyName, &DescKeyName, FALSE );
+    AppendUnicodeString( &LinkageKeyName, &Linkage, TRUE );
+
+    Status = OpenRegistryKey( &LinkageKeyName, &LinkageKey );
+    if( !NT_SUCCESS(Status) ) goto cleanup;
+
+    Status = ReadStringFromRegistry( LinkageKey, L"RootDevice", &RootDevice );
+    if( !NT_SUCCESS(Status) ) goto cleanup;
+
+    if( RtlCompareUnicodeString( &RootDevice, ShortName, TRUE ) == 0 ) {
+        Status = OpenRegistryKey( &DescKeyName, &DescKey );
+        if( !NT_SUCCESS(Status) ) goto cleanup;
+
+        Status = ReadStringFromRegistry( DescKey, L"DriverDesc", OutName );
+        if( !NT_SUCCESS(Status) ) goto cleanup;
+
+        TI_DbgPrint(DEBUG_DATALINK,("ADAPTER NAME: %wZ\n", OutName));
+    } else Status = STATUS_UNSUCCESSFUL;
+
+cleanup:
+    RtlFreeUnicodeString( &RootDevice );
+    RtlFreeUnicodeString( &LinkageKeyName );
+    RtlFreeUnicodeString( &DescKeyName );
+    if( LinkageKey ) NtClose( LinkageKey );
+    if( DescKey ) NtClose( DescKey );
+
+    TI_DbgPrint(DEBUG_DATALINK,("Returning %x\n", Status));
+
+    return Status;
+}
+
+static NTSTATUS FindDeviceNameForAdapter( PUNICODE_STRING ShortName,
+                                          PUNICODE_STRING OutName ) {
+    UNICODE_STRING EnumKeyName, TargetKeyName;
+    HANDLE EnumKey;
+    NTSTATUS Status;
+    ULONG i;
+    KEY_BASIC_INFORMATION *Kbio = 
+        ExAllocatePool(NonPagedPool, sizeof(KEY_BASIC_INFORMATION));
+    ULONG KbioLength = sizeof(KEY_BASIC_INFORMATION), ResultLength;
+
+    RtlInitUnicodeString
+        (&EnumKeyName, CCS_ROOT L"\\Control\\Class\\" TCPIP_GUID);
+
+    Status = OpenRegistryKey( &EnumKeyName, &EnumKey );
+
+    if( !NT_SUCCESS(Status) )
+        TI_DbgPrint(DEBUG_DATALINK,("Couldn't open Enum key %wZ: %x\n", 
+                                    &EnumKeyName, Status));
+    
+    for( i = 0; NT_SUCCESS(Status); i++ ) {
+        Status = ZwEnumerateKey( EnumKey, i, KeyBasicInformation, 
+                                 Kbio, KbioLength, &ResultLength );
+
+        if( Status == STATUS_BUFFER_TOO_SMALL ) {
+            ExFreePool( Kbio );
+            KbioLength = ResultLength;
+            Kbio = ExAllocatePool( NonPagedPool, KbioLength );
+
+            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) ) {
+            TargetKeyName.Length = TargetKeyName.MaximumLength = 
+                Kbio->NameLength;
+            TargetKeyName.Buffer = Kbio->Name;
+
+            Status = CheckForDeviceDesc
+                ( &EnumKeyName, &TargetKeyName, ShortName, OutName );
+            if( NT_SUCCESS(Status) ) {
+                NtClose( EnumKey );
+                return Status;
+            } else Status = STATUS_SUCCESS;
+        }
     }
 
-    TargetString->Length = TargetString->MaximumLength = NewStringLength;
-    RtlCopyMemory( TargetString->Buffer, LastSlash, NewStringLength );
+    RtlInitUnicodeString( OutName, L"" );
+    AppendUnicodeString( OutName, &TargetKeyName, FALSE );
+    NtClose( EnumKey );
+    return STATUS_UNSUCCESSFUL;
 }
 
+VOID GetShortName( PUNICODE_STRING RegistryKey,
+                   PUNICODE_STRING ShortNameOut ) {
+    PWCHAR Ptr;
+    ShortNameOut->Buffer = 
+        RegistryKey->Buffer + wcslen(CCS_ROOT L"\\Services\\");
+    Ptr = ShortNameOut->Buffer;
+
+    while( *Ptr != L'\\' && 
+           ((PCHAR)Ptr) < ((PCHAR)RegistryKey->Buffer) + RegistryKey->Length ) 
+        Ptr++;
+
+    ShortNameOut->Length = ShortNameOut->MaximumLength = 
+        (Ptr - ShortNameOut->Buffer) * sizeof(WCHAR);
+}
+
 VOID BindAdapter(
     PLAN_ADAPTER Adapter,
     PNDIS_STRING RegistryPath)
@@ -873,18 +1005,21 @@
     ULONG Lookahead = LOOKAHEAD_SIZE;
     NTSTATUS Status;
     HANDLE RegHandle = 0;
+    UNICODE_STRING ShortName;
 
     TI_DbgPrint(DEBUG_DATALINK, ("Called.\n"));
 
     Adapter->State = LAN_STATE_OPENING;
 
+    GetShortName( RegistryPath, &ShortName );
+
     NdisStatus = NDISCall(Adapter,
                           NdisRequestSetInformation,
                           OID_GEN_CURRENT_LOOKAHEAD,
                           &Lookahead,
                           sizeof(ULONG));
     if (NdisStatus != NDIS_STATUS_SUCCESS) {
-        TI_DbgPrint(MID_TRACE, ("Could not set lookahead buffer size (0x%X).\n", NdisStatus));
+        TI_DbgPrint(DEBUG_DATALINK, ("Could not set lookahead buffer size (0x%X).\n", NdisStatus));
         return;
     }
 
@@ -915,6 +1050,11 @@
     
     Status = OpenRegistryKey( RegistryPath, &RegHandle );
 	    
+    if(NT_SUCCESS(Status)) {
+	Status = FindDeviceNameForAdapter( &ShortName, &IF->Name );
+        TI_DbgPrint(DEBUG_DATALINK,("Adapter Name: %wZ\n", &IF->Name));
+    }
+
     if(NT_SUCCESS(Status))
 	Status = ReadIPAddressFromRegistry( RegHandle, L"DefaultGateway",
 					    &DefaultGateway );
@@ -935,58 +1075,35 @@
         IF->Unicast.Address.IPv4Address | 
         ~IF->Netmask.Address.IPv4Address;
 
-    TI_DbgPrint(MID_TRACE,("BCAST(IF) %s\n", A2S(&IF->Broadcast)));
+    TI_DbgPrint(DEBUG_DATALINK,("BCAST(IF) %s\n", A2S(&IF->Broadcast)));
 
     if(NT_SUCCESS(Status)) {
-        RtlZeroMemory( &IF->Name, sizeof(IF->Name) );
-	Status = ReadStringFromRegistry( RegHandle, L"DeviceDesc",
-					 &IF->Name );
-
-	/* I think that not getting a devicedesc is not a fatal error */
-	if( !NT_SUCCESS(Status) ) {
-	    if( IF->Name.Buffer ) exFreePool( IF->Name.Buffer );
-	    GetSimpleAdapterNameFromRegistryPath( &IF->Name, RegistryPath );
-	}
-	Status = STATUS_SUCCESS;
+        /* It's ok to fail some of the above.  We'll just use DHCP. */
+        TI_DbgPrint
+            (DEBUG_DATALINK, 
+             ("--> Our IP address on this interface: '%s'\n", 
+              A2S(&IF->Unicast)));
+        
+        TI_DbgPrint
+            (DEBUG_DATALINK, 
+             ("--> Our net mask on this interface: '%s'\n", 
+              A2S(&IF->Netmask)));
+        
+        if( DefaultGateway.Address.IPv4Address ) {
+            TI_DbgPrint
+                (DEBUG_DATALINK, 
+                 ("--> Our gateway is: '%s'\n", 
+                  A2S(&DefaultGateway)));
+            
+            /* Create a default route */
+            RouterCreateRoute( &DefaultMask, /* Zero */
+                               &DefaultMask, /* Zero */
+                               &DefaultGateway,
+                               IF,
+                               1 );
+        }
     }
 
-    TI_DbgPrint(MID_TRACE,("Adapter Name: %wZ\n", &IF->Name));
-
-    if(!NT_SUCCESS(Status))
-    {
-	TI_DbgPrint(MIN_TRACE, ("Unable to open protocol-specific registry key: 0x%x\n", Status));
-	
-	/* XXX how do we proceed?  No ip address, no parameters... do we guess? */
-	if(RegHandle)  
-	    ZwClose(RegHandle);
-	IPDestroyInterface(IF);
-	return;
-    }
-    
-    TI_DbgPrint
-	(MID_TRACE, 
-	 ("--> Our IP address on this interface: '%s'\n", 
-	  A2S(&IF->Unicast)));
-    
-    TI_DbgPrint
-	(MID_TRACE, 
-	 ("--> Our net mask on this interface: '%s'\n", 
-	  A2S(&IF->Netmask)));
-
-    if( DefaultGateway.Address.IPv4Address ) {
-	TI_DbgPrint
-	    (MID_TRACE, 
-	     ("--> Our gateway is: '%s'\n", 
-	      A2S(&DefaultGateway)));
-
-	/* Create a default route */
-	RouterCreateRoute( &DefaultMask, /* Zero */
-			   &DefaultMask, /* Zero */
-			   &DefaultGateway,
-			   IF,
-			   1 );
-    }
-
     /* Get maximum link speed */
     NdisStatus = NDISCall(Adapter,
                           NdisRequestQueryInformation,
@@ -1008,7 +1125,7 @@
                           sizeof(UINT));
 
     if (NdisStatus != NDIS_STATUS_SUCCESS) {
-        TI_DbgPrint(MID_TRACE, ("Could not set packet filter (0x%X).\n", NdisStatus));
+        TI_DbgPrint(DEBUG_DATALINK, ("Could not set packet filter (0x%X).\n", NdisStatus));
         IPDestroyInterface(IF);
         return;
     }
@@ -1232,10 +1349,10 @@
         NdisCloseAdapter(&NdisStatus, NdisHandle);
         if (NdisStatus == NDIS_STATUS_PENDING) {
             TcpipWaitForSingleObject(&Adapter->Event,
-                                  UserRequest,
-                                  KernelMode,
-                                  FALSE,
-                                  NULL);
+                                     UserRequest,
+                                     KernelMode,
+                                     FALSE,
+                                     NULL);
             NdisStatus = Adapter->NdisStatus;
         }
     } else
@@ -1284,16 +1401,16 @@
     ProtChars.StatusCompleteHandler          = ProtocolStatusComplete;
     ProtChars.BindAdapterHandler             = ProtocolBindAdapter;
 
-	/* Try to register protocol */
+    /* Try to register protocol */
     NdisRegisterProtocol(&NdisStatus,
                          &NdisProtocolHandle,
                          &ProtChars,
                          sizeof(NDIS_PROTOCOL_CHARACTERISTICS));
     if (NdisStatus != NDIS_STATUS_SUCCESS)
-	 {
-		 TI_DbgPrint(MID_TRACE, ("NdisRegisterProtocol failed, status 0x%x\n", NdisStatus));
+    {
+        TI_DbgPrint(DEBUG_DATALINK, ("NdisRegisterProtocol failed, status 0x%x\n", NdisStatus));
         return (NTSTATUS)NdisStatus;
-	 }
+    }
 
     ProtocolRegistered = TRUE;
 
@@ -1323,7 +1440,7 @@
         CurrentEntry = AdapterListHead.Flink;
         while (CurrentEntry != &AdapterListHead) {
             NextEntry = CurrentEntry->Flink;
-	        Current = CONTAINING_RECORD(CurrentEntry, LAN_ADAPTER, ListEntry);
+            Current = CONTAINING_RECORD(CurrentEntry, LAN_ADAPTER, ListEntry);
             /* Unregister it */
             LANUnregisterAdapter(Current);
             CurrentEntry = NextEntry;

Modified: trunk/reactos/drivers/net/tcpip/include/info.h
--- trunk/reactos/drivers/net/tcpip/include/info.h	2005-04-14 22:41:48 UTC (rev 14623)
+++ trunk/reactos/drivers/net/tcpip/include/info.h	2005-04-15 00:48:25 UTC (rev 14624)
@@ -74,11 +74,13 @@
     ULONG LastChange;
     ULONG InOctets;
     ULONG InUcastPackets;
+    ULONG InNUcastPackets;
     ULONG InDiscards;
     ULONG InErrors;
     ULONG InUnknownProtos;
     ULONG OutOctets;
     ULONG OutUcastPackets;
+    ULONG OutNUcastPackets;
     ULONG OutDiscards;
     ULONG OutErrors;
     ULONG OutQLen;

Modified: trunk/reactos/drivers/net/tcpip/include/tcpip.h
--- trunk/reactos/drivers/net/tcpip/include/tcpip.h	2005-04-14 22:41:48 UTC (rev 14623)
+++ trunk/reactos/drivers/net/tcpip/include/tcpip.h	2005-04-15 00:48:25 UTC (rev 14624)
@@ -30,6 +30,7 @@
 
 #include <debug.h>
 
+#define TAG_STRING	TAG('S', 'T', 'R', ' ') /* string */
 
 /* Define _NTTEST_ to make test version. Device names are prefixed with
    'NT' to allow the driver to run side by side with MS TCP/IP driver */