Esempio n. 1
0
PVOID
WinLdrLoadModule(PCSTR ModuleName,
                 ULONG *Size,
                 TYPE_OF_MEMORY MemoryType)
{
    ULONG FileId;
    PVOID PhysicalBase;
    FILEINFORMATION FileInfo;
    ULONG FileSize;
    ULONG Status;
    ULONG BytesRead;

    //CHAR ProgressString[256];

    /* Inform user we are loading files */
    //sprintf(ProgressString, "Loading %s...", FileName);
    //UiDrawProgressBarCenter(1, 100, ProgressString);

    TRACE("Loading module %s\n", ModuleName);
    *Size = 0;

    /* Open the image file */
    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 */
    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)
    {
        ArcClose(FileId);
        return NULL;
    }

    /* Load whole file */
    Status = ArcRead(FileId, PhysicalBase, FileSize, &BytesRead);
    ArcClose(FileId);
    if (Status != ESUCCESS)
    {
        return NULL;
    }

    TRACE("Loaded %s at 0x%x with size 0x%x\n", ModuleName, PhysicalBase, FileSize);

    return PhysicalBase;
}
Esempio n. 2
0
VOID LoadOperatingSystem(IN OperatingSystemItem* OperatingSystem)
{
    ULONG_PTR SectionId;
    PCSTR SectionName = OperatingSystem->SystemPartition;
    CHAR BootType[80];
    ULONG i;

    /* Try to open the operating system section in the .ini file */
    if (IniOpenSection(SectionName, &SectionId))
    {
        /* Try to read the boot type */
        IniReadSettingByName(SectionId, "BootType", BootType, sizeof(BootType));
    }
    else
    {
        BootType[0] = ANSI_NULL;
    }

    if (BootType[0] == ANSI_NULL && SectionName[0] != ANSI_NULL)
    {
        /* Try to infer the boot type value */
#ifdef _M_IX86
        ULONG FileId;
        if (ArcOpen((PSTR)SectionName, OpenReadOnly, &FileId) == ESUCCESS)
        {
            ArcClose(FileId);
            strcpy(BootType, "BootSector");
        }
        else
#endif
        {
            strcpy(BootType, "Windows");
        }
    }

#if defined(_M_IX86)
    /* Install the drive mapper according to this section drive mappings */
    DriveMapMapDrivesInSection(SectionName);
#endif

    /* Loop through the OS loading method table and find a suitable OS to boot */
    for (i = 0; i < sizeof(OSLoadingMethods) / sizeof(OSLoadingMethods[0]); ++i)
    {
        if (_stricmp(BootType, OSLoadingMethods[i].BootType) == 0)
        {
            OSLoadingMethods[i].Load(OperatingSystem,
                                     OSLoadingMethods[i].OperatingSystemVersion);
            return;
        }
    }
}
Esempio n. 3
0
File: low.c Progetto: BuloZB/WinNT4
ARC_STATUS
LowCloseDisk(
    IN  ULONG    DiskId
    )
/*++

Routine Description:

    This routine closes the supplied device.

Arguments:

    DiskId      - Supplies the disk id.

Return Value:

    ArcClose

--*/
{
    return ArcClose(DiskId);
}
Esempio n. 4
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;
}
Esempio n. 5
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;
}
Esempio n. 6
0
BOOLEAN
BlReadSignature(
    IN PCHAR DiskName,
    IN BOOLEAN IsCdRom
    )

/*++

Routine Description:

    Given an ARC disk name, reads the MBR and adds its signature to the list of
    disks.

Arguments:

    Diskname - Supplies the name of the disk.

    IsCdRom - Indicates whether the disk is a CD-ROM.

Return Value:

    TRUE - Success

    FALSE - Failure

--*/

