[CRT] Massively improve performance of rand_s
[reactos.git] / drivers / filesystems / fs_rec / cdfs.c
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 */