ReactOS  0.4.14-dev-55-g2da92ac
volinfo.c
Go to the documentation of this file.
1 /*
2  * ReactOS kernel
3  * Copyright (C) 2002, 2014 ReactOS Team
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
18  *
19  * COPYRIGHT: See COPYING in the top level directory
20  * PROJECT: ReactOS kernel
21  * FILE: drivers/filesystem/ntfs/volume.c
22  * PURPOSE: NTFS filesystem driver
23  * PROGRAMMERS: Eric Kohl
24  * Pierre Schweitzer (pierre@reactos.org)
25  */
26 
27 /* INCLUDES *****************************************************************/
28 
29 #include "ntfs.h"
30 
31 #define NDEBUG
32 #include <debug.h>
33 
34 /* FUNCTIONS ****************************************************************/
35 
38 {
40  PFILE_RECORD_HEADER BitmapRecord;
41  PNTFS_ATTR_CONTEXT DataContext;
42  ULONGLONG BitmapDataSize;
45  ULONG Read = 0;
47 
48  DPRINT("NtfsGetFreeClusters(%p)\n", DeviceExt);
49 
50  BitmapRecord = ExAllocateFromNPagedLookasideList(&DeviceExt->FileRecLookasideList);
51  if (BitmapRecord == NULL)
52  {
53  return 0;
54  }
55 
56  Status = ReadFileRecord(DeviceExt, NTFS_FILE_BITMAP, BitmapRecord);
57  if (!NT_SUCCESS(Status))
58  {
59  ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, BitmapRecord);
60  return 0;
61  }
62 
63  Status = FindAttribute(DeviceExt, BitmapRecord, AttributeData, L"", 0, &DataContext, NULL);
64  if (!NT_SUCCESS(Status))
65  {
66  ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, BitmapRecord);
67  return 0;
68  }
69 
70  BitmapDataSize = AttributeDataLength(DataContext->pRecord);
71  ASSERT((BitmapDataSize * 8) >= DeviceExt->NtfsInfo.ClusterCount);
72  BitmapData = ExAllocatePoolWithTag(NonPagedPool, ROUND_UP(BitmapDataSize, DeviceExt->NtfsInfo.BytesPerSector), TAG_NTFS);
73  if (BitmapData == NULL)
74  {
75  ReleaseAttributeContext(DataContext);
76  ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, BitmapRecord);
77  return 0;
78  }
79 
80  /* FIXME: Totally underoptimized! */
81  for (; Read < BitmapDataSize; Read += DeviceExt->NtfsInfo.BytesPerSector)
82  {
83  ReadAttribute(DeviceExt, DataContext, Read, (PCHAR)((ULONG_PTR)BitmapData + Read), DeviceExt->NtfsInfo.BytesPerSector);
84  }
85  ReleaseAttributeContext(DataContext);
86 
87  DPRINT1("Total clusters: %I64x\n", DeviceExt->NtfsInfo.ClusterCount);
88  DPRINT1("Total clusters in bitmap: %I64x\n", BitmapDataSize * 8);
89  DPRINT1("Diff in size: %I64d B\n", ((BitmapDataSize * 8) - DeviceExt->NtfsInfo.ClusterCount) * DeviceExt->NtfsInfo.SectorsPerCluster * DeviceExt->NtfsInfo.BytesPerSector);
90 
91  RtlInitializeBitMap(&Bitmap, (PULONG)BitmapData, DeviceExt->NtfsInfo.ClusterCount);
93 
95  ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, BitmapRecord);
96 
97  return FreeClusters;
98 }
99 
104 NTSTATUS
106  ULONG FirstDesiredCluster,
107  ULONG DesiredClusters,
108  PULONG FirstAssignedCluster,
109  PULONG AssignedClusters)
110 {
112  PFILE_RECORD_HEADER BitmapRecord;
113  PNTFS_ATTR_CONTEXT DataContext;
114  ULONGLONG BitmapDataSize;
118  ULONG AssignedRun;
119  ULONG LengthWritten;
120 
121  DPRINT("NtfsAllocateClusters(%p, %lu, %lu, %p, %p)\n", DeviceExt, FirstDesiredCluster, DesiredClusters, FirstAssignedCluster, AssignedClusters);
122 
123  BitmapRecord = ExAllocateFromNPagedLookasideList(&DeviceExt->FileRecLookasideList);
124  if (BitmapRecord == NULL)
125  {
127  }
128 
129  Status = ReadFileRecord(DeviceExt, NTFS_FILE_BITMAP, BitmapRecord);
130  if (!NT_SUCCESS(Status))
131  {
132  ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, BitmapRecord);
133  return Status;
134  }
135 
136  Status = FindAttribute(DeviceExt, BitmapRecord, AttributeData, L"", 0, &DataContext, NULL);
137  if (!NT_SUCCESS(Status))
138  {
139  ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, BitmapRecord);
140  return Status;
141  }
142 
143  BitmapDataSize = AttributeDataLength(DataContext->pRecord);
144  BitmapDataSize = min(BitmapDataSize, 0xffffffff);
145  ASSERT((BitmapDataSize * 8) >= DeviceExt->NtfsInfo.ClusterCount);
146  BitmapData = ExAllocatePoolWithTag(NonPagedPool, ROUND_UP(BitmapDataSize, DeviceExt->NtfsInfo.BytesPerSector), TAG_NTFS);
147  if (BitmapData == NULL)
148  {
149  ReleaseAttributeContext(DataContext);
150  ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, BitmapRecord);
152  }
153 
154  DPRINT("Total clusters: %I64x\n", DeviceExt->NtfsInfo.ClusterCount);
155  DPRINT("Total clusters in bitmap: %I64x\n", BitmapDataSize * 8);
156  DPRINT("Diff in size: %I64d B\n", ((BitmapDataSize * 8) - DeviceExt->NtfsInfo.ClusterCount) * DeviceExt->NtfsInfo.SectorsPerCluster * DeviceExt->NtfsInfo.BytesPerSector);
157 
158  ReadAttribute(DeviceExt, DataContext, 0, (PCHAR)BitmapData, (ULONG)BitmapDataSize);
159 
160  RtlInitializeBitMap(&Bitmap, (PULONG)BitmapData, DeviceExt->NtfsInfo.ClusterCount);
162 
163  if (FreeClusters < DesiredClusters)
164  {
165  ReleaseAttributeContext(DataContext);
166 
168  ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, BitmapRecord);
169  return STATUS_DISK_FULL;
170  }
171 
172  // TODO: Observe MFT reservation zone
173 
174  // Can we get one contiguous run?
175  AssignedRun = RtlFindClearBitsAndSet(&Bitmap, DesiredClusters, FirstDesiredCluster);
176 
177  if (AssignedRun != 0xFFFFFFFF)
178  {
179  *FirstAssignedCluster = AssignedRun;
180  *AssignedClusters = DesiredClusters;
181  }
182  else
183  {
184  // we can't get one contiguous run
185  *AssignedClusters = RtlFindNextForwardRunClear(&Bitmap, FirstDesiredCluster, FirstAssignedCluster);
186 
187  if (*AssignedClusters == 0)
188  {
189  // we couldn't find any runs starting at DesiredFirstCluster
190  *AssignedClusters = RtlFindLongestRunClear(&Bitmap, FirstAssignedCluster);
191  }
192 
193  }
194 
195  Status = WriteAttribute(DeviceExt, DataContext, 0, BitmapData, (ULONG)BitmapDataSize, &LengthWritten, BitmapRecord);
196 
197  ReleaseAttributeContext(DataContext);
198 
200  ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, BitmapRecord);
201 
202  return Status;
203 }
204 
205 static
206 NTSTATUS
210 {
211  DPRINT("NtfsGetFsVolumeInformation() called\n");
212  DPRINT("FsVolumeInfo = %p\n", FsVolumeInfo);
213  DPRINT("BufferLength %lu\n", *BufferLength);
214 
215  DPRINT("Vpb %p\n", DeviceObject->Vpb);
216 
217  DPRINT("Required length %lu\n",
218  sizeof(FILE_FS_VOLUME_INFORMATION) + DeviceObject->Vpb->VolumeLabelLength);
219  DPRINT("LabelLength %hu\n",
220  DeviceObject->Vpb->VolumeLabelLength);
221  DPRINT("Label %.*S\n",
222  DeviceObject->Vpb->VolumeLabelLength / sizeof(WCHAR),
223  DeviceObject->Vpb->VolumeLabel);
224 
227 
228  if (*BufferLength < (sizeof(FILE_FS_VOLUME_INFORMATION) + DeviceObject->Vpb->VolumeLabelLength))
229  return STATUS_BUFFER_OVERFLOW;
230 
231  /* valid entries */
232  FsVolumeInfo->VolumeSerialNumber = DeviceObject->Vpb->SerialNumber;
233  FsVolumeInfo->VolumeLabelLength = DeviceObject->Vpb->VolumeLabelLength;
234  memcpy(FsVolumeInfo->VolumeLabel,
235  DeviceObject->Vpb->VolumeLabel,
236  DeviceObject->Vpb->VolumeLabelLength);
237 
238  /* dummy entries */
239  FsVolumeInfo->VolumeCreationTime.QuadPart = 0;
240  FsVolumeInfo->SupportsObjects = FALSE;
241 
242  *BufferLength -= (sizeof(FILE_FS_VOLUME_INFORMATION) + DeviceObject->Vpb->VolumeLabelLength);
243 
244  DPRINT("BufferLength %lu\n", *BufferLength);
245  DPRINT("NtfsGetFsVolumeInformation() done\n");
246 
247  return STATUS_SUCCESS;
248 }
249 
250 
251 static
252 NTSTATUS
254  PFILE_FS_ATTRIBUTE_INFORMATION FsAttributeInfo,
256 {
257  UNREFERENCED_PARAMETER(DeviceExt);
258 
259  DPRINT("NtfsGetFsAttributeInformation()\n");
260  DPRINT("FsAttributeInfo = %p\n", FsAttributeInfo);
261  DPRINT("BufferLength %lu\n", *BufferLength);
262  DPRINT("Required length %lu\n", (sizeof(FILE_FS_ATTRIBUTE_INFORMATION) + 8));
263 
266 
267  if (*BufferLength < (sizeof(FILE_FS_ATTRIBUTE_INFORMATION) + 8))
268  return STATUS_BUFFER_OVERFLOW;
269 
270  FsAttributeInfo->FileSystemAttributes =
272  FsAttributeInfo->MaximumComponentNameLength = 255;
273  FsAttributeInfo->FileSystemNameLength = 8;
274 
275  memcpy(FsAttributeInfo->FileSystemName, L"NTFS", 8);
276 
277  DPRINT("Finished NtfsGetFsAttributeInformation()\n");
278 
280  DPRINT("BufferLength %lu\n", *BufferLength);
281 
282  return STATUS_SUCCESS;
283 }
284 
285 
286 static
287 NTSTATUS
289  PFILE_FS_SIZE_INFORMATION FsSizeInfo,
291 {
292  PDEVICE_EXTENSION DeviceExt;
294 
295  DPRINT("NtfsGetFsSizeInformation()\n");
296  DPRINT("FsSizeInfo = %p\n", FsSizeInfo);
297 
298  if (*BufferLength < sizeof(FILE_FS_SIZE_INFORMATION))
299  return STATUS_BUFFER_OVERFLOW;
300 
301  DeviceExt = DeviceObject->DeviceExtension;
302 
303  FsSizeInfo->AvailableAllocationUnits.QuadPart = NtfsGetFreeClusters(DeviceExt);
304  FsSizeInfo->TotalAllocationUnits.QuadPart = DeviceExt->NtfsInfo.ClusterCount;
305  FsSizeInfo->SectorsPerAllocationUnit = DeviceExt->NtfsInfo.SectorsPerCluster;
306  FsSizeInfo->BytesPerSector = DeviceExt->NtfsInfo.BytesPerSector;
307 
308  DPRINT("Finished NtfsGetFsSizeInformation()\n");
309  if (NT_SUCCESS(Status))
311 
312  return Status;
313 }
314 
315 
316 static
317 NTSTATUS
319  PFILE_FS_DEVICE_INFORMATION FsDeviceInfo,
321 {
322  DPRINT("NtfsGetFsDeviceInformation()\n");
323  DPRINT("FsDeviceInfo = %p\n", FsDeviceInfo);
324  DPRINT("BufferLength %lu\n", *BufferLength);
325  DPRINT("Required length %lu\n", sizeof(FILE_FS_DEVICE_INFORMATION));
326 
328  return STATUS_BUFFER_OVERFLOW;
329 
330  FsDeviceInfo->DeviceType = FILE_DEVICE_DISK;
331  FsDeviceInfo->Characteristics = DeviceObject->Characteristics;
332 
333  DPRINT("NtfsGetFsDeviceInformation() finished.\n");
334 
336  DPRINT("BufferLength %lu\n", *BufferLength);
337 
338  return STATUS_SUCCESS;
339 }
340 
341 
342 NTSTATUS
344 {
345  PIRP Irp;
348  PIO_STACK_LOCATION Stack;
350  PVOID SystemBuffer;
352  PDEVICE_EXTENSION DeviceExt;
353 
354  DPRINT("NtfsQueryVolumeInformation() called\n");
355 
356  ASSERT(IrpContext);
357 
358  Irp = IrpContext->Irp;
359  DeviceObject = IrpContext->DeviceObject;
360  DeviceExt = DeviceObject->DeviceExtension;
361  Stack = IrpContext->Stack;
362 
363  if (!ExAcquireResourceSharedLite(&DeviceExt->DirResource,
364  BooleanFlagOn(IrpContext->Flags, IRPCONTEXT_CANWAIT)))
365  {
366  return NtfsMarkIrpContextForQueue(IrpContext);
367  }
368 
369  FsInformationClass = Stack->Parameters.QueryVolume.FsInformationClass;
370  BufferLength = Stack->Parameters.QueryVolume.Length;
371  SystemBuffer = Irp->AssociatedIrp.SystemBuffer;
372  RtlZeroMemory(SystemBuffer, BufferLength);
373 
374  DPRINT("FsInformationClass %d\n", FsInformationClass);
375  DPRINT("SystemBuffer %p\n", SystemBuffer);
376 
377  switch (FsInformationClass)
378  {
381  SystemBuffer,
382  &BufferLength);
383  break;
384 
387  SystemBuffer,
388  &BufferLength);
389  break;
390 
393  SystemBuffer,
394  &BufferLength);
395  break;
396 
399  SystemBuffer,
400  &BufferLength);
401  break;
402 
403  default:
405  }
406 
407  ExReleaseResourceLite(&DeviceExt->DirResource);
408 
409  if (NT_SUCCESS(Status))
410  Irp->IoStatus.Information =
411  Stack->Parameters.QueryVolume.Length - BufferLength;
412  else
413  Irp->IoStatus.Information = 0;
414 
415  return Status;
416 }
417 
418 
419 NTSTATUS
421 {
422  PIRP Irp;
423 
424  DPRINT("NtfsSetVolumeInformation() called\n");
425 
426  ASSERT(IrpContext);
427 
428  Irp = IrpContext->Irp;
429  Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;
430  Irp->IoStatus.Information = 0;
431 
432  return STATUS_NOT_SUPPORTED;
433 }
434 
435 /* EOF */
signed char * PCHAR
Definition: retypes.h:7
LARGE_INTEGER TotalAllocationUnits
Definition: from_kernel.h:263
#define FILE_DEVICE_DISK
Definition: winioctl.h:112
_In_ BOOLEAN Read
Definition: strmini.h:479
PDEVICE_OBJECT DeviceObject
Definition: ntfs.h:484
_Must_inspect_result_ _In_ PFILE_OBJECT _In_ ULONG _In_ FS_INFORMATION_CLASS FsInformationClass
Definition: fltkernel.h:1329
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
NTSYSAPI void WINAPI RtlInitializeBitMap(PRTL_BITMAP, PULONG, ULONG)
#define ROUND_UP(n, align)
Definition: eventvwr.h:31
#define STATUS_INFO_LENGTH_MISMATCH
Definition: udferr_usr.h:133
NTSYSAPI ULONG WINAPI RtlFindLongestRunClear(PCRTL_BITMAP, PULONG)
#define NTFS_FILE_BITMAP
Definition: ntfs.h:29
PIO_STACK_LOCATION Stack
Definition: ntfs.h:478
static NTSTATUS NtfsGetFsAttributeInformation(PDEVICE_EXTENSION DeviceExt, PFILE_FS_ATTRIBUTE_INFORMATION FsAttributeInfo, PULONG BufferLength)
Definition: volinfo.c:253
_In_ PIRP Irp
Definition: csq.h:116
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:323
#define BooleanFlagOn(F, SF)
Definition: ext2fs.h:183
FORCEINLINE NTSTATUS NtfsMarkIrpContextForQueue(PNTFS_IRP_CONTEXT IrpContext)
Definition: ntfs.h:565
NTSTATUS FreeClusters(PNTFS_VCB Vcb, PNTFS_ATTR_CONTEXT AttrContext, ULONG AttrOffset, PFILE_RECORD_HEADER FileRecord, ULONG ClustersToFree)
Definition: attrib.c:1057
unsigned char * PUCHAR
Definition: retypes.h:3
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS NtfsAllocateClusters(PDEVICE_EXTENSION DeviceExt, ULONG FirstDesiredCluster, ULONG DesiredClusters, PULONG FirstAssignedCluster, PULONG AssignedClusters)
Definition: volinfo.c:105
NTSTATUS FindAttribute(PDEVICE_EXTENSION Vcb, PFILE_RECORD_HEADER MftRecord, ULONG Type, PCWSTR Name, ULONG NameLength, PNTFS_ATTR_CONTEXT *AttrCtx, PULONG Offset)
Definition: mft.c:131
struct _FILE_FS_ATTRIBUTE_INFORMATION FILE_FS_ATTRIBUTE_INFORMATION
static NTSTATUS NtfsGetFsSizeInformation(PDEVICE_OBJECT DeviceObject, PFILE_FS_SIZE_INFORMATION FsSizeInfo, PULONG BufferLength)
Definition: volinfo.c:288
uint32_t ULONG_PTR
Definition: typedefs.h:63
_In_ ULONG BufferLength
Definition: usbdlib.h:225
LARGE_INTEGER AvailableAllocationUnits
Definition: from_kernel.h:264
NTSYSAPI ULONG WINAPI RtlFindNextForwardRunClear(PCRTL_BITMAP, ULONG, PULONG)
PVOID DeviceExtension
Definition: env_spec_w32.h:418
smooth NULL
Definition: ftsmooth.c:416
#define IRPCONTEXT_CANWAIT
Definition: vfat.h:569
static FsInfoType * FsVolumeInfo(char *fpath)
Definition: disk.c:974
NTSYSAPI ULONG WINAPI RtlNumberOfClearBits(PCRTL_BITMAP)
void DPRINT(...)
Definition: polytest.cpp:61
enum _FSINFOCLASS FS_INFORMATION_CLASS
#define FILE_UNICODE_ON_DISK
Definition: from_kernel.h:235
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
uint64_t ULONGLONG
Definition: typedefs.h:65
struct BitmapData BitmapData
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1817
#define TAG_NTFS
Definition: ntfs.h:12
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
NTSTATUS WriteAttribute(PDEVICE_EXTENSION Vcb, PNTFS_ATTR_CONTEXT Context, ULONGLONG Offset, const PUCHAR Buffer, ULONG Length, PULONG RealLengthWritten, PFILE_RECORD_HEADER FileRecord)
Definition: mft.c:1315
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
static const WCHAR L[]
Definition: oid.c:1250
struct _FILE_FS_DEVICE_INFORMATION FILE_FS_DEVICE_INFORMATION
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
ULONG Flags
Definition: ntfs.h:477
#define FILE_CASE_PRESERVED_NAMES
Definition: from_kernel.h:234
NTSYSAPI ULONG WINAPI RtlFindClearBitsAndSet(PRTL_BITMAP, ULONG, ULONG)
Status
Definition: gdiplustypes.h:24
struct _FILE_FS_SIZE_INFORMATION FILE_FS_SIZE_INFORMATION
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:61
NTSTATUS ReadFileRecord(PDEVICE_EXTENSION Vcb, ULONGLONG index, PFILE_RECORD_HEADER file)
Definition: mft.c:1631
VOID ReleaseAttributeContext(PNTFS_ATTR_CONTEXT Context)
Definition: mft.c:104
unsigned int * PULONG
Definition: retypes.h:1
ULONG ReadAttribute(PDEVICE_EXTENSION Vcb, PNTFS_ATTR_CONTEXT Context, ULONGLONG Offset, PCHAR Buffer, ULONG Length)
Definition: mft.c:1065
#define min(a, b)
Definition: monoChain.cc:55
static NTSTATUS NtfsGetFsVolumeInformation(PDEVICE_OBJECT DeviceObject, PFILE_FS_VOLUME_INFORMATION FsVolumeInfo, PULONG BufferLength)
Definition: volinfo.c:207
BOOLEAN NTAPI ExAcquireResourceSharedLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:885
#define DPRINT1
Definition: precomp.h:8
ULONGLONG NtfsGetFreeClusters(PDEVICE_EXTENSION DeviceExt)
Definition: volinfo.c:37
struct _FILE_FS_VOLUME_INFORMATION FILE_FS_VOLUME_INFORMATION
#define STATUS_DISK_FULL
Definition: udferr_usr.h:155
NTSTATUS NtfsQueryVolumeInformation(PNTFS_IRP_CONTEXT IrpContext)
Definition: volinfo.c:343
#define STATUS_NOT_SUPPORTED
Definition: ntstatus.h:409
unsigned int ULONG
Definition: retypes.h:1
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
NTSTATUS NtfsSetVolumeInformation(PNTFS_IRP_CONTEXT IrpContext)
Definition: volinfo.c:420
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
#define FILE_READ_ONLY_VOLUME
Definition: from_kernel.h:246
struct _NAMED_PIPE_CREATE_PARAMETERS * Parameters
Definition: iotypes.h:2772
return STATUS_SUCCESS
Definition: btrfs.c:2966
ULONGLONG AttributeDataLength(PNTFS_ATTR_RECORD AttrRecord)
Definition: mft.c:259
LONGLONG QuadPart
Definition: typedefs.h:112
static NTSTATUS NtfsGetFsDeviceInformation(PDEVICE_OBJECT DeviceObject, PFILE_FS_DEVICE_INFORMATION FsDeviceInfo, PULONG BufferLength)
Definition: volinfo.c:318