{
    PARC_DISK_SIGNATURE Signature;
    UCHAR SectorBuffer[2048+256];
    UCHAR Partition[100];
    ULONG DiskId;
    ULONG Status;
    LARGE_INTEGER SeekValue;
    PUCHAR Sector;
    ULONG i;
    ULONG Sum;
    ULONG Count;
    ULONG SectorSize;

    if (IsCdRom) {
        SectorSize = 2048;
    } else {
        SectorSize = 512;
    }

    Signature = BlAllocateHeap(sizeof(ARC_DISK_SIGNATURE));
    if (Signature==NULL) {
        return(FALSE);
    }

    Signature->ArcName = BlAllocateHeap(strlen(DiskName)+2);
    if (Signature->ArcName==NULL) {
        return(FALSE);
    }
#if defined(_i386_)
    //
    // NTDETECT creates an "eisa(0)..." arcname for detected
    // BIOS disks on an EISA machine.  Change this to "multi(0)..."
    // in order to be consistent with the rest of the system
    // (particularly the arcname in boot.ini)
    //
    if (_strnicmp(DiskName,"eisa",4)==0) {
        strcpy(Signature->ArcName,"multi");
        strcpy(Partition,"multi");
        strcat(Signature->ArcName,DiskName+4);
        strcat(Partition,DiskName+4);
    } else {
        strcpy(Signature->ArcName, DiskName);
        strcpy(Partition, DiskName);
    }
#else
    strcpy(Signature->ArcName, DiskName);
    strcpy(Partition, DiskName);
#endif

    strcat(Partition, "partition(0)");

    Status = ArcOpen(Partition, ArcOpenReadOnly, &DiskId);
    if (Status != ESUCCESS) {
        return(TRUE);
    }

    //
    // Read in the first sector
    //
    Sector = ALIGN_BUFFER(SectorBuffer);
    if (IsCdRom) {
        //
        // For a CD-ROM, the interesting data starts at 0x8000.
        //
        SeekValue.QuadPart = 0x8000;
    } else {
        SeekValue.QuadPart = 0;
    }
    Status = ArcSeek(DiskId, &SeekValue, SeekAbsolute);
    if (Status == ESUCCESS) {
        Status = ArcRead(DiskId,
                         Sector,
                         SectorSize,
                         &Count);
    }
    ArcClose(DiskId);
    if (Status != ESUCCESS) {
        return(TRUE);
    }

    //
    // Check to see whether this disk has a valid partition table signature or not.
    //
    if (((PUSHORT)Sector)[BOOT_SIGNATURE_OFFSET] != BOOT_RECORD_SIGNATURE) {
        Signature->ValidPartitionTable = FALSE;
    } else {
        Signature->ValidPartitionTable = TRUE;
    }

    Signature->Signature = ((PULONG)Sector)[PARTITION_TABLE_OFFSET/2-1];

    //
    // compute the checksum
    //
    Sum = 0;
    for (i=0; i<(SectorSize/4); i++) {
        Sum += ((PULONG)Sector)[i];
    }
    Signature->CheckSum = ~Sum + 1;

    InsertHeadList(&BlLoaderBlock->ArcDiskInformation->DiskSignatures,
                   &Signature->ListEntry);

    return(TRUE);

}
Esempio n. 7
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;
}
Esempio n. 8
0
File: low.c Progetto: BuloZB/WinNT4
ARC_STATUS
LowGetPartitionGeometry(
    IN  PCHAR   PartitionPath,
    OUT PULONG  TotalSectorCount,
    OUT PULONG  SectorSize,
    OUT PULONG  SectorsPerTrack,
    OUT PULONG  Heads
    )
