ReactOS  0.4.14-dev-323-g6fe6a88
drivemap.c
Go to the documentation of this file.
1 /*
2  * FreeLoader
3  * Copyright (C) 1998-2003 Brian Palmer <brianp@sginet.com>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License along
16  * with this program; if not, write to the Free Software Foundation, Inc.,
17  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18  */
19 
20 #include <freeldr.h>
21 
22 #include <debug.h>
24 
25 #ifdef _M_IX86
26 
27 BOOLEAN DriveMapInstalled = FALSE; // Tells us if we have already installed our drive map int 13h handler code
28 ULONG OldInt13HandlerAddress = 0; // Address of BIOS int 13h handler
29 ULONG DriveMapHandlerAddress = 0; // Linear address of our drive map handler
30 ULONG DriveMapHandlerSegOff = 0; // Segment:offset style address of our drive map handler
31 
32 #endif // _M_IX86
33 
35 {
36  ULONG Index;
37 
38  // Now verify that the user has given us appropriate strings
39  if ((strlen(DriveString) < 3) ||
40  ((DriveString[0] != 'f') && (DriveString[0] != 'F') &&
41  (DriveString[0] != 'h') && (DriveString[0] != 'H')) ||
42  ((DriveString[1] != 'd') && (DriveString[1] != 'D')))
43  {
44  return FALSE;
45  }
46 
47  // Now verify that the user has given us appropriate numbers
48  // Make sure that only numeric characters were given
49  for (Index = 2; Index < strlen(DriveString); Index++)
50  {
51  if (DriveString[Index] < '0' || DriveString[Index] > '9')
52  {
53  return FALSE;
54  }
55  }
56 
57  // Now make sure that they are not outrageous values (i.e. hd90874)
58  if ((atoi(&DriveString[2]) < 0) || (atoi(&DriveString[2]) > 0xff))
59  {
60  return FALSE;
61  }
62 
63  return TRUE;
64 }
65 
67 {
68  UCHAR BiosDriveNumber = 0;
69 
70  TRACE("DriveMapGetBiosDriveNumber(%s)\n", DeviceName);
71 
72  // If they passed in a number string then just
73  // convert it to decimal and return it
74  if (DeviceName[0] >= '0' && DeviceName[0] <= '9')
75  {
76  return (UCHAR)strtoul(DeviceName, NULL, 0);
77  }
78 
79  // Convert the drive number string into a number
80  // 'hd1' = 1
81  BiosDriveNumber = atoi(&DeviceName[2]);
82 
83  // If it's a hard disk then set the high bit
84  if ((DeviceName[0] == 'h' || DeviceName[0] == 'H') &&
85  (DeviceName[1] == 'd' || DeviceName[1] == 'D'))
86  {
87  BiosDriveNumber |= 0x80;
88  }
89 
90  return BiosDriveNumber;
91 }
92 
93 #ifdef _M_IX86
94 
95 VOID
96 DriveMapMapDrivesInSection(
97  IN ULONG_PTR SectionId)
98 {
99  CHAR SettingName[80];
100  CHAR SettingValue[80];
101  CHAR Drive1[80];
102  CHAR Drive2[80];
103  ULONG SectionItemCount;
104  ULONG Index;
105  ULONG Index2;
106  DRIVE_MAP_LIST DriveMapList;
107 
108  if (SectionId == 0)
109  return;
110 
111  RtlZeroMemory(&DriveMapList, sizeof(DRIVE_MAP_LIST));
112 
113  // Get the number of items in this section
114  SectionItemCount = IniGetNumSectionItems(SectionId);
115 
116  // Loop through each one and check if its a DriveMap= setting
117  for (Index=0; Index<SectionItemCount; Index++)
118  {
119  // Get the next setting from the .ini file section
120  if (IniReadSettingByNumber(SectionId, Index, SettingName, sizeof(SettingName), SettingValue, sizeof(SettingValue)))
121  {
122  if (_stricmp(SettingName, "DriveMap") == 0)
123  {
124  // Make sure we haven't exceeded the drive map max count
125  if (DriveMapList.DriveMapCount >= 4)
126  {
127  UiMessageBox("Max DriveMap count exceeded in section [%s]:\n\n%s=%s", ((PINI_SECTION)SectionId)->SectionName, SettingName, SettingValue);
128  continue;
129  }
130 
131  RtlZeroMemory(Drive1, 80);
132  RtlZeroMemory(Drive2, 80);
133 
134  strcpy(Drive1, SettingValue);
135 
136  // Parse the setting value and separate a string "hd0,hd1"
137  // into two strings "hd0" and "hd1"
138  for (Index2=0; Index2<strlen(Drive1); Index2++)
139  {
140  // Check if this character is the separater character (comma - ',')
141  if (Drive1[Index2] == ',')
142  {
143  Drive1[Index2] = '\0';
144  strcpy(Drive2, &Drive1[Index2+1]);
145  break;
146  }
147  }
148 
149  // Make sure we got good values before we add them to the map
151  {
152  UiMessageBox("Error in DriveMap setting in section [%s]:\n\n%s=%s", ((PINI_SECTION)SectionId)->SectionName, SettingName, SettingValue);
153  continue;
154  }
155 
156  // Add them to the map
157  DriveMapList.DriveMap[(DriveMapList.DriveMapCount * 2)] = DriveMapGetBiosDriveNumber(Drive1);
158  DriveMapList.DriveMap[(DriveMapList.DriveMapCount * 2)+1] = DriveMapGetBiosDriveNumber(Drive2);
159  DriveMapList.DriveMapCount++;
160 
161  TRACE("Mapping BIOS drive 0x%x to drive 0x%x\n", DriveMapGetBiosDriveNumber(Drive1), DriveMapGetBiosDriveNumber(Drive2));
162  }
163  }
164  }
165 
166  if (DriveMapList.DriveMapCount)
167  {
168  TRACE("Installing Int13 drive map for %d drives.\n", DriveMapList.DriveMapCount);
169  DriveMapInstallInt13Handler(&DriveMapList);
170  }
171  else
172  {
173  TRACE("Removing any previously installed Int13 drive map.\n");
174  DriveMapRemoveInt13Handler();
175  }
176 }
177 
178 VOID DriveMapInstallInt13Handler(PDRIVE_MAP_LIST DriveMap)
179 {
180  ULONG* RealModeIVT = (ULONG*)UlongToPtr(0x00000000);
181  USHORT* BiosLowMemorySize = (USHORT*)ULongToPtr(0x00000413);
182 
183  if (!DriveMapInstalled)
184  {
185  // Get the old INT 13h handler address from the vector table
186  OldInt13HandlerAddress = RealModeIVT[0x13];
187 
188  // Decrease the size of low memory
189  (*BiosLowMemorySize)--;
190 
191  // Get linear address for drive map handler
192  DriveMapHandlerAddress = (ULONG)(*BiosLowMemorySize) << 10;
193 
194  // Convert to segment:offset style address
195  DriveMapHandlerSegOff = (DriveMapHandlerAddress << 12) & 0xffff0000;
196  }
197 
198  // Copy the drive map structure to the proper place
199  RtlCopyMemory(&DriveMapInt13HandlerMapList, DriveMap, sizeof(DRIVE_MAP_LIST));
200 
201  // Set the address of the BIOS INT 13h handler
202  DriveMapOldInt13HandlerAddress = OldInt13HandlerAddress;
203 
204  // Copy the code to our reserved area
205  RtlCopyMemory(UlongToPtr(DriveMapHandlerAddress),
206  &DriveMapInt13HandlerStart,
207  ((PUCHAR)&DriveMapInt13HandlerEnd - (PUCHAR)&DriveMapInt13HandlerStart));
208 
209  // Update the IVT
210  RealModeIVT[0x13] = DriveMapHandlerSegOff;
211 
213  DriveMapInstalled = TRUE;
214 }
215 
216 VOID DriveMapRemoveInt13Handler(VOID)
217 {
218  ULONG* RealModeIVT = (ULONG*)0x00000000;
219  USHORT* BiosLowMemorySize = (USHORT*)0x00000413;
220 
221  if (DriveMapInstalled)
222  {
223  // Get the old INT 13h handler address from the vector table
224  RealModeIVT[0x13] = OldInt13HandlerAddress;
225 
226  // Increase the size of low memory
227  (*BiosLowMemorySize)++;
228 
230  DriveMapInstalled = FALSE;
231  }
232 }
233 
234 #endif // _M_IX86
#define IN
Definition: typedefs.h:38
UINT32 strtoul(const char *String, char **Terminator, UINT32 Base)
Definition: utclib.c:696
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define ULongToPtr(ul)
Definition: basetsd.h:92
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
VOID CacheInvalidateCacheData(VOID)
Definition: cache.c:108
unsigned char * PUCHAR
Definition: retypes.h:3
char CHAR
Definition: xmlstorage.h:175
WCHAR DeviceName[]
Definition: adapter.cpp:21
#define _stricmp
Definition: cat.c:22
uint32_t ULONG_PTR
Definition: typedefs.h:63
DBG_DEFAULT_CHANNEL(DISK)
VOID UiMessageBox(PCSTR Format,...)
Definition: ui.c:320
unsigned char BOOLEAN
UCHAR DriveMapGetBiosDriveNumber(PCSTR DeviceName)
Definition: drivemap.c:66
smooth NULL
Definition: ftsmooth.c:416
#define UlongToPtr(u)
Definition: config.h:106
#define TRACE(s)
Definition: solgame.cpp:4
static const UCHAR Index[8]
Definition: usbohci.c:18
unsigned char UCHAR
Definition: xmlstorage.h:181
unsigned short USHORT
Definition: pedump.c:61
BOOLEAN DriveMapIsValidDriveString(PCSTR DriveString)
Definition: drivemap.c:34
_Check_return_ int __cdecl atoi(_In_z_ const char *_Str)
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
unsigned int ULONG
Definition: retypes.h:1
ULONG IniGetNumSectionItems(ULONG_PTR SectionId)
Definition: inifile.c:54
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
const char * PCSTR
Definition: typedefs.h:51
BOOLEAN IniReadSettingByNumber(ULONG_PTR SectionId, ULONG SettingNumber, PCHAR SettingName, ULONG NameSize, PCHAR SettingValue, ULONG ValueSize)
Definition: inifile.c:114