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