- Merge 54895, 54896, 54899, 54912, 54913, 54915, and 54916 from wlan-bringup
authorCameron Gutman <aicommander@gmail.com>
Thu, 12 Jan 2012 03:12:49 +0000 (03:12 +0000)
committerCameron Gutman <aicommander@gmail.com>
Thu, 12 Jan 2012 03:12:49 +0000 (03:12 +0000)
svn path=/trunk/; revision=54917

reactos/dll/win32/dhcpcsvc/dhcp/adapter.c
reactos/dll/win32/dhcpcsvc/dhcp/api.c
reactos/dll/win32/dhcpcsvc/dhcp/dispatch.c
reactos/drivers/network/dd/pcnet/requests.c
reactos/drivers/network/ndis/ndis/time.c
reactos/drivers/network/tcpip/datalink/lan.c
reactos/lib/drivers/ip/network/interface.c

index 833d06c..d79b76b 100644 (file)
@@ -1,6 +1,6 @@
 #include "rosdhcp.h"
 
-static SOCKET DhcpSocket = INVALID_SOCKET;
+SOCKET DhcpSocket = INVALID_SOCKET;
 static LIST_ENTRY AdapterList;
 static WSADATA wsd;
 
@@ -209,6 +209,7 @@ DWORD WINAPI AdapterDiscoveryThread(LPVOID Context) {
     PDHCP_ADAPTER Adapter = NULL;
     HANDLE AdapterStateChangedEvent = (HANDLE)Context;
     struct interface_info *ifi = NULL;
+    struct protocol *proto;
     int i, AdapterCount = 0, Broadcast;
 
     /* FIXME: Kill this thread when the service is stopped */
@@ -245,6 +246,10 @@ DWORD WINAPI AdapterDiscoveryThread(LPVOID Context) {
                     /* We're still active so we stay in the list */
                     ifi = &Adapter->DhclientInfo;
                 } else {
+                    proto = find_protocol_by_adapter(&Adapter->DhclientInfo);
+                    if (proto)
+                        remove_protocol(proto);
+
                     /* We've lost our link so out we go */
                     RemoveEntryList(&Adapter->ListEntry);
                     free(Adapter);
@@ -330,7 +335,7 @@ DWORD WINAPI AdapterDiscoveryThread(LPVOID Context) {
                                      Adapter->DhclientInfo.rfdesc,
                                      got_one, &Adapter->DhclientInfo);
 
-                       state_init(&Adapter->DhclientInfo);
+                        state_init(&Adapter->DhclientInfo);
                     }
 
                     ApiLock();
@@ -345,15 +350,12 @@ DWORD WINAPI AdapterDiscoveryThread(LPVOID Context) {
                 DH_DbgPrint(MID_TRACE,("Adapter %d was rejected\n",
                                        Table->table[i].dwIndex));
         }
-        Error = NotifyAddrChange(NULL, NULL);
 #if 0
+        Error = NotifyAddrChange(NULL, NULL);
         if (Error != NO_ERROR)
             break;
 #else
-        if (AdapterCount)
-            break;
-        else
-            Sleep(3000);
+        Sleep(3000);
 #endif
     } while (TRUE);
 
