Synchronize up to trunk's revision r57756.
[reactos.git] / drivers / filesystems / fs_rec / ntfs.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS File System Recognizer
4 * FILE: drivers/filesystems/fs_rec/ntfs.c
5 * PURPOSE: NTFS Recognizer
6 * PROGRAMMER: Alex Ionescu (alex.ionescu@reactos.org)
7 * Eric Kohl
8 */
9
10 /* INCLUDES *****************************************************************/
11
12 #include "fs_rec.h"
13 #define NDEBUG
14 #include <debug.h>
15
16 /* FUNCTIONS ****************************************************************/
17
18 BOOLEAN
19 NTAPI
20 FsRecIsNtfsVolume(IN PPACKED_BOOT_SECTOR BootSector,
21 IN ULONG BytesPerSector,
22 IN PLARGE_INTEGER NumberOfSectors)
23 {
24 /* Assume failure */
25 BOOLEAN Result = FALSE;
26
27 PAGED_CODE();
28
29 if ((BootSector->Oem[0] == 'N') &&
30 (BootSector->Oem[1] == 'T') &&
31 (BootSector->Oem[2] == 'F') &&
32 (BootSector->Oem[3] == 'S') &&
33 (BootSector->Oem[4] == ' ') &&
34 (BootSector->Oem[5] == ' ') &&
35 (BootSector->Oem[6] == ' ') &&
36 (BootSector->Oem[7] == ' '))
37 {
38 /* Success */
39 Result = TRUE;
40 }
41
42 /* Return the result */
43 return Result;
44 }
45
46 NTSTATUS
47 NTAPI
48 FsRecNtfsFsControl(IN PDEVICE_OBJECT DeviceObject,
49 IN PIRP Irp)
50 {
51 PIO_STACK_LOCATION Stack;
52 NTSTATUS Status;
53 PDEVICE_OBJECT MountDevice;
54 PPACKED_BOOT_SECTOR Bpb = NULL;
55 ULONG SectorSize;
56 LARGE_INTEGER Offset = {{0, 0}}, Offset2, Offset3, SectorCount;
57 PAGED_CODE();
58
59 /* Get the I/O Stack and check the function type */
60 Stack = IoGetCurrentIrpStackLocation(Irp);
61 switch (Stack->MinorFunction)
62 {
63 case IRP_MN_MOUNT_VOLUME:
64
65 /* Assume failure */
66 Status = STATUS_UNRECOGNIZED_VOLUME;
67
68 /* Get the device object and request the sector size */
69 MountDevice = Stack->Parameters.MountVolume.DeviceObject;
70 if ((FsRecGetDeviceSectorSize(MountDevice, &SectorSize)) &&
71 (FsRecGetDeviceSectors(MountDevice, SectorSize, &SectorCount)))
72 {
73 /* Setup other offsets to try */
74 Offset2.QuadPart = SectorCount.QuadPart >> 1;
75 Offset2.QuadPart *= SectorSize;
76 Offset3.QuadPart = (SectorCount.QuadPart - 1) * SectorSize;
77
78 /* Try to read the BPB */
79 if (FsRecReadBlock(MountDevice,
80 &Offset,
81 512,
82 SectorSize,
83 (PVOID)&Bpb,
84 NULL))
85 {
86 /* Check if it's an actual NTFS volume */
87 if (FsRecIsNtfsVolume(Bpb, SectorSize, &SectorCount))
88 {
89 /* It is! */
90 Status = STATUS_FS_DRIVER_REQUIRED;
91 }
92 }
93 else if (FsRecReadBlock(MountDevice,
94 &Offset2,
95 512,
96 SectorSize,
97 (PVOID)&Bpb,
98 NULL))
99 {
100 /* Check if it's an actual NTFS volume */
101 if (FsRecIsNtfsVolume(Bpb, SectorSize, &SectorCount))
102 {
103 /* It is! */
104 Status = STATUS_FS_DRIVER_REQUIRED;
105 }
106 }
107 else if (FsRecReadBlock(MountDevice,
108 &Offset3,
109 512,
110 SectorSize,
111 (PVOID)&Bpb,
112 NULL))
113 {
114 /* Check if it's an actual NTFS volume */
115 if (FsRecIsNtfsVolume(Bpb, SectorSize, &SectorCount))
116 {
117 /* It is! */
118 Status = STATUS_FS_DRIVER_REQUIRED;
119 }
120 }
121
122 /* Free the boot sector if we have one */
123 ExFreePool(Bpb);
124 }
125 break;
126
127 case IRP_MN_LOAD_FILE_SYSTEM:
128
129 /* Load the file system */
130 Status = FsRecLoadFileSystem(DeviceObject,
131 L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\Ntfs");
132 break;
133
134 default:
135
136 /* Invalid request */
137 Status = STATUS_INVALID_DEVICE_REQUEST;
138 }
139
140 /* Return Status */
141 return Status;
142 }
143
144 /* EOF */