|
|
//================================================================================
// 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
//================================================================================
|