ReactOS 0.4.15-dev-7931-gfd331f1
fsrec.c File Reference
#include "precomp.h"
#include "fsrec.h"
#include <debug.h>
Include dependency graph for fsrec.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

static NTSTATUS GetFileSystemNameWorker (IN HANDLE PartitionHandle, OUT PIO_STATUS_BLOCK IoStatusBlock, IN OUT PWSTR FileSystemName, IN SIZE_T FileSystemNameSize)
 
NTSTATUS GetFileSystemName_UStr (IN PUNICODE_STRING PartitionPath OPTIONAL, IN HANDLE PartitionHandle OPTIONAL, IN OUT PWSTR FileSystemName, IN SIZE_T FileSystemNameSize)
 
NTSTATUS GetFileSystemName (IN PCWSTR PartitionPath OPTIONAL, IN HANDLE PartitionHandle OPTIONAL, IN OUT PWSTR FileSystemName, IN SIZE_T FileSystemNameSize)
 
static NTSTATUS InferFileSystemWorker (IN HANDLE PartitionHandle, OUT PIO_STATUS_BLOCK IoStatusBlock, IN OUT PWSTR FileSystemName, IN SIZE_T FileSystemNameSize)
 
NTSTATUS InferFileSystem (IN PCWSTR PartitionPath OPTIONAL, IN HANDLE PartitionHandle OPTIONAL, IN OUT PWSTR FileSystemName, IN SIZE_T FileSystemNameSize)
 
UCHAR FileSystemToMBRPartitionType (IN PCWSTR FileSystem, IN ULONGLONG StartSector, IN ULONGLONG SectorCount)
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 15 of file fsrec.c.

Function Documentation

◆ FileSystemToMBRPartitionType()

UCHAR FileSystemToMBRPartitionType ( IN PCWSTR  FileSystem,
IN ULONGLONG  StartSector,
IN ULONGLONG  SectorCount 
)

Definition at line 333 of file fsrec.c.

337{
339
340 if (SectorCount == 0)
342
343 if (wcsicmp(FileSystem, L"FAT") == 0 ||
344 wcsicmp(FileSystem, L"FAT32") == 0 ||
345 wcsicmp(FileSystem, L"RAW") == 0)
346 {
347 if (SectorCount < 8192ULL)
348 {
349 /* FAT12 CHS partition (disk is smaller than 4.1MB) */
350 return PARTITION_FAT_12;
351 }
352 else if (StartSector < 1450560ULL)
353 {
354 /* Partition starts below the 8.4GB boundary ==> CHS partition */
355
356 if (SectorCount < 65536ULL)
357 {
358 /* FAT16 CHS partition (partition size < 32MB) */
359 return PARTITION_FAT_16;
360 }
361 else if (SectorCount < 1048576ULL)
362 {
363 /* FAT16 CHS partition (partition size < 512MB) */
364 return PARTITION_HUGE;
365 }
366 else
367 {
368 /* FAT32 CHS partition (partition size >= 512MB) */
369 return PARTITION_FAT32;
370 }
371 }
372 else
373 {
374 /* Partition starts above the 8.4GB boundary ==> LBA partition */
375
376 if (SectorCount < 1048576ULL)
377 {
378 /* FAT16 LBA partition (partition size < 512MB) */
379 return PARTITION_XINT13;
380 }
381 else
382 {
383 /* FAT32 LBA partition (partition size >= 512MB) */
385 }
386 }
387 }
388 else if (wcsicmp(FileSystem, L"NTFS") == 0)
389 {
390 return PARTITION_IFS;
391 }
392 else if (wcsicmp(FileSystem, L"BTRFS") == 0 ||
393 wcsicmp(FileSystem, L"EXT2") == 0 ||
394 wcsicmp(FileSystem, L"EXT3") == 0 ||
395 wcsicmp(FileSystem, L"EXT4") == 0)
396 {
397 return PARTITION_LINUX;
398 }
399 else
400 {
401 /* Unknown file system */
402 DPRINT1("Unknown file system '%S'\n", FileSystem);
404 }
405}
#define DPRINT1
Definition: precomp.h:8
PWCHAR FileSystem
Definition: format.c:72
#define PARTITION_IFS
Definition: disk.h:93
#define PARTITION_ENTRY_UNUSED
Definition: disk.h:86
#define PARTITION_XINT13
Definition: disk.h:97
#define PARTITION_FAT32
Definition: disk.h:95
#define PARTITION_FAT_12
Definition: disk.h:87
#define PARTITION_HUGE
Definition: disk.h:92
#define PARTITION_FAT_16
Definition: disk.h:90
#define PARTITION_FAT32_XINT13
Definition: disk.h:96
#define wcsicmp
Definition: compat.h:15
#define ASSERT(a)
Definition: mode.c:44
#define L(x)
Definition: ntvdm.h:50
ULONG SectorCount
Definition: part_xbox.c:31
#define PARTITION_LINUX
Definition: partlist.c:36

