ReactOS 0.4.15-dev-7842-g558ab78
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
27BOOLEAN DriveMapInstalled = FALSE; // Tells us if we have already installed our drive map int 13h handler code
28ULONG OldInt13HandlerAddress = 0; // Address of BIOS int 13h handler
29ULONG DriveMapHandlerAddress = 0; // Linear address of our drive map handler
30ULONG DriveMapHandlerSegOff = 0; // Segment:offset style address of our drive map handler
31
32#endif // _M_IX86
33
35{
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
95VOID
96DriveMapMapDrivesInSection(
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
178VOID DriveMapInstallInt13Handler(PDRIVE_MAP_LIST DriveMap)
179{
180 ULONG* RealModeIVT = (ULONG*)UlongToPtr(0x00000000);
181 USHORT* BiosLowMemorySize = (USHORT*)ULongToPtr(0x00000413);
182
183#if defined(SARCH_PC98)
184 /* FIXME */
185 return;
186#endif
187
188 if (!DriveMapInstalled)
189 {
190 // Get the old INT 13h handler address from the vector table
191 OldInt13HandlerAddress = RealModeIVT[0x13];
192
193 // Decrease the size of low memory
194 (*BiosLowMemorySize)--;
195
196 // Get linear address for drive map handler
197 DriveMapHandlerAddress = (ULONG)(*BiosLowMemorySize) << 10;
198
199 // Convert to segment:offset style address
200 DriveMapHandlerSegOff = (DriveMapHandlerAddress << 12) & 0xffff0000;
201 }
202
203 // Copy the drive map structure to the proper place
204 RtlCopyMemory(&DriveMapInt13HandlerMapList, DriveMap, sizeof(DRIVE_MAP_LIST));
205
206 // Set the address of the BIOS INT 13h handler
207 DriveMapOldInt13HandlerAddress = OldInt13HandlerAddress;
208
209 // Copy the code to our reserved area
210 RtlCopyMemory(UlongToPtr(DriveMapHandlerAddress),
211 &DriveMapInt13HandlerStart,
212 ((PUCHAR)&DriveMapInt13HandlerEnd - (PUCHAR)&DriveMapInt13HandlerStart));
213
214 // Update the IVT
215 RealModeIVT[0x13] = DriveMapHandlerSegOff;
216
218 DriveMapInstalled = TRUE;
219}
220
221VOID DriveMapRemoveInt13Handler(VOID)
222{
223 ULONG* RealModeIVT = (ULONG*)0x00000000;
224 USHORT* BiosLowMemorySize = (USHORT*)0x00000413;
225
226#if defined(SARCH_PC98)
227 /* FIXME */
228 return;
229#endif
230
231 if (DriveMapInstalled)
232 {
233 // Get the old INT 13h handler address from the vector table
234 RealModeIVT[0x13] = OldInt13HandlerAddress;
235
236 // Increase the size of low memory
237 (*BiosLowMemorySize)++;
238
240 DriveMapInstalled = FALSE;
241 }
242}
243
244#endif // _M_IX86
unsigned char BOOLEAN
UINT32 strtoul(const char *String, char **Terminator, UINT32 Base)
Definition: utclib.c:696
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
#define ULongToPtr(ul)
Definition: basetsd.h:92
#define DriveMapGetBiosDriveNumber(DeviceName)
Definition: hardware.h:35
VOID CacheInvalidateCacheData(VOID)
Definition: cache.c:108
#define DBG_DEFAULT_CHANNEL(ch)
Definition: debug.h:103
VOID UiMessageBox(_In_ PCSTR Format,...)
Definition: ui.c:359
#define _stricmp
Definition: cat.c:22
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
BOOLEAN DriveMapIsValidDriveString(PCSTR DriveString)
Definition: drivemap.c:34
#define UlongToPtr(u)
Definition: config.h:106
_Check_return_ int __cdecl atoi(_In_z_ const char *_Str)
ULONG IniGetNumSectionItems(ULONG_PTR SectionId)
Definition: inifile.c:55
BOOLEAN IniReadSettingByNumber(ULONG_PTR SectionId, ULONG SettingNumber, PCHAR SettingName, ULONG NameSize, PCHAR SettingValue, ULONG ValueSize)
Definition: inifile.c:116
unsigned short USHORT
Definition: pedump.c:61
#define TRACE(s)
Definition: solgame.cpp:4
const char * PCSTR
Definition: typedefs.h:52
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
_In_ WDFCOLLECTION _In_ ULONG Index
_Must_inspect_result_ _In_ PWDFDEVICE_INIT _In_opt_ PCUNICODE_STRING DeviceName
Definition: wdfdevice.h:3275
unsigned char UCHAR
Definition: xmlstorage.h:181
char CHAR
Definition: xmlstorage.h:175