ReactOS  0.4.14-dev-554-g2f8d847
ramdisk.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS Kernel
3  * LICENSE: BSD - See COPYING.ARM in the top level directory
4  * FILE: ntoskrnl/io/iomgr/ramdisk.c
5  * PURPOSE: Allows booting from RAM disk
6  * PROGRAMMERS: ReactOS Portable Systems Group
7  */
8 
9 /* INCLUDES *******************************************************************/
10 
11 #include <ntoskrnl.h>
12 #include <initguid.h>
13 #include <ntddrdsk.h>
14 #define NDEBUG
15 #include <debug.h>
16 
17 /* DATA ***********************************************************************/
18 
19 #if defined (ALLOC_PRAGMA)
20 #pragma alloc_text(INIT, IopStartRamdisk)
21 #endif
22 
23 /* FUNCTIONS ******************************************************************/
24 
25 INIT_FUNCTION
27 NTAPI
29 {
32  PCHAR CommandLine, Offset, OffsetValue, Length, LengthValue;
33  HANDLE DriverHandle;
34  RAMDISK_CREATE_INPUT RamdiskCreate;
36  UNICODE_STRING GuidString, SymbolicLinkName, ObjectName, DeviceString;
37  PLIST_ENTRY ListHead, NextEntry;
39  WCHAR SourceString[54];
40 
41  //
42  // Scan memory descriptors
43  //
45  ListHead = &LoaderBlock->MemoryDescriptorListHead;
46  NextEntry = ListHead->Flink;
47  while (NextEntry != ListHead)
48  {
49  //
50  // Get the descriptor
51  //
54  ListEntry);
55 
56  //
57  // Needs to be a ROM/RAM descriptor
58  //
59  if (MemoryDescriptor->MemoryType == LoaderXIPRom) break;
60 
61  //
62  // Keep trying
63  //
64  NextEntry = NextEntry->Flink;
65  }
66 
67  //
68  // Nothing found?
69  //
70  if (NextEntry == ListHead)
71  {
72  //
73  // Bugcheck -- no data
74  //
75  KeBugCheckEx(RAMDISK_BOOT_INITIALIZATION_FAILED,
78  0,
79  0);
80  }
81 
82  //
83  // Setup the input buffer
84  //
85  RtlZeroMemory(&RamdiskCreate, sizeof(RamdiskCreate));
86  RamdiskCreate.Version = sizeof(RamdiskCreate);
87  RamdiskCreate.DiskType = RAMDISK_BOOT_DISK;
88  RamdiskCreate.BasePage = MemoryDescriptor->BasePage;
89  RamdiskCreate.DiskOffset = 0;
90  RamdiskCreate.DiskLength.QuadPart = MemoryDescriptor->PageCount << PAGE_SHIFT;
91  RamdiskCreate.DiskGuid = RAMDISK_BOOTDISK_GUID;
92  RamdiskCreate.DriveLetter = L'C';
93  RamdiskCreate.Options.Fixed = TRUE;
94 
95  //
96  // Check for commandline parameters
97  //
98  CommandLine = LoaderBlock->LoadOptions;
99  if (CommandLine)
100  {
101  //
102  // Make everything upper case
103  //
104  _strupr(CommandLine);
105 
106  //
107  // Check for offset parameter
108  //
109  Offset = strstr(CommandLine, "RDIMAGEOFFSET");
110  if (Offset)
111  {
112  //
113  // Get to the actual value
114  //
115  OffsetValue = strstr(Offset, "=");
116  if (OffsetValue)
117  {
118  //
119  // Set the offset
120  //
121  RamdiskCreate.DiskOffset = atol(OffsetValue + 1);
122  }
123  }
124 
125  //
126  // Reduce the disk length
127  //
128  RamdiskCreate.DiskLength.QuadPart -= RamdiskCreate.DiskOffset;
129 
130  //
131  // Check for length parameter
132  //
133  Length = strstr(CommandLine, "RDIMAGELENGTH");
134  if (Length)
135  {
136  //
137  // Get to the actual value
138  //
139  LengthValue = strstr(Length, "=");
140  if (LengthValue)
141  {
142  //
143  // Set the offset
144  //
145  RamdiskCreate.DiskLength.QuadPart = _atoi64(LengthValue + 1);
146  }
147  }
148  }
149 
150  //
151  // Setup object attributes
152  //
153  RtlInitUnicodeString(&ObjectName, L"\\Device\\Ramdisk");
155  &ObjectName,
157  NULL,
158  NULL);
159 
160  //
161  // Open a handle to the driver
162  //
163  Status = ZwOpenFile(&DriverHandle,
166  &IoStatusBlock,
170  {
171  //
172  // Bugcheck -- no driver
173  //
174  KeBugCheckEx(RAMDISK_BOOT_INITIALIZATION_FAILED,
177  0,
178  0);
179  }
180 
181  //
182  // Send create command
183  //
184  Status = ZwDeviceIoControlFile(DriverHandle,
185  NULL,
186  NULL,
187  NULL,
188  &IoStatusBlock,
190  &RamdiskCreate,
191  sizeof(RamdiskCreate),
192  NULL,
193  0);
194  ZwClose(DriverHandle);
196  {
197  //
198  // Bugcheck -- driver failed
199  //
200  KeBugCheckEx(RAMDISK_BOOT_INITIALIZATION_FAILED,
203  0,
204  0);
205  }
206 
207  //
208  // Convert the GUID
209  //
210  Status = RtlStringFromGUID(&RamdiskCreate.DiskGuid, &GuidString);
211  if (!NT_SUCCESS(Status))
212  {
213  //
214  // Bugcheck -- GUID convert failed
215  //
216  KeBugCheckEx(RAMDISK_BOOT_INITIALIZATION_FAILED,
218  Status,
219  0,
220  0);
221  }
222 
223  //
224  // Build the symbolic link name and target
225  //
227  sizeof(SourceString)/sizeof(WCHAR),
228  L"\\Device\\Ramdisk%wZ",
229  &GuidString);
230  SymbolicLinkName.Length = 38;
231  SymbolicLinkName.MaximumLength = 38 + sizeof(UNICODE_NULL);
232  SymbolicLinkName.Buffer = L"\\ArcName\\ramdisk(0)";
233 
234  //
235  // Create the symbolic link
236  //
237  RtlInitUnicodeString(&DeviceString, SourceString);
238  Status = IoCreateSymbolicLink(&SymbolicLinkName, &DeviceString);
240  if (!NT_SUCCESS(Status))
241  {
242  //
243  // Bugcheck -- symlink create failed
244  //
245  KeBugCheckEx(RAMDISK_BOOT_INITIALIZATION_FAILED,
247  Status,
248  0,
249  0);
250  }
251 
252  //
253  // ReactOS hack (drive letter should not be hardcoded, and maybe set by mountmgr.sys)
254  //
255  {
256  ANSI_STRING AnsiPath;
257  CHAR Buffer[256];
259  UNICODE_STRING DriveLetter = RTL_CONSTANT_STRING(L"\\??\\X:");
260 
261  AnsiPath.Length = sprintf(Buffer, "X:%s", LoaderBlock->NtBootPathName);
262  AnsiPath.MaximumLength = AnsiPath.Length + 1;
263  AnsiPath.Buffer = Buffer;
264  RtlInitEmptyUnicodeString(&NtSystemRoot,
265  SharedUserData->NtSystemRoot,
266  sizeof(SharedUserData->NtSystemRoot));
268  IoCreateSymbolicLink(&DriveLetter, &DeviceString);
269  }
270 
271  //
272  // We made it
273  //
274  return STATUS_SUCCESS;
275 }
signed char * PCHAR
Definition: retypes.h:7
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
static PWSTR GuidString
Definition: apphelp.c:91
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
#define IN
Definition: typedefs.h:38
#define GENERIC_ALL
Definition: nt_native.h:92
#define TRUE
Definition: types.h:120
#define FSCTL_CREATE_RAM_DISK
Definition: ntddrdsk.h:45
NTSYSAPI NTSTATUS NTAPI ZwDeviceIoControlFile(IN HANDLE DeviceHandle, IN HANDLE Event OPTIONAL, IN PIO_APC_ROUTINE UserApcRoutine OPTIONAL, IN PVOID UserApcContext OPTIONAL, OUT PIO_STATUS_BLOCK IoStatusBlock, IN ULONG IoControlCode, IN PVOID InputBuffer, IN ULONG InputBufferSize, OUT PVOID OutputBuffer, IN ULONG OutputBufferSize)
_Out_ PNDIS_BUFFER _In_ NDIS_HANDLE _In_ PVOID MemoryDescriptor
Definition: ndis.h:3270
UNICODE_STRING NtSystemRoot
Definition: init.c:72
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
char * strstr(char *String1, char *String2)
Definition: utclib.c:653
#define RD_NO_RAMDISK_DRIVER
Definition: io.h:70
char CHAR
Definition: xmlstorage.h:175
LONG NTSTATUS
Definition: precomp.h:26
#define RD_NO_XIPROM_DESCRIPTOR
Definition: io.h:66
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
_In_ PVOID _Out_opt_ PULONG_PTR _Outptr_opt_ PCUNICODE_STRING * ObjectName
Definition: cmfuncs.h:62
#define FILE_SHARE_READ
Definition: compat.h:125
#define sprintf(buf, format,...)
Definition: sprintf.c:55
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
#define UNICODE_NULL
int _snwprintf(wchar_t *buffer, size_t count, const wchar_t *format,...)
smooth NULL
Definition: ftsmooth.c:416
Definition: bufpool.h:45
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
#define RAMDISK_BOOT_DISK
Definition: ntddrdsk.h:52
USHORT MaximumLength
Definition: env_spec_w32.h:377
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define RD_GUID_CONVERT_FAILED
Definition: io.h:78
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
_Check_return_ long __cdecl atol(_In_z_ const char *_Str)
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
INIT_FUNCTION NTSTATUS NTAPI IopStartRamdisk(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
Definition: ramdisk.c:28
ULONG_PTR BasePage
Definition: ntddrdsk.h:89
RAMDISK_CREATE_OPTIONS Options
Definition: ntddrdsk.h:76
NTSYSAPI NTSTATUS NTAPI ZwOpenFile(_Out_ PHANDLE FileHandle, _In_ ACCESS_MASK DesiredAccess, _In_ POBJECT_ATTRIBUTES ObjectAttributes, _Out_ PIO_STATUS_BLOCK IoStatusBlock, _In_ ULONG ShareAccess, _In_ ULONG OpenOptions)
#define SharedUserData
_Out_ _Inout_ POEM_STRING _In_ PCUNICODE_STRING SourceString
Definition: rtlfuncs.h:1869
static const WCHAR L[]
Definition: oid.c:1250
Definition: typedefs.h:117
NTSYSAPI NTSTATUS WINAPI RtlStringFromGUID(REFGUID, PUNICODE_STRING)
#define SYNCHRONIZE
Definition: nt_native.h:61
Status
Definition: gdiplustypes.h:24
_CRTIMP char *__cdecl _strupr(_Inout_z_ char *_String)
NTSYSAPI NTSTATUS NTAPI RtlAnsiStringToUnicodeString(PUNICODE_STRING DestinationString, PANSI_STRING SourceString, BOOLEAN AllocateDestinationString)
_Check_return_ __MINGW_EXTENSION _CRTIMP __int64 __cdecl _atoi64(_In_z_ const char *_String)
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#define FILE_SYNCHRONOUS_IO_NONALERT
Definition: from_kernel.h:31
#define RD_SYMLINK_CREATE_FAILED
Definition: io.h:82
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
return STATUS_SUCCESS
Definition: btrfs.c:2938
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define RD_FSCTL_FAILED
Definition: io.h:74
VOID NTAPI KeBugCheckEx(_In_ ULONG BugCheckCode, _In_ ULONG_PTR BugCheckParameter1, _In_ ULONG_PTR BugCheckParameter2, _In_ ULONG_PTR BugCheckParameter3, _In_ ULONG_PTR BugCheckParameter4)
Definition: rtlcompat.c:107
LARGE_INTEGER DiskLength
Definition: ntddrdsk.h:77
LONGLONG QuadPart
Definition: typedefs.h:112
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14