mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 16:32:59 +00:00
Added ISO-9660 support.
svn path=/trunk/; revision=2865
This commit is contained in:
parent
13206a61a1
commit
c1e3c3d7fe
7 changed files with 770 additions and 1 deletions
|
@ -112,6 +112,7 @@ BOOL DiskReadLogicalSectors(ULONG DriveNumber, ULONG SectorNumber, ULONG SectorC
|
||||||
//
|
//
|
||||||
///////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////
|
||||||
BOOL DiskIsDriveRemovable(ULONG DriveNumber);
|
BOOL DiskIsDriveRemovable(ULONG DriveNumber);
|
||||||
|
BOOL DiskIsDriveCdRom(ULONG DriveNumber);
|
||||||
BOOL DiskGetActivePartitionEntry(ULONG DriveNumber, PPARTITION_TABLE_ENTRY PartitionTableEntry);
|
BOOL DiskGetActivePartitionEntry(ULONG DriveNumber, PPARTITION_TABLE_ENTRY PartitionTableEntry);
|
||||||
BOOL DiskGetPartitionEntry(ULONG DriveNumber, ULONG PartitionNumber, PPARTITION_TABLE_ENTRY PartitionTableEntry);
|
BOOL DiskGetPartitionEntry(ULONG DriveNumber, ULONG PartitionNumber, PPARTITION_TABLE_ENTRY PartitionTableEntry);
|
||||||
BOOL DiskGetFirstPartitionEntry(PMASTER_BOOT_RECORD MasterBootRecord, PPARTITION_TABLE_ENTRY PartitionTableEntry);
|
BOOL DiskGetFirstPartitionEntry(PMASTER_BOOT_RECORD MasterBootRecord, PPARTITION_TABLE_ENTRY PartitionTableEntry);
|
||||||
|
|
|
@ -40,6 +40,43 @@ BOOL DiskIsDriveRemovable(ULONG DriveNumber)
|
||||||
return TRUE;
|
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)
|
BOOL DiskGetActivePartitionEntry(ULONG DriveNumber, PPARTITION_TABLE_ENTRY PartitionTableEntry)
|
||||||
{
|
{
|
||||||
ULONG BootablePartitionCount = 0;
|
ULONG BootablePartitionCount = 0;
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
#define FS_NTFS 2
|
#define FS_NTFS 2
|
||||||
#define FS_EXT2 3
|
#define FS_EXT2 3
|
||||||
#define FS_REISER 4
|
#define FS_REISER 4
|
||||||
|
#define FS_ISO9660 5
|
||||||
|
|
||||||
#define FILE VOID
|
#define FILE VOID
|
||||||
#define PFILE FILE *
|
#define PFILE FILE *
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
|
|
||||||
include ../rules.mk
|
include ../rules.mk
|
||||||
|
|
||||||
OBJS = fs.o fat.o
|
OBJS = fs.o fat.o iso.o
|
||||||
|
|
||||||
.PHONY : clean
|
.PHONY : clean
|
||||||
|
|
||||||
|
@ -34,6 +34,9 @@ fs.o: fs.c fat.h ../fs.h
|
||||||
fat.o: fat.c fat.h ../fs.h
|
fat.o: fat.c fat.h ../fs.h
|
||||||
$(CC) $(FLAGS) -o fat.o -c fat.c
|
$(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:
|
clean:
|
||||||
- $(RM) *.o
|
- $(RM) *.o
|
||||||
- $(RM) *.a
|
- $(RM) *.a
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include <freeldr.h>
|
#include <freeldr.h>
|
||||||
#include <fs.h>
|
#include <fs.h>
|
||||||
#include "fat.h"
|
#include "fat.h"
|
||||||
|
#include "iso.h"
|
||||||
#include <disk.h>
|
#include <disk.h>
|
||||||
#include <rtl.h>
|
#include <rtl.h>
|
||||||
#include <ui.h>
|
#include <ui.h>
|
||||||
|
@ -84,6 +85,16 @@ BOOL OpenDiskDrive(ULONG DriveNumber, ULONG PartitionNumber)
|
||||||
return FatOpenVolume(DriveNumber, 0);
|
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
|
// Set the boot partition
|
||||||
BootPartition = PartitionNumber;
|
BootPartition = PartitionNumber;
|
||||||
|
|
||||||
|
@ -93,6 +104,7 @@ BOOL OpenDiskDrive(ULONG DriveNumber, ULONG PartitionNumber)
|
||||||
// Partition requested was zero which means the boot partition
|
// Partition requested was zero which means the boot partition
|
||||||
if (DiskGetActivePartitionEntry(DriveNumber, &PartitionTableEntry) == FALSE)
|
if (DiskGetActivePartitionEntry(DriveNumber, &PartitionTableEntry) == FALSE)
|
||||||
{
|
{
|
||||||
|
FileSystemError("No active partition.");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -101,6 +113,7 @@ BOOL OpenDiskDrive(ULONG DriveNumber, ULONG PartitionNumber)
|
||||||
// Get requested partition
|
// Get requested partition
|
||||||
if (DiskGetPartitionEntry(DriveNumber, PartitionNumber, &PartitionTableEntry) == FALSE)
|
if (DiskGetPartitionEntry(DriveNumber, PartitionNumber, &PartitionTableEntry) == FALSE)
|
||||||
{
|
{
|
||||||
|
FileSystemError("Partition not found.");
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -147,6 +160,10 @@ PFILE OpenFile(PUCHAR FileName)
|
||||||
{
|
{
|
||||||
FileHandle = FatOpenFile(FileName);
|
FileHandle = FatOpenFile(FileName);
|
||||||
}
|
}
|
||||||
|
else if (FileSystemType == FS_ISO9660)
|
||||||
|
{
|
||||||
|
FileHandle = IsoOpenFile(FileName);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
FileSystemError("Error: Unknown filesystem.");
|
FileSystemError("Error: Unknown filesystem.");
|
||||||
|
@ -193,6 +210,10 @@ BOOL ReadFile(PFILE FileHandle, ULONG BytesToRead, PULONG BytesRead, PVOID Buffe
|
||||||
|
|
||||||
return FatReadFile(FileHandle, BytesToRead, BytesRead, Buffer);
|
return FatReadFile(FileHandle, BytesToRead, BytesRead, Buffer);
|
||||||
|
|
||||||
|
case FS_ISO9660:
|
||||||
|
|
||||||
|
return IsoReadFile(FileHandle, BytesToRead, BytesRead, Buffer);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
||||||
FileSystemError("Unknown file system.");
|
FileSystemError("Unknown file system.");
|
||||||
|
@ -210,6 +231,10 @@ ULONG GetFileSize(PFILE FileHandle)
|
||||||
|
|
||||||
return FatGetFileSize(FileHandle);
|
return FatGetFileSize(FileHandle);
|
||||||
|
|
||||||
|
case FS_ISO9660:
|
||||||
|
|
||||||
|
return IsoGetFileSize(FileHandle);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
FileSystemError("Unknown file system.");
|
FileSystemError("Unknown file system.");
|
||||||
break;
|
break;
|
||||||
|
@ -227,6 +252,11 @@ VOID SetFilePointer(PFILE FileHandle, ULONG NewFilePointer)
|
||||||
FatSetFilePointer(FileHandle, NewFilePointer);
|
FatSetFilePointer(FileHandle, NewFilePointer);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case FS_ISO9660:
|
||||||
|
|
||||||
|
IsoSetFilePointer(FileHandle, NewFilePointer);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
FileSystemError("Unknown file system.");
|
FileSystemError("Unknown file system.");
|
||||||
break;
|
break;
|
||||||
|
@ -242,6 +272,11 @@ ULONG GetFilePointer(PFILE FileHandle)
|
||||||
return FatGetFilePointer(FileHandle);
|
return FatGetFilePointer(FileHandle);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case FS_ISO9660:
|
||||||
|
|
||||||
|
return IsoGetFilePointer(FileHandle);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
FileSystemError("Unknown file system.");
|
FileSystemError("Unknown file system.");
|
||||||
break;
|
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…
Add table
Add a link
Reference in a new issue