2 * Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC.
3 * Copyright (c) 2009, 2010, 2011 Your File System, Inc.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * - Redistributions of source code must retain the above copyright notice,
11 * this list of conditions and the following disclaimer.
12 * - Redistributions in binary form must reproduce the above copyright
14 * this list of conditions and the following disclaimer in the
16 * and/or other materials provided with the distribution.
17 * - Neither the names of Kernel Drivers, LLC and Your File System, Inc.
18 * nor the names of their contributors may be used to endorse or promote
19 * products derived from this software without specific prior written
20 * permission from Kernel Drivers, LLC and Your File System, Inc.
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
24 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
25 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
26 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 // File: AFSVolumeInfo.cpp
39 #include "AFSCommon.h"
42 AFSQueryVolumeInfo( IN PDEVICE_OBJECT LibDeviceObject,
46 UNREFERENCED_PARAMETER(LibDeviceObject);
47 NTSTATUS ntStatus = STATUS_SUCCESS;
48 IO_STACK_LOCATION *pIrpSp;
49 FS_INFORMATION_CLASS FsInformationClass = FileFsMaximumInformation;
52 BOOLEAN bReleaseResource = FALSE;
53 PFILE_OBJECT pFileObject = NULL;
55 AFSObjectInfoCB *pObjectInfo = NULL;
56 AFSVolumeCB *pVolumeCB = NULL;
57 BOOLEAN bDosDevice = FALSE;
59 pIrpSp = IoGetCurrentIrpStackLocation( Irp);
64 pFileObject = pIrpSp->FileObject;
66 if( pFileObject == NULL)
69 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
70 AFS_TRACE_LEVEL_ERROR,
71 "AFSQueryVolumeInfo Failing request with NULL FileObject\n"));
73 try_return( ntStatus = STATUS_INVALID_DEVICE_REQUEST);
76 pFcb = (AFSFcb *)pFileObject->FsContext;
81 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
82 AFS_TRACE_LEVEL_ERROR,
83 "AFSQueryVolumeInfo Failing request with NULL Fcb\n"));
85 try_return( ntStatus = STATUS_INVALID_DEVICE_REQUEST);
88 pObjectInfo = pFcb->ObjectInformation;
90 if( pObjectInfo == NULL)
93 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
94 AFS_TRACE_LEVEL_ERROR,
95 "AFSQueryVolumeInfo Failing request with NULL ObjectInformation\n"));
97 try_return( ntStatus = STATUS_INVALID_DEVICE_REQUEST);
100 bDosDevice = pFileObject->FileName.Length > 4 * sizeof( WCHAR) &&
101 pFileObject->FileName.Buffer[0] == L'\\' &&
102 pFileObject->FileName.Buffer[1] == L';' &&
103 pFileObject->FileName.Buffer[3] == L':';
105 pVolumeCB = pObjectInfo->VolumeCB;
107 ulLength = pIrpSp->Parameters.QueryVolume.Length;
108 FsInformationClass = pIrpSp->Parameters.QueryVolume.FsInformationClass;
109 pBuffer = Irp->AssociatedIrp.SystemBuffer;
111 AFSAcquireShared( pVolumeCB->VolumeLock,
114 bReleaseResource = TRUE;
117 // Don't allow requests against IOCtl nodes
120 if( pFcb->Header.NodeTypeCode == AFS_IOCTL_FCB)
123 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
124 AFS_TRACE_LEVEL_ERROR,
125 "AFSQueryVolumeInfo Failing request against PIOCtl Fcb\n"));
127 try_return( ntStatus = STATUS_INVALID_DEVICE_REQUEST);
129 else if( pFcb->Header.NodeTypeCode == AFS_SPECIAL_SHARE_FCB)
132 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
133 AFS_TRACE_LEVEL_ERROR,
134 "AFSQueryVolumeInfo Failing request against SpecialShare Fcb\n"));
136 try_return( ntStatus = STATUS_INVALID_DEVICE_REQUEST);
138 else if( pFcb->Header.NodeTypeCode == AFS_INVALID_FCB)
141 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
142 AFS_TRACE_LEVEL_ERROR,
143 "AFSQueryVolumeInfo Failing request against SpecialShare Fcb\n"));
145 try_return( ntStatus = STATUS_INVALID_DEVICE_REQUEST);
149 // Process the request
152 switch( FsInformationClass)
155 case FileFsVolumeInformation:
158 ntStatus = AFSQueryFsVolumeInfo( &pVolumeCB->VolumeInformation,
159 (PFILE_FS_VOLUME_INFORMATION)pBuffer,
166 case FileFsSizeInformation:
169 ntStatus = AFSQueryFsSizeInfo( &pVolumeCB->VolumeInformation,
170 (PFILE_FS_SIZE_INFORMATION)pBuffer,
176 case FileFsDeviceInformation:
179 ntStatus = AFSQueryFsDeviceInfo( &pVolumeCB->VolumeInformation,
180 (PFILE_FS_DEVICE_INFORMATION)pBuffer,
186 case FileFsAttributeInformation:
189 ntStatus = AFSQueryFsAttributeInfo( &pVolumeCB->VolumeInformation,
190 (PFILE_FS_ATTRIBUTE_INFORMATION)pBuffer,
196 case FileFsFullSizeInformation:
199 ntStatus = AFSQueryFsFullSizeInfo( &pVolumeCB->VolumeInformation,
200 (PFILE_FS_FULL_SIZE_INFORMATION)pBuffer,
208 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
209 AFS_TRACE_LEVEL_WARNING,
210 "AFSQueryVolumeInfo Invalid class %d\n",
211 FsInformationClass));
213 ntStatus = STATUS_INVALID_PARAMETER;
221 // Setup the Irp's information field to what we actually copied in.
224 Irp->IoStatus.Information = pIrpSp->Parameters.QueryVolume.Length - ulLength;
226 if( bReleaseResource)
229 AFSReleaseResource( pVolumeCB->VolumeLock);
232 AFSCompleteRequest( Irp,
236 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
241 "EXCEPTION - AFSQueryVolumeInfo FO %p InfoClass %d FCB %p ObjectInfo %p VolCB %p\n",
248 AFSDumpTraceFilesFnc();
255 AFSSetVolumeInfo( IN PDEVICE_OBJECT DeviceObject,
259 UNREFERENCED_PARAMETER(DeviceObject);
260 NTSTATUS ntStatus = STATUS_SUCCESS;
261 IO_STACK_LOCATION *pIrpSp;
263 pIrpSp = IoGetCurrentIrpStackLocation( Irp);
268 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
269 AFS_TRACE_LEVEL_WARNING,
270 "AFSSetVolumeInfo Entry for FO %p\n",
271 pIrpSp->FileObject));
273 AFSCompleteRequest( Irp,
277 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
282 "EXCEPTION - AFSSetVolumeInfo\n"));
284 AFSDumpTraceFilesFnc();
291 AFSQueryFsVolumeInfo( IN AFSVolumeInfoCB *VolumeInfo,
292 IN PFILE_FS_VOLUME_INFORMATION Buffer,
293 IN BOOLEAN bDosDevice,
294 IN OUT PULONG Length)
298 NTSTATUS ntStatus = STATUS_BUFFER_TOO_SMALL;
301 RtlZeroMemory( Buffer,
304 if( *Length >= (ULONG)sizeof( FILE_FS_VOLUME_INFORMATION))
310 ulLabelLength = VolumeInfo->VolumeLabelLength;
315 ulLabelLength = VolumeInfo->VolumeLabelLength +
316 VolumeInfo->CellLength + sizeof( WCHAR);
319 if( *Length >= (ULONG)(FIELD_OFFSET( FILE_FS_VOLUME_INFORMATION, VolumeLabel) + ulLabelLength))
322 ntStatus = STATUS_SUCCESS;
327 ntStatus = STATUS_BUFFER_OVERFLOW;
330 Buffer->VolumeCreationTime.QuadPart = VolumeInfo->VolumeCreationTime.QuadPart;
332 Buffer->VolumeSerialNumber = VolumeInfo->VolumeID;
334 Buffer->VolumeLabelLength = ulLabelLength;
336 Buffer->SupportsObjects = FALSE;
338 *Length -= FIELD_OFFSET( FILE_FS_VOLUME_INFORMATION, VolumeLabel);
346 RtlCopyMemory( Buffer->VolumeLabel,
347 VolumeInfo->VolumeLabel,
348 min( *Length, VolumeInfo->VolumeLabelLength));
350 *Length -= min( *Length, VolumeInfo->VolumeLabelLength);
355 RtlCopyMemory( Buffer->VolumeLabel,
357 min( *Length, VolumeInfo->CellLength));
359 *Length -= min( *Length, VolumeInfo->CellLength);
361 if ( *Length >= sizeof( WCHAR))
364 Buffer->VolumeLabel[ VolumeInfo->CellLength / sizeof( WCHAR)] = L'#';
366 *Length -= sizeof( WCHAR);
370 RtlCopyMemory( &Buffer->VolumeLabel[ (VolumeInfo->CellLength + sizeof( WCHAR)) / sizeof( WCHAR)],
371 VolumeInfo->VolumeLabel,
372 min( *Length, VolumeInfo->VolumeLabelLength));
374 *Length -= min( *Length, VolumeInfo->VolumeLabelLength);
385 AFSQueryFsSizeInfo( IN AFSVolumeInfoCB *VolumeInfo,
386 IN PFILE_FS_SIZE_INFORMATION Buffer,
387 IN OUT PULONG Length)
390 NTSTATUS ntStatus = STATUS_SUCCESS;
392 AFSVolumeSizeInfoCB VolumeSizeInfo;
394 RtlZeroMemory( Buffer,
397 if( *Length >= sizeof( FILE_FS_SIZE_INFORMATION))
400 RtlZeroMemory( &FileID,
403 FileID.Cell = VolumeInfo->CellID;
405 FileID.Volume = VolumeInfo->VolumeID;
407 ntStatus = AFSRetrieveVolumeSizeInformation( NULL,
411 if ( NT_SUCCESS( ntStatus))
414 Buffer->TotalAllocationUnits.QuadPart = VolumeSizeInfo.TotalAllocationUnits.QuadPart;
416 Buffer->AvailableAllocationUnits.QuadPart = VolumeSizeInfo.AvailableAllocationUnits.QuadPart;
418 Buffer->SectorsPerAllocationUnit = VolumeSizeInfo.SectorsPerAllocationUnit;
420 Buffer->BytesPerSector = VolumeSizeInfo.BytesPerSector;
422 *Length -= sizeof( FILE_FS_SIZE_INFORMATION);
428 ntStatus = STATUS_BUFFER_TOO_SMALL;
435 AFSQueryFsDeviceInfo( IN AFSVolumeInfoCB *VolumeInfo,
436 IN PFILE_FS_DEVICE_INFORMATION Buffer,
437 IN OUT PULONG Length)
439 NTSTATUS ntStatus = STATUS_SUCCESS;
441 RtlZeroMemory( Buffer,
444 if( *Length >= (LONG)sizeof( FILE_FS_DEVICE_INFORMATION))
448 // This value is used to determine the return type of
449 // Win32 GetFileType(). Returning FILE_DEVICE_NETWORK_FILE_SYSTEM
450 // results in GetFileType returning FILE_TYPE_UNKNOWN which breaks
451 // msys-based applications. They treat all files as character
452 // special devices instead of files.
455 Buffer->DeviceType = FILE_DEVICE_DISK;
457 Buffer->Characteristics = VolumeInfo->Characteristics;
459 *Length -= sizeof( FILE_FS_DEVICE_INFORMATION);
464 ntStatus = STATUS_BUFFER_TOO_SMALL;
471 AFSQueryFsAttributeInfo( IN AFSVolumeInfoCB *VolumeInfo,
472 IN PFILE_FS_ATTRIBUTE_INFORMATION Buffer,
473 IN OUT PULONG Length)
475 NTSTATUS ntStatus = STATUS_SUCCESS;
477 RtlZeroMemory( Buffer,
480 if( *Length >= (LONG)(sizeof( FILE_FS_ATTRIBUTE_INFORMATION)))
483 Buffer->FileSystemAttributes = VolumeInfo->FileSystemAttributes;
485 Buffer->MaximumComponentNameLength = 255;
487 Buffer->FileSystemNameLength = 18;
489 *Length -= FIELD_OFFSET( FILE_FS_ATTRIBUTE_INFORMATION, FileSystemName);
494 RtlCopyMemory( Buffer->FileSystemName,
503 ntStatus = STATUS_BUFFER_OVERFLOW;
509 ntStatus = STATUS_BUFFER_TOO_SMALL;
516 AFSQueryFsFullSizeInfo( IN AFSVolumeInfoCB *VolumeInfo,
517 IN PFILE_FS_FULL_SIZE_INFORMATION Buffer,
518 IN OUT PULONG Length)
521 NTSTATUS ntStatus = STATUS_SUCCESS;
523 AFSVolumeSizeInfoCB VolumeSizeInfo;
525 RtlZeroMemory( Buffer,
528 if( *Length >= sizeof( FILE_FS_FULL_SIZE_INFORMATION))
531 RtlZeroMemory( &FileID,
534 FileID.Cell = VolumeInfo->CellID;
536 FileID.Volume = VolumeInfo->VolumeID;
538 ntStatus = AFSRetrieveVolumeSizeInformation( NULL,
542 if ( NT_SUCCESS( ntStatus))
545 Buffer->TotalAllocationUnits.QuadPart = VolumeSizeInfo.TotalAllocationUnits.QuadPart;
547 Buffer->CallerAvailableAllocationUnits.QuadPart = VolumeSizeInfo.AvailableAllocationUnits.QuadPart;
549 Buffer->ActualAvailableAllocationUnits.QuadPart = VolumeSizeInfo.AvailableAllocationUnits.QuadPart;
551 Buffer->SectorsPerAllocationUnit = VolumeSizeInfo.SectorsPerAllocationUnit;
553 Buffer->BytesPerSector = VolumeSizeInfo.BytesPerSector;
555 *Length -= sizeof( FILE_FS_FULL_SIZE_INFORMATION);
561 ntStatus = STATUS_BUFFER_TOO_SMALL;