sync with trunk r47346
[reactos.git] / dll / win32 / dhcpcsvc / dhcpcsvc.c
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
11 #define NDEBUG
12 #include <debug.h>
13
14 static HANDLE PipeHandle = INVALID_HANDLE_VALUE;
15
16 DWORD APIENTRY DhcpCApiInitialize(LPDWORD Version) {
17 DWORD PipeMode;
18
19 /* Wait for the pipe to be available */
20 if (WaitNamedPipeW(DHCP_PIPE_NAME, NMPWAIT_USE_DEFAULT_WAIT))
21 {
22 /* It's available, let's try to open it */
23 PipeHandle = CreateFileW(DHCP_PIPE_NAME,
24 GENERIC_READ | GENERIC_WRITE,
25 FILE_SHARE_READ | FILE_SHARE_WRITE,
26 NULL,
27 OPEN_EXISTING,
28 0,
29 NULL);
30
31 /* Check if we succeeded in opening the pipe */
32 if (PipeHandle == INVALID_HANDLE_VALUE)
33 {
34 /* We didn't */
35 return GetLastError();
36 }
37 else
38 {
39 /* Change the pipe into message mode */
40 PipeMode = PIPE_READMODE_MESSAGE;
41 if (!SetNamedPipeHandleState(PipeHandle, &PipeMode, NULL, NULL))
42 {
43 /* Mode change failed */
44 CloseHandle(PipeHandle);
45 PipeHandle = INVALID_HANDLE_VALUE;
46 return GetLastError();
47 }
48 else
49 {
50 /* We're good to go */
51 *Version = 2;
52 return NO_ERROR;
53 }
54 }
55 }
56 else
57 {
58 /* No good, we failed */
59 return GetLastError();
60 }
61 }
62
63 VOID APIENTRY DhcpCApiCleanup() {
64 CloseHandle(PipeHandle);
65 PipeHandle = INVALID_HANDLE_VALUE;
66 }
67
68 DWORD APIENTRY DhcpQueryHWInfo( DWORD AdapterIndex,
69 PDWORD MediaType,
70 PDWORD Mtu,
71 PDWORD Speed ) {
72 COMM_DHCP_REQ Req;
73 COMM_DHCP_REPLY Reply;
74 DWORD BytesRead;
75 BOOL Result;
76
77 ASSERT(PipeHandle != INVALID_HANDLE_VALUE);
78
79 Req.Type = DhcpReqQueryHWInfo;
80 Req.AdapterIndex = AdapterIndex;
81
82 Result = TransactNamedPipe(PipeHandle,
83 &Req, sizeof(Req),
84 &Reply, sizeof(Reply),
85 &BytesRead, NULL);
86 if (!Result)
87 {
88 /* Pipe transaction failed */
89 return 0;
90 }
91
92 if( !Reply.Reply ) return 0;
93 else {
94 *MediaType = Reply.QueryHWInfo.MediaType;
95 *Mtu = Reply.QueryHWInfo.Mtu;
96 *Speed = Reply.QueryHWInfo.Speed;
97 return 1;
98 }
99 }
100
101 DWORD APIENTRY DhcpLeaseIpAddress( DWORD AdapterIndex ) {
102 COMM_DHCP_REQ Req;
103 COMM_DHCP_REPLY Reply;
104 DWORD BytesRead;
105 BOOL Result;
106
107 ASSERT(PipeHandle != INVALID_HANDLE_VALUE);
108
109 Req.Type = DhcpReqLeaseIpAddress;
110 Req.AdapterIndex = AdapterIndex;
111
112 Result = TransactNamedPipe(PipeHandle,
113 &Req, sizeof(Req),
114 &Reply, sizeof(Reply),
115 &BytesRead, NULL);
116 if (!Result)
117 {
118 /* Pipe transaction failed */
119 return 0;
120 }
121
122 return Reply.Reply;
123 }
124
125 DWORD APIENTRY DhcpReleaseIpAddressLease( DWORD AdapterIndex ) {
126 COMM_DHCP_REQ Req;
127 COMM_DHCP_REPLY Reply;
128 DWORD BytesRead;
129 BOOL Result;
130
131 ASSERT(PipeHandle != INVALID_HANDLE_VALUE);
132
133 Req.Type = DhcpReqReleaseIpAddress;
134 Req.AdapterIndex = AdapterIndex;
135
136 Result = TransactNamedPipe(PipeHandle,
137 &Req, sizeof(Req),
138 &Reply, sizeof(Reply),
139 &BytesRead, NULL);
140 if (!Result)
141 {
142 /* Pipe transaction failed */
143 return 0;
144 }
145
146 return Reply.Reply;
147 }
148
149 DWORD APIENTRY DhcpRenewIpAddressLease( DWORD AdapterIndex ) {
150 COMM_DHCP_REQ Req;
151 COMM_DHCP_REPLY Reply;
152 DWORD BytesRead;
153 BOOL Result;
154
155 ASSERT(PipeHandle != INVALID_HANDLE_VALUE);
156
157 Req.Type = DhcpReqRenewIpAddress;
158 Req.AdapterIndex = AdapterIndex;
159
160 Result = TransactNamedPipe(PipeHandle,
161 &Req, sizeof(Req),
162 &Reply, sizeof(Reply),
163 &BytesRead, NULL);
164 if (!Result)
165 {
166 /* Pipe transaction failed */
167 return 0;
168 }
169
170 return Reply.Reply;
171 }
172
173 DWORD APIENTRY DhcpStaticRefreshParams( DWORD AdapterIndex,
174 DWORD Address,
175 DWORD Netmask ) {
176 COMM_DHCP_REQ Req;
177 COMM_DHCP_REPLY Reply;
178 DWORD BytesRead;
179 BOOL Result;
180
181 ASSERT(PipeHandle != INVALID_HANDLE_VALUE);
182
183 Req.Type = DhcpReqStaticRefreshParams;
184 Req.AdapterIndex = AdapterIndex;
185 Req.Body.StaticRefreshParams.IPAddress = Address;
186 Req.Body.StaticRefreshParams.Netmask = Netmask;
187
188 Result = TransactNamedPipe(PipeHandle,
189 &Req, sizeof(Req),
190 &Reply, sizeof(Reply),
191 &BytesRead, NULL);
192 if (!Result)
193 {
194 /* Pipe transaction failed */
195 return 0;
196 }
197
198 return Reply.Reply;
199 }
200
201 /*!
202 * Set new TCP/IP parameters and notify DHCP client service of this
203 *
204 * \param[in] ServerName
205 * NULL for local machine
206 *
207 * \param[in] AdapterName
208 * IPHLPAPI name of adapter to change
209 *
210 * \param[in] NewIpAddress
211 * TRUE if IP address changes
212 *
213 * \param[in] IpAddress
214 * New IP address (network byte order)
215 *
216 * \param[in] SubnetMask
217 * New subnet mask (network byte order)
218 *
219 * \param[in] DhcpAction
220 * 0 - don't modify
221 * 1 - enable DHCP
222 * 2 - disable DHCP
223 *
224 * \return non-zero on success
225 *
226 * \remarks Undocumented by Microsoft
227 */
228 DWORD APIENTRY
229 DhcpNotifyConfigChange(LPWSTR ServerName,
230 LPWSTR AdapterName,
231 BOOL NewIpAddress,
232 DWORD IpIndex,
233 DWORD IpAddress,
234 DWORD SubnetMask,
235 int DhcpAction)
236 {
237 DbgPrint("DHCPCSVC: DhcpNotifyConfigChange not implemented yet\n");
238 return 0;
239 }
240
241 /*!
242 * Get DHCP info for an adapter
243 *
244 * \param[in] AdapterIndex
245 * Index of the adapter (iphlpapi-style) for which info is
246 * requested
247 *
248 * \param[out] DhcpEnabled
249 * Returns whether DHCP is enabled for the adapter
250 *
251 * \param[out] DhcpServer
252 * Returns DHCP server IP address (255.255.255.255 if no
253 * server reached yet), in network byte order
254 *
255 * \param[out] LeaseObtained
256 * Returns time at which the lease was obtained
257 *
258 * \param[out] LeaseExpires
259 * Returns time at which the lease will expire
260 *
261 * \return non-zero on success
262 *
263 * \remarks This is a ReactOS-only routine
264 */
265 DWORD APIENTRY DhcpRosGetAdapterInfo( DWORD AdapterIndex,
266 PBOOL DhcpEnabled,
267 PDWORD DhcpServer,
268 time_t *LeaseObtained,
269 time_t *LeaseExpires )
270 {
271 COMM_DHCP_REQ Req;
272 COMM_DHCP_REPLY Reply;
273 DWORD BytesRead;
274 BOOL Result;
275
276 ASSERT(PipeHandle != INVALID_HANDLE_VALUE);
277
278 Req.Type = DhcpReqGetAdapterInfo;
279 Req.AdapterIndex = AdapterIndex;
280
281 Result = TransactNamedPipe(PipeHandle,
282 &Req, sizeof(Req),
283 &Reply, sizeof(Reply),
284 &BytesRead, NULL);
285
286 if ( 0 != Result && 0 != Reply.Reply ) {
287 *DhcpEnabled = Reply.GetAdapterInfo.DhcpEnabled;
288 } else {
289 *DhcpEnabled = FALSE;
290 }
291 if ( *DhcpEnabled ) {
292 *DhcpServer = Reply.GetAdapterInfo.DhcpServer;
293 *LeaseObtained = Reply.GetAdapterInfo.LeaseObtained;
294 *LeaseExpires = Reply.GetAdapterInfo.LeaseExpires;
295 } else {
296 *DhcpServer = INADDR_NONE;
297 *LeaseObtained = 0;
298 *LeaseExpires = 0;
299 }
300
301 return Reply.Reply;
302 }
303
304 INT WINAPI
305 DllMain(PVOID hinstDll,
306 ULONG dwReason,
307 PVOID reserved)
308 {
309 switch (dwReason)
310 {
311 case DLL_PROCESS_ATTACH:
312 DisableThreadLibraryCalls(hinstDll);
313 break;
314
315 case DLL_PROCESS_DETACH:
316 break;
317 }
318
319 return TRUE;
320 }
321
322 /* EOF */