Simple Win32 boot sector installer. Will not work under Win9x.
authorBrian Palmer <brianp@sginet.com>
Tue, 7 Aug 2001 05:37:13 +0000 (05:37 +0000)
committerBrian Palmer <brianp@sginet.com>
Tue, 7 Aug 2001 05:37:13 +0000 (05:37 +0000)
svn path=/trunk/; revision=2158

freeldr/install/Makefile [new file with mode: 0644]
freeldr/install/install.c [new file with mode: 0644]
freeldr/install/install.h [new file with mode: 0644]
freeldr/install/volume.c [new file with mode: 0644]
freeldr/install/volume.h [new file with mode: 0644]

diff --git a/freeldr/install/Makefile b/freeldr/install/Makefile
new file mode 100644 (file)
index 0000000..9d867c5
--- /dev/null
@@ -0,0 +1,49 @@
+#
+#  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
diff --git a/freeldr/install/install.c b/freeldr/install/install.c
new file mode 100644 (file)
index 0000000..536dd49
--- /dev/null
@@ -0,0 +1,189 @@
+/*
+ *  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;
+}
diff --git a/freeldr/install/install.h b/freeldr/install/install.h
new file mode 100644 (file)
index 0000000..4a3a746
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ *  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
diff --git a/freeldr/install/volume.c b/freeldr/install/volume.c
new file mode 100644 (file)
index 0000000..43a9dd3
--- /dev/null
@@ -0,0 +1,135 @@
+/*
+ *  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;
+}
diff --git a/freeldr/install/volume.h b/freeldr/install/volume.h
new file mode 100644 (file)
index 0000000..4155429
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ *  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