Exemplo n.º 1
0
const DEVVTBL* IsoMount(ULONG DeviceId)
{
    UCHAR Buffer[SECTORSIZE];
    PPVD Pvd = (PPVD)Buffer;
    LARGE_INTEGER Position;
    ULONG Count;
    LONG ret;

    //
    // Read The Primary Volume Descriptor
    //
    Position.HighPart = 0;
    Position.LowPart = 16 * SECTORSIZE;
    ret = ArcSeek(DeviceId, &Position, SeekAbsolute);
    if (ret != ESUCCESS)
        return NULL;
    ret = ArcRead(DeviceId, Pvd, SECTORSIZE, &Count);
    if (ret != ESUCCESS || Count < sizeof(PVD))
        return NULL;

    //
    // Check if PVD is valid. If yes, return ISO9660 function table
    //
    if (Pvd->VdType == 1 && RtlEqualMemory(Pvd->StandardId, "CD001", 5))
        return &Iso9660FuncTable;
    else
        return NULL;
}
Exemplo n.º 2
0
/*
 * IsoBufferDirectory()
 * This function allocates a buffer, reads the specified directory
 * and returns a pointer to that buffer into pDirectoryBuffer. The
 * function returns an ARC error code. The directory is specified
 * by its starting sector and length.
 */
