ReactOS 0.4.16-dev-2617-g01a0906
disk.c
Go to the documentation of this file.
1/*
2 * PROJECT: FreeLoader
3 * LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4 * or MIT (https://spdx.org/licenses/MIT)
5 * PURPOSE: Disk devices helpers
6 * COPYRIGHT: Copyright 2025-2026 Hermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
7 */
8
9/* INCLUDES ******************************************************************/
10
11#include <freeldr.h>
12
13#include <debug.h>
15
16#include "part_mbr.h" // FIXME: For MASTER_BOOT_RECORD
17#include "part_gpt.h"
18
19// Defined in part_gpt.c
20extern BOOLEAN
22 _In_ UCHAR DriveNumber,
23 _Out_ PGPT_TABLE_HEADER GptHeader);
24
25#define GUID_FORMAT_STR "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x"
26#define GUID_ELEMENTS(Guid) \
27 (Guid)->Data1, (Guid)->Data2, (Guid)->Data3, \
28 (Guid)->Data4[0], (Guid)->Data4[1], (Guid)->Data4[2], (Guid)->Data4[3], \
29 (Guid)->Data4[4], (Guid)->Data4[5], (Guid)->Data4[6], (Guid)->Data4[7]
30
31#define FIRST_PARTITION 1
32
33/* DISK IO ERROR SUPPORT *****************************************************/
34
35static LONG lReportError = 0; // >= 0: display errors; < 0: hide errors.
36
37LONG
39 _In_ BOOLEAN bShowError)
40{
41 /* Set the reference count */
42 if (bShowError) ++lReportError;
43 else --lReportError;
44 return lReportError;
45}
46
47VOID
49 _In_ PCSTR ErrorString,
51{
52 PCSTR ErrorDescription;
53 CHAR ErrorCodeString[200];
54
55 if (lReportError < 0)
56 return;
57
58 ErrorDescription = DiskGetErrorCodeString(ErrorCode);
59 if (ErrorDescription)
60 {
61 RtlStringCbPrintfA(ErrorCodeString, sizeof(ErrorCodeString),
62 "%s\n\nError Code: 0x%lx\nError: %s",
63 ErrorString, ErrorCode, ErrorDescription);
64 }
65 else
66 {
67 RtlStringCbCopyA(ErrorCodeString, sizeof(ErrorCodeString), ErrorString);
68 }
69
70 ERR("%s\n", ErrorCodeString);
71 UiMessageBox(ErrorCodeString);
72}
73
74
75/* FUNCTIONS *****************************************************************/
76
79 _In_ UCHAR DriveNumber, // FIXME: Arch-specific
82 _In_ const DEVVTBL* FuncTable,
83 _Out_opt_ PULONG pChecksum,
84 _Out_opt_ PULONG pSignature,
85 _Out_opt_ PBOOLEAN pValidPartitionTable)
86{
89 GEOMETRY Geometry;
91 ULONG MbrSectorSize;
92 ULONG i;
93 ULONG Checksum, Signature;
94 BOOLEAN ValidPartitionTable;
95 BOOLEAN IsCdRom;
96 PGUID GptDiskGuid = NULL;
97 GPT_TABLE_HEADER GptHeader;
98 PARTITION_INFORMATION PartitionEntry;
99 CHAR ArcName[MAX_PATH];
100 NTSTATUS NtStatus;
101
102 TRACE("DiskInitialize(0x%02X, '%s', Type: %lu)\n", DriveNumber, DeviceName, DeviceType);
103
104 if (!MachDiskGetDriveGeometry(DriveNumber, &Geometry))
105 return FALSE;
106
107 IsCdRom = (DeviceType == CdromController);
108 if (IsCdRom)
109 {
110 SectorStart = 16ULL;
111 MbrSectorSize = 2048;
112 }
113 else // (DeviceType == FloppyDiskPeripheral || DiskPeripheral)
114 {
115 SectorStart = 0ULL;
116 MbrSectorSize = 512;
117 }
118
119 /* Read the MBR */
121 {
122 ERR("Reading MBR failed\n");
123 return EIO;
124 }
125
128
129 Signature = Mbr->Signature;
130 TRACE("Signature: %x\n", Signature);
131
132 /* Calculate the MBR checksum */
133 Checksum = 0;
134 for (i = 0; i < MbrSectorSize / sizeof(ULONG); i++)
135 {
136 Checksum += Buffer[i];
137 }
138 Checksum = ~Checksum + 1;
139 TRACE("Checksum: %x\n", Checksum);
140
141 ValidPartitionTable = (IsCdRom || (Mbr->MasterBootRecordMagic == 0xAA55));
142 TRACE("IsPartitionValid: %s\n", ValidPartitionTable ? "TRUE" : "FALSE");
143
144 /* Register the device */
145 // NOTE: For now, only register the direct device if it's not a
146 // "rigid" disk, i.e. peripherals not of the form 'xxx(y)rdisk(z)'.
147 // Rigid disks are registered with the 'partition(0)' suffix below.
149 {
150 if (!FsRegisterDevice(DeviceName, FuncTable))
151 return ENOMEM;
152 }
153
154 /* GPT disk signature support */
156 {
157 if (DiskReadGptHeader(DriveNumber, &GptHeader))
158 GptDiskGuid = &GptHeader.DiskGuid;
159 }
160 if (GptDiskGuid)
161 {
162 TRACE("Disk 0x%02X is GPT, DiskGuid: {" GUID_FORMAT_STR "}\n",
163 DriveNumber, GUID_ELEMENTS(GptDiskGuid));
164 }
165
166 /* Fill out the ARC disk block */
168 Checksum, ValidPartitionTable);
169
170 if (pChecksum)
171 *pChecksum = Checksum;
172 if (pSignature)
173 *pSignature = Signature;
174 if (pValidPartitionTable)
175 *pValidPartitionTable = ValidPartitionTable;
176
177 /* Don't search for partitions in non-"rigid" disks (floppies, CD-ROMs) */
179 return ESUCCESS;
180
181 /* Register the device with the 'partition(0)' suffix */
182 NtStatus = RtlStringCbPrintfA(ArcName, sizeof(ArcName), "%spartition(0)", DeviceName);
183 if (!NT_SUCCESS(NtStatus))
184 return ENAMETOOLONG;
185 if (!FsRegisterDevice(ArcName, FuncTable))
186 return ENOMEM;
187
188 /* Detect disk partition type */
189 DiskDetectPartitionType(DriveNumber);
190
191 /* Add partitions */
193 while (DiskGetPartitionEntry(DriveNumber, Geometry.BytesPerSector, i, &PartitionEntry))
194 {
195 if (PartitionEntry.PartitionType != PARTITION_ENTRY_UNUSED)
196 {
197 NtStatus = RtlStringCbPrintfA(ArcName, sizeof(ArcName),
198 "%spartition(%lu)", DeviceName, i);
199 if (!NT_SUCCESS(NtStatus))
200 return ENAMETOOLONG;
201 if (!FsRegisterDevice(ArcName, FuncTable))
202 return ENOMEM;
203 }
204 i++;
205 }
206
207 return ESUCCESS;
208}
unsigned char BOOLEAN
Definition: actypes.h:127
VOID AddReactOSArcDiskInfo(_In_ PCSTR ArcName, _In_opt_ PGUID GptDiskGuid, _In_ ULONG Signature, _In_ ULONG Checksum, _In_ BOOLEAN ValidPartitionTable)
Definition: archwsup.c:77
LONG NTSTATUS
Definition: precomp.h:26
#define ERR(fmt,...)
Definition: precomp.h:57
#define GUID_FORMAT_STR
Definition: disk.c:25
static LONG lReportError
Definition: disk.c:35
ARC_STATUS DiskInitialize(_In_ UCHAR DriveNumber, _In_ PCSTR DeviceName, _In_ CONFIGURATION_TYPE DeviceType, _In_ const DEVVTBL *FuncTable, _Out_opt_ PULONG pChecksum, _Out_opt_ PULONG pSignature, _Out_opt_ PBOOLEAN pValidPartitionTable)
Definition: disk.c:78
BOOLEAN DiskReadGptHeader(_In_ UCHAR DriveNumber, _Out_ PGPT_TABLE_HEADER GptHeader)
Definition: part_gpt.c:22
#define GUID_ELEMENTS(Guid)
Definition: disk.c:26
LONG DiskReportError(_In_ BOOLEAN bShowError)
Definition: disk.c:38
VOID DiskError(_In_ PCSTR ErrorString, _In_ ULONG ErrorCode)
Definition: disk.c:48
#define FIRST_PARTITION
Definition: disk.c:31
VOID DiskDetectPartitionType(_In_ UCHAR DriveNumber)
Definition: partition.c:66
BOOLEAN DiskGetPartitionEntry(_In_ UCHAR DriveNumber, _In_opt_ ULONG SectorSize, _In_ ULONG PartitionNumber, _Out_ PPARTITION_INFORMATION PartitionEntry)
Definition: partition.c:178
#define DiskReadBuffer
Definition: hardware.h:33
#define DBG_DEFAULT_CHANNEL(ch)
Definition: debug.h:106
BOOLEAN FsRegisterDevice(_In_ PCSTR DeviceName, _In_ const DEVVTBL *FuncTable)
Definition: fs.c:673
#define MachDiskGetDriveGeometry(Drive, Geom)
Definition: machine.h:122
#define MachDiskReadLogicalSectors(Drive, Start, Count, Buf)
Definition: machine.h:120
VOID UiMessageBox(_In_ PCSTR Format,...)
Definition: ui.c:359
Definition: bufpool.h:45
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define MAX_PATH
Definition: compat.h:34
#define ENAMETOOLONG
Definition: errno.h:58
#define ENOMEM
Definition: errno.h:35
#define EIO
Definition: errno.h:28
static const WCHAR Signature[]
Definition: parser.c:141
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
DeviceType
Definition: mmdrv.h:42
#define ULL(a, b)
Definition: format_msg.c:27
_In_ NDIS_ERROR_CODE ErrorCode
Definition: ndis.h:4436
#define _Out_opt_
Definition: no_sal2.h:214
#define _Out_
Definition: no_sal2.h:160
#define _In_
Definition: no_sal2.h:158
NTSTRSAFEVAPI RtlStringCbPrintfA(_Out_writes_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest, _In_ size_t cbDest, _In_ _Printf_format_string_ NTSTRSAFE_PCSTR pszFormat,...)
Definition: ntstrsafe.h:1148
NTSTRSAFEAPI RtlStringCbCopyA(_Out_writes_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PSTR pszDest, _In_ size_t cbDest, _In_ NTSTRSAFE_PCSTR pszSrc)
Definition: ntstrsafe.h:156
ULONG SectorStart
Definition: part_brfr.c:21
#define PARTITION_ENTRY_UNUSED
Definition: part_mbr.h:50
struct _MASTER_BOOT_RECORD * PMASTER_BOOT_RECORD
PCSTR DiskGetErrorCodeString(_In_ ULONG ErrorCode)
Definition: pcdisk.c:136
long LONG
Definition: pedump.c:60
char CHAR
Definition: pedump.c:57
@ ESUCCESS
Definition: arc.h:32
ULONG ARC_STATUS
Definition: arc.h:4
@ DiskPeripheral
Definition: arc.h:138
@ CdromController
Definition: arc.h:128
enum _CONFIGURATION_TYPE CONFIGURATION_TYPE
#define TRACE(s)
Definition: solgame.cpp:4
Definition: disk.h:24
ULONG BytesPerSector
Number of bytes per sector.
Definition: disk.h:28
USHORT MasterBootRecordMagic
Definition: part_mbr.h:40
Definition: fs.h:25
uint32_t * PULONG
Definition: typedefs.h:59
unsigned char UCHAR
Definition: typedefs.h:53
unsigned char * PBOOLEAN
Definition: typedefs.h:53
const char * PCSTR
Definition: typedefs.h:52
uint32_t ULONG
Definition: typedefs.h:59
uint64_t ULONGLONG
Definition: typedefs.h:67
_Must_inspect_result_ _In_ PWDFDEVICE_INIT _In_opt_ PCUNICODE_STRING DeviceName
Definition: wdfdevice.h:3281