mirror of
https://github.com/reactos/reactos.git
synced 2024-09-28 21:44:31 +00:00
Added ISO-9660 support.
svn path=/trunk/; revision=2865
This commit is contained in:
parent
13206a61a1
commit
c1e3c3d7fe
|
@ -112,6 +112,7 @@ BOOL DiskReadLogicalSectors(ULONG DriveNumber, ULONG SectorNumber, ULONG SectorC
|
|||
//
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
BOOL DiskIsDriveRemovable(ULONG DriveNumber);
|
||||
BOOL DiskIsDriveCdRom(ULONG DriveNumber);
|
||||
BOOL DiskGetActivePartitionEntry(ULONG DriveNumber, PPARTITION_TABLE_ENTRY PartitionTableEntry);
|
||||
BOOL DiskGetPartitionEntry(ULONG DriveNumber, ULONG PartitionNumber, PPARTITION_TABLE_ENTRY PartitionTableEntry);
|
||||
BOOL DiskGetFirstPartitionEntry(PMASTER_BOOT_RECORD MasterBootRecord, PPARTITION_TABLE_ENTRY PartitionTableEntry);
|
||||
|
|
|
@ -40,6 +40,43 @@ BOOL DiskIsDriveRemovable(ULONG DriveNumber)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
BOOL DiskIsDriveCdRom(ULONG DriveNumber)
|
||||
{
|
||||
PUCHAR Sector;
|
||||
BOOL Result;
|
||||
|
||||
// Hard disks use drive numbers >= 0x80
|
||||
// So if the drive number indicates a hard disk
|
||||
// then return FALSE
|
||||
if ((DriveNumber >= 0x80) && (BiosInt13ExtensionsSupported(DriveNumber)))
|
||||
{
|
||||
Sector = AllocateMemory(2048);
|
||||
|
||||
if (!BiosInt13ReadExtended(DriveNumber, 16, 1, Sector))
|
||||
{
|
||||
DiskError("Disk read error.");
|
||||
FreeMemory(Sector);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Result = (Sector[0] == 1 &&
|
||||
Sector[1] == 'C' &&
|
||||
Sector[2] == 'D' &&
|
||||
Sector[3] == '0' &&
|
||||
Sector[4] == '0' &&
|
||||
Sector[5] == '1');
|
||||
|
||||
FreeMemory(Sector);
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
// Drive is not CdRom so return FALSE
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
BOOL DiskGetActivePartitionEntry(ULONG DriveNumber, PPARTITION_TABLE_ENTRY PartitionTableEntry)
|
||||
{
|
||||
ULONG BootablePartitionCount = 0;
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#define FS_NTFS 2
|
||||
#define FS_EXT2 3
|
||||
#define FS_REISER 4
|
||||
#define FS_ISO9660 5
|
||||
|
||||
#define FILE VOID
|
||||
#define PFILE FILE *
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
include ../rules.mk
|
||||
|
||||
OBJS = fs.o fat.o
|
||||
OBJS = fs.o fat.o iso.o
|
||||
|
||||
.PHONY : clean
|
||||
|
||||
|
@ -34,6 +34,9 @@ fs.o: fs.c fat.h ../fs.h
|
|||
fat.o: fat.c fat.h ../fs.h
|
||||
$(CC) $(FLAGS) -o fat.o -c fat.c
|
||||
|
||||
iso.o: iso.c iso.h ../fs.h
|
||||
$(CC) $(FLAGS) -o iso.o -c iso.c
|
||||
|
||||
clean:
|
||||
- $(RM) *.o
|
||||
- $(RM) *.a
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include <freeldr.h>
|
||||
#include <fs.h>
|
||||
#include "fat.h"
|
||||
#include "iso.h"
|
||||
#include <disk.h>
|
||||
#include <rtl.h>
|
||||
#include <ui.h>
|
||||
|
@ -84,6 +85,16 @@ BOOL OpenDiskDrive(ULONG DriveNumber, ULONG PartitionNumber)
|
|||
return FatOpenVolume(DriveNumber, 0);
|
||||
}
|
||||
|
||||
// Check and see if it is a cdrom drive
|
||||
// If so then just assume ISO9660 file system type
|
||||
if (DiskIsDriveCdRom(DriveNumber))
|
||||
{
|
||||
DbgPrint((DPRINT_FILESYSTEM, "Drive is a cdrom drive. Assuming ISO-9660 file system.\n"));
|
||||
|
||||
FileSystemType = FS_ISO9660;
|
||||
return IsoOpenVolume(DriveNumber);
|
||||
}
|
||||
|
||||
// Set the boot partition
|
||||
BootPartition = PartitionNumber;
|
||||
|
||||
|
@ -93,6 +104,7 @@ BOOL OpenDiskDrive(ULONG DriveNumber, ULONG PartitionNumber)
|
|||
// Partition requested was zero which means the boot partition
|
||||
if (DiskGetActivePartitionEntry(DriveNumber, &PartitionTableEntry) == FALSE)
|
||||
{
|
||||
FileSystemError("No active partition.");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
@ -101,6 +113,7 @@ BOOL OpenDiskDrive(ULONG DriveNumber, ULONG PartitionNumber)
|
|||
// Get requested partition
|
||||
if (DiskGetPartitionEntry(DriveNumber, PartitionNumber, &PartitionTableEntry) == FALSE)
|
||||
{
|
||||
FileSystemError("Partition not found.");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
@ -147,6 +160,10 @@ PFILE OpenFile(PUCHAR FileName)
|
|||
{
|
||||
FileHandle = FatOpenFile(FileName);
|
||||
}
|
||||
else if (FileSystemType == FS_ISO9660)
|
||||
{
|
||||
FileHandle = IsoOpenFile(FileName);
|
||||
}
|
||||
else
|
||||
{
|
||||
FileSystemError("Error: Unknown filesystem.");
|
||||
|
@ -193,6 +210,10 @@ BOOL ReadFile(PFILE FileHandle, ULONG BytesToRead, PULONG BytesRead, PVOID Buffe
|
|||
|
||||
return FatReadFile(FileHandle, BytesToRead, BytesRead, Buffer);
|
||||
|
||||
case FS_ISO9660:
|
||||
|
||||
return IsoReadFile(FileHandle, BytesToRead, BytesRead, Buffer);
|
||||
|
||||
default:
|
||||
|
||||
FileSystemError("Unknown file system.");
|
||||
|
@ -210,6 +231,10 @@ ULONG GetFileSize(PFILE FileHandle)
|
|||
|
||||
return FatGetFileSize(FileHandle);
|
||||
|
||||
case FS_ISO9660:
|
||||
|
||||
return IsoGetFileSize(FileHandle);
|
||||
|
||||
default:
|
||||
FileSystemError("Unknown file system.");
|
||||
break;
|
||||
|
@ -227,6 +252,11 @@ VOID SetFilePointer(PFILE FileHandle, ULONG NewFilePointer)
|
|||
FatSetFilePointer(FileHandle, NewFilePointer);
|
||||
break;
|
||||
|
||||
case FS_ISO9660:
|
||||
|
||||
IsoSetFilePointer(FileHandle, NewFilePointer);
|
||||
break;
|
||||
|
||||
default:
|
||||
FileSystemError("Unknown file system.");
|
||||
break;
|
||||
|
@ -242,6 +272,11 @@ ULONG GetFilePointer(PFILE FileHandle)
|
|||
return FatGetFilePointer(FileHandle);
|
||||
break;
|
||||
|
||||
case FS_ISO9660:
|
||||
|
||||
return IsoGetFilePointer(FileHandle);
|
||||
break;
|
||||
|
||||
default:
|
||||
FileSystemError("Unknown file system.");
|
||||
break;
|
||||
|
|
577
freeldr/freeldr/fs/iso.c
Normal file
577
freeldr/freeldr/fs/iso.c
Normal file
|
@ -0,0 +1,577 @@
|
|||
/*
|
||||
* FreeLoader
|
||||
* Copyright (C) 1998-2002 Brian Palmer <brianp@sginet.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <freeldr.h>
|
||||
#include <fs.h>
|
||||
#include "iso.h"
|
||||
#include <disk.h>
|
||||
#include <rtl.h>
|
||||
#include <ui.h>
|
||||
#include <arch.h>
|
||||
#include <mm.h>
|
||||
#include <debug.h>
|
||||
#include <cache.h>
|
||||
|
||||
|
||||
#define SECTORSIZE 2048
|
||||
|
||||
static ULONG IsoRootSector; // Starting sector of the root directory
|
||||
static ULONG IsoRootLength; // Length of the root directory
|
||||
|
||||
ULONG IsoDriveNumber = 0;
|
||||
|
||||
|
||||
BOOL IsoOpenVolume(ULONG DriveNumber)
|
||||
{
|
||||
PPVD Pvd;
|
||||
|
||||
// DbgPrint((DPRINT_FILESYSTEM, "IsoOpenVolume() DriveNumber = 0x%x VolumeStartSector = 16\n", DriveNumber));
|
||||
printf("IsoOpenVolume() DriveNumber = 0x%x\n", DriveNumber);
|
||||
|
||||
// Store the drive number
|
||||
IsoDriveNumber = DriveNumber;
|
||||
|
||||
IsoRootSector = 0;
|
||||
IsoRootLength = 0;
|
||||
|
||||
Pvd = AllocateMemory(SECTORSIZE);
|
||||
|
||||
if (!BiosInt13ReadExtended(DriveNumber, 16, 1, Pvd))
|
||||
{
|
||||
FileSystemError("Failed to read the PVD.");
|
||||
FreeMemory(Pvd);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
IsoRootSector = Pvd->RootDirRecord.ExtentLocationL;
|
||||
IsoRootLength = Pvd->RootDirRecord.DataLengthL;
|
||||
|
||||
FreeMemory(Pvd);
|
||||
|
||||
// DbgPrint((DPRINT_FILESYSTEM, "IsoRootSector = %u IsoRootLegth = %u\n", IsoRootSector, IsoRootLength));
|
||||
printf("IsoRootSector = %u IsoRootLegth = %u\n", IsoRootSector, IsoRootLength);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
static BOOL IsoSearchDirectoryBufferForFile(PVOID DirectoryBuffer, UINT32 DirectoryLength, PUCHAR FileName, PISO_FILE_INFO IsoFileInfoPointer)
|
||||
{
|
||||
PDIR_RECORD Record;
|
||||
ULONG Offset;
|
||||
ULONG i;
|
||||
UCHAR Name[32];
|
||||
|
||||
// DbgPrint((DPRINT_FILESYSTEM, "IsoSearchDirectoryBufferForFile() DirectoryBuffer = 0x%x DirectoryLength = %d FileName = %s\n", DirectoryBuffer, DirectoryLength, FileName));
|
||||
printf("IsoSearchDirectoryBufferForFile() DirectoryBuffer = 0x%x DirectoryLength = %d FileName = %s\n", DirectoryBuffer, DirectoryLength, FileName);
|
||||
|
||||
memset(Name, 0, 32 * sizeof(UCHAR));
|
||||
|
||||
Offset = 0;
|
||||
Record = (PDIR_RECORD)DirectoryBuffer;
|
||||
while (TRUE)
|
||||
{
|
||||
Offset = Offset + Record->RecordLength;
|
||||
Record = (PDIR_RECORD)(DirectoryBuffer + Offset);
|
||||
|
||||
if (Record->RecordLength == 0)
|
||||
{
|
||||
Offset = ROUND_UP(Offset, SECTORSIZE);
|
||||
Record = (PDIR_RECORD)(DirectoryBuffer + Offset);
|
||||
}
|
||||
|
||||
if (Record->FileIdLength == 1 && Record->FileId[0] == 0)
|
||||
{
|
||||
// DbgPrint((DPRINT_FILESYSTEM, "Name '.'\n"));
|
||||
printf("Name '.'\n");
|
||||
}
|
||||
else if (Record->FileIdLength == 1 && Record->FileId[0] == 1)
|
||||
{
|
||||
// DbgPrint((DPRINT_FILESYSTEM, "Name '..'\n"));
|
||||
printf("Name '..'\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 0; i < Record->FileIdLength && Record->FileId[i] != ';'; i++)
|
||||
Name[i] = Record->FileId[i];
|
||||
Name[i] = 0;
|
||||
// DbgPrint((DPRINT_FILESYSTEM, "Name '%s'\n", Name));
|
||||
printf("Name '%s'\n", Name);
|
||||
|
||||
if (strlen(FileName) == strlen(Name) && stricmp(FileName, Name) == 0)
|
||||
{
|
||||
IsoFileInfoPointer->FileStart = Record->ExtentLocationL;
|
||||
IsoFileInfoPointer->FileSize = Record->DataLengthL;
|
||||
IsoFileInfoPointer->FilePointer = 0;
|
||||
IsoFileInfoPointer->Directory = (Record->FileFlags & 0x02)?TRUE:FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (Offset >= DirectoryLength)
|
||||
return FALSE;
|
||||
|
||||
memset(Name, 0, 32 * sizeof(UCHAR));
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static PVOID IsoBufferDirectory(UINT32 DirectoryStartSector, UINT32 DirectoryLength)
|
||||
{
|
||||
PVOID DirectoryBuffer;
|
||||
UINT32 SectorCount;
|
||||
|
||||
// DbgPrint((DPRINT_FILESYSTEM, "IsoBufferDirectory() DirectoryStartSector = %d DirectoryLength = %d\n", DirectoryStartSector, DirectoryLength));
|
||||
printf("IsoBufferDirectory() DirectoryStartSector = %d DirectoryLength = %d\n", DirectoryStartSector, DirectoryLength);
|
||||
|
||||
//
|
||||
// Attempt to allocate memory for directory buffer
|
||||
//
|
||||
// DbgPrint((DPRINT_FILESYSTEM, "Trying to allocate (DirectoryLength) %d bytes.\n", DirectoryLength));
|
||||
printf("Trying to allocate (DirectoryLength) %d bytes.\n", DirectoryLength);
|
||||
DirectoryBuffer = AllocateMemory(DirectoryLength);
|
||||
|
||||
if (DirectoryBuffer == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SectorCount = ROUND_UP(DirectoryLength, SECTORSIZE) / SECTORSIZE;
|
||||
// DbgPrint((DPRINT_FILESYSTEM, "Trying to read (DirectoryCount) %d sectors.\n", SectorCount));
|
||||
printf("Trying to read (DirectoryCount) %d sectors.\n", SectorCount);
|
||||
|
||||
//
|
||||
// Now read directory contents into DirectoryBuffer
|
||||
//
|
||||
if (!BiosInt13ReadExtended(IsoDriveNumber, DirectoryStartSector, SectorCount, DirectoryBuffer))
|
||||
{
|
||||
FreeMemory(DirectoryBuffer);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return DirectoryBuffer;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* IsoGetNumPathParts()
|
||||
* This function parses a path in the form of dir1\dir2\file1.ext
|
||||
* and returns the number of parts it has (i.e. 3 - dir1,dir2,file1.ext)
|
||||
*/
|
||||
static ULONG IsoGetNumPathParts(PUCHAR Path)
|
||||
{
|
||||
ULONG i;
|
||||
ULONG num;
|
||||
|
||||
for (i=0,num=0; i<(int)strlen(Path); i++)
|
||||
{
|
||||
if (Path[i] == '\\')
|
||||
{
|
||||
num++;
|
||||
}
|
||||
}
|
||||
num++;
|
||||
|
||||
// DbgPrint((DPRINT_FILESYSTEM, "IsoGetNumPathParts() Path = %s NumPathParts = %d\n", Path, num));
|
||||
printf("IsoGetNumPathParts() Path = %s NumPathParts = %d\n", Path, num);
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* IsoGetFirstNameFromPath()
|
||||
* This function parses a path in the form of dir1\dir2\file1.ext
|
||||
* and puts the first name of the path (e.g. "dir1") in buffer
|
||||
* compatible with the MSDOS directory structure
|
||||
*/
|
||||
static VOID IsoGetFirstNameFromPath(PUCHAR Buffer, PUCHAR Path)
|
||||
{
|
||||
ULONG i;
|
||||
|
||||
// Copy all the characters up to the end of the
|
||||
// string or until we hit a '\' character
|
||||
// and put them in Buffer
|
||||
for (i=0; i<(int)strlen(Path); i++)
|
||||
{
|
||||
if (Path[i] == '\\')
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
Buffer[i] = Path[i];
|
||||
}
|
||||
}
|
||||
|
||||
Buffer[i] = 0;
|
||||
|
||||
// DbgPrint((DPRINT_FILESYSTEM, "IsoGetFirstNameFromPath() Path = %s FirstName = %s\n", Path, Buffer));
|
||||
printf("IsoGetFirstNameFromPath() Path = %s FirstName = %s\n", Path, Buffer);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 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 true
|
||||
* if the file exists or false otherwise
|
||||
*/
|
||||
static BOOL IsoLookupFile(PUCHAR FileName, PISO_FILE_INFO IsoFileInfoPointer)
|
||||
{
|
||||
int i;
|
||||
ULONG NumberOfPathParts;
|
||||
UCHAR PathPart[261];
|
||||
PVOID DirectoryBuffer;
|
||||
UINT32 DirectorySector;
|
||||
UINT32 DirectoryLength;
|
||||
ISO_FILE_INFO IsoFileInfo;
|
||||
|
||||
// DbgPrint((DPRINT_FILESYSTEM, "IsoLookupFile() FileName = %s\n", FileName));
|
||||
printf("IsoLookupFile() FileName = %s\n", FileName);
|
||||
|
||||
memset(IsoFileInfoPointer, 0, sizeof(ISO_FILE_INFO));
|
||||
|
||||
//
|
||||
// Check and see if the first character is '\' and remove it if so
|
||||
//
|
||||
while (*FileName == '\\')
|
||||
{
|
||||
FileName++;
|
||||
}
|
||||
|
||||
//
|
||||
// Figure out how many sub-directories we are nested in
|
||||
//
|
||||
NumberOfPathParts = IsoGetNumPathParts(FileName);
|
||||
|
||||
DirectorySector = IsoRootSector;
|
||||
DirectoryLength = IsoRootLength;
|
||||
|
||||
//
|
||||
// Loop once for each part
|
||||
//
|
||||
for (i=0; i<NumberOfPathParts; i++)
|
||||
{
|
||||
//
|
||||
// Get first path part
|
||||
//
|
||||
IsoGetFirstNameFromPath(PathPart, FileName);
|
||||
|
||||
//
|
||||
// Advance to the next part of the path
|
||||
//
|
||||
for (; (*FileName != '\\') && (*FileName != '\0'); FileName++)
|
||||
{
|
||||
}
|
||||
FileName++;
|
||||
|
||||
//
|
||||
// Buffer the directory contents
|
||||
//
|
||||
DirectoryBuffer = IsoBufferDirectory(DirectorySector, DirectoryLength);
|
||||
if (DirectoryBuffer == NULL)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//
|
||||
// Search for file name in directory
|
||||
//
|
||||
if (!IsoSearchDirectoryBufferForFile(DirectoryBuffer, DirectoryLength, PathPart, &IsoFileInfo))
|
||||
{
|
||||
FreeMemory(DirectoryBuffer);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
FreeMemory(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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
memcpy(IsoFileInfoPointer, &IsoFileInfo, sizeof(ISO_FILE_INFO));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* IsoOpenFile()
|
||||
* Tries to open the file 'name' and returns true or false
|
||||
* for success and failure respectively
|
||||
*/
|
||||
FILE* IsoOpenFile(PUCHAR FileName)
|
||||
{
|
||||
ISO_FILE_INFO TempFileInfo;
|
||||
PISO_FILE_INFO FileHandle;
|
||||
|
||||
// DbgPrint((DPRINT_FILESYSTEM, "IsoOpenFile() FileName = %s\n", FileName));
|
||||
printf("IsoOpenFile() FileName = %s\n", FileName);
|
||||
|
||||
if (!IsoLookupFile(FileName, &TempFileInfo))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
FileHandle = AllocateMemory(sizeof(ISO_FILE_INFO));
|
||||
|
||||
if (FileHandle == NULL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memcpy(FileHandle, &TempFileInfo, sizeof(ISO_FILE_INFO));
|
||||
|
||||
return (FILE*)FileHandle;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* IsoReadPartialSector()
|
||||
* Reads part of a cluster into memory
|
||||
*/
|
||||
static BOOL IsoReadPartialSector(ULONG SectorNumber, ULONG StartingOffset, ULONG Length, PVOID Buffer)
|
||||
{
|
||||
PUCHAR SectorBuffer;
|
||||
|
||||
// DbgPrint((DPRINT_FILESYSTEM, "IsoReadPartialSector() SectorNumber = %d StartingOffset = %d Length = %d Buffer = 0x%x\n", SectorNumber, StartingOffset, Length, Buffer));
|
||||
printf("IsoReadPartialSector() SectorNumber = %d StartingOffset = %d Length = %d Buffer = 0x%x\n", SectorNumber, StartingOffset, Length, Buffer);
|
||||
|
||||
SectorBuffer = AllocateMemory(SECTORSIZE);
|
||||
if (SectorBuffer == NULL)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!BiosInt13ReadExtended(IsoDriveNumber, SectorNumber, 1, SectorBuffer))
|
||||
{
|
||||
FreeMemory(SectorBuffer);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
memcpy(Buffer, ((PVOID)SectorBuffer + StartingOffset), Length);
|
||||
|
||||
FreeMemory(SectorBuffer);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* IsoReadFile()
|
||||
* Reads BytesToRead from open file and
|
||||
* returns the number of bytes read in BytesRead
|
||||
*/
|
||||
BOOL IsoReadFile(FILE *FileHandle, ULONG BytesToRead, PULONG BytesRead, PVOID Buffer)
|
||||
{
|
||||
PISO_FILE_INFO IsoFileInfo = (PISO_FILE_INFO)FileHandle;
|
||||
UINT32 SectorNumber;
|
||||
UINT32 OffsetInSector;
|
||||
UINT32 LengthInSector;
|
||||
UINT32 NumberOfSectors;
|
||||
|
||||
// DbgPrint((DPRINT_FILESYSTEM, "IsoReadFile() BytesToRead = %d Buffer = 0x%x\n", BytesToRead, Buffer));
|
||||
printf("IsoReadFile() BytesToRead = %d Buffer = 0x%x\n", BytesToRead, Buffer);
|
||||
|
||||
if (BytesRead != NULL)
|
||||
{
|
||||
*BytesRead = 0;
|
||||
}
|
||||
|
||||
//
|
||||
// If they are trying to read past the
|
||||
// end of the file then return success
|
||||
// with BytesRead == 0
|
||||
//
|
||||
if (IsoFileInfo->FilePointer >= IsoFileInfo->FileSize)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
//
|
||||
// If they are trying to read more than there is to read
|
||||
// then adjust the amount to read
|
||||
//
|
||||
if ((IsoFileInfo->FilePointer + BytesToRead) > IsoFileInfo->FileSize)
|
||||
{
|
||||
BytesToRead = (IsoFileInfo->FileSize - IsoFileInfo->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 |
|
||||
// +-----------+-----------+-----------+-----------+
|
||||
// | |
|
||||
// +---------------+--------------------+
|
||||
// |
|
||||
// BytesToRead -------+
|
||||
//
|
||||
// 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 (IsoFileInfo->FilePointer % SECTORSIZE)
|
||||
{
|
||||
//
|
||||
// Do the math for our first read
|
||||
//
|
||||
SectorNumber = IsoFileInfo->FileStart + (IsoFileInfo->FilePointer / SECTORSIZE);
|
||||
OffsetInSector = IsoFileInfo->FilePointer % SECTORSIZE;
|
||||
LengthInSector = (BytesToRead > (SECTORSIZE - OffsetInSector)) ? (SECTORSIZE - OffsetInSector) : BytesToRead;
|
||||
|
||||
//
|
||||
// Now do the read and update BytesRead, BytesToRead, FilePointer, & Buffer
|
||||
//
|
||||
if (!IsoReadPartialSector(SectorNumber, OffsetInSector, LengthInSector, Buffer))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
if (BytesRead != NULL)
|
||||
{
|
||||
*BytesRead += LengthInSector;
|
||||
}
|
||||
BytesToRead -= LengthInSector;
|
||||
IsoFileInfo->FilePointer += LengthInSector;
|
||||
Buffer += LengthInSector;
|
||||
}
|
||||
|
||||
//
|
||||
// Do the math for our second read (if any data left)
|
||||
//
|
||||
if (BytesToRead > 0)
|
||||
{
|
||||
//
|
||||
// Determine how many full clusters we need to read
|
||||
//
|
||||
NumberOfSectors = (BytesToRead / SECTORSIZE);
|
||||
|
||||
if (NumberOfSectors > 0)
|
||||
{
|
||||
SectorNumber = IsoFileInfo->FileStart + (IsoFileInfo->FilePointer / SECTORSIZE);
|
||||
|
||||
//
|
||||
// Now do the read and update BytesRead, BytesToRead, FilePointer, & Buffer
|
||||
//
|
||||
if (!BiosInt13ReadExtended(IsoDriveNumber, SectorNumber, NumberOfSectors, Buffer))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
if (BytesRead != NULL)
|
||||
{
|
||||
*BytesRead += (NumberOfSectors * SECTORSIZE);
|
||||
}
|
||||
BytesToRead -= (NumberOfSectors * SECTORSIZE);
|
||||
IsoFileInfo->FilePointer += (NumberOfSectors * SECTORSIZE);
|
||||
Buffer += (NumberOfSectors * SECTORSIZE);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Do the math for our third read (if any data left)
|
||||
//
|
||||
if (BytesToRead > 0)
|
||||
{
|
||||
SectorNumber = IsoFileInfo->FileStart + (IsoFileInfo->FilePointer / SECTORSIZE);
|
||||
|
||||
//
|
||||
// Now do the read and update BytesRead, BytesToRead, FilePointer, & Buffer
|
||||
//
|
||||
if (!IsoReadPartialSector(SectorNumber, 0, BytesToRead, Buffer))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
if (BytesRead != NULL)
|
||||
{
|
||||
*BytesRead += BytesToRead;
|
||||
}
|
||||
BytesToRead -= BytesToRead;
|
||||
IsoFileInfo->FilePointer += BytesToRead;
|
||||
Buffer += BytesToRead;
|
||||
}
|
||||
|
||||
printf("IsoReadFile() done\n");
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
ULONG IsoGetFileSize(FILE *FileHandle)
|
||||
{
|
||||
PISO_FILE_INFO IsoFileHandle = (PISO_FILE_INFO)FileHandle;
|
||||
|
||||
// DbgPrint((DPRINT_FILESYSTEM, "IsoGetFileSize() FileSize = %d\n", IsoFileHandle->FileSize));
|
||||
printf("IsoGetFileSize() FileSize = %d\n", IsoFileHandle->FileSize);
|
||||
|
||||
return IsoFileHandle->FileSize;
|
||||
}
|
||||
|
||||
VOID IsoSetFilePointer(FILE *FileHandle, ULONG NewFilePointer)
|
||||
{
|
||||
PISO_FILE_INFO IsoFileHandle = (PISO_FILE_INFO)FileHandle;
|
||||
|
||||
// DbgPrint((DPRINT_FILESYSTEM, "IsoSetFilePointer() NewFilePointer = %d\n", NewFilePointer));
|
||||
printf("IsoSetFilePointer() NewFilePointer = %d\n", NewFilePointer);
|
||||
|
||||
IsoFileHandle->FilePointer = NewFilePointer;
|
||||
}
|
||||
|
||||
ULONG IsoGetFilePointer(FILE *FileHandle)
|
||||
{
|
||||
PISO_FILE_INFO IsoFileHandle = (PISO_FILE_INFO)FileHandle;
|
||||
|
||||
// DbgPrint((DPRINT_FILESYSTEM, "IsoGetFilePointer() FilePointer = %d\n", IsoFileHandle->FilePointer));
|
||||
printf("IsoGetFilePointer() FilePointer = %d\n", IsoFileHandle->FilePointer);
|
||||
|
||||
return IsoFileHandle->FilePointer;
|
||||
}
|
115
freeldr/freeldr/fs/iso.h
Normal file
115
freeldr/freeldr/fs/iso.h
Normal file
|
@ -0,0 +1,115 @@
|
|||
/*
|
||||
* FreeLoader
|
||||
* Copyright (C) 1998-2002 Brian Palmer <brianp@sginet.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef __ISO_H
|
||||
#define __ISO_H
|
||||
|
||||
|
||||
struct _DIR_RECORD
|
||||
{
|
||||
UCHAR RecordLength; // 1
|
||||
UCHAR ExtAttrRecordLength; // 2
|
||||
ULONG ExtentLocationL; // 3-6
|
||||
ULONG ExtentLocationM; // 7-10
|
||||
ULONG DataLengthL; // 11-14
|
||||
ULONG DataLengthM; // 15-18
|
||||
UCHAR Year; // 19
|
||||
UCHAR Month; // 20
|
||||
UCHAR Day; // 21
|
||||
UCHAR Hour; // 22
|
||||
UCHAR Minute; // 23
|
||||
UCHAR Second; // 24
|
||||
UCHAR TimeZone; // 25
|
||||
UCHAR FileFlags; // 26
|
||||
UCHAR FileUnitSize; // 27
|
||||
UCHAR InterleaveGapSize; // 28
|
||||
ULONG VolumeSequenceNumber; // 29-32
|
||||
UCHAR FileIdLength; // 33
|
||||
UCHAR FileId[1]; // 34
|
||||
} __attribute__((packed));
|
||||
|
||||
typedef struct _DIR_RECORD DIR_RECORD, *PDIR_RECORD;
|
||||
|
||||
|
||||
|
||||
|
||||
/* Volume Descriptor header*/
|
||||
struct _VD_HEADER
|
||||
{
|
||||
UCHAR VdType; // 1
|
||||
UCHAR StandardId[5]; // 2-6
|
||||
UCHAR VdVersion; // 7
|
||||
} __attribute__((packed));
|
||||
|
||||
typedef struct _VD_HEADER VD_HEADER, *PVD_HEADER;
|
||||
|
||||
|
||||
|
||||
/* Primary Volume Descriptor */
|
||||
struct _PVD
|
||||
{
|
||||
UCHAR VdType; // 1
|
||||
UCHAR StandardId[5]; // 2-6
|
||||
UCHAR VdVersion; // 7
|
||||
UCHAR unused0; // 8
|
||||
UCHAR SystemId[32]; // 9-40
|
||||
UCHAR VolumeId[32]; // 41-72
|
||||
UCHAR unused1[8]; // 73-80
|
||||
ULONG VolumeSpaceSizeL; // 81-84
|
||||
ULONG VolumeSpaceSizeM; // 85-88
|
||||
UCHAR unused2[32]; // 89-120
|
||||
ULONG VolumeSetSize; // 121-124
|
||||
ULONG VolumeSequenceNumber; // 125-128
|
||||
ULONG LogicalBlockSize; // 129-132
|
||||
ULONG PathTableSizeL; // 133-136
|
||||
ULONG PathTableSizeM; // 137-140
|
||||
ULONG LPathTablePos; // 141-144
|
||||
ULONG LOptPathTablePos; // 145-148
|
||||
ULONG MPathTablePos; // 149-152
|
||||
ULONG MOptPathTablePos; // 153-156
|
||||
DIR_RECORD RootDirRecord; // 157-190
|
||||
UCHAR VolumeSetIdentifier[128]; // 191-318
|
||||
UCHAR PublisherIdentifier[128]; // 319-446
|
||||
|
||||
/* more data ... */
|
||||
|
||||
} __attribute__((packed));
|
||||
|
||||
typedef struct _PVD PVD, *PPVD;
|
||||
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
ULONG FileStart; // File start sector
|
||||
ULONG FileSize; // File size
|
||||
ULONG FilePointer; // File pointer
|
||||
BOOL Directory;
|
||||
ULONG DriveNumber;
|
||||
} ISO_FILE_INFO, * PISO_FILE_INFO;
|
||||
|
||||
|
||||
BOOL IsoOpenVolume(ULONG DriveNumber);
|
||||
FILE* IsoOpenFile(PUCHAR FileName);
|
||||
BOOL IsoReadFile(FILE *FileHandle, ULONG BytesToRead, PULONG BytesRead, PVOID Buffer);
|
||||
ULONG IsoGetFileSize(FILE *FileHandle);
|
||||
VOID IsoSetFilePointer(FILE *FileHandle, ULONG NewFilePointer);
|
||||
ULONG IsoGetFilePointer(FILE *FileHandle);
|
||||
|
||||
#endif // #defined __FAT_H
|
Loading…
Reference in a new issue