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

ramdisk.c
Go to the documentation of this file.
00001 /*
00002  * PROJECT:         ReactOS Boot Loader
00003  * LICENSE:         BSD - See COPYING.ARM in the top level directory
00004  * FILE:            boot/freeldr/freeldr/disk/ramdisk.c
00005  * PURPOSE:         Implements routines to support booting from a RAM Disk
00006  * PROGRAMMERS:     ReactOS Portable Systems Group
00007  *                  Hervé Poussineau
00008  */
00009 
00010 /* INCLUDES *******************************************************************/
00011 
00012 #include <freeldr.h>
00013 #define NDEBUG
00014 #include <debug.h>
00015 
00016 /* GLOBALS ********************************************************************/
00017 
00018 PVOID gRamDiskBase;
00019 ULONG gRamDiskSize;
00020 ULONG gRamDiskOffset;
00021 
00022 /* FUNCTIONS ******************************************************************/
00023 
00024 static LONG RamDiskClose(ULONG FileId)
00025 {
00026     //
00027     // Nothing to do
00028     //
00029     return ESUCCESS;
00030 }
00031 
00032 static LONG RamDiskGetFileInformation(ULONG FileId, FILEINFORMATION* Information)
00033 {
00034     //
00035     // Give current seek offset and ram disk size to caller
00036     //
00037     RtlZeroMemory(Information, sizeof(FILEINFORMATION));
00038     Information->EndingAddress.LowPart = gRamDiskSize;
00039     Information->CurrentAddress.LowPart = gRamDiskOffset;
00040 
00041     return ESUCCESS;
00042 }
00043 
00044 static LONG RamDiskOpen(CHAR* Path, OPENMODE OpenMode, ULONG* FileId)
00045 {
00046     //
00047     // Always return success, as contents are already in memory
00048     //
00049     return ESUCCESS;
00050 }
00051 
00052 static LONG RamDiskRead(ULONG FileId, VOID* Buffer, ULONG N, ULONG* Count)
00053 {
00054     PVOID StartAddress;
00055 
00056     //
00057     // Get actual pointer
00058     //
00059     StartAddress = (PVOID)((ULONG_PTR)gRamDiskBase + gRamDiskOffset);
00060 
00061     //
00062     // Don't allow reads past our image
00063     //
00064     if (gRamDiskOffset + N > gRamDiskSize)
00065     {
00066         *Count = 0;
00067         return EIO;
00068     }
00069 
00070     //
00071     // Do the read
00072     //
00073     RtlCopyMemory(Buffer, StartAddress, N);
00074     *Count = N;
00075 
00076     return ESUCCESS;
00077 }
00078 
00079 static LONG RamDiskSeek(ULONG FileId, LARGE_INTEGER* Position, SEEKMODE SeekMode)
00080 {
00081     //
00082     // Only accept absolute mode now
00083     //
00084     if (SeekMode != SeekAbsolute)
00085         return EINVAL;
00086 
00087     //
00088     // Check if we're in the ramdisk
00089     //
00090     if (Position->HighPart != 0)
00091         return EINVAL;
00092     if (Position->LowPart >= gRamDiskSize)
00093         return EINVAL;
00094 
00095     //
00096     // OK, remember seek position
00097     //
00098     gRamDiskOffset = Position->LowPart;
00099 
00100     return ESUCCESS;
00101 }
00102 
00103 static const DEVVTBL RamDiskVtbl = {
00104     RamDiskClose,
00105     RamDiskGetFileInformation,
00106     RamDiskOpen,
00107     RamDiskRead,
00108     RamDiskSeek,
00109 };
00110 
00111 VOID
00112 NTAPI
00113 RamDiskInitialize(VOID)
00114 {
00115     /* Setup the RAMDISK device */
00116     FsRegisterDevice("ramdisk(0)", &RamDiskVtbl);
00117 }
00118 
00119 VOID
00120 NTAPI
00121 RamDiskLoadVirtualFile(IN PCHAR FileName)
00122 {
00123     ULONG RamFile;
00124     ULONG TotalRead, ChunkSize, Count;
00125     PCHAR MsgBuffer = "Loading ramdisk...";
00126     ULONG PercentPerChunk, Percent;
00127     FILEINFORMATION Information;
00128     LARGE_INTEGER Position;
00129     LONG ret;
00130 
00131     //
00132     // Display progress
00133     //
00134     UiDrawProgressBarCenter(1, 100, MsgBuffer);
00135 
00136     //
00137     // Try opening the ramdisk file
00138     //
00139     ret = ArcOpen(FileName, OpenReadOnly, &RamFile);
00140     if (ret == ESUCCESS)
00141     {
00142         //
00143         // Get the file size
00144         //
00145         ret = ArcGetFileInformation(RamFile, &Information);
00146         if (ret != ESUCCESS)
00147         {
00148             ArcClose(RamFile);
00149             return;
00150         }
00151 
00152         //
00153         // For now, limit RAM disks to 4GB
00154         //
00155         if (Information.EndingAddress.HighPart != 0)
00156         {
00157             UiMessageBox("RAM disk too big\n");
00158             ArcClose(RamFile);
00159             return;
00160         }
00161         gRamDiskSize = Information.EndingAddress.LowPart;
00162 
00163         //
00164         // Allocate memory for it
00165         //
00166         ChunkSize = 8 * 1024 * 1024;
00167         if (gRamDiskSize < ChunkSize)
00168             Percent = PercentPerChunk = 0;
00169         else
00170             Percent = PercentPerChunk = 100 / (gRamDiskSize / ChunkSize);
00171         gRamDiskBase = MmAllocateMemoryWithType(gRamDiskSize, LoaderXIPRom);
00172         if (!gRamDiskBase)
00173         {
00174             UiMessageBox("Failed to allocate memory for RAM disk\n");
00175             ArcClose(RamFile);
00176             return;
00177         }
00178 
00179         //
00180         // Read it in chunks
00181         //
00182         for (TotalRead = 0; TotalRead < gRamDiskSize; TotalRead += ChunkSize)
00183         {
00184             //
00185             // Check if we're at the last chunk
00186             //
00187             if ((gRamDiskSize - TotalRead) < ChunkSize)
00188             {
00189                 //
00190                 // Only need the actual data required
00191                 //
00192                 ChunkSize = gRamDiskSize - TotalRead;
00193             }
00194 
00195             //
00196             // Draw progress
00197             //
00198             UiDrawProgressBarCenter(Percent, 100, MsgBuffer);
00199             Percent += PercentPerChunk;
00200 
00201             //
00202             // Copy the contents
00203             //
00204             Position.HighPart = 0;
00205             Position.LowPart = TotalRead;
00206             ret = ArcSeek(RamFile, &Position, SeekAbsolute);
00207             if (ret == ESUCCESS)
00208             {
00209                 ret = ArcRead(RamFile,
00210                               (PVOID)((ULONG_PTR)gRamDiskBase + TotalRead),
00211                               ChunkSize,
00212                               &Count);
00213             }
00214 
00215             //
00216             // Check for success
00217             //
00218             if (ret != ESUCCESS || Count != ChunkSize)
00219             {
00220                 MmFreeMemory(gRamDiskBase);
00221                 gRamDiskBase = NULL;
00222                 gRamDiskSize = 0;
00223                 ArcClose(RamFile);
00224                 UiMessageBox("Failed to read ramdisk\n");
00225                 return;
00226             }
00227         }
00228 
00229         ArcClose(RamFile);
00230 
00231         // Register a new device for the ramdisk
00232         FsRegisterDevice("ramdisk(0)", &RamDiskVtbl);
00233     }
00234 }

Generated on Sun May 27 2012 04:19:10 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.