Referenced by FormatPartition(), and InitializePartitionEntry().

◆ GetFileSystemName()

NTSTATUS GetFileSystemName ( IN PCWSTR PartitionPath  OPTIONAL,
IN HANDLE PartitionHandle  OPTIONAL,
IN OUT PWSTR  FileSystemName,
IN SIZE_T  FileSystemNameSize 
)

Definition at line 112 of file fsrec.c.

117{
118 UNICODE_STRING PartitionPathU;
119
120 if (PartitionPath && PartitionHandle)
122
123 if (PartitionPath)
124 RtlInitUnicodeString(&PartitionPathU, PartitionPath);
125
126 return GetFileSystemName_UStr(PartitionPath ? &PartitionPathU : NULL,
127 PartitionPath ? NULL : PartitionHandle,
128 FileSystemName,
129 FileSystemNameSize);
130}
#define NULL
Definition: types.h:112
NTSTATUS GetFileSystemName_UStr(IN PUNICODE_STRING PartitionPath OPTIONAL, IN HANDLE PartitionHandle OPTIONAL, IN OUT PWSTR FileSystemName, IN SIZE_T FileSystemNameSize)
Definition: fsrec.c:55
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135

◆ GetFileSystemName_UStr()

NTSTATUS GetFileSystemName_UStr ( IN PUNICODE_STRING PartitionPath  OPTIONAL,
IN HANDLE PartitionHandle  OPTIONAL,
IN OUT PWSTR  FileSystemName,
IN SIZE_T  FileSystemNameSize 
)

Definition at line 55 of file fsrec.c.

60{
64
65 if (PartitionPath && PartitionHandle)
67
68 /* Open the partition if a path has been given;
69 * otherwise just use the provided handle. */
70 if (PartitionPath)
71 {
73 PartitionPath,
75 NULL,
76 NULL);
77 Status = NtOpenFile(&PartitionHandle,
78 FILE_GENERIC_READ /* | SYNCHRONIZE */,
82 0 /* FILE_SYNCHRONOUS_IO_NONALERT */);
83 if (!NT_SUCCESS(Status))
84 {
85 DPRINT1("Failed to open partition '%wZ', Status 0x%08lx\n",
86 PartitionPath, Status);
87 return Status;
88 }
89 }
90
91 /* Retrieve the FS attributes */
92 Status = GetFileSystemNameWorker(PartitionHandle,
94 FileSystemName,
95 FileSystemNameSize);
96 if (!NT_SUCCESS(Status))
97 {
98 DPRINT1("GetFileSystemName() failed for partition '%wZ' (0x%p), Status 0x%08lx\n",
99 PartitionPath, PartitionHandle, Status);
100 }
101
102 if (PartitionPath)
103 {
104 /* Close the partition */
105 NtClose(PartitionHandle);
106 }
107
108 return Status;
109}
LONG NTSTATUS
Definition: precomp.h:26
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define FILE_SHARE_READ
Definition: compat.h:136
static NTSTATUS GetFileSystemNameWorker(IN HANDLE PartitionHandle, OUT PIO_STATUS_BLOCK IoStatusBlock, IN OUT PWSTR FileSystemName, IN SIZE_T FileSystemNameSize)
Definition: fsrec.c:24
Status
Definition: gdiplustypes.h:25
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
NTSYSAPI NTSTATUS NTAPI NtOpenFile(OUT PHANDLE phFile, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, OUT PIO_STATUS_BLOCK pIoStatusBlock, IN ULONG ShareMode, IN ULONG OpenMode)
Definition: file.c:3952
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3402
#define FILE_GENERIC_READ
Definition: nt_native.h:653

Referenced by GetFileSystemName(), and InferFileSystemWorker().

◆ GetFileSystemNameWorker()

static NTSTATUS GetFileSystemNameWorker ( IN HANDLE  PartitionHandle,
OUT PIO_STATUS_BLOCK  IoStatusBlock,
IN OUT PWSTR  FileSystemName,
IN SIZE_T  FileSystemNameSize 
)
inlinestatic

Definition at line 24 of file fsrec.c.

