Merged mingw32 branch into main trunk
[reactos.git] / reactos / ntoskrnl / io / vpb.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: ntoskrnl/io/vpb.c
5 * PURPOSE: Volume Parameter Block managment
6 * PROGRAMMER: David Welch (welch@mcmail.com)
7 * UPDATE HISTORY:
8 * Created 22/05/98
9 */
10
11 /* INCLUDES *****************************************************************/
12
13 #include <ddk/ntddk.h>
14 #include <string.h>
15 #include <internal/string.h>
16 #include <internal/ob.h>
17
18 #include <internal/debug.h>
19
20 /* FUNCTIONS *****************************************************************/
21
22 NTSTATUS IoAttachVpb(PDEVICE_OBJECT DeviceObject)
23 {
24 PVPB Vpb;
25
26 Vpb = ExAllocatePool(NonPagedPool,sizeof(VPB));
27 if (Vpb==NULL)
28 {
29 return(STATUS_UNSUCCESSFUL);
30 }
31
32 Vpb->Type = 0;
33 Vpb->Size = sizeof(VPB) / sizeof(DWORD);
34 Vpb->Flags = 0;
35 Vpb->VolumeLabelLength = 0;
36 Vpb->DeviceObject = NULL;
37 Vpb->RealDevice = DeviceObject;
38 Vpb->SerialNumber = 0;
39 Vpb->ReferenceCount = 0;
40 RtlZeroMemory(Vpb->VolumeLabel,sizeof(WCHAR)*MAXIMUM_VOLUME_LABEL_LENGTH);
41
42 DeviceObject->Vpb = Vpb;
43 }
44
45 PIRP IoBuildVolumeInformationIrp(ULONG MajorFunction,
46 PFILE_OBJECT FileObject,
47 PVOID FSInformation,
48 ULONG Length,
49 CINT FSInformationClass,
50 PIO_STATUS_BLOCK IoStatusBlock,
51 PKEVENT Event)
52 {
53 PIRP Irp;
54 PIO_STACK_LOCATION StackPtr;
55 PDEVICE_OBJECT DeviceObject;
56
57 DeviceObject = FileObject->DeviceObject;
58
59 Irp = IoAllocateIrp(DeviceObject->StackSize,TRUE);
60 if (Irp==NULL)
61 {
62 return(NULL);
63 }
64
65 Irp->AssociatedIrp.SystemBuffer = FSInformation;
66
67 StackPtr = IoGetNextIrpStackLocation(Irp);
68 StackPtr->MajorFunction = MajorFunction;
69 StackPtr->MinorFunction = 0;
70 StackPtr->Flags = 0;
71 StackPtr->Control = 0;
72 StackPtr->DeviceObject = DeviceObject;
73 StackPtr->FileObject = FileObject;
74 Irp->UserEvent = Event;
75 Irp->UserIosb = IoStatusBlock;
76
77 if (MajorFunction == IRP_MJ_QUERY_VOLUME_INFORMATION)
78 {
79 StackPtr->Parameters.SetVolume.Length = Length;
80 StackPtr->Parameters.SetVolume.FileInformationClass =
81 FSInformationClass;
82 }
83 else
84 {
85 StackPtr->Parameters.QueryVolume.Length = Length;
86 StackPtr->Parameters.QueryVolume.FileInformationClass =
87 FSInformationClass;
88 }
89 return(Irp);
90 }
91
92 NTSTATUS STDCALL NtQueryVolumeInformationFile(
93 IN HANDLE FileHandle,
94 OUT PIO_STATUS_BLOCK IoStatusBlock,
95 OUT PVOID FSInformation,
96 IN ULONG Length,
97 IN FS_INFORMATION_CLASS FSInformationClass)
98
99 /*
100 * FUNCTION: Queries the volume information
101 * ARGUMENTS:
102 * FileHandle = Handle to a file object on the target volume
103 * ReturnLength = DataWritten
104 * FSInformation = Caller should supply storage for the information
105 * structure.
106 * Length = Size of the information structure
107 * FSInformationClass = Index to a information structure
108 *
109 * FileFsVolumeInformation FILE_FS_VOLUME_INFORMATION
110 * FileFsLabelInformation FILE_FS_LABEL_INFORMATION
111 * FileFsSizeInformation FILE_FS_SIZE_INFORMATION
112 * FileFsDeviceInformation FILE_FS_DEVICE_INFORMATION
113 * FileFsAttributeInformation FILE_FS_ATTRIBUTE_INFORMATION
114 * FileFsControlInformation
115 * FileFsQuotaQueryInformation --
116 * FileFsQuotaSetInformation --
117 * FileFsMaximumInformation
118 *
119 * RETURNS: Status
120 */
121 {
122 return(ZwQueryVolumeInformationFile(FileHandle,IoStatusBlock,FSInformation,
123 Length,FSInformationClass));
124 }
125
126 NTSTATUS
127 STDCALL
128 ZwQueryVolumeInformationFile(
129 IN HANDLE FileHandle,
130 OUT PIO_STATUS_BLOCK IoStatusBlock,
131 OUT PVOID FSInformation,
132 IN ULONG Length,
133 IN FS_INFORMATION_CLASS FSInformationClass)
134 {
135 PFILE_OBJECT FileObject;
136 PDEVICE_OBJECT DeviceObject;
137 PIRP Irp;
138 KEVENT Event;
139 NTSTATUS Status;
140
141 Status = ObReferenceObjectByHandle(FileHandle,
142 FILE_READ_ATTRIBUTES,
143 NULL,
144 UserMode,
145 (PVOID*)&FileObject,
146 NULL);
147 if (Status != STATUS_SUCCESS)
148 {
149 return(Status);
150 }
151
152 DeviceObject = FileObject->DeviceObject;
153
154 KeInitializeEvent(&Event,NotificationEvent,FALSE);
155
156 Irp = IoBuildVolumeInformationIrp(IRP_MJ_QUERY_VOLUME_INFORMATION,
157 FileObject,
158 FSInformation,
159 Length,
160 FSInformationClass,
161 IoStatusBlock,
162 &Event);
163 Status = IoCallDriver(DeviceObject,Irp);
164 if (Status == STATUS_PENDING)
165 {
166 KeWaitForSingleObject(&Event,UserRequest,KernelMode,FALSE,NULL);
167 Status = IoStatusBlock->Status;
168 }
169 return(Status);
170 }
171
172 NTSTATUS
173 STDCALL
174 NtSetVolumeInformationFile(
175 IN HANDLE FileHandle,
176 IN CINT VolumeInformationClass,
177 PVOID VolumeInformation,
178 ULONG Length
179 )
180 {
181 return(ZwSetVolumeInformationFile(FileHandle,VolumeInformationClass,
182 VolumeInformation,Length));
183 }
184
185 NTSTATUS
186 STDCALL
187 ZwSetVolumeInformationFile(
188 IN HANDLE FileHandle,
189 IN CINT VolumeInformationClass,
190 PVOID VolumeInformation,
191 ULONG Length
192 )
193 {
194
195 PFILE_OBJECT FileObject;
196 PDEVICE_OBJECT DeviceObject;
197 PIRP Irp;
198 KEVENT Event;
199 NTSTATUS Status;
200
201 Status = ObReferenceObjectByHandle(FileHandle,
202 FILE_WRITE_ATTRIBUTES,
203 NULL,
204 UserMode,
205 (PVOID*)&FileObject,
206 NULL);
207 if (Status != STATUS_SUCCESS)
208 {
209 return(Status);
210 }
211
212 DeviceObject = FileObject->DeviceObject;
213
214 KeInitializeEvent(&Event,NotificationEvent,FALSE);
215
216 Irp = IoBuildVolumeInformationIrp(IRP_MJ_SET_VOLUME_INFORMATION,
217 FileObject,
218 VolumeInformation,
219 Length,
220 VolumeInformationClass,
221 NULL,
222 &Event);
223 Status = IoCallDriver(DeviceObject,Irp);
224 if (Status == STATUS_PENDING)
225 {
226 KeWaitForSingleObject(&Event,UserRequest,KernelMode,FALSE,NULL);
227 }
228 return(Status);
229 }