Added client API interface.
Modified: trunk/reactos/subsys/system/dhcp/Makefile
Added: trunk/reactos/subsys/system/dhcp/api.c
Modified: trunk/reactos/subsys/system/dhcp/dhclient.c
Modified: trunk/reactos/subsys/system/dhcp/dispatch.c
Modified: trunk/reactos/subsys/system/dhcp/include/dhcpd.h
Modified: trunk/reactos/subsys/system/dhcp/include/rosdhcp.h
Added: trunk/reactos/subsys/system/dhcp/pipe.c

Modified: trunk/reactos/subsys/system/dhcp/Makefile
--- trunk/reactos/subsys/system/dhcp/Makefile	2005-04-12 21:25:58 UTC (rev 14598)
+++ trunk/reactos/subsys/system/dhcp/Makefile	2005-04-12 23:23:26 UTC (rev 14599)
@@ -10,8 +10,9 @@
 
 TARGET_CFLAGS = -D__REACTOS__ -D_WIN32_WINNT=0x0501 -D__USE_W32API -Iinclude
 
-TARGET_OBJECTS = adapter.o alloc.o compat.o dhclient.o dispatch.o hash.o \
-		options.o privsep.o socket.o tables.o timer.o util.o
+TARGET_OBJECTS = adapter.o alloc.o api.o compat.o dhclient.o dispatch.o \
+		hash.o options.o pipe.o privsep.o socket.o tables.o timer.o \
+		util.o
 
 TARGET_SDKLIBS = iphlpapi.a ws2_32.a ntdll.a
 

Added: trunk/reactos/subsys/system/dhcp/api.c
--- trunk/reactos/subsys/system/dhcp/api.c	2005-04-12 21:25:58 UTC (rev 14598)
+++ trunk/reactos/subsys/system/dhcp/api.c	2005-04-12 23:23:26 UTC (rev 14599)
@@ -0,0 +1,136 @@
+/* $Id: $
+ *
+ * COPYRIGHT:        See COPYING in the top level directory
+ * PROJECT:          ReactOS kernel
+ * FILE:             subsys/system/dhcp/api.c
+ * PURPOSE:          DHCP client api handlers
+ * PROGRAMMER:       arty
+ */
+
+#include <winsock2.h>
+#include <iphlpapi.h>
+#include "rosdhcp.h"
+
+static CRITICAL_SECTION ApiCriticalSection;
+
+VOID ApiInit() {
+    InitializeCriticalSection( &ApiCriticalSection );
+}
+
+VOID ApiLock() {
+    EnterCriticalSection( &ApiCriticalSection );
+}
+
+VOID ApiUnlock() {
+    LeaveCriticalSection( &ApiCriticalSection );
+}
+
+/* This represents the service portion of the DHCP client API */
+
+DWORD DSLeaseIpAddress( PipeSendFunc Send, COMM_DHCP_REQ *Req ) {
+    COMM_DHCP_REPLY Reply;
+    PDHCP_ADAPTER Adapter;
+
+    ApiLock();
+
+    Adapter = AdapterFindIndex( Req->AdapterIndex );
+
+    Reply.Reply = Adapter ? 1 : 0;
+
+    if( Adapter ) {
+        Adapter->DhclientState.state = S_REBOOTING;
+        send_discover( &Adapter->DhclientInfo );
+    }
+
+    ApiUnlock();
+
+    return Send( &Reply );
+}
+
+DWORD DSQueryHWInfo( PipeSendFunc Send, COMM_DHCP_REQ *Req ) {
+    COMM_DHCP_REPLY Reply;
+    PDHCP_ADAPTER Adapter;
+
+    ApiLock();
+
+    Adapter = AdapterFindIndex( Req->AdapterIndex );
+
+    Reply.QueryHWInfo.AdapterIndex = Req->AdapterIndex;
+    Reply.QueryHWInfo.MediaType = Adapter->IfMib.dwType;
+    Reply.QueryHWInfo.Mtu = Adapter->IfMib.dwMtu;
+    Reply.QueryHWInfo.Speed = Adapter->IfMib.dwSpeed;
+
+    ApiUnlock();
+
+    return Send( &Reply );
+}
+
+DWORD DSReleaseIpAddressLease( PipeSendFunc Send, COMM_DHCP_REQ *Req ) {
+    COMM_DHCP_REPLY Reply;
+    PDHCP_ADAPTER Adapter;
+
+    ApiLock();
+
+    Adapter = AdapterFindIndex( Req->AdapterIndex );
+
+    Reply.Reply = Adapter ? 1 : 0;
+
+    if( Adapter ) {
+        DeleteIPAddress( Adapter->NteContext );
+    }
+
+    ApiUnlock();
+
+    return Send( &Reply );
+}
+
+DWORD DSRenewIpAddressLease( PipeSendFunc Send, COMM_DHCP_REQ *Req ) {
+    COMM_DHCP_REPLY Reply;
+    PDHCP_ADAPTER Adapter;
+
+    ApiLock();
+
+    Adapter = AdapterFindIndex( Req->AdapterIndex );
+
+    Reply.Reply = Adapter ? 1 : 0;
+
+    if( !Adapter || Adapter->DhclientState.state != S_BOUND ) {
+        Reply.Reply = 0;
+        return Send( &Reply );
+    }
+
+    Adapter->DhclientState.state = S_BOUND;
+
+    state_bound( &Adapter->DhclientInfo );
+
+    ApiUnlock();
+
+    return Send( &Reply );
+}
+
+DWORD DSStaticRefreshParams( PipeSendFunc Send, COMM_DHCP_REQ *Req ) {
+    NTSTATUS Status;
+    COMM_DHCP_REPLY Reply;
+    PDHCP_ADAPTER Adapter;
+
+    ApiLock();
+
+    Adapter = AdapterFindIndex( Req->AdapterIndex );
+
+    Reply.Reply = Adapter ? 1 : 0;
+
+    if( Adapter ) {
+        DeleteIPAddress( Adapter->NteContext );
+        Adapter->DhclientState.state = S_BOUND;
+        Status = AddIPAddress( Req->Body.StaticRefreshParams.IPAddress,
+                               Req->Body.StaticRefreshParams.Netmask,
+                               Req->AdapterIndex,
+                               &Adapter->NteContext,
+                               &Adapter->NteInstance );
+        Reply.Reply = NT_SUCCESS(Status);
+    }
+
+    ApiUnlock();
+
+    return Send( &Reply );
+}