/*++

Routine Description:

    This routine computes the drive geometry for the given partition or
    physical disk.

Arguments:

    PartitionPath   - Supplies a path to the partition or physical disk.
    NumberOfSectors - Returns the number of sectors.
    SectorSize      - Returns the sector size.
    SectorsPerTrack - Returns the number of sectors per track.
    Heads           - Returns the number of heads.

Return Value:

    ArcOpen, ArcGetFileInformation, ArcClose, E2BIG, ESUCCESS

--*/
{
    FILE_INFORMATION    file_info;
    ARC_STATUS          r;
    ULONG               fileid;
    LARGE_INTEGER       l;
    CM_DISK_GEOMETRY_DEVICE_DATA    *DiskGeometry;
    CONFIGURATION_COMPONENT         *DiskComponent;
    CM_PARTIAL_RESOURCE_LIST        *DiskConfiguration;
    CHAR                            DataBuffer[sizeof(CM_PARTIAL_RESOURCE_LIST) +
                                               sizeof(CM_DISK_GEOMETRY_DEVICE_DATA)];
    CM_PARTIAL_RESOURCE_DESCRIPTOR  *DiskData;

    // Always assume 512 bytes per sector.

    *SectorSize      = 512;

    // Assume the SCSI default values for number of heads and sectors per track

    *SectorsPerTrack = 32;
    *Heads           = 64;

    // See if there is device specific data describing the geometry of
    // the drive.  If there is none, then just use the default SCSI
    // values.

    DiskComponent = ArcGetComponent(PartitionPath);

    if (DiskComponent == NULL) {
        return EINVAL;
    }

    //
    // See if the ConfigurationDataLength is correct
    // It should contain one DeviceSpecific resource descriptor
    //

    if (DiskComponent->ConfigurationDataLength == sizeof(CM_PARTIAL_RESOURCE_LIST) +
                                                  sizeof(CM_DISK_GEOMETRY_DEVICE_DATA)  ) {

        DiskConfiguration = (CM_PARTIAL_RESOURCE_LIST *)DataBuffer;

        r = ArcGetConfigurationData(DiskConfiguration,DiskComponent);

        if (r == ESUCCESS) {

            //
            // See if the Configuration Data has ARC version 1.3 or greater
            //

            if  ( (DiskConfiguration->Version == 1 && DiskConfiguration->Revision >=3 ) ||
                  (DiskConfiguration->Version >  1)                                        ) {

                DiskData = &(DiskConfiguration->PartialDescriptors[DiskConfiguration->Count-1]);

                if (DiskData->Type == CmResourceTypeDeviceSpecific) {

                    if (DiskData->u.DeviceSpecificData.DataSize == sizeof(CM_DISK_GEOMETRY_DEVICE_DATA)) {
                        DiskGeometry     = (CM_DISK_GEOMETRY_DEVICE_DATA *)
                                           &(DiskConfiguration->PartialDescriptors[DiskConfiguration->Count]);
                        *SectorsPerTrack = DiskGeometry->SectorsPerTrack;
                        *Heads           = DiskGeometry->NumberOfHeads;
                        *SectorSize      = DiskGeometry->BytesPerSector;
                    }
                }
            }
        }
    }

//    PrintError("SectorSize = %08x",*SectorSize);
//    PrintError("SectorsPerTrack = %08x",*SectorsPerTrack);
//    PrintError("Heads = %08x",*Heads);

    r = ArcOpen(PartitionPath, ArcOpenReadOnly, &fileid);

    if (r != ESUCCESS) {
        return r;
    }

    r = ArcGetFileInformation(fileid, &file_info);

    if (r != ESUCCESS) {
        return r;
    }

    r = ArcClose(fileid);

    if (r != ESUCCESS) {
        return r;
    }

    l.QuadPart = file_info.EndingAddress.QuadPart -
                 file_info.StartingAddress.QuadPart;

    l.QuadPart = ((ULONGLONG)l.QuadPart) / ((ULONGLONG)(*SectorSize));

    if (l.HighPart) {
        return E2BIG;
    }

    *TotalSectorCount = l.LowPart;

    return ESUCCESS;
}
Esempio n. 9
0
BOOLEAN
InfOpenFile(
    PHINF InfHandle,
    PCSTR FileName,
    PULONG ErrorLine)
{
    FILEINFORMATION Information;
    ULONG FileId;
    PCHAR FileBuffer;
    ULONG FileSize, Count;
    PINFCACHE Cache;
    BOOLEAN Success;
    LONG ret;

    *InfHandle = NULL;
    *ErrorLine = (ULONG) - 1;

    //
    // Open the .inf file
    //
    FileId = FsOpenFile(FileName);
    if (!FileId)
    {
        return FALSE;
    }

    //
    // Query file size
    //
    ret = ArcGetFileInformation(FileId, &Information);
    if ((ret != ESUCCESS) || (Information.EndingAddress.HighPart != 0))
    {
        ArcClose(FileId);
        return FALSE;
    }
    FileSize = Information.EndingAddress.LowPart;

    //
    // Allocate buffer to cache the file
    //
    FileBuffer = MmHeapAlloc(FileSize + 1);
    if (!FileBuffer)
    {
        ArcClose(FileId);
        return FALSE;
    }

    //
    // Read file into memory
    //
    ret = ArcRead(FileId, FileBuffer, FileSize, &Count);
    if ((ret != ESUCCESS) || (Count != FileSize))
    {
        ArcClose(FileId);
        MmHeapFree(FileBuffer);
        return FALSE;
    }

    //
    // We don't need the file anymore. Close it
    //
    ArcClose(FileId);

    //
    // Append string terminator
    //
    FileBuffer[FileSize] = 0;

    //
    // Allocate infcache header
    //
    Cache = (PINFCACHE)MmHeapAlloc(sizeof(INFCACHE));
    if (!Cache)
    {
        MmHeapFree(FileBuffer);
        return FALSE;
    }

    //
    // Initialize inicache header
    //
    RtlZeroMemory(Cache, sizeof(INFCACHE));

    //
    // Parse the inf buffer
    //
    Success = InfpParseBuffer(Cache,
                              FileBuffer,
                              FileBuffer + FileSize,
                              ErrorLine);
    if (!Success)
    {
        MmHeapFree(Cache);
        Cache = NULL;
    }

    //
    // Free file buffer, as it has been parsed
    //
    MmHeapFree(FileBuffer);

    //
    // Return .inf parsed contents
    //
    *InfHandle = (HINF)Cache;

    return Success;
}
Esempio n. 10
0
ARC_STATUS
ReadAndVerifyUpdateFile(
    IN PCHAR PathName,
    OUT PULONG BufferAddress,
    OUT PULONG FirmwareStart,
    OUT PULONG BufferLength,
    OUT PULONG LowROMBlock,
    OUT PULONG HighROMBlock
    )
