ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

rangelist.c
Go to the documentation of this file.
00001 /*
00002  * COPYRIGHT:         See COPYING in the top level directory
00003  * PROJECT:           ReactOS system libraries
00004  * FILE:              lib/rtl/rangelist.c
00005  * PURPOSE:           Range list implementation
00006  * PROGRAMMERS:       No programmer listed.
00007  */
00008 
00009 /* INCLUDES *****************************************************************/
00010 
00011 #include <rtl.h>
00012 
00013 #define NDEBUG
00014 #include <debug.h>
00015 
00016 /* TYPES ********************************************************************/
00017 
00018 typedef struct _RTL_RANGE_ENTRY
00019 {
00020     LIST_ENTRY Entry;
00021     RTL_RANGE Range;
00022 } RTL_RANGE_ENTRY, *PRTL_RANGE_ENTRY;
00023 
00024 /* FUNCTIONS ***************************************************************/
00025 
00026 /**********************************************************************
00027  * NAME                         EXPORTED
00028  *  RtlAddRange
00029  *
00030  * DESCRIPTION
00031  *  Adds a range to a range list.
00032  *
00033  * ARGUMENTS
00034  *  RangeList       Range list.
00035  *  Start
00036  *  End
00037  *  Attributes
00038  *  Flags
00039  *  UserData
00040  *  Owner
00041  *
00042  * RETURN VALUE
00043  *  Status
00044  *
00045  * TODO:
00046  *   - Support shared ranges.
00047  *
00048  * @implemented
00049  */
00050 NTSTATUS
00051 NTAPI
00052 RtlAddRange(IN OUT PRTL_RANGE_LIST RangeList,
00053             IN ULONGLONG Start,
00054             IN ULONGLONG End,
00055             IN UCHAR Attributes,
00056             IN ULONG Flags,
00057             IN PVOID UserData OPTIONAL,
00058             IN PVOID Owner OPTIONAL)
00059 {
00060     PRTL_RANGE_ENTRY RangeEntry;
00061     //PRTL_RANGE_ENTRY Previous;
00062     PRTL_RANGE_ENTRY Current;
00063     PLIST_ENTRY Entry;
00064 
00065     if (Start > End)
00066         return STATUS_INVALID_PARAMETER;
00067 
00068     /* Create new range entry */
00069     RangeEntry = RtlpAllocateMemory(sizeof(RTL_RANGE_ENTRY), 'elRR');
00070     if (RangeEntry == NULL)
00071         return STATUS_INSUFFICIENT_RESOURCES;
00072 
00073     /* Initialize range entry */
00074     RangeEntry->Range.Start = Start;
00075     RangeEntry->Range.End = End;
00076     RangeEntry->Range.Attributes = Attributes;
00077     RangeEntry->Range.UserData = UserData;
00078     RangeEntry->Range.Owner = Owner;
00079 
00080     RangeEntry->Range.Flags = 0;
00081     if (Flags & RTL_RANGE_LIST_ADD_SHARED)
00082         RangeEntry->Range.Flags |= RTL_RANGE_SHARED;
00083 
00084     /* Insert range entry */
00085     if (RangeList->Count == 0)
00086     {
00087         InsertTailList(&RangeList->ListHead,
00088                        &RangeEntry->Entry);
00089         RangeList->Count++;
00090         RangeList->Stamp++;
00091         return STATUS_SUCCESS;
00092     }
00093     else
00094     {
00095          //Previous = NULL;
00096         Entry = RangeList->ListHead.Flink;
00097         while (Entry != &RangeList->ListHead)
00098         {
00099             Current = CONTAINING_RECORD(Entry, RTL_RANGE_ENTRY, Entry);
00100             if (Current->Range.Start > RangeEntry->Range.End)
00101             {
00102                 /* Insert before current */
00103                 DPRINT("Insert before current\n");
00104                 InsertTailList(&Current->Entry,
00105                                &RangeEntry->Entry);
00106 
00107                 RangeList->Count++;
00108                 RangeList->Stamp++;
00109                 return STATUS_SUCCESS;
00110             }
00111 
00112             //Previous = Current;
00113             Entry = Entry->Flink;
00114         }
00115 
00116         DPRINT("Insert tail\n");
00117         InsertTailList(&RangeList->ListHead,
00118                        &RangeEntry->Entry);
00119         RangeList->Count++;
00120         RangeList->Stamp++;
00121         return STATUS_SUCCESS;
00122     }
00123 
00124     RtlpFreeMemory(RangeEntry, 0);
00125 
00126     return STATUS_UNSUCCESSFUL;
00127 }
00128 
00129 
00130 /**********************************************************************
00131  * NAME                         EXPORTED
00132  *  RtlCopyRangeList
00133  *
00134  * DESCRIPTION
00135  *  Copy a range list.
00136  *
00137  * ARGUMENTS
00138  *  CopyRangeList   Pointer to the destination range list.
00139  *  RangeList   Pointer to the source range list.
00140  *
00141  * RETURN VALUE
00142  *  Status
00143  *
00144  * @implemented
00145  */
00146 NTSTATUS
00147 NTAPI
00148 RtlCopyRangeList(OUT PRTL_RANGE_LIST CopyRangeList,
00149                  IN PRTL_RANGE_LIST RangeList)
00150 {
00151     PRTL_RANGE_ENTRY Current;
00152     PRTL_RANGE_ENTRY NewEntry;
00153     PLIST_ENTRY Entry;
00154 
00155     CopyRangeList->Flags = RangeList->Flags;
00156 
00157     Entry = RangeList->ListHead.Flink;
00158     while (Entry != &RangeList->ListHead)
00159     {
00160         Current = CONTAINING_RECORD(Entry, RTL_RANGE_ENTRY, Entry);
00161 
00162         NewEntry = RtlpAllocateMemory(sizeof(RTL_RANGE_ENTRY), 'elRR');
00163         if (NewEntry == NULL)
00164             return STATUS_INSUFFICIENT_RESOURCES;
00165 
00166         RtlCopyMemory(&NewEntry->Range,
00167                       &Current->Range,
00168                       sizeof(RTL_RANGE_ENTRY));
00169 
00170         InsertTailList(&CopyRangeList->ListHead,
00171                        &NewEntry->Entry);
00172 
00173         CopyRangeList->Count++;
00174 
00175         Entry = Entry->Flink;
00176     }
00177 
00178     CopyRangeList->Stamp++;
00179 
00180     return STATUS_SUCCESS;
00181 }
00182 
00183 
00184 /**********************************************************************
00185  * NAME                         EXPORTED
00186  *  RtlDeleteOwnersRanges
00187  *
00188  * DESCRIPTION
00189  *  Delete all ranges that belong to the given owner.
00190  *
00191  * ARGUMENTS
00192  *  RangeList   Pointer to the range list.
00193  *  Owner       User supplied value that identifies the owner
00194  *          of the ranges to be deleted.
00195  *
00196  * RETURN VALUE
00197  *  Status
00198  *
00199  * @implemented
00200  */
00201 NTSTATUS
00202 NTAPI
00203 RtlDeleteOwnersRanges(IN OUT PRTL_RANGE_LIST RangeList,
00204                       IN PVOID Owner)
00205 {
00206     PRTL_RANGE_ENTRY Current;
00207     PLIST_ENTRY Entry;
00208 
00209     Entry = RangeList->ListHead.Flink;
00210     while (Entry != &RangeList->ListHead)
00211     {
00212         Current = CONTAINING_RECORD(Entry, RTL_RANGE_ENTRY, Entry);
00213         if (Current->Range.Owner == Owner)
00214         {
00215             RemoveEntryList (Entry);
00216             RtlpFreeMemory(Current, 0);
00217 
00218             RangeList->Count--;
00219             RangeList->Stamp++;
00220         }
00221 
00222         Entry = Entry->Flink;
00223     }
00224 
00225     return STATUS_SUCCESS;
00226 }
00227 
00228 
00229 /**********************************************************************
00230  * NAME                         EXPORTED
00231  *  RtlDeleteRange
00232  *
00233  * DESCRIPTION
00234  *  Deletes a given range.
00235  *
00236  * ARGUMENTS
00237  *  RangeList   Pointer to the range list.
00238  *  Start       Start of the range to be deleted.
00239  *  End     End of the range to be deleted.
00240  *  Owner       Owner of the ranges to be deleted.
00241  *
00242  * RETURN VALUE
00243  *  Status
00244  *
00245  * @implemented
00246  */
00247 NTSTATUS
00248 NTAPI
00249 RtlDeleteRange(IN OUT PRTL_RANGE_LIST RangeList,
00250                IN ULONGLONG Start,
00251                IN ULONGLONG End,
00252                IN PVOID Owner)
00253 {
00254     PRTL_RANGE_ENTRY Current;
00255     PLIST_ENTRY Entry;
00256 
00257     Entry = RangeList->ListHead.Flink;
00258     while (Entry != &RangeList->ListHead)
00259     {
00260         Current = CONTAINING_RECORD(Entry, RTL_RANGE_ENTRY, Entry);
00261         if (Current->Range.Start == Start &&
00262             Current->Range.End == End &&
00263             Current->Range.Owner == Owner)
00264         {
00265             RemoveEntryList(Entry);
00266 
00267             RtlpFreeMemory(Current, 0);
00268 
00269             RangeList->Count--;
00270             RangeList->Stamp++;
00271             return STATUS_SUCCESS;
00272         }
00273 
00274         Entry = Entry->Flink;
00275     }
00276 
00277     return STATUS_RANGE_NOT_FOUND;
00278 }
00279 
00280 
00281 /**********************************************************************
00282  * NAME                         EXPORTED
00283  *  RtlFindRange
00284  *
00285  * DESCRIPTION
00286  *  Searches for an unused range.
00287  *
00288  * ARGUMENTS
00289  *  RangeList       Pointer to the range list.
00290  *  Minimum
00291  *  Maximum
00292  *  Length
00293  *  Alignment
00294  *  Flags
00295  *  AttributeAvailableMask
00296  *  Context
00297  *  Callback
00298  *  Start
00299  *
00300  * RETURN VALUE
00301  *  Status
00302  *
00303  * TODO
00304  *  Support shared ranges and callback.
00305  *
00306  * @implemented
00307  */
00308 NTSTATUS
00309 NTAPI
00310 RtlFindRange(IN PRTL_RANGE_LIST RangeList,
00311              IN ULONGLONG Minimum,
00312              IN ULONGLONG Maximum,
00313              IN ULONG Length,
00314              IN ULONG Alignment,
00315              IN ULONG Flags,
00316              IN UCHAR AttributeAvailableMask,
00317              IN PVOID Context OPTIONAL,
00318              IN PRTL_CONFLICT_RANGE_CALLBACK Callback OPTIONAL,
00319              OUT PULONGLONG Start)
00320 {
00321     PRTL_RANGE_ENTRY CurrentEntry;
00322     PRTL_RANGE_ENTRY NextEntry;
00323     PLIST_ENTRY Entry;
00324     ULONGLONG RangeMin;
00325     ULONGLONG RangeMax;
00326 
00327     if (Alignment == 0 || Length == 0)
00328     {
00329         return STATUS_INVALID_PARAMETER;
00330     }
00331 
00332     if (IsListEmpty(&RangeList->ListHead))
00333     {
00334         *Start = ROUND_DOWN(Maximum - (Length - 1), Alignment);
00335         return STATUS_SUCCESS;
00336     }
00337 
00338     NextEntry = NULL;
00339     Entry = RangeList->ListHead.Blink;
00340     while (Entry != &RangeList->ListHead)
00341     {
00342         CurrentEntry = CONTAINING_RECORD(Entry, RTL_RANGE_ENTRY, Entry);
00343 
00344         RangeMax = NextEntry ? (NextEntry->Range.Start - 1) : Maximum;
00345         if (RangeMax + (Length - 1) < Minimum)
00346         {
00347             return STATUS_RANGE_NOT_FOUND;
00348         }
00349 
00350         RangeMin = ROUND_DOWN(RangeMax - (Length - 1), Alignment);
00351         if (RangeMin < Minimum ||
00352             (RangeMax - RangeMin) < (Length - 1))
00353         {
00354             return STATUS_RANGE_NOT_FOUND;
00355         }
00356 
00357         DPRINT("RangeMax: %I64x\n", RangeMax);
00358         DPRINT("RangeMin: %I64x\n", RangeMin);
00359 
00360         if (RangeMin > CurrentEntry->Range.End)
00361         {
00362             *Start = RangeMin;
00363             return STATUS_SUCCESS;
00364         }
00365 
00366         NextEntry = CurrentEntry;
00367         Entry = Entry->Blink;
00368     }
00369 
00370     RangeMax = NextEntry ? (NextEntry->Range.Start - 1) : Maximum;
00371     if (RangeMax + (Length - 1) < Minimum)
00372     {
00373         return STATUS_RANGE_NOT_FOUND;
00374     }
00375 
00376     RangeMin = ROUND_DOWN(RangeMax - (Length - 1), Alignment);
00377     if (RangeMin < Minimum ||
00378         (RangeMax - RangeMin) < (Length - 1))
00379     {
00380         return STATUS_RANGE_NOT_FOUND;
00381     }
00382 
00383     DPRINT("RangeMax: %I64x\n", RangeMax);
00384     DPRINT("RangeMin: %I64x\n", RangeMin);
00385 
00386     *Start = RangeMin;
00387 
00388     return STATUS_SUCCESS;
00389 }
00390 
00391 
00392 /**********************************************************************
00393  * NAME                         EXPORTED
00394  *  RtlFreeRangeList
00395  *
00396  * DESCRIPTION
00397  *  Deletes all ranges in a range list.
00398  *
00399  * ARGUMENTS
00400  *  RangeList   Pointer to the range list.
00401  *
00402  * RETURN VALUE
00403  *  None
00404  *
00405  * @implemented
00406  */
00407 VOID
00408 NTAPI
00409 RtlFreeRangeList(IN PRTL_RANGE_LIST RangeList)
00410 {
00411     PLIST_ENTRY Entry;
00412     PRTL_RANGE_ENTRY Current;
00413 
00414     while (!IsListEmpty(&RangeList->ListHead))
00415     {
00416         Entry = RemoveHeadList(&RangeList->ListHead);
00417         Current = CONTAINING_RECORD(Entry, RTL_RANGE_ENTRY, Entry);
00418 
00419         DPRINT ("Range start: %I64u\n", Current->Range.Start);
00420         DPRINT ("Range end:   %I64u\n", Current->Range.End);
00421 
00422         RtlpFreeMemory(Current, 0);
00423     }
00424 
00425     RangeList->Flags = 0;
00426     RangeList->Count = 0;
00427 }
00428 
00429 
00430 /**********************************************************************
00431  * NAME                         EXPORTED
00432  *  RtlGetFirstRange
00433  *
00434  * DESCRIPTION
00435  *  Retrieves the first range of a range list.
00436  *
00437  * ARGUMENTS
00438  *  RangeList   Pointer to the range list.
00439  *  Iterator    Pointer to a user supplied list state buffer.
00440  *  Range       Pointer to the first range.
00441  *
00442  * RETURN VALUE
00443  *  Status
00444  *
00445  * @implemented
00446  */
00447 NTSTATUS
00448 NTAPI
00449 RtlGetFirstRange(IN PRTL_RANGE_LIST RangeList,
00450                  OUT PRTL_RANGE_LIST_ITERATOR Iterator,
00451                  OUT PRTL_RANGE *Range)
00452 {
00453     Iterator->RangeListHead = &RangeList->ListHead;
00454     Iterator->MergedHead = NULL;
00455     Iterator->Stamp = RangeList->Stamp;
00456 
00457     if (IsListEmpty(&RangeList->ListHead))
00458     {
00459         Iterator->Current = NULL;
00460         *Range = NULL;
00461         return STATUS_NO_MORE_ENTRIES;
00462     }
00463 
00464     Iterator->Current = RangeList->ListHead.Flink;
00465     *Range = &((PRTL_RANGE_ENTRY)Iterator->Current)->Range;
00466 
00467     return STATUS_SUCCESS;
00468 }
00469 
00470 
00471 /**********************************************************************
00472  * NAME                         EXPORTED
00473  *  RtlGetNextRange
00474  *
00475  * DESCRIPTION
00476  *  Retrieves the next (or previous) range of a range list.
00477  *
00478  * ARGUMENTS
00479  *  Iterator    Pointer to a user supplied list state buffer.
00480  *  Range       Pointer to the first range.
00481  *  MoveForwards    TRUE, get next range
00482  *          FALSE, get previous range
00483  *
00484  * RETURN VALUE
00485  *  Status
00486  *
00487  * @implemented
00488  */
00489 NTSTATUS
00490 NTAPI
00491 RtlGetNextRange(IN OUT PRTL_RANGE_LIST_ITERATOR Iterator,
00492                 OUT PRTL_RANGE *Range,
00493                 IN BOOLEAN MoveForwards)
00494 {
00495     PRTL_RANGE_LIST RangeList;
00496     PLIST_ENTRY Next;
00497 
00498     RangeList = CONTAINING_RECORD(Iterator->RangeListHead, RTL_RANGE_LIST, ListHead);
00499     if (Iterator->Stamp != RangeList->Stamp)
00500         return STATUS_INVALID_PARAMETER;
00501 
00502     if (MoveForwards)
00503     {
00504         Next = ((PRTL_RANGE_ENTRY)Iterator->Current)->Entry.Flink;
00505     }
00506     else
00507     {
00508         Next = ((PRTL_RANGE_ENTRY)Iterator->Current)->Entry.Blink;
00509     }
00510 
00511     if (Next == Iterator->RangeListHead)
00512         return STATUS_NO_MORE_ENTRIES;
00513 
00514     Iterator->Current = Next;
00515     *Range = &((PRTL_RANGE_ENTRY)Next)->Range;
00516 
00517     return STATUS_SUCCESS;
00518 }
00519 
00520 
00521 /**********************************************************************
00522  * NAME                         EXPORTED
00523  *  RtlInitializeRangeList
00524  *
00525  * DESCRIPTION
00526  *  Initializes a range list.
00527  *
00528  * ARGUMENTS
00529  *  RangeList   Pointer to a user supplied range list.
00530  *
00531  * RETURN VALUE
00532  *  None
00533  *
00534  * @implemented
00535  */
00536 VOID
00537 NTAPI
00538 RtlInitializeRangeList(IN OUT PRTL_RANGE_LIST RangeList)
00539 {
00540     InitializeListHead(&RangeList->ListHead);
00541     RangeList->Flags = 0;
00542     RangeList->Count = 0;
00543     RangeList->Stamp = 0;
00544 }
00545 
00546 
00547 /**********************************************************************
00548  * NAME                         EXPORTED
00549  *  RtlInvertRangeList
00550  *
00551  * DESCRIPTION
00552  *  Inverts a range list.
00553  *
00554  * ARGUMENTS
00555  *  InvertedRangeList   Inverted range list.
00556  *  RangeList       Range list.
00557  *
00558  * RETURN VALUE
00559  *  Status
00560  *
00561  * @implemented
00562  */
00563 NTSTATUS
00564 NTAPI
00565 RtlInvertRangeList(OUT PRTL_RANGE_LIST InvertedRangeList,
00566                    IN PRTL_RANGE_LIST RangeList)
00567 {
00568     PRTL_RANGE_ENTRY Previous;
00569     PRTL_RANGE_ENTRY Current;
00570     PLIST_ENTRY Entry;
00571     NTSTATUS Status;
00572 
00573     /* Don't invert an empty range list */
00574     if (IsListEmpty(&RangeList->ListHead))
00575     {
00576         return STATUS_SUCCESS;
00577     }
00578 
00579     /* Add leading and intermediate ranges */
00580     Previous = NULL;
00581     Entry = RangeList->ListHead.Flink;
00582     while (Entry != &RangeList->ListHead)
00583     {
00584         Current = CONTAINING_RECORD(Entry, RTL_RANGE_ENTRY, Entry);
00585 
00586         if (Previous == NULL)
00587         {
00588             if (Current->Range.Start != (ULONGLONG)0)
00589             {
00590                 Status = RtlAddRange(InvertedRangeList,
00591                                      (ULONGLONG)0,
00592                                      Current->Range.Start - 1,
00593                                      0,
00594                                      0,
00595                                      NULL,
00596                                      NULL);
00597                 if (!NT_SUCCESS(Status))
00598                     return Status;
00599             }
00600         }
00601         else
00602         {
00603             if (Previous->Range.End + 1 != Current->Range.Start)
00604             {
00605                 Status = RtlAddRange(InvertedRangeList,
00606                                      Previous->Range.End + 1,
00607                                      Current->Range.Start - 1,
00608                                      0,
00609                                      0,
00610                                      NULL,
00611                                      NULL);
00612                 if (!NT_SUCCESS(Status))
00613                     return Status;
00614             }
00615         }
00616 
00617         Previous = Current;
00618         Entry = Entry->Flink;
00619     }
00620 
00621     /* Add trailing range */
00622     if (Previous->Range.End + 1 != (ULONGLONG)-1)
00623     {
00624         Status = RtlAddRange(InvertedRangeList,
00625                              Previous->Range.End + 1,
00626                              (ULONGLONG)-1,
00627                              0,
00628                              0,
00629                              NULL,
00630                              NULL);
00631         if (!NT_SUCCESS(Status))
00632             return Status;
00633     }
00634 
00635     return STATUS_SUCCESS;
00636 }
00637 
00638 
00639 /**********************************************************************
00640  * NAME                         EXPORTED
00641  *  RtlIsRangeAvailable
00642  *
00643  * DESCRIPTION
00644  *  Checks whether a range is available or not.
00645  *
00646  * ARGUMENTS
00647  *  RangeList       Pointer to the range list.
00648  *  Start
00649  *  End
00650  *  Flags
00651  *  AttributeAvailableMask
00652  *  Context
00653  *  Callback
00654  *  Available
00655  *
00656  * RETURN VALUE
00657  *  Status
00658  *
00659  * TODO:
00660  *   - honor Flags and AttributeAvailableMask.
00661  *
00662  * @implemented
00663  */
00664 NTSTATUS
00665 NTAPI
00666 RtlIsRangeAvailable(IN PRTL_RANGE_LIST RangeList,
00667                     IN ULONGLONG Start,
00668                     IN ULONGLONG End,
00669                     IN ULONG Flags,
00670                     IN UCHAR AttributeAvailableMask,
00671                     IN PVOID Context OPTIONAL,
00672                     IN PRTL_CONFLICT_RANGE_CALLBACK Callback OPTIONAL,
00673                     OUT PBOOLEAN Available)
00674 {
00675     PRTL_RANGE_ENTRY Current;
00676     PLIST_ENTRY Entry;
00677 
00678     *Available = TRUE;
00679 
00680     Entry = RangeList->ListHead.Flink;
00681     while (Entry != &RangeList->ListHead)
00682     {
00683         Current = CONTAINING_RECORD (Entry, RTL_RANGE_ENTRY, Entry);
00684 
00685         if (!((Current->Range.Start >= End && Current->Range.End > End) ||
00686               (Current->Range.Start <= Start && Current->Range.End < Start &&
00687                (!(Flags & RTL_RANGE_SHARED) ||
00688                 !(Current->Range.Flags & RTL_RANGE_SHARED)))))
00689         {
00690             if (Callback != NULL)
00691             {
00692                 *Available = Callback(Context,
00693                                       &Current->Range);
00694             }
00695             else
00696             {
00697                 *Available = FALSE;
00698             }
00699         }
00700 
00701         Entry = Entry->Flink;
00702     }
00703 
00704     return STATUS_SUCCESS;
00705 }
00706 
00707 
00708 /**********************************************************************
00709  * NAME                         EXPORTED
00710  *  RtlMergeRangeList
00711  *
00712  * DESCRIPTION
00713  *  Merges two range lists.
00714  *
00715  * ARGUMENTS
00716  *  MergedRangeList Resulting range list.
00717  *  RangeList1  First range list.
00718  *  RangeList2  Second range list
00719  *  Flags
00720  *
00721  * RETURN VALUE
00722  *  Status
00723  *
00724  * @implemented
00725  */
00726 NTSTATUS
00727 NTAPI
00728 RtlMergeRangeLists(OUT PRTL_RANGE_LIST MergedRangeList,
00729                    IN PRTL_RANGE_LIST RangeList1,
00730                    IN PRTL_RANGE_LIST RangeList2,
00731                    IN ULONG Flags)
00732 {
00733     RTL_RANGE_LIST_ITERATOR Iterator;
00734     PRTL_RANGE Range;
00735     NTSTATUS Status;
00736 
00737     /* Copy range list 1 to the merged range list */
00738     Status = RtlCopyRangeList(MergedRangeList,
00739                               RangeList1);
00740     if (!NT_SUCCESS(Status))
00741         return Status;
00742 
00743     /* Add range list 2 entries to the merged range list */
00744     Status = RtlGetFirstRange(RangeList2,
00745                               &Iterator,
00746                               &Range);
00747     if (!NT_SUCCESS(Status))
00748         return (Status == STATUS_NO_MORE_ENTRIES) ? STATUS_SUCCESS : Status;
00749 
00750     while (TRUE)
00751     {
00752         Status = RtlAddRange(MergedRangeList,
00753                              Range->Start,
00754                              Range->End,
00755                              Range->Attributes,
00756                              Range->Flags | Flags,
00757                              Range->UserData,
00758                              Range->Owner);
00759         if (!NT_SUCCESS(Status))
00760             break;
00761 
00762         Status = RtlGetNextRange(&Iterator,
00763                                  &Range,
00764                                  TRUE);
00765         if (!NT_SUCCESS(Status))
00766             break;
00767     }
00768 
00769     return (Status == STATUS_NO_MORE_ENTRIES) ? STATUS_SUCCESS : Status;
00770 }
00771 
00772 /* EOF */

Generated on Sat May 26 2012 04:35:22 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.