29{
33
34 /* Retrieve the FS attributes */
35 Status = NtQueryVolumeInformationFile(PartitionHandle,
37 FileFsAttribute,
38 sizeof(Buffer),
40 if (!NT_SUCCESS(Status))
41 {
42 DPRINT1("NtQueryVolumeInformationFile() failed, Status 0x%08lx\n", Status);
43 return Status;
44 }
45
46 if (FileSystemNameSize < FileFsAttribute->FileSystemNameLength + sizeof(WCHAR))
48
49 return RtlStringCbCopyNW(FileSystemName, FileSystemNameSize,
50 FileFsAttribute->FileSystemName,
51 FileFsAttribute->FileSystemNameLength);
52}
Definition: bufpool.h:45
#define MAX_PATH
Definition: compat.h:34
struct _FILE_FS_ATTRIBUTE_INFORMATION FILE_FS_ATTRIBUTE_INFORMATION
@ FileFsAttributeInformation
Definition: from_kernel.h:223
struct _FILE_FS_ATTRIBUTE_INFORMATION * PFILE_FS_ATTRIBUTE_INFORMATION
NTSTRSAFEAPI RtlStringCbCopyNW(_Out_writes_bytes_(cbDest) NTSTRSAFE_PWSTR pszDest, _In_ size_t cbDest, _In_reads_bytes_(cbToCopy) STRSAFE_LPCWSTR pszSrc, _In_ size_t cbToCopy)
Definition: ntstrsafe.h:416
NTSTATUS NTAPI NtQueryVolumeInformationFile(HANDLE FileHandle, PIO_STATUS_BLOCK IoStatusBlock, PVOID FsInformation, ULONG Length, FS_INFORMATION_CLASS FsInformationClass)
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
unsigned char UCHAR
Definition: xmlstorage.h:181
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by GetFileSystemName_UStr().

◆ InferFileSystem()

NTSTATUS InferFileSystem ( IN PCWSTR PartitionPath  OPTIONAL,
IN HANDLE PartitionHandle  OPTIONAL,
IN OUT PWSTR  FileSystemName,
IN SIZE_T  FileSystemNameSize 
)

Definition at line 269 of file fsrec.c.

274{
276 UNICODE_STRING PartitionPathU;
279
280 if (PartitionPath && PartitionHandle)
282
283 /* Open the partition if a path has been given;
284 * otherwise just use the provided handle. */
285 if (PartitionPath)
286 {
287 RtlInitUnicodeString(&PartitionPathU, PartitionPath);
289 &PartitionPathU,
291 NULL,
292 NULL);
293 Status = NtOpenFile(&PartitionHandle,
294 FILE_GENERIC_READ /* | SYNCHRONIZE */,
298 0 /* FILE_SYNCHRONOUS_IO_NONALERT */);
299 if (!NT_SUCCESS(Status))
300 {
301 DPRINT1("Failed to open partition '%S', Status 0x%08lx\n",
302 PartitionPath, Status);
303 return Status;
304 }
305 }
306
307 /* Retrieve the FS */
308 Status = InferFileSystemWorker(PartitionHandle,
310 FileSystemName,
311 FileSystemNameSize);
312 if (!NT_SUCCESS(Status))
313 {
314 DPRINT1("InferFileSystem() failed for partition '%S' (0x%p), Status 0x%08lx\n",
315 PartitionPath, PartitionHandle, Status);
316 }
317 else
318 {
319 DPRINT1("InferFileSystem(): FileSystem (guessed): %S\n",
320 *FileSystemName ? FileSystemName : L"None");
321 }
322
323 if (PartitionPath)
324 {
325 /* Close the partition */
326 NtClose(PartitionHandle);
327 }
328
329 return Status;
330}
static NTSTATUS InferFileSystemWorker(IN HANDLE PartitionHandle, OUT PIO_STATUS_BLOCK IoStatusBlock, IN OUT PWSTR FileSystemName, IN SIZE_T FileSystemNameSize)
Definition: fsrec.c:134

Referenced by AddPartitionToDisk().

◆ InferFileSystemWorker()

static NTSTATUS InferFileSystemWorker ( IN HANDLE  PartitionHandle,
OUT PIO_STATUS_BLOCK  IoStatusBlock,
IN OUT PWSTR  FileSystemName,
IN SIZE_T  FileSystemNameSize 
)
inlinestatic

Definition at line 134 of file fsrec.c.

