Use DriverDesc in the registry as the adapter name since the ndis name OID

seems generally unimplemented.  What a pain.

svn path=/trunk/; revision=14624
This commit is contained in:
Art Yerkes 2005-04-15 00:48:25 +00:00
parent 34eabf82b5
commit 3e3c9e9775
3 changed files with 233 additions and 113 deletions

View file

@ -18,6 +18,9 @@ UINT TransferDataCompleteCalled = 0;
UINT LanReceiveWorkerCalled = 0; UINT LanReceiveWorkerCalled = 0;
BOOLEAN LanReceiveWorkerBusy = FALSE; BOOLEAN LanReceiveWorkerBusy = FALSE;
#define CCS_ROOT L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet"
#define TCPIP_GUID L"{4D36E972-E325-11CE-BFC1-08002BE10318}"
#define NGFP(_Packet) \ #define NGFP(_Packet) \
{ \ { \
PVOID _Header; \ PVOID _Header; \
@ -331,21 +334,21 @@ VOID STDCALL LanReceiveWorker( PVOID Context ) {
IPPacket.Position = 0; IPPacket.Position = 0;
TI_DbgPrint TI_DbgPrint
(DEBUG_DATALINK, (DEBUG_DATALINK,
("Ether Type = %x ContigSize = %d Total = %d\n", ("Ether Type = %x ContigSize = %d Total = %d\n",
PacketType, IPPacket.ContigSize, IPPacket.TotalSize)); PacketType, IPPacket.ContigSize, IPPacket.TotalSize));
switch (PacketType) { switch (PacketType) {
case ETYPE_IPv4: case ETYPE_IPv4:
case ETYPE_IPv6: case ETYPE_IPv6:
TI_DbgPrint(MID_TRACE,("Received IP Packet\n")); TI_DbgPrint(MID_TRACE,("Received IP Packet\n"));
IPReceive(Adapter->Context, &IPPacket); IPReceive(Adapter->Context, &IPPacket);
break; break;
case ETYPE_ARP: case ETYPE_ARP:
TI_DbgPrint(MID_TRACE,("Received ARP Packet\n")); TI_DbgPrint(MID_TRACE,("Received ARP Packet\n"));
ARPReceive(Adapter->Context, &IPPacket); ARPReceive(Adapter->Context, &IPPacket);
default: default:
break; break;
} }
FreeNdisPacket( Packet ); FreeNdisPacket( Packet );
@ -599,10 +602,10 @@ VOID STDCALL ProtocolBindAdapter(
* SystemSpecific2: Unused & must not be touched * SystemSpecific2: Unused & must not be touched
*/ */
{ {
/* XXX confirm that this is still true, or re-word the following comment */ /* 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 */ /* 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)); TI_DbgPrint(DEBUG_DATALINK, ("Called with registry path %wZ for %wZ\n", SystemSpecific1, DeviceName));
*Status = LANRegisterAdapter(DeviceName, SystemSpecific1); *Status = LANRegisterAdapter(DeviceName, SystemSpecific1);
} }
@ -664,25 +667,25 @@ VOID LANTransmit(
RtlCopyMemory(EHeader->SrcAddr, Adapter->HWAddress, IEEE_802_ADDR_LENGTH); RtlCopyMemory(EHeader->SrcAddr, Adapter->HWAddress, IEEE_802_ADDR_LENGTH);
switch (Type) { switch (Type) {
case LAN_PROTO_IPv4: case LAN_PROTO_IPv4:
EHeader->EType = ETYPE_IPv4; EHeader->EType = ETYPE_IPv4;
break; break;
case LAN_PROTO_ARP: case LAN_PROTO_ARP:
EHeader->EType = ETYPE_ARP; EHeader->EType = ETYPE_ARP;
break; break;
case LAN_PROTO_IPv6: case LAN_PROTO_IPv6:
EHeader->EType = ETYPE_IPv6; EHeader->EType = ETYPE_IPv6;
break; break;
default: default:
#ifdef DBG #ifdef DBG
/* Should not happen */ /* Should not happen */
TI_DbgPrint(MIN_TRACE, ("Unknown LAN protocol.\n")); TI_DbgPrint(MIN_TRACE, ("Unknown LAN protocol.\n"));
ProtocolSendComplete((NDIS_HANDLE)Context, ProtocolSendComplete((NDIS_HANDLE)Context,
NdisPacket, NdisPacket,
NDIS_STATUS_FAILURE); NDIS_STATUS_FAILURE);
#endif #endif
return; return;
} }
break; break;
@ -729,7 +732,7 @@ OpenRegistryKey( PNDIS_STRING RegistryPath, PHANDLE RegHandle ) {
NTSTATUS Status; NTSTATUS Status;
InitializeObjectAttributes(&Attributes, RegistryPath, OBJ_CASE_INSENSITIVE, 0, 0); InitializeObjectAttributes(&Attributes, RegistryPath, OBJ_CASE_INSENSITIVE, 0, 0);
Status = ZwOpenKey(RegHandle, GENERIC_READ, &Attributes); Status = ZwOpenKey(RegHandle, KEY_ALL_ACCESS, &Attributes);
return Status; return Status;
} }
@ -811,7 +814,7 @@ static NTSTATUS ReadStringFromRegistry( HANDLE RegHandle,
TI_DbgPrint(MIN_TRACE, ("Information DataLength: 0x%x\n", Information->DataLength)); TI_DbgPrint(MIN_TRACE, ("Information DataLength: 0x%x\n", Information->DataLength));
UnicodeString.Buffer = (PWCHAR)&Information->Data; UnicodeString.Buffer = (PWCHAR)&Information->Data;
UnicodeString.Length = Information->DataLength; UnicodeString.Length = Information->DataLength - sizeof(WCHAR);
UnicodeString.MaximumLength = Information->DataLength; UnicodeString.MaximumLength = Information->DataLength;
String->Buffer = String->Buffer =
@ -826,32 +829,161 @@ static NTSTATUS ReadStringFromRegistry( HANDLE RegHandle,
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
static VOID GetSimpleAdapterNameFromRegistryPath /*
( PUNICODE_STRING TargetString, * Utility to copy and append two unicode strings.
PUNICODE_STRING RegistryPath ) { *
PWCHAR i, LastSlash = NULL; * IN OUT PUNICODE_STRING ResultFirst -> First string and result
UINT NewStringLength = 0; * IN PUNICODE_STRING Second -> Second string to append
* IN BOOL Deallocate -> TRUE: Deallocate First string before
* overwriting.
*
* Returns NTSTATUS.
*/
for( i = RegistryPath->Buffer; NTSTATUS NTAPI AppendUnicodeString(PUNICODE_STRING ResultFirst,
i < RegistryPath->Buffer + PUNICODE_STRING Second,
(RegistryPath->Length / sizeof(WCHAR)); BOOL Deallocate) {
i++ ) if( *i == '\\' ) LastSlash = i; 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 - TI_DbgPrint(DEBUG_DATALINK,("EnumKeyName %wZ\n", EnumKeyName));
((LastSlash - RegistryPath->Buffer) * sizeof(WCHAR));
TargetString->Buffer = RtlInitUnicodeString(&BackSlash, L"\\");
(PWCHAR)exAllocatePool( NonPagedPool, NewStringLength ); RtlInitUnicodeString(&Linkage, L"\\Linkage");
if( !TargetString->Buffer ) { RtlInitUnicodeString(&DescKeyName, L"");
TargetString->Length = TargetString->MaximumLength = 0; AppendUnicodeString( &DescKeyName, EnumKeyName, FALSE );
return; 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; RtlInitUnicodeString( OutName, L"" );
RtlCopyMemory( TargetString->Buffer, LastSlash, NewStringLength ); 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( VOID BindAdapter(
@ -873,18 +1005,21 @@ VOID BindAdapter(
ULONG Lookahead = LOOKAHEAD_SIZE; ULONG Lookahead = LOOKAHEAD_SIZE;
NTSTATUS Status; NTSTATUS Status;
HANDLE RegHandle = 0; HANDLE RegHandle = 0;
UNICODE_STRING ShortName;
TI_DbgPrint(DEBUG_DATALINK, ("Called.\n")); TI_DbgPrint(DEBUG_DATALINK, ("Called.\n"));
Adapter->State = LAN_STATE_OPENING; Adapter->State = LAN_STATE_OPENING;
GetShortName( RegistryPath, &ShortName );
NdisStatus = NDISCall(Adapter, NdisStatus = NDISCall(Adapter,
NdisRequestSetInformation, NdisRequestSetInformation,
OID_GEN_CURRENT_LOOKAHEAD, OID_GEN_CURRENT_LOOKAHEAD,
&Lookahead, &Lookahead,
sizeof(ULONG)); sizeof(ULONG));
if (NdisStatus != NDIS_STATUS_SUCCESS) { 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; return;
} }
@ -915,6 +1050,11 @@ VOID BindAdapter(
Status = OpenRegistryKey( RegistryPath, &RegHandle ); 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)) if(NT_SUCCESS(Status))
Status = ReadIPAddressFromRegistry( RegHandle, L"DefaultGateway", Status = ReadIPAddressFromRegistry( RegHandle, L"DefaultGateway",
&DefaultGateway ); &DefaultGateway );
@ -935,56 +1075,33 @@ VOID BindAdapter(
IF->Unicast.Address.IPv4Address | IF->Unicast.Address.IPv4Address |
~IF->Netmask.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)) { if(NT_SUCCESS(Status)) {
RtlZeroMemory( &IF->Name, sizeof(IF->Name) ); /* It's ok to fail some of the above. We'll just use DHCP. */
Status = ReadStringFromRegistry( RegHandle, L"DeviceDesc", TI_DbgPrint
&IF->Name ); (DEBUG_DATALINK,
("--> Our IP address on this interface: '%s'\n",
/* I think that not getting a devicedesc is not a fatal error */ A2S(&IF->Unicast)));
if( !NT_SUCCESS(Status) ) {
if( IF->Name.Buffer ) exFreePool( IF->Name.Buffer ); TI_DbgPrint
GetSimpleAdapterNameFromRegistryPath( &IF->Name, RegistryPath ); (DEBUG_DATALINK,
} ("--> Our net mask on this interface: '%s'\n",
Status = STATUS_SUCCESS; A2S(&IF->Netmask)));
}
if( DefaultGateway.Address.IPv4Address ) {
TI_DbgPrint(MID_TRACE,("Adapter Name: %wZ\n", &IF->Name)); TI_DbgPrint
(DEBUG_DATALINK,
if(!NT_SUCCESS(Status)) ("--> Our gateway is: '%s'\n",
{ A2S(&DefaultGateway)));
TI_DbgPrint(MIN_TRACE, ("Unable to open protocol-specific registry key: 0x%x\n", Status));
/* Create a default route */
/* XXX how do we proceed? No ip address, no parameters... do we guess? */ RouterCreateRoute( &DefaultMask, /* Zero */
if(RegHandle) &DefaultMask, /* Zero */
ZwClose(RegHandle); &DefaultGateway,
IPDestroyInterface(IF); IF,
return; 1 );
} }
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 */ /* Get maximum link speed */
@ -1008,7 +1125,7 @@ VOID BindAdapter(
sizeof(UINT)); sizeof(UINT));
if (NdisStatus != NDIS_STATUS_SUCCESS) { 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); IPDestroyInterface(IF);
return; return;
} }
@ -1232,10 +1349,10 @@ NDIS_STATUS LANUnregisterAdapter(
NdisCloseAdapter(&NdisStatus, NdisHandle); NdisCloseAdapter(&NdisStatus, NdisHandle);
if (NdisStatus == NDIS_STATUS_PENDING) { if (NdisStatus == NDIS_STATUS_PENDING) {
TcpipWaitForSingleObject(&Adapter->Event, TcpipWaitForSingleObject(&Adapter->Event,
UserRequest, UserRequest,
KernelMode, KernelMode,
FALSE, FALSE,
NULL); NULL);
NdisStatus = Adapter->NdisStatus; NdisStatus = Adapter->NdisStatus;
} }
} else } else
@ -1284,16 +1401,16 @@ NTSTATUS LANRegisterProtocol(
ProtChars.StatusCompleteHandler = ProtocolStatusComplete; ProtChars.StatusCompleteHandler = ProtocolStatusComplete;
ProtChars.BindAdapterHandler = ProtocolBindAdapter; ProtChars.BindAdapterHandler = ProtocolBindAdapter;
/* Try to register protocol */ /* Try to register protocol */
NdisRegisterProtocol(&NdisStatus, NdisRegisterProtocol(&NdisStatus,
&NdisProtocolHandle, &NdisProtocolHandle,
&ProtChars, &ProtChars,
sizeof(NDIS_PROTOCOL_CHARACTERISTICS)); sizeof(NDIS_PROTOCOL_CHARACTERISTICS));
if (NdisStatus != NDIS_STATUS_SUCCESS) 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; return (NTSTATUS)NdisStatus;
} }
ProtocolRegistered = TRUE; ProtocolRegistered = TRUE;
@ -1323,7 +1440,7 @@ VOID LANUnregisterProtocol(
CurrentEntry = AdapterListHead.Flink; CurrentEntry = AdapterListHead.Flink;
while (CurrentEntry != &AdapterListHead) { while (CurrentEntry != &AdapterListHead) {
NextEntry = CurrentEntry->Flink; NextEntry = CurrentEntry->Flink;
Current = CONTAINING_RECORD(CurrentEntry, LAN_ADAPTER, ListEntry); Current = CONTAINING_RECORD(CurrentEntry, LAN_ADAPTER, ListEntry);
/* Unregister it */ /* Unregister it */
LANUnregisterAdapter(Current); LANUnregisterAdapter(Current);
CurrentEntry = NextEntry; CurrentEntry = NextEntry;

View file

@ -74,11 +74,13 @@ typedef struct IFENTRY {
ULONG LastChange; ULONG LastChange;
ULONG InOctets; ULONG InOctets;
ULONG InUcastPackets; ULONG InUcastPackets;
ULONG InNUcastPackets;
ULONG InDiscards; ULONG InDiscards;
ULONG InErrors; ULONG InErrors;
ULONG InUnknownProtos; ULONG InUnknownProtos;
ULONG OutOctets; ULONG OutOctets;
ULONG OutUcastPackets; ULONG OutUcastPackets;
ULONG OutNUcastPackets;
ULONG OutDiscards; ULONG OutDiscards;
ULONG OutErrors; ULONG OutErrors;
ULONG OutQLen; ULONG OutQLen;

View file

@ -30,6 +30,7 @@
#include <debug.h> #include <debug.h>
#define TAG_STRING TAG('S', 'T', 'R', ' ') /* string */
/* Define _NTTEST_ to make test version. Device names are prefixed with /* 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 */ 'NT' to allow the driver to run side by side with MS TCP/IP driver */