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

meminit.c
Go to the documentation of this file.
00001 /*
00002  *  FreeLoader
00003  *  Copyright (C) 2006-2008     Aleksey Bragin  <aleksey@reactos.org>
00004  *  Copyright (C) 2006-2009     Hervé Poussineau  <hpoussin@reactos.org>
00005  *
00006  *  This program is free software; you can redistribute it and/or modify
00007  *  it under the terms of the GNU General Public License as published by
00008  *  the Free Software Foundation; either version 2 of the License, or
00009  *  (at your option) any later version.
00010  *
00011  *  This program is distributed in the hope that it will be useful,
00012  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  *  GNU General Public License for more details.
00015  *
00016  *  You should have received a copy of the GNU General Public License along
00017  *  with this program; if not, write to the Free Software Foundation, Inc.,
00018  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
00019  */
00020 
00021 #include <freeldr.h>
00022 #include <debug.h>
00023 
00024 DBG_DEFAULT_CHANNEL(MEMORY);
00025 
00026 #if DBG
00027 typedef struct
00028 {
00029     TYPE_OF_MEMORY Type;
00030     PCSTR TypeString;
00031 } FREELDR_MEMORY_TYPE, *PFREELDR_MEMORY_TYPE;
00032 
00033 FREELDR_MEMORY_TYPE MemoryTypeArray[] =
00034 {
00035     { LoaderMaximum, "Unknown memory" },
00036     { LoaderFree, "Free memory" },
00037     { LoaderBad, "Bad memory" },
00038     { LoaderLoadedProgram, "LoadedProgram" },
00039     { LoaderFirmwareTemporary, "FirmwareTemporary" },
00040     { LoaderFirmwarePermanent, "FirmwarePermanent" },
00041     { LoaderOsloaderHeap, "OsloaderHeap" },
00042     { LoaderOsloaderStack, "OsloaderStack" },
00043     { LoaderSystemCode, "SystemCode" },
00044     { LoaderHalCode, "HalCode" },
00045     { LoaderBootDriver, "BootDriver" },
00046     { LoaderRegistryData, "RegistryData" },
00047     { LoaderMemoryData, "MemoryData" },
00048     { LoaderNlsData, "NlsData" },
00049     { LoaderSpecialMemory, "SpecialMemory" },
00050     { LoaderReserve, "Reserve" },
00051 };
00052 ULONG MemoryTypeCount = sizeof(MemoryTypeArray) / sizeof(MemoryTypeArray[0]);
00053 #endif
00054 
00055 PVOID   PageLookupTableAddress = NULL;
00056 PFN_NUMBER TotalPagesInLookupTable = 0;
00057 PFN_NUMBER FreePagesInLookupTable = 0;
00058 PFN_NUMBER LastFreePageHint = 0;
00059 PFN_NUMBER MmLowestPhysicalPage = 0xFFFFFFFF;
00060 PFN_NUMBER MmHighestPhysicalPage = 0;
00061 
00062 PFREELDR_MEMORY_DESCRIPTOR BiosMemoryMap;
00063 ULONG BiosMemoryMapEntryCount;
00064 
00065 extern ULONG_PTR    MmHeapPointer;
00066 extern ULONG_PTR    MmHeapStart;
00067 
00068 ULONG
00069 AddMemoryDescriptor(
00070     IN OUT PFREELDR_MEMORY_DESCRIPTOR List,
00071     IN ULONG MaxCount,
00072     IN PFN_NUMBER BasePage,
00073     IN PFN_NUMBER PageCount,
00074     IN TYPE_OF_MEMORY MemoryType)
00075 {
00076     ULONG i, c;
00077     PFN_NUMBER NextBase;
00078     TRACE("AddMemoryDescriptor(0x%lx-0x%lx [0x%lx pages])\n",
00079           BasePage, BasePage + PageCount, PageCount);
00080 
00081     /* Scan through all existing descriptors */
00082     for (i = 0, c = 0; (c < MaxCount) && (List[c].PageCount != 0); c++)
00083     {
00084         /* Count entries completely below the new range */
00085         if (List[i].BasePage + List[i].PageCount <= BasePage) i++;
00086     }
00087 
00088     /* Check if the list is full */
00089     if (c >= MaxCount) return c;
00090 
00091     /* Is there an existing descriptor starting before the new range */
00092     while ((i < c) && (List[i].BasePage <= BasePage))
00093     {
00094         /* The end of the existing one is the minimum for the new range */
00095         NextBase = List[i].BasePage + List[i].PageCount;
00096 
00097         /* Bail out, if everything is trimmed away */
00098         if ((BasePage + PageCount) <= NextBase) return c;
00099 
00100         /* Trim the naew range at the lower end */
00101         PageCount -= (NextBase - BasePage);
00102         BasePage = NextBase;
00103 
00104         /* Go to the next entry and repeat */
00105         i++;
00106     }
00107 
00108     ASSERT(PageCount > 0);
00109 
00110     /* Are there still entries above? */
00111     if (i < c)
00112     {
00113         /* Shift the following entries one up */
00114         RtlMoveMemory(&List[i+1], &List[i], (c - i) * sizeof(List[0]));
00115 
00116         /* Insert the new range */
00117         List[i].BasePage = BasePage;
00118         List[i].PageCount = min(PageCount, List[i+1].BasePage - BasePage);
00119         List[i].MemoryType = MemoryType;
00120         c++;
00121 
00122         TRACE("Inserting at i=%ld: (0x%lx:0x%lx)\n",
00123               i, List[i].BasePage, List[i].PageCount);
00124 
00125         /* Check if the range was trimmed */
00126         if (PageCount > List[i].PageCount)
00127         {
00128             /* Recursively process the trimmed part */
00129             c = AddMemoryDescriptor(List,
00130                                     MaxCount,
00131                                     BasePage + List[i].PageCount,
00132                                     PageCount - List[i].PageCount,
00133                                     MemoryType);
00134         }
00135     }
00136     else
00137     {
00138         /* We can simply add the range here */
00139         TRACE("Adding i=%ld: (0x%lx:0x%lx)\n", i, BasePage, PageCount);
00140         List[i].BasePage = BasePage;
00141         List[i].PageCount = PageCount;
00142         List[i].MemoryType = MemoryType;
00143         c++;
00144     }
00145 
00146     /* Return the new count */
00147     return c;
00148 }
00149 
00150 const FREELDR_MEMORY_DESCRIPTOR*
00151 ArcGetMemoryDescriptor(const FREELDR_MEMORY_DESCRIPTOR* Current)
00152 {
00153     if (Current == NULL)
00154     {
00155         return BiosMemoryMap;
00156     }
00157     else
00158     {
00159         Current++;
00160         if (Current->PageCount == 0) return NULL;
00161         return Current;
00162     }
00163 }
00164 
00165 
00166 BOOLEAN MmInitializeMemoryManager(VOID)
00167 {
00168 #if DBG
00169     const FREELDR_MEMORY_DESCRIPTOR* MemoryDescriptor = NULL;
00170 #endif
00171 
00172     TRACE("Initializing Memory Manager.\n");
00173 
00174     BiosMemoryMap = MachVtbl.GetMemoryMap(&BiosMemoryMapEntryCount);
00175 
00176 #if DBG
00177     // Dump the system memory map
00178     TRACE("System Memory Map (Base Address, Length, Type):\n");
00179     while ((MemoryDescriptor = ArcGetMemoryDescriptor(MemoryDescriptor)) != NULL)
00180     {
00181         TRACE("%x\t %x\t %s\n",
00182             MemoryDescriptor->BasePage * MM_PAGE_SIZE,
00183             MemoryDescriptor->PageCount * MM_PAGE_SIZE,
00184             MmGetSystemMemoryMapTypeString(MemoryDescriptor->MemoryType));
00185     }
00186 #endif
00187 
00188     // Find address for the page lookup table
00189     TotalPagesInLookupTable = MmGetAddressablePageCountIncludingHoles();
00190     PageLookupTableAddress = MmFindLocationForPageLookupTable(TotalPagesInLookupTable);
00191     LastFreePageHint = MmHighestPhysicalPage;
00192 
00193     if (PageLookupTableAddress == 0)
00194     {
00195         // If we get here then we probably couldn't
00196         // find a contiguous chunk of memory big
00197         // enough to hold the page lookup table
00198         printf("Error initializing memory manager!\n");
00199         return FALSE;
00200     }
00201 
00202     // Initialize the page lookup table
00203     MmInitPageLookupTable(PageLookupTableAddress, TotalPagesInLookupTable);
00204 
00205     MmUpdateLastFreePageHint(PageLookupTableAddress, TotalPagesInLookupTable);
00206 
00207     FreePagesInLookupTable = MmCountFreePagesInLookupTable(PageLookupTableAddress,
00208                                                         TotalPagesInLookupTable);
00209 
00210     MmInitializeHeap(PageLookupTableAddress);
00211 
00212     TRACE("Memory Manager initialized. 0x%x pages available.\n", FreePagesInLookupTable);
00213 
00214 
00215     return TRUE;
00216 }
00217 
00218 #if DBG
00219 PCSTR MmGetSystemMemoryMapTypeString(TYPE_OF_MEMORY Type)
00220 {
00221     ULONG       Index;
00222 
00223     for (Index=1; Index<MemoryTypeCount; Index++)
00224     {
00225         if (MemoryTypeArray[Index].Type == Type)
00226         {
00227             return MemoryTypeArray[Index].TypeString;
00228         }
00229     }
00230 
00231     return MemoryTypeArray[0].TypeString;
00232 }
00233 #endif
00234 
00235 PFN_NUMBER MmGetPageNumberFromAddress(PVOID Address)
00236 {
00237     return ((ULONG_PTR)Address) / MM_PAGE_SIZE;
00238 }
00239 
00240 PFN_NUMBER MmGetAddressablePageCountIncludingHoles(VOID)
00241 {
00242     const FREELDR_MEMORY_DESCRIPTOR* MemoryDescriptor = NULL;
00243     PFN_NUMBER PageCount;
00244 
00245     //
00246     // Go through the whole memory map to get max address
00247     //
00248     while ((MemoryDescriptor = ArcGetMemoryDescriptor(MemoryDescriptor)) != NULL)
00249     {
00250         //
00251         // Check if we got a higher end page address
00252         //
00253         if (MemoryDescriptor->BasePage + MemoryDescriptor->PageCount > MmHighestPhysicalPage)
00254         {
00255             //
00256             // Yes, remember it if this is real memory
00257             //
00258             if (MemoryDescriptor->MemoryType == LoaderFree)
00259                 MmHighestPhysicalPage = MemoryDescriptor->BasePage + MemoryDescriptor->PageCount;
00260         }
00261 
00262         //
00263         // Check if we got a higher (usable) start page address
00264         //
00265         if (MemoryDescriptor->BasePage < MmLowestPhysicalPage)
00266         {
00267             //
00268             // Yes, remember it if this is real memory
00269             //
00270             MmLowestPhysicalPage = MemoryDescriptor->BasePage;
00271         }
00272     }
00273 
00274     TRACE("lo/hi %lx %lx\n", MmLowestPhysicalPage, MmHighestPhysicalPage);
00275     PageCount = MmHighestPhysicalPage - MmLowestPhysicalPage;
00276     TRACE("MmGetAddressablePageCountIncludingHoles() returning 0x%x\n", PageCount);
00277     return PageCount;
00278 }
00279 
00280 PVOID MmFindLocationForPageLookupTable(PFN_NUMBER TotalPageCount)
00281 {
00282     const FREELDR_MEMORY_DESCRIPTOR* MemoryDescriptor = NULL;
00283     SIZE_T PageLookupTableSize;
00284     PFN_NUMBER PageLookupTablePages;
00285     PFN_NUMBER PageLookupTableStartPage = 0;
00286     PVOID PageLookupTableMemAddress = NULL;
00287 
00288     // Calculate how much pages we need to keep the page lookup table
00289     PageLookupTableSize = TotalPageCount * sizeof(PAGE_LOOKUP_TABLE_ITEM);
00290     PageLookupTablePages = PageLookupTableSize / MM_PAGE_SIZE;
00291 
00292     // Search the highest memory block big enough to contain lookup table
00293     while ((MemoryDescriptor = ArcGetMemoryDescriptor(MemoryDescriptor)) != NULL)
00294     {
00295         // Continue, if memory is not free
00296         if (MemoryDescriptor->MemoryType != LoaderFree) continue;
00297 
00298         // Continue, if the block is not big enough?
00299         if (MemoryDescriptor->PageCount < PageLookupTablePages) continue;
00300 
00301         // Continue, if it is not at a higher address than previous address
00302         if (MemoryDescriptor->BasePage < PageLookupTableStartPage) continue;
00303 
00304         // Continue, if the address is too high
00305         if (MemoryDescriptor->BasePage >= MM_MAX_PAGE) continue;
00306 
00307         // Memory block is more suitable than the previous one
00308         PageLookupTableStartPage = MemoryDescriptor->BasePage;
00309         PageLookupTableMemAddress = (PVOID)((ULONG_PTR)
00310             (MemoryDescriptor->BasePage + MemoryDescriptor->PageCount) * MM_PAGE_SIZE
00311             - PageLookupTableSize);
00312     }
00313 
00314     TRACE("MmFindLocationForPageLookupTable() returning 0x%x\n", PageLookupTableMemAddress);
00315 
00316     return PageLookupTableMemAddress;
00317 }
00318 
00319 VOID MmInitPageLookupTable(PVOID PageLookupTable, PFN_NUMBER TotalPageCount)
00320 {
00321     const FREELDR_MEMORY_DESCRIPTOR* MemoryDescriptor = NULL;
00322     PFN_NUMBER PageLookupTableStartPage;
00323     PFN_NUMBER PageLookupTablePageCount;
00324 
00325     TRACE("MmInitPageLookupTable()\n");
00326 
00327     // Mark every page as allocated initially
00328     // We will go through and mark pages again according to the memory map
00329     // But this will mark any holes not described in the map as allocated
00330     MmMarkPagesInLookupTable(PageLookupTable, MmLowestPhysicalPage, TotalPageCount, LoaderFirmwarePermanent);
00331 
00332     // Parse the whole memory map
00333     while ((MemoryDescriptor = ArcGetMemoryDescriptor(MemoryDescriptor)) != NULL)
00334     {
00335         // Mark used pages in the lookup table
00336 
00337         if (MemoryDescriptor->BasePage + MemoryDescriptor->PageCount <= TotalPageCount)
00338         {
00339             TRACE("Marking pages 0x%lx-0x%lx as type %s\n",
00340                   MemoryDescriptor->BasePage,
00341                   MemoryDescriptor->BasePage + MemoryDescriptor->PageCount,
00342                   MmGetSystemMemoryMapTypeString(MemoryDescriptor->MemoryType));
00343             MmMarkPagesInLookupTable(PageLookupTable,
00344                                      MemoryDescriptor->BasePage,
00345                                      MemoryDescriptor->PageCount,
00346                                      MemoryDescriptor->MemoryType);
00347         }
00348         else
00349             TRACE("Ignoring pages 0x%lx-0x%lx (%s)\n",
00350                   MemoryDescriptor->BasePage,
00351                   MemoryDescriptor->BasePage + MemoryDescriptor->PageCount,
00352                   MmGetSystemMemoryMapTypeString(MemoryDescriptor->MemoryType));
00353     }
00354 
00355     // Mark the pages that the lookup table occupies as reserved
00356     PageLookupTableStartPage = MmGetPageNumberFromAddress(PageLookupTable);
00357     PageLookupTablePageCount = MmGetPageNumberFromAddress((PVOID)((ULONG_PTR)PageLookupTable + ROUND_UP(TotalPageCount * sizeof(PAGE_LOOKUP_TABLE_ITEM), MM_PAGE_SIZE))) - PageLookupTableStartPage;
00358     TRACE("Marking the page lookup table pages as reserved StartPage: 0x%x PageCount: 0x%x\n", PageLookupTableStartPage, PageLookupTablePageCount);
00359     MmMarkPagesInLookupTable(PageLookupTable, PageLookupTableStartPage, PageLookupTablePageCount, LoaderFirmwareTemporary);
00360 }
00361 
00362 VOID MmMarkPagesInLookupTable(PVOID PageLookupTable, PFN_NUMBER StartPage, PFN_NUMBER PageCount, TYPE_OF_MEMORY PageAllocated)
00363 {
00364     PPAGE_LOOKUP_TABLE_ITEM RealPageLookupTable = (PPAGE_LOOKUP_TABLE_ITEM)PageLookupTable;
00365     PFN_NUMBER Index;
00366     TRACE("MmMarkPagesInLookupTable()\n");
00367 
00368     /* Validate the range */
00369     if ((StartPage < MmLowestPhysicalPage) ||
00370         ((StartPage + PageCount - 1) > MmHighestPhysicalPage))
00371     {
00372         ERR("Memory (0x%lx:0x%lx) outside of lookup table! Valid range: 0x%lx-0x%lx.\n",
00373             StartPage, PageCount, MmLowestPhysicalPage, MmHighestPhysicalPage);
00374         return;
00375     }
00376 
00377     StartPage -= MmLowestPhysicalPage;
00378     for (Index=StartPage; Index<(StartPage+PageCount); Index++)
00379     {
00380 #if 0
00381         if ((Index <= (StartPage + 16)) || (Index >= (StartPage+PageCount-16)))
00382         {
00383             TRACE("Index = 0x%x StartPage = 0x%x PageCount = 0x%x\n", Index, StartPage, PageCount);
00384         }
00385 #endif
00386         RealPageLookupTable[Index].PageAllocated = PageAllocated;
00387         RealPageLookupTable[Index].PageAllocationLength = (PageAllocated != LoaderFree) ? 1 : 0;
00388     }
00389     TRACE("MmMarkPagesInLookupTable() Done\n");
00390 }
00391 
00392 VOID MmAllocatePagesInLookupTable(PVOID PageLookupTable, PFN_NUMBER StartPage, PFN_NUMBER PageCount, TYPE_OF_MEMORY MemoryType)
00393 {
00394     PPAGE_LOOKUP_TABLE_ITEM     RealPageLookupTable = (PPAGE_LOOKUP_TABLE_ITEM)PageLookupTable;
00395     PFN_NUMBER                  Index;
00396 
00397     StartPage -= MmLowestPhysicalPage;
00398     for (Index=StartPage; Index<(StartPage+PageCount); Index++)
00399     {
00400         RealPageLookupTable[Index].PageAllocated = MemoryType;
00401         RealPageLookupTable[Index].PageAllocationLength = (Index == StartPage) ? PageCount : 0;
00402     }
00403 }
00404 
00405 PFN_NUMBER MmCountFreePagesInLookupTable(PVOID PageLookupTable, PFN_NUMBER TotalPageCount)
00406 {
00407     PPAGE_LOOKUP_TABLE_ITEM     RealPageLookupTable = (PPAGE_LOOKUP_TABLE_ITEM)PageLookupTable;
00408     PFN_NUMBER                          Index;
00409     PFN_NUMBER                          FreePageCount;
00410 
00411     FreePageCount = 0;
00412     for (Index=0; Index<TotalPageCount; Index++)
00413     {
00414         if (RealPageLookupTable[Index].PageAllocated == LoaderFree)
00415         {
00416             FreePageCount++;
00417         }
00418     }
00419 
00420     return FreePageCount;
00421 }
00422 
00423 PFN_NUMBER MmFindAvailablePages(PVOID PageLookupTable, PFN_NUMBER TotalPageCount, PFN_NUMBER PagesNeeded, BOOLEAN FromEnd)
00424 {
00425     PPAGE_LOOKUP_TABLE_ITEM RealPageLookupTable = (PPAGE_LOOKUP_TABLE_ITEM)PageLookupTable;
00426     PFN_NUMBER AvailablePagesSoFar;
00427     PFN_NUMBER Index;
00428 
00429     if (LastFreePageHint > TotalPageCount)
00430     {
00431         LastFreePageHint = TotalPageCount;
00432     }
00433 
00434     AvailablePagesSoFar = 0;
00435     if (FromEnd)
00436     {
00437         /* Allocate "high" (from end) pages */
00438         for (Index=LastFreePageHint-1; Index>0; Index--)
00439         {
00440             if (RealPageLookupTable[Index].PageAllocated != LoaderFree)
00441             {
00442                 AvailablePagesSoFar = 0;
00443                 continue;
00444             }
00445             else
00446             {
00447                 AvailablePagesSoFar++;
00448             }
00449 
00450             if (AvailablePagesSoFar >= PagesNeeded)
00451             {
00452                 return Index + MmLowestPhysicalPage;
00453             }
00454         }
00455     }
00456     else
00457     {
00458         TRACE("Alloc low memory, LastFreePageHint 0x%x, TPC 0x%x\n", LastFreePageHint, TotalPageCount);
00459         /* Allocate "low" pages */
00460         for (Index=1; Index < LastFreePageHint; Index++)
00461         {
00462             if (RealPageLookupTable[Index].PageAllocated != LoaderFree)
00463             {
00464                 AvailablePagesSoFar = 0;
00465                 continue;
00466             }
00467             else
00468             {
00469                 AvailablePagesSoFar++;
00470             }
00471 
00472             if (AvailablePagesSoFar >= PagesNeeded)
00473             {
00474                 return Index - AvailablePagesSoFar + 1 + MmLowestPhysicalPage;
00475             }
00476         }
00477     }
00478 
00479     return 0;
00480 }
00481 
00482 PFN_NUMBER MmFindAvailablePagesBeforePage(PVOID PageLookupTable, PFN_NUMBER TotalPageCount, PFN_NUMBER PagesNeeded, PFN_NUMBER LastPage)
00483 {
00484     PPAGE_LOOKUP_TABLE_ITEM     RealPageLookupTable = (PPAGE_LOOKUP_TABLE_ITEM)PageLookupTable;
00485     PFN_NUMBER                  AvailablePagesSoFar;
00486     PFN_NUMBER                  Index;
00487 
00488     if (LastPage > TotalPageCount)
00489     {
00490         return MmFindAvailablePages(PageLookupTable, TotalPageCount, PagesNeeded, TRUE);
00491     }
00492 
00493     AvailablePagesSoFar = 0;
00494     for (Index=LastPage-1; Index>0; Index--)
00495     {
00496         if (RealPageLookupTable[Index].PageAllocated != LoaderFree)
00497         {
00498             AvailablePagesSoFar = 0;
00499             continue;
00500         }
00501         else
00502         {
00503             AvailablePagesSoFar++;
00504         }
00505 
00506         if (AvailablePagesSoFar >= PagesNeeded)
00507         {
00508             return Index + MmLowestPhysicalPage;
00509         }
00510     }
00511 
00512     return 0;
00513 }
00514 
00515 VOID MmUpdateLastFreePageHint(PVOID PageLookupTable, PFN_NUMBER TotalPageCount)
00516 {
00517     PPAGE_LOOKUP_TABLE_ITEM     RealPageLookupTable = (PPAGE_LOOKUP_TABLE_ITEM)PageLookupTable;
00518     PFN_NUMBER                          Index;
00519 
00520     for (Index=TotalPageCount-1; Index>0; Index--)
00521     {
00522         if (RealPageLookupTable[Index].PageAllocated == LoaderFree)
00523         {
00524             LastFreePageHint = Index + 1 + MmLowestPhysicalPage;
00525             break;
00526         }
00527     }
00528 }
00529 
00530 BOOLEAN MmAreMemoryPagesAvailable(PVOID PageLookupTable, PFN_NUMBER TotalPageCount, PVOID PageAddress, PFN_NUMBER PageCount)
00531 {
00532     PPAGE_LOOKUP_TABLE_ITEM     RealPageLookupTable = (PPAGE_LOOKUP_TABLE_ITEM)PageLookupTable;
00533     PFN_NUMBER                          StartPage;
00534     PFN_NUMBER                          Index;
00535 
00536     StartPage = MmGetPageNumberFromAddress(PageAddress);
00537 
00538     if (StartPage < MmLowestPhysicalPage) return FALSE;
00539 
00540     StartPage -= MmLowestPhysicalPage;
00541 
00542     // Make sure they aren't trying to go past the
00543     // end of availabe memory
00544     if ((StartPage + PageCount) > TotalPageCount)
00545     {
00546         return FALSE;
00547     }
00548 
00549     for (Index = StartPage; Index < (StartPage + PageCount); Index++)
00550     {
00551         // If this page is allocated then there obviously isn't
00552         // memory availabe so return FALSE
00553         if (RealPageLookupTable[Index].PageAllocated != LoaderFree)
00554         {
00555             return FALSE;
00556         }
00557     }
00558 
00559     return TRUE;
00560 }

Generated on Sat May 26 2012 04:18:03 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.