Reactos
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

at master 534 lines 12 kB view raw
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 15static WCHAR ServiceName[] = L"DHCP"; 16 17SERVICE_STATUS_HANDLE ServiceStatusHandle = 0; 18SERVICE_STATUS ServiceStatus; 19HANDLE hStopEvent = NULL; 20HANDLE hAdapterStateChangedEvent = NULL; 21 22extern SOCKET DhcpSocket; 23 24 25void __RPC_FAR * __RPC_USER MIDL_user_allocate(SIZE_T len) 26{ 27 return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len); 28} 29 30void __RPC_USER MIDL_user_free(void __RPC_FAR * ptr) 31{ 32 HeapFree(GetProcessHeap(), 0, ptr); 33} 34 35handle_t __RPC_USER 36PDHCP_SERVER_NAME_bind( 37 _In_ PDHCP_SERVER_NAME pszServerName) 38{ 39 handle_t hBinding = NULL; 40 LPWSTR pszStringBinding; 41 RPC_STATUS status; 42 43 DPRINT("PDHCP_SERVER_NAME_bind() called\n"); 44 45 status = RpcStringBindingComposeW(NULL, 46 L"ncacn_np", 47 pszServerName, 48 L"\\pipe\\dhcpcsvc", 49 NULL, 50 &pszStringBinding); 51 if (status) 52 { 53 DPRINT1("RpcStringBindingCompose returned 0x%x\n", status); 54 return NULL; 55 } 56 57 /* Set the binding handle that will be used to bind to the server. */ 58 status = RpcBindingFromStringBindingW(pszStringBinding, 59 &hBinding); 60 if (status) 61 { 62 DPRINT1("RpcBindingFromStringBinding returned 0x%x\n", status); 63 } 64 65 status = RpcStringFreeW(&pszStringBinding); 66 if (status) 67 { 68 DPRINT1("RpcStringFree returned 0x%x\n", status); 69 } 70 71 return hBinding; 72} 73 74void __RPC_USER 75PDHCP_SERVER_NAME_unbind( 76 _In_ PDHCP_SERVER_NAME pszServerName, 77 _In_ handle_t hBinding) 78{ 79 RPC_STATUS status; 80 81 DPRINT("PDHCP_SERVER_NAME_unbind() called\n"); 82 83 status = RpcBindingFree(&hBinding); 84 if (status) 85 { 86 DPRINT1("RpcBindingFree returned 0x%x\n", status); 87 } 88} 89 90/*! 91 * Initializes the DHCP interface 92 * 93 * \param[out] Version 94 * Returns the DHCP Interface Version 95 * 96 * \return ERROR_SUCCESS on success 97 * 98 * \remarks DhcpCApiInitialized must be called before any other DHCP Function. 99 */ 100DWORD 101APIENTRY 102DhcpCApiInitialize( 103 _Out_ LPDWORD Version) 104{ 105 *Version = 2; 106 return ERROR_SUCCESS; 107} 108 109/*! 110 * Cleans up the DHCP interface 111 * 112 * \remarks Other DHCP Functions must not be called after DhcpCApiCleanup. 113 */ 114VOID 115APIENTRY 116DhcpCApiCleanup(VOID) 117{ 118} 119 120/*! 121 * Renews a DHCP Lease 122 * 123 * \param[in] AdapterName 124 * Name (GUID) of the Adapter 125 * 126 * \return ERROR_SUCCESS on success 127 * 128 * \remarks Undocumented by Microsoft 129 */ 130DWORD 131APIENTRY 132DhcpAcquireParameters( 133 _In_ PWSTR AdapterName) 134{ 135 DWORD ret; 136 137 DPRINT("DhcpAcquireParameters(%S)\n", AdapterName); 138 139 RpcTryExcept 140 { 141 ret = Client_AcquireParameters(NULL, AdapterName); 142 } 143 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 144 { 145 ret = I_RpcMapWin32Status(RpcExceptionCode()); 146 } 147 RpcEndExcept; 148 149 return ret; 150} 151 152DWORD 153APIENTRY 154DhcpEnumClasses( 155 _In_ DWORD Unknown1, 156 _In_ PWSTR AdapterName, 157 _In_ DWORD Unknown3, 158 _In_ DWORD Unknown4) 159{ 160 DPRINT1("DhcpEnumClasses(%lx %S %lx %lx)\n", 161 Unknown1, AdapterName, Unknown3, Unknown4); 162 return 0; 163} 164 165DWORD 166APIENTRY 167DhcpHandlePnPEvent( 168 _In_ DWORD Unknown1, 169 _In_ DWORD Unknown2, 170 _In_ PWSTR AdapterName, 171 _In_ DWORD Unknown4, 172 _In_ DWORD Unknown5) 173{ 174 DPRINT1("DhcpHandlePnPEvent(%lx %lx %S %lx %lx)\n", 175 Unknown1, Unknown2, AdapterName, Unknown4, Unknown5); 176 return 0; 177} 178 179/*! 180 * Set new TCP/IP parameters and notify DHCP client service of this 181 * 182 * \param[in] ServerName 183 * NULL for local machine 184 * 185 * \param[in] AdapterName 186 * IPHLPAPI name of adapter to change 187 * 188 * \param[in] NewIpAddress 189 * TRUE if IP address changes 190 191 * \param[in] IpIndex 192 * ... 193 * 194 * \param[in] IpAddress 195 * New IP address (network byte order) 196 * 197 * \param[in] SubnetMask 198 * New subnet mask (network byte order) 199 * 200 * \param[in] DhcpAction 201 * 0 - don't modify 202 * 1 - enable DHCP 203 * 2 - disable DHCP 204 * 205 * \return ERROR_SUCCESS on success 206 * 207 * \remarks Undocumented by Microsoft 208 */ 209DWORD 210APIENTRY 211DhcpNotifyConfigChange( 212 _In_ LPWSTR ServerName, 213 _In_ LPWSTR AdapterName, 214 _In_ BOOL NewIpAddress, 215 _In_ DWORD IpIndex, 216 _In_ DWORD IpAddress, 217 _In_ DWORD SubnetMask, 218 _In_ INT DhcpAction) 219{ 220 DPRINT1("DHCPCSVC: DhcpNotifyConfigChange not implemented yet\n"); 221 DPRINT1("DhcpNotifyConfigChange(%S %S %lu %lu %lu %lu %d)\n", 222 ServerName, AdapterName, NewIpAddress, IpIndex, IpAddress, SubnetMask, DhcpAction); 223 224 if (AdapterName == NULL) 225 return ERROR_INVALID_PARAMETER; 226 227 UNIMPLEMENTED; 228 return ERROR_SUCCESS; 229} 230 231DWORD APIENTRY 232DhcpQueryHWInfo(DWORD AdapterIndex, 233 PDWORD MediaType, 234 PDWORD Mtu, 235 PDWORD Speed) 236{ 237 DWORD ret; 238 239 DPRINT("DhcpQueryHWInfo()\n"); 240 241 RpcTryExcept 242 { 243 ret = Client_QueryHWInfo(NULL, AdapterIndex, MediaType, Mtu, Speed); 244 } 245 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 246 { 247 ret = I_RpcMapWin32Status(RpcExceptionCode()); 248 } 249 RpcEndExcept; 250 251 return (ret == ERROR_SUCCESS) ? 1 : 0; 252} 253 254/*! 255 * Releases a DHCP Lease 256 * 257 * \param[in] AdapterName 258 * Name (GUID) of the Adapter 259 * 260 * \return ERROR_SUCCESS on success 261 * 262 * \remarks Undocumented by Microsoft 263 */ 264DWORD 265APIENTRY 266DhcpReleaseParameters( 267 _In_ PWSTR AdapterName) 268{ 269 DWORD ret; 270 271 DPRINT("DhcpReleaseParameters(%S)\n", AdapterName); 272 273 RpcTryExcept 274 { 275 ret = Client_ReleaseParameters(NULL, AdapterName); 276 } 277 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 278 { 279 ret = I_RpcMapWin32Status(RpcExceptionCode()); 280 } 281 RpcEndExcept; 282 283 return ret; 284} 285 286/*! 287 * Removes all DNS Registrations which were added by the DHCP Client 288 * 289 * \return ERROR_SUCCESS on success 290 */ 291DWORD 292WINAPI 293DhcpRemoveDNSRegistrations(VOID) 294{ 295 DWORD ret; 296 297 DPRINT("DhcpRemoveDNSRegistrations()\n"); 298 299 RpcTryExcept 300 { 301 ret = Client_RemoveDNSRegistrations(NULL); 302 } 303 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 304 { 305 ret = I_RpcMapWin32Status(RpcExceptionCode()); 306 } 307 RpcEndExcept; 308 309 return ret; 310} 311 312DWORD 313APIENTRY 314DhcpStaticRefreshParams(DWORD AdapterIndex, 315 DWORD Address, 316 DWORD Netmask) 317{ 318 DWORD ret; 319 320 DPRINT("DhcpStaticRefreshParams()\n"); 321 322 RpcTryExcept 323 { 324 ret = Client_StaticRefreshParams(NULL, AdapterIndex, Address, Netmask); 325 } 326 RpcExcept(EXCEPTION_EXECUTE_HANDLER) 327 { 328 ret = I_RpcMapWin32Status(RpcExceptionCode()); 329 } 330 RpcEndExcept; 331 332 return (ret == ERROR_SUCCESS) ? 1 : 0; 333} 334 335 336DWORD APIENTRY 337DhcpRequestParams(DWORD Flags, 338 PVOID Reserved, 339 LPWSTR AdapterName, 340 LPDHCPCAPI_CLASSID ClassId, 341 DHCPCAPI_PARAMS_ARRAY SendParams, 342 DHCPCAPI_PARAMS_ARRAY RecdParams, 343 LPBYTE Buffer, 344 LPDWORD pSize, 345 LPWSTR RequestIdStr) 346{ 347 UNIMPLEMENTED; 348 return 0; 349} 350 351static VOID 352UpdateServiceStatus(DWORD dwState) 353{ 354 ServiceStatus.dwServiceType = SERVICE_WIN32_SHARE_PROCESS; 355 ServiceStatus.dwCurrentState = dwState; 356 357 if (dwState == SERVICE_RUNNING) 358 ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_SHUTDOWN | SERVICE_ACCEPT_STOP; 359 else 360 ServiceStatus.dwControlsAccepted = 0; 361 362 ServiceStatus.dwWin32ExitCode = 0; 363 ServiceStatus.dwServiceSpecificExitCode = 0; 364 ServiceStatus.dwCheckPoint = 0; 365 366 if (dwState == SERVICE_START_PENDING || 367 dwState == SERVICE_STOP_PENDING) 368 ServiceStatus.dwWaitHint = 1000; 369 else 370 ServiceStatus.dwWaitHint = 0; 371 372 SetServiceStatus(ServiceStatusHandle, 373 &ServiceStatus); 374} 375 376static DWORD WINAPI 377ServiceControlHandler(DWORD dwControl, 378 DWORD dwEventType, 379 LPVOID lpEventData, 380 LPVOID lpContext) 381{ 382 switch (dwControl) 383 { 384 case SERVICE_CONTROL_STOP: 385 case SERVICE_CONTROL_SHUTDOWN: 386 UpdateServiceStatus(SERVICE_STOP_PENDING); 387 if (hStopEvent != NULL) 388 SetEvent(hStopEvent); 389 return ERROR_SUCCESS; 390 391 case SERVICE_CONTROL_INTERROGATE: 392 SetServiceStatus(ServiceStatusHandle, 393 &ServiceStatus); 394 return ERROR_SUCCESS; 395 396 default: 397 return ERROR_CALL_NOT_IMPLEMENTED; 398 } 399} 400 401VOID WINAPI 402ServiceMain(DWORD argc, LPWSTR* argv) 403{ 404 HANDLE hPipeThread = INVALID_HANDLE_VALUE; 405 HANDLE hDiscoveryThread = INVALID_HANDLE_VALUE; 406 DWORD ret; 407 408 ServiceStatusHandle = RegisterServiceCtrlHandlerExW(ServiceName, 409 ServiceControlHandler, 410 NULL); 411 if (!ServiceStatusHandle) 412 { 413 DPRINT1("DHCPCSVC: Unable to register service control handler (%lx)\n", GetLastError()); 414 return; 415 } 416 417 UpdateServiceStatus(SERVICE_START_PENDING); 418 419 /* Create the stop event */ 420 hStopEvent = CreateEventW(NULL, TRUE, FALSE, NULL); 421 if (hStopEvent == NULL) 422 { 423 UpdateServiceStatus(SERVICE_STOPPED); 424 return; 425 } 426 427 hAdapterStateChangedEvent = CreateEvent(NULL, FALSE, FALSE, NULL); 428 if (hAdapterStateChangedEvent == NULL) 429 { 430 CloseHandle(hStopEvent); 431 UpdateServiceStatus(SERVICE_STOPPED); 432 return; 433 } 434 435 UpdateServiceStatus(SERVICE_START_PENDING); 436 437 if (!init_client()) 438 { 439 DbgPrint("DHCPCSVC: init_client() failed!\n"); 440 CloseHandle(hAdapterStateChangedEvent); 441 CloseHandle(hStopEvent); 442 UpdateServiceStatus(SERVICE_STOPPED); 443 return; 444 } 445 446 UpdateServiceStatus(SERVICE_START_PENDING); 447 448 hPipeThread = InitRpc(); 449 if (hPipeThread == INVALID_HANDLE_VALUE) 450 { 451 DbgPrint("DHCPCSVC: PipeInit() failed!\n"); 452 stop_client(); 453 CloseHandle(hAdapterStateChangedEvent); 454 CloseHandle(hStopEvent); 455 UpdateServiceStatus(SERVICE_STOPPED); 456 return; 457 } 458 459 hDiscoveryThread = StartAdapterDiscovery(hStopEvent); 460 if (hDiscoveryThread == INVALID_HANDLE_VALUE) 461 { 462 DbgPrint("DHCPCSVC: StartAdapterDiscovery() failed!\n"); 463 ShutdownRpc(); 464 stop_client(); 465 CloseHandle(hAdapterStateChangedEvent); 466 CloseHandle(hStopEvent); 467 UpdateServiceStatus(SERVICE_STOPPED); 468 return; 469 } 470 471 DH_DbgPrint(MID_TRACE,("DHCP Service Started\n")); 472 473 UpdateServiceStatus(SERVICE_RUNNING); 474 475 DH_DbgPrint(MID_TRACE,("Going into dispatch()\n")); 476 DH_DbgPrint(MID_TRACE,("DHCPCSVC: DHCP service is starting up\n")); 477 478 dispatch(hStopEvent); 479 480 DH_DbgPrint(MID_TRACE,("DHCPCSVC: DHCP service is shutting down\n")); 481 482 ShutdownRpc(); 483 stop_client(); 484 485 DPRINT("Wait for pipe thread to close! %p\n", hPipeThread); 486 if (hPipeThread != INVALID_HANDLE_VALUE) 487 { 488 DPRINT("Waiting for pipe thread\n"); 489 ret = WaitForSingleObject(hPipeThread, 5000); 490 DPRINT("Done %lx\n", ret); 491 } 492 493 DPRINT("Wait for discovery thread to close! %p\n", hDiscoveryThread); 494 if (hDiscoveryThread != INVALID_HANDLE_VALUE) 495 { 496 DPRINT("Waiting for discovery thread\n"); 497 ret = WaitForSingleObject(hDiscoveryThread, 5000); 498 DPRINT("Done %lx\n", ret); 499 } 500 501 DPRINT("Closing events!\n"); 502 CloseHandle(hAdapterStateChangedEvent); 503 CloseHandle(hStopEvent); 504 505 if (DhcpSocket != INVALID_SOCKET) 506 closesocket(DhcpSocket); 507 508 CloseHandle(hDiscoveryThread); 509 CloseHandle(hPipeThread); 510 511 DPRINT("Done!\n"); 512 513 UpdateServiceStatus(SERVICE_STOPPED); 514} 515 516BOOL WINAPI 517DllMain(HINSTANCE hinstDLL, 518 DWORD fdwReason, 519 LPVOID lpvReserved) 520{ 521 switch (fdwReason) 522 { 523 case DLL_PROCESS_ATTACH: 524 DisableThreadLibraryCalls(hinstDLL); 525 break; 526 527 case DLL_PROCESS_DETACH: 528 break; 529 } 530 531 return TRUE; 532} 533 534/* EOF */