ReactOS 0.4.15-dev-7842-g558ab78
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/* FUNCTIONS ******************************************************************/
22
23CODE_SEG("INIT")
27{
30 PCHAR CommandLine, Offset, OffsetValue, Length, LengthValue;
32 RAMDISK_CREATE_INPUT RamdiskCreate;
35 PLIST_ENTRY ListHead, NextEntry;
38
39 //
40 // Scan memory descriptors
41 //
43 ListHead = &LoaderBlock->MemoryDescriptorListHead;
44 NextEntry = ListHead->Flink;
45 while (NextEntry != ListHead)
46 {
47 //
48 // Get the descriptor
49 //
52 ListEntry);
53
54 //
55 // Needs to be a ROM/RAM descriptor
56 //
57 if (MemoryDescriptor->MemoryType == LoaderXIPRom) break;
58
59 //
60 // Keep trying
61 //
62 NextEntry = NextEntry->Flink;
63 }
64
65 //
66 // Nothing found?
67 //
68 if (NextEntry == ListHead)
69 {
70 //
71 // Bugcheck -- no data
72 //
73 KeBugCheckEx(RAMDISK_BOOT_INITIALIZATION_FAILED,
76 0,
77 0);
78 }
79
80 //
81 // Setup the input buffer
82 //
83 RtlZeroMemory(&RamdiskCreate, sizeof(RamdiskCreate));
84 RamdiskCreate.Version = sizeof(RamdiskCreate);
85 RamdiskCreate.DiskType = RAMDISK_BOOT_DISK;
86 RamdiskCreate.BasePage = MemoryDescriptor->BasePage;
87 RamdiskCreate.DiskOffset = 0;
88 RamdiskCreate.DiskLength.QuadPart = MemoryDescriptor->PageCount << PAGE_SHIFT;
89 RamdiskCreate.DiskGuid = RAMDISK_BOOTDISK_GUID;
90 RamdiskCreate.DriveLetter = L'C';
91 RamdiskCreate.Options.Fixed = TRUE;
92
93 //
94 // Check for commandline parameters
95 //
96 CommandLine = LoaderBlock->LoadOptions;
97 if (CommandLine)
98 {
99 //
100 // Make everything upper case
101 //
102 _strupr(CommandLine);
103
104 //
105 // Check for offset parameter
106 //
107 Offset = strstr(CommandLine, "RDIMAGEOFFSET");
108 if (Offset)
109 {
110 //
111 // Get to the actual value
112 //
113 OffsetValue = strstr(Offset, "=");
114 if (OffsetValue)
115 {
116 //
117 // Set the offset
118 //
119 RamdiskCreate.DiskOffset = atol(OffsetValue + 1);
120 }
121 }
122
123 //
124 // Reduce the disk length
125 //
126 RamdiskCreate.DiskLength.QuadPart -= RamdiskCreate.DiskOffset;
127
128 //
129 // Check for length parameter
130 //
131 Length = strstr(CommandLine, "RDIMAGELENGTH");
132 if (Length)
133 {
134 //
135 // Get to the actual value
136 //
137 LengthValue = strstr(Length, "=");
138 if (LengthValue)
139 {
140 //
141 // Set the offset
142 //
143 RamdiskCreate.DiskLength.QuadPart = _atoi64(LengthValue + 1);
144 }
145 }
146 }
147
148 //
149 // Setup object attributes
150 //
151 RtlInitUnicodeString(&ObjectName, L"\\Device\\Ramdisk");
153 &ObjectName,
155 NULL,
156 NULL);
157
158 //
159 // Open a handle to the driver
160 //
168 {
169 //
170 // Bugcheck -- no driver
171 //
172 KeBugCheckEx(RAMDISK_BOOT_INITIALIZATION_FAILED,
175 0,
176 0);
177 }
178
179 //
180 // Send create command
181 //
183 NULL,
184 NULL,
185 NULL,
188 &RamdiskCreate,
189 sizeof(RamdiskCreate),
190 NULL,
191 0);
194 {
195 //
196 // Bugcheck -- driver failed
197 //
198 KeBugCheckEx(RAMDISK_BOOT_INITIALIZATION_FAILED,
201 0,
202 0);
203 }
204
205 //
206 // Convert the GUID
207 //
208 Status = RtlStringFromGUID(&RamdiskCreate.DiskGuid, &GuidString);
209 if (!NT_SUCCESS(Status))
210 {
211 //
212 // Bugcheck -- GUID convert failed
213 //
214 KeBugCheckEx(RAMDISK_BOOT_INITIALIZATION_FAILED,
216 Status,
217 0,
218 0);
219 }
220
221 //
222 // Build the symbolic link name and target
223 //
225 sizeof(SourceString)/sizeof(WCHAR),
226 L"\\Device\\Ramdisk%wZ",
227 &GuidString);
228 SymbolicLinkName.Length = 38;
229 SymbolicLinkName.MaximumLength = 38 + sizeof(UNICODE_NULL);
230 SymbolicLinkName.Buffer = L"\\ArcName\\ramdisk(0)";
231
232 //
233 // Create the symbolic link
234 //
235 RtlInitUnicodeString(&DeviceString, SourceString);
238 if (!NT_SUCCESS(Status))
239 {
240 //
241 // Bugcheck -- symlink create failed
242 //
243 KeBugCheckEx(RAMDISK_BOOT_INITIALIZATION_FAILED,
245 Status,
246 0,
247 0);
248 }
249
250 //
251 // ReactOS hack (drive letter should not be hardcoded, and maybe set by mountmgr.sys)
252 //
253 {
254 ANSI_STRING AnsiPath;
255 CHAR Buffer[256];
257 UNICODE_STRING DriveLetter = RTL_CONSTANT_STRING(L"\\??\\X:");
258
259 AnsiPath.Length = sprintf(Buffer, "X:%s", LoaderBlock->NtBootPathName);
260 AnsiPath.MaximumLength = AnsiPath.Length + 1;
261 AnsiPath.Buffer = Buffer;
262 RtlInitEmptyUnicodeString(&NtSystemRoot,
263 SharedUserData->NtSystemRoot,
264 sizeof(SharedUserData->NtSystemRoot));
266 if (!NT_SUCCESS(Status))
267 {
268 KeBugCheckEx(RAMDISK_BOOT_INITIALIZATION_FAILED,
270 Status,
271 0,
272 0);
273 }
274 IoCreateSymbolicLink(&DriveLetter, &DeviceString);
275 }
276
277 //
278 // Wait for ramdisk relations being initialized
279 //
280
282
283 //
284 // We made it
285 //
286 return STATUS_SUCCESS;
287}
static NDIS_HANDLE DriverHandle
char * strstr(char *String1, char *String2)
Definition: utclib.c:653
__int64 CDECL _atoi64(const char *nptr)
Definition: atoi64.c:18
LONG NTSTATUS
Definition: precomp.h:26
Definition: bufpool.h:45
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define FILE_SHARE_READ
Definition: compat.h:136
#define KeWaitForSingleObject(pEvt, foo, a, b, c)
Definition: env_spec_w32.h:478
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
#define FILE_SYNCHRONOUS_IO_NONALERT
Definition: from_kernel.h:31
Status
Definition: gdiplustypes.h:25
_Check_return_ long __cdecl atol(_In_z_ const char *_Str)
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
NTSYSAPI NTSTATUS WINAPI RtlStringFromGUID(REFGUID, PUNICODE_STRING)
static CODE_SEG("PAGE")
Definition: isapnp.c:1482
int _snwprintf(wchar_t *buffer, size_t count, const wchar_t *format,...)
static PWSTR GuidString
Definition: apphelp.c:93
#define sprintf(buf, format,...)
Definition: sprintf.c:55
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define KernelMode
Definition: asm.h:34
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)
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
_Out_ _Inout_ POEM_STRING _In_ PCUNICODE_STRING SourceString
Definition: rtlfuncs.h:1910
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
#define SYNCHRONIZE
Definition: nt_native.h:61
NTSYSAPI NTSTATUS NTAPI RtlAnsiStringToUnicodeString(PUNICODE_STRING DestinationString, PANSI_STRING SourceString, BOOLEAN AllocateDestinationString)
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define GENERIC_ALL
Definition: nt_native.h:92
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
#define UNICODE_NULL
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
#define RAMDISK_BOOT_DISK
Definition: ntddrdsk.h:52
#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)
UNICODE_STRING NtSystemRoot
Definition: init.c:76
#define RD_NO_RAMDISK_DRIVER
Definition: io.h:70
#define RD_NO_XIPROM_DESCRIPTOR
Definition: io.h:66
#define RD_SYSROOT_INIT_FAILED
Definition: io.h:86
#define RD_FSCTL_FAILED
Definition: io.h:74
#define RD_GUID_CONVERT_FAILED
Definition: io.h:78
#define RD_SYMLINK_CREATE_FAILED
Definition: io.h:82
KEVENT PiEnumerationFinished
Definition: devaction.c:50
NTSTATUS NTAPI IopStartRamdisk(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
Definition: ramdisk.c:26
#define L(x)
Definition: ntvdm.h:50
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
_CRTIMP char *__cdecl _strupr(_Inout_z_ char *_String)
@ LoaderXIPRom
Definition: arc.h:199
#define SharedUserData
#define STATUS_SUCCESS
Definition: shellext.h:65
USHORT MaximumLength
Definition: env_spec_w32.h:377
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
RAMDISK_CREATE_OPTIONS Options
Definition: ntddrdsk.h:76
LARGE_INTEGER DiskLength
Definition: ntddrdsk.h:77
ULONG_PTR BasePage
Definition: ntddrdsk.h:89
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14
#define NTAPI
Definition: typedefs.h:36
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define IN
Definition: typedefs.h:39
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
char * PCHAR
Definition: typedefs.h:51
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
LONGLONG QuadPart
Definition: typedefs.h:114
_Must_inspect_result_ _In_ WDFDEVICE _In_ PCUNICODE_STRING SymbolicLinkName
Definition: wdfdevice.h:3739
_Must_inspect_result_ _In_ WDFUSBDEVICE _In_opt_ WDFREQUEST _In_opt_ PWDF_REQUEST_SEND_OPTIONS _In_ PWDF_USB_CONTROL_SETUP_PACKET _In_opt_ PWDF_MEMORY_DESCRIPTOR MemoryDescriptor
Definition: wdfusb.h:1339
_In_ PVOID _Out_opt_ PULONG_PTR _Outptr_opt_ PCUNICODE_STRING * ObjectName
Definition: cmfuncs.h:64
@ Executive
Definition: ketypes.h:415
__wchar_t WCHAR
Definition: xmlstorage.h:180
char CHAR
Definition: xmlstorage.h:175