From 10092f846609576814df40c5770dbc4e0aba2de2 Mon Sep 17 00:00:00 2001 From: Eric Kohl Date: Tue, 7 Apr 2026 00:55:32 +0200 Subject: [PATCH] [DHCPCSVC] Load and update the alternate configuration data --- base/services/dhcpcsvc/dhcp/adapter.c | 116 ++++++++++++++++++++++- base/services/dhcpcsvc/dhcp/api.c | 14 ++- base/services/dhcpcsvc/include/rosdhcp.h | 15 ++- 3 files changed, 139 insertions(+), 6 deletions(-) diff --git a/base/services/dhcpcsvc/dhcp/adapter.c b/base/services/dhcpcsvc/dhcp/adapter.c index 727a27625c1..2cef7cb828c 100644 --- a/base/services/dhcpcsvc/dhcp/adapter.c +++ b/base/services/dhcpcsvc/dhcp/adapter.c @@ -150,6 +150,101 @@ cleanup: return OutKey; } +DWORD +LoadAlternateConfiguration( + PDHCP_ADAPTER Adapter, + HKEY hAdapterKey) +{ + PWSTR pszConfigName = NULL; + HKEY hConfigsKey = NULL, hConfigKey = NULL; + PALTERNATE_CONFIGURATION pAltConfig = NULL; + DWORD dwSize; + DWORD dwError; + + DPRINT("LoadAlternateConfiguration()\n"); + + dwSize = 0; + RegQueryValueExW(hAdapterKey, L"ActiveConfigurations", NULL, NULL, NULL, &dwSize); + if (dwSize == 0) + { + DPRINT1("There is no active configuration!\n"); + return ERROR_SUCCESS; + } + + pszConfigName = malloc(dwSize); + if (pszConfigName == NULL) + { + DPRINT1("Failed to allocate memory!\n"); + return ERROR_NOT_ENOUGH_MEMORY; + } + + dwError = RegQueryValueExW(hAdapterKey, L"ActiveConfigurations", NULL, NULL, (PBYTE)pszConfigName, &dwSize); + if (dwError != ERROR_SUCCESS) + { + DPRINT1("Failed to read the ActiveConfigurations value!\n"); + goto done; + } + + DPRINT("ActiveConfigurations: %S\n", pszConfigName); + + dwError = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"System\\CurrentControlSet\\Services\\DHCP\\Configurations", 0, KEY_READ, &hConfigsKey); + if (dwError != ERROR_SUCCESS) + { + DPRINT1("Failed to open configurations key!\n"); + goto done; + } + + dwError = RegOpenKeyExW(hConfigsKey, pszConfigName, 0, KEY_READ, &hConfigKey); + if (dwError != ERROR_SUCCESS) + { + DPRINT1("Failed to open configuration key %S!\n", pszConfigName); + goto done; + } + + dwSize = 0; + RegQueryValueExW(hConfigKey, L"Options", NULL, NULL, NULL, &dwSize); + + DbgPrint("Found alternate configuration: Size %lu\n", dwSize); + pAltConfig = malloc(dwSize); + if (pAltConfig == NULL) + { + DPRINT1("Failed to allocate memory!\n"); + dwError = ERROR_NOT_ENOUGH_MEMORY; + goto done; + } + + dwError = RegQueryValueExW(hConfigKey, L"Options", NULL, NULL, (PBYTE)pAltConfig, &dwSize); + if (dwError != ERROR_SUCCESS) + { + DPRINT1("Failed to read the alternate configuration!\n"); + goto done; + } + + DPRINT("IpAddress: %08lx\n", pAltConfig->IpAddress); + DPRINT("SubnetMask: %08lx\n", pAltConfig->SubnetMask); + + Adapter->AlternateConfiguration = pAltConfig; + DPRINT("Success!\n"); + +done: + if (dwError != ERROR_SUCCESS) + { + if (pAltConfig) + free(pAltConfig); + } + + if (hConfigKey) + RegCloseKey(hConfigKey); + + if (hConfigsKey) + RegCloseKey(hConfigsKey); + + if (pszConfigName) + free(pszConfigName); + + return dwError; +} + BOOL PrepareAdapterForService( PDHCP_ADAPTER Adapter ) { HKEY AdapterKey; DWORD Error = ERROR_SUCCESS, DhcpEnabled, Length = sizeof(DWORD); @@ -166,6 +261,8 @@ BOOL PrepareAdapterForService( PDHCP_ADAPTER Adapter ) { if (Error != ERROR_SUCCESS || Length != sizeof(DWORD)) DhcpEnabled = 1; + LoadAlternateConfiguration(Adapter, AdapterKey); + CloseHandle(AdapterKey); } else @@ -183,7 +280,7 @@ BOOL PrepareAdapterForService( PDHCP_ADAPTER Adapter ) { /* Automatic case */ DbgPrint("DHCPCSVC: Adapter Name: [%s] (dynamic)\n", Adapter->DhclientInfo.name); - Adapter->DhclientInfo.client->state = S_INIT; + Adapter->DhclientInfo.client->state = S_INIT; } return TRUE; @@ -285,6 +382,17 @@ IsReconnectHackNeeded(PDHCP_ADAPTER Adapter, const MIB_IFROW* IfEntry) } } +VOID +FreeAdapter( + PDHCP_ADAPTER Adapter) +{ + if (Adapter == NULL) + return; + if (Adapter->AlternateConfiguration) + free(Adapter->AlternateConfiguration); + free(Adapter); +} + /* * XXX Figure out the way to bind a specific adapter to a socket. */ @@ -452,8 +560,8 @@ DWORD WINAPI AdapterDiscoveryThread(LPVOID Context) { AdapterCount++; SetEvent(hAdapterStateChangedEvent); ApiUnlock(); - } else { free( Adapter ); Adapter = 0; } - } else { free( Adapter ); Adapter = 0; } + } else { FreeAdapter( Adapter ); Adapter = 0; } + } else { FreeAdapter( Adapter ); Adapter = 0; } if( !Adapter ) DH_DbgPrint(MID_TRACE,("Adapter %d was rejected\n", @@ -491,7 +599,7 @@ void AdapterStop() { while( !IsListEmpty( &AdapterList ) ) { ListEntry = (PLIST_ENTRY)RemoveHeadList( &AdapterList ); Adapter = CONTAINING_RECORD( ListEntry, DHCP_ADAPTER, ListEntry ); - free( Adapter ); + FreeAdapter( Adapter ); } ApiUnlock(); WSACleanup(); diff --git a/base/services/dhcpcsvc/dhcp/api.c b/base/services/dhcpcsvc/dhcp/api.c index 933ff83abdc..14942b31d66 100644 --- a/base/services/dhcpcsvc/dhcp/api.c +++ b/base/services/dhcpcsvc/dhcp/api.c @@ -167,6 +167,7 @@ Server_FallbackRefreshParams( _In_ LPWSTR AdapterName) { PDHCP_ADAPTER Adapter; + HKEY hAdapterKey; DWORD ret = ERROR_SUCCESS; DPRINT("Server_FallbackRefreshParams(%S)\n", AdapterName); @@ -182,7 +183,18 @@ Server_FallbackRefreshParams( DPRINT("Adapter: %p\n", Adapter); - /* FIXME */ + if (Adapter->AlternateConfiguration) + { + free(Adapter->AlternateConfiguration); + Adapter->AlternateConfiguration = NULL; + } + + hAdapterKey = FindAdapterKey(Adapter); + if (hAdapterKey) + { + ret = LoadAlternateConfiguration(Adapter, hAdapterKey); + RegCloseKey(hAdapterKey); + } done: ApiUnlock(); diff --git a/base/services/dhcpcsvc/include/rosdhcp.h b/base/services/dhcpcsvc/include/rosdhcp.h index 26714604426..b7058d2be78 100644 --- a/base/services/dhcpcsvc/include/rosdhcp.h +++ b/base/services/dhcpcsvc/include/rosdhcp.h @@ -65,8 +65,19 @@ typedef void (*handler_t) PROTO ((struct packet *)); struct iaddr; struct interface_info; -typedef struct _DHCP_ADAPTER { +typedef struct _ALTERNATE_CONFIGURATION +{ + DWORD IpAddress; + DWORD SubnetMask; + DWORD DefaultGateway; + DWORD DnsServer1; + DWORD DnsServer2; +} ALTERNATE_CONFIGURATION, *PALTERNATE_CONFIGURATION; + +typedef struct _DHCP_ADAPTER +{ LIST_ENTRY ListEntry; + PALTERNATE_CONFIGURATION AlternateConfiguration; MIB_IFROW IfMib; MIB_IPFORWARDROW RouterMib; MIB_IPADDRROW IfAddr; @@ -89,6 +100,8 @@ void stop_client(void); void AdapterInit(VOID); HANDLE StartAdapterDiscovery(HANDLE hStopEvent); void AdapterStop(VOID); +HKEY FindAdapterKey(PDHCP_ADAPTER Adapter); +DWORD LoadAlternateConfiguration(PDHCP_ADAPTER Adapter, HKEY AdapterKey); extern PDHCP_ADAPTER AdapterGetFirst(VOID); extern PDHCP_ADAPTER AdapterGetNext(PDHCP_ADAPTER); extern PDHCP_ADAPTER AdapterFindIndex( unsigned int AdapterIndex );