@@ -364,14 +366,13 @@ DWORD WINAPI AdapterDiscoveryThread(LPVOID Context) {
 }
 
 HANDLE StartAdapterDiscovery(VOID) {
-    HANDLE /* ThreadHandle, */ EventHandle;
+    HANDLE ThreadHandle, EventHandle;
 
     EventHandle = CreateEvent(NULL,
                               FALSE,
                               FALSE,
                               NULL);
 
-#if 0
     ThreadHandle = CreateThread(NULL,
                                 0,
                                 AdapterDiscoveryThread,
@@ -383,9 +384,6 @@ HANDLE StartAdapterDiscovery(VOID) {
         return NULL;
 
     CloseHandle(ThreadHandle);
-#else
-    AdapterDiscoveryThread((LPVOID)EventHandle);
-#endif
 
     return EventHandle;
 }
index 7623be3..26723f9 100644 (file)
@@ -14,6 +14,8 @@
 
 static CRITICAL_SECTION ApiCriticalSection;
 
+extern HANDLE AdapterStateChangedEvent;
+
 VOID ApiInit() {
     InitializeCriticalSection( &ApiCriticalSection );
 }
@@ -35,6 +37,7 @@ VOID ApiFree() {
 DWORD DSLeaseIpAddress( PipeSendFunc Send, COMM_DHCP_REQ *Req ) {
     COMM_DHCP_REPLY Reply;
     PDHCP_ADAPTER Adapter;
+    struct protocol* proto;
 
     ApiLock();
 
@@ -43,11 +46,19 @@ DWORD DSLeaseIpAddress( PipeSendFunc Send, COMM_DHCP_REQ *Req ) {
     Reply.Reply = Adapter ? 1 : 0;
 
     if( Adapter ) {
+        proto = find_protocol_by_adapter( &Adapter->DhclientInfo );
+        if (proto)
+            remove_protocol(proto);
+
         add_protocol( Adapter->DhclientInfo.name,
                       Adapter->DhclientInfo.rfdesc, got_one,
                       &Adapter->DhclientInfo );
-       Adapter->DhclientInfo.client->state = S_INIT;
-       state_reboot(&Adapter->DhclientInfo);
+
+        Adapter->DhclientInfo.client->state = S_INIT;
+        state_reboot(&Adapter->DhclientInfo);
+
+        if (AdapterStateChangedEvent != NULL)
+            SetEvent(AdapterStateChangedEvent);
     }
 
     ApiUnlock();
@@ -91,10 +102,18 @@ DWORD DSReleaseIpAddressLease( PipeSendFunc Send, COMM_DHCP_REQ *Req ) {
     if( Adapter ) {
         if (Adapter->NteContext)
             DeleteIPAddress( Adapter->NteContext );
+        if (Adapter->RouterMib.dwForwardNextHop)
+            DeleteIpForwardEntry( &Adapter->RouterMib );
 
         proto = find_protocol_by_adapter( &Adapter->DhclientInfo );
         if (proto)
            remove_protocol(proto);
+
+        Adapter->DhclientInfo.client->active = NULL;
+        Adapter->DhclientInfo.client->state = S_INIT;
+
+        if (AdapterStateChangedEvent != NULL)
+            SetEvent(AdapterStateChangedEvent);
     }
 
     ApiUnlock();
@@ -105,6 +124,7 @@ DWORD DSReleaseIpAddressLease( PipeSendFunc Send, COMM_DHCP_REQ *Req ) {
 DWORD DSRenewIpAddressLease( PipeSendFunc Send, COMM_DHCP_REQ *Req ) {
     COMM_DHCP_REPLY Reply;
     PDHCP_ADAPTER Adapter;
+    struct protocol* proto;
 
     ApiLock();
 
@@ -118,12 +138,20 @@ DWORD DSRenewIpAddressLease( PipeSendFunc Send, COMM_DHCP_REQ *Req ) {
 
     Reply.Reply = 1;
 
+    proto = find_protocol_by_adapter( &Adapter->DhclientInfo );
+    if (proto)
+        remove_protocol(proto);
+
     add_protocol( Adapter->DhclientInfo.name,
                   Adapter->DhclientInfo.rfdesc, got_one,
                   &Adapter->DhclientInfo );
+
     Adapter->DhclientInfo.client->state = S_INIT;
     state_reboot(&Adapter->DhclientInfo);
 
+    if (AdapterStateChangedEvent != NULL)
+        SetEvent(AdapterStateChangedEvent);
+
     ApiUnlock();
 
     return Send( &Reply );
@@ -144,6 +172,9 @@ DWORD DSStaticRefreshParams( PipeSendFunc Send, COMM_DHCP_REQ *Req ) {
     if( Adapter ) {
         if (Adapter->NteContext)
             DeleteIPAddress( Adapter->NteContext );
+        if (Adapter->RouterMib.dwForwardNextHop)
+            DeleteIpForwardEntry( &Adapter->RouterMib );
+        
         Adapter->DhclientState.state = S_STATIC;
         proto = find_protocol_by_adapter( &Adapter->DhclientInfo );
         if (proto)
@@ -154,6 +185,9 @@ DWORD DSStaticRefreshParams( PipeSendFunc Send, COMM_DHCP_REQ *Req ) {
                                &Adapter->NteContext,
                                &Adapter->NteInstance );
         Reply.Reply = NT_SUCCESS(Status);
+
+        if (AdapterStateChangedEvent != NULL)
+            SetEvent(AdapterStateChangedEvent);
     }
 
     ApiUnlock();
index d3872d0..0215a0e 100644 (file)
@@ -47,6 +47,8 @@
 //#include <ifaddrs.h>
 //#include <poll.h>
 
+extern SOCKET DhcpSocket;
+HANDLE AdapterStateChangedEvent = NULL;
 struct protocol *protocols = NULL;
 struct timeout *timeouts = NULL;
 static struct timeout *free_timeouts = NULL;
@@ -63,17 +65,19 @@ void (*bootp_packet_handler)(struct interface_info *,
 void
 dispatch(void)
 {
-    int count, to_msec, err;
+    int count, to_msec;
     struct protocol *l;
-    fd_set fds;
     time_t howlong, cur_time;
-    struct timeval timeval;
-    HANDLE AdapterStateChangedEvent;
+    HANDLE Events[2];
+    int EventCount = 1;
 
-    AdapterStateChangedEvent = StartAdapterDiscovery();
-    if (!AdapterStateChangedEvent)
+    Events[0] = StartAdapterDiscovery();
+    if (!Events[0])
          return;
-
+    AdapterStateChangedEvent = Events[0];
+    
+    Events[1] = WSA_INVALID_EVENT;
+    
     ApiLock();
 
     do {
@@ -83,7 +87,8 @@ dispatch(void)
          */
         time(&cur_time);
 
-        if (timeouts) {
+        if (timeouts)
+        {
             struct timeout *t;
 
             if (timeouts->when <= cur_time) {
@@ -105,55 +110,75 @@ dispatch(void)
             if (howlong > INT_MAX / 1000)
                 howlong = INT_MAX / 1000;
             to_msec = howlong * 1000;
-
-            /* Set up the descriptors to be polled. */
-            FD_ZERO(&fds);
-
-            for (l = protocols; l; l = l->next)
-                 FD_SET(l->fd, &fds);
-
-            /* Wait for a packet or a timeout... XXX */
-            timeval.tv_sec = to_msec / 1000;
-            timeval.tv_usec = to_msec % 1000;
-
-            ApiUnlock();
-
-            count = select(0, &fds, NULL, NULL, &timeval);
-
-            ApiLock();
         }
         else
         {
-            ApiUnlock();
-            WaitForSingleObject(AdapterStateChangedEvent, INFINITE);
-            ApiLock();
+            to_msec = INFINITE;
+        }
 
-            continue;
+        if (Events[1] == WSA_INVALID_EVENT && DhcpSocket != INVALID_SOCKET)
+        {
+            Events[1] = WSACreateEvent();
+            if (Events[1] != WSA_INVALID_EVENT)
+            {
+                count = WSAEventSelect(DhcpSocket, Events[1], FD_READ | FD_CLOSE);
+                if (count != NO_ERROR)
+                {
+                    WSACloseEvent(Events[1]);
+                    Events[1] = WSA_INVALID_EVENT;
+                }
+                else
+                {
+                    EventCount = 2;
+                }
+            }
         }
+        else if (Events[1] != WSA_INVALID_EVENT && DhcpSocket == INVALID_SOCKET)
+        {
+            WSACloseEvent(Events[1]);
+            Events[1] = WSA_INVALID_EVENT;
 
-        DH_DbgPrint(MID_TRACE,("Select: %d\n", count));
+            EventCount = 1;
+        }
 
-        /* Not likely to be transitory... */
-        if (count == SOCKET_ERROR) {
-            err = WSAGetLastError();
-            error("poll: %d", err);
-            break;
+        ApiUnlock();
+        count = WaitForMultipleObjects(EventCount,
+                                       Events,
+                                       FALSE,
+                                       to_msec);
+        ApiLock();
+        if (count == WAIT_OBJECT_0)
+        {
+            /* Adapter state change */
+            continue;
+        }
+        else if (count == WAIT_OBJECT_0 + 1)
+        {
+            /* Packet received */
+            
+            /* WSA events are manual reset events */
+            WSAResetEvent(Events[1]);
+        }
+        else
+        {
+            /* Timeout */
+            continue;
         }
 
         for (l = protocols; l; l = l->next) {
             struct interface_info *ip;
             ip = l->local;
-            if (FD_ISSET(l->fd, &fds)) {
-                if (ip && (l->handler != got_one ||
-                           !ip->dead)) {
-                    DH_DbgPrint(MID_TRACE,("Handling %x\n", l));
-                    (*(l->handler))(l);
-                }
+            if (ip && (l->handler != got_one ||
+                        !ip->dead)) {
+                DH_DbgPrint(MID_TRACE,("Handling %x\n", l));
+                (*(l->handler))(l);
             }
         }
     } while (1);
 
-    CloseHandle(AdapterStateChangedEvent);
+    AdapterStateChangedEvent = NULL;
+    CloseHandle(Events[0]);
+    WSACloseEvent(Events[1]);
 
     ApiUnlock();
 }
@@ -327,6 +352,41 @@ void
 remove_protocol(struct protocol *proto)
 {
     struct protocol *p, *next, *prev;
+    struct interface_info *ip = proto->local;
+    struct timeout *t, *q, *u;
+    
+    t = NULL;
+    q = timeouts;
+    while (q != NULL)
+    {
+        /* Remove all timeouts for this protocol */
+        if (q->what == ip)
+        {
+            /* Unlink the timeout from previous */
+            if (t)
+                t->next = q->next;
+            else
+                timeouts = q->next;
+                        
+            /* Advance to the next timeout */
+            u = q->next;
+            
+            /* Add it to the free list */
+            q->next = free_timeouts;
+            free_timeouts = q;
+        }
+        else
+        {
+            /* Advance to the next timeout */
+            u = q->next;
+            
+            /* Update the previous pointer */
+            t = q;
+        }
+        
+        /* Advance */
+        q = u;
+    }
 
     prev = NULL;
     for (p = protocols; p; p = next) {
index 79faee5..5500ac0 100644 (file)
@@ -266,7 +266,7 @@ MiniportQueryInformation(
 
     case OID_GEN_MEDIA_CONNECT_STATUS:
         {
-          GenericULONG = Adapter->MediaState;
+          GenericULONG = (ULONG)NdisMediaStateConnected; /* Adapter->MediaState */
           break;
         }
 
index f1fe891..28b66f4 100644 (file)
@@ -57,10 +57,9 @@ NdisGetCurrentSystemTime (
  * ARGUMENTS:
  *     pSystemTime: pointer to the returned system time
  * NOTES:
- *     - call at IRQL <= DISPATCH_LEVEL
+ *     - call at any IRQL
  */
 {
-  ASSERT_IRQL(DISPATCH_LEVEL);
   ASSERT(pSystemTime);
 
   KeQuerySystemTime (pSystemTime);
index d833d33..955fbe3 100644 (file)
@@ -185,7 +185,9 @@ NTSTATUS TcpipLanGetDwordOid
     case OID_GEN_HARDWARE_STATUS:
         *Result = NdisHardwareStatusReady;
         return STATUS_SUCCESS;
-
+    case OID_GEN_MEDIA_CONNECT_STATUS:
+        *Result = NdisMediaStateConnected;
+        return STATUS_SUCCESS;
     default:
         return STATUS_INVALID_PARAMETER;
     }
index f61cb4d..0d127ca 100644 (file)
@@ -196,27 +196,26 @@ PIP_INTERFACE FindOnLinkInterface(PIP_ADDRESS Address)
     return NULL;
 }
 
-NTSTATUS GetInterfaceConnectionStatus
-( PIP_INTERFACE Interface, PULONG Result ) {
-    NTSTATUS Status = TcpipLanGetDwordOid
-        ( Interface, OID_GEN_HARDWARE_STATUS, Result );
-    if( NT_SUCCESS(Status) ) switch( *Result ) {
-    case NdisHardwareStatusReady:
+NTSTATUS GetInterfaceConnectionStatus(PIP_INTERFACE Interface, PULONG Result)
+{
+    NTSTATUS Status;
+
+    /* Query OID_GEN_MEDIA_CONNECT_STATUS for connection status information */
+    Status = TcpipLanGetDwordOid(Interface, OID_GEN_MEDIA_CONNECT_STATUS, Result);
+    if (!NT_SUCCESS(Status))
+        return Status;
+
+    /* Translate the result into MIB_IF_OPER_STATUS_XXX */
+    if (*Result == NdisMediaStateConnected)
+    {
+        /* Up and running */
         *Result = MIB_IF_OPER_STATUS_OPERATIONAL;
-        break;
-    case NdisHardwareStatusInitializing:
-        *Result = MIB_IF_OPER_STATUS_CONNECTING;
-        break;
-    case NdisHardwareStatusReset:
-        *Result = MIB_IF_OPER_STATUS_DISCONNECTED;
-        break;
-    case NdisHardwareStatusNotReady:
+    }
+    else
+    {
+        /* Down */
         *Result = MIB_IF_OPER_STATUS_DISCONNECTED;
-        break;
-    case NdisHardwareStatusClosing:
-    default:
-        *Result = MIB_IF_OPER_STATUS_NON_OPERATIONAL;
-        break;
     }
-    return Status;
+
+    return STATUS_SUCCESS;
 }