1 /* $Id: vpb.c,v 1.14 2001/11/02 22:22:33 hbirr Exp $
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
;
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 KeInitializeEvent(&Event
,
129 Irp
= IoAllocateIrp(DeviceObject
->StackSize
,
133 ObDereferenceObject(FileObject
);
134 return(STATUS_INSUFFICIENT_RESOURCES
);
137 SystemBuffer
= ExAllocatePoolWithTag(NonPagedPool
,
140 if (SystemBuffer
== NULL
)
143 ObDereferenceObject(FileObject
);
144 return(STATUS_INSUFFICIENT_RESOURCES
);
147 Irp
->AssociatedIrp
.SystemBuffer
= SystemBuffer
;
148 Irp
->UserEvent
= &Event
;
149 Irp
->UserIosb
= &IoSB
;
150 Irp
->Tail
.Overlay
.Thread
= PsGetCurrentThread();
152 StackPtr
= IoGetNextIrpStackLocation(Irp
);
153 StackPtr
->MajorFunction
= IRP_MJ_QUERY_VOLUME_INFORMATION
;
154 StackPtr
->MinorFunction
= 0;
156 StackPtr
->Control
= 0;
157 StackPtr
->DeviceObject
= DeviceObject
;
158 StackPtr
->FileObject
= FileObject
;
159 StackPtr
->Parameters
.QueryVolume
.Length
= Length
;
160 StackPtr
->Parameters
.QueryVolume
.FsInformationClass
=
163 Status
= IoCallDriver(DeviceObject
,
165 if (Status
== STATUS_PENDING
)
167 KeWaitForSingleObject(&Event
,
172 Status
= IoSB
.Status
;
174 DPRINT("Status %x\n", Status
);
176 if (NT_SUCCESS(Status
))
178 DPRINT("Information %lu\n", IoStatusBlock
->Information
);
179 MmSafeCopyToUser(FsInformation
,
185 *IoStatusBlock
= IoSB
;
187 ExFreePool(SystemBuffer
);
188 ObDereferenceObject(FileObject
);
195 IoQueryVolumeInformation(IN PFILE_OBJECT FileObject
,
196 IN FS_INFORMATION_CLASS FsInformationClass
,
198 OUT PVOID FsInformation
,
199 OUT PULONG ReturnedLength
)
201 IO_STATUS_BLOCK IoStatusBlock
;
202 PIO_STACK_LOCATION StackPtr
;
203 PDEVICE_OBJECT DeviceObject
;
208 assert(FsInformation
!= NULL
);
210 DPRINT("FsInformation %p\n", FsInformation
);
212 Status
= ObReferenceObjectByPointer(FileObject
,
213 FILE_READ_ATTRIBUTES
,
216 if (!NT_SUCCESS(Status
))
221 DeviceObject
= FileObject
->DeviceObject
;
223 KeInitializeEvent(&Event
,
227 Irp
= IoAllocateIrp(DeviceObject
->StackSize
,
231 ObDereferenceObject(FileObject
);
232 return(STATUS_INSUFFICIENT_RESOURCES
);
235 Irp
->AssociatedIrp
.SystemBuffer
= FsInformation
;
236 Irp
->UserEvent
= &Event
;
237 Irp
->UserIosb
= &IoStatusBlock
;
238 Irp
->Tail
.Overlay
.Thread
= PsGetCurrentThread();
240 StackPtr
= IoGetNextIrpStackLocation(Irp
);
241 StackPtr
->MajorFunction
= IRP_MJ_QUERY_VOLUME_INFORMATION
;
242 StackPtr
->MinorFunction
= 0;
244 StackPtr
->Control
= 0;
245 StackPtr
->DeviceObject
= DeviceObject
;
246 StackPtr
->FileObject
= FileObject
;
247 StackPtr
->Parameters
.QueryVolume
.Length
= Length
;
248 StackPtr
->Parameters
.QueryVolume
.FsInformationClass
=
251 Status
= IoCallDriver(DeviceObject
,
253 if (Status
== STATUS_PENDING
)
255 KeWaitForSingleObject(&Event
,
260 Status
= IoStatusBlock
.Status
;
262 DPRINT("Status %x\n", Status
);
264 if (ReturnedLength
!= NULL
)
266 *ReturnedLength
= IoStatusBlock
.Information
;
268 ObDereferenceObject(FileObject
);
275 NtSetVolumeInformationFile(IN HANDLE FileHandle
,
276 OUT PIO_STATUS_BLOCK IoStatusBlock
,
277 IN PVOID FsInformation
,
279 IN FS_INFORMATION_CLASS FsInformationClass
)
281 PFILE_OBJECT FileObject
;
282 PDEVICE_OBJECT DeviceObject
;
286 PIO_STACK_LOCATION StackPtr
;
288 IO_STATUS_BLOCK IoSB
;
290 Status
= ObReferenceObjectByHandle(FileHandle
,
291 FILE_WRITE_ATTRIBUTES
,
296 if (Status
!= STATUS_SUCCESS
)
301 DeviceObject
= FileObject
->DeviceObject
;
303 KeInitializeEvent(&Event
,
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 Irp
->AssociatedIrp
.SystemBuffer
= SystemBuffer
;
329 Irp
->UserEvent
= &Event
;
330 Irp
->UserIosb
= &IoSB
;
331 Irp
->Tail
.Overlay
.Thread
= PsGetCurrentThread();
333 StackPtr
= IoGetNextIrpStackLocation(Irp
);
334 StackPtr
->MajorFunction
= IRP_MJ_SET_VOLUME_INFORMATION
;
335 StackPtr
->MinorFunction
= 0;
337 StackPtr
->Control
= 0;
338 StackPtr
->DeviceObject
= DeviceObject
;
339 StackPtr
->FileObject
= FileObject
;
340 StackPtr
->Parameters
.SetVolume
.Length
= Length
;
341 StackPtr
->Parameters
.SetVolume
.FsInformationClass
=
344 Status
= IoCallDriver(DeviceObject
,Irp
);
345 if (Status
== STATUS_PENDING
)
347 KeWaitForSingleObject(&Event
,
352 Status
= IoSB
.Status
;
356 *IoStatusBlock
= IoSB
;
358 ExFreePool(SystemBuffer
);
365 IoAcquireVpbSpinLock(OUT PKIRQL Irql
)
367 KeAcquireSpinLock(&IoVpbLock
,
373 IoReleaseVpbSpinLock(IN KIRQL Irql
)
375 KeReleaseSpinLock(&IoVpbLock
,
381 IoVerifyVolume(IN PDEVICE_OBJECT DeviceObject
,
382 IN BOOLEAN AllowRawMount
)
385 return(STATUS_NOT_IMPLEMENTED
);