/** Remove the block number from the block range list. @param[in] Head The block range list to remove from. @param[in] Num The block number to remove. @param[in] Completed Whether Num is the last block number @param[out] TotalBlock The continuous block number in all @retval EFI_NOT_FOUND The block number isn't in the block range list. @retval EFI_SUCCESS The block number has been removed from the list. @retval EFI_OUT_OF_RESOURCES Failed to allocate resources. **/ EFI_STATUS Mtftp6RemoveBlockNum ( IN LIST_ENTRY *Head, IN UINT16 Num, IN BOOLEAN Completed, OUT UINT64 *TotalBlock ) { MTFTP6_BLOCK_RANGE *Range; MTFTP6_BLOCK_RANGE *NewRange; LIST_ENTRY *Entry; NET_LIST_FOR_EACH (Entry, Head) { // // Each block represents a hole [Start, End] in the file, // skip to the first range with End >= Num // Range = NET_LIST_USER_STRUCT (Entry, MTFTP6_BLOCK_RANGE, Link); if (Range->End < Num) { continue; } // // There are three different cases for Start // 1. (Start > Num) && (End >= Num): // because all the holes before this one has the condition of // End < Num, so this block number has been removed. // // 2. (Start == Num) && (End >= Num): // Need to increase the Start by one, and if End == Num, this // hole has been removed completely, remove it. // // 3. (Start < Num) && (End >= Num): // if End == Num, only need to decrease the End by one because // we have (Start < Num) && (Num == End), so (Start <= End - 1). // if (End > Num), the hold is splited into two holes, with // [Start, Num - 1] and [Num + 1, End]. // if (Range->Start > Num) { return EFI_NOT_FOUND; } else if (Range->Start == Num) { Range->Start++; // // Note that: RFC 1350 does not mention block counter roll-over, // but several TFTP hosts implement the roll-over be able to accept // transfers of unlimited size. There is no consensus, however, whether // the counter should wrap around to zero or to one. Many implementations // wrap to zero, because this is the simplest to implement. Here we choose // this solution. // *TotalBlock = Num; if (Range->Round > 0) { *TotalBlock += Range->Bound + MultU64x32 (Range->Round - 1, (UINT32)(Range->Bound + 1)) + 1; } if (Range->Start > Range->Bound) { Range->Start = 0; Range->Round ++; } if ((Range->Start > Range->End) || Completed) { RemoveEntryList (&Range->Link); FreePool (Range); } return EFI_SUCCESS; } else { if (Range->End == Num) { Range->End--; } else { NewRange = Mtftp6AllocateRange ((UINT16) (Num + 1), (UINT16) Range->End); if (NewRange == NULL) { return EFI_OUT_OF_RESOURCES; } Range->End = Num - 1; NetListInsertAfter (&Range->Link, &NewRange->Link); } return EFI_SUCCESS; } }
EFI_STATUS Mtftp4RemoveBlockNum ( IN NET_LIST_ENTRY *Head, IN UINT16 Num ) /*++ Routine Description: Remove the block number from the block range list. Arguments: Head - The block range list to remove from Num - The block number to remove Returns: EFI_NOT_FOUND - The block number isn't in the block range list EFI_SUCCESS - The block number has been removed from the list EFI_OUT_OF_RESOURCES - Failed to allocate resource --*/ { MTFTP4_BLOCK_RANGE *Range; MTFTP4_BLOCK_RANGE *NewRange; NET_LIST_ENTRY *Entry; NET_LIST_FOR_EACH (Entry, Head) { // // Each block represents a hole [Start, End] in the file, // skip to the first range with End >= Num // Range = NET_LIST_USER_STRUCT (Entry, MTFTP4_BLOCK_RANGE, Link); if (Range->End < Num) { continue; } // // There are three different cases for Start // 1. (Start > Num) && (End >= Num): // because all the holes before this one has the condition of // End < Num, so this block number has been removed. // // 2. (Start == Num) && (End >= Num): // Need to increase the Start by one, and if End == Num, this // hole has been removed completely, remove it. // // 3. (Start < Num) && (End >= Num): // if End == Num, only need to decrease the End by one because // we have (Start < Num) && (Num == End), so (Start <= End - 1). // if (End > Num), the hold is splited into two holes, with // [Start, Num - 1] and [Num + 1, End]. // if (Range->Start > Num) { return EFI_NOT_FOUND; } else if (Range->Start == Num) { Range->Start++; if (Range->Start > Range->End) { NetListRemoveEntry (&Range->Link); NetFreePool (Range); } return EFI_SUCCESS; } else { if (Range->End == Num) { Range->End--; } else { NewRange = Mtftp4AllocateRange (Num + 1, (UINT16) Range->End); if (NewRange == NULL) { return EFI_OUT_OF_RESOURCES; } Range->End = Num - 1; NetListInsertAfter (&Range->Link, &NewRange->Link); } return EFI_SUCCESS; } }