/*++

Routine Description:

    This attempts to load and verify the firmware update file.

Arguments:

    PathName		A pointer to string descriptor for the name of
		        the file to load.

    BufferAddress	A pointer to a variable that receives the
		        address of the image base.

    FirmwareStart	A pointer to a variable that receives the address
    			of the start of the firmware.  This is the first
    			byte after the null byte that terminates the
    			identifier string.

    BufferLength	A pointer to a variable that receives the length of
			the image.

    LowROMBlock		A pointer to a variable that receives the low ROM
    			block to be updated.

    HighROMBlock	A pointer to a variable that receives the low ROM
    			block to be updated.

Return Value:

    ESUCCESS is returned if the image file is loaded and verified.

    Otherwise, an unsuccessful status is returned that describes the
    reason for failure.  Additionally, some detailed error messages
    may be printed out by this function.

    With any return, the file will have already been closed.
--*/

{

    ULONG ActualBase;
    ULONG Count;
    ULONG FileId;
    ULONG Index;
    ULONG PageCount;
    ARC_STATUS Status;
    LARGE_INTEGER SeekPosition;
    FILE_INFORMATION FileInfo;
    ULONG FileSize;
    CHAR ChecksumAdjustment[4];
    ULONG AccumulatedSum;
    ULONG AmountOfBinaryData;
    

    //
    // Attempt to open the file.
    //

    Status = ArcOpen(PathName, ArcOpenReadOnly, &FileId);
    if (Status != ESUCCESS) {
        VenPrint(FWUP_READ_CANT_OPEN_MSG);
        return Status;
    }

    //
    // Get the file information to figure out how big the file is.
    //

    Status = ArcGetFileInformation(FileId, &FileInfo);

    if (Status != ESUCCESS) {
        VenPrint(FWUP_READ_CANT_GET_FILE_INFO_MSG);
        ArcClose(FileId);
	return Status;
    }

    FileSize = FileInfo.EndingAddress.LowPart - FileInfo.StartingAddress.LowPart;

    if ((FileSize < MINIMUM_UPDATE_FILE_SIZE) || (FileSize > MAXIMUM_UPDATE_FILE_SIZE)) {
    	VenPrint(FWUP_READ_BAD_SIZE_MSG);
    	ArcClose(FileId);
    	return EINVAL;
    }
    

    //
    // Compute number of pages in the file and read it in.
    //

    PageCount = (FileSize + PAGE_SIZE - 1) >> PAGE_SHIFT;

    Status = JnFsAllocateDescriptor(MemoryFree, PageCount, &ActualBase);

    if (Status != ESUCCESS) {
	VenPrint1(FWUP_READ_NOT_ENOUGH_MEMORY, PageCount);
        ArcClose(FileId);
        return Status;
    }

    //
    // Compute the byte address of the update file buffer
    //
    *BufferAddress = KSEG0_BASE | (ActualBase << PAGE_SHIFT);
    VenPrint(FWUP_READ_READING_MSG);
    Status = ArcRead(FileId, (PUCHAR)*BufferAddress, FileSize, &Count);
    ArcClose(FileId);

    if (Count != FileSize) {
        VenPrint2(FWUP_READ_BAD_READ_COUNT_MSG, FileSize, Count);
	if (Status != ESUCCESS) {
	    return Status;
	} else {
	    return EIO;
	}
    }    	
    if (Status != ESUCCESS) {
        return Status;
    }


    //
    // Verify the file's checksum.
    //

    VenPrint(FWUP_READ_VERIFYING_CHECKSUM_MSG);
    AccumulatedSum = 0;
    Index = 0;
    do {
        ChecksumAdjustment[0] = ChecksumAdjustment[1];
        ChecksumAdjustment[1] = ChecksumAdjustment[2];
        ChecksumAdjustment[2] = ChecksumAdjustment[3];
        ChecksumAdjustment[3] = *(((PUCHAR)*BufferAddress)+Index);
    	AccumulatedSum += *(((PUCHAR)*BufferAddress)+Index);
        Index++;
    } while (Index < FileSize);     // Filesize is 1-based, Index is 0-based

    // The last four bytes were really a 32-bit additive-zero checksum,
    // order of {low byte -- high byte }
    AccumulatedSum = AccumulatedSum -
		     ChecksumAdjustment[3] -
        	     ChecksumAdjustment[2] -
		     ChecksumAdjustment[1] -
		     ChecksumAdjustment[0];
    AccumulatedSum = AccumulatedSum +
    		     ((ChecksumAdjustment[3] << 24) |
    		      (ChecksumAdjustment[2] << 16) |
    		      (ChecksumAdjustment[1] << 8) |
    		      (ChecksumAdjustment[0]));
    		      
    if (AccumulatedSum != 0) {
    	VenPrint1 (FWUP_READ_BAD_CHECKSUM_MSG, AccumulatedSum);
        return ENOEXEC;
    }


    //
    // The checksum is good.  Find the start of the firmware data.
    //

    Index = 0;
    while ((Index < MAXIMUM_IDENTIFIER_LENGTH) &&
	   (*(((PUCHAR)*BufferAddress)+Index) != 0)) {
        Index++;
    }

    if (Index == MAXIMUM_IDENTIFIER_LENGTH) {
    	VenPrint(FWUP_READ_IDENTIFIER_TOO_LONG_MSG);
    	return ENOEXEC;
    }

    //
    // Skip over the starting block byte
    //

    *FirmwareStart = (ULONG)(((PUCHAR)*BufferAddress) + Index + 2);

    
    //
    // Now verify legality of the starting block number, and verify that
    // we have at least that much data in the binary section of the file.
    //

    *LowROMBlock = *(((PUCHAR)*BufferAddress) + Index + 1);

    if (*LowROMBlock > 0xf) {
    	VenPrint1(FWUP_READ_BAD_START_BLOCK_MSG, *LowROMBlock);
    	return ENOEXEC;
    }

    AmountOfBinaryData = FileSize -
                         (ULONG)((PUCHAR)*FirmwareStart -
				 (PUCHAR)*BufferAddress) -
                         4;
          
    *BufferLength = AmountOfBinaryData;

    if ((AmountOfBinaryData % SIXTY_FOUR_KB) != 0) {
    	VenPrint(FWUP_READ_BAD_BINARY_DATA_MSG);
    	return EBADF;
    }

    *HighROMBlock = *LowROMBlock + (AmountOfBinaryData / SIXTY_FOUR_KB) - 1;
    
    if ((*HighROMBlock < *LowROMBlock) || (*HighROMBlock > 0xf)) {
    	VenPrint2(FWUP_READ_TOO_MUCH_DATA_MSG, *LowROMBlock, *HighROMBlock);
    	return E2BIG;
    }


    return ESUCCESS;
}
Esempio n. 11
0
BOOLEAN IniFileInitialize(VOID)
{
    FILEINFORMATION FileInformation;
    ULONG FileId; // File handle for freeldr.ini
    PCHAR FreeLoaderIniFileData;
    ULONG FreeLoaderIniFileSize, Count;
    LONG ret;
    BOOLEAN Success;
    TRACE("IniFileInitialize()\n");

    //
    // Open freeldr.ini
    //
    ret = IniOpenIniFile(&FileId);
    if (ret != ESUCCESS)
    {
        UiMessageBoxCritical("Error opening freeldr.ini or file not found.\nYou need to re-install FreeLoader.");
        return FALSE;
    }

    //
    // Get the file size
    //
    ret = ArcGetFileInformation(FileId, &FileInformation);
    if (ret != ESUCCESS || FileInformation.EndingAddress.HighPart != 0)
    {
        UiMessageBoxCritical("Error while getting informations about freeldr.ini.\nYou need to re-install FreeLoader.");
        return FALSE;
    }
    FreeLoaderIniFileSize = FileInformation.EndingAddress.LowPart;

    //
    // Allocate memory to cache the whole freeldr.ini
    //
    FreeLoaderIniFileData = MmHeapAlloc(FreeLoaderIniFileSize);
    if (!FreeLoaderIniFileData)
    {
        UiMessageBoxCritical("Out of memory while loading freeldr.ini.");
        ArcClose(FileId);
        return FALSE;
    }

    //
    // Read freeldr.ini off the disk
    //
    ret = ArcRead(FileId, FreeLoaderIniFileData, FreeLoaderIniFileSize, &Count);
    if (ret != ESUCCESS || Count != FreeLoaderIniFileSize)
    {
        UiMessageBoxCritical("Error while reading freeldr.ini.");
        ArcClose(FileId);
        MmHeapFree(FreeLoaderIniFileData);
        return FALSE;
    }

    //
    // Parse the .ini file data
    //
    Success = IniParseFile(FreeLoaderIniFileData, FreeLoaderIniFileSize);

    //
    // Do some cleanup, and return
    //
    ArcClose(FileId);
    MmHeapFree(FreeLoaderIniFileData);

    return Success;
}
Esempio n. 12
0
VOID
BlGetActivePartition(
    OUT PUCHAR BootPartitionName
    )

