3220 lines
112 KiB
C
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
|
||
|
//================================================================================
|