static LONG IsoBufferDirectory(ULONG DeviceId, ULONG DirectoryStartSector, ULONG DirectoryLength,
    PVOID* pDirectoryBuffer)
{
    PVOID DirectoryBuffer;
    ULONG SectorCount;
    LARGE_INTEGER Position;
    ULONG Count;
    ULONG ret;

    TRACE("IsoBufferDirectory() DirectoryStartSector = %d DirectoryLength = %d\n", DirectoryStartSector, DirectoryLength);

    SectorCount = ROUND_UP(DirectoryLength, SECTORSIZE) / SECTORSIZE;
    TRACE("Trying to read (DirectoryCount) %d sectors.\n", SectorCount);

    //
    // Attempt to allocate memory for directory buffer
    //
    TRACE("Trying to allocate (DirectoryLength) %d bytes.\n", DirectoryLength);
    DirectoryBuffer = MmHeapAlloc(DirectoryLength);
    if (!DirectoryBuffer)
        return ENOMEM;

    //
    // Now read directory contents into DirectoryBuffer
    //
    Position.HighPart = 0;
    Position.LowPart = DirectoryStartSector * SECTORSIZE;
    ret = ArcSeek(DeviceId, &Position, SeekAbsolute);
    if (ret != ESUCCESS)
    {
        MmHeapFree(DirectoryBuffer);
        return ret;
    }
    ret = ArcRead(DeviceId, DirectoryBuffer, SectorCount * SECTORSIZE, &Count);
    if (ret != ESUCCESS || Count != SectorCount * SECTORSIZE)
    {
        MmHeapFree(DirectoryBuffer);
        return EIO;
    }

    *pDirectoryBuffer = DirectoryBuffer;
    return ESUCCESS;
}
Exemplo n.º 3
0
NTSTATUS
NTAPI
IopReadBootRecord(
    IN PDEVICE_OBJECT DeviceObject,
    IN ULONGLONG LogicalSectorNumber,
    IN ULONG SectorSize,
    OUT PMASTER_BOOT_RECORD BootRecord)
{
    ULONG FileId = (ULONG)DeviceObject;
    LARGE_INTEGER Position;
    ULONG BytesRead;
    ARC_STATUS Status;

    Position.QuadPart = LogicalSectorNumber * SectorSize;
    Status = ArcSeek(FileId, &Position, SeekAbsolute);
    if (Status != ESUCCESS)
        return STATUS_IO_DEVICE_ERROR;

    Status = ArcRead(FileId, BootRecord, SectorSize, &BytesRead);
    if (Status != ESUCCESS || BytesRead != SectorSize)
        return STATUS_IO_DEVICE_ERROR;

    return STATUS_SUCCESS;
}
Exemplo n.º 4
0
LONG IsoRead(ULONG FileId, VOID* Buffer, ULONG N, ULONG* Count)
{
    PISO_FILE_INFO FileHandle = FsGetDeviceSpecific(FileId);
    UCHAR SectorBuffer[SECTORSIZE];
    LARGE_INTEGER Position;
    ULONG DeviceId;
    ULONG FilePointer;
    ULONG        SectorNumber;
    ULONG        OffsetInSector;
    ULONG        LengthInSector;
    ULONG        NumberOfSectors;
    ULONG BytesRead;
    LONG ret;

    TRACE("IsoRead() Buffer = %p, N = %lu\n", Buffer, N);

    DeviceId = FsGetDeviceId(FileId);
    *Count = 0;

    //
    // If they are trying to read past the
    // end of the file then return success
    // with Count == 0
    //
    FilePointer = FileHandle->FilePointer;
    if (FilePointer >= FileHandle->FileSize)
    {
        return ESUCCESS;
    }

    //
    // If they are trying to read more than there is to read
    // then adjust the amount to read
    //
    if (FilePointer + N > FileHandle->FileSize)
    {
        N = FileHandle->FileSize - FilePointer;
    }

    //
    // Ok, now we have to perform at most 3 calculations
    // I'll draw you a picture (using nifty ASCII art):
    //
    // CurrentFilePointer -+
    //                     |
    //    +----------------+
    //    |
    // +-----------+-----------+-----------+-----------+
    // | Sector  1 | Sector  2 | Sector  3 | Sector  4 |
    // +-----------+-----------+-----------+-----------+
    //    |                                    |
    //    +---------------+--------------------+
    //                    |
    // N -----------------+
    //
    // 1 - The first calculation (and read) will align
    //     the file pointer with the next sector
    //     boundary (if we are supposed to read that much)
    // 2 - The next calculation (and read) will read
    //     in all the full sectors that the requested
    //     amount of data would cover (in this case
    //     sectors 2 & 3).
    // 3 - The last calculation (and read) would read
    //     in the remainder of the data requested out of
    //     the last sector.
    //


    //
    // Only do the first read if we
    // aren't aligned on a cluster boundary
    //
    if (FilePointer % SECTORSIZE)
    {
        //
        // Do the math for our first read
        //
        SectorNumber = FileHandle->FileStart + (FilePointer / SECTORSIZE);
        OffsetInSector = FilePointer % SECTORSIZE;
        LengthInSector = (N > (SECTORSIZE - OffsetInSector)) ? (SECTORSIZE - OffsetInSector) : N;

        //
        // Now do the read and update Count, N, FilePointer, & Buffer
        //
        Position.HighPart = 0;
        Position.LowPart = SectorNumber * SECTORSIZE;
        ret = ArcSeek(DeviceId, &Position, SeekAbsolute);
        if (ret != ESUCCESS)
        {
            return ret;
        }
        ret = ArcRead(DeviceId, SectorBuffer, SECTORSIZE, &BytesRead);
        if (ret != ESUCCESS || BytesRead != SECTORSIZE)
        {
            return EIO;
        }
        RtlCopyMemory(Buffer, SectorBuffer + OffsetInSector, LengthInSector);
        *Count += LengthInSector;
        N -= LengthInSector;
        FilePointer += LengthInSector;
        Buffer = (PVOID)((ULONG_PTR)Buffer + LengthInSector);
    }

    //
    // Do the math for our second read (if any data left)
    //
    if (N > 0)
    {
        //
        // Determine how many full clusters we need to read
        //
        NumberOfSectors = (N / SECTORSIZE);

        SectorNumber = FileHandle->FileStart + (FilePointer / SECTORSIZE);

        //
        // Now do the read and update Count, N, FilePointer, & Buffer
        //
        Position.HighPart = 0;
        Position.LowPart = SectorNumber * SECTORSIZE;
        ret = ArcSeek(DeviceId, &Position, SeekAbsolute);
        if (ret != ESUCCESS)
        {
            return ret;
        }
        ret = ArcRead(DeviceId, Buffer, NumberOfSectors * SECTORSIZE, &BytesRead);
        if (ret != ESUCCESS || BytesRead != NumberOfSectors * SECTORSIZE)
        {
            return EIO;
        }

        *Count += NumberOfSectors * SECTORSIZE;
        N -= NumberOfSectors * SECTORSIZE;
        FilePointer += NumberOfSectors * SECTORSIZE;
        Buffer = (PVOID)((ULONG_PTR)Buffer + NumberOfSectors * SECTORSIZE);
    }

    //
    // Do the math for our third read (if any data left)
    //
    if (N > 0)
    {
        SectorNumber = FileHandle->FileStart + (FilePointer / SECTORSIZE);

        //
        // Now do the read and update Count, N, FilePointer, & Buffer
        //
        Position.HighPart = 0;
        Position.LowPart = SectorNumber * SECTORSIZE;
        ret = ArcSeek(DeviceId, &Position, SeekAbsolute);
        if (ret != ESUCCESS)
        {
            return ret;
        }
        ret = ArcRead(DeviceId, SectorBuffer, SECTORSIZE, &BytesRead);
        if (ret != ESUCCESS || BytesRead != SECTORSIZE)
        {
            return EIO;
        }
        RtlCopyMemory(Buffer, SectorBuffer, N);
        *Count += N;
        FilePointer += N;
    }

    TRACE("IsoRead() done\n");

    return ESUCCESS;
}
Exemplo n.º 5
0
/*
 * IsoLookupFile()
 * This function searches the file system for the
 * specified filename and fills in an ISO_FILE_INFO structure
 * with info describing the file, etc. returns ARC error code
 */
