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