645 lines
24 KiB
C
645 lines
24 KiB
C
|
//================================================================================
|
||
|
// Copyright (C) 1997 Microsoft Corporation
|
||
|
// Author: RameshV
|
||
|
// Description: Download and Upload related code.
|
||
|
//================================================================================
|
||
|
|
||
|
//================================================================================
|
||
|
// includes
|
||
|
//================================================================================
|
||
|
#include <hdrmacro.h>
|
||
|
#include <store.h>
|
||
|
#include <dhcpmsg.h>
|
||
|
#include <wchar.h>
|
||
|
#include <dhcpbas.h>
|
||
|
#include <mm\opt.h>
|
||
|
#include <mm\optl.h>
|
||
|
#include <mm\optdefl.h>
|
||
|
#include <mm\optclass.h>
|
||
|
#include <mm\classdefl.h>
|
||
|
#include <mm\bitmask.h>
|
||
|
#include <mm\reserve.h>
|
||
|
#include <mm\range.h>
|
||
|
#include <mm\subnet.h>
|
||
|
#include <mm\sscope.h>
|
||
|
#include <mm\oclassdl.h>
|
||
|
#include <mm\server.h>
|
||
|
#include <mm\address.h>
|
||
|
#include <mm\server2.h>
|
||
|
#include <mm\memfree.h>
|
||
|
#include <mmreg\regutil.h>
|
||
|
#include <mmreg\regread.h>
|
||
|
#include <mmreg\regsave.h>
|
||
|
#include <dhcpapi.h>
|
||
|
#include <delete.h>
|
||
|
#include <st_srvr.h>
|
||
|
#include <rpcapi2.h>
|
||
|
#include <rpcstubs.h>
|
||
|
|
||
|
//================================================================================
|
||
|
// utilities
|
||
|
//================================================================================
|
||
|
|
||
|
//DOC DhcpDsServerGetLastUpdateTime gets the last update time for this server in the DS
|
||
|
DWORD
|
||
|
DhcpDsServerGetLastUpdateTime( // get last update time for server
|
||
|
IN LPSTORE_HANDLE hServer, // server to get last update time of
|
||
|
IN OUT LPFILETIME Time // set this struct appropriately
|
||
|
)
|
||
|
{
|
||
|
HRESULT Err;
|
||
|
DWORD nAttributes;
|
||
|
LPWSTR TimeAttrName; // attribute name for time..
|
||
|
PADS_ATTR_INFO Attributes;
|
||
|
SYSTEMTIME SysTime;
|
||
|
|
||
|
TimeAttrName = DHCP_ATTRIB_WHEN_CHANGED;
|
||
|
|
||
|
Attributes = NULL; nAttributes = 0;
|
||
|
Err = ADSIGetObjectAttributes // now read the last changed time attr
|
||
|
(
|
||
|
hServer->ADSIHandle,
|
||
|
&TimeAttrName,
|
||
|
1, // only 1 attribute in above array
|
||
|
&Attributes,
|
||
|
&nAttributes
|
||
|
);
|
||
|
if( FAILED(Err) || 0 == nAttributes || 0 == Attributes->dwNumValues ) {
|
||
|
if( Attributes ) {
|
||
|
FreeADsMem(Attributes);
|
||
|
return ERROR_GEN_FAILURE; // blanket error? maybe better err msg..
|
||
|
}
|
||
|
return ConvertHresult(Err);
|
||
|
}
|
||
|
|
||
|
if( Attributes->pADsValues[0].dwType != ADSTYPE_UTC_TIME ) {
|
||
|
FreeADsMem(Attributes);
|
||
|
return ERROR_GEN_FAILURE; // unexpected data format
|
||
|
}
|
||
|
|
||
|
SysTime = Attributes->pADsValues[0].UTCTime; // copy time structs
|
||
|
FreeADsMem(Attributes);
|
||
|
|
||
|
Err = SystemTimeToFileTime(&SysTime, Time); // try to convert to filetime struct
|
||
|
if( FAILED( Err ) ) return GetLastError(); // something went wrong?
|
||
|
return ERROR_SUCCESS;
|
||
|
}
|
||
|
|
||
|
BOOL _inline
|
||
|
AddressFoundInHostent(
|
||
|
IN DHCP_IP_ADDRESS AddrToSearch, // Host-Order addr
|
||
|
IN HOSTENT *ServerEntry // entry to search for..
|
||
|
)
|
||
|
{
|
||
|
ULONG nAddresses, ThisAddress;
|
||
|
|
||
|
if( NULL == ServerEntry ) return FALSE; // no address to search in
|
||
|
|
||
|
nAddresses = 0; // have a host entry to compare for addresses
|
||
|
while( ServerEntry->h_addr_list[nAddresses] ) {
|
||
|
ThisAddress = ntohl(*(DHCP_IP_ADDRESS*)ServerEntry->h_addr_list[nAddresses++] );
|
||
|
if( ThisAddress == AddrToSearch ) {
|
||
|
return TRUE; // yeah address matched.
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
|
||
|
//================================================================================
|
||
|
// exports
|
||
|
//================================================================================
|
||
|
//BeginExport(function)
|
||
|
//DOC DhcpDsGetLastUpdateTime gets the last update time for the server
|
||
|
//DOC specified by name. If the server does not exist, or if server object doesnt
|
||
|
//DOC exist, then an error is returned. If the time value
|
||
|
//DOC does not exist on the server object, again, an error is returned.
|
||
|
DWORD
|
||
|
DhcpDsGetLastUpdateTime( // last update time for server
|
||
|
IN LPWSTR ServerName, // this is server of interest
|
||
|
IN OUT LPFILETIME Time // fill in this w./ the time
|
||
|
) //EndExport(function)
|
||
|
{
|
||
|
DWORD Err,i, LocType ;
|
||
|
LPDHCPDS_SERVERS Servers;
|
||
|
extern STORE_HANDLE hDhcpC, hDhcpRoot; // From rpcstubs.c
|
||
|
LPWSTR Location, LocStr;
|
||
|
BOOL Found;
|
||
|
STORE_HANDLE hServer;
|
||
|
HOSTENT *ServerEntry;
|
||
|
|
||
|
if( NULL == ServerName ) return ERROR_INVALID_PARAMETER;
|
||
|
do { // name to IP lookup
|
||
|
CHAR TmpBuf[300];
|
||
|
wcstombs(TmpBuf, ServerName, sizeof(TmpBuf)-1);
|
||
|
TmpBuf[sizeof(TmpBuf)-1] = '\0';
|
||
|
ServerEntry = gethostbyname(TmpBuf);
|
||
|
} while(0);
|
||
|
|
||
|
Servers = NULL;
|
||
|
Err = DhcpDsEnumServers // first get a list of servers
|
||
|
(
|
||
|
/* hDhcpC */ &hDhcpC, // frm rpcstubs.c, opened in DhcpDsInitDS
|
||
|
/* hDhcpRoot */ &hDhcpRoot, // ditto
|
||
|
/* Reserved */ DDS_RESERVED_DWORD,
|
||
|
/* ServersInfo */ &Servers
|
||
|
);
|
||
|
if( ERROR_SUCCESS != Err ) {
|
||
|
Time->dwLowDateTime = Time->dwHighDateTime = 0;
|
||
|
return Err; // error.. return w/ no time
|
||
|
}
|
||
|
|
||
|
Found = FALSE;
|
||
|
LocStr = Location = NULL; // initialize..
|
||
|
for( i = 0; i < Servers->NumElements ; i ++ ) {
|
||
|
if( 0 != _wcsicmp(ServerName, Servers->Servers[i].ServerName) &&
|
||
|
!AddressFoundInHostent(Servers->Servers[i].ServerAddress, ServerEntry) ) {
|
||
|
|
||
|
continue; // ughm.. not the same server..
|
||
|
|
||
|
} else { // ok got the server
|
||
|
|
||
|
Location = Servers->Servers[i].DsLocation;
|
||
|
LocType = Servers->Servers[i].DsLocType;
|
||
|
Found = TRUE;
|
||
|
if( NULL != Location ) break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if( ! Found ) { // could not find server in list..?
|
||
|
MemFree(Servers);
|
||
|
return ERROR_FILE_NOT_FOUND;
|
||
|
}
|
||
|
|
||
|
if( NULL == Location ) { // could not find server location?
|
||
|
MemFree(Servers); // dont need this anymore
|
||
|
Servers = NULL;
|
||
|
Location = MakeColumnName(ServerName); // just presume it is under hDhcpC container
|
||
|
LocType = StoreGetChildType; // child type
|
||
|
if( NULL == Location ) return ERROR_NOT_ENOUGH_MEMORY;
|
||
|
}
|
||
|
|
||
|
Err = StoreGetHandle // now try to open the server object
|
||
|
(
|
||
|
/* hStore */ &hDhcpC,
|
||
|
/* Reserved */ DDS_RESERVED_DWORD,
|
||
|
/* StoreGetType */ LocType,
|
||
|
/* Path */ Location,
|
||
|
/* hStoreOut */ &hServer
|
||
|
);
|
||
|
|
||
|
if( Servers ) { // Location points into this
|
||
|
MemFree(Servers); // freeing this also free Location
|
||
|
} else { // Location is allocated memory
|
||
|
MemFree(Location);
|
||
|
}
|
||
|
|
||
|
if( ERROR_SUCCESS != Err ) return Err; // some DS trouble?
|
||
|
|
||
|
Err = DhcpDsServerGetLastUpdateTime(&hServer, Time);
|
||
|
|
||
|
(void)StoreCleanupHandle(&hServer, 0); // assume this wont fail.
|
||
|
|
||
|
return Err;
|
||
|
}
|
||
|
|
||
|
//DOC ServerUploadClasses does rpc calls to server and copies stuff over to DS.
|
||
|
DWORD
|
||
|
ServerUploadClasses( // upload classes info to DS
|
||
|
IN OUT LPSTORE_HANDLE hDhcpC, // dhcp container to store at
|
||
|
IN OUT LPSTORE_HANDLE hServer, // server obj in DS
|
||
|
IN LPWSTR ServerAddress // server ip address
|
||
|
)
|
||
|
{
|
||
|
DWORD Err, Resume, PrefMax, i, nRead, nTotal;
|
||
|
LPDHCP_CLASS_INFO_ARRAY ClassesInfo;
|
||
|
|
||
|
Resume = 0; PrefMax = 0xFFFFFFFF; nRead = nTotal = 0;
|
||
|
ClassesInfo = NULL;
|
||
|
Err = DhcpEnumClasses(ServerAddress, 0, &Resume, PrefMax, &ClassesInfo, &nRead, &nTotal);
|
||
|
if( ERROR_NO_MORE_ITEMS == Err ) return ERROR_SUCCESS;
|
||
|
if( ERROR_SUCCESS != Err ) return Err; // could not enumerate classes.
|
||
|
|
||
|
for( i = 0; i < ClassesInfo->NumElements; i ++ ) {
|
||
|
Err = DhcpCreateClassDS(ServerAddress, 0, &ClassesInfo->Classes[i]);
|
||
|
if( ERROR_SUCCESS != Err ) break;
|
||
|
#if 0
|
||
|
Err = ServerUploadOptDefsForClass(
|
||
|
hDhcpC,
|
||
|
hServer,
|
||
|
ServerAddress,
|
||
|
ClassesInfo->Classes[i].ClassName
|
||
|
);
|
||
|
if( ERROR_SUCCESS != Err ) break;
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
if( ClassesInfo ) MemFree(ClassesInfo);
|
||
|
return Err;
|
||
|
}
|
||
|
|
||
|
//DOC ServerUploadOptdefs does rpc calls to server and copies stuff over to DS
|
||
|
DWORD
|
||
|
ServerUploadOptdefs( // upload opt defs info to DS
|
||
|
IN OUT LPSTORE_HANDLE hDhcpC, // dhcp container to store at
|
||
|
IN OUT LPSTORE_HANDLE hServer, // server obj in DS
|
||
|
IN LPWSTR ServerAddress // server ip address
|
||
|
)
|
||
|
{
|
||
|
DWORD Err, i;
|
||
|
LPDHCP_ALL_OPTIONS Options;
|
||
|
|
||
|
Options = NULL;
|
||
|
Err = DhcpGetAllOptions(ServerAddress,0, &Options);
|
||
|
if( ERROR_NO_MORE_ITEMS == Err ) return ERROR_SUCCESS;
|
||
|
if( ERROR_SUCCESS != Err ) return Err;
|
||
|
|
||
|
if( Options->NonVendorOptions ) {
|
||
|
for( i = 0; i < Options->NonVendorOptions->NumElements; i ++ ) {
|
||
|
Err = DhcpCreateOptionV5DS(
|
||
|
ServerAddress,
|
||
|
0,
|
||
|
Options->NonVendorOptions->Options[i].OptionID,
|
||
|
NULL /* no class */,
|
||
|
NULL /* no vendor */,
|
||
|
&Options->NonVendorOptions->Options[i]
|
||
|
);
|
||
|
if( ERROR_SUCCESS != Err ) break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if( ERROR_SUCCESS != Err ) {
|
||
|
MemFree(Options);
|
||
|
return Err;
|
||
|
}
|
||
|
|
||
|
|
||
|
for( i = 0; i < Options->NumVendorOptions; i ++ ) {
|
||
|
Err = DhcpCreateOptionV5DS(
|
||
|
ServerAddress,
|
||
|
DHCP_FLAGS_OPTION_IS_VENDOR,
|
||
|
Options->VendorOptions[i].Option.OptionID,
|
||
|
Options->VendorOptions[i].ClassName,
|
||
|
Options->VendorOptions[i].VendorName,
|
||
|
&Options->VendorOptions[i].Option
|
||
|
);
|
||
|
if( ERROR_SUCCESS != Err ) break;
|
||
|
}
|
||
|
|
||
|
if( ERROR_SUCCESS != Err ) {
|
||
|
MemFree(Options);
|
||
|
return Err;
|
||
|
}
|
||
|
|
||
|
if( Options ) MemFree(Options);
|
||
|
return Err;
|
||
|
}
|
||
|
|
||
|
//DOC UploadOptiosn does rpc calls to server and copies stuff over to DS
|
||
|
UploadOptions( // upload options to DS
|
||
|
IN LPWSTR ServerAddress,
|
||
|
IN LPDHCP_OPTION_SCOPE_INFO ScopeInfo
|
||
|
)
|
||
|
{
|
||
|
DWORD Err, Resume, PrefMax, i, nRead, nTotal;
|
||
|
LPDHCP_ALL_OPTION_VALUES Options;
|
||
|
|
||
|
Resume = 0; PrefMax = 0xFFFFFFFF; nRead = nTotal = 0;
|
||
|
Options = NULL;
|
||
|
Err = DhcpGetAllOptionValues( // get list of default opt values
|
||
|
ServerAddress,
|
||
|
0,
|
||
|
ScopeInfo,
|
||
|
&Options
|
||
|
);
|
||
|
if( ERROR_NO_MORE_ITEMS == Err ) return ERROR_SUCCESS;
|
||
|
if( ERROR_SUCCESS != Err ) return Err; // oops could not do this simple task?
|
||
|
|
||
|
for( i = 0; i < Options->NumElements; i ++ ) {// now try to set each list of options..
|
||
|
if( NULL == Options->Options[i].OptionsArray ) {
|
||
|
continue; // uh? another way to say no options..
|
||
|
}
|
||
|
|
||
|
Err = DhcpSetOptionValuesV5DS (
|
||
|
ServerAddress,
|
||
|
Options->Options[i].IsVendor? DHCP_FLAGS_OPTION_IS_VENDOR:0,
|
||
|
Options->Options[i].ClassName,
|
||
|
Options->Options[i].VendorName,
|
||
|
ScopeInfo,
|
||
|
Options->Options[i].OptionsArray
|
||
|
);
|
||
|
if( ERROR_SUCCESS != Err ) {
|
||
|
MemFree(Options);
|
||
|
return Err;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return ERROR_SUCCESS; // saved it
|
||
|
}
|
||
|
|
||
|
//DOC ServerUploadOptions does rpc calls to server and copies stuff over to DS
|
||
|
DWORD
|
||
|
ServerUploadOptions( // upload options info to DS
|
||
|
IN OUT LPSTORE_HANDLE hDhcpC, // dhcp container to store at
|
||
|
IN OUT LPSTORE_HANDLE hServer, // server obj in DS
|
||
|
IN LPWSTR ServerAddress // server ip address
|
||
|
)
|
||
|
{
|
||
|
DWORD Err;
|
||
|
DHCP_OPTION_SCOPE_INFO ScopeInfo;
|
||
|
|
||
|
#if 0
|
||
|
ScopeInfo.ScopeInfo.DefaultScopeInfo = NULL;
|
||
|
ScopeInfo.ScopeType = DhcpDefaultOptions;
|
||
|
Err = UploadOptions(ServerAddress, &ScopeInfo);
|
||
|
if( ERROR_SUCCESS != Err ) return Err; // could not save default options..
|
||
|
#endif
|
||
|
|
||
|
ScopeInfo.ScopeType = DhcpGlobalOptions;
|
||
|
ScopeInfo.ScopeInfo.GlobalScopeInfo = NULL;
|
||
|
Err = UploadOptions(ServerAddress, &ScopeInfo);
|
||
|
if( ERROR_SUCCESS != Err ) return Err; // could not save global options..
|
||
|
|
||
|
return ERROR_SUCCESS;
|
||
|
}
|
||
|
|
||
|
//DOC ReservationUploadOptions does rpc calls to server and copies stuff to DS
|
||
|
DWORD
|
||
|
ReservationUploadOptions( // upload reservation options to DS
|
||
|
IN OUT LPSTORE_HANDLE hDhcpC, // dhcp container to store at
|
||
|
IN OUT LPSTORE_HANDLE hServer, // server obj in DS
|
||
|
IN LPWSTR ServerAddress, // server ip address
|
||
|
IN DWORD SubnetAddress, // add of subnet to add
|
||
|
IN DWORD ReserveAddress // address of reservation
|
||
|
)
|
||
|
{
|
||
|
DHCP_OPTION_SCOPE_INFO ScopeInfo;
|
||
|
|
||
|
ScopeInfo.ScopeType = DhcpReservedOptions;
|
||
|
ScopeInfo.ScopeInfo.ReservedScopeInfo.ReservedIpSubnetAddress = SubnetAddress;
|
||
|
ScopeInfo.ScopeInfo.ReservedScopeInfo.ReservedIpAddress = ReserveAddress;
|
||
|
return UploadOptions(ServerAddress, &ScopeInfo);
|
||
|
}
|
||
|
|
||
|
//DOC SubnetUploadOptions does rpc calls to server and copies stuff to DS
|
||
|
DWORD
|
||
|
SubnetUploadOptions( // upload subnet options to DS
|
||
|
IN OUT LPSTORE_HANDLE hDhcpC, // dhcp container to store at
|
||
|
IN OUT LPSTORE_HANDLE hServer, // server obj in DS
|
||
|
IN LPWSTR ServerAddress, // server ip address
|
||
|
IN DWORD SubnetAddress // add of subnet to add
|
||
|
)
|
||
|
{
|
||
|
DHCP_OPTION_SCOPE_INFO ScopeInfo;
|
||
|
|
||
|
ScopeInfo.ScopeType = DhcpSubnetOptions;
|
||
|
ScopeInfo.ScopeInfo.SubnetScopeInfo = SubnetAddress;
|
||
|
return UploadOptions(ServerAddress, &ScopeInfo);
|
||
|
}
|
||
|
|
||
|
//DOC ServerUploadSubnet does rpc calls to server and copies stuff over to DS
|
||
|
DWORD
|
||
|
ServerUploadSubnet( // upload subnet and relevant info to DS
|
||
|
IN OUT LPSTORE_HANDLE hDhcpC, // dhcp container to store at
|
||
|
IN OUT LPSTORE_HANDLE hServer, // server obj in DS
|
||
|
IN LPWSTR ServerAddress, // server ip address
|
||
|
IN DWORD SubnetAddress // add of subnet to add
|
||
|
)
|
||
|
{
|
||
|
DWORD Err, Resume, PrefMax, i, nRead, nTotal;
|
||
|
LPDHCP_SUBNET_INFO SubnetInfo;
|
||
|
DHCP_SUBNET_ELEMENT_TYPE SubnetEltType;
|
||
|
LPDHCP_SUBNET_ELEMENT_INFO_ARRAY_V4 EltInfo;
|
||
|
LPDHCP_SUPER_SCOPE_TABLE SScopeTbl;
|
||
|
|
||
|
Err = DhcpGetSubnetInfo(ServerAddress, SubnetAddress, &SubnetInfo);
|
||
|
if( ERROR_SUCCESS != Err ) return Err; // could not get subnet info..
|
||
|
|
||
|
Err = DhcpCreateSubnetDS(ServerAddress, SubnetAddress, SubnetInfo);
|
||
|
if( SubnetInfo ) MemFree(SubnetInfo);
|
||
|
if( ERROR_SUCCESS != Err ) return Err; // could not save onto DS
|
||
|
|
||
|
SScopeTbl = NULL;
|
||
|
Err = DhcpGetSuperScopeInfoV4( // get superscope table
|
||
|
ServerAddress,
|
||
|
&SScopeTbl
|
||
|
);
|
||
|
if( ERROR_SUCCESS == Err ) { // could get superscope table
|
||
|
for( i = 0; i < SScopeTbl->cEntries ; i ++ ) {
|
||
|
if( SScopeTbl->pEntries[i].SubnetAddress == SubnetAddress ) {
|
||
|
Err = DhcpSetSuperScopeV4DS(
|
||
|
ServerAddress,
|
||
|
SubnetAddress,
|
||
|
SScopeTbl->pEntries[i].SuperScopeName,
|
||
|
TRUE /* change superscope if it exists..*/
|
||
|
);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
MemFree(SScopeTbl);
|
||
|
if( ERROR_SUCCESS != Err ) return Err; // could not set superscope..
|
||
|
}
|
||
|
|
||
|
Resume = 0; PrefMax = 0xFFFFFFFF;
|
||
|
EltInfo = NULL; nRead = nTotal = 0;
|
||
|
Err = DhcpEnumSubnetElementsV4( // enumerate ranges
|
||
|
ServerAddress,
|
||
|
SubnetAddress,
|
||
|
DhcpIpRanges,
|
||
|
&Resume,
|
||
|
PrefMax,
|
||
|
&EltInfo,
|
||
|
&nRead,
|
||
|
&nTotal
|
||
|
);
|
||
|
if( ERROR_SUCCESS != Err ) return Err; // could not get ranges
|
||
|
|
||
|
for( i = 0; i < EltInfo->NumElements; i ++ ) {// try to add each range
|
||
|
Err = DhcpAddSubnetElementV4DS(
|
||
|
ServerAddress,
|
||
|
SubnetAddress,
|
||
|
&EltInfo->Elements[i]
|
||
|
);
|
||
|
if( ERROR_SUCCESS != Err ) break;
|
||
|
}
|
||
|
if( EltInfo ) MemFree(EltInfo); // free-up memory
|
||
|
if( ERROR_SUCCESS != Err ) return Err; // could not add ranges
|
||
|
|
||
|
Resume = 0; PrefMax = 0xFFFFFFFF;
|
||
|
EltInfo = NULL;
|
||
|
Err = DhcpEnumSubnetElementsV4( // enumerate reservations
|
||
|
ServerAddress,
|
||
|
SubnetAddress,
|
||
|
DhcpReservedIps,
|
||
|
&Resume,
|
||
|
PrefMax,
|
||
|
&EltInfo,
|
||
|
&nRead,
|
||
|
&nTotal
|
||
|
);
|
||
|
if( ERROR_NO_MORE_ITEMS == Err ) goto try_Excl;
|
||
|
if( ERROR_SUCCESS != Err ) return Err; // could not get exclusions
|
||
|
|
||
|
for( i = 0; i < EltInfo->NumElements; i ++ ) {// try to add each reservation
|
||
|
Err = DhcpAddSubnetElementV4DS(
|
||
|
ServerAddress,
|
||
|
SubnetAddress,
|
||
|
&EltInfo->Elements[i]
|
||
|
);
|
||
|
if( ERROR_SUCCESS != Err ) break; // could not add reseration in DS
|
||
|
|
||
|
Err = ReservationUploadOptions(
|
||
|
hDhcpC,
|
||
|
hServer,
|
||
|
ServerAddress,
|
||
|
SubnetAddress,
|
||
|
EltInfo->Elements[i].Element.ReservedIp->ReservedIpAddress
|
||
|
);
|
||
|
if( ERROR_SUCCESS != Err ) break; // could not add reservaation options
|
||
|
}
|
||
|
if( EltInfo ) MemFree(EltInfo); // free-up memory
|
||
|
if( ERROR_SUCCESS != Err ) return Err; // could not add exclusions
|
||
|
|
||
|
try_Excl:
|
||
|
|
||
|
Resume = 0; PrefMax = 0xFFFFFFFF;
|
||
|
EltInfo = NULL;
|
||
|
Err = DhcpEnumSubnetElementsV4( // enumerate exclusions
|
||
|
ServerAddress,
|
||
|
SubnetAddress,
|
||
|
DhcpReservedIps,
|
||
|
&Resume,
|
||
|
PrefMax,
|
||
|
&EltInfo,
|
||
|
&nRead,
|
||
|
&nTotal
|
||
|
);
|
||
|
if( ERROR_NO_MORE_ITEMS == Err ) goto try_Options;
|
||
|
if( ERROR_SUCCESS != Err ) return Err; // could not get exclusions
|
||
|
|
||
|
for( i = 0; i < EltInfo->NumElements; i ++ ) {// try to add each exclusion
|
||
|
Err = DhcpAddSubnetElementV4DS(
|
||
|
ServerAddress,
|
||
|
SubnetAddress,
|
||
|
&EltInfo->Elements[i]
|
||
|
);
|
||
|
if( ERROR_SUCCESS != Err ) break;
|
||
|
}
|
||
|
if( EltInfo ) MemFree(EltInfo); // free-up memory
|
||
|
if( ERROR_SUCCESS != Err ) return Err; // could not add exclusions
|
||
|
|
||
|
try_Options:
|
||
|
return SubnetUploadOptions(hDhcpC,hServer,ServerAddress,SubnetAddress);
|
||
|
}
|
||
|
|
||
|
//DOC ServerUploadSubnets does rpc calls to server and copies stuff over to DS
|
||
|
DWORD
|
||
|
ServerUploadSubnets( // upload subnets info to DS
|
||
|
IN OUT LPSTORE_HANDLE hDhcpC, // dhcp container to store at
|
||
|
IN OUT LPSTORE_HANDLE hServer, // server obj in DS
|
||
|
IN LPWSTR ServerAddress // server ip address
|
||
|
)
|
||
|
{
|
||
|
DWORD Err, Resume, PrefMax, i, nRead, nTotal;
|
||
|
LPDHCP_IP_ARRAY Subnets;
|
||
|
|
||
|
Resume = 0; PrefMax = 0xFFFFFFFF; nRead = nTotal = 0;
|
||
|
Subnets = NULL;
|
||
|
Err = DhcpEnumSubnets(ServerAddress, &Resume, PrefMax, &Subnets, &nRead, &nTotal);
|
||
|
if( ERROR_NO_MORE_ITEMS == Err ) return ERROR_SUCCESS;
|
||
|
if( ERROR_SUCCESS != Err ) return Err; // could not get list of elements?
|
||
|
|
||
|
for( i = 0; i < Subnets->NumElements ; i ++ ) {
|
||
|
Err = ServerUploadSubnet(hDhcpC, hServer, ServerAddress, Subnets->Elements[i]);
|
||
|
if( ERROR_SUCCESS != Err ) break;
|
||
|
}
|
||
|
|
||
|
if( Subnets ) MemFree(Subnets);
|
||
|
return Err;
|
||
|
}
|
||
|
|
||
|
//DOC UploadServer downloads the server info by making RPC calls..
|
||
|
DWORD
|
||
|
UploadServer( // make rpc calls and pull up info to DS.
|
||
|
IN OUT LPSTORE_HANDLE hDhcpC, // general container where info is stored
|
||
|
IN OUT LPSTORE_HANDLE hServer, // server obj in DS
|
||
|
IN LPWSTR ServerName, // name of server
|
||
|
IN DWORD IpAddress // ip address of server
|
||
|
)
|
||
|
{
|
||
|
DWORD Err;
|
||
|
LPSTR IpAddrStr;
|
||
|
WCHAR ServerAddress[sizeof("000.000.000.000")];
|
||
|
|
||
|
IpAddress = htonl(IpAddress); // use n/w order ip address..
|
||
|
IpAddrStr = inet_ntoa(*(struct in_addr *)&IpAddress);
|
||
|
Err = mbstowcs(ServerAddress, IpAddrStr, ( sizeof(ServerAddress)/sizeof( WCHAR ) ) );
|
||
|
if( -1 == Err ) { // could not convert to LPWSTR
|
||
|
return ERROR_GEN_FAILURE;
|
||
|
}
|
||
|
|
||
|
Err = ServerUploadClasses(hDhcpC, hServer, ServerAddress);
|
||
|
if( ERROR_SUCCESS != Err ) { // could not upload server classes info
|
||
|
return Err;
|
||
|
}
|
||
|
|
||
|
Err = ServerUploadOptdefs(hDhcpC, hServer, ServerAddress);
|
||
|
if( ERROR_SUCCESS != Err ) { // could not upload option defs ?
|
||
|
return Err;
|
||
|
}
|
||
|
|
||
|
Err = ServerUploadOptions(hDhcpC, hServer, ServerAddress);
|
||
|
if( ERROR_SUCCESS != Err ) { // could not upload options?
|
||
|
return Err;
|
||
|
}
|
||
|
|
||
|
Err = ServerUploadSubnets(hDhcpC, hServer, ServerAddress);
|
||
|
if( ERROR_SUCCESS != Err ) { // could not upload subnets?
|
||
|
return Err;
|
||
|
}
|
||
|
|
||
|
return ERROR_SUCCESS;
|
||
|
}
|
||
|
|
||
|
//BeginExport(function)
|
||
|
//DOC AddServer should add the new address to the server's attribs
|
||
|
//DOC it should take this opportunity to reconcile the server.
|
||
|
//DOC Currently it does nothing. (at the least it should probably try to
|
||
|
//DOC check if the object exists, and if not create it.)
|
||
|
//DOC
|
||
|
DWORD
|
||
|
AddServer( // add server and do misc work
|
||
|
IN OUT LPSTORE_HANDLE hDhcpC, // container for server obj
|
||
|
IN LPWSTR ServerName, // [DNS?] name of server
|
||
|
IN LPWSTR ADsPath, // ADS path to server object
|
||
|
IN DWORD IpAddress, // IpAddress to add to server
|
||
|
IN DWORD State // state of server
|
||
|
) //EndExport(function)
|
||
|
{
|
||
|
DWORD Err, Err2;
|
||
|
STORE_HANDLE hServer;
|
||
|
|
||
|
Err = StoreGetHandle( // get the server obj..
|
||
|
hDhcpC,
|
||
|
DDS_RESERVED_DWORD,
|
||
|
StoreGetChildType,
|
||
|
ADsPath,
|
||
|
&hServer
|
||
|
);
|
||
|
|
||
|
if( ERROR_SUCCESS != Err ) return Err; // could be because server obj elsewhere??
|
||
|
|
||
|
if( !CFLAG_DONT_DO_DSWORK ) { // if DS stuff is enabled in the first place
|
||
|
Err = UploadServer(hDhcpC, &hServer, ServerName, IpAddress);
|
||
|
}
|
||
|
|
||
|
StoreCleanupHandle(&hServer, 0); // cleanup this server..
|
||
|
|
||
|
return Err;
|
||
|
}
|
||
|
|
||
|
//================================================================================
|
||
|
// end of file
|
||
|
//================================================================================
|