diff --git a/freeldr/freeldr/arch/i386/disk.S b/freeldr/freeldr/arch/i386/disk.S index 8b3c1979350..f8ccf551429 100644 --- a/freeldr/freeldr/arch/i386/disk.S +++ b/freeldr/freeldr/arch/i386/disk.S @@ -292,7 +292,7 @@ EXTERN(_BiosInt13ExtensionsSupported) movb _int13_extension_check_drive,%dl // DL = drive (80h-FFh) int $0x13 // IBM/MS INT 13 Extensions - INSTALLATION CHECK jc _int13_extension_check_error // CF set on error (extensions not supported) - cmpw $0x55aa,%bx // BX = AA55h if installed + cmpw $0xaa55,%bx // BX = AA55h if installed jne _int13_extension_check_error testb $1,%cl // CX = API subset support bitmap jz _int13_extension_check_error // Bit 0, extended disk access functions (AH=42h-44h,47h,48h) supported diff --git a/freeldr/freeldr/fs/fat.c b/freeldr/freeldr/fs/fat.c index 8cb6836110b..c7ac7e76735 100644 --- a/freeldr/freeldr/fs/fat.c +++ b/freeldr/freeldr/fs/fat.c @@ -285,10 +285,35 @@ PVOID FatBufferDirectory(UINT32 DirectoryStartCluster, PUINT32 EntryCountPointer // if ((RootDirectory) && (FatType != FAT32)) { - DirectorySize = (FatVolumeBootSector->RootDirEntries / 32) * 512; + DbgPrint((DPRINT_FILESYSTEM, "We are here.\n")); + /*DbgPrint((DPRINT_FILESYSTEM, "sizeof(FAT_BOOTSECTOR) = 0x%x.\n", sizeof(FAT_BOOTSECTOR))); + + DbgPrint((DPRINT_FILESYSTEM, "JumpBoot: 0x%x 0x%x 0x%x\n", FatVolumeBootSector->JumpBoot[0], FatVolumeBootSector->JumpBoot[1], FatVolumeBootSector->JumpBoot[2])); + DbgPrint((DPRINT_FILESYSTEM, "OemName: %c%c%c%c%c%c%c%c\n", FatVolumeBootSector->OemName[0], FatVolumeBootSector->OemName[1], FatVolumeBootSector->OemName[2], FatVolumeBootSector->OemName[3], FatVolumeBootSector->OemName[4], FatVolumeBootSector->OemName[5], FatVolumeBootSector->OemName[6], FatVolumeBootSector->OemName[7]));*/ + DbgPrint((DPRINT_FILESYSTEM, "BytesPerSector: %d\n", FatVolumeBootSector->BytesPerSector)); + DbgPrint((DPRINT_FILESYSTEM, "SectorsPerCluster: %d\n", FatVolumeBootSector->SectorsPerCluster)); + DbgPrint((DPRINT_FILESYSTEM, "ReservedSectors: %d\n", FatVolumeBootSector->ReservedSectors)); + DbgPrint((DPRINT_FILESYSTEM, "NumberOfFats: %d\n", FatVolumeBootSector->NumberOfFats)); + DbgPrint((DPRINT_FILESYSTEM, "RootDirEntries: %d\n", FatVolumeBootSector->RootDirEntries)); + DbgPrint((DPRINT_FILESYSTEM, "TotalSectors: %d\n", FatVolumeBootSector->TotalSectors)); + DbgPrint((DPRINT_FILESYSTEM, "MediaDescriptor: 0x%x\n", FatVolumeBootSector->MediaDescriptor)); + DbgPrint((DPRINT_FILESYSTEM, "SectorsPerFat: %d\n", FatVolumeBootSector->SectorsPerFat)); + DbgPrint((DPRINT_FILESYSTEM, "SectorsPerTrack: %d\n", FatVolumeBootSector->SectorsPerTrack)); + DbgPrint((DPRINT_FILESYSTEM, "NumberOfHeads: %d\n", FatVolumeBootSector->NumberOfHeads)); + DbgPrint((DPRINT_FILESYSTEM, "HiddenSectors: %d\n", FatVolumeBootSector->HiddenSectors)); + DbgPrint((DPRINT_FILESYSTEM, "TotalSectorsBig: %d\n", FatVolumeBootSector->TotalSectorsBig)); + DbgPrint((DPRINT_FILESYSTEM, "DriveNumber: 0x%x\n", FatVolumeBootSector->DriveNumber)); + DbgPrint((DPRINT_FILESYSTEM, "Reserved1: 0x%x\n", FatVolumeBootSector->Reserved1)); + DbgPrint((DPRINT_FILESYSTEM, "BootSignature: 0x%x\n", FatVolumeBootSector->BootSignature)); + DbgPrint((DPRINT_FILESYSTEM, "VolumeSerialNumber: 0x%x\n", FatVolumeBootSector->VolumeSerialNumber)); + /*DbgPrint((DPRINT_FILESYSTEM, "VolumeLabel: %c%c%c%c%c%c%c%c%c%c%c\n", FatVolumeBootSector->VolumeLabel[0], FatVolumeBootSector->VolumeLabel[1], FatVolumeBootSector->VolumeLabel[2], FatVolumeBootSector->VolumeLabel[3], FatVolumeBootSector->VolumeLabel[4], FatVolumeBootSector->VolumeLabel[5], FatVolumeBootSector->VolumeLabel[6], FatVolumeBootSector->VolumeLabel[7], FatVolumeBootSector->VolumeLabel[8], FatVolumeBootSector->VolumeLabel[9], FatVolumeBootSector->VolumeLabel[10])); + DbgPrint((DPRINT_FILESYSTEM, "FileSystemType: %c%c%c%c%c%c%c%c\n", FatVolumeBootSector->FileSystemType[0], FatVolumeBootSector->FileSystemType[1], FatVolumeBootSector->FileSystemType[2], FatVolumeBootSector->FileSystemType[3], FatVolumeBootSector->FileSystemType[4], FatVolumeBootSector->FileSystemType[5], FatVolumeBootSector->FileSystemType[6], FatVolumeBootSector->FileSystemType[7]));*/ + DbgPrint((DPRINT_FILESYSTEM, "BootSectorMagic: 0x%x\n", FatVolumeBootSector->BootSectorMagic)); + DirectorySize = ROUND_UP((FatVolumeBootSector->RootDirEntries * 32), FatVolumeBootSector->BytesPerSector); } else { + DbgPrint((DPRINT_FILESYSTEM, "No we are here.\n")); if (RootDirectory) { DirectorySize = (FatCountClustersInChain(Fat32VolumeBootSector->RootDirStartCluster) * Fat32VolumeBootSector->SectorsPerCluster) * Fat32VolumeBootSector->BytesPerSector; @@ -302,6 +327,7 @@ PVOID FatBufferDirectory(UINT32 DirectoryStartCluster, PUINT32 EntryCountPointer // // Attempt to allocate memory for directory buffer // + DbgPrint((DPRINT_FILESYSTEM, "Trying to allocate (DirectorySize) %d bytes.\n", DirectorySize)); DirectoryBuffer = AllocateMemory(DirectorySize); if (DirectoryBuffer == NULL) @@ -328,7 +354,7 @@ PVOID FatBufferDirectory(UINT32 DirectoryStartCluster, PUINT32 EntryCountPointer // FAT type is not FAT32 so the root directory comes right after the fat table // RootDirectoryStartSector = FatVolumeBootSector->ReservedSectors + (FatVolumeBootSector->NumberOfFats * FatVolumeBootSector->SectorsPerFat); - RootDirectorySectorCount = FatVolumeBootSector->RootDirEntries / 32; + RootDirectorySectorCount = (DirectorySize / FatVolumeBootSector->BytesPerSector); if (!FatReadVolumeSectors(FatDriveNumber, RootDirectoryStartSector, RootDirectorySectorCount, DirectoryBuffer)) { diff --git a/freeldr/freeldr/inifile/Makefile b/freeldr/freeldr/inifile/Makefile new file mode 100644 index 00000000000..55309ff74c8 --- /dev/null +++ b/freeldr/freeldr/inifile/Makefile @@ -0,0 +1,42 @@ +# +# FreeLoader +# Copyright (C) 1998-2002 Brian Palmer +# +# 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 ../rules.mk + +OBJS = inifile.o init.o parse.o + +.PHONY : clean + +all: inifile.a + +inifile.a: $(OBJS) + $(LD) -r -o inifile.a $(OBJS) + +inifile.o: inifile.c ../inifile.h + $(CC) $(FLAGS) -o inifile.o -c inifile.c + +init.o: init.c ../inifile.h + $(CC) $(FLAGS) -o init.o -c init.c + +parse.o: parse.c ../inifile.h + $(CC) $(FLAGS) -o parse.o -c parse.c + +clean: + - $(RM) *.o + - $(RM) *.a diff --git a/freeldr/freeldr/inifile/ini.h b/freeldr/freeldr/inifile/ini.h new file mode 100644 index 00000000000..3fc08b97250 --- /dev/null +++ b/freeldr/freeldr/inifile/ini.h @@ -0,0 +1,55 @@ +/* + * FreeLoader + * Copyright (C) 1998-2002 Brian Palmer + * + * 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 __INI_H +#define __INI_H + +#include + + +#define INI_FILE_COMMENT_CHAR ';' + + + +// This structure describes a single .ini file item +// The item format in the .ini file is: +// Name=Value +typedef struct +{ + LIST_ITEM ListEntry; + PUCHAR ItemName; + PUCHAR ItemValue; + +} INI_SECTION_ITEM, *PINI_SECTION_ITEM; + +// This structure describes a .ini file section +// The section format in the .ini file is: +// [Section Name] +// This structure has a list of section items with +// one INI_SECTION_ITEM for each line in the section +typedef struct +{ + LIST_ITEM ListEntry; + PUCHAR SectionName; + ULONG SectionItemCount; + PINI_SECTION_ITEM SectionItemList; + +} INI_SECTION, *PINI_SECTION; + +#endif // defined __INI_H diff --git a/freeldr/freeldr/inifile/inifile.c b/freeldr/freeldr/inifile/inifile.c new file mode 100644 index 00000000000..aafe03357c2 --- /dev/null +++ b/freeldr/freeldr/inifile/inifile.c @@ -0,0 +1,433 @@ +/* + * FreeLoader + * Copyright (C) 1998-2002 Brian Palmer + * + * 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 "parseini.h" +#include "ui.h" +#include "fs.h" +#include "rtl.h" +#include "mm.h" +#include "debug.h" + +PUCHAR FreeLoaderIniFileData = NULL; +ULONG FreeLoaderIniFileSize = 0; + +BOOL ParseIniFile(VOID) +{ + //int i; + //char name[1024]; + //char value[1024]; + PFILE Freeldr_Ini; // File handle for freeldr.ini + + // Open the boot drive for file access + if (!OpenDiskDrive(BootDrive, 0)) + { + printf("Error opening boot drive for file access.\n"); + return FALSE; + } + + // Try to open freeldr.ini or fail + Freeldr_Ini = OpenFile("freeldr.ini"); + if (Freeldr_Ini == NULL) + { + printf("FREELDR.INI not found.\nYou need to re-install FreeLoader.\n"); + return FALSE; + } + + // Get the file size & allocate enough memory for it + FreeLoaderIniFileSize = GetFileSize(Freeldr_Ini); + FreeLoaderIniFileData = AllocateMemory(FreeLoaderIniFileSize); + + // If we are out of memory then return FALSE + if (FreeLoaderIniFileData == NULL) + { + printf("Out of memory while loading FREELDR.INI.\n"); + CloseFile(Freeldr_Ini); + return FALSE; + } + + // Read freeldr.ini off the disk + ReadFile(Freeldr_Ini, FreeLoaderIniFileSize, NULL, FreeLoaderIniFileData); + CloseFile(Freeldr_Ini); + + // Make sure the [FREELOADER] section exists + /*if (OpenSection("FREELOADER", NULL)) + { + printf("Section [FREELOADER] not found in FREELDR.INI.\nYou need to re-install FreeLoader.\n"); + return FALSE; + } + + // Validate the settings in the [FREELOADER] section + for (i=1; i<=GetNumSectionItems("FREELOADER"); i++) + { + ReadSectionSettingByNumber("FREELOADER", i, name, value); + if (!IsValidSetting(name, value)) + { + printf("Invalid setting in freeldr.ini.\nName: \"%s\", Value: \"%s\"\n", name, value); + printf("Press any key to continue.\n"); + getch(); + } + else + SetSetting(name, value); + }*/ + + return TRUE; +} + +ULONG GetNextLineOfFileData(PUCHAR Buffer, ULONG BufferSize, ULONG CurrentOffset) +{ + ULONG Idx; + + // Loop through grabbing chars until we hit the end of the + // file or we encounter a new line char + for (Idx=0; (CurrentOffset < FreeLoaderIniFileSize); CurrentOffset++) + { + // If we haven't exceeded our buffer size yet + // then store another char + if (Idx < (BufferSize - 1)) + { + Buffer[Idx++] = FreeLoaderIniFileData[CurrentOffset]; + } + + // Check for new line char + if (FreeLoaderIniFileData[CurrentOffset] == '\n') + { + CurrentOffset++; + break; + } + } + + // Terminate the string + Buffer[Idx] = '\0'; + + // Get rid of newline & linefeed characters (if any) + if((Buffer[strlen(Buffer)-1] == '\n') || (Buffer[strlen(Buffer)-1] == '\r')) + Buffer[strlen(Buffer)-1] = '\0'; + if((Buffer[strlen(Buffer)-1] == '\n') || (Buffer[strlen(Buffer)-1] == '\r')) + Buffer[strlen(Buffer)-1] = '\0'; + + // Send back new offset + return CurrentOffset; +} + +BOOL OpenSection(PUCHAR SectionName, PULONG SectionId) +{ + UCHAR TempString[80]; + UCHAR RealSectionName[80]; + ULONG FileOffset; + BOOL SectionFound = FALSE; + + // + // Get the real section name + // + strcpy(RealSectionName, "["); + strcat(RealSectionName, SectionName); + strcat(RealSectionName, "]"); + + // + // Get to the beginning of the file + // + FileOffset = 0; + + // + // Find the section + // + while (FileOffset < FreeLoaderIniFileSize) + { + // + // Read a line + // + FileOffset = GetNextLineOfFileData(TempString, 80, FileOffset); + + // + // If it isn't a section header then continue on + // + if (TempString[0] != '[') + continue; + + // + // Check and see if we found it + // + if (stricmp(TempString, RealSectionName) == 0) + { + SectionFound = TRUE; + break; + } + } + + if (SectionId) + { + *SectionId = FileOffset; + } + + return SectionFound; +} + +ULONG GetNumSectionItems(ULONG SectionId) +{ + UCHAR TempString[80]; + ULONG SectionItemCount = 0; + + // Now count how many settings are in this section + while (SectionId < FreeLoaderIniFileSize) + { + // Read a line + SectionId = GetNextLineOfFileData(TempString, 80, SectionId); + + // If we hit a new section then we're done + if (TempString[0] == '[') + break; + + // Skip comments + if (TempString[0] == '#') + continue; + + // Skip blank lines + if (!strlen(TempString)) + continue; + + SectionItemCount++; + } + + return SectionItemCount; +} + +BOOL ReadSectionSettingByNumber(ULONG SectionId, ULONG SettingNumber, PUCHAR SettingName, ULONG NameSize, PUCHAR SettingValue, ULONG ValueSize) +{ + UCHAR TempString[1024]; + ULONG SectionItemCount = 0; + ULONG Idx; + ULONG FileOffset; + + // + // Get to the beginning of the section + // + FileOffset = SectionId; + + // + // Now find the setting we are looking for + // + do + { + // Read a line + FileOffset = GetNextLineOfFileData(TempString, 1024, FileOffset); + + // Skip comments + if (TempString[0] == '#') + continue; + + // Skip blank lines + if (!strlen(TempString)) + continue; + + // If we hit a new section then we're done + if (TempString[0] == '[') + break; + + // Check and see if we found the setting + if (SectionItemCount == SettingNumber) + { + for (Idx=0; Idx + * + * 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 +#include "ini.h" +#include +#include +#include +#include +#include + + +BOOL InitializeIniFile(VOID) +{ + PFILE Freeldr_Ini; // File handle for freeldr.ini + PUCHAR FreeLoaderIniFileData; + ULONG FreeLoaderIniFileSize; + + // Open the boot drive for file access + if (!OpenDiskDrive(BootDrive, 0)) + { + printf("Error opening boot drive for file access.\n"); + return FALSE; + } + + // Try to open freeldr.ini or fail + Freeldr_Ini = OpenFile("freeldr.ini"); + if (Freeldr_Ini == NULL) + { + printf("FREELDR.INI not found.\nYou need to re-install FreeLoader.\n"); + return FALSE; + } + + // Get the file size & allocate enough memory for it + FreeLoaderIniFileSize = GetFileSize(Freeldr_Ini); + FreeLoaderIniFileData = AllocateMemory(FreeLoaderIniFileSize); + + // If we are out of memory then return FALSE + if (FreeLoaderIniFileData == NULL) + { + printf("Out of memory while loading FREELDR.INI.\n"); + CloseFile(Freeldr_Ini); + return FALSE; + } + + // Read freeldr.ini off the disk + if (!ReadFile(Freeldr_Ini, FreeLoaderIniFileSize, NULL, FreeLoaderIniFileData)) + { + CloseFile(Freeldr_Ini); + FreeMemory(FreeLoaderIniFileData); + return FALSE; + } + + CloseFile(Freeldr_Ini); + FreeMemory(FreeLoaderIniFileData); + + return TRUE; +} diff --git a/freeldr/freeldr/inifile/parse.c b/freeldr/freeldr/inifile/parse.c new file mode 100644 index 00000000000..ea255370ab3 --- /dev/null +++ b/freeldr/freeldr/inifile/parse.c @@ -0,0 +1,243 @@ +/* + * FreeLoader + * Copyright (C) 1998-2002 Brian Palmer + * + * 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 +#include "ini.h" +#include +#include +#include +#include +#include + + +VOID IniParseFile(PUCHAR IniFileData, ULONG IniFileSize) +{ +} + +ULONG IniGetNextLineSize(PUCHAR IniFileData, ULONG IniFileSize, ULONG CurrentOffset) +{ + ULONG Idx; + ULONG LineCharCount = 0; + + // Loop through grabbing chars until we hit the end of the + // file or we encounter a new line char + for (Idx=0; (CurrentOffset < IniFileSize); CurrentOffset++) + { + // Increment the line character count + LineCharCount++; + + // Check for new line char + if (IniFileData[CurrentOffset] == '\n') + { + CurrentOffset++; + break; + } + } + + // Send back line character count + return LineCharCount; +} + +ULONG IniGetNextLine(PUCHAR IniFileData, ULONG IniFileSize, PUCHAR Buffer, ULONG BufferSize, ULONG CurrentOffset) +{ + ULONG Idx; + + // Loop through grabbing chars until we hit the end of the + // file or we encounter a new line char + for (Idx=0; (CurrentOffset < IniFileSize); CurrentOffset++) + { + // If we haven't exceeded our buffer size yet + // then store another char + if (Idx < (BufferSize - 1)) + { + Buffer[Idx++] = IniFileData[CurrentOffset]; + } + + // Check for new line char + if (IniFileData[CurrentOffset] == '\n') + { + CurrentOffset++; + break; + } + } + + // Terminate the string + Buffer[Idx] = '\0'; + + // Get rid of newline & linefeed characters (if any) + if((Buffer[strlen(Buffer)-1] == '\n') || (Buffer[strlen(Buffer)-1] == '\r')) + Buffer[strlen(Buffer)-1] = '\0'; + if((Buffer[strlen(Buffer)-1] == '\n') || (Buffer[strlen(Buffer)-1] == '\r')) + Buffer[strlen(Buffer)-1] = '\0'; + + // Send back new offset + return CurrentOffset; +} + +BOOL IniIsLineEmpty(PUCHAR LineOfText, ULONG TextLength) +{ + ULONG Idx; + + // Check the first character (skipping whitespace) + // and make sure that it is an opening bracket + for (Idx=0; Idx