1 /*
2  * COPYRIGHT:        See COPYING in the top level directory
3  * PROJECT:          ReactOS File System Recognizer
4  * FILE:             drivers/filesystems/fs_rec/btrfs.c
5  * PURPOSE:          Btrfs Recognizer
6  * PROGRAMMER:       Peter Hater
7  *                   Pierre Schweitzer (pierre@reactos.org)
8  */
9 
10 /* INCLUDES *****************************************************************/
11 
12 #include "fs_rec.h"
13 #include "reiserfs.h"
14 
15 #define NDEBUG
16 #include <debug.h>
17 
18 /* FUNCTIONS ****************************************************************/
19 
20 BOOLEAN
21 NTAPI
22 FsRecIsReiserfsVolume(IN PRFSD_SUPER_BLOCK sb)
23 {
24     UCHAR sz_MagicKey[] = REISER2FS_SUPER_MAGIC_STRING;
25     UCHAR currentChar;
26     int   i;
27 
28     // If any characters read from disk don't match the expected magic key, we don't have a ReiserFS volume.
29     for (i = 0; i < MAGIC_KEY_LENGTH; i++)
30     {
31         currentChar = sb->s_magic[i];
32         if (currentChar != sz_MagicKey[i])
33         {
34             return FALSE;
35         }
36     }
37 
38     return TRUE;
39 }
40 
41 NTSTATUS
42 NTAPI
43 FsRecReiserfsFsControl(IN PDEVICE_OBJECT DeviceObject,
44                     IN PIRP Irp)
45 {
46     PIO_STACK_LOCATION Stack;
47     NTSTATUS Status;
48     PDEVICE_OBJECT MountDevice;
49     PRFSD_SUPER_BLOCK Spb = NULL;
50     ULONG SectorSize;
51     LARGE_INTEGER Offset;
52     BOOLEAN DeviceError = FALSE;
53     PAGED_CODE();
54 
55     /* Get the I/O Stack and check the function type */
56     Stack = IoGetCurrentIrpStackLocation(Irp);
57     switch (Stack->MinorFunction)
58     {
59         case IRP_MN_MOUNT_VOLUME:
60 
61             /* Assume failure */
62             Status = STATUS_UNRECOGNIZED_VOLUME;
63 
64             /* Get the device object and request the sector size */
65             MountDevice = Stack->Parameters.MountVolume.DeviceObject;
66             if (FsRecGetDeviceSectorSize(MountDevice, &SectorSize))
67             {
68                 /* Try to read the superblock */
69                 Offset.QuadPart = REISERFS_DISK_OFFSET_IN_BYTES;
70                 if (FsRecReadBlock(MountDevice,
71                                    &Offset,
72                                    SectorSize,
73                                    SectorSize,
74                                    (PVOID)&Spb,
75                                    &DeviceError))
76                 {
77                     /* Check if it's an actual BTRFS volume */
78                     if (FsRecIsReiserfsVolume(Spb))
79                     {
80                         /* It is! */
81                         Status = STATUS_FS_DRIVER_REQUIRED;
82                     }
83                 }
84 
85                 /* Free the boot sector if we have one */
86                 ExFreePool(Spb);
87             }
88             else
89             {
90                 /* We have some sort of failure in the storage stack */
91                 DeviceError = TRUE;
92             }
93 
94             /* Check if we have an error on the stack */
95             if (DeviceError)
96             {
97                 /* Was this because of a floppy? */
98                 if (MountDevice->Characteristics & FILE_FLOPPY_DISKETTE)
99                 {
100                     /* Let the FS try anyway */
101                     Status = STATUS_FS_DRIVER_REQUIRED;
102                 }
103             }
104 
105             break;
106 
107         case IRP_MN_LOAD_FILE_SYSTEM:
108 
109             /* Load the file system */
110             Status = FsRecLoadFileSystem(DeviceObject,
111                                          L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\reiserfs");
112             break;
113 
114         default:
115 
116             /* Invalid request */
117             Status = STATUS_INVALID_DEVICE_REQUEST;
118     }
119 
120     /* Return Status */
121     return Status;
122 }
123