Пример #1
0
VOID
List_PaToVa(LIST_ENTRY *ListEntry)
{
	LIST_ENTRY *ListHead = ListEntry;
	LIST_ENTRY *Next = ListEntry->Flink;
	LIST_ENTRY *NextPA;

	//Print(L"\n\nList_Entry: %X, First Next: %X\n", ListEntry, Next);
	//
	// Walk through the whole list
	//
	if (Next != NULL)
	{
		while (Next != PaToVa(ListHead))
		{
			NextPA = VaToPa(Next);
			//Print(L"Current: %X, Flink: %X, Blink: %X\n", Next, NextPA->Flink, NextPA->Blink);

			NextPA->Flink = PaToVa((PVOID)NextPA->Flink);
			NextPA->Blink = PaToVa((PVOID)NextPA->Blink);

			//Print(L"After converting Flink: %X, Blink: %X\n", NextPA->Flink, NextPA->Blink);

			Next = NextPA->Flink;
		}

		//
		// Finally convert first Flink/Blink
		//
		ListEntry->Flink = PaToVa((PVOID)ListEntry->Flink);
		if (ListEntry->Blink)
			ListEntry->Blink = PaToVa((PVOID)ListEntry->Blink);
	}
}
Пример #2
0
BOOLEAN
WinLdrLoadBootDrivers(PLOADER_PARAMETER_BLOCK LoaderBlock,
                      LPCSTR BootPath)
{
    PLIST_ENTRY NextBd;
    PBOOT_DRIVER_LIST_ENTRY BootDriver;
    BOOLEAN Success;
    BOOLEAN ret = TRUE;

    // Walk through the boot drivers list
    NextBd = LoaderBlock->BootDriverListHead.Flink;

    while (NextBd != &LoaderBlock->BootDriverListHead)
    {
        BootDriver = CONTAINING_RECORD(NextBd, BOOT_DRIVER_LIST_ENTRY, Link);

        TRACE("BootDriver %wZ DTE %08X RegPath: %wZ\n", &BootDriver->FilePath,
            BootDriver->LdrEntry, &BootDriver->RegistryPath);

        // Paths are relative (FIXME: Are they always relative?)

        // Load it
        Success = WinLdrLoadDeviceDriver(&LoaderBlock->LoadOrderListHead,
                                         BootPath,
                                         &BootDriver->FilePath,
                                         0,
                                         &BootDriver->LdrEntry);

        if (Success)
        {
            // Convert the RegistryPath and DTE addresses to VA since we are not going to use it anymore
            BootDriver->RegistryPath.Buffer = PaToVa(BootDriver->RegistryPath.Buffer);
            BootDriver->FilePath.Buffer = PaToVa(BootDriver->FilePath.Buffer);
            BootDriver->LdrEntry = PaToVa(BootDriver->LdrEntry);
        }
        else
        {
            // Loading failed - cry loudly
            ERR("Can't load boot driver '%wZ'!\n", &BootDriver->FilePath);
            UiMessageBox("Can't load boot driver '%wZ'!", &BootDriver->FilePath);
            ret = FALSE;

            // Remove it from the list and try to continue
            RemoveEntryList(NextBd);
        }

        NextBd = BootDriver->Link.Flink;
    }

    return ret;
}
Пример #3
0
BOOLEAN
WinLdrLoadSystemHive(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
                     IN LPCSTR DirectoryPath,
                     IN LPCSTR HiveName)
{
	ULONG FileId;
	CHAR FullHiveName[256];
	LONG Status;
	FILEINFORMATION FileInfo;
	ULONG HiveFileSize;
	ULONG_PTR HiveDataPhysical;
	PVOID HiveDataVirtual;
	ULONG BytesRead;
	LPCWSTR FsService;

	/* Concatenate path and filename to get the full name */
	strcpy(FullHiveName, DirectoryPath);
	strcat(FullHiveName, HiveName);
	//Print(L"Loading %s...\n", FullHiveName);
	Status = ArcOpen(FullHiveName, OpenReadOnly, &FileId);

	if (Status != ESUCCESS)
	{
		UiMessageBox("Opening hive file failed!");
		return FALSE;
	}

	/* Get the file length */
	Status = ArcGetFileInformation(FileId, &FileInfo);

	if (Status != ESUCCESS)
	{
		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(
		MM_SIZE_TO_PAGES(HiveFileSize + MM_PAGE_SIZE - 1) << MM_PAGE_SHIFT,
		LoaderRegistryData);

	if (HiveDataPhysical == 0)
	{
		ArcClose(FileId);
		UiMessageBox("Unable to alloc memory for a hive!");
		return FALSE;
	}

	/* Convert address to virtual */
    HiveDataVirtual = PaToVa((PVOID)HiveDataPhysical);

	/* Fill LoaderBlock's entries */
	LoaderBlock->RegistryLength = HiveFileSize;
	LoaderBlock->RegistryBase = HiveDataVirtual;

	/* Finally read from file to the memory */
	Status = ArcRead(FileId, (PVOID)HiveDataPhysical, HiveFileSize, &BytesRead);
	if (Status != ESUCCESS)
	{
		ArcClose(FileId);
		UiMessageBox("Unable to read from hive file!");
		return FALSE;
	}

	// Add boot filesystem driver to the list
	FsService = FsGetServiceName(FileId);
	if (FsService)
	{
		TRACE("  Adding filesystem service %S\n", FsService);
		Status = WinLdrAddDriverToList(&LoaderBlock->BootDriverListHead,
			L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\",
			NULL,
			(LPWSTR)FsService);
		if (!Status)
			TRACE(" Failed to add filesystem service\n");
	}
	else
	{
		TRACE("  No required filesystem service\n");
	}

	ArcClose(FileId);
	return TRUE;
}
Пример #4
0
BOOLEAN
WinLdrLoadNLSData(IN OUT PLOADER_PARAMETER_BLOCK LoaderBlock,
                  IN LPCSTR DirectoryPath,
                  IN LPCSTR AnsiFileName,
                  IN LPCSTR OemFileName,
                  IN LPCSTR LanguageFileName)
{
	CHAR FileName[255];
	ULONG AnsiFileId;
	ULONG OemFileId;
	ULONG LanguageFileId;
	ULONG AnsiFileSize, OemFileSize, LanguageFileSize;
	ULONG TotalSize;
	ULONG_PTR NlsDataBase;
	PVOID NlsVirtual;
	BOOLEAN AnsiEqualsOem = FALSE;
	FILEINFORMATION FileInfo;
	ULONG BytesRead, Status;

	/* There may be a case, when OEM and ANSI page coincide */
	if (!strcmp(AnsiFileName, OemFileName))
		AnsiEqualsOem = TRUE;

	/* Open file with ANSI and store its size */
	//Print(L"Loading %s...\n", Filename);
	strcpy(FileName, DirectoryPath);
	strcat(FileName, AnsiFileName);
	Status = ArcOpen(FileName, OpenReadOnly, &AnsiFileId);

	if (Status != ESUCCESS)
		goto Failure;

	Status = ArcGetFileInformation(AnsiFileId, &FileInfo);
	if (Status != ESUCCESS)
		goto Failure;
	AnsiFileSize = FileInfo.EndingAddress.LowPart;
	TRACE("AnsiFileSize: %d\n", AnsiFileSize);
	ArcClose(AnsiFileId);

	/* Open OEM file and store its length */
	if (AnsiEqualsOem)
	{
		OemFileSize = 0;
	}
	else
	{
		//Print(L"Loading %s...\n", Filename);
		strcpy(FileName, DirectoryPath);
		strcat(FileName, OemFileName);
		Status = ArcOpen(FileName, OpenReadOnly, &OemFileId);

		if (Status != ESUCCESS)
			goto Failure;

		Status = ArcGetFileInformation(OemFileId, &FileInfo);
		if (Status != ESUCCESS)
			goto Failure;
		OemFileSize = FileInfo.EndingAddress.LowPart;
		ArcClose(OemFileId);
	}
	TRACE("OemFileSize: %d\n", OemFileSize);

	/* And finally open the language codepage file and store its length */
	//Print(L"Loading %s...\n", Filename);
	strcpy(FileName, DirectoryPath);
	strcat(FileName, LanguageFileName);
	Status = ArcOpen(FileName, OpenReadOnly, &LanguageFileId);

	if (Status != ESUCCESS)
		goto Failure;

	Status = ArcGetFileInformation(LanguageFileId, &FileInfo);
	if (Status != ESUCCESS)
		goto Failure;
	LanguageFileSize = FileInfo.EndingAddress.LowPart;
	ArcClose(LanguageFileId);
	TRACE("LanguageFileSize: %d\n", LanguageFileSize);

	/* Sum up all three length, having in mind that every one of them
	   must start at a page boundary => thus round up each file to a page */
	TotalSize = MM_SIZE_TO_PAGES(AnsiFileSize) +
		MM_SIZE_TO_PAGES(OemFileSize)  +
		MM_SIZE_TO_PAGES(LanguageFileSize);

	/* Store it for later marking the pages as NlsData type */
	TotalNLSSize = TotalSize;

	NlsDataBase = (ULONG_PTR)MmAllocateMemoryWithType(TotalSize*MM_PAGE_SIZE, LoaderNlsData);

	if (NlsDataBase == 0)
		goto Failure;

	NlsVirtual = PaToVa((PVOID)NlsDataBase);
	LoaderBlock->NlsData->AnsiCodePageData = NlsVirtual;
	LoaderBlock->NlsData->OemCodePageData = (PVOID)((PUCHAR)NlsVirtual +
		(MM_SIZE_TO_PAGES(AnsiFileSize) << MM_PAGE_SHIFT));
	LoaderBlock->NlsData->UnicodeCodePageData = (PVOID)((PUCHAR)NlsVirtual +
		(MM_SIZE_TO_PAGES(AnsiFileSize) << MM_PAGE_SHIFT) +
		(MM_SIZE_TO_PAGES(OemFileSize) << MM_PAGE_SHIFT));

	/* Ansi and OEM data are the same - just set pointers to the same area */
	if (AnsiEqualsOem)
		LoaderBlock->NlsData->OemCodePageData = LoaderBlock->NlsData->AnsiCodePageData;


	/* Now actually read the data into memory, starting with Ansi file */
	strcpy(FileName, DirectoryPath);
	strcat(FileName, AnsiFileName);
	Status = ArcOpen(FileName, OpenReadOnly, &AnsiFileId);

	if (Status != ESUCCESS)
		goto Failure;

	Status = ArcRead(AnsiFileId, VaToPa(LoaderBlock->NlsData->AnsiCodePageData), AnsiFileSize, &BytesRead);

	if (Status != ESUCCESS)
		goto Failure;

	ArcClose(AnsiFileId);

	/* OEM now, if it doesn't equal Ansi of course */
	if (!AnsiEqualsOem)
	{
		strcpy(FileName, DirectoryPath);
		strcat(FileName, OemFileName);
		Status = ArcOpen(FileName, OpenReadOnly, &OemFileId);

		if (Status != ESUCCESS)
			goto Failure;

		Status = ArcRead(OemFileId, VaToPa(LoaderBlock->NlsData->OemCodePageData), OemFileSize, &BytesRead);

		if (Status != ESUCCESS)
			goto Failure;

		ArcClose(OemFileId);
	}

	/* finally the language file */
	strcpy(FileName, DirectoryPath);
	strcat(FileName, LanguageFileName);
	Status = ArcOpen(FileName, OpenReadOnly, &LanguageFileId);

	if (Status != ESUCCESS)
		goto Failure;

	Status = ArcRead(LanguageFileId, VaToPa(LoaderBlock->NlsData->UnicodeCodePageData), LanguageFileSize, &BytesRead);

	if (Status != ESUCCESS)
		goto Failure;

	ArcClose(LanguageFileId);

	//
	// THIS IS HAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACK
	// Should go to WinLdrLoadOemHalFont(), when it will be implemented
	//
	LoaderBlock->OemFontFile = VaToPa(LoaderBlock->NlsData->UnicodeCodePageData);

	/* Convert NlsTables address to VA */
	LoaderBlock->NlsData = PaToVa(LoaderBlock->NlsData);

	return TRUE;

Failure:
	//UiMessageBox("Error reading NLS file %s\n", Filename);
	UiMessageBox("Error reading NLS file!");
	return FALSE;
}
Пример #5
0
/*
 * WinLdrLoadImage loads the specified image from the file (it doesn't
 * perform any additional operations on the filename, just directly
 * calls the file I/O routines), and relocates it so that it's ready
 * to be used when paging is enabled.
 * Addressing mode: physical
 */
BOOLEAN
WinLdrLoadImage(IN PCHAR FileName,
                TYPE_OF_MEMORY MemoryType,
                OUT PVOID *ImageBasePA)
{
    ULONG FileId;
    PVOID PhysicalBase;
    PVOID VirtualBase = NULL;
    UCHAR HeadersBuffer[SECTOR_SIZE * 2];
    PIMAGE_NT_HEADERS NtHeaders;
    PIMAGE_SECTION_HEADER SectionHeader;
    ULONG VirtualSize, SizeOfRawData, NumberOfSections;
    ARC_STATUS Status;
    LARGE_INTEGER Position;
    ULONG i, BytesRead;
    TRACE("WinLdrLoadImage(%s, %ld, *)\n", FileName, MemoryType);

    /* Open the image file */
    Status = ArcOpen(FileName, OpenReadOnly, &FileId);
    if (Status != ESUCCESS)
    {
        // UiMessageBox("Can not open the file.");
        return FALSE;
    }

    /* Load the first 2 sectors of the image so we can read the PE header */
    Status = ArcRead(FileId, HeadersBuffer, SECTOR_SIZE * 2, &BytesRead);
    if (Status != ESUCCESS)
    {
        UiMessageBox("Error reading from file.");
        ArcClose(FileId);
        return FALSE;
    }

    /* Now read the MZ header to get the offset to the PE Header */
    NtHeaders = RtlImageNtHeader(HeadersBuffer);
    if (!NtHeaders)
    {
        // Print(L"Error - no NT header found in %s\n", FileName);
        UiMessageBox("Error - no NT header found.");
        ArcClose(FileId);
        return FALSE;
    }

    /* Ensure this is executable image */
    if (((NtHeaders->FileHeader.Characteristics & IMAGE_FILE_EXECUTABLE_IMAGE) == 0))
    {
        // Print(L"Not an executable image %s\n", FileName);
        UiMessageBox("Not an executable image.");
        ArcClose(FileId);
        return FALSE;
    }

    /* Store number of sections to read and a pointer to the first section */
    NumberOfSections = NtHeaders->FileHeader.NumberOfSections;
    SectionHeader = IMAGE_FIRST_SECTION(NtHeaders);

    /* Try to allocate this memory, if fails - allocate somewhere else */
    PhysicalBase = MmAllocateMemoryAtAddress(NtHeaders->OptionalHeader.SizeOfImage,
                       (PVOID)((ULONG)NtHeaders->OptionalHeader.ImageBase & (KSEG0_BASE - 1)),
                       MemoryType);

    if (PhysicalBase == NULL)
    {
        /* It's ok, we don't panic - let's allocate again at any other "low" place */
        PhysicalBase = MmAllocateMemoryWithType(NtHeaders->OptionalHeader.SizeOfImage, MemoryType);

        if (PhysicalBase == NULL)
        {
            // Print(L"Failed to alloc pages for image %s\n", FileName);
            UiMessageBox("Failed to alloc pages for image.");
            ArcClose(FileId);
            return FALSE;
        }
    }

    /* This is the real image base - in form of a virtual address */
    VirtualBase = PaToVa(PhysicalBase);

    TRACE("Base PA: 0x%X, VA: 0x%X\n", PhysicalBase, VirtualBase);

    /* Set to 0 position and fully load the file image */
    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 = ArcRead(FileId, PhysicalBase, NtHeaders->OptionalHeader.SizeOfHeaders, &BytesRead);
    if (Status != ESUCCESS)
    {
        // Print(L"Error reading headers %s\n", FileName);
        UiMessageBox("Error reading headers.");
        ArcClose(FileId);
        return FALSE;
    }

    /* Reload the NT Header */
    NtHeaders = RtlImageNtHeader(PhysicalBase);

    /* Load the first section */
    SectionHeader = IMAGE_FIRST_SECTION(NtHeaders);

    /* Fill output parameters */
    *ImageBasePA = PhysicalBase;

    /* Walk through each section and read it (check/fix any possible
       bad situations, if they arise) */
    for (i = 0; i < NumberOfSections; i++)
    {
        VirtualSize = SectionHeader->Misc.VirtualSize;
        SizeOfRawData = SectionHeader->SizeOfRawData;

        /* Handle a case when VirtualSize equals 0 */
        if (VirtualSize == 0)
            VirtualSize = SizeOfRawData;

        /* If PointerToRawData is 0, then force its size to be also 0 */
        if (SectionHeader->PointerToRawData == 0)
        {
            SizeOfRawData = 0;
        }
        else
        {
            /* Cut the loaded size to the VirtualSize extents */
            if (SizeOfRawData > VirtualSize)
                SizeOfRawData = VirtualSize;
        }

        /* Actually read the section (if its size is not 0) */
        if (SizeOfRawData != 0)
        {
            /* Seek to the correct position */
            Position.LowPart = SectionHeader->PointerToRawData;
            Status = ArcSeek(FileId, &Position, SeekAbsolute);

            TRACE("SH->VA: 0x%X\n", SectionHeader->VirtualAddress);

            /* Read this section from the file, size = SizeOfRawData */
            Status = ArcRead(FileId, (PUCHAR)PhysicalBase + SectionHeader->VirtualAddress, SizeOfRawData, &BytesRead);
            if (Status != ESUCCESS)
            {
                ERR("WinLdrLoadImage(): Error reading section from file!\n");
                break;
            }
        }

        /* Size of data is less than the virtual size - fill up the remainder with zeroes */
        if (SizeOfRawData < VirtualSize)
        {
            TRACE("WinLdrLoadImage(): SORD %d < VS %d\n", SizeOfRawData, VirtualSize);
            RtlZeroMemory((PVOID)(SectionHeader->VirtualAddress + (ULONG_PTR)PhysicalBase + SizeOfRawData), VirtualSize - SizeOfRawData);
        }

        SectionHeader++;
    }

    /* We are done with the file - close it */
    ArcClose(FileId);

    /* If loading failed - return right now */
    if (Status != ESUCCESS)
        return FALSE;

    /* Relocate the image, if it needs it */
    if (NtHeaders->OptionalHeader.ImageBase != (ULONG_PTR)VirtualBase)
    {
        WARN("Relocating %p -> %p\n", NtHeaders->OptionalHeader.ImageBase,
             VirtualBase);
        return (BOOLEAN)LdrRelocateImageWithBias(PhysicalBase,
                                                 (ULONG_PTR)VirtualBase - (ULONG_PTR)PhysicalBase,
                                                 "FreeLdr",
                                                 TRUE,
                                                 TRUE, /* in case of conflict still return success */
                                                 FALSE);
    }

    TRACE("WinLdrLoadImage() done, PA = %p\n", *ImageBasePA);
    return TRUE;
}
Пример #6
0
BOOLEAN
WinLdrAllocateDataTableEntry(IN OUT PLIST_ENTRY ModuleListHead,
                             IN PCCH BaseDllName,
                             IN PCCH FullDllName,
                             IN PVOID BasePA,
                             OUT PLDR_DATA_TABLE_ENTRY *NewEntry)
{
    PVOID BaseVA = PaToVa(BasePA);
    PWSTR Buffer;
    PLDR_DATA_TABLE_ENTRY DataTableEntry;
    PIMAGE_NT_HEADERS NtHeaders;
    USHORT Length;
    TRACE("WinLdrAllocateDataTableEntry(, '%s', '%s', %p)\n",
       BaseDllName, FullDllName, BasePA);

    /* Allocate memory for a data table entry, zero-initialize it */
    DataTableEntry = (PLDR_DATA_TABLE_ENTRY)FrLdrHeapAlloc(sizeof(LDR_DATA_TABLE_ENTRY),
                                                           TAG_WLDR_DTE);
    if (DataTableEntry == NULL)
        return FALSE;
    RtlZeroMemory(DataTableEntry, sizeof(LDR_DATA_TABLE_ENTRY));

    /* Get NT headers from the image */
    NtHeaders = RtlImageNtHeader(BasePA);

    /* Initialize corresponding fields of DTE based on NT headers value */
    DataTableEntry->DllBase = BaseVA;
    DataTableEntry->SizeOfImage = NtHeaders->OptionalHeader.SizeOfImage;
    DataTableEntry->EntryPoint = RVA(BaseVA, NtHeaders->OptionalHeader.AddressOfEntryPoint);
    DataTableEntry->SectionPointer = 0;
    DataTableEntry->CheckSum = NtHeaders->OptionalHeader.CheckSum;

    /* Initialize BaseDllName field (UNICODE_STRING) from the Ansi BaseDllName
       by simple conversion - copying each character */
    Length = (USHORT)(strlen(BaseDllName) * sizeof(WCHAR));
    Buffer = (PWSTR)FrLdrHeapAlloc(Length, TAG_WLDR_NAME);
    if (Buffer == NULL)
    {
        FrLdrHeapFree(DataTableEntry, TAG_WLDR_DTE);
        return FALSE;
    }
    RtlZeroMemory(Buffer, Length);

    DataTableEntry->BaseDllName.Length = Length;
    DataTableEntry->BaseDllName.MaximumLength = Length;
    DataTableEntry->BaseDllName.Buffer = PaToVa(Buffer);
    while (*BaseDllName != 0)
    {
        *Buffer++ = *BaseDllName++;
    }

    /* Initialize FullDllName field (UNICODE_STRING) from the Ansi FullDllName
       using the same method */
    Length = (USHORT)(strlen(FullDllName) * sizeof(WCHAR));
    Buffer = (PWSTR)FrLdrHeapAlloc(Length, TAG_WLDR_NAME);
    if (Buffer == NULL)
    {
        FrLdrHeapFree(DataTableEntry, TAG_WLDR_DTE);
        return FALSE;
    }
    RtlZeroMemory(Buffer, Length);

    DataTableEntry->FullDllName.Length = Length;
    DataTableEntry->FullDllName.MaximumLength = Length;
    DataTableEntry->FullDllName.Buffer = PaToVa(Buffer);
    while (*FullDllName != 0)
    {
        *Buffer++ = *FullDllName++;
    }

    /* Initialize what's left - LoadCount which is 1, and set Flags so that
       we know this entry is processed */
    DataTableEntry->Flags = LDRP_ENTRY_PROCESSED;
    DataTableEntry->LoadCount = 1;

    /* Insert this DTE to a list in the LPB */
    InsertTailList(ModuleListHead, &DataTableEntry->InLoadOrderLinks);
    TRACE("Inserting DTE %p, name='%.*S' DllBase=%p \n", DataTableEntry,
          DataTableEntry->BaseDllName.Length / 2,
          VaToPa(DataTableEntry->BaseDllName.Buffer),
          DataTableEntry->DllBase);

    /* Save pointer to a newly allocated and initialized entry */
    *NewEntry = DataTableEntry;

    /* Return success */
    return TRUE;
}
Пример #7
0
// Init "phase 1"
VOID
WinLdrInitializePhase1(PLOADER_PARAMETER_BLOCK LoaderBlock,
                       LPCSTR Options,
                       LPCSTR SystemRoot,
                       LPCSTR BootPath,
                       USHORT VersionToBoot)
{
    /* Examples of correct options and paths */
    //CHAR    Options[] = "/DEBUGPORT=COM1 /BAUDRATE=115200";
    //CHAR    Options[] = "/NODEBUG";
    //CHAR    SystemRoot[] = "\\WINNT\\";
    //CHAR    ArcBoot[] = "multi(0)disk(0)rdisk(0)partition(1)";

    LPSTR LoadOptions, NewLoadOptions;
    CHAR  HalPath[] = "\\";
    CHAR  ArcBoot[256];
    CHAR  MiscFiles[256];
    ULONG i;
    ULONG_PTR PathSeparator;
    PLOADER_PARAMETER_EXTENSION Extension;

    /* Construct SystemRoot and ArcBoot from SystemPath */
    PathSeparator = strstr(BootPath, "\\") - BootPath;
    strncpy(ArcBoot, BootPath, PathSeparator);
    ArcBoot[PathSeparator] = 0;

    TRACE("ArcBoot: %s\n", ArcBoot);
    TRACE("SystemRoot: %s\n", SystemRoot);
    TRACE("Options: %s\n", Options);

    /* Fill Arc BootDevice */
    LoaderBlock->ArcBootDeviceName = WinLdrSystemBlock->ArcBootDeviceName;
    strncpy(LoaderBlock->ArcBootDeviceName, ArcBoot, MAX_PATH);
    LoaderBlock->ArcBootDeviceName = PaToVa(LoaderBlock->ArcBootDeviceName);

    /* Fill Arc HalDevice, it matches ArcBoot path */
    LoaderBlock->ArcHalDeviceName = WinLdrSystemBlock->ArcBootDeviceName;
    LoaderBlock->ArcHalDeviceName = PaToVa(LoaderBlock->ArcHalDeviceName);

    /* Fill SystemRoot */
    LoaderBlock->NtBootPathName = WinLdrSystemBlock->NtBootPathName;
    strncpy(LoaderBlock->NtBootPathName, SystemRoot, MAX_PATH);
    LoaderBlock->NtBootPathName = PaToVa(LoaderBlock->NtBootPathName);

    /* Fill NtHalPathName */
    LoaderBlock->NtHalPathName = WinLdrSystemBlock->NtHalPathName;
    strncpy(LoaderBlock->NtHalPathName, HalPath, MAX_PATH);
    LoaderBlock->NtHalPathName = PaToVa(LoaderBlock->NtHalPathName);

    /* Fill LoadOptions and strip the '/' commutator symbol in front of each option */
    NewLoadOptions = LoadOptions = LoaderBlock->LoadOptions = WinLdrSystemBlock->LoadOptions;
    strncpy(LoaderBlock->LoadOptions, Options, MAX_OPTIONS_LENGTH);

    do
    {
        while (*LoadOptions == '/')
            ++LoadOptions;

        *NewLoadOptions++ = *LoadOptions;
    } while (*LoadOptions++);

    LoaderBlock->LoadOptions = PaToVa(LoaderBlock->LoadOptions);

    /* Arc devices */
    LoaderBlock->ArcDiskInformation = &WinLdrSystemBlock->ArcDiskInformation;
    InitializeListHead(&LoaderBlock->ArcDiskInformation->DiskSignatureListHead);

    /* Convert ARC disk information from freeldr to a correct format */
    for (i = 0; i < reactos_disk_count; i++)
    {
        PARC_DISK_SIGNATURE_EX ArcDiskSig;

        /* Allocate the ARC structure */
        ArcDiskSig = HeapAllocate(FrLdrDefaultHeap,
                                  sizeof(ARC_DISK_SIGNATURE_EX),
                                  'giSD');

        /* Copy the data over */
        ArcDiskSig->DiskSignature.Signature = reactos_arc_disk_info[i].Signature;
        ArcDiskSig->DiskSignature.CheckSum = reactos_arc_disk_info[i].CheckSum;

        /* Copy the ARC Name */
        strncpy(ArcDiskSig->ArcName, reactos_arc_disk_info[i].ArcName, MAX_PATH);
        ArcDiskSig->DiskSignature.ArcName = PaToVa(ArcDiskSig->ArcName);

        /* Mark partition table as valid */
        ArcDiskSig->DiskSignature.ValidPartitionTable = TRUE;

        /* Insert into the list */
        InsertTailList(&LoaderBlock->ArcDiskInformation->DiskSignatureListHead,
                       &ArcDiskSig->DiskSignature.ListEntry);
    }

    /* Convert all list's to Virtual address */

    /* Convert the ArcDisks list to virtual address */
    List_PaToVa(&LoaderBlock->ArcDiskInformation->DiskSignatureListHead);
    LoaderBlock->ArcDiskInformation = PaToVa(LoaderBlock->ArcDiskInformation);

    /* Convert configuration entries to VA */
    ConvertConfigToVA(LoaderBlock->ConfigurationRoot);
    LoaderBlock->ConfigurationRoot = PaToVa(LoaderBlock->ConfigurationRoot);

    /* Convert all DTE into virtual addresses */
    List_PaToVa(&LoaderBlock->LoadOrderListHead);

    /* this one will be converted right before switching to
       virtual paging mode */
    //List_PaToVa(&LoaderBlock->MemoryDescriptorListHead);

    /* Convert list of boot drivers */
    List_PaToVa(&LoaderBlock->BootDriverListHead);

    /* Initialize Extension now */
    Extension = &WinLdrSystemBlock->Extension;
    Extension->Size = sizeof(LOADER_PARAMETER_EXTENSION);
    Extension->MajorVersion = (VersionToBoot & 0xFF00) >> 8;
    Extension->MinorVersion = VersionToBoot & 0xFF;
    Extension->Profile.Status = 2;

    /* Check if ACPI is present */
    if (AcpiPresent)
    {
        /* See KiRosFrldrLpbToNtLpb for details */
        Extension->AcpiTable = (PVOID)1;
    }

#ifdef _M_IX86
    /* Set headless block pointer */
    if (WinLdrTerminalConnected)
    {
        Extension->HeadlessLoaderBlock = &WinLdrSystemBlock->HeadlessLoaderBlock;
        RtlCopyMemory(Extension->HeadlessLoaderBlock,
                      &LoaderRedirectionInformation,
                      sizeof(HEADLESS_LOADER_BLOCK));
        Extension->HeadlessLoaderBlock = PaToVa(Extension->HeadlessLoaderBlock);
    }
#endif
    /* Load drivers database */
    strcpy(MiscFiles, BootPath);
    strcat(MiscFiles, "AppPatch\\drvmain.sdb");
    Extension->DrvDBImage = PaToVa(WinLdrLoadModule(MiscFiles,
                                   &Extension->DrvDBSize,
                                   LoaderRegistryData));

    /* Convert extension and setup block pointers */
    LoaderBlock->Extension = PaToVa(Extension);

    if (LoaderBlock->SetupLdrBlock)
        LoaderBlock->SetupLdrBlock = PaToVa(LoaderBlock->SetupLdrBlock);

    TRACE("WinLdrInitializePhase1() completed\n");
}
Пример #8
0
VOID
LoadAndBootWindowsCommon(
    USHORT OperatingSystemVersion,
    PLOADER_PARAMETER_BLOCK LoaderBlock,
    LPCSTR BootOptions,
    LPCSTR BootPath,
    BOOLEAN Setup)
{
    PLOADER_PARAMETER_BLOCK LoaderBlockVA;
    BOOLEAN Status;
    PLDR_DATA_TABLE_ENTRY KernelDTE;
    KERNEL_ENTRY_POINT KiSystemStartup;
    LPCSTR SystemRoot;
    TRACE("LoadAndBootWindowsCommon()\n");

    /* Convert BootPath to SystemRoot */
    SystemRoot = strstr(BootPath, "\\");

    /* Detect hardware */
    LoaderBlock->ConfigurationRoot = MachHwDetect();

    if (OperatingSystemVersion == 0)
        OperatingSystemVersion = WinLdrDetectVersion();

    /* Load the operating system core: the Kernel, the HAL and the Kernel Debugger Transport DLL */
    Status = LoadWindowsCore(OperatingSystemVersion,
                             LoaderBlock,
                             BootOptions,
                             BootPath,
                             &KernelDTE);
    if (!Status)
    {
        UiMessageBox("Error loading NTOS core.");
        return;
    }

    /* Load boot drivers */
    UiDrawBackdrop();
    UiDrawProgressBarCenter(100, 100, "Loading boot drivers...");
    Status = WinLdrLoadBootDrivers(LoaderBlock, BootPath);
    TRACE("Boot drivers loaded with status %d\n", Status);

    /* Initialize Phase 1 - no drivers loading anymore */
    WinLdrInitializePhase1(LoaderBlock,
                           BootOptions,
                           SystemRoot,
                           BootPath,
                           OperatingSystemVersion);

    /* Save entry-point pointer and Loader block VAs */
    KiSystemStartup = (KERNEL_ENTRY_POINT)KernelDTE->EntryPoint;
    LoaderBlockVA = PaToVa(LoaderBlock);

    /* "Stop all motors", change videomode */
    MachPrepareForReactOS(Setup);

    /* Debugging... */
    //DumpMemoryAllocMap();

    /* Do the machine specific initialization */
    WinLdrSetupMachineDependent(LoaderBlock);

    /* Map pages and create memory descriptors */
    WinLdrSetupMemoryLayout(LoaderBlock);

    /* Set processor context */
    WinLdrSetProcessorContext();

    /* Save final value of LoaderPagesSpanned */
    LoaderBlock->Extension->LoaderPagesSpanned = LoaderPagesSpanned;

    TRACE("Hello from paged mode, KiSystemStartup %p, LoaderBlockVA %p!\n",
          KiSystemStartup, LoaderBlockVA);

    // Zero KI_USER_SHARED_DATA page
    memset((PVOID)KI_USER_SHARED_DATA, 0, MM_PAGE_SIZE);

    WinLdrpDumpMemoryDescriptors(LoaderBlockVA);
    WinLdrpDumpBootDriver(LoaderBlockVA);
#ifndef _M_AMD64
    WinLdrpDumpArcDisks(LoaderBlockVA);
#endif

    //FIXME: If I substitute this debugging checkpoint, GCC will "optimize away" the code below
    //while (1) {};
    /*asm(".intel_syntax noprefix\n");
        asm("test1:\n");
        asm("jmp test1\n");
    asm(".att_syntax\n");*/

    /* Pass control */
    (*KiSystemStartup)(LoaderBlockVA);
}
Пример #9
0
// This function converts only Child->Child, and calls itself for each Sibling
VOID
ConvertConfigToVA(PCONFIGURATION_COMPONENT_DATA Start)
{
	PCONFIGURATION_COMPONENT_DATA Child;
	PCONFIGURATION_COMPONENT_DATA Sibling;

	TRACE("ConvertConfigToVA(Start 0x%X)\n", Start);
	Child = Start;

	while (Child != NULL)
	{
		if (Child->ConfigurationData)
			Child->ConfigurationData = PaToVa(Child->ConfigurationData);

		if (Child->Child)
			Child->Child = PaToVa(Child->Child);

		if (Child->Parent)
			Child->Parent = PaToVa(Child->Parent);

		if (Child->Sibling)
			Child->Sibling = PaToVa(Child->Sibling);

		if (Child->ComponentEntry.Identifier)
			Child->ComponentEntry.Identifier = PaToVa(Child->ComponentEntry.Identifier);

		TRACE("Device 0x%X class %d type %d id '%s', parent %p\n", Child,
			Child->ComponentEntry.Class, Child->ComponentEntry.Type, VaToPa(Child->ComponentEntry.Identifier), Child->Parent);

		// Go through siblings list
		Sibling = VaToPa(Child->Sibling);
		while (Sibling != NULL)
		{
			if (Sibling->ConfigurationData)
				Sibling->ConfigurationData = PaToVa(Sibling->ConfigurationData);

			if (Sibling->Child)
				Sibling->Child = PaToVa(Sibling->Child);

			if (Sibling->Parent)
				Sibling->Parent = PaToVa(Sibling->Parent);

			if (Sibling->Sibling)
				Sibling->Sibling = PaToVa(Sibling->Sibling);

			if (Sibling->ComponentEntry.Identifier)
				Sibling->ComponentEntry.Identifier = PaToVa(Sibling->ComponentEntry.Identifier);

			TRACE("Device 0x%X class %d type %d id '%s', parent %p\n", Sibling,
				Sibling->ComponentEntry.Class, Sibling->ComponentEntry.Type, VaToPa(Sibling->ComponentEntry.Identifier), Sibling->Parent);

			// Recurse into the Child tree
			if (VaToPa(Sibling->Child) != NULL)
				ConvertConfigToVA(VaToPa(Sibling->Child));

			Sibling = VaToPa(Sibling->Sibling);
		}

		// Go to the next child
		Child = VaToPa(Child->Child);
	}
}