ReactOS  0.4.13-dev-249-gcba1a2f
ramdisk.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS Boot Loader
3  * LICENSE: BSD - See COPYING.ARM in the top level directory
4  * FILE: boot/freeldr/freeldr/disk/ramdisk.c
5  * PURPOSE: Implements routines to support booting from a RAM Disk
6  * PROGRAMMERS: ReactOS Portable Systems Group
7  * Hervé Poussineau
8  */
9 
10 /* INCLUDES *******************************************************************/
11 
12 #include <freeldr.h>
13 
14 #include <debug.h>
15 
16 /* GLOBALS ********************************************************************/
17 
21 
22 /* FUNCTIONS ******************************************************************/
23 
25 {
26  //
27  // Nothing to do
28  //
29  return ESUCCESS;
30 }
31 
33 {
34  //
35  // Give current seek offset and ram disk size to caller
36  //
38  Information->EndingAddress.LowPart = gRamDiskSize;
39  Information->CurrentAddress.LowPart = gRamDiskOffset;
40 
41  return ESUCCESS;
42 }
43 
44 static ARC_STATUS RamDiskOpen(CHAR* Path, OPENMODE OpenMode, ULONG* FileId)
45 {
46  //
47  // Always return success, as contents are already in memory
48  //
49  return ESUCCESS;
50 }
51 
53 {
54  PVOID StartAddress;
55 
56  //
57  // Get actual pointer
58  //
59  StartAddress = (PVOID)((ULONG_PTR)gRamDiskBase + gRamDiskOffset);
60 
61  //
62  // Don't allow reads past our image
63  //
65  {
66  *Count = 0;
67  return EIO;
68  }
69 
70  //
71  // Do the read
72  //
73  RtlCopyMemory(Buffer, StartAddress, N);
74  *Count = N;
75 
76  return ESUCCESS;
77 }
78 
80 {
81  //
82  // Only accept absolute mode now
83  //
84  if (SeekMode != SeekAbsolute)
85  return EINVAL;
86 
87  //
88  // Check if we're in the ramdisk
89  //
90  if (Position->HighPart != 0)
91  return EINVAL;
92  if (Position->LowPart >= gRamDiskSize)
93  return EINVAL;
94 
95  //
96  // OK, remember seek position
97  //
98  gRamDiskOffset = Position->LowPart;
99 
100  return ESUCCESS;
101 }
102 
103 static const DEVVTBL RamDiskVtbl = {
104  RamDiskClose,
106  RamDiskOpen,
107  RamDiskRead,
108  RamDiskSeek,
109 };
110 
111 VOID
112 NTAPI
114 {
115  /* Register the RAMDISK device */
116  FsRegisterDevice("ramdisk(0)", &RamDiskVtbl);
117 }
118 
119 BOOLEAN
120 NTAPI
122 {
123  PFILE RamFile;
124  ULONG TotalRead, ChunkSize, Count;
125  PCHAR MsgBuffer = "Loading RamDisk...";
126  ULONG PercentPerChunk, Percent;
130 
131  //
132  // Display progress
133  //
134  UiDrawBackdrop();
135  UiDrawProgressBarCenter(1, 100, MsgBuffer);
136 
137  //
138  // Try opening the ramdisk file
139  //
140  RamFile = FsOpenFile(FileName);
141  if (!RamFile)
142  return FALSE;
143 
144  //
145  // Get the file size
146  //
148  if (Status != ESUCCESS)
149  {
150  FsCloseFile(RamFile);
151  return FALSE;
152  }
153 
154  //
155  // For now, limit RAM disks to 4GB
156  //
157  if (Information.EndingAddress.HighPart != 0)
158  {
159  UiMessageBox("RAM disk too big.");
160  FsCloseFile(RamFile);
161  return FALSE;
162  }
163  gRamDiskSize = Information.EndingAddress.LowPart;
164 
165  //
166  // Allocate memory for it
167  //
168  ChunkSize = 8 * 1024 * 1024;
169  if (gRamDiskSize < ChunkSize)
170  Percent = PercentPerChunk = 0;
171  else
172  Percent = PercentPerChunk = 100 / (gRamDiskSize / ChunkSize);
174  if (!gRamDiskBase)
175  {
176  UiMessageBox("Failed to allocate memory for RAM disk.");
177  FsCloseFile(RamFile);
178  return FALSE;
179  }
180 
181  //
182  // Read it in chunks
183  //
184  for (TotalRead = 0; TotalRead < gRamDiskSize; TotalRead += ChunkSize)
185  {
186  //
187  // Check if we're at the last chunk
188  //
189  if ((gRamDiskSize - TotalRead) < ChunkSize)
190  {
191  //
192  // Only need the actual data required
193  //
194  ChunkSize = gRamDiskSize - TotalRead;
195  }
196 
197  //
198  // Draw progress
199  //
200  UiDrawProgressBarCenter(Percent, 100, MsgBuffer);
201  Percent += PercentPerChunk;
202 
203  //
204  // Copy the contents
205  //
206  Position.HighPart = 0;
207  Position.LowPart = TotalRead;
208  Status = ArcSeek(RamFile, &Position, SeekAbsolute);
209  if (Status == ESUCCESS)
210  {
211  Status = ArcRead(RamFile,
212  (PVOID)((ULONG_PTR)gRamDiskBase + TotalRead),
213  ChunkSize,
214  &Count);
215  }
216 
217  //
218  // Check for success
219  //
220  if (Status != ESUCCESS || Count != ChunkSize)
221  {
223  gRamDiskBase = NULL;
224  gRamDiskSize = 0;
225  FsCloseFile(RamFile);
226  UiMessageBox("Failed to read RAM disk.");
227  return FALSE;
228  }
229  }
230 
231  FsCloseFile(RamFile);
232 
233  /* Setup the RAMDISK device */
235 
236  return TRUE;
237 }
signed char * PCHAR
Definition: retypes.h:7
#define IN
Definition: typedefs.h:38
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
static ARC_STATUS RamDiskClose(ULONG FileId)
Definition: ramdisk.c:24
BOOLEAN NTAPI RamDiskLoadVirtualFile(IN PCHAR FileName)
Definition: ramdisk.c:121
Definition: arc.h:32
Definition: arc.h:39
static COORD Position
Definition: mouse.c:34
char CHAR
Definition: xmlstorage.h:175
Definition: fs.h:22
_Inout_ __drv_aliasesMem PSLIST_ENTRY _Inout_ PSLIST_ENTRY _In_ ULONG Count
Definition: exfuncs.h:1015
ULONG ARC_STATUS
Definition: arc.h:4
VOID FsCloseFile(PFILE FileHandle)
Definition: fs.c:309
static const DEVVTBL RamDiskVtbl
Definition: ramdisk.c:103
uint32_t ULONG_PTR
Definition: typedefs.h:63
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
_Inout_ PUCHAR _In_ PUCHAR _Out_ PUCHAR _Out_ PULONG ChunkSize
Definition: rtlfuncs.h:2276
Definition: bidi.c:97
VOID UiMessageBox(PCSTR Format,...)
Definition: ui.c:347
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
enum _SEEKMODE SEEKMODE
Definition: bufpool.h:45
void * PVOID
Definition: retypes.h:9
static ARC_STATUS RamDiskGetFileInformation(ULONG FileId, FILEINFORMATION *Information)
Definition: ramdisk.c:32
static ARC_STATUS RamDiskOpen(CHAR *Path, OPENMODE OpenMode, ULONG *FileId)
Definition: ramdisk.c:44
ULONG gRamDiskSize
Definition: ramdisk.c:19
static ARC_STATUS RamDiskRead(ULONG FileId, VOID *Buffer, ULONG N, ULONG *Count)
Definition: ramdisk.c:52
ARC_STATUS ArcRead(ULONG FileId, VOID *Buffer, ULONG N, ULONG *Count)
Definition: fs.c:237
ULONG gRamDiskOffset
Definition: ramdisk.c:20
VOID FsRegisterDevice(CHAR *Prefix, const DEVVTBL *FuncTable)
Definition: fs.c:441
VOID NTAPI RamDiskInitialize(VOID)
Definition: ramdisk.c:113
PVOID MmAllocateMemoryWithType(SIZE_T MemorySize, TYPE_OF_MEMORY MemoryType)
Definition: mm.c:31
ARC_STATUS ArcSeek(ULONG FileId, LARGE_INTEGER *Position, SEEKMODE SeekMode)
Definition: fs.c:244
VOID UiDrawBackdrop(VOID)
Definition: ui.c:241
Status
Definition: gdiplustypes.h:24
VOID MmFreeMemory(PVOID MemoryPointer)
Definition: mm.c:215
PRTL_UNICODE_STRING_BUFFER Path
static ARC_STATUS RamDiskSeek(ULONG FileId, LARGE_INTEGER *Position, SEEKMODE SeekMode)
Definition: ramdisk.c:79
Definition: arc.h:40
ARC_STATUS ArcGetFileInformation(ULONG FileId, FILEINFORMATION *Information)
Definition: fs.c:251
PVOID gRamDiskBase
Definition: ramdisk.c:18
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
enum _OPENMODE OPENMODE
#define PFILE
Definition: fs.h:37
Iosb Information
Definition: create.c:4377
PFILE FsOpenFile(PCSTR FileName)
Definition: fs.c:266
VOID UiDrawProgressBarCenter(ULONG Position, ULONG Range, PCHAR ProgressText)
Definition: ui.c:373