--- /dev/null
+#
+# FreeLoader
+# Copyright (C) 1999, 2000, 2001 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.
+#
+
+
+export CC = gcc
+export LD = ld
+export AR = ar
+export RM = cmd /C del
+export CP = cmd /C copy
+export NASM = nasm
+export MAKE = make
+
+FLAGS = -Wall
+
+OBJS = install.o volume.o
+
+LIBS = -lkernel32
+
+.PHONY : clean
+
+all: install.exe
+
+install.exe: $(OBJS)
+ $(CC) $(FLAGS) -o install.exe $(OBJS)
+
+install.o: install.c install.h volume.h
+ $(CC) $(FLAGS) -o install.o -c install.c
+
+volume.o: volume.c volume.h install.h
+ $(CC) $(FLAGS) -o volume.o -c volume.c
+
+clean:
+
\ No newline at end of file
--- /dev/null
+/*
+ * FreeLoader - install.c
+ *
+ * Copyright (C) 2001 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 <windows.h>
+#include <tchar.h>
+#include <stdio.h>
+#include "install.h"
+#include "volume.h"
+#include "../bootsect/fat.h"
+#include "../bootsect/fat32.h"
+
+BOOL BackupBootSector(LPCTSTR lpszVolumeName);
+BOOL InstallBootSector(LPCTSTR lpszVolumeType);
+
+int main(int argc, char *argv[])
+{
+
+ if (argc < 3)
+ {
+ _tprintf(_T("syntax: install x: [fs_type]\nwhere fs_type is fat or fat32\n"));
+ return -1;
+ }
+
+ if (!OpenVolume(argv[1]))
+ {
+ return -1;
+ }
+
+ BackupBootSector(argv[1]);
+
+ InstallBootSector(argv[2]);
+
+ _tprintf(_T("You must now copy freeldr.sys & freeldr.ini to %s.\n"), argv[1]);
+
+ CloseVolume();
+
+ return 0;
+}
+
+BOOL BackupBootSector(LPCTSTR lpszVolumeName)
+{
+ HANDLE hBackupFile;
+ TCHAR szFileName[MAX_PATH];
+ ULONG Count;
+ BYTE BootSectorBuffer[512];
+ DWORD dwNumberOfBytesWritten;
+ BOOL bRetVal;
+
+ //
+ // Find the next unused filename and open it
+ //
+ for (Count=0; ; Count++)
+ {
+ //
+ // Generate the next filename
+ //
+ _stprintf(szFileName, _T("%s\\bootsect.%03d"), lpszVolumeName, Count);
+
+ //
+ // Try to create a new file, fail if exists
+ //
+ hBackupFile = CreateFile(szFileName, GENERIC_WRITE, 0, NULL, CREATE_NEW, /*FILE_ATTRIBUTE_SYSTEM*/0, NULL);
+
+ //
+ // Check to see if it worked
+ //
+ if (hBackupFile != INVALID_HANDLE_VALUE)
+ {
+ break;
+ }
+
+ //
+ // Nope, didn't work
+ // Check to see if it already existed
+ //
+ if (!(GetLastError() != ERROR_ALREADY_EXISTS))
+ {
+ _tprintf(_T("%s:%d: "), __FILE__, __LINE__);
+ _tprintf(_T("Boot sector backup failed. Error code %d.\n"), GetLastError());
+ return FALSE;
+ }
+ }
+
+ //
+ // Try to read the boot sector
+ //
+ if (!ReadVolumeSector(0, BootSectorBuffer))
+ {
+ CloseHandle(hBackupFile);
+ return FALSE;
+ }
+
+ //
+ // Try to write the boot sector data to the file
+ //
+ bRetVal = WriteFile(hBackupFile, BootSectorBuffer, 512, &dwNumberOfBytesWritten, NULL);
+ if (!bRetVal || (dwNumberOfBytesWritten != 512))
+ {
+ CloseHandle(hBackupFile);
+ _tprintf(_T("%s:%d: "), __FILE__, __LINE__);
+ _tprintf(_T("WriteFile() failed. Error code %d.\n"), GetLastError());
+ return FALSE;
+ }
+
+ _tprintf(_T("Boot sector backed up to file: %s\n"), szFileName);
+
+ CloseHandle(hBackupFile);
+
+ return TRUE;
+}
+
+BOOL InstallBootSector(LPCTSTR lpszVolumeType)
+{
+ BYTE BootSectorBuffer[512];
+
+ //
+ // Read in the old boot sector
+ //
+ if (!ReadVolumeSector(0, BootSectorBuffer))
+ {
+ return FALSE;
+ }
+
+ if (_tcsicmp(lpszVolumeType, _T("fat")) == 0)
+ {
+ //
+ // Update the BPB in the new boot sector
+ //
+ memcpy((fat_data+3), (BootSectorBuffer+3), 59 /*fat BPB length*/);
+
+ //
+ // Write out new boot sector
+ //
+ if (!WriteVolumeSector(0, fat_data))
+ {
+ return FALSE;
+ }
+ }
+ else if (_tcsicmp(lpszVolumeType, _T("fat32")) == 0)
+ {
+ //
+ // Update the BPB in the new boot sector
+ //
+ memcpy((fat32_data+3), (BootSectorBuffer+3), 87 /*fat32 BPB length*/);
+
+ //
+ // Write out new boot sector
+ //
+ if (!WriteVolumeSector(0, fat32_data))
+ {
+ return FALSE;
+ }
+
+ //
+ // Write out new extra sector
+ //
+ if (!WriteVolumeSector(14, (fat_data+512) ))
+ {
+ return FALSE;
+ }
+ }
+ else
+ {
+ _tprintf(_T("%s:%d: "), __FILE__, __LINE__);
+ _tprintf(_T("File system type %s unknown.\n"), lpszVolumeType);
+ return FALSE;
+ }
+
+ _tprintf(_T("%s boot sector installed.\n"), lpszVolumeType);
+
+ return TRUE;
+}
--- /dev/null
+/*
+ * FreeLoader - install.h
+ *
+ * Copyright (C) 2001 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 __INSTALL_H
+#define __INSTALL_H
+
+#endif // defined __INSTALL_H
\ No newline at end of file
--- /dev/null
+/*
+ * FreeLoader - volume.c
+ *
+ * Copyright (C) 2001 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 <windows.h>
+#include <stdio.h>
+#include <tchar.h>
+#include "volume.h"
+
+static HANDLE hDiskVolume = NULL;
+
+BOOL OpenVolume(LPCTSTR lpszVolumeName)
+{
+ TCHAR RealVolumeName[MAX_PATH];
+
+ //
+ // If they passed in a drive letter (e.g. "A:")
+ // then try to open the physical device volume,
+ // otherwise we will assume it is a disk image
+ // file they are writing to. (not fully supported yet)
+ //
+ if ((_tcslen(lpszVolumeName) == 2) && (lpszVolumeName[1] == _T(':')))
+ {
+ _tcscpy(RealVolumeName, _T("\\\\.\\"));
+ _tcscat(RealVolumeName, lpszVolumeName);
+ }
+ else
+ {
+ _tcscpy(RealVolumeName, lpszVolumeName);
+ }
+
+ _tprintf(_T("Opening volume \'%s\'\n"), lpszVolumeName);
+
+ hDiskVolume = CreateFile(RealVolumeName,
+ GENERIC_READ | GENERIC_WRITE,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL,
+ OPEN_EXISTING,
+ 0,
+ NULL);
+
+ if (hDiskVolume == INVALID_HANDLE_VALUE)
+ {
+ _tprintf(_T("%s:%d: "), __FILE__, __LINE__);
+ _tprintf(_T("Failed. Error code %d.\n"), GetLastError());
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+void CloseVolume(void)
+{
+ CloseHandle(hDiskVolume);
+}
+
+BOOL ReadVolumeSector(ULONG SectorNumber, PVOID SectorBuffer)
+{
+ DWORD dwNumberOfBytesRead;
+ DWORD dwFilePosition;
+ BOOL bRetVal;
+
+ //
+ // FIXME: this doesn't seem to handle the situation
+ // properly when SectorNumber is bigger than the
+ // amount of sectors on the disk. Seems to me that
+ // the call to SetFilePointer() should just give an
+ // out of bounds error or something but it doesn't.
+ //
+ dwFilePosition = SetFilePointer(hDiskVolume, (SectorNumber * 512), NULL, FILE_BEGIN);
+ if (dwFilePosition != (SectorNumber * 512))
+ {
+ _tprintf(_T("%s:%d: "), __FILE__, __LINE__);
+ _tprintf(_T("SetFilePointer() failed. Error code %d.\n"), GetLastError());
+ return FALSE;
+ }
+
+ bRetVal = ReadFile(hDiskVolume, SectorBuffer, 512, &dwNumberOfBytesRead, NULL);
+ if (!bRetVal || (dwNumberOfBytesRead != 512))
+ {
+ _tprintf(_T("%s:%d: "), __FILE__, __LINE__);
+ _tprintf(_T("ReadFile() failed. Error code %d.\n"), GetLastError());
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+BOOL WriteVolumeSector(ULONG SectorNumber, PVOID SectorBuffer)
+{
+ DWORD dwNumberOfBytesWritten;
+ DWORD dwFilePosition;
+ BOOL bRetVal;
+
+ //
+ // FIXME: this doesn't seem to handle the situation
+ // properly when SectorNumber is bigger than the
+ // amount of sectors on the disk. Seems to me that
+ // the call to SetFilePointer() should just give an
+ // out of bounds error or something but it doesn't.
+ //
+ dwFilePosition = SetFilePointer(hDiskVolume, (SectorNumber * 512), NULL, FILE_BEGIN);
+ if (dwFilePosition != (SectorNumber * 512))
+ {
+ _tprintf(_T("%s:%d: "), __FILE__, __LINE__);
+ _tprintf(_T("SetFilePointer() failed. Error code %d.\n"), GetLastError());
+ return FALSE;
+ }
+
+ bRetVal = WriteFile(hDiskVolume, SectorBuffer, 512, &dwNumberOfBytesWritten, NULL);
+ if (!bRetVal || (dwNumberOfBytesWritten != 512))
+ {
+ _tprintf(_T("%s:%d: "), __FILE__, __LINE__);
+ _tprintf(_T("WriteFile() failed. Error code %d.\n"), GetLastError());
+ return FALSE;
+ }
+
+ return TRUE;
+}
--- /dev/null
+/*
+ * FreeLoader - volume.h
+ *
+ * Copyright (C) 2001 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 __VOLUME_H
+#define __VOLUME_H
+
+BOOL OpenVolume(LPCTSTR lpszVolumeName);
+void CloseVolume(void);
+BOOL ReadVolumeSector(ULONG SectorNumber, PVOID SectorBuffer);
+BOOL WriteVolumeSector(ULONG SectorNumber, PVOID SectorBuffer);
+
+#endif // defined __VOLUME_H