Reverted latest changes.
[reactos.git] / reactos / ntoskrnl / io / vpb.c
1 /* $Id: vpb.c,v 1.19 2002/09/08 10:23:26 chorns Exp $
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/io/vpb.c
6 * PURPOSE: Volume Parameter Block managment
7 * PROGRAMMER: David Welch (welch@mcmail.com)
8 * UPDATE HISTORY:
9 * Created 22/05/98
10 */
11
12 /* INCLUDES *****************************************************************/
13
14 #include <ddk/ntddk.h>
15 #include <internal/io.h>
16 #include <internal/mm.h>
17 #include <internal/pool.h>
18
19
20 #define NDEBUG
21 #include <internal/debug.h>
22
23 /* GLOBALS *******************************************************************/
24
25 static KSPIN_LOCK IoVpbLock;
26
27 #define TAG_VPB TAG('V', 'P', 'B', ' ')
28 #define TAG_SYSB TAG('S', 'Y', 'S', 'B')
29
30 /* FUNCTIONS *****************************************************************/
31
32 VOID
33 IoInitVpbImplementation(VOID)
34 {
35 KeInitializeSpinLock(&IoVpbLock);
36 }
37
38 NTSTATUS
39 IoAttachVpb(PDEVICE_OBJECT DeviceObject)
40 {
41 PVPB Vpb;
42
43 Vpb = ExAllocatePoolWithTag(NonPagedPool,
44 sizeof(VPB),
45 TAG_VPB);
46 if (Vpb == NULL)
47 {
48 return(STATUS_UNSUCCESSFUL);
49 }
50
51 Vpb->Type = 0;
52 Vpb->Size = sizeof(VPB) / sizeof(DWORD);
53 Vpb->Flags = 0;
54 Vpb->VolumeLabelLength = 0;
55 Vpb->DeviceObject = NULL;
56 Vpb->RealDevice = DeviceObject;
57 Vpb->SerialNumber = 0;
58 Vpb->ReferenceCount = 0;
59 RtlZeroMemory(Vpb->VolumeLabel,
60 sizeof(WCHAR) * MAXIMUM_VOLUME_LABEL_LENGTH);
61
62 DeviceObject->Vpb = Vpb;
63
64 return(STATUS_SUCCESS);
65 }
66
67
68 NTSTATUS STDCALL
69 NtQueryVolumeInformationFile(IN HANDLE FileHandle,
70 OUT PIO_STATUS_BLOCK IoStatusBlock,
71 OUT PVOID FsInformation,
72 IN ULONG Length,
73 IN FS_INFORMATION_CLASS FsInformationClass)
74
75 /*
76 * FUNCTION: Queries the volume information
77 * ARGUMENTS:
78 * FileHandle = Handle to a file object on the target volume
79 * ReturnLength = DataWritten
80 * FsInformation = Caller should supply storage for the information
81 * structure.
82 * Length = Size of the information structure
83 * FsInformationClass = Index to a information structure
84 *
85 * FileFsVolumeInformation FILE_FS_VOLUME_INFORMATION
86 * FileFsLabelInformation FILE_FS_LABEL_INFORMATION
87 * FileFsSizeInformation FILE_FS_SIZE_INFORMATION
88 * FileFsDeviceInformation FILE_FS_DEVICE_INFORMATION
89 * FileFsAttributeInformation FILE_FS_ATTRIBUTE_INFORMATION
90 * FileFsControlInformation
91 * FileFsQuotaQueryInformation --
92 * FileFsQuotaSetInformation --
93 * FileFsMaximumInformation
94 *
95 * RETURNS: Status
96 */
97 {
98 PFILE_OBJECT FileObject;
99 PDEVICE_OBJECT DeviceObject;
100 PIRP Irp;
101 NTSTATUS Status;
102 PIO_STACK_LOCATION StackPtr;
103 PVOID SystemBuffer;
104 IO_STATUS_BLOCK IoSB;
105
106 assert(IoStatusBlock != NULL);
107 assert(FsInformation != NULL);
108
109 DPRINT("FsInformation %p\n", FsInformation);
110
111 Status = ObReferenceObjectByHandle(FileHandle,
112 FILE_READ_ATTRIBUTES,
113 IoFileObjectType,
114 UserMode,
115 (PVOID*)&FileObject,
116 NULL);
117 if (!NT_SUCCESS(Status))
118 {
119 return(Status);
120 }
121
122 DeviceObject = FileObject->DeviceObject;
123
124 Irp = IoAllocateIrp(DeviceObject->StackSize,
125 TRUE);
126 if (Irp == NULL)
127 {
128 ObDereferenceObject(FileObject);
129 return(STATUS_INSUFFICIENT_RESOURCES);
130 }
131
132 SystemBuffer = ExAllocatePoolWithTag(NonPagedPool,
133 Length,
134 TAG_SYSB);
135 if (SystemBuffer == NULL)
136 {
137 IoFreeIrp(Irp);
138 ObDereferenceObject(FileObject);
139 return(STATUS_INSUFFICIENT_RESOURCES);
140 }
141
142 Irp->AssociatedIrp.SystemBuffer = SystemBuffer;
143 KeResetEvent( &FileObject->Event );
144 Irp->UserEvent = &FileObject->Event;
145 Irp->UserIosb = &IoSB;
146 Irp->Tail.Overlay.Thread = PsGetCurrentThread();
147
148 StackPtr = IoGetNextIrpStackLocation(Irp);
149 StackPtr->MajorFunction = IRP_MJ_QUERY_VOLUME_INFORMATION;
150 StackPtr->MinorFunction = 0;
151 StackPtr->Flags = 0;
152 StackPtr->Control = 0;
153 StackPtr->DeviceObject = DeviceObject;
154 StackPtr->FileObject = FileObject;
155 StackPtr->Parameters.QueryVolume.Length = Length;
156 StackPtr->Parameters.QueryVolume.FsInformationClass =
157 FsInformationClass;
158
159 Status = IoCallDriver(DeviceObject,
160 Irp);
161 if (Status == STATUS_PENDING)
162 {
163 KeWaitForSingleObject(&FileObject->Event,
164 UserRequest,
165 KernelMode,
166 FALSE,
167 NULL);
168 Status = IoSB.Status;
169 }
170 DPRINT("Status %x\n", Status);
171
172 if (NT_SUCCESS(Status))
173 {
174 DPRINT("Information %lu\n", IoStatusBlock->Information);
175 MmSafeCopyToUser(FsInformation,
176 SystemBuffer,
177 IoSB.Information);
178 }
179 if (IoStatusBlock)
180 {
181 *IoStatusBlock = IoSB;
182 }
183 ExFreePool(SystemBuffer);
184
185 return(Status);
186 }
187
188
189 NTSTATUS STDCALL
190 IoQueryVolumeInformation(IN PFILE_OBJECT FileObject,
191 IN FS_INFORMATION_CLASS FsInformationClass,
192 IN ULONG Length,
193 OUT PVOID FsInformation,
194 OUT PULONG ReturnedLength)
195 {
196 IO_STATUS_BLOCK IoStatusBlock;
197 PIO_STACK_LOCATION StackPtr;
198 PDEVICE_OBJECT DeviceObject;
199 PIRP Irp;
200 NTSTATUS Status;
201
202 assert(FsInformation != NULL);
203
204 DPRINT("FsInformation %p\n", FsInformation);
205
206 Status = ObReferenceObjectByPointer(FileObject,
207 FILE_READ_ATTRIBUTES,
208 IoFileObjectType,
209 KernelMode);
210 if (!NT_SUCCESS(Status))
211 {
212 return(Status);
213 }
214
215 DeviceObject = FileObject->DeviceObject;
216
217 Irp = IoAllocateIrp(DeviceObject->StackSize,
218 TRUE);
219 if (Irp == NULL)
220 {
221 ObDereferenceObject(FileObject);
222 return(STATUS_INSUFFICIENT_RESOURCES);
223 }
224
225 Irp->AssociatedIrp.SystemBuffer = FsInformation;
226 KeResetEvent( &FileObject->Event );
227 Irp->UserEvent = &FileObject->Event;
228 Irp->UserIosb = &IoStatusBlock;
229 Irp->Tail.Overlay.Thread = PsGetCurrentThread();
230
231 StackPtr = IoGetNextIrpStackLocation(Irp);
232 StackPtr->MajorFunction = IRP_MJ_QUERY_VOLUME_INFORMATION;
233 StackPtr->MinorFunction = 0;
234 StackPtr->Flags = 0;
235 StackPtr->Control = 0;
236 StackPtr->DeviceObject = DeviceObject;
237 StackPtr->FileObject = FileObject;
238 StackPtr->Parameters.QueryVolume.Length = Length;
239 StackPtr->Parameters.QueryVolume.FsInformationClass =
240 FsInformationClass;
241
242 Status = IoCallDriver(DeviceObject,
243 Irp);
244 if (Status == STATUS_PENDING)
245 {
246 KeWaitForSingleObject(&FileObject->Event,
247 UserRequest,
248 KernelMode,
249 FALSE,
250 NULL);
251 Status = IoStatusBlock.Status;
252 }
253 DPRINT("Status %x\n", Status);
254
255 if (ReturnedLength != NULL)
256 {
257 *ReturnedLength = IoStatusBlock.Information;
258 }
259
260 return(Status);
261 }
262
263
264 NTSTATUS STDCALL
265 NtSetVolumeInformationFile(IN HANDLE FileHandle,
266 OUT PIO_STATUS_BLOCK IoStatusBlock,
267 IN PVOID FsInformation,
268 IN ULONG Length,
269 IN FS_INFORMATION_CLASS FsInformationClass)
270 {
271 PFILE_OBJECT FileObject;
272 PDEVICE_OBJECT DeviceObject;
273 PIRP Irp;
274 NTSTATUS Status;
275 PIO_STACK_LOCATION StackPtr;
276 PVOID SystemBuffer;
277 IO_STATUS_BLOCK IoSB;
278
279 Status = ObReferenceObjectByHandle(FileHandle,
280 FILE_WRITE_ATTRIBUTES,
281 NULL,
282 UserMode,
283 (PVOID*)&FileObject,
284 NULL);
285 if (Status != STATUS_SUCCESS)
286 {
287 return(Status);
288 }
289
290 DeviceObject = FileObject->DeviceObject;
291
292 Irp = IoAllocateIrp(DeviceObject->StackSize,TRUE);
293 if (Irp == NULL)
294 {
295 ObDereferenceObject(FileObject);
296 return(STATUS_INSUFFICIENT_RESOURCES);
297 }
298
299 SystemBuffer = ExAllocatePoolWithTag(NonPagedPool,
300 Length,
301 TAG_SYSB);
302 if (SystemBuffer == NULL)
303 {
304 IoFreeIrp(Irp);
305 ObDereferenceObject(FileObject);
306 return(STATUS_INSUFFICIENT_RESOURCES);
307 }
308
309 MmSafeCopyFromUser(SystemBuffer,
310 FsInformation,
311 Length);
312
313 Irp->AssociatedIrp.SystemBuffer = SystemBuffer;
314 KeResetEvent( &FileObject->Event );
315 Irp->UserEvent = &FileObject->Event;
316 Irp->UserIosb = &IoSB;
317 Irp->Tail.Overlay.Thread = PsGetCurrentThread();
318
319 StackPtr = IoGetNextIrpStackLocation(Irp);
320 StackPtr->MajorFunction = IRP_MJ_SET_VOLUME_INFORMATION;
321 StackPtr->MinorFunction = 0;
322 StackPtr->Flags = 0;
323 StackPtr->Control = 0;
324 StackPtr->DeviceObject = DeviceObject;
325 StackPtr->FileObject = FileObject;
326 StackPtr->Parameters.SetVolume.Length = Length;
327 StackPtr->Parameters.SetVolume.FsInformationClass =
328 FsInformationClass;
329
330 Status = IoCallDriver(DeviceObject,Irp);
331 if (Status == STATUS_PENDING)
332 {
333 KeWaitForSingleObject(&FileObject->Event,
334 UserRequest,
335 KernelMode,
336 FALSE,
337 NULL);
338 Status = IoSB.Status;
339 }
340 if (IoStatusBlock)
341 {
342 *IoStatusBlock = IoSB;
343 }
344 ExFreePool(SystemBuffer);
345
346 return(Status);
347 }
348
349
350 VOID STDCALL
351 IoAcquireVpbSpinLock(OUT PKIRQL Irql)
352 {
353 KeAcquireSpinLock(&IoVpbLock,
354 Irql);
355 }
356
357
358 VOID STDCALL
359 IoReleaseVpbSpinLock(IN KIRQL Irql)
360 {
361 KeReleaseSpinLock(&IoVpbLock,
362 Irql);
363 }
364
365 /* EOF */