Modified: trunk/reactos/subsys/system/dhcp/dhclient.c
--- trunk/reactos/subsys/system/dhcp/dhclient.c	2005-04-12 21:25:58 UTC (rev 14598)
+++ trunk/reactos/subsys/system/dhcp/dhclient.c	2005-04-12 23:23:26 UTC (rev 14599)
@@ -259,7 +259,9 @@
 	int			 pipe_fd[2];
 	struct passwd		*pw;
 
+        ApiInit();
         AdapterInit();
+        PipeInit();
 
 	tzset();
 	time(&cur_time);

Modified: trunk/reactos/subsys/system/dhcp/dispatch.c
--- trunk/reactos/subsys/system/dhcp/dispatch.c	2005-04-12 21:25:58 UTC (rev 14598)
+++ trunk/reactos/subsys/system/dhcp/dispatch.c	2005-04-12 23:23:26 UTC (rev 14599)
@@ -199,6 +199,8 @@
     time_t howlong;
     struct timeval timeval;
 
+    ApiLock();
+
     for (l = protocols; l; l = l->next)
         nfds++;
 
@@ -269,9 +271,14 @@
         timeval.tv_usec = (to_msec % 1000) * 1000;
         DH_DbgPrint(MID_TRACE,("select(%d,%d.%03d) =>\n", 
                  nfds,timeval.tv_sec,timeval.tv_usec/1000));
+
+        ApiUnlock();
+
         count = select(nfds, &fds, NULL, NULL, &timeval);
         DH_DbgPrint(MID_TRACE,(" => %d\n", count));
 
+        ApiLock();
+
         /* Not likely to be transitory... */
         if (count == SOCKET_ERROR) {
             if (errno == EAGAIN || errno == EINTR) {
@@ -304,6 +311,8 @@
         }
         DH_DbgPrint(MID_TRACE,("Done\n"));
     } while (1);
+
+    ApiUnlock(); /* Not reached currently */
 }
 
 void

Modified: trunk/reactos/subsys/system/dhcp/include/dhcpd.h
--- trunk/reactos/subsys/system/dhcp/include/dhcpd.h	2005-04-12 21:25:58 UTC (rev 14598)
+++ trunk/reactos/subsys/system/dhcp/include/dhcpd.h	2005-04-12 23:23:26 UTC (rev 14599)
@@ -93,33 +93,17 @@
 #define USE_SOCKET_SEND
 
 #include <sys/types.h>
