ReactOS  0.4.15-dev-1187-g119f102
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 /* GLOBALS *******************************************************************/
18 
20 
21 /* DATA ***********************************************************************/
22 
23 #if defined (ALLOC_PRAGMA)
24 #pragma alloc_text(INIT, IopStartRamdisk)
25 #endif
26 
27 /* FUNCTIONS ******************************************************************/
28 
29 INIT_FUNCTION
31 NTAPI
33 {
36  PCHAR CommandLine, Offset, OffsetValue, Length, LengthValue;
38  RAMDISK_CREATE_INPUT RamdiskCreate;
40  UNICODE_STRING GuidString, SymbolicLinkName, ObjectName, DeviceString;
41  PLIST_ENTRY ListHead, NextEntry;
43  WCHAR SourceString[54];
44 
45  //
46  // Scan memory descriptors
47  //
49  ListHead = &LoaderBlock->MemoryDescriptorListHead;
50  NextEntry = ListHead->Flink;
51  while (NextEntry != ListHead)
52  {
53  //
54  // Get the descriptor
55  //
58  ListEntry);
59 
60  //
61  // Needs to be a ROM/RAM descriptor
62  //
63  if (MemoryDescriptor->MemoryType == LoaderXIPRom) break;
64 
65  //
66  // Keep trying
67  //
68  NextEntry = NextEntry->Flink;
69  }
70 
71  //
72  // Nothing found?
73  //
74  if (NextEntry == ListHead)
75  {
76  //
77  // Bugcheck -- no data
78  //
79  KeBugCheckEx(RAMDISK_BOOT_INITIALIZATION_FAILED,
82  0,
83  0);
84  }
85 
86  //
87  // Setup the input buffer
88  //
89  RtlZeroMemory(&RamdiskCreate, sizeof(RamdiskCreate));
90  RamdiskCreate.Version = sizeof(RamdiskCreate);
91  RamdiskCreate.DiskType = RAMDISK_BOOT_DISK;
92  RamdiskCreate.BasePage = MemoryDescriptor->BasePage;
93  RamdiskCreate.DiskOffset = 0;
94  RamdiskCreate.DiskLength.QuadPart = MemoryDescriptor->PageCount << PAGE_SHIFT;
95  RamdiskCreate.DiskGuid = RAMDISK_BOOTDISK_GUID;
96  RamdiskCreate.DriveLetter = L'C';
97  RamdiskCreate.Options.Fixed = TRUE;
98 
99  //
100  // Check for commandline parameters
101  //
102  CommandLine = LoaderBlock->LoadOptions;
103  if (CommandLine)
104  {
105  //
106  // Make everything upper case
107  //
108  _strupr(CommandLine);
109 
110  //
111  // Check for offset parameter
112  //
113  Offset = strstr(CommandLine, "RDIMAGEOFFSET");
114  if (Offset)
115  {
116  //
117  // Get to the actual value
118  //
119  OffsetValue = strstr(Offset, "=");
120  if (OffsetValue)
121  {
122  //
123  // Set the offset
124  //
125  RamdiskCreate.DiskOffset = atol(OffsetValue + 1);
126  }
127  }
128 
129  //
130  // Reduce the disk length
131  //
132  RamdiskCreate.DiskLength.QuadPart -= RamdiskCreate.DiskOffset;
133 
134  //
135  // Check for length parameter
136  //
137  Length = strstr(CommandLine, "RDIMAGELENGTH");
138  if (Length)
139  {
140  //
141  // Get to the actual value
142  //
143  LengthValue = strstr(Length, "=");
144  if (LengthValue)
145  {
146  //
147  // Set the offset
148  //
149  RamdiskCreate.DiskLength.QuadPart = _atoi64(LengthValue + 1);
150  }
151  }
152  }
153 
154  //
155  // Setup object attributes
156  //
157  RtlInitUnicodeString(&ObjectName, L"\\Device\\Ramdisk");
159  &ObjectName,
161  NULL,
162  NULL);
163 
164  //
165  // Open a handle to the driver
166  //
170  &IoStatusBlock,
174  {
175  //
176  // Bugcheck -- no driver
177  //
178  KeBugCheckEx(RAMDISK_BOOT_INITIALIZATION_FAILED,
181  0,
182  0);
183  }
184 
185  //
186  // Send create command
187  //
189  NULL,
190  NULL,
191  NULL,
192  &IoStatusBlock,
194  &RamdiskCreate,
195  sizeof(RamdiskCreate),
196  NULL,
197  0);
200  {
201  //
202  // Bugcheck -- driver failed
203  //
204  KeBugCheckEx(RAMDISK_BOOT_INITIALIZATION_FAILED,
207  0,
208  0);
209  }
210 
211  //
212  // Convert the GUID
213  //
214  Status = RtlStringFromGUID(&RamdiskCreate.DiskGuid, &GuidString);
215  if (!NT_SUCCESS(Status))
216  {
217  //
218  // Bugcheck -- GUID convert failed
219  //
220  KeBugCheckEx(RAMDISK_BOOT_INITIALIZATION_FAILED,
222  Status,
223  0,
224  0);
225  }
226 
227  //
228  // Build the symbolic link name and target
229  //
231  sizeof(SourceString)/sizeof(WCHAR),
232  L"\\Device\\Ramdisk%wZ",
233  &GuidString);
234  SymbolicLinkName.Length = 38;
235  SymbolicLinkName.MaximumLength = 38 + sizeof(UNICODE_NULL);
236  SymbolicLinkName.Buffer = L"\\ArcName\\ramdisk(0)";
237 
238  //
239  // Create the symbolic link
240  //
241  RtlInitUnicodeString(&DeviceString, SourceString);
242  Status = IoCreateSymbolicLink(&SymbolicLinkName, &DeviceString);
244  if (!NT_SUCCESS(Status))
245  {
246  //
247  // Bugcheck -- symlink create failed
248  //
249  KeBugCheckEx(RAMDISK_BOOT_INITIALIZATION_FAILED,
251  Status,
252  0,
253  0);
254  }
255 
256  //
257  // ReactOS hack (drive letter should not be hardcoded, and maybe set by mountmgr.sys)
258  //
259  {
260  ANSI_STRING AnsiPath;
261  CHAR Buffer[256];
263  UNICODE_STRING DriveLetter = RTL_CONSTANT_STRING(L"\\??\\X:");
264 
265  AnsiPath.Length = sprintf(Buffer, "X:%s", LoaderBlock->NtBootPathName);
266  AnsiPath.MaximumLength = AnsiPath.Length + 1;
267  AnsiPath.Buffer = Buffer;
268  RtlInitEmptyUnicodeString(&NtSystemRoot,
269  SharedUserData->NtSystemRoot,
270  sizeof(SharedUserData->NtSystemRoot));
272  IoCreateSymbolicLink(&DriveLetter, &DeviceString);
273  }
274 
275  //
276  // Wait for ramdisk relations being initialized
277  //
278 
280 
281  //
282  // We made it
283  //
284  return STATUS_SUCCESS;
285 }
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:39
#define GENERIC_ALL
Definition: nt_native.h:92
#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:73
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define TRUE
Definition: types.h:120
#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
NTSTATUS NTAPI KeWaitForSingleObject(IN PVOID Object, IN KWAIT_REASON WaitReason, IN KPROCESSOR_MODE WaitMode, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL)
Definition: wait.c:416
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define FILE_SHARE_READ
Definition: compat.h:136
#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 FALSE
Definition: types.h:117
#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
static NDIS_HANDLE DriverHandle
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:121
__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)
INIT_FUNCTION NTSTATUS NTAPI IopStartRamdisk(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
Definition: ramdisk.c:32
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
Status
Definition: gdiplustypes.h:24
_Out_ _Inout_ POEM_STRING _In_ PCUNICODE_STRING SourceString
Definition: rtlfuncs.h:1868
static const WCHAR L[]
Definition: oid.c:1250
Definition: typedefs.h:119
#define SYNCHRONIZE
Definition: nt_native.h:61
_CRTIMP char *__cdecl _strupr(_Inout_z_ char *_String)
NTSYSAPI NTSTATUS NTAPI RtlAnsiStringToUnicodeString(PUNICODE_STRING DestinationString, PANSI_STRING SourceString, BOOLEAN AllocateDestinationString)
KEVENT PiEnumerationFinished
Definition: devaction.c:49
NTSYSAPI NTSTATUS WINAPI RtlStringFromGUID(REFGUID, PUNICODE_STRING)
_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:262
#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:3014
#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:108
LARGE_INTEGER DiskLength
Definition: ntddrdsk.h:77
LONGLONG QuadPart
Definition: typedefs.h:114
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14