- Merge 54895, 54896, 54899, 54912, 54913, 54915, and 54916 from wlan-bringup

svn path=/trunk/; revision=54917
This commit is contained in:
Cameron Gutman 2012-01-12 03:12:49 +00:00
parent b56fc432c1
commit 3a504014d4
7 changed files with 173 additions and 81 deletions

View file

@ -1,6 +1,6 @@
#include "rosdhcp.h" #include "rosdhcp.h"
static SOCKET DhcpSocket = INVALID_SOCKET; SOCKET DhcpSocket = INVALID_SOCKET;
static LIST_ENTRY AdapterList; static LIST_ENTRY AdapterList;
static WSADATA wsd; static WSADATA wsd;
@ -209,6 +209,7 @@ DWORD WINAPI AdapterDiscoveryThread(LPVOID Context) {
PDHCP_ADAPTER Adapter = NULL; PDHCP_ADAPTER Adapter = NULL;
HANDLE AdapterStateChangedEvent = (HANDLE)Context; HANDLE AdapterStateChangedEvent = (HANDLE)Context;
struct interface_info *ifi = NULL; struct interface_info *ifi = NULL;
struct protocol *proto;
int i, AdapterCount = 0, Broadcast; int i, AdapterCount = 0, Broadcast;
/* FIXME: Kill this thread when the service is stopped */ /* 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 */ /* We're still active so we stay in the list */
ifi = &Adapter->DhclientInfo; ifi = &Adapter->DhclientInfo;
} else { } else {
proto = find_protocol_by_adapter(&Adapter->DhclientInfo);
if (proto)
remove_protocol(proto);
/* We've lost our link so out we go */ /* We've lost our link so out we go */
RemoveEntryList(&Adapter->ListEntry); RemoveEntryList(&Adapter->ListEntry);
free(Adapter); free(Adapter);
@ -330,7 +335,7 @@ DWORD WINAPI AdapterDiscoveryThread(LPVOID Context) {
Adapter->DhclientInfo.rfdesc, Adapter->DhclientInfo.rfdesc,
got_one, &Adapter->DhclientInfo); got_one, &Adapter->DhclientInfo);
state_init(&Adapter->DhclientInfo); state_init(&Adapter->DhclientInfo);
} }
ApiLock(); ApiLock();
@ -345,15 +350,12 @@ DWORD WINAPI AdapterDiscoveryThread(LPVOID Context) {
DH_DbgPrint(MID_TRACE,("Adapter %d was rejected\n", DH_DbgPrint(MID_TRACE,("Adapter %d was rejected\n",
Table->table[i].dwIndex)); Table->table[i].dwIndex));
} }
Error = NotifyAddrChange(NULL, NULL);
#if 0 #if 0
Error = NotifyAddrChange(NULL, NULL);
if (Error != NO_ERROR) if (Error != NO_ERROR)
break; break;
#else #else
if (AdapterCount) Sleep(3000);
break;
else
Sleep(3000);
#endif #endif
} while (TRUE); } while (TRUE);
@ -364,14 +366,13 @@ DWORD WINAPI AdapterDiscoveryThread(LPVOID Context) {
} }
HANDLE StartAdapterDiscovery(VOID) { HANDLE StartAdapterDiscovery(VOID) {
HANDLE /* ThreadHandle, */ EventHandle; HANDLE ThreadHandle, EventHandle;
EventHandle = CreateEvent(NULL, EventHandle = CreateEvent(NULL,
FALSE, FALSE,
FALSE, FALSE,
NULL); NULL);
#if 0
ThreadHandle = CreateThread(NULL, ThreadHandle = CreateThread(NULL,
0, 0,
AdapterDiscoveryThread, AdapterDiscoveryThread,
@ -383,9 +384,6 @@ HANDLE StartAdapterDiscovery(VOID) {
return NULL; return NULL;
CloseHandle(ThreadHandle); CloseHandle(ThreadHandle);
#else
AdapterDiscoveryThread((LPVOID)EventHandle);
#endif
return EventHandle; return EventHandle;
} }

View file

@ -14,6 +14,8 @@
static CRITICAL_SECTION ApiCriticalSection; static CRITICAL_SECTION ApiCriticalSection;
extern HANDLE AdapterStateChangedEvent;
VOID ApiInit() { VOID ApiInit() {
InitializeCriticalSection( &ApiCriticalSection ); InitializeCriticalSection( &ApiCriticalSection );
} }
@ -35,6 +37,7 @@ VOID ApiFree() {
DWORD DSLeaseIpAddress( PipeSendFunc Send, COMM_DHCP_REQ *Req ) { DWORD DSLeaseIpAddress( PipeSendFunc Send, COMM_DHCP_REQ *Req ) {
COMM_DHCP_REPLY Reply; COMM_DHCP_REPLY Reply;
PDHCP_ADAPTER Adapter; PDHCP_ADAPTER Adapter;
struct protocol* proto;
ApiLock(); ApiLock();
@ -43,11 +46,19 @@ DWORD DSLeaseIpAddress( PipeSendFunc Send, COMM_DHCP_REQ *Req ) {
Reply.Reply = Adapter ? 1 : 0; Reply.Reply = Adapter ? 1 : 0;
if( Adapter ) { if( Adapter ) {
proto = find_protocol_by_adapter( &Adapter->DhclientInfo );
if (proto)
remove_protocol(proto);
add_protocol( Adapter->DhclientInfo.name, add_protocol( Adapter->DhclientInfo.name,
Adapter->DhclientInfo.rfdesc, got_one, Adapter->DhclientInfo.rfdesc, got_one,
&Adapter->DhclientInfo ); &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(); ApiUnlock();
@ -91,10 +102,18 @@ DWORD DSReleaseIpAddressLease( PipeSendFunc Send, COMM_DHCP_REQ *Req ) {
if( Adapter ) { if( Adapter ) {
if (Adapter->NteContext) if (Adapter->NteContext)
DeleteIPAddress( Adapter->NteContext ); DeleteIPAddress( Adapter->NteContext );
if (Adapter->RouterMib.dwForwardNextHop)
DeleteIpForwardEntry( &Adapter->RouterMib );
proto = find_protocol_by_adapter( &Adapter->DhclientInfo ); proto = find_protocol_by_adapter( &Adapter->DhclientInfo );
if (proto) if (proto)
remove_protocol(proto); remove_protocol(proto);
Adapter->DhclientInfo.client->active = NULL;
Adapter->DhclientInfo.client->state = S_INIT;
if (AdapterStateChangedEvent != NULL)
SetEvent(AdapterStateChangedEvent);
} }
ApiUnlock(); ApiUnlock();
@ -105,6 +124,7 @@ DWORD DSReleaseIpAddressLease( PipeSendFunc Send, COMM_DHCP_REQ *Req ) {
DWORD DSRenewIpAddressLease( PipeSendFunc Send, COMM_DHCP_REQ *Req ) { DWORD DSRenewIpAddressLease( PipeSendFunc Send, COMM_DHCP_REQ *Req ) {
COMM_DHCP_REPLY Reply; COMM_DHCP_REPLY Reply;
PDHCP_ADAPTER Adapter; PDHCP_ADAPTER Adapter;
struct protocol* proto;
ApiLock(); ApiLock();
@ -118,12 +138,20 @@ DWORD DSRenewIpAddressLease( PipeSendFunc Send, COMM_DHCP_REQ *Req ) {
Reply.Reply = 1; Reply.Reply = 1;
proto = find_protocol_by_adapter( &Adapter->DhclientInfo );
if (proto)
remove_protocol(proto);
add_protocol( Adapter->DhclientInfo.name, add_protocol( Adapter->DhclientInfo.name,
Adapter->DhclientInfo.rfdesc, got_one, Adapter->DhclientInfo.rfdesc, got_one,
&Adapter->DhclientInfo ); &Adapter->DhclientInfo );
Adapter->DhclientInfo.client->state = S_INIT; Adapter->DhclientInfo.client->state = S_INIT;
state_reboot(&Adapter->DhclientInfo); state_reboot(&Adapter->DhclientInfo);
if (AdapterStateChangedEvent != NULL)
SetEvent(AdapterStateChangedEvent);
ApiUnlock(); ApiUnlock();
return Send( &Reply ); return Send( &Reply );
@ -144,6 +172,9 @@ DWORD DSStaticRefreshParams( PipeSendFunc Send, COMM_DHCP_REQ *Req ) {
if( Adapter ) { if( Adapter ) {
if (Adapter->NteContext) if (Adapter->NteContext)
DeleteIPAddress( Adapter->NteContext ); DeleteIPAddress( Adapter->NteContext );
if (Adapter->RouterMib.dwForwardNextHop)
DeleteIpForwardEntry( &Adapter->RouterMib );
Adapter->DhclientState.state = S_STATIC; Adapter->DhclientState.state = S_STATIC;
proto = find_protocol_by_adapter( &Adapter->DhclientInfo ); proto = find_protocol_by_adapter( &Adapter->DhclientInfo );
if (proto) if (proto)
@ -154,6 +185,9 @@ DWORD DSStaticRefreshParams( PipeSendFunc Send, COMM_DHCP_REQ *Req ) {
&Adapter->NteContext, &Adapter->NteContext,
&Adapter->NteInstance ); &Adapter->NteInstance );
Reply.Reply = NT_SUCCESS(Status); Reply.Reply = NT_SUCCESS(Status);
if (AdapterStateChangedEvent != NULL)
SetEvent(AdapterStateChangedEvent);
} }
ApiUnlock(); ApiUnlock();

View file

@ -47,6 +47,8 @@
//#include <ifaddrs.h> //#include <ifaddrs.h>
//#include <poll.h> //#include <poll.h>
extern SOCKET DhcpSocket;
HANDLE AdapterStateChangedEvent = NULL;
struct protocol *protocols = NULL; struct protocol *protocols = NULL;
struct timeout *timeouts = NULL; struct timeout *timeouts = NULL;
static struct timeout *free_timeouts = NULL; static struct timeout *free_timeouts = NULL;
@ -63,17 +65,19 @@ void (*bootp_packet_handler)(struct interface_info *,
void void
dispatch(void) dispatch(void)
{ {
int count, to_msec, err; int count, to_msec;
struct protocol *l; struct protocol *l;
fd_set fds;
time_t howlong, cur_time; time_t howlong, cur_time;
struct timeval timeval; HANDLE Events[2];
HANDLE AdapterStateChangedEvent; int EventCount = 1;
AdapterStateChangedEvent = StartAdapterDiscovery(); Events[0] = StartAdapterDiscovery();
if (!AdapterStateChangedEvent) if (!Events[0])
return; return;
AdapterStateChangedEvent = Events[0];
Events[1] = WSA_INVALID_EVENT;
ApiLock(); ApiLock();
do { do {
@ -83,7 +87,8 @@ dispatch(void)
*/ */
time(&cur_time); time(&cur_time);
if (timeouts) { if (timeouts)
{
struct timeout *t; struct timeout *t;
if (timeouts->when <= cur_time) { if (timeouts->when <= cur_time) {
@ -105,55 +110,75 @@ dispatch(void)
if (howlong > INT_MAX / 1000) if (howlong > INT_MAX / 1000)
howlong = INT_MAX / 1000; howlong = INT_MAX / 1000;
to_msec = howlong * 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 else
{ {
ApiUnlock(); to_msec = INFINITE;
WaitForSingleObject(AdapterStateChangedEvent, INFINITE);
ApiLock();
continue;
} }
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... */ EventCount = 1;
if (count == SOCKET_ERROR) { }
err = WSAGetLastError();
error("poll: %d", err); ApiUnlock();
break; 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) { for (l = protocols; l; l = l->next) {
struct interface_info *ip; struct interface_info *ip;
ip = l->local; ip = l->local;
if (FD_ISSET(l->fd, &fds)) { if (ip && (l->handler != got_one ||
if (ip && (l->handler != got_one || !ip->dead)) {
!ip->dead)) { DH_DbgPrint(MID_TRACE,("Handling %x\n", l));
DH_DbgPrint(MID_TRACE,("Handling %x\n", l)); (*(l->handler))(l);
(*(l->handler))(l);
}
} }
} }
} while (1); } while (1);
CloseHandle(AdapterStateChangedEvent); AdapterStateChangedEvent = NULL;
CloseHandle(Events[0]);
WSACloseEvent(Events[1]);
ApiUnlock(); ApiUnlock();
} }
@ -327,6 +352,41 @@ void
remove_protocol(struct protocol *proto) remove_protocol(struct protocol *proto)
{ {
struct protocol *p, *next, *prev; 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; prev = NULL;
for (p = protocols; p; p = next) { for (p = protocols; p; p = next) {

View file

@ -266,7 +266,7 @@ MiniportQueryInformation(
case OID_GEN_MEDIA_CONNECT_STATUS: case OID_GEN_MEDIA_CONNECT_STATUS:
{ {
GenericULONG = Adapter->MediaState; GenericULONG = (ULONG)NdisMediaStateConnected; /* Adapter->MediaState */
break; break;
} }

View file

@ -57,10 +57,9 @@ NdisGetCurrentSystemTime (
* ARGUMENTS: * ARGUMENTS:
* pSystemTime: pointer to the returned system time * pSystemTime: pointer to the returned system time
* NOTES: * NOTES:
* - call at IRQL <= DISPATCH_LEVEL * - call at any IRQL
*/ */
{ {
ASSERT_IRQL(DISPATCH_LEVEL);
ASSERT(pSystemTime); ASSERT(pSystemTime);
KeQuerySystemTime (pSystemTime); KeQuerySystemTime (pSystemTime);

View file

@ -185,7 +185,9 @@ NTSTATUS TcpipLanGetDwordOid
case OID_GEN_HARDWARE_STATUS: case OID_GEN_HARDWARE_STATUS:
*Result = NdisHardwareStatusReady; *Result = NdisHardwareStatusReady;
return STATUS_SUCCESS; return STATUS_SUCCESS;
case OID_GEN_MEDIA_CONNECT_STATUS:
*Result = NdisMediaStateConnected;
return STATUS_SUCCESS;
default: default:
return STATUS_INVALID_PARAMETER; return STATUS_INVALID_PARAMETER;
} }

View file

@ -196,27 +196,26 @@ PIP_INTERFACE FindOnLinkInterface(PIP_ADDRESS Address)
return NULL; return NULL;
} }
NTSTATUS GetInterfaceConnectionStatus NTSTATUS GetInterfaceConnectionStatus(PIP_INTERFACE Interface, PULONG Result)
( PIP_INTERFACE Interface, PULONG Result ) { {
NTSTATUS Status = TcpipLanGetDwordOid NTSTATUS Status;
( Interface, OID_GEN_HARDWARE_STATUS, Result );
if( NT_SUCCESS(Status) ) switch( *Result ) { /* Query OID_GEN_MEDIA_CONNECT_STATUS for connection status information */
case NdisHardwareStatusReady: 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; *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;
} }