/*++ Copyright (c) 1989 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. Author: Balan Sethu Raman [SethuR] 7-March-1995 Revision History: --*/ #include "precomp.h" #pragma hdrstop #pragma warning(error:4101) // Unreferenced local variable RXDT_DefineCategory(VOLINFO); #undef Dbg #define Dbg (DEBUG_TRACE_VOLINFO) NTSTATUS MRxProxyQueryVolumeInformation( IN OUT PRX_CONTEXT RxContext ) /*++ Routine Description: This routine queries the volume information Arguments: pRxContext - the RDBSS context Return Value: RXSTATUS - The return status for the operation --*/ { NTSTATUS Status; RxCaptureFcb; RxCaptureFobx; PMRX_PROXY_SRV_OPEN proxySrvOpen; FS_INFORMATION_CLASS FsInformationClass = RxContext->Info.FsInformationClass; PVOID pBuffer = RxContext->Info.Buffer; PLONG pLengthRemaining = &RxContext->Info.LengthRemaining; PFILE_OBJECT FileObject; ULONG PassedInLength,ReturnedLength; PAGED_CODE(); if (capFobx == NULL) { return STATUS_INVALID_PARAMETER; } TURN_BACK_ASYNCHRONOUS_OPERATIONS(); proxySrvOpen = MRxProxyGetSrvOpenExtension(capFobx->pSrvOpen); FileObject = proxySrvOpen->UnderlyingFileObject; ASSERT (FileObject); PassedInLength = *pLengthRemaining; Status = MRxProxySyncXxxInformation( RxContext, //IN OUT PRX_CONTEXT RxContext, IRP_MJ_QUERY_VOLUME_INFORMATION, //IN UCHAR MajorFunction, FileObject, //IN PFILE_OBJECT FileObject, FsInformationClass, //IN ULONG InformationClass, PassedInLength, //IN ULONG Length, pBuffer, //OUT PVOID Information, &ReturnedLength //OUT PULONG ReturnedLength OPTIONAL ); if (!NT_ERROR(Status)) { *pLengthRemaining -= ReturnedLength; } if (!NT_SUCCESS(Status)) { RxDbgTrace( 0, Dbg, ("MRxProxyQueryVolumeInformation: Failed .. returning %lx\n",Status)); } return Status; } NTSTATUS MRxProxySetVolumeInformation( 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: RXSTATUS - The return status for the operation --*/ { //FS_INFORMATION_CLASS FsInformationClass = RxContext->Info.FsInformationClass; //PVOID pBuffer = RxContext->Info.Buffer; //LONG BufferLength = RxContext->Info.Length; return STATUS_NOT_IMPLEMENTED; } RXDT_DefineCategory(FILEINFO); #undef Dbg #define Dbg (DEBUG_TRACE_FILEINFO) NTSTATUS MRxProxyQueryFileInformation( IN PRX_CONTEXT RxContext ) /*++ Routine Description: This routine does a query file info. Arguments: RxContext - the RDBSS context Return Value: RXSTATUS - The return status for the operation --*/ { NTSTATUS Status; RxCaptureFcb; RxCaptureFobx; FILE_INFORMATION_CLASS FileInformationClass; PVOID pBuffer; PULONG pLengthRemaining; PMRX_PROXY_SRV_OPEN proxySrvOpen = MRxProxyGetSrvOpenExtension(capFobx->pSrvOpen); //PMRX_PROXY_FCB proxyFcb = MRxProxyGetFcbExtension(capFcb); PFILE_OBJECT FileObject; ULONG PassedInLength,ReturnedLength; PUNICODE_STRING RemainingName = &(capFcb->AlreadyPrefixedName); PMRX_NET_ROOT NetRoot = capFcb->pNetRoot; PAGED_CODE(); FileInformationClass = RxContext->Info.FileInformationClass; pBuffer = RxContext->Info.Buffer; pLengthRemaining = &RxContext->Info.LengthRemaining; RxDbgTrace(+1, Dbg, ("MRxProxyQueryFileInformation: class=%08lx\n",FileInformationClass)); TURN_BACK_ASYNCHRONOUS_OPERATIONS(); FileObject = proxySrvOpen->UnderlyingFileObject; ASSERT (FileObject); PassedInLength = *pLengthRemaining; Status = MRxProxySyncXxxInformation( RxContext, //IN OUT PRX_CONTEXT RxContext, IRP_MJ_QUERY_INFORMATION, //IN UCHAR MajorFunction, FileObject, //IN PFILE_OBJECT FileObject, FileInformationClass, //IN ULONG InformationClass, PassedInLength, //IN ULONG Length, pBuffer, //OUT PVOID Information, &ReturnedLength //OUT PULONG ReturnedLength OPTIONAL ); if (!NT_ERROR(Status)) { *pLengthRemaining -= ReturnedLength; } if (!NT_SUCCESS(Status)) { RxDbgTrace( 0, Dbg, ("MRxProxyQueryFile: Failed .. returning %lx\n",Status)); } RxDbgTraceUnIndent(-1,Dbg); return Status; } typedef enum _INTERESTING_SFI_FOLLOWONS { SFI_FOLLOWON_NOTHING, SFI_FOLLOWON_DISPOSITION_SENT } INTERESTING_SFI_FOLLOWONS; #if DBG VOID MRxProxyDumpRenameInfo ( PSZ Msg, PFILE_RENAME_INFORMATION RenameInfo, ULONG BufferLength ) { UNICODE_STRING sss; sss.Buffer = &RenameInfo->FileName[0]; sss.Length = ((USHORT)(RenameInfo->FileNameLength)); RxDbgTrace(0, Dbg, ("MRxProxyDumpRenameInfo: %s %08lx %wZ\n",Msg,BufferLength,&sss)); } #else #define MRxProxyDumpRenameInfo(a,b,c); #endif NTSTATUS MRxProxySetFileInformation( IN PRX_CONTEXT RxContext ) /*++ Routine Description: This routine does a set file info. it works by just remoting the call basically without further ado. Arguments: RxContext - the RDBSS context Return Value: RXSTATUS - The return status for the operation --*/ { NTSTATUS Status; RxCaptureFcb; RxCaptureFobx; FILE_INFORMATION_CLASS FileInformationClass; PVOID pBuffer; ULONG BufferLength; //PMRX_PROXY_FOBX proxyFobx = MRxProxyGetFileObjectExtension(capFobx); PMRX_PROXY_SRV_OPEN proxySrvOpen = MRxProxyGetSrvOpenExtension(capFobx->pSrvOpen); //PMRX_PROXY_FCB proxyFcb = MRxProxyGetFcbExtension(capFcb); PFILE_OBJECT UnderlyingFileObject = proxySrvOpen->UnderlyingFileObject; PAGED_CODE(); TURN_BACK_ASYNCHRONOUS_OPERATIONS(); FileInformationClass = RxContext->Info.FileInformationClass; pBuffer = RxContext->Info.Buffer; BufferLength = RxContext->Info.Length; RxDbgTrace(+1, Dbg, ("MRxProxySetFile: Class %08lx size %08lx\n",FileInformationClass,BufferLength)); if (FileInformationClass==FileRenameInformation) { PFILE_RENAME_INFORMATION RenameInfo = (PFILE_RENAME_INFORMATION)pBuffer; if (RenameInfo->FileName[0] == L'\\') { //here, we have to carefully copy the the rename prefix PWCHAR w; PMRXPROXY_DEVICE_OBJECT MRxProxyDeviceObject = (PMRXPROXY_DEVICE_OBJECT)(RxContext->RxDeviceObject); PUNICODE_STRING RenamePrefix = &MRxProxyDeviceObject->PrefixForRename; ULONG prefixlength; MRxProxyDumpRenameInfo("Before:",RenameInfo,BufferLength); prefixlength = (RenamePrefix->Length)/sizeof(WCHAR); w = (&(RenameInfo->FileName[0])) + ((RenameInfo->FileNameLength)/sizeof(WCHAR)); for (;;) { w--; //DbgPrint ("yaya %c\n",*w); *(w+prefixlength) = *w; if ( w == (&(RenameInfo->FileName[0])) ) { break; } } RtlCopyMemory(&(RenameInfo->FileName[0]),RenamePrefix->Buffer,RenamePrefix->Length); RenameInfo->FileNameLength += RenamePrefix->Length; BufferLength += RenamePrefix->Length; MRxProxyDumpRenameInfo(" After:",RenameInfo,BufferLength); //DbgBreakPoint(); } } if(BufferLength==0){ //zero length means that this is the special calldown from the cachemanager...for now just boost //joejoe this should be fixed soon BufferLength = sizeof(FILE_END_OF_FILE_INFORMATION); } RxDbgTrace( 0, Dbg, (" ---->UserBuffer = %08lx\n", pBuffer)); ASSERT (UnderlyingFileObject); //this could be a setfileinfo that comes in from the lazywriter //after the underlying file has already been cleaned up //BUGBUG not too sure about this........... if (UnderlyingFileObject == NULL) { Status = STATUS_FILE_CLOSED; RxDbgTrace(-1, Dbg, (" ---->AlreadyClosed!!! Status = %08lx\n", Status)); return(Status); } Status = MRxProxySyncXxxInformation( RxContext, //IN OUT PRX_CONTEXT RxContext, IRP_MJ_SET_INFORMATION, //IN UCHAR MajorFunction, UnderlyingFileObject, //IN PFILE_OBJECT FileObject, FileInformationClass, //IN ULONG InformationClass, BufferLength, //IN ULONG Length, pBuffer, //OUT PVOID Information, NULL //OUT PULONG ReturnedLength OPTIONAL ); if (!NT_SUCCESS(Status)) { RxDbgTrace( 0, Dbg, ("MRxProxySetFile: Failed .. returning %lx\n",Status)); } RxDbgTraceUnIndent(-1,Dbg); return Status; } NTSTATUS MRxProxySetFileInformationAtCleanup( IN PRX_CONTEXT RxContext ) /*++ Routine Description: This routine sets the file information on cleanup. rdrs just swallow this operation (i.e. it doesn't generate it). we cannot do the same because we are local.......... This routine implements the set file info call called on cleanup or flush. We dont actually set the times but we do the endoffile info. Arguments: pRxContext - the RDBSS context Return Value: RXSTATUS - The return status for the operation --*/ { NTSTATUS Status; FILE_INFORMATION_CLASS FileInformationClass; TURN_BACK_ASYNCHRONOUS_OPERATIONS(); FileInformationClass = RxContext->Info.FileInformationClass; if (FileInformationClass == FileBasicInformation) { return(STATUS_SUCCESS); } RxDbgTrace(+1, Dbg, ("MRxLocalSetFileInfoAtCleanup...\n")); Status = MRxProxySetFileInformation(RxContext); RxDbgTrace(-1, Dbg, ("MRxLocalSetFileInfoAtCleanup...status =%08lx\n", Status)); }