Implement agnostic architecture for file system access, according to Advanced RISC Computing Specification Version 1.2

Some shortcuts still exist, and will need to be addressed later
Use this new API in the NTLDR-style loader

svn path=/trunk/; revision=40613
This commit is contained in:
Hervé Poussineau 2009-04-20 20:04:23 +00:00
parent 549e5d1a61
commit 7a499db296
9 changed files with 530 additions and 114 deletions

View file

@ -395,6 +395,99 @@ SetHarddiskConfigurationData(PCONFIGURATION_COMPONENT_DATA DiskKey,
MmHeapFree(PartialResourceList);
}
typedef struct tagDISKCONTEXT
{
ULONG DriveNumber;
ULONG SectorSize;
ULONGLONG SectorOffset;
ULONGLONG SectorNumber;
} DISKCONTEXT;
static LONG DiskClose(ULONG FileId)
{
DISKCONTEXT* Context = FsGetDeviceSpecific(FileId);
MmHeapFree(Context);
return ESUCCESS;
}
static LONG DiskGetFileInformation(ULONG FileId, FILEINFORMATION* Information)
{
return EINVAL;
}
static LONG DiskOpen(CHAR* Path, OPENMODE OpenMode, ULONG* FileId)
{
DISKCONTEXT* Context;
ULONG DriveNumber, DrivePartition, SectorSize;
ULONGLONG SectorOffset = 0;
PARTITION_TABLE_ENTRY PartitionTableEntry;
CHAR FileName[1];
if (!DissectArcPath(Path, FileName, &DriveNumber, &DrivePartition))
return EINVAL;
SectorSize = (DrivePartition == 0xff ? 2048 : 512);
if (DrivePartition != 0xff && DrivePartition != 0)
{
if (!MachDiskGetPartitionEntry(DriveNumber, DrivePartition, &PartitionTableEntry))
return EINVAL;
SectorOffset = PartitionTableEntry.SectorCountBeforePartition;
}
Context = MmHeapAlloc(sizeof(DISKCONTEXT));
if (!Context)
return ENOMEM;
Context->DriveNumber = DriveNumber;
Context->SectorSize = SectorSize;
Context->SectorOffset = SectorOffset;
Context->SectorNumber = 0;
FsSetDeviceSpecific(*FileId, Context);
return ESUCCESS;
}
static LONG DiskRead(ULONG FileId, VOID* Buffer, ULONG N, ULONG* Count)
{
DISKCONTEXT* Context = FsGetDeviceSpecific(FileId);
BOOLEAN ret;
*Count = 0;
if (N & (Context->SectorSize - 1))
return EINVAL;
ret = MachDiskReadLogicalSectors(
Context->DriveNumber,
Context->SectorNumber + Context->SectorOffset,
N / Context->SectorSize,
Buffer);
if (!ret)
return EIO;
*Count = N;
return ESUCCESS;
}
static LONG DiskSeek(ULONG FileId, LARGE_INTEGER* Position, SEEKMODE SeekMode)
{
DISKCONTEXT* Context = FsGetDeviceSpecific(FileId);
if (SeekMode != SeekAbsolute)
return EINVAL;
if (Position->LowPart & (Context->SectorSize - 1))
return EINVAL;
/* FIXME: take HighPart into account */
Context->SectorNumber = Position->LowPart / Context->SectorSize;
return ESUCCESS;
}
static const DEVVTBL DiskVtbl = {
DiskClose,
DiskGetFileInformation,
DiskOpen,
DiskRead,
DiskSeek,
};
static VOID
SetHarddiskIdentifier(PCONFIGURATION_COMPONENT_DATA DiskKey,
@ -407,6 +500,7 @@ SetHarddiskIdentifier(PCONFIGURATION_COMPONENT_DATA DiskKey,
ULONG Signature;
CHAR Identifier[20];
CHAR ArcName[256];
PARTITION_TABLE_ENTRY PartitionTableEntry;
/* Read the MBR */
if (!MachDiskReadLogicalSectors(DriveNumber, 0ULL, 1, (PVOID)DISKREADBUFFER))
@ -439,6 +533,21 @@ SetHarddiskIdentifier(PCONFIGURATION_COMPONENT_DATA DiskKey,
reactos_arc_strings[reactos_disk_count];
reactos_disk_count++;
sprintf(ArcName, "multi(0)disk(0)rdisk(%lu)partition(0)", DriveNumber - 0x80);
FsRegisterDevice(ArcName, &DiskVtbl);
/* Add partitions */
i = 0;
while (MachDiskGetPartitionEntry(DriveNumber, i, &PartitionTableEntry))
{
if (PartitionTableEntry.SystemIndicator != PARTITION_ENTRY_UNUSED)
{
sprintf(ArcName, "multi(0)disk(0)rdisk(%lu)partition(%lu)", DriveNumber - 0x80, i);
FsRegisterDevice(ArcName, &DiskVtbl);
}
i++;
}
/* Convert checksum and signature to identifier string */
Identifier[0] = Hex[(Checksum >> 28) & 0x0F];
Identifier[1] = Hex[(Checksum >> 24) & 0x0F];
@ -776,6 +885,9 @@ DetectBiosDisks(PCONFIGURATION_COMPONENT_DATA SystemKey,
SetHarddiskConfigurationData(DiskKey, 0x80 + i);
SetHarddiskIdentifier(DiskKey, 0x80 + i);
}
/* Also add one cdrom drive */
FsRegisterDevice("multi(0)disk(0)cdrom(224)", &DiskVtbl);
}
static VOID

View file

@ -26,6 +26,8 @@ VOID BootMain(LPSTR CmdLine)
MachInit(CmdLine);
FsInit();
DebugInit();
DPRINTM(DPRINT_WARNING, "BootMain() called.\n");

View file

@ -319,3 +319,279 @@ VOID FsGetFirstNameFromPath(PCHAR Buffer, PCSTR Path)
DPRINTM(DPRINT_FILESYSTEM, "FatGetFirstNameFromPath() Path = %s FirstName = %s\n", Path, Buffer);
}
LONG CompatFsClose(ULONG FileId)
{
PFILE FileHandle = FsGetDeviceSpecific(FileId);
FsCloseFile(FileHandle);
return ESUCCESS;
}
LONG CompatFsGetFileInformation(ULONG FileId, FILEINFORMATION* Information)
{
PFILE FileHandle = FsGetDeviceSpecific(FileId);
memset(Information, 0, sizeof(FILEINFORMATION));
Information->EndingAddress.LowPart = FsGetFileSize(FileHandle);
Information->CurrentAddress.LowPart = FsGetFilePointer(FileHandle);
return ESUCCESS;
}
LONG CompatFsOpen(CHAR* Path, OPENMODE OpenMode, ULONG* FileId)
{
PFILE FileHandle;
static BOOLEAN bVolumeOpened = FALSE;
if (!bVolumeOpened)
{
bVolumeOpened = FsOpenBootVolume();
if (!bVolumeOpened)
return EIO;
}
FileHandle = FsOpenFile(Path);
if (!FileHandle)
return EIO;
FsSetDeviceSpecific(*FileId, FileHandle);
return ESUCCESS;
}
LONG CompatFsRead(ULONG FileId, VOID* Buffer, ULONG N, ULONG* Count)
{
PFILE FileHandle = FsGetDeviceSpecific(FileId);
BOOLEAN ret;
ret = FsReadFile(FileHandle, N, Count, Buffer);
return (ret ? ESUCCESS : EFAULT);
}
LONG CompatFsSeek(ULONG FileId, LARGE_INTEGER* Position, SEEKMODE SeekMode)
{
PFILE FileHandle = FsGetDeviceSpecific(FileId);
if (SeekMode != SeekAbsolute)
return EINVAL;
FsSetFilePointer(FileHandle, Position->LowPart);
return ESUCCESS;
}
const DEVVTBL CompatFsFuncTable = {
CompatFsClose,
CompatFsGetFileInformation,
CompatFsOpen,
CompatFsRead,
CompatFsSeek,
};
#define MAX_FDS 20
typedef struct tagFILEDATA
{
ULONG DeviceId;
ULONG ReferenceCount;
const DEVVTBL* FuncTable;
const DEVVTBL* FileFuncTable;
VOID* Specific;
} FILEDATA;
typedef struct tagDEVICE
{
LIST_ENTRY ListEntry;
const DEVVTBL* FuncTable;
CHAR* Prefix;
ULONG DeviceId;
ULONG ReferenceCount;
} DEVICE;
static FILEDATA FileData[MAX_FDS];
static LIST_ENTRY DeviceListHead;
LONG ArcClose(ULONG FileId)
{
LONG ret;
if (FileId >= MAX_FDS || !FileData[FileId].FuncTable)
return EBADF;
ret = FileData[FileId].FuncTable->Close(FileId);
if (ret == ESUCCESS)
{
FileData[FileId].FuncTable = NULL;
FileData[FileId].Specific = NULL;
}
return ret;
}
LONG ArcGetFileInformation(ULONG FileId, FILEINFORMATION* Information)
{
if (FileId >= MAX_FDS || !FileData[FileId].FuncTable)
return EBADF;
return FileData[FileId].FuncTable->GetFileInformation(FileId, Information);
}
LONG ArcOpen(CHAR* Path, OPENMODE OpenMode, ULONG* FileId)
{
ULONG i, ret;
PLIST_ENTRY pEntry;
DEVICE* pDevice;
CHAR* DeviceName;
CHAR* FileName;
CHAR* p;
CHAR* q;
ULONG dwCount, dwLength;
OPENMODE DeviceOpenMode;
ULONG DeviceId;
*FileId = MAX_FDS;
/* Search last ')', which delimits device and path */
FileName = strrchr(Path, ')');
if (!FileName)
return EINVAL;
FileName++;
/* Count number of "()", which needs to be replaced by "(0)" */
dwCount = 0;
for (p = Path; p != FileName; p++)
if (*p == '(' && *(p + 1) == ')')
dwCount++;
/* Duplicate device name, and replace "()" by "(0)" (if required) */
dwLength = FileName - Path + dwCount;
if (dwCount != 0)
{
DeviceName = MmHeapAlloc(FileName - Path + dwCount);
if (!DeviceName)
return ENOMEM;
for (p = Path, q = DeviceName; p != FileName; p++)
{
*q++ = *p;
if (*p == '(' && *(p + 1) == ')')
*q++ = '0';
}
}
else
DeviceName = Path;
/* Search for the device */
pEntry = DeviceListHead.Flink;
if (OpenMode == OpenReadOnly || OpenMode == OpenWriteOnly)
DeviceOpenMode = OpenMode;
else
DeviceOpenMode = OpenReadWrite;
while (pEntry != &DeviceListHead)
{
pDevice = CONTAINING_RECORD(pEntry, DEVICE, ListEntry);
if (strncmp(pDevice->Prefix, DeviceName, dwLength) == 0)
{
/* OK, device found. It is already opened? */
if (pDevice->ReferenceCount == 0)
{
/* Search some room for the device */
for (DeviceId = 0; DeviceId < MAX_FDS; DeviceId++)
if (!FileData[DeviceId].FuncTable)
break;
if (DeviceId == MAX_FDS)
return EMFILE;
/* Try to open the device */
FileData[DeviceId].FuncTable = pDevice->FuncTable;
ret = pDevice->FuncTable->Open(pDevice->Prefix, DeviceOpenMode, &DeviceId);
if (ret != ESUCCESS)
{
FileData[DeviceId].FuncTable = NULL;
return ret;
}
/* Try to detect the file system */
/* FIXME: we link there to old infrastructure... */
FileData[DeviceId].FileFuncTable = &CompatFsFuncTable;
pDevice->DeviceId = DeviceId;
}
else
{
DeviceId = pDevice->DeviceId;
}
pDevice->ReferenceCount++;
break;
}
pEntry = pEntry->Flink;
}
if (pEntry == &DeviceListHead)
return ENODEV;
/* At this point, device is found and opened. Its file id is stored
* in DeviceId, and FileData[DeviceId].FileFuncTable contains what
* needs to be called to open the file */
/* Search some room for the device */
for (i = 0; i < MAX_FDS; i++)
if (!FileData[i].FuncTable)
break;
if (i == MAX_FDS)
return EMFILE;
/* Open the file */
FileData[i].FuncTable = FileData[DeviceId].FileFuncTable;
*FileId = i;
ret = FileData[i].FuncTable->Open(FileName, OpenMode, FileId);
if (ret != ESUCCESS)
{
FileData[i].FuncTable = NULL;
*FileId = MAX_FDS;
}
return ret;
}
LONG ArcRead(ULONG FileId, VOID* Buffer, ULONG N, ULONG* Count)
{
if (FileId >= MAX_FDS || !FileData[FileId].FuncTable)
return EBADF;
return FileData[FileId].FuncTable->Read(FileId, Buffer, N, Count);
}
LONG ArcSeek(ULONG FileId, LARGE_INTEGER* Position, SEEKMODE SeekMode)
{
if (FileId >= MAX_FDS || !FileData[FileId].FuncTable)
return EBADF;
return FileData[FileId].FuncTable->Seek(FileId, Position, SeekMode);
}
VOID FsRegisterDevice(CHAR* Prefix, const DEVVTBL* FuncTable)
{
DEVICE* pNewEntry;
ULONG dwLength;
dwLength = strlen(Prefix) + 1;
pNewEntry = MmHeapAlloc(sizeof(DEVICE) + dwLength);
if (!pNewEntry)
return;
pNewEntry->FuncTable = FuncTable;
pNewEntry->ReferenceCount = 0;
pNewEntry->Prefix = (CHAR*)(pNewEntry + 1);
memcpy(pNewEntry->Prefix, Prefix, dwLength);
InsertHeadList(&DeviceListHead, &pNewEntry->ListEntry);
}
VOID FsSetDeviceSpecific(ULONG FileId, VOID* Specific)
{
if (FileId >= MAX_FDS || !FileData[FileId].FuncTable)
return;
FileData[FileId].Specific = Specific;
}
VOID* FsGetDeviceSpecific(ULONG FileId)
{
if (FileId >= MAX_FDS || !FileData[FileId].FuncTable)
return NULL;
return FileData[FileId].Specific;
}
VOID FsInit(VOID)
{
memset(FileData, 0, sizeof(FileData));
InitializeListHead(&DeviceListHead);
}

View file

@ -20,6 +20,14 @@
#ifndef __FS_H
#define __FS_H
typedef struct tagDEVVTBL
{
ARC_CLOSE Close;
ARC_GET_FILE_INFORMATION GetFileInformation;
ARC_OPEN Open;
ARC_READ Read;
ARC_SEEK Seek;
} DEVVTBL;
//#define EOF -1
@ -33,6 +41,17 @@
#define FILE VOID
#define PFILE FILE *
VOID FsRegisterDevice(CHAR* Prefix, const DEVVTBL* FuncTable);
VOID FsSetDeviceSpecific(ULONG FileId, VOID* Specific);
VOID* FsGetDeviceSpecific(ULONG FileId);
VOID FsInit(VOID);
LONG ArcClose(ULONG FileId);
LONG ArcGetFileInformation(ULONG FileId, FILEINFORMATION* Information);
LONG ArcOpen(CHAR* Path, OPENMODE OpenMode, ULONG* FileId);
LONG ArcRead(ULONG FileId, VOID* Buffer, ULONG N, ULONG* Count);
LONG ArcSeek(ULONG FileId, LARGE_INTEGER* Position, SEEKMODE SeekMode);
VOID FileSystemError(PCSTR ErrorString);
BOOLEAN FsOpenBootVolume();
BOOLEAN FsOpenSystemVolume(PCHAR SystemPath, PCHAR RemainingPath, PULONG BootDevice);

View file

@ -28,6 +28,10 @@
#include "mm.h"
#endif
#ifndef __FS_H
#include "fs.h"
#endif
typedef enum tagVIDEODISPLAYMODE
{
VideoTextMode,

View file

@ -255,14 +255,15 @@ WinLdrLoadImage(IN PCHAR FileName,
TYPE_OF_MEMORY MemoryType,
OUT PVOID *ImageBasePA)
{
PFILE FileHandle;
ULONG FileId;
PVOID PhysicalBase;
PVOID VirtualBase = NULL;
UCHAR HeadersBuffer[SECTOR_SIZE * 2];
PIMAGE_NT_HEADERS NtHeaders;
PIMAGE_SECTION_HEADER SectionHeader;
ULONG VirtualSize, SizeOfRawData, NumberOfSections;
BOOLEAN Status;
LONG Status;
LARGE_INTEGER Position;
ULONG i, BytesRead;
CHAR ProgressString[256];
@ -272,22 +273,19 @@ WinLdrLoadImage(IN PCHAR FileName,
UiDrawProgressBarCenter(1, 100, ProgressString);
/* Open the image file */
FileHandle = FsOpenFile(FileName);
if (FileHandle == NULL)
Status = ArcOpen(FileName, OpenReadOnly, &FileId);
if (Status != ESUCCESS)
{
//Print(L"Can not open the file %s\n",FileName);
UiMessageBox("Can not open the file");
return FALSE;
}
/* Load the first 2 sectors of the image so we can read the PE header */
Status = FsReadFile(FileHandle, SECTOR_SIZE * 2, NULL, HeadersBuffer);
if (!Status)
Status = ArcRead(FileId, HeadersBuffer, SECTOR_SIZE * 2, &BytesRead);
if (Status != ESUCCESS)
{
//Print(L"Error reading from file %s\n", FileName);
UiMessageBox("Error reading from file");
FsCloseFile(FileHandle);
ArcClose(FileId);
return FALSE;
}
@ -298,7 +296,7 @@ WinLdrLoadImage(IN PCHAR FileName,
{
//Print(L"Error - no NT header found in %s\n", FileName);
UiMessageBox("Error - no NT header found");
FsCloseFile(FileHandle);
ArcClose(FileId);
return FALSE;
}
@ -307,7 +305,7 @@ WinLdrLoadImage(IN PCHAR FileName,
{
//Print(L"Not an executable image %s\n", FileName);
UiMessageBox("Not an executable image");
FsCloseFile(FileHandle);
ArcClose(FileId);
return FALSE;
}
@ -329,7 +327,7 @@ WinLdrLoadImage(IN PCHAR FileName,
{
//Print(L"Failed to alloc pages for image %s\n", FileName);
UiMessageBox("Failed to alloc pages for image");
FsCloseFile(FileHandle);
ArcClose(FileId);
return FALSE;
}
}
@ -340,15 +338,22 @@ WinLdrLoadImage(IN PCHAR FileName,
DPRINTM(DPRINT_PELOADER, "Base PA: 0x%X, VA: 0x%X\n", PhysicalBase, VirtualBase);
/* Set to 0 position and fully load the file image */
FsSetFilePointer(FileHandle, 0);
Position.HighPart = Position.LowPart = 0;
Status = ArcSeek(FileId, &Position, SeekAbsolute);
if (Status != ESUCCESS)
{
UiMessageBox("Error seeking to start of file");
ArcClose(FileId);
return FALSE;
}
Status = FsReadFile(FileHandle, NtHeaders->OptionalHeader.SizeOfHeaders, NULL, PhysicalBase);
Status = ArcRead(FileId, PhysicalBase, NtHeaders->OptionalHeader.SizeOfHeaders, &BytesRead);
if (!Status)
if (Status != ESUCCESS)
{
//Print(L"Error reading headers %s\n", FileName);
UiMessageBox("Error reading headers");
FsCloseFile(FileHandle);
ArcClose(FileId);
return FALSE;
}
@ -388,14 +393,15 @@ WinLdrLoadImage(IN PCHAR FileName,
if (SizeOfRawData != 0)
{
/* Seek to the correct position */
FsSetFilePointer(FileHandle, SectionHeader->PointerToRawData);
Position.LowPart = SectionHeader->PointerToRawData;
Status = ArcSeek(FileId, &Position, SeekAbsolute);
DPRINTM(DPRINT_PELOADER, "SH->VA: 0x%X\n", SectionHeader->VirtualAddress);
/* Read this section from the file, size = SizeOfRawData */
Status = FsReadFile(FileHandle, SizeOfRawData, &BytesRead, (PUCHAR)PhysicalBase + SectionHeader->VirtualAddress);
Status = ArcRead(FileId, (PUCHAR)PhysicalBase + SectionHeader->VirtualAddress, SizeOfRawData, &BytesRead);
if (!Status && (BytesRead == 0))
if (Status != ESUCCESS)
{
DPRINTM(DPRINT_PELOADER, "WinLdrLoadImage(): Error reading section from file!\n");
break;
@ -413,10 +419,10 @@ WinLdrLoadImage(IN PCHAR FileName,
}
/* We are done with the file - close it */
FsCloseFile(FileHandle);
ArcClose(FileId);
/* If loading failed - return right now */
if (!Status)
if (Status != ESUCCESS)
return FALSE;
@ -425,7 +431,7 @@ WinLdrLoadImage(IN PCHAR FileName,
{
DPRINTM(DPRINT_PELOADER, "Relocating %p -> %p\n",
NtHeaders->OptionalHeader.ImageBase, VirtualBase);
Status = (BOOLEAN)LdrRelocateImageWithBias(PhysicalBase,
return (BOOLEAN)LdrRelocateImageWithBias(PhysicalBase,
(ULONG_PTR)VirtualBase - (ULONG_PTR)PhysicalBase,
"FreeLdr",
TRUE,
@ -433,7 +439,7 @@ WinLdrLoadImage(IN PCHAR FileName,
FALSE);
}
return Status;
return TRUE;
}
/* PRIVATE FUNCTIONS *******************************************************/

View file

@ -161,7 +161,6 @@ VOID LoadReactOSSetup2(VOID)
LPCSTR BootOptions;
PVOID NtosBase = NULL, HalBase = NULL, KdComBase = NULL;
BOOLEAN Status;
ULONG BootDevice;
ULONG i, ErrorLine;
HINF InfHandle;
INFCONTEXT InfContext;
@ -188,10 +187,11 @@ VOID LoadReactOSSetup2(VOID)
NULL
};
/* Get boot device number */
MachDiskGetBootDevice(&BootDevice);
/* Try to open system drive */
FsOpenBootVolume();
/* Open 'txtsetup.sif' from any of source paths */
MachDiskGetBootPath(SystemPath, sizeof(SystemPath));
for (i = MachDiskBootingFromFloppy() ? 0 : 1; ; i++)
{
SourcePath = SourcePaths[i];
@ -200,15 +200,14 @@ VOID LoadReactOSSetup2(VOID)
printf("Failed to open 'txtsetup.sif'\n");
return;
}
sprintf(FileName,"%s\\txtsetup.sif", SourcePath);
sprintf(FileName, "%s\\txtsetup.sif", SourcePath);
if (InfOpenFile (&InfHandle, FileName, &ErrorLine))
{
sprintf(BootPath, "%s%s\\", SystemPath, SourcePath);
break;
}
}
/* If we didn't find it anywhere, then just use root */
if (!*SourcePath)
SourcePath = "\\";
/* Load options */
if (!InfFindFirstLine(InfHandle,
"SetupData",
@ -225,9 +224,6 @@ VOID LoadReactOSSetup2(VOID)
return;
}
/* Save source path */
strcpy(BootPath, SourcePath);
SetupUiInitialize();
UiDrawStatusText("");
UiDrawStatusText("Detecting Hardware...");
@ -235,18 +231,8 @@ VOID LoadReactOSSetup2(VOID)
/* Let user know we started loading */
UiDrawStatusText("Loading...");
/* Try to open system drive */
FsOpenBootVolume();
/* Append a backslash to the bootpath if needed */
if ((strlen(BootPath)==0) || BootPath[strlen(BootPath)] != '\\')
{
strcat(BootPath, "\\");
}
/* Construct the system path */
MachDiskGetBootPath(SystemPath, sizeof(SystemPath));
strcat(SystemPath, SourcePath);
sprintf(SystemPath, "%s\\", SourcePath);
DPRINTM(DPRINT_WINDOWS,"SystemRoot: '%s', SystemPath: '%s'\n", BootPath, SystemPath);

View file

@ -374,10 +374,12 @@ WinLdrLoadBootDrivers(PLOADER_PARAMETER_BLOCK LoaderBlock,
PVOID WinLdrLoadModule(PCSTR ModuleName, ULONG *Size,
TYPE_OF_MEMORY MemoryType)
{
PFILE FileHandle;
ULONG FileId;
PVOID PhysicalBase;
FILEINFORMATION FileInfo;
ULONG FileSize;
BOOLEAN Status;
ULONG Status;
ULONG BytesRead;
//CHAR ProgressString[256];
@ -389,39 +391,41 @@ PVOID WinLdrLoadModule(PCSTR ModuleName, ULONG *Size,
*Size = 0;
/* Open the image file */
FileHandle = FsOpenFile(ModuleName);
if (FileHandle == NULL)
Status = ArcOpen((PCHAR)ModuleName, OpenReadOnly, &FileId);
if (Status != ESUCCESS)
{
/* In case of errors, we just return, without complaining to the user */
return NULL;
}
/* Get this file's size */
FileSize = FsGetFileSize(FileHandle);
Status = ArcGetFileInformation(FileId, &FileInfo);
if (Status != ESUCCESS)
{
ArcClose(FileId);
return NULL;
}
FileSize = FileInfo.EndingAddress.LowPart;
*Size = FileSize;
/* Allocate memory */
PhysicalBase = MmAllocateMemoryWithType(FileSize, MemoryType);
if (PhysicalBase == NULL)
{
FsCloseFile(FileHandle);
ArcClose(FileId);
return NULL;
}
/* Load whole file */
Status = FsReadFile(FileHandle, FileSize, NULL, PhysicalBase);
if (!Status)
Status = ArcRead(FileId, PhysicalBase, FileSize, &BytesRead);
ArcClose(FileId);
if (Status != ESUCCESS)
{
FsCloseFile(FileHandle);
return NULL;
}
DPRINTM(DPRINT_WINDOWS, "Loaded %s at 0x%x with size 0x%x\n", ModuleName, PhysicalBase, FileSize);
/* We are done with the file - close it */
FsCloseFile(FileHandle);
return PhysicalBase;
}
@ -437,7 +441,6 @@ LoadAndBootWindows(PCSTR OperatingSystemName, USHORT OperatingSystemVersion)
PVOID NtosBase = NULL, HalBase = NULL, KdComBase = NULL;
BOOLEAN Status;
ULONG SectionId;
ULONG BootDevice;
PLOADER_PARAMETER_BLOCK LoaderBlock, LoaderBlockVA;
KERNEL_ENTRY_POINT KiSystemStartup;
PLDR_DATA_TABLE_ENTRY KernelDTE, HalDTE, KdComDTE = NULL;
@ -476,25 +479,19 @@ LoadAndBootWindows(PCSTR OperatingSystemName, USHORT OperatingSystemVersion)
strcpy(BootOptions, "");
}
/* Normalize system path */
if (!MachDiskNormalizeSystemPath(SystemPath, sizeof(SystemPath)))
/* Special case for LiveCD */
if (!_strnicmp(SystemPath, "LiveCD", strlen("LiveCD")))
{
UiMessageBox("Invalid system path");
return;
strcpy(BootPath, SystemPath + strlen("LiveCD"));
MachDiskGetBootPath(SystemPath, sizeof(SystemPath));
strcat(SystemPath, BootPath);
}
/* Let user know we started loading */
UiDrawStatusText("Loading...");
/* Try to open system drive */
BootDevice = 0xffffffff;
if (!FsOpenSystemVolume(SystemPath, BootPath, &BootDevice))
{
UiMessageBox("Failed to open boot drive.");
return;
}
/* append a backslash */
strcpy(BootPath, SystemPath);
if ((strlen(BootPath)==0) ||
BootPath[strlen(BootPath)] != '\\')
strcat(BootPath, "\\");

View file

@ -42,34 +42,37 @@ WinLdrLoadSystemHive(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
IN LPCSTR DirectoryPath,
IN LPCSTR HiveName)
{
PFILE FileHandle;
ULONG FileId;
CHAR FullHiveName[256];
BOOLEAN Status;
LONG Status;
FILEINFORMATION FileInfo;
ULONG HiveFileSize;
ULONG_PTR HiveDataPhysical;
PVOID HiveDataVirtual;
ULONG BytesRead;
/* Concatenate path and filename to get the full name */
strcpy(FullHiveName, DirectoryPath);
strcat(FullHiveName, HiveName);
//Print(L"Loading %s...\n", FullHiveName);
FileHandle = FsOpenFile(FullHiveName);
Status = ArcOpen(FullHiveName, OpenReadOnly, &FileId);
if (FileHandle == NULL)
if (Status != ESUCCESS)
{
UiMessageBox("Opening hive file failed!");
return FALSE;
}
/* Get the file length */
HiveFileSize = FsGetFileSize(FileHandle);
Status = ArcGetFileInformation(FileId, &FileInfo);
if (HiveFileSize == 0)
if (Status != ESUCCESS)
{
FsCloseFile(FileHandle);
ArcClose(FileId);
UiMessageBox("Hive file has 0 size!");
return FALSE;
}
HiveFileSize = FileInfo.EndingAddress.LowPart;
/* Round up the size to page boundary and alloc memory */
HiveDataPhysical = (ULONG_PTR)MmAllocateMemoryWithType(
@ -78,7 +81,7 @@ WinLdrLoadSystemHive(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
if (HiveDataPhysical == 0)
{
FsCloseFile(FileHandle);
ArcClose(FileId);
UiMessageBox("Unable to alloc memory for a hive!");
return FALSE;
}
@ -91,9 +94,9 @@ WinLdrLoadSystemHive(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
LoaderBlock->RegistryBase = HiveDataVirtual;
/* Finally read from file to the memory */
Status = FsReadFile(FileHandle, HiveFileSize, NULL, (PVOID)HiveDataPhysical);
FsCloseFile(FileHandle);
if (!Status)
Status = ArcRead(FileId, (PVOID)HiveDataPhysical, HiveFileSize, &BytesRead);
ArcClose(FileId);
if (Status != ESUCCESS)
{
UiMessageBox("Unable to read from hive file!");
return FALSE;
@ -272,14 +275,16 @@ WinLdrLoadNLSData(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
IN LPCSTR LanguageFileName)
{
CHAR FileName[255];
PFILE AnsiFileHandle;
PFILE OemFileHandle;
PFILE LanguageFileHandle;
ULONG AnsiFileId;
ULONG OemFileId;
ULONG LanguageFileId;
ULONG AnsiFileSize, OemFileSize, LanguageFileSize;
ULONG TotalSize;
ULONG_PTR NlsDataBase;
PVOID NlsVirtual;
BOOLEAN Status, AnsiEqualsOem = FALSE;
BOOLEAN AnsiEqualsOem = FALSE;
FILEINFORMATION FileInfo;
ULONG BytesRead, Status;
/* There may be a case, when OEM and ANSI page coincide */
if (!strcmp(AnsiFileName, OemFileName))
@ -289,14 +294,17 @@ WinLdrLoadNLSData(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
//Print(L"Loading %s...\n", Filename);
strcpy(FileName, DirectoryPath);
strcat(FileName, AnsiFileName);
AnsiFileHandle = FsOpenFile(FileName);
Status = ArcOpen(FileName, OpenReadOnly, &AnsiFileId);
if (AnsiFileHandle == NULL)
if (Status != ESUCCESS)
goto Failure;
AnsiFileSize = FsGetFileSize(AnsiFileHandle);
Status = ArcGetFileInformation(AnsiFileId, &FileInfo);
if (Status != ESUCCESS)
goto Failure;
AnsiFileSize = FileInfo.EndingAddress.LowPart;
DPRINTM(DPRINT_WINDOWS, "AnsiFileSize: %d\n", AnsiFileSize);
FsCloseFile(AnsiFileHandle);
ArcClose(AnsiFileId);
/* Open OEM file and store its length */
if (AnsiEqualsOem)
@ -308,13 +316,16 @@ WinLdrLoadNLSData(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
//Print(L"Loading %s...\n", Filename);
strcpy(FileName, DirectoryPath);
strcat(FileName, OemFileName);
OemFileHandle = FsOpenFile(FileName);
Status = ArcOpen(FileName, OpenReadOnly, &OemFileId);
if (OemFileHandle == NULL)
if (Status != ESUCCESS)
goto Failure;
OemFileSize = FsGetFileSize(OemFileHandle);
FsCloseFile(OemFileHandle);
Status = ArcGetFileInformation(OemFileId, &FileInfo);
if (Status != ESUCCESS)
goto Failure;
OemFileSize = FileInfo.EndingAddress.LowPart;
ArcClose(OemFileId);
}
DPRINTM(DPRINT_WINDOWS, "OemFileSize: %d\n", OemFileSize);
@ -322,13 +333,16 @@ WinLdrLoadNLSData(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
//Print(L"Loading %s...\n", Filename);
strcpy(FileName, DirectoryPath);
strcat(FileName, LanguageFileName);
LanguageFileHandle = FsOpenFile(FileName);
Status = ArcOpen(FileName, OpenReadOnly, &LanguageFileId);
if (LanguageFileHandle == NULL)
if (Status != ESUCCESS)
goto Failure;
LanguageFileSize = FsGetFileSize(LanguageFileHandle);
FsCloseFile(LanguageFileHandle);
Status = ArcGetFileInformation(LanguageFileId, &FileInfo);
if (Status != ESUCCESS)
goto Failure;
LanguageFileSize = FileInfo.EndingAddress.LowPart;
ArcClose(LanguageFileId);
DPRINTM(DPRINT_WINDOWS, "LanguageFileSize: %d\n", LanguageFileSize);
/* Sum up all three length, having in mind that every one of them
@ -361,50 +375,50 @@ WinLdrLoadNLSData(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
/* Now actually read the data into memory, starting with Ansi file */
strcpy(FileName, DirectoryPath);
strcat(FileName, AnsiFileName);
AnsiFileHandle = FsOpenFile(FileName);
Status = ArcOpen(FileName, OpenReadOnly, &AnsiFileId);
if (AnsiFileHandle == NULL)
if (Status != ESUCCESS)
goto Failure;
Status = FsReadFile(AnsiFileHandle, AnsiFileSize, NULL, VaToPa(LoaderBlock->NlsData->AnsiCodePageData));
Status = ArcRead(AnsiFileId, VaToPa(LoaderBlock->NlsData->AnsiCodePageData), AnsiFileSize, &BytesRead);
if (!Status)
if (Status != ESUCCESS)
goto Failure;
FsCloseFile(AnsiFileHandle);
ArcClose(AnsiFileId);
/* OEM now, if it doesn't equal Ansi of course */
if (!AnsiEqualsOem)
{
strcpy(FileName, DirectoryPath);
strcat(FileName, OemFileName);
OemFileHandle = FsOpenFile(FileName);
Status = ArcOpen(FileName, OpenReadOnly, &OemFileId);
if (OemFileHandle == NULL)
if (Status != ESUCCESS)
goto Failure;
Status = FsReadFile(OemFileHandle, OemFileSize, NULL, VaToPa(LoaderBlock->NlsData->OemCodePageData));
Status = ArcRead(OemFileId, VaToPa(LoaderBlock->NlsData->OemCodePageData), OemFileSize, &BytesRead);
if (!Status)
if (Status != ESUCCESS)
goto Failure;
FsCloseFile(OemFileHandle);
ArcClose(OemFileId);
}
/* finally the language file */
strcpy(FileName, DirectoryPath);
strcat(FileName, LanguageFileName);
LanguageFileHandle = FsOpenFile(FileName);
Status = ArcOpen(FileName, OpenReadOnly, &LanguageFileId);
if (LanguageFileHandle == NULL)
if (Status != ESUCCESS)
goto Failure;
Status = FsReadFile(LanguageFileHandle, LanguageFileSize, NULL, VaToPa(LoaderBlock->NlsData->UnicodeCodePageData));
Status = ArcRead(LanguageFileId, VaToPa(LoaderBlock->NlsData->UnicodeCodePageData), LanguageFileSize, &BytesRead);
if (!Status)
if (Status != ESUCCESS)
goto Failure;
FsCloseFile(LanguageFileHandle);
ArcClose(LanguageFileId);
//
// THIS IS HAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACK