ReactOS  0.4.15-dev-3295-gaa8fc87
dhcpcsvc.c
Go to the documentation of this file.
1 /*
2  * COPYRIGHT: See COPYING in the top level directory
3  * PROJECT: ReactOS system libraries
4  * FILE: lib/dhcpcapi/dhcpcapi.c
5  * PURPOSE: Client API for DHCP
6  * COPYRIGHT: Copyright 2005 Art Yerkes <ayerkes@speakeasy.net>
7  */
8 
9 #include <rosdhcp.h>
10 #include <winsvc.h>
11 
12 #define NDEBUG
13 #include <debug.h>
14 
15 static WCHAR ServiceName[] = L"DHCP";
16 
21 
23 extern SOCKET DhcpSocket;
24 
27 {
28  DWORD PipeMode;
29 
30  /* Wait for the pipe to be available */
32  {
33  /* No good, we failed */
34  return GetLastError();
35  }
36 
37  /* It's available, let's try to open it */
41  NULL,
43  0,
44  NULL);
45 
46  /* Check if we succeeded in opening the pipe */
48  {
49  /* We didn't */
50  return GetLastError();
51  }
52 
53  /* Change the pipe into message mode */
54  PipeMode = PIPE_READMODE_MESSAGE;
55  if (!SetNamedPipeHandleState(PipeHandle, &PipeMode, NULL, NULL))
56  {
57  /* Mode change failed */
60  return GetLastError();
61  }
62  else
63  {
64  /* We're good to go */
65  *Version = 2;
66  return NO_ERROR;
67  }
68 }
69 
72 {
75 }
76 
78 DhcpQueryHWInfo(DWORD AdapterIndex,
79  PDWORD MediaType,
80  PDWORD Mtu,
81  PDWORD Speed)
82 {
83  COMM_DHCP_REQ Req;
84  COMM_DHCP_REPLY Reply;
86  BOOL Result;
87 
89 
91  Req.AdapterIndex = AdapterIndex;
92 
94  &Req, sizeof(Req),
95  &Reply, sizeof(Reply),
96  &BytesRead, NULL);
97  if (!Result)
98  {
99  /* Pipe transaction failed */
100  return 0;
101  }
102 
103  if (Reply.Reply == 0)
104  return 0;
105 
106  *MediaType = Reply.QueryHWInfo.MediaType;
107  *Mtu = Reply.QueryHWInfo.Mtu;
108  *Speed = Reply.QueryHWInfo.Speed;
109  return 1;
110 }
111 
114 {
115  COMM_DHCP_REQ Req;
116  COMM_DHCP_REPLY Reply;
118  BOOL Result;
119 
121 
123  Req.AdapterIndex = AdapterIndex;
124 
126  &Req, sizeof(Req),
127  &Reply, sizeof(Reply),
128  &BytesRead, NULL);
129  if (!Result)
130  {
131  /* Pipe transaction failed */
132  return 0;
133  }
134 
135  return Reply.Reply;
136 }
137 
140 {
141  COMM_DHCP_REQ Req;
142  COMM_DHCP_REPLY Reply;
144  BOOL Result;
145 
147 
149  Req.AdapterIndex = AdapterIndex;
150 
152  &Req, sizeof(Req),
153  &Reply, sizeof(Reply),
154  &BytesRead, NULL);
155  if (!Result)
156  {
157  /* Pipe transaction failed */
158  return 0;
159  }
160 
161  return Reply.Reply;
162 }
163 
166 {
167  COMM_DHCP_REQ Req;
168  COMM_DHCP_REPLY Reply;
170  BOOL Result;
171 
173 
175  Req.AdapterIndex = AdapterIndex;
176 
178  &Req, sizeof(Req),
179  &Reply, sizeof(Reply),
180  &BytesRead, NULL);
181  if (!Result)
182  {
183  /* Pipe transaction failed */
184  return 0;
185  }
186 
187  return Reply.Reply;
188 }
189 
192  DWORD Address,
193  DWORD Netmask)
194 {
195  COMM_DHCP_REQ Req;
196  COMM_DHCP_REPLY Reply;
198  BOOL Result;
199 
201 
203  Req.AdapterIndex = AdapterIndex;
204  Req.Body.StaticRefreshParams.IPAddress = Address;
205  Req.Body.StaticRefreshParams.Netmask = Netmask;
206 
208  &Req, sizeof(Req),
209  &Reply, sizeof(Reply),
210  &BytesRead, NULL);
211  if (!Result)
212  {
213  /* Pipe transaction failed */
214  return 0;
215  }
216 
217  return Reply.Reply;
218 }
219 
250  BOOL NewIpAddress,
251  DWORD IpIndex,
252  DWORD IpAddress,
253  DWORD SubnetMask,
254  INT DhcpAction)
255 {
256  DPRINT1("DHCPCSVC: DhcpNotifyConfigChange not implemented yet\n");
257  return 0;
258 }
259 
262  PVOID Reserved,
264  LPDHCPCAPI_CLASSID ClassId,
265  DHCPCAPI_PARAMS_ARRAY SendParams,
266  DHCPCAPI_PARAMS_ARRAY RecdParams,
267  LPBYTE Buffer,
268  LPDWORD pSize,
269  LPWSTR RequestIdStr)
270 {
272  return 0;
273 }
274 
301  PBOOL DhcpEnabled,
302  PDWORD DhcpServer,
303  time_t* LeaseObtained,
304  time_t* LeaseExpires)
305 {
306  COMM_DHCP_REQ Req;
307  COMM_DHCP_REPLY Reply;
309  BOOL Result;
310 
312 
314  Req.AdapterIndex = AdapterIndex;
315 
317  &Req, sizeof(Req),
318  &Reply, sizeof(Reply),
319  &BytesRead, NULL);
320 
321  if (Result && Reply.Reply != 0)
322  *DhcpEnabled = Reply.GetAdapterInfo.DhcpEnabled;
323  else
324  *DhcpEnabled = FALSE;
325 
326  if (*DhcpEnabled)
327  {
328  *DhcpServer = Reply.GetAdapterInfo.DhcpServer;
329  *LeaseObtained = Reply.GetAdapterInfo.LeaseObtained;
330  *LeaseExpires = Reply.GetAdapterInfo.LeaseExpires;
331  }
332  else
333  {
334  *DhcpServer = INADDR_NONE;
335  *LeaseObtained = 0;
336  *LeaseExpires = 0;
337  }
338 
339  return Reply.Reply;
340 }
341 
342 
343 static VOID
345 {
347  ServiceStatus.dwCurrentState = dwState;
348 
349  if (dwState == SERVICE_RUNNING)
351  else
353 
357 
358  if (dwState == SERVICE_START_PENDING ||
359  dwState == SERVICE_STOP_PENDING)
360  ServiceStatus.dwWaitHint = 1000;
361  else
363 
365  &ServiceStatus);
366 }
367 
368 static DWORD WINAPI
370  DWORD dwEventType,
371  LPVOID lpEventData,
372  LPVOID lpContext)
373 {
374  switch (dwControl)
375  {
379  if (hStopEvent != NULL)
381  return ERROR_SUCCESS;
382 
385  &ServiceStatus);
386  return ERROR_SUCCESS;
387 
388  default:
390  }
391 }
392 
393 VOID WINAPI
395 {
396  HANDLE hPipeThread = INVALID_HANDLE_VALUE;
397  HANDLE hDiscoveryThread = INVALID_HANDLE_VALUE;
398  DWORD ret;
399 
402  NULL);
403  if (!ServiceStatusHandle)
404  {
405  DPRINT1("DHCPCSVC: Unable to register service control handler (%lx)\n", GetLastError());
406  return;
407  }
408 
410 
411  /* Create the stop event */
413  if (hStopEvent == NULL)
414  {
416  return;
417  }
418 
421  {
424  return;
425  }
426 
428 
429  if (!init_client())
430  {
431  DbgPrint("DHCPCSVC: init_client() failed!\n");
435  return;
436  }
437 
439 
440  hPipeThread = PipeInit(hStopEvent);
441  if (hPipeThread == INVALID_HANDLE_VALUE)
442  {
443  DbgPrint("DHCPCSVC: PipeInit() failed!\n");
444  stop_client();
448  return;
449  }
450 
451  hDiscoveryThread = StartAdapterDiscovery(hStopEvent);
452  if (hDiscoveryThread == INVALID_HANDLE_VALUE)
453  {
454  DbgPrint("DHCPCSVC: StartAdapterDiscovery() failed!\n");
455  stop_client();
459  return;
460  }
461 
462  DH_DbgPrint(MID_TRACE,("DHCP Service Started\n"));
463 
465 
466  DH_DbgPrint(MID_TRACE,("Going into dispatch()\n"));
467  DH_DbgPrint(MID_TRACE,("DHCPCSVC: DHCP service is starting up\n"));
468 
470 
471  DH_DbgPrint(MID_TRACE,("DHCPCSVC: DHCP service is shutting down\n"));
472 
473  stop_client();
474 
475  DPRINT("Wait for pipe thread to close! %p\n", hPipeThread);
476  if (hPipeThread != INVALID_HANDLE_VALUE)
477  {
478  DPRINT("Waiting for pipe thread\n");
479  ret = WaitForSingleObject(hPipeThread, 5000);
480  DPRINT("Done %lx\n", ret);
481  }
482 
483  DPRINT("Wait for discovery thread to close! %p\n", hDiscoveryThread);
484  if (hDiscoveryThread != INVALID_HANDLE_VALUE)
485  {
486  DPRINT("Waiting for discovery thread\n");
487  ret = WaitForSingleObject(hDiscoveryThread, 5000);
488  DPRINT("Done %lx\n", ret);
489  }
490 
491  DPRINT("Closing events!\n");
494 
495  if (DhcpSocket != INVALID_SOCKET)
497 
498  CloseHandle(hDiscoveryThread);
499  CloseHandle(hPipeThread);
500 
501  DPRINT("Done!\n");
502 
504 }
505 
506 BOOL WINAPI
508  DWORD fdwReason,
510 {
511  switch (fdwReason)
512  {
513  case DLL_PROCESS_ATTACH:
514  DisableThreadLibraryCalls(hinstDLL);
515  break;
516 
517  case DLL_PROCESS_DETACH:
518  break;
519  }
520 
521  return TRUE;
522 }
523 
524 /* EOF */
#define CreateEvent
Definition: winbase.h:3604
static int argc
Definition: ServiceArgs.c:12
#define CloseHandle
Definition: compat.h:598
#define MID_TRACE
Definition: debug.h:15
#define ERROR_SUCCESS
Definition: deptool.c:10
DWORD dwCurrentState
Definition: winsvc.h:100
#define DbgPrint
Definition: hal.h:12
static DWORD WINAPI ServiceControlHandler(DWORD dwControl, DWORD dwEventType, LPVOID lpEventData, LPVOID lpContext)
Definition: dhcpcsvc.c:369
struct _COMM_DHCP_REPLY::@3367 QueryHWInfo
#define TRUE
Definition: types.h:120
HANDLE StartAdapterDiscovery(HANDLE hStopEvent)
Definition: adapter.c:481
SERVICE_STATUS_HANDLE ServiceStatusHandle
Definition: dhcpcsvc.c:17
DWORD APIENTRY DhcpReleaseIpAddressLease(DWORD AdapterIndex)
Definition: dhcpcsvc.c:139
BOOL WINAPI WaitNamedPipeW(LPCWSTR lpNamedPipeName, DWORD nTimeOut)
Definition: npipe.c:458
#define INADDR_NONE
Definition: tcp.c:42
#define SERVICE_ACCEPT_STOP
Definition: winsvc.h:28
BOOL WINAPI DisableThreadLibraryCalls(IN HMODULE hLibModule)
Definition: loader.c:85
static WCHAR ServiceName[]
Definition: dhcpcsvc.c:15
#define INVALID_HANDLE_VALUE
Definition: compat.h:590
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:733
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1040
#define SERVICE_START_PENDING
Definition: winsvc.h:22
DWORD dwServiceSpecificExitCode
Definition: winsvc.h:103
DWORD APIENTRY DhcpQueryHWInfo(DWORD AdapterIndex, PDWORD MediaType, PDWORD Mtu, PDWORD Speed)
Definition: dhcpcsvc.c:78
#define closesocket
Definition: ncftp.h:477
#define DLL_PROCESS_ATTACH
Definition: compat.h:131
#define NMPWAIT_USE_DEFAULT_WAIT
Definition: winbase.h:134
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
Definition: dhcpcsvc.c:507
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
#define argv
Definition: mplay32.c:18
#define NO_ERROR
Definition: dderror.h:5
int32_t INT
Definition: typedefs.h:58
static VOID UpdateServiceStatus(DWORD dwState)
Definition: dhcpcsvc.c:344
static IN DWORD IN LPVOID lpvReserved
#define FILE_SHARE_READ
Definition: compat.h:136
HANDLE WINAPI DECLSPEC_HOTPATCH CreateEventW(IN LPSECURITY_ATTRIBUTES lpEventAttributes OPTIONAL, IN BOOL bManualReset, IN BOOL bInitialState, IN LPCWSTR lpName OPTIONAL)
Definition: synch.c:651
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_opt_ PWDF_MEMORY_DESCRIPTOR _In_opt_ PLONGLONG _In_opt_ PWDF_REQUEST_SEND_OPTIONS _Out_opt_ PULONG_PTR BytesRead
Definition: wdfiotarget.h:859
VOID WINAPI ServiceMain(DWORD argc, LPWSTR *argv)
Definition: dhcpcsvc.c:394
DWORD APIENTRY DhcpNotifyConfigChange(LPWSTR ServerName, LPWSTR AdapterName, BOOL NewIpAddress, DWORD IpIndex, DWORD IpAddress, DWORD SubnetMask, INT DhcpAction)
Definition: dhcpcsvc.c:248
BOOL WINAPI SetServiceStatus(SERVICE_STATUS_HANDLE hServiceStatus, LPSERVICE_STATUS lpServiceStatus)
Definition: sctrl.c:997
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
DWORD dwCheckPoint
Definition: winsvc.h:104
SOCKET DhcpSocket
Definition: adapter.c:8
#define SERVICE_STOPPED
Definition: winsvc.h:21
DWORD APIENTRY DhcpLeaseIpAddress(DWORD AdapterIndex)
Definition: dhcpcsvc.c:113
void stop_client(void)
Definition: dhclient.c:129
unsigned char * LPBYTE
Definition: typedefs.h:53
#define FALSE
Definition: types.h:117
unsigned int BOOL
Definition: ntddk_ex.h:94
HANDLE hStopEvent
Definition: dhcpcsvc.c:19
#define GENERIC_WRITE
Definition: nt_native.h:90
#define SERVICE_RUNNING
Definition: winsvc.h:24
static WCHAR Address[46]
Definition: ping.c:68
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:426
#define DH_DbgPrint(_t_, _x_)
Definition: debug.h:49
_Reserved_ PVOID Reserved
Definition: winddi.h:3974
#define SERVICE_CONTROL_INTERROGATE
Definition: winsvc.h:39
Definition: bufpool.h:45
#define SERVICE_WIN32_OWN_PROCESS
Definition: cmtypes.h:962
BOOL * PBOOL
Definition: windef.h:161
#define OPEN_EXISTING
Definition: compat.h:634
#define DLL_PROCESS_DETACH
Definition: compat.h:130
static SERVICE_STATUS_HANDLE(WINAPI *pRegisterServiceCtrlHandlerExA)(LPCSTR
#define SERVICE_ACCEPT_SHUTDOWN
Definition: winsvc.h:30
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
#define INVALID_SOCKET
Definition: winsock.h:332
BOOL WINAPI SetNamedPipeHandleState(HANDLE hNamedPipe, LPDWORD lpMode, LPDWORD lpMaxCollectionCount, LPDWORD lpCollectDataTimeout)
Definition: npipe.c:774
#define ASSERT(a)
Definition: mode.c:44
__wchar_t WCHAR
Definition: xmlstorage.h:180
DWORD dwWaitHint
Definition: winsvc.h:105
#define WINAPI
Definition: msvc.h:6
DWORD dwWin32ExitCode
Definition: winsvc.h:102
unsigned long DWORD
Definition: ntddk_ex.h:95
HANDLE PipeInit(HANDLE hStopEvent)
Definition: pipe.c:171
DWORD dwServiceType
Definition: winsvc.h:99
IN PVOID IN PVOID IN USHORT Version
Definition: pci.h:361
DWORD APIENTRY DhcpStaticRefreshParams(DWORD AdapterIndex, DWORD Address, DWORD Netmask)
Definition: dhcpcsvc.c:191
HANDLE hAdapterStateChangedEvent
Definition: dhcpcsvc.c:20
int ret
static const WCHAR L[]
Definition: oid.c:1250
DWORD APIENTRY DhcpCApiInitialize(LPDWORD Version)
Definition: dhcpcsvc.c:26
#define GENERIC_READ
Definition: compat.h:135
SERVICE_STATUS_HANDLE WINAPI RegisterServiceCtrlHandlerExW(LPCWSTR lpServiceName, LPHANDLER_FUNCTION_EX lpHandlerProc, LPVOID lpContext)
Definition: sctrl.c:812
BOOL WINAPI TransactNamedPipe(IN HANDLE hNamedPipe, IN LPVOID lpInBuffer, IN DWORD nInBufferSize, OUT LPVOID lpOutBuffer, IN DWORD nOutBufferSize, OUT LPDWORD lpBytesRead OPTIONAL, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: npipe.c:1315
void dispatch(HANDLE hStopEvent)
Definition: dispatch.c:70
#define PIPE_READMODE_MESSAGE
Definition: winbase.h:170
DWORD dwControlsAccepted
Definition: winsvc.h:101
#define DHCP_PIPE_NAME
__kernel_time_t time_t
Definition: linux.h:252
int init_client(void)
Definition: dhclient.c:111
struct _COMM_DHCP_REQ::@3362::@3366 StaticRefreshParams
static HANDLE PipeHandle
Definition: dhcpcsvc.c:22
#define NULL
Definition: types.h:112
DWORD * PDWORD
Definition: pedump.c:68
#define DPRINT1
Definition: precomp.h:8
#define CreateFileW
Definition: compat.h:600
SERVICE_STATUS ServiceStatus
Definition: dhcpcsvc.c:18
DWORD APIENTRY DhcpRosGetAdapterInfo(DWORD AdapterIndex, PBOOL DhcpEnabled, PDWORD DhcpServer, time_t *LeaseObtained, time_t *LeaseExpires)
Definition: dhcpcsvc.c:300
uint32_t * LPDWORD
Definition: typedefs.h:59
DWORD APIENTRY DhcpRenewIpAddressLease(DWORD AdapterIndex)
Definition: dhcpcsvc.c:165
#define ERROR_CALL_NOT_IMPLEMENTED
Definition: compat.h:102
#define UNIMPLEMENTED
Definition: debug.h:115
#define SERVICE_CONTROL_STOP
Definition: winsvc.h:36
UINT_PTR SOCKET
Definition: winsock.h:47
struct _COMM_DHCP_REPLY::@3368 GetAdapterInfo
#define DPRINT
Definition: sndvol32.h:71
WCHAR * LPWSTR
Definition: xmlstorage.h:184
_Must_inspect_result_ _Out_ PNDIS_STATUS _Out_ PNDIS_STATUS _Out_ PNDIS_HANDLE _Out_ PUINT _In_ UINT _In_ NDIS_HANDLE _In_ NDIS_HANDLE _In_ PNDIS_STRING AdapterName
Definition: ndis.h:6013
union _COMM_DHCP_REQ::@3362 Body
#define SERVICE_STOP_PENDING
Definition: winsvc.h:23
#define APIENTRY
Definition: api.h:79
VOID APIENTRY DhcpCApiCleanup(VOID)
Definition: dhcpcsvc.c:71
DWORD APIENTRY DhcpRequestParams(DWORD Flags, PVOID Reserved, LPWSTR AdapterName, LPDHCPCAPI_CLASSID ClassId, DHCPCAPI_PARAMS_ARRAY SendParams, DHCPCAPI_PARAMS_ARRAY RecdParams, LPBYTE Buffer, LPDWORD pSize, LPWSTR RequestIdStr)
Definition: dhcpcsvc.c:261
#define SERVICE_CONTROL_SHUTDOWN
Definition: winsvc.h:40