Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenramdisk.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
1.7.6.1
|