-
-//#include <sys/socket.h>
-//#include <sys/sockio.h>
 #include <sys/stat.h>
 #include <sys/time.h>
-//#include <sys/un.h>
-//#include <sys/wait.h>
-
-//#include <net/if.h>
-//#include <net/if_dl.h>
-//#include <net/route.h>
-
-//#include <netinet/in.h>
-//#include <arpa/inet.h>
-
 #include <ctype.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <limits.h>
-//#include <netdb.h>
-//#include <paths.h>
 #include <unistd.h>
 #include <stdarg.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-//#include <syslog.h>
 #include <time.h>
 #include <unistd.h>
 

Modified: trunk/reactos/subsys/system/dhcp/include/rosdhcp.h
--- trunk/reactos/subsys/system/dhcp/include/rosdhcp.h	2005-04-12 21:25:58 UTC (rev 14598)
+++ trunk/reactos/subsys/system/dhcp/include/rosdhcp.h	2005-04-12 23:23:26 UTC (rev 14599)
@@ -7,6 +7,7 @@
 #include <iprtrmib.h>
 #include <iphlpapi.h>
 #include <winsock2.h>
+#include <dhcpcsdk.h>
 #include <stdio.h>
 #include <setjmp.h>
 #include "stdint.h"
@@ -41,6 +42,7 @@
     MIB_IFROW      IfMib;
     MIB_IPADDRROW  IfAddr;
     SOCKADDR       Address;
+    ULONG NteContext,NteInstance;
     struct interface_info DhclientInfo;
     struct client_state DhclientState;
     struct client_config DhclientConfig;
@@ -49,7 +51,20 @@
     char recv_buf[1];
 } DHCP_ADAPTER, *PDHCP_ADAPTER;
 
+#include <rosdhcp_public.h>
+
+typedef DWORD (*PipeSendFunc)( COMM_DHCP_REPLY *Reply );
+
 #define random rand
 #define srandom srand
 
+extern PDHCP_ADAPTER AdapterFindIndex( unsigned int AdapterIndex );
+extern VOID ApiInit();
+extern VOID ApiLock();
+extern VOID ApiUnlock();
+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 );
+
 #endif/*ROSDHCP_H*/

Added: trunk/reactos/subsys/system/dhcp/pipe.c
--- trunk/reactos/subsys/system/dhcp/pipe.c	2005-04-12 21:25:58 UTC (rev 14598)
+++ trunk/reactos/subsys/system/dhcp/pipe.c	2005-04-12 23:23:26 UTC (rev 14599)
@@ -0,0 +1,90 @@
+/* $Id: $
+ *
+ * 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>
+
+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 Written = 0;
+    BOOL Success = 
+        WriteFile( CommPipe,
+                   Reply,
+                   sizeof(*Reply),
+                   &Written,
+                   NULL );
+    return Success ? Written : -1;
+}
+
+DWORD WINAPI PipeThreadProc( LPVOID Parameter ) {
+    DWORD BytesRead, BytesWritten;
+    COMM_DHCP_REQ Req;
+    BOOL Result;
+    HANDLE Connection;
+
+    while( (Connection = ConnectNamedPipe( CommPipe, NULL )) ) {
+        Result = ReadFile( Connection, &Req, sizeof(Req), &BytesRead, NULL );
+        if( Result ) {
+            switch( Req.Type ) {
+            case DhcpReqQueryHWInfo:
+                BytesWritten = DSQueryHWInfo( PipeSend, &Req );
+                break;
+                
+            case DhcpReqLeaseIpAddress:
+                BytesWritten = DSLeaseIpAddress( PipeSend, &Req );
+                break;
+                
+            case DhcpReqReleaseIpAddress:
+                BytesWritten = DSReleaseIpAddressLease( PipeSend, &Req );
+                break;
+                
+            case DhcpReqRenewIpAddress:
+                BytesWritten = DSRenewIpAddressLease( PipeSend, &Req );
+                break;
+            }
+        }
+        CloseHandle( Connection );
+    }
+}
+
+HANDLE PipeInit() {
+    CommPipe = CreateNamedPipe
+        ( 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;
+}