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 ******************************************************************/
27 IopStartRamdisk(IN PLOADER_PARAMETER_BLOCK LoaderBlock
)
29 PMEMORY_ALLOCATION_DESCRIPTOR MemoryDescriptor
;
31 PCHAR CommandLine
, Offset
, OffsetValue
, Length
, LengthValue
;
33 RAMDISK_CREATE_INPUT RamdiskCreate
;
34 IO_STATUS_BLOCK IoStatusBlock
;
35 UNICODE_STRING GuidString
, SymbolicLinkName
, ObjectName
, DeviceString
;
36 PLIST_ENTRY ListHead
, NextEntry
;
37 OBJECT_ATTRIBUTES ObjectAttributes
;
38 WCHAR SourceString
[54];
41 // Scan memory descriptors
43 MemoryDescriptor
= NULL
;
44 ListHead
= &LoaderBlock
->MemoryDescriptorListHead
;
45 NextEntry
= ListHead
->Flink
;
46 while (NextEntry
!= ListHead
)
51 MemoryDescriptor
= CONTAINING_RECORD(NextEntry
,
52 MEMORY_ALLOCATION_DESCRIPTOR
,
56 // Needs to be a ROM/RAM descriptor
58 if (MemoryDescriptor
->MemoryType
== LoaderXIPRom
) break;
63 NextEntry
= NextEntry
->Flink
;
69 if (NextEntry
== ListHead
)
72 // Bugcheck -- no data
74 KeBugCheckEx(RAMDISK_BOOT_INITIALIZATION_FAILED
,
75 RD_NO_XIPROM_DESCRIPTOR
,
76 STATUS_INVALID_PARAMETER
,
82 // Setup the input buffer
84 RtlZeroMemory(&RamdiskCreate
, sizeof(RamdiskCreate
));
85 RamdiskCreate
.Version
= sizeof(RamdiskCreate
);
86 RamdiskCreate
.DiskType
= RAMDISK_BOOT_DISK
;
87 RamdiskCreate
.BasePage
= MemoryDescriptor
->BasePage
;
88 RamdiskCreate
.DiskOffset
= 0;
89 RamdiskCreate
.DiskLength
.QuadPart
= MemoryDescriptor
->PageCount
<< PAGE_SHIFT
;
90 RamdiskCreate
.DiskGuid
= RAMDISK_BOOTDISK_GUID
;
91 RamdiskCreate
.DriveLetter
= L
'C';
92 RamdiskCreate
.Options
.Fixed
= TRUE
;
95 // Check for commandline parameters
97 CommandLine
= LoaderBlock
->LoadOptions
;
101 // Make everything upper case
103 _strupr(CommandLine
);
106 // Check for offset parameter
108 Offset
= strstr(CommandLine
, "RDIMAGEOFFSET");
112 // Get to the actual value
114 OffsetValue
= strstr(Offset
, "=");
120 RamdiskCreate
.DiskOffset
= atol(OffsetValue
+ 1);
125 // Reduce the disk length
127 RamdiskCreate
.DiskLength
.QuadPart
-= RamdiskCreate
.DiskOffset
;
130 // Check for length parameter
132 Length
= strstr(CommandLine
, "RDIMAGELENGTH");
136 // Get to the actual value
138 LengthValue
= strstr(Length
, "=");
144 RamdiskCreate
.DiskLength
.QuadPart
= _atoi64(LengthValue
+ 1);
150 // Setup object attributes
152 RtlInitUnicodeString(&ObjectName
, L
"\\Device\\Ramdisk");
153 InitializeObjectAttributes(&ObjectAttributes
,
155 OBJ_KERNEL_HANDLE
| OBJ_CASE_INSENSITIVE
,
160 // Open a handle to the driver
162 Status
= ZwOpenFile(&DriverHandle
,
166 FILE_SHARE_READ
| FILE_SHARE_WRITE
,
167 FILE_SYNCHRONOUS_IO_NONALERT
);
168 if (!(NT_SUCCESS(Status
)) || !(NT_SUCCESS(IoStatusBlock
.Status
)))
171 // Bugcheck -- no driver
173 KeBugCheckEx(RAMDISK_BOOT_INITIALIZATION_FAILED
,
174 RD_NO_RAMDISK_DRIVER
,
175 IoStatusBlock
.Status
,
181 // Send create command
183 Status
= ZwDeviceIoControlFile(DriverHandle
,
188 FSCTL_CREATE_RAM_DISK
,
190 sizeof(RamdiskCreate
),
193 ZwClose(DriverHandle
);
194 if (!(NT_SUCCESS(Status
)) || !(NT_SUCCESS(IoStatusBlock
.Status
)))
197 // Bugcheck -- driver failed
199 KeBugCheckEx(RAMDISK_BOOT_INITIALIZATION_FAILED
,
201 IoStatusBlock
.Status
,
209 Status
= RtlStringFromGUID(&RamdiskCreate
.DiskGuid
, &GuidString
);
210 if (!NT_SUCCESS(Status
))
213 // Bugcheck -- GUID convert failed
215 KeBugCheckEx(RAMDISK_BOOT_INITIALIZATION_FAILED
,
216 RD_GUID_CONVERT_FAILED
,
223 // Build the symbolic link name and target
225 _snwprintf(SourceString
,
226 sizeof(SourceString
),
227 L
"\\Device\\Ramdisk%wZ",
229 SymbolicLinkName
.Length
= 38;
230 SymbolicLinkName
.MaximumLength
= 38 + sizeof(UNICODE_NULL
);
231 SymbolicLinkName
.Buffer
= L
"\\ArcName\\ramdisk(0)";
234 // Create the symbolic link
236 RtlInitUnicodeString(&DeviceString
, SourceString
);
237 Status
= IoCreateSymbolicLink(&SymbolicLinkName
, &DeviceString
);
238 RtlFreeUnicodeString(&GuidString
);
239 if (!NT_SUCCESS(Status
))
242 // Bugcheck -- symlink create failed
244 KeBugCheckEx(RAMDISK_BOOT_INITIALIZATION_FAILED
,
245 RD_SYMLINK_CREATE_FAILED
,
254 return STATUS_SUCCESS
;