windows-nt/Source/XPSP1/NT/net/dhcp/server/dhcpds/rpcstubs.c
2020-09-26 16:20:57 +08:00

3220 lines
112 KiB
C

//================================================================================
// Copyright (C) 1997 Microsoft Corporation
// Author: RameshV
// Description: Actual stubs that are the equivalent the rpcapi1.c and rpcapi2.c
// in the server\server directory.. (or more accurately, the implementations are
// the same as for the functions defined in server\client\dhcpsapi.def)
// NOTE: THE FOLLOWING FUNCTIONS ARE NOT RPC, BUT THEY BEHAVE JUST THE SAME AS
// THE DHCP RPC CALLS, EXCEPT THEY ACCESS THE DS DIRECTLY.
//================================================================================
#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 <rpcapi1.h>
#include <st_srvr.h>
#include <rpcapi2.h>
//================================================================================
// global variables..
//================================================================================
BOOL
StubInitialized = FALSE;
STORE_HANDLE hDhcpC, hDhcpRoot;
CRITICAL_SECTION DhcpDsDllCriticalSection;
//================================================================================
// THE FOLLOWING FUNCTIONS HAVE BEEN COPIED OVER FROM RPCAPI1.C (IN THE
// DHCP\SERVER\SERVER DIRECTORY).
//================================================================================
#undef DhcpPrint
#define DhcpPrint(X)
#define DhcpAssert(X)
typedef struct _OPTION_BIN {
DWORD DataSize;
DHCP_OPTION_DATA_TYPE OptionType;
DWORD NumElements;
BYTE Data[0];
} OPTION_BIN, *LPOPTION_BIN;
#define IS_SPACE_AVAILABLE(FilledSize, AvailableSize, RequiredSpace ) ((FilledSize) + (RequiredSpace) <= (AvailableSize) )
BOOL _inline
CheckForVendor(
IN DWORD OptId,
IN BOOL IsVendor
)
{
if( IsVendor ) return (256 <= OptId);
return 256 > OptId;
}
DWORD _inline
ConvertOptIdToRPCValue(
IN DWORD OptId,
IN BOOL IsVendorUnused
)
{
return OptId % 256;
}
DWORD _inline
ConvertOptIdToMemValue(
IN DWORD OptId,
IN BOOL IsVendor
)
{
if( IsVendor ) return OptId + 256;
return OptId;
}
extern // defined in rpcapi1.c
DWORD
DhcpConvertOptionRPCToRegFormat(
IN LPDHCP_OPTION_DATA Option,
IN OUT LPBYTE RegBuffer, // OPTIONAL
IN OUT DWORD *BufferSize // input: buffer size, output: filled buffer size
);
DWORD
ConvertOptionInfoRPCToMemFormat(
IN LPDHCP_OPTION OptionInfo,
OUT LPWSTR *Name,
OUT LPWSTR *Comment,
OUT DWORD *OptId,
OUT LPBYTE *Value,
OUT DWORD *ValueSize
)
{
DWORD Error;
if( Name ) *Name = OptionInfo->OptionName;
if( Comment ) *Comment = OptionInfo->OptionComment;
if( OptId ) *OptId = (DWORD)(OptionInfo->OptionID);
if( Value ) {
*Value = NULL;
if( !ValueSize ) return ERROR_INVALID_PARAMETER;
*ValueSize = 0;
Error = DhcpConvertOptionRPCToRegFormat(
&OptionInfo->DefaultValue,
NULL,
ValueSize
);
if( ERROR_MORE_DATA != Error ) return Error;
DhcpAssert(0 != *ValueSize);
*Value = MemAlloc(*ValueSize);
if( NULL == *Value ) {
*ValueSize = 0;
return ERROR_NOT_ENOUGH_MEMORY;
}
Error = DhcpConvertOptionRPCToRegFormat(
&OptionInfo->DefaultValue,
*Value,
ValueSize
);
DhcpAssert(ERROR_MORE_DATA != Error);
DhcpAssert(ERROR_SUCCESS == Error);
if( ERROR_SUCCESS != Error ) {
MemFree(*Value);
*Value = NULL;
*ValueSize = 0;
return Error;
}
}
return ERROR_SUCCESS;
}
//================================================================================
// helper routines
//================================================================================
VOID
MemFreeFunc( // free memory
IN OUT LPVOID Mem
)
{
MemFree(Mem);
}
//
// ErrorNotInitialized used to be ZERO.. but why would we NOT return an error?
// so changed it to return errors..
//
#define ErrorNotInitialized Err
#define STUB_NOT_INITIALIZED(Err) ( !StubInitialized && ((Err) = StubInitialize()))
//DOC StubInitialize initializes all the modules involved in the dhcp ds dll.
//DOC It also sets a global variable StubInitialized to TRUE to indicate that
//DOC initialization went fine. This should be called as part of DllInit so that
//DOC everything can be done at this point..
DWORD
StubInitialize( // initialize all global vars
VOID
)
{
DWORD Err,Err2;
STORE_HANDLE ConfigC;
if( StubInitialized ) return ERROR_SUCCESS; // already initialized
Err = Err2 = ERROR_SUCCESS;
EnterCriticalSection( &DhcpDsDllCriticalSection );
do {
if( StubInitialized ) break;
Err = StoreInitHandle(
/* hStore */ &ConfigC,
/* Reserved */ DDS_RESERVED_DWORD,
/* ThisDomain */ NULL, // current domain
/* UserName */ NULL, // current user
/* Password */ NULL, // current credentials
/* AuthFlags */ ADS_SECURE_AUTHENTICATION
);
if( ERROR_SUCCESS != Err ) {
Err = ERROR_DDS_NO_DS_AVAILABLE; // could not get config hdl
break;
}
Err = DhcpDsGetDhcpC(
DDS_RESERVED_DWORD, &ConfigC, &hDhcpC
);
if( ERROR_SUCCESS == Err ) {
Err2 = DhcpDsGetRoot( // now try to get root handle
DDS_FLAGS_CREATE, &ConfigC, &hDhcpRoot
);
}
StoreCleanupHandle(&ConfigC, DDS_RESERVED_DWORD);
} while (0);
if( ERROR_SUCCESS != Err2 ) { // could not get dhcp root hdl
DhcpAssert(ERROR_SUCCESS == Err);
StoreCleanupHandle(&hDhcpC, DDS_RESERVED_DWORD);
Err = Err2;
}
StubInitialized = (ERROR_SUCCESS == Err );
LeaveCriticalSection( &DhcpDsDllCriticalSection );
return Err;
}
//DOC StubCleanup de-initializes all the modules involved in the dhcp ds dll.
//DOC its effect is to undo everything done by StubInitialize
VOID
StubCleanup( // undo StubInitialize
VOID
)
{
if( ! StubInitialized ) return; // never initialized anyways
EnterCriticalSection(&DhcpDsDllCriticalSection);
if( StubInitialized ) {
StoreCleanupHandle(&hDhcpC, DDS_RESERVED_DWORD);
StoreCleanupHandle(&hDhcpRoot, DDS_RESERVED_DWORD);
StubInitialized = FALSE;
}
LeaveCriticalSection(&DhcpDsDllCriticalSection);
}
//DOC DhcpDsLock is not yet implemented
DWORD
DhcpDsLock( // lock the ds
IN OUT LPSTORE_HANDLE hDhcpRoot // dhcp root object to lock via
)
{
EnterCriticalSection(&DhcpDsDllCriticalSection);
return ERROR_SUCCESS;
}
//DOC DhcpDsUnlock not yet implemented
VOID
DhcpDsUnlock(
IN OUT LPSTORE_HANDLE hDhcpRoot // dhcp root object..
)
{
LeaveCriticalSection(&DhcpDsDllCriticalSection);
}
//DOC GetServerNameFromAddr gets the server name given ip address
DWORD
GetServerNameFromAddr( // get server name from ip addr
IN DWORD IpAddress, // look for server w/ this addr
OUT LPWSTR *ServerName // fill this with matching name
)
{
DWORD Err, Err2;
ARRAY Servers;
ARRAY_LOCATION Loc;
PEATTRIB ThisAttrib;
LPWSTR ThisStr, AllocStr;
MemArrayInit(&Servers);
Err = DhcpDsGetLists // get list of servers
(
/* Reserved */ DDS_RESERVED_DWORD,
/* hStore */ &hDhcpRoot,
/* RecursionDepth */ 0xFFFFFFFF,
/* Servers */ &Servers, // array of PEATTRIB 's
/* Subnets */ NULL,
/* IpAddress */ NULL,
/* Mask */ NULL,
/* Ranges */ NULL,
/* Sites */ NULL,
/* Reservations */ NULL,
/* SuperScopes */ NULL,
/* OptionDescription */ NULL,
/* OptionsLocation */ NULL,
/* Options */ NULL,
/* Classes */ NULL
);
if( ERROR_SUCCESS != Err ) return Err;
ThisStr = NULL;
for( // find name for ip-address
Err = MemArrayInitLoc(&Servers,&Loc)
; ERROR_FILE_NOT_FOUND != Err ;
Err = MemArrayNextLoc(&Servers, &Loc)
) {
//= require ERROR_SUCCESS == Err
Err = MemArrayGetElement(&Servers, &Loc, &ThisAttrib);
//= require ERROR_SUCCESS == Err && NULL != ThisAttrib
if( !IS_STRING1_PRESENT(ThisAttrib) || // no name for this server
!IS_ADDRESS1_PRESENT(ThisAttrib) ) { // no address for this server
continue; //= ds inconsistent
}
ThisStr = ThisAttrib->String1;
break;
}
AllocStr = NULL;
if( NULL == ThisStr ) { // didnt find server name
Err = ERROR_FILE_NOT_FOUND;
} else { // found the server name
AllocStr = MemAlloc(sizeof(WCHAR)*(1+wcslen(ThisStr)));
if( NULL == AllocStr ) { // couldnt alloc mem?
Err = ERROR_NOT_ENOUGH_MEMORY;
} else { // now just copy the str over
wcscpy(AllocStr, ThisStr);
Err = ERROR_SUCCESS;
}
}
MemArrayFree(&Servers, MemFreeFunc);
*ServerName = AllocStr;
return Err;
}
//DOC GetServerNameFromStr gets the server name given ip address string
DWORD
GetServerNameFromStr( // get srvr name from ip string
IN LPWSTR Str, // ip address string
OUT LPWSTR *ServerName // output the server name
)
{
DWORD Err, Err2;
DWORD IpAddress;
CHAR IpAddressBuf[sizeof("000.000.000.000")];
Err = wcstombs(IpAddressBuf, Str, sizeof(IpAddressBuf));
if( -1 == Err ) { // could not convert address
return ERROR_INVALID_DATA;
}
IpAddress = ntohl(inet_addr(IpAddressBuf)); // convert to DWORD Address, host order
return GetServerNameFromAddr(IpAddress, ServerName);
}
//DOC TouchServer writes the "instancetype" attrib w/ default value so that the time
//DOC stamp on the server object is brought up to date..
DWORD
TouchServer( // touch server object
IN LPSTORE_HANDLE hServer
)
{
DWORD nAttribs = 1;
return StoreSetAttributesVA(
hServer,0, &nAttribs,
ADSTYPE_INTEGER, ADS_ATTR_UPDATE, ATTRIB_INSTANCE_TYPE, DEFAULT_INSTANCE_TYPE_ATTRIB_VALUE,
ADSTYPE_INVALID
);
}
//DOC GetServer translates the server ip address to a server object in DS.
DWORD
GetServer( // get a server object frm ip-addr
OUT LPSTORE_HANDLE hServer, // fill up this object
IN LPWSTR Address // server ip address
)
{
DWORD Err, Err2;
DWORD IpAddress;
CHAR IpAddressBuf[sizeof("000.000.000.000")];
ARRAY Servers;
ARRAY_LOCATION Loc;
PEATTRIB ThisAttrib;
LPWSTR ServerLocation, ServerName;
DWORD ServerGetType;
if( NULL == Address ) { // if DhcpRoot object requested
return DhcpDsGetRoot( 0, &hDhcpC, hServer );
}
Err = wcstombs(IpAddressBuf, Address, sizeof(IpAddressBuf));
if( -1 == Err ) { // could not convert address
return ERROR_INVALID_DATA;
}
IpAddress = ntohl(inet_addr(IpAddressBuf)); // convert to DWORD Address, host order
MemArrayInit(&Servers);
Err = DhcpDsGetLists // get list of servers
(
/* Reserved */ DDS_RESERVED_DWORD,
/* hStore */ &hDhcpRoot,
/* RecursionDepth */ 0xFFFFFFFF,
/* Servers */ &Servers, // array of PEATTRIB 's
/* Subnets */ NULL,
/* IpAddress */ NULL,
/* Mask */ NULL,
/* Ranges */ NULL,
/* Sites */ NULL,
/* Reservations */ NULL,
/* SuperScopes */ NULL,
/* OptionDescription */ NULL,
/* OptionsLocation */ NULL,
/* Options */ NULL,
/* Classes */ NULL
);
if( ERROR_SUCCESS != Err ) return Err;
ServerLocation = ServerName = NULL; // havent found server yet
for( // find name for ip-address
Err = MemArrayInitLoc(&Servers,&Loc)
; ERROR_FILE_NOT_FOUND != Err ;
Err = MemArrayNextLoc(&Servers, &Loc)
) {
//= require ERROR_SUCCESS == Err
Err = MemArrayGetElement(&Servers, &Loc, &ThisAttrib);
//= require ERROR_SUCCESS == Err && NULL != ThisAttrib
if( !IS_STRING1_PRESENT(ThisAttrib) || // no name for this server
!IS_ADDRESS1_PRESENT(ThisAttrib) ) { // no address for this server
continue; //= ds inconsistent
}
if( ThisAttrib->Address1 == IpAddress ) { // matching address?
if( IS_ADSPATH_PRESENT(ThisAttrib) ) {// found location
ServerLocation = ThisAttrib->ADsPath;
ServerGetType = ThisAttrib->StoreGetType;
ServerName = NULL;
break;
} else { // location not found
ServerName = ThisAttrib->String1; // remember server name
}
}
}
if( NULL == ServerLocation ) { // did not find location
if( NULL == ServerName ) { // did not find server name either
MemArrayFree(&Servers, MemFreeFunc);
return ERROR_DDS_DHCP_SERVER_NOT_FOUND;
}
ServerName = MakeColumnName(ServerName); // make this into a "CN=X" types
if( NULL == ServerName ) { // could not allocate mme
MemArrayFree(&Servers, MemFreeFunc);
return ERROR_NOT_ENOUGH_MEMORY;
}
ServerGetType = StoreGetChildType; // search in hDhcpC container
ServerLocation = ServerName;
}
Err = StoreGetHandle // now try to open server object
(
/* hStore */ &hDhcpC,
/* Reserved */ DDS_RESERVED_DWORD,
/* StoreGetType */ ServerGetType,
/* Path */ ServerLocation,
/* hStoreOut */ hServer
);
MemArrayFree(&Servers, MemFreeFunc);
if( ServerName ) MemFree(ServerName);
if( ERROR_SUCCESS == Err ) { // update the last changed time on server
TouchServer(hServer);
}
return Err;
}
//DOC GetSubnet translates an ip-address to a subnet object.
//DOC : if the subnet attrib does not have an ADsPath this does not guess..
DWORD
GetSubnet(
IN OUT LPSTORE_HANDLE hServer, // server object
OUT LPSTORE_HANDLE hSubnet, // fill this subnet object
IN DWORD IpAddress
)
{
DWORD Err, Err2;
ARRAY Subnets;
ARRAY_LOCATION Loc;
PEATTRIB ThisAttrib;
LPWSTR SubnetLocation;
DWORD SubnetGetType;
MemArrayInit(&Subnets);
Err = DhcpDsGetLists // get list of subnets
(
/* Reserved */ DDS_RESERVED_DWORD,
/* hStore */ hServer,
/* RecursionDepth */ 0xFFFFFFFF,
/* Servers */ NULL,
/* Subnets */ &Subnets, // array of PEATTRIB 's
/* IpAddress */ NULL,
/* Mask */ NULL,
/* Ranges */ NULL,
/* Sites */ NULL,
/* Reservations */ NULL,
/* SuperScopes */ NULL,
/* OptionDescription */ NULL,
/* OptionsLocation */ NULL,
/* Options */ NULL,
/* Classes */ NULL
);
if( ERROR_SUCCESS != Err ) return Err;
SubnetLocation = NULL;
for( // find match for ip-address
Err = MemArrayInitLoc(&Subnets,&Loc)
; ERROR_FILE_NOT_FOUND != Err ;
Err = MemArrayNextLoc(&Subnets, &Loc)
) {
//= require ERROR_SUCCESS == Err
Err = MemArrayGetElement(&Subnets, &Loc, &ThisAttrib);
//= require ERROR_SUCCESS == Err && NULL != ThisAttrib
if( !IS_ADDRESS1_PRESENT(ThisAttrib) || // no address for this subnet
!IS_ADDRESS2_PRESENT(ThisAttrib) ) { // no mask for this subnet
continue; //= ds inconsistent
}
if( ThisAttrib->Address1 == IpAddress ) { // matching address?
if( IS_ADSPATH_PRESENT(ThisAttrib) ) {// found location
SubnetLocation = ThisAttrib->ADsPath;
SubnetGetType = ThisAttrib->StoreGetType;
break;
} else { // oops.. need to hdl this!
MemArrayFree(&Subnets, MemFreeFunc);
return ERROR_DDS_UNEXPECTED_ERROR;
}
}
}
if( NULL == SubnetLocation ) { // did not find location
MemArrayFree(&Subnets, MemFreeFunc);
return ERROR_DDS_SUBNET_NOT_PRESENT;
}
Err = StoreGetHandle // now try to open server object
(
/* hStore */ &hDhcpC,
/* Reserved */ DDS_RESERVED_DWORD,
/* StoreGetType */ SubnetGetType,
/* Path */ SubnetLocation,
/* hStoreOut */ hSubnet
);
MemArrayFree(&Subnets, MemFreeFunc);
return Err;
}
//DOC GetReservationInternal translates an ip-address to a reservation object.
//DOC : if the Reservation attrib does not have an ADsPath this does not guess..
DWORD
GetReservationInternal(
IN OUT LPSTORE_HANDLE hServer, // server object
IN OUT LPSTORE_HANDLE hSubnet, // subnet object
IN OUT LPSTORE_HANDLE hReservation, // fill this with reservation object
IN DWORD IpAddress // reserved ip address to search for
)
{
DWORD Err, Err2;
ARRAY Res;
ARRAY_LOCATION Loc;
PEATTRIB ThisAttrib;
LPWSTR ResLocation;
DWORD ResGetType;
MemArrayInit(&Res);
Err = DhcpDsGetLists // get list of subnets
(
/* Reserved */ DDS_RESERVED_DWORD,
/* hStore */ hSubnet,
/* RecursionDepth */ 0xFFFFFFFF,
/* Servers */ NULL,
/* Subnets */ NULL,
/* IpAddress */ NULL,
/* Mask */ NULL,
/* Ranges */ NULL,
/* Sites */ NULL,
/* Reservations */ &Res,
/* SuperScopes */ NULL,
/* OptionDescription */ NULL,
/* OptionsLocation */ NULL,
/* Options */ NULL,
/* Classes */ NULL
);
if( ERROR_SUCCESS != Err ) return Err;
ResLocation = NULL;
for( // find match for ip-address
Err = MemArrayInitLoc(&Res,&Loc)
; ERROR_FILE_NOT_FOUND != Err ;
Err = MemArrayNextLoc(&Res, &Loc)
) {
//= require ERROR_SUCCESS == Err
Err = MemArrayGetElement(&Res, &Loc, &ThisAttrib);
//= require ERROR_SUCCESS == Err && NULL != ThisAttrib
if( !IS_ADDRESS1_PRESENT(ThisAttrib) || // no address for this reservation
!IS_BINARY1_PRESENT(ThisAttrib) ) { // no client uid for this res.
continue; //= ds inconsistent
}
if( ThisAttrib->Address1 == IpAddress ) { // matching address?
if( IS_ADSPATH_PRESENT(ThisAttrib) ) {// found location
ResLocation = ThisAttrib->ADsPath;
ResGetType = ThisAttrib->StoreGetType;
break;
} else { // oops.. need to hdl this!
MemArrayFree(&Res, MemFreeFunc);
return ERROR_DDS_UNEXPECTED_ERROR;
}
}
}
if( NULL == ResLocation ) { // did not find location
MemArrayFree(&Res, MemFreeFunc);
return ERROR_DDS_RESERVATION_NOT_PRESENT;
}
Err = StoreGetHandle // now try to open server object
(
/* hStore */ &hDhcpC,
/* Reserved */ DDS_RESERVED_DWORD,
/* StoreGetType */ ResGetType,
/* Path */ ResLocation,
/* hStoreOut */ hReservation
);
MemArrayFree(&Res, MemFreeFunc);
return Err;
}
//DOC GetReservation translates an ip-address to a subnet object.
//DOC : if the Reservation attrib does not have an ADsPath this does not guess..
DWORD
GetReservation(
IN OUT LPSTORE_HANDLE hServer, // server object
IN OUT LPSTORE_HANDLE hReservation, // fill this with reservation object
IN DWORD SubnetAddr, // address of subnet
IN DWORD IpAddress
)
{
DWORD Err, Err2;
STORE_HANDLE hSubnet;
Err = GetSubnet(hServer, &hSubnet, SubnetAddr);
if( ERROR_SUCCESS != Err) return Err; // try to get the subnet obj first
Err = GetReservationInternal(hServer, &hSubnet, hReservation, IpAddress);
StoreCleanupHandle(&hSubnet, 0);
return Err;
}
//DOC AddSubnetElementOld adds one of Excl,Ip Range or Reservation to the subnet
//DOC object specified in the DS.
DWORD
AddSubnetElementOld( // add excl/range/res. to subnet
IN OUT LPSTORE_HANDLE hServer, // server obj in DS
IN OUT LPSTORE_HANDLE hSubnet, // subnet obj in DS
IN LPWSTR ServerName, // name of dhcp server
IN LPDHCP_SUBNET_ELEMENT_DATA Elt // the element to add
)
{
DWORD Err;
if( DhcpIpRanges == Elt->ElementType ) { // add a new range
Err = DhcpDsSubnetAddRangeOrExcl // add its
(
/* hDhcpC */ &hDhcpC,
/* hServer */ hServer,
/* hSubnet */ hSubnet,
/* Reserved */ DDS_RESERVED_DWORD,
/* ServerName */ ServerName,
/* Start */ Elt->Element.IpRange->StartAddress,
/* End */ Elt->Element.IpRange->EndAddress,
/* RangeOrExcl */ TRUE // range
);
} else if( DhcpExcludedIpRanges == Elt->ElementType ) {
Err = DhcpDsSubnetAddRangeOrExcl // add its
(
/* hDhcpC */ &hDhcpC,
/* hServer */ hServer,
/* hSubnet */ hSubnet,
/* Reserved */ DDS_RESERVED_DWORD,
/* ServerName */ ServerName,
/* Start */ Elt->Element.ExcludeIpRange->StartAddress,
/* End */ Elt->Element.ExcludeIpRange->EndAddress,
/* RangeOrExcl */ FALSE // excl
);
} else if( DhcpReservedIps == Elt->ElementType ) {
Err = DhcpDsSubnetAddReservation // add its
(
/* hDhcpC */ &hDhcpC,
/* hServer */ hServer,
/* hSubnet */ hSubnet,
/* Reserved */ DDS_RESERVED_DWORD,
/* ServerName */ ServerName,
/* ReservedAddddr */ Elt->Element.ReservedIp->ReservedIpAddress,
/* HwAddr */ Elt->Element.ReservedIp->ReservedForClient->Data,
/* HwAddrLen */ Elt->Element.ReservedIp->ReservedForClient->DataLength,
/* ClientType */ CLIENT_TYPE_DHCP
);
} else {
Err = ERROR_CALL_NOT_IMPLEMENTED;
}
return Err;
}
//DOC AddSubnetElement adds one of Excl,Ip Range or Reservation to the subnet
//DOC object specified in the DS.
DWORD
AddSubnetElement( // add excl/range/res. to subnet
IN OUT LPSTORE_HANDLE hServer, // server obj in DS
IN OUT LPSTORE_HANDLE hSubnet, // subnet obj in DS
IN LPWSTR ServerName, // name of dhcp server
IN LPDHCP_SUBNET_ELEMENT_DATA_V4 Elt // the element to add
)
{
DWORD Err;
if( DhcpIpRanges == Elt->ElementType ) { // add a new range
Err = DhcpDsSubnetAddRangeOrExcl // add its
(
/* hDhcpC */ &hDhcpC,
/* hServer */ hServer,
/* hSubnet */ hSubnet,
/* Reserved */ DDS_RESERVED_DWORD,
/* ServerName */ ServerName,
/* Start */ Elt->Element.IpRange->StartAddress,
/* End */ Elt->Element.IpRange->EndAddress,
/* RangeOrExcl */ TRUE // range
);
} else if( DhcpExcludedIpRanges == Elt->ElementType ) {
Err = DhcpDsSubnetAddRangeOrExcl // add its
(
/* hDhcpC */ &hDhcpC,
/* hServer */ hServer,
/* hSubnet */ hSubnet,
/* Reserved */ DDS_RESERVED_DWORD,
/* ServerName */ ServerName,
/* Start */ Elt->Element.ExcludeIpRange->StartAddress,
/* End */ Elt->Element.ExcludeIpRange->EndAddress,
/* RangeOrExcl */ FALSE // excl
);
} else if( DhcpReservedIps == Elt->ElementType ) {
Err = DhcpDsSubnetAddReservation // add its
(
/* hDhcpC */ &hDhcpC,
/* hServer */ hServer,
/* hSubnet */ hSubnet,
/* Reserved */ DDS_RESERVED_DWORD,
/* ServerName */ ServerName,
/* ReservedAddddr */ Elt->Element.ReservedIp->ReservedIpAddress,
/* HwAddr */ Elt->Element.ReservedIp->ReservedForClient->Data,
/* HwAddrLen */ Elt->Element.ReservedIp->ReservedForClient->DataLength,
/* ClientType */ Elt->Element.ReservedIp->bAllowedClientTypes
);
} else {
Err = ERROR_CALL_NOT_IMPLEMENTED;
}
return Err;
}
//DOC DelSubnetElementOld deltes one of Excl,Ip Range or Reservation to frm subnet
//DOC object specified in the DS.
DWORD
DelSubnetElementOld( // del excl/range/res. frm subnet
IN OUT LPSTORE_HANDLE hServer, // server obj in DS
IN OUT LPSTORE_HANDLE hSubnet, // subnet obj in DS
IN LPWSTR ServerName, // name of dhcp server
IN LPDHCP_SUBNET_ELEMENT_DATA Elt // the element to add
)
{
DWORD Err;
if( DhcpIpRanges == Elt->ElementType ) { // del a new range
Err = DhcpDsSubnetDelRangeOrExcl // del its
(
/* hDhcpC */ &hDhcpC,
/* hServer */ hServer,
/* hSubnet */ hSubnet,
/* Reserved */ DDS_RESERVED_DWORD,
/* ServerName */ ServerName,
/* Start */ Elt->Element.IpRange->StartAddress,
/* End */ Elt->Element.IpRange->EndAddress,
/* RangeOrExcl */ TRUE // range
);
} else if( DhcpExcludedIpRanges == Elt->ElementType ) {
Err = DhcpDsSubnetDelRangeOrExcl // del its
(
/* hDhcpC */ &hDhcpC,
/* hServer */ hServer,
/* hSubnet */ hSubnet,
/* Reserved */ DDS_RESERVED_DWORD,
/* ServerName */ ServerName,
/* Start */ Elt->Element.ExcludeIpRange->StartAddress,
/* End */ Elt->Element.ExcludeIpRange->EndAddress,
/* RangeOrExcl */ FALSE // excl
);
} else if( DhcpReservedIps == Elt->ElementType ) {
Err = DhcpDsSubnetDelReservation // del its
(
/* hDhcpC */ &hDhcpC,
/* hServer */ hServer,
/* hSubnet */ hSubnet,
/* Reserved */ DDS_RESERVED_DWORD,
/* ServerName */ ServerName,
/* ReservedAddddr */ Elt->Element.ReservedIp->ReservedIpAddress
);
} else {
Err = ERROR_CALL_NOT_IMPLEMENTED;
}
return Err;
}
//DOC DelSubnetElement deltes one of Excl,Ip Range or Reservation to frm subnet
//DOC object specified in the DS.
DWORD
DelSubnetElement( // del excl/range/res. frm subnet
IN OUT LPSTORE_HANDLE hServer, // server obj in DS
IN OUT LPSTORE_HANDLE hSubnet, // subnet obj in DS
IN LPWSTR ServerName, // name of dhcp server
IN LPDHCP_SUBNET_ELEMENT_DATA_V4 Elt // the element to add
)
{
DWORD Err;
if( DhcpIpRanges == Elt->ElementType ) { // del a new range
Err = DhcpDsSubnetDelRangeOrExcl // del its
(
/* hDhcpC */ &hDhcpC,
/* hServer */ hServer,
/* hSubnet */ hSubnet,
/* Reserved */ DDS_RESERVED_DWORD,
/* ServerName */ ServerName,
/* Start */ Elt->Element.IpRange->StartAddress,
/* End */ Elt->Element.IpRange->EndAddress,
/* RangeOrExcl */ TRUE // range
);
} else if( DhcpExcludedIpRanges == Elt->ElementType ) {
Err = DhcpDsSubnetDelRangeOrExcl // del its
(
/* hDhcpC */ &hDhcpC,
/* hServer */ hServer,
/* hSubnet */ hSubnet,
/* Reserved */ DDS_RESERVED_DWORD,
/* ServerName */ ServerName,
/* Start */ Elt->Element.ExcludeIpRange->StartAddress,
/* End */ Elt->Element.ExcludeIpRange->EndAddress,
/* RangeOrExcl */ FALSE // excl
);
} else if( DhcpReservedIps == Elt->ElementType ) {
Err = DhcpDsSubnetDelReservation // del its
(
/* hDhcpC */ &hDhcpC,
/* hServer */ hServer,
/* hSubnet */ hSubnet,
/* Reserved */ DDS_RESERVED_DWORD,
/* ServerName */ ServerName,
/* ReservedAddddr */ Elt->Element.ReservedIp->ReservedIpAddress
);
} else {
Err = ERROR_CALL_NOT_IMPLEMENTED;
}
return Err;
}
//================================================================================
// the following functions are NOT based on RPC, but actually direct calls to
// the DS. But, they have the same interface as the RPC stubs in dhcpsapi.dll.
//================================================================================
//================================================================================
// Names for functions here and in dhcpsapi.dll should not be same. So, here is
// a bunch of hash defines to take care fo that problem..
//================================================================================
//BeginExport(defines)
#ifndef CONVERT_NAMES
#define DhcpCreateSubnet DhcpCreateSubnetDS
#define DhcpSetSubnetInfo DhcpSetSubnetInfoDS
#define DhcpGetSubnetInfo DhcpGetSubnetInfoDS
#define DhcpEnumSubnets DhcpEnumSubnetsDS
#define DhcpDeleteSubnet DhcpDeleteSubnetDS
#define DhcpCreateOption DhcpCreateOptionDS
#define DhcpSetOptionInfo DhcpSetOptionInfoDS
#define DhcpGetOptionInfo DhcpGetOptionInfoDS
#define DhcpRemoveOption DhcpRemoveOptionDS
#define DhcpSetOptionValue DhcpSetOptionValueDS
#define DhcpGetOptionValue DhcpGetOptionValueDS
#define DhcpEnumOptionValues DhcpEnumOptionValuesDS
#define DhcpRemoveOptionValue DhcpRemoveOptionValueDS
#define DhcpEnumOptions DhcpEnumOptionsDS
#define DhcpSetOptionValues DhcpSetOptionValuesDS
#define DhcpAddSubnetElement DhcpAddSubnetElementDS
#define DhcpEnumSubnetElements DhcpEnumSubnetElementsDS
#define DhcpRemoveSubnetElement DhcpRemoveSubnetElementDS
#define DhcpAddSubnetElementV4 DhcpAddSubnetElementV4DS
#define DhcpEnumSubnetElementsV4 DhcpEnumSubnetElementsV4DS
#define DhcpRemoveSubnetElementV4 DhcpRemoveSubnetElementV4DS
#define DhcpSetSuperScopeV4 DhcpSetSuperScopeV4DS
#define DhcpGetSuperScopeInfoV4 DhcpGetSuperScopeInfoV4DS
#define DhcpDeleteSuperScopeV4 DhcpDeleteSuperScopeV4DS
#define DhcpSetClientInfo DhcpSetClientInfoDS
#define DhcpGetClientInfo DhcpGetClientInfoDS
#define DhcpSetClientInfoV4 DhcpSetClientInfoV4DS
#define DhcpGetClientInfoV4 DhcpGetClientInfoV4DS
#define DhcpCreateOptionV5 DhcpCreateOptionV5DS
#define DhcpSetOptionInfoV5 DhcpSetOptionInfoV5DS
#define DhcpGetOptionInfoV5 DhcpGetOptionInfoV5DS
#define DhcpEnumOptionsV5 DhcpEnumOptionsV5DS
#define DhcpRemoveOptionV5 DhcpRemoveOptionV5DS
#define DhcpSetOptionValueV5 DhcpSetOptionValueV5DS
#define DhcpSetOptionValuesV5 DhcpSetOptionValuesV5DS
#define DhcpGetOptionValueV5 DhcpGetOptionValueV5DS
#define DhcpEnumOptionValuesV5 DhcpEnumOptionValuesV5DS
#define DhcpRemoveOptionValueV5 DhcpRemoveOptionValueV5DS
#define DhcpCreateClass DhcpCreateClassDS
#define DhcpModifyClass DhcpModifyClassDS
#define DhcpDeleteClass DhcpDeleteClassDS
#define DhcpGetClassInfo DhcpGetClassInfoDS
#define DhcpEnumClasses DhcpEnumClassesDS
#define DhcpGetAllOptions DhcpGetAllOptionsDS
#define DhcpGetAllOptionValues DhcpGetAllOptionValuesDS
#endif CONVERT_NAMES
//EndExport(defines)
BOOLEAN
DhcpDsDllInit(
IN HINSTANCE DllHandle,
IN ULONG Reason,
IN PCONTEXT Context OPTIONAL
)
/*++
Routine Description:
This routine is the standard DLL initialization
routine and all it does is intiialize a critical section
for actual initialization to be done at startup elsewhere.
Arguments:
DllHandle -- handle to current module
Reason -- reason for DLL_PROCESS_ATTACH.. DLL_PROCESS_DETACH
Return Value:
TRUE -- success, FALSE -- failure
--*/
{
if( DLL_PROCESS_ATTACH == Reason ) {
//
// First disable further calls to DllInit
//
if( !DisableThreadLibraryCalls( DllHandle ) ) return FALSE;
//
// Now try to create critical section
//
try {
InitializeCriticalSection(&DhcpDsDllCriticalSection);
} except ( EXCEPTION_EXECUTE_HANDLER ) {
// shouldnt happen but you never know.
return FALSE;
}
} else if( DLL_PROCESS_DETACH == Reason ) {
//
// Cleanup the initialization critical section
//
DeleteCriticalSection(&DhcpDsDllCriticalSection);
}
//
// InitializeCriticalSection does not fail, just throws exception..
// so we always return success.
//
return TRUE;
}
//================================================================================
//================================================================================
// OPTIONS STUFF. Several of the "get" api's are not yet implemneted here.. but
// it is a straigthforward thing to call the DhcpDs versions... they will get
// filled here someday soon.
//================================================================================
//================================================================================
//BeginExport(function)
//DOC Create an option in DS. Checkout DhcpDsCreateOptionDef for more info...
DWORD
DhcpCreateOptionV5( // create a new option (must not exist)
IN LPWSTR ServerIpAddress,
IN DWORD Flags,
IN DHCP_OPTION_ID OptionId, // must be between 0-255 or 256-511 (for vendor stuff)
IN LPWSTR ClassName,
IN LPWSTR VendorName,
IN LPDHCP_OPTION OptionInfo
) //EndExport(function)
{
DWORD Err, Err2;
STORE_HANDLE hServer,hSubnet;
LPBYTE OptVal;
DWORD OptLen, OptId;
BOOL IsVendor = (0 != (Flags & DHCP_FLAGS_OPTION_IS_VENDOR));
if( Flags & ~DHCP_FLAGS_OPTION_IS_VENDOR ) return ERROR_INVALID_PARAMETER;
if( STUB_NOT_INITIALIZED(Err) ) return ErrorNotInitialized;
Err = DhcpDsLock(&hDhcpRoot); // take a lock on the DS
if( ERROR_SUCCESS != Err ) return ERROR_DDS_NO_DS_AVAILABLE;
OptId = ConvertOptIdToMemValue(OptionId, IsVendor);
Err = ConvertOptionInfoRPCToMemFormat(OptionInfo, NULL, NULL, NULL, &OptVal, &OptLen);
if( ERROR_SUCCESS != Err ) { // could not convert to easy format
DhcpDsUnlock(&hDhcpRoot);
return Err;
}
Err = GetServer(&hServer, ServerIpAddress );
if( ERROR_SUCCESS != Err ) { // get the server object
DhcpDsUnlock(&hDhcpRoot);
if( OptVal ) MemFree(OptVal);
return Err;
}
Err = DhcpDsCreateOptionDef // create the required option
(
/* hDhcpC */ &hDhcpC,
/* hServer */ &hServer,
/* Reserved */ DDS_RESERVED_DWORD,
/* Name */ OptionInfo->OptionName,
/* Comment */ OptionInfo->OptionComment,
/* ClassName */ VendorName,
/* OptId */ OptId,
/* OptType */ OptionInfo->OptionType,
/* OptVal */ OptVal,
/* OptLen */ OptLen
);
if( OptVal ) MemFree(OptVal);
StoreCleanupHandle(&hServer, 0);
DhcpDsUnlock(&hDhcpRoot);
return Err;
}
//BeginExport(function)
//DOC Modify existing option's fields in the DS. See DhcpDsModifyOptionDef for more
//DOC details
DWORD
DhcpSetOptionInfoV5( // Modify existing option's fields
IN LPWSTR ServerIpAddress,
IN DWORD Flags,
IN DHCP_OPTION_ID OptionId,
IN LPWSTR ClassName,
IN LPWSTR VendorName,
IN LPDHCP_OPTION OptionInfo
) //EndExport(function)
{
DWORD Err, Err2;
STORE_HANDLE hServer,hSubnet;
LPBYTE OptVal;
DWORD OptLen, OptId;
BOOL IsVendor = (0 != (Flags & DHCP_FLAGS_OPTION_IS_VENDOR));
if( Flags & ~DHCP_FLAGS_OPTION_IS_VENDOR ) return ERROR_INVALID_PARAMETER;
if( STUB_NOT_INITIALIZED(Err)) return ErrorNotInitialized;
Err = DhcpDsLock(&hDhcpRoot); // take a lock on the DS
if( ERROR_SUCCESS != Err ) return ERROR_DDS_NO_DS_AVAILABLE;
OptId = ConvertOptIdToMemValue(OptionId, IsVendor);
Err = ConvertOptionInfoRPCToMemFormat(OptionInfo, NULL, NULL, NULL, &OptVal, &OptLen);
if( ERROR_SUCCESS != Err ) { // could not convert to easy format
DhcpDsUnlock(&hDhcpRoot);
return Err;
}
Err = GetServer(&hServer, ServerIpAddress );
if( ERROR_SUCCESS != Err ) { // get the server object
DhcpDsUnlock(&hDhcpRoot);
if( OptVal ) MemFree(OptVal);
return Err;
}
Err = DhcpDsModifyOptionDef // modify the required option
(
/* hDhcpC */ &hDhcpC,
/* hServer */ &hServer,
/* Reserved */ DDS_RESERVED_DWORD,
/* Name */ OptionInfo->OptionName,
/* Comment */ OptionInfo->OptionComment,
/* ClassName */ VendorName,
/* OptId */ OptId,
/* OptType */ OptionInfo->OptionType,
/* OptVal */ OptVal,
/* OptLen */ OptLen
);
if( OptVal ) MemFree(OptVal);
StoreCleanupHandle(&hServer, 0);
DhcpDsUnlock(&hDhcpRoot);
return Err;
}
//BeginExport(function)
//DOC not yet supported at this level... (this is supported in a
//DOC DhcpDs function, no wrapper yet)
DWORD
DhcpGetOptionInfoV5( // retrieve option info from off ds structures
IN LPWSTR ServerIpAddress,
IN DWORD Flags,
IN DHCP_OPTION_ID OptionId,
IN LPWSTR ClassName,
IN LPWSTR VendorName,
OUT LPDHCP_OPTION *OptionInfo // allocate memory
) //EndExport(function)
{
DWORD Err, Err2;
STORE_HANDLE hServer,hSubnet;
LPBYTE OptVal;
DWORD OptLen, OptId;
BOOL IsVendor = (0 != (Flags & DHCP_FLAGS_OPTION_IS_VENDOR));
if( Flags & ~DHCP_FLAGS_OPTION_IS_VENDOR ) return ERROR_INVALID_PARAMETER;
OptionId = ConvertOptIdToMemValue(OptionId, IsVendor);
if( STUB_NOT_INITIALIZED(Err) ) return ErrorNotInitialized;
Err = DhcpDsLock(&hDhcpRoot); // take a lock on the DS
if( ERROR_SUCCESS != Err ) return ERROR_DDS_NO_DS_AVAILABLE;
Err = GetServer(&hServer, ServerIpAddress );
if( ERROR_SUCCESS != Err ) { // get the server object
DhcpDsUnlock(&hDhcpRoot);
return Err;
}
Err = DhcpDsGetOptionDef // get the option info from DS
(
/* hDhcpC */ &hDhcpC,
/* hServer */ &hServer,
/* Reserved */ DDS_RESERVED_DWORD,
/* ClassName */ VendorName,
/* OptId */ OptionId,
/* OptInfo */ OptionInfo
);
StoreCleanupHandle(&hServer, 0);
DhcpDsUnlock(&hDhcpRoot);
return Err;
}
//BeginExport(function)
//DOC See DhcpDsEnumOptionDefs for more info on this function.. but essentially, all this
//DOC does is to read thru the options and create a list of options..
DWORD
DhcpEnumOptionsV5( // create list of all options in ds
IN LPWSTR ServerIpAddress,
IN DWORD Flags,
IN LPWSTR ClassName,
IN LPWSTR VendorName,
IN OUT DHCP_RESUME_HANDLE *ResumeHandle,
IN DWORD PreferredMaximum,
OUT LPDHCP_OPTION_ARRAY *Options,
OUT DWORD *OptionsRead,
OUT DWORD *OptionsTotal
) //EndExport(function)
{
DWORD Err, Err2;
STORE_HANDLE hServer,hSubnet;
BOOL IsVendor = (0 != (Flags & DHCP_FLAGS_OPTION_IS_VENDOR));
if( Flags & ~DHCP_FLAGS_OPTION_IS_VENDOR ) return ERROR_INVALID_PARAMETER;
if( NULL == OptionsRead || NULL == OptionsTotal
|| NULL == Options || NULL == ResumeHandle ) {
return ERROR_INVALID_PARAMETER;
}
if( STUB_NOT_INITIALIZED(Err) ) return ErrorNotInitialized;
Err = DhcpDsLock(&hDhcpRoot); // take a lock on the DS
if( ERROR_SUCCESS != Err ) return ERROR_DDS_NO_DS_AVAILABLE;
Err = GetServer(&hServer, ServerIpAddress );
if( ERROR_SUCCESS != Err ) { // get the server object
DhcpDsUnlock(&hDhcpRoot);
return Err;
}
Err = DhcpDsEnumOptionDefs // get opt list from ds
(
/* hDhcpC */ &hDhcpC,
/* hServer */ &hServer,
/* Reserved */ DDS_RESERVED_DWORD,
/* ClassName */ VendorName,
/* IsVendor */ IsVendor,
/* RetOptArray */ Options
);
if( ERROR_SUCCESS == Err ) {
*OptionsRead = (*Options)->NumElements;
*OptionsTotal = *OptionsRead;
}
StoreCleanupHandle(&hServer, 0);
DhcpDsUnlock(&hDhcpRoot);
return Err;
}
//BeginExport(function)
//DOC Delete an option from off the DS. See DhcpDsDeleteOptionDef for
//DOC more details.
DWORD
DhcpRemoveOptionV5( // remove an option from off DS
IN LPWSTR ServerIpAddress,
IN DWORD Flags,
IN DHCP_OPTION_ID OptionId,
IN LPWSTR ClassName,
IN LPWSTR VendorName
) //EndExport(function)
{
DWORD Err, Err2;
STORE_HANDLE hServer,hSubnet;
DWORD OptId;
BOOL IsVendor = (0 != (Flags & DHCP_FLAGS_OPTION_IS_VENDOR));
if( Flags & ~DHCP_FLAGS_OPTION_IS_VENDOR ) return ERROR_INVALID_PARAMETER;
if( STUB_NOT_INITIALIZED(Err) ) return ErrorNotInitialized;
Err = DhcpDsLock(&hDhcpRoot); // take a lock on the DS
if( ERROR_SUCCESS != Err ) return ERROR_DDS_NO_DS_AVAILABLE;
OptId = ConvertOptIdToMemValue(OptionId, IsVendor);
Err = GetServer(&hServer, ServerIpAddress );
if( ERROR_SUCCESS != Err ) { // get the server object
DhcpDsUnlock(&hDhcpRoot);
return Err;
}
Err = DhcpDsDeleteOptionDef // delete the required option
(
/* hDhcpC */ &hDhcpC,
/* hServer */ &hServer,
/* Reserved */ DDS_RESERVED_DWORD,
/* ClassName */ VendorName,
/* OptId */ OptId
);
StoreCleanupHandle(&hServer, 0);
DhcpDsUnlock(&hDhcpRoot);
return Err;
}
//BeginExport(function)
//DOC Set the specified option value in the DS. For more information,
//DOC see DhcpDsSetOptionValue.
DWORD
DhcpSetOptionValueV5( // set the option value in ds
IN LPWSTR ServerIpAddress,
IN DWORD Flags,
IN DHCP_OPTION_ID OptionId,
IN LPWSTR ClassName,
IN LPWSTR VendorName,
IN LPDHCP_OPTION_SCOPE_INFO ScopeInfo,
IN LPDHCP_OPTION_DATA OptionValue
) //EndExport(function)
{
DWORD Err, Err2;
STORE_HANDLE hServer,hSubnet,hReservation;
LPSTORE_HANDLE hObject;
DWORD OptId;
BOOL IsVendor = (0 != (Flags & DHCP_FLAGS_OPTION_IS_VENDOR));
if( Flags & ~DHCP_FLAGS_OPTION_IS_VENDOR ) return ERROR_INVALID_PARAMETER;
if( NULL == ScopeInfo ) {
return ERROR_INVALID_PARAMETER;
}
if( DhcpDefaultOptions == ScopeInfo->ScopeType ) {
return ERROR_CALL_NOT_IMPLEMENTED;
#if 0
return DhcpSetOptionInfoV5( // setting default options?
ServerIpAddress,
OptionId,
ClassName,
IsVendor,
OptionInfo
);
#endif
}
if( NULL == OptionValue ) {
return ERROR_INVALID_PARAMETER;
}
if( STUB_NOT_INITIALIZED(Err) ) return ErrorNotInitialized;
Err = DhcpDsLock(&hDhcpRoot); // take a lock on the DS
if( ERROR_SUCCESS != Err ) return ERROR_DDS_NO_DS_AVAILABLE;
Err = GetServer(&hServer, ServerIpAddress );
if( ERROR_SUCCESS != Err ) { // get the server object
DhcpDsUnlock(&hDhcpRoot);
return Err;
}
if( DhcpGlobalOptions == ScopeInfo->ScopeType ) {
hObject = &hServer; // server level options
Err = ERROR_SUCCESS;
} else {
if( DhcpSubnetOptions == ScopeInfo->ScopeType ) {
Err = GetSubnet(&hServer, &hSubnet, ScopeInfo->ScopeInfo.SubnetScopeInfo);
hObject = &hSubnet; // subnet level options
} else if( DhcpReservedOptions != ScopeInfo->ScopeType ) {
Err = ERROR_INVALID_PARAMETER;
} else { // reservation level options
Err = GetReservation(
&hServer,
&hReservation,
ScopeInfo->ScopeInfo.ReservedScopeInfo.ReservedIpSubnetAddress,
ScopeInfo->ScopeInfo.ReservedScopeInfo.ReservedIpAddress
);
hObject = &hReservation;
}
}
if( ERROR_SUCCESS != Err ) {
DhcpDsUnlock(&hDhcpRoot);
StoreCleanupHandle(&hServer, 0);
return Err;
}
OptId = ConvertOptIdToMemValue(OptionId, IsVendor);
Err = DhcpDsSetOptionValue // set the option value in DS now
(
/* hDhcpC */ &hDhcpC,
/* hObject */ hObject,
/* Reserved */ DDS_RESERVED_DWORD,
/* ClassName */ VendorName,
/* UserClass */ ClassName,
/* OptId */ OptId,
/* OptData */ OptionValue
);
StoreCleanupHandle(&hServer, 0);
if( hObject != &hServer ) StoreCleanupHandle(hObject, 0);
DhcpDsUnlock(&hDhcpRoot);
return Err;
}
//BeginExport(function)
//DOC This function just calls the SetOptionValue function N times.. this is not
//DOC atomic (), but even worse, it is highly inefficient, as it creates the
//DOC required objects over and over again!!!!!
//DOC This has to be fixed..
DWORD
DhcpSetOptionValuesV5( // set a series of option values
IN LPWSTR ServerIpAddress,
IN DWORD Flags,
IN LPWSTR ClassName,
IN LPWSTR VendorName,
IN LPDHCP_OPTION_SCOPE_INFO ScopeInfo,
IN LPDHCP_OPTION_VALUE_ARRAY OptionValues
) //EndExport(function)
{
DWORD Err, Err2;
STORE_HANDLE hServer,hSubnet,hReservation;
LPSTORE_HANDLE hObject;
DWORD OptId, i, OptionId;
BOOL IsVendor = (0 != (Flags & DHCP_FLAGS_OPTION_IS_VENDOR));
if( Flags & ~DHCP_FLAGS_OPTION_IS_VENDOR ) return ERROR_INVALID_PARAMETER;
if( NULL == ScopeInfo ) {
return ERROR_INVALID_PARAMETER;
}
if( DhcpDefaultOptions == ScopeInfo->ScopeType ) {
return ERROR_CALL_NOT_IMPLEMENTED;
#if 0
for( i = 0; i < OptionValues->NumElements; i ++ ) {
Err = DhcpSetOptionInfoV5( // setting default options?
ServerIpAddress,
OptionValues->Values[i].OptionID,
ClassName,
IsVendor,
&OptionValues->Values[i].Value
);
if( ERROR_SUCCESS != Err ) break;
}
return Err;
#endif
}
if( NULL == OptionValues ) {
return ERROR_INVALID_PARAMETER;
}
if( STUB_NOT_INITIALIZED(Err) ) return ErrorNotInitialized;
Err = DhcpDsLock(&hDhcpRoot); // take a lock on the DS
if( ERROR_SUCCESS != Err ) return ERROR_DDS_NO_DS_AVAILABLE;
Err = GetServer(&hServer, ServerIpAddress );
if( ERROR_SUCCESS != Err ) { // get the server object
DhcpDsUnlock(&hDhcpRoot);
return Err;
}
if( DhcpGlobalOptions == ScopeInfo->ScopeType ) {
hObject = &hServer; // server level options
Err = ERROR_SUCCESS;
} else {
if( DhcpSubnetOptions == ScopeInfo->ScopeType ) {
Err = GetSubnet(&hServer, &hSubnet, ScopeInfo->ScopeInfo.SubnetScopeInfo);
hObject = &hSubnet; // subnet level options
} else if( DhcpReservedOptions != ScopeInfo->ScopeType ) {
Err = ERROR_INVALID_PARAMETER;
} else { // reservation level options
Err = GetReservation(
&hServer,
&hReservation,
ScopeInfo->ScopeInfo.ReservedScopeInfo.ReservedIpSubnetAddress,
ScopeInfo->ScopeInfo.ReservedScopeInfo.ReservedIpAddress
);
hObject = &hReservation;
}
}
if( ERROR_SUCCESS != Err ) {
DhcpDsUnlock(&hDhcpRoot);
StoreCleanupHandle(&hServer, 0);
return Err;
}
for( i = 0; i < OptionValues->NumElements; i ++ ) {
OptionId = OptionValues->Values[i].OptionID;
OptId = ConvertOptIdToMemValue(OptionId, IsVendor);
Err = DhcpDsSetOptionValue // set the option value in DS now
(
/* hDhcpC */ &hDhcpC,
/* hObject */ hObject,
/* Reserved */ DDS_RESERVED_DWORD,
/* ClassName */ VendorName,
/* UserClass */ ClassName,
/* OptId */ OptId,
/* OptData */ &OptionValues->Values[i].Value
);
if( ERROR_SUCCESS != Err ) break; // not atomic, so break whenever err
}
StoreCleanupHandle(&hServer, 0);
if( hObject != &hServer ) StoreCleanupHandle(hObject, 0);
DhcpDsUnlock(&hDhcpRoot);
return Err;
}
//BeginExport(function)
//DOC This function retrives the value of an option from the DS. For more info,
//DOC pl check DhcpDsGetOptionValue.
DWORD
DhcpGetOptionValueV5(
IN LPWSTR ServerIpAddress,
IN DWORD Flags,
IN DHCP_OPTION_ID OptionId,
IN LPWSTR ClassName,
IN LPWSTR VendorName,
IN LPDHCP_OPTION_SCOPE_INFO ScopeInfo,
OUT LPDHCP_OPTION_VALUE *OptionValue
) //EndExport(function)
{
DWORD Err, Err2;
STORE_HANDLE hServer,hSubnet,hReservation;
LPSTORE_HANDLE hObject;
DWORD OptId;
BOOL IsVendor = (0 != (Flags & DHCP_FLAGS_OPTION_IS_VENDOR));
if( Flags & ~DHCP_FLAGS_OPTION_IS_VENDOR ) return ERROR_INVALID_PARAMETER;
if( NULL == ScopeInfo ) {
return ERROR_INVALID_PARAMETER;
}
if( DhcpDefaultOptions == ScopeInfo->ScopeType ) {
return ERROR_CALL_NOT_IMPLEMENTED;
#if 0
return DhcpGetOptionInfoV5( // getting default options?
ServerIpAddress,
OptionId,
ClassName,
IsVendor,
OptionValue
);
#endif 0
}
if( NULL == OptionValue ) {
return ERROR_INVALID_PARAMETER;
}
if( STUB_NOT_INITIALIZED(Err) ) return ErrorNotInitialized;
Err = DhcpDsLock(&hDhcpRoot); // take a lock on the DS
if( ERROR_SUCCESS != Err ) return ERROR_DDS_NO_DS_AVAILABLE;
OptId = ConvertOptIdToMemValue(OptionId, IsVendor);
Err = GetServer(&hServer, ServerIpAddress );
if( ERROR_SUCCESS != Err ) { // get the server object
DhcpDsUnlock(&hDhcpRoot);
return Err;
}
if( DhcpGlobalOptions == ScopeInfo->ScopeType ) {
hObject = &hServer; // server level options
Err = ERROR_SUCCESS;
} else {
if( DhcpSubnetOptions == ScopeInfo->ScopeType ) {
Err = GetSubnet(&hServer, &hSubnet, ScopeInfo->ScopeInfo.SubnetScopeInfo);
hObject = &hSubnet; // subnet level options
} else if( DhcpReservedOptions != ScopeInfo->ScopeType ) {
Err = ERROR_INVALID_PARAMETER;
} else { // reservation level options
Err = GetReservation(
&hServer,
&hReservation,
ScopeInfo->ScopeInfo.ReservedScopeInfo.ReservedIpSubnetAddress,
ScopeInfo->ScopeInfo.ReservedScopeInfo.ReservedIpAddress
);
hObject = &hReservation;
}
}
if( ERROR_SUCCESS != Err ) {
DhcpDsUnlock(&hDhcpRoot);
StoreCleanupHandle(&hServer, 0);
return Err;
}
Err = DhcpDsGetOptionValue // get the option value in DS now
(
/* hDhcpC */ &hDhcpC,
/* hObject */ hObject,
/* Reserved */ DDS_RESERVED_DWORD,
/* ClassName */ VendorName,
/* UserClass */ ClassName,
/* OptId */ OptId,
/* OptData */ OptionValue
);
StoreCleanupHandle(&hServer, 0);
if( hObject != &hServer ) StoreCleanupHandle(hObject, 0);
DhcpDsUnlock(&hDhcpRoot);
return Err;
}
//BeginExport(function)
//DOC Get the list of option values defined in DS. For more information,
//DOC check DhcpDsEnumOptionValues.
DWORD
DhcpEnumOptionValuesV5( // get list of options defined in DS
IN LPWSTR ServerIpAddress,
IN DWORD Flags,
IN LPWSTR ClassName,
IN LPWSTR VendorName,
IN LPDHCP_OPTION_SCOPE_INFO ScopeInfo,
IN DHCP_RESUME_HANDLE *ResumeHandle,
IN DWORD PreferredMaximum,
OUT LPDHCP_OPTION_VALUE_ARRAY *OptionValues,
OUT DWORD *OptionsRead,
OUT DWORD *OptionsTotal
) //EndExport(function)
{
DWORD Err, Err2;
STORE_HANDLE hServer,hSubnet,hReservation;
LPSTORE_HANDLE hObject;
DWORD OptId;
BOOL IsVendor = (0 != (Flags & DHCP_FLAGS_OPTION_IS_VENDOR));
if( Flags & ~DHCP_FLAGS_OPTION_IS_VENDOR ) return ERROR_INVALID_PARAMETER;
if( NULL == ScopeInfo ) {
return ERROR_INVALID_PARAMETER;
}
if( DhcpDefaultOptions == ScopeInfo->ScopeType ) {
return ERROR_INVALID_PARAMETER; // : totally suspcicious..
}
if( STUB_NOT_INITIALIZED(Err) ) return ErrorNotInitialized;
Err = DhcpDsLock(&hDhcpRoot); // take a lock on the DS
if( ERROR_SUCCESS != Err ) return ERROR_DDS_NO_DS_AVAILABLE;
Err = GetServer(&hServer, ServerIpAddress );
if( ERROR_SUCCESS != Err ) { // get the server object
DhcpDsUnlock(&hDhcpRoot);
return Err;
}
if( DhcpGlobalOptions == ScopeInfo->ScopeType ) {
hObject = &hServer; // server level options
Err = ERROR_SUCCESS;
} else {
if( DhcpSubnetOptions == ScopeInfo->ScopeType ) {
Err = GetSubnet(&hServer, &hSubnet, ScopeInfo->ScopeInfo.SubnetScopeInfo);
hObject = &hSubnet; // subnet level options
} else if( DhcpReservedOptions != ScopeInfo->ScopeType ) {
Err = ERROR_INVALID_PARAMETER;
} else { // reservation level options
Err = GetReservation(
&hServer,
&hReservation,
ScopeInfo->ScopeInfo.ReservedScopeInfo.ReservedIpSubnetAddress,
ScopeInfo->ScopeInfo.ReservedScopeInfo.ReservedIpAddress
);
hObject = &hReservation;
}
}
if( ERROR_SUCCESS != Err ) {
DhcpDsUnlock(&hDhcpRoot);
StoreCleanupHandle(&hServer, 0);
return Err;
}
Err = DhcpDsEnumOptionValues // remove opt val frm DS now
(
/* hDhcpC */ &hDhcpC,
/* hObject */ hObject,
/* Reserved */ DDS_RESERVED_DWORD,
/* ClassName */ VendorName,
/* UserClass */ ClassName,
/* IsVendor */ IsVendor,
/* OptionValues */ OptionValues
);
if( ERROR_SUCCESS == Err ) { // set the read etc params
*OptionsRead = *OptionsTotal = (*OptionValues)->NumElements;
}
StoreCleanupHandle(&hServer, 0);
if( hObject != &hServer ) StoreCleanupHandle(hObject, 0);
DhcpDsUnlock(&hDhcpRoot);
return Err;
}
//BeginExport(function)
//DOC Remove the option value from off the DS. See DhcpDsRemoveOptionValue
//DOC for further information.
DWORD
DhcpRemoveOptionValueV5( // remove option value from DS
IN LPWSTR ServerIpAddress,
IN DWORD Flags,
IN DHCP_OPTION_ID OptionId,
IN LPWSTR ClassName,
IN LPWSTR VendorName,
IN LPDHCP_OPTION_SCOPE_INFO ScopeInfo
) //EndExport(function)
{
DWORD Err, Err2;
STORE_HANDLE hServer,hSubnet,hReservation;
LPSTORE_HANDLE hObject;
DWORD OptId;
BOOL IsVendor = (0 != (Flags & DHCP_FLAGS_OPTION_IS_VENDOR));
if( Flags & ~DHCP_FLAGS_OPTION_IS_VENDOR ) return ERROR_INVALID_PARAMETER;
if( NULL == ScopeInfo ) {
return ERROR_INVALID_PARAMETER;
}
if( DhcpDefaultOptions == ScopeInfo->ScopeType ) {
return ERROR_INVALID_PARAMETER; // : totally suspcicious..
}
if( STUB_NOT_INITIALIZED(Err) ) return ErrorNotInitialized;
Err = DhcpDsLock(&hDhcpRoot); // take a lock on the DS
if( ERROR_SUCCESS != Err ) return ERROR_DDS_NO_DS_AVAILABLE;
OptId = ConvertOptIdToMemValue(OptionId, IsVendor);
Err = GetServer(&hServer, ServerIpAddress );
if( ERROR_SUCCESS != Err ) { // get the server object
DhcpDsUnlock(&hDhcpRoot);
return Err;
}
if( DhcpGlobalOptions == ScopeInfo->ScopeType ) {
hObject = &hServer; // server level options
Err = ERROR_SUCCESS;
} else {
if( DhcpSubnetOptions == ScopeInfo->ScopeType ) {
Err = GetSubnet(&hServer, &hSubnet, ScopeInfo->ScopeInfo.SubnetScopeInfo);
hObject = &hSubnet; // subnet level options
} else if( DhcpReservedOptions != ScopeInfo->ScopeType ) {
Err = ERROR_INVALID_PARAMETER;
} else { // reservation level options
Err = GetReservation(
&hServer,
&hReservation,
ScopeInfo->ScopeInfo.ReservedScopeInfo.ReservedIpSubnetAddress,
ScopeInfo->ScopeInfo.ReservedScopeInfo.ReservedIpAddress
);
hObject = &hReservation;
}
}
if( ERROR_SUCCESS != Err ) {
DhcpDsUnlock(&hDhcpRoot);
StoreCleanupHandle(&hServer, 0);
return Err;
}
Err = DhcpDsRemoveOptionValue // remove opt val frm DS now
(
/* hDhcpC */ &hDhcpC,
/* hObject */ hObject,
/* Reserved */ DDS_RESERVED_DWORD,
/* ClassName */ VendorName,
/* UserClass */ ClassName,
/* OptId */ OptId
);
StoreCleanupHandle(&hServer, 0);
if( hObject != &hServer ) StoreCleanupHandle(hObject, 0);
DhcpDsUnlock(&hDhcpRoot);
return Err;
}
//BeginExport(function)
//DOC Create a class in the DS. Please see DhcpDsCreateClass for more
//DOC details on this function.
DWORD
DhcpCreateClass( // create a class in DS
IN LPWSTR ServerIpAddress,
IN DWORD ReservedMustBeZero,
IN LPDHCP_CLASS_INFO ClassInfo
) //EndExport(function)
{
DWORD Err, Err2;
STORE_HANDLE hServer,hSubnet;
if( NULL == ClassInfo || 0 != ReservedMustBeZero ) {
return ERROR_INVALID_PARAMETER;
}
if( STUB_NOT_INITIALIZED(Err) ) return ErrorNotInitialized;
Err = DhcpDsLock(&hDhcpRoot); // take a lock on the DS
if( ERROR_SUCCESS != Err ) return ERROR_DDS_NO_DS_AVAILABLE;
Err = GetServer(&hServer, ServerIpAddress );
if( ERROR_SUCCESS != Err ) { // get the server object
DhcpDsUnlock(&hDhcpRoot);
return Err;
}
Err = DhcpDsCreateClass // create the class
(
/* hDhcpC */ &hDhcpC,
/* hServer */ &hServer,
/* Reserved */ DDS_RESERVED_DWORD,
/* ClassName */ ClassInfo->ClassName,
/* ClassComment */ ClassInfo->ClassComment,
/* ClassData */ ClassInfo->ClassData,
/* ClassDataLength */ ClassInfo->ClassDataLength,
/* IsVendor */ ClassInfo->IsVendor
);
StoreCleanupHandle(&hServer, 0);
DhcpDsUnlock(&hDhcpRoot);
return Err;
}
//BeginExport(function)
//DOC Modify an existing class in DS. Please see DhcpDsModifyClass for more
//DOC details on this function (this is just a wrapper).
DWORD
DhcpModifyClass( // modify existing class
IN LPWSTR ServerIpAddress,
IN DWORD ReservedMustBeZero,
IN LPDHCP_CLASS_INFO ClassInfo
) //EndExport(function)
{
DWORD Err, Err2;
STORE_HANDLE hServer,hSubnet;
if( NULL == ClassInfo || 0 != ReservedMustBeZero ) {
return ERROR_INVALID_PARAMETER;
}
if( STUB_NOT_INITIALIZED(Err) ) return ErrorNotInitialized;
Err = DhcpDsLock(&hDhcpRoot); // take a lock on the DS
if( ERROR_SUCCESS != Err ) return ERROR_DDS_NO_DS_AVAILABLE;
Err = GetServer(&hServer, ServerIpAddress );
if( ERROR_SUCCESS != Err ) { // get the server object
DhcpDsUnlock(&hDhcpRoot);
return Err;
}
Err = DhcpDsModifyClass // modify the class
(
/* hDhcpC */ &hDhcpC,
/* hServer */ &hServer,
/* Reserved */ DDS_RESERVED_DWORD,
/* ClassName */ ClassInfo->ClassName,
/* ClassComment */ ClassInfo->ClassComment,
/* ClassData */ ClassInfo->ClassData,
/* ClassDataLength */ ClassInfo->ClassDataLength
);
StoreCleanupHandle(&hServer, 0);
DhcpDsUnlock(&hDhcpRoot);
return Err;
}
//BeginExport(function)
//DOC Delete an existing class in DS. Please see DhcpDsModifyClass for more
//DOC details on this function (this is just a wrapper).
DWORD
DhcpDeleteClass( // delete a class from off DS
IN LPWSTR ServerIpAddress,
IN DWORD ReservedMustBeZero,
IN LPWSTR ClassName
) //EndExport(function)
{
DWORD Err, Err2;
STORE_HANDLE hServer,hSubnet;
if( NULL == ClassName || 0 != ReservedMustBeZero ) {
return ERROR_INVALID_PARAMETER;
}
if( STUB_NOT_INITIALIZED(Err) ) return ErrorNotInitialized;
Err = DhcpDsLock(&hDhcpRoot); // take a lock on the DS
if( ERROR_SUCCESS != Err ) return ERROR_DDS_NO_DS_AVAILABLE;
Err = GetServer(&hServer, ServerIpAddress );
if( ERROR_SUCCESS != Err ) { // get the server object
DhcpDsUnlock(&hDhcpRoot);
return Err;
}
Err = DhcpDsDeleteClass // delete the class
(
/* hDhcpC */ &hDhcpC,
/* hServer */ &hServer,
/* Reserved */ DDS_RESERVED_DWORD,
/* ClassName */ ClassName
);
StoreCleanupHandle(&hServer, 0);
DhcpDsUnlock(&hDhcpRoot);
return Err;
}
//BeginExport(function)
//DOC DhcpGetClassInfo completes the information provided for a class in struct
//DOC PartialClassInfo. For more details pl see DhcpDsGetClassInfo.
DWORD
DhcpGetClassInfo( // fetch complete info frm DS
IN LPWSTR ServerIpAddress,
IN DWORD ReservedMustBeZero,
IN LPDHCP_CLASS_INFO PartialClassInfo,
OUT LPDHCP_CLASS_INFO *FilledClassInfo
) //EndExport(function)
{
DWORD Err, Err2;
STORE_HANDLE hServer,hSubnet;
if( NULL == PartialClassInfo || 0 != ReservedMustBeZero ) {
return ERROR_INVALID_PARAMETER;
}
if( NULL == FilledClassInfo ) {
return ERROR_INVALID_PARAMETER;
}
if( STUB_NOT_INITIALIZED(Err) ) return ErrorNotInitialized;
Err = DhcpDsLock(&hDhcpRoot); // take a lock on the DS
if( ERROR_SUCCESS != Err ) return ERROR_DDS_NO_DS_AVAILABLE;
Err = GetServer(&hServer, ServerIpAddress );
if( ERROR_SUCCESS != Err ) { // get the server object
DhcpDsUnlock(&hDhcpRoot);
return Err;
}
Err = DhcpDsGetClassInfo // get class info from DS
(
/* hDhcpC */ &hDhcpC,
/* hServer */ &hServer,
/* Reserved */ DDS_RESERVED_DWORD,
/* ClassName */ PartialClassInfo->ClassName,
/* ClassData */ PartialClassInfo->ClassData,
/* ClassDataLen */ PartialClassInfo->ClassDataLength,
/* ClassInfo */ FilledClassInfo
);
StoreCleanupHandle(&hServer, 0);
DhcpDsUnlock(&hDhcpRoot);
return Err;
}
//BeginExport(function)
//DOC This is implemented in the DHCPDS module, but not exported here yet..
DWORD
DhcpEnumClasses(
IN LPWSTR ServerIpAddress,
IN DWORD ReservedMustBeZero,
IN OUT DHCP_RESUME_HANDLE *ResumeHandle,
IN DWORD PreferredMaximum,
OUT LPDHCP_CLASS_INFO_ARRAY *ClassInfoArray,
OUT DWORD *nRead,
OUT DWORD *nTotal
) //EndExport(function)
{
DWORD Err, Err2;
STORE_HANDLE hServer,hSubnet;
if( NULL == ClassInfoArray ) return ERROR_INVALID_PARAMETER;
*nRead = *nTotal = 0;
if( STUB_NOT_INITIALIZED(Err) ) return ErrorNotInitialized;
Err = DhcpDsLock(&hDhcpRoot); // take a lock on the DS
if( ERROR_SUCCESS != Err ) return ERROR_DDS_NO_DS_AVAILABLE;
Err = GetServer(&hServer, ServerIpAddress );
if( ERROR_SUCCESS != Err ) { // get the server object
DhcpDsUnlock(&hDhcpRoot);
return Err;
}
Err = DhcpDsEnumClasses // get list of classes
(
/* hDhcpC */ &hDhcpC,
/* hServer */ &hServer,
/* Reserved */ DDS_RESERVED_DWORD,
/* Classes */ ClassInfoArray
);
if( ERROR_SUCCESS == Err ) { // filled nRead&nTotal
*nRead = *nTotal = (*ClassInfoArray)->NumElements;
}
StoreCleanupHandle(&hServer, 0);
DhcpDsUnlock(&hDhcpRoot);
return Err;
}
//BeginExport(function)
//DOC This is implemented in the DHCPDS module, but not exported here yet..
DWORD
DhcpGetAllOptionValues(
IN LPWSTR ServerIpAddress,
IN DWORD Flags,
IN LPDHCP_OPTION_SCOPE_INFO ScopeInfo,
OUT LPDHCP_ALL_OPTION_VALUES *Values
) //EndExport(function)
{
DWORD Err, Err2;
STORE_HANDLE hServer,hSubnet,hReservation;
LPSTORE_HANDLE hObject;
DWORD OptId;
if( 0 != Flags ) return ERROR_INVALID_PARAMETER;
if( NULL == ScopeInfo ) {
return ERROR_INVALID_PARAMETER;
}
if( DhcpDefaultOptions == ScopeInfo->ScopeType ) {
return ERROR_CALL_NOT_IMPLEMENTED;
}
if( NULL == Values ) {
return ERROR_INVALID_PARAMETER;
}
if( STUB_NOT_INITIALIZED(Err) ) return ErrorNotInitialized;
Err = DhcpDsLock(&hDhcpRoot); // take a lock on the DS
if( ERROR_SUCCESS != Err ) return ERROR_DDS_NO_DS_AVAILABLE;
Err = GetServer(&hServer, ServerIpAddress );
if( ERROR_SUCCESS != Err ) { // get the server object
DhcpDsUnlock(&hDhcpRoot);
return Err;
}
if( DhcpGlobalOptions == ScopeInfo->ScopeType ) {
hObject = &hServer; // server level options
Err = ERROR_SUCCESS;
} else {
if( DhcpSubnetOptions == ScopeInfo->ScopeType ) {
Err = GetSubnet(&hServer, &hSubnet, ScopeInfo->ScopeInfo.SubnetScopeInfo);
hObject = &hSubnet; // subnet level options
} else if( DhcpReservedOptions != ScopeInfo->ScopeType ) {
Err = ERROR_INVALID_PARAMETER;
} else { // reservation level options
Err = GetReservation(
&hServer,
&hReservation,
ScopeInfo->ScopeInfo.ReservedScopeInfo.ReservedIpSubnetAddress,
ScopeInfo->ScopeInfo.ReservedScopeInfo.ReservedIpAddress
);
hObject = &hReservation;
}
}
if( ERROR_SUCCESS != Err ) {
DhcpDsUnlock(&hDhcpRoot);
StoreCleanupHandle(&hServer, 0);
return Err;
}
Err = DhcpDsGetAllOptionValues // get all the option values from DS
(
/* hDhcpC */ &hDhcpC,
/* hObject */ hObject,
/* Reserved */ DDS_RESERVED_DWORD,
/* Values */ Values
);
StoreCleanupHandle(&hServer, 0);
if( hObject != &hServer ) StoreCleanupHandle(hObject, 0);
DhcpDsUnlock(&hDhcpRoot);
return Err;
}
//BeginExport(function)
//DOC This is implememented in the DHCPDS module, but not exported here yet..
DWORD
DhcpGetAllOptions(
IN LPWSTR ServerIpAddress,
IN DWORD Flags,
OUT LPDHCP_ALL_OPTIONS *Options
) //EndExport(function)
{
DWORD Err, Err2;
STORE_HANDLE hServer,hSubnet;
if( NULL == Options || 0 != Flags ) {
return ERROR_INVALID_PARAMETER;
}
if( STUB_NOT_INITIALIZED(Err) ) return ErrorNotInitialized;
Err = DhcpDsLock(&hDhcpRoot); // take a lock on the DS
if( ERROR_SUCCESS != Err ) return ERROR_DDS_NO_DS_AVAILABLE;
Err = GetServer(&hServer, ServerIpAddress );
if( ERROR_SUCCESS != Err ) { // get the server object
DhcpDsUnlock(&hDhcpRoot);
return Err;
}
Err = DhcpDsGetAllOptions // get opt list from ds
(
/* hDhcpC */ &hDhcpC,
/* hServer */ &hServer,
/* Reserved */ DDS_RESERVED_DWORD,
/* Options */ Options
);
StoreCleanupHandle(&hServer, 0);
DhcpDsUnlock(&hDhcpRoot);
return Err;
}
//================================================================================
// NT 5 beta1 and before -- the stubs for those are here...
//================================================================================
//BeginExport(function)
DWORD // ERROR_DHCP_OPTION_EXITS if option is already there
DhcpCreateOption( // create a new option (must not exist)
IN LPWSTR ServerIpAddress,
IN DHCP_OPTION_ID OptionId, // must be between 0-255 or 256-511 (for vendor stuff)
IN LPDHCP_OPTION OptionInfo
) //EndExport(function)
{
return DhcpCreateOptionV5(
ServerIpAddress,
0,
OptionId,
NULL,
NULL,
OptionInfo
);
}
//BeginExport(function)
DWORD // ERROR_DHCP_OPTION_NOT_PRESENT if option does not exist
DhcpSetOptionInfo( // Modify existing option's fields
IN LPWSTR ServerIpAddress,
IN DHCP_OPTION_ID OptionID,
IN LPDHCP_OPTION OptionInfo
) //EndExport(function)
{
return DhcpSetOptionInfoV5(
ServerIpAddress,
0,
OptionID,
NULL,
NULL,
OptionInfo
);
}
//BeginExport(function)
DWORD // ERROR_DHCP_OPTION_NOT_PRESENT
DhcpGetOptionInfo( // retrieve the information from off the mem structures
IN LPWSTR ServerIpAddress,
IN DHCP_OPTION_ID OptionID,
OUT LPDHCP_OPTION *OptionInfo // allocate memory using MIDL functions
) //EndExport(function)
{
return DhcpGetOptionInfoV5(
ServerIpAddress,
0,
OptionID,
NULL,
NULL,
OptionInfo
);
}
//BeginExport(function)
DWORD // ERROR_DHCP_OPTION_NOT_PRESENT if option does not exist
DhcpEnumOptions( // enumerate the options defined
IN LPWSTR ServerIpAddress,
IN OUT DHCP_RESUME_HANDLE *ResumeHandle, // must be zero intially and then never touched
IN DWORD PreferredMaximum, // max # of bytes of info to pass along
OUT LPDHCP_OPTION_ARRAY *Options, // fill this option array
OUT DWORD *OptionsRead, // fill in the # of options read
OUT DWORD *OptionsTotal // fill in the total # here
) //EndExport(function)
{
return DhcpEnumOptionsV5(
ServerIpAddress,
0,
NULL,
NULL,
ResumeHandle,
PreferredMaximum,
Options,
OptionsRead,
OptionsTotal
);
}
//BeginExport(function)
DWORD // ERROR_DHCP_OPTION_NOT_PRESENT if option not existent
DhcpRemoveOption( // remove the option definition from the registry
IN LPWSTR ServerIpAddress,
IN DHCP_OPTION_ID OptionID
) //EndExport(function)
{
return DhcpRemoveOptionV5(
ServerIpAddress,
0,
OptionID,
NULL,
NULL
);
}
//BeginExport(function)
DWORD // OPTION_NOT_PRESENT if option is not defined
DhcpSetOptionValue( // replace or add a new option value
IN LPWSTR ServerIpAddress,
IN DHCP_OPTION_ID OptionID,
IN LPDHCP_OPTION_SCOPE_INFO ScopeInfo,
IN LPDHCP_OPTION_DATA OptionValue
) //EndExport(function)
{
return DhcpSetOptionValueV5(
ServerIpAddress,
0,
OptionID,
NULL,
NULL,
ScopeInfo,
OptionValue
);
}
//BeginExport(function)
DWORD // not atomic!!!!
DhcpSetOptionValues( // set a bunch of options
IN LPWSTR ServerIpAddress,
IN LPDHCP_OPTION_SCOPE_INFO ScopeInfo,
IN LPDHCP_OPTION_VALUE_ARRAY OptionValues
) //EndExport(function)
{
return DhcpSetOptionValuesV5(
ServerIpAddress,
0,
NULL,
NULL,
ScopeInfo,
OptionValues
);
}
//BeginExport(function)
DWORD
DhcpGetOptionValue( // fetch the required option at required level
IN LPWSTR ServerIpAddress,
IN DHCP_OPTION_ID OptionID,
IN LPDHCP_OPTION_SCOPE_INFO ScopeInfo,
OUT LPDHCP_OPTION_VALUE *OptionValue // allocate memory using MIDL_user_allocate
) //EndExport(function)
{
return DhcpGetOptionValueV5(
ServerIpAddress,
0,
OptionID,
NULL,
NULL,
ScopeInfo,
OptionValue
);
}
//BeginExport(function)
DWORD
DhcpEnumOptionValues(
IN LPWSTR ServerIpAddress,
IN LPDHCP_OPTION_SCOPE_INFO ScopeInfo,
IN DHCP_RESUME_HANDLE *ResumeHandle,
IN DWORD PreferredMaximum,
OUT LPDHCP_OPTION_VALUE_ARRAY *OptionValues,
OUT DWORD *OptionsRead,
OUT DWORD *OptionsTotal
) //EndExport(function)
{
return DhcpEnumOptionValuesV5(
ServerIpAddress,
0,
NULL,
NULL,
ScopeInfo,
ResumeHandle,
PreferredMaximum,
OptionValues,
OptionsRead,
OptionsTotal
);
}
//BeginExport(function)
DWORD
DhcpRemoveOptionValue(
IN LPWSTR ServerIpAddress,
IN DHCP_OPTION_ID OptionID,
IN LPDHCP_OPTION_SCOPE_INFO ScopeInfo
) //EndExport(function)
{
return DhcpRemoveOptionValueV5(
ServerIpAddress,
0,
OptionID,
NULL,
NULL,
ScopeInfo
);
}
//================================================================================
//================================================================================
// The following are the miscellaneous APIs found in rpcapi2.c. Most of the
// following APIs are not really implementable with the DS alone, and so they
// just return error. They are provided here so that the dhcpds.dll can be linked
// to the dhcpcmd.exe program instead of the other dll.
//================================================================================
//================================================================================
//BeginExport(function)
//DOC This function sets the superscope of a subnet, thereby creating the superscope
//DOC if required. Please see DhcpDsSetSScope for more details.
DWORD
DhcpSetSuperScopeV4( // set superscope in DS.
IN LPWSTR ServerIpAddress,
IN DHCP_IP_ADDRESS SubnetAddress,
IN LPWSTR SuperScopeName,
IN BOOL ChangeExisting
) //EndExport(function)
{
DWORD Err, Err2;
STORE_HANDLE hServer,hSubnet;
if( STUB_NOT_INITIALIZED(Err) ) return ErrorNotInitialized;
Err = DhcpDsLock(&hDhcpRoot); // take a lock on the DS
if( ERROR_SUCCESS != Err ) return ERROR_DDS_NO_DS_AVAILABLE;
Err = GetServer(&hServer, ServerIpAddress );
if( ERROR_SUCCESS != Err ) { // get the server object
DhcpDsUnlock(&hDhcpRoot);
return Err;
}
Err = DhcpDsSetSScope // set the sscope in DS
(
/* hDhcpC */ &hDhcpC,
/* hServer */ &hServer,
/* Reserved */ DDS_RESERVED_DWORD,
/* IpAddress */ SubnetAddress,
/* SScopeName */ SuperScopeName,
/* ChangeSScope */ ChangeExisting
);
DhcpDsUnlock(&hDhcpRoot);
return Err;
}
//BeginExport(function)
//DOC This function removes the superscope, and resets any subnet with this
//DOC superscope.. so that all those subnets end up with no superscopes..
//DOC Please see DhcpDsDelSScope for more details.
DWORD
DhcpDeleteSuperScopeV4( // delete subnet sscope from DS
IN LPWSTR ServerIpAddress,
IN LPWSTR SuperScopeName
) //EndExport(function)
{
DWORD Err, Err2;
STORE_HANDLE hServer,hSubnet;
if( STUB_NOT_INITIALIZED(Err) ) return ErrorNotInitialized;
Err = DhcpDsLock(&hDhcpRoot); // take a lock on the DS
if( ERROR_SUCCESS != Err ) return ERROR_DDS_NO_DS_AVAILABLE;
Err = GetServer(&hServer, ServerIpAddress );
if( ERROR_SUCCESS != Err ) { // get the server object
DhcpDsUnlock(&hDhcpRoot);
return Err;
}
Err = DhcpDsDelSScope // delete the sscope in DS
(
/* hDhcpC */ &hDhcpC,
/* hServer */ &hServer,
/* Reserved */ DDS_RESERVED_DWORD,
/* SScopeName */ SuperScopeName
);
DhcpDsUnlock(&hDhcpRoot);
return Err;
}
//BeginExport(function)
//DOC This function retrievs the supercsope info for each subnet that is
//DOC present for the given server. Please see DhcpDsGetSScopeInfo for more
//DOC details on this..
DWORD
DhcpGetSuperScopeInfoV4( // get sscope tbl from DS
IN LPWSTR ServerIpAddress,
OUT LPDHCP_SUPER_SCOPE_TABLE *SuperScopeTable
) //EndExport(function)
{
DWORD Err, Err2;
STORE_HANDLE hServer,hSubnet;
if( STUB_NOT_INITIALIZED(Err) ) return ErrorNotInitialized;
Err = DhcpDsLock(&hDhcpRoot); // take a lock on the DS
if( ERROR_SUCCESS != Err ) return ERROR_DDS_NO_DS_AVAILABLE;
Err = GetServer(&hServer, ServerIpAddress );
if( ERROR_SUCCESS != Err ) { // get the server object
DhcpDsUnlock(&hDhcpRoot);
return Err;
}
Err = DhcpDsGetSScopeInfo // get sscope tbl frm DS
(
/* hDhcpC */ &hDhcpC,
/* hServer */ &hServer,
/* Reserved */ DDS_RESERVED_DWORD,
/* SScopeTbl */ SuperScopeTable
);
DhcpDsUnlock(&hDhcpRoot);
return Err;
}
//BeginExport(function)
//DOC This function creates a subnet in the DS with the specified params.
//DOC Please see DhcpDsServerAddSubnet for more details on this function.
DWORD
DhcpCreateSubnet( // add subnet 2 DS for this srvr
IN LPWSTR ServerIpAddress,
IN DHCP_IP_ADDRESS SubnetAddress,
IN LPDHCP_SUBNET_INFO SubnetInfo
) //EndExport(function)
{
DWORD Err, Err2;
STORE_HANDLE hServer,hSubnet;
LPWSTR ServerName;
if( STUB_NOT_INITIALIZED(Err) ) return ErrorNotInitialized;
Err = DhcpDsLock(&hDhcpRoot); // take a lock on the DS
if( ERROR_SUCCESS != Err ) return ERROR_DDS_NO_DS_AVAILABLE;
Err = GetServer(&hServer, ServerIpAddress );
if( ERROR_SUCCESS != Err ) { // get the server object
DhcpDsUnlock(&hDhcpRoot);
return Err;
}
Err = GetServerNameFromStr(ServerIpAddress, &ServerName);
if( ERROR_SUCCESS == Err ) {
Err = DhcpDsServerAddSubnet // add a new subnet to this srvr
(
/* hDhcpC */ &hDhcpC,
/* hServer */ &hServer,
/* Reserved */ DDS_RESERVED_DWORD,
/* ServerName */ ServerName,
/* Info */ SubnetInfo
);
MemFree(ServerName);
}
DhcpDsUnlock(&hDhcpRoot);
return Err;
}
//BeginExport(function)
//DOC Modify existing subnet with new parameters... some restrictions apply.
//DOC Please see DhcpDsServerModifySubnet for further details.
DWORD
DhcpSetSubnetInfo( // modify existing subnet params
IN LPWSTR ServerIpAddress,
IN DHCP_IP_ADDRESS SubnetAddress,
IN LPDHCP_SUBNET_INFO SubnetInfo
) //EndExport(function)
{
DWORD Err, Err2;
STORE_HANDLE hServer,hSubnet;
LPWSTR ServerName;
if( STUB_NOT_INITIALIZED(Err) ) return ErrorNotInitialized;
Err = DhcpDsLock(&hDhcpRoot); // take a lock on the DS
if( ERROR_SUCCESS != Err ) return ERROR_DDS_NO_DS_AVAILABLE;
Err = GetServer(&hServer, ServerIpAddress );
if( ERROR_SUCCESS != Err ) { // get the server object
DhcpDsUnlock(&hDhcpRoot);
return Err;
}
Err = GetServerNameFromStr(ServerIpAddress, &ServerName);
if( ERROR_SUCCESS == Err ) {
Err = DhcpDsServerModifySubnet // modify subnet for this srvr
(
/* hDhcpC */ &hDhcpC,
/* hServer */ &hServer,
/* Reserved */ DDS_RESERVED_DWORD,
/* ServerName */ ServerName,
/* Info */ SubnetInfo
);
MemFree(ServerName);
}
DhcpDsUnlock(&hDhcpRoot);
return Err;
}
//BeginExport(function)
//DOC Implemented in the DHCPDS module but not exported thru here
DWORD
DhcpGetSubnetInfo(
IN LPWSTR ServerIpAddress,
IN DHCP_IP_ADDRESS SubnetAddress,
OUT LPDHCP_SUBNET_INFO *SubnetInfo
) //EndExport(function)
{
DWORD Err, Err2;
STORE_HANDLE hServer,hSubnet;
LPWSTR ServerName;
if( STUB_NOT_INITIALIZED(Err) ) return ErrorNotInitialized;
Err = DhcpDsLock(&hDhcpRoot); // take a lock on the DS
if( ERROR_SUCCESS != Err ) return ERROR_DDS_NO_DS_AVAILABLE;
Err = GetServer(&hServer, ServerIpAddress );
if( ERROR_SUCCESS != Err ) { // get the server object
DhcpDsUnlock(&hDhcpRoot);
return Err;
}
Err = GetServerNameFromStr(ServerIpAddress, &ServerName);
if( ERROR_SUCCESS == Err ) {
Err = DhcpDsServerGetSubnetInfo // get subnet info for server
(
/* hDhcpC */ &hDhcpC,
/* hServer */ &hServer,
/* Reserved */ DDS_RESERVED_DWORD,
/* ServerName */ ServerName,
/* SubnetAddress */ SubnetAddress,
/* Info */ SubnetInfo
);
MemFree(ServerName);
}
DhcpDsUnlock(&hDhcpRoot);
return Err;
}
//BeginExport(function)
//DOC Implemented in the DHCPDS module but not exported thru here
DWORD
DhcpEnumSubnets(
IN LPWSTR ServerIpAddress,
IN DHCP_RESUME_HANDLE *ResumeHandle,
IN DWORD PreferredMaximum,
IN LPDHCP_IP_ARRAY *EnumInfo,
IN DWORD *ElementsRead,
IN DWORD *ElementsTotal
) //EndExport(function)
{
DWORD Err, Err2;
STORE_HANDLE hServer,hSubnet;
LPWSTR ServerName;
*EnumInfo = NULL;
*ElementsRead = *ElementsTotal = 0;
if( STUB_NOT_INITIALIZED(Err) ) return ErrorNotInitialized;
Err = DhcpDsLock(&hDhcpRoot); // take a lock on the DS
if( ERROR_SUCCESS != Err ) return ERROR_DDS_NO_DS_AVAILABLE;
Err = GetServer(&hServer, ServerIpAddress );
if( ERROR_SUCCESS != Err ) { // get the server object
DhcpDsUnlock(&hDhcpRoot);
return Err;
}
Err = GetServerNameFromStr(ServerIpAddress, &ServerName);
if( ERROR_SUCCESS == Err ) {
Err = DhcpDsServerEnumSubnets // enum subnets for this srvr
(
/* hDhcpC */ &hDhcpC,
/* hServer */ &hServer,
/* Reserved */ DDS_RESERVED_DWORD,
/* ServerName */ ServerName,
/* SubnetsArray */ EnumInfo
);
MemFree(ServerName);
if( ERROR_SUCCESS == Err ) {
*ElementsTotal = (*EnumInfo)->NumElements;
*ElementsRead = *ElementsTotal;
}
}
DhcpDsUnlock(&hDhcpRoot);
return Err;
}
//BeginExport(function)
//DOC This function deletes the subnet from the DS. For further information, pl
//DOC see DhcpDsServerDelSubnet..
DWORD
DhcpDeleteSubnet( // Del subnet from off DS
IN LPWSTR ServerIpAddress,
IN DHCP_IP_ADDRESS SubnetAddress,
IN DHCP_FORCE_FLAG ForceFlag
) //EndExport(function)
{
DWORD Err, Err2;
STORE_HANDLE hServer,hSubnet;
LPWSTR ServerName;
if( STUB_NOT_INITIALIZED(Err) ) return ErrorNotInitialized;
Err = DhcpDsLock(&hDhcpRoot); // take a lock on the DS
if( ERROR_SUCCESS != Err ) return ERROR_DDS_NO_DS_AVAILABLE;
Err = GetServer(&hServer, ServerIpAddress );
if( ERROR_SUCCESS != Err ) { // get the server object
DhcpDsUnlock(&hDhcpRoot);
return Err;
}
Err = GetServerNameFromStr(ServerIpAddress, &ServerName);
if( ERROR_SUCCESS == Err ) {
Err = DhcpDsServerDelSubnet // Del subnet for this srvr
(
/* hDhcpC */ &hDhcpC,
/* hServer */ &hServer,
/* Reserved */ DDS_RESERVED_DWORD,
/* ServerName */ ServerName,
/* IpAddress */ SubnetAddress
);
MemFree(ServerName);
}
DhcpDsUnlock(&hDhcpRoot);
return Err;
}
//BeginExport(function)
//DOC This function sets some particular information for RESERVATIONS only
//DOC all other stuff it just ignores and returns success..
DWORD
DhcpSetClientInfo(
IN LPWSTR ServerIpAddresess,
IN LPDHCP_CLIENT_INFO ClientInfo
) //EndExport(function)
{
return ERROR_SUCCESS;
}
//BeginExport(function)
//DOC This function retrieves some particular client's information
//DOC for RESERVATIONS only.. For all other stuff it returns CALL_NOT_IMPLEMENTED
DWORD
DhcpGetClientInfo(
IN LPWSTR ServerIpAddress,
IN LPDHCP_SEARCH_INFO SearchInfo,
OUT LPDHCP_CLIENT_INFO *ClientInfo
) //EndExport(function)
{
return ERROR_CALL_NOT_IMPLEMENTED;
}
//BeginExport(function)
//DOC This function sets the client informatoin for RESERVATIONS only in DS
//DOC For all toher clients it returns ERROR_SUCCESS w/o doing anything
DWORD
DhcpSetClientInfoV4(
IN LPWSTR ServerIpAddress,
IN LPDHCP_CLIENT_INFO_V4 ClientInfo
) //EndExport(function)
{
return ERROR_SUCCESS;
}
//BeginExport(function)
//DOC Thsi function sets the client information for RESERVATIONS only
//DOC For all others it returns ERROR_CALL_NOT_IMPLEMENTED
DWORD
DhcpGetClientInfoV4(
IN LPWSTR ServerIpAddress,
IN LPDHCP_SEARCH_INFO SearchInfo,
OUT LPDHCP_CLIENT_INFO_V4 *ClientInfo
) //EndExport(function)
{
return ERROR_CALL_NOT_IMPLEMENTED;
}
//BeginExport(function)
//DOC This function adds a subnet element to a subnet in the DS.
DWORD
DhcpAddSubnetElement(
IN LPWSTR ServerIpAddress,
IN DHCP_IP_ADDRESS SubnetAddress,
IN LPDHCP_SUBNET_ELEMENT_DATA AddElementInfo
) //EndExport(function)
{
DWORD Err, Err2;
STORE_HANDLE hServer,hSubnet;
LPWSTR ServerName;
if( NULL == AddElementInfo ) {
return ERROR_INVALID_PARAMETER;
}
if( STUB_NOT_INITIALIZED(Err) ) return ErrorNotInitialized;
Err = DhcpDsLock(&hDhcpRoot); // take a lock on the DS
if( ERROR_SUCCESS != Err ) return ERROR_DDS_NO_DS_AVAILABLE;
Err = GetServer(&hServer, ServerIpAddress );
if( ERROR_SUCCESS != Err ) { // get the server object
DhcpDsUnlock(&hDhcpRoot);
return Err;
}
Err = GetSubnet(&hServer, &hSubnet, SubnetAddress);
if( ERROR_SUCCESS != Err ) {
DhcpDsUnlock(&hDhcpRoot);
StoreCleanupHandle(&hServer, 0);
return Err;
}
Err = GetServerNameFromStr(ServerIpAddress, &ServerName);
if( ERROR_SUCCESS == Err ) {
Err = AddSubnetElementOld( // now add subnet to DS
&hServer,
&hSubnet,
ServerName,
AddElementInfo
);
MemFree(ServerName);
}
StoreCleanupHandle(&hServer, 0);
StoreCleanupHandle(&hSubnet, 0);
DhcpDsUnlock(&hDhcpRoot);
return Err;
}
//BeginExport(function)
//DOC This function adds a subnet element to a subnet in the DS.
DWORD
DhcpAddSubnetElementV4(
IN LPWSTR ServerIpAddress,
IN DHCP_IP_ADDRESS SubnetAddress,
IN LPDHCP_SUBNET_ELEMENT_DATA_V4 AddElementInfo
) //EndExport(function)
{
DWORD Err, Err2;
STORE_HANDLE hServer,hSubnet;
LPWSTR ServerName;
if( NULL == AddElementInfo ) {
return ERROR_INVALID_PARAMETER;
}
if( STUB_NOT_INITIALIZED(Err) ) return ErrorNotInitialized;
Err = DhcpDsLock(&hDhcpRoot); // take a lock on the DS
if( ERROR_SUCCESS != Err ) return ERROR_DDS_NO_DS_AVAILABLE;
Err = GetServer(&hServer, ServerIpAddress );
if( ERROR_SUCCESS != Err ) { // get the server object
DhcpDsUnlock(&hDhcpRoot);
return Err;
}
Err = GetSubnet(&hServer, &hSubnet, SubnetAddress);
if( ERROR_SUCCESS != Err ) {
DhcpDsUnlock(&hDhcpRoot);
StoreCleanupHandle(&hServer, 0);
return Err;
}
Err = GetServerNameFromStr(ServerIpAddress, &ServerName);
if( ERROR_SUCCESS == Err ) {
Err = AddSubnetElement( // now add subnet to DS
&hServer,
&hSubnet,
ServerName,
AddElementInfo
);
MemFree(ServerName);
}
StoreCleanupHandle(&hServer, 0);
StoreCleanupHandle(&hSubnet, 0);
DhcpDsUnlock(&hDhcpRoot);
return Err;
}
//BeginExport(function)
//DOC This is not yet implemented here..
DWORD
DhcpEnumSubnetElementsV4(
IN LPWSTR ServerIpAddress,
IN DHCP_IP_ADDRESS SubnetAddress,
IN DHCP_SUBNET_ELEMENT_TYPE EnumElementType,
IN OUT DHCP_RESUME_HANDLE *ResumeHandle,
IN DWORD PreferredMaximum,
OUT LPDHCP_SUBNET_ELEMENT_INFO_ARRAY_V4 *EnumElementInfo,
OUT DWORD *ElementsRead,
OUT DWORD *ElementsTotal
) //EndExport(function)
{
DWORD Err, Err2;
STORE_HANDLE hServer,hSubnet;
LPWSTR ServerName;
*ElementsRead = *ElementsTotal = 0;
if( STUB_NOT_INITIALIZED(Err) ) return ErrorNotInitialized;
Err = DhcpDsLock(&hDhcpRoot); // take a lock on the DS
if( ERROR_SUCCESS != Err ) return ERROR_DDS_NO_DS_AVAILABLE;
Err = GetServer(&hServer, ServerIpAddress );
if( ERROR_SUCCESS != Err ) { // get the server object
DhcpDsUnlock(&hDhcpRoot);
return Err;
}
Err = GetSubnet(&hServer, &hSubnet, SubnetAddress);
if( ERROR_SUCCESS != Err ) {
DhcpDsUnlock(&hDhcpRoot);
StoreCleanupHandle(&hServer, 0);
return Err;
}
Err = GetServerNameFromStr(ServerIpAddress, &ServerName);
if( ERROR_SUCCESS == Err ) {
Err = DhcpDsEnumSubnetElements // enumerate subnet elements..
(
/* hDhcpC */ &hDhcpC,
/* hServer */ &hServer,
/* hSubnet */ &hSubnet,
/* Reserved */ DDS_RESERVED_DWORD,
/* ServerName */ ServerName,
/* ElementType */ EnumElementType,
/* EnumElementInfo */ EnumElementInfo
);
if( ERROR_SUCCESS == Err ) {
*ElementsRead = *ElementsTotal = (*EnumElementInfo)->NumElements;
}
MemFree(ServerName);
}
StoreCleanupHandle(&hServer, 0);
StoreCleanupHandle(&hSubnet, 0);
DhcpDsUnlock(&hDhcpRoot);
return Err;
}
//BeginExport(function)
//DOC This is not yet implemented here..
DWORD
DhcpEnumSubnetElements(
IN LPWSTR ServerIpAddress,
IN DHCP_IP_ADDRESS SubnetAddress,
IN DHCP_SUBNET_ELEMENT_TYPE EnumElementType,
IN OUT DHCP_RESUME_HANDLE *ResumeHandle,
IN DWORD PreferredMaximum,
OUT LPDHCP_SUBNET_ELEMENT_INFO_ARRAY *EnumElementInfo,
OUT DWORD *ElementsRead,
OUT DWORD *ElementsTotal
) //EndExport(function)
{
DHCP_SUBNET_ELEMENT_INFO_ARRAY_V4 *pEnumElementInfoV4;
DWORD Result;
pEnumElementInfoV4 = NULL;
Result = DhcpEnumSubnetElementsV4(
ServerIpAddress,
SubnetAddress,
EnumElementType,
ResumeHandle,
PreferredMaximum,
&pEnumElementInfoV4,
ElementsRead,
ElementsTotal
);
if( ERROR_SUCCESS == Result || ERROR_MORE_DATA == Result ) {
// since the only difference between DHCP_SUBNET_ELEMENT_INFO_ARRAY_V4 and
// DHCP_SUBNET_ELEMENT_INFO_ARRAY are a couple of fields at the end of the
// embedded DHCP_IP_RESERVATION_V4 struct, it is safe to simply return the
// V4 struct.
*EnumElementInfo = ( DHCP_SUBNET_ELEMENT_INFO_ARRAY *) pEnumElementInfoV4;
} else {
DhcpAssert( !pEnumElementInfoV4 );
}
return Result;
}
//BeginExport(function)
//DOC This function removes either an exclusion, ip range or reservation
//DOC from the subnet... in the DS.
DWORD
DhcpRemoveSubnetElement( // remove subnet element
IN LPWSTR ServerIpAddress,
IN DHCP_IP_ADDRESS SubnetAddress,
IN LPDHCP_SUBNET_ELEMENT_DATA RemoveElementInfo,
IN DHCP_FORCE_FLAG ForceFlag
) //EndExport(function)
{
DWORD Err, Err2;
STORE_HANDLE hServer,hSubnet;
LPWSTR ServerName;
if( NULL == RemoveElementInfo ) {
return ERROR_INVALID_PARAMETER;
}
if( STUB_NOT_INITIALIZED(Err) ) return ErrorNotInitialized;
Err = DhcpDsLock(&hDhcpRoot); // take a lock on the DS
if( ERROR_SUCCESS != Err ) return ERROR_DDS_NO_DS_AVAILABLE;
Err = GetServer(&hServer, ServerIpAddress );
if( ERROR_SUCCESS != Err ) { // get the server object
DhcpDsUnlock(&hDhcpRoot);
return Err;
}
Err = GetSubnet(&hServer, &hSubnet, SubnetAddress);
if( ERROR_SUCCESS != Err ) {
DhcpDsUnlock(&hDhcpRoot);
StoreCleanupHandle(&hServer, 0);
return Err;
}
Err = GetServerNameFromStr(ServerIpAddress, &ServerName);
if( ERROR_SUCCESS == Err ) {
Err = DelSubnetElementOld( // now del subnt elt frm DS
&hServer,
&hSubnet,
ServerName,
RemoveElementInfo
);
MemFree(ServerName);
}
StoreCleanupHandle(&hServer, 0);
StoreCleanupHandle(&hSubnet, 0);
DhcpDsUnlock(&hDhcpRoot);
return Err;
}
//BeginExport(function)
//DOC This function removes either an exclusion, ip range or reservation
//DOC from the subnet... in the DS.
DWORD
DhcpRemoveSubnetElementV4( // remove subnet element
IN LPWSTR ServerIpAddress,
IN DHCP_IP_ADDRESS SubnetAddress,
IN LPDHCP_SUBNET_ELEMENT_DATA_V4 RemoveElementInfo,
IN DHCP_FORCE_FLAG ForceFlag
) //EndExport(function)
{
DWORD Err, Err2;
STORE_HANDLE hServer,hSubnet;
LPWSTR ServerName;
if( NULL == RemoveElementInfo ) {
return ERROR_INVALID_PARAMETER;
}
if( STUB_NOT_INITIALIZED(Err) ) return ErrorNotInitialized;
Err = DhcpDsLock(&hDhcpRoot); // take a lock on the DS
if( ERROR_SUCCESS != Err ) return ERROR_DDS_NO_DS_AVAILABLE;
Err = GetServer(&hServer, ServerIpAddress );
if( ERROR_SUCCESS != Err ) { // get the server object
DhcpDsUnlock(&hDhcpRoot);
return Err;
}
Err = GetSubnet(&hServer, &hSubnet, SubnetAddress);
if( ERROR_SUCCESS != Err ) {
DhcpDsUnlock(&hDhcpRoot);
StoreCleanupHandle(&hServer, 0);
return Err;
}
Err = GetServerNameFromStr(ServerIpAddress, &ServerName);
if( ERROR_SUCCESS == Err ) {
Err = DelSubnetElement( // now del subnt elt frm DS
&hServer,
&hSubnet,
ServerName,
RemoveElementInfo
);
MemFree(ServerName);
}
StoreCleanupHandle(&hServer, 0);
StoreCleanupHandle(&hSubnet, 0);
DhcpDsUnlock(&hDhcpRoot);
return Err;
}
//================================================================================
// get rid of the defines so far as exports are concerned. (rpcstubs.h)
//================================================================================
//BeginExport(defines)
#ifndef CONVERT_NAMES
#undef DhcpCreateSubnet
#undef DhcpSetSubnetInfo
#undef DhcpGetSubnetInfo
#undef DhcpEnumSubnets
#undef DhcpDeleteSubnet
#undef DhcpCreateOption
#undef DhcpSetOptionInfo
#undef DhcpGetOptionInfo
#undef DhcpRemoveOption
#undef DhcpSetOptionValue
#undef DhcpGetOptionValue
#undef DhcpEnumOptionValues
#undef DhcpRemoveOptionValue
#undef DhcpEnumOptions
#undef DhcpSetOptionValues
#undef DhcpAddSubnetElementV4
#undef DhcpEnumSubnetElementsV4
#undef DhcpRemoveSubnetElementV4
#undef DhcpAddSubnetElement
#undef DhcpEnumSubnetElements
#undef DhcpRemoveSubnetElement
#undef DhcpSetSuperScopeV4
#undef DhcpGetSuperScopeInfoV4
#undef DhcpDeleteSuperScopeV4
#undef DhcpSetClientInfo
#undef DhcpGetClientInfo
#undef DhcpSetClientInfoV4
#undef DhcpGetClientInfoV4
#undef DhcpCreateOptionV5
#undef DhcpSetOptionInfoV5
#undef DhcpGetOptionInfoV5
#undef DhcpEnumOptionsV5
#undef DhcpRemoveOptionV5
#undef DhcpSetOptionValueV5
#undef DhcpSetOptionValuesV5
#undef DhcpGetOptionValueV5
#undef DhcpEnumOptionValuesV5
#undef DhcpRemoveOptionValueV5
#undef DhcpCreateClass
#undef DhcpModifyClass
#undef DhcpDeleteClass
#undef DhcpGetClassInfo
#undef DhcpEnumClasses
#undef DhcpGetAllOptions
#undef DhcpGetAllOptionValues
#endif CONVERT_NAMES
//EndExport(defines)
//BeginExport(typedef)
#define DHCP_SERVER_ANOTHER_ENTERPRISE 0x01
typedef DHCPDS_SERVER DHCP_SERVER_INFO;
typedef PDHCPDS_SERVER PDHCP_SERVER_INFO;
typedef LPDHCPDS_SERVER LPDHCP_SERVER_INFO;
typedef DHCPDS_SERVERS DHCP_SERVER_INFO_ARRAY;
typedef PDHCPDS_SERVERS PDHCP_SERVER_INFO_ARRAY;
typedef LPDHCPDS_SERVERS LPDHCP_SERVER_INFO_ARRAY;
//EndExport(typedef)
//================================================================================
// DS only NON-rpc stubs
//================================================================================
//BeginExport(function)
//DOC DhcpEnumServersDS lists the servers found in the DS along with the
//DOC addresses and other information. The whole server is allocated as a blob,
//DOC and should be freed in one shot. No parameters are currently used, other
//DOC than Servers which will be an OUT parameter only.
DWORD
DhcpEnumServersDS(
IN DWORD Flags,
IN LPVOID IdInfo,
OUT LPDHCP_SERVER_INFO_ARRAY *Servers,
IN LPVOID CallbackFn,
IN LPVOID CallbackData
) //EndExport(function)
{
DWORD Err, Err2, Size,i;
LPDHCPDS_SERVERS DhcpDsServers;
AssertRet(Servers, ERROR_INVALID_PARAMETER);
AssertRet(!Flags, ERROR_INVALID_PARAMETER);
*Servers = NULL;
if( STUB_NOT_INITIALIZED(Err) ) return ERROR_DDS_NO_DS_AVAILABLE;
Err = DhcpDsLock(&hDhcpRoot); // take a lock on the DS
if( ERROR_SUCCESS != Err ) return ERROR_DDS_NO_DS_AVAILABLE;
DhcpDsServers = NULL;
Err = DhcpDsEnumServers // get the list of servers
(
/* hDhcpC */ &hDhcpC,
/* hDhcpRoot */ &hDhcpRoot,
/* Reserved */ DDS_RESERVED_DWORD,
/* ServersInfo */ &DhcpDsServers
);
DhcpDsUnlock(&hDhcpRoot);
if( ERROR_SUCCESS != Err ) return Err; // return err..
*Servers = DhcpDsServers;
return ERROR_SUCCESS;
}
//BeginExport(function)
//DOC DhcpAddServerDS adds a particular server to the DS. If the server exists,
//DOC then, this returns error. If the server does not exist, then this function
//DOC adds the server in DS, and also uploads the configuration from the server
//DOC to the ds.
DWORD
DhcpAddServerDS(
IN DWORD Flags,
IN LPVOID IdInfo,
IN LPDHCP_SERVER_INFO NewServer,
IN LPVOID CallbackFn,
IN LPVOID CallbackData
) //EndExport(function)
{
DWORD Err, Err2;
WCHAR TmpBuf[sizeof(L"000.000.000.000")];
AssertRet(NewServer, ERROR_INVALID_PARAMETER);
AssertRet(!Flags, ERROR_INVALID_PARAMETER);
if( STUB_NOT_INITIALIZED(Err) ) return ERROR_DDS_NO_DS_AVAILABLE;
Err = DhcpDsLock(&hDhcpRoot); // take a lock on the DS
if( ERROR_SUCCESS != Err ) return ERROR_DDS_NO_DS_AVAILABLE;
Err = DhcpDsAddServer // add the new server
(
/* hDhcpC */ &hDhcpC,
/* hDhcpRoot */ &hDhcpRoot,
/* Reserved */ DDS_RESERVED_DWORD,
/* ServerName */ NewServer->ServerName,
/* ReservedPtr */ DDS_RESERVED_PTR,
/* IpAddress */ NewServer->ServerAddress,
/* State */ Flags
);
DhcpDsUnlock(&hDhcpRoot);
return Err;
}
//BeginExport(function)
//DOC DhcpDeleteServerDS deletes the servers from off the DS and recursively
//DOC deletes the server object..(i.e everything belonging to the server is deleted).
//DOC If the server does not exist, it returns an error.
DWORD
DhcpDeleteServerDS(
IN DWORD Flags,
IN LPVOID IdInfo,
IN LPDHCP_SERVER_INFO NewServer,
IN LPVOID CallbackFn,
IN LPVOID CallbackData
) //EndExport(function)
{
DWORD Err, Err2;
AssertRet(NewServer, ERROR_INVALID_PARAMETER);
AssertRet(!Flags, ERROR_INVALID_PARAMETER);
if( STUB_NOT_INITIALIZED(Err) ) return ERROR_DDS_NO_DS_AVAILABLE;
Err = DhcpDsLock(&hDhcpRoot); // take a lock on the DS
if( ERROR_SUCCESS != Err ) return ERROR_DDS_NO_DS_AVAILABLE;
Err = DhcpDsDelServer // del this server
(
/* hDhcpC */ &hDhcpC,
/* hDhcpRoot */ &hDhcpRoot,
/* Reserved */ DDS_RESERVED_DWORD,
/* ServerName */ NewServer->ServerName,
/* ReservedPtr */ DDS_RESERVED_PTR,
/* IpAddress */ NewServer->ServerAddress
);
DhcpDsUnlock(&hDhcpRoot);
return Err;
}
//BeginExport(function)
//DOC DhcpDsInitDS initializes everything in this module.
DWORD
DhcpDsInitDS(
DWORD Flags,
LPVOID IdInfo
) //EndExport(function)
{
return StubInitialize();
}
//BeginExport(function)
//DOC DhcpDsCleanupDS uninitiailzes everything in this module.
VOID
DhcpDsCleanupDS(
VOID
) //EndExport(function)
{
StubCleanup();
}
//BeginExport(header)
//DOC This function is defined in validate.c
//DOC Only the stub is here.
DWORD
DhcpDsValidateService( // check to validate for dhcp
IN LPWSTR Domain,
IN DWORD *Addresses OPTIONAL,
IN ULONG nAddresses,
IN LPWSTR UserName,
IN LPWSTR Password,
IN DWORD AuthFlags,
OUT LPBOOL Found,
OUT LPBOOL IsStandAlone
);
//DOC DhcpDsGetLastUpdateTime is defined in upndown.c --> see there for more details.
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(header)
//================================================================================
// end of file
//================================================================================