static LONG IsoLookupFile(PCSTR FileName, ULONG DeviceId, PISO_FILE_INFO IsoFileInfoPointer)
{
    UCHAR Buffer[SECTORSIZE];
    PPVD Pvd = (PPVD)Buffer;
    UINT32        i;
    ULONG            NumberOfPathParts;
    CHAR        PathPart[261];
    PVOID        DirectoryBuffer;
    ULONG        DirectorySector;
    ULONG        DirectoryLength;
    ISO_FILE_INFO    IsoFileInfo;
    LARGE_INTEGER Position;
    ULONG Count;
    LONG ret;

    TRACE("IsoLookupFile() FileName = %s\n", FileName);

    RtlZeroMemory(IsoFileInfoPointer, sizeof(ISO_FILE_INFO));
    RtlZeroMemory(&IsoFileInfo, sizeof(ISO_FILE_INFO));

    //
    // Read The Primary Volume Descriptor
    //
    Position.HighPart = 0;
    Position.LowPart = 16 * SECTORSIZE;
    ret = ArcSeek(DeviceId, &Position, SeekAbsolute);
    if (ret != ESUCCESS)
        return ret;
    ret = ArcRead(DeviceId, Pvd, SECTORSIZE, &Count);
    if (ret != ESUCCESS || Count < sizeof(PVD))
        return EIO;

    DirectorySector = Pvd->RootDirRecord.ExtentLocationL;
    DirectoryLength = Pvd->RootDirRecord.DataLengthL;

    //
    // Figure out how many sub-directories we are nested in
    //
    NumberOfPathParts = FsGetNumPathParts(FileName);

    //
    // Loop once for each part
    //
    for (i=0; i<NumberOfPathParts; i++)
    {
        //
        // Get first path part
        //
        FsGetFirstNameFromPath(PathPart, FileName);

        //
        // Advance to the next part of the path
        //
        for (; (*FileName != '\\') && (*FileName != '/') && (*FileName != '\0'); FileName++)
        {
        }
        FileName++;

        //
        // Buffer the directory contents
        //
        ret = IsoBufferDirectory(DeviceId, DirectorySector, DirectoryLength, &DirectoryBuffer);
        if (ret != ESUCCESS)
            return ret;

        //
        // Search for file name in directory
        //
        if (!IsoSearchDirectoryBufferForFile(DirectoryBuffer, DirectoryLength, PathPart, &IsoFileInfo))
        {
            MmHeapFree(DirectoryBuffer);
            return ENOENT;
        }

        MmHeapFree(DirectoryBuffer);

        //
        // If we have another sub-directory to go then
        // grab the start sector and file size
        //
        if ((i+1) < NumberOfPathParts)
        {
            DirectorySector = IsoFileInfo.FileStart;
            DirectoryLength = IsoFileInfo.FileSize;
        }

    }

    RtlCopyMemory(IsoFileInfoPointer, &IsoFileInfo, sizeof(ISO_FILE_INFO));

    return ESUCCESS;
}
Exemplo 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);

}
Exemplo 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;
}
Exemplo n.º 8
0
Arquivo: low.c Projeto: BuloZB/WinNT4
ARC_STATUS
LowWriteSectors(
    IN  ULONG   VolumeId,
    IN  ULONG   SectorSize,
    IN  ULONG   StartingSector,
    IN  ULONG   NumberOfSectors,
    IN  PVOID   Buffer
    )
