[ros-diffs] [hpoussin] 40710: Remove MachGetMemoryMap() and replace it by ArcGetMemoryDescriptor(). Rework memory initialization to use it. As a bonus, we're not limited anymore to 32 memory descriptors, and having more than 4GB of RAM doesn't lead to out of bounds accesses

hpoussin at svn.reactos.org hpoussin at svn.reactos.org
Sun Apr 26 22:22:17 CEST 2009


Author: hpoussin
Date: Mon Apr 27 00:22:16 2009
New Revision: 40710

URL: http://svn.reactos.org/svn/reactos?rev=40710&view=rev
Log:
Remove MachGetMemoryMap() and replace it by ArcGetMemoryDescriptor(). Rework memory initialization to use it.
As a bonus, we're not limited anymore to 32 memory descriptors, and having more than 4GB of RAM doesn't lead to out of bounds accesses

Modified:
    trunk/reactos/boot/freeldr/freeldr/arch/amd64/hwacpi.c
    trunk/reactos/boot/freeldr/freeldr/arch/i386/hwacpi.c
    trunk/reactos/boot/freeldr/freeldr/include/machine.h
    trunk/reactos/boot/freeldr/freeldr/include/mm.h
    trunk/reactos/boot/freeldr/freeldr/machine.c
    trunk/reactos/boot/freeldr/freeldr/mm/meminit.c
    trunk/reactos/boot/freeldr/freeldr/reactos/reactos.c
    trunk/reactos/boot/freeldr/freeldr/reactos/setupldr.c
    trunk/reactos/boot/freeldr/freeldr/windows/peloader.c

Modified: trunk/reactos/boot/freeldr/freeldr/arch/amd64/hwacpi.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/arch/amd64/hwacpi.c?rev=40710&r1=40709&r2=40710&view=diff
==============================================================================
--- trunk/reactos/boot/freeldr/freeldr/arch/amd64/hwacpi.c [iso-8859-1] (original)
+++ trunk/reactos/boot/freeldr/freeldr/arch/amd64/hwacpi.c [iso-8859-1] Mon Apr 27 00:22:16 2009
@@ -1,130 +1,5 @@
-/*
- *  FreeLoader
- *
- *  Copyright (C) 2004  Eric Kohl
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
+/* No need to duplicate code ; import the i386 version */
 
-#include <freeldr.h>
-#include <debug.h>
-
-BOOLEAN AcpiPresent = FALSE;
-
-static PRSDP_DESCRIPTOR
-FindAcpiBios(VOID)
-{
-    PUCHAR Ptr;
-
-    /* Find the 'Root System Descriptor Table Pointer' */
-    Ptr = (PUCHAR)0xE0000;
-    while ((ULONG_PTR)Ptr < 0x100000)
-    {
-        if (!memcmp(Ptr, "RSD PTR ", 8))
-        {
-            DbgPrint((DPRINT_HWDETECT, "ACPI supported\n"));
-
-            return (PRSDP_DESCRIPTOR)Ptr;
-        }
-
-        Ptr = (PUCHAR)((ULONG_PTR)Ptr + 0x10);
-    }
-
-    DbgPrint((DPRINT_HWDETECT, "ACPI not supported\n"));
-
-    return NULL;
-}
-
-
-VOID
-DetectAcpiBios(PCONFIGURATION_COMPONENT_DATA SystemKey, ULONG *BusNumber)
-{
-    PCONFIGURATION_COMPONENT_DATA BiosKey;
-    PCM_PARTIAL_RESOURCE_LIST PartialResourceList;
-    PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor;
-    PRSDP_DESCRIPTOR Rsdp;
-    PACPI_BIOS_DATA AcpiBiosData;
-    BIOS_MEMORY_MAP BiosMemoryMap[32];
-    ULONG BiosMemoryMapEntryCount, TableSize;
-
-    Rsdp = FindAcpiBios();
-
-    if (Rsdp)
-    {
-        /* Set up the flag in the loader block */
-        AcpiPresent = TRUE;
-        LoaderBlock.Flags |= MB_FLAGS_ACPI_TABLE;
-
-        /* Create new bus key */
-        FldrCreateComponentKey(SystemKey,
-                               L"MultifunctionAdapter",
-                               *BusNumber,
-                               AdapterClass,
-                               MultiFunctionAdapter,
-                               &BiosKey);
-
-        /* Set 'Component Information' */
-        FldrSetComponentInformation(BiosKey,
-                                    0x0,
-                                    0x0,
-                                    0xFFFFFFFF);
-
-        /* Get BIOS memory map */
-        RtlZeroMemory(BiosMemoryMap, sizeof(BIOS_MEMORY_MAP) * 32);
-        BiosMemoryMapEntryCount = MachGetMemoryMap(BiosMemoryMap,
-            sizeof(BiosMemoryMap) / sizeof(BIOS_MEMORY_MAP));
-
-        /* Calculate the table size */
-        TableSize = BiosMemoryMapEntryCount * sizeof(BIOS_MEMORY_MAP) +
-            sizeof(ACPI_BIOS_DATA) - sizeof(BIOS_MEMORY_MAP);
-
-        /* Set 'Configuration Data' value */
-        PartialResourceList =
-            MmHeapAlloc(sizeof(CM_PARTIAL_RESOURCE_LIST) + TableSize);
-        memset(PartialResourceList, 0, sizeof(CM_PARTIAL_RESOURCE_LIST) + TableSize);
-        PartialResourceList->Version = 0;
-        PartialResourceList->Revision = 0;
-        PartialResourceList->Count = 1;
-
-        PartialDescriptor = &PartialResourceList->PartialDescriptors[0];
-        PartialDescriptor->Type = CmResourceTypeDeviceSpecific;
-        PartialDescriptor->ShareDisposition = CmResourceShareUndetermined;
-        PartialDescriptor->u.DeviceSpecificData.DataSize = TableSize;
-
-        /* Fill the table */
-        AcpiBiosData = (PACPI_BIOS_DATA)&PartialResourceList->PartialDescriptors[1];
-        AcpiBiosData->RSDTAddress.LowPart = Rsdp->rsdt_physical_address;
-        AcpiBiosData->Count = BiosMemoryMapEntryCount;
-        memcpy(AcpiBiosData->MemoryMap, BiosMemoryMap,
-            BiosMemoryMapEntryCount * sizeof(BIOS_MEMORY_MAP));
-
-        DbgPrint((DPRINT_HWDETECT, "RSDT %p, data size %x\n", Rsdp->rsdt_physical_address,
-            TableSize));
-
-        FldrSetConfigurationData(BiosKey,
-                                 PartialResourceList,
-                                 sizeof(CM_PARTIAL_RESOURCE_LIST) + TableSize
-                                 );
-
-        /* Increment bus number */
-        (*BusNumber)++;
-
-        /* Set 'Identifier' value */
-        FldrSetIdentifier(BiosKey, "ACPI BIOS");
-        MmFreeMemory(PartialResourceList);
-    }
-}
+#include "../i386/hwacpi.c"
 
 /* EOF */

