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;
58 pIrpSp = IoGetCurrentIrpStackLocation( Irp);
63 pFileObject = pIrpSp->FileObject;
65 if( pFileObject == NULL)
68 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
69 AFS_TRACE_LEVEL_ERROR,
70 "AFSQueryVolumeInfo Failing request with NULL FileObject\n");
72 try_return( ntStatus = STATUS_INVALID_DEVICE_REQUEST);
75 pFcb = (AFSFcb *)pFileObject->FsContext;
80 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
81 AFS_TRACE_LEVEL_ERROR,
82 "AFSQueryVolumeInfo Failing request with NULL Fcb\n");
84 try_return( ntStatus = STATUS_INVALID_DEVICE_REQUEST);
87 pObjectInfo = pFcb->ObjectInformation;
89 if( pObjectInfo == NULL)
92 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
93 AFS_TRACE_LEVEL_ERROR,
94 "AFSQueryVolumeInfo Failing request with NULL ObjectInformation\n");
96 try_return( ntStatus = STATUS_INVALID_DEVICE_REQUEST);
99 pVolumeCB = pObjectInfo->VolumeCB;
101 ulLength = pIrpSp->Parameters.QueryVolume.Length;
102 FsInformationClass = pIrpSp->Parameters.QueryVolume.FsInformationClass;
103 pBuffer = Irp->AssociatedIrp.SystemBuffer;
105 AFSAcquireShared( pVolumeCB->VolumeLock,
108 bReleaseResource = TRUE;
111 // Don't allow requests against IOCtl nodes
114 if( pFcb->Header.NodeTypeCode == AFS_IOCTL_FCB)
117 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
118 AFS_TRACE_LEVEL_ERROR,
119 "AFSQueryVolumeInfo Failing request against PIOCtl Fcb\n");
121 try_return( ntStatus = STATUS_INVALID_DEVICE_REQUEST);
123 else if( pFcb->Header.NodeTypeCode == AFS_SPECIAL_SHARE_FCB)
126 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
127 AFS_TRACE_LEVEL_ERROR,
128 "AFSQueryVolumeInfo Failing request against SpecialShare Fcb\n");
130 try_return( ntStatus = STATUS_INVALID_DEVICE_REQUEST);
132 else if( pFcb->Header.NodeTypeCode == AFS_INVALID_FCB)
135 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
136 AFS_TRACE_LEVEL_ERROR,
137 "AFSQueryVolumeInfo Failing request against SpecialShare Fcb\n");
139 try_return( ntStatus = STATUS_INVALID_DEVICE_REQUEST);
143 // Process the request
146 switch( FsInformationClass)
149 case FileFsVolumeInformation:
152 ntStatus = AFSQueryFsVolumeInfo( &pVolumeCB->VolumeInformation,
153 (PFILE_FS_VOLUME_INFORMATION)pBuffer,
159 case FileFsSizeInformation:
162 ntStatus = AFSQueryFsSizeInfo( &pVolumeCB->VolumeInformation,
163 (PFILE_FS_SIZE_INFORMATION)pBuffer,
169 case FileFsDeviceInformation:
172 ntStatus = AFSQueryFsDeviceInfo( &pVolumeCB->VolumeInformation,
173 (PFILE_FS_DEVICE_INFORMATION)pBuffer,
179 case FileFsAttributeInformation:
182 ntStatus = AFSQueryFsAttributeInfo( &pVolumeCB->VolumeInformation,
183 (PFILE_FS_ATTRIBUTE_INFORMATION)pBuffer,
189 case FileFsFullSizeInformation:
192 ntStatus = AFSQueryFsFullSizeInfo( &pVolumeCB->VolumeInformation,
193 (PFILE_FS_FULL_SIZE_INFORMATION)pBuffer,
201 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
202 AFS_TRACE_LEVEL_WARNING,
203 "AFSQueryVolumeInfo Invalid class %d\n",
206 ntStatus = STATUS_INVALID_PARAMETER;
214 // Setup the Irp's information field to what we actually copied in.
217 Irp->IoStatus.Information = pIrpSp->Parameters.QueryVolume.Length - ulLength;
219 if( bReleaseResource)
222 AFSReleaseResource( pVolumeCB->VolumeLock);
225 AFSCompleteRequest( Irp,
229 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
234 "EXCEPTION - AFSQueryVolumeInfo FO %p InfoClass %d FCB %p ObjectInfo %p VolCB %p\n",
241 AFSDumpTraceFilesFnc();
248 AFSSetVolumeInfo( IN PDEVICE_OBJECT DeviceObject,
252 UNREFERENCED_PARAMETER(DeviceObject);
253 NTSTATUS ntStatus = STATUS_SUCCESS;
254 IO_STACK_LOCATION *pIrpSp;
256 pIrpSp = IoGetCurrentIrpStackLocation( Irp);
261 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
262 AFS_TRACE_LEVEL_WARNING,
263 "AFSSetVolumeInfo Entry for FO %p\n", pIrpSp->FileObject);
265 AFSCompleteRequest( Irp,
269 __except( AFSExceptionFilter( __FUNCTION__, GetExceptionCode(), GetExceptionInformation()) )
274 "EXCEPTION - AFSSetVolumeInfo\n");
276 AFSDumpTraceFilesFnc();
283 AFSQueryFsVolumeInfo( IN AFSVolumeInfoCB *VolumeInfo,
284 IN PFILE_FS_VOLUME_INFORMATION Buffer,
285 IN OUT PULONG Length)
289 NTSTATUS ntStatus = STATUS_BUFFER_TOO_SMALL;
292 RtlZeroMemory( Buffer,
295 if( *Length >= (ULONG)sizeof( FILE_FS_VOLUME_INFORMATION))
298 ulLabelLength = VolumeInfo->VolumeLabelLength +
299 VolumeInfo->CellLength + sizeof( WCHAR);
301 if( *Length >= (ULONG)(FIELD_OFFSET( FILE_FS_VOLUME_INFORMATION, VolumeLabel) + ulLabelLength))
304 ntStatus = STATUS_SUCCESS;
309 ntStatus = STATUS_BUFFER_OVERFLOW;
312 Buffer->VolumeCreationTime.QuadPart = VolumeInfo->VolumeCreationTime.QuadPart;
314 Buffer->VolumeSerialNumber = VolumeInfo->VolumeID;
316 Buffer->VolumeLabelLength = ulLabelLength;
318 Buffer->SupportsObjects = FALSE;
320 *Length -= FIELD_OFFSET( FILE_FS_VOLUME_INFORMATION, VolumeLabel);
325 RtlCopyMemory( Buffer->VolumeLabel,
327 min( *Length, VolumeInfo->CellLength));
329 *Length -= min( *Length, VolumeInfo->CellLength);
331 if ( *Length >= sizeof( WCHAR))
334 Buffer->VolumeLabel[ VolumeInfo->CellLength / sizeof( WCHAR)] = L'#';
336 *Length -= sizeof( WCHAR);
340 RtlCopyMemory( &Buffer->VolumeLabel[ (VolumeInfo->CellLength + sizeof( WCHAR)) / sizeof( WCHAR)],
341 VolumeInfo->VolumeLabel,
342 min( *Length, VolumeInfo->VolumeLabelLength));
344 *Length -= min( *Length, VolumeInfo->VolumeLabelLength);
354 AFSQueryFsSizeInfo( IN AFSVolumeInfoCB *VolumeInfo,
355 IN PFILE_FS_SIZE_INFORMATION Buffer,
356 IN OUT PULONG Length)
359 NTSTATUS ntStatus = STATUS_SUCCESS;
361 AFSVolumeSizeInfoCB VolumeSizeInfo;
363 RtlZeroMemory( Buffer,
366 if( *Length >= sizeof( FILE_FS_SIZE_INFORMATION))
369 RtlZeroMemory( &FileID,
372 FileID.Cell = VolumeInfo->CellID;
374 FileID.Volume = VolumeInfo->VolumeID;
376 ntStatus = AFSRetrieveVolumeSizeInformation( NULL,
380 if ( NT_SUCCESS( ntStatus))
383 Buffer->TotalAllocationUnits.QuadPart = VolumeSizeInfo.TotalAllocationUnits.QuadPart;
385 Buffer->AvailableAllocationUnits.QuadPart = VolumeSizeInfo.AvailableAllocationUnits.QuadPart;
387 Buffer->SectorsPerAllocationUnit = VolumeSizeInfo.SectorsPerAllocationUnit;
389 Buffer->BytesPerSector = VolumeSizeInfo.BytesPerSector;
391 *Length -= sizeof( FILE_FS_SIZE_INFORMATION);
397 ntStatus = STATUS_BUFFER_TOO_SMALL;
404 AFSQueryFsDeviceInfo( IN AFSVolumeInfoCB *VolumeInfo,
405 IN PFILE_FS_DEVICE_INFORMATION Buffer,
406 IN OUT PULONG Length)
408 NTSTATUS ntStatus = STATUS_SUCCESS;
410 RtlZeroMemory( Buffer,
413 if( *Length >= (LONG)sizeof( FILE_FS_DEVICE_INFORMATION))
417 // This value is used to determine the return type of
418 // Win32 GetFileType(). Returning FILE_DEVICE_NETWORK_FILE_SYSTEM
419 // results in GetFileType returning FILE_TYPE_UNKNOWN which breaks
420 // msys-based applications. They treat all files as character
421 // special devices instead of files.
424 Buffer->DeviceType = FILE_DEVICE_DISK;
426 Buffer->Characteristics = VolumeInfo->Characteristics;
428 *Length -= sizeof( FILE_FS_DEVICE_INFORMATION);
433 ntStatus = STATUS_BUFFER_TOO_SMALL;
440 AFSQueryFsAttributeInfo( IN AFSVolumeInfoCB *VolumeInfo,
441 IN PFILE_FS_ATTRIBUTE_INFORMATION Buffer,
442 IN OUT PULONG Length)
444 NTSTATUS ntStatus = STATUS_SUCCESS;
446 RtlZeroMemory( Buffer,
449 if( *Length >= (LONG)(sizeof( FILE_FS_ATTRIBUTE_INFORMATION)))
452 Buffer->FileSystemAttributes = VolumeInfo->FileSystemAttributes;
454 Buffer->MaximumComponentNameLength = 255;
456 Buffer->FileSystemNameLength = 18;
458 *Length -= FIELD_OFFSET( FILE_FS_ATTRIBUTE_INFORMATION, FileSystemName);
463 RtlCopyMemory( Buffer->FileSystemName,
472 ntStatus = STATUS_BUFFER_OVERFLOW;
478 ntStatus = STATUS_BUFFER_TOO_SMALL;
485 AFSQueryFsFullSizeInfo( IN AFSVolumeInfoCB *VolumeInfo,
486 IN PFILE_FS_FULL_SIZE_INFORMATION Buffer,
487 IN OUT PULONG Length)
490 NTSTATUS ntStatus = STATUS_SUCCESS;
492 AFSVolumeSizeInfoCB VolumeSizeInfo;
494 RtlZeroMemory( Buffer,
497 if( *Length >= sizeof( FILE_FS_FULL_SIZE_INFORMATION))
500 RtlZeroMemory( &FileID,
503 FileID.Cell = VolumeInfo->CellID;
505 FileID.Volume = VolumeInfo->VolumeID;
507 ntStatus = AFSRetrieveVolumeSizeInformation( NULL,
511 if ( NT_SUCCESS( ntStatus))
514 Buffer->TotalAllocationUnits.QuadPart = VolumeSizeInfo.TotalAllocationUnits.QuadPart;
516 Buffer->CallerAvailableAllocationUnits.QuadPart = VolumeSizeInfo.AvailableAllocationUnits.QuadPart;
518 Buffer->ActualAvailableAllocationUnits.QuadPart = VolumeSizeInfo.AvailableAllocationUnits.QuadPart;
520 Buffer->SectorsPerAllocationUnit = VolumeSizeInfo.SectorsPerAllocationUnit;
522 Buffer->BytesPerSector = VolumeSizeInfo.BytesPerSector;
524 *Length -= sizeof( FILE_FS_FULL_SIZE_INFORMATION);
530 ntStatus = STATUS_BUFFER_TOO_SMALL;