4a2ee5fa3b8bd1d0a65e297829fde230dc7a555e
[reactos.git] / reactos / drivers / filesystems / fastfat_new / volume.c
1 /*
2 * PROJECT: ReactOS FAT file system driver
3 * LICENSE: GNU GPLv3 as published by the Free Software Foundation
4 * FILE: drivers/filesystems/fastfat/volume.c
5 * PURPOSE: Volume information
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 FatiQueryFsVolumeInfo(PVCB Vcb,
19 PFILE_FS_VOLUME_INFORMATION Buffer,
20 PLONG Length)
21 {
22 ULONG ByteSize;
23 NTSTATUS Status = STATUS_SUCCESS;
24
25 /* Deduct the minimum written length */
26 *Length -= FIELD_OFFSET(FILE_FS_VOLUME_INFORMATION, VolumeLabel[0]);
27
28 /* Zero it */
29 RtlZeroMemory(Buffer, sizeof(FILE_FS_VOLUME_INFORMATION));
30
31 DPRINT("Serial number 0x%x, label length %d\n",
32 Vcb->Vpb->SerialNumber, Vcb->Vpb->VolumeLabelLength);
33
34 /* Save serial number */
35 Buffer->VolumeSerialNumber = Vcb->Vpb->SerialNumber;
36
37 /* Set max byte size */
38 ByteSize = Vcb->Vpb->VolumeLabelLength;
39
40 /* Check buffer length and reduce byte size if needed */
41 if (*Length < Vcb->Vpb->VolumeLabelLength)
42 {
43 /* Copy only up to what buffer size was provided */
44 ByteSize = *Length;
45 Status = STATUS_BUFFER_OVERFLOW;
46 }
47
48 /* Copy volume label */
49 Buffer->VolumeLabelLength = Vcb->Vpb->VolumeLabelLength;
50 RtlCopyMemory(Buffer->VolumeLabel, Vcb->Vpb->VolumeLabel, ByteSize);
51 *Length -= ByteSize;
52
53 return Status;
54 }
55
56 NTSTATUS
57 NTAPI
58 FatiQueryVolumeInfo(PFAT_IRP_CONTEXT IrpContext, PIRP Irp)
59 {
60 PFILE_OBJECT FileObject;
61 PIO_STACK_LOCATION IrpSp;
62 FILE_INFORMATION_CLASS InfoClass;
63 TYPE_OF_OPEN FileType;
64 PVCB Vcb;
65 PFCB Fcb;
66 PCCB Ccb;
67 LONG Length;
68 PVOID Buffer;
69 BOOLEAN VcbLocked = FALSE;
70 NTSTATUS Status = STATUS_SUCCESS;
71
72 /* Get IRP stack location */
73 IrpSp = IoGetCurrentIrpStackLocation(Irp);
74
75 /* Get the file object */
76 FileObject = IrpSp->FileObject;
77
78 /* Copy variables to something with shorter names */
79 InfoClass = IrpSp->Parameters.QueryVolume.FsInformationClass;
80 Length = IrpSp->Parameters.QueryVolume.Length;
81 Buffer = Irp->AssociatedIrp.SystemBuffer;
82
83 DPRINT("FatiQueryVolumeInfo\n", 0);
84 DPRINT("\tIrp = %08lx\n", Irp);
85 DPRINT("\tLength = %08lx\n", Length);
86 DPRINT("\tFsInformationClass = %08lx\n", InfoClass);
87 DPRINT("\tBuffer = %08lx\n", Buffer);
88
89 FileType = FatDecodeFileObject(FileObject, &Vcb, &Fcb, &Ccb);
90
91 DPRINT("Vcb %p, Fcb %p, Ccb %p, open type %d\n", Vcb, Fcb, Ccb, FileType);
92
93 switch (InfoClass)
94 {
95 case FileFsVolumeInformation:
96 /* Acquired the shared VCB lock */
97 if (!FatAcquireSharedVcb(IrpContext, Vcb))
98 {
99 ASSERT(FALSE);
100 }
101
102 /* Remember we locked it */
103 VcbLocked = TRUE;
104
105 /* Call FsVolumeInfo handler */
106 Status = FatiQueryFsVolumeInfo(Vcb, Buffer, &Length);
107 break;
108 default:
109 DPRINT1("Volume information class %d is not supported!\n", InfoClass);
110 UNIMPLEMENTED;
111 }
112
113 /* Set IoStatus.Information to amount of filled bytes */
114 Irp->IoStatus.Information = IrpSp->Parameters.QueryVolume.Length - Length;
115
116 /* Release VCB lock */
117 if (VcbLocked) FatReleaseVcb(IrpContext, Vcb);
118
119 /* Complete request and return status */
120 FatCompleteRequest(IrpContext, Irp, Status);
121 return Status;
122 }
123
124 NTSTATUS
125 NTAPI
126 FatQueryVolumeInfo(PDEVICE_OBJECT DeviceObject, PIRP Irp)
127 {
128 NTSTATUS Status;
129 BOOLEAN TopLevel, CanWait;
130 PFAT_IRP_CONTEXT IrpContext;
131
132 CanWait = TRUE;
133 TopLevel = FALSE;
134 Status = STATUS_INVALID_DEVICE_REQUEST;
135
136 /* Get CanWait flag */
137 if (IoGetCurrentIrpStackLocation(Irp)->FileObject != NULL)
138 CanWait = IoIsOperationSynchronous(Irp);
139
140 /* Enter FsRtl critical region */
141 FsRtlEnterFileSystem();
142
143 /* Set Top Level IRP if not set */
144 if (IoGetTopLevelIrp() == NULL)
145 {
146 IoSetTopLevelIrp(Irp);
147 TopLevel = TRUE;
148 }
149
150 /* Build an irp context */
151 IrpContext = FatBuildIrpContext(Irp, CanWait);
152
153 /* Call the request handler */
154 Status = FatiQueryVolumeInfo(IrpContext, Irp);
155
156 /* Restore top level Irp */
157 if (TopLevel)
158 IoSetTopLevelIrp(NULL);
159
160 /* Leave FsRtl critical region */
161 FsRtlExitFileSystem();
162
163 return Status;
164 }
165
166 NTSTATUS
167 NTAPI
168 FatSetVolumeInfo(PDEVICE_OBJECT DeviceObject, PIRP Irp)
169 {
170 DPRINT1("FatSetVolumeInfo()\n");
171 return STATUS_NOT_IMPLEMENTED;
172 }
173
174 VOID
175 NTAPI
176 FatReadStreamFile(PVCB Vcb,
177 ULONGLONG ByteOffset,
178 ULONG ByteSize,
179 PBCB *Bcb,
180 PVOID *Buffer)
181 {
182 LARGE_INTEGER Offset;
183
184 Offset.QuadPart = ByteOffset;
185
186 if (!CcMapData(Vcb->StreamFileObject,
187 &Offset,
188 ByteSize,
189 TRUE, // FIXME: CanWait
190 Bcb,
191 Buffer))
192 {
193 ASSERT(FALSE);
194 }
195 }
196
197 /* EOF */