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
9 /* INCLUDES *******************************************************************/
17 /* DATA ***********************************************************************/
19 #if defined (ALLOC_PRAGMA)
20 #pragma alloc_text(INIT, IopStartRamdisk)
23 /* FUNCTIONS ******************************************************************/
28 IopStartRamdisk(IN PLOADER_PARAMETER_BLOCK LoaderBlock
)
30 PMEMORY_ALLOCATION_DESCRIPTOR MemoryDescriptor
;
32 PCHAR CommandLine
, Offset
, OffsetValue
, Length
, LengthValue
;
34 RAMDISK_CREATE_INPUT RamdiskCreate
;
35 IO_STATUS_BLOCK IoStatusBlock
;
36 UNICODE_STRING GuidString
, SymbolicLinkName
, ObjectName
, DeviceString
;
37 PLIST_ENTRY ListHead
, NextEntry
;
38 OBJECT_ATTRIBUTES ObjectAttributes
;
39 WCHAR SourceString
[54];
42 // Scan memory descriptors
44 MemoryDescriptor
= NULL
;
45 ListHead
= &LoaderBlock
->MemoryDescriptorListHead
;
46 NextEntry
= ListHead
->Flink
;
47 while (NextEntry
!= ListHead
)
52 MemoryDescriptor
= CONTAINING_RECORD(NextEntry
,
53 MEMORY_ALLOCATION_DESCRIPTOR
,
57 // Needs to be a ROM/RAM descriptor
59 if (MemoryDescriptor
->MemoryType
== LoaderXIPRom
) break;
64 NextEntry
= NextEntry
->Flink
;
70 if (NextEntry
== ListHead
)
73 // Bugcheck -- no data
75 KeBugCheckEx(RAMDISK_BOOT_INITIALIZATION_FAILED
,
76 RD_NO_XIPROM_DESCRIPTOR
,
77 STATUS_INVALID_PARAMETER
,
83 // Setup the input buffer
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
;
96 // Check for commandline parameters
98 CommandLine
= LoaderBlock
->LoadOptions
;
102 // Make everything upper case
104 _strupr(CommandLine
);
107 // Check for offset parameter
109 Offset
= strstr(CommandLine
, "RDIMAGEOFFSET");
113 // Get to the actual value
115 OffsetValue
= strstr(Offset
, "=");
121 RamdiskCreate
.DiskOffset
= atol(OffsetValue
+ 1);
126 // Reduce the disk length
128 RamdiskCreate
.DiskLength
.QuadPart
-= RamdiskCreate
.DiskOffset
;
131 // Check for length parameter
133 Length
= strstr(CommandLine
, "RDIMAGELENGTH");
137 // Get to the actual value
139 LengthValue
= strstr(Length
, "=");
145 RamdiskCreate
.DiskLength
.QuadPart
= _atoi64(LengthValue
+ 1);
151 // Setup object attributes
153 RtlInitUnicodeString(&ObjectName
, L
"\\Device\\Ramdisk");
154 InitializeObjectAttributes(&ObjectAttributes
,
156 OBJ_KERNEL_HANDLE
| OBJ_CASE_INSENSITIVE
,
161 // Open a handle to the driver
163 Status
= ZwOpenFile(&DriverHandle
,
164 GENERIC_ALL
| SYNCHRONIZE
,
167 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
168 FILE_SYNCHRONOUS_IO_NONALERT
);
169 if (!(NT_SUCCESS(Status
)) || !(NT_SUCCESS(IoStatusBlock
.Status
)))
172 // Bugcheck -- no driver
174 KeBugCheckEx(RAMDISK_BOOT_INITIALIZATION_FAILED
,
175 RD_NO_RAMDISK_DRIVER
,
176 IoStatusBlock
.Status
,
182 // Send create command
184 Status
= ZwDeviceIoControlFile(DriverHandle
,
189 FSCTL_CREATE_RAM_DISK
,
191 sizeof(RamdiskCreate
),
194 ZwClose(DriverHandle
);
195 if (!(NT_SUCCESS(Status
)) || !(NT_SUCCESS(IoStatusBlock
.Status
)))
198 // Bugcheck -- driver failed
200 KeBugCheckEx(RAMDISK_BOOT_INITIALIZATION_FAILED
,
202 IoStatusBlock
.Status
,
210 Status
= RtlStringFromGUID(&RamdiskCreate
.DiskGuid
, &GuidString
);
211 if (!NT_SUCCESS(Status
))
214 // Bugcheck -- GUID convert failed
216 KeBugCheckEx(RAMDISK_BOOT_INITIALIZATION_FAILED
,
217 RD_GUID_CONVERT_FAILED
,
224 // Build the symbolic link name and target
226 _snwprintf(SourceString
,
227 sizeof(SourceString
)/sizeof(WCHAR
),
228 L
"\\Device\\Ramdisk%wZ",
230 SymbolicLinkName
.Length
= 38;
231 SymbolicLinkName
.MaximumLength
= 38 + sizeof(UNICODE_NULL
);
232 SymbolicLinkName
.Buffer
= L
"\\ArcName\\ramdisk(0)";
235 // Create the symbolic link
237 RtlInitUnicodeString(&DeviceString
, SourceString
);
238 Status
= IoCreateSymbolicLink(&SymbolicLinkName
, &DeviceString
);
239 RtlFreeUnicodeString(&GuidString
);
240 if (!NT_SUCCESS(Status
))
243 // Bugcheck -- symlink create failed
245 KeBugCheckEx(RAMDISK_BOOT_INITIALIZATION_FAILED
,
246 RD_SYMLINK_CREATE_FAILED
,
255 return STATUS_SUCCESS
;