Modified: trunk/reactos/boot/freeldr/freeldr/arch/i386/hwacpi.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/arch/i386/hwacpi.c?rev=40710&r1=40709&r2=40710&view=diff
==============================================================================
--- trunk/reactos/boot/freeldr/freeldr/arch/i386/hwacpi.c [iso-8859-1] (original)
+++ trunk/reactos/boot/freeldr/freeldr/arch/i386/hwacpi.c [iso-8859-1] Mon Apr 27 00:22:16 2009
@@ -83,7 +83,7 @@
 
         /* Get BIOS memory map */
         RtlZeroMemory(BiosMemoryMap, sizeof(BIOS_MEMORY_MAP) * 32);
-        BiosMemoryMapEntryCount = MachGetMemoryMap(BiosMemoryMap,
+        BiosMemoryMapEntryCount = PcMemGetMemoryMap(BiosMemoryMap,
             sizeof(BiosMemoryMap) / sizeof(BIOS_MEMORY_MAP));
 
         /* Calculate the table size */

Modified: trunk/reactos/boot/freeldr/freeldr/include/machine.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/include/machine.h?rev=40710&r1=40709&r2=40710&view=diff
==============================================================================
--- trunk/reactos/boot/freeldr/freeldr/include/machine.h [iso-8859-1] (original)
+++ trunk/reactos/boot/freeldr/freeldr/include/machine.h [iso-8859-1] Mon Apr 27 00:22:16 2009
@@ -59,6 +59,7 @@
   VOID (*Beep)(VOID);
   VOID (*PrepareForReactOS)(IN BOOLEAN Setup);
 
+  MEMORY_DESCRIPTOR* (*GetMemoryDescriptor)(MEMORY_DESCRIPTOR* Current);
   ULONG (*GetMemoryMap)(PBIOS_MEMORY_MAP BiosMemoryMap, ULONG MaxMemoryMapSize);
 
   BOOLEAN (*DiskGetBootVolume)(PULONG DriveNumber, PULONGLONG StartSector, PULONGLONG SectorCount, int *FsType);
@@ -98,7 +99,7 @@
 VOID MachVideoGetPaletteColor(UCHAR Color, UCHAR *Red, UCHAR *Green, UCHAR *Blue);
 VOID MachVideoSync(VOID);
 VOID MachBeep(VOID);
-ULONG MachGetMemoryMap(PBIOS_MEMORY_MAP BiosMemoryMap, ULONG MaxMemoryMapSize);
+MEMORY_DESCRIPTOR* ArcGetMemoryDescriptor(MEMORY_DESCRIPTOR* Current);
 BOOLEAN MachDiskGetBootVolume(PULONG DriveNumber, PULONGLONG StartSector, PULONGLONG SectorCount, int *FsType);
 BOOLEAN
 MachDiskGetSystemVolume(char *SystemPath,
@@ -138,7 +139,6 @@
 #define MachVideoSync()				MachVtbl.VideoSync()
 #define MachBeep()                   MachVtbl.Beep()
 #define MachPrepareForReactOS(a)		MachVtbl.PrepareForReactOS(a)
-#define MachGetMemoryMap(MMap, Size)		MachVtbl.GetMemoryMap((MMap), (Size))
 #define MachDiskGetBootVolume(Drv, Start, Cnt, FsType)	MachVtbl.DiskGetBootVolume((Drv), (Start), (Cnt), (FsType))
 #define MachDiskGetSystemVolume(SysPath, RemPath, Dev, Drv, Start, Cnt, FsType)	MachVtbl.DiskGetSystemVolume((SysPath), (RemPath), (Dev), (Drv), (Start), (Cnt), (FsType))
 #define MachDiskGetBootPath(Path, Size)		MachVtbl.DiskGetBootPath((Path), (Size))

Modified: trunk/reactos/boot/freeldr/freeldr/include/mm.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/include/mm.h?rev=40710&r1=40709&r2=40710&view=diff
==============================================================================
--- trunk/reactos/boot/freeldr/freeldr/include/mm.h [iso-8859-1] (original)
+++ trunk/reactos/boot/freeldr/freeldr/include/mm.h [iso-8859-1] Mon Apr 27 00:22:16 2009
@@ -88,21 +88,18 @@
 extern	ULONG		LastFreePageHint;
 
 #ifdef DBG
-PUCHAR	MmGetSystemMemoryMapTypeString(ULONG Type);
+PCSTR MmGetSystemMemoryMapTypeString(MEMORY_TYPE Type);
 #endif
 
 ULONG		MmGetPageNumberFromAddress(PVOID Address);	// Returns the page number that contains a linear address
-PVOID	MmGetEndAddressOfAnyMemory(PBIOS_MEMORY_MAP BiosMemoryMap, ULONG MapCount);	// Returns the last address of memory from the memory map
-ULONG		MmGetAddressablePageCountIncludingHoles(PBIOS_MEMORY_MAP BiosMemoryMap, ULONG MapCount);	// Returns the count of addressable pages from address zero including any memory holes and reserved memory regions
-PVOID	MmFindLocationForPageLookupTable(PBIOS_MEMORY_MAP BiosMemoryMap, ULONG MapCount);	// Returns the address for a memory chunk big enough to hold the page lookup table (starts search from end of memory)
-VOID	MmSortBiosMemoryMap(PBIOS_MEMORY_MAP BiosMemoryMap, ULONG MapCount);	// Sorts the BIOS_MEMORY_MAP array so the first element corresponds to the first address in memory
-VOID	MmInitPageLookupTable(PVOID PageLookupTable, ULONG TotalPageCount, PBIOS_MEMORY_MAP BiosMemoryMap, ULONG MapCount);	// Inits the page lookup table according to the memory types in the memory map
+ULONG		MmGetAddressablePageCountIncludingHoles(VOID);	// Returns the count of addressable pages from address zero including any memory holes and reserved memory regions
+PVOID	MmFindLocationForPageLookupTable(ULONG TotalPageCount);	// Returns the address for a memory chunk big enough to hold the page lookup table (starts search from end of memory)
+VOID	MmInitPageLookupTable(PVOID PageLookupTable, ULONG TotalPageCount);	// Inits the page lookup table according to the memory types in the memory map
 VOID	MmMarkPagesInLookupTable(PVOID PageLookupTable, ULONG StartPage, ULONG PageCount, TYPE_OF_MEMORY PageAllocated);	// Marks the specified pages as allocated or free in the lookup table
 VOID	MmAllocatePagesInLookupTable(PVOID PageLookupTable, ULONG StartPage, ULONG PageCount, TYPE_OF_MEMORY MemoryType);	// Allocates the specified pages in the lookup table
 ULONG		MmCountFreePagesInLookupTable(PVOID PageLookupTable, ULONG TotalPageCount);	// Returns the number of free pages in the lookup table
 ULONG		MmFindAvailablePages(PVOID PageLookupTable, ULONG TotalPageCount, ULONG PagesNeeded, BOOLEAN FromEnd);	// Returns the page number of the first available page range from the beginning or end of memory
 ULONG		MmFindAvailablePagesBeforePage(PVOID PageLookupTable, ULONG TotalPageCount, ULONG PagesNeeded, ULONG LastPage);	// Returns the page number of the first available page range before the specified page
-VOID	MmFixupSystemMemoryMap(PBIOS_MEMORY_MAP BiosMemoryMap, ULONG* MapCount);	// Removes entries in the memory map that describe memory above 4G
 VOID	MmUpdateLastFreePageHint(PVOID PageLookupTable, ULONG TotalPageCount);	// Sets the LastFreePageHint to the last usable page of memory
 BOOLEAN	MmAreMemoryPagesAvailable(PVOID PageLookupTable, ULONG TotalPageCount, PVOID PageAddress, ULONG PageCount);	// Returns TRUE if the specified pages of memory are available, otherwise FALSE
 VOID	MmSetMemoryType(PVOID MemoryAddress, ULONG MemorySize, TYPE_OF_MEMORY NewType); // Use with EXTREME caution!

Modified: trunk/reactos/boot/freeldr/freeldr/machine.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/machine.c?rev=40710&r1=40709&r2=40710&view=diff
==============================================================================
--- trunk/reactos/boot/freeldr/freeldr/machine.c [iso-8859-1] (original)
+++ trunk/reactos/boot/freeldr/freeldr/machine.c [iso-8859-1] Mon Apr 27 00:22:16 2009
@@ -36,7 +36,6 @@
 #undef MachVideoSync
 #undef MachBeep
 #undef MachPrepareForReactOS
-#undef MachGetMemoryMap
 #undef MachDiskGetBootVolume
 #undef MachDiskGetSystemVolume
 #undef MachDiskGetBootPath
@@ -153,10 +152,176 @@
   MachVtbl.PrepareForReactOS(Setup);
 }
 
-ULONG
-MachGetMemoryMap(PBIOS_MEMORY_MAP BiosMemoryMap, ULONG MaxMemoryMapSize)
-{
-  return MachVtbl.GetMemoryMap(BiosMemoryMap, MaxMemoryMapSize);
+typedef struct
+{
+    MEMORY_DESCRIPTOR m;
+    ULONG Index;
+    BOOLEAN GeneratedDescriptor;
+} MEMORY_DESCRIPTOR_INT;
+static const MEMORY_DESCRIPTOR_INT MemoryDescriptors[] =
+{
+#if defined (__i386__) || defined (_M_AMD64)
+    { { MemoryFirmwarePermanent, 0x00, 1 }, 0, }, // realmode int vectors
+    { { MemoryFirmwareTemporary, 0x01, 7 }, 1, }, // freeldr stack + cmdline
+    { { MemoryLoadedProgram, 0x08, 0x70 }, 2, }, // freeldr image (roughly max. 0x64 pages)
+    { { MemorySpecialMemory, 0x78, 8 }, 3, }, // prot mode stack. BIOSCALLBUFFER
+    { { MemoryFirmwareTemporary, 0x80, 0x10 }, 4, }, // File system read buffer. FILESYSBUFFER
+    { { MemoryFirmwareTemporary, 0x90, 0x10 }, 5, }, // Disk read buffer for int 13h. DISKREADBUFFER
+    { { MemoryFirmwarePermanent, 0xA0, 0x60 }, 6, }, // ROM / Video
+    { { MemorySpecialMemory, 0xFFF, 1 }, 7, }, // unusable memory
+#elif __arm__
+    { { MemoryFirmwarePermanent, 0x00, 1 }, 0, }, // arm exception handlers
+    { { MemoryFirmwareTemporary, 0x01, 7 }, 1, }, // arm board block + freeldr stack + cmdline
+    { { MemoryLoadedProgram, 0x08, 0x70 }, 2, }, // freeldr image (roughly max. 0x64 pages)
+#endif
+};
+MEMORY_DESCRIPTOR*
+ArcGetMemoryDescriptor(MEMORY_DESCRIPTOR* Current)
+{
+    MEMORY_DESCRIPTOR_INT* CurrentDescriptor;
+    BIOS_MEMORY_MAP BiosMemoryMap[32];
+    static ULONG BiosMemoryMapEntryCount;
+    static MEMORY_DESCRIPTOR_INT BiosMemoryDescriptors[32];
+    static BOOLEAN MemoryMapInitialized = FALSE;
+    ULONG i, j;
+
+    //
+    // Does machine provide an override for this function?
+    //
+    if (MachVtbl.GetMemoryDescriptor)
+    {
+        //
+        // Yes. Use it instead
+        //
+        return MachVtbl.GetMemoryDescriptor(Current);
+    }
+
+    //
+    // Check if it is the first time we're called
+    //
+    if (!MemoryMapInitialized)
+    {
+        //
+        // Get the machine generated memory map
+        //
+        RtlZeroMemory(BiosMemoryMap, sizeof(BIOS_MEMORY_MAP) * 32);
+        BiosMemoryMapEntryCount = MachVtbl.GetMemoryMap(BiosMemoryMap,
+            sizeof(BiosMemoryMap) / sizeof(BIOS_MEMORY_MAP));
+
+        //
+        // Copy the entries to our structure
+        //
+        for (i = 0, j = 0; i < BiosMemoryMapEntryCount; i++)
+        {
+            //
+            // Is it suitable memory?
+            //
+            if (BiosMemoryMap[i].Type != BiosMemoryUsable)
+            {
+                //
+                // No. Process next descriptor
+                //
+                continue;
+            }
+
+            //
+            // Copy this memory descriptor
+            //
+            BiosMemoryDescriptors[j].m.MemoryType = MemoryFree;
+            BiosMemoryDescriptors[j].m.BasePage = BiosMemoryMap[i].BaseAddress / MM_PAGE_SIZE;
+            BiosMemoryDescriptors[j].m.PageCount = BiosMemoryMap[i].Length / MM_PAGE_SIZE;
+            BiosMemoryDescriptors[j].Index = j;
+            BiosMemoryDescriptors[j].GeneratedDescriptor = TRUE;
+            j++;
+        }
+
+        //
+        // Remember how much descriptors we found
+        //
+        BiosMemoryMapEntryCount = j;
+
+        //
+        // Mark memory map as already retrieved and initialized
+        //
+        MemoryMapInitialized = TRUE;
+    }
+
+    CurrentDescriptor = CONTAINING_RECORD(Current, MEMORY_DESCRIPTOR_INT, m);
+
+    if (Current == NULL)
+    {
+        //
+        // First descriptor requested
+        //
+        if (BiosMemoryMapEntryCount > 0)
+        {
+            //
+            // Return first generated memory descriptor
+            //
+            return &BiosMemoryDescriptors[0].m;
+        }
+        else if (sizeof(MemoryDescriptors) > 0)
+        {
+            //
+            // Return first fixed memory descriptor
+            //
+            return (MEMORY_DESCRIPTOR*)&MemoryDescriptors[0].m;
+        }
+        else
+        {
+            //
+            // Strange case, we have no memory descriptor
+            //
+            return NULL;
+        }
+    }
+    else if (CurrentDescriptor->GeneratedDescriptor)
+    {
+        //
+        // Current entry is a generated descriptor
+        //
+        if (CurrentDescriptor->Index + 1 < BiosMemoryMapEntryCount)
+        {
+            //
+            // Return next generated descriptor
+            //
+            return &BiosMemoryDescriptors[CurrentDescriptor->Index + 1].m;
+        }
+        else if (sizeof(MemoryDescriptors) > 0)
+        {
+            //
+            // Return first fixed memory descriptor
+            //
+            return (MEMORY_DESCRIPTOR*)&MemoryDescriptors[0].m;
+        }
+        else
+        {
+            //
+            // No fixed memory descriptor; end of memory map
+            //
+            return NULL;
+        }
+    }
+    else
+    {
+        //
+        // Current entry is a fixed descriptor
+        //
+        if (CurrentDescriptor->Index + 1 < sizeof(MemoryDescriptors) / sizeof(MemoryDescriptors[0]))
+        {
+            //
+            // Return next fixed descriptor
+            //
+            return (MEMORY_DESCRIPTOR*)&MemoryDescriptors[CurrentDescriptor->Index + 1].m;
+        }
+        else
+        {
+            //
+            // No more fixed memory descriptor; end of memory map
+            //
+            return NULL;
+        }
+    }
 }
 
 BOOLEAN

Modified: trunk/reactos/boot/freeldr/freeldr/mm/meminit.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/mm/meminit.c?rev=40710&r1=40709&r2=40710&view=diff
==============================================================================
--- trunk/reactos/boot/freeldr/freeldr/mm/meminit.c [iso-8859-1] (original)
+++ trunk/reactos/boot/freeldr/freeldr/mm/meminit.c [iso-8859-1] Mon Apr 27 00:22:16 2009
@@ -1,6 +1,7 @@
 /*
  *  FreeLoader
  *  Copyright (C) 2006-2008     Aleksey Bragin  <aleksey at reactos.org>
+ *  Copyright (C) 2006-2009     Hervé Poussineau  <hpoussin at reactos.org>
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -23,19 +24,24 @@
 #ifdef DBG
 typedef struct
 {
-	ULONG		Type;
-	UCHAR	TypeString[20];
+    MEMORY_TYPE Type;
+    PCSTR TypeString;
 } FREELDR_MEMORY_TYPE, *PFREELDR_MEMORY_TYPE;
 
-ULONG				MemoryTypeCount = 5;
-FREELDR_MEMORY_TYPE		MemoryTypeArray[] =
-{
-	{ 0, "Unknown Memory" },
-	{ BiosMemoryUsable, "Usable Memory" },
-	{ BiosMemoryReserved, "Reserved Memory" },
-	{ BiosMemoryAcpiReclaim, "ACPI Reclaim Memory" },
-	{ BiosMemoryAcpiNvs, "ACPI NVS Memory" },
+FREELDR_MEMORY_TYPE MemoryTypeArray[] =
+{
+    { MemoryMaximum, "Unknown memory" },
+    { MemoryExceptionBlock, "Exception block" },
+    { MemorySystemBlock, "System block" },
+    { MemoryFree, "Free memory" },
+    { MemoryBad, "Bad memory" },
+    { MemoryLoadedProgram, "Loaded program" },
+    { MemoryFirmwareTemporary, "Firmware temporary" },
+    { MemoryFirmwarePermanent, "Firmware permanent" },
+    { MemoryFreeContiguous, "Free contiguous memory" },
+    { MemorySpecialMemory, "Special memory" },
 };
+ULONG MemoryTypeCount = sizeof(MemoryTypeArray) / sizeof(MemoryTypeArray[0]);
 #endif
 
 PVOID	PageLookupTableAddress = NULL;
@@ -48,39 +54,27 @@
 
 BOOLEAN MmInitializeMemoryManager(VOID)
 {
-	BIOS_MEMORY_MAP	BiosMemoryMap[32];
-	ULONG		BiosMemoryMapEntryCount;
 #ifdef DBG
-	ULONG		Index;
+	MEMORY_DESCRIPTOR* MemoryDescriptor = NULL;
 #endif
 
 	DPRINTM(DPRINT_MEMORY, "Initializing Memory Manager.\n");
-
-	RtlZeroMemory(BiosMemoryMap, sizeof(BIOS_MEMORY_MAP) * 32);
-
-	BiosMemoryMapEntryCount = MachGetMemoryMap(BiosMemoryMap, sizeof(BiosMemoryMap) / sizeof(BIOS_MEMORY_MAP));
 
 #ifdef DBG
 	// Dump the system memory map
-	if (BiosMemoryMapEntryCount != 0)
-	{
-		DPRINTM(DPRINT_MEMORY, "System Memory Map (Base Address, Length, Type):\n");
-		for (Index=0; Index<BiosMemoryMapEntryCount; Index++)
-		{
-			DPRINTM(DPRINT_MEMORY, "%x%x\t %x%x\t %s\n", BiosMemoryMap[Index].BaseAddress, BiosMemoryMap[Index].Length, MmGetSystemMemoryMapTypeString(BiosMemoryMap[Index].Type));
-		}
+	DPRINTM(DPRINT_MEMORY, "System Memory Map (Base Address, Length, Type):\n");
+	while ((MemoryDescriptor = ArcGetMemoryDescriptor(MemoryDescriptor)) != NULL)
+	{
+		DPRINTM(DPRINT_MEMORY, "%x\t %x\t %s\n",
+			MemoryDescriptor->BasePage * MM_PAGE_SIZE,
+			MemoryDescriptor->PageCount * MM_PAGE_SIZE,
+			MmGetSystemMemoryMapTypeString(MemoryDescriptor->MemoryType));
 	}
 #endif
 
-	// If we got the system memory map then fixup invalid entries
-	if (BiosMemoryMapEntryCount != 0)
-	{
-		MmFixupSystemMemoryMap(BiosMemoryMap, &BiosMemoryMapEntryCount);
-	}
-
 	// Find address for the page lookup table
-	TotalPagesInLookupTable = MmGetAddressablePageCountIncludingHoles(BiosMemoryMap, BiosMemoryMapEntryCount);
-	PageLookupTableAddress = MmFindLocationForPageLookupTable(BiosMemoryMap, BiosMemoryMapEntryCount);
+	TotalPagesInLookupTable = MmGetAddressablePageCountIncludingHoles();
+	PageLookupTableAddress = MmFindLocationForPageLookupTable(TotalPagesInLookupTable);
 	LastFreePageHint = TotalPagesInLookupTable;
 
 	if (PageLookupTableAddress == 0)
@@ -93,24 +87,8 @@
 	}
 
 	// Initialize the page lookup table
-	MmInitPageLookupTable(PageLookupTableAddress, TotalPagesInLookupTable, BiosMemoryMap, BiosMemoryMapEntryCount);
+	MmInitPageLookupTable(PageLookupTableAddress, TotalPagesInLookupTable);
 	MmUpdateLastFreePageHint(PageLookupTableAddress, TotalPagesInLookupTable);
-
-	// Add machine-dependent stuff
-#if defined (__i386__) || defined (_M_AMD64)
-	MmMarkPagesInLookupTable(PageLookupTableAddress, 0x00, 1, LoaderFirmwarePermanent); // realmode int vectors
-	MmMarkPagesInLookupTable(PageLookupTableAddress, 0x01, 7, LoaderFirmwareTemporary); // freeldr stack + cmdline
-	MmMarkPagesInLookupTable(PageLookupTableAddress, 0x08, 0x70, LoaderLoadedProgram); // freeldr image (roughly max. 0x64 pages)
-	MmMarkPagesInLookupTable(PageLookupTableAddress, 0x78, 8, LoaderOsloaderStack); // prot mode stack. BIOSCALLBUFFER
-	MmMarkPagesInLookupTable(PageLookupTableAddress, 0x80, 0x10, LoaderOsloaderHeap); // File system read buffer. FILESYSBUFFER
-	MmMarkPagesInLookupTable(PageLookupTableAddress, 0x90, 0x10, LoaderOsloaderHeap); // Disk read buffer for int 13h. DISKREADBUFFER
-	MmMarkPagesInLookupTable(PageLookupTableAddress, 0xA0, 0x60, LoaderFirmwarePermanent); // ROM / Video
-	MmMarkPagesInLookupTable(PageLookupTableAddress, 0xFFF, 1, LoaderSpecialMemory); // unusable memory
-#elif __arm__
-	MmMarkPagesInLookupTable(PageLookupTableAddress, 0x00, 1, LoaderFirmwarePermanent); // arm exception handlers
-	MmMarkPagesInLookupTable(PageLookupTableAddress, 0x01, 7, LoaderFirmwareTemporary); // arm board block + freeldr stack + cmdline
-	MmMarkPagesInLookupTable(PageLookupTableAddress, 0x08, 0x70, LoaderLoadedProgram); // freeldr image (roughly max. 0x64 pages)
-#endif
 
 	FreePagesInLookupTable = MmCountFreePagesInLookupTable(PageLookupTableAddress, TotalPagesInLookupTable);
 
@@ -151,7 +129,7 @@
 }
 
 #ifdef DBG
-PUCHAR MmGetSystemMemoryMapTypeString(ULONG Type)
+PCSTR MmGetSystemMemoryMapTypeString(MEMORY_TYPE Type)
 {
 	ULONG		Index;
 
@@ -172,165 +150,157 @@
 	return ((ULONG_PTR)Address) / MM_PAGE_SIZE;
 }
 
-PVOID MmGetEndAddressOfAnyMemory(PBIOS_MEMORY_MAP BiosMemoryMap, ULONG MapCount)
-{
-	ULONGLONG		MaxStartAddressSoFar;
-	ULONGLONG		EndAddressOfMemory;
-	ULONG		Index;
-
-	MaxStartAddressSoFar = 0;
-	EndAddressOfMemory = 0;
-	for (Index=0; Index<MapCount; Index++)
-	{
-		if (MaxStartAddressSoFar <= BiosMemoryMap[Index].BaseAddress)
-		{
-			MaxStartAddressSoFar = BiosMemoryMap[Index].BaseAddress;
-			EndAddressOfMemory = (MaxStartAddressSoFar + BiosMemoryMap[Index].Length);
-			if (EndAddressOfMemory > 0xFFFFFFFF)
-			{
-				EndAddressOfMemory = 0xFFFFFFFF;
-			}
-		}
-	}
-
-	DPRINTM(DPRINT_MEMORY, "MmGetEndAddressOfAnyMemory() returning 0x%x\n", (ULONG)EndAddressOfMemory);
-
-	return (PVOID)(ULONG_PTR)EndAddressOfMemory;
-}
-
-ULONG MmGetAddressablePageCountIncludingHoles(PBIOS_MEMORY_MAP BiosMemoryMap, ULONG MapCount)
-{
-	ULONG		PageCount;
-	ULONGLONG		EndAddress;
-
-	EndAddress = (ULONGLONG)(ULONG_PTR)MmGetEndAddressOfAnyMemory(BiosMemoryMap, MapCount);
-
-	// Since MmGetEndAddressOfAnyMemory() won't
-	// return addresses higher than 0xFFFFFFFF
-	// then we need to adjust the end address
-	// to 0x100000000 so we don't get an
-	// off-by-one error
-	if (EndAddress >= 0xFFFFFFFF)
-	{
-		EndAddress = 0x100000000LL;
-
-		DPRINTM(DPRINT_MEMORY, "MmGetEndAddressOfAnyMemory() returned 0xFFFFFFFF, correcting to be 0x100000000.\n");
-	}
-
-	PageCount = (EndAddress / MM_PAGE_SIZE);
-
-	DPRINTM(DPRINT_MEMORY, "MmGetAddressablePageCountIncludingHoles() returning %d\n", PageCount);
-
-	return PageCount;
-}
-
-PVOID MmFindLocationForPageLookupTable(PBIOS_MEMORY_MAP BiosMemoryMap, ULONG MapCount)
-{
-	ULONG					TotalPageCount;
-	ULONG					PageLookupTableSize;
-	PVOID				PageLookupTableMemAddress;
-	int					Index;
-	BIOS_MEMORY_MAP		TempBiosMemoryMap[32];
-
-	TotalPageCount = MmGetAddressablePageCountIncludingHoles(BiosMemoryMap, MapCount);
-	PageLookupTableSize = TotalPageCount * sizeof(PAGE_LOOKUP_TABLE_ITEM);
-	PageLookupTableMemAddress = 0;
-
-	RtlCopyMemory(TempBiosMemoryMap, BiosMemoryMap, sizeof(BIOS_MEMORY_MAP) * 32);
-	MmSortBiosMemoryMap(TempBiosMemoryMap, MapCount);
-
-	// Find a place, starting from the highest memory
-	// (thus leaving low memory for kernel/drivers)
-	for (Index=(MapCount-1); Index>=0; Index--)
-	{
-		// If this is usable memory with a big enough length
-		// then we'll put our page lookup table here
-
-		// skip if this is not usable region
-		if (TempBiosMemoryMap[Index].Type != BiosMemoryUsable)
-			continue;
-
-		if (TempBiosMemoryMap[Index].Length >= PageLookupTableSize)
-		{
-			PageLookupTableMemAddress = (PVOID)(ULONG_PTR)
-				(TempBiosMemoryMap[Index].BaseAddress + (TempBiosMemoryMap[Index].Length - PageLookupTableSize));
-			break;
-		}
-	}
-
-	DPRINTM(DPRINT_MEMORY, "MmFindLocationForPageLookupTable() returning 0x%x\n", PageLookupTableMemAddress);
-
-	return PageLookupTableMemAddress;
-}
-
-VOID MmSortBiosMemoryMap(PBIOS_MEMORY_MAP BiosMemoryMap, ULONG MapCount)
-{
-	ULONG					Index;
-	ULONG					LoopCount;
-	BIOS_MEMORY_MAP		TempMapItem;
-
-	// Loop once for each entry in the memory map minus one
-	// On each loop iteration go through and sort the memory map
-	for (LoopCount=0; LoopCount<(MapCount-1); LoopCount++)
-	{
-		for (Index=0; Index<(MapCount-1); Index++)
-		{
-			if (BiosMemoryMap[Index].BaseAddress > BiosMemoryMap[Index+1].BaseAddress)
-			{
-				TempMapItem = BiosMemoryMap[Index];
-				BiosMemoryMap[Index] = BiosMemoryMap[Index+1];
-				BiosMemoryMap[Index+1] = TempMapItem;
-			}
-		}
-	}
-}
-
-VOID MmInitPageLookupTable(PVOID PageLookupTable, ULONG TotalPageCount, PBIOS_MEMORY_MAP BiosMemoryMap, ULONG MapCount)
-{
-	ULONG		MemoryMapStartPage;
-	ULONG		MemoryMapEndPage;
-	ULONG		MemoryMapPageCount;
-	ULONG		MemoryMapPageAllocated;
-	ULONG		PageLookupTableStartPage;
-	ULONG		PageLookupTablePageCount;
-	ULONG		Index;
-
-	DPRINTM(DPRINT_MEMORY, "MmInitPageLookupTable()\n");
-
-	// Mark every page as allocated initially
-	// We will go through and mark pages again according to the memory map
-	// But this will mark any holes not described in the map as allocated
-	MmMarkPagesInLookupTable(PageLookupTable, 0, TotalPageCount, LoaderFirmwarePermanent);
-
-	for (Index=0; Index<MapCount; Index++)
-	{
-		MemoryMapStartPage = MmGetPageNumberFromAddress((PVOID)(ULONG_PTR)BiosMemoryMap[Index].BaseAddress);
-		MemoryMapEndPage = MmGetPageNumberFromAddress((PVOID)(ULONG_PTR)(BiosMemoryMap[Index].BaseAddress + BiosMemoryMap[Index].Length - 1));
-		MemoryMapPageCount = (MemoryMapEndPage - MemoryMapStartPage) + 1;
-
-		switch (BiosMemoryMap[Index].Type)
-		{
-			case BiosMemoryUsable:
-				MemoryMapPageAllocated = LoaderFree;
-				break;
-
-			case BiosMemoryAcpiReclaim:
-			case BiosMemoryAcpiNvs:
-				MemoryMapPageAllocated = LoaderSpecialMemory;
-				break;
-
-			default:
-				MemoryMapPageAllocated = LoaderSpecialMemory;
-		}
-		DPRINTM(DPRINT_MEMORY, "Marking pages as type %d: StartPage: %d PageCount: %d\n", MemoryMapPageAllocated, MemoryMapStartPage, MemoryMapPageCount);
-		MmMarkPagesInLookupTable(PageLookupTable, MemoryMapStartPage, MemoryMapPageCount, MemoryMapPageAllocated);
-	}
-
-	// Mark the pages that the lookup table occupies as reserved
-	PageLookupTableStartPage = MmGetPageNumberFromAddress(PageLookupTable);
-	PageLookupTablePageCount = MmGetPageNumberFromAddress((PVOID)((ULONG_PTR)PageLookupTable + ROUND_UP(TotalPageCount * sizeof(PAGE_LOOKUP_TABLE_ITEM), MM_PAGE_SIZE))) - PageLookupTableStartPage;
-	DPRINTM(DPRINT_MEMORY, "Marking the page lookup table pages as reserved StartPage: %d PageCount: %d\n", PageLookupTableStartPage, PageLookupTablePageCount);
-	MmMarkPagesInLookupTable(PageLookupTable, PageLookupTableStartPage, PageLookupTablePageCount, LoaderFirmwareTemporary);
+ULONG MmGetAddressablePageCountIncludingHoles(VOID)
+{
+    MEMORY_DESCRIPTOR* MemoryDescriptor = NULL;
+    ULONG EndPage = 0;
+
+    //
+    // Go through the whole memory map to get max address
+    //
+    while ((MemoryDescriptor = ArcGetMemoryDescriptor(MemoryDescriptor)) != NULL)
+    {
+        //
+        // Check if we got a higher end page address
+        //
+        if (MemoryDescriptor->BasePage + MemoryDescriptor->PageCount > EndPage)
+        {
+            //
+            // Yes, remember it
+            //
+            EndPage = MemoryDescriptor->BasePage + MemoryDescriptor->PageCount;
+        }
+    }
+
+    DPRINTM(DPRINT_MEMORY, "MmGetAddressablePageCountIncludingHoles() returning 0x%x\n", EndPage);
+
+    return EndPage;
+}
+
+PVOID MmFindLocationForPageLookupTable(ULONG TotalPageCount)
+{
+    MEMORY_DESCRIPTOR* MemoryDescriptor = NULL;
+    ULONG PageLookupTableSize;
+    ULONG PageLookupTablePages;
+    ULONG PageLookupTableStartPage = 0;
+    PVOID PageLookupTableMemAddress = NULL;
+
+    //
+    // Calculate how much pages we need to keep the page lookup table
+    //
+    PageLookupTableSize = TotalPageCount * sizeof(PAGE_LOOKUP_TABLE_ITEM);
+    PageLookupTablePages = PageLookupTableSize / MM_PAGE_SIZE;
+
+    //
+    // Search the highest memory block big enough to contain lookup table
+    //
+    while ((MemoryDescriptor = ArcGetMemoryDescriptor(MemoryDescriptor)) != NULL)
+    {
+        //
+        // Is it suitable memory?
+        //
+        if (MemoryDescriptor->MemoryType != MemoryFree)
+        {
+            //
+            // No. Process next descriptor
+            //
+            continue;
+        }
+
+        //
+        // Is the block big enough?
+        //
+        if (MemoryDescriptor->PageCount < PageLookupTablePages)
+        {
+            //
+            // No. Process next descriptor
+            //
+            continue;
+        }
+
+        //
+        // Is it at a higher address than previous suitable address?
+        //
+        if (MemoryDescriptor->BasePage < PageLookupTableStartPage)
+        {
+            //
+            // No. Process next descriptor
+            //
+            continue;
+        }
+
+        //
+        // Memory block is more suitable than the previous one
+        //
+        PageLookupTableStartPage = MemoryDescriptor->BasePage;
+        PageLookupTableMemAddress = (PVOID)((ULONG_PTR)
+            (MemoryDescriptor->BasePage + MemoryDescriptor->PageCount) * MM_PAGE_SIZE
+            - PageLookupTableSize);
+    }
+
+    DPRINTM(DPRINT_MEMORY, "MmFindLocationForPageLookupTable() returning 0x%x\n", PageLookupTableMemAddress);
+
+    return PageLookupTableMemAddress;
+}
+
+VOID MmInitPageLookupTable(PVOID PageLookupTable, ULONG TotalPageCount)
+{
+    MEMORY_DESCRIPTOR* MemoryDescriptor = NULL;
+    TYPE_OF_MEMORY MemoryMapPageAllocated;
+    ULONG PageLookupTableStartPage;
+    ULONG PageLookupTablePageCount;
+
+    DPRINTM(DPRINT_MEMORY, "MmInitPageLookupTable()\n");
+
+    //
+    // Mark every page as allocated initially
+    // We will go through and mark pages again according to the memory map
+    // But this will mark any holes not described in the map as allocated
+    //
+    MmMarkPagesInLookupTable(PageLookupTable, 0, TotalPageCount, LoaderFirmwarePermanent);
+
+    //
+    // Parse the whole memory map
+    //
+    while ((MemoryDescriptor = ArcGetMemoryDescriptor(MemoryDescriptor)) != NULL)
+    {
+        //
+        // Convert ARC memory type to loader memory type
+        //
+        switch (MemoryDescriptor->MemoryType)
+        {
+            case MemoryFree:
+            {
+                //
+                // Allocatable memory
+                //
+                MemoryMapPageAllocated = LoaderFree;
+                break;
+            }
+            default:
+            {
+                //
+                // Put something sensible here, which won't be overwritten
+                //
+                MemoryMapPageAllocated = LoaderSpecialMemory;
+                break;
+            }
+        }
+
+        //
+        // Mark used pages in the lookup table
+        //
+        DPRINTM(DPRINT_MEMORY, "Marking pages as type %d: StartPage: %d PageCount: %d\n", MemoryMapPageAllocated, MemoryDescriptor->BasePage, MemoryDescriptor->PageCount);
+        MmMarkPagesInLookupTable(PageLookupTable, MemoryDescriptor->BasePage, MemoryDescriptor->PageCount, MemoryMapPageAllocated);
+    }
+
+    //
+    // Mark the pages that the lookup table occupies as reserved
+    //
+    PageLookupTableStartPage = MmGetPageNumberFromAddress(PageLookupTable);
+    PageLookupTablePageCount = MmGetPageNumberFromAddress((PVOID)((ULONG_PTR)PageLookupTable + ROUND_UP(TotalPageCount * sizeof(PAGE_LOOKUP_TABLE_ITEM), MM_PAGE_SIZE))) - PageLookupTableStartPage;
+    DPRINTM(DPRINT_MEMORY, "Marking the page lookup table pages as reserved StartPage: %d PageCount: %d\n", PageLookupTableStartPage, PageLookupTablePageCount);
+    MmMarkPagesInLookupTable(PageLookupTable, PageLookupTableStartPage, PageLookupTablePageCount, LoaderFirmwareTemporary);
 }
 
 VOID MmMarkPagesInLookupTable(PVOID PageLookupTable, ULONG StartPage, ULONG PageCount, TYPE_OF_MEMORY PageAllocated)
@@ -474,30 +444,6 @@
 	return 0;
 }
 
-VOID MmFixupSystemMemoryMap(PBIOS_MEMORY_MAP BiosMemoryMap, ULONG* MapCount)
-{
-	UINT32		Index;
-	UINT32		Index2;
-
-	// Loop through each entry in the array
-	for (Index=0; Index<*MapCount; Index++)
-	{
-		// If the entry type isn't usable then remove
-		// it from the memory map (this will help reduce
-		// the size of our lookup table)
-		if (BiosMemoryMap[Index].Type != BiosMemoryUsable)
-		{
-			// Slide every entry after this down one
-			for (Index2=Index; Index2<(*MapCount - 1); Index2++)
-			{
-				BiosMemoryMap[Index2] = BiosMemoryMap[Index2 + 1];
-			}
-			(*MapCount)--;
-			Index--;
-		}
-	}
-}
-
 VOID MmUpdateLastFreePageHint(PVOID PageLookupTable, ULONG TotalPageCount)
 {
 	PPAGE_LOOKUP_TABLE_ITEM		RealPageLookupTable = (PPAGE_LOOKUP_TABLE_ITEM)PageLookupTable;

Modified: trunk/reactos/boot/freeldr/freeldr/reactos/reactos.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/reactos/reactos.c?rev=40710&r1=40709&r2=40710&view=diff
==============================================================================
--- trunk/reactos/boot/freeldr/freeldr/reactos/reactos.c [iso-8859-1] (original)
+++ trunk/reactos/boot/freeldr/freeldr/reactos/reactos.c [iso-8859-1] Mon Apr 27 00:22:16 2009
@@ -642,7 +642,7 @@
     LoaderBlock.DrivesAddr = reactos_arc_disk_info;
     LoaderBlock.RdAddr = (ULONG_PTR)gRamDiskBase;
     LoaderBlock.RdLength = gRamDiskSize;
-    LoaderBlock.MmapLength = (SIZE_T)MachGetMemoryMap((PBIOS_MEMORY_MAP)reactos_memory_map, 32) * sizeof(memory_map_t);
+    LoaderBlock.MmapLength = (SIZE_T)MachVtbl.GetMemoryMap((PBIOS_MEMORY_MAP)reactos_memory_map, 32) * sizeof(memory_map_t);
     if (LoaderBlock.MmapLength)
     {
         ULONG i;

Modified: trunk/reactos/boot/freeldr/freeldr/reactos/setupldr.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/reactos/setupldr.c?rev=40710&r1=40709&r2=40710&view=diff
==============================================================================
--- trunk/reactos/boot/freeldr/freeldr/reactos/setupldr.c [iso-8859-1] (original)
+++ trunk/reactos/boot/freeldr/freeldr/reactos/setupldr.c [iso-8859-1] Mon Apr 27 00:22:16 2009
@@ -72,7 +72,7 @@
   LoaderBlock.PageDirectoryEnd = (ULONG_PTR)&PageDirectoryEnd;
   LoaderBlock.ModsCount = 0;
   LoaderBlock.ModsAddr = reactos_modules;
-  LoaderBlock.MmapLength = (unsigned long)MachGetMemoryMap((PBIOS_MEMORY_MAP)reactos_memory_map, 32) * sizeof(memory_map_t);
+  LoaderBlock.MmapLength = (unsigned long)MachVtbl.GetMemoryMap((PBIOS_MEMORY_MAP)reactos_memory_map, 32) * sizeof(memory_map_t);
   if (LoaderBlock.MmapLength)
   {
 #if defined (_M_IX86) || defined (_M_AMD64)

Modified: trunk/reactos/boot/freeldr/freeldr/windows/peloader.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/freeldr/freeldr/windows/peloader.c?rev=40710&r1=40709&r2=40710&view=diff
==============================================================================
--- trunk/reactos/boot/freeldr/freeldr/windows/peloader.c [iso-8859-1] (original)
+++ trunk/reactos/boot/freeldr/freeldr/windows/peloader.c [iso-8859-1] Mon Apr 27 00:22:16 2009
@@ -269,7 +269,7 @@
 	CHAR ProgressString[256];
 
 	/* Inform user we are loading files */
-	sprintf(ProgressString, "Loading %s...", FileName);
+	sprintf(ProgressString, "Loading %s...", strchr(FileName, '\\') + 1);
 	UiDrawProgressBarCenter(1, 100, ProgressString);
 
 	/* Open the image file */



More information about the Ros-diffs mailing list