From 3a504014d4da914d0a5055a2c6a933682f83b120 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Thu, 12 Jan 2012 03:12:49 +0000 Subject: [PATCH] - Merge 54895, 54896, 54899, 54912, 54913, 54915, and 54916 from wlan-bringup svn path=/trunk/; revision=54917 --- reactos/dll/win32/dhcpcsvc/dhcp/adapter.c | 22 ++- reactos/dll/win32/dhcpcsvc/dhcp/api.c | 38 ++++- reactos/dll/win32/dhcpcsvc/dhcp/dispatch.c | 144 +++++++++++++------ reactos/drivers/network/dd/pcnet/requests.c | 2 +- reactos/drivers/network/ndis/ndis/time.c | 3 +- reactos/drivers/network/tcpip/datalink/lan.c | 4 +- reactos/lib/drivers/ip/network/interface.c | 41 +++--- 7 files changed, 173 insertions(+), 81 deletions(-) diff --git a/reactos/dll/win32/dhcpcsvc/dhcp/adapter.c b/reactos/dll/win32/dhcpcsvc/dhcp/adapter.c index 833d06cfa00..d79b76b112b 100644 --- a/reactos/dll/win32/dhcpcsvc/dhcp/adapter.c +++ b/reactos/dll/win32/dhcpcsvc/dhcp/adapter.c @@ -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; } diff --git a/reactos/dll/win32/dhcpcsvc/dhcp/api.c b/reactos/dll/win32/dhcpcsvc/dhcp/api.c index 7623be382ac..26723f9c38e 100644 --- a/reactos/dll/win32/dhcpcsvc/dhcp/api.c +++ b/reactos/dll/win32/dhcpcsvc/dhcp/api.c @@ -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(); diff --git a/reactos/dll/win32/dhcpcsvc/dhcp/dispatch.c b/reactos/dll/win32/dhcpcsvc/dhcp/dispatch.c index d3872d0d02f..0215a0e70c4 100644 --- a/reactos/dll/win32/dhcpcsvc/dhcp/dispatch.c +++ b/reactos/dll/win32/dhcpcsvc/dhcp/dispatch.c @@ -47,6 +47,8 @@ //#include //#include +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(); - - continue; + to_msec = INFINITE; } - DH_DbgPrint(MID_TRACE,("Select: %d\n", count)); + 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; - /* Not likely to be transitory... */ - if (count == SOCKET_ERROR) { - err = WSAGetLastError(); - error("poll: %d", err); - break; + EventCount = 1; + } + + 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) { diff --git a/reactos/drivers/network/dd/pcnet/requests.c b/reactos/drivers/network/dd/pcnet/requests.c index 79faee5d14e..5500ac007fe 100644 --- a/reactos/drivers/network/dd/pcnet/requests.c +++ b/reactos/drivers/network/dd/pcnet/requests.c @@ -266,7 +266,7 @@ MiniportQueryInformation( case OID_GEN_MEDIA_CONNECT_STATUS: { - GenericULONG = Adapter->MediaState; + GenericULONG = (ULONG)NdisMediaStateConnected; /* Adapter->MediaState */ break; } diff --git a/reactos/drivers/network/ndis/ndis/time.c b/reactos/drivers/network/ndis/ndis/time.c index f1fe891638a..28b66f443d3 100644 --- a/reactos/drivers/network/ndis/ndis/time.c +++ b/reactos/drivers/network/ndis/ndis/time.c @@ -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); diff --git a/reactos/drivers/network/tcpip/datalink/lan.c b/reactos/drivers/network/tcpip/datalink/lan.c index d833d332f3c..955fbe3ca7b 100644 --- a/reactos/drivers/network/tcpip/datalink/lan.c +++ b/reactos/drivers/network/tcpip/datalink/lan.c @@ -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; } diff --git a/reactos/lib/drivers/ip/network/interface.c b/reactos/lib/drivers/ip/network/interface.c index f61cb4d0742..0d127ca9bcb 100644 --- a/reactos/lib/drivers/ip/network/interface.c +++ b/reactos/lib/drivers/ip/network/interface.c @@ -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: - *Result = MIB_IF_OPER_STATUS_DISCONNECTED; - break; - case NdisHardwareStatusClosing: - default: - *Result = MIB_IF_OPER_STATUS_NON_OPERATIONAL; - break; } - return Status; + else + { + /* Down */ + *Result = MIB_IF_OPER_STATUS_DISCONNECTED; + } + + return STATUS_SUCCESS; }