/*++

Routine Description:

    Determine the ARC name for the partition NTLDR was started from

Arguments:

    BootPartitionName - Supplies a buffer where the ARC name of the
        partition will be returned.

Return Value:

    Name of the partition is in BootPartitionName.

    Must always succeed.
--*/

{
    UCHAR SectorBuffer[512];
    UCHAR NameBuffer[80];
    ARC_STATUS Status;
    ULONG FileId;
    ULONG Count;
    int i;

    //
    // The method we use is to open each partition on the first drive
    // and read in its boot sector.  Then we compare that to the boot
    // sector that we used to boot from (at physical address 0x7c00.
    // If they are the same, we've found it.  If we run out of partitions,
    // just try partition 1
    //
    i=1;
    do {
        sprintf(NameBuffer, "multi(0)disk(0)rdisk(0)partition(%u)",i);
        Status = ArcOpen(NameBuffer,ArcOpenReadOnly,&FileId);
        if (Status != ESUCCESS) {
            //
            // we've run out of partitions, return the default.
            //
            i=1;
            break;
        } else {
            //
            // Read in the first 512 bytes
            //
            Status = ArcRead(FileId, SectorBuffer, 512, &Count);
            ArcClose(FileId);
            if (Status==ESUCCESS) {

                //
                // only need to compare the first 36 bytes
                //    Jump instr. == 3 bytes
                //    Oem field   == 8 bytes
                //    BPB         == 25 bytes
                //

                if (memcmp(SectorBuffer, (PVOID)0x7c00, 36)==0) {
                    //
                    // we have found a match.
                    //
                    break;
                }
            }
        }

        ++i;
    } while ( TRUE );

    sprintf(BootPartitionName, "multi(0)disk(0)rdisk(0)partition(%u)",i);
    return;
}
Esempio n. 13
0
VOID
BlpRebootDOS(
    IN PCHAR BootSectorImage OPTIONAL
    )

