#include "precomp.h"
-/* Define this to bugcheck on double complete */
-/* #define BREAK_ON_DOUBLE_COMPLETE */
-
UINT TransferDataCalled = 0;
UINT TransferDataCompleteCalled = 0;
UINT LanReceiveWorkerCalled = 0;
LIST_ENTRY AdapterListHead;
KSPIN_LOCK AdapterListLock;
-/* Double complete protection */
-KSPIN_LOCK LanSendCompleteLock;
-LIST_ENTRY LanSendCompleteList;
-
-VOID LanChainCompletion( PLAN_ADAPTER Adapter, PNDIS_PACKET NdisPacket ) {
- PLAN_WQ_ITEM PendingCompletion =
- ExAllocatePool( NonPagedPool, sizeof(LAN_WQ_ITEM) );
-
- if( !PendingCompletion ) return;
-
- PendingCompletion->Packet = NdisPacket;
- PendingCompletion->Adapter = Adapter;
-
- ExInterlockedInsertTailList( &LanSendCompleteList,
- &PendingCompletion->ListEntry,
- &LanSendCompleteLock );
-}
-
-BOOLEAN LanShouldComplete( PLAN_ADAPTER Adapter, PNDIS_PACKET NdisPacket ) {
- PLIST_ENTRY ListEntry;
- PLAN_WQ_ITEM CompleteEntry;
- KIRQL OldIrql;
-
- KeAcquireSpinLock( &LanSendCompleteLock, &OldIrql );
- for( ListEntry = LanSendCompleteList.Flink;
- ListEntry != &LanSendCompleteList;
- ListEntry = ListEntry->Flink ) {
- CompleteEntry = CONTAINING_RECORD(ListEntry, LAN_WQ_ITEM, ListEntry);
-
- if( CompleteEntry->Adapter == Adapter &&
- CompleteEntry->Packet == NdisPacket ) {
- RemoveEntryList( ListEntry );
- KeReleaseSpinLock( &LanSendCompleteLock, OldIrql );
- ExFreePool( CompleteEntry );
- return TRUE;
- }
- }
- KeReleaseSpinLock( &LanSendCompleteLock, OldIrql );
-
- DbgPrint("NDIS completed the same send packet twice "
- "(Adapter %x Packet %x)!!\n", Adapter, NdisPacket);
-#ifdef BREAK_ON_DOUBLE_COMPLETE
- KeBugCheck(0);
-#endif
-
- return FALSE;
-}
-
NDIS_STATUS NDISCall(
PLAN_ADAPTER Adapter,
NDIS_REQUEST_TYPE Type,
* Adapter = Pointer to LAN_ADAPTER structure to free
*/
{
- exFreePool(Adapter);
+ ExFreePoolWithTag(Adapter, LAN_ADAPTER_TAG);
}
NTSTATUS TcpipLanGetDwordOid
( PIP_INTERFACE Interface,
NDIS_OID Oid,
- PDWORD Result ) {
+ PULONG Result ) {
/* Get maximum frame size */
if( Interface->Context ) {
return NDISCall((PLAN_ADAPTER)Interface->Context,
NdisRequestQueryInformation,
Oid,
Result,
- sizeof(DWORD));
+ sizeof(ULONG));
} else switch( Oid ) { /* Loopback Case */
case OID_GEN_HARDWARE_STATUS:
*Result = NdisHardwareStatusReady;
}
-VOID STDCALL ProtocolOpenAdapterComplete(
+VOID NTAPI ProtocolOpenAdapterComplete(
NDIS_HANDLE BindingContext,
NDIS_STATUS Status,
NDIS_STATUS OpenErrorStatus)
TI_DbgPrint(DEBUG_DATALINK, ("Called.\n"));
+ Adapter->NdisStatus = Status;
+
KeSetEvent(&Adapter->Event, 0, FALSE);
}
-VOID STDCALL ProtocolCloseAdapterComplete(
+VOID NTAPI ProtocolCloseAdapterComplete(
NDIS_HANDLE BindingContext,
NDIS_STATUS Status)
/*
}
-VOID STDCALL ProtocolResetComplete(
+VOID NTAPI ProtocolResetComplete(
NDIS_HANDLE BindingContext,
NDIS_STATUS Status)
/*
* 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);
}
-VOID STDCALL ProtocolRequestComplete(
+VOID NTAPI ProtocolRequestComplete(
NDIS_HANDLE BindingContext,
PNDIS_REQUEST NdisRequest,
NDIS_STATUS Status)
}
-VOID STDCALL ProtocolSendComplete(
+VOID NTAPI ProtocolSendComplete(
NDIS_HANDLE BindingContext,
PNDIS_PACKET Packet,
NDIS_STATUS Status)
* Status = Status of the operation
*/
{
- TI_DbgPrint(DEBUG_DATALINK, ("Calling completion routine\n"));
- if( LanShouldComplete( (PLAN_ADAPTER)BindingContext, Packet ) ) {
- ASSERT_KM_POINTER(Packet);
- ASSERT_KM_POINTER(PC(Packet));
- ASSERT_KM_POINTER(PC(Packet)->DLComplete);
- (*PC(Packet)->DLComplete)( PC(Packet)->Context, Packet, Status);
- TI_DbgPrint(DEBUG_DATALINK, ("Finished\n"));
- }
+ FreeNdisPacket(Packet);
}
VOID LanReceiveWorker( PVOID Context ) {
Adapter = WorkItem->Adapter;
BytesTransferred = WorkItem->BytesTransferred;
+ ExFreePoolWithTag(WorkItem, WQ_CONTEXT_TAG);
+
+ IPInitializePacket(&IPPacket, 0);
+
IPPacket.NdisPacket = Packet;
NdisGetFirstBufferFromPacket(Packet,
TI_DbgPrint(MID_TRACE,("Received ARP Packet\n"));
ARPReceive(Adapter->Context, &IPPacket);
default:
+ IPPacket.Free(&IPPacket);
break;
}
PNDIS_PACKET Packet,
NDIS_STATUS Status,
UINT BytesTransferred) {
- LAN_WQ_ITEM WQItem;
+ PLAN_WQ_ITEM WQItem = ExAllocatePoolWithTag(NonPagedPool, sizeof(LAN_WQ_ITEM),
+ WQ_CONTEXT_TAG);
PLAN_ADAPTER Adapter = (PLAN_ADAPTER)BindingContext;
- PVOID LanWorkItem;
TI_DbgPrint(DEBUG_DATALINK,("called\n"));
- WQItem.Packet = Packet;
- WQItem.Adapter = Adapter;
- WQItem.BytesTransferred = BytesTransferred;
+ if (!WQItem) return;
- if( !ChewCreate
- ( &LanWorkItem, sizeof(LAN_WQ_ITEM), LanReceiveWorker, &WQItem ) )
- ASSERT(0);
+ WQItem->Packet = Packet;
+ WQItem->Adapter = Adapter;
+ WQItem->BytesTransferred = BytesTransferred;
+
+ if (!ChewCreate( LanReceiveWorker, WQItem ))
+ ExFreePoolWithTag(WQItem, WQ_CONTEXT_TAG);
}
-VOID STDCALL ProtocolTransferDataComplete(
+VOID NTAPI ProtocolTransferDataComplete(
NDIS_HANDLE BindingContext,
PNDIS_PACKET Packet,
NDIS_STATUS Status,
LanSubmitReceiveWork( BindingContext, Packet, Status, BytesTransferred );
}
-NDIS_STATUS STDCALL ProtocolReceive(
+NDIS_STATUS NTAPI ProtocolReceive(
NDIS_HANDLE BindingContext,
NDIS_HANDLE MacReceiveContext,
PVOID HeaderBuffer,
Adapter, Adapter->MTU));
NdisStatus = AllocatePacketWithBuffer( &NdisPacket, NULL,
- PacketSize + HeaderBufferSize );
+ PacketSize );
if( NdisStatus != NDIS_STATUS_SUCCESS ) {
return NDIS_STATUS_NOT_ACCEPTED;
}
}
-VOID STDCALL ProtocolReceiveComplete(
+VOID NTAPI ProtocolReceiveComplete(
NDIS_HANDLE BindingContext)
/*
* FUNCTION: Called by NDIS when we're done receiving data
}
-VOID STDCALL ProtocolStatus(
+VOID NTAPI 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;
+ }
}
+NDIS_STATUS NTAPI
+ProtocolPnPEvent(
+ NDIS_HANDLE NdisBindingContext,
+ PNET_PNP_EVENT PnPEvent)
+{
+ switch(PnPEvent->NetEvent)
+ {
+ case NetEventSetPower:
+ DbgPrint("Device transitioned to power state %ld\n", PnPEvent->Buffer);
+ return NDIS_STATUS_SUCCESS;
+
+ case NetEventQueryPower:
+ DbgPrint("Device wants to go into power state %ld\n", PnPEvent->Buffer);
+ return NDIS_STATUS_SUCCESS;
+
+ case NetEventQueryRemoveDevice:
+ DbgPrint("Device is about to be removed\n");
+ return NDIS_STATUS_SUCCESS;
+
+ case NetEventCancelRemoveDevice:
+ DbgPrint("Device removal cancelled\n");
+ return NDIS_STATUS_SUCCESS;
+
+ default:
+ DbgPrint("Unhandled event type: %ld\n", PnPEvent->NetEvent);
+ return NDIS_STATUS_SUCCESS;
+ }
+}
-VOID STDCALL ProtocolStatusComplete(
+VOID NTAPI ProtocolStatusComplete(
NDIS_HANDLE NdisBindingContext)
/*
* FUNCTION: Called by NDIS when a status-change has occurred
TI_DbgPrint(DEBUG_DATALINK, ("Called.\n"));
}
-VOID STDCALL ProtocolBindAdapter(
+VOID NTAPI ProtocolBindAdapter(
OUT PNDIS_STATUS Status,
IN NDIS_HANDLE BindContext,
IN PNDIS_STRING DeviceName,
{
NDIS_STATUS NdisStatus;
PETH_HEADER EHeader;
- PCHAR Data;
- UINT Size;
+ PCHAR Data, OldData;
+ UINT Size, OldSize;
PLAN_ADAPTER Adapter = (PLAN_ADAPTER)Context;
KIRQL OldIrql;
+ PNDIS_PACKET XmitPacket;
TI_DbgPrint(DEBUG_DATALINK,
("Called( NdisPacket %x, Offset %d, Adapter %x )\n",
NdisPacket, Offset, Adapter));
+ if (Adapter->State != LAN_STATE_STARTED) {
+ (*PC(NdisPacket)->DLComplete)(PC(NdisPacket)->Context, NdisPacket, NDIS_STATUS_NOT_ACCEPTED);
+ return;
+ }
+
TI_DbgPrint(DEBUG_DATALINK,
("Adapter Address [%02x %02x %02x %02x %02x %02x]\n",
Adapter->HWAddress[0] & 0xff,
Adapter->HWAddress[4] & 0xff,
Adapter->HWAddress[5] & 0xff));
- /* XXX arty -- Handled adjustment in a saner way than before ...
- * not needed immediately */
- GetDataPtr( NdisPacket, 0, &Data, &Size );
+ GetDataPtr( NdisPacket, 0, &OldData, &OldSize );
- LanChainCompletion( Adapter, NdisPacket );
+ NdisStatus = AllocatePacketWithBuffer(&XmitPacket, NULL, OldSize + Adapter->HeaderSize);
+ if (NdisStatus != NDIS_STATUS_SUCCESS) {
+ (*PC(NdisPacket)->DLComplete)(PC(NdisPacket)->Context, NdisPacket, NDIS_STATUS_RESOURCES);
+ return;
+ }
+
+ GetDataPtr(XmitPacket, 0, &Data, &Size);
+
+ RtlCopyMemory(Data + Adapter->HeaderSize, OldData, OldSize);
+
+ (*PC(NdisPacket)->DLComplete)(PC(NdisPacket)->Context, NdisPacket, NDIS_STATUS_SUCCESS);
- if (Adapter->State == LAN_STATE_STARTED) {
switch (Adapter->Media) {
case NdisMedium802_3:
EHeader = (PETH_HEADER)Data;
EHeader->EType = ETYPE_IPv6;
break;
default:
-#ifdef DBG
- /* Should not happen */
- TI_DbgPrint(MIN_TRACE, ("Unknown LAN protocol.\n"));
-
- ProtocolSendComplete((NDIS_HANDLE)Context,
- NdisPacket,
- NDIS_STATUS_FAILURE);
-#endif
+ ASSERT(FALSE);
return;
}
break;
((PCHAR)LinkAddress)[5] & 0xff));
}
+ if (Adapter->MTU < Size) {
+ /* This is NOT a pointer. MSDN explicitly says so. */
+ NDIS_PER_PACKET_INFO_FROM_PACKET(NdisPacket,
+ TcpLargeSendPacketInfo) = (PVOID)((ULONG_PTR)Adapter->MTU);
+ }
+
TcpipAcquireSpinLock( &Adapter->Lock, &OldIrql );
TI_DbgPrint(MID_TRACE, ("NdisSend\n"));
- NdisSend(&NdisStatus, Adapter->NdisHandle, NdisPacket);
+ NdisSend(&NdisStatus, Adapter->NdisHandle, XmitPacket);
TI_DbgPrint(MID_TRACE, ("NdisSend %s\n",
NdisStatus == NDIS_STATUS_PENDING ?
"Pending" : "Complete"));
* status_pending is returned. Note that this is different from
* the situation with IRPs. */
if (NdisStatus != NDIS_STATUS_PENDING)
- ProtocolSendComplete((NDIS_HANDLE)Context, NdisPacket, NdisStatus);
- } else {
- ProtocolSendComplete((NDIS_HANDLE)Context, NdisPacket, NDIS_STATUS_CLOSED);
- }
+ ProtocolSendComplete((NDIS_HANDLE)Context, XmitPacket, NdisStatus);
}
static NTSTATUS
UnicodeString.MaximumLength = Information->DataLength;
String->Buffer =
- (PWCHAR)exAllocatePool( NonPagedPool,
+ (PWCHAR)ExAllocatePool( NonPagedPool,
UnicodeString.MaximumLength + sizeof(WCHAR) );
if( !String->Buffer ) return STATUS_NO_MEMORY;
NTSTATUS NTAPI AppendUnicodeString(PUNICODE_STRING ResultFirst,
PUNICODE_STRING Second,
- BOOL Deallocate) {
+ BOOLEAN Deallocate) {
NTSTATUS Status;
UNICODE_STRING Ustr = *ResultFirst;
- PWSTR new_string = ExAllocatePoolWithTag
+ PWSTR new_string = ExAllocatePool
(PagedPool,
- (ResultFirst->Length + Second->Length + sizeof(WCHAR)), TAG_STRING);
+ (ResultFirst->Length + Second->Length + sizeof(WCHAR)));
if( !new_string ) {
return STATUS_NO_MEMORY;
}
PUNICODE_STRING TargetKeyName,
PUNICODE_STRING Name,
PUNICODE_STRING DeviceDesc ) {
- UNICODE_STRING RootDevice = { 0 }, LinkageKeyName = { 0 };
- UNICODE_STRING DescKeyName = { 0 }, Linkage = { 0 };
- UNICODE_STRING BackSlash = { 0 };
+ UNICODE_STRING RootDevice = { 0, 0, NULL }, LinkageKeyName = { 0, 0, NULL };
+ UNICODE_STRING DescKeyName = { 0, 0, NULL }, Linkage = { 0, 0, NULL };
+ UNICODE_STRING BackSlash = { 0, 0, NULL };
HANDLE DescKey = NULL, LinkageKey = NULL;
NTSTATUS Status;
ExAllocatePool(NonPagedPool, sizeof(KEY_BASIC_INFORMATION));
ULONG KbioLength = sizeof(KEY_BASIC_INFORMATION), ResultLength;
+ RtlInitUnicodeString( DeviceDesc, NULL );
+
if( !Kbio ) return STATUS_INSUFFICIENT_RESOURCES;
RtlInitUnicodeString
}
}
- RtlInitUnicodeString( DeviceDesc, L"" );
- AppendUnicodeString( DeviceDesc, &TargetKeyName, FALSE );
NtClose( EnumKey );
ExFreePool( Kbio );
return STATUS_UNSUCCESSFUL;
PIP_INTERFACE IF;
NDIS_STATUS NdisStatus;
LLIP_BIND_INFO BindInfo;
- IP_ADDRESS DefaultMask = { 0 };
- ULONG Lookahead = LOOKAHEAD_SIZE;
+ IP_ADDRESS DefaultMask, Router;
+ ULONG Lookahead = LOOKAHEAD_SIZE, Unused;
NTSTATUS Status;
- HANDLE RegHandle = 0;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ HANDLE ParameterHandle;
+ PKEY_VALUE_PARTIAL_INFORMATION KeyValueInfo;
+ UNICODE_STRING IPAddress = RTL_CONSTANT_STRING(L"IPAddress");
+ UNICODE_STRING Netmask = RTL_CONSTANT_STRING(L"SubnetMask");
+ UNICODE_STRING Gateway = RTL_CONSTANT_STRING(L"DefaultGateway");
+ UNICODE_STRING RegistryDataU;
+ ANSI_STRING RegistryDataA;
TI_DbgPrint(DEBUG_DATALINK, ("Called.\n"));
GetName( RegistryPath, &IF->Name );
- Status = OpenRegistryKey( RegistryPath, &RegHandle );
+ Status = FindDeviceDescForAdapter( &IF->Name, &IF->Description );
+ if (!NT_SUCCESS(Status)) {
+ TI_DbgPrint(MIN_TRACE, ("Failed to get device description.\n"));
+ IPDestroyInterface(IF);
+ return FALSE;
+ }
- if(NT_SUCCESS(Status)) {
- Status = FindDeviceDescForAdapter( &IF->Name, &IF->Description );
- TI_DbgPrint(DEBUG_DATALINK,("Adapter Description: %wZ\n",
- &IF->Description));
- } else {
- IPDestroyInterface( IF );
- return FALSE;
+ TI_DbgPrint(DEBUG_DATALINK,("Adapter Description: %wZ\n",
+ &IF->Description));
+
+ DbgPrint("Opening %wZ\n", RegistryPath);
+
+ InitializeObjectAttributes(&ObjectAttributes,
+ RegistryPath,
+ OBJ_CASE_INSENSITIVE,
+ 0,
+ NULL);
+
+ AddrInitIPv4(&DefaultMask, 0);
+
+ Status = ZwOpenKey(&ParameterHandle, KEY_READ, &ObjectAttributes);
+ if (!NT_SUCCESS(Status))
+ {
+ IF->Unicast = DefaultMask;
+ IF->Netmask = DefaultMask;
}
+ else
+ {
+ KeyValueInfo = ExAllocatePool(PagedPool, sizeof(KEY_VALUE_PARTIAL_INFORMATION) + 16 * sizeof(WCHAR));
+ if (!KeyValueInfo)
+ {
+ ZwClose(ParameterHandle);
+ IPDestroyInterface(IF);
+ return FALSE;
+ }
+
+ RegistryDataU.MaximumLength = 16 + sizeof(WCHAR);
+ RegistryDataU.Buffer = (PWCHAR)KeyValueInfo->Data;
+
+ Status = ZwQueryValueKey(ParameterHandle,
+ &IPAddress,
+ KeyValuePartialInformation,
+ KeyValueInfo,
+ sizeof(KEY_VALUE_PARTIAL_INFORMATION) + 16 * sizeof(WCHAR),
+ &Unused);
+ if (NT_SUCCESS(Status))
+ {
+ RegistryDataU.Length = KeyValueInfo->DataLength;
+
+ RtlUnicodeStringToAnsiString(&RegistryDataA,
+ &RegistryDataU,
+ TRUE);
- DefaultMask.Type = IP_ADDRESS_V4;
+ AddrInitIPv4(&IF->Unicast, inet_addr(RegistryDataA.Buffer));
+
+ RtlFreeAnsiString(&RegistryDataA);
+
+ }
+ else
+ {
+ IF->Unicast = DefaultMask;
+ }
+
+ Status = ZwQueryValueKey(ParameterHandle,
+ &Netmask,
+ KeyValuePartialInformation,
+ KeyValueInfo,
+ sizeof(KEY_VALUE_PARTIAL_INFORMATION) + 16 * sizeof(WCHAR),
+ &Unused);
+ if (NT_SUCCESS(Status))
+ {
+ RegistryDataU.Length = KeyValueInfo->DataLength;
+
+ RtlUnicodeStringToAnsiString(&RegistryDataA,
+ &RegistryDataU,
+ TRUE);
+
+ AddrInitIPv4(&IF->Netmask, inet_addr(RegistryDataA.Buffer));
+
+ RtlFreeAnsiString(&RegistryDataA);
+ }
+ else
+ {
+ IF->Netmask = DefaultMask;
+ }
- IF->Unicast = DefaultMask;
- IF->Netmask = DefaultMask;
+ Status = ZwQueryValueKey(ParameterHandle,
+ &Gateway,
+ KeyValuePartialInformation,
+ KeyValueInfo,
+ sizeof(KEY_VALUE_PARTIAL_INFORMATION) + 16 * sizeof(WCHAR),
+ &Unused);
+ if (NT_SUCCESS(Status))
+ {
+ RegistryDataU.Length = KeyValueInfo->DataLength;
+
+ RtlUnicodeStringToAnsiString(&RegistryDataA,
+ &RegistryDataU,
+ TRUE);
+
+ AddrInitIPv4(&Router, inet_addr(RegistryDataA.Buffer));
+
+ RtlFreeAnsiString(&RegistryDataA);
+
+ if (!AddrIsUnspecified(&Router)) RouterCreateRoute(&DefaultMask, &DefaultMask, &Router, IF, 1);
+ }
+
+ ZwClose(ParameterHandle);
+ }
IF->Broadcast.Type = IP_ADDRESS_V4;
IF->Broadcast.Address.IPv4Address =
if (NdisStatus != NDIS_STATUS_SUCCESS) {
TI_DbgPrint(DEBUG_DATALINK, ("Could not set packet filter (0x%X).\n", NdisStatus));
+ IPUnregisterInterface(IF);
IPDestroyInterface(IF);
return FALSE;
}
TI_DbgPrint(DEBUG_DATALINK, ("Called.\n"));
- IF = exAllocatePool(NonPagedPool, sizeof(LAN_ADAPTER));
+ IF = ExAllocatePoolWithTag(NonPagedPool, sizeof(LAN_ADAPTER), LAN_ADAPTER_TAG);
if (!IF) {
TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
return NDIS_STATUS_RESOURCES;
KeWaitForSingleObject(&IF->Event, UserRequest, KernelMode, FALSE, NULL);
else if (NdisStatus != NDIS_STATUS_SUCCESS) {
TI_DbgPrint(DEBUG_DATALINK,("denying adapter %wZ\n", AdapterName));
- exFreePool(IF);
+ ExFreePoolWithTag(IF, LAN_ADAPTER_TAG);
return NdisStatus;
}
default:
/* Unsupported media */
TI_DbgPrint(MIN_TRACE, ("Unsupported media.\n"));
- exFreePool(IF);
+ ExFreePoolWithTag(IF, LAN_ADAPTER_TAG);
return NDIS_STATUS_NOT_SUPPORTED;
}
sizeof(UINT));
if (NdisStatus != NDIS_STATUS_SUCCESS) {
TI_DbgPrint(DEBUG_DATALINK,("denying adapter %wZ (NDISCall)\n", AdapterName));
- exFreePool(IF);
+ ExFreePoolWithTag(IF, LAN_ADAPTER_TAG);
return NdisStatus;
}
sizeof(UINT));
if (NdisStatus != NDIS_STATUS_SUCCESS) {
TI_DbgPrint(MIN_TRACE, ("Query for maximum packet size failed.\n"));
- exFreePool(IF);
+ ExFreePoolWithTag(IF, LAN_ADAPTER_TAG);
return NdisStatus;
}
IF->HWAddressLength);
if (NdisStatus != NDIS_STATUS_SUCCESS) {
TI_DbgPrint(MIN_TRACE, ("Query for current hardware address failed.\n"));
- exFreePool(IF);
+ ExFreePoolWithTag(IF, LAN_ADAPTER_TAG);
return NdisStatus;
}
sizeof(UINT));
if (NdisStatus != NDIS_STATUS_SUCCESS) {
TI_DbgPrint(MIN_TRACE, ("Query for maximum link speed failed.\n"));
- exFreePool(IF);
+ ExFreePoolWithTag(IF, LAN_ADAPTER_TAG);
return NdisStatus;
}
/* Bind adapter to IP layer */
if( !BindAdapter(IF, RegistryPath) ) {
TI_DbgPrint(DEBUG_DATALINK,("denying adapter %wZ (BindAdapter)\n", AdapterName));
- exFreePool(IF);
+ ExFreePoolWithTag(IF, LAN_ADAPTER_TAG);
return NDIS_STATUS_NOT_ACCEPTED;
}
return NdisStatus;
}
+VOID
+NTAPI
+LANUnregisterProtocol(VOID)
+/*
+ * FUNCTION: Unregisters this protocol driver with NDIS
+ * NOTES: Does not care wether we are already registered
+ */
+{
+ TI_DbgPrint(DEBUG_DATALINK, ("Called.\n"));
+
+ if (ProtocolRegistered) {
+ NDIS_STATUS NdisStatus;
+ PLIST_ENTRY CurrentEntry;
+ PLIST_ENTRY NextEntry;
+ PLAN_ADAPTER Current;
+ KIRQL OldIrql;
+
+ TcpipAcquireSpinLock(&AdapterListLock, &OldIrql);
+
+ /* Search the list and remove every adapter we find */
+ CurrentEntry = AdapterListHead.Flink;
+ while (CurrentEntry != &AdapterListHead) {
+ NextEntry = CurrentEntry->Flink;
+ Current = CONTAINING_RECORD(CurrentEntry, LAN_ADAPTER, ListEntry);
+ /* Unregister it */
+ LANUnregisterAdapter(Current);
+ CurrentEntry = NextEntry;
+ }
+
+ TcpipReleaseSpinLock(&AdapterListLock, OldIrql);
+
+ NdisDeregisterProtocol(&NdisStatus, NdisProtocolHandle);
+ ProtocolRegistered = FALSE;
+ }
+}
+
+VOID
+NTAPI
+ProtocolUnbindAdapter(
+ PNDIS_STATUS Status,
+ NDIS_HANDLE ProtocolBindingContext,
+ NDIS_HANDLE UnbindContext)
+{
+ /* We don't pend any unbinding so we can just ignore UnbindContext */
+ *Status = LANUnregisterAdapter((PLAN_ADAPTER)ProtocolBindingContext);
+}
NTSTATUS LANRegisterProtocol(
PNDIS_STRING Name)
ProtChars.StatusHandler = ProtocolStatus;
ProtChars.StatusCompleteHandler = ProtocolStatusComplete;
ProtChars.BindAdapterHandler = ProtocolBindAdapter;
+ ProtChars.PnPEventHandler = ProtocolPnPEvent;
+ ProtChars.UnbindAdapterHandler = ProtocolUnbindAdapter;
+ ProtChars.UnloadHandler = LANUnregisterProtocol;
/* Try to register protocol */
NdisRegisterProtocol(&NdisStatus,
return STATUS_SUCCESS;
}
-
-VOID LANUnregisterProtocol(
- VOID)
-/*
- * FUNCTION: Unregisters this protocol driver with NDIS
- * NOTES: Does not care wether we are already registered
- */
-{
- TI_DbgPrint(DEBUG_DATALINK, ("Called.\n"));
-
- if (ProtocolRegistered) {
- NDIS_STATUS NdisStatus;
- PLIST_ENTRY CurrentEntry;
- PLIST_ENTRY NextEntry;
- PLAN_ADAPTER Current;
- KIRQL OldIrql;
-
- TcpipAcquireSpinLock(&AdapterListLock, &OldIrql);
-
- /* Search the list and remove every adapter we find */
- CurrentEntry = AdapterListHead.Flink;
- while (CurrentEntry != &AdapterListHead) {
- NextEntry = CurrentEntry->Flink;
- Current = CONTAINING_RECORD(CurrentEntry, LAN_ADAPTER, ListEntry);
- /* Unregister it */
- LANUnregisterAdapter(Current);
- CurrentEntry = NextEntry;
- }
-
- TcpipReleaseSpinLock(&AdapterListLock, OldIrql);
-
- NdisDeregisterProtocol(&NdisStatus, NdisProtocolHandle);
- ProtocolRegistered = FALSE;
- }
-}
-
-VOID LANStartup() {
- InitializeListHead( &LanSendCompleteList );
- KeInitializeSpinLock( &LanSendCompleteLock );
-}
-
-VOID LANShutdown() {
- KIRQL OldIrql;
- PLAN_WQ_ITEM WorkItem;
- PLIST_ENTRY ListEntry;
-
- KeAcquireSpinLock( &LanSendCompleteLock, &OldIrql );
- while( !IsListEmpty( &LanSendCompleteList ) ) {
- ListEntry = RemoveHeadList( &LanSendCompleteList );
- WorkItem = CONTAINING_RECORD(ListEntry, LAN_WQ_ITEM, ListEntry);
- FreeNdisPacket( WorkItem->Packet );
- ExFreePool( WorkItem );
- }
- KeReleaseSpinLock( &LanSendCompleteLock, OldIrql );
-}
-
/* EOF */