https://git.reactos.org/?p=reactos.git;a=commitdiff;h=033b6639e4c9394c26a47…
commit 033b6639e4c9394c26a47e18752accaf17a8756e
Author: Eric Kohl <eric.kohl(a)reactos.org>
AuthorDate: Sun Aug 8 14:09:31 2021 +0200
Commit: Eric Kohl <eric.kohl(a)reactos.org>
CommitDate: Sun Aug 8 14:10:25 2021 +0200
[DHCPCSVC] Make the DHCP client service stoppable
- Make all threads (pipe thread, adapter discovery thread and dispatcher thread) wait
on the stop event.
- Close shared resources in the main (dispatcher) thread after the pipe thread and the
adapter discovery thread have shut down.
This enables us to stop and restart the DHCP client properly.
CORE-14390
---
base/services/dhcpcsvc/dhcp/adapter.c | 59 +++++--------
base/services/dhcpcsvc/dhcp/api.c | 44 +++++-----
base/services/dhcpcsvc/dhcp/dhclient.c | 8 --
base/services/dhcpcsvc/dhcp/dispatch.c | 19 ++--
base/services/dhcpcsvc/dhcp/pipe.c | 145 +++++++++++++++++++++----------
base/services/dhcpcsvc/dhcpcsvc.c | 73 +++++++++++++++-
base/services/dhcpcsvc/include/rosdhcp.h | 18 ++--
7 files changed, 233 insertions(+), 133 deletions(-)
diff --git a/base/services/dhcpcsvc/dhcp/adapter.c
b/base/services/dhcpcsvc/dhcp/adapter.c
index b2ff127285f..65f620360b8 100644
--- a/base/services/dhcpcsvc/dhcp/adapter.c
+++ b/base/services/dhcpcsvc/dhcp/adapter.c
@@ -1,5 +1,10 @@
#include <rosdhcp.h>
+#define NDEBUG
+#include <reactos/debug.h>
+
+extern HANDLE hAdapterStateChangedEvent;
+
SOCKET DhcpSocket = INVALID_SOCKET;
static LIST_ENTRY AdapterList;
static WSADATA wsd;
@@ -287,14 +292,13 @@ DWORD WINAPI AdapterDiscoveryThread(LPVOID Context) {
PMIB_IFTABLE Table = (PMIB_IFTABLE) malloc(sizeof(MIB_IFTABLE));
DWORD Error, Size = sizeof(MIB_IFTABLE);
PDHCP_ADAPTER Adapter = NULL;
- HANDLE AdapterStateChangedEvent = (HANDLE)Context;
+ HANDLE hStopEvent = (HANDLE)Context;
struct interface_info *ifi = NULL;
struct protocol *proto;
int i, AdapterCount = 0, Broadcast;
- /* FIXME: Kill this thread when the service is stopped */
-
- do {
+ while (TRUE)
+ {
DH_DbgPrint(MID_TRACE,("Getting Adapter List...\n"));
while( (Error = GetIfTable(Table, &Size, 0 )) ==
@@ -346,7 +350,7 @@ DWORD WINAPI AdapterDiscoveryThread(LPVOID Context) {
got_one, &Adapter->DhclientInfo);
state_init(&Adapter->DhclientInfo);
- SetEvent(AdapterStateChangedEvent);
+ SetEvent(hAdapterStateChangedEvent);
}
} else {
@@ -444,7 +448,7 @@ DWORD WINAPI AdapterDiscoveryThread(LPVOID Context) {
ApiLock();
InsertTailList( &AdapterList, &Adapter->ListEntry );
AdapterCount++;
- SetEvent(AdapterStateChangedEvent);
+ SetEvent(hAdapterStateChangedEvent);
ApiUnlock();
} else { free( Adapter ); Adapter = 0; }
} else { free( Adapter ); Adapter = 0; }
@@ -458,43 +462,24 @@ DWORD WINAPI AdapterDiscoveryThread(LPVOID Context) {
if (Error != NO_ERROR)
break;
#else
- Sleep(3000);
+ if (WaitForSingleObject(hStopEvent, 3000) == WAIT_OBJECT_0)
+ {
+ DPRINT("Stopping the discovery thread!\n");
+ break;
+ }
#endif
- } while (TRUE);
+ }
- DbgPrint("DHCPCSVC: Adapter discovery thread is terminating! (Error:
%d)\n", Error);
+ if (Table)
+ free(Table);
+
+ DPRINT("Adapter discovery thread terminated! (Error: %d)\n", Error);
- if( Table ) free( Table );
return Error;
}
-HANDLE StartAdapterDiscovery(VOID) {
- HANDLE ThreadHandle, EventHandle;
-
- EventHandle = CreateEvent(NULL,
- FALSE,
- FALSE,
- NULL);
-
- if (EventHandle == NULL)
- return NULL;
-
- ThreadHandle = CreateThread(NULL,
- 0,
- AdapterDiscoveryThread,
- (LPVOID)EventHandle,
- 0,
- NULL);
-
- if (ThreadHandle == NULL)
- {
- CloseHandle(EventHandle);
- return NULL;
- }
-
- CloseHandle(ThreadHandle);
-
- return EventHandle;
+HANDLE StartAdapterDiscovery(HANDLE hStopEvent) {
+ return CreateThread(NULL, 0, AdapterDiscoveryThread, (LPVOID)hStopEvent, 0, NULL);
}
void AdapterStop() {
diff --git a/base/services/dhcpcsvc/dhcp/api.c b/base/services/dhcpcsvc/dhcp/api.c
index 62fd2c56551..28d19cacba7 100644
--- a/base/services/dhcpcsvc/dhcp/api.c
+++ b/base/services/dhcpcsvc/dhcp/api.c
@@ -13,7 +13,7 @@
static CRITICAL_SECTION ApiCriticalSection;
-extern HANDLE AdapterStateChangedEvent;
+extern HANDLE hAdapterStateChangedEvent;
VOID ApiInit() {
InitializeCriticalSection( &ApiCriticalSection );
@@ -33,7 +33,7 @@ VOID ApiFree() {
/* This represents the service portion of the DHCP client API */
-DWORD DSLeaseIpAddress( PipeSendFunc Send, COMM_DHCP_REQ *Req ) {
+DWORD DSLeaseIpAddress( PipeSendFunc Send, HANDLE CommPipe, COMM_DHCP_REQ *Req ) {
COMM_DHCP_REPLY Reply;
PDHCP_ADAPTER Adapter;
struct protocol* proto;
@@ -56,16 +56,16 @@ DWORD DSLeaseIpAddress( PipeSendFunc Send, COMM_DHCP_REQ *Req ) {
Adapter->DhclientInfo.client->state = S_INIT;
state_reboot(&Adapter->DhclientInfo);
- if (AdapterStateChangedEvent != NULL)
- SetEvent(AdapterStateChangedEvent);
+ if (hAdapterStateChangedEvent != NULL)
+ SetEvent(hAdapterStateChangedEvent);
}
ApiUnlock();
- return Send( &Reply );
+ return Send(CommPipe, &Reply );
}
-DWORD DSQueryHWInfo( PipeSendFunc Send, COMM_DHCP_REQ *Req ) {
+DWORD DSQueryHWInfo( PipeSendFunc Send, HANDLE CommPipe, COMM_DHCP_REQ *Req ) {
COMM_DHCP_REPLY Reply;
PDHCP_ADAPTER Adapter;
@@ -84,10 +84,10 @@ DWORD DSQueryHWInfo( PipeSendFunc Send, COMM_DHCP_REQ *Req ) {
ApiUnlock();
- return Send( &Reply );
+ return Send(CommPipe, &Reply );
}
-DWORD DSReleaseIpAddressLease( PipeSendFunc Send, COMM_DHCP_REQ *Req ) {
+DWORD DSReleaseIpAddressLease( PipeSendFunc Send, HANDLE CommPipe, COMM_DHCP_REQ *Req )
{
COMM_DHCP_REPLY Reply;
PDHCP_ADAPTER Adapter;
struct protocol* proto;
@@ -117,16 +117,16 @@ DWORD DSReleaseIpAddressLease( PipeSendFunc Send, COMM_DHCP_REQ *Req
) {
Adapter->DhclientInfo.client->active = NULL;
Adapter->DhclientInfo.client->state = S_INIT;
- if (AdapterStateChangedEvent != NULL)
- SetEvent(AdapterStateChangedEvent);
+ if (hAdapterStateChangedEvent != NULL)
+ SetEvent(hAdapterStateChangedEvent);
}
ApiUnlock();
- return Send( &Reply );
+ return Send(CommPipe, &Reply );
}
-DWORD DSRenewIpAddressLease( PipeSendFunc Send, COMM_DHCP_REQ *Req ) {
+DWORD DSRenewIpAddressLease( PipeSendFunc Send, HANDLE CommPipe, COMM_DHCP_REQ *Req ) {
COMM_DHCP_REPLY Reply;
PDHCP_ADAPTER Adapter;
struct protocol* proto;
@@ -138,7 +138,7 @@ DWORD DSRenewIpAddressLease( PipeSendFunc Send, COMM_DHCP_REQ *Req )
{
if( !Adapter || Adapter->DhclientState.state == S_STATIC ) {
Reply.Reply = 0;
ApiUnlock();
- return Send( &Reply );
+ return Send(CommPipe, &Reply );
}
Reply.Reply = 1;
@@ -154,15 +154,15 @@ DWORD DSRenewIpAddressLease( PipeSendFunc Send, COMM_DHCP_REQ *Req )
{
Adapter->DhclientInfo.client->state = S_INIT;
state_reboot(&Adapter->DhclientInfo);
- if (AdapterStateChangedEvent != NULL)
- SetEvent(AdapterStateChangedEvent);
+ if (hAdapterStateChangedEvent != NULL)
+ SetEvent(hAdapterStateChangedEvent);
ApiUnlock();
- return Send( &Reply );
+ return Send(CommPipe, &Reply );
}
-DWORD DSStaticRefreshParams( PipeSendFunc Send, COMM_DHCP_REQ *Req ) {
+DWORD DSStaticRefreshParams( PipeSendFunc Send, HANDLE CommPipe, COMM_DHCP_REQ *Req ) {
NTSTATUS Status;
COMM_DHCP_REPLY Reply;
PDHCP_ADAPTER Adapter;
@@ -197,16 +197,16 @@ DWORD DSStaticRefreshParams( PipeSendFunc Send, COMM_DHCP_REQ *Req )
{
&Adapter->NteInstance );
Reply.Reply = NT_SUCCESS(Status);
- if (AdapterStateChangedEvent != NULL)
- SetEvent(AdapterStateChangedEvent);
+ if (hAdapterStateChangedEvent != NULL)
+ SetEvent(hAdapterStateChangedEvent);
}
ApiUnlock();
- return Send( &Reply );
+ return Send(CommPipe, &Reply );
}
-DWORD DSGetAdapterInfo( PipeSendFunc Send, COMM_DHCP_REQ *Req ) {
+DWORD DSGetAdapterInfo( PipeSendFunc Send, HANDLE CommPipe, COMM_DHCP_REQ *Req ) {
COMM_DHCP_REPLY Reply;
PDHCP_ADAPTER Adapter;
@@ -240,5 +240,5 @@ DWORD DSGetAdapterInfo( PipeSendFunc Send, COMM_DHCP_REQ *Req ) {
ApiUnlock();
- return Send( &Reply );
+ return Send(CommPipe, &Reply );
}
diff --git a/base/services/dhcpcsvc/dhcp/dhclient.c
b/base/services/dhcpcsvc/dhcp/dhclient.c
index f97a7ca83df..5d8964b216d 100644
--- a/base/services/dhcpcsvc/dhcp/dhclient.c
+++ b/base/services/dhcpcsvc/dhcp/dhclient.c
@@ -122,14 +122,6 @@ init_client(void)
inaddr_any.s_addr = INADDR_ANY;
bootp_packet_handler = do_packet;
- if (PipeInit() == INVALID_HANDLE_VALUE)
- {
- DbgPrint("DHCPCSVC: PipeInit() failed!\n");
- AdapterStop();
- ApiFree();
- return 0; // FALSE
- }
-
return 1; // TRUE
}
diff --git a/base/services/dhcpcsvc/dhcp/dispatch.c
b/base/services/dhcpcsvc/dhcp/dispatch.c
index d72e0928047..7b973310bb0 100644
--- a/base/services/dhcpcsvc/dhcp/dispatch.c
+++ b/base/services/dhcpcsvc/dhcp/dispatch.c
@@ -41,6 +41,9 @@
#include <rosdhcp.h>
+#define NDEBUG
+#include <reactos/debug.h>
+
//#include <sys/ioctl.h>
//#include <net/if_media.h>
@@ -48,7 +51,8 @@
//#include <poll.h>
extern SOCKET DhcpSocket;
-HANDLE AdapterStateChangedEvent = NULL;
+extern HANDLE hAdapterStateChangedEvent;
+
struct protocol *protocols = NULL;
struct timeout *timeouts = NULL;
static struct timeout *free_timeouts = NULL;
@@ -71,12 +75,7 @@ dispatch(HANDLE hStopEvent)
HANDLE Events[3];
int EventCount = 2;
- Events[0] = StartAdapterDiscovery();
- if (!Events[0])
- return;
-
- AdapterStateChangedEvent = Events[0];
-
+ Events[0] = hAdapterStateChangedEvent;
Events[1] = hStopEvent;
Events[2] = WSA_INVALID_EVENT;
@@ -157,6 +156,7 @@ dispatch(HANDLE hStopEvent)
else if (count == WAIT_OBJECT_0 + 1)
{
/* Stop event signalled */
+ DPRINT("Dispatch thread stop event!\n");
break;
}
else if (count == WAIT_OBJECT_0 + 2)
@@ -183,12 +183,11 @@ dispatch(HANDLE hStopEvent)
}
} while (1);
- AdapterStateChangedEvent = NULL;
- CloseHandle(Events[0]);
- CloseHandle(Events[1]);
WSACloseEvent(Events[2]);
ApiUnlock();
+
+ DPRINT("Dispatch thread stopped!\n");
}
void
diff --git a/base/services/dhcpcsvc/dhcp/pipe.c b/base/services/dhcpcsvc/dhcp/pipe.c
index aff1812675c..a323d171ebd 100644
--- a/base/services/dhcpcsvc/dhcp/pipe.c
+++ b/base/services/dhcpcsvc/dhcp/pipe.c
@@ -11,21 +11,28 @@
#define NDEBUG
#include <reactos/debug.h>
-static HANDLE CommPipe = INVALID_HANDLE_VALUE, CommThread;
-DWORD CommThrId;
-
#define COMM_PIPE_OUTPUT_BUFFER sizeof(COMM_DHCP_REQ)
#define COMM_PIPE_INPUT_BUFFER sizeof(COMM_DHCP_REPLY)
#define COMM_PIPE_DEFAULT_TIMEOUT 1000
-DWORD PipeSend( COMM_DHCP_REPLY *Reply ) {
+DWORD PipeSend( HANDLE CommPipe, COMM_DHCP_REPLY *Reply ) {
DWORD Written = 0;
+ OVERLAPPED Overlapped = {0};
BOOL Success =
WriteFile( CommPipe,
Reply,
sizeof(*Reply),
&Written,
- NULL );
+ &Overlapped);
+ if (!Success)
+ {
+ WaitForSingleObject(CommPipe, INFINITE);
+ Success = GetOverlappedResult(CommPipe,
+ &Overlapped,
+ &Written,
+ TRUE);
+ }
+
return Success ? Written : -1;
}
@@ -34,10 +41,57 @@ DWORD WINAPI PipeThreadProc( LPVOID Parameter ) {
COMM_DHCP_REQ Req;
COMM_DHCP_REPLY Reply;
BOOL Result, Connected;
+ HANDLE Events[2];
+ HANDLE CommPipe;
+ OVERLAPPED Overlapped = {0};
+ DWORD dwError;
- while( TRUE ) {
- Connected = ConnectNamedPipe( CommPipe, NULL ) ?
- TRUE : GetLastError() == ERROR_PIPE_CONNECTED;
+ DPRINT("PipeThreadProc(%p)\n", Parameter);
+
+ CommPipe = CreateNamedPipeW
+ ( DHCP_PIPE_NAME,
+ PIPE_ACCESS_DUPLEX | FILE_FLAG_FIRST_PIPE_INSTANCE | FILE_FLAG_OVERLAPPED,
+ PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
+ 1,
+ COMM_PIPE_OUTPUT_BUFFER,
+ COMM_PIPE_INPUT_BUFFER,
+ COMM_PIPE_DEFAULT_TIMEOUT,
+ NULL );
+ if (CommPipe == INVALID_HANDLE_VALUE)
+ {
+ DbgPrint("DHCP: Could not create named pipe\n");
+ return FALSE;
+ }
+
+ Events[0] = (HANDLE)Parameter;
+ Events[1] = CommPipe;
+
+ while( TRUE )
+ {
+ Connected = ConnectNamedPipe(CommPipe, &Overlapped);
+ if (!Connected)
+ {
+ dwError = GetLastError();
+ if (dwError == ERROR_IO_PENDING)
+ {
+ dwError = WaitForMultipleObjects(2, Events, FALSE, INFINITE);
+ DPRINT("WaitForMultipleObjects() returned %lu\n", dwError);
+ if (dwError == WAIT_OBJECT_0 + 1)
+ {
+ Connected = GetOverlappedResult(CommPipe,
+ &Overlapped,
+ &BytesRead,
+ TRUE);
+ }
+ else if (dwError == WAIT_OBJECT_0)
+ {
+ CancelIo(CommPipe);
+ CloseHandle(CommPipe);
+ CommPipe = INVALID_HANDLE_VALUE;
+ break;
+ }
+ }
+ }
if (!Connected) {
DbgPrint("DHCP: Could not connect named pipe\n");
@@ -46,74 +100,75 @@ DWORD WINAPI PipeThreadProc( LPVOID Parameter ) {
break;
}
- Result = ReadFile( CommPipe, &Req, sizeof(Req), &BytesRead, NULL );
+ Result = ReadFile(CommPipe, &Req, sizeof(Req), &BytesRead,
&Overlapped);
+ if (!Result)
+ {
+ dwError = GetLastError();
+ if (dwError == ERROR_IO_PENDING)
+ {
+ dwError = WaitForMultipleObjects(2, Events, FALSE, INFINITE);
+ DPRINT("WaitForMultipleObjects() returned %lu\n", dwError);
+ if (dwError == WAIT_OBJECT_0 + 1)
+ {
+ Result = GetOverlappedResult(CommPipe,
+ &Overlapped,
+ &BytesRead,
+ TRUE);
+ }
+ else if (dwError == WAIT_OBJECT_0)
+ {
+ CancelIo(CommPipe);
+ DisconnectNamedPipe( CommPipe );
+ CloseHandle(CommPipe);
+ CommPipe = INVALID_HANDLE_VALUE;
+ break;
+ }
+ }
+ }
+
if( Result ) {
switch( Req.Type ) {
case DhcpReqQueryHWInfo:
- DSQueryHWInfo( PipeSend, &Req );
+ DSQueryHWInfo( PipeSend, CommPipe, &Req );
break;
case DhcpReqLeaseIpAddress:
- DSLeaseIpAddress( PipeSend, &Req );
+ DSLeaseIpAddress( PipeSend, CommPipe, &Req );
break;
case DhcpReqReleaseIpAddress:
- DSReleaseIpAddressLease( PipeSend, &Req );
+ DSReleaseIpAddressLease( PipeSend, CommPipe, &Req );
break;
case DhcpReqRenewIpAddress:
- DSRenewIpAddressLease( PipeSend, &Req );
+ DSRenewIpAddressLease( PipeSend, CommPipe, &Req );
break;
case DhcpReqStaticRefreshParams:
- DSStaticRefreshParams( PipeSend, &Req );
+ DSStaticRefreshParams( PipeSend, CommPipe, &Req );
break;
case DhcpReqGetAdapterInfo:
- DSGetAdapterInfo( PipeSend, &Req );
+ DSGetAdapterInfo( PipeSend, CommPipe, &Req );
break;
default:
DPRINT1("Unrecognized request type %d\n", Req.Type);
ZeroMemory( &Reply, sizeof( COMM_DHCP_REPLY ) );
Reply.Reply = 0;
- PipeSend( &Reply );
+ PipeSend(CommPipe, &Reply );
break;
}
}
DisconnectNamedPipe( CommPipe );
}
- return TRUE;
-}
+ DPRINT("Pipe thread stopped!\n");
-HANDLE PipeInit() {
- CommPipe = CreateNamedPipeW
- ( DHCP_PIPE_NAME,
- PIPE_ACCESS_DUPLEX | FILE_FLAG_FIRST_PIPE_INSTANCE,
- PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT,
- 1,
- COMM_PIPE_OUTPUT_BUFFER,
- COMM_PIPE_INPUT_BUFFER,
- COMM_PIPE_DEFAULT_TIMEOUT,
- NULL );
-
- if( CommPipe == INVALID_HANDLE_VALUE ) {
- DbgPrint("DHCP: Could not create named pipe\n");
- return CommPipe;
- }
-
- CommThread = CreateThread( NULL, 0, PipeThreadProc, NULL, 0, &CommThrId );
-
- if( !CommThread ) {
- CloseHandle( CommPipe );
- CommPipe = INVALID_HANDLE_VALUE;
- }
-
- return CommPipe;
+ return TRUE;
}
-VOID PipeDestroy() {
- CloseHandle( CommPipe );
- CommPipe = INVALID_HANDLE_VALUE;
+HANDLE PipeInit(HANDLE hStopEvent)
+{
+ return CreateThread( NULL, 0, PipeThreadProc, (LPVOID)hStopEvent, 0, NULL);
}
diff --git a/base/services/dhcpcsvc/dhcpcsvc.c b/base/services/dhcpcsvc/dhcpcsvc.c
index e1f131c6c50..819af629a79 100644
--- a/base/services/dhcpcsvc/dhcpcsvc.c
+++ b/base/services/dhcpcsvc/dhcpcsvc.c
@@ -17,8 +17,10 @@ static WCHAR ServiceName[] = L"DHCP";
SERVICE_STATUS_HANDLE ServiceStatusHandle = 0;
SERVICE_STATUS ServiceStatus;
HANDLE hStopEvent = NULL;
+HANDLE hAdapterStateChangedEvent = NULL;
static HANDLE PipeHandle = INVALID_HANDLE_VALUE;
+extern SOCKET DhcpSocket;
DWORD APIENTRY
DhcpCApiInitialize(LPDWORD Version)
@@ -391,6 +393,10 @@ ServiceControlHandler(DWORD dwControl,
VOID WINAPI
ServiceMain(DWORD argc, LPWSTR* argv)
{
+ HANDLE hPipeThread = INVALID_HANDLE_VALUE;
+ HANDLE hDiscoveryThread = INVALID_HANDLE_VALUE;
+ DWORD ret;
+
ServiceStatusHandle = RegisterServiceCtrlHandlerExW(ServiceName,
ServiceControlHandler,
NULL);
@@ -403,18 +409,52 @@ ServiceMain(DWORD argc, LPWSTR* argv)
UpdateServiceStatus(SERVICE_START_PENDING);
/* Create the stop event */
- hStopEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
+ hStopEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
if (hStopEvent == NULL)
{
UpdateServiceStatus(SERVICE_STOPPED);
return;
}
+ hAdapterStateChangedEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
+ if (hAdapterStateChangedEvent == NULL)
+ {
+ CloseHandle(hStopEvent);
+ UpdateServiceStatus(SERVICE_STOPPED);
+ return;
+ }
+
UpdateServiceStatus(SERVICE_START_PENDING);
if (!init_client())
{
- DPRINT1("DHCPCSVC: init_client() failed!\n");
+ DbgPrint("DHCPCSVC: init_client() failed!\n");
+ CloseHandle(hAdapterStateChangedEvent);
+ CloseHandle(hStopEvent);
+ UpdateServiceStatus(SERVICE_STOPPED);
+ return;
+ }
+
+ UpdateServiceStatus(SERVICE_START_PENDING);
+
+ hPipeThread = PipeInit(hStopEvent);
+ if (hPipeThread == INVALID_HANDLE_VALUE)
+ {
+ DbgPrint("DHCPCSVC: PipeInit() failed!\n");
+ stop_client();
+ CloseHandle(hAdapterStateChangedEvent);
+ CloseHandle(hStopEvent);
+ UpdateServiceStatus(SERVICE_STOPPED);
+ return;
+ }
+
+ hDiscoveryThread = StartAdapterDiscovery(hStopEvent);
+ if (hDiscoveryThread == INVALID_HANDLE_VALUE)
+ {
+ DbgPrint("DHCPCSVC: StartAdapterDiscovery() failed!\n");
+ stop_client();
+ CloseHandle(hAdapterStateChangedEvent);
+ CloseHandle(hStopEvent);
UpdateServiceStatus(SERVICE_STOPPED);
return;
}
@@ -429,8 +469,37 @@ ServiceMain(DWORD argc, LPWSTR* argv)
dispatch(hStopEvent);
DH_DbgPrint(MID_TRACE,("DHCPCSVC: DHCP service is shutting down\n"));
+
stop_client();
+ DPRINT("Wait for pipe thread to close! %p\n", hPipeThread);
+ if (hPipeThread != INVALID_HANDLE_VALUE)
+ {
+ DPRINT("Waiting for pipe thread\n");
+ ret = WaitForSingleObject(hPipeThread, 5000);
+ DPRINT("Done %lx\n", ret);
+ }
+
+ DPRINT("Wait for discovery thread to close! %p\n", hDiscoveryThread);
+ if (hDiscoveryThread != INVALID_HANDLE_VALUE)
+ {
+ DPRINT("Waiting for discovery thread\n");
+ ret = WaitForSingleObject(hDiscoveryThread, 5000);
+ DPRINT("Done %lx\n", ret);
+ }
+
+ DPRINT("Closing events!\n");
+ CloseHandle(hAdapterStateChangedEvent);
+ CloseHandle(hStopEvent);
+
+ if (DhcpSocket != INVALID_SOCKET)
+ closesocket(DhcpSocket);
+
+ CloseHandle(hDiscoveryThread);
+ CloseHandle(hPipeThread);
+
+ DPRINT("Done!\n");
+
UpdateServiceStatus(SERVICE_STOPPED);
}
diff --git a/base/services/dhcpcsvc/include/rosdhcp.h
b/base/services/dhcpcsvc/include/rosdhcp.h
index ffb2ee8ff31..3f278a31a4f 100644
--- a/base/services/dhcpcsvc/include/rosdhcp.h
+++ b/base/services/dhcpcsvc/include/rosdhcp.h
@@ -76,7 +76,7 @@ typedef struct _DHCP_ADAPTER {
unsigned char recv_buf[1];
} DHCP_ADAPTER, *PDHCP_ADAPTER;
-typedef DWORD (*PipeSendFunc)( COMM_DHCP_REPLY *Reply );
+typedef DWORD (*PipeSendFunc)(HANDLE CommPipe, COMM_DHCP_REPLY *Reply );
#define random rand
#define srandom srand
@@ -85,24 +85,24 @@ int init_client(void);
void stop_client(void);
void AdapterInit(VOID);
-HANDLE StartAdapterDiscovery(VOID);
+HANDLE StartAdapterDiscovery(HANDLE hStopEvent);
void AdapterStop(VOID);
extern PDHCP_ADAPTER AdapterGetFirst(VOID);
extern PDHCP_ADAPTER AdapterGetNext(PDHCP_ADAPTER);
extern PDHCP_ADAPTER AdapterFindIndex( unsigned int AdapterIndex );
extern PDHCP_ADAPTER AdapterFindInfo( struct interface_info *info );
extern PDHCP_ADAPTER AdapterFindByHardwareAddress( u_int8_t haddr[16], u_int8_t hlen );
-extern HANDLE PipeInit(VOID);
+extern HANDLE PipeInit(HANDLE hStopEvent);
extern VOID ApiInit(VOID);
extern VOID ApiFree(VOID);
extern VOID ApiLock(VOID);
extern VOID ApiUnlock(VOID);
-extern DWORD DSQueryHWInfo( PipeSendFunc Send, COMM_DHCP_REQ *Req );
-extern DWORD DSLeaseIpAddress( PipeSendFunc Send, COMM_DHCP_REQ *Req );
-extern DWORD DSRenewIpAddressLease( PipeSendFunc Send, COMM_DHCP_REQ *Req );
-extern DWORD DSReleaseIpAddressLease( PipeSendFunc Send, COMM_DHCP_REQ *Req );
-extern DWORD DSStaticRefreshParams( PipeSendFunc Send, COMM_DHCP_REQ *Req );
-extern DWORD DSGetAdapterInfo( PipeSendFunc Send, COMM_DHCP_REQ *Req );
+extern DWORD DSQueryHWInfo( PipeSendFunc Send, HANDLE CommPipe, COMM_DHCP_REQ *Req );
+extern DWORD DSLeaseIpAddress( PipeSendFunc Send, HANDLE CommPipe, COMM_DHCP_REQ *Req );
+extern DWORD DSRenewIpAddressLease( PipeSendFunc Send, HANDLE CommPipe, COMM_DHCP_REQ
*Req );
+extern DWORD DSReleaseIpAddressLease( PipeSendFunc Send, HANDLE CommPipe, COMM_DHCP_REQ
*Req );
+extern DWORD DSStaticRefreshParams( PipeSendFunc Send, HANDLE CommPipe, COMM_DHCP_REQ
*Req );
+extern DWORD DSGetAdapterInfo( PipeSendFunc Send, HANDLE CommPipe, COMM_DHCP_REQ *Req );
extern int inet_aton(const char *s, struct in_addr *addr);
int warn( char *format, ... );