Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

2290 lines
53 KiB

/*++
Copyright (c) 1994 Microsoft Corporation
Module Name:
dhcpreg.c
Abstract:
Stubs functions that manipulate NT registry.
Author:
Madan Appiah (madana) 7-Dec-1993.
Environment:
User Mode - Win32
Revision History:
--*/
#include <dhcpcli.h>
#include <dhcploc.h>
#include <dhcppro.h>
#include <dhcpcapi.h>
#include <align.h>
#include <lmcons.h>
DWORD
DhcpRegQueryInfoKey(
HKEY KeyHandle,
LPDHCP_KEY_QUERY_INFO QueryInfo
)
/*++
Routine Description:
This function retrieves information about given key.
Arguments:
KeyHandle - handle to a registry key whose info will be retrieved.
QueryInfo - pointer to a info structure where the key info will be
returned.
Return Value:
Registry Errors.
--*/
{
DWORD Error;
QueryInfo->ClassSize = DHCP_CLASS_SIZE;
Error = RegQueryInfoKey(
KeyHandle,
QueryInfo->Class,
&QueryInfo->ClassSize,
NULL,
&QueryInfo->NumSubKeys,
&QueryInfo->MaxSubKeyLen,
&QueryInfo->MaxClassLen,
&QueryInfo->NumValues,
&QueryInfo->MaxValueNameLen,
&QueryInfo->MaxValueLen,
&QueryInfo->SecurityDescriptorLen,
&QueryInfo->LastWriteTime
);
DhcpAssert( Error != ERROR_MORE_DATA );
if( Error == ERROR_MORE_DATA ){
Error = ERROR_SUCCESS;
}
return( Error );
}
DWORD
GetRegistryString(
HKEY Key,
LPWSTR ValueStringName,
LPWSTR *String,
LPDWORD StringSize
)
/*++
Routine Description:
This function retrieves the specified string value from the
registry. It allocates local memory for the returned string.
Arguments:
Key : registry handle to the key where the value is.
ValueStringName : name of the value string.
String : pointer to a location where the string pointer is returned.
StringSize : size of the string data returned. Optional
Return Value:
The status of the operation.
--*/
{
DWORD Error;
DWORD LocalValueType;
DWORD ValueSize;
LPWSTR LocalString;
DhcpAssert( *String == NULL );
//
// Query DataType and BufferSize.
//
Error = RegQueryValueEx(
Key,
ValueStringName,
0,
&LocalValueType,
NULL,
&ValueSize );
if( Error != ERROR_SUCCESS ) {
return(Error);
}
DhcpAssert( (LocalValueType == REG_SZ) ||
(LocalValueType == REG_MULTI_SZ) );
if( ValueSize == 0 ) {
if( StringSize != NULL ) {
*StringSize = 0;
}
*String = NULL;
return( ERROR_SUCCESS );
}
//
// now allocate memory for string data.
//
LocalString = DhcpAllocateMemory( ValueSize );
if(LocalString == NULL) {
return( ERROR_NOT_ENOUGH_MEMORY );
}
//
// Now query the string data.
//
Error = RegQueryValueEx(
Key,
ValueStringName,
0,
&LocalValueType,
(LPBYTE)(LocalString),
&ValueSize );
if( Error != ERROR_SUCCESS ) {
DhcpFreeMemory(LocalString);
return(Error);
}
*String = LocalString;
if( StringSize != NULL ) {
*StringSize = ValueSize;
}
return( ERROR_SUCCESS );
}
DWORD
RegSetIpAddress(
HKEY KeyHandle,
LPWSTR ValueName,
DWORD ValueType,
DHCP_IP_ADDRESS IpAddress
)
/*++
Routine Description:
This function sets IpAddress Value in the registry.
Arguments:
KeyHandle - handle to the key.
ValueName - name of the value field.
ValueType - Type of the value field.
IpAddress - Ipaddress to be set.
Return Value:
Registry Error.
--*/
{
DWORD Error;
LPSTR AnsiAddressString;
WCHAR UnicodeAddressBuf[DOT_IP_ADDR_SIZE];
LPWSTR UnicodeAddressString;
LPWSTR MultiIpAddressString = NULL;
LPWSTR NewMultiIpAddressString = NULL;
DWORD MultiIpAddressStringSize;
DWORD NewMultiIpAddressStringSize;
DWORD FirstOldIpAddressSize;
AnsiAddressString = inet_ntoa( *(struct in_addr *)&IpAddress );
UnicodeAddressString = DhcpOemToUnicode(
AnsiAddressString,
UnicodeAddressBuf );
DhcpAssert( UnicodeAddressString != NULL );
if( ValueType == REG_SZ ) {
Error = RegSetValueEx(
KeyHandle,
ValueName,
0,
ValueType,
(LPBYTE)UnicodeAddressString,
(wcslen(UnicodeAddressString) + 1) * sizeof(WCHAR) );
goto Cleanup;
}
DhcpAssert( ValueType == REG_MULTI_SZ );
//
// replace the first IpAddress.
//
//
// query current multi-IpAddress string.
//
Error = GetRegistryString(
KeyHandle,
ValueName,
&MultiIpAddressString,
&MultiIpAddressStringSize );
if( Error != ERROR_SUCCESS ) {
goto Cleanup;
}
//
// allocate new address string.
//
DhcpAssert(MultiIpAddressString != NULL);
FirstOldIpAddressSize =
(wcslen(MultiIpAddressString) + 1) * sizeof(WCHAR);
NewMultiIpAddressStringSize =
MultiIpAddressStringSize - FirstOldIpAddressSize +
(wcslen(UnicodeAddressString) + 1) * sizeof(WCHAR);
NewMultiIpAddressString = DhcpAllocateMemory( NewMultiIpAddressStringSize );
if( NewMultiIpAddressString == NULL ) {
Error = ERROR_NOT_ENOUGH_MEMORY;
goto Cleanup;
}
//
// make new address string first.
//
wcscpy( NewMultiIpAddressString, UnicodeAddressString );
//
// copy rest of the old addresses
//
RtlCopyMemory(
(LPBYTE)NewMultiIpAddressString +
(wcslen(UnicodeAddressString) + 1) * sizeof(WCHAR),
(LPBYTE)MultiIpAddressString + FirstOldIpAddressSize,
MultiIpAddressStringSize - FirstOldIpAddressSize );
Error = RegSetValueEx(
KeyHandle,
ValueName,
0,
ValueType,
(LPBYTE)NewMultiIpAddressString,
NewMultiIpAddressStringSize );
Cleanup:
if( MultiIpAddressString != NULL) {
DhcpFreeMemory( MultiIpAddressString );
}
if( NewMultiIpAddressString != NULL) {
DhcpFreeMemory( NewMultiIpAddressString );
}
return( Error );
}
#if DBG
DWORD
RegSetTimeField(
HKEY KeyHandle,
LPWSTR ValueName,
DWORD ValueType,
time_t Time
)
/*++
Routine Description:
This function sets time Value in string form in the registry.
Arguments:
KeyHandle - handle to the key.
ValueName - name of the value field.
ValueType - Type of the value field.
Time - time value to be set.
Return Value:
Registry Error.
--*/
{
DWORD Error;
WCHAR UnicodeTimeBuf[TIME_STRING_LEN];
LPWSTR UnicodeTimeString;
UnicodeTimeString =
DhcpOemToUnicode( ctime( &Time ), UnicodeTimeBuf ) ;
DhcpAssert( UnicodeTimeString != NULL );
DhcpAssert( ValueType == REG_SZ );
Error = RegSetValueEx(
KeyHandle,
ValueName,
0,
ValueType,
(LPBYTE)UnicodeTimeString,
(wcslen(UnicodeTimeString) + 1) * sizeof(WCHAR) );
return( Error );
}
#endif
DWORD
DhcpGetRegistryValue(
LPWSTR RegKey,
LPWSTR ValueName,
DWORD ValueType,
PVOID *Data
)
/*++
Routine Description:
This function retrieves the option information from registry.
Arguments:
RegKey - pointer to registry location. like
system\currentcontrolset\services\..
ValueName - name of the value to read.
ValueType - type of reg value, REG_DWORD, REG_SZ ..
Data - pointer to a location where the data will be returned.
For string data and binary data, the function allocates
memory, the caller is responsible to free it.
Return Value:
Registry Errors.
--*/
{
DWORD Error;
HKEY KeyHandle = NULL;
DWORD LocalValueType;
DWORD ValueSize;
LPWSTR LocalString;
DhcpAssert( *Data == NULL );
//
// open key.
//
Error = RegOpenKeyEx(
HKEY_LOCAL_MACHINE,
RegKey,
0, // Reserved field
DHCP_CLIENT_KEY_ACCESS,
&KeyHandle
);
if( Error != ERROR_SUCCESS ) {
goto Cleanup;
}
//
// Query DataType and BufferSize.
//
Error = RegQueryValueEx(
KeyHandle,
ValueName,
0,
&LocalValueType,
NULL,
&ValueSize );
if( Error != ERROR_SUCCESS ) {
goto Cleanup;
}
if( LocalValueType != ValueType ) {
Error = ERROR_INVALID_PARAMETER;
goto Cleanup;
}
switch( LocalValueType ) {
case REG_DWORD:
DhcpAssert( ValueSize == sizeof(DWORD) );
Error = RegQueryValueEx(
KeyHandle,
ValueName,
0,
&LocalValueType,
(LPBYTE)Data,
&ValueSize );
if( Error != ERROR_SUCCESS ) {
goto Cleanup;
}
DhcpAssert( LocalValueType == REG_DWORD );
DhcpAssert( ValueSize == sizeof(DWORD) );
break;
case REG_SZ :
case REG_MULTI_SZ:
if( ValueSize == 0 ) {
Error = ERROR_SUCCESS;
break;
}
//
// now allocate memory for string data.
//
LocalString = DhcpAllocateMemory( ValueSize );
if(LocalString == NULL) {
Error = ERROR_NOT_ENOUGH_MEMORY;
goto Cleanup;
}
//
// Now query the string data.
//
Error = RegQueryValueEx(
KeyHandle,
ValueName,
0,
&LocalValueType,
(LPBYTE)(LocalString),
&ValueSize );
if( Error != ERROR_SUCCESS ) {
DhcpFreeMemory(LocalString);
goto Cleanup;
}
DhcpAssert( (LocalValueType == REG_SZ) ||
(LocalValueType == REG_MULTI_SZ) );
*Data = (LPBYTE)LocalString;
Error = ERROR_SUCCESS;
break;
default:
Error = ERROR_INVALID_PARAMETER;
break;
}
Cleanup:
if( KeyHandle != NULL ) {
RegCloseKey( KeyHandle );
}
return( Error );
}
DWORD
DhcpSetAddressOption(
HKEY KeyHandle,
LPWSTR ValueName,
DWORD ValueType,
DHCP_IP_ADDRESS UNALIGNED *Data,
DWORD DataLength
)
/*++
Routine Description:
This rountine sets the address option obtained from DHCP server in the
registry.
Arguments:
KeyHandle - handle to the DNS key.
ValueName - name of the DNS parameter.
ValueType - type of the DNS parameter.
Data - raw DNS data.
DataLength - length of the raw data.
Return Value:
Windows Error Code.
--*/
{
DWORD Error;
LPWSTR IpAddresses = NULL;
DWORD i;
DWORD NumIpAddresses;
LPWSTR NextIpAddressAt;
DhcpAssert( ValueType == REG_SZ ||
ValueType == REG_MULTI_SZ );
if( (DataLength == 0) || (Data == NULL) ) {
//
// write empty address string.
//
IpAddresses = L"";
Error = RegSetValueEx(
KeyHandle,
ValueName,
0,
ValueType,
(LPBYTE)IpAddresses,
wcslen(IpAddresses) );
return( Error );
}
NumIpAddresses = DataLength / sizeof(DHCP_IP_ADDRESS);
DhcpAssert( NumIpAddresses != 0 );
//
// allocate buffer for the unicode addresses.
//
IpAddresses = DhcpAllocateMemory(
((DOT_IP_ADDR_SIZE + 1) * NumIpAddresses + 1) * sizeof(WCHAR) );
if( IpAddresses == NULL ) {
return(ERROR_NOT_ENOUGH_MEMORY);
}
NextIpAddressAt = IpAddresses;
for (i = 0; i < (DWORD)NumIpAddresses; i++) {
DHCP_IP_ADDRESS IPAddress;
PCHAR DotIPAddress;
WCHAR UnicodeDotIPAddressBuf[DOT_IP_ADDR_SIZE];
LPWSTR UnicodeDotIPAddress;
//
// covert each DHCP_IP_ADDRESS to dotted unicode address and
// append to the address buffer.
//
IPAddress = *Data++;
DotIPAddress = inet_ntoa( *(struct in_addr *)&IPAddress );
UnicodeDotIPAddress = DhcpOemToUnicode(
DotIPAddress,
UnicodeDotIPAddressBuf);
DhcpAssert( UnicodeDotIPAddress != NULL );
if ( UnicodeDotIPAddress != NULL ) {
if( ValueType == REG_SZ ) {
wcscpy( NextIpAddressAt, UnicodeDotIPAddress );
//
// append space " " if we have additional entries.
//
if( (i + 1) < (DWORD)NumIpAddresses ) {
wcscat( NextIpAddressAt, L" ");
NextIpAddressAt += wcslen(NextIpAddressAt);
}
else {
NextIpAddressAt += (wcslen(NextIpAddressAt) + 1);
}
}
else { // ValueType == REG_MULTI_SZ
wcscpy( NextIpAddressAt, UnicodeDotIPAddress );
NextIpAddressAt += (wcslen(NextIpAddressAt) + 1);
//
// if this is last entry append terminating char.
//
if( (i + 1) == (DWORD)NumIpAddresses ) {
*NextIpAddressAt = L'\0';
NextIpAddressAt++;
}
}
}
}
//
// Write DNS address.
//
Error = RegSetValueEx(
KeyHandle,
ValueName,
0,
ValueType,
(LPBYTE)IpAddresses,
(NextIpAddressAt - IpAddresses) * sizeof(WCHAR) );
if( IpAddresses != NULL ) {
DhcpFreeMemory( IpAddresses );
}
return(Error);
}
BOOL
SetOverRideDefaultGateway(
LPWSTR AdapterName
)
/*++
Routine Description:
This function reads the override default gateway parameter from
registry and if this parameter is non-null, it sets the gateway
value in the TCP/IP stack and return TRUE, otherwise it returns
FALSE.
Arguments:
AdapterName - name of the adapter we are working on.
Return Value:
TRUE: If the override gateway parameter is specified in the registry
and it is succssfully set in the TCP/IP router table.
FALSE : Otherwise.
--*/
{
DWORD Error;
LPWSTR RegKey = NULL;
DWORD RegKeyLength;
HKEY KeyHandle = NULL;
LPWSTR DefaultGatewayString = NULL;
DWORD DefaultGatewayStringSize;
BOOL EmptyDefaultGatewayString = FALSE;
LPWSTR String;
DWORD ValueSize,ValueType;
DWORD DontAddGatewayFlag;
RegKeyLength = sizeof(DHCP_SERVICES_KEY) +
sizeof(REGISTRY_CONNECT_STRING) +
wcslen(AdapterName) * sizeof(WCHAR) +
sizeof(DHCP_ADAPTER_PARAMETERS_KEY);
RegKey = DhcpAllocateMemory( RegKeyLength );
if( RegKey == NULL ) {
Error = ERROR_NOT_ENOUGH_MEMORY;
goto Cleanup;
}
wcscpy( RegKey, DHCP_SERVICES_KEY );
wcscat( RegKey, REGISTRY_CONNECT_STRING );
wcscat( RegKey, AdapterName);
wcscat( RegKey, DHCP_ADAPTER_PARAMETERS_KEY );
Error = RegOpenKeyEx(
HKEY_LOCAL_MACHINE,
RegKey,
0, // Reserved field
DHCP_CLIENT_KEY_ACCESS,
&KeyHandle
);
if( Error != ERROR_SUCCESS ) {
goto Cleanup;
}
DhcpAssert( KeyHandle != NULL );
ValueSize = sizeof(DWORD);
Error = RegQueryValueEx(
KeyHandle,
DHCP_DONT_ADD_DEFAULT_GATEWAY_FLAG,
0,
&ValueType,
(LPBYTE)&DontAddGatewayFlag,
&ValueSize );
if ( Error == ERROR_SUCCESS && DontAddGatewayFlag > 0 ) {
return TRUE;
}
Error = GetRegistryString(
KeyHandle,
DHCP_DEFAULT_GATEWAY_PARAMETER,
&DefaultGatewayString,
&DefaultGatewayStringSize );
if( Error != ERROR_SUCCESS ) {
goto Cleanup;
}
if ( (DefaultGatewayStringSize == 0) ||
(wcslen(DefaultGatewayString) == 0) ) {
EmptyDefaultGatewayString = TRUE;
goto Cleanup;
}
for( String = DefaultGatewayString;
wcslen(String) != 0;
String += (wcslen(String) + 1) ) {
CHAR OemIpAddressBuffer[DOT_IP_ADDR_SIZE];
LPSTR OemIpAddressString;
DHCP_IP_ADDRESS GatewayAddress;
OemIpAddressString = DhcpUnicodeToOem( String, OemIpAddressBuffer );
GatewayAddress = DhcpDottedStringToIpAddress( OemIpAddressString );
Error = SetDefaultGateway(
DEFAULT_GATEWAY_ADD,
GatewayAddress );
if( Error != ERROR_SUCCESS ) {
goto Cleanup;
}
}
Cleanup:
if( RegKey != NULL ) {
DhcpFreeMemory( RegKey );
}
if( KeyHandle != NULL ) {
RegCloseKey( KeyHandle );
}
if( DefaultGatewayString != NULL ) {
DhcpFreeMemory( DefaultGatewayString );
}
if( Error != ERROR_SUCCESS ) {
DhcpPrint((DEBUG_ERRORS,
"SetOverRideDefaultGateway failed, %ld.\n", Error ));
return( FALSE );
}
if( EmptyDefaultGatewayString ) {
return( FALSE );
}
return( TRUE );
}
DWORD
SetDhcpOption(
LPWSTR AdapterName,
DHCP_OPTION_ID OptionId,
LPBOOL DefaultGatewaysSet,
BOOL LastKnownDefaultGateway
)
/*++
Routine Description:
This function sets the option information from registry.
Arguments:
AdapterName - name of the adapter where this parameter belongs.
OptionId - ID of the option to be set.
LPBOOL DefaultGatewaysSet - pointer to BOOL, where the default
gateways for this adapter is set info is stored.
LastKnownDefaultGateway : if this flag is TRUE and OptionId is
OPTION_ROUTER_ADDRESS, then this function sets the last known
DefaultGateways to IP Stack.
Return Value:
ERROR_INVALID_PARAMETER - if we don't care the specified option.
Registry Errors.
--*/
{
DWORD Error;
DWORD Index;
HKEY KeyHandle = NULL;
LPWSTR RegKey;
BOOL RegKeyAllocated = FALSE;
LPWSTR ReplaceLoc;
LPWSTR OldDefaultString = NULL;
LPWSTR NewDefaultString = NULL;
DWORD OldStringSize;
DWORD NewStringSize;
DWORD OptionLength;
//
// do we care this option.
//
for( Index = 0; Index < DhcpGlobalOptionCount; Index++ ) {
if( DhcpGlobalOptionInfo[Index].OptionId == OptionId ) {
goto OptionFound;
}
}
return( ERROR_INVALID_PARAMETER );
OptionFound:
//
// if this parameter is an adapter parameter then replace "?" value
// with adaptername.
//
ReplaceLoc = wcschr(
DhcpGlobalOptionInfo[Index].RegKey,
OPTION_REPLACE_CHAR );
if( ReplaceLoc == NULL ) {
RegKey = DhcpGlobalOptionInfo[Index].RegKey;
}
else {
DhcpAssert( AdapterName != NULL );
if( AdapterName == NULL ) {
return( ERROR_FILE_NOT_FOUND );
}
RegKey = DhcpAllocateMemory(
(wcslen( DhcpGlobalOptionInfo[Index].RegKey ) +
wcslen( AdapterName ) ) * sizeof(WCHAR) );
if(RegKey == NULL) {
return(ERROR_NOT_ENOUGH_MEMORY);
}
RegKeyAllocated = TRUE;
wcsncpy(
RegKey,
DhcpGlobalOptionInfo[Index].RegKey,
(ReplaceLoc - DhcpGlobalOptionInfo[Index].RegKey) );
wcscpy(
RegKey + (ReplaceLoc - DhcpGlobalOptionInfo[Index].RegKey),
AdapterName );
wcscat( RegKey, ReplaceLoc + 1 );
}
//
// open key.
//
Error = RegOpenKeyEx(
HKEY_LOCAL_MACHINE,
RegKey,
0, // Reserved field
DHCP_CLIENT_KEY_ACCESS,
&KeyHandle
);
if( Error != ERROR_SUCCESS ) {
goto Cleanup;
}
switch( OptionId ) {
//
// convert the option data to proper format before writing into the
// registry.
//
case OPTION_NETBIOS_NAME_SERVER: {
WCHAR BackupServerValueName[PATHLEN];
//
// read first two addresses from the Name Servers option.
// Write the first one as primary server in the registry and
// the second as backup name server. Rest of them are unused.
//
if( DhcpGlobalOptionInfo[Index].OptionLength >=
sizeof(DHCP_IP_ADDRESS) ) {
OptionLength = sizeof(DHCP_IP_ADDRESS);
}
else {
OptionLength = 0;
}
//
// write primary server.
//
Error = DhcpSetAddressOption(
KeyHandle,
DhcpGlobalOptionInfo[Index].ValueName,
DhcpGlobalOptionInfo[Index].ValueType,
(DHCP_IP_ADDRESS UNALIGNED *)
DhcpGlobalOptionInfo[Index].RawOptionValue,
OptionLength );
if( Error != ERROR_SUCCESS ) {
break;
}
//
// make BackupServer Value Name.
//
DhcpAssert(
(wcslen(DhcpGlobalOptionInfo[Index].ValueName) +
wcslen(DHCP_NAMESERVER_BACKUP)) < PATHLEN );
wcscpy( BackupServerValueName,
DhcpGlobalOptionInfo[Index].ValueName );
wcscat( BackupServerValueName,
DHCP_NAMESERVER_BACKUP );
//
// if the DHCP server returned the backup server, set
// it, otherwise reset the backup server address to 0.
//
if( DhcpGlobalOptionInfo[Index].OptionLength >=
2 * sizeof(DHCP_IP_ADDRESS) ) {
OptionLength = sizeof(DHCP_IP_ADDRESS);
}
else {
OptionLength = 0;
}
Error = DhcpSetAddressOption(
KeyHandle,
BackupServerValueName,
DhcpGlobalOptionInfo[Index].ValueType,
(DHCP_IP_ADDRESS UNALIGNED *)
(DhcpGlobalOptionInfo[Index].RawOptionValue +
sizeof(DHCP_IP_ADDRESS)),
OptionLength );
break;
}
case OPTION_DOMAIN_NAME_SERVERS: {
if( DhcpGlobalOptionInfo[Index].OptionLength >=
sizeof(DHCP_IP_ADDRESS) ) {
OptionLength = DhcpGlobalOptionInfo[Index].OptionLength;
}
else {
OptionLength = 0;
}
Error = DhcpSetAddressOption(
KeyHandle,
DhcpGlobalOptionInfo[Index].ValueName,
DhcpGlobalOptionInfo[Index].ValueType,
(DHCP_IP_ADDRESS UNALIGNED *)
DhcpGlobalOptionInfo[Index].RawOptionValue,
OptionLength );
break;
}
case OPTION_NETBIOS_NODE_TYPE : {
DWORD NodeType;
if( DhcpGlobalOptionInfo[Index].OptionLength ) {
DhcpAssert(
DhcpGlobalOptionInfo[Index].OptionLength ==
sizeof(BYTE) );
NodeType = (DWORD)(*DhcpGlobalOptionInfo[Index].RawOptionValue);
}
else {
NodeType = 1; // default to BNode.
}
Error = RegSetValueEx(
KeyHandle,
DhcpGlobalOptionInfo[Index].ValueName,
0,
DhcpGlobalOptionInfo[Index].ValueType,
(LPBYTE)&NodeType,
sizeof(NodeType) );
break;
}
case OPTION_ROUTER_ADDRESS: {
LPWSTR String;
CHAR OemIpAddressBuffer[DOT_IP_ADDR_SIZE];
LPSTR OemIpAddressString;
DHCP_IP_ADDRESS GatewayAddress;
//
// special case: If the user specified override default gateway
// in the registry (instead using the DHCP obtained default
// gateways). TCP/IP stack couldn't set this value during system
// start (or anytime later) when DHCP is enabled.
//
if( SetOverRideDefaultGateway( AdapterName ) ) {
break;
}
//
// read current value.
//
Error = GetRegistryString(
KeyHandle,
DhcpGlobalOptionInfo[Index].ValueName,
&OldDefaultString,
&OldStringSize );
if( Error != ERROR_SUCCESS ) {
if( Error != ERROR_FILE_NOT_FOUND ) {
goto Cleanup;
}
Error = ERROR_SUCCESS;
OldStringSize = 0;
}
if ( LastKnownDefaultGateway ) {
if( OldDefaultString != NULL ) {
//
// we are asked to set the last known DefaultGateways to
// IP stack.
//
for( String = OldDefaultString;
wcslen(String) != 0;
String += (wcslen(String) + 1) ) {
OemIpAddressString =
DhcpUnicodeToOem( String, OemIpAddressBuffer );
GatewayAddress =
DhcpDottedStringToIpAddress( OemIpAddressString );
Error = SetDefaultGateway(
DEFAULT_GATEWAY_ADD,
GatewayAddress );
if( Error != ERROR_SUCCESS ) {
goto Cleanup;
}
}
*DefaultGatewaysSet = TRUE;
}
}
else {
//
// Set New Value.
//
if( DhcpGlobalOptionInfo[Index].OptionLength >=
sizeof(DHCP_IP_ADDRESS) ) {
OptionLength = DhcpGlobalOptionInfo[Index].OptionLength;
}
else {
OptionLength = 0;
}
Error = DhcpSetAddressOption(
KeyHandle,
DhcpGlobalOptionInfo[Index].ValueName,
DhcpGlobalOptionInfo[Index].ValueType,
(DHCP_IP_ADDRESS UNALIGNED *)
DhcpGlobalOptionInfo[Index].RawOptionValue,
OptionLength );
if( Error != ERROR_SUCCESS ) {
goto Cleanup;
}
//
// Read new value.
//
Error = GetRegistryString(
KeyHandle,
DhcpGlobalOptionInfo[Index].ValueName,
&NewDefaultString,
&NewStringSize );
if( Error != ERROR_SUCCESS ) {
goto Cleanup;
}
//
// if the new value is not same as the old value, delete
// all old gateways and add new gateways.
//
// However if you are setting default gateways first time,
// don't delete the old values, but set new values.
//
if( (*DefaultGatewaysSet == FALSE) ||
(OldStringSize != NewStringSize) ||
(OldDefaultString == NULL) ||
(RtlCompareMemory(
NewDefaultString,
OldDefaultString,
NewStringSize) != NewStringSize) ) {
if( (*DefaultGatewaysSet == TRUE) &&
(OldDefaultString != NULL) ) {
//
// delete old gateways.
//
for( String = OldDefaultString;
wcslen(String) != 0;
String += (wcslen(String) + 1) ) {
OemIpAddressString =
DhcpUnicodeToOem( String, OemIpAddressBuffer );
GatewayAddress =
DhcpDottedStringToIpAddress( OemIpAddressString );
Error = SetDefaultGateway(
DEFAULT_GATEWAY_DELETE,
GatewayAddress );
if( Error != ERROR_SUCCESS ) {
goto Cleanup;
}
}
}
//
// Add New gateways.
//
if( NewDefaultString != NULL ) {
for( String = NewDefaultString;
wcslen(String) != 0;
String += (wcslen(String) + 1) ) {
OemIpAddressString =
DhcpUnicodeToOem( String, OemIpAddressBuffer );
GatewayAddress =
DhcpDottedStringToIpAddress( OemIpAddressString );
Error = SetDefaultGateway(
DEFAULT_GATEWAY_ADD,
GatewayAddress );
if( Error != ERROR_SUCCESS ) {
goto Cleanup;
}
}
}
*DefaultGatewaysSet = TRUE;
}
}
break;
}
case OPTION_NETBIOS_SCOPE_OPTION:
case OPTION_DOMAIN_NAME: {
LPSTR ScopeString;
LPWSTR UnicodeScopeString;
//
// allocate memory for scope strings.
//
ScopeString = DhcpAllocateMemory(
DhcpGlobalOptionInfo[Index].OptionLength + 1 );
if( ScopeString == NULL ) {
Error = ERROR_NOT_ENOUGH_MEMORY;
break;
}
UnicodeScopeString = DhcpAllocateMemory(
(DhcpGlobalOptionInfo[Index].OptionLength +
1) * sizeof(WCHAR) );
if( UnicodeScopeString == NULL ) {
DhcpFreeMemory( ScopeString );
Error = ERROR_NOT_ENOUGH_MEMORY;
break;
}
memcpy( ScopeString,
DhcpGlobalOptionInfo[Index].RawOptionValue,
DhcpGlobalOptionInfo[Index].OptionLength );
//
// terminate scope string.
//
ScopeString[DhcpGlobalOptionInfo[Index].OptionLength] = '\0';
//
// convert it unicode string.
//
UnicodeScopeString = DhcpOemToUnicode(
ScopeString,
UnicodeScopeString );
//
// write it to registry.
//
DhcpAssert( DhcpGlobalOptionInfo[Index].ValueType == REG_SZ );
Error = RegSetValueEx(
KeyHandle,
DhcpGlobalOptionInfo[Index].ValueName,
0,
DhcpGlobalOptionInfo[Index].ValueType,
(LPBYTE)UnicodeScopeString,
(wcslen(UnicodeScopeString) + 1) * sizeof(WCHAR) );
//
// free locally allocated memories.
DhcpFreeMemory( ScopeString );
DhcpFreeMemory( UnicodeScopeString );
break;
}
//
// for all unknown parameters, simply write them into the
// registry as they received.
//
default:
Error = RegSetValueEx(
KeyHandle,
DhcpGlobalOptionInfo[Index].ValueName,
0,
DhcpGlobalOptionInfo[Index].ValueType,
DhcpGlobalOptionInfo[Index].RawOptionValue,
DhcpGlobalOptionInfo[Index].OptionLength );
break;
}
Cleanup:
if( OldDefaultString != NULL ) {
DhcpFreeMemory( OldDefaultString );
}
if( NewDefaultString != NULL ) {
DhcpFreeMemory( NewDefaultString );
}
if( RegKeyAllocated == TRUE ) {
DhcpFreeMemory( RegKey );
}
if( KeyHandle != NULL ) {
RegCloseKey( KeyHandle );
}
return( Error );
}
DWORD
DhcpMakeAndInsertNICEntry(
PDHCP_CONTEXT *ReturnDhcpContext,
DHCP_IP_ADDRESS IpAddress,
DHCP_IP_ADDRESS SubnetMask,
DHCP_IP_ADDRESS DhcpServerAddress,
DHCP_IP_ADDRESS DesiredIpAddress,
BYTE HardwareAddressType,
LPBYTE HardwareAddress,
DWORD HardwareAddressLength,
BOOL fClientIDSpecified,
BYTE bClientIDType,
DWORD cbClientID,
BYTE *pbClientID,
DWORD Lease,
time_t LeaseObtainedTime,
time_t T1Time,
time_t T2Time,
time_t LeaseTerminatesTime,
DWORD IpInterfaceContext,
DWORD IpInterfaceInstance,
LPWSTR AdapterName,
LPWSTR DeviceName,
LPWSTR RegKey
)
/*++
Routine Description:
This function allocates, initializes and inserts an entry for a new
NIC.
Arguments:
Parameter for new entry :
IpAddress,
SubnetMask,
DhcpServerAddress,
DesiredIpAddress,
HardwareAddressType,
HardwareAddress,
HardwareAddressLength,
Lease,
LeaseObtainedTime,
T1Time,
T2Time,
LeaseTerminatesTime,
IpInterfaceContext,
AdapterName,
DeviceName,
RegKey
Return Value:
Windows Error.
History:
8/26/96 Frankbee Added Client ID (option 61) support
--*/
{
PDHCP_CONTEXT DhcpContext = NULL;
ULONG DhcpContextSize;
PLOCAL_CONTEXT_INFO LocalInfo;
LPVOID Ptr;
DWORD AdapterNameLen;
DWORD DeviceNameLen;
DWORD NetBTDeviceNameLen;
DWORD RegKeyLen;
AdapterNameLen = ((wcslen(AdapterName) + 1) * sizeof(WCHAR));
DeviceNameLen = ((wcslen(DeviceName) + 1) * sizeof(WCHAR));
NetBTDeviceNameLen =
((wcslen(DHCP_ADAPTERS_DEVICE_STRING) +
wcslen(DHCP_NETBT_DEVICE_STRING) +
wcslen(AdapterName) + 1) * sizeof(WCHAR));
RegKeyLen = ((wcslen(RegKey) + 1) * sizeof(WCHAR));
DhcpContextSize =
ROUND_UP_COUNT(sizeof(DHCP_CONTEXT), ALIGN_WORST) +
ROUND_UP_COUNT(HardwareAddressLength, ALIGN_WORST) +
ROUND_UP_COUNT(sizeof(LOCAL_CONTEXT_INFO), ALIGN_WORST) +
ROUND_UP_COUNT(AdapterNameLen, ALIGN_WORST) +
ROUND_UP_COUNT(DeviceNameLen, ALIGN_WORST) +
ROUND_UP_COUNT(NetBTDeviceNameLen, ALIGN_WORST) +
ROUND_UP_COUNT(RegKeyLen, ALIGN_WORST) +
ROUND_UP_COUNT(DHCP_MESSAGE_SIZE, ALIGN_WORST);
if ( fClientIDSpecified )
{
DhcpAssert( cbClientID );
DhcpContextSize += ROUND_UP_COUNT( cbClientID, ALIGN_WORST );
}
Ptr = DhcpAllocateMemory( DhcpContextSize );
if ( Ptr == NULL ) {
return( ERROR_NOT_ENOUGH_MEMORY );
}
//
// Initialize internal pointers.
//
//
// make sure the pointers are aligned.
//
DhcpContext = Ptr;
Ptr = ROUND_UP_POINTER( (LPBYTE)Ptr + sizeof(DHCP_CONTEXT), ALIGN_WORST);
DhcpContext->HardwareAddress = Ptr;
Ptr = ROUND_UP_POINTER( (LPBYTE)Ptr + HardwareAddressLength, ALIGN_WORST);
if ( fClientIDSpecified )
{
DhcpContext->ClientIdentifier.pbID = Ptr;
Ptr = ROUND_UP_POINTER( (LPBYTE)Ptr + cbClientID, ALIGN_WORST );
}
DhcpContext->LocalInformation = Ptr;
LocalInfo = Ptr;
Ptr = ROUND_UP_POINTER( (LPBYTE)Ptr + sizeof(LOCAL_CONTEXT_INFO), ALIGN_WORST);
LocalInfo->AdapterName= Ptr;
Ptr = ROUND_UP_POINTER( (LPBYTE)Ptr + AdapterNameLen, ALIGN_WORST);
LocalInfo->DeviceName= Ptr;
Ptr = ROUND_UP_POINTER( (LPBYTE)Ptr + DeviceNameLen, ALIGN_WORST);
LocalInfo->NetBTDeviceName= Ptr;
Ptr = ROUND_UP_POINTER( (LPBYTE)Ptr + NetBTDeviceNameLen, ALIGN_WORST);
LocalInfo->RegistryKey= Ptr;
Ptr = ROUND_UP_POINTER( (LPBYTE)Ptr + RegKeyLen, ALIGN_WORST);
DhcpContext->MessageBuffer = Ptr;
//
// initialize fields.
//
DhcpContext->HardwareAddressType = HardwareAddressType;
DhcpContext->HardwareAddressLength = HardwareAddressLength;
RtlCopyMemory(
DhcpContext->HardwareAddress,
HardwareAddress,
HardwareAddressLength
);
DhcpContext->ClientIdentifier.fSpecified = fClientIDSpecified;
if ( fClientIDSpecified )
{
DhcpContext->ClientIdentifier.bType = bClientIDType;
DhcpContext->ClientIdentifier.cbID = cbClientID;
RtlCopyMemory(
DhcpContext->ClientIdentifier.pbID,
pbClientID,
cbClientID
);
}
DhcpContext->IpAddress = IpAddress;
DhcpContext->SubnetMask = SubnetMask;
DhcpContext->DhcpServerAddress = DhcpServerAddress;
DhcpContext->DesiredIpAddress = DesiredIpAddress;
DhcpContext->Lease = Lease;
DhcpContext->LeaseObtained = LeaseObtainedTime;
DhcpContext->T1Time = T1Time;
DhcpContext->T2Time = T2Time;
DhcpContext->LeaseExpires = LeaseTerminatesTime;
DhcpContext->InterfacePlumbed = FALSE;
//
// copy local info.
//
LocalInfo->IpInterfaceContext = IpInterfaceContext;
LocalInfo->IpInterfaceInstance = IpInterfaceInstance;
RtlCopyMemory(LocalInfo->AdapterName, AdapterName, AdapterNameLen);
RtlCopyMemory(LocalInfo->DeviceName, DeviceName, DeviceNameLen);
wcscpy( LocalInfo->NetBTDeviceName, DHCP_ADAPTERS_DEVICE_STRING );
wcscat( LocalInfo->NetBTDeviceName, DHCP_NETBT_DEVICE_STRING );
wcscat( LocalInfo->NetBTDeviceName, AdapterName );
RtlCopyMemory(LocalInfo->RegistryKey, RegKey, RegKeyLen);
LocalInfo->Socket = INVALID_SOCKET;
LocalInfo->DefaultGatewaysSet = FALSE;
//
// finally add this to DHCP NIC list.
//
LOCK_RENEW_LIST();
InsertTailList( &DhcpGlobalNICList, &DhcpContext->NicListEntry );
UNLOCK_RENEW_LIST();
//
// return this context pointer.
//
if( ReturnDhcpContext != NULL ) {
*ReturnDhcpContext = DhcpContext;
}
return( ERROR_SUCCESS );
}
/*++
Function:
ReadClientID
Routine Description:
Reads and validates the optional Client-Identifier option
Arguments:
hKey - handle to a registry key whose info will be retrieved.
pbClientIDType - Recieves the client ID option type
pcbClientID - Receives the size of the client id option
ppbClientID - Receives a pointer to a buffer containing the
client ID option
Return Value:
TRUE - A valid client ID was read from the registry
FALSE - Client ID could not be read
Comments:
If ReadClientID returns false, pbClientIDType, pcbClientID and ppbClientID
will be set to NULL.
History
7/14/96 Frankbee Created
--*/
BOOL
ReadClientID(
HKEY hKey,
BYTE *pbClientIDType,
DWORD *pcbClientID,
BYTE *ppbClientID[]
)
{
DWORD dwResult,
dwDataType,
dwcb,
dwClientIDType,
dwClientID;
BYTE *pbClientID;
BOOL fClientIDSpecified = FALSE;
//
// read the client id and client id type, if present
//
dwcb = sizeof(dwClientIDType);
dwResult = RegQueryValueEx(
hKey,
DHCP_CLIENT_IDENTIFIER_FORMAT,
0,
&dwDataType,
(LPBYTE)&dwClientIDType,
&dwcb );
if ( ERROR_SUCCESS != dwResult )
{
DhcpPrint( (DEBUG_MISC,
"Client-Indentifier type not present in registry.\n" ));
//
// specify ID type 0 to indicate that the client ID is not a hardware
// address
//
dwClientIDType = 0;
}
else
{
//
// the client id type is present, make sure it is the correct
// data type and within range
//
if ( DHCP_CLIENT_IDENTIFIER_FORMAT_TYPE != dwDataType || dwClientIDType > 0xFF )
{
DhcpPrint( (DEBUG_ERRORS,
"Invalid Client-Indentifier type: %d\n", dwClientIDType ));
goto done;
}
}
//
// Now try to read the client ID
//
// first try to read the size
dwcb = 0;
dwResult = RegQueryValueEx(
hKey,
DHCP_CLIENT_IDENTIFIER,
0,
0, // don't care about the type
NULL, // specify null buffer to obtain size
&dwcb );
// make the the value is present
if ( ERROR_SUCCESS != dwResult || !dwcb )
{
DhcpPrint( (DEBUG_ERRORS,
"Client-Identifier is not present or invalid.\n" ));
goto done;
}
// allocate the buffer and read the value
pbClientID = (BYTE*) DhcpAllocateMemory ( dwcb );
if ( !pbClientID )
{
DhcpPrint( (DEBUG_ERRORS,
"Unable to allocate memory for Client-Identifier "));
goto done;
}
dwResult = RegQueryValueEx(
hKey,
DHCP_CLIENT_IDENTIFIER,
0,
0, // client id can be any type
pbClientID,
&dwcb );
if ( ERROR_SUCCESS != dwResult )
{
DhcpPrint( (DEBUG_ERRORS,
"Unable to read Client-Identifier from registry: %d\n", dwResult ));
DhcpFreeMemory( pbClientID );
goto done;
}
//
// we have a client id
//
fClientIDSpecified = TRUE;
done:
if ( fClientIDSpecified )
{
*pbClientIDType = (BYTE) dwClientIDType;
*pcbClientID = dwcb;
*ppbClientID = pbClientID;
}
else
{
*pbClientIDType = 0;
*pcbClientID = 0;
*ppbClientID = NULL;
}
#ifdef DBG
if ( fClientIDSpecified )
{
int i;
//
// A valid client-identifier was obtained from the registry. dump out
// the contents
//
DhcpPrint( (DEBUG_MISC,
"A Client Identifier was obtained from the registry:\n" ));
DhcpPrint( (DEBUG_MISC,
"Client-Identifier Type == %#2x\n", (int) *pbClientIDType ));
DhcpPrint( (DEBUG_MISC,
"Client-Indentifier length == %d\n", (int) *pcbClientID ));
DhcpPrint( (DEBUG_MISC,
"Client-Identifier == " ));
for ( i = 0; i < (int) *pcbClientID; i++ )
DbgPrint( "%#2x ", (int) ((*ppbClientID)[i]) );
DhcpPrint( (DEBUG_MISC, "\n" ));
}
#endif
return fClientIDSpecified;
}
DWORD
DhcpAddNICtoList(
LPWSTR AdapterName,
LPWSTR DeviceName,
PDHCP_CONTEXT *DhcpContext
)
/*++
Routine Description:
This function reads NIC parameters from registry, makes a NIC
entry with the parameters and appends this new entry to DHCP NIC
list.
Arguments:
AdapterName - Name of the Adapter.
DeviceName - Name of the Device.
DhcpContext - pointer to a location where the new DhcpContext
structure pointer is returned.
Return Value:
Windows Error.
History:
8/26/96 Frankbee Added registry support for Client-ID (option 61)
--*/
{
DWORD Error;
LPWSTR RegKey = NULL;
HKEY KeyHandle = NULL;
DWORD ValueType;
DWORD ValueSize;
LPWSTR IpAddressString = NULL;
CHAR OemIpAddressString[DOT_IP_ADDR_SIZE];
LPWSTR SubnetMaskString = NULL;
CHAR OemSubnetMaskString[DOT_IP_ADDR_SIZE];
WCHAR DhcpServerString[DOT_IP_ADDR_SIZE];
CHAR OemDhcpServerString[DOT_IP_ADDR_SIZE];
DWORD EnableDhcp;
DHCP_IP_ADDRESS IpAddress;
DHCP_IP_ADDRESS SubnetMask;
DHCP_IP_ADDRESS DhcpServerAddress;
DHCP_IP_ADDRESS DesiredIpAddress;
BYTE HardwareAddressType;
LPBYTE HardwareAddress = NULL;
DWORD HardwareAddressLength;
BYTE bClientIDType;
DWORD cbClientID;
BYTE *pbClientID;
BOOL fClientIDSpecified;
DWORD Lease;
time_t LeaseObtainedTime;
time_t T1Time;
time_t T2Time;
time_t LeaseTerminatesTime;
DWORD IpInterfaceContext;
DWORD IpInterfaceInstance;
//
// make NIC IP parameter key.
//
RegKey = DhcpAllocateMemory(
(wcslen(DHCP_SERVICES_KEY) +
wcslen(REGISTRY_CONNECT_STRING) +
wcslen(AdapterName) +
wcslen(DHCP_ADAPTER_PARAMETERS_KEY) + 1) *
sizeof(WCHAR) ); // termination char.
if( RegKey == NULL ) {
Error = ERROR_NOT_ENOUGH_MEMORY;
goto Cleanup;
}
wcscpy( RegKey, DHCP_SERVICES_KEY );
wcscat( RegKey, REGISTRY_CONNECT_STRING );
wcscat( RegKey, AdapterName );
wcscat( RegKey, DHCP_ADAPTER_PARAMETERS_KEY );
//
// open this key.
//
Error = RegOpenKeyEx(
HKEY_LOCAL_MACHINE,
RegKey,
0, // Reserved field
DHCP_CLIENT_KEY_ACCESS,
&KeyHandle
);
if( Error != ERROR_SUCCESS ) {
goto Cleanup;
}
//
// read parameters.
//
ValueSize = sizeof(EnableDhcp);
Error = RegQueryValueEx(
KeyHandle,
DHCP_ENABLE_STRING,
0,
&ValueType,
(LPBYTE)&EnableDhcp,
&ValueSize );
if( Error != ERROR_SUCCESS ) {
//
// dhcp can't be enabled on this NIC.
//
Error = ERROR_SUCCESS;
goto Cleanup;
}
else {
if( !EnableDhcp ) {
//
// dhcp is not enabled on this NIC.
//
Error = ERROR_SUCCESS;
goto Cleanup;
}
}
//
// Read and validate the optional client ID
//
fClientIDSpecified = ReadClientID(
KeyHandle,
&bClientIDType,
&cbClientID,
&pbClientID );
ValueSize = sizeof(DWORD);
Error = RegQueryValueEx(
KeyHandle,
DHCP_IP_INTERFACE_CONTEXT,
0,
&ValueType,
(LPBYTE)&IpInterfaceContext,
&ValueSize );
if( Error != ERROR_SUCCESS ) {
goto Cleanup;
}
else {
DhcpAssert( ValueType == DHCP_IP_INTERFACE_CONTEXT_TYPE );
if( IpInterfaceContext == INVALID_INTERFACE_CONTEXT ) {
//
// invalid adapter, skip this.
//
Error = ERROR_SUCCESS;
goto Cleanup;
}
}
Error = GetRegistryString(
KeyHandle,
DHCP_IP_ADDRESS_STRING,
&IpAddressString,
NULL );
if( Error != ERROR_SUCCESS ) {
IpAddress = 0;
}
else {
//
// IpAddressString is Multiple IpAddress Strings,
// we do DHCP on the first address only, convert
// the first string to IpAddress.
//
DhcpAssert( IpAddressString != NULL );
IpAddress = inet_addr(
DhcpUnicodeToOem(
IpAddressString,
OemIpAddressString) );
}
Error = GetRegistryString(
KeyHandle,
DHCP_SUBNET_MASK_STRING,
&SubnetMaskString,
NULL );
if( Error != ERROR_SUCCESS ) {
SubnetMask = 0;
}
else {
DhcpAssert( SubnetMaskString != NULL );
SubnetMask = inet_addr(
DhcpUnicodeToOem(
SubnetMaskString,
OemSubnetMaskString) );
}
if( IpAddress != 0 ) {
ValueSize = DOT_IP_ADDR_SIZE * sizeof(WCHAR);
Error = RegQueryValueEx(
KeyHandle,
DHCP_SERVER,
0,
&ValueType,
(LPBYTE)DhcpServerString,
&ValueSize );
if( Error != ERROR_SUCCESS ) {
DhcpAssert( Error == ERROR_FILE_NOT_FOUND );
DhcpServerAddress = (DHCP_IP_ADDRESS)(-1);
}
else {
DhcpAssert( ValueType == DHCP_SERVER_TYPE );
DhcpServerAddress = inet_addr(
DhcpUnicodeToOem(
DhcpServerString,
OemDhcpServerString) );
}
}
else {
DhcpServerAddress = (DHCP_IP_ADDRESS)(-1);
}
ValueSize = sizeof(DWORD);
Error = RegQueryValueEx(
KeyHandle,
DHCP_LEASE,
0,
&ValueType,
(LPBYTE)&Lease,
&ValueSize );
if( Error != ERROR_SUCCESS ) {
DhcpAssert( Error == ERROR_FILE_NOT_FOUND );
Lease = 0;
}
else {
DhcpAssert( ValueType == DHCP_LEASE_TYPE );
}
ValueSize = sizeof(time_t);
Error = RegQueryValueEx(
KeyHandle,
DHCP_LEASE_OBTAINED_TIME,
0,
&ValueType,
(LPBYTE)&LeaseObtainedTime,
&ValueSize );
if( Error != ERROR_SUCCESS ) {
DhcpAssert( Error == ERROR_FILE_NOT_FOUND );
LeaseObtainedTime = 0;
}
else {
DhcpAssert( ValueType == DHCP_LEASE_OBTAINED_TIME_TYPE );
}
ValueSize = sizeof(time_t);
Error = RegQueryValueEx(
KeyHandle,
DHCP_LEASE_T1_TIME,
0,
&ValueType,
(LPBYTE)&T1Time,
&ValueSize );
if( Error != ERROR_SUCCESS ) {
DhcpAssert( Error == ERROR_FILE_NOT_FOUND );
T1Time = 0;
}
else {
DhcpAssert( ValueType == DHCP_LEASE_T1_TIME_TYPE );
}
ValueSize = sizeof(time_t);
Error = RegQueryValueEx(
KeyHandle,
DHCP_LEASE_T2_TIME,
0,
&ValueType,
(LPBYTE)&T2Time,
&ValueSize );
if( Error != ERROR_SUCCESS ) {
DhcpAssert( Error == ERROR_FILE_NOT_FOUND );
T2Time = 0;
}
else {
DhcpAssert( ValueType == DHCP_LEASE_T2_TIME_TYPE );
}
ValueSize = sizeof(time_t);
Error = RegQueryValueEx(
KeyHandle,
DHCP_LEASE_TERMINATED_TIME,
0,
&ValueType,
(LPBYTE)&LeaseTerminatesTime,
&ValueSize );
if( Error != ERROR_SUCCESS ) {
DhcpAssert( Error == ERROR_FILE_NOT_FOUND );
LeaseTerminatesTime = 0;
}
else {
DhcpAssert( ValueType == DHCP_LEASE_TERMINATED_TIME_TYPE );
}
//
// set desired IP address.
//
DesiredIpAddress = IpAddress;
//
// Query IP stack for Hardware Info.
//
Error = DhcpQueryHWInfo(
IpInterfaceContext,
&IpInterfaceInstance,
&HardwareAddressType,
&HardwareAddress,
&HardwareAddressLength );
if( Error != ERROR_SUCCESS ) {
goto Cleanup;
}
if( (time( NULL ) > LeaseTerminatesTime) ||
(IpAddress == 0) ) {
IpAddress = 0;
SubnetMask = htonl(DhcpDefaultSubnetMask( IpAddress ));
Lease = 0;
LeaseObtainedTime = T1Time = T2Time = LeaseTerminatesTime = 0;
}
//
// finally call maker routine.
//
Error = DhcpMakeAndInsertNICEntry(
DhcpContext,
IpAddress,
SubnetMask,
DhcpServerAddress,
DesiredIpAddress,
HardwareAddressType,
HardwareAddress,
HardwareAddressLength,
fClientIDSpecified,
bClientIDType,
cbClientID,
pbClientID,
Lease,
LeaseObtainedTime,
T1Time,
T2Time,
LeaseTerminatesTime,
IpInterfaceContext,
IpInterfaceInstance,
AdapterName,
DeviceName,
RegKey );
if( Error != ERROR_SUCCESS ) {
goto Cleanup;
}
Cleanup:
if( RegKey != NULL ) {
DhcpFreeMemory( RegKey );
}
if( KeyHandle != NULL ) {
RegCloseKey( KeyHandle );
}
if( HardwareAddress != NULL ) {
DhcpFreeMemory( HardwareAddress );
}
if( IpAddressString != NULL ) {
DhcpFreeMemory( IpAddressString );
}
if( SubnetMaskString != NULL ) {
DhcpFreeMemory( SubnetMaskString );
}
if ( pbClientID )
{
DhcpFreeMemory( pbClientID );
}
return( Error );
}
DWORD
DhcpMakeNICList(
VOID
)
/*++
Routine Description:
This function reads registry and determines the adpters that are
bound to the IP layer. For each adpter that is bound to the IP layer
this function creates a NIC entry in thr DHCP NIC list.
Arguments:
none.
Return Value:
Windows Error.
--*/
{
DWORD Error;
LPWSTR DeviceNames = NULL;
LPWSTR NextDevice;
Error = DhcpGetRegistryValue(
DHCP_ADAPTERS_KEY,
DHCP_ADAPTERS_VALUE,
DHCP_ADAPTERS_VALUE_TYPE,
&DeviceNames );
if( Error != ERROR_SUCCESS ) {
goto Cleanup;
}
DhcpAssert( DeviceNames != NULL );
if( (DeviceNames == NULL) || (wcslen(DeviceNames) == 0) ) {
Error = ERROR_INVALID_FUNCTION; // ?? better error code.
goto Cleanup;
}
NextDevice = DeviceNames;
while ( wcslen(NextDevice) != 0 ) {
LPWSTR AdapterName;
AdapterName = NextDevice + wcslen(DHCP_ADAPTERS_DEVICE_STRING);
Error = DhcpAddNICtoList( AdapterName, NextDevice, NULL );
if( Error != ERROR_SUCCESS ) {
goto Cleanup;
}
NextDevice += (wcslen(NextDevice) + 1);
}
Cleanup:
if( DeviceNames != NULL ) {
DhcpFreeMemory( DeviceNames );
}
return( Error );
}