- Fix epic naming fail (DhcpEnabled -> EnableDHCP
[reactos.git] / reactos / drivers / network / tcpip / datalink / lan.c
index d813ec8..2d44955 100644 (file)
@@ -108,7 +108,7 @@ VOID FreeAdapter(
  *     Adapter = Pointer to LAN_ADAPTER structure to free
  */
 {
-    exFreePool(Adapter);
+    ExFreePoolWithTag(Adapter, LAN_ADAPTER_TAG);
 }
 
 
@@ -231,12 +231,7 @@ VOID NTAPI ProtocolSendComplete(
  *     Status         = Status of the operation
  */
 {
-    TI_DbgPrint(DEBUG_DATALINK, ("Calling completion routine\n"));
-    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 ) {
@@ -254,7 +249,7 @@ VOID LanReceiveWorker( PVOID Context ) {
     Adapter = WorkItem->Adapter;
     BytesTransferred = WorkItem->BytesTransferred;
 
-    exFreePool(WorkItem);
+    ExFreePoolWithTag(WorkItem, WQ_CONTEXT_TAG);
 
     IPInitializePacket(&IPPacket, 0);
 
@@ -305,7 +300,8 @@ VOID LanSubmitReceiveWork(
     PNDIS_PACKET Packet,
     NDIS_STATUS Status,
     UINT BytesTransferred) {
-    PLAN_WQ_ITEM WQItem = exAllocatePool(NonPagedPool, sizeof(LAN_WQ_ITEM));
+    PLAN_WQ_ITEM WQItem = ExAllocatePoolWithTag(NonPagedPool, sizeof(LAN_WQ_ITEM),
+                                                WQ_CONTEXT_TAG);
     PLAN_ADAPTER Adapter = (PLAN_ADAPTER)BindingContext;
 
     TI_DbgPrint(DEBUG_DATALINK,("called\n"));
@@ -317,7 +313,7 @@ VOID LanSubmitReceiveWork(
     WQItem->BytesTransferred = BytesTransferred;
 
     if (!ChewCreate( LanReceiveWorker, WQItem ))
-        exFreePool(WQItem);
+        ExFreePoolWithTag(WQItem, WQ_CONTEXT_TAG);
 }
 
 VOID NTAPI ProtocolTransferDataComplete(
@@ -418,7 +414,7 @@ NDIS_STATUS NTAPI ProtocolReceive(
                                 Adapter, Adapter->MTU));
 
     NdisStatus = AllocatePacketWithBuffer( &NdisPacket, NULL,
-                                           PacketSize + HeaderBufferSize );
+                                           PacketSize );
     if( NdisStatus != NDIS_STATUS_SUCCESS ) {
        return NDIS_STATUS_NOT_ACCEPTED;
     }
@@ -599,18 +595,18 @@ VOID LANTransmit(
 {
     NDIS_STATUS NdisStatus;
     PETH_HEADER EHeader;
-    PCHAR Data;
-    UINT Size;
+    PCHAR Data, OldData;
+    UINT Size, OldSize;
     PLAN_ADAPTER Adapter = (PLAN_ADAPTER)Context;
     KIRQL OldIrql;
-    UINT PacketLength;
+    PNDIS_PACKET XmitPacket;
 
     TI_DbgPrint(DEBUG_DATALINK,
                ("Called( NdisPacket %x, Offset %d, Adapter %x )\n",
                 NdisPacket, Offset, Adapter));
 
     if (Adapter->State != LAN_STATE_STARTED) {
-        ProtocolSendComplete(Context, NdisPacket, NDIS_STATUS_NOT_ACCEPTED);
+        (*PC(NdisPacket)->DLComplete)(PC(NdisPacket)->Context, NdisPacket, NDIS_STATUS_NOT_ACCEPTED);
         return;
     }
 
@@ -623,9 +619,19 @@ VOID LANTransmit(
                 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 );
+
+    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);
 
         switch (Adapter->Media) {
         case NdisMedium802_3:
@@ -652,14 +658,7 @@ VOID LANTransmit(
                 EHeader->EType = ETYPE_IPv6;
                 break;
             default:
-#if 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;
@@ -682,17 +681,15 @@ VOID LANTransmit(
                   ((PCHAR)LinkAddress)[5] & 0xff));
        }
 
-        NdisQueryPacketLength(NdisPacket, &PacketLength);
-
-        if (Adapter->MTU < PacketLength) {
+        if (Adapter->MTU < Size) {
             /* This is NOT a pointer. MSDN explicitly says so. */
             NDIS_PER_PACKET_INFO_FROM_PACKET(NdisPacket,
-                                             TcpLargeSendPacketInfo) = (PVOID)((ULONG)Adapter->MTU);
+                                             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"));
@@ -703,7 +700,7 @@ VOID LANTransmit(
         * 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);
+            ProtocolSendComplete((NDIS_HANDLE)Context, XmitPacket, NdisStatus);
 }
 
 static NTSTATUS
@@ -772,9 +769,9 @@ NTSTATUS NTAPI AppendUnicodeString(PUNICODE_STRING ResultFirst,
                                   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;
     }
@@ -949,9 +946,18 @@ BOOLEAN BindAdapter(
     PIP_INTERFACE IF;
     NDIS_STATUS NdisStatus;
     LLIP_BIND_INFO BindInfo;
-    IP_ADDRESS DefaultMask;
-    ULONG Lookahead = LOOKAHEAD_SIZE;
+    IP_ADDRESS DefaultMask, Router;
+    ULONG Lookahead = LOOKAHEAD_SIZE, Unused;
     NTSTATUS Status;
+    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 EnableDhcp = RTL_CONSTANT_STRING(L"EnableDHCP");
+    UNICODE_STRING RegistryDataU;
+    ANSI_STRING RegistryDataA;
 
     TI_DbgPrint(DEBUG_DATALINK, ("Called.\n"));
 
@@ -995,14 +1001,126 @@ BOOLEAN BindAdapter(
     GetName( RegistryPath, &IF->Name );
 
     Status = FindDeviceDescForAdapter( &IF->Name, &IF->Description );
+    if (!NT_SUCCESS(Status)) {
+        TI_DbgPrint(MIN_TRACE, ("Failed to get device description.\n"));
+        IPDestroyInterface(IF);
+        return FALSE;
+    }
 
     TI_DbgPrint(DEBUG_DATALINK,("Adapter Description: %wZ\n",
                 &IF->Description));
 
+    InitializeObjectAttributes(&ObjectAttributes,
+                               RegistryPath,
+                               OBJ_CASE_INSENSITIVE,
+                               0,
+                               NULL);
+
     AddrInitIPv4(&DefaultMask, 0);
 
-    IF->Unicast = DefaultMask;
-    IF->Netmask = DefaultMask;
+    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;
+        }
+
+        Status = ZwQueryValueKey(ParameterHandle,
+                                 &EnableDhcp,
+                                 KeyValuePartialInformation,
+                                 KeyValueInfo,
+                                 sizeof(KEY_VALUE_PARTIAL_INFORMATION) + sizeof(ULONG),
+                                 &Unused);
+        if (NT_SUCCESS(Status) && KeyValueInfo->DataLength == sizeof(ULONG) && (*(PULONG)KeyValueInfo->Data) != 0)
+        {
+            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);
+
+                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;
+            }
+
+            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);
+            }
+        }
+        else
+        {
+            IF->Unicast = DefaultMask;
+            IF->Netmask = DefaultMask;
+        }
+
+        ZwClose(ParameterHandle);
+    }
 
     IF->Broadcast.Type = IP_ADDRESS_V4;
     IF->Broadcast.Address.IPv4Address =
@@ -1086,7 +1204,7 @@ NDIS_STATUS LANRegisterAdapter(
 
     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;
@@ -1124,7 +1242,7 @@ NDIS_STATUS LANRegisterAdapter(
         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;
     }
 
@@ -1149,7 +1267,7 @@ NDIS_STATUS LANRegisterAdapter(
     default:
         /* Unsupported media */
         TI_DbgPrint(MIN_TRACE, ("Unsupported media.\n"));
-        exFreePool(IF);
+        ExFreePoolWithTag(IF, LAN_ADAPTER_TAG);
         return NDIS_STATUS_NOT_SUPPORTED;
     }
 
@@ -1161,7 +1279,7 @@ NDIS_STATUS LANRegisterAdapter(
                           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;
     }
 
@@ -1173,7 +1291,7 @@ NDIS_STATUS LANRegisterAdapter(
                           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;
     }
 
@@ -1196,7 +1314,7 @@ NDIS_STATUS LANRegisterAdapter(
                           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;
     }
 
@@ -1208,7 +1326,7 @@ NDIS_STATUS LANRegisterAdapter(
                           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;
     }
 
@@ -1218,7 +1336,7 @@ NDIS_STATUS LANRegisterAdapter(
     /* 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;
     }