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.
1781 lines
61 KiB
1781 lines
61 KiB
//================================================================================
|
|
// Copyright (C) 1997 Microsoft Corporation
|
|
// Author: RameshV
|
|
// Description: simple registry utilities
|
|
//================================================================================
|
|
|
|
#include <mmregpch.h>
|
|
|
|
//BeginExport(typedef)
|
|
typedef struct _REG_HANDLE {
|
|
HKEY Key;
|
|
HKEY SubKey;
|
|
LPWSTR SubKeyLocation;
|
|
} REG_HANDLE, *PREG_HANDLE, *LPREG_HANDLE;
|
|
//EndExport(typedef)
|
|
|
|
//BeginExport(constants)
|
|
#define REG_THIS_SERVER L"Software\\Microsoft\\DHCPServer\\Configuration"
|
|
#define REG_THIS_SERVER_DS L"Software\\Microsoft\\DHCPServer\\Config_DS"
|
|
#define REG_THIS_SERVER_DS_VALUE L"Config_DS"
|
|
#define REG_THIS_SERVER_DS_PARENT L"Software\\Microsoft\\DHCPServer"
|
|
|
|
#define REG_SERVER_GLOBAL_OPTIONS L"GlobalOptionValues"
|
|
#define REG_SERVER_OPTDEFS L"OptionInfo"
|
|
#define REG_SERVER_SUBNETS L"Subnets"
|
|
#define REG_SERVER_SSCOPES L"SuperScope"
|
|
#define REG_SERVER_CLASSDEFS L"ClassDefs"
|
|
#define REG_SERVER_MSCOPES L"MulticastScopes"
|
|
|
|
#define REG_SUBNET_SERVERS L"DHCPServers"
|
|
#define REG_SUBNET_RANGES L"IpRanges"
|
|
#define REG_SUBNET_RESERVATIONS L"ReservedIps"
|
|
#define REG_SUBNET_OPTIONS L"SubnetOptions"
|
|
|
|
#define REG_SUBNET_EXCL L"ExcludedIpRanges"
|
|
#define REG_SUBNET_ADDRESS L"SubnetAddress"
|
|
#define REG_SUBNET_NAME L"SubnetName"
|
|
#define REG_SUBNET_COMMENT L"SubnetComment"
|
|
#define REG_SUBNET_MASK L"SubnetMask"
|
|
#define REG_SUBNET_STATE L"SubnetState"
|
|
#define REG_SUBNET_SWITCHED_FLAG L"SwitchedNetworkFlag"
|
|
|
|
#define REG_MSCOPE_NAME L"MScopeName"
|
|
#define REG_MSCOPE_COMMENT L"MScopeComment"
|
|
//
|
|
// Win2K Beta2 and Beta3 went out with scope id param value MScopeId.
|
|
// Since their meaning is being changed, to avoid any costly upgrade
|
|
// code, this value is being changed to MScopeIdValue: to automatically
|
|
// chose a good scope id, TTL values. Note that the default value of
|
|
// zero is treated specially for this scope id param. It implies that
|
|
// this was probably a pre-RC1 upgrade. In this case, the Scope ID
|
|
// defaults to first value in the range.
|
|
//
|
|
#define REG_MSCOPE_SCOPEID L"MScopeIdValue"
|
|
#define REG_MSCOPE_STATE L"MScopeState"
|
|
#define REG_MSCOPE_ADDR_POLICY L"MScopeAddressPolicy"
|
|
#define REG_MSCOPE_TTL L"MScopeTTL"
|
|
#define REG_MSCOPE_LANG_TAG L"MScopeLangTag"
|
|
#define REG_MSCOPE_EXPIRY_TIME L"MScopeExpiryTime"
|
|
|
|
#define REG_SUB_SERVER_NAME L"ServerHostName"
|
|
#define REG_SUB_SERVER_COMMENT L"ServerComment"
|
|
#define REG_SUB_SERVER_ADDRESS L"ServerAddress"
|
|
#define REG_SUB_SERVER_ROLE L"Role"
|
|
|
|
#define REG_RANGE_NAME L"RangeName"
|
|
#define REG_RANGE_COMMENT L"RangeComment"
|
|
#define REG_RANGE_START_ADDRESS L"StartAddress"
|
|
#define REG_RANGE_END_ADDRESS L"EndAddress"
|
|
#define REG_RANGE_INUSE_CLUSTERS L"InUseClusters"
|
|
#define REG_RANGE_USED_CLUSTERS L"UsedClusters"
|
|
#define REG_RANGE_BITS_PREFIX L"Bits "
|
|
#define REG_RANGE_BITS_PREFIX_WCHAR_COUNT (5)
|
|
#define REG_RANGE_FLAGS L"RangeFlags"
|
|
#define REG_RANGE_ALLOC L"RangeBootpAllocated"
|
|
#define REG_RANGE_MAX_ALLOC L"RangeBootpMaxAllowed"
|
|
|
|
#define REG_OPTION_NAME L"OptionName"
|
|
#define REG_OPTION_COMMENT L"OptionComment"
|
|
#define REG_OPTION_TYPE L"OptionType"
|
|
#define REG_OPTION_VALUE L"OptionValue"
|
|
#define REG_OPTION_ID L"OptionId"
|
|
#define REG_OPTION_CLASSNAME L"OptionClassName"
|
|
#define REG_OPTION_VENDORNAME L"OptionVendorName"
|
|
|
|
#define REG_CLASSDEF_NAME L"ClassName"
|
|
#define REG_CLASSDEF_COMMENT L"ClassComment"
|
|
#define REG_CLASSDEF_TYPE L"ClassType"
|
|
#define REG_CLASSDEF_VALUE L"ClassValue"
|
|
|
|
#define REG_RESERVATION_ADDRESS L"IpAddress"
|
|
#define REG_RESERVATION_UID L"ClientUID"
|
|
#define REG_RESERVATION_TYPE L"AllowedClientTypes"
|
|
#define REG_RESERVATION_NAME L"ReservationName"
|
|
#define REG_RESERVATION_COMMENT L"ReservationComment"
|
|
|
|
#define REG_FLAGS L"Flags"
|
|
|
|
#define REG_ACCESS KEY_ALL_ACCESS
|
|
#define REG_DEFAULT_SUBNET_STATE 0
|
|
#define REG_DEFAULT_SUBNET_MASK 0xFFFFFFFF
|
|
#define REG_DEFAULT_SWITCHED_FLAG FALSE
|
|
|
|
#define REG_CLASS L"DhcpClass"
|
|
|
|
#define DHCP_LAST_DOWNLOAD_TIME_VALUE L"LastDownloadTime"
|
|
#define DHCP_LAST_DOWNLOAD_TIME_TYPE REG_BINARY
|
|
|
|
#define DEF_RANGE_ALLOC 0
|
|
#define DEF_RANGE_MAX_ALLOC (~(ULONG)0)
|
|
|
|
//EndExport(constants)
|
|
|
|
const DWORD ZeroReserved = 0;
|
|
const LPVOID NullReserved = 0;
|
|
#define MAX_KEY_SIZE 512
|
|
#define DEF_RANGE_FLAG_VAL (MM_FLAG_ALLOW_DHCP)
|
|
#define DEF_RESERVATION_TYPE (MM_FLAG_ALLOW_DHCP|MM_FLAG_ALLOW_BOOTP)
|
|
|
|
//BeginExport(comment)
|
|
//================================================================================
|
|
// The basic open/traverse/close functions are here
|
|
//================================================================================
|
|
//EndExport(comment)
|
|
HKEY CurrentServerKey = NULL;
|
|
|
|
//BeginExport(function)
|
|
DWORD
|
|
DhcpRegSetCurrentServer(
|
|
IN OUT PREG_HANDLE Hdl
|
|
) //EndExport(function)
|
|
{
|
|
CurrentServerKey = Hdl? Hdl->Key : NULL;
|
|
return ERROR_SUCCESS;
|
|
}
|
|
|
|
//BeginExport(function)
|
|
DWORD
|
|
DhcpRegGetThisServer(
|
|
IN OUT PREG_HANDLE Hdl
|
|
) //EndExport(function)
|
|
{
|
|
DWORD Disposition;
|
|
|
|
if( NULL != CurrentServerKey ) {
|
|
return RegOpenKeyEx( // duplicate key
|
|
CurrentServerKey,
|
|
NULL,
|
|
ZeroReserved,
|
|
REG_ACCESS,
|
|
&Hdl->Key
|
|
);
|
|
}
|
|
return RegCreateKeyEx(
|
|
HKEY_LOCAL_MACHINE,
|
|
REG_THIS_SERVER,
|
|
ZeroReserved,
|
|
REG_CLASS,
|
|
REG_OPTION_NON_VOLATILE,
|
|
REG_ACCESS,
|
|
NULL,
|
|
&Hdl->Key,
|
|
&Disposition
|
|
);
|
|
}
|
|
|
|
//BeginExport(function)
|
|
DWORD
|
|
DhcpRegGetNextHdl(
|
|
IN PREG_HANDLE Hdl,
|
|
IN LPWSTR NextLoc,
|
|
OUT PREG_HANDLE OutHdl
|
|
) //EndExport(function)
|
|
{
|
|
DWORD Disposition;
|
|
DWORD Error;
|
|
|
|
Error = RegCreateKeyEx(
|
|
Hdl->Key,
|
|
NextLoc,
|
|
ZeroReserved,
|
|
REG_CLASS,
|
|
REG_OPTION_NON_VOLATILE,
|
|
REG_ACCESS,
|
|
NULL,
|
|
&OutHdl->Key,
|
|
&Disposition
|
|
);
|
|
return Error;
|
|
}
|
|
|
|
//BeginExport(function)
|
|
DWORD
|
|
DhcpRegCloseHdl(
|
|
IN OUT PREG_HANDLE Hdl
|
|
) //EndExport(function)
|
|
{
|
|
DWORD Error;
|
|
|
|
Error = RegCloseKey(Hdl->Key);
|
|
Hdl->Key = NULL;
|
|
return Error;
|
|
}
|
|
|
|
//BeginExport(comment)
|
|
//================================================================================
|
|
// MISC utilities for registry manipulation
|
|
//================================================================================
|
|
//EndExport(comment)
|
|
//BeginExport(function)
|
|
DWORD
|
|
DhcpRegFillSubKeys(
|
|
IN PREG_HANDLE Hdl,
|
|
IN OUT PARRAY Array // fill in a list of key names
|
|
) //EndExport(function)
|
|
{
|
|
DWORD Error;
|
|
DWORD Index;
|
|
DWORD Size;
|
|
WCHAR KeyName[MAX_KEY_SIZE];
|
|
LPWSTR ThisKeyName;
|
|
|
|
Index = 0;
|
|
do {
|
|
Size = sizeof(KeyName)/sizeof(KeyName[0]);
|
|
Error = RegEnumKeyEx(
|
|
Hdl->Key,
|
|
Index++,
|
|
KeyName,
|
|
&Size,
|
|
NullReserved,
|
|
NULL,
|
|
NULL,
|
|
NULL
|
|
);
|
|
if( ERROR_NO_MORE_ITEMS == Error ) {
|
|
Error = ERROR_SUCCESS;
|
|
break;
|
|
}
|
|
if( ERROR_SUCCESS != Error ) break;
|
|
Require(0 != Size);
|
|
Size += 1; // for the terminating L'\0' char
|
|
Size *= sizeof(WCHAR); // looks like the units are WCHAR!!
|
|
|
|
ThisKeyName = MemAlloc(Size);
|
|
if( NULL == ThisKeyName ) return ERROR_NOT_ENOUGH_MEMORY;
|
|
|
|
wcscpy(ThisKeyName, KeyName);
|
|
|
|
Error = MemArrayAddElement(Array, (LPVOID)ThisKeyName);
|
|
if( ERROR_SUCCESS != Error ) {
|
|
MemFree(ThisKeyName);
|
|
}
|
|
} while( ERROR_SUCCESS == Error );
|
|
|
|
Require(ERROR_MORE_DATA != Error);
|
|
return Index? ERROR_SUCCESS : Error; // if we added something, dont bother about reporting error
|
|
}
|
|
|
|
//BeginExport(function)
|
|
LPVOID // DWORD or LPWSTR or LPBYTE
|
|
DhcpRegRead( // read differnt values from registry and allocate if not DWORD
|
|
IN PREG_HANDLE Hdl,
|
|
IN DWORD Type, // if DWORD dont allocate memory
|
|
IN LPWSTR ValueName,
|
|
IN LPVOID RetValue // value to use if nothing found
|
|
) //EndExport(function)
|
|
{
|
|
DWORD Error;
|
|
DWORD Size;
|
|
DWORD Dword;
|
|
LPVOID Ret;
|
|
|
|
if( REG_DWORD == Type ) {
|
|
Size = sizeof(DWORD);
|
|
Ret = (LPVOID)&Dword;
|
|
} else {
|
|
Size = 0;
|
|
Error = RegQueryValueEx(
|
|
Hdl->Key,
|
|
ValueName,
|
|
NullReserved,
|
|
NULL,
|
|
NULL,
|
|
&Size
|
|
);
|
|
if( ERROR_SUCCESS != Error ) return RetValue;
|
|
if (Size == 0) return RetValue; // MemAlloc does not check the size!
|
|
Ret = MemAlloc(Size);
|
|
if( NULL == Ret ) return RetValue; // should not really happen
|
|
}
|
|
|
|
Error = RegQueryValueEx(
|
|
Hdl->Key,
|
|
ValueName,
|
|
NullReserved,
|
|
NULL,
|
|
Ret,
|
|
&Size
|
|
);
|
|
if( ERROR_SUCCESS != Error && Ret != (LPVOID)&Dword ) {
|
|
MemFree(Ret);
|
|
Ret = NULL;
|
|
}
|
|
|
|
if( ERROR_SUCCESS != Error) return RetValue;
|
|
|
|
if( Ret == (LPVOID)&Dword ) {
|
|
return ULongToPtr(Dword);
|
|
} else {
|
|
return Ret;
|
|
}
|
|
}
|
|
|
|
//BeginExport(function)
|
|
DWORD
|
|
DhcpRegReadBinary( // read binary type
|
|
IN PREG_HANDLE Hdl,
|
|
IN LPWSTR ValueName,
|
|
OUT LPBYTE *RetVal,
|
|
OUT DWORD *RetValSize
|
|
) //EndExport(function)
|
|
{
|
|
DWORD Error;
|
|
DWORD Size;
|
|
LPVOID Ret;
|
|
|
|
*RetVal = NULL;
|
|
*RetValSize = 0;
|
|
|
|
Size = 0;
|
|
Error = RegQueryValueEx(
|
|
Hdl->Key,
|
|
ValueName,
|
|
NullReserved,
|
|
NULL,
|
|
NULL,
|
|
&Size
|
|
);
|
|
if( ERROR_SUCCESS != Error ) return Error;
|
|
if( 0 == Size ) return ERROR_SUCCESS;
|
|
Ret = MemAlloc(Size);
|
|
if( NULL == Ret ) return ERROR_NOT_ENOUGH_MEMORY;
|
|
|
|
Error = RegQueryValueEx(
|
|
Hdl->Key,
|
|
ValueName,
|
|
NullReserved,
|
|
NULL,
|
|
Ret,
|
|
&Size
|
|
);
|
|
if( ERROR_SUCCESS != Error ) {
|
|
MemFree(Ret);
|
|
return Error;
|
|
}
|
|
|
|
*RetVal = Ret;
|
|
*RetValSize = Size;
|
|
return ERROR_SUCCESS;
|
|
}
|
|
|
|
//BeginExport(function)
|
|
LPWSTR
|
|
DhcpRegCombineClassAndOption( // create string based on class name and option id
|
|
IN LPWSTR ClassName,
|
|
IN LPWSTR VendorName,
|
|
IN DWORD OptionId
|
|
) //EndExport(function)
|
|
{
|
|
DWORD Size;
|
|
LPWSTR Ptr;
|
|
|
|
if( NULL == VendorName && NULL == ClassName ) {
|
|
|
|
//
|
|
// Special case usual options for downward compatability with older
|
|
// options.. (NT4 options in registry don't have any "!" in them.
|
|
//
|
|
|
|
Ptr = MemAlloc( 4 * sizeof(WCHAR) );
|
|
if( NULL == Ptr ) return NULL;
|
|
Ptr [2] = L'0' + (BYTE)(OptionId %10); OptionId /= 10;
|
|
Ptr [1] = L'0' + (BYTE)(OptionId %10); OptionId /= 10;
|
|
Ptr [0] = L'0' + (BYTE)(OptionId %10);
|
|
Ptr [3] = L'\0';
|
|
return Ptr;
|
|
}
|
|
|
|
if( NULL == VendorName ) VendorName = L"";
|
|
if( NULL == ClassName ) ClassName = L"";
|
|
Size = (wcslen(ClassName) + 1 + 5)*sizeof(WCHAR);
|
|
Size += wcslen(VendorName)*sizeof(WCHAR);
|
|
|
|
Ptr = MemAlloc(Size);
|
|
if( NULL == Ptr ) return NULL;
|
|
|
|
Size = 0;
|
|
|
|
Ptr[2+Size] = L'0' + (BYTE)(OptionId % 10); OptionId /= 10;
|
|
Ptr[1+Size] = L'0' + (BYTE)(OptionId % 10); OptionId /= 10;
|
|
Ptr[0+Size] = L'0' + (BYTE)(OptionId % 10);
|
|
Ptr[3+Size] = L'\0';
|
|
wcscat(Ptr, L"!");
|
|
wcscat(Ptr, VendorName);
|
|
wcscat(Ptr, L"!");
|
|
wcscat(Ptr, ClassName);
|
|
return Ptr;
|
|
}
|
|
|
|
//BeginExport(function)
|
|
LPWSTR
|
|
ConvertAddressToLPWSTR(
|
|
IN DWORD Address,
|
|
IN OUT LPWSTR BufferStr // input buffer to fill with dotted notation
|
|
) //EndExport(function)
|
|
{
|
|
LPSTR AddressStr;
|
|
DWORD Count;
|
|
|
|
Address = ntohl(Address);
|
|
AddressStr = inet_ntoa(*(struct in_addr *)&Address);
|
|
Count = mbstowcs(BufferStr, AddressStr, sizeof("000.000.000.000"));
|
|
if( -1 == Count ) return NULL;
|
|
return BufferStr;
|
|
}
|
|
|
|
//BeginExport(comment)
|
|
//================================================================================
|
|
// the following functions help traversing the registry
|
|
//================================================================================
|
|
//EndExport(comment)
|
|
|
|
DWORD
|
|
DhcpRegGetNextNextHdl(
|
|
IN PREG_HANDLE Hdl,
|
|
IN LPWSTR Loc1,
|
|
IN LPWSTR Loc2,
|
|
OUT PREG_HANDLE Hdl2
|
|
)
|
|
{
|
|
WCHAR Loc[MAX_KEY_SIZE*2];
|
|
Loc[ 0 ] = L'\0';
|
|
|
|
if ( ( wcslen(Loc1) + wcslen(Loc2) + 1 ) < ( MAX_KEY_SIZE * 2 ) )
|
|
{
|
|
wcscpy(Loc,Loc1);
|
|
wcscat(Loc, L"\\");
|
|
wcscat(Loc,Loc2);
|
|
}
|
|
|
|
return DhcpRegGetNextHdl(Hdl, Loc, Hdl2);
|
|
}
|
|
|
|
//BeginExport(function)
|
|
DWORD
|
|
DhcpRegServerGetSubnetHdl(
|
|
IN PREG_HANDLE Hdl,
|
|
IN LPWSTR Subnet,
|
|
OUT PREG_HANDLE Hdl2
|
|
) //EndExport(function)
|
|
{
|
|
return DhcpRegGetNextNextHdl(Hdl, REG_SERVER_SUBNETS, Subnet, Hdl2);
|
|
}
|
|
|
|
//BeginExport(function)
|
|
DWORD
|
|
DhcpRegServerGetSScopeHdl(
|
|
IN PREG_HANDLE Hdl,
|
|
IN LPWSTR SScope,
|
|
OUT PREG_HANDLE Hdl2
|
|
) //EndExport(function)
|
|
{
|
|
return DhcpRegGetNextNextHdl(Hdl, REG_SERVER_SSCOPES, SScope, Hdl2);
|
|
}
|
|
|
|
//BeginExport(function)
|
|
DWORD
|
|
DhcpRegServerGetOptDefHdl(
|
|
IN PREG_HANDLE Hdl,
|
|
IN LPWSTR OptDef,
|
|
OUT PREG_HANDLE Hdl2
|
|
) //EndExport(function)
|
|
{
|
|
return DhcpRegGetNextNextHdl(Hdl, REG_SERVER_OPTDEFS, OptDef, Hdl2);
|
|
}
|
|
|
|
//BeginExport(function)
|
|
DWORD
|
|
DhcpRegServerGetOptHdl(
|
|
IN PREG_HANDLE Hdl,
|
|
IN LPWSTR Opt,
|
|
OUT PREG_HANDLE Hdl2
|
|
) //EndExport(function)
|
|
{
|
|
return DhcpRegGetNextNextHdl(Hdl, REG_SERVER_GLOBAL_OPTIONS, Opt, Hdl2);
|
|
}
|
|
|
|
//BeginExport(function)
|
|
DWORD
|
|
DhcpRegServerGetMScopeHdl(
|
|
IN PREG_HANDLE Hdl,
|
|
IN LPWSTR MScope,
|
|
OUT PREG_HANDLE Hdl2
|
|
) //EndExport(function)
|
|
{
|
|
return DhcpRegGetNextNextHdl(Hdl, REG_SERVER_MSCOPES, MScope, Hdl2);
|
|
}
|
|
|
|
//BeginExport(function)
|
|
DWORD
|
|
DhcpRegServerGetClassDefHdl(
|
|
IN PREG_HANDLE Hdl,
|
|
IN LPWSTR ClassDef,
|
|
OUT PREG_HANDLE Hdl2
|
|
) //EndExport(function)
|
|
{
|
|
return DhcpRegGetNextNextHdl(Hdl, REG_SERVER_CLASSDEFS, ClassDef, Hdl2);
|
|
}
|
|
|
|
//BeginExport(function)
|
|
DWORD
|
|
DhcpRegSubnetGetOptHdl(
|
|
IN PREG_HANDLE Hdl,
|
|
IN LPWSTR Opt,
|
|
OUT PREG_HANDLE Hdl2
|
|
) //EndExport(function)
|
|
{
|
|
return DhcpRegGetNextNextHdl(Hdl, REG_SUBNET_OPTIONS, Opt, Hdl2);
|
|
}
|
|
|
|
//BeginExport(function)
|
|
DWORD
|
|
DhcpRegSubnetGetRangeHdl(
|
|
IN PREG_HANDLE Hdl,
|
|
IN LPWSTR Range,
|
|
OUT PREG_HANDLE Hdl2
|
|
) //EndExport(function)
|
|
{
|
|
return DhcpRegGetNextNextHdl(Hdl, REG_SUBNET_RANGES, Range, Hdl2);
|
|
}
|
|
|
|
//BeginExport(function)
|
|
DWORD
|
|
DhcpRegSubnetGetReservationHdl(
|
|
IN PREG_HANDLE Hdl,
|
|
IN LPWSTR Reservation,
|
|
OUT PREG_HANDLE Hdl2
|
|
) //EndExport(function)
|
|
{
|
|
return DhcpRegGetNextNextHdl(Hdl, REG_SUBNET_RESERVATIONS, Reservation, Hdl2);
|
|
}
|
|
|
|
//BeginExport(function)
|
|
DWORD
|
|
DhcpRegSubnetGetServerHdl(
|
|
IN PREG_HANDLE Hdl,
|
|
IN LPWSTR Server,
|
|
OUT PREG_HANDLE Hdl2
|
|
) //EndExport(function)
|
|
{
|
|
return DhcpRegGetNextNextHdl(Hdl, REG_SUBNET_SERVERS, Server, Hdl2);
|
|
}
|
|
|
|
//BeginExport(function)
|
|
DWORD
|
|
DhcpRegReservationGetOptHdl(
|
|
IN PREG_HANDLE Hdl,
|
|
IN LPWSTR OptionName,
|
|
OUT PREG_HANDLE Hdl2
|
|
) //EndExport(function)
|
|
{
|
|
return DhcpRegGetNextHdl(Hdl, OptionName, Hdl2);
|
|
}
|
|
|
|
//BeginExport(comment)
|
|
//================================================================================
|
|
// List retrieval functions.. for servers, subnets, ranges etc.
|
|
//================================================================================
|
|
//EndExport(comment)
|
|
|
|
//BeginExport(function)
|
|
DWORD
|
|
DhcpRegServerGetList(
|
|
IN PREG_HANDLE Hdl, // ptr to server location
|
|
IN OUT PARRAY OptList, // list of LPWSTR options
|
|
IN OUT PARRAY OptDefList, // list of LPWSTR optdefs
|
|
IN OUT PARRAY Subnets, // list of LPWSTR subnets
|
|
IN OUT PARRAY SScopes, // list of LPWSTR sscopes
|
|
IN OUT PARRAY ClassDefs, // list of LPWSTR classes
|
|
IN OUT PARRAY MScopes // list of LPWSTR mscopes
|
|
) //EndExport(function)
|
|
{
|
|
DWORD Error;
|
|
DWORD LocalError;
|
|
DWORD Index;
|
|
REG_HANDLE Hdl2;
|
|
struct {
|
|
PARRAY Array;
|
|
LPWSTR Location;
|
|
} Table[] = {
|
|
OptList, REG_SERVER_GLOBAL_OPTIONS,
|
|
OptDefList, REG_SERVER_OPTDEFS,
|
|
Subnets, REG_SERVER_SUBNETS,
|
|
SScopes, REG_SERVER_SSCOPES,
|
|
ClassDefs, REG_SERVER_CLASSDEFS,
|
|
MScopes, REG_SERVER_MSCOPES
|
|
};
|
|
|
|
Error = ERROR_SUCCESS;
|
|
|
|
for( Index = 0; Index < sizeof(Table)/sizeof(Table[0]); Index ++ ) {
|
|
if( NULL == Table[Index].Array ) continue;
|
|
|
|
Error = DhcpRegGetNextHdl(Hdl, Table[Index].Location, &Hdl2);
|
|
if( ERROR_SUCCESS != Error ) return Error;
|
|
|
|
Error = DhcpRegFillSubKeys(&Hdl2, Table[Index].Array);
|
|
LocalError = DhcpRegCloseHdl(&Hdl2);
|
|
Require(ERROR_SUCCESS == LocalError);
|
|
|
|
if( ERROR_SUCCESS != Error ) return Error;
|
|
}
|
|
|
|
return Error;
|
|
}
|
|
|
|
//BeginExport(function)
|
|
DWORD
|
|
DhcpRegSubnetGetExclusions(
|
|
IN PREG_HANDLE Hdl,
|
|
OUT LPBYTE *Excl,
|
|
OUT DWORD *ExclSize
|
|
) //EndExport(function)
|
|
{
|
|
DWORD Error;
|
|
DWORD Size;
|
|
DWORD Type;
|
|
|
|
if( NULL == Excl ) return ERROR_SUCCESS;
|
|
|
|
Size = 0;
|
|
Error = RegQueryValueEx(
|
|
Hdl->Key,
|
|
REG_SUBNET_EXCL,
|
|
NullReserved,
|
|
&Type,
|
|
NULL,
|
|
&Size
|
|
);
|
|
if( ERROR_SUCCESS != Error ) return Error;
|
|
|
|
*Excl = NULL;
|
|
*ExclSize = 0;
|
|
if( 0 == Size ) return ERROR_SUCCESS;
|
|
|
|
*Excl = MemAlloc(Size);
|
|
if( NULL == *Excl ) return ERROR_NOT_ENOUGH_MEMORY;
|
|
*ExclSize = Size;
|
|
Error = RegQueryValueEx(
|
|
Hdl->Key,
|
|
REG_SUBNET_EXCL,
|
|
NullReserved,
|
|
&Type,
|
|
*Excl,
|
|
ExclSize
|
|
);
|
|
if( ERROR_SUCCESS != Error ) {
|
|
MemFree(*Excl);
|
|
*Excl = NULL;
|
|
}
|
|
return Error;
|
|
}
|
|
|
|
//BeginExport(function)
|
|
DWORD
|
|
DhcpRegSubnetGetList(
|
|
IN PREG_HANDLE Hdl,
|
|
IN OUT PARRAY Servers,
|
|
IN OUT PARRAY IpRanges,
|
|
IN OUT PARRAY Reservations,
|
|
IN OUT PARRAY Options,
|
|
OUT LPBYTE *Excl,
|
|
OUT DWORD *ExclSizeInBytes
|
|
) //EndExport(function)
|
|
{
|
|
DWORD Error;
|
|
DWORD LocalError;
|
|
DWORD Index;
|
|
REG_HANDLE Hdl2;
|
|
struct {
|
|
PARRAY Array;
|
|
LPWSTR Location;
|
|
} Table[] = {
|
|
Servers, REG_SUBNET_SERVERS,
|
|
IpRanges, REG_SUBNET_RANGES,
|
|
Reservations, REG_SUBNET_RESERVATIONS,
|
|
Options, REG_SUBNET_OPTIONS,
|
|
// Exclusions are to be handled a bit differently
|
|
};
|
|
|
|
for( Index = 0; Index < sizeof(Table)/sizeof(Table[0]); Index ++ ) {
|
|
if( NULL == Table[Index].Array ) continue;
|
|
|
|
Error = DhcpRegGetNextHdl(Hdl, Table[Index].Location, &Hdl2);
|
|
if( ERROR_SUCCESS != Error ) return Error;
|
|
|
|
Error = DhcpRegFillSubKeys(&Hdl2, Table[Index].Array);
|
|
LocalError = DhcpRegCloseHdl(&Hdl2);
|
|
Require(ERROR_SUCCESS == LocalError);
|
|
|
|
if( ERROR_SUCCESS != Error ) return Error;
|
|
}
|
|
|
|
// Now read the exclusions from off here
|
|
return DhcpRegSubnetGetExclusions(Hdl, Excl, ExclSizeInBytes );
|
|
}
|
|
|
|
//BeginExport(function)
|
|
DWORD
|
|
DhcpRegSScopeGetList(
|
|
IN PREG_HANDLE Hdl,
|
|
IN OUT PARRAY Subnets
|
|
) //EndExport(function)
|
|
{
|
|
return DhcpRegFillSubKeys(Hdl, Subnets);
|
|
}
|
|
|
|
//BeginExport(function)
|
|
DWORD
|
|
DhcpRegReservationGetList(
|
|
IN PREG_HANDLE Hdl,
|
|
IN OUT PARRAY Options
|
|
) //EndExport(function)
|
|
{
|
|
return DhcpRegFillSubKeys(Hdl, Options);
|
|
}
|
|
|
|
//BeginExport(comment)
|
|
//================================================================================
|
|
// the separate stuff are here -- these are not list stuff, but just simple
|
|
// single valued attributes
|
|
// some of these actually, dont even go to the registry, but that's fine alright?
|
|
//================================================================================
|
|
//EndExport(comment)
|
|
|
|
//BeginExport(function)
|
|
DWORD
|
|
DhcpRegServerGetAttributes(
|
|
IN PREG_HANDLE Hdl,
|
|
OUT LPWSTR *Name,
|
|
OUT LPWSTR *Comment,
|
|
OUT DWORD *Flags
|
|
// more attributes will come here soon?
|
|
) //EndExport(function)
|
|
{
|
|
if( Name ) *Name = NULL;
|
|
if( Comment ) *Comment = NULL;
|
|
if( Flags ) *Flags = 0;
|
|
|
|
return ERROR_SUCCESS;
|
|
}
|
|
|
|
//BeginExport(function)
|
|
DWORD
|
|
DhcpRegSubnetGetAttributes(
|
|
IN PREG_HANDLE Hdl,
|
|
OUT LPWSTR *Name,
|
|
OUT LPWSTR *Comment,
|
|
OUT DWORD *Flags,
|
|
OUT DWORD *Address,
|
|
OUT DWORD *Mask
|
|
) //EndExport(function)
|
|
{
|
|
DWORD fSwitched;
|
|
|
|
if( Name ) *Name = DhcpRegRead(Hdl, REG_SZ, REG_SUBNET_NAME, NULL);
|
|
if( Comment ) *Comment = DhcpRegRead(Hdl, REG_SZ, REG_SUBNET_COMMENT, NULL);
|
|
if( Flags ) {
|
|
*Flags = PtrToUlong(DhcpRegRead(Hdl, REG_DWORD, REG_SUBNET_STATE, (LPVOID)REG_DEFAULT_SUBNET_STATE));
|
|
fSwitched = PtrToUlong(DhcpRegRead(Hdl, REG_DWORD, REG_SUBNET_SWITCHED_FLAG, (LPVOID)REG_DEFAULT_SWITCHED_FLAG));
|
|
if(fSwitched) SWITCHED(( DHCP_SUBNET_STATE * ) Flags);
|
|
}
|
|
if( Address )
|
|
*Address = PtrToUlong(DhcpRegRead(Hdl, REG_DWORD, REG_SUBNET_ADDRESS, (LPVOID)0));
|
|
if( Mask ) *Mask = PtrToUlong(DhcpRegRead(Hdl, REG_DWORD, REG_SUBNET_MASK, ULongToPtr(REG_DEFAULT_SUBNET_MASK)));
|
|
|
|
return ERROR_SUCCESS;
|
|
}
|
|
|
|
typedef struct {
|
|
LPVOID RetPtr;
|
|
LPWSTR ValueName;
|
|
DWORD ValueType;
|
|
LPVOID Defaults;
|
|
} ATTRIB_TBL, *PATTRIB_TBL, *LPATTRIB_TBL;
|
|
|
|
VOID
|
|
DhcpRegFillAttribTable(
|
|
IN PREG_HANDLE Hdl,
|
|
IN PATTRIB_TBL Table,
|
|
IN DWORD TableSize
|
|
) {
|
|
DWORD i;
|
|
PVOID Tmp;
|
|
|
|
for( i = 0; i < TableSize ; i ++ ) {
|
|
if( NULL == Table[i].RetPtr) continue;
|
|
Tmp = DhcpRegRead(
|
|
Hdl,
|
|
Table[i].ValueType,
|
|
Table[i].ValueName,
|
|
Table[i].Defaults
|
|
);
|
|
if( REG_DWORD == Table[i].ValueType ) {
|
|
*((DWORD *)Table[i].RetPtr) = PtrToUlong(Tmp);
|
|
} else {
|
|
*((LPVOID *)Table[i].RetPtr) = Tmp;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Hack O Rama -- This routine returns ERROR_INVALID_DATA if
|
|
// the registry has been upgraded from pre-win2k build to win2k.
|
|
// So that defaults can be chosen for ScopeId etc.
|
|
//
|
|
//BeginExport(function)
|
|
DWORD
|
|
DhcpRegMScopeGetAttributes(
|
|
IN PREG_HANDLE Hdl,
|
|
OUT LPWSTR *Comments,
|
|
OUT DWORD *State,
|
|
OUT DWORD *ScopeId,
|
|
OUT DWORD *Policy,
|
|
OUT DWORD *TTL,
|
|
OUT LPWSTR *LangTag,
|
|
OUT PDATE_TIME *ExpiryTime
|
|
) //EndExport(function)
|
|
{
|
|
DATE_TIME DefaultExpiryTime = {DHCP_DATE_TIME_INFINIT_LOW, DHCP_DATE_TIME_INFINIT_HIGH};
|
|
LPWSTR DefaultLangTag = L"en-US";
|
|
|
|
ATTRIB_TBL Table[] = {
|
|
Comments, REG_MSCOPE_COMMENT, REG_SZ, NULL,
|
|
State, REG_MSCOPE_STATE, REG_DWORD, (LPVOID)0,
|
|
ScopeId, REG_MSCOPE_SCOPEID, REG_DWORD, (LPVOID)0,
|
|
Policy, REG_MSCOPE_ADDR_POLICY, REG_DWORD, (LPVOID)0,
|
|
TTL, REG_MSCOPE_TTL, REG_DWORD, (LPVOID)DEFAULT_MCAST_TTL,
|
|
LangTag, REG_MSCOPE_LANG_TAG, REG_SZ, (LPVOID)0,
|
|
ExpiryTime, REG_MSCOPE_EXPIRY_TIME, REG_BINARY, (LPVOID)0
|
|
};
|
|
DhcpRegFillAttribTable(Hdl, Table, sizeof(Table)/sizeof(Table[0]));
|
|
if (*LangTag == 0) {
|
|
*LangTag = MemAlloc(wcslen((DefaultLangTag)+1)*sizeof(WCHAR));
|
|
if (*LangTag) {
|
|
wcscpy(*LangTag, DefaultLangTag);
|
|
} else {
|
|
return ERROR_NOT_ENOUGH_MEMORY;
|
|
}
|
|
}
|
|
if (*ExpiryTime == 0) {
|
|
*ExpiryTime = MemAlloc(sizeof (DefaultExpiryTime));
|
|
if (*ExpiryTime) {
|
|
**ExpiryTime = DefaultExpiryTime;
|
|
} else {
|
|
return ERROR_NOT_ENOUGH_MEMORY;
|
|
}
|
|
|
|
}
|
|
|
|
return ERROR_SUCCESS;
|
|
}
|
|
|
|
//BeginExport(function)
|
|
DWORD
|
|
DhcpRegOptDefGetAttributes(
|
|
IN PREG_HANDLE Hdl,
|
|
OUT LPWSTR *Name,
|
|
OUT LPWSTR *Comments,
|
|
OUT DWORD *Flags,
|
|
OUT DWORD *OptionId,
|
|
OUT LPWSTR *ClassName,
|
|
OUT LPWSTR *VendorName,
|
|
OUT LPBYTE *Value,
|
|
OUT DWORD *ValueSize
|
|
) //EndExport(function)
|
|
{
|
|
DWORD Error;
|
|
ATTRIB_TBL Table[] = {
|
|
Name, REG_OPTION_NAME, REG_SZ, NULL,
|
|
Comments, REG_OPTION_COMMENT, REG_SZ, NULL,
|
|
ClassName, REG_OPTION_CLASSNAME, REG_SZ, NULL,
|
|
VendorName, REG_OPTION_VENDORNAME, REG_SZ, NULL,
|
|
Flags, REG_OPTION_TYPE, REG_DWORD, (LPVOID)0,
|
|
OptionId, REG_OPTION_ID, REG_DWORD, (LPVOID)0
|
|
};
|
|
|
|
DhcpRegFillAttribTable(Hdl, Table, sizeof(Table)/sizeof(Table[0]));
|
|
if( Value ) {
|
|
Error = DhcpRegReadBinary(Hdl, REG_OPTION_VALUE, Value, ValueSize);
|
|
Require(*Value);
|
|
}
|
|
return ERROR_SUCCESS;
|
|
}
|
|
|
|
//BeginExport(function)
|
|
DWORD
|
|
DhcpRegSScopeGetAttributes( // superscopes dont have any information stored.. dont use this
|
|
IN PREG_HANDLE Hdl,
|
|
OUT LPWSTR *Name,
|
|
OUT LPWSTR *Comment,
|
|
OUT DWORD *Flags
|
|
) //EndExport(function)
|
|
{
|
|
Require(FALSE);
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
//BeginExport(function)
|
|
DWORD
|
|
DhcpRegClassDefGetAttributes(
|
|
IN PREG_HANDLE Hdl,
|
|
OUT LPWSTR *Name,
|
|
OUT LPWSTR *Comment,
|
|
OUT DWORD *Flags,
|
|
OUT LPBYTE *Value,
|
|
OUT DWORD *ValueSize
|
|
) //EndExport(function)
|
|
{
|
|
DWORD Error;
|
|
ATTRIB_TBL Table[] = {
|
|
Name, REG_CLASSDEF_NAME, REG_SZ, NULL,
|
|
Comment, REG_CLASSDEF_COMMENT, REG_SZ, NULL,
|
|
Flags, REG_CLASSDEF_TYPE, REG_DWORD, (LPVOID)0
|
|
};
|
|
|
|
DhcpRegFillAttribTable(Hdl, Table, sizeof(Table)/sizeof(Table[0]));
|
|
if( Value ) {
|
|
Error = DhcpRegReadBinary(Hdl, REG_CLASSDEF_VALUE, Value, ValueSize);
|
|
Require(*Value);
|
|
}
|
|
return ERROR_SUCCESS;
|
|
}
|
|
|
|
//BeginExport(function)
|
|
DWORD
|
|
DhcpRegSubnetServerGetAttributes(
|
|
IN PREG_HANDLE Hdl,
|
|
OUT LPWSTR *Name,
|
|
OUT LPWSTR *Comment,
|
|
OUT DWORD *Flags,
|
|
OUT DWORD *Address,
|
|
OUT DWORD *Role
|
|
) //EndExport(function)
|
|
{
|
|
ATTRIB_TBL Table[] = {
|
|
Name, REG_SUB_SERVER_NAME, REG_SZ, NULL,
|
|
Comment, REG_SUB_SERVER_COMMENT,REG_SZ, NULL,
|
|
Flags, REG_FLAGS, REG_DWORD, (LPVOID)0,
|
|
Address, REG_SUB_SERVER_ADDRESS,REG_DWORD, (LPVOID)0,
|
|
Role, REG_SUB_SERVER_ROLE, REG_DWORD, (LPVOID)0
|
|
};
|
|
|
|
DhcpRegFillAttribTable(Hdl, Table, sizeof(Table)/sizeof(Table[0]));
|
|
return ERROR_SUCCESS;
|
|
}
|
|
|
|
//BeginExport(function)
|
|
DWORD
|
|
DhcpRegRangeGetAttributes(
|
|
IN PREG_HANDLE Hdl,
|
|
OUT LPWSTR *Name,
|
|
OUT LPWSTR *Comment,
|
|
OUT DWORD *Flags,
|
|
OUT ULONG *AllocCount,
|
|
OUT ULONG *MaxAllocCount,
|
|
OUT DWORD *StartAddress,
|
|
OUT DWORD *EndAddress,
|
|
OUT LPBYTE *InUseClusters,
|
|
OUT DWORD *InUseClusterSize,
|
|
OUT LPBYTE *UsedClusters,
|
|
OUT DWORD *UsedClustersSize
|
|
) //EndExport(function)
|
|
{
|
|
DWORD Error;
|
|
ATTRIB_TBL Table[] = {
|
|
Name, REG_RANGE_NAME, REG_SZ, NULL,
|
|
Comment, REG_RANGE_COMMENT, REG_SZ, NULL,
|
|
Flags, REG_RANGE_FLAGS, REG_DWORD, (LPVOID)(DEF_RANGE_FLAG_VAL),
|
|
AllocCount, REG_RANGE_ALLOC, REG_DWORD, (LPVOID)(DEF_RANGE_ALLOC),
|
|
MaxAllocCount, REG_RANGE_MAX_ALLOC, REG_DWORD, (LPVOID)(ULONG_PTR)(DEF_RANGE_MAX_ALLOC),
|
|
StartAddress, REG_RANGE_START_ADDRESS, REG_DWORD, (LPVOID)0,
|
|
EndAddress, REG_RANGE_END_ADDRESS, REG_DWORD, (LPVOID)0
|
|
};
|
|
|
|
DhcpRegFillAttribTable(Hdl, Table, sizeof(Table)/sizeof(Table[0]));
|
|
if( InUseClusters ) {
|
|
Error = DhcpRegReadBinary(Hdl, REG_RANGE_INUSE_CLUSTERS, InUseClusters, InUseClusterSize);
|
|
//Require(ERROR_SUCCESS == Error); //-- after registry changed, NO_SUCH_FILE could come up here as well.
|
|
}
|
|
if( UsedClusters ) {
|
|
Error = DhcpRegReadBinary(Hdl, REG_RANGE_USED_CLUSTERS, UsedClusters, UsedClustersSize);
|
|
//Require(ERROR_SUCCESS == Error); //-- after registry changed, NO_SUCH_FILE could come up here as well.
|
|
}
|
|
return ERROR_SUCCESS;
|
|
}
|
|
|
|
//BeginExport(function)
|
|
DWORD
|
|
DhcpRegReservationGetAttributes(
|
|
IN PREG_HANDLE Hdl,
|
|
OUT LPWSTR *Name,
|
|
OUT LPWSTR *Comment,
|
|
OUT DWORD *Flags,
|
|
OUT DWORD *Address,
|
|
OUT LPBYTE *ClientUID,
|
|
OUT DWORD *ClientUIDSize
|
|
) //EndExport(function)
|
|
{
|
|
DWORD Error;
|
|
DWORD deftype = DEF_RESERVATION_TYPE;
|
|
ATTRIB_TBL Table[] = {
|
|
Name, REG_RESERVATION_NAME, REG_SZ, NULL,
|
|
Comment, REG_RESERVATION_COMMENT, REG_SZ, NULL,
|
|
Flags, REG_RESERVATION_TYPE, REG_DWORD, ULongToPtr(deftype),
|
|
Address, REG_RESERVATION_ADDRESS, REG_DWORD, (LPVOID)0,
|
|
};
|
|
|
|
DhcpRegFillAttribTable(Hdl, Table, sizeof(Table)/sizeof(Table[0]));
|
|
if( ClientUID ) {
|
|
Error = DhcpRegReadBinary(Hdl, REG_RESERVATION_UID, ClientUID, ClientUIDSize);
|
|
Require(ERROR_SUCCESS == Error);
|
|
}
|
|
return ERROR_SUCCESS;
|
|
}
|
|
|
|
//BeginExport(function)
|
|
DWORD
|
|
DhcpRegOptGetAttributes(
|
|
IN PREG_HANDLE Hdl,
|
|
OUT DWORD *OptionId,
|
|
OUT LPWSTR *ClassName,
|
|
OUT LPWSTR *VendorName,
|
|
OUT DWORD *Flags,
|
|
OUT LPBYTE *Value,
|
|
OUT DWORD *ValueSize
|
|
) //EndExport(function)
|
|
{
|
|
DWORD Error;
|
|
ATTRIB_TBL Table[] = {
|
|
OptionId, REG_OPTION_ID, REG_DWORD, (LPVOID)0,
|
|
ClassName, REG_OPTION_CLASSNAME, REG_SZ, NULL,
|
|
VendorName, REG_OPTION_VENDORNAME, REG_SZ, NULL,
|
|
Flags, REG_OPTION_TYPE, REG_DWORD, (LPVOID)0,
|
|
};
|
|
|
|
DhcpRegFillAttribTable(Hdl, Table, sizeof(Table)/sizeof(Table[0]));
|
|
if( Value ) {
|
|
Error = DhcpRegReadBinary(Hdl, REG_OPTION_VALUE, Value, ValueSize);
|
|
}
|
|
return ERROR_SUCCESS;
|
|
}
|
|
|
|
//BeginExport(comment)
|
|
//================================================================================
|
|
// the following functiosn help in writing to the registry
|
|
//================================================================================
|
|
//EndExport(comment)
|
|
|
|
typedef struct {
|
|
LPVOID Value;
|
|
DWORD Size;
|
|
DWORD Type;
|
|
LPWSTR ValueName;
|
|
} WATTRIB_TBL, *PWATTRIB_TBL, *LPWATTRIB_TBL;
|
|
|
|
DWORD
|
|
DhcpRegSaveAttribTable(
|
|
IN PREG_HANDLE Hdl,
|
|
IN PWATTRIB_TBL Table,
|
|
IN DWORD Size
|
|
)
|
|
{
|
|
DWORD i;
|
|
DWORD Error;
|
|
DWORD PtrSize;
|
|
LPBYTE Ptr;
|
|
|
|
for(i = 0; i < Size; i ++ ) {
|
|
if( NULL == Table[i].Value ) continue;
|
|
PtrSize = Table[i].Size;
|
|
Ptr = *(LPBYTE *)Table[i].Value;
|
|
switch(Table[i].Type) {
|
|
case REG_SZ:
|
|
if( NULL == *(LPWSTR *)Table[i].Value) { PtrSize = sizeof(WCHAR); Ptr = (LPBYTE)L""; break; }
|
|
PtrSize = sizeof(WCHAR)*(wcslen(*((LPWSTR *)Table[i].Value))+1);
|
|
Ptr = *(LPBYTE *)Table[i].Value;
|
|
break;
|
|
case REG_DWORD:
|
|
PtrSize = sizeof(DWORD);
|
|
Ptr = Table[i].Value; // This is because we deref this ptr down below..
|
|
break;
|
|
}
|
|
|
|
Error = RegSetValueEx(
|
|
Hdl->Key,
|
|
Table[i].ValueName,
|
|
ZeroReserved,
|
|
Table[i].Type,
|
|
Ptr,
|
|
PtrSize
|
|
);
|
|
if( ERROR_SUCCESS != Error ) {
|
|
return Error;
|
|
}
|
|
}
|
|
return ERROR_SUCCESS;
|
|
}
|
|
|
|
//BeginExport(functions)
|
|
DWORD
|
|
DhcpRegSaveSubKeys(
|
|
IN PREG_HANDLE Hdl,
|
|
IN OUT PARRAY Array
|
|
) //EndExport(function)
|
|
{
|
|
ARRAY_LOCATION Loc;
|
|
DWORD Error;
|
|
REG_HANDLE Hdl2;
|
|
LPWSTR KeyName;
|
|
|
|
Error = MemArrayInitLoc(Array, &Loc);
|
|
while(ERROR_FILE_NOT_FOUND != Error ) {
|
|
Require(ERROR_SUCCESS == Error);
|
|
|
|
Error = MemArrayGetElement(Array, &Loc, (LPVOID *)&KeyName);
|
|
Require(ERROR_SUCCESS == Error && NULL != KeyName);
|
|
|
|
Error = DhcpRegGetNextHdl(Hdl, KeyName, &Hdl2);
|
|
if( ERROR_SUCCESS != Error ) return Error;
|
|
|
|
Error = DhcpRegCloseHdl(&Hdl2);
|
|
Require(ERROR_SUCCESS == Error);
|
|
|
|
Error = MemArrayNextLoc(Array, &Loc);
|
|
}
|
|
return ERROR_SUCCESS;
|
|
}
|
|
|
|
//BeginExport(functions)
|
|
DWORD
|
|
DhcpRegSaveSubKeysPrefixed(
|
|
IN PREG_HANDLE Hdl,
|
|
IN OUT PARRAY Array,
|
|
IN LPWSTR CommonPrefix
|
|
) //EndExport(function)
|
|
{
|
|
ARRAY_LOCATION Loc;
|
|
DWORD Error;
|
|
REG_HANDLE Hdl2;
|
|
LPWSTR KeyName;
|
|
|
|
Error = MemArrayInitLoc(Array, &Loc);
|
|
while(ERROR_FILE_NOT_FOUND != Error ) {
|
|
Require(ERROR_SUCCESS == Error);
|
|
|
|
Error = MemArrayGetElement(Array, &Loc, (LPVOID *)&KeyName);
|
|
Require(ERROR_SUCCESS == Error && NULL != KeyName);
|
|
|
|
Error = DhcpRegGetNextNextHdl(Hdl, CommonPrefix, KeyName, &Hdl2);
|
|
if( ERROR_SUCCESS != Error ) return Error;
|
|
|
|
Error = DhcpRegCloseHdl(&Hdl2);
|
|
Require(ERROR_SUCCESS == Error);
|
|
|
|
Error = MemArrayNextLoc(Array, &Loc);
|
|
}
|
|
return ERROR_SUCCESS;
|
|
}
|
|
|
|
//BeginExport(function)
|
|
DWORD
|
|
DhcpRegServerSetList(
|
|
IN PREG_HANDLE Hdl,
|
|
IN PARRAY OptList, // list of LPWSTR options
|
|
IN PARRAY OptDefList, // list of LPWSTR optdefs
|
|
IN PARRAY Subnets, // list of LPWSTR subnets
|
|
IN PARRAY SScopes, // list of LPWSTR sscopes
|
|
IN PARRAY ClassDefs, // list of LPWSTR classes
|
|
IN PARRAY MScopes // list of LPWSTR mscopes
|
|
) //EndExport(function)
|
|
{
|
|
DWORD Error;
|
|
DWORD LocalError;
|
|
DWORD Index;
|
|
REG_HANDLE Hdl2;
|
|
struct {
|
|
PARRAY Array;
|
|
LPWSTR Location;
|
|
} Table[] = {
|
|
OptList, REG_SERVER_GLOBAL_OPTIONS,
|
|
OptDefList, REG_SERVER_OPTDEFS,
|
|
Subnets, REG_SERVER_SUBNETS,
|
|
SScopes, REG_SERVER_SSCOPES,
|
|
ClassDefs, REG_SERVER_CLASSDEFS,
|
|
MScopes, REG_SERVER_MSCOPES
|
|
};
|
|
|
|
Error = ERROR_SUCCESS;
|
|
|
|
for( Index = 0; Index < sizeof(Table)/sizeof(Table[0]); Index ++ ) {
|
|
if( NULL == Table[Index].Array ) continue;
|
|
|
|
Error = DhcpRegGetNextHdl(Hdl, Table[Index].Location, &Hdl2);
|
|
if( ERROR_SUCCESS != Error ) return Error;
|
|
|
|
Error = DhcpRegSaveSubKeys(&Hdl2, Table[Index].Array);
|
|
LocalError = DhcpRegCloseHdl(&Hdl2);
|
|
Require(ERROR_SUCCESS == LocalError);
|
|
|
|
if( ERROR_SUCCESS != Error ) return Error;
|
|
}
|
|
|
|
return Error;
|
|
}
|
|
|
|
//BeginExport(function)
|
|
DWORD
|
|
DhcpRegSubnetSetExclusions(
|
|
IN PREG_HANDLE Hdl,
|
|
IN LPBYTE *Excl,
|
|
IN DWORD ExclSize
|
|
) //EndExport(function)
|
|
{
|
|
DWORD Error;
|
|
WATTRIB_TBL Table[] = {
|
|
(LPVOID*)Excl, ExclSize, REG_BINARY, REG_SUBNET_EXCL,
|
|
};
|
|
|
|
return DhcpRegSaveAttribTable(Hdl, Table, sizeof(Table)/sizeof(Table[0]));
|
|
}
|
|
|
|
//BeginExport(function)
|
|
DWORD
|
|
DhcpRegSubnetSetList(
|
|
IN PREG_HANDLE Hdl,
|
|
IN PARRAY Servers,
|
|
IN PARRAY IpRanges,
|
|
IN PARRAY Reservations,
|
|
IN PARRAY Options,
|
|
IN LPBYTE *Excl,
|
|
IN DWORD ExclSizeInBytes
|
|
) //EndExport(function)
|
|
{
|
|
DWORD Error;
|
|
DWORD LocalError;
|
|
DWORD Index;
|
|
REG_HANDLE Hdl2;
|
|
struct {
|
|
PARRAY Array;
|
|
LPWSTR Location;
|
|
} Table[] = {
|
|
Servers, REG_SUBNET_SERVERS,
|
|
IpRanges, REG_SUBNET_RANGES,
|
|
Reservations, REG_SUBNET_RESERVATIONS,
|
|
Options, REG_SUBNET_OPTIONS,
|
|
// Exclusions are to be handled a bit differently
|
|
};
|
|
|
|
for( Index = 0; Index < sizeof(Table)/sizeof(Table[0]); Index ++ ) {
|
|
if( NULL == Table[Index].Array ) continue;
|
|
|
|
Error = DhcpRegGetNextHdl(Hdl, Table[Index].Location, &Hdl2);
|
|
if( ERROR_SUCCESS != Error ) return Error;
|
|
|
|
Error = DhcpRegSaveSubKeys(&Hdl2, Table[Index].Array);
|
|
LocalError = DhcpRegCloseHdl(&Hdl2);
|
|
Require(ERROR_SUCCESS == LocalError);
|
|
|
|
if( ERROR_SUCCESS != Error ) return Error;
|
|
}
|
|
|
|
// Now read the exclusions from off here
|
|
return DhcpRegSubnetSetExclusions(Hdl, Excl, ExclSizeInBytes );
|
|
}
|
|
|
|
//BeginExport(function)
|
|
DWORD
|
|
DhcpRegSScopeSetList(
|
|
IN PREG_HANDLE Hdl,
|
|
IN OUT PARRAY Subnets
|
|
) //EndExport(function)
|
|
{
|
|
return DhcpRegSaveSubKeys(Hdl, Subnets);
|
|
}
|
|
|
|
//BeginExport(function)
|
|
DWORD
|
|
DhcpRegReservationSetList(
|
|
IN PREG_HANDLE Hdl,
|
|
IN PARRAY Subnets
|
|
) //EndExport(function)
|
|
{
|
|
return DhcpRegSaveSubKeys(Hdl, Subnets);
|
|
}
|
|
|
|
//BeginExport(comment)
|
|
//================================================================================
|
|
// the single stuff are here -- these are not list stuff, but just simple
|
|
// single valued attributes
|
|
// some of these actually, dont even go to the registry, but that's fine alright?
|
|
//================================================================================
|
|
//EndExport(comment)
|
|
|
|
//BeginExport(function)
|
|
DWORD
|
|
DhcpRegServerSetAttributes(
|
|
IN PREG_HANDLE Hdl,
|
|
IN LPWSTR *Name,
|
|
IN LPWSTR *Comment,
|
|
IN DWORD *Flags
|
|
// more attributes will come here soon?
|
|
) //EndExport(function)
|
|
{
|
|
#if 0
|
|
WATTRIB_TBL Table[] = {
|
|
Name, REG_SERVER_NAME
|
|
}
|
|
if( Name ) *Name = NULL;
|
|
if( Comment ) *Comment = NULL;
|
|
if( Flags ) *Flags = 0;
|
|
#endif
|
|
|
|
return ERROR_SUCCESS;
|
|
}
|
|
|
|
DWORD
|
|
DhcpRegSubnetSetAttributesInternal(
|
|
IN PREG_HANDLE Hdl,
|
|
IN LPWSTR *Name,
|
|
IN LPWSTR *Comment,
|
|
IN DWORD *Flags,
|
|
IN DWORD *Address,
|
|
IN DWORD *Mask,
|
|
IN DWORD *SwitchedNetwork
|
|
)
|
|
{
|
|
DWORD Error, SrvIpAddress, SrvRole;
|
|
LPWSTR EmptyString;
|
|
REG_HANDLE Hdl2;
|
|
WATTRIB_TBL Table[] = {
|
|
Name, 0, REG_SZ, REG_SUBNET_NAME,
|
|
Comment, 0, REG_SZ, REG_SUBNET_COMMENT,
|
|
Flags, 0, REG_DWORD, REG_SUBNET_STATE,
|
|
Address, 0, REG_DWORD, REG_SUBNET_ADDRESS,
|
|
Mask, 0, REG_DWORD, REG_SUBNET_MASK,
|
|
SwitchedNetwork, 0, REG_DWORD, REG_SUBNET_SWITCHED_FLAG
|
|
};
|
|
|
|
Error = DhcpRegSaveAttribTable(Hdl, Table, sizeof(Table)/sizeof(Table[0]));
|
|
if( NO_ERROR != Error ) return Error;
|
|
|
|
//
|
|
// The following lines are for backward compat with NT4.
|
|
//
|
|
|
|
//
|
|
// Create the reservation key in any case
|
|
//
|
|
|
|
Error = DhcpRegGetNextHdl(
|
|
Hdl, REG_SUBNET_RESERVATIONS, &Hdl2 );
|
|
if( NO_ERROR != Error ) return Error;
|
|
|
|
DhcpRegCloseHdl( &Hdl2 );
|
|
|
|
//
|
|
// Create the servers key
|
|
//
|
|
|
|
Error = DhcpRegGetNextHdl(
|
|
Hdl, L"DHCPServers", &Hdl2 );
|
|
if( NO_ERROR != Error ) return Error;
|
|
DhcpRegCloseHdl( &Hdl2 );
|
|
|
|
Error = DhcpRegGetNextNextHdl(
|
|
Hdl, L"DHCPServers", L"127.0.0.1", &Hdl2 );
|
|
if( NO_ERROR != Error ) return Error;
|
|
|
|
//
|
|
// Now set the role of the newly created server as primary
|
|
//
|
|
SrvIpAddress = INADDR_LOOPBACK;
|
|
SrvRole = 1; // primary
|
|
EmptyString = L"";
|
|
{
|
|
WATTRIB_TBL SrvTable[] = {
|
|
&SrvRole, 0, REG_DWORD, L"Role",
|
|
&SrvIpAddress, 0, REG_DWORD, L"ServerIpAddress",
|
|
&EmptyString, 0, REG_SZ, L"ServerHostName",
|
|
&EmptyString, 0, REG_SZ, L"ServerNetBiosName"
|
|
};
|
|
|
|
Error = DhcpRegSaveAttribTable(
|
|
&Hdl2, SrvTable, sizeof(SrvTable)/sizeof(SrvTable[0]));
|
|
}
|
|
|
|
DhcpRegCloseHdl(&Hdl2);
|
|
return Error;
|
|
}
|
|
|
|
//BeginExport(function)
|
|
DWORD
|
|
DhcpRegSubnetSetAttributes(
|
|
IN PREG_HANDLE Hdl,
|
|
IN LPWSTR *Name,
|
|
IN LPWSTR *Comment,
|
|
IN DWORD *Flags,
|
|
IN DWORD *Address,
|
|
IN DWORD *Mask
|
|
) //EndExport(function)
|
|
{
|
|
DWORD xFlags, SwitchedNetwork = FALSE;
|
|
OSVERSIONINFO Ver;
|
|
|
|
Ver.dwOSVersionInfoSize = sizeof(Ver);
|
|
if( FALSE == GetVersionEx(&Ver) ) return GetLastError();
|
|
|
|
if( Flags && Ver.dwMajorVersion < 5 ) {
|
|
SwitchedNetwork = IS_SWITCHED(*Flags);
|
|
xFlags = IS_DISABLED(*Flags);
|
|
Flags = &xFlags;
|
|
}
|
|
|
|
return DhcpRegSubnetSetAttributesInternal(
|
|
Hdl, Name, Comment, Flags, Address, Mask,
|
|
Flags ? &SwitchedNetwork : NULL );
|
|
}
|
|
|
|
//BeginExport(function)
|
|
DWORD
|
|
DhcpRegMScopeSetAttributes(
|
|
IN PREG_HANDLE Hdl,
|
|
IN LPWSTR *Comments,
|
|
IN DWORD *State,
|
|
IN DWORD *ScopeId,
|
|
IN DWORD *Policy,
|
|
IN DWORD *TTL,
|
|
IN LPWSTR *LangTag,
|
|
IN PDATE_TIME *ExpiryTime
|
|
) //EndExport(function)
|
|
{
|
|
WATTRIB_TBL Table[] = {
|
|
Comments, 0, REG_SZ, REG_MSCOPE_COMMENT,
|
|
State, 0, REG_DWORD, REG_MSCOPE_STATE,
|
|
ScopeId, 0, REG_DWORD, REG_MSCOPE_SCOPEID,
|
|
Policy, 0, REG_DWORD, REG_MSCOPE_ADDR_POLICY,
|
|
TTL, 0, REG_DWORD, REG_MSCOPE_TTL,
|
|
LangTag, 0, REG_SZ, REG_MSCOPE_LANG_TAG,
|
|
ExpiryTime, sizeof(**ExpiryTime), REG_BINARY, REG_MSCOPE_EXPIRY_TIME
|
|
};
|
|
return DhcpRegSaveAttribTable(Hdl, Table, sizeof(Table)/sizeof(Table[0]));
|
|
}
|
|
|
|
//BeginExport(function)
|
|
DWORD
|
|
DhcpRegOptDefSetAttributes(
|
|
IN PREG_HANDLE Hdl,
|
|
IN LPWSTR *Name,
|
|
IN LPWSTR *Comments,
|
|
IN DWORD *Flags,
|
|
IN DWORD *OptionId,
|
|
IN LPWSTR *ClassName,
|
|
IN LPWSTR *VendorName,
|
|
IN LPBYTE *Value,
|
|
IN DWORD ValueSize
|
|
) //EndExport(function)
|
|
{
|
|
DWORD Error;
|
|
WATTRIB_TBL Table[] = {
|
|
Name, 0, REG_SZ, REG_OPTION_NAME,
|
|
Comments, 0, REG_SZ, REG_OPTION_COMMENT,
|
|
ClassName, 0, REG_SZ, REG_OPTION_CLASSNAME,
|
|
VendorName, 0, REG_SZ, REG_OPTION_VENDORNAME,
|
|
Flags, 0, REG_DWORD, REG_OPTION_TYPE,
|
|
OptionId, 0, REG_DWORD, REG_OPTION_ID,
|
|
Value, ValueSize,REG_BINARY, REG_OPTION_VALUE
|
|
};
|
|
|
|
return DhcpRegSaveAttribTable(Hdl, Table, sizeof(Table)/sizeof(Table[0]));
|
|
}
|
|
|
|
//BeginExport(function)
|
|
DWORD
|
|
DhcpRegSScopeSetAttributes( // superscopes dont have any information stored.. dont use this
|
|
IN PREG_HANDLE Hdl,
|
|
IN LPWSTR *Name,
|
|
IN LPWSTR *Comment,
|
|
IN DWORD *Flags
|
|
) //EndExport(function)
|
|
{
|
|
Require(FALSE);
|
|
return ERROR_INVALID_PARAMETER;
|
|
}
|
|
|
|
//BeginExport(function)
|
|
DWORD
|
|
DhcpRegClassDefSetAttributes(
|
|
IN PREG_HANDLE Hdl,
|
|
IN LPWSTR *Name,
|
|
IN LPWSTR *Comment,
|
|
IN DWORD *Flags,
|
|
IN LPBYTE *Value,
|
|
IN DWORD ValueSize
|
|
) //EndExport(function)
|
|
{
|
|
DWORD Error;
|
|
WATTRIB_TBL Table[] = {
|
|
Name, 0, REG_SZ, REG_CLASSDEF_NAME,
|
|
Comment, 0, REG_SZ, REG_CLASSDEF_COMMENT,
|
|
Flags, 0, REG_DWORD, REG_CLASSDEF_TYPE,
|
|
Value, ValueSize,REG_BINARY, REG_CLASSDEF_VALUE
|
|
};
|
|
|
|
return DhcpRegSaveAttribTable(Hdl, Table, sizeof(Table)/sizeof(Table[0]));
|
|
}
|
|
|
|
//BeginExport(function)
|
|
DWORD
|
|
DhcpRegSubnetServerSetAttributes(
|
|
IN PREG_HANDLE Hdl,
|
|
IN LPWSTR *Name,
|
|
IN LPWSTR *Comment,
|
|
IN DWORD *Flags,
|
|
IN DWORD *Address,
|
|
IN DWORD *Role
|
|
) //EndExport(function)
|
|
{
|
|
WATTRIB_TBL Table[] = {
|
|
Name, 0, REG_SZ, REG_SUB_SERVER_NAME,
|
|
Comment, 0, REG_SZ, REG_SUB_SERVER_COMMENT,
|
|
Flags, 0, REG_DWORD, REG_FLAGS,
|
|
Address, 0, REG_DWORD, REG_SUB_SERVER_ADDRESS,
|
|
Role, 0, REG_DWORD, REG_SUB_SERVER_ROLE,
|
|
};
|
|
|
|
return DhcpRegSaveAttribTable(Hdl, Table, sizeof(Table)/sizeof(Table[0]));
|
|
}
|
|
|
|
//BeginExport(function)
|
|
DWORD
|
|
DhcpRegRangeSetAttributes(
|
|
IN PREG_HANDLE Hdl,
|
|
IN LPWSTR *Name,
|
|
IN LPWSTR *Comment,
|
|
IN DWORD *Flags,
|
|
IN ULONG *AllocCount,
|
|
IN ULONG *MaxAllocCount,
|
|
IN DWORD *StartAddress,
|
|
IN DWORD *EndAddress,
|
|
IN LPBYTE *InUseClusters,
|
|
IN DWORD InUseClusterSize,
|
|
IN LPBYTE *UsedClusters,
|
|
IN DWORD UsedClustersSize
|
|
) //EndExport(function)
|
|
{
|
|
DWORD Error;
|
|
WATTRIB_TBL Table[] = {
|
|
Name, 0, REG_SZ, REG_RANGE_NAME,
|
|
Comment, 0, REG_SZ, REG_RANGE_COMMENT,
|
|
Flags, 0, REG_DWORD, REG_RANGE_FLAGS,
|
|
AllocCount, 0, REG_DWORD, REG_RANGE_ALLOC,
|
|
MaxAllocCount, 0, REG_DWORD, REG_RANGE_MAX_ALLOC,
|
|
StartAddress, 0, REG_DWORD, REG_RANGE_START_ADDRESS,
|
|
EndAddress, 0, REG_DWORD, REG_RANGE_END_ADDRESS,
|
|
InUseClusters, InUseClusterSize, REG_BINARY, REG_RANGE_INUSE_CLUSTERS,
|
|
UsedClusters, UsedClustersSize, REG_BINARY, REG_RANGE_USED_CLUSTERS,
|
|
};
|
|
|
|
return DhcpRegSaveAttribTable(Hdl, Table, sizeof(Table)/sizeof(Table[0]));
|
|
}
|
|
|
|
//BeginExport(function)
|
|
DWORD
|
|
DhcpRegReservationSetAttributes(
|
|
IN PREG_HANDLE Hdl,
|
|
IN LPWSTR *Name,
|
|
IN LPWSTR *Comment,
|
|
IN DWORD *Flags,
|
|
IN DWORD *Address,
|
|
IN LPBYTE *ClientUID,
|
|
IN DWORD ClientUIDSize
|
|
) //EndExport(function)
|
|
{
|
|
DWORD Error;
|
|
WATTRIB_TBL Table[] = {
|
|
Name, 0, REG_SZ, REG_RESERVATION_NAME,
|
|
Comment, 0, REG_SZ, REG_RESERVATION_COMMENT,
|
|
Flags, 0, REG_DWORD, REG_RESERVATION_TYPE,
|
|
Address, 0, REG_DWORD, REG_RESERVATION_ADDRESS,
|
|
ClientUID, ClientUIDSize, REG_BINARY, REG_RESERVATION_UID,
|
|
};
|
|
|
|
return DhcpRegSaveAttribTable(Hdl, Table, sizeof(Table)/sizeof(Table[0]));
|
|
}
|
|
|
|
//BeginExport(function)
|
|
DWORD
|
|
DhcpRegOptSetAttributes(
|
|
IN PREG_HANDLE Hdl,
|
|
IN DWORD *OptionId,
|
|
IN LPWSTR *ClassName,
|
|
IN LPWSTR *VendorName,
|
|
IN DWORD *Flags,
|
|
IN LPBYTE *Value,
|
|
IN DWORD ValueSize
|
|
) //EndExport(function)
|
|
{
|
|
DWORD Error;
|
|
WATTRIB_TBL Table[] = {
|
|
OptionId, 0, REG_DWORD, REG_OPTION_ID,
|
|
ClassName, 0, REG_SZ, REG_OPTION_CLASSNAME,
|
|
VendorName, 0, REG_SZ, REG_OPTION_VENDORNAME,
|
|
Flags, 0, REG_DWORD, REG_OPTION_TYPE,
|
|
Value, ValueSize,REG_BINARY, REG_OPTION_VALUE,
|
|
};
|
|
|
|
return DhcpRegSaveAttribTable(Hdl, Table, sizeof(Table)/sizeof(Table[0]));
|
|
}
|
|
|
|
//================================================================================
|
|
// recursive deleting of keys...
|
|
//================================================================================
|
|
|
|
//BeginExport(function)
|
|
DWORD
|
|
DhcpRegRecurseDelete(
|
|
IN PREG_HANDLE Hdl,
|
|
IN LPWSTR KeyName
|
|
) //EndExport(function)
|
|
{
|
|
REG_HANDLE Hdl2;
|
|
DWORD Error;
|
|
DWORD LocalError, RetError;
|
|
ARRAY Array; // sub keys
|
|
ARRAY_LOCATION Loc;
|
|
LPWSTR SubKey;
|
|
|
|
RetError = ERROR_SUCCESS;
|
|
|
|
Error = DhcpRegGetNextHdl(Hdl, KeyName, &Hdl2);
|
|
if( ERROR_SUCCESS != Error ) return Error;
|
|
|
|
Error = MemArrayInit(&Array);
|
|
if( ERROR_SUCCESS != Error ) {
|
|
LocalError = DhcpRegCloseHdl(&Hdl2);
|
|
Require(ERROR_SUCCESS == LocalError);
|
|
return Error;
|
|
}
|
|
|
|
Error = DhcpRegFillSubKeys(&Hdl2, &Array);
|
|
Require( ERROR_SUCCESS == Error );
|
|
|
|
Error = MemArrayInitLoc(&Array, &Loc);
|
|
while(ERROR_FILE_NOT_FOUND != Error) {
|
|
Require(ERROR_SUCCESS == Error);
|
|
|
|
Error = MemArrayGetElement(&Array, &Loc, (LPVOID *)&SubKey);
|
|
Require(ERROR_SUCCESS == Error && SubKey);
|
|
|
|
Error = DhcpRegRecurseDelete(&Hdl2, SubKey);
|
|
if( ERROR_SUCCESS != Error ) RetError = Error;
|
|
|
|
if( SubKey ) MemFree(SubKey);
|
|
|
|
Error = MemArrayNextLoc(&Array, &Loc);
|
|
}
|
|
|
|
Error = MemArrayCleanup(&Array);
|
|
Require(ERROR_SUCCESS == Error);
|
|
|
|
Error = DhcpRegCloseHdl(&Hdl2);
|
|
Require(ERROR_SUCCESS == Error);
|
|
|
|
Error = RegDeleteKey(Hdl->Key, KeyName);
|
|
if( ERROR_SUCCESS != Error ) RetError = Error;
|
|
|
|
return RetError;
|
|
}
|
|
|
|
//BeginExport(function)
|
|
DWORD
|
|
DhcpRegRecurseDeleteBunch(
|
|
IN PREG_HANDLE Hdl,
|
|
IN PARRAY KeysArray
|
|
) //EndExport(function)
|
|
{
|
|
ARRAY_LOCATION Loc;
|
|
LPWSTR ThisKeyName;
|
|
DWORD Error;
|
|
|
|
Error = MemArrayInitLoc(KeysArray, &Loc);
|
|
while( ERROR_FILE_NOT_FOUND != Error ) {
|
|
Require(ERROR_SUCCESS == Error);
|
|
|
|
Error = MemArrayGetElement(KeysArray, &Loc, &ThisKeyName);
|
|
Require(ERROR_SUCCESS == Error && NULL != ThisKeyName);
|
|
|
|
Error = DhcpRegRecurseDelete(Hdl, ThisKeyName);
|
|
if( ERROR_SUCCESS != Error ) return Error;
|
|
|
|
Error = MemArrayNextLoc(KeysArray, &Loc);
|
|
}
|
|
|
|
return ERROR_SUCCESS;
|
|
}
|
|
|
|
static
|
|
VOID
|
|
GetLocalFileTime( // fill in filetime struct w/ current local time
|
|
IN OUT LPFILETIME Time // struct to fill in
|
|
)
|
|
{
|
|
BOOL Status;
|
|
SYSTEMTIME SysTime;
|
|
|
|
GetSystemTime(&SysTime); // get sys time as UTC time.
|
|
Status = SystemTimeToFileTime(&SysTime,Time); // conver system time to file time
|
|
if( FALSE == Status ) { // convert failed?
|
|
Time->dwLowDateTime = 0xFFFFFFFF; // set time to weird value in case of failiure
|
|
Time->dwHighDateTime = 0xFFFFFFFF;
|
|
}
|
|
}
|
|
|
|
//BeginExport(function)
|
|
DWORD
|
|
DhcpRegUpdateTime( // update the last modified time
|
|
VOID
|
|
) //EndExport(function)
|
|
{
|
|
FILETIME Time;
|
|
DWORD Err, Size;
|
|
HKEY hKey;
|
|
|
|
GetLocalFileTime(&Time); // first get current time
|
|
(*(LONGLONG *)&Time) += 10*1000*60*2; // 2 minutes (Filetime is in 100-nano seconds)
|
|
// HACK! the previous line is there as the DS takes a little while to update the
|
|
// last changed time..
|
|
Time.dwLowDateTime =Time.dwHighDateTime =0; // set time to "long back" initially
|
|
Err = RegOpenKeyEx // try to open the config key.
|
|
(
|
|
/* hKey */ HKEY_LOCAL_MACHINE,
|
|
/* lpSubKey */ REG_THIS_SERVER,
|
|
/* ulOptions */ 0 /* Reserved */ ,
|
|
/* samDesired */ KEY_ALL_ACCESS,
|
|
/* phkResult */ &hKey
|
|
);
|
|
if( ERROR_SUCCESS != Err ) return Err; // time is still set to ages back
|
|
|
|
Err = RegSetValueEx // now save the time value
|
|
(
|
|
/* hKey */ hKey,
|
|
/* lpValueName */ DHCP_LAST_DOWNLOAD_TIME_VALUE,
|
|
/* lpReserved */ 0,
|
|
/* lpType */ REG_BINARY,
|
|
/* lpData */ (LPBYTE)&Time,
|
|
/* lpcData */ sizeof(Time)
|
|
);
|
|
RegCloseKey(hKey); // close key before we forget
|
|
|
|
return Err;
|
|
}
|
|
|
|
|
|
//================================================================================
|
|
// end of file
|
|
//================================================================================
|
|
|
|
|
|
|