xref: /reactos/drivers/filesystems/fs_rec/cdfs.c (revision 8a978a17)
1 /*
2  * PROJECT:     ReactOS File System Recognizer
3  * LICENSE:     GPL-2.0 (https://spdx.org/licenses/GPL-2.0)
4  * PURPOSE:     CDFS Recognizer
5  * COPYRIGHT:   Copyright 2002 Eric Kohl
6  *              Copyright 2007 Alex Ionescu <alex.ionescu@reactos.org>
7  *              Copyright 2017 Colin Finck <colin@reactos.org>
8  */
9 
10 /* INCLUDES *****************************************************************/
11 
12 #include "fs_rec.h"
13 
14 #define NDEBUG
15 #include <debug.h>
16 
17 #include "cdfs.h"
18 
19 /* FUNCTIONS ****************************************************************/
20 
21 BOOLEAN
22 NTAPI
23 FsRecIsCdfsVolume(IN PDEVICE_OBJECT DeviceObject,
24                   IN ULONG SectorSize)
25 {
26     BOOLEAN bReturnValue = FALSE;
27     LARGE_INTEGER Offset;
28     PVD_HEADER pVdHeader = NULL;
29     PAGED_CODE();
30 
31     // Read the Primary Volume Descriptor.
32     Offset.QuadPart = VD_HEADER_OFFSET;
33     if (!FsRecReadBlock(DeviceObject, &Offset, sizeof(VD_HEADER), SectorSize, (PVOID*)&pVdHeader, NULL))
34     {
35         // We cannot read this block, so no reason to let the CDFS driver try it.
36         goto Cleanup;
37     }
38 
39     // Verify the fields.
40     if (pVdHeader->Type != VD_TYPE_PRIMARY)
41         goto Cleanup;
42 
43     DPRINT("pVdHeader->Type verified!\n");
44 
45     if (RtlCompareMemory(pVdHeader->Identifier, VD_IDENTIFIER, VD_IDENTIFIER_LENGTH) != VD_IDENTIFIER_LENGTH)
46         goto Cleanup;
47 
48     DPRINT("pVdHeader->Identifier verified!\n");
49 
50     if (pVdHeader->Version != VD_VERSION)
51         goto Cleanup;
52 
53     DPRINT("pVdHeader->Version verified! This is a CDFS volume!\n");
54 
55     bReturnValue = TRUE;
56 
57 Cleanup:
58     if (pVdHeader)
59         ExFreePool(pVdHeader);
60 
61     return bReturnValue;
62 }
63 
64 NTSTATUS
65 NTAPI
66 FsRecCdfsFsControl(IN PDEVICE_OBJECT DeviceObject,
67                    IN PIRP Irp)
68 {
69     PDEVICE_OBJECT MountDevice;
70     ULONG SectorSize;
71     PIO_STACK_LOCATION Stack;
72     NTSTATUS Status;
73     PAGED_CODE();
74 
75     /* Get the I/O Stack and check the function type */
76     Stack = IoGetCurrentIrpStackLocation(Irp);
77     switch (Stack->MinorFunction)
78     {
79         case IRP_MN_MOUNT_VOLUME:
80 
81             /* Assume failure */
82             Status = STATUS_UNRECOGNIZED_VOLUME;
83 
84             /* Get the device object and request the sector size */
85             MountDevice = Stack->Parameters.MountVolume.DeviceObject;
86             if (FsRecGetDeviceSectorSize(MountDevice, &SectorSize))
87             {
88                 /* Check if it's an actual CDFS (ISO-9660) volume */
89                 if (FsRecIsCdfsVolume(MountDevice, SectorSize))
90                 {
91                     /* It is! */
92                     Status = STATUS_FS_DRIVER_REQUIRED;
93                 }
94             }
95 
96             break;
97 
98         case IRP_MN_LOAD_FILE_SYSTEM:
99 
100             /* Load the file system */
101             Status = FsRecLoadFileSystem(DeviceObject,
102                                          L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\Cdfs");
103             break;
104 
105         default:
106 
107             /* Invalid request */
108             Status = STATUS_INVALID_DEVICE_REQUEST;
109     }
110 
111     /* Return Status */
112     return Status;
113 }
114 
115 /* EOF */
116