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);
69 NtQueryVolumeInformationFile(IN HANDLE FileHandle,
70 OUT PIO_STATUS_BLOCK IoStatusBlock,
71 OUT PVOID FsInformation,
73 IN FS_INFORMATION_CLASS FsInformationClass)
76 * FUNCTION: Queries the volume information
78 * FileHandle = Handle to a file object on the target volume
79 * ReturnLength = DataWritten
80 * FsInformation = Caller should supply storage for the information
82 * Length = Size of the information structure
83 * FsInformationClass = Index to a information structure
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
98 PFILE_OBJECT FileObject;
99 PDEVICE_OBJECT DeviceObject;
102 PIO_STACK_LOCATION StackPtr;
104 IO_STATUS_BLOCK IoSB;
106 assert(IoStatusBlock != NULL);
107 assert(FsInformation != NULL);
109 DPRINT("FsInformation %p\n", FsInformation);
111 Status = ObReferenceObjectByHandle(FileHandle,
112 FILE_READ_ATTRIBUTES,
117 if (!NT_SUCCESS(Status))
122 DeviceObject = FileObject->DeviceObject;
124 Irp = IoAllocateIrp(DeviceObject->StackSize,
128 ObDereferenceObject(FileObject);
129 return(STATUS_INSUFFICIENT_RESOURCES);
132 SystemBuffer = ExAllocatePoolWithTag(NonPagedPool,
135 if (SystemBuffer == NULL)
138 ObDereferenceObject(FileObject);
139 return(STATUS_INSUFFICIENT_RESOURCES);
142 Irp->AssociatedIrp.SystemBuffer = SystemBuffer;
143 KeResetEvent( &FileObject->Event );
144 Irp->UserEvent = &FileObject->Event;
145 Irp->UserIosb = &IoSB;
146 Irp->Tail.Overlay.Thread = PsGetCurrentThread();
148 StackPtr = IoGetNextIrpStackLocation(Irp);
149 StackPtr->MajorFunction = IRP_MJ_QUERY_VOLUME_INFORMATION;
150 StackPtr->MinorFunction = 0;
152 StackPtr->Control = 0;
153 StackPtr->DeviceObject = DeviceObject;
154 StackPtr->FileObject = FileObject;
155 StackPtr->Parameters.QueryVolume.Length = Length;
156 StackPtr->Parameters.QueryVolume.FsInformationClass =
159 Status = IoCallDriver(DeviceObject,
161 if (Status == STATUS_PENDING)
163 KeWaitForSingleObject(&FileObject->Event,
168 Status = IoSB.Status;
170 DPRINT("Status %x\n", Status);
172 if (NT_SUCCESS(Status))
174 DPRINT("Information %lu\n", IoStatusBlock->Information);
175 MmSafeCopyToUser(FsInformation,
181 *IoStatusBlock = IoSB;
183 ExFreePool(SystemBuffer);
190 IoQueryVolumeInformation(IN PFILE_OBJECT FileObject,
191 IN FS_INFORMATION_CLASS FsInformationClass,
193 OUT PVOID FsInformation,
194 OUT PULONG ReturnedLength)
196 IO_STATUS_BLOCK IoStatusBlock;
197 PIO_STACK_LOCATION StackPtr;
198 PDEVICE_OBJECT DeviceObject;
202 assert(FsInformation != NULL);
204 DPRINT("FsInformation %p\n", FsInformation);
206 Status = ObReferenceObjectByPointer(FileObject,
207 FILE_READ_ATTRIBUTES,
210 if (!NT_SUCCESS(Status))
215 DeviceObject = FileObject->DeviceObject;
217 Irp = IoAllocateIrp(DeviceObject->StackSize,
221 ObDereferenceObject(FileObject);
222 return(STATUS_INSUFFICIENT_RESOURCES);
225 Irp->AssociatedIrp.SystemBuffer = FsInformation;
226 KeResetEvent( &FileObject->Event );
227 Irp->UserEvent = &FileObject->Event;
228 Irp->UserIosb = &IoStatusBlock;
229 Irp->Tail.Overlay.Thread = PsGetCurrentThread();
231 StackPtr = IoGetNextIrpStackLocation(Irp);
232 StackPtr->MajorFunction = IRP_MJ_QUERY_VOLUME_INFORMATION;
233 StackPtr->MinorFunction = 0;
235 StackPtr->Control = 0;
236 StackPtr->DeviceObject = DeviceObject;
237 StackPtr->FileObject = FileObject;
238 StackPtr->Parameters.QueryVolume.Length = Length;
239 StackPtr->Parameters.QueryVolume.FsInformationClass =
242 Status = IoCallDriver(DeviceObject,
244 if (Status == STATUS_PENDING)
246 KeWaitForSingleObject(&FileObject->Event,
251 Status = IoStatusBlock.Status;
253 DPRINT("Status %x\n", Status);
255 if (ReturnedLength != NULL)
257 *ReturnedLength = IoStatusBlock.Information;
265 NtSetVolumeInformationFile(IN HANDLE FileHandle,
266 OUT PIO_STATUS_BLOCK IoStatusBlock,
267 IN PVOID FsInformation,
269 IN FS_INFORMATION_CLASS FsInformationClass)
271 PFILE_OBJECT FileObject;
272 PDEVICE_OBJECT DeviceObject;
275 PIO_STACK_LOCATION StackPtr;
277 IO_STATUS_BLOCK IoSB;
279 Status = ObReferenceObjectByHandle(FileHandle,
280 FILE_WRITE_ATTRIBUTES,
285 if (Status != STATUS_SUCCESS)
290 DeviceObject = FileObject->DeviceObject;
292 Irp = IoAllocateIrp(DeviceObject->StackSize,TRUE);
295 ObDereferenceObject(FileObject);
296 return(STATUS_INSUFFICIENT_RESOURCES);
299 SystemBuffer = ExAllocatePoolWithTag(NonPagedPool,
302 if (SystemBuffer == NULL)
305 ObDereferenceObject(FileObject);
306 return(STATUS_INSUFFICIENT_RESOURCES);
309 MmSafeCopyFromUser(SystemBuffer,
313 Irp->AssociatedIrp.SystemBuffer = SystemBuffer;
314 KeResetEvent( &FileObject->Event );
315 Irp->UserEvent = &FileObject->Event;
316 Irp->UserIosb = &IoSB;
317 Irp->Tail.Overlay.Thread = PsGetCurrentThread();
319 StackPtr = IoGetNextIrpStackLocation(Irp);
320 StackPtr->MajorFunction = IRP_MJ_SET_VOLUME_INFORMATION;
321 StackPtr->MinorFunction = 0;
323 StackPtr->Control = 0;
324 StackPtr->DeviceObject = DeviceObject;
325 StackPtr->FileObject = FileObject;
326 StackPtr->Parameters.SetVolume.Length = Length;
327 StackPtr->Parameters.SetVolume.FsInformationClass =
330 Status = IoCallDriver(DeviceObject,Irp);
331 if (Status == STATUS_PENDING)
333 KeWaitForSingleObject(&FileObject->Event,
338 Status = IoSB.Status;
342 *IoStatusBlock = IoSB;
344 ExFreePool(SystemBuffer);
351 IoAcquireVpbSpinLock(OUT PKIRQL Irql)
353 KeAcquireSpinLock(&IoVpbLock,
359 IoReleaseVpbSpinLock(IN KIRQL Irql)
361 KeReleaseSpinLock(&IoVpbLock,