2008-06-30 02:15:48 +00:00
|
|
|
/*
|
|
|
|
* PROJECT: ReactOS Kernel
|
|
|
|
* LICENSE: BSD - See COPYING.ARM in the top level directory
|
|
|
|
* FILE: ntoskrnl/io/iomgr/ramdisk.c
|
|
|
|
* PURPOSE: Allows booting from RAM disk
|
|
|
|
* PROGRAMMERS: ReactOS Portable Systems Group
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* INCLUDES *******************************************************************/
|
|
|
|
|
|
|
|
#include <ntoskrnl.h>
|
|
|
|
#include <initguid.h>
|
|
|
|
#include <ntddrdsk.h>
|
|
|
|
#define NDEBUG
|
|
|
|
#include <debug.h>
|
|
|
|
|
|
|
|
/* DATA ***********************************************************************/
|
|
|
|
|
|
|
|
#if defined (ALLOC_PRAGMA)
|
|
|
|
#pragma alloc_text(INIT, IopStartRamdisk)
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* FUNCTIONS ******************************************************************/
|
|
|
|
|
|
|
|
NTSTATUS
|
|
|
|
NTAPI
|
2010-11-02 16:29:06 +00:00
|
|
|
INIT_FUNCTION
|
2008-06-30 02:15:48 +00:00
|
|
|
IopStartRamdisk(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
|
|
|
|
{
|
|
|
|
PMEMORY_ALLOCATION_DESCRIPTOR MemoryDescriptor;
|
|
|
|
NTSTATUS Status;
|
|
|
|
PCHAR CommandLine, Offset, OffsetValue, Length, LengthValue;
|
|
|
|
HANDLE DriverHandle;
|
|
|
|
RAMDISK_CREATE_INPUT RamdiskCreate;
|
|
|
|
IO_STATUS_BLOCK IoStatusBlock;
|
|
|
|
UNICODE_STRING GuidString, SymbolicLinkName, ObjectName, DeviceString;
|
|
|
|
PLIST_ENTRY ListHead, NextEntry;
|
|
|
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
|
|
|
WCHAR SourceString[54];
|
|
|
|
|
|
|
|
//
|
|
|
|
// Scan memory descriptors
|
|
|
|
//
|
|
|
|
MemoryDescriptor = NULL;
|
|
|
|
ListHead = &LoaderBlock->MemoryDescriptorListHead;
|
|
|
|
NextEntry = ListHead->Flink;
|
|
|
|
while (NextEntry != ListHead)
|
|
|
|
{
|
|
|
|
//
|
|
|
|
// Get the descriptor
|
|
|
|
//
|
|
|
|
MemoryDescriptor = CONTAINING_RECORD(NextEntry,
|
|
|
|
MEMORY_ALLOCATION_DESCRIPTOR,
|
|
|
|
ListEntry);
|
|
|
|
|
|
|
|
//
|
|
|
|
// Needs to be a ROM/RAM descriptor
|
|
|
|
//
|
|
|
|
if (MemoryDescriptor->MemoryType == LoaderXIPRom) break;
|
|
|
|
|
|
|
|
//
|
|
|
|
// Keep trying
|
|
|
|
//
|
|
|
|
NextEntry = NextEntry->Flink;
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// Nothing found?
|
|
|
|
//
|
|
|
|
if (NextEntry == ListHead)
|
|
|
|
{
|
|
|
|
//
|
|
|
|
// Bugcheck -- no data
|
|
|
|
//
|
|
|
|
KeBugCheckEx(RAMDISK_BOOT_INITIALIZATION_FAILED,
|
|
|
|
RD_NO_XIPROM_DESCRIPTOR,
|
|
|
|
STATUS_INVALID_PARAMETER,
|
|
|
|
0,
|
|
|
|
0);
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// Setup the input buffer
|
|
|
|
//
|
|
|
|
RtlZeroMemory(&RamdiskCreate, sizeof(RamdiskCreate));
|
|
|
|
RamdiskCreate.Version = sizeof(RamdiskCreate);
|
2008-07-22 05:49:52 +00:00
|
|
|
RamdiskCreate.DiskType = RAMDISK_BOOT_DISK;
|
2008-06-30 02:15:48 +00:00
|
|
|
RamdiskCreate.BasePage = MemoryDescriptor->BasePage;
|
|
|
|
RamdiskCreate.DiskOffset = 0;
|
2008-07-22 09:57:36 +00:00
|
|
|
RamdiskCreate.DiskLength.QuadPart = MemoryDescriptor->PageCount << PAGE_SHIFT;
|
2008-06-30 02:15:48 +00:00
|
|
|
RamdiskCreate.DiskGuid = RAMDISK_BOOTDISK_GUID;
|
|
|
|
RamdiskCreate.DriveLetter = L'C';
|
|
|
|
RamdiskCreate.Options.Fixed = TRUE;
|
|
|
|
|
|
|
|
//
|
|
|
|
// Check for commandline parameters
|
|
|
|
//
|
|
|
|
CommandLine = LoaderBlock->LoadOptions;
|
|
|
|
if (CommandLine)
|
|
|
|
{
|
|
|
|
//
|
|
|
|
// Make everything upper case
|
|
|
|
//
|
|
|
|
_strupr(CommandLine);
|
|
|
|
|
|
|
|
//
|
|
|
|
// Check for offset parameter
|
|
|
|
//
|
|
|
|
Offset = strstr(CommandLine, "RDIMAGEOFFSET");
|
|
|
|
if (Offset)
|
|
|
|
{
|
|
|
|
//
|
|
|
|
// Get to the actual value
|
|
|
|
//
|
|
|
|
OffsetValue = strstr(Offset, "=");
|
|
|
|
if (OffsetValue)
|
|
|
|
{
|
|
|
|
//
|
|
|
|
// Set the offset
|
|
|
|
//
|
|
|
|
RamdiskCreate.DiskOffset = atol(OffsetValue + 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// Reduce the disk length
|
|
|
|
//
|
2008-07-22 09:57:36 +00:00
|
|
|
RamdiskCreate.DiskLength.QuadPart -= RamdiskCreate.DiskOffset;
|
2008-06-30 02:15:48 +00:00
|
|
|
|
|
|
|
//
|
|
|
|
// Check for length parameter
|
|
|
|
//
|
|
|
|
Length = strstr(CommandLine, "RDIMAGELENGTH");
|
|
|
|
if (Length)
|
|
|
|
{
|
|
|
|
//
|
|
|
|
// Get to the actual value
|
|
|
|
//
|
|
|
|
LengthValue = strstr(Length, "=");
|
|
|
|
if (LengthValue)
|
|
|
|
{
|
|
|
|
//
|
|
|
|
// Set the offset
|
|
|
|
//
|
2008-07-22 09:57:36 +00:00
|
|
|
RamdiskCreate.DiskLength.QuadPart = _atoi64(LengthValue + 1);
|
2008-06-30 02:15:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// Setup object attributes
|
|
|
|
//
|
|
|
|
RtlInitUnicodeString(&ObjectName, L"\\Device\\Ramdisk");
|
|
|
|
InitializeObjectAttributes(&ObjectAttributes,
|
|
|
|
&ObjectName,
|
|
|
|
OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE,
|
|
|
|
NULL,
|
|
|
|
NULL);
|
|
|
|
|
|
|
|
//
|
|
|
|
// Open a handle to the driver
|
|
|
|
//
|
|
|
|
Status = ZwOpenFile(&DriverHandle,
|
2013-07-19 15:05:28 +00:00
|
|
|
GENERIC_ALL | SYNCHRONIZE,
|
2008-06-30 02:15:48 +00:00
|
|
|
&ObjectAttributes,
|
|
|
|
&IoStatusBlock,
|
|
|
|
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
|
|
|
FILE_SYNCHRONOUS_IO_NONALERT);
|
|
|
|
if (!(NT_SUCCESS(Status)) || !(NT_SUCCESS(IoStatusBlock.Status)))
|
|
|
|
{
|
|
|
|
//
|
|
|
|
// Bugcheck -- no driver
|
|
|
|
//
|
|
|
|
KeBugCheckEx(RAMDISK_BOOT_INITIALIZATION_FAILED,
|
|
|
|
RD_NO_RAMDISK_DRIVER,
|
|
|
|
IoStatusBlock.Status,
|
|
|
|
0,
|
|
|
|
0);
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// Send create command
|
|
|
|
//
|
|
|
|
Status = ZwDeviceIoControlFile(DriverHandle,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
NULL,
|
|
|
|
&IoStatusBlock,
|
|
|
|
FSCTL_CREATE_RAM_DISK,
|
|
|
|
&RamdiskCreate,
|
|
|
|
sizeof(RamdiskCreate),
|
|
|
|
NULL,
|
|
|
|
0);
|
|
|
|
ZwClose(DriverHandle);
|
|
|
|
if (!(NT_SUCCESS(Status)) || !(NT_SUCCESS(IoStatusBlock.Status)))
|
|
|
|
{
|
|
|
|
//
|
|
|
|
// Bugcheck -- driver failed
|
|
|
|
//
|
|
|
|
KeBugCheckEx(RAMDISK_BOOT_INITIALIZATION_FAILED,
|
|
|
|
RD_FSCTL_FAILED,
|
|
|
|
IoStatusBlock.Status,
|
|
|
|
0,
|
|
|
|
0);
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// Convert the GUID
|
|
|
|
//
|
|
|
|
Status = RtlStringFromGUID(&RamdiskCreate.DiskGuid, &GuidString);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
//
|
|
|
|
// Bugcheck -- GUID convert failed
|
|
|
|
//
|
|
|
|
KeBugCheckEx(RAMDISK_BOOT_INITIALIZATION_FAILED,
|
|
|
|
RD_GUID_CONVERT_FAILED,
|
|
|
|
Status,
|
|
|
|
0,
|
|
|
|
0);
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// Build the symbolic link name and target
|
|
|
|
//
|
|
|
|
_snwprintf(SourceString,
|
[NTOSKRNL]
Coverity code defects fixes :
- Cache: CID 701441
- Config: CIDs 716570, 716669, 716760
- Dbgk: Kdbg: CIDs 716571, 515128/9, 500432
- Ex: CIDs 500156/7, 515122, 716200/67, 701301, 514669
- Fsrtl: Fstub: CIDs 701341/2, 701288, 716770, 701302, and CIDs 716576/7/8 + 514636 + 716805 thanks to Thomas Faber
- Io: CIDs 514576, 514643, 514672/3, 716203, 716269, 716581, 716591, 716713
- Ke: CIDs 515125, 716592
- Ps: CIDs 716603/4, 701422
- Ob: Po: CIDs 514671/680, 701419/420/421, 716763, 716601/2
All the details are given in the different bug reports.
CORE-6677 CORE-6679 CORE-6680 CORE-6683 CORE-6686 CORE-6692 CORE-6693 CORE-6694 CORE-6695 CORE-6696 #comment Committed in rev.57400 #resolve #close
svn path=/trunk/; revision=57400
2012-09-27 17:16:31 +00:00
|
|
|
sizeof(SourceString)/sizeof(WCHAR),
|
2008-06-30 02:15:48 +00:00
|
|
|
L"\\Device\\Ramdisk%wZ",
|
|
|
|
&GuidString);
|
|
|
|
SymbolicLinkName.Length = 38;
|
|
|
|
SymbolicLinkName.MaximumLength = 38 + sizeof(UNICODE_NULL);
|
|
|
|
SymbolicLinkName.Buffer = L"\\ArcName\\ramdisk(0)";
|
|
|
|
|
|
|
|
//
|
|
|
|
// Create the symbolic link
|
|
|
|
//
|
|
|
|
RtlInitUnicodeString(&DeviceString, SourceString);
|
|
|
|
Status = IoCreateSymbolicLink(&SymbolicLinkName, &DeviceString);
|
|
|
|
RtlFreeUnicodeString(&GuidString);
|
|
|
|
if (!NT_SUCCESS(Status))
|
|
|
|
{
|
|
|
|
//
|
|
|
|
// Bugcheck -- symlink create failed
|
|
|
|
//
|
|
|
|
KeBugCheckEx(RAMDISK_BOOT_INITIALIZATION_FAILED,
|
|
|
|
RD_SYMLINK_CREATE_FAILED,
|
|
|
|
Status,
|
|
|
|
0,
|
|
|
|
0);
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// We made it
|
|
|
|
//
|
|
|
|
return STATUS_SUCCESS;
|
|
|
|
}
|