/*++

Routine Description:

    This routine write 'NumberOfSectors' sectors starting at sector
    'StartingSector' on the volume with ID 'VolumeId'.

Arguments:

    VolumeId        - Supplies the ID for the volume.
    SectorSize      - Supplies the number of bytes per sector.
    StartingSector  - Supplies the starting sector for the write.
    NumberOfSectors - Supplies the number of sectors to write.
    Buffer          - Supplies the sectors to write.

Return Value:

    ArcSeek, ArcWrite, EIO, ESUCCESS

--*/
{
    ARC_STATUS    r;
    ULONG         c;
    LARGE_INTEGER l;
    ULONG         i;
    ULONG         transfer;
    PCHAR         buf;
    ULONG         total;

    l.QuadPart = UInt32x32To64(StartingSector,SectorSize);

    buf = (PCHAR) Buffer;

    r = ArcSeek(VolumeId, &l, SeekAbsolute);

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

    total = SectorSize*NumberOfSectors;

    for (i = 0; i < total; i += MAX_TRANSFER) {

        transfer = min(MAX_TRANSFER, total - i);

        r = ArcWrite(VolumeId, &buf[i], transfer, &c);

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

        if (c != transfer) {
            return EIO;
        }
    }

    return ESUCCESS;
}
Exemplo n.º 9
0
ARC_STATUS
CdfsReadDisk(
    IN ULONG DeviceId,
    IN ULONG Lbo,
    IN ULONG ByteCount,
    IN OUT PVOID Buffer
    )

/*++

Routine Description:

    This routine reads in zero or more sectors from the specified device.

Arguments:

    DeviceId - Supplies the device id to use in the arc calls.

    Lbo - Supplies the LBO to start reading from.

    ByteCount - Supplies the number of bytes to read.

    Buffer - Supplies a pointer to the buffer to read the bytes into.

Return Value:

    ESUCCESS is returned if the read operation is successful. Otherwise,
    an unsuccessful status is returned that describes the reason for failure.

--*/

{
    LARGE_INTEGER LargeLbo;
    ARC_STATUS Status;
    ULONG i;

    //
    //  Seek to the appropriate offset on the volume
    //

    LargeLbo.LowPart = Lbo;
    LargeLbo.HighPart = 0;
    if ((Status = ArcSeek( DeviceId, &LargeLbo , SeekAbsolute )) != ESUCCESS) {

        return Status;
    }

    //
    //  Issue the arc read request
    //

    if ((Status = ArcRead( DeviceId, Buffer, ByteCount, &i)) != ESUCCESS) {

        return Status;
    }

    //
    //  Make sure we got back the amount requested
    //

    if (ByteCount != i) {

        return EIO;
    }

    //
    //  Everything is fine so return success to our caller
    //

    return ESUCCESS;
}
Exemplo n.º 10
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);

}