3 * Copyright (C) 1998-2003 Brian Palmer <brianp@sginet.com>
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.
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.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 BOOLEAN DriveMapInstalled
= FALSE
; // Tells us if we have already installed our drive map int 13h handler code
25 ULONG OldInt13HandlerAddress
= 0; // Address of BIOS int 13h handler
26 ULONG DriveMapHandlerAddress
= 0; // Linear address of our drive map handler
27 ULONG DriveMapHandlerSegOff
= 0; // Segment:offset style address of our drive map handler
29 VOID
DriveMapMapDrivesInSection(PCSTR SectionName
)
32 CHAR SettingValue
[80];
37 ULONG SectionItemCount
;
40 DRIVE_MAP_LIST DriveMapList
;
42 RtlZeroMemory(&DriveMapList
, sizeof(DRIVE_MAP_LIST
));
44 if (!IniOpenSection(SectionName
, &SectionId
))
49 // Get the number of items in this section
50 SectionItemCount
= IniGetNumSectionItems(SectionId
);
52 // Loop through each one and check if its a DriveMap= setting
53 for (Index
=0; Index
<SectionItemCount
; Index
++)
55 // Get the next setting from the .ini file section
56 if (IniReadSettingByNumber(SectionId
, Index
, SettingName
, sizeof(SettingName
), SettingValue
, sizeof(SettingValue
)))
58 if (_stricmp(SettingName
, "DriveMap") == 0)
60 // Make sure we haven't exceeded the drive map max count
61 if (DriveMapList
.DriveMapCount
>= 4)
63 sprintf(ErrorText
, "Max DriveMap count exceeded in section [%s]:\n\n%s=%s", SectionName
, SettingName
, SettingValue
);
64 UiMessageBox(ErrorText
);
68 RtlZeroMemory(Drive1
, 80);
69 RtlZeroMemory(Drive2
, 80);
71 strcpy(Drive1
, SettingValue
);
73 // Parse the setting value and separate a string "hd0,hd1"
74 // into two strings "hd0" and "hd1"
75 for (Index2
=0; Index2
<strlen(Drive1
); Index2
++)
77 // Check if this character is the separater character (comma - ',')
78 if (Drive1
[Index2
] == ',')
80 Drive1
[Index2
] = '\0';
81 strcpy(Drive2
, &Drive1
[Index2
+1]);
86 // Make sure we got good values before we add them to the map
87 if (!DriveMapIsValidDriveString(Drive1
) || !DriveMapIsValidDriveString(Drive2
))
89 sprintf(ErrorText
, "Error in DriveMap setting in section [%s]:\n\n%s=%s", SectionName
, SettingName
, SettingValue
);
90 UiMessageBox(ErrorText
);
94 // Add them to the map
95 DriveMapList
.DriveMap
[(DriveMapList
.DriveMapCount
* 2)] = DriveMapGetBiosDriveNumber(Drive1
);
96 DriveMapList
.DriveMap
[(DriveMapList
.DriveMapCount
* 2)+1] = DriveMapGetBiosDriveNumber(Drive2
);
97 DriveMapList
.DriveMapCount
++;
99 DbgPrint((DPRINT_WARNING
, "Mapping BIOS drive 0x%x to drive 0x%x\n", DriveMapGetBiosDriveNumber(Drive1
), DriveMapGetBiosDriveNumber(Drive2
)));
104 if (DriveMapList
.DriveMapCount
)
106 DbgPrint((DPRINT_WARNING
, "Installing Int13 drive map for %d drives.\n", DriveMapList
.DriveMapCount
));
107 DriveMapInstallInt13Handler(&DriveMapList
);
111 DbgPrint((DPRINT_WARNING
, "Removing any previously installed Int13 drive map.\n"));
112 DriveMapRemoveInt13Handler();
116 BOOLEAN
DriveMapIsValidDriveString(PCSTR DriveString
)
120 // Now verify that the user has given us appropriate strings
121 if ((strlen(DriveString
) < 3) ||
122 ((DriveString
[0] != 'f') && (DriveString
[0] != 'F') && (DriveString
[0] != 'h') && (DriveString
[0] != 'H')) ||
123 ((DriveString
[1] != 'd') && (DriveString
[1] != 'D')))
128 // Now verify that the user has given us appropriate numbers
129 // Make sure that only numeric characters were given
130 for (Index
=2; Index
<strlen(DriveString
); Index
++)
132 if (DriveString
[Index
] < '0' || DriveString
[Index
] > '9')
137 // Now make sure that they are not outrageous values (i.e. hd90874)
138 if ((atoi(&DriveString
[2]) < 0) || (atoi(&DriveString
[2]) > 0xff))
146 ULONG
DriveMapGetBiosDriveNumber(PCSTR DeviceName
)
148 ULONG BiosDriveNumber
= 0;
150 // If they passed in a number string then just
151 // convert it to decimal and return it
152 if (DeviceName
[0] >= '0' && DeviceName
[0] <= '9')
154 return atoi(DeviceName
);
157 // Convert the drive number string into a number
159 BiosDriveNumber
= atoi(&DeviceName
[2]);
161 // If it's a hard disk then set the high bit
162 if ((DeviceName
[0] == 'h' || DeviceName
[0] == 'H') &&
163 (DeviceName
[1] == 'd' || DeviceName
[1] == 'D'))
165 BiosDriveNumber
|= 0x80;
168 return BiosDriveNumber
;
171 VOID
DriveMapInstallInt13Handler(PDRIVE_MAP_LIST DriveMap
)
173 ULONG
* RealModeIVT
= (ULONG
*)0x00000000;
174 USHORT
* BiosLowMemorySize
= (USHORT
*)0x00000413;
176 if (!DriveMapInstalled
)
178 // Get the old INT 13h handler address from the vector table
179 OldInt13HandlerAddress
= RealModeIVT
[0x13];
181 // Decrease the size of low memory
182 (*BiosLowMemorySize
)--;
184 // Get linear address for drive map handler
185 DriveMapHandlerAddress
= (ULONG
)(*BiosLowMemorySize
) << 10;
187 // Convert to segment:offset style address
188 DriveMapHandlerSegOff
= (DriveMapHandlerAddress
<< 12) & 0xffff0000;
191 // Copy the drive map structure to the proper place
192 RtlCopyMemory(&DriveMapInt13HandlerMapList
, DriveMap
, sizeof(DRIVE_MAP_LIST
));
194 // Set the address of the BIOS INT 13h handler
195 DriveMapOldInt13HandlerAddress
= OldInt13HandlerAddress
;
197 // Copy the code to our reserved area
198 RtlCopyMemory((PVOID
)DriveMapHandlerAddress
, &DriveMapInt13HandlerStart
, ((ULONG
)&DriveMapInt13HandlerEnd
- (ULONG
)&DriveMapInt13HandlerStart
));
201 RealModeIVT
[0x13] = DriveMapHandlerSegOff
;
203 CacheInvalidateCacheData();
204 DriveMapInstalled
= TRUE
;
207 VOID
DriveMapRemoveInt13Handler(VOID
)
209 ULONG
* RealModeIVT
= (ULONG
*)0x00000000;
210 USHORT
* BiosLowMemorySize
= (USHORT
*)0x00000413;
212 if (DriveMapInstalled
)
214 // Get the old INT 13h handler address from the vector table
215 RealModeIVT
[0x13] = OldInt13HandlerAddress
;
217 // Increase the size of low memory
218 (*BiosLowMemorySize
)++;
220 CacheInvalidateCacheData();
221 DriveMapInstalled
= FALSE
;
224 #endif /* __i386__ */