/*++

Routine Description:

    Loads up the bootstrap sectors and executes them (thereby rebooting
    into DOS or OS/2)

Arguments:

    BootSectorImage - If specified, supplies name of file on the C: drive
        that contains the boot sector image. In this case, this routine
        will return if that file cannot be opened (for example, if it's
        a directory).  If not specified, then default to \bootsect.dos,
        and this routine will never return.

Return Value:

    None.

--*/

{
    ULONG SectorId;
    ARC_STATUS Status;
    ULONG Read;
    ULONG DriveId;
    ULONG BootType;
    LARGE_INTEGER SeekPosition;
    extern UCHAR BootPartitionName[];

    //
    // HACKHACK John Vert (jvert)
    //     Some SCSI drives get really confused and return zeroes when
    //     you use the BIOS to query their size after the AHA driver has
    //     initialized.  This can completely tube OS/2 or DOS.  So here
    //     we try and open both BIOS-accessible hard drives.  Our open
    //     code is smart enough to retry if it gets back zeros, so hopefully
    //     this will give the SCSI drives a chance to get their act together.
    //
    Status = ArcOpen("multi(0)disk(0)rdisk(0)partition(0)",
                     ArcOpenReadOnly,
                     &DriveId);
    if (Status == ESUCCESS) {
        ArcClose(DriveId);
    }

    Status = ArcOpen("multi(0)disk(0)rdisk(1)partition(0)",
                     ArcOpenReadOnly,
                     &DriveId);
    if (Status == ESUCCESS) {
        ArcClose(DriveId);
    }

    //
    // Load the boot sector at address 0x7C00 (expected by Reboot callback)
    //
    Status = ArcOpen(BootPartitionName,
                     ArcOpenReadOnly,
                     &DriveId);
    if (Status != ESUCCESS) {
        BlPrint(BlFindMessage(BL_REBOOT_IO_ERROR),BootPartitionName);
        while (1) {
            GET_KEY();
        }
    }
    Status = BlOpen( DriveId,
                     BootSectorImage ? BootSectorImage : "\\bootsect.dos",
                     ArcOpenReadOnly,
                     &SectorId );

    if (Status != ESUCCESS) {
        if(BootSectorImage) {
            //
            // The boot sector image might actually be a directory.
            // Return to the caller to attempt standard boot.
            //
            BlClose(DriveId);
            return;
        }
        BlPrint(BlFindMessage(BL_REBOOT_IO_ERROR),BootPartitionName);
        while (1) {
        }
    }

    Status = BlRead( SectorId,
                     (PVOID)0x7c00,
                     SECTOR_SIZE,
                     &Read );

    if (Status != ESUCCESS) {
        BlPrint(BlFindMessage(BL_REBOOT_IO_ERROR),BootPartitionName);
        while (1) {
        }
    }

    //
    // The FAT boot code is only one sector long so we just want
    // to load it up and jump to it.
    //
    // For HPFS and NTFS, we can't do this because the first sector
    // loads the rest of the boot sectors -- but we want to use
    // the boot code in the boot sector image file we loaded.
    //
    // For HPFS, we load the first 20 sectors (boot code + super and
    // space blocks) into d00:200.  Fortunately this works for both
    // NT and OS/2.
    //
    // For NTFS, we load the first 16 sectors and jump to d00:256.
    // If the OEM field of the boot sector starts with NTFS, we
    // assume it's NTFS boot code.
    //

    //
    // Try to read 8K from the boot code image.
    // If this succeeds, we have either HPFS or NTFS.
    //
    SeekPosition.QuadPart = 0;
    BlSeek(SectorId,&SeekPosition,SeekAbsolute);
    BlRead(SectorId,(PVOID)0xd000,SECTOR_SIZE*16,&Read);

    if(Read == SECTOR_SIZE*16) {

        if(memcmp((PVOID)0x7c03,"NTFS",4)) {

            //
            // HPFS -- we need to load the super block.
            //
            BootType = 1;       // HPFS

            SeekPosition.QuadPart = 16*SECTOR_SIZE;
            ArcSeek(DriveId,&SeekPosition,SeekAbsolute);
            ArcRead(DriveId,(PVOID)0xf000,SECTOR_SIZE*4,&Read);

        } else {

            //
            // NTFS -- we've loaded everything we need to load.
            //
            BootType = 2;   // NTFS
        }
    } else {

        BootType = 0;       // FAT
    }

    //
    // DX must be the drive to boot from
    //

    _asm {
        mov dx, 0x80
    }
    REBOOT(BootType);

}