https://git.reactos.org/?p=reactos.git;a=commitdiff;h=9febc82acf317ea16ddb0…
commit 9febc82acf317ea16ddb04cda88e24051bacd8c4
Author: Eric Kohl <eric.kohl(a)reactos.org>
AuthorDate: Wed Mar 21 21:07:26 2018 +0100
Commit: Eric Kohl <eric.kohl(a)reactos.org>
CommitDate: Wed Mar 21 21:07:26 2018 +0100
[DHCPCSVC] Add the ability to stop the DHCP client
- Use a stop event to terminate the dispatch loop.
- Report to the services manager that the service can be stopped or shut-down while it
is running.
CORE-14390
---
base/services/dhcpcsvc/dhcp/dispatch.c | 48 ++++++++++++++++++++--------------
base/services/dhcpcsvc/dhcpcsvc.c | 44 +++++++++++++++----------------
base/services/dhcpcsvc/include/dhcpd.h | 2 +-
3 files changed, 51 insertions(+), 43 deletions(-)
diff --git a/base/services/dhcpcsvc/dhcp/dispatch.c
b/base/services/dhcpcsvc/dhcp/dispatch.c
index d9ef98271a..d72e092804 100644
--- a/base/services/dhcpcsvc/dhcp/dispatch.c
+++ b/base/services/dhcpcsvc/dhcp/dispatch.c
@@ -63,21 +63,23 @@ void (*bootp_packet_handler)(struct interface_info *,
* bootp_packet_handler hook to try to do something with it.
*/
void
-dispatch(void)
+dispatch(HANDLE hStopEvent)
{
int count, to_msec;
struct protocol *l;
time_t howlong, cur_time;
- HANDLE Events[2];
- int EventCount = 1;
+ HANDLE Events[3];
+ int EventCount = 2;
Events[0] = StartAdapterDiscovery();
if (!Events[0])
return;
+
AdapterStateChangedEvent = Events[0];
-
- Events[1] = WSA_INVALID_EVENT;
-
+
+ Events[1] = hStopEvent;
+ Events[2] = WSA_INVALID_EVENT;
+
ApiLock();
do {
@@ -116,29 +118,29 @@ dispatch(void)
to_msec = INFINITE;
}
- if (Events[1] == WSA_INVALID_EVENT && DhcpSocket != INVALID_SOCKET)
+ if (Events[2] == WSA_INVALID_EVENT && DhcpSocket != INVALID_SOCKET)
{
- Events[1] = WSACreateEvent();
- if (Events[1] != WSA_INVALID_EVENT)
+ Events[2] = WSACreateEvent();
+ if (Events[2] != WSA_INVALID_EVENT)
{
- count = WSAEventSelect(DhcpSocket, Events[1], FD_READ | FD_CLOSE);
+ count = WSAEventSelect(DhcpSocket, Events[2], FD_READ | FD_CLOSE);
if (count != NO_ERROR)
{
- WSACloseEvent(Events[1]);
- Events[1] = WSA_INVALID_EVENT;
+ WSACloseEvent(Events[2]);
+ Events[2] = WSA_INVALID_EVENT;
}
else
{
- EventCount = 2;
+ EventCount = 3;
}
}
}
- else if (Events[1] != WSA_INVALID_EVENT && DhcpSocket == INVALID_SOCKET)
+ else if (Events[2] != WSA_INVALID_EVENT && DhcpSocket == INVALID_SOCKET)
{
- WSACloseEvent(Events[1]);
- Events[1] = WSA_INVALID_EVENT;
+ WSACloseEvent(Events[2]);
+ Events[2] = WSA_INVALID_EVENT;
- EventCount = 1;
+ EventCount = 2;
}
ApiUnlock();
@@ -153,11 +155,16 @@ dispatch(void)
continue;
}
else if (count == WAIT_OBJECT_0 + 1)
+ {
+ /* Stop event signalled */
+ break;
+ }
+ else if (count == WAIT_OBJECT_0 + 2)
{
/* Packet received */
-
+
/* WSA events are manual reset events */
- WSAResetEvent(Events[1]);
+ WSAResetEvent(Events[2]);
}
else
{
@@ -178,7 +185,8 @@ dispatch(void)
AdapterStateChangedEvent = NULL;
CloseHandle(Events[0]);
- WSACloseEvent(Events[1]);
+ CloseHandle(Events[1]);
+ WSACloseEvent(Events[2]);
ApiUnlock();
}
diff --git a/base/services/dhcpcsvc/dhcpcsvc.c b/base/services/dhcpcsvc/dhcpcsvc.c
index a96e372fc8..bfd3dbf6a5 100644
--- a/base/services/dhcpcsvc/dhcpcsvc.c
+++ b/base/services/dhcpcsvc/dhcpcsvc.c
@@ -16,6 +16,7 @@ static WCHAR ServiceName[] = L"DHCP";
SERVICE_STATUS_HANDLE ServiceStatusHandle = 0;
SERVICE_STATUS ServiceStatus;
+HANDLE hStopEvent = NULL;
static HANDLE PipeHandle = INVALID_HANDLE_VALUE;
@@ -328,17 +329,18 @@ UpdateServiceStatus(DWORD dwState)
ServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
ServiceStatus.dwCurrentState = dwState;
- ServiceStatus.dwControlsAccepted = 0;
+ if (dwState == SERVICE_RUNNING)
+ ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_SHUTDOWN |
SERVICE_ACCEPT_STOP;
+ else
+ ServiceStatus.dwControlsAccepted = 0;
ServiceStatus.dwWin32ExitCode = 0;
ServiceStatus.dwServiceSpecificExitCode = 0;
ServiceStatus.dwCheckPoint = 0;
if (dwState == SERVICE_START_PENDING ||
- dwState == SERVICE_STOP_PENDING ||
- dwState == SERVICE_PAUSE_PENDING ||
- dwState == SERVICE_CONTINUE_PENDING)
- ServiceStatus.dwWaitHint = 10000;
+ dwState == SERVICE_STOP_PENDING)
+ ServiceStatus.dwWaitHint = 1000;
else
ServiceStatus.dwWaitHint = 0;
@@ -355,17 +357,10 @@ ServiceControlHandler(DWORD dwControl,
switch (dwControl)
{
case SERVICE_CONTROL_STOP:
+ case SERVICE_CONTROL_SHUTDOWN:
UpdateServiceStatus(SERVICE_STOP_PENDING);
- UpdateServiceStatus(SERVICE_STOPPED);
- return ERROR_SUCCESS;
-
- case SERVICE_CONTROL_PAUSE:
- UpdateServiceStatus(SERVICE_PAUSED);
- return ERROR_SUCCESS;
-
- case SERVICE_CONTROL_CONTINUE:
- UpdateServiceStatus(SERVICE_START_PENDING);
- UpdateServiceStatus(SERVICE_RUNNING);
+ if (hStopEvent != NULL)
+ SetEvent(hStopEvent);
return ERROR_SUCCESS;
case SERVICE_CONTROL_INTERROGATE:
@@ -373,12 +368,7 @@ ServiceControlHandler(DWORD dwControl,
&ServiceStatus);
return ERROR_SUCCESS;
- case SERVICE_CONTROL_SHUTDOWN:
- UpdateServiceStatus(SERVICE_STOP_PENDING);
- UpdateServiceStatus(SERVICE_STOPPED);
- return ERROR_SUCCESS;
-
- default :
+ default:
return ERROR_CALL_NOT_IMPLEMENTED;
}
}
@@ -397,6 +387,16 @@ ServiceMain(DWORD argc, LPWSTR* argv)
UpdateServiceStatus(SERVICE_START_PENDING);
+ /* Create the stop event */
+ hStopEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
+ if (hStopEvent == NULL)
+ {
+ UpdateServiceStatus(SERVICE_STOPPED);
+ return;
+ }
+
+ UpdateServiceStatus(SERVICE_START_PENDING);
+
if (!init_client())
{
DPRINT1("DHCPCSVC: init_client() failed!\n");
@@ -411,7 +411,7 @@ ServiceMain(DWORD argc, LPWSTR* argv)
DH_DbgPrint(MID_TRACE,("Going into dispatch()\n"));
DH_DbgPrint(MID_TRACE,("DHCPCSVC: DHCP service is starting up\n"));
- dispatch();
+ dispatch(hStopEvent);
DH_DbgPrint(MID_TRACE,("DHCPCSVC: DHCP service is shutting down\n"));
stop_client();
diff --git a/base/services/dhcpcsvc/include/dhcpd.h
b/base/services/dhcpcsvc/include/dhcpd.h
index d6a2fa405b..b7b01b4e00 100644
--- a/base/services/dhcpcsvc/include/dhcpd.h
+++ b/base/services/dhcpcsvc/include/dhcpd.h
@@ -351,7 +351,7 @@ extern void (*bootp_packet_handler)(struct interface_info *,
struct dhcp_packet *, int, unsigned int, struct iaddr, struct hardware *);
void discover_interfaces(struct interface_info *);
void reinitialize_interfaces(void);
-void dispatch(void);
+void dispatch(HANDLE hStopEvent);
void got_one(struct protocol *);
void add_timeout(time_t, void (*)(void *), void *);
void cancel_timeout(void (*)(void *), void *);