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 +#define NDEBUG +#include + +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 +#define NDEBUG +#include + //#include //#include @@ -48,7 +51,8 @@ //#include 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 -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 ); } + DPRINT("Pipe thread stopped!\n"); + return TRUE; } -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; -} - -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, ... );