mirror of
https://github.com/reactos/reactos.git
synced 2024-10-15 13:45:58 +00:00
033b6639e4
- 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
175 lines
5.3 KiB
C
175 lines
5.3 KiB
C
/*
|
|
* COPYRIGHT: See COPYING in the top level directory
|
|
* PROJECT: ReactOS kernel
|
|
* FILE: subsys/system/dhcp/pipe.c
|
|
* PURPOSE: DHCP client pipe
|
|
* PROGRAMMER: arty
|
|
*/
|
|
|
|
#include <rosdhcp.h>
|
|
|
|
#define NDEBUG
|
|
#include <reactos/debug.h>
|
|
|
|
#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( HANDLE CommPipe, COMM_DHCP_REPLY *Reply ) {
|
|
DWORD Written = 0;
|
|
OVERLAPPED Overlapped = {0};
|
|
BOOL Success =
|
|
WriteFile( CommPipe,
|
|
Reply,
|
|
sizeof(*Reply),
|
|
&Written,
|
|
&Overlapped);
|
|
if (!Success)
|
|
{
|
|
WaitForSingleObject(CommPipe, INFINITE);
|
|
Success = GetOverlappedResult(CommPipe,
|
|
&Overlapped,
|
|
&Written,
|
|
TRUE);
|
|
}
|
|
|
|
return Success ? Written : -1;
|
|
}
|
|
|
|
DWORD WINAPI PipeThreadProc( LPVOID Parameter ) {
|
|
DWORD BytesRead;
|
|
COMM_DHCP_REQ Req;
|
|
COMM_DHCP_REPLY Reply;
|
|
BOOL Result, Connected;
|
|
HANDLE Events[2];
|
|
HANDLE CommPipe;
|
|
OVERLAPPED Overlapped = {0};
|
|
DWORD dwError;
|
|
|
|
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");
|
|
CloseHandle( CommPipe );
|
|
CommPipe = INVALID_HANDLE_VALUE;
|
|
break;
|
|
}
|
|
|
|
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, CommPipe, &Req );
|
|
break;
|
|
|
|
case DhcpReqLeaseIpAddress:
|
|
DSLeaseIpAddress( PipeSend, CommPipe, &Req );
|
|
break;
|
|
|
|
case DhcpReqReleaseIpAddress:
|
|
DSReleaseIpAddressLease( PipeSend, CommPipe, &Req );
|
|
break;
|
|
|
|
case DhcpReqRenewIpAddress:
|
|
DSRenewIpAddressLease( PipeSend, CommPipe, &Req );
|
|
break;
|
|
|
|
case DhcpReqStaticRefreshParams:
|
|
DSStaticRefreshParams( PipeSend, CommPipe, &Req );
|
|
break;
|
|
|
|
case DhcpReqGetAdapterInfo:
|
|
DSGetAdapterInfo( PipeSend, CommPipe, &Req );
|
|
break;
|
|
|
|
default:
|
|
DPRINT1("Unrecognized request type %d\n", Req.Type);
|
|
ZeroMemory( &Reply, sizeof( COMM_DHCP_REPLY ) );
|
|
Reply.Reply = 0;
|
|
PipeSend(CommPipe, &Reply );
|
|
break;
|
|
}
|
|
}
|
|
DisconnectNamedPipe( CommPipe );
|
|
}
|
|
|
|
DPRINT("Pipe thread stopped!\n");
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
HANDLE PipeInit(HANDLE hStopEvent)
|
|
{
|
|
return CreateThread( NULL, 0, PipeThreadProc, (LPVOID)hStopEvent, 0, NULL);
|
|
}
|