e28313f71e7098aeed89ccee2c4d38c0b43aade3
[reactos.git] / freeldr / freeldr / disk / geometry.c
1 /*
2 * FreeLoader
3 * Copyright (C) 1998-2002 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
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19
20 #include <freeldr.h>
21 #include <disk.h>
22 #include <rtl.h>
23 #include <mm.h>
24
25
26 typedef struct
27 {
28 LIST_ITEM ListEntry;
29
30 ULONG DriveNumber;
31 GEOMETRY DriveGeometry;
32
33 } DRIVE_GEOMETRY, *PDRIVE_GEOMETRY;
34
35
36 PDRIVE_GEOMETRY DriveGeometryListHead = NULL;
37
38
39 BOOL DiskGetDriveGeometry(ULONG DriveNumber, PGEOMETRY DriveGeometry)
40 {
41 PDRIVE_GEOMETRY DriveGeometryListEntry;
42
43 //
44 // Search the drive geometry list for the requested drive
45 //
46 DriveGeometryListEntry = DriveGeometryListHead;
47 while (DriveGeometryListEntry != NULL)
48 {
49 //
50 // Check to see if this is the drive we want
51 //
52 if (DriveGeometryListEntry->DriveNumber == DriveNumber)
53 {
54 //
55 // Yep - return the information
56 //
57 RtlCopyMemory(DriveGeometry, &DriveGeometryListEntry->DriveGeometry, sizeof(GEOMETRY));
58 return TRUE;
59 }
60
61 //
62 // Nope, get next item
63 //
64 DriveGeometryListEntry = (PDRIVE_GEOMETRY)RtlListGetNext((PLIST_ITEM)DriveGeometryListEntry);
65 }
66
67 DiskError("Drive geometry unknown.");
68 return FALSE;
69 }
70
71 BOOL DiskSetDriveGeometry(ULONG DriveNumber, ULONG Cylinders, ULONG Heads, ULONG Sectors, ULONG BytesPerSector)
72 {
73 PDRIVE_GEOMETRY DriveGeometryListEntry;
74
75 //
76 // Search the drive geometry list for the requested drive
77 //
78 DriveGeometryListEntry = DriveGeometryListHead;
79 while (DriveGeometryListEntry != NULL)
80 {
81 //
82 // Check to see if this is the drive
83 //
84 if (DriveGeometryListEntry->DriveNumber == DriveNumber)
85 {
86 //
87 // Yes, we already have this drive's geometry information
88 // so just return
89 //
90 return TRUE;
91 }
92
93 //
94 // Nope, get next item
95 //
96 DriveGeometryListEntry = (PDRIVE_GEOMETRY)RtlListGetNext((PLIST_ITEM)DriveGeometryListEntry);
97 }
98
99 //
100 // If we get here then this is a new drive and we have
101 // to add it's information to our list
102 //
103 DriveGeometryListEntry = (PDRIVE_GEOMETRY)AllocateMemory(sizeof(DRIVE_GEOMETRY));
104 if (DriveGeometryListEntry == NULL)
105 {
106 return FALSE;
107 }
108
109 RtlZeroMemory(DriveGeometryListEntry, sizeof(DRIVE_GEOMETRY));
110 DriveGeometryListEntry->DriveNumber = DriveNumber;
111 DriveGeometryListEntry->DriveGeometry.Cylinders = Cylinders;
112 DriveGeometryListEntry->DriveGeometry.Heads = Heads;
113 DriveGeometryListEntry->DriveGeometry.Sectors = Sectors;
114 DriveGeometryListEntry->DriveGeometry.BytesPerSector = BytesPerSector;
115
116 if (DriveGeometryListHead == NULL)
117 {
118 DriveGeometryListHead = DriveGeometryListEntry;
119 }
120 else
121 {
122 RtlListInsertTail((PLIST_ITEM)DriveGeometryListHead, (PLIST_ITEM)DriveGeometryListEntry);
123 }
124
125 return TRUE;
126 }