//================================================================================ // Copyright (C) 1997 Microsoft Corporation // Author: RameshV // Description: This module has helper routines to delete the objects recursively. // //================================================================================ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include //================================================================================ // helper functions //================================================================================ VOID static MemFreeFunc( IN OUT LPVOID Memory ) { MemFree(Memory); } //================================================================================ // exposed functions //================================================================================ //BeginExport(function) //DOC SubnetDeleteReservation deletes the reservation object from off the DS. SubnetDeleteReservation( // delete reservation from DS IN OUT LPSTORE_HANDLE hDhcpC, // container for resrevation objs IN LPWSTR ServerName, // name of dhcp server IN OUT LPSTORE_HANDLE hServer, // server object in DS IN OUT LPSTORE_HANDLE hSubnet, // subnet object in DS IN LPWSTR ADsPath, // path of reservation object IN DWORD StoreGetType // path is relative, abs, or dif server? ) //EndExport(function) { return StoreDeleteThisObject // just delete the reservation object ( /* hStore */ hDhcpC, /* Reserved */ DDS_RESERVED_DWORD, /* StoreGetType */ StoreGetType, /* Path */ ADsPath ); } //BeginExport(function) //DOC ServerDeleteSubnet deletes the subnet specified from the DS by removing //DOC the subnet object. ServerDeleteSubnet( // remove subnet object from DS IN OUT LPSTORE_HANDLE hDhcpC, // container for subnet objs in Ds IN LPWSTR ServerName, // name of server this deletion is for IN OUT LPSTORE_HANDLE hServer, // server object in DS IN LPWSTR ADsPath, // Location of the subnet in DS IN DWORD StoreGetType // path is relative,abs or diff srvr? ) //EndExport(function) { DWORD Err, LastErr, LocType; STORE_HANDLE hSubnet; ARRAY Reservations; ARRAY_LOCATION Loc; PEATTRIB ThisAttrib; LPWSTR Location; LPVOID Ptr; Err = StoreGetHandle // get the server object from the DS ( /* hStore */ hDhcpC, /* Reserved */ DDS_RESERVED_DWORD, /* StoreGetType */ StoreGetType, /* Path */ ADsPath, /* hStoreOut */ &hSubnet ); if( ERROR_SUCCESS != Err ) return Err; Err = MemArrayInit(&Reservations); //= require ERROR_SUCCESS == Err Err = DhcpDsGetLists // get list or reservations ( /* Reserved */ DDS_RESERVED_DWORD, /* hStore */ &hSubnet, /* RecursionDepth */ 0xFFFFFFFF, /* Servers */ NULL, /* Subnets */ NULL, /* IpAddress */ NULL, /* Mask */ NULL, /* Ranges */ NULL, /* Sites */ NULL, /* Reservations */ &Reservations, /* SuperScopes */ NULL, /* OptionDescription */ NULL, /* OptionsLocation */ NULL, /* Options */ NULL, /* Classes */ NULL ); if( ERROR_SUCCESS != Err ) return Err; LastErr = ERROR_SUCCESS; for( // delete each subnet Err = MemArrayInitLoc(&Reservations, &Loc) ; ERROR_FILE_NOT_FOUND != Err; Err = MemArrayNextLoc(&Reservations, &Loc) ) { Err = MemArrayGetElement(&Reservations, &Loc, &ThisAttrib); //= require ERROR_SUCCESS == Err && NULL != ThisAttrib if( !IS_ADDRESS1_PRESENT(ThisAttrib) || // reserved address !IS_BINARY1_PRESENT(ThisAttrib) ) { // HW address info continue; // invalid subnet } if( !IS_ADSPATH_PRESENT(ThisAttrib) ) { // no location specified Location = MakeReservationLocation(ServerName, ThisAttrib->Address1); LocType = StoreGetChildType; Ptr = Location; } else { Location = ThisAttrib->ADsPath; LocType = ThisAttrib->StoreGetType; Ptr = NULL; } Err = SubnetDeleteReservation // now delete the reservation ( /* hDhcpC */ hDhcpC, /* ServerName */ ServerName, /* hServer */ hServer, /* hSubnet */ &hSubnet, /* ADsPath */ Location, /* StoreGetType */ LocType ); if( ERROR_SUCCESS != Err ) LastErr = Err; if( Ptr ) MemFree(Ptr); } MemArrayFree(&Reservations, MemFreeFunc); Err = StoreCleanupHandle(&hSubnet, 0); //= require ERROR_SUCCESS == Err Err = StoreDeleteThisObject // now really delete the subnet object ( /* hStore */ hDhcpC, /* Reserved */ DDS_RESERVED_DWORD, /* StoreGetType */ StoreGetType, /* Path */ ADsPath ); if( ERROR_SUCCESS != Err ) LastErr = Err; // try to delete the store object itself return LastErr; } //BeginExport(function) //DOC DeleteServer deletes the server object from the DS and deletes any SUBNET and //DOC reservation objects that it may point to. //DOC The hDhcpC parameter is the handle of the container where the server object //DOC may be located. This used in conjunction with the ADsPath and StoreGetType //DOC defines the location of the ServerObject. DWORD DeleteServer( // recurse delete server from DS IN OUT LPSTORE_HANDLE hDhcpC, // container where server obj may be IN LPWSTR ServerName, // name of server.. IN LPWSTR ADsPath, // path of the server object IN DWORD StoreGetType // is path relative, absolute or dif srvr? ) //EndExport(function) { DWORD Err, LastErr, LocType; STORE_HANDLE hServer; ARRAY Subnets; ARRAY_LOCATION Loc; PEATTRIB ThisAttrib; LPWSTR Location; LPVOID Ptr; Err = StoreGetHandle // get the server object from the DS ( /* hStore */ hDhcpC, /* Reserved */ DDS_RESERVED_DWORD, /* StoreGetType */ StoreGetType, /* Path */ ADsPath, /* hStoreOut */ &hServer ); if( ERROR_SUCCESS != Err ) return Err; Err = MemArrayInit(&Subnets); //= require ERROR_SUCCESS == Err Err = DhcpDsGetLists // get subnets and other stuff ( /* Reserved */ DDS_RESERVED_DWORD, /* hStore */ &hServer, /* RecursionDepth */ 0xFFFFFFFF, /* Servers */ NULL, /* Subnets */ &Subnets, /* 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; LastErr = ERROR_SUCCESS; for( // delete each subnet Err = MemArrayInitLoc(&Subnets, &Loc) ; ERROR_FILE_NOT_FOUND != Err; Err = MemArrayNextLoc(&Subnets, &Loc) ) { Err = MemArrayGetElement(&Subnets, &Loc, &ThisAttrib); //= require ERROR_SUCCESS == Err && NULL != ThisAttrib if( !IS_ADDRESS1_PRESENT(ThisAttrib) || // subnet address !IS_ADDRESS2_PRESENT(ThisAttrib) ) { // subnet mask continue; // invalid subnet } if( !IS_ADSPATH_PRESENT(ThisAttrib) ) { // no location specified Location = MakeSubnetLocation(ServerName, ThisAttrib->Address1); LocType = StoreGetChildType; Ptr = Location; } else { Location = ThisAttrib->ADsPath; LocType = ThisAttrib->StoreGetType; Ptr = NULL; } Err = ServerDeleteSubnet // now delete the subnet ( /* hDhcpC */ hDhcpC, /* ServerName */ ServerName, /* hServer */ &hServer, /* ADsPath */ Location, /* StoreGetType */ LocType ); if( ERROR_SUCCESS != Err ) LastErr = Err; if( Ptr ) MemFree(Ptr); } MemArrayFree(&Subnets, MemFreeFunc); Err = StoreCleanupHandle( &hServer, DDS_RESERVED_DWORD ); Err = StoreDeleteThisObject // now really delete the server object ( /* hStore */ hDhcpC, /* Reserved */ DDS_RESERVED_DWORD, /* StoreGetType */ StoreGetType, /* Path */ ADsPath ); if( ERROR_SUCCESS != Err ) LastErr = Err; // try to delete the store object itself return LastErr; } //================================================================================ // end of file //================================================================================