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);
70 NtQueryVolumeInformationFile(IN HANDLE FileHandle,
71 OUT PIO_STATUS_BLOCK IoStatusBlock,
72 OUT PVOID FsInformation,
74 IN FS_INFORMATION_CLASS FsInformationClass)
77 * FUNCTION: Queries the volume information
79 * FileHandle = Handle to a file object on the target volume
80 * ReturnLength = DataWritten
81 * FsInformation = Caller should supply storage for the information
83 * Length = Size of the information structure
84 * FsInformationClass = Index to a information structure
86 * FileFsVolumeInformation FILE_FS_VOLUME_INFORMATION
87 * FileFsLabelInformation FILE_FS_LABEL_INFORMATION
88 * FileFsSizeInformation FILE_FS_SIZE_INFORMATION
89 * FileFsDeviceInformation FILE_FS_DEVICE_INFORMATION
90 * FileFsAttributeInformation FILE_FS_ATTRIBUTE_INFORMATION
91 * FileFsControlInformation
92 * FileFsQuotaQueryInformation --
93 * FileFsQuotaSetInformation --
94 * FileFsMaximumInformation
99 PFILE_OBJECT FileObject;
100 PDEVICE_OBJECT DeviceObject;
103 PIO_STACK_LOCATION StackPtr;
105 IO_STATUS_BLOCK IoSB;
107 assert(IoStatusBlock != NULL);
108 assert(FsInformation != NULL);
110 DPRINT("FsInformation %p\n", FsInformation);
112 Status = ObReferenceObjectByHandle(FileHandle,
113 FILE_READ_ATTRIBUTES,
118 if (!NT_SUCCESS(Status))
123 DeviceObject = FileObject->DeviceObject;
125 Irp = IoAllocateIrp(DeviceObject->StackSize,
129 ObDereferenceObject(FileObject);
130 return(STATUS_INSUFFICIENT_RESOURCES);
133 SystemBuffer = ExAllocatePoolWithTag(NonPagedPool,
136 if (SystemBuffer == NULL)
139 ObDereferenceObject(FileObject);
140 return(STATUS_INSUFFICIENT_RESOURCES);
143 Irp->AssociatedIrp.SystemBuffer = SystemBuffer;
144 KeResetEvent( &FileObject->Event );
145 Irp->UserEvent = &FileObject->Event;
146 Irp->UserIosb = &IoSB;
147 Irp->Tail.Overlay.Thread = PsGetCurrentThread();
149 StackPtr = IoGetNextIrpStackLocation(Irp);
150 StackPtr->MajorFunction = IRP_MJ_QUERY_VOLUME_INFORMATION;
151 StackPtr->MinorFunction = 0;
153 StackPtr->Control = 0;
154 StackPtr->DeviceObject = DeviceObject;
155 StackPtr->FileObject = FileObject;
156 StackPtr->Parameters.QueryVolume.Length = Length;
157 StackPtr->Parameters.QueryVolume.FsInformationClass =
160 Status = IoCallDriver(DeviceObject,
162 if (Status == STATUS_PENDING)
164 KeWaitForSingleObject(&FileObject->Event,
169 Status = IoSB.Status;
171 DPRINT("Status %x\n", Status);
173 if (NT_SUCCESS(Status))
175 DPRINT("Information %lu\n", IoStatusBlock->Information);
176 MmSafeCopyToUser(FsInformation,
182 *IoStatusBlock = IoSB;
184 ExFreePool(SystemBuffer);
191 IoQueryVolumeInformation(IN PFILE_OBJECT FileObject,
192 IN FS_INFORMATION_CLASS FsInformationClass,
194 OUT PVOID FsInformation,
195 OUT PULONG ReturnedLength)
197 IO_STATUS_BLOCK IoStatusBlock;
198 PIO_STACK_LOCATION StackPtr;
199 PDEVICE_OBJECT DeviceObject;
203 assert(FsInformation != NULL);
205 DPRINT("FsInformation %p\n", FsInformation);
207 Status = ObReferenceObjectByPointer(FileObject,
208 FILE_READ_ATTRIBUTES,
211 if (!NT_SUCCESS(Status))
216 DeviceObject = FileObject->DeviceObject;
218 Irp = IoAllocateIrp(DeviceObject->StackSize,
222 ObDereferenceObject(FileObject);
223 return(STATUS_INSUFFICIENT_RESOURCES);
226 Irp->AssociatedIrp.SystemBuffer = FsInformation;
227 KeResetEvent( &FileObject->Event );
228 Irp->UserEvent = &FileObject->Event;
229 Irp->UserIosb = &IoStatusBlock;
230 Irp->Tail.Overlay.Thread = PsGetCurrentThread();
232 StackPtr = IoGetNextIrpStackLocation(Irp);
233 StackPtr->MajorFunction = IRP_MJ_QUERY_VOLUME_INFORMATION;
234 StackPtr->MinorFunction = 0;
236 StackPtr->Control = 0;
237 StackPtr->DeviceObject = DeviceObject;
238 StackPtr->FileObject = FileObject;
239 StackPtr->Parameters.QueryVolume.Length = Length;
240 StackPtr->Parameters.QueryVolume.FsInformationClass =
243 Status = IoCallDriver(DeviceObject,
245 if (Status == STATUS_PENDING)
247 KeWaitForSingleObject(&FileObject->Event,
252 Status = IoStatusBlock.Status;
254 DPRINT("Status %x\n", Status);
256 if (ReturnedLength != NULL)
258 *ReturnedLength = IoStatusBlock.Information;
266 NtSetVolumeInformationFile(IN HANDLE FileHandle,
267 OUT PIO_STATUS_BLOCK IoStatusBlock,
268 IN PVOID FsInformation,
270 IN FS_INFORMATION_CLASS FsInformationClass)
272 PFILE_OBJECT FileObject;
273 PDEVICE_OBJECT DeviceObject;
276 PIO_STACK_LOCATION StackPtr;
278 IO_STATUS_BLOCK IoSB;
280 Status = ObReferenceObjectByHandle(FileHandle,
281 FILE_WRITE_ATTRIBUTES,
286 if (Status != STATUS_SUCCESS)
291 DeviceObject = FileObject->DeviceObject;
293 Irp = IoAllocateIrp(DeviceObject->StackSize,TRUE);
296 ObDereferenceObject(FileObject);
297 return(STATUS_INSUFFICIENT_RESOURCES);
300 SystemBuffer = ExAllocatePoolWithTag(NonPagedPool,
303 if (SystemBuffer == NULL)
306 ObDereferenceObject(FileObject);
307 return(STATUS_INSUFFICIENT_RESOURCES);
310 MmSafeCopyFromUser(SystemBuffer,
314 Irp->AssociatedIrp.SystemBuffer = SystemBuffer;
315 KeResetEvent( &FileObject->Event );
316 Irp->UserEvent = &FileObject->Event;
317 Irp->UserIosb = &IoSB;
318 Irp->Tail.Overlay.Thread = PsGetCurrentThread();
320 StackPtr = IoGetNextIrpStackLocation(Irp);
321 StackPtr->MajorFunction = IRP_MJ_SET_VOLUME_INFORMATION;
322 StackPtr->MinorFunction = 0;
324 StackPtr->Control = 0;
325 StackPtr->DeviceObject = DeviceObject;
326 StackPtr->FileObject = FileObject;
327 StackPtr->Parameters.SetVolume.Length = Length;
328 StackPtr->Parameters.SetVolume.FsInformationClass =
331 Status = IoCallDriver(DeviceObject,Irp);
332 if (Status == STATUS_PENDING)
334 KeWaitForSingleObject(&FileObject->Event,
339 Status = IoSB.Status;
343 *IoStatusBlock = IoSB;
345 ExFreePool(SystemBuffer);
352 IoAcquireVpbSpinLock(OUT PKIRQL Irql)
354 KeAcquireSpinLock(&IoVpbLock,
360 IoReleaseVpbSpinLock(IN KIRQL Irql)
362 KeReleaseSpinLock(&IoVpbLock,
366 #endif /* LIBCAPTIVE */