139{
140 NTSTATUS Status, Status2;
141 union
142 {
145 } PartInfo;
147
148 if (FileSystemNameSize < sizeof(WCHAR))
150
151 *FileSystemName = L'\0';
152
153 /* Try to infer a file system using NT file system recognition */
154 Status = GetFileSystemName_UStr(NULL, PartitionHandle,
155 FileSystemName,
156 FileSystemNameSize);
157 if (NT_SUCCESS(Status) && *FileSystemName)
158 goto Quit;
159
160 /*
161 * Check whether the partition is MBR, and if so, retrieve its MBR
162 * partition type and try to infer a preferred file system for it.
163 */
164
165 // NOTE: Use Status2 in order not to clobber the original Status.
166 Status2 = NtDeviceIoControlFile(PartitionHandle,
167 NULL,
168 NULL,
169 NULL,
172 NULL,
173 0,
174 &PartInfo.InfoEx,
175 sizeof(PartInfo.InfoEx));
176 if (!NT_SUCCESS(Status2))
177 {
178 DPRINT1("IOCTL_DISK_GET_PARTITION_INFO_EX failed (Status %lx)\n", Status2);
179
180 if (Status2 != STATUS_INVALID_DEVICE_REQUEST)
181 goto Quit;
182
183 /*
184 * We could have failed because the partition is on a dynamic
185 * MBR or GPT data disk, so retry with the non-EX IOCTL.
186 */
187 Status2 = NtDeviceIoControlFile(PartitionHandle,
188 NULL,
189 NULL,
190 NULL,
193 NULL,
194 0,
195 &PartInfo.Info,
196 sizeof(PartInfo.Info));
197 if (!NT_SUCCESS(Status2))
198 {
199 /* We failed again, bail out */
200 DPRINT1("IOCTL_DISK_GET_PARTITION_INFO failed (Status %lx)\n", Status2);
201 goto Quit;
202 }
203
204 /* The partition is supposed to be on an MBR disk; retrieve its type */
205 PartitionType = PartInfo.Info.PartitionType;
206 }
207 else
208 {
209 /* We succeeded; retrieve the partition type only if it is on an MBR disk */
210 if (PartInfo.InfoEx.PartitionStyle != PARTITION_STYLE_MBR)
211 {
212 /* Disk is not MBR, bail out */
213 goto Quit;
214 }
215 PartitionType = PartInfo.InfoEx.Mbr.PartitionType;
216 }
217
218 /*
219 * Given an MBR partition type, try to infer a preferred file system.
220 *
221 * WARNING: This is partly a hack, since partitions with the same type
222 * can be formatted with different file systems: for example, usual Linux
223 * partitions that are formatted in EXT2/3/4, ReiserFS, etc... have the
224 * same partition type 0x83.
225 *
226 * The proper fix is to make a function that detects the existing FS
227 * from a given partition (not based on the partition type).
228 * On the contrary, for unformatted partitions with a given type, the
229 * following code is OK.
230 */
235 {
236 /* FAT12 or FAT16 */
237 Status = RtlStringCbCopyW(FileSystemName, FileSystemNameSize, L"FAT");
238 }
239 else if ((PartitionType == PARTITION_FAT32) ||
241 {
242 Status = RtlStringCbCopyW(FileSystemName, FileSystemNameSize, L"FAT32");
243 }
244 else if (PartitionType == PARTITION_LINUX)
245 {
246 // WARNING: See the warning above.
247 /* Could also be EXT2/3/4, ReiserFS, ... */
248 Status = RtlStringCbCopyW(FileSystemName, FileSystemNameSize, L"BTRFS");
249 }
250 else if (PartitionType == PARTITION_IFS)
251 {
252 // WARNING: See the warning above.
253 /* Could also be HPFS */
254 Status = RtlStringCbCopyW(FileSystemName, FileSystemNameSize, L"NTFS");
255 }
256
257Quit:
258 if (*FileSystemName && wcsicmp(FileSystemName, L"NTFS") == 0)
259 {
260 // WARNING: We cannot write on this FS yet!
261 DPRINT1("Recognized file system '%S' that doesn't have write support yet!\n",
262 FileSystemName);
263 }
264
265 return Status;
266}
#define IOCTL_DISK_GET_PARTITION_INFO_EX
Definition: ntddk_ex.h:206
@ PARTITION_STYLE_MBR
Definition: imports.h:201
NTSYSAPI NTSTATUS NTAPI NtDeviceIoControlFile(IN HANDLE hFile, IN HANDLE hEvent OPTIONAL, IN PIO_APC_ROUTINE IoApcRoutine OPTIONAL, IN PVOID IoApcContext OPTIONAL, OUT PIO_STATUS_BLOCK pIoStatusBlock, IN ULONG DeviceIoControlCode, IN PVOID InBuffer OPTIONAL, IN ULONG InBufferLength, OUT PVOID OutBuffer OPTIONAL, IN ULONG OutBufferLength)
#define IOCTL_DISK_GET_PARTITION_INFO
Definition: ntdddisk.h:106
NTSTRSAFEAPI RtlStringCbCopyW(_Out_writes_bytes_(cbDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cbDest, _In_ NTSTRSAFE_PCWSTR pszSrc)
Definition: ntstrsafe.h:174
CHAR PartitionType
Definition: part_xbox.c:32
#define STATUS_INVALID_DEVICE_REQUEST
Definition: udferr_usr.h:138
_Must_inspect_result_ _In_ WDFCHILDLIST _In_ PWDF_CHILD_LIST_ITERATOR _Out_ WDFDEVICE _Inout_opt_ PWDF_CHILD_RETRIEVE_INFO Info
Definition: wdfchildlist.h:690

Referenced by InferFileSystem().