1 /* $Id: vpb.c,v 1.19 2002/09/08 10:23:26 chorns 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
;
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
,