|
|
/*++
Copyright (c) 1989 - 1999 Microsoft Corporation
Module Name:
fileinfo.c
Abstract:
This module implements the mini redirector call down routines pertaining to retrieval/ update of file/directory/volume information.
--*/
#include "precomp.h"
#pragma hdrstop
#pragma warning(error:4101) // Unreferenced local variable
//
// The local debug trace level
//
#define Dbg (DEBUG_TRACE_FILEINFO)
NTSTATUS NulMRxQueryDirectory( IN OUT PRX_CONTEXT RxContext ) /*++
Routine Description:
This routine does a directory query. Only the NT-->NT path is implemented.
Arguments:
RxContext - the RDBSS context
Return Value:
NTSTATUS - The return status for the operation
--*/ { NTSTATUS Status = STATUS_INVALID_PARAMETER; FILE_INFORMATION_CLASS FileInformationClass; PVOID Buffer; PULONG pLengthRemaining; ULONG CopySize;
FileInformationClass = RxContext->Info.FileInformationClass; Buffer = RxContext->Info.Buffer; pLengthRemaining = &RxContext->Info.LengthRemaining;
switch (FileInformationClass) { case FileDirectoryInformation: { PFILE_DIRECTORY_INFORMATION pDirInfo = (PFILE_DIRECTORY_INFORMATION) Buffer; CopySize = sizeof( FILE_DIRECTORY_INFORMATION ); if ( *pLengthRemaining >= CopySize ) { RtlZeroMemory( pDirInfo, CopySize ); pDirInfo->FileAttributes = FILE_ATTRIBUTE_DIRECTORY; pDirInfo->FileNameLength = sizeof( WCHAR ); pDirInfo->FileName[0] = L'.'; *pLengthRemaining -= CopySize; Status = RxContext->QueryDirectory.InitialQuery ? STATUS_SUCCESS : STATUS_NO_MORE_FILES; } } break;
case FileFullDirectoryInformation: { PFILE_FULL_DIR_INFORMATION pFullDirInfo = (PFILE_FULL_DIR_INFORMATION) Buffer; CopySize = sizeof( FILE_FULL_DIR_INFORMATION ); if ( *pLengthRemaining >= CopySize ) { RtlZeroMemory( pFullDirInfo, CopySize ); pFullDirInfo->FileAttributes = FILE_ATTRIBUTE_DIRECTORY; pFullDirInfo->FileNameLength = sizeof( WCHAR ); pFullDirInfo->FileName[0] = L'.'; *pLengthRemaining -= CopySize; Status = RxContext->QueryDirectory.InitialQuery ? STATUS_SUCCESS : STATUS_NO_MORE_FILES; } } break;
case FileBothDirectoryInformation: { PFILE_BOTH_DIR_INFORMATION pBothDirInfo = (PFILE_BOTH_DIR_INFORMATION) Buffer; CopySize = sizeof( FILE_BOTH_DIR_INFORMATION ); if ( *pLengthRemaining >= CopySize ) { RtlZeroMemory( pBothDirInfo, CopySize ); pBothDirInfo->FileAttributes = FILE_ATTRIBUTE_DIRECTORY; pBothDirInfo->FileNameLength = sizeof( WCHAR ); pBothDirInfo->FileName[0] = L'.'; pBothDirInfo->ShortNameLength = sizeof( WCHAR ); pBothDirInfo->ShortName[0] = L'.'; *pLengthRemaining -= CopySize; Status = RxContext->QueryDirectory.InitialQuery ? STATUS_SUCCESS : STATUS_NO_MORE_FILES; } } break;
case FileNamesInformation: { PFILE_NAMES_INFORMATION pNamesDirInfo = (PFILE_NAMES_INFORMATION) Buffer; CopySize = sizeof( FILE_NAMES_INFORMATION ); if ( *pLengthRemaining >= CopySize ) { RtlZeroMemory( pNamesDirInfo, CopySize ); pNamesDirInfo->FileNameLength = sizeof( WCHAR ); pNamesDirInfo->FileName[0] = L'.'; *pLengthRemaining -= CopySize; Status = RxContext->QueryDirectory.InitialQuery ? STATUS_SUCCESS : STATUS_NO_MORE_FILES; } } break;
default: RxDbgTrace( 0, Dbg, ("NulMRxQueryDirectory: Invalid FS information class\n")); Status = STATUS_INVALID_PARAMETER; break; }
DbgPrint("NulMRxQueryDirectory \n"); return(Status); }
NTSTATUS NulMRxQueryVolumeInformation( IN OUT PRX_CONTEXT RxContext ) /*++
Routine Description:
This routine queries the volume information
Arguments:
pRxContext - the RDBSS context
FsInformationClass - the kind of Fs information desired.
pBuffer - the buffer for copying the information
pBufferLength - the buffer length ( set to buffer length on input and set to the remaining length on output)
Return Value:
NTSTATUS - The return status for the operation
--*/ { NTSTATUS Status = STATUS_INVALID_PARAMETER; RxCaptureFcb;
ULONG RemainingLength = RxContext->Info.LengthRemaining; FS_INFORMATION_CLASS FsInformationClass = RxContext->Info.FsInformationClass; PVOID OriginalBuffer = RxContext->Info.Buffer; UNICODE_STRING ustrVolume; ULONG BytesToCopy;
RxTraceEnter("NulMRxQueryVolumeInformation");
switch( FsInformationClass ) { case FileFsVolumeInformation: { PFILE_FS_VOLUME_INFORMATION pVolInfo = (PFILE_FS_VOLUME_INFORMATION) OriginalBuffer;
if(RemainingLength < sizeof(FILE_FS_VOLUME_INFORMATION)) { break; } RtlZeroMemory( pVolInfo, sizeof(FILE_FS_VOLUME_INFORMATION) ); pVolInfo->VolumeCreationTime.QuadPart = 0; pVolInfo->VolumeSerialNumber = 0xBABAFACE; pVolInfo->SupportsObjects = FALSE; RtlInitUnicodeString( &ustrVolume, L"NULMRX" );
RemainingLength -= FIELD_OFFSET(FILE_FS_VOLUME_INFORMATION, VolumeLabel[0]);
if (RemainingLength >= (ULONG)ustrVolume.Length) { BytesToCopy = ustrVolume.Length; } else { BytesToCopy = RemainingLength; }
RtlCopyMemory( &pVolInfo->VolumeLabel[0], (PVOID)ustrVolume.Buffer, BytesToCopy ); RemainingLength -= BytesToCopy; pVolInfo->VolumeLabelLength = BytesToCopy;
RxContext->Info.LengthRemaining = RemainingLength; Status = STATUS_SUCCESS; DbgPrint("FileFsVolumeInformation\n"); } break; case FileFsLabelInformation: DbgPrint("FileFsLabelInformation\n"); break; case FileFsSizeInformation: DbgPrint("FileFsSizeInformation\n"); break; case FileFsDeviceInformation: DbgPrint("FileFsDeviceInformation\n"); break; case FileFsAttributeInformation: { PFILE_FS_ATTRIBUTE_INFORMATION pAttribInfo = (PFILE_FS_ATTRIBUTE_INFORMATION) OriginalBuffer;
if(RemainingLength < sizeof(FILE_FS_ATTRIBUTE_INFORMATION)) { break; }
RtlZeroMemory(pAttribInfo, sizeof(FILE_FS_ATTRIBUTE_INFORMATION));
pAttribInfo->FileSystemAttributes = 0; pAttribInfo->MaximumComponentNameLength = 32;
RemainingLength -= FIELD_OFFSET(FILE_FS_ATTRIBUTE_INFORMATION, FileSystemName[0]); RtlInitUnicodeString( &ustrVolume, L"SampleFS" );
BytesToCopy = RemainingLength; if(RemainingLength >= ustrVolume.Length) { BytesToCopy = ustrVolume.Length; }
pAttribInfo->FileSystemNameLength = BytesToCopy;
RtlCopyMemory( pAttribInfo->FileSystemName, (PVOID)ustrVolume.Buffer, BytesToCopy ); RemainingLength -= BytesToCopy; RxContext->Info.LengthRemaining = RemainingLength; Status = STATUS_SUCCESS; DbgPrint("FileFsAttributeInformation\n"); } break; case FileFsControlInformation: DbgPrint("FileFsControlInformation\n"); break; case FileFsFullSizeInformation: DbgPrint("FileFsFullSizeInformation\n"); break; case FileFsObjectIdInformation: DbgPrint("FileFsObjectIdInformation\n"); break; case FileFsMaximumInformation: DbgPrint("FileFsMaximumInformation\n"); break; default: break; }
RxTraceLeave(Status); return(Status); }
NTSTATUS NulMRxSetVolumeInformation( IN OUT PRX_CONTEXT pRxContext ) /*++
Routine Description:
This routine sets the volume information
Arguments:
pRxContext - the RDBSS context
FsInformationClass - the kind of Fs information desired.
pBuffer - the buffer for copying the information
BufferLength - the buffer length
Return Value:
NTSTATUS - The return status for the operation
--*/ { NTSTATUS Status = STATUS_NOT_IMPLEMENTED;
DbgPrint("NulMRxSetVolumeInformation \n"); return(Status); }
NTSTATUS NulMRxQueryFileInformation( IN PRX_CONTEXT RxContext ) /*++
Routine Description:
This routine does a query file info. Only the NT-->NT path is implemented.
The NT-->NT path works by just remoting the call basically without further ado.
Arguments:
RxContext - the RDBSS context
Return Value:
NTSTATUS - The return status for the operation
--*/ { NTSTATUS Status = STATUS_INVALID_PARAMETER; ULONG RemainingLength = RxContext->Info.LengthRemaining; RxCaptureFcb; FILE_INFORMATION_CLASS FunctionalityRequested = RxContext->Info.FileInformationClass; PFILE_STANDARD_INFORMATION pFileStdInfo = (PFILE_STANDARD_INFORMATION) RxContext->Info.Buffer;
RxTraceEnter("NulMRxQueryFileInformation");
switch( FunctionalityRequested ) { case FileBasicInformation: if(RemainingLength < sizeof(FILE_BASIC_INFORMATION)) { break; } RemainingLength -= sizeof(FILE_BASIC_INFORMATION); Status = STATUS_SUCCESS; break; case FileInternalInformation: if(RemainingLength < sizeof(FILE_INTERNAL_INFORMATION)) { break; } RemainingLength -= sizeof(FILE_INTERNAL_INFORMATION); Status = STATUS_SUCCESS; break; case FileEaInformation: if(RemainingLength < sizeof(FILE_EA_INFORMATION)) { break; } RemainingLength -= sizeof(FILE_EA_INFORMATION); Status = STATUS_SUCCESS; break; case FileStandardInformation:
if(RemainingLength < sizeof(FILE_STANDARD_INFORMATION)) { break; } RxDbgTrace(0, Dbg, ("FileSize is %d AllocationSize is %d\n", pFileStdInfo->EndOfFile.LowPart,pFileStdInfo->AllocationSize.LowPart)); //(RxContext->CurrentIrp)->IoStatus.Information = sizeof(FILE_STANDARD_INFORMATION);
RemainingLength -= sizeof(FILE_STANDARD_INFORMATION); Status = STATUS_SUCCESS; break; default: break; }
RxContext->Info.LengthRemaining = RemainingLength; RxTraceLeave(Status); return(Status); }
NTSTATUS NulMRxSetFileInformation( IN PRX_CONTEXT RxContext ) /*++
Routine Description:
This routine does a set file info. Only the NT-->NT path is implemented.
The NT-->NT path works by just remoting the call basically without further ado.
Arguments:
RxContext - the RDBSS context
Return Value:
NTSTATUS - The return status for the operation
--*/ { NTSTATUS Status = STATUS_INVALID_PARAMETER; RxCaptureFcb; ULONG BufferLength = RxContext->Info.Length; FILE_INFORMATION_CLASS FunctionalityRequested = RxContext->Info.FileInformationClass; PFILE_END_OF_FILE_INFORMATION pEndOfFileInfo = (PFILE_END_OF_FILE_INFORMATION) RxContext->Info.Buffer; LARGE_INTEGER NewAllocationSize;
RxTraceEnter("NulMRxSetFileInformation");
switch( FunctionalityRequested ) { case FileBasicInformation: RxDbgTrace(0, Dbg, ("FileBasicInformation\n")); if(BufferLength < sizeof(FILE_BASIC_INFORMATION)) { break; } Status = STATUS_SUCCESS; break; case FileDispositionInformation: RxDbgTrace(0, Dbg, ("FileDispositionInformation\n")); if(BufferLength < sizeof(FILE_DISPOSITION_INFORMATION)) { break; } Status = STATUS_SUCCESS; break; case FilePositionInformation: RxDbgTrace(0, Dbg, ("FilePositionInformation\n")); if(BufferLength < sizeof(FILE_POSITION_INFORMATION)) { break; } Status = STATUS_SUCCESS; break; case FileAllocationInformation: RxDbgTrace(0, Dbg, ("FileAllocationInformation\n")); RxDbgTrace(0, Dbg, ("AllocSize is %d AllocSizeHigh is %d\n", pEndOfFileInfo->EndOfFile.LowPart,pEndOfFileInfo->EndOfFile.HighPart)); if(BufferLength < sizeof(FILE_ALLOCATION_INFORMATION)) { break; } Status = STATUS_SUCCESS; break; case FileEndOfFileInformation:
RxDbgTrace(0, Dbg, ("FileSize is %d FileSizeHigh is %d\n", capFcb->Header.AllocationSize.LowPart,capFcb->Header.AllocationSize.HighPart)); if(BufferLength < sizeof(FILE_END_OF_FILE_INFORMATION)) { break; }
if( pEndOfFileInfo->EndOfFile.QuadPart > capFcb->Header.AllocationSize.QuadPart ) { Status = NulMRxExtendFile( RxContext, &pEndOfFileInfo->EndOfFile, &NewAllocationSize );
RxDbgTrace(0, Dbg, ("AllocSize is %d AllocSizeHigh is %d\n", NewAllocationSize.LowPart,NewAllocationSize.HighPart));
//
// Change the file allocation
//
capFcb->Header.AllocationSize.QuadPart = NewAllocationSize.QuadPart; } else { Status = NulMRxTruncateFile( RxContext, &pEndOfFileInfo->EndOfFile, &NewAllocationSize ); }
break; case FileRenameInformation: RxDbgTrace(0, Dbg, ("FileRenameInformation\n")); if(BufferLength < sizeof(FILE_RENAME_INFORMATION)) { break; } Status = STATUS_SUCCESS; break; default: break; } RxTraceLeave(Status); return Status; }
NTSTATUS NulMRxSetFileInformationAtCleanup( IN PRX_CONTEXT RxContext ) /*++
Routine Description:
This routine sets the file information on cleanup. the old rdr just swallows this operation (i.e. it doesn't generate it). we are doing the same..........
Arguments:
pRxContext - the RDBSS context
Return Value:
NTSTATUS - The return status for the operation
--*/ { NTSTATUS Status = STATUS_NOT_IMPLEMENTED;
return(Status); }
|