xref: /reactos/boot/freeldr/install/install.c (revision 8a978a17)
1 /*
2  *  FreeLoader - install.c
3  *
4  *  Copyright (C) 2001  Brian Palmer  <brianp@sginet.com>
5  *
6  *  This program is free software; you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation; either version 2 of the License, or
9  *  (at your option) any later version.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License along
17  *  with this program; if not, write to the Free Software Foundation, Inc.,
18  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19  */
20 
21 #include <windows.h>
22 #include <tchar.h>
23 #include <stdio.h>
24 #include "install.h"
25 #include "volume.h"
26 
27 /*
28  * These includes are required to define
29  * the fat_data and fat32_data arrays.
30  */
31 #include "fat.h"
32 #include "fat32.h"
33 
34 BOOL    BackupBootSector(LPCTSTR lpszVolumeName);
35 BOOL    InstallBootSector(LPCTSTR lpszVolumeType);
36 
37 int main(int argc, char *argv[])
38 {
39     if (argc < 3)
40     {
41         _tprintf(_T("syntax: install x: [fs_type]\nwhere fs_type is fat or fat32\n"));
42         return -1;
43     }
44 
45     if (!OpenVolume(argv[1]))
46     {
47         return -1;
48     }
49 
50     BackupBootSector(argv[1]);
51 
52     InstallBootSector(argv[2]);
53 
54     _tprintf(_T("You must now copy freeldr.sys & freeldr.ini to %s.\n"), argv[1]);
55 
56     CloseVolume();
57 
58     return 0;
59 }
60 
61 BOOL BackupBootSector(LPCTSTR lpszVolumeName)
62 {
63     HANDLE    hBackupFile;
64     TCHAR    szFileName[MAX_PATH];
65     ULONG    Count;
66     BYTE    BootSectorBuffer[512];
67     DWORD    dwNumberOfBytesWritten;
68     BOOL    bRetVal;
69 
70     //
71     // Find the next unused filename and open it
72     //
73     for (Count=0; ; Count++)
74     {
75         //
76         // Generate the next filename
77         //
78         _stprintf(szFileName, _T("%s\\bootsect.%03ld"), lpszVolumeName, Count);
79 
80         //
81         // Try to create a new file, fail if exists
82         //
83         hBackupFile = CreateFile(szFileName, GENERIC_WRITE, 0, NULL, CREATE_NEW, /*FILE_ATTRIBUTE_SYSTEM*/0, NULL);
84 
85         //
86         // Check to see if it worked
87         //
88         if (hBackupFile != INVALID_HANDLE_VALUE)
89         {
90             break;
91         }
92 
93         //
94         // Nope, didn't work
95         // Check to see if it already existed
96         //
97         if (!(GetLastError() != ERROR_ALREADY_EXISTS))
98         {
99             _tprintf(_T("%s:%d: "), __FILE__, __LINE__);
100             _tprintf(_T("Boot sector backup failed. Error code %ld.\n"), GetLastError());
101             return FALSE;
102         }
103     }
104 
105     //
106     // Try to read the boot sector
107     //
108     if (!ReadVolumeSector(0, BootSectorBuffer))
109     {
110         CloseHandle(hBackupFile);
111         return FALSE;
112     }
113 
114     //
115     // Try to write the boot sector data to the file
116     //
117     bRetVal = WriteFile(hBackupFile, BootSectorBuffer, 512, &dwNumberOfBytesWritten, NULL);
118     if (!bRetVal || (dwNumberOfBytesWritten != 512))
119     {
120         CloseHandle(hBackupFile);
121         _tprintf(_T("%s:%d: "), __FILE__, __LINE__);
122         _tprintf(_T("WriteFile() failed. Error code %ld.\n"), GetLastError());
123         return FALSE;
124     }
125 
126     _tprintf(_T("Boot sector backed up to file: %s\n"), szFileName);
127 
128     CloseHandle(hBackupFile);
129 
130     return TRUE;
131 }
132 
133 BOOL InstallBootSector(LPCTSTR lpszVolumeType)
134 {
135     BYTE    BootSectorBuffer[512];
136 
137     //
138     // Read in the old boot sector
139     //
140     if (!ReadVolumeSector(0, BootSectorBuffer))
141     {
142         return FALSE;
143     }
144 
145     if (_tcsicmp(lpszVolumeType, _T("fat")) == 0)
146     {
147         //
148         // Update the BPB in the new boot sector
149         //
150         memcpy((fat_data+3), (BootSectorBuffer+3), 59 /*fat BPB length*/);
151 
152         //
153         // Write out new boot sector
154         //
155         if (!WriteVolumeSector(0, fat_data))
156         {
157             return FALSE;
158         }
159     }
160     else if (_tcsicmp(lpszVolumeType, _T("fat32")) == 0)
161     {
162         //
163         // Update the BPB in the new boot sector
164         //
165         memcpy((fat32_data+3), (BootSectorBuffer+3), 87 /*fat32 BPB length*/);
166 
167         //
168         // Write out new boot sector
169         //
170         if (!WriteVolumeSector(0, fat32_data))
171         {
172             return FALSE;
173         }
174 
175         //
176         // Write out new extra sector
177         //
178         if (!WriteVolumeSector(14, (fat32_data+512)))
179         {
180             return FALSE;
181         }
182     }
183     else
184     {
185         _tprintf(_T("%s:%d: "), __FILE__, __LINE__);
186         _tprintf(_T("File system type %s unknown.\n"), lpszVolumeType);
187         return FALSE;
188     }
189 
190     _tprintf(_T("%s boot sector installed.\n"), lpszVolumeType);
191 
192     return TRUE;
193 }
194