Don't leak IRPs in case of failure
[reactos.git] / reactos / drivers / filesystems / fastfat_new / fsctl.c
1 /*
2 * PROJECT: ReactOS FAT file system driver
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: drivers/filesystems/fastfat/fsctl.c
5 * PURPOSE: Filesystem control
6 * PROGRAMMERS: Aleksey Bragin (aleksey@reactos.org)
7 */
8
9 /* INCLUDES *****************************************************************/
10
11 #define NDEBUG
12 #include "fastfat.h"
13
14 /* FUNCTIONS ****************************************************************/
15
16 NTSTATUS
17 NTAPI
18 FatUserFsCtrl(PFAT_IRP_CONTEXT IrpContext, PIRP Irp)
19 {
20 DPRINT1("FatUserFsCtrl()\n");
21 FatCompleteRequest(IrpContext, Irp, STATUS_INVALID_DEVICE_REQUEST);
22 return STATUS_INVALID_DEVICE_REQUEST;
23 }
24
25 NTSTATUS
26 NTAPI
27 FatVerifyVolume(PFAT_IRP_CONTEXT IrpContext, PIRP Irp)
28 {
29 DPRINT1("FatVerifyVolume()\n");
30 FatCompleteRequest(IrpContext, Irp, STATUS_INVALID_DEVICE_REQUEST);
31 return STATUS_INVALID_DEVICE_REQUEST;
32 }
33
34 VOID
35 NTAPI
36 FatiCleanVcbs(PFAT_IRP_CONTEXT IrpContext)
37 {
38 /* Make sure this IRP is waitable */
39 ASSERT(IrpContext->Flags & IRPCONTEXT_CANWAIT);
40
41 /* Acquire global resource */
42 ExAcquireResourceExclusiveLite(&FatGlobalData.Resource, TRUE);
43
44 /* TODO: Go through all VCBs and delete unmounted ones */
45
46 /* Release global resource */
47 ExReleaseResourceLite(&FatGlobalData.Resource);
48 }
49
50 NTSTATUS
51 NTAPI
52 FatMountVolume(PFAT_IRP_CONTEXT IrpContext,
53 PDEVICE_OBJECT TargetDeviceObject,
54 PVPB Vpb,
55 PDEVICE_OBJECT FsDeviceObject)
56 {
57 NTSTATUS Status;
58 PVOLUME_DEVICE_OBJECT VolumeDevice;
59
60 DPRINT1("FatMountVolume()\n");
61
62 /* Make sure this IRP is waitable */
63 ASSERT(IrpContext->Flags & IRPCONTEXT_CANWAIT);
64
65 /* TODO: IOCTL_DISK_CHECK_VERIFY */
66 /* TODO: Check if data-track present in case of a CD drive */
67 /* TODO: IOCTL_DISK_GET_PARTITION_INFO_EX */
68
69 /* Remove unmounted VCBs */
70 FatiCleanVcbs(IrpContext);
71
72 /* Create a new volume device object */
73 Status = IoCreateDevice(FatGlobalData.DriverObject,
74 sizeof(VOLUME_DEVICE_OBJECT) - sizeof(DEVICE_OBJECT),
75 NULL,
76 FILE_DEVICE_DISK_FILE_SYSTEM,
77 0,
78 FALSE,
79 (PDEVICE_OBJECT *)&VolumeDevice);
80
81 if (!NT_SUCCESS(Status)) return Status;
82
83 /* Match alignment requirements */
84 if (TargetDeviceObject->AlignmentRequirement > VolumeDevice->DeviceObject.AlignmentRequirement)
85 {
86 VolumeDevice->DeviceObject.AlignmentRequirement = TargetDeviceObject->AlignmentRequirement;
87 }
88
89 /* Init stack size */
90 VolumeDevice->DeviceObject.StackSize = TargetDeviceObject->StackSize + 1;
91
92 /* TODO: IOCTL_DISK_GET_DRIVE_GEOMETRY to obtain BytesPerSector */
93 VolumeDevice->DeviceObject.SectorSize = 512;
94
95 /* Signal we're done with initializing */
96 VolumeDevice->DeviceObject.Flags &= ~DO_DEVICE_INITIALIZING;
97
98 /* Save device object in a VPB */
99 Vpb->DeviceObject = (PDEVICE_OBJECT)VolumeDevice;
100
101 /* TODO: Initialize VCB for this volume */
102
103 /* Return success */
104 return STATUS_SUCCESS;
105 }
106
107
108
109 NTSTATUS
110 NTAPI
111 FatiFileSystemControl(PFAT_IRP_CONTEXT IrpContext, PIRP Irp)
112 {
113 PIO_STACK_LOCATION IrpSp;
114 NTSTATUS Status;
115
116 /* Get current IRP stack location */
117 IrpSp = IoGetCurrentIrpStackLocation(Irp);
118
119 /* Dispatch depending on the minor function */
120 switch (IrpSp->MinorFunction)
121 {
122 case IRP_MN_USER_FS_REQUEST:
123 Status = FatUserFsCtrl(IrpContext, Irp);
124 break;
125
126 case IRP_MN_MOUNT_VOLUME:
127 Status = FatMountVolume(IrpContext,
128 IrpSp->Parameters.MountVolume.DeviceObject,
129 IrpSp->Parameters.MountVolume.Vpb,
130 IrpSp->DeviceObject);
131
132 if (!NT_SUCCESS(Status))
133 FatCompleteRequest(IrpContext, Irp, Status);
134
135 break;
136
137 case IRP_MN_VERIFY_VOLUME:
138 Status = FatVerifyVolume(IrpContext, Irp);
139 break;
140
141 default:
142 DPRINT1("Unhandled FSCTL minor 0x%x\n", IrpSp->MinorFunction);
143 FatCompleteRequest(IrpContext, Irp, STATUS_INVALID_DEVICE_REQUEST);
144 Status = STATUS_INVALID_DEVICE_REQUEST;
145 }
146
147 return Status;
148 }
149
150
151 NTSTATUS
152 NTAPI
153 FatFileSystemControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
154 {
155 NTSTATUS Status = STATUS_SUCCESS;
156 PFAT_IRP_CONTEXT IrpContext;
157 BOOLEAN CanWait = TRUE;
158
159 DPRINT1("FatFileSystemControl(DeviceObject %p, Irp %p)\n", DeviceObject, Irp);
160
161 /* Get CanWait flag */
162 if (IoGetCurrentIrpStackLocation(Irp)->FileObject)
163 {
164 CanWait = IoIsOperationSynchronous(Irp);
165 }
166
167 /* Enter FsRtl critical region */
168 FsRtlEnterFileSystem();
169
170 /* Build an irp context */
171 IrpContext = FatBuildIrpContext(Irp, CanWait);
172
173 /* Call internal function */
174 Status = FatiFileSystemControl(IrpContext, Irp);
175
176 /* Leave FsRtl critical region */
177 FsRtlExitFileSystem();
178
179 return Status;
180 }