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)
12 /* INCLUDES *****************************************************************/
14 #include <ddk/ntddk.h>
15 #include <internal/io.h>
16 #include <internal/mm.h>
17 #include <internal/pool.h>
21 #include <internal/debug.h>
23 /* GLOBALS *******************************************************************/
25 static KSPIN_LOCK IoVpbLock;
27 #define TAG_VPB TAG('V', 'P', 'B', ' ')
28 #define TAG_SYSB TAG('S', 'Y', 'S', 'B')
30 /* FUNCTIONS *****************************************************************/
33 IoInitVpbImplementation(VOID)
35 KeInitializeSpinLock(&IoVpbLock);
39 IoAttachVpb(PDEVICE_OBJECT DeviceObject)
43 Vpb = ExAllocatePoolWithTag(NonPagedPool,
48 return(STATUS_UNSUCCESSFUL);
52 Vpb->Size = sizeof(VPB) / sizeof(DWORD);
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);
62 DeviceObject->Vpb = Vpb;
64 return(STATUS_SUCCESS);
72 NtQueryVolumeInformationFile(IN HANDLE FileHandle,
73 OUT PIO_STATUS_BLOCK IoStatusBlock,
74 OUT PVOID FsInformation,
76 IN FS_INFORMATION_CLASS FsInformationClass)
79 * FUNCTION: Queries the volume information
81 * FileHandle = Handle to a file object on the target volume
82 * ReturnLength = DataWritten
83 * FsInformation = Caller should supply storage for the information
85 * Length = Size of the information structure
86 * FsInformationClass = Index to a information structure
88 * FileFsVolumeInformation FILE_FS_VOLUME_INFORMATION
89 * FileFsLabelInformation FILE_FS_LABEL_INFORMATION
90 * FileFsSizeInformation FILE_FS_SIZE_INFORMATION
91 * FileFsDeviceInformation FILE_FS_DEVICE_INFORMATION
92 * FileFsAttributeInformation FILE_FS_ATTRIBUTE_INFORMATION
93 * FileFsControlInformation
94 * FileFsQuotaQueryInformation --
95 * FileFsQuotaSetInformation --
96 * FileFsMaximumInformation
101 PFILE_OBJECT FileObject;
102 PDEVICE_OBJECT DeviceObject;
105 PIO_STACK_LOCATION StackPtr;
107 IO_STATUS_BLOCK IoSB;
109 assert(IoStatusBlock != NULL);
110 assert(FsInformation != NULL);
112 DPRINT("FsInformation %p\n", FsInformation);
114 Status = ObReferenceObjectByHandle(FileHandle,
115 FILE_READ_ATTRIBUTES,
120 if (!NT_SUCCESS(Status))
125 DeviceObject = FileObject->DeviceObject;
127 Irp = IoAllocateIrp(DeviceObject->StackSize,
131 ObDereferenceObject(FileObject);
132 return(STATUS_INSUFFICIENT_RESOURCES);
135 SystemBuffer = ExAllocatePoolWithTag(NonPagedPool,
138 if (SystemBuffer == NULL)
141 ObDereferenceObject(FileObject);
142 return(STATUS_INSUFFICIENT_RESOURCES);
145 //trigger FileObject/Event dereferencing
146 Irp->Tail.Overlay.OriginalFileObject = FileObject;
148 Irp->AssociatedIrp.SystemBuffer = SystemBuffer;
149 KeResetEvent( &FileObject->Event );
150 Irp->UserEvent = &FileObject->Event;
151 Irp->UserIosb = &IoSB;
152 Irp->Tail.Overlay.Thread = PsGetCurrentThread();
154 StackPtr = IoGetNextIrpStackLocation(Irp);
155 StackPtr->MajorFunction = IRP_MJ_QUERY_VOLUME_INFORMATION;
156 StackPtr->MinorFunction = 0;
158 StackPtr->Control = 0;
159 StackPtr->DeviceObject = DeviceObject;
160 StackPtr->FileObject = FileObject;
161 StackPtr->Parameters.QueryVolume.Length = Length;
162 StackPtr->Parameters.QueryVolume.FsInformationClass =
165 Status = IoCallDriver(DeviceObject,
167 if (Status == STATUS_PENDING)
169 KeWaitForSingleObject(&FileObject->Event,
174 Status = IoSB.Status;
176 DPRINT("Status %x\n", Status);
178 if (NT_SUCCESS(Status))
180 DPRINT("Information %lu\n", IoStatusBlock->Information);
181 MmSafeCopyToUser(FsInformation,
187 *IoStatusBlock = IoSB;
189 ExFreePool(SystemBuffer);
199 IoQueryVolumeInformation(IN PFILE_OBJECT FileObject,
200 IN FS_INFORMATION_CLASS FsInformationClass,
202 OUT PVOID FsInformation,
203 OUT PULONG ReturnedLength)
205 IO_STATUS_BLOCK IoStatusBlock;
206 PIO_STACK_LOCATION StackPtr;
207 PDEVICE_OBJECT DeviceObject;
211 assert(FsInformation != NULL);
213 DPRINT("FsInformation %p\n", FsInformation);
215 Status = ObReferenceObjectByPointer(FileObject,
216 FILE_READ_ATTRIBUTES,
219 if (!NT_SUCCESS(Status))
224 DeviceObject = FileObject->DeviceObject;
226 Irp = IoAllocateIrp(DeviceObject->StackSize,
230 ObDereferenceObject(FileObject);
231 return(STATUS_INSUFFICIENT_RESOURCES);
234 //trigger FileObject/Event dereferencing
235 Irp->Tail.Overlay.OriginalFileObject = FileObject;
237 Irp->AssociatedIrp.SystemBuffer = FsInformation;
238 KeResetEvent( &FileObject->Event );
239 Irp->UserEvent = &FileObject->Event;
240 Irp->UserIosb = &IoStatusBlock;
241 Irp->Tail.Overlay.Thread = PsGetCurrentThread();
243 StackPtr = IoGetNextIrpStackLocation(Irp);
244 StackPtr->MajorFunction = IRP_MJ_QUERY_VOLUME_INFORMATION;
245 StackPtr->MinorFunction = 0;
247 StackPtr->Control = 0;
248 StackPtr->DeviceObject = DeviceObject;
249 StackPtr->FileObject = FileObject;
250 StackPtr->Parameters.QueryVolume.Length = Length;
251 StackPtr->Parameters.QueryVolume.FsInformationClass =
254 Status = IoCallDriver(DeviceObject,
256 if (Status == STATUS_PENDING)
258 KeWaitForSingleObject(&FileObject->Event,
263 Status = IoStatusBlock.Status;
265 DPRINT("Status %x\n", Status);
267 if (ReturnedLength != NULL)
269 *ReturnedLength = IoStatusBlock.Information;
280 NtSetVolumeInformationFile(IN HANDLE FileHandle,
281 OUT PIO_STATUS_BLOCK IoStatusBlock,
282 IN PVOID FsInformation,
284 IN FS_INFORMATION_CLASS FsInformationClass)
286 PFILE_OBJECT FileObject;
287 PDEVICE_OBJECT DeviceObject;
290 PEXTENDED_IO_STACK_LOCATION StackPtr;
292 IO_STATUS_BLOCK IoSB;
294 Status = ObReferenceObjectByHandle(FileHandle,
295 FILE_WRITE_ATTRIBUTES,
300 if (Status != STATUS_SUCCESS)
305 DeviceObject = FileObject->DeviceObject;
307 Irp = IoAllocateIrp(DeviceObject->StackSize,TRUE);
310 ObDereferenceObject(FileObject);
311 return(STATUS_INSUFFICIENT_RESOURCES);
314 SystemBuffer = ExAllocatePoolWithTag(NonPagedPool,
317 if (SystemBuffer == NULL)
320 ObDereferenceObject(FileObject);
321 return(STATUS_INSUFFICIENT_RESOURCES);
324 MmSafeCopyFromUser(SystemBuffer,
328 //trigger FileObject/Event dereferencing
329 Irp->Tail.Overlay.OriginalFileObject = FileObject;
331 Irp->AssociatedIrp.SystemBuffer = SystemBuffer;
332 KeResetEvent( &FileObject->Event );
333 Irp->UserEvent = &FileObject->Event;
334 Irp->UserIosb = &IoSB;
335 Irp->Tail.Overlay.Thread = PsGetCurrentThread();
337 StackPtr = (PEXTENDED_IO_STACK_LOCATION) IoGetNextIrpStackLocation(Irp);
338 StackPtr->MajorFunction = IRP_MJ_SET_VOLUME_INFORMATION;
339 StackPtr->MinorFunction = 0;
341 StackPtr->Control = 0;
342 StackPtr->DeviceObject = DeviceObject;
343 StackPtr->FileObject = FileObject;
344 StackPtr->Parameters.SetVolume.Length = Length;
345 StackPtr->Parameters.SetVolume.FsInformationClass =
348 Status = IoCallDriver(DeviceObject,Irp);
349 if (Status == STATUS_PENDING)
351 KeWaitForSingleObject(&FileObject->Event,
356 Status = IoSB.Status;
360 *IoStatusBlock = IoSB;
362 ExFreePool(SystemBuffer);
372 IoAcquireVpbSpinLock(OUT PKIRQL Irql)
374 KeAcquireSpinLock(&IoVpbLock,
383 IoReleaseVpbSpinLock(IN KIRQL Irql)
385 KeReleaseSpinLock(&IoVpbLock,