From 9399093a767c0638ee247d89d5f8f70b518b9396 Mon Sep 17 00:00:00 2001 From: Peter Scott Date: Thu, 15 Sep 2011 01:33:20 -0400 Subject: [PATCH] Windows: RDR File System Framework driver This is the first of two kernel drivers used to implement the AFS Redirector: AFSRedir.sys. This driver is registered at boot time and provides the binding to the Windows kernel infrastructure. However, it only provides a framework of a file system driver. All of the AFS specific interfaces are actually implemented in a secondary library driver, AFSRedirLib.sys. The rationale for this model is that file system drivers cannot be unloaded on a running system. By using this approach the library driver can be unloaded which permits systems to be live updated. To permit this model to work, all memory allocation is performed by AFSRedir.sys. This confuses the driver verifier tool. When the library is unloaded all objects are still valid. Operation is simply paused until a new library is brought up. Under the current configuration the library is loaded as part of afsd_service initialization of AFSRedir.sys and is automatically unloaded when afsd_service.exe shuts down. The framework driver also implements all of the process and thread tracking logic necessary to support Authentication Groups. Communication between AFSRedir.sys and afsd_service.exe is performed via a reverse ioctl model whereby the service contributes threads to the driver to convey requests for processing. The original file system was derived from the Kernel Drivers File System under license from Kernel Drivers, LLC. Rod Widdowson and Jeffrey Altman contributed to the development of this driver. Change-Id: Ic123cacd868ddde31d66bf17d3ad2a13c22cd1f4 Reviewed-on: http://gerrit.openafs.org/5437 Tested-by: BuildBot Reviewed-by: Rod Widdowson Tested-by: Rod Widdowson Reviewed-by: Jeffrey Altman Tested-by: Jeffrey Altman --- .../afsrdr/kernel/fs/AFSAuthGroupSupport.cpp | 1736 ++++++++++++++ .../afsrdr/kernel/fs/AFSBTreeSupport.cpp | 413 ++++ src/WINNT/afsrdr/kernel/fs/AFSCleanup.cpp | 202 ++ src/WINNT/afsrdr/kernel/fs/AFSClose.cpp | 151 ++ src/WINNT/afsrdr/kernel/fs/AFSCommSupport.cpp | 1591 +++++++++++++ src/WINNT/afsrdr/kernel/fs/AFSCreate.cpp | 264 +++ src/WINNT/afsrdr/kernel/fs/AFSData.cpp | 123 + src/WINNT/afsrdr/kernel/fs/AFSDevControl.cpp | 90 + src/WINNT/afsrdr/kernel/fs/AFSDirControl.cpp | 119 + src/WINNT/afsrdr/kernel/fs/AFSEa.cpp | 191 ++ src/WINNT/afsrdr/kernel/fs/AFSFSControl.cpp | 108 + .../afsrdr/kernel/fs/AFSFastIoSupport.cpp | 510 ++++ src/WINNT/afsrdr/kernel/fs/AFSFileInfo.cpp | 232 ++ .../afsrdr/kernel/fs/AFSFlushBuffers.cpp | 98 + src/WINNT/afsrdr/kernel/fs/AFSGeneric.cpp | 2050 +++++++++++++++++ src/WINNT/afsrdr/kernel/fs/AFSInit.cpp | 503 ++++ .../kernel/fs/AFSInternalDevControl.cpp | 67 + .../afsrdr/kernel/fs/AFSLibrarySupport.cpp | 923 ++++++++ src/WINNT/afsrdr/kernel/fs/AFSLockControl.cpp | 108 + src/WINNT/afsrdr/kernel/fs/AFSLogSupport.cpp | 756 ++++++ .../kernel/fs/AFSNetworkProviderSupport.cpp | 456 ++++ .../afsrdr/kernel/fs/AFSProcessSupport.cpp | 812 +++++++ src/WINNT/afsrdr/kernel/fs/AFSQuota.cpp | 104 + src/WINNT/afsrdr/kernel/fs/AFSRDRSupport.cpp | 793 +++++++ src/WINNT/afsrdr/kernel/fs/AFSRead.cpp | 111 + .../afsrdr/kernel/fs/AFSRedirInstall.inf | 84 + src/WINNT/afsrdr/kernel/fs/AFSSecurity.cpp | 217 ++ src/WINNT/afsrdr/kernel/fs/AFSShutdown.cpp | 100 + .../afsrdr/kernel/fs/AFSSystemControl.cpp | 72 + src/WINNT/afsrdr/kernel/fs/AFSVolumeInfo.cpp | 141 ++ src/WINNT/afsrdr/kernel/fs/AFSWrite.cpp | 115 + src/WINNT/afsrdr/kernel/fs/Filesystem.rc | 15 + .../afsrdr/kernel/fs/Include/AFSCommon.h | 809 +++++++ .../afsrdr/kernel/fs/Include/AFSDefines.h | 348 +++ .../afsrdr/kernel/fs/Include/AFSExtern.h | 108 + .../afsrdr/kernel/fs/Include/AFSStructs.h | 137 ++ src/WINNT/afsrdr/kernel/fs/MAKEFILE | 6 + src/WINNT/afsrdr/kernel/fs/sources | 46 + 38 files changed, 14709 insertions(+) create mode 100644 src/WINNT/afsrdr/kernel/fs/AFSAuthGroupSupport.cpp create mode 100644 src/WINNT/afsrdr/kernel/fs/AFSBTreeSupport.cpp create mode 100644 src/WINNT/afsrdr/kernel/fs/AFSCleanup.cpp create mode 100644 src/WINNT/afsrdr/kernel/fs/AFSClose.cpp create mode 100644 src/WINNT/afsrdr/kernel/fs/AFSCommSupport.cpp create mode 100644 src/WINNT/afsrdr/kernel/fs/AFSCreate.cpp create mode 100644 src/WINNT/afsrdr/kernel/fs/AFSData.cpp create mode 100644 src/WINNT/afsrdr/kernel/fs/AFSDevControl.cpp create mode 100644 src/WINNT/afsrdr/kernel/fs/AFSDirControl.cpp create mode 100644 src/WINNT/afsrdr/kernel/fs/AFSEa.cpp create mode 100644 src/WINNT/afsrdr/kernel/fs/AFSFSControl.cpp create mode 100644 src/WINNT/afsrdr/kernel/fs/AFSFastIoSupport.cpp create mode 100644 src/WINNT/afsrdr/kernel/fs/AFSFileInfo.cpp create mode 100644 src/WINNT/afsrdr/kernel/fs/AFSFlushBuffers.cpp create mode 100644 src/WINNT/afsrdr/kernel/fs/AFSGeneric.cpp create mode 100644 src/WINNT/afsrdr/kernel/fs/AFSInit.cpp create mode 100644 src/WINNT/afsrdr/kernel/fs/AFSInternalDevControl.cpp create mode 100644 src/WINNT/afsrdr/kernel/fs/AFSLibrarySupport.cpp create mode 100644 src/WINNT/afsrdr/kernel/fs/AFSLockControl.cpp create mode 100644 src/WINNT/afsrdr/kernel/fs/AFSLogSupport.cpp create mode 100644 src/WINNT/afsrdr/kernel/fs/AFSNetworkProviderSupport.cpp create mode 100644 src/WINNT/afsrdr/kernel/fs/AFSProcessSupport.cpp create mode 100644 src/WINNT/afsrdr/kernel/fs/AFSQuota.cpp create mode 100644 src/WINNT/afsrdr/kernel/fs/AFSRDRSupport.cpp create mode 100644 src/WINNT/afsrdr/kernel/fs/AFSRead.cpp create mode 100644 src/WINNT/afsrdr/kernel/fs/AFSRedirInstall.inf create mode 100644 src/WINNT/afsrdr/kernel/fs/AFSSecurity.cpp create mode 100644 src/WINNT/afsrdr/kernel/fs/AFSShutdown.cpp create mode 100644 src/WINNT/afsrdr/kernel/fs/AFSSystemControl.cpp create mode 100644 src/WINNT/afsrdr/kernel/fs/AFSVolumeInfo.cpp create mode 100644 src/WINNT/afsrdr/kernel/fs/AFSWrite.cpp create mode 100644 src/WINNT/afsrdr/kernel/fs/Filesystem.rc create mode 100644 src/WINNT/afsrdr/kernel/fs/Include/AFSCommon.h create mode 100644 src/WINNT/afsrdr/kernel/fs/Include/AFSDefines.h create mode 100644 src/WINNT/afsrdr/kernel/fs/Include/AFSExtern.h create mode 100644 src/WINNT/afsrdr/kernel/fs/Include/AFSStructs.h create mode 100644 src/WINNT/afsrdr/kernel/fs/MAKEFILE create mode 100644 src/WINNT/afsrdr/kernel/fs/sources diff --git a/src/WINNT/afsrdr/kernel/fs/AFSAuthGroupSupport.cpp b/src/WINNT/afsrdr/kernel/fs/AFSAuthGroupSupport.cpp new file mode 100644 index 0000000000..4eb31a1160 --- /dev/null +++ b/src/WINNT/afsrdr/kernel/fs/AFSAuthGroupSupport.cpp @@ -0,0 +1,1736 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC. + * Copyright (c) 2009, 2010, 2011 Your File System, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, + * this list of conditions and the following disclaimer in the + * documentation + * and/or other materials provided with the distribution. + * - Neither the names of Kernel Drivers, LLC and Your File System, Inc. + * nor the names of their contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission from Kernel Drivers, LLC and Your File System, Inc. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +// +// File: AFSAuthGroupSupport.cpp +// + +#include "AFSCommon.h" + +void +AFSRetrieveAuthGroup( IN ULONGLONG ProcessId, + IN ULONGLONG ThreadId, + OUT GUID *AuthGroup) +{ + + NTSTATUS ntStatus = STATUS_SUCCESS; + AFSProcessCB *pProcessCB = NULL; + AFSThreadCB *pThreadCB = NULL; + AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension; + GUID *pAuthGroup = NULL; + UNICODE_STRING uniGUIDString; + ULONG ulSessionId = 0; + BOOLEAN bImpersonation = FALSE; + + __Enter + { + + ulSessionId = AFSGetSessionId( (HANDLE)ProcessId, &bImpersonation); + + if( ulSessionId == (ULONG)-1) + { + + AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, + AFS_TRACE_LEVEL_ERROR, + "%s Failed to retrieve session ID for PID %I64X\n", + __FUNCTION__, + ProcessId); + + try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES); + } + + AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "%s Entry for Session %08lX PID %I64X TID %I64X\n", + __FUNCTION__, + ulSessionId, + ProcessId, + ThreadId); + + ntStatus = AFSCheckThreadDacl( AuthGroup); + + if( NT_SUCCESS( ntStatus)) + { + + uniGUIDString.Buffer = NULL; + uniGUIDString.Length = 0; + uniGUIDString.MaximumLength = 0; + + RtlStringFromGUID( *AuthGroup, + &uniGUIDString); + + AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "%s Located AuthGroup %wZ via DACL for Session %08lX PID %I64X TID %I64X\n", + __FUNCTION__, + &uniGUIDString, + ulSessionId, + ProcessId, + ThreadId); + + if( uniGUIDString.Buffer != NULL) + { + RtlFreeUnicodeString( &uniGUIDString); + } + + try_return( ntStatus = STATUS_SUCCESS); + } + + AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "AFSRetrieveAuthGroup Acquiring Control ProcessTree.TreeLock lock %08lX SHARED %08lX\n", + pDeviceExt->Specific.Control.ProcessTree.TreeLock, + PsGetCurrentThread()); + + ntStatus = STATUS_SUCCESS; + + AFSAcquireShared( pDeviceExt->Specific.Control.ProcessTree.TreeLock, + TRUE); + + ntStatus = AFSLocateHashEntry( pDeviceExt->Specific.Control.ProcessTree.TreeHead, + (ULONGLONG)ProcessId, + (AFSBTreeEntry **)&pProcessCB); + + if( !NT_SUCCESS( ntStatus) || + pProcessCB == NULL) + { + + AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, + AFS_TRACE_LEVEL_ERROR, + "%s Failed to locate process entry for Session %08lX PID %I64X TID %I64X\n", + __FUNCTION__, + ulSessionId, + ProcessId, + ThreadId); + + AFSReleaseResource( pDeviceExt->Specific.Control.ProcessTree.TreeLock); + try_return( ntStatus); + } + + for ( pThreadCB = pProcessCB->ThreadList; + pThreadCB != NULL; + pThreadCB = pThreadCB->Next) + { + + if( pThreadCB->ThreadId == ThreadId) + { + break; + } + } + + if( pThreadCB != NULL && + pThreadCB->ActiveAuthGroup != NULL) + { + pAuthGroup = pThreadCB->ActiveAuthGroup; + + RtlCopyMemory( AuthGroup, + pAuthGroup, + sizeof( GUID)); + + uniGUIDString.Buffer = NULL; + uniGUIDString.Length = 0; + uniGUIDString.MaximumLength = 0; + + RtlStringFromGUID( *AuthGroup, + &uniGUIDString); + + AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "%s Located AuthGroup %wZ in thread Session %08lX PID %I64X TID %I64X\n", + __FUNCTION__, + &uniGUIDString, + ulSessionId, + ProcessId, + ThreadId); + + if( uniGUIDString.Buffer != NULL) + { + RtlFreeUnicodeString( &uniGUIDString); + } + } + else if( pProcessCB->ActiveAuthGroup != NULL) + { + + pAuthGroup = pProcessCB->ActiveAuthGroup; + + RtlCopyMemory( AuthGroup, + pAuthGroup, + sizeof( GUID)); + + uniGUIDString.Buffer = NULL; + uniGUIDString.Length = 0; + uniGUIDString.MaximumLength = 0; + + RtlStringFromGUID( *AuthGroup, + &uniGUIDString); + + AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "%s Located AuthGroup %wZ in process Session %08lX PID %I64X TID %I64X\n", + __FUNCTION__, + &uniGUIDString, + ulSessionId, + ProcessId, + ThreadId); + + if( uniGUIDString.Buffer != NULL) + { + RtlFreeUnicodeString( &uniGUIDString); + } + } + + AFSReleaseResource( pDeviceExt->Specific.Control.ProcessTree.TreeLock); + + if( pAuthGroup == NULL || + AFSIsNoPAGAuthGroup( pAuthGroup)) + { + + AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "%s No AuthGroup located, validating process for Session %08lX PID %I64X TID %I64X\n", + __FUNCTION__, + ulSessionId, + ProcessId, + ThreadId); + + pAuthGroup = AFSValidateProcessEntry(); + + if( pAuthGroup != NULL) + { + RtlCopyMemory( AuthGroup, + pAuthGroup, + sizeof( GUID)); + + uniGUIDString.Buffer = NULL; + uniGUIDString.Length = 0; + uniGUIDString.MaximumLength = 0; + + RtlStringFromGUID( *AuthGroup, + &uniGUIDString); + + AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "%s Located AuthGroup %wZ after validation Session %08lX PID %I64X TID %I64X\n", + __FUNCTION__, + &uniGUIDString, + ulSessionId, + ProcessId, + ThreadId); + + if( uniGUIDString.Buffer != NULL) + { + RtlFreeUnicodeString( &uniGUIDString); + } + } + else + { + AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, + AFS_TRACE_LEVEL_ERROR, + "%s Failed to locate AuthGroup for Session %08lX PID %I64X TID %I64X\n", + __FUNCTION__, + ulSessionId, + ProcessId, + ThreadId); + } + } + +try_exit: + + NOTHING; + } + + return; +} + +// +// AFSIsLocalSystemAuthGroup returns TRUE if the AuthGroup matches +// the AuthGroup associated with the first process that communicates +// with the redirector which will always be "System" (PID 4). +// + +BOOLEAN +AFSIsLocalSystemAuthGroup( IN GUID *AuthGroup) +{ + + BOOLEAN bIsLocalSys = FALSE; + AFSProcessCB *pProcessCB = NULL; + AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension; + UNICODE_STRING uniGUIDString; + + __Enter + { + + uniGUIDString.Length = 0; + uniGUIDString.MaximumLength = 0; + uniGUIDString.Buffer = NULL; + + RtlStringFromGUID( *AuthGroup, + &uniGUIDString); + + AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE_2, + "%s Checking AuthGroup %wZ\n", + __FUNCTION__, + &uniGUIDString); + + AFSAcquireShared( pDeviceExt->Specific.Control.ProcessTree.TreeLock, + TRUE); + + pProcessCB = (AFSProcessCB *)pDeviceExt->Specific.Control.ProcessTree.TreeHead; + + if( pProcessCB->ActiveAuthGroup != NULL && + RtlCompareMemory( pProcessCB->ActiveAuthGroup, + AuthGroup, + sizeof( GUID)) == sizeof( GUID)) + { + bIsLocalSys = TRUE; + + AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "%s AuthGroup %wZ is LOCAL SYSTEM\n", + __FUNCTION__, + &uniGUIDString); + } + + AFSReleaseResource( pDeviceExt->Specific.Control.ProcessTree.TreeLock); + + if( uniGUIDString.Buffer != NULL) + { + RtlFreeUnicodeString( &uniGUIDString); + } + } + + return bIsLocalSys; +} + +BOOLEAN +AFSIsLocalSystemSID( IN UNICODE_STRING *SIDString) +{ + + BOOLEAN bIsLocalSys = FALSE; + UNICODE_STRING uniSysLocal; + + __Enter + { + + RtlInitUnicodeString( &uniSysLocal, + L"S-1-5-18"); + + if( RtlCompareUnicodeString( &uniSysLocal, + SIDString, + TRUE) == 0) + { + bIsLocalSys = TRUE; + } + + AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE_2, + "%s AuthGroup SID %wZ is %sLOCAL SYSTEM\n", + __FUNCTION__, + SIDString, + bIsLocalSys ? "" : "not "); + } + + return bIsLocalSys; +} + +BOOLEAN +AFSIsNoPAGAuthGroup( IN GUID *AuthGroup) +{ + + BOOLEAN bIsNoPAG = FALSE; + UNICODE_STRING uniGUIDString; + + __Enter + { + + uniGUIDString.Length = 0; + uniGUIDString.MaximumLength = 0; + uniGUIDString.Buffer = NULL; + + RtlStringFromGUID( *AuthGroup, + &uniGUIDString); + + if( RtlCompareMemory( AuthGroup, + &AFSNoPAGAuthGroup, + sizeof( GUID)) == sizeof( GUID)) + { + bIsNoPAG = TRUE; + } + + AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE_2, + "%s AuthGroup %wZ is %sNoPAG\n", + __FUNCTION__, + &uniGUIDString, + bIsNoPAG ? "" : "not "); + + if( uniGUIDString.Buffer != NULL) + { + RtlFreeUnicodeString( &uniGUIDString); + } + } + + return bIsNoPAG; +} + +// +// Creates a new AuthGroup and either activates it for +// the process or the current thread. If set as the +// new process AuthGroup, the prior AuthGroup list is +// cleared. +// + +NTSTATUS +AFSCreateSetProcessAuthGroup( AFSAuthGroupRequestCB *CreateSetAuthGroup) +{ + + NTSTATUS ntStatus = STATUS_SUCCESS; + AFSProcessCB *pProcessCB = NULL; + AFSThreadCB *pThreadCB = NULL; + AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension; + ULONGLONG ullProcessID = (ULONGLONG)PsGetCurrentProcessId(); + ULONGLONG ullThreadId = (ULONGLONG)PsGetCurrentThreadId(); + UNICODE_STRING uniSIDString, uniPassedSIDString; + ULONG ulSIDHash = 0; + AFSProcessAuthGroupCB *pAuthGroup = NULL, *pLastAuthGroup = NULL; + ULONG ulSessionId = 0; + ULONGLONG ullTableHash = 0; + GUID stAuthGroup; + UNICODE_STRING uniCallerSID; + BOOLEAN bImpersonation = FALSE; + + __Enter + { + + uniCallerSID.Length = 0; + uniCallerSID.MaximumLength = 0; + uniCallerSID.Buffer = NULL; + + AFSAcquireShared( pDeviceExt->Specific.Control.ProcessTree.TreeLock, + TRUE); + + ntStatus = AFSLocateHashEntry( pDeviceExt->Specific.Control.ProcessTree.TreeHead, + (ULONGLONG)ullProcessID, + (AFSBTreeEntry **)&pProcessCB); + + if( !NT_SUCCESS( ntStatus) || + pProcessCB == NULL) + { + + AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, + AFS_TRACE_LEVEL_ERROR, + "%s Failed to locate process CB for PID %I64X\n", + __FUNCTION__, + ullProcessID); + + AFSReleaseResource( pDeviceExt->Specific.Control.ProcessTree.TreeLock); + try_return( ntStatus = STATUS_UNSUCCESSFUL); + } + + AFSAcquireExcl( &pProcessCB->Lock, + TRUE); + + AFSReleaseResource( pDeviceExt->Specific.Control.ProcessTree.TreeLock); + + ntStatus = AFSGetCallerSID( &uniCallerSID, &bImpersonation); + + if( !NT_SUCCESS( ntStatus)) + { + + AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, + AFS_TRACE_LEVEL_ERROR, + "%s Failed to locate caller SID for PID %I64X Status %08lX\n", + __FUNCTION__, + ullProcessID, + ntStatus); + + try_return( ntStatus); + } + + AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "%s Retrieved caller SID %wZ for PID %I64X\n", + __FUNCTION__, + &uniCallerSID, + ullProcessID); + + + if( CreateSetAuthGroup->SIDLength != 0) + { + + uniPassedSIDString.Length = CreateSetAuthGroup->SIDLength; + uniPassedSIDString.MaximumLength = uniPassedSIDString.Length; + + uniPassedSIDString.Buffer = CreateSetAuthGroup->SIDString; + + AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "%s Validating passed SID %wZ for PID %I64X\n", + __FUNCTION__, + &uniPassedSIDString, + ullProcessID); + + if( RtlCompareUnicodeString( &uniCallerSID, + &uniPassedSIDString, + TRUE) != 0) + { + + if( !BooleanFlagOn( pProcessCB->Flags, AFS_PROCESS_LOCAL_SYSTEM_AUTH)) + { + + AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, + AFS_TRACE_LEVEL_ERROR, + "%s Caller specified SID %wZ for PID %I64X but caller is not LOCAL SYSTEM AUTHORITY\n", + __FUNCTION__, + &uniPassedSIDString, + ullProcessID); + + try_return( ntStatus = STATUS_ACCESS_DENIED); + } + + uniSIDString = uniPassedSIDString; + + AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "%s Using passed SID %wZ for PID %I64X\n", + __FUNCTION__, + &uniSIDString, + ullProcessID); + } + else + { + uniSIDString = uniCallerSID; + + AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "%s Caller and passed SID are equal SID %wZ for PID %I64X\n", + __FUNCTION__, + &uniSIDString, + ullProcessID); + } + } + else + { + uniSIDString = uniCallerSID; + + AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "%s No SID passed, using callers SID %wZ for PID %I64X\n", + __FUNCTION__, + &uniSIDString, + ullProcessID); + } + + ntStatus = RtlHashUnicodeString( &uniSIDString, + TRUE, + HASH_STRING_ALGORITHM_DEFAULT, + &ulSIDHash); + + if( !NT_SUCCESS( ntStatus)) + { + + AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, + AFS_TRACE_LEVEL_ERROR, + "%s Failed to hash SID %wZ for PID %I64X Status %08lX\n", + __FUNCTION__, + &uniSIDString, + ullProcessID, + ntStatus); + + try_return( ntStatus); + } + + ulSessionId = AFSGetSessionId( (HANDLE)ullProcessID, &bImpersonation); + + if( ulSessionId == (ULONG)-1) + { + + AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, + AFS_TRACE_LEVEL_ERROR, + "%s Failed to retrieve SessionID PID %I64X Status %08lX\n", + __FUNCTION__, + ullProcessID, + ntStatus); + + try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES); + } + + if( CreateSetAuthGroup->SessionId != (ULONG)-1) + { + + AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "%s Checking passed SessionID %08lX for PID %I64X\n", + __FUNCTION__, + CreateSetAuthGroup->SessionId, + ullProcessID); + + if( ulSessionId != CreateSetAuthGroup->SessionId) + { + + if( !BooleanFlagOn( pProcessCB->Flags, AFS_PROCESS_LOCAL_SYSTEM_AUTH)) + { + + AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, + AFS_TRACE_LEVEL_ERROR, + "%s Passed SessionID %08lX for PID %I64X, failed because caller is not LOCAL SYSTEM AUTHORITY\n", + __FUNCTION__, + CreateSetAuthGroup->SessionId, + ullProcessID); + + try_return( ntStatus = STATUS_ACCESS_DENIED); + } + + ulSessionId = CreateSetAuthGroup->SessionId; + + AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "%s Using passed SessionID %08lX for PID %I64X\n", + __FUNCTION__, + ulSessionId, + ullProcessID); + } + } + else + { + AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "%s Using callers SessionID %08lX for PID %I64X\n", + __FUNCTION__, + ulSessionId, + ullProcessID); + } + + ullTableHash = ( ((ULONGLONG)ulSessionId << 32) | ulSIDHash); + + pAuthGroup = pProcessCB->AuthGroupList; + + while( pAuthGroup != NULL) + { + + if( pAuthGroup->AuthGroupHash == ullTableHash) + { + break; + } + + pLastAuthGroup = pAuthGroup; + + pAuthGroup = pAuthGroup->Next; + } + + if( pAuthGroup != NULL) + { + + AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, + AFS_TRACE_LEVEL_ERROR, + "%s Located AuthGroup for SID %wZ SessionID %08lX for PID %I64X, failing request\n", + __FUNCTION__, + &uniSIDString, + ulSessionId, + ullProcessID); + + try_return( ntStatus = STATUS_INVALID_PARAMETER); + } + + pAuthGroup = (AFSProcessAuthGroupCB *)AFSExAllocatePoolWithTag( NonPagedPool, + sizeof( AFSProcessAuthGroupCB), + AFS_AG_ENTRY_CB_TAG); + + if( pAuthGroup == NULL) + { + try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES); + } + + RtlZeroMemory( pAuthGroup, + sizeof( AFSProcessAuthGroupCB)); + + pAuthGroup->AuthGroupHash = (ULONGLONG)ullTableHash; + + while( ExUuidCreate( &pAuthGroup->AuthGroup) == STATUS_RETRY); + + if( pLastAuthGroup == NULL) + { + pProcessCB->AuthGroupList = pAuthGroup; + } + else + { + pLastAuthGroup->Next = pAuthGroup; + } + + AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "%s Allocated new AuthGroup for SID %wZ SessionID %08lX for PID %I64X\n", + __FUNCTION__, + &uniSIDString, + ulSessionId, + ullProcessID); + + if( BooleanFlagOn( CreateSetAuthGroup->Flags, AFS_PAG_FLAGS_THREAD_AUTH_GROUP)) + { + + pThreadCB = pProcessCB->ThreadList; + + while( pThreadCB != NULL) + { + + if( pThreadCB->ThreadId == ullThreadId) + { + pThreadCB->ActiveAuthGroup = &pAuthGroup->AuthGroup; + break; + } + + pThreadCB = pThreadCB->Next; + } + + if( pThreadCB == NULL) + { + + pThreadCB = AFSInitializeThreadCB( pProcessCB, + ullThreadId); + + if( pThreadCB == NULL) + { + try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES); + } + + pThreadCB->ActiveAuthGroup = &pAuthGroup->AuthGroup; + } + + AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "%s Set new AuthGroup for SID %wZ SessionID %08lX for PID %I64X on thread ID %I64X\n", + __FUNCTION__, + &uniSIDString, + ulSessionId, + ullProcessID, + ullThreadId); + } + else if( BooleanFlagOn( CreateSetAuthGroup->Flags, AFS_PAG_FLAGS_SET_AS_ACTIVE)) + { + pProcessCB->ActiveAuthGroup = &pAuthGroup->AuthGroup; + + AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "%s Set new AuthGroup for SID %wZ SessionID %08lX for PID %I64X on process\n", + __FUNCTION__, + &uniSIDString, + ulSessionId, + ullProcessID); + } + +try_exit: + + if( pProcessCB != NULL) + { + AFSReleaseResource( &pProcessCB->Lock); + } + + if( uniCallerSID.Length > 0) + { + RtlFreeUnicodeString( &uniCallerSID); + } + } + + return ntStatus; +} + +// +// Returns a list of the AuthGroup GUIDS associated +// with the current process, the current process GUID, +// and the current thread GUID. +// + +NTSTATUS +AFSQueryProcessAuthGroupList( IN GUID *GUIDList, + IN ULONG BufferLength, + OUT ULONG_PTR *ReturnLength) +{ + + NTSTATUS ntStatus = STATUS_SUCCESS; + AFSProcessCB *pProcessCB = NULL; + AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension; + ULONGLONG ullProcessID = (ULONGLONG)PsGetCurrentProcessId(); + ULONG ulRequiredLength = 0; + AFSProcessAuthGroupCB *pAuthGroup = NULL; + GUID *pCurrentGUID = GUIDList; + UNICODE_STRING uniGUIDString; + + __Enter + { + + AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "%s Entry for PID %I64X\n", + __FUNCTION__, + ullProcessID); + + AFSAcquireShared( pDeviceExt->Specific.Control.ProcessTree.TreeLock, + TRUE); + + ntStatus = AFSLocateHashEntry( pDeviceExt->Specific.Control.ProcessTree.TreeHead, + (ULONGLONG)ullProcessID, + (AFSBTreeEntry **)&pProcessCB); + + if( !NT_SUCCESS( ntStatus) || + pProcessCB == NULL) + { + + AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, + AFS_TRACE_LEVEL_ERROR, + "%s Failed to locate process entry PID %I64X\n", + __FUNCTION__, + ullProcessID); + + AFSReleaseResource( pDeviceExt->Specific.Control.ProcessTree.TreeLock); + try_return( ntStatus = STATUS_UNSUCCESSFUL); + } + + AFSAcquireShared( &pProcessCB->Lock, + TRUE); + + AFSReleaseResource( pDeviceExt->Specific.Control.ProcessTree.TreeLock); + + pAuthGroup = pProcessCB->AuthGroupList; + + ulRequiredLength = 0; + + while( pAuthGroup != NULL) + { + ulRequiredLength += sizeof( GUID); + pAuthGroup = pAuthGroup->Next; + } + + if( BufferLength == 0 || + BufferLength < ulRequiredLength || + GUIDList == NULL) + { + + AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "%s Buffer too small for query, required %08lX for PID %I64X\n", + __FUNCTION__, + ulRequiredLength, + ullProcessID); + + *ReturnLength = ulRequiredLength; + try_return( ntStatus = STATUS_BUFFER_OVERFLOW); + } + + pAuthGroup = pProcessCB->AuthGroupList; + + *ReturnLength = 0; + + while( pAuthGroup != NULL) + { + RtlCopyMemory( pCurrentGUID, + &pAuthGroup->AuthGroup, + sizeof( GUID)); + + uniGUIDString.Buffer = NULL; + uniGUIDString.Length = 0; + uniGUIDString.MaximumLength = 0; + + RtlStringFromGUID( pAuthGroup->AuthGroup, + &uniGUIDString); + + AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "%s Adding AuthGroup %wZ for PID %I64X\n", + __FUNCTION__, + &uniGUIDString, + ullProcessID); + + if( uniGUIDString.Buffer != NULL) + { + RtlFreeUnicodeString( &uniGUIDString); + } + + pCurrentGUID = (GUID *)((char *)pCurrentGUID + sizeof( GUID)); + + *ReturnLength += sizeof( GUID); + + pAuthGroup = pAuthGroup->Next; + } + +try_exit: + + if( pProcessCB != NULL) + { + AFSReleaseResource( &pProcessCB->Lock); + } + } + + return ntStatus; +} + +// +// Permits the current AuthGroup for the process or +// thread to be set to the specified GUID. The GUID +// must be in the list of current values for the process. +// + +NTSTATUS +AFSSetActiveProcessAuthGroup( IN AFSAuthGroupRequestCB *ActiveAuthGroup) +{ + + NTSTATUS ntStatus = STATUS_SUCCESS; + AFSProcessCB *pProcessCB = NULL; + AFSThreadCB *pThreadCB = NULL; + AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension; + ULONGLONG ullProcessID = (ULONGLONG)PsGetCurrentProcessId(); + ULONGLONG ullThreadId = (ULONGLONG)PsGetCurrentThreadId(); + AFSProcessAuthGroupCB *pAuthGroup = NULL; + UNICODE_STRING uniGUIDString; + + __Enter + { + + uniGUIDString.Length = 0; + uniGUIDString.MaximumLength = 0; + uniGUIDString.Buffer = NULL; + + RtlStringFromGUID( ActiveAuthGroup->AuthGroup, + &uniGUIDString); + + AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "%s Entry for ProcessID %I64X AuthGroup GUID %wZ\n", + __FUNCTION__, + ullProcessID, + &uniGUIDString); + + AFSAcquireShared( pDeviceExt->Specific.Control.ProcessTree.TreeLock, + TRUE); + + ntStatus = AFSLocateHashEntry( pDeviceExt->Specific.Control.ProcessTree.TreeHead, + (ULONGLONG)ullProcessID, + (AFSBTreeEntry **)&pProcessCB); + + if( !NT_SUCCESS( ntStatus) || + pProcessCB == NULL) + { + + AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, + AFS_TRACE_LEVEL_ERROR, + "%s Failed to locate process entry for ProcessID %I64X\n", + __FUNCTION__, + ullProcessID); + + AFSReleaseResource( pDeviceExt->Specific.Control.ProcessTree.TreeLock); + try_return( ntStatus = STATUS_UNSUCCESSFUL); + } + + + AFSAcquireExcl( &pProcessCB->Lock, + TRUE); + + AFSReleaseResource( pDeviceExt->Specific.Control.ProcessTree.TreeLock); + + pAuthGroup = pProcessCB->AuthGroupList; + + while( pAuthGroup != NULL) + { + + if( RtlCompareMemory( &ActiveAuthGroup->AuthGroup, + &pAuthGroup->AuthGroup, + sizeof( GUID)) == sizeof( GUID)) + { + break; + } + pAuthGroup = pAuthGroup->Next; + } + + if( pAuthGroup == NULL) + { + + AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "%s Failed to locate AuthGroup for ProcessID %I64X AuthGroup GUID %wZ\n", + __FUNCTION__, + ullProcessID, + &uniGUIDString); + + try_return( ntStatus = STATUS_INVALID_PARAMETER); + } + + if( BooleanFlagOn( ActiveAuthGroup->Flags, AFS_PAG_FLAGS_THREAD_AUTH_GROUP)) + { + + pThreadCB = pProcessCB->ThreadList; + + while( pThreadCB != NULL) + { + + if( pThreadCB->ThreadId == ullThreadId) + { + pThreadCB->ActiveAuthGroup = &pAuthGroup->AuthGroup; + break; + } + + pThreadCB = pThreadCB->Next; + } + + if( pThreadCB == NULL) + { + + pThreadCB = AFSInitializeThreadCB( pProcessCB, + ullThreadId); + + if( pThreadCB == NULL) + { + try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES); + } + + pThreadCB->ActiveAuthGroup = &pAuthGroup->AuthGroup; + } + + AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "%s Set active AuthGroup for ProcessID %I64X AuthGroup GUID %wZ on thread %I64X\n", + __FUNCTION__, + ullProcessID, + &uniGUIDString, + ullThreadId); + } + else + { + pProcessCB->ActiveAuthGroup = &pAuthGroup->AuthGroup; + + AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "%s Set active AuthGroup for ProcessID %I64X AuthGroup GUID %wZ on process\n", + __FUNCTION__, + ullProcessID, + &uniGUIDString); + } + +try_exit: + + if( pProcessCB != NULL) + { + AFSReleaseResource( &pProcessCB->Lock); + } + + if( uniGUIDString.Buffer != NULL) + { + RtlFreeUnicodeString( &uniGUIDString); + } + } + + return ntStatus; +} + +// +// Resets the current AuthGroup for the process or +// thread to the SID-AuthGroup +// + +NTSTATUS +AFSResetActiveProcessAuthGroup( IN IN AFSAuthGroupRequestCB *AuthGroup) +{ + + NTSTATUS ntStatus = STATUS_SUCCESS; + GUID *pAuthGroup = NULL; + AFSProcessCB *pProcessCB = NULL; + AFSThreadCB *pThreadCB = NULL; + AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension; + ULONGLONG ullProcessID = (ULONGLONG)PsGetCurrentProcessId(); + ULONGLONG ullThreadId = (ULONGLONG)PsGetCurrentThreadId(); + + __Enter + { + + AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "%s Entry for ProcessID %I64X\n", + __FUNCTION__, + ullProcessID); + + AFSAcquireShared( pDeviceExt->Specific.Control.ProcessTree.TreeLock, + TRUE); + + ntStatus = AFSLocateHashEntry( pDeviceExt->Specific.Control.ProcessTree.TreeHead, + (ULONGLONG)ullProcessID, + (AFSBTreeEntry **)&pProcessCB); + + if( !NT_SUCCESS( ntStatus) || + pProcessCB == NULL) + { + + AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, + AFS_TRACE_LEVEL_ERROR, + "%s Failed to locate AuthGroup for ProcessID %I64X\n", + __FUNCTION__, + ullProcessID); + + AFSReleaseResource( pDeviceExt->Specific.Control.ProcessTree.TreeLock); + try_return( ntStatus = STATUS_UNSUCCESSFUL); + } + + AFSAcquireExcl( &pProcessCB->Lock, + TRUE); + + AFSReleaseResource( pDeviceExt->Specific.Control.ProcessTree.TreeLock); + + if( BooleanFlagOn( AuthGroup->Flags, AFS_PAG_FLAGS_THREAD_AUTH_GROUP)) + { + + pThreadCB = pProcessCB->ThreadList; + + while( pThreadCB != NULL) + { + + if( pThreadCB->ThreadId == ullThreadId) + { + pThreadCB->ActiveAuthGroup = NULL; + break; + } + + pThreadCB = pThreadCB->Next; + } + + AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "%s Reset AuthGroup list on thread %I64X for ProcessID %I64X\n", + __FUNCTION__, + ullThreadId, + ullProcessID); + } + else + { + pProcessCB->ActiveAuthGroup = NULL; + + pThreadCB = pProcessCB->ThreadList; + + while( pThreadCB != NULL) + { + pThreadCB->ActiveAuthGroup = NULL; + pThreadCB = pThreadCB->Next; + } + + AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "%s Reset AuthGroup list on process for ProcessID %I64X\n", + __FUNCTION__, + ullProcessID); + } + + AFSReleaseResource( &pProcessCB->Lock); + +try_exit: + + NOTHING; + } + + return ntStatus; +} + +// +// When bLogonSession == FALSE, the SID must not be specified +// and the SessionId must be -1. A new AuthGroup GUID is +// assigned to the SID and SessionId of the calling Process. +// +// When bLogonSession == TRUE, the SID must be specified and +// the SessionId must not be -1. The SID of the calling process +// must be LOCAL_SYSTEM and a new AuthGroup GUID is assigned to +// the specified SID and logon session. +// + +NTSTATUS +AFSCreateAuthGroupForSIDorLogonSession( IN AFSAuthGroupRequestCB *AuthGroupRequestCB, + IN BOOLEAN bLogonSession) +{ + + NTSTATUS ntStatus = STATUS_SUCCESS; + AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension; + ULONGLONG ullProcessID = (ULONGLONG)PsGetCurrentProcessId(); + ULONGLONG ullThreadId = (ULONGLONG)PsGetCurrentThreadId(); + UNICODE_STRING uniSIDString, uniPassedSIDString; + ULONG ulSIDHash = 0; + AFSSIDEntryCB *pSIDEntryCB = NULL; + ULONG ulSessionId = 0; + ULONGLONG ullTableHash = 0; + GUID stAuthGroup; + UNICODE_STRING uniCallerSID; + UNICODE_STRING uniGUID; + BOOLEAN bLocalSystem = FALSE; + BOOLEAN bImpersonation = FALSE; + + __Enter + { + + AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "%s Entry for ProcessID %I64X ThreadID %I64X\n", + __FUNCTION__, + ullProcessID, + ullThreadId); + + ntStatus = AFSGetCallerSID( &uniCallerSID, &bImpersonation); + + if( !NT_SUCCESS( ntStatus)) + { + + AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, + AFS_TRACE_LEVEL_ERROR, + "%s Failed to retrieve callers SID for ProcessID %I64X ThreadID %I64X Status %08lX\n", + __FUNCTION__, + ullProcessID, + ullThreadId, + ntStatus); + + try_return( ntStatus); + } + + bLocalSystem = AFSIsLocalSystemSID( &uniCallerSID); + + if( bLogonSession == TRUE && + bLocalSystem == FALSE) + { + + AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, + AFS_TRACE_LEVEL_ERROR, + "%s caller is %wZ and LOCAL SYSTEM AUTHORITY required\n", + __FUNCTION__, + uniCallerSID); + + try_return( ntStatus = STATUS_ACCESS_DENIED); + } + + if ( bLogonSession == TRUE && + ( AuthGroupRequestCB == NULL || + AuthGroupRequestCB->SIDLength == 0 || + AuthGroupRequestCB->SessionId == (ULONG)-1)) + { + + AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, + AFS_TRACE_LEVEL_ERROR, + "%s SID and SessionId are mandatory\n", + __FUNCTION__); + + try_return( ntStatus = STATUS_INVALID_PARAMETER); + } + + if ( bLogonSession == FALSE && + AuthGroupRequestCB != NULL && + ( AuthGroupRequestCB->SIDLength > 0 || + AuthGroupRequestCB->SessionId != (ULONG)-1)) + { + + AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, + AFS_TRACE_LEVEL_ERROR, + "%s SID and SessionId must not be specified\n", + __FUNCTION__); + + try_return( ntStatus = STATUS_INVALID_PARAMETER); + } + + + AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "%s Retrieved callers SID %wZ for ProcessID %I64X ThreadID %I64X\n", + __FUNCTION__, + &uniCallerSID, + ullProcessID, + ullThreadId); + + if( AuthGroupRequestCB != NULL && + AuthGroupRequestCB->SIDLength != 0) + { + + uniPassedSIDString.Length = AuthGroupRequestCB->SIDLength; + uniPassedSIDString.MaximumLength = uniPassedSIDString.Length; + + uniPassedSIDString.Buffer = AuthGroupRequestCB->SIDString; + + AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "%s Checking passed SID %wZ for ProcessID %I64X ThreadID %I64X\n", + __FUNCTION__, + &uniPassedSIDString, + ullProcessID, + ullThreadId); + + if( RtlCompareUnicodeString( &uniCallerSID, + &uniPassedSIDString, + TRUE) != 0) + { + + if( !bLocalSystem) + { + + AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, + AFS_TRACE_LEVEL_ERROR, + "%s Not using passed SID %wZ for ProcessID %I64X ThreadID %I64X caller is not LOCAL SYSTEM AUTHORITY\n", + __FUNCTION__, + &uniPassedSIDString, + ullProcessID, + ullThreadId); + + try_return( ntStatus = STATUS_ACCESS_DENIED); + } + + uniSIDString = uniPassedSIDString; + + AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "%s Using passed SID %wZ for ProcessID %I64X ThreadID %I64X\n", + __FUNCTION__, + &uniSIDString, + ullProcessID, + ullThreadId); + } + else + { + uniSIDString = uniCallerSID; + + AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "%s Both SIDs are equal, using callers SID %wZ for ProcessID %I64X ThreadID %I64X\n", + __FUNCTION__, + &uniSIDString, + ullProcessID, + ullThreadId); + } + } + else + { + uniSIDString = uniCallerSID; + + AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "%s Using callers SID %wZ for ProcessID %I64X ThreadID %I64X\n", + __FUNCTION__, + &uniSIDString, + ullProcessID, + ullThreadId); + } + + ntStatus = RtlHashUnicodeString( &uniSIDString, + TRUE, + HASH_STRING_ALGORITHM_DEFAULT, + &ulSIDHash); + + if( !NT_SUCCESS( ntStatus)) + { + + AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, + AFS_TRACE_LEVEL_ERROR, + "%s Failed to hash SID %wZ for ProcessID %I64X ThreadID %I64X Status %08lX\n", + __FUNCTION__, + &uniSIDString, + ullProcessID, + ullThreadId, + ntStatus); + + try_return( ntStatus); + } + + ulSessionId = AFSGetSessionId( (HANDLE)ullProcessID, &bImpersonation); + + if( ulSessionId == (ULONG)-1) + { + + AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, + AFS_TRACE_LEVEL_ERROR, + "%s Failed to retrieve session ID for ProcessID %I64X ThreadID %I64X\n", + __FUNCTION__, + ullProcessID, + ullThreadId); + + try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES); + } + + if( bLogonSession == TRUE && + AuthGroupRequestCB != NULL && + AuthGroupRequestCB->SessionId != (ULONG)-1) + { + + AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "%s Checking passed SessionID %08lX for ProcessID %I64X ThreadID %I64X\n", + __FUNCTION__, + AuthGroupRequestCB->SessionId, + ullProcessID, + ullThreadId); + + if( ulSessionId != AuthGroupRequestCB->SessionId) + { + + ulSessionId = AuthGroupRequestCB->SessionId; + + AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "%s Using passed SessionID %08lX for ProcessID %I64X ThreadID %I64X\n", + __FUNCTION__, + AuthGroupRequestCB->SessionId, + ullProcessID, + ullThreadId); + } + } + else + { + + AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "%s Using callers SessionID %08lX for ProcessID %I64X ThreadID %I64X\n", + __FUNCTION__, + ulSessionId, + ullProcessID, + ullThreadId); + } + + ullTableHash = ( ((ULONGLONG)ulSessionId << 32) | ulSIDHash); + + AFSAcquireExcl( pDeviceExt->Specific.Control.AuthGroupTree.TreeLock, + TRUE); + + ntStatus = AFSLocateHashEntry( pDeviceExt->Specific.Control.AuthGroupTree.TreeHead, + (ULONGLONG)ullTableHash, + (AFSBTreeEntry **)&pSIDEntryCB); + + if( NT_SUCCESS( ntStatus) && + pSIDEntryCB != NULL) + { + + AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "%s Located SID entry for SID %wZ SessionID %08lX ProcessID %I64X ThreadID %I64X, updating GUID\n", + __FUNCTION__, + &uniSIDString, + ulSessionId, + ullProcessID, + ullThreadId); + + uniGUID.Buffer = NULL; + + RtlStringFromGUID( pSIDEntryCB->AuthGroup, + &uniGUID); + + AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "%s Updating existing AuthGroup GUID %wZ\n", + __FUNCTION__, + &uniGUID); + + if( uniGUID.Buffer != NULL) + { + RtlFreeUnicodeString( &uniGUID); + } + + while( ExUuidCreate( &pSIDEntryCB->AuthGroup) == STATUS_RETRY); + + uniGUID.Buffer = NULL; + + RtlStringFromGUID( pSIDEntryCB->AuthGroup, + &uniGUID); + + AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "%s Updated existing AuthGroup GUID %wZ\n", + __FUNCTION__, + &uniGUID); + + if( uniGUID.Buffer != NULL) + { + RtlFreeUnicodeString( &uniGUID); + } + + AFSReleaseResource( pDeviceExt->Specific.Control.AuthGroupTree.TreeLock); + try_return( ntStatus); + } + + pSIDEntryCB = (AFSSIDEntryCB *)AFSExAllocatePoolWithTag( NonPagedPool, + sizeof( AFSSIDEntryCB), + AFS_AG_ENTRY_CB_TAG); + + if( pSIDEntryCB == NULL) + { + AFSReleaseResource( pDeviceExt->Specific.Control.AuthGroupTree.TreeLock); + try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES); + } + + RtlZeroMemory( pSIDEntryCB, + sizeof( AFSSIDEntryCB)); + + pSIDEntryCB->TreeEntry.HashIndex = (ULONGLONG)ullTableHash; + + while( ExUuidCreate( &pSIDEntryCB->AuthGroup) == STATUS_RETRY); + + if( pDeviceExt->Specific.Control.AuthGroupTree.TreeHead == NULL) + { + pDeviceExt->Specific.Control.AuthGroupTree.TreeHead = (AFSBTreeEntry *)pSIDEntryCB; + } + else + { + AFSInsertHashEntry( pDeviceExt->Specific.Control.AuthGroupTree.TreeHead, + &pSIDEntryCB->TreeEntry); + } + + AFSReleaseResource( pDeviceExt->Specific.Control.AuthGroupTree.TreeLock); + + uniGUID.Buffer = NULL; + + RtlStringFromGUID( pSIDEntryCB->AuthGroup, + &uniGUID); + + AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "%s Created new AuthGroup GUID %wZ SID %wZ Session %08lX\n", + __FUNCTION__, + &uniGUID, + &uniSIDString, + ulSessionId); + + if( uniGUID.Buffer != NULL) + { + RtlFreeUnicodeString( &uniGUID); + } + +try_exit: + + if( uniCallerSID.Length > 0) + { + RtlFreeUnicodeString( &uniCallerSID); + } + } + + return ntStatus; +} + +// +// Given a SID and SessionId as input, returns the associated AuthGroup GUID. +// If SID or SessionId are not specified, the current process values are used. +// + +NTSTATUS +AFSQueryAuthGroup( IN AFSAuthGroupRequestCB *AuthGroup, + OUT GUID *AuthGroupGUID, + OUT ULONG_PTR *ReturnLength) +{ + + NTSTATUS ntStatus = STATUS_SUCCESS; + AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension; + ULONGLONG ullProcessID = (ULONGLONG)PsGetCurrentProcessId(); + UNICODE_STRING uniSIDString; + ULONG ulSIDHash = 0; + AFSSIDEntryCB *pSIDEntryCB = NULL; + ULONG ulSessionId = 0; + ULONGLONG ullTableHash = 0; + BOOLEAN bReleaseSID = FALSE; + UNICODE_STRING uniGUID; + BOOLEAN bImpersonation = FALSE; + + __Enter + { + + AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "%s Entry for ProcessID %I64X\n", + __FUNCTION__, + ullProcessID); + + if( AuthGroup == NULL || + AuthGroup->SIDLength == 0) + { + + AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "%s No SID specified, retrieving callers SID for ProcessID %I64X\n", + __FUNCTION__, + ullProcessID); + + ntStatus = AFSGetCallerSID( &uniSIDString, &bImpersonation); + + if( !NT_SUCCESS( ntStatus)) + { + + AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, + AFS_TRACE_LEVEL_ERROR, + "%s Failed to retrieve callers SID for ProcessID %I64X Status %08lX\n", + __FUNCTION__, + ullProcessID, + ntStatus); + + try_return( ntStatus); + } + + bReleaseSID = TRUE; + + AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "%s Retrieved callers SID %wZ for ProcessID %I64X\n", + __FUNCTION__, + &uniSIDString, + ullProcessID); + } + else + { + + uniSIDString.Length = AuthGroup->SIDLength; + uniSIDString.MaximumLength = uniSIDString.Length; + + uniSIDString.Buffer = AuthGroup->SIDString; + + AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "%s Using passed SID %wZ for ProcessID %I64X\n", + __FUNCTION__, + &uniSIDString, + ullProcessID); + } + + ntStatus = RtlHashUnicodeString( &uniSIDString, + TRUE, + HASH_STRING_ALGORITHM_DEFAULT, + &ulSIDHash); + + if( !NT_SUCCESS( ntStatus)) + { + + AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, + AFS_TRACE_LEVEL_ERROR, + "%s Failed to hash SID %wZ for ProcessID %I64X Status %08lX\n", + __FUNCTION__, + &uniSIDString, + ullProcessID, + ntStatus); + + try_return( ntStatus); + } + + if( AuthGroup == NULL || + AuthGroup->SessionId == -1) + { + + AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "%s No SessionID specified, retrieving callers for ProcessID %I64X\n", + __FUNCTION__, + ullProcessID); + + ulSessionId = AFSGetSessionId( (HANDLE)ullProcessID, &bImpersonation); + + if( ulSessionId == (ULONG)-1) + { + + AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, + AFS_TRACE_LEVEL_ERROR, + "%s Failed to retrieve callers Session ID for ProcessID %I64X\n", + __FUNCTION__, + ullProcessID); + + try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES); + } + + AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "%s Retrieved callers SessionID %08lX for ProcessID %I64X\n", + __FUNCTION__, + ulSessionId, + ullProcessID); + } + else + { + ulSessionId = AuthGroup->SessionId; + + AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "%s Using passed SessionID %08lX for ProcessID %I64X\n", + __FUNCTION__, + ulSessionId, + ullProcessID); + } + + ullTableHash = ( ((ULONGLONG)ulSessionId << 32) | ulSIDHash); + + AFSAcquireShared( pDeviceExt->Specific.Control.AuthGroupTree.TreeLock, + TRUE); + + ntStatus = AFSLocateHashEntry( pDeviceExt->Specific.Control.AuthGroupTree.TreeHead, + (ULONGLONG)ullTableHash, + (AFSBTreeEntry **)&pSIDEntryCB); + + if( pSIDEntryCB == NULL) + { + + AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, + AFS_TRACE_LEVEL_ERROR, + "%s Failed to locate SID entry for SID %wZ SessionID %08lX ProcessID %I64X\n", + __FUNCTION__, + &uniSIDString, + ulSessionId, + ullProcessID); + + AFSReleaseResource( pDeviceExt->Specific.Control.AuthGroupTree.TreeLock); + try_return( ntStatus = STATUS_NOT_FOUND); + } + + RtlCopyMemory( AuthGroupGUID, + &pSIDEntryCB->AuthGroup, + sizeof( GUID)); + + *ReturnLength = sizeof( GUID); + + uniGUID.Buffer = NULL; + + RtlStringFromGUID( pSIDEntryCB->AuthGroup, + &uniGUID); + + AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "%s Retrieved AuthGroup GUID %wZ for ProcessID %I64X\n", + __FUNCTION__, + &uniGUID, + ullProcessID); + + if( uniGUID.Buffer != NULL) + { + RtlFreeUnicodeString( &uniGUID); + } + + AFSReleaseResource( pDeviceExt->Specific.Control.AuthGroupTree.TreeLock); + +try_exit: + + if( bReleaseSID && + uniSIDString.Length > 0) + { + RtlFreeUnicodeString( &uniSIDString); + } + } + + return ntStatus; +} diff --git a/src/WINNT/afsrdr/kernel/fs/AFSBTreeSupport.cpp b/src/WINNT/afsrdr/kernel/fs/AFSBTreeSupport.cpp new file mode 100644 index 0000000000..13bb42f711 --- /dev/null +++ b/src/WINNT/afsrdr/kernel/fs/AFSBTreeSupport.cpp @@ -0,0 +1,413 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC. + * Copyright (c) 2009, 2010, 2011 Your File System, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, + * this list of conditions and the following disclaimer in the + * documentation + * and/or other materials provided with the distribution. + * - Neither the names of Kernel Drivers, LLC and Your File System, Inc. + * nor the names of their contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission from Kernel Drivers, LLC and Your File System, Inc. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +// +// File: AFSBTreeSupport.cpp +// + +#include "AFSCommon.h" + +NTSTATUS +AFSLocateHashEntry( IN AFSBTreeEntry *TopNode, + IN ULONGLONG HashIndex, + IN OUT AFSBTreeEntry **TreeEntry) +{ + + NTSTATUS ntStatus = STATUS_SUCCESS; + AFSBTreeEntry *pEntry = NULL; + AFSBTreeEntry *pCurrentEntry = NULL; + + pCurrentEntry = TopNode; + + __Enter + { + + // + // If the rootnode passed is null then the directory is empty + // + + if( TopNode == NULL) + { + + try_return( ntStatus = STATUS_INVALID_PARAMETER); + } + + // + // If the requestor is looking for the root node itself, then return it. + // + + if( TopNode->HashIndex == HashIndex) + { + + *TreeEntry = TopNode; + + try_return( ntStatus); + } + + // + // Loop through the nodes in the tree + // + + while( pCurrentEntry != NULL) + { + + // + // Greater values are to the right link. + // + + if( HashIndex > pCurrentEntry->HashIndex) + { + + // + // Go to the next RIGHT entry, if there is one + // + + if( pCurrentEntry->rightLink != NULL) + { + + pCurrentEntry = (AFSBTreeEntry *)pCurrentEntry->rightLink; + } + else + { + + // + // Came to the end of the branch so bail + // + + pCurrentEntry = NULL; + + break; + } + } + else if( HashIndex < pCurrentEntry->HashIndex) + { + + // + // Go to the next LEFT entry, if one exists + // + + if( pCurrentEntry->leftLink != NULL) + { + + pCurrentEntry = (AFSBTreeEntry *)pCurrentEntry->leftLink; + } + else + { + + // + // End of the branch ... + // + + pCurrentEntry = NULL; + + break; + } + } + else + { + + // + // Found the entry. + // + + *TreeEntry = pCurrentEntry; + + break; + } + } + +try_exit: + + NOTHING; + } + + return ntStatus; +} + +NTSTATUS +AFSInsertHashEntry( IN AFSBTreeEntry *TopNode, + IN AFSBTreeEntry *FileIDEntry) +{ + + NTSTATUS ntStatus = STATUS_SUCCESS; + AFSBTreeEntry *pCurrentEntry = NULL; + + pCurrentEntry = TopNode; + + __Enter + { + + // + // If we have no root node then we can;t start the search. + // + + if( pCurrentEntry == NULL) + { + + AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING, + AFS_TRACE_LEVEL_WARNING, + "AFSInsertHashEntry Invalid root node\n"); + + try_return( ntStatus = STATUS_UNSUCCESSFUL); + } + + // + // Locate the branch end to insert the node + // + + while( pCurrentEntry != NULL) + { + + // + // Greater vlued indices are to the right link + // + + if( FileIDEntry->HashIndex > pCurrentEntry->HashIndex) + { + + // + // Go to the next RIGHT entry, if it exists + // + + if( pCurrentEntry->rightLink != NULL) + { + pCurrentEntry = (AFSBTreeEntry *)pCurrentEntry->rightLink; + } + else + { + + // + // Located the end of the branch line so insert the node + // + + pCurrentEntry->rightLink = (void *)FileIDEntry; + + FileIDEntry->parentLink = (void *)pCurrentEntry; + + break; + } + } + else if( FileIDEntry->HashIndex < pCurrentEntry->HashIndex) + { + + // + // Go to the next LEFT entry, if it exists + // + + if( pCurrentEntry->leftLink != NULL) + { + pCurrentEntry = (AFSBTreeEntry *)pCurrentEntry->leftLink; + } + else + { + + // + // Located the branch line end so insert the node here + // + + pCurrentEntry->leftLink = (void *)FileIDEntry; + + FileIDEntry->parentLink = (void *)pCurrentEntry; + + break; + } + } + else + { + + AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING, + AFS_TRACE_LEVEL_WARNING, + "AFSInsertHashEntry Attempt to re-insert a CRC %I64X\n", + FileIDEntry->HashIndex); + + ASSERT( FALSE); + + ntStatus = STATUS_UNSUCCESSFUL; + + break; + } + } + +try_exit: + + NOTHING; + } + + return ntStatus; +} + +NTSTATUS +AFSRemoveHashEntry( IN AFSBTreeEntry **TopNode, + IN AFSBTreeEntry *FileIDEntry) +{ + + NTSTATUS ntStatus = STATUS_UNSUCCESSFUL; + AFSBTreeEntry *pRightNode = NULL; + AFSBTreeEntry *pLeftNode = NULL; + AFSBTreeEntry *pCurrentNode = NULL; + AFSBTreeEntry *pParentNode = NULL; + + pRightNode = (AFSBTreeEntry *)FileIDEntry->rightLink; + pLeftNode = (AFSBTreeEntry *)FileIDEntry->leftLink; + pParentNode = (AFSBTreeEntry *)FileIDEntry->parentLink; + + __Enter + { + + if( (pRightNode == NULL) && (pLeftNode == NULL)) + { + + if( pParentNode != NULL) + { + + if( pParentNode->leftLink == FileIDEntry) + { + + pParentNode->leftLink = NULL; + } + else + { + + pParentNode->rightLink = NULL; + } + } + else + { + + // + // Removing the top node + // + + *TopNode = NULL; + } + } + else + { + + if( pRightNode != NULL) + { + + if( pParentNode != NULL) + { + + // Replace the parent node where this entry was. + if( pParentNode->rightLink == FileIDEntry) + { + + pParentNode->rightLink = pRightNode; + } + else + { + + pParentNode->leftLink = pRightNode; + } + } + else + { + + *TopNode = pRightNode; + + pRightNode->parentLink = NULL; + } + + pRightNode->parentLink = pParentNode; + } + + if( pLeftNode != NULL) + { + + // To connect the left node, we must walk the chain of the + // right nodes left side until we reach the end. + // At the end attach the leftNode + if( pRightNode != NULL) + { + + pCurrentNode = pRightNode; + + while( pCurrentNode->leftLink != NULL) + { + + pCurrentNode = (AFSBTreeEntry *)pCurrentNode->leftLink; + } + + pCurrentNode->leftLink = pLeftNode; + + pLeftNode->parentLink = pCurrentNode; + } + else + { + + if( pParentNode != NULL) + { + + // This is where we have a left node with no right node. + // So, attach the left node to the parent of + // the removed nodes branch + if( pParentNode->rightLink == FileIDEntry) + { + + pParentNode->rightLink = pLeftNode; + } + else + { + + pParentNode->leftLink = pLeftNode; + } + + pLeftNode->parentLink = pParentNode; + } + else + { + + *TopNode = pLeftNode; + + pLeftNode->parentLink = NULL; + } + } + } + } + + // + // Cleanup the just removed node + // + + FileIDEntry->leftLink = NULL; + FileIDEntry->parentLink = NULL; + FileIDEntry->rightLink = NULL; + + ntStatus = STATUS_SUCCESS; + } + + return ntStatus; +} diff --git a/src/WINNT/afsrdr/kernel/fs/AFSCleanup.cpp b/src/WINNT/afsrdr/kernel/fs/AFSCleanup.cpp new file mode 100644 index 0000000000..5209873b0e --- /dev/null +++ b/src/WINNT/afsrdr/kernel/fs/AFSCleanup.cpp @@ -0,0 +1,202 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC. + * Copyright (c) 2009, 2010, 2011 Your File System, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, + * this list of conditions and the following disclaimer in the + * documentation + * and/or other materials provided with the distribution. + * - Neither the names of Kernel Drivers, LLC and Your File System, Inc. + * nor the names of their contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission from Kernel Drivers, LLC and Your File System, Inc. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +// +// File: AFSCleanup.cpp +// + +#include "AFSCommon.h" + +// +// Function: AFSCleanup +// +// Description: +// +// This function is the IRP_MJ_CLEANUP dispatch handler +// +// Return: +// +// A status is returned for the handling of this request +// + +NTSTATUS +AFSCleanup( IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + + NTSTATUS ntStatus = STATUS_SUCCESS; + AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)DeviceObject->DeviceExtension; + IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp); + + __try + { + + // + // Set some initial variables to make processing easier + // + + if( DeviceObject == AFSDeviceObject) + { + + if( FlagOn( (ULONG_PTR)pIrpSp->FileObject->FsContext, AFS_CONTROL_INSTANCE)) + { + + // + // This is the process which was registered for the callback pool so cleanup the pool + // + + AFSCleanupIrpPool(); + } + + if( FlagOn( (ULONG_PTR)pIrpSp->FileObject->FsContext, AFS_REDIRECTOR_INSTANCE)) + { + + // + // Close the redirector + // + + AFSCloseRedirector(); + } + + AFSCompleteRequest( Irp, + ntStatus); + + try_return( ntStatus); + } + + ntStatus = AFSCommonCleanup( DeviceObject, + Irp); + +try_exit: + + NOTHING; + } + __except( AFSExceptionFilter( GetExceptionCode(), GetExceptionInformation()) ) + { + + AFSDbgLogMsg( 0, + 0, + "EXCEPTION - AFSCleanup\n"); + } + + return ntStatus; +} + +NTSTATUS +AFSCommonCleanup( IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + + NTSTATUS ntStatus = STATUS_SUCCESS; + AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)DeviceObject->DeviceExtension; + IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp); + PFILE_OBJECT pFileObject = NULL; + AFSDeviceExt *pControlDeviceExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension; + BOOLEAN bCompleteRequest = TRUE; + + __Enter + { + + // + // Set some initial variables to make processing easier + // + + pFileObject = pIrpSp->FileObject; + + if( pIrpSp->FileObject->FsContext == NULL) + { + + // + // Root open + // + + try_return( ntStatus); + } + + // + // Check the state of the library + // + + ntStatus = AFSCheckLibraryState( Irp); + + if( !NT_SUCCESS( ntStatus) || + ntStatus == STATUS_PENDING) + { + + if( ntStatus == STATUS_PENDING) + { + bCompleteRequest = FALSE; + } + + try_return( ntStatus); + } + + bCompleteRequest = FALSE; + + IoSkipCurrentIrpStackLocation( Irp); + + ntStatus = IoCallDriver( pControlDeviceExt->Specific.Control.LibraryDeviceObject, + Irp); + + // + // Indicate the library is done with the request + // + + AFSClearLibraryRequest(); + +try_exit: + + if( bCompleteRequest) + { + + if( pFileObject != NULL) + { + + // + // Setup the fileobject flags to indicate cleanup is complete. + // + + SetFlag( pFileObject->Flags, FO_CLEANUP_COMPLETE); + } + + // + // Complete the request + // + + AFSCompleteRequest( Irp, ntStatus); + } + } + + return ntStatus; +} diff --git a/src/WINNT/afsrdr/kernel/fs/AFSClose.cpp b/src/WINNT/afsrdr/kernel/fs/AFSClose.cpp new file mode 100644 index 0000000000..159dd115f4 --- /dev/null +++ b/src/WINNT/afsrdr/kernel/fs/AFSClose.cpp @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC. + * Copyright (c) 2009, 2010, 2011 Your File System, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, + * this list of conditions and the following disclaimer in the + * documentation + * and/or other materials provided with the distribution. + * - Neither the names of Kernel Drivers, LLC and Your File System, Inc. + * nor the names of their contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission from Kernel Drivers, LLC and Your File System, Inc. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +// +// File: AFSClose.cpp +// + +#include "AFSCommon.h" + +// +// Function: AFSClose +// +// Description: +// +// This function is the IRP_MJ_CLOSE dispatch handler +// +// Return: +// +// A status is returned for the handling of this request +// + +NTSTATUS +AFSClose( IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + + NTSTATUS ntStatus = STATUS_SUCCESS; + + __try + { + + if( DeviceObject == AFSDeviceObject) + { + + AFSCompleteRequest( Irp, + ntStatus); + + try_return( ntStatus); + } + + ntStatus = AFSCommonClose( DeviceObject, + Irp); + +try_exit: + + NOTHING; + } + __except( AFSExceptionFilter( GetExceptionCode(), GetExceptionInformation()) ) + { + + AFSDbgLogMsg( 0, + 0, + "EXCEPTION - AFSClose\n"); + } + + return ntStatus; +} + +NTSTATUS +AFSCommonClose( IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + + NTSTATUS ntStatus = STATUS_SUCCESS; + ULONG ulRequestType = 0; + IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp); + AFSDeviceExt *pDeviceExt = NULL; + AFSDeviceExt *pControlDeviceExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension; + + __Enter + { + + pDeviceExt = (AFSDeviceExt *)DeviceObject->DeviceExtension; + + pIrpSp = IoGetCurrentIrpStackLocation( Irp); + + if( pIrpSp->FileObject->FsContext == NULL) + { + + AFSCompleteRequest( Irp, ntStatus); + + try_return( ntStatus); + } + + // + // Check the state of the library + // + + ntStatus = AFSCheckLibraryState( Irp); + + if( !NT_SUCCESS( ntStatus) || + ntStatus == STATUS_PENDING) + { + + if( ntStatus != STATUS_PENDING) + { + AFSCompleteRequest( Irp, ntStatus); + } + + try_return( ntStatus); + } + + IoSkipCurrentIrpStackLocation( Irp); + + ntStatus = IoCallDriver( pControlDeviceExt->Specific.Control.LibraryDeviceObject, + Irp); + + // + // Indicate the library is done with the request + // + + AFSClearLibraryRequest(); + +try_exit: + + NOTHING; + } + + return ntStatus; +} diff --git a/src/WINNT/afsrdr/kernel/fs/AFSCommSupport.cpp b/src/WINNT/afsrdr/kernel/fs/AFSCommSupport.cpp new file mode 100644 index 0000000000..f803c7ef38 --- /dev/null +++ b/src/WINNT/afsrdr/kernel/fs/AFSCommSupport.cpp @@ -0,0 +1,1591 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC. + * Copyright (c) 2009, 2010, 2011 Your File System, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, + * this list of conditions and the following disclaimer in the + * documentation + * and/or other materials provided with the distribution. + * - Neither the names of Kernel Drivers, LLC and Your File System, Inc. + * nor the names of their contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission from Kernel Drivers, LLC and Your File System, Inc. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +// +// File: AFSCommSupport.cpp +// + +#include "AFSCommon.h" + +NTSTATUS +AFSReleaseFid( IN AFSFileID *FileId) +{ + + NTSTATUS ntStatus = STATUS_SUCCESS; + + __Enter + { + + ntStatus = AFSProcessRequest( AFS_REQUEST_TYPE_RELEASE_FID, + 0, + NULL, + NULL, + FileId, + NULL, + 0, + NULL, + NULL); + } + + return ntStatus; +} + +NTSTATUS +AFSProcessRequest( IN ULONG RequestType, + IN ULONG RequestFlags, + IN GUID *AuthGroup, + IN PUNICODE_STRING FileName, + IN AFSFileID *FileId, + IN void *Data, + IN ULONG DataLength, + IN OUT void *ResultBuffer, + IN OUT PULONG ResultBufferLength) +{ + + NTSTATUS ntStatus = STATUS_SUCCESS; + AFSPoolEntry stPoolEntry, *pPoolEntry = NULL; + AFSCommSrvcCB *pCommSrvc = NULL; + BOOLEAN bReleasePool = FALSE; + AFSDeviceExt *pControlDevExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension; + AFSDeviceExt *pRDRDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension; + BOOLEAN bWait = BooleanFlagOn( RequestFlags, AFS_REQUEST_FLAG_SYNCHRONOUS); + ULONG ulPoolEntryLength = 0; + BOOLEAN bDecrementCount = FALSE; + + __try + { + + if( BooleanFlagOn( pRDRDevExt->DeviceFlags, AFS_DEVICE_FLAG_REDIRECTOR_SHUTDOWN)) + { + try_return( ntStatus = STATUS_DEVICE_NOT_READY); + } + + if( InterlockedIncrement( &pControlDevExt->Specific.Control.OutstandingServiceRequestCount) == 1) + { + KeClearEvent( &pControlDevExt->Specific.Control.OutstandingServiceRequestEvent); + } + + bDecrementCount = TRUE; + + pCommSrvc = &pControlDevExt->Specific.Control.CommServiceCB; + + // + // Grab the pool resource and check the state + // + + AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "AFSProcessRequest Acquiring IrpPoolLock lock %08lX EXCL %08lX\n", + &pCommSrvc->IrpPoolLock, + PsGetCurrentThread()); + + AFSAcquireExcl( &pCommSrvc->IrpPoolLock, + TRUE); + + bReleasePool = TRUE; + + if( pCommSrvc->IrpPoolControlFlag != POOL_ACTIVE) + { + + // + // Pool not running so bail. + // + + try_return( ntStatus = STATUS_DEVICE_NOT_READY); + } + + // + // If this is an async request we need to allocate a pool entry for the request + // + + pPoolEntry = &stPoolEntry; + + if( !bWait) + { + + ASSERT( ResultBuffer == NULL); + + ulPoolEntryLength = sizeof( AFSPoolEntry) + QuadAlign( DataLength); + + if( FileName != NULL) + { + + ulPoolEntryLength += FileName->Length; + } + + pPoolEntry = (AFSPoolEntry *)AFSExAllocatePoolWithTag( NonPagedPool, + ulPoolEntryLength, + AFS_POOL_ENTRY_TAG); + + if( pPoolEntry == NULL) + { + + try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES); + } + + RtlZeroMemory( pPoolEntry, + ulPoolEntryLength); + + pPoolEntry->Data = (void *)((char *)pPoolEntry + sizeof( AFSPoolEntry)); + + pPoolEntry->FileName.Buffer = (WCHAR *)((char *)pPoolEntry->Data + DataLength); + } + else + { + + RtlZeroMemory( pPoolEntry, + sizeof( AFSPoolEntry)); + + KeInitializeEvent( &pPoolEntry->Event, + NotificationEvent, + FALSE); + } + + pPoolEntry->RequestType = RequestType; + + pPoolEntry->RequestIndex = pCommSrvc->IrpPoolRequestIndex++; + + pPoolEntry->RequestFlags = RequestFlags; + + pPoolEntry->ResultBufferLength = 0; + + if( FileId != NULL) + { + + pPoolEntry->FileId = *FileId; + } + + pPoolEntry->FileName.Length = 0; + + if( FileName != NULL) + { + + if( bWait) + { + + pPoolEntry->FileName = *FileName; + } + else + { + + pPoolEntry->FileName.Length = FileName->Length; + + pPoolEntry->FileName.MaximumLength = pPoolEntry->FileName.Length; + + RtlCopyMemory( pPoolEntry->FileName.Buffer, + FileName->Buffer, + pPoolEntry->FileName.Length); + } + } + + // + // Move in the data if there is some + // + + pPoolEntry->DataLength = DataLength; + + if( Data != NULL && + DataLength > 0) + { + + if( bWait) + { + + pPoolEntry->Data = Data; + } + else + { + + RtlCopyMemory( pPoolEntry->Data, + Data, + DataLength); + } + } + + pPoolEntry->ResultBuffer = ResultBuffer; + + pPoolEntry->ResultBufferLength = ResultBufferLength; + + // + // Store off the auth group + // + + if( AuthGroup == NULL) + { + AFSRetrieveAuthGroup( (ULONGLONG)PsGetCurrentProcessId(), + (ULONGLONG)PsGetCurrentThreadId(), + &pPoolEntry->AuthGroup); + } + else + { + RtlCopyMemory( &pPoolEntry->AuthGroup, + AuthGroup, + sizeof( GUID)); + } + + if( AFSIsLocalSystemAuthGroup( &pPoolEntry->AuthGroup)) + { + SetFlag( pPoolEntry->RequestFlags, AFS_REQUEST_LOCAL_SYSTEM_PAG); + } + + if( AFSIsNoPAGAuthGroup( &pPoolEntry->AuthGroup)) + { + AFSDbgLogMsg( 0, + 0, + "AFSProcessRequest NoPAG Auth Group %08lX\n", + PsGetCurrentThread()); + } + + // + // Indicate the type of process + // + +#ifdef AMD64 + + if( !AFSIs64BitProcess( (ULONGLONG)PsGetCurrentProcessId())) + { + SetFlag( pPoolEntry->RequestFlags, AFS_REQUEST_FLAG_WOW64); + } + +#endif + + // + // Insert the entry into the request pool + // + + ntStatus = AFSInsertRequest( pCommSrvc, + pPoolEntry); + + if( !NT_SUCCESS( ntStatus)) + { + + if( !bWait) + { + + ExFreePool( pPoolEntry); + } + + try_return( ntStatus); + } + + // + // Drop the lock on the pool prior to waiting + // + + AFSReleaseResource( &pCommSrvc->IrpPoolLock); + + bReleasePool = FALSE; + + // + // Wait for the result if this is NOT an asynchronous request + // + + if( bWait) + { + + // + // Wait for the result of the request. We specify no timeout ... + // + + ntStatus = KeWaitForSingleObject( &pPoolEntry->Event, + Executive, + KernelMode, + FALSE, + NULL); + + // + // Process the result of the request + // + + if( ntStatus == STATUS_SUCCESS) + { + + ntStatus = pPoolEntry->ResultStatus; + } + else + { + + ntStatus = STATUS_DEVICE_NOT_READY; + } + } + +try_exit: + + if( bReleasePool) + { + + AFSReleaseResource( &pCommSrvc->IrpPoolLock); + } + + if( bDecrementCount && + InterlockedDecrement( &pControlDevExt->Specific.Control.OutstandingServiceRequestCount) == 0) + { + KeSetEvent( &pControlDevExt->Specific.Control.OutstandingServiceRequestEvent, + 0, + FALSE); + } + } + __except( AFSExceptionFilter( GetExceptionCode(), GetExceptionInformation())) + { + + if( bReleasePool) + { + + AFSReleaseResource( &pCommSrvc->IrpPoolLock); + } + + if( bDecrementCount && + InterlockedDecrement( &pControlDevExt->Specific.Control.OutstandingServiceRequestCount) == 0) + { + KeSetEvent( &pControlDevExt->Specific.Control.OutstandingServiceRequestEvent, + 0, + FALSE); + } + + if ( ntStatus == STATUS_SUCCESS) + { + + ntStatus = STATUS_UNSUCCESSFUL; + } + } + + return ntStatus; +} + +NTSTATUS +AFSProcessControlRequest( IN PIRP Irp) +{ + + NTSTATUS ntStatus = STATUS_SUCCESS; + PIO_STACK_LOCATION pIrpSp; + ULONG ulIoControlCode; + BOOLEAN bCompleteRequest = TRUE; + AFSDeviceExt *pDevExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension; + ULONG ulBytesProcessed = 0; + + __try + { + + pIrpSp = IoGetCurrentIrpStackLocation( Irp); + + ulIoControlCode = pIrpSp->Parameters.DeviceIoControl.IoControlCode; + + switch( ulIoControlCode) + { + + case IOCTL_AFS_INITIALIZE_CONTROL_DEVICE: + { + + // + // Go intialize the pool + // + + ntStatus = AFSInitIrpPool(); + + if( !NT_SUCCESS( ntStatus)) + { + + // + // Don't initialize + // + + break; + } + + // + // Tag this instance as the one to close the irp pool when it is closed + // + + pIrpSp->FileObject->FsContext = (void *)((ULONG_PTR)pIrpSp->FileObject->FsContext | AFS_CONTROL_INSTANCE); + + break; + } + + case IOCTL_AFS_INITIALIZE_REDIRECTOR_DEVICE: + { + + AFSRedirectorInitInfo *pRedirInitInfo = (AFSRedirectorInitInfo *)Irp->AssociatedIrp.SystemBuffer; + + // + // Extract off the passed in information which contains the + // cache file parameters + // + + if( pIrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof( AFSRedirectorInitInfo) || + pIrpSp->Parameters.DeviceIoControl.InputBufferLength < (ULONG)FIELD_OFFSET( AFSRedirectorInitInfo, CacheFileName) + + pRedirInitInfo->CacheFileNameLength) + { + + ntStatus = STATUS_INVALID_PARAMETER; + + break; + } + + // + // Initialize the Redirector device + // + + ntStatus = AFSInitializeRedirector( pRedirInitInfo); + + if( !NT_SUCCESS( ntStatus)) + { + + break; + } + + // + // Stash away context so we know the instance used to initialize the redirector + // + + pIrpSp->FileObject->FsContext = (void *)((ULONG_PTR)pIrpSp->FileObject->FsContext | AFS_REDIRECTOR_INSTANCE); + + break; + } + + case IOCTL_AFS_PROCESS_IRP_REQUEST: + { + + ntStatus = AFSProcessIrpRequest( Irp); + + break; + } + + case IOCTL_AFS_PROCESS_IRP_RESULT: + { + + ntStatus = AFSProcessIrpResult( Irp); + + break; + } + + case IOCTL_AFS_SYSNAME_NOTIFICATION: + { + + AFSSysNameNotificationCB *pSysNameInfo = (AFSSysNameNotificationCB *)Irp->AssociatedIrp.SystemBuffer; + + if( pSysNameInfo == NULL || + pIrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof( AFSSysNameNotificationCB)) + { + + ntStatus = STATUS_INVALID_PARAMETER; + + break; + } + + ntStatus = AFSSetSysNameInformation( pSysNameInfo, + pIrpSp->Parameters.DeviceIoControl.InputBufferLength); + + break; + } + + case IOCTL_AFS_CONFIGURE_DEBUG_TRACE: + { + + AFSTraceConfigCB *pTraceInfo = (AFSTraceConfigCB *)Irp->AssociatedIrp.SystemBuffer; + + if( pTraceInfo == NULL || + pIrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof( AFSTraceConfigCB)) + { + + ntStatus = STATUS_INVALID_PARAMETER; + + break; + } + + ntStatus = AFSConfigureTrace( pTraceInfo); + + break; + } + + case IOCTL_AFS_GET_TRACE_BUFFER: + { + + if( pIrpSp->Parameters.DeviceIoControl.OutputBufferLength == 0) + { + + ntStatus = STATUS_INVALID_PARAMETER; + + break; + } + + ntStatus = AFSGetTraceBuffer( pIrpSp->Parameters.DeviceIoControl.OutputBufferLength, + Irp->AssociatedIrp.SystemBuffer, + &Irp->IoStatus.Information); + + break; + } + + case IOCTL_AFS_FORCE_CRASH: + { + +#if DBG + + if( BooleanFlagOn( AFSDebugFlags, AFS_DBG_FLAG_ENABLE_FORCE_CRASH)) + { + + KeBugCheck( (ULONG)-1); + } +#endif + + break; + } + +#ifdef NOT_IMPLEMENTED + case IOCTL_AFS_LOAD_LIBRARY: + { + + AFSLoadLibraryCB *pLoadLib = (AFSLoadLibraryCB *)Irp->AssociatedIrp.SystemBuffer; + UNICODE_STRING uniServicePath; + + if( pLoadLib == NULL || + pIrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof( AFSLoadLibraryCB) || + pIrpSp->Parameters.DeviceIoControl.InputBufferLength < (ULONG)FIELD_OFFSET( AFSLoadLibraryCB, LibraryServicePath) + + pLoadLib->LibraryServicePathLength) + { + + ntStatus = STATUS_INVALID_PARAMETER; + + break; + } + + uniServicePath.Length = pLoadLib->LibraryServicePathLength; + uniServicePath.MaximumLength = uniServicePath.Length; + + uniServicePath.Buffer = pLoadLib->LibraryServicePath; + + if( uniServicePath.Length == 0) + { + + ntStatus = STATUS_INVALID_PARAMETER; + + break; + } + + ntStatus = AFSLoadLibrary( pLoadLib->Flags, + &uniServicePath); + + if( NT_SUCCESS( ntStatus)) + { + + // + // Intialize the library + // + + ntStatus = AFSInitializeLibrary( NULL, + FALSE); + } + + break; + } + + case IOCTL_AFS_UNLOAD_LIBRARY: + { + + // + // Try to unload the library we currently have in place + // + + ntStatus = AFSUnloadLibrary( FALSE); + + break; + } +#endif + + case IOCTL_AFS_SHUTDOWN: + { + + ntStatus = AFSShutdownRedirector(); + + break; + } + + case IOCTL_AFS_AUTHGROUP_CREATE_AND_SET: + { + + + AFSAuthGroupRequestCB *pAuthGroupRequestCB = (AFSAuthGroupRequestCB *)Irp->AssociatedIrp.SystemBuffer; + + if( pAuthGroupRequestCB == NULL || + pIrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof( AFSAuthGroupRequestCB)) + { + + ntStatus = STATUS_INVALID_PARAMETER; + + break; + } + + ntStatus = AFSCreateSetProcessAuthGroup( pAuthGroupRequestCB); + + break; + } + + case IOCTL_AFS_AUTHGROUP_QUERY: + { + + ntStatus = AFSQueryProcessAuthGroupList( ( GUID *)Irp->AssociatedIrp.SystemBuffer, + pIrpSp->Parameters.DeviceIoControl.OutputBufferLength, + &Irp->IoStatus.Information); + + break; + } + + case IOCTL_AFS_AUTHGROUP_SET: + { + + AFSAuthGroupRequestCB *pAuthGroupRequestCB = (AFSAuthGroupRequestCB *)Irp->AssociatedIrp.SystemBuffer; + + if( pAuthGroupRequestCB == NULL || + pIrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof( AFSAuthGroupRequestCB)) + { + + ntStatus = STATUS_INVALID_PARAMETER; + + break; + } + + ntStatus = AFSSetActiveProcessAuthGroup( pAuthGroupRequestCB); + + break; + } + + case IOCTL_AFS_AUTHGROUP_RESET: + { + + AFSAuthGroupRequestCB *pAuthGroupRequestCB = (AFSAuthGroupRequestCB *)Irp->AssociatedIrp.SystemBuffer; + + if( pAuthGroupRequestCB == NULL || + pIrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof( AFSAuthGroupRequestCB)) + { + + ntStatus = STATUS_INVALID_PARAMETER; + + break; + } + + ntStatus = AFSResetActiveProcessAuthGroup( pAuthGroupRequestCB); + + break; + } + + case IOCTL_AFS_AUTHGROUP_LOGON_CREATE: + case IOCTL_AFS_AUTHGROUP_SID_CREATE: + { + + AFSAuthGroupRequestCB *pAuthGroupRequestCB = (AFSAuthGroupRequestCB *)Irp->AssociatedIrp.SystemBuffer; + + if( pAuthGroupRequestCB != NULL && + pIrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof( AFSAuthGroupRequestCB)) + { + + ntStatus = STATUS_INVALID_PARAMETER; + + break; + } + + ntStatus = AFSCreateAuthGroupForSIDorLogonSession( pAuthGroupRequestCB, + ulIoControlCode == IOCTL_AFS_AUTHGROUP_LOGON_CREATE); + + break; + } + + case IOCTL_AFS_AUTHGROUP_SID_QUERY: + { + + AFSAuthGroupRequestCB *pAuthGroupRequestCB = NULL; + + if( pIrpSp->Parameters.DeviceIoControl.OutputBufferLength < sizeof( GUID)) + { + ntStatus = STATUS_INVALID_PARAMETER; + break; + } + + if( pIrpSp->Parameters.DeviceIoControl.InputBufferLength >= sizeof( AFSAuthGroupRequestCB)) + { + pAuthGroupRequestCB = (AFSAuthGroupRequestCB *)Irp->AssociatedIrp.SystemBuffer; + } + + ntStatus = AFSQueryAuthGroup( pAuthGroupRequestCB, + (GUID *)Irp->AssociatedIrp.SystemBuffer, + &Irp->IoStatus.Information); + + break; + } + + default: + { + + // + // Check the state of the library + // + + ntStatus = AFSCheckLibraryState( Irp); + + if( !NT_SUCCESS( ntStatus) || + ntStatus == STATUS_PENDING) + { + + if( ntStatus == STATUS_PENDING) + { + bCompleteRequest = FALSE; + } + + break; + } + + bCompleteRequest = FALSE; + + IoSkipCurrentIrpStackLocation( Irp); + + ntStatus = IoCallDriver( pDevExt->Specific.Control.LibraryDeviceObject, + Irp); + + // + // Indicate the library is done with the request + // + + AFSClearLibraryRequest(); + + break; + } + } + +//try_exit: + + } + __except( AFSExceptionFilter( GetExceptionCode(), GetExceptionInformation())) + { + + ntStatus = STATUS_UNSUCCESSFUL; + } + + if( bCompleteRequest) + { + + Irp->IoStatus.Status = ntStatus; + + AFSCompleteRequest( Irp, + ntStatus); + } + + return ntStatus; +} + +NTSTATUS +AFSInitIrpPool() +{ + + NTSTATUS ntStatus = STATUS_SUCCESS; + AFSCommSrvcCB *pCommSrvc = NULL; + BOOLEAN bReleasePools = FALSE; + AFSDeviceExt *pDevExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension; + + __Enter + { + + pCommSrvc = &pDevExt->Specific.Control.CommServiceCB; + + // + // Whenever we change state we must grab both pool locks. On the checking of the state + // within the processing routines for these respective pools, we only grab one lock to + // minimize serialization. The ordering is always the Irp pool then the result pool + // locks. We also do this in the tear down of the pool + // + + AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "AFSInitIrpPool Acquiring IrpPoolLock lock %08lX EXCL %08lX\n", + &pCommSrvc->IrpPoolLock, + PsGetCurrentThread()); + + AFSAcquireExcl( &pCommSrvc->IrpPoolLock, + TRUE); + + AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "AFSInitIrpPool Acquiring ResultPoolLock lock %08lX EXCL %08lX\n", + &pCommSrvc->ResultPoolLock, + PsGetCurrentThread()); + + AFSAcquireExcl( &pCommSrvc->ResultPoolLock, + TRUE); + + bReleasePools = TRUE; + + // + // The pool can be either ACTIVE or INACTIVE. If the pool state is INACTIVE and we + // are receiving the INIT request, then activate it. If the pool is ACTIVE, then we + // shouldn't be getting this request ... + // + + if( pCommSrvc->IrpPoolControlFlag == POOL_ACTIVE) + { + + // + // We have already been activated so just fail this request + // + + try_return( ntStatus = STATUS_INVALID_PARAMETER); + } + else if( pCommSrvc->IrpPoolControlFlag == POOL_INACTIVE) + { + + // + // The pool is currently INACTIVE so start it up and ready it to + // receive irp requests + // + + pCommSrvc->IrpPoolControlFlag = POOL_ACTIVE; + + pDevExt->Specific.Control.ServiceProcess = (PKPROCESS)PsGetCurrentProcess(); + + try_return( ntStatus = STATUS_SUCCESS); + } + else + { + + // + // The pool is in some mixed state, fail the request. + // + + try_return( ntStatus = STATUS_DEVICE_NOT_READY); + } + +try_exit: + + if( bReleasePools) + { + + AFSReleaseResource( &pCommSrvc->IrpPoolLock); + + AFSReleaseResource( &pCommSrvc->ResultPoolLock); + } + } + + return ntStatus; +} + +void +AFSCleanupIrpPool() +{ + + NTSTATUS ntStatus = STATUS_SUCCESS; + AFSPoolEntry *pEntry = NULL, *pNextEntry = NULL; + AFSDeviceExt *pDevExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension; + AFSCommSrvcCB *pCommSrvc = (AFSCommSrvcCB *)&pDevExt->Specific.Control.CommServiceCB; + + __Enter + { + + // + // When we change the state, grab both pool locks exclusive. The order is always the + // Irp pool then the result pool lock + // + + AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "AFSCleanupIrpPool Acquiring IrpPoolLock lock %08lX EXCL %08lX\n", + &pCommSrvc->IrpPoolLock, + PsGetCurrentThread()); + + AFSAcquireExcl( &pCommSrvc->IrpPoolLock, + TRUE); + + AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "AFSCleanupIrpPool Acquiring ResultPoolLock lock %08lX EXCL %08lX\n", + &pCommSrvc->ResultPoolLock, + PsGetCurrentThread()); + + AFSAcquireExcl( &pCommSrvc->ResultPoolLock, + TRUE); + + // + // Indicate we are pending stop + // + + pCommSrvc->IrpPoolControlFlag = POOL_INACTIVE; + + // + // Set the event to release any waiting workers + // + + KeSetEvent( &pCommSrvc->IrpPoolHasEntries, + 0, + FALSE); + + KeSetEvent( &pCommSrvc->IrpPoolHasReleaseEntries, + 0, + FALSE); + + // + // Go through the pool entries and free up the structures. + // + + pEntry = pCommSrvc->RequestPoolHead; + + while( pEntry != NULL) + { + + pNextEntry = pEntry->fLink; + + if( BooleanFlagOn( pEntry->RequestFlags, AFS_REQUEST_FLAG_SYNCHRONOUS)) + { + + // + // Here we need to complete the irp, cancelled, and delete the data block + // + + pEntry->ResultStatus = STATUS_CANCELLED; + + KeSetEvent( &pEntry->Event, + 0, + FALSE); + } + else + { + + ExFreePool( pEntry); + } + + pEntry = pNextEntry; + } + + // + // Cleanup the control structure for the request pool + // + + pCommSrvc->RequestPoolHead = NULL; + + pCommSrvc->RequestPoolTail = NULL; + + pCommSrvc->IrpPoolRequestIndex = 1; + + KeClearEvent( &pCommSrvc->IrpPoolHasEntries); + + KeClearEvent( &pCommSrvc->IrpPoolHasReleaseEntries); + + // + // Release the irp pool lock. + // + + AFSReleaseResource( &pCommSrvc->IrpPoolLock); + + // + // Go through the result pool entries and free up the structures. + // + + pEntry = pCommSrvc->ResultPoolHead; + + while( pEntry != NULL) + { + + pNextEntry = pEntry->fLink; + + pEntry->ResultStatus = STATUS_CANCELLED; + + // + // Here we will set the event of the requestor and let the blocked thread + // free the data block + // + + KeSetEvent( &pEntry->Event, + 0, + FALSE); + + // + // Go onto the next entry + // + + pEntry = pNextEntry; + } + + // + // Cleanup the control structure for the result pool + // + + pCommSrvc->ResultPoolHead = NULL; + + pCommSrvc->ResultPoolTail = NULL; + + // + // Release the result pool lock. + // + + AFSReleaseResource( &pCommSrvc->ResultPoolLock); + } + + return; +} + +NTSTATUS +AFSInsertRequest( IN AFSCommSrvcCB *CommSrvc, + IN AFSPoolEntry *Entry) +{ + + NTSTATUS ntStatus = STATUS_SUCCESS; + + __Enter + { + + AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "AFSInsertRequest Acquiring IrpPoolLock lock %08lX EXCL %08lX\n", + &CommSrvc->IrpPoolLock, + PsGetCurrentThread()); + + AFSAcquireExcl( &CommSrvc->IrpPoolLock, + TRUE); + + if( CommSrvc->IrpPoolControlFlag != POOL_ACTIVE) + { + + try_return( ntStatus = STATUS_DEVICE_NOT_READY); + } + + if( CommSrvc->RequestPoolHead == NULL) + { + + CommSrvc->RequestPoolHead = Entry; + } + else + { + + CommSrvc->RequestPoolTail->fLink = Entry; + + Entry->bLink = CommSrvc->RequestPoolTail; + } + + CommSrvc->RequestPoolTail = Entry; + + if( Entry->RequestType == AFS_REQUEST_TYPE_RELEASE_FILE_EXTENTS) + { + + KeSetEvent( &CommSrvc->IrpPoolHasReleaseEntries, + 0, + FALSE); + } + else + { + + KeSetEvent( &CommSrvc->IrpPoolHasEntries, + 0, + FALSE); + } + + InterlockedIncrement( &CommSrvc->QueueCount); + +try_exit: + + AFSReleaseResource( &CommSrvc->IrpPoolLock); + } + + return ntStatus; +} + +NTSTATUS +AFSProcessIrpRequest( IN PIRP Irp) +{ + + NTSTATUS ntStatus = STATUS_SUCCESS; + AFSDeviceExt *pDevExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension; + IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp); + AFSCommSrvcCB *pCommSrvc = NULL; + AFSPoolEntry *pEntry = NULL, *pPrevEntry = NULL; + AFSCommRequest *pRequest = NULL; + BOOLEAN bReleaseRequestThread = FALSE; + + __Enter + { + + pCommSrvc = &pDevExt->Specific.Control.CommServiceCB; + + pRequest = (AFSCommRequest *)Irp->AssociatedIrp.SystemBuffer; + + AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "AFSProcessIrpRequest Acquiring IrpPoolLock lock %08lX EXCL %08lX\n", + &pCommSrvc->IrpPoolLock, + PsGetCurrentThread()); + + AFSAcquireExcl( &pCommSrvc->IrpPoolLock, + TRUE); + + if( pCommSrvc->IrpPoolControlFlag != POOL_ACTIVE) + { + + AFSReleaseResource( &pCommSrvc->IrpPoolLock); + + try_return( ntStatus = STATUS_DEVICE_NOT_READY); + } + + AFSReleaseResource( &pCommSrvc->IrpPoolLock); + + // + // Is this a dedicated flush thread? + // + + if( BooleanFlagOn( pRequest->RequestFlags, AFS_REQUEST_RELEASE_THREAD)) + { + + bReleaseRequestThread = TRUE; + } + + // + // Wait on the 'have items' event until we can retrieve an item + // + + while( TRUE) + { + + if( bReleaseRequestThread) + { + + ntStatus = KeWaitForSingleObject( &pCommSrvc->IrpPoolHasReleaseEntries, + UserRequest, + UserMode, + TRUE, + NULL); + } + else + { + + ntStatus = KeWaitForSingleObject( &pCommSrvc->IrpPoolHasEntries, + UserRequest, + UserMode, + TRUE, + NULL); + } + + if( ntStatus != STATUS_SUCCESS) + { + + ntStatus = STATUS_DEVICE_NOT_READY; + + break; + } + + // + // Grab the lock on the request pool + // + + AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "AFSProcessIrpRequest Acquiring IrpPoolLock (WAIT) lock %08lX EXCL %08lX\n", + &pCommSrvc->IrpPoolLock, + PsGetCurrentThread()); + + AFSAcquireExcl( &pCommSrvc->IrpPoolLock, + TRUE); + + if( pCommSrvc->IrpPoolControlFlag != POOL_ACTIVE) + { + + AFSReleaseResource( &pCommSrvc->IrpPoolLock); + + try_return( ntStatus = STATUS_DEVICE_NOT_READY); + } + + // + // If this is a dedicated flush thread only look for a flush request in the queue + // + + if( bReleaseRequestThread) + { + + pEntry = pCommSrvc->RequestPoolHead; + + pPrevEntry = NULL; + + while( pEntry != NULL) + { + + if( pEntry->RequestType == AFS_REQUEST_TYPE_RELEASE_FILE_EXTENTS) + { + + if( pPrevEntry == NULL) + { + + pCommSrvc->RequestPoolHead = pEntry->fLink; + + if( pCommSrvc->RequestPoolHead == NULL) + { + + pCommSrvc->RequestPoolTail = NULL; + } + } + else + { + + pPrevEntry->fLink = pEntry->fLink; + + if( pPrevEntry->fLink == NULL) + { + + pCommSrvc->RequestPoolTail = pPrevEntry; + } + } + + break; + } + + pPrevEntry = pEntry; + + pEntry = pEntry->fLink; + } + + if( pCommSrvc->RequestPoolHead == NULL) + { + + KeClearEvent( &pCommSrvc->IrpPoolHasEntries); + } + + if( pEntry == NULL) + { + + KeClearEvent( &pCommSrvc->IrpPoolHasReleaseEntries); + } + + // + // And release the request pool lock + // + + AFSReleaseResource( &pCommSrvc->IrpPoolLock); + } + else + { + + pEntry = pCommSrvc->RequestPoolHead; + + if( pEntry != NULL) + { + + pCommSrvc->RequestPoolHead = pEntry->fLink; + + pEntry->bLink = NULL; + + if( pCommSrvc->RequestPoolHead == NULL) + { + + pCommSrvc->RequestPoolTail = NULL; + } + } + else + { + + KeClearEvent( &pCommSrvc->IrpPoolHasEntries); + } + + // + // And release the request pool lock + // + + AFSReleaseResource( &pCommSrvc->IrpPoolLock); + } + + // + // Insert the entry into the result pool, if we have one + // + + if( pEntry != NULL) + { + + // + // Move the request data into the passed in buffer + // + + ASSERT( sizeof( AFSCommRequest) + + pEntry->FileName.Length + + pEntry->DataLength <= pIrpSp->Parameters.DeviceIoControl.OutputBufferLength); + + RtlCopyMemory( &pRequest->AuthGroup, + &pEntry->AuthGroup, + sizeof( GUID)); + + pRequest->FileId = pEntry->FileId; + + pRequest->RequestType = pEntry->RequestType; + + pRequest->RequestIndex = pEntry->RequestIndex; + + pRequest->RequestFlags = pEntry->RequestFlags; + + pRequest->NameLength = pEntry->FileName.Length; + + pRequest->QueueCount = InterlockedDecrement( &pCommSrvc->QueueCount); + + if( pRequest->NameLength > 0) + { + + RtlCopyMemory( pRequest->Name, + pEntry->FileName.Buffer, + pRequest->NameLength); + } + + pRequest->DataOffset = 0; + + pRequest->DataLength = pEntry->DataLength; + + if( pRequest->DataLength > 0) + { + + pRequest->DataOffset = pEntry->FileName.Length; + + RtlCopyMemory( (void *)((char *)pRequest->Name + pRequest->DataOffset), + pEntry->Data, + pRequest->DataLength); + } + + pRequest->ResultBufferLength = 0; + + if( pEntry->ResultBufferLength != NULL) + { + + pRequest->ResultBufferLength = *(pEntry->ResultBufferLength); + } + + Irp->IoStatus.Information = sizeof( AFSCommRequest) + + pEntry->FileName.Length + + pEntry->DataLength; + + // + // If this is a synchronous request then move the request into the + // result pool + // + + if( BooleanFlagOn( pEntry->RequestFlags, AFS_REQUEST_FLAG_SYNCHRONOUS)) + { + + pEntry->fLink = NULL; + pEntry->bLink = NULL; + + AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "AFSProcessIrpRequest Acquiring ResultPoolLock lock %08lX EXCL %08lX\n", + &pCommSrvc->ResultPoolLock, + PsGetCurrentThread()); + + AFSAcquireExcl( &pCommSrvc->ResultPoolLock, + TRUE); + + if( pCommSrvc->ResultPoolHead == NULL) + { + + pCommSrvc->ResultPoolHead = pEntry; + } + else + { + + pCommSrvc->ResultPoolTail->fLink = pEntry; + + pEntry->bLink = pCommSrvc->ResultPoolTail; + } + + pCommSrvc->ResultPoolTail = pEntry; + + AFSReleaseResource( &pCommSrvc->ResultPoolLock); + } + else + { + + // + // Free up the pool entry + // + + ExFreePool( pEntry); + } + + break; + } + } + +try_exit: + + NOTHING; + } + + return ntStatus; +} + +NTSTATUS +AFSProcessIrpResult( IN PIRP Irp) +{ + + NTSTATUS ntStatus = STATUS_SUCCESS; + AFSDeviceExt *pDevExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension; + IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp); + AFSCommSrvcCB *pCommSrvc = NULL; + AFSPoolEntry *pCurrentEntry = NULL; + AFSCommResult *pResult = NULL; + ULONG ulCopyLen = 0; + + __Enter + { + + pCommSrvc = &pDevExt->Specific.Control.CommServiceCB; + + // + // Get the request for the incoming result + // + + pResult = (AFSCommResult *)Irp->AssociatedIrp.SystemBuffer; + + if( pResult == NULL) + { + + try_return( ntStatus = STATUS_INVALID_PARAMETER); + } + + // + // Go look for our entry + // + + AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "AFSProcessIrpResult Acquiring ResultPoolLock lock %08lX EXCL %08lX\n", + &pCommSrvc->ResultPoolLock, + PsGetCurrentThread()); + + AFSAcquireExcl( &pCommSrvc->ResultPoolLock, + TRUE); + + pCurrentEntry = pCommSrvc->ResultPoolHead; + + while( pCurrentEntry != NULL) + { + + if( pCurrentEntry->RequestIndex == pResult->RequestIndex) + { + + // + // Found the entry so remove it from the queue + // + + if( pCurrentEntry->bLink == NULL) + { + + // + // At the head of the list + // + + pCommSrvc->ResultPoolHead = pCurrentEntry->fLink; + + if( pCommSrvc->ResultPoolHead != NULL) + { + + pCommSrvc->ResultPoolHead->bLink = NULL; + } + } + else + { + + pCurrentEntry->bLink->fLink = pCurrentEntry->fLink; + } + + if( pCurrentEntry->fLink == NULL) + { + + pCommSrvc->ResultPoolTail = pCurrentEntry->bLink; + + if( pCommSrvc->ResultPoolTail != NULL) + { + + pCommSrvc->ResultPoolTail->fLink = NULL; + } + } + else + { + + pCurrentEntry->fLink->bLink = pCurrentEntry->bLink; + } + + break; + } + + pCurrentEntry = pCurrentEntry->fLink; + } + + AFSReleaseResource( &pCommSrvc->ResultPoolLock); + + if( pCurrentEntry == NULL) + { + + try_return( ntStatus = STATUS_INVALID_PARAMETER); + } + + // + // OK, move in the result information + // + + pCurrentEntry->ResultStatus = pResult->ResultStatus; + + if( ( pCurrentEntry->ResultStatus == STATUS_SUCCESS || + pCurrentEntry->ResultStatus == STATUS_BUFFER_OVERFLOW) && + pCurrentEntry->ResultBufferLength != NULL && + pCurrentEntry->ResultBuffer != NULL) + { + + ASSERT( pResult->ResultBufferLength <= *(pCurrentEntry->ResultBufferLength)); + + ulCopyLen = pResult->ResultBufferLength; + + if( ulCopyLen > *(pCurrentEntry->ResultBufferLength)) + { + ulCopyLen = *(pCurrentEntry->ResultBufferLength); + } + + *(pCurrentEntry->ResultBufferLength) = ulCopyLen; + + if( pResult->ResultBufferLength > 0) + { + + RtlCopyMemory( pCurrentEntry->ResultBuffer, + pResult->ResultData, + ulCopyLen); + } + } + + KeSetEvent( &pCurrentEntry->Event, + 0, + FALSE); + +try_exit: + + if( !NT_SUCCESS( ntStatus)) + { + + } + } + + return ntStatus; +} diff --git a/src/WINNT/afsrdr/kernel/fs/AFSCreate.cpp b/src/WINNT/afsrdr/kernel/fs/AFSCreate.cpp new file mode 100644 index 0000000000..2401b53663 --- /dev/null +++ b/src/WINNT/afsrdr/kernel/fs/AFSCreate.cpp @@ -0,0 +1,264 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC. + * Copyright (c) 2009, 2010, 2011 Your File System, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, + * this list of conditions and the following disclaimer in the + * documentation + * and/or other materials provided with the distribution. + * - Neither the names of Kernel Drivers, LLC and Your File System, Inc. + * nor the names of their contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission from Kernel Drivers, LLC and Your File System, Inc. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +// +// File: AFSCreate.cpp +// + +#include "AFSCommon.h" + +// +// Function: AFSCreate +// +// Description: +// +// This function is the dispatch handler for the IRP_MJ_CREATE requests. It makes the determination to +// which interface this request is destined. +// +// Return: +// +// A status is returned for the function. The Irp completion processing is handled in the specific +// interface handler. +// + +NTSTATUS +AFSCreate( IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + + NTSTATUS ntStatus = STATUS_SUCCESS; + + __try + { + + if( DeviceObject == AFSDeviceObject) + { + + ntStatus = AFSControlDeviceCreate( Irp); + + try_return( ntStatus); + } + + ntStatus = AFSCommonCreate( DeviceObject, + Irp); + +try_exit: + + NOTHING; + } + __except( AFSExceptionFilter( GetExceptionCode(), GetExceptionInformation()) ) + { + + AFSDbgLogMsg( 0, + 0, + "EXCEPTION - AFSCreate\n"); + + ntStatus = STATUS_ACCESS_DENIED; + } + + return ntStatus; +} + +NTSTATUS +AFSCommonCreate( IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + + NTSTATUS ntStatus = STATUS_SUCCESS; + FILE_OBJECT *pFileObject = NULL; + IO_STACK_LOCATION *pIrpSp; + AFSDeviceExt *pDeviceExt = NULL; + AFSDeviceExt *pControlDevExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension; + GUID *pAuthGroup = NULL; + UNICODE_STRING uniGUIDString; + + __Enter + { + + pIrpSp = IoGetCurrentIrpStackLocation( Irp); + pDeviceExt = (AFSDeviceExt *)DeviceObject->DeviceExtension; + pFileObject = pIrpSp->FileObject; + + uniGUIDString.Buffer = NULL; + uniGUIDString.Length = 0; + uniGUIDString.MaximumLength = 0; + + // + // Validate the process entry + // + + pAuthGroup = AFSValidateProcessEntry(); + + if( pAuthGroup != NULL) + { + + RtlStringFromGUID( *pAuthGroup, + &uniGUIDString); + + AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "%s (%08lX) Located AuthGroup %wZ after validation\n", + __FUNCTION__, + Irp, + &uniGUIDString); + + } + else + { + AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "%s (%08lX) Failed to locate AuthGroup\n", + __FUNCTION__, + Irp); + } + + // + // Root open? + // + + if( pFileObject == NULL || + pFileObject->FileName.Buffer == NULL) + { + + AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "AFSCommonCreate (%08lX) Processing volume open request\n", + Irp); + + ntStatus = AFSOpenRedirector( Irp); + + AFSCompleteRequest( Irp, + ntStatus); + + try_return( ntStatus); + } + + + // + // Check the state of the library + // + + ntStatus = AFSCheckLibraryState( Irp); + + if( !NT_SUCCESS( ntStatus) || + ntStatus == STATUS_PENDING) + { + + if( ntStatus != STATUS_PENDING) + { + AFSCompleteRequest( Irp, ntStatus); + } + + try_return( ntStatus); + } + + IoSkipCurrentIrpStackLocation( Irp); + + ntStatus = IoCallDriver( pControlDevExt->Specific.Control.LibraryDeviceObject, + Irp); + + // + // Indicate the library is done with the request + // + + AFSClearLibraryRequest(); + +try_exit: + + if ( pFileObject) { + AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "%s (%08lX) File \"%wZ\" AuthGroup '%wZ' ntStatus %08lX\n", + __FUNCTION__, + Irp, + &pFileObject->FileName, + &uniGUIDString, + ntStatus); + } + + if( uniGUIDString.Buffer != NULL) + { + RtlFreeUnicodeString( &uniGUIDString); + } + } + + return ntStatus; +} + +NTSTATUS +AFSControlDeviceCreate( IN PIRP Irp) +{ + + NTSTATUS ntStatus = STATUS_SUCCESS; + + __Enter + { + + // + // For now, jsut let the open happen + // + + Irp->IoStatus.Information = FILE_OPENED; + + AFSCompleteRequest( Irp, ntStatus); + } + + return ntStatus; +} + +NTSTATUS +AFSOpenRedirector( IN PIRP Irp) +{ + + NTSTATUS ntStatus = STATUS_SUCCESS; + FILE_OBJECT *pFileObject = NULL; + IO_STACK_LOCATION *pIrpSp; + + __Enter + { + + pIrpSp = IoGetCurrentIrpStackLocation( Irp); + pFileObject = pIrpSp->FileObject; + + // + // Return the open result for this file + // + + Irp->IoStatus.Information = FILE_OPENED; + + Irp->IoStatus.Status = ntStatus; + } + + return ntStatus; +} diff --git a/src/WINNT/afsrdr/kernel/fs/AFSData.cpp b/src/WINNT/afsrdr/kernel/fs/AFSData.cpp new file mode 100644 index 0000000000..4fd9894e44 --- /dev/null +++ b/src/WINNT/afsrdr/kernel/fs/AFSData.cpp @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC. + * Copyright (c) 2009, 2010, 2011 Your File System, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, + * this list of conditions and the following disclaimer in the + * documentation + * and/or other materials provided with the distribution. + * - Neither the names of Kernel Drivers, LLC and Your File System, Inc. + * nor the names of their contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission from Kernel Drivers, LLC and Your File System, Inc. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +// +// File: AFSData.cpp +// + +#define NO_EXTERN + +#include "AFSCommon.h" + +extern "C" { + +PDRIVER_OBJECT AFSDriverObject = NULL; + +PDEVICE_OBJECT AFSDeviceObject = NULL; + +PDEVICE_OBJECT AFSRDRDeviceObject = NULL; + +FAST_IO_DISPATCH AFSFastIoDispatch; + +UNICODE_STRING AFSRegistryPath; + +ULONG AFSDebugFlags = 0; + +ULONG AFSTraceLevel = 0; + +ULONG AFSTraceComponent = 0; + +HANDLE AFSSysProcess = NULL; + +HANDLE AFSMUPHandle = NULL; + +UNICODE_STRING AFSServerName; + +UNICODE_STRING AFSGlobalRootName; + +CACHE_MANAGER_CALLBACKS AFSCacheManagerCallbacks; + +// +// Max Length IO (Mb) +// +ULONG AFSMaxDirectIo = 0; + +// +// Maximum dirtiness that a file can get +// +ULONG AFSMaxDirtyFile = 0; + +// +// Dbg log information +// + +ERESOURCE AFSDbgLogLock; + +ULONG AFSDbgLogRemainingLength = 0; + +char *AFSDbgCurrentBuffer = NULL; + +char *AFSDbgBuffer = NULL; + +ULONG AFSDbgLogCounter = 0; + +ULONG AFSDbgBufferLength = 0; + +ULONG AFSDbgLogFlags = 0; + +PAFSDumpTraceFiles AFSDumpTraceFilesFnc = AFSDumpTraceFiles; + +UNICODE_STRING AFSDumpFileLocation; + +KEVENT AFSDumpFileEvent; + +UNICODE_STRING AFSDumpFileName; + +void *AFSDumpBuffer = NULL; + +ULONG AFSDumpBufferLength = 0; + +// +// Authentication group information +// + +ULONG AFSAuthGroupFlags = 0; + +GUID AFSActiveAuthGroup; + +GUID AFSNoPAGAuthGroup; + +PAFSSetInformationToken AFSSetInformationToken = NULL; + +} diff --git a/src/WINNT/afsrdr/kernel/fs/AFSDevControl.cpp b/src/WINNT/afsrdr/kernel/fs/AFSDevControl.cpp new file mode 100644 index 0000000000..31c29572fa --- /dev/null +++ b/src/WINNT/afsrdr/kernel/fs/AFSDevControl.cpp @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC. + * Copyright (c) 2009, 2010, 2011 Your File System, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, + * this list of conditions and the following disclaimer in the + * documentation + * and/or other materials provided with the distribution. + * - Neither the names of Kernel Drivers, LLC and Your File System, Inc. + * nor the names of their contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission from Kernel Drivers, LLC and Your File System, Inc. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +// +// File: AFSDevControl.cpp +// + +#include "AFSCommon.h" + +// +// Function: AFSDevControl +// +// Description: +// +// This is the dipatch handler for the IRP_MJ_DEVICE_CONTROL requests. +// +// Return: +// +// A status is returned for the function +// + +NTSTATUS +AFSDevControl( IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + + NTSTATUS ntStatus = STATUS_SUCCESS; + IO_STACK_LOCATION *pIrpSp; + + pIrpSp = IoGetCurrentIrpStackLocation( Irp); + + __try + { + + if( DeviceObject == AFSDeviceObject) + { + + ntStatus = AFSProcessControlRequest( Irp); + + try_return( ntStatus); + } + + ntStatus = AFSRDRDeviceControl( DeviceObject, + Irp); + +try_exit: + + NOTHING; + } + __except( AFSExceptionFilter( GetExceptionCode(), GetExceptionInformation()) ) + { + + AFSDbgLogMsg( 0, + 0, + "EXCEPTION - AFSDevControl\n"); + } + + return ntStatus; +} diff --git a/src/WINNT/afsrdr/kernel/fs/AFSDirControl.cpp b/src/WINNT/afsrdr/kernel/fs/AFSDirControl.cpp new file mode 100644 index 0000000000..c4e2ff6dc3 --- /dev/null +++ b/src/WINNT/afsrdr/kernel/fs/AFSDirControl.cpp @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC. + * Copyright (c) 2009, 2010, 2011 Your File System, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, + * this list of conditions and the following disclaimer in the + * documentation + * and/or other materials provided with the distribution. + * - Neither the names of Kernel Drivers, LLC and Your File System, Inc. + * nor the names of their contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission from Kernel Drivers, LLC and Your File System, Inc. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +// +// File: AFSDirControl.cpp +// + +#include "AFSCommon.h" + +// +// Function: AFSDirControl +// +// Description: +// +// This function is the IRP_MJ_DIRECTORY_CONTROL dispatch handler +// +// Return: +// +// A status is returned for the handling of this request +// + +NTSTATUS +AFSDirControl( IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + + NTSTATUS ntStatus = STATUS_SUCCESS; + ULONG ulRequestType = 0; + IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp); + AFSDeviceExt *pControlDeviceExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension; + + __try + { + + if( DeviceObject == AFSDeviceObject) + { + + ntStatus = STATUS_INVALID_DEVICE_REQUEST; + + AFSCompleteRequest( Irp, + ntStatus); + + try_return( ntStatus); + } + + // + // Check the state of the library + // + + ntStatus = AFSCheckLibraryState( Irp); + + if( !NT_SUCCESS( ntStatus) || + ntStatus == STATUS_PENDING) + { + + if( ntStatus != STATUS_PENDING) + { + AFSCompleteRequest( Irp, ntStatus); + } + + try_return( ntStatus); + } + + IoSkipCurrentIrpStackLocation( Irp); + + ntStatus = IoCallDriver( pControlDeviceExt->Specific.Control.LibraryDeviceObject, + Irp); + + // + // Indicate the library is done with the request + // + + AFSClearLibraryRequest(); + +try_exit: + + NOTHING; + } + __except( AFSExceptionFilter( GetExceptionCode(), GetExceptionInformation()) ) + { + + AFSDbgLogMsg( 0, + 0, + "EXCEPTION - AFSDirControl\n"); + } + + return ntStatus; +} diff --git a/src/WINNT/afsrdr/kernel/fs/AFSEa.cpp b/src/WINNT/afsrdr/kernel/fs/AFSEa.cpp new file mode 100644 index 0000000000..adf90666ca --- /dev/null +++ b/src/WINNT/afsrdr/kernel/fs/AFSEa.cpp @@ -0,0 +1,191 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC. + * Copyright (c) 2009, 2010, 2011 Your File System, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, + * this list of conditions and the following disclaimer in the + * documentation + * and/or other materials provided with the distribution. + * - Neither the names of Kernel Drivers, LLC and Your File System, Inc. + * nor the names of their contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission from Kernel Drivers, LLC and Your File System, Inc. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +// +// File: AFSEa.cpp +// + +#include "AFSCommon.h" + +// +// Function: AFSQueryEA +// +// Description: +// +// This function is the dipatch handler for the IRP_MJ_QUERY_EA request +// +// Return: +// +// A status is returned for the function +// + +NTSTATUS +AFSQueryEA( IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + + NTSTATUS ntStatus = STATUS_EAS_NOT_SUPPORTED; + AFSDeviceExt *pControlDeviceExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension; + + __try + { + + if( DeviceObject == AFSDeviceObject) + { + + AFSCompleteRequest( Irp, + ntStatus); + + try_return( ntStatus); + } + + // + // Check the state of the library + // + + ntStatus = AFSCheckLibraryState( Irp); + + if( !NT_SUCCESS( ntStatus) || + ntStatus == STATUS_PENDING) + { + + if( ntStatus != STATUS_PENDING) + { + AFSCompleteRequest( Irp, ntStatus); + } + + try_return( ntStatus); + } + + IoSkipCurrentIrpStackLocation( Irp); + + ntStatus = IoCallDriver( pControlDeviceExt->Specific.Control.LibraryDeviceObject, + Irp); + + // + // Indicate the library is done with the request + // + + AFSClearLibraryRequest(); + +try_exit: + + NOTHING; + } + __except( AFSExceptionFilter( GetExceptionCode(), GetExceptionInformation()) ) + { + + AFSDbgLogMsg( 0, + 0, + "EXCEPTION - AFSQueryEA\n"); + } + + return ntStatus; +} + +// +// Function: AFSSetEA +// +// Description: +// +// This function is the dipatch handler for the IRP_MJ_SET_EA request +// +// Return: +// +// A status is returned for the function +// + +NTSTATUS +AFSSetEA( IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + + NTSTATUS ntStatus = STATUS_EAS_NOT_SUPPORTED; + AFSDeviceExt *pControlDeviceExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension; + + __try + { + + if( DeviceObject == AFSDeviceObject) + { + + AFSCompleteRequest( Irp, + ntStatus); + + try_return( ntStatus); + } + + // + // Check the state of the library + // + + ntStatus = AFSCheckLibraryState( Irp); + + if( !NT_SUCCESS( ntStatus) || + ntStatus == STATUS_PENDING) + { + + if( ntStatus != STATUS_PENDING) + { + AFSCompleteRequest( Irp, ntStatus); + } + + try_return( ntStatus); + } + + IoSkipCurrentIrpStackLocation( Irp); + + ntStatus = IoCallDriver( pControlDeviceExt->Specific.Control.LibraryDeviceObject, + Irp); + + // + // Indicate the library is done with the request + // + + AFSClearLibraryRequest(); + +try_exit: + + NOTHING; + } + __except( AFSExceptionFilter( GetExceptionCode(), GetExceptionInformation()) ) + { + + AFSDbgLogMsg( 0, + 0, + "EXCEPTION - AFSSetEA\n"); + } + + return ntStatus; +} diff --git a/src/WINNT/afsrdr/kernel/fs/AFSFSControl.cpp b/src/WINNT/afsrdr/kernel/fs/AFSFSControl.cpp new file mode 100644 index 0000000000..d2a486800e --- /dev/null +++ b/src/WINNT/afsrdr/kernel/fs/AFSFSControl.cpp @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC. + * Copyright (c) 2009, 2010, 2011 Your File System, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, + * this list of conditions and the following disclaimer in the + * documentation + * and/or other materials provided with the distribution. + * - Neither the names of Kernel Drivers, LLC and Your File System, Inc. + * nor the names of their contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission from Kernel Drivers, LLC and Your File System, Inc. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +// +// File: AFSFSControl.cpp +// + +#include "AFSCommon.h" + +NTSTATUS +AFSFSControl( IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + + NTSTATUS ntStatus = STATUS_SUCCESS; + IO_STACK_LOCATION *pIrpSp; + AFSDeviceExt *pControlDeviceExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension; + + pIrpSp = IoGetCurrentIrpStackLocation( Irp); + + __try + { + + if( DeviceObject == AFSDeviceObject) + { + + ntStatus = STATUS_INVALID_DEVICE_REQUEST; + + AFSCompleteRequest( Irp, + ntStatus); + + try_return( ntStatus); + } + + // + // Check the state of the library + // + + ntStatus = AFSCheckLibraryState( Irp); + + if( !NT_SUCCESS( ntStatus) || + ntStatus == STATUS_PENDING) + { + + if( ntStatus != STATUS_PENDING) + { + AFSCompleteRequest( Irp, ntStatus); + } + + try_return( ntStatus); + } + + IoSkipCurrentIrpStackLocation( Irp); + + ntStatus = IoCallDriver( pControlDeviceExt->Specific.Control.LibraryDeviceObject, + Irp); + + // + // Indicate the library is done with the request + // + + AFSClearLibraryRequest(); + +try_exit: + + NOTHING; + } + __except( AFSExceptionFilter( GetExceptionCode(), GetExceptionInformation()) ) + { + + AFSDbgLogMsg( 0, + 0, + "EXCEPTION - AFSFSControl\n"); + } + + return ntStatus; +} diff --git a/src/WINNT/afsrdr/kernel/fs/AFSFastIoSupport.cpp b/src/WINNT/afsrdr/kernel/fs/AFSFastIoSupport.cpp new file mode 100644 index 0000000000..9fe9436906 --- /dev/null +++ b/src/WINNT/afsrdr/kernel/fs/AFSFastIoSupport.cpp @@ -0,0 +1,510 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC. + * Copyright (c) 2009, 2010, 2011 Your File System, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, + * this list of conditions and the following disclaimer in the + * documentation + * and/or other materials provided with the distribution. + * - Neither the names of Kernel Drivers, LLC and Your File System, Inc. + * nor the names of their contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission from Kernel Drivers, LLC and Your File System, Inc. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +// +// File: AFSFastIoSupport.cpp +// + +#include "AFSCommon.h" + +BOOLEAN +AFSFastIoCheckIfPossible( IN struct _FILE_OBJECT *FileObject, + IN PLARGE_INTEGER FileOffset, + IN ULONG Length, + IN BOOLEAN Wait, + IN ULONG LockKey, + IN BOOLEAN CheckForReadOperation, + OUT PIO_STATUS_BLOCK IoStatus, + IN struct _DEVICE_OBJECT *DeviceObject) +{ + + BOOLEAN bStatus = FALSE; + + return bStatus; +} + +BOOLEAN +AFSFastIoRead( IN struct _FILE_OBJECT *FileObject, + IN PLARGE_INTEGER FileOffset, + IN ULONG Length, + IN BOOLEAN Wait, + IN ULONG LockKey, + OUT PVOID Buffer, + OUT PIO_STATUS_BLOCK IoStatus, + IN struct _DEVICE_OBJECT *DeviceObject) +{ + + BOOLEAN bStatus = FALSE; + + return bStatus; +} + +BOOLEAN +AFSFastIoWrite( IN struct _FILE_OBJECT *FileObject, + IN PLARGE_INTEGER FileOffset, + IN ULONG Length, + IN BOOLEAN Wait, + IN ULONG LockKey, + IN PVOID Buffer, + OUT PIO_STATUS_BLOCK IoStatus, + IN struct _DEVICE_OBJECT *DeviceObject) +{ + + BOOLEAN bStatus = FALSE; + + return bStatus; +} + +BOOLEAN +AFSFastIoQueryBasicInfo( IN struct _FILE_OBJECT *FileObject, + IN BOOLEAN Wait, + OUT PFILE_BASIC_INFORMATION Buffer, + OUT PIO_STATUS_BLOCK IoStatus, + IN struct _DEVICE_OBJECT *DeviceObject) +{ + + BOOLEAN bStatus = FALSE; + + return bStatus; +} + +BOOLEAN +AFSFastIoQueryStandardInfo( IN struct _FILE_OBJECT *FileObject, + IN BOOLEAN Wait, + OUT PFILE_STANDARD_INFORMATION Buffer, + OUT PIO_STATUS_BLOCK IoStatus, + IN struct _DEVICE_OBJECT *DeviceObject) +{ + + BOOLEAN bStatus = FALSE; + + return bStatus; +} + +BOOLEAN +AFSFastIoLock( IN struct _FILE_OBJECT *FileObject, + IN PLARGE_INTEGER FileOffset, + IN PLARGE_INTEGER Length, + IN PEPROCESS ProcessId, + IN ULONG Key, + IN BOOLEAN FailImmediately, + IN BOOLEAN ExclusiveLock, + OUT PIO_STATUS_BLOCK IoStatus, + IN struct _DEVICE_OBJECT *DeviceObject) +{ + + BOOLEAN bStatus = FALSE; + + return bStatus; +} + +BOOLEAN +AFSFastIoUnlockSingle( IN struct _FILE_OBJECT *FileObject, + IN PLARGE_INTEGER FileOffset, + IN PLARGE_INTEGER Length, + IN PEPROCESS ProcessId, + IN ULONG Key, + OUT PIO_STATUS_BLOCK IoStatus, + IN struct _DEVICE_OBJECT *DeviceObject) +{ + + BOOLEAN bStatus = FALSE; + + return bStatus; +} + +BOOLEAN +AFSFastIoUnlockAll( IN struct _FILE_OBJECT *FileObject, + IN PEPROCESS ProcessId, + OUT PIO_STATUS_BLOCK IoStatus, + IN struct _DEVICE_OBJECT *DeviceObject) +{ + + BOOLEAN bStatus = FALSE; + + return bStatus; +} + +BOOLEAN +AFSFastIoUnlockAllByKey( IN struct _FILE_OBJECT *FileObject, + IN PVOID ProcessId, + IN ULONG Key, + OUT PIO_STATUS_BLOCK IoStatus, + IN struct _DEVICE_OBJECT *DeviceObject) +{ + + BOOLEAN bStatus = FALSE; + + return bStatus; +} + +BOOLEAN +AFSFastIoDevCtrl( IN struct _FILE_OBJECT *FileObject, + IN BOOLEAN Wait, + IN PVOID InputBuffer OPTIONAL, + IN ULONG InputBufferLength, + OUT PVOID OutputBuffer OPTIONAL, + IN ULONG OutputBufferLength, + IN ULONG IoControlCode, + OUT PIO_STATUS_BLOCK IoStatus, + IN struct _DEVICE_OBJECT *DeviceObject) +{ + + BOOLEAN bStatus = FALSE; + + return bStatus; +} + +void +AFSFastIoAcquireFile( IN struct _FILE_OBJECT *FileObject) +{ + + AFSFcb *pFcb = (AFSFcb *)FileObject->FsContext; + + AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "AFSFastIoAcquireFile Acquiring Fcb lock %08lX EXCL %08lX\n", + &pFcb->NPFcb->Resource, + PsGetCurrentThread()); + + AFSAcquireExcl( &pFcb->NPFcb->Resource, + TRUE); + + return; +} + +void +AFSFastIoReleaseFile( IN struct _FILE_OBJECT *FileObject) +{ + + AFSFcb *pFcb = (AFSFcb *)FileObject->FsContext; + + if( ExIsResourceAcquiredExclusiveLite( &pFcb->NPFcb->Resource)) + { + + AFSReleaseResource( &pFcb->NPFcb->Resource); + } + + return; +} + +VOID +AFSFastIoDetachDevice( IN struct _DEVICE_OBJECT *SourceDevice, + IN struct _DEVICE_OBJECT *TargetDevice) +{ + + return; +} + +BOOLEAN +AFSFastIoQueryNetworkOpenInfo( IN struct _FILE_OBJECT *FileObject, + IN BOOLEAN Wait, + OUT struct _FILE_NETWORK_OPEN_INFORMATION *Buffer, + OUT struct _IO_STATUS_BLOCK *IoStatus, + IN struct _DEVICE_OBJECT *DeviceObject) +{ + + BOOLEAN bStatus = FALSE; + + return bStatus; +} + +BOOLEAN +AFSFastIoMdlRead( IN struct _FILE_OBJECT *FileObject, + IN PLARGE_INTEGER FileOffset, + IN ULONG Length, + IN ULONG LockKey, + OUT PMDL *MdlChain, + OUT PIO_STATUS_BLOCK IoStatus, + IN struct _DEVICE_OBJECT *DeviceObject) +{ + + BOOLEAN bStatus = FALSE; + + return bStatus; +} + +BOOLEAN +AFSFastIoMdlReadComplete( IN struct _FILE_OBJECT *FileObject, + IN PMDL MdlChain, + IN struct _DEVICE_OBJECT *DeviceObject) +{ + + BOOLEAN bStatus = FALSE; + + return bStatus; +} + +BOOLEAN +AFSFastIoPrepareMdlWrite( IN struct _FILE_OBJECT *FileObject, + IN PLARGE_INTEGER FileOffset, + IN ULONG Length, + IN ULONG LockKey, + OUT PMDL *MdlChain, + OUT PIO_STATUS_BLOCK IoStatus, + IN struct _DEVICE_OBJECT *DeviceObject) +{ + + BOOLEAN bStatus = FALSE; + + return bStatus; +} + +BOOLEAN +AFSFastIoMdlWriteComplete( IN struct _FILE_OBJECT *FileObject, + IN PLARGE_INTEGER FileOffset, + IN PMDL MdlChain, + IN struct _DEVICE_OBJECT *DeviceObject) +{ + + BOOLEAN bStatus = FALSE; + + return bStatus; +} + +NTSTATUS +AFSFastIoAcquireForModWrite( IN struct _FILE_OBJECT *FileObject, + IN PLARGE_INTEGER EndingOffset, + OUT struct _ERESOURCE **ResourceToRelease, + IN struct _DEVICE_OBJECT *DeviceObject) +{ + + NTSTATUS ntStatus = STATUS_FILE_LOCK_CONFLICT; + AFSFcb *pFcb = (AFSFcb *)FileObject->FsContext; + + __Enter + { + + if( AFSAcquireExcl( &pFcb->NPFcb->Resource, + BooleanFlagOn( FileObject->Flags, FO_SYNCHRONOUS_IO))) + { + + AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "AFSFastIoAcquireForModWrite Acquired Fcb lock %08lX EXCL %08lX\n", + &pFcb->NPFcb->Resource, + PsGetCurrentThread()); + + ntStatus = STATUS_SUCCESS; + + *ResourceToRelease = &pFcb->NPFcb->Resource; + } + } + + return ntStatus; +} + +NTSTATUS +AFSFastIoReleaseForModWrite( IN struct _FILE_OBJECT *FileObject, + IN struct _ERESOURCE *ResourceToRelease, + IN struct _DEVICE_OBJECT *DeviceObject) +{ + + NTSTATUS ntStatus = STATUS_SUCCESS; + + AFSReleaseResource( ResourceToRelease); + + return ntStatus; +} + +NTSTATUS +AFSFastIoAcquireForCCFlush( IN struct _FILE_OBJECT *FileObject, + IN struct _DEVICE_OBJECT *DeviceObject) +{ + + NTSTATUS ntStatus = STATUS_FILE_LOCK_CONFLICT; + AFSFcb *pFcb = (AFSFcb *)FileObject->FsContext; + + if( !ExIsResourceAcquiredSharedLite( &pFcb->NPFcb->Resource)) + { + + AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "AFSFastIoAcquireForCCFlush Acquiring Fcb lock %08lX EXCL %08lX\n", + &pFcb->NPFcb->Resource, + PsGetCurrentThread()); + + AFSAcquireExcl( &pFcb->NPFcb->Resource, + TRUE); + } + else + { + + AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "AFSFastIoAcquireForCCFlush Acquiring Fcb lock %08lX SHARED %08lX\n", + &pFcb->NPFcb->Resource, + PsGetCurrentThread()); + + AFSAcquireShared( &pFcb->NPFcb->Resource, + TRUE); + } + + ntStatus = STATUS_SUCCESS; + + AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "AFSFastIoAcquireForCCFlush Acquiring Fcb PagingIo lock %08lX SHARED %08lX\n", + &pFcb->NPFcb->PagingResource, + PsGetCurrentThread()); + + AFSAcquireShared( &pFcb->NPFcb->PagingResource, + TRUE); + + // + // Set the TopLevelIrp field for this caller + // + + if( IoGetTopLevelIrp() == NULL) + { + + IoSetTopLevelIrp( (PIRP)FSRTL_CACHE_TOP_LEVEL_IRP); + } + + return ntStatus; +} + +NTSTATUS +AFSFastIoReleaseForCCFlush( IN struct _FILE_OBJECT *FileObject, + IN struct _DEVICE_OBJECT *DeviceObject) +{ + + NTSTATUS ntStatus = STATUS_SUCCESS; + AFSFcb *pFcb = (AFSFcb *)FileObject->FsContext; + + if( IoGetTopLevelIrp() == (PIRP)FSRTL_CACHE_TOP_LEVEL_IRP) + { + + IoSetTopLevelIrp( NULL); + } + + if( ExIsResourceAcquiredExclusiveLite( &pFcb->NPFcb->Resource) || + ExIsResourceAcquiredSharedLite( &pFcb->NPFcb->Resource)) + { + + AFSReleaseResource( &pFcb->NPFcb->Resource); + } + else + { + + AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING, + AFS_TRACE_LEVEL_ERROR, + "AFSFastIoReleaseForCCFlush Called for non-acquired main resource Fcb\n"); + } + + if( ExIsResourceAcquiredSharedLite( &pFcb->NPFcb->PagingResource)) + { + + AFSReleaseResource( &pFcb->NPFcb->PagingResource); + } + else + { + + AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING, + AFS_TRACE_LEVEL_ERROR, + "AFSFastIoReleaseForCCFlush Called for non-acquired paging resource Fcb\n"); + } + + return ntStatus; +} + +BOOLEAN +AFSFastIoReadCompressed( IN struct _FILE_OBJECT *FileObject, + IN PLARGE_INTEGER FileOffset, + IN ULONG Length, + IN ULONG LockKey, + OUT PVOID Buffer, + OUT PMDL *MdlChain, + OUT PIO_STATUS_BLOCK IoStatus, + OUT struct _COMPRESSED_DATA_INFO *CompressedDataInfo, + IN ULONG CompressedDataInfoLength, + IN struct _DEVICE_OBJECT *DeviceObject) +{ + + BOOLEAN bStatus = FALSE; + + return bStatus; +} + +BOOLEAN +AFSFastIoWriteCompressed( IN struct _FILE_OBJECT *FileObject, + IN PLARGE_INTEGER FileOffset, + IN ULONG Length, + IN ULONG LockKey, + IN PVOID Buffer, + OUT PMDL *MdlChain, + OUT PIO_STATUS_BLOCK IoStatus, + IN struct _COMPRESSED_DATA_INFO *CompressedDataInfo, + IN ULONG CompressedDataInfoLength, + IN struct _DEVICE_OBJECT *DeviceObject) +{ + + BOOLEAN bStatus = FALSE; + + return bStatus; +} + +BOOLEAN +AFSFastIoMdlReadCompleteCompressed( IN struct _FILE_OBJECT *FileObject, + IN PMDL MdlChain, + IN struct _DEVICE_OBJECT *DeviceObject) +{ + + BOOLEAN bStatus = FALSE; + + return bStatus; +} + +BOOLEAN +AFSFastIoMdlWriteCompleteCompressed( IN struct _FILE_OBJECT *FileObject, + IN PLARGE_INTEGER FileOffset, + IN PMDL MdlChain, + IN struct _DEVICE_OBJECT *DeviceObject) +{ + + BOOLEAN bStatus = FALSE; + + return bStatus; +} + +BOOLEAN +AFSFastIoQueryOpen( IN struct _IRP *Irp, + OUT PFILE_NETWORK_OPEN_INFORMATION NetworkInformation, + IN struct _DEVICE_OBJECT *DeviceObject) +{ + + BOOLEAN bStatus = FALSE; + + return bStatus; +} diff --git a/src/WINNT/afsrdr/kernel/fs/AFSFileInfo.cpp b/src/WINNT/afsrdr/kernel/fs/AFSFileInfo.cpp new file mode 100644 index 0000000000..74bbad3176 --- /dev/null +++ b/src/WINNT/afsrdr/kernel/fs/AFSFileInfo.cpp @@ -0,0 +1,232 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC. + * Copyright (c) 2009, 2010, 2011 Your File System, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, + * this list of conditions and the following disclaimer in the + * documentation + * and/or other materials provided with the distribution. + * - Neither the names of Kernel Drivers, LLC and Your File System, Inc. + * nor the names of their contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission from Kernel Drivers, LLC and Your File System, Inc. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +// +// File: AFSFileInfo.cpp +// + +#include "AFSCommon.h" + +// +// Function: AFSQueryFileInfo +// +// Description: +// +// This function is the dispatch handler for the IRP_MJ_QUERY_FILE_INFORMATION request +// +// Return: +// +// A status is returned for the function +// + +NTSTATUS +AFSQueryFileInfo( IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + + NTSTATUS ntStatus = STATUS_SUCCESS; + IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp); + AFSDeviceExt *pControlDeviceExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension; + + __try + { + + if( DeviceObject == AFSDeviceObject) + { + + ntStatus = STATUS_INVALID_DEVICE_REQUEST; + + AFSCompleteRequest( Irp, + ntStatus); + + try_return( ntStatus); + } + + if( pIrpSp->FileObject->FsContext == NULL) + { + + // + // Root open + // + + ntStatus = STATUS_INVALID_DEVICE_REQUEST; + + AFSCompleteRequest( Irp, + ntStatus); + + try_return( ntStatus); + } + + // + // Check the state of the library + // + + ntStatus = AFSCheckLibraryState( Irp); + + if( !NT_SUCCESS( ntStatus) || + ntStatus == STATUS_PENDING) + { + + if( ntStatus != STATUS_PENDING) + { + AFSCompleteRequest( Irp, ntStatus); + } + + try_return( ntStatus); + } + + IoSkipCurrentIrpStackLocation( Irp); + + ntStatus = IoCallDriver( pControlDeviceExt->Specific.Control.LibraryDeviceObject, + Irp); + + // + // Indicate the library is done with the request + // + + AFSClearLibraryRequest(); + +try_exit: + + NOTHING; + } + __except( AFSExceptionFilter( GetExceptionCode(), GetExceptionInformation()) ) + { + + AFSDbgLogMsg( 0, + 0, + "EXCEPTION - AFSQueryFileInfo\n"); + + ntStatus = STATUS_UNSUCCESSFUL; + } + + return ntStatus; +} + +// +// Function: AFSSetFileInfo +// +// Description: +// +// This function is the dispatch handler for the IRP_MJ_SET_FILE_INFORMATION request +// +// Return: +// +// A status is returned for the function +// + +NTSTATUS +AFSSetFileInfo( IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + + NTSTATUS ntStatus = STATUS_SUCCESS; + AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)DeviceObject->DeviceExtension; + AFSDeviceExt *pControlDeviceExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension; + IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp); + + __try + { + + if( DeviceObject == AFSDeviceObject) + { + + ntStatus = STATUS_INVALID_DEVICE_REQUEST; + + AFSCompleteRequest( Irp, + ntStatus); + + try_return( ntStatus); + } + + if( pIrpSp->FileObject->FsContext == NULL) + { + + // + // Root open + // + + ntStatus = STATUS_INVALID_DEVICE_REQUEST; + + AFSCompleteRequest( Irp, + ntStatus); + + try_return( ntStatus); + } + + // + // Check the state of the library + // + + ntStatus = AFSCheckLibraryState( Irp); + + if( !NT_SUCCESS( ntStatus) || + ntStatus == STATUS_PENDING) + { + + if( ntStatus != STATUS_PENDING) + { + AFSCompleteRequest( Irp, ntStatus); + } + + try_return( ntStatus); + } + + IoSkipCurrentIrpStackLocation( Irp); + + ntStatus = IoCallDriver( pControlDeviceExt->Specific.Control.LibraryDeviceObject, + Irp); + + // + // Indicate the library is done with the request + // + + AFSClearLibraryRequest(); + +try_exit: + + NOTHING; + } + __except( AFSExceptionFilter( GetExceptionCode(), GetExceptionInformation()) ) + { + + AFSDbgLogMsg( 0, + 0, + "EXCEPTION - AFSSetFileInfo\n"); + + ntStatus = STATUS_UNSUCCESSFUL; + } + + return ntStatus; +} diff --git a/src/WINNT/afsrdr/kernel/fs/AFSFlushBuffers.cpp b/src/WINNT/afsrdr/kernel/fs/AFSFlushBuffers.cpp new file mode 100644 index 0000000000..aecc04c2a5 --- /dev/null +++ b/src/WINNT/afsrdr/kernel/fs/AFSFlushBuffers.cpp @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC. + * Copyright (c) 2009, 2010, 2011 Your File System, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, + * this list of conditions and the following disclaimer in the + * documentation + * and/or other materials provided with the distribution. + * - Neither the names of Kernel Drivers, LLC and Your File System, Inc. + * nor the names of their contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission from Kernel Drivers, LLC and Your File System, Inc. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +// +// File: AFSFlushBuffers.cpp +// + +#include "AFSCommon.h" + +NTSTATUS +AFSFlushBuffers( IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + + NTSTATUS ntStatus = STATUS_SUCCESS; + AFSDeviceExt *pControlDeviceExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension; + + __Enter + { + + if( DeviceObject == AFSDeviceObject) + { + + ntStatus = STATUS_INVALID_DEVICE_REQUEST; + + AFSCompleteRequest( Irp, + ntStatus); + + try_return( ntStatus); + } + + // + // Check the state of the library + // + + ntStatus = AFSCheckLibraryState( Irp); + + if( !NT_SUCCESS( ntStatus) || + ntStatus == STATUS_PENDING) + { + + if( ntStatus != STATUS_PENDING) + { + AFSCompleteRequest( Irp, ntStatus); + } + + try_return( ntStatus); + } + + IoSkipCurrentIrpStackLocation( Irp); + + ntStatus = IoCallDriver( pControlDeviceExt->Specific.Control.LibraryDeviceObject, + Irp); + + // + // Indicate the library is done with the request + // + + AFSClearLibraryRequest(); + +try_exit: + + NOTHING; + } + + return ntStatus; +} diff --git a/src/WINNT/afsrdr/kernel/fs/AFSGeneric.cpp b/src/WINNT/afsrdr/kernel/fs/AFSGeneric.cpp new file mode 100644 index 0000000000..bd01b56560 --- /dev/null +++ b/src/WINNT/afsrdr/kernel/fs/AFSGeneric.cpp @@ -0,0 +1,2050 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC. + * Copyright (c) 2009, 2010, 2011 Your File System, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, + * this list of conditions and the following disclaimer in the + * documentation + * and/or other materials provided with the distribution. + * - Neither the names of Kernel Drivers, LLC and Your File System, Inc. + * nor the names of their contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission from Kernel Drivers, LLC and Your File System, Inc. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +// +// File: AFSGeneric.cpp +// + +#include "AFSCommon.h" + +// +// Function: AFSExceptionFilter +// +// Description: +// +// This function is the exception handler +// +// Return: +// +// A status is returned for the function +// + +ULONG +AFSExceptionFilter( IN ULONG Code, + IN PEXCEPTION_POINTERS ExceptPtrs) +{ + + PEXCEPTION_RECORD ExceptRec; + PCONTEXT Context; + + __try + { + + ExceptRec = ExceptPtrs->ExceptionRecord; + + Context = ExceptPtrs->ContextRecord; + + AFSDbgLogMsg( 0, + 0, + "AFSExceptionFilter (Framework) - EXR %p CXR %p Code %08lX Address %p\n", + ExceptRec, + Context, + ExceptRec->ExceptionCode, + ExceptRec->ExceptionAddress); + + DbgPrint("**** Exception Caught in AFS Redirector ****\n"); + + DbgPrint("\n\nPerform the following WnDbg Cmds:\n"); + DbgPrint("\n\t.exr %p ; .cxr %p\n\n", ExceptRec, Context); + + DbgPrint("**** Exception Complete from AFS Redirector ****\n"); + + if( BooleanFlagOn( AFSDebugFlags, AFS_DBG_BUGCHECK_EXCEPTION)) + { + + KeBugCheck( (ULONG)-2); + } + else + { + + AFSBreakPoint(); + } + } + __except( EXCEPTION_EXECUTE_HANDLER) + { + + NOTHING; + } + + return EXCEPTION_EXECUTE_HANDLER; +} + +// +// Function: AFSAcquireExcl() +// +// Purpose: Called to acquire a resource exclusive with optional wait +// +// Parameters: +// PERESOURCE Resource - Resource to acquire +// BOOLEAN Wait - Whether to block +// +// Return: +// BOOLEAN - Whether the mask was acquired +// + +BOOLEAN +AFSAcquireExcl( IN PERESOURCE Resource, + IN BOOLEAN wait) +{ + + BOOLEAN bStatus = FALSE; + + // + // Normal kernel APCs must be disabled before calling + // ExAcquireResourceExclusiveLite. Otherwise a bugcheck occurs. + // + + KeEnterCriticalRegion(); + + bStatus = ExAcquireResourceExclusiveLite( Resource, + wait); + + if( !bStatus) + { + + KeLeaveCriticalRegion(); + } + + return bStatus; +} + +BOOLEAN +AFSAcquireSharedStarveExclusive( IN PERESOURCE Resource, + IN BOOLEAN Wait) +{ + + BOOLEAN bStatus = FALSE; + + KeEnterCriticalRegion(); + + bStatus = ExAcquireSharedStarveExclusive( Resource, + Wait); + + if( !bStatus) + { + + KeLeaveCriticalRegion(); + } + + return bStatus; +} + +// +// Function: AFSAcquireShared() +// +// Purpose: Called to acquire a resource shared with optional wait +// +// Parameters: +// PERESOURCE Resource - Resource to acquire +// BOOLEAN Wait - Whether to block +// +// Return: +// BOOLEAN - Whether the mask was acquired +// + +BOOLEAN +AFSAcquireShared( IN PERESOURCE Resource, + IN BOOLEAN wait) +{ + + BOOLEAN bStatus = FALSE; + + KeEnterCriticalRegion(); + + bStatus = ExAcquireResourceSharedLite( Resource, + wait); + + if( !bStatus) + { + + KeLeaveCriticalRegion(); + } + + return bStatus; +} + +// +// Function: AFSReleaseResource() +// +// Purpose: Called to release a resource +// +// Parameters: +// PERESOURCE Resource - Resource to release +// +// Return: +// None +// + +void +AFSReleaseResource( IN PERESOURCE Resource) +{ + + if( Resource != &AFSDbgLogLock) + { + + AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "AFSReleaseResource Releasing lock %08lX Thread %08lX\n", + Resource, + PsGetCurrentThread()); + } + + ExReleaseResourceLite( Resource); + + KeLeaveCriticalRegion(); + + return; +} + +void +AFSConvertToShared( IN PERESOURCE Resource) +{ + + AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "AFSConvertToShared Converting lock %08lX Thread %08lX\n", + Resource, + PsGetCurrentThread()); + + ExConvertExclusiveToSharedLite( Resource); + + return; +} + +// +// Function: AFSCompleteRequest +// +// Description: +// +// This function completes irps +// +// Return: +// +// A status is returned for the function +// + +void +AFSCompleteRequest( IN PIRP Irp, + IN ULONG Status) +{ + + Irp->IoStatus.Status = Status; + + IoCompleteRequest( Irp, + IO_NO_INCREMENT); + + return; +} + +NTSTATUS +AFSReadRegistry( IN PUNICODE_STRING RegistryPath) +{ + + NTSTATUS ntStatus = STATUS_SUCCESS; + ULONG Default = 0; + UNICODE_STRING paramPath; + ULONG Value = 0; + RTL_QUERY_REGISTRY_TABLE paramTable[2]; + UNICODE_STRING defaultUnicodeName; + WCHAR SubKeyString[] = L"\\Parameters"; + + // + // Setup the paramPath buffer. + // + + paramPath.MaximumLength = RegistryPath->Length + sizeof( SubKeyString); + paramPath.Buffer = (PWSTR)AFSExAllocatePoolWithTag( PagedPool, + paramPath.MaximumLength, + AFS_GENERIC_MEMORY_15_TAG); + + RtlInitUnicodeString( &defaultUnicodeName, + L"NO NAME"); + + // + // If it exists, setup the path. + // + + if( paramPath.Buffer != NULL) + { + + // + // Move in the paths + // + + RtlCopyMemory( ¶mPath.Buffer[ 0], + &RegistryPath->Buffer[ 0], + RegistryPath->Length); + + RtlCopyMemory( ¶mPath.Buffer[ RegistryPath->Length / 2], + SubKeyString, + sizeof( SubKeyString)); + + paramPath.Length = paramPath.MaximumLength; + + RtlZeroMemory( paramTable, + sizeof( paramTable)); + + Value = 0; + + // + // Setup the table to query the registry for the needed value + // + + paramTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT; + paramTable[0].Name = AFS_REG_DEBUG_FLAGS; + paramTable[0].EntryContext = &Value; + + paramTable[0].DefaultType = REG_DWORD; + paramTable[0].DefaultData = &Default; + paramTable[0].DefaultLength = sizeof (ULONG) ; + + // + // Query the registry + // + + ntStatus = RtlQueryRegistryValues( RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL, + paramPath.Buffer, + paramTable, + NULL, + NULL); + + if( NT_SUCCESS( ntStatus)) + { + + AFSDebugFlags = Value; + } + + RtlZeroMemory( paramTable, + sizeof( paramTable)); + + Value = 0; + + // + // Setup the table to query the registry for the needed value + // + + paramTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT; + paramTable[0].Name = AFS_REG_TRACE_SUBSYSTEM; + paramTable[0].EntryContext = &Value; + + paramTable[0].DefaultType = REG_DWORD; + paramTable[0].DefaultData = &Default; + paramTable[0].DefaultLength = sizeof (ULONG) ; + + // + // Query the registry + // + + ntStatus = RtlQueryRegistryValues( RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL, + paramPath.Buffer, + paramTable, + NULL, + NULL); + + if( NT_SUCCESS( ntStatus)) + { + + AFSTraceComponent = Value; + } + + RtlZeroMemory( paramTable, + sizeof( paramTable)); + + Value = 0; + + // + // Setup the table to query the registry for the needed value + // + + paramTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT; + paramTable[0].Name = AFS_REG_TRACE_BUFFER_LENGTH; + paramTable[0].EntryContext = &Value; + + paramTable[0].DefaultType = REG_DWORD; + paramTable[0].DefaultData = &Default; + paramTable[0].DefaultLength = sizeof (ULONG); + + // + // Query the registry + // + + ntStatus = RtlQueryRegistryValues( RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL, + paramPath.Buffer, + paramTable, + NULL, + NULL); + + if( NT_SUCCESS( ntStatus) && + Value > 0) + { + + AFSDbgBufferLength = Value; + + // + // Let's limit things a bit ... + // + + if( AFSDbgBufferLength > 10240) + { + + AFSDbgBufferLength = 1024; + } + } + else + { + + AFSDbgBufferLength = 0; + } + + // + // Make it bytes + // + + AFSDbgBufferLength *= 1024; + + // + // Now get ready to set up for MaxServerDirty + // + + paramTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT; + paramTable[0].Name = AFS_REG_MAX_DIRTY; + paramTable[0].EntryContext = &Value; + + paramTable[0].DefaultType = REG_DWORD; + paramTable[0].DefaultData = &Default; + paramTable[0].DefaultLength = sizeof (ULONG) ; + + // + // Query the registry + // + + ntStatus = RtlQueryRegistryValues( RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL, + paramPath.Buffer, + paramTable, + NULL, + NULL); + + if( NT_SUCCESS( ntStatus)) + { + + AFSMaxDirtyFile = Value; + } + + RtlZeroMemory( paramTable, + sizeof( paramTable)); + + Value = 0; + + // + // Setup the table to query the registry for the needed value + // + + paramTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT; + paramTable[0].Name = AFS_REG_TRACE_LEVEL; + paramTable[0].EntryContext = &Value; + + paramTable[0].DefaultType = REG_DWORD; + paramTable[0].DefaultData = &Default; + paramTable[0].DefaultLength = sizeof (ULONG) ; + + // + // Query the registry + // + + ntStatus = RtlQueryRegistryValues( RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL, + paramPath.Buffer, + paramTable, + NULL, + NULL); + + if( NT_SUCCESS( ntStatus)) + { + + AFSTraceLevel = Value; + } + + // + // MaxIO + // + + paramTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT; + paramTable[0].Name = AFS_REG_MAX_IO; + paramTable[0].EntryContext = &Value; + + paramTable[0].DefaultType = REG_DWORD; + paramTable[0].DefaultData = &Default; + paramTable[0].DefaultLength = sizeof (ULONG) ; + + // + // Query the registry + // + + ntStatus = RtlQueryRegistryValues( RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL, + paramPath.Buffer, + paramTable, + NULL, + NULL); + + if( NT_SUCCESS( ntStatus)) + { + + AFSMaxDirectIo = Value; + } + + // + // Now set up for ShutdownStatus query + // + + paramTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT; + paramTable[0].Name = AFS_REG_SHUTDOWN_STATUS; + paramTable[0].EntryContext = &Value; + + paramTable[0].DefaultType = REG_DWORD; + paramTable[0].DefaultData = &Default; + paramTable[0].DefaultLength = sizeof (ULONG) ; + + // + // Query the registry + // + + ntStatus = RtlQueryRegistryValues( RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL, + paramPath.Buffer, + paramTable, + NULL, + NULL); + + if( !NT_SUCCESS( ntStatus) || + Value != (ULONG)-1) + { + + SetFlag( AFSDebugFlags, AFS_DBG_CLEAN_SHUTDOWN); + } + + // + // Now set up for RequireCleanShutdown query + // + + paramTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT; + paramTable[0].Name = AFS_REG_REQUIRE_CLEAN_SHUTDOWN; + paramTable[0].EntryContext = &Value; + + paramTable[0].DefaultType = REG_DWORD; + paramTable[0].DefaultData = &Default; + paramTable[0].DefaultLength = sizeof (ULONG) ; + + // + // Query the registry + // + + ntStatus = RtlQueryRegistryValues( RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL, + paramPath.Buffer, + paramTable, + NULL, + NULL); + + if( !NT_SUCCESS( ntStatus) || + Value != 0L) + { + + SetFlag( AFSDebugFlags, AFS_DBG_REQUIRE_CLEAN_SHUTDOWN); + } + + // + // Free up the buffer + // + + ExFreePool( paramPath.Buffer); + + ntStatus = STATUS_SUCCESS; + } + else + { + ntStatus = STATUS_INSUFFICIENT_RESOURCES; + } + + return ntStatus; +} + +NTSTATUS +AFSUpdateRegistryParameter( IN PUNICODE_STRING ValueName, + IN ULONG ValueType, + IN void *ValueData, + IN ULONG ValueDataLength) +{ + + NTSTATUS ntStatus = STATUS_SUCCESS; + UNICODE_STRING paramPath, uniParamKey; + HANDLE hParameters = 0; + ULONG ulDisposition = 0; + OBJECT_ATTRIBUTES stObjectAttributes; + + __Enter + { + + RtlInitUnicodeString( &uniParamKey, + L"\\Parameters"); + + // + // Setup the paramPath buffer. + // + + paramPath.MaximumLength = AFSRegistryPath.Length + uniParamKey.Length; + paramPath.Buffer = (PWSTR)AFSExAllocatePoolWithTag( PagedPool, + paramPath.MaximumLength, + AFS_GENERIC_MEMORY_16_TAG); + + if( paramPath.Buffer == NULL) + { + + try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES); + } + + // + // Move in the paths + // + + RtlCopyMemory( paramPath.Buffer, + AFSRegistryPath.Buffer, + AFSRegistryPath.Length); + + paramPath.Length = AFSRegistryPath.Length; + + RtlCopyMemory( ¶mPath.Buffer[ paramPath.Length / 2], + uniParamKey.Buffer, + uniParamKey.Length); + + paramPath.Length += uniParamKey.Length; + + InitializeObjectAttributes( &stObjectAttributes, + ¶mPath, + OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, + NULL, + NULL); + + ntStatus = ZwOpenKey( &hParameters, + KEY_ALL_ACCESS, + &stObjectAttributes); + + if( !NT_SUCCESS( ntStatus)) + { + + try_return( ntStatus); + } + + // + // Set the value + // + + ntStatus = ZwSetValueKey( hParameters, + ValueName, + 0, + ValueType, + ValueData, + ValueDataLength); + + ZwClose( hParameters); + +try_exit: + + if( paramPath.Buffer != NULL) + { + + // + // Free up the buffer + // + + ExFreePool( paramPath.Buffer); + } + } + + return ntStatus; +} + +NTSTATUS +AFSInitializeControlDevice() +{ + + NTSTATUS ntStatus = STATUS_SUCCESS; + AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension; + AFSProcessCB *pProcessCB = NULL; + + __Enter + { + + // + // Initialize the comm pool resources + // + + ExInitializeResourceLite( &pDeviceExt->Specific.Control.CommServiceCB.IrpPoolLock); + + ExInitializeResourceLite( &pDeviceExt->Specific.Control.CommServiceCB.ResultPoolLock); + + ExInitializeResourceLite( &pDeviceExt->Specific.Control.ExtentReleaseResource); + + ExInitializeResourceLite( &pDeviceExt->Specific.Control.SysName32ListLock); + + ExInitializeResourceLite( &pDeviceExt->Specific.Control.SysName64ListLock); + + // + // And the events + // + + KeInitializeEvent( &pDeviceExt->Specific.Control.CommServiceCB.IrpPoolHasEntries, + NotificationEvent, + FALSE); + + KeInitializeEvent( &pDeviceExt->Specific.Control.CommServiceCB.IrpPoolHasReleaseEntries, + NotificationEvent, + FALSE); + + KeInitializeEvent( &pDeviceExt->Specific.Control.ExtentReleaseEvent, + NotificationEvent, + FALSE); + + pDeviceExt->Specific.Control.ExtentReleaseSequence = 0; + + KeInitializeEvent( &pDeviceExt->Specific.Control.VolumeWorkerCloseEvent, + NotificationEvent, + TRUE); + + // + // Library support information + // + + KeInitializeEvent( &pDeviceExt->Specific.Control.LoadLibraryEvent, + SynchronizationEvent, + TRUE); + + // + // Initialize the library queued as cancelled + // + + pDeviceExt->Specific.Control.LibraryState = AFS_LIBRARY_QUEUE_CANCELLED; + + ExInitializeResourceLite( &pDeviceExt->Specific.Control.LibraryStateLock); + + pDeviceExt->Specific.Control.InflightLibraryRequests = 0; + + KeInitializeEvent( &pDeviceExt->Specific.Control.InflightLibraryEvent, + NotificationEvent, + FALSE); + + pDeviceExt->Specific.Control.ExtentCount = 0; + pDeviceExt->Specific.Control.ExtentsHeldLength = 0; + + KeInitializeEvent( &pDeviceExt->Specific.Control.ExtentsHeldEvent, + NotificationEvent, + TRUE); + + pDeviceExt->Specific.Control.OutstandingServiceRequestCount = 0; + + KeInitializeEvent( &pDeviceExt->Specific.Control.OutstandingServiceRequestEvent, + NotificationEvent, + TRUE); + + ExInitializeResourceLite( &pDeviceExt->Specific.Control.LibraryQueueLock); + + pDeviceExt->Specific.Control.LibraryQueueHead = NULL; + + pDeviceExt->Specific.Control.LibraryQueueTail = NULL; + + // + // Set the initial state of the irp pool + // + + pDeviceExt->Specific.Control.CommServiceCB.IrpPoolControlFlag = POOL_INACTIVE; + + // + // Initialize our process and sid tree information + // + + ExInitializeResourceLite( &pDeviceExt->Specific.Control.ProcessTreeLock); + + pDeviceExt->Specific.Control.ProcessTree.TreeLock = &pDeviceExt->Specific.Control.ProcessTreeLock; + + pDeviceExt->Specific.Control.ProcessTree.TreeHead = NULL; + + ExInitializeResourceLite( &pDeviceExt->Specific.Control.AuthGroupTreeLock); + + pDeviceExt->Specific.Control.AuthGroupTree.TreeLock = &pDeviceExt->Specific.Control.AuthGroupTreeLock; + + pDeviceExt->Specific.Control.AuthGroupTree.TreeHead = NULL; + } + + return ntStatus; +} + +NTSTATUS +AFSRemoveControlDevice() +{ + + NTSTATUS ntStatus = STATUS_SUCCESS; + AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension; + AFSProcessCB *pProcessCB = NULL; + + __Enter + { + + // + // Initialize the comm pool resources + // + + ExDeleteResourceLite( &pDeviceExt->Specific.Control.CommServiceCB.IrpPoolLock); + + ExDeleteResourceLite( &pDeviceExt->Specific.Control.CommServiceCB.ResultPoolLock); + + ExDeleteResourceLite( &pDeviceExt->Specific.Control.ExtentReleaseResource); + + ExDeleteResourceLite( &pDeviceExt->Specific.Control.SysName32ListLock); + + ExDeleteResourceLite( &pDeviceExt->Specific.Control.SysName64ListLock); + + ExDeleteResourceLite( &pDeviceExt->Specific.Control.ProcessTreeLock); + + if( pDeviceExt->Specific.Control.ProcessTree.TreeHead != NULL) + { + ExFreePool( pDeviceExt->Specific.Control.ProcessTree.TreeHead); + } + + ExDeleteResourceLite( &pDeviceExt->Specific.Control.AuthGroupTreeLock); + + ExDeleteResourceLite( &pDeviceExt->Specific.Control.LibraryStateLock); + + ExDeleteResourceLite( &pDeviceExt->Specific.Control.LibraryQueueLock); + } + + return ntStatus; +} + +void +AFSInitServerStrings() +{ + + UNICODE_STRING uniFullName; + WCHAR wchBuffer[ 50]; + + // + // Add the server name into the list of resources + // + + uniFullName.Length = (2 * sizeof( WCHAR)) + AFSServerName.Length; + uniFullName.MaximumLength = uniFullName.Length + sizeof( WCHAR); + + uniFullName.Buffer = wchBuffer; + + wchBuffer[ 0] = L'\\'; + wchBuffer[ 1] = L'\\'; + + RtlCopyMemory( &wchBuffer[ 2], + AFSServerName.Buffer, + AFSServerName.Length); + + AFSAddConnectionEx( &uniFullName, + RESOURCEDISPLAYTYPE_SERVER, + 0); + + // + // Add in the global share name + // + + wchBuffer[ uniFullName.Length/sizeof( WCHAR)] = L'\\'; + + uniFullName.Length += sizeof( WCHAR); + + RtlCopyMemory( &wchBuffer[ uniFullName.Length/sizeof( WCHAR)], + AFSGlobalRootName.Buffer, + AFSGlobalRootName.Length); + + uniFullName.Length += AFSGlobalRootName.Length; + + AFSAddConnectionEx( &uniFullName, + RESOURCEDISPLAYTYPE_SHARE, + AFS_CONNECTION_FLAG_GLOBAL_SHARE); + + return; +} + +NTSTATUS +AFSReadServerName() +{ + + NTSTATUS ntStatus = STATUS_SUCCESS; + ULONG Default = 0; + UNICODE_STRING paramPath; + RTL_QUERY_REGISTRY_TABLE paramTable[2]; + + __Enter + { + + // + // Setup the paramPath buffer. + // + + paramPath.MaximumLength = PAGE_SIZE; + paramPath.Buffer = (PWSTR)AFSExAllocatePoolWithTag( PagedPool, + paramPath.MaximumLength, + AFS_GENERIC_MEMORY_17_TAG); + + // + // If it exists, setup the path. + // + + if( paramPath.Buffer == NULL) + { + + try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES); + } + + // + // Move in the paths + // + + RtlZeroMemory( paramPath.Buffer, + paramPath.MaximumLength); + + RtlCopyMemory( ¶mPath.Buffer[ 0], + L"\\TransarcAFSDaemon\\Parameters", + 58); + + paramPath.Length = 58; + + RtlZeroMemory( paramTable, + sizeof( paramTable)); + + // + // Setup the table to query the registry for the needed value + // + + AFSServerName.Length = 0; + AFSServerName.MaximumLength = 0; + AFSServerName.Buffer = NULL; + + paramTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT; + paramTable[0].Name = AFS_NETBIOS_NAME; + paramTable[0].EntryContext = &AFSServerName; + + paramTable[0].DefaultType = REG_NONE; + paramTable[0].DefaultData = NULL; + paramTable[0].DefaultLength = 0; + + // + // Query the registry + // + + ntStatus = RtlQueryRegistryValues( RTL_REGISTRY_SERVICES, + paramPath.Buffer, + paramTable, + NULL, + NULL); + + // + // Free up the buffer + // + + ExFreePool( paramPath.Buffer); + +try_exit: + + if( !NT_SUCCESS( ntStatus)) + { + + RtlInitUnicodeString( &AFSServerName, + L"AFS"); + } + } + + return ntStatus; +} + +NTSTATUS +AFSSetSysNameInformation( IN AFSSysNameNotificationCB *SysNameInfo, + IN ULONG SysNameInfoBufferLength) +{ + + NTSTATUS ntStatus = STATUS_SUCCESS; + AFSDeviceExt *pControlDevExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension; + AFSSysNameCB *pSysName = NULL; + ERESOURCE *pSysNameLock = NULL; + AFSSysNameCB **pSysNameListHead = NULL, **pSysNameListTail = NULL; + ULONG ulIndex = 0; + __Enter + { + + // + // Depending on the architecture of the information, set up the lsit + // + + if( SysNameInfo->Architecture == AFS_SYSNAME_ARCH_32BIT) + { + + pSysNameLock = &pControlDevExt->Specific.Control.SysName32ListLock; + + pSysNameListHead = &pControlDevExt->Specific.Control.SysName32ListHead; + + pSysNameListTail = &pControlDevExt->Specific.Control.SysName32ListTail; + } + else + { + +#if defined(_WIN64) + + pSysNameLock = &pControlDevExt->Specific.Control.SysName64ListLock; + + pSysNameListHead = &pControlDevExt->Specific.Control.SysName64ListHead; + + pSysNameListTail = &pControlDevExt->Specific.Control.SysName64ListTail; + +#else + + try_return( ntStatus = STATUS_INVALID_PARAMETER); +#endif + } + + // + // Process the request + // + + AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "AFSSetSysNameInformation Acquiring SysName lock %08lX EXCL %08lX\n", + pSysNameLock, + PsGetCurrentThread()); + + AFSAcquireExcl( pSysNameLock, + TRUE); + + // + // If we already have a list, then tear it down + // + + if( *pSysNameListHead != NULL) + { + + AFSResetSysNameList( *pSysNameListHead); + + *pSysNameListHead = NULL; + } + + // + // Loop through the entries adding in a node for each + // + + while( ulIndex < SysNameInfo->NumberOfNames) + { + + pSysName = (AFSSysNameCB *)AFSExAllocatePoolWithTag( PagedPool, + sizeof( AFSSysNameCB) + + SysNameInfo->SysNames[ ulIndex].Length + + sizeof( WCHAR), + AFS_SYS_NAME_NODE_TAG); + + if( pSysName == NULL) + { + + // + // Reset the current list + // + + AFSResetSysNameList( *pSysNameListHead); + + *pSysNameListHead = NULL; + + try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES); + } + + RtlZeroMemory( pSysName, + sizeof( AFSSysNameCB) + + SysNameInfo->SysNames[ ulIndex].Length + + sizeof( WCHAR)); + + pSysName->SysName.Length = (USHORT)SysNameInfo->SysNames[ ulIndex].Length; + + pSysName->SysName.MaximumLength = pSysName->SysName.Length + sizeof( WCHAR); + + pSysName->SysName.Buffer = (WCHAR *)((char *)pSysName + sizeof( AFSSysNameCB)); + + RtlCopyMemory( pSysName->SysName.Buffer, + SysNameInfo->SysNames[ ulIndex].String, + pSysName->SysName.Length); + + if( *pSysNameListHead == NULL) + { + + *pSysNameListHead = pSysName; + } + else + { + + (*pSysNameListTail)->fLink = pSysName; + } + + *pSysNameListTail = pSysName; + + ulIndex++; + } + +try_exit: + + AFSReleaseResource( pSysNameLock); + } + + return ntStatus; +} + +void +AFSResetSysNameList( IN AFSSysNameCB *SysNameList) +{ + + AFSSysNameCB *pNextEntry = NULL, *pCurrentEntry = SysNameList; + + while( pCurrentEntry != NULL) + { + + pNextEntry = pCurrentEntry->fLink; + + ExFreePool( pCurrentEntry); + + pCurrentEntry = pNextEntry; + } + + return; +} + +NTSTATUS +AFSDefaultDispatch( IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + + NTSTATUS ntStatus = STATUS_INVALID_DEVICE_REQUEST; + PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp); + + AFSCompleteRequest( Irp, + ntStatus); + + return ntStatus; +} + +NTSTATUS +AFSSendDeviceIoControl( IN DEVICE_OBJECT *TargetDeviceObject, + IN ULONG IOControl, + IN void *InputBuffer, + IN ULONG InputBufferLength, + IN OUT void *OutputBuffer, + IN ULONG OutputBufferLength, + OUT ULONG *ResultLength) +{ + + NTSTATUS ntStatus = STATUS_SUCCESS; + PIRP pIrp = NULL; + KEVENT kEvent; + PIO_STACK_LOCATION pIoStackLocation = NULL; + + __Enter + { + + // + // Initialize the event + // + + KeInitializeEvent( &kEvent, + SynchronizationEvent, + FALSE); + + // + // Allocate an irp for this request. This could also come from a + // private pool, for instance. + // + + pIrp = IoAllocateIrp( TargetDeviceObject->StackSize, + FALSE); + + if( pIrp == NULL) + { + + try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES); + } + + // + // Build the IRP's main body + // + + pIrp->RequestorMode = KernelMode; + + // + // Set up the I/O stack location. + // + + pIoStackLocation = IoGetNextIrpStackLocation( pIrp); + pIoStackLocation->MajorFunction = IRP_MJ_DEVICE_CONTROL; + pIoStackLocation->DeviceObject = TargetDeviceObject; + + pIoStackLocation->Parameters.DeviceIoControl.IoControlCode = IOControl; + + pIrp->AssociatedIrp.SystemBuffer = (void *)InputBuffer; + pIoStackLocation->Parameters.DeviceIoControl.InputBufferLength = InputBufferLength; + + // + // Set the completion routine. + // + + IoSetCompletionRoutine( pIrp, + AFSIrpComplete, + &kEvent, + TRUE, + TRUE, + TRUE); + + // + // Send it to the FSD + // + + ntStatus = IoCallDriver( TargetDeviceObject, + pIrp); + + if( NT_SUCCESS( ntStatus)) + { + + // + // Wait for the I/O + // + + ntStatus = KeWaitForSingleObject( &kEvent, + Executive, + KernelMode, + FALSE, + 0); + + if( NT_SUCCESS( ntStatus)) + { + + ntStatus = pIrp->IoStatus.Status; + + if( ResultLength != NULL) + { + *ResultLength = (ULONG)pIrp->IoStatus.Information; + } + } + } + +try_exit: + + if( pIrp != NULL) + { + + if( pIrp->MdlAddress != NULL) + { + + if( FlagOn( pIrp->MdlAddress->MdlFlags, MDL_PAGES_LOCKED)) + { + + MmUnlockPages( pIrp->MdlAddress); + } + + IoFreeMdl( pIrp->MdlAddress); + } + + pIrp->MdlAddress = NULL; + + // + // Free the Irp + // + + IoFreeIrp( pIrp); + } + } + + return ntStatus; +} + +NTSTATUS +AFSIrpComplete( IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp, + IN PVOID Context) +{ + + KEVENT *pEvent = (KEVENT *)Context; + + KeSetEvent( pEvent, + 0, + FALSE); + + return STATUS_MORE_PROCESSING_REQUIRED; +} + +void * +AFSExAllocatePoolWithTag( IN POOL_TYPE PoolType, + IN SIZE_T NumberOfBytes, + IN ULONG Tag) +{ + + void *pBuffer = NULL; + + pBuffer = ExAllocatePoolWithTag( PoolType, + NumberOfBytes, + Tag); + + if( pBuffer == NULL) + { + + if( BooleanFlagOn( AFSDebugFlags, AFS_DBG_BUGCHECK_EXCEPTION)) + { + + KeBugCheck( (ULONG)-2); + } + else + { + + AFSDbgLogMsg( 0, + 0, + "AFSExAllocatePoolWithTag failure Type %08lX Size %08lX Tag %08lX %08lX\n", + PoolType, + NumberOfBytes, + Tag, + PsGetCurrentThread()); + + switch ( Tag ) { + + case AFS_GENERIC_MEMORY_21_TAG: + case AFS_GENERIC_MEMORY_22_TAG: + // AFSDumpTraceFiles -- do nothing; + break; + + default: + AFSBreakPoint(); + } + } + } + + return pBuffer; +} + +void +AFSExFreePool( IN void *Buffer) +{ + + ExFreePool( Buffer); + + return; +} + +NTSTATUS +AFSShutdownRedirector() +{ + + NTSTATUS ntStatus = STATUS_SUCCESS; + AFSDeviceExt *pRDRDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension; + AFSDeviceExt *pControlDevExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension; + LARGE_INTEGER liTimeout; + + __Enter + { + + AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "%s Shutting down redirector Extent count %08lX Request count %08lX\n", + __FUNCTION__, + pControlDevExt->Specific.Control.ExtentCount, + pControlDevExt->Specific.Control.OutstandingServiceRequestCount); + + // + // Set the shutdown flag so the worker is more agressive in tearing down extents + // + + SetFlag( pRDRDevExt->DeviceFlags, AFS_DEVICE_FLAG_REDIRECTOR_SHUTDOWN); + + // + // Wait on any outstanding service requests + // + + liTimeout.QuadPart = -(30 *AFS_ONE_SECOND); + + ntStatus = KeWaitForSingleObject( &pControlDevExt->Specific.Control.OutstandingServiceRequestEvent, + Executive, + KernelMode, + FALSE, + &liTimeout); + + if( ntStatus == STATUS_TIMEOUT) + { + + AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING, + AFS_TRACE_LEVEL_WARNING, + "AFSShutdownRedirector Failed to complete all service requests Remaining count %08lX\n", + pControlDevExt->Specific.Control.OutstandingServiceRequestCount); + + try_return( ntStatus = STATUS_UNSUCCESSFUL); + } + + AFSProcessQueuedResults( TRUE); + + // + // Wait for all extents to be released + // + + liTimeout.QuadPart = -(30 *AFS_ONE_SECOND); + + ntStatus = KeWaitForSingleObject( &pControlDevExt->Specific.Control.ExtentsHeldEvent, + Executive, + KernelMode, + FALSE, + &liTimeout); + + if( ntStatus == STATUS_TIMEOUT) + { + + AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING, + AFS_TRACE_LEVEL_WARNING, + "AFSShutdownRedirector Failed to purge all extents Remaining count %08lX\n", + pControlDevExt->Specific.Control.ExtentCount); + + try_return( ntStatus = STATUS_UNSUCCESSFUL); + } + + ntStatus = AFSUnloadLibrary( TRUE); + + if( !NT_SUCCESS( ntStatus)) + { + + try_return( ntStatus); + } + +try_exit: + + AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "%s Completed shut down of redirector Extent count %08lX Request count %08lX Status %08lX\n", + __FUNCTION__, + pControlDevExt->Specific.Control.ExtentCount, + pControlDevExt->Specific.Control.OutstandingServiceRequestCount, + ntStatus); + } + + return ntStatus; +} + +// +// Cache manager callback routines +// + +BOOLEAN +AFSAcquireFcbForLazyWrite( IN PVOID Fcb, + IN BOOLEAN Wait) +{ + + BOOLEAN bStatus = FALSE; + AFSFcb *pFcb = (AFSFcb *)Fcb; + BOOLEAN bReleaseMain = FALSE, bReleasePaging = FALSE; + + // + // Try and acquire the Fcb resource + // + + AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "AFSAcquireFcbForLazyWrite Acquiring Fcb %08lX\n", + Fcb); + + ASSERT( NULL == pFcb->Specific.File.LazyWriterThread); + + pFcb->Specific.File.LazyWriterThread = PsGetCurrentThread(); + + AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "AFSAcquireFcbForLazyWrite Attempt to acquire Fcb lock %08lX SHARED %08lX\n", + &pFcb->NPFcb->Resource, + PsGetCurrentThread()); + + if( AFSAcquireShared( &pFcb->NPFcb->Resource, + Wait)) + { + + AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "AFSAcquireFcbForLazyWrite Acquired Fcb lock %08lX SHARED %08lX\n", + &pFcb->NPFcb->Resource, + PsGetCurrentThread()); + + bReleaseMain = TRUE; + + // + // Try and grab the paging + // + + AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "AFSAcquireFcbForLazyWrite Attempt to acquire Fcb PagingIo lock %08lX SHARED %08lX\n", + &pFcb->NPFcb->PagingResource, + PsGetCurrentThread()); + + if( AFSAcquireShared( &pFcb->NPFcb->PagingResource, + Wait)) + { + + AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "AFSAcquireFcbForLazyWrite Acquired Fcb PagingIo lock %08lX SHARED %08lX\n", + &pFcb->NPFcb->PagingResource, + PsGetCurrentThread()); + + bReleasePaging = TRUE; + + // + // All is well ... + // + + bStatus = TRUE; + + IoSetTopLevelIrp( (PIRP)FSRTL_CACHE_TOP_LEVEL_IRP); + } + } + + if( !bStatus) + { + + if( bReleaseMain) + { + + AFSReleaseResource( &pFcb->NPFcb->Resource); + } + + if( bReleasePaging) + { + + AFSReleaseResource( &pFcb->NPFcb->PagingResource); + } + } + + return bStatus; +} + +VOID +AFSReleaseFcbFromLazyWrite( IN PVOID Fcb) +{ + + AFSFcb *pFcb = (AFSFcb *)Fcb; + + AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "AFSReleaseFcbFromLazyWrite Releasing Fcb %08lX\n", + Fcb); + + IoSetTopLevelIrp( NULL); + + ASSERT( PsGetCurrentThread() == pFcb->Specific.File.LazyWriterThread); + + pFcb->Specific.File.LazyWriterThread = NULL; + + + AFSReleaseResource( &pFcb->NPFcb->PagingResource); + + AFSReleaseResource( &pFcb->NPFcb->Resource); + + return; +} + +BOOLEAN +AFSAcquireFcbForReadAhead( IN PVOID Fcb, + IN BOOLEAN Wait) +{ + + BOOLEAN bStatus = FALSE; + AFSFcb *pFcb = (AFSFcb *)Fcb; + + AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "AFSAcquireFcbForReadAhead Attempt to acquire Fcb lock %08lX SHARED %08lX\n", + &pFcb->NPFcb->Resource, + PsGetCurrentThread()); + + if( AFSAcquireShared( &pFcb->NPFcb->Resource, + Wait)) + { + + AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "AFSAcquireFcbForReadAhead Acquired Fcb lock %08lX SHARED %08lX\n", + &pFcb->NPFcb->Resource, + PsGetCurrentThread()); + + bStatus = TRUE; + + IoSetTopLevelIrp( (PIRP)FSRTL_CACHE_TOP_LEVEL_IRP); + } + + return bStatus; +} + +VOID +AFSReleaseFcbFromReadAhead( IN PVOID Fcb) +{ + + AFSFcb *pFcb = (AFSFcb *)Fcb; + + IoSetTopLevelIrp( NULL); + + AFSReleaseResource( &pFcb->NPFcb->Resource); + + return; +} + +NTSTATUS +AFSGetCallerSID( OUT UNICODE_STRING *SIDString, OUT BOOLEAN *pbImpersonation) +{ + + NTSTATUS ntStatus = STATUS_SUCCESS; + PACCESS_TOKEN hToken = NULL; + TOKEN_USER *pTokenInfo = NULL; + BOOLEAN bCopyOnOpen = FALSE; + BOOLEAN bEffectiveOnly = FALSE; + BOOLEAN bPrimaryToken = FALSE; + SECURITY_IMPERSONATION_LEVEL stImpersonationLevel; + UNICODE_STRING uniSIDString; + + __Enter + { + + hToken = PsReferenceImpersonationToken( PsGetCurrentThread(), + &bCopyOnOpen, + &bEffectiveOnly, + &stImpersonationLevel); + + if( hToken == NULL) + { + + hToken = PsReferencePrimaryToken( PsGetCurrentProcess()); + + if( hToken == NULL) + { + + AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING, + AFS_TRACE_LEVEL_ERROR, + "AFSGetCallerSID Failed to retrieve impersonation or primary token\n"); + + try_return( ntStatus); + } + + bPrimaryToken = TRUE; + } + + ntStatus = SeQueryInformationToken( hToken, + TokenUser, + (PVOID *)&pTokenInfo); + + if( !NT_SUCCESS( ntStatus)) + { + + AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING, + AFS_TRACE_LEVEL_ERROR, + "AFSGetCallerSID Failed to retrieve information Status %08lX\n", ntStatus); + + try_return( ntStatus); + } + + uniSIDString.Length = 0; + uniSIDString.MaximumLength = 0; + uniSIDString.Buffer = NULL; + + ntStatus = RtlConvertSidToUnicodeString( &uniSIDString, + pTokenInfo->User.Sid, + TRUE); + + if( !NT_SUCCESS( ntStatus)) + { + + AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING, + AFS_TRACE_LEVEL_ERROR, + "AFSGetCallerSID Failed to convert sid to string Status %08lX\n", ntStatus); + + try_return( ntStatus); + } + + *SIDString = uniSIDString; + + AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING | AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE_2, + "AFSGetCallerSID Successfully retrieved SID %wZ\n", + SIDString); + + if ( bPrimaryToken == FALSE && + pbImpersonation) + { + *pbImpersonation = TRUE; + } + +try_exit: + + if( hToken != NULL) + { + if( bPrimaryToken) + { + PsDereferencePrimaryToken( hToken); + } + else + { + PsDereferenceImpersonationToken( hToken); + } + } + + if( pTokenInfo != NULL) + { + AFSExFreePool( pTokenInfo); + } + } + + return ntStatus; +} + +ULONG +AFSGetSessionId( IN HANDLE ProcessId, OUT BOOLEAN *pbImpersonation) +{ + + NTSTATUS ntStatus = STATUS_SUCCESS; + PACCESS_TOKEN hToken = NULL; + ULONG ulSessionId = (ULONG)-1; + BOOLEAN bCopyOnOpen = FALSE; + BOOLEAN bEffectiveOnly = FALSE; + BOOLEAN bPrimaryToken = FALSE; + SECURITY_IMPERSONATION_LEVEL stImpersonationLevel; + + __Enter + { + + hToken = PsReferenceImpersonationToken( PsGetCurrentThread(), + &bCopyOnOpen, + &bEffectiveOnly, + &stImpersonationLevel); + + if( hToken == NULL) + { + + hToken = PsReferencePrimaryToken( PsGetCurrentProcess()); + + if( hToken == NULL) + { + + AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING, + AFS_TRACE_LEVEL_ERROR, + "AFSGetSessionId Failed to retrieve impersonation or primary token\n"); + + try_return( ntStatus); + } + + bPrimaryToken = TRUE; + } + + ntStatus = SeQueryInformationToken( hToken, + TokenSessionId, + (PVOID *)&ulSessionId); + + if( !NT_SUCCESS( ntStatus)) + { + ulSessionId = (ULONG)-1; + + AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING, + AFS_TRACE_LEVEL_ERROR, + "AFSGetSessionId Failed to retrieve session id Status %08lX\n", + ntStatus); + + try_return( ntStatus); + } + + AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING | AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE_2, + "AFSGetSessionId found %08lX\n", + ulSessionId); + + if ( bPrimaryToken == FALSE && + pbImpersonation) + { + *pbImpersonation = TRUE; + } + +try_exit: + + if( hToken != NULL) + { + if( bPrimaryToken) + { + PsDereferencePrimaryToken( hToken); + } + else + { + PsDereferenceImpersonationToken( hToken); + } + } + } + + return ulSessionId; +} + +NTSTATUS +AFSCheckThreadDacl( OUT GUID *AuthGroup) +{ + + NTSTATUS ntStatus = STATUS_UNSUCCESSFUL; + ULONG idx; + PACCESS_TOKEN token = NULL; + PTOKEN_DEFAULT_DACL defDacl = NULL; + PACE_HEADER ace; + PACCESS_ALLOWED_ACE adace; + BOOLEAN bCopyOnOpen = FALSE, bEffectiveOnly = FALSE; + SECURITY_IMPERSONATION_LEVEL stImpersonationLevel; + BOOLEAN bLocatedACE = FALSE; + + __Enter + { + + token = PsReferenceImpersonationToken( PsGetCurrentThread(), + &bCopyOnOpen, + &bEffectiveOnly, + &stImpersonationLevel); + + if( token == NULL) + { + try_return( ntStatus); + } + + ntStatus = SeQueryInformationToken( token, + TokenDefaultDacl, + (PVOID *)&defDacl); + + if( ntStatus != STATUS_SUCCESS) + { + try_return( ntStatus); + } + + // scan through all ACEs in the DACL + for (idx = 0, ace = (PACE_HEADER)((char *)defDacl->DefaultDacl + sizeof(ACL)); idx < defDacl->DefaultDacl->AceCount; idx++) + { + if (ace->AceType == ACCESS_ALLOWED_ACE_TYPE) + { + adace = (PACCESS_ALLOWED_ACE)ace; + + if (adace->Header.AceSize == (FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + AFS_DACL_SID_LENGTH)) + { + if (RtlCompareMemory( RtlSubAuthoritySid((PSID)&adace->SidStart, 0), &AFSSidGuid, sizeof(GUID)) == sizeof(GUID)) + { + + RtlCopyMemory( AuthGroup, + RtlSubAuthoritySid((PSID)&adace->SidStart, 4), + sizeof( GUID)); + + bLocatedACE = TRUE; + + break; + } + } + } + + // go to next ace + ace = (PACE_HEADER)((char *)ace + ace->AceSize); + } + +try_exit: + + if( token != NULL) + { + PsDereferenceImpersonationToken( token); + } + + if (defDacl != NULL) + { + ExFreePool(defDacl); + } + + if( !bLocatedACE) + { + ntStatus = STATUS_UNSUCCESSFUL; + } + } + + return ntStatus; +} + +NTSTATUS +AFSProcessSetProcessDacl( IN AFSProcessCB *ProcessCB) +{ + + PTOKEN_DEFAULT_DACL defDacl = NULL; + HANDLE hToken = NULL; + PACE_HEADER ace = NULL; + SID_IDENTIFIER_AUTHORITY sia = SECURITY_NT_AUTHORITY; + PACCESS_ALLOWED_ACE aaace; + ULONG bytesNeeded; + ULONG bytesReturned; + ULONG idx; + PSID psid; + NTSTATUS ntStatus = STATUS_SUCCESS; + + __Enter + { + + ntStatus = ZwOpenProcessTokenEx( NtCurrentProcess(), + GENERIC_ALL, + OBJ_KERNEL_HANDLE, + &hToken); + + if( !NT_SUCCESS( ntStatus)) + { + try_return( ntStatus); + } + + // get the size of the current DACL + ntStatus = ZwQueryInformationToken( hToken, + TokenDefaultDacl, + NULL, + 0, + &bytesNeeded); + + // if we failed to get the buffer size needed + if ((ntStatus != STATUS_SUCCESS) && (ntStatus != STATUS_BUFFER_TOO_SMALL)) + { + try_return( ntStatus); + } + + // tack on enough space for our ACE if we need to add it... + bytesNeeded += FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + AFS_DACL_SID_LENGTH; + + // allocate space for the DACL + defDacl = (PTOKEN_DEFAULT_DACL)ExAllocatePoolWithTag( PagedPool, bytesNeeded, AFS_GENERIC_MEMORY_26_TAG); + + if (defDacl == NULL) + { + try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES); + } + + // get the DACL + ntStatus = ZwQueryInformationToken( hToken, + TokenDefaultDacl, + defDacl, + bytesNeeded, + &bytesReturned); + + if( ntStatus != STATUS_SUCCESS) + { + try_return( ntStatus); + } + + // scan through DACL to see if we have the SID set already... + ace = (PACE_HEADER)((char *)defDacl->DefaultDacl + sizeof(ACL)); + for (idx = 0; idx < defDacl->DefaultDacl->AceCount; idx++) + { + if (ace->AceType == ACCESS_ALLOWED_ACE_TYPE) + { + aaace = (PACCESS_ALLOWED_ACE)ace; + + if (aaace->Header.AceSize == (FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + AFS_DACL_SID_LENGTH)) + { + // if the GUID part matches + if( RtlCompareMemory( RtlSubAuthoritySid((PSID)&aaace->SidStart, 0), + &AFSSidGuid, + sizeof(GUID)) == sizeof(GUID)) + { + + if ( RtlCompareMemory( RtlSubAuthoritySid((PSID)&aaace->SidStart, 4), + ProcessCB->ActiveAuthGroup, + sizeof( GUID)) != sizeof( GUID)) + { + + RtlCopyMemory( RtlSubAuthoritySid((PSID)&aaace->SidStart, 4), + ProcessCB->ActiveAuthGroup, + sizeof( GUID)); + + if( AFSSetInformationToken != NULL) + { + ntStatus = AFSSetInformationToken( hToken, + TokenDefaultDacl, + defDacl, + bytesReturned); + } + } + + try_return( ntStatus); + } + } + } + + // go to next ace + ace = (PACE_HEADER)((char *)ace + ace->AceSize); + } + + // + // if we made it here we need to add a new ACE to the DACL + // + + aaace = (ACCESS_ALLOWED_ACE *)ace; + aaace->Header.AceType = ACCESS_ALLOWED_ACE_TYPE; + aaace->Header.AceFlags = 0; + aaace->Mask = GENERIC_ALL; + psid = (PSID)&aaace->SidStart; + RtlInitializeSid( psid, &sia, 8); + + RtlCopyMemory( RtlSubAuthoritySid(psid, 0), + &AFSSidGuid, + sizeof(GUID)); + + RtlCopyMemory( RtlSubAuthoritySid(psid, 4), + ProcessCB->ActiveAuthGroup, + sizeof( GUID)); + + aaace->Header.AceSize = (USHORT)(FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + RtlLengthSid( psid)); + + defDacl->DefaultDacl->AclSize += aaace->Header.AceSize; + defDacl->DefaultDacl->AceCount++; + + if( AFSSetInformationToken != NULL) + { + ntStatus = AFSSetInformationToken( hToken, + TokenDefaultDacl, + defDacl, + defDacl->DefaultDacl->AclSize + sizeof(PTOKEN_DEFAULT_DACL)); + } + +try_exit: + + if( hToken != NULL) + { + ZwClose( hToken); + } + + if (defDacl != NULL) + { + ExFreePool( defDacl); + } + } + + return ntStatus; +} + + diff --git a/src/WINNT/afsrdr/kernel/fs/AFSInit.cpp b/src/WINNT/afsrdr/kernel/fs/AFSInit.cpp new file mode 100644 index 0000000000..770de37934 --- /dev/null +++ b/src/WINNT/afsrdr/kernel/fs/AFSInit.cpp @@ -0,0 +1,503 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC. + * Copyright (c) 2009, 2010, 2011 Your File System, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, + * this list of conditions and the following disclaimer in the + * documentation + * and/or other materials provided with the distribution. + * - Neither the names of Kernel Drivers, LLC and Your File System, Inc. + * nor the names of their contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission from Kernel Drivers, LLC and Your File System, Inc. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +// +// File: AFSInit.cpp +// + +#include "AFSCommon.h" + +#ifndef AMD64 +extern "C" +{ +extern void *KeServiceDescriptorTable; +}; +#endif + +// +// DriverEntry +// +// This is the initial entry point for the driver. +// +// Inputs: +// DriverObject Pointer to Driver Object created by I/O manager +// RegistryPath Pointer to registry path representing this Driver +// +// Returns: +// Success To indicate Driver's inituaialization processing +// was successful +// NT ERROR STATUS Otherwise -- Driver does not remain loaded +// + +NTSTATUS +DriverEntry( PDRIVER_OBJECT DriverObject, + PUNICODE_STRING RegistryPath) +{ + + NTSTATUS ntStatus = STATUS_SUCCESS; + AFSDeviceExt *pDeviceExt; + ULONG ulTimeIncrement = 0; + UNICODE_STRING uniSymLinkName; + UNICODE_STRING uniDeviceName; + ULONG ulIndex = 0; + ULONG ulValue = 0; + UNICODE_STRING uniValueName; + BOOLEAN bExit = FALSE; + UNICODE_STRING uniRoutine; + RTL_OSVERSIONINFOW sysVersion; + + __try + { + + DbgPrint("AFSRedirFs DriverEntry Initialization build %s:%s\n", __DATE__, __TIME__); + + // + // Initialize some local variables for easier processing + // + + uniSymLinkName.Buffer = NULL; + + AFSDumpFileLocation.Length = 0; + AFSDumpFileLocation.MaximumLength = 0; + AFSDumpFileLocation.Buffer = NULL; + + AFSDumpFileName.Length = 0; + AFSDumpFileName.Buffer = NULL; + AFSDumpFileName.MaximumLength = 0; + + ExInitializeResourceLite( &AFSDbgLogLock); + + // + // Initialize the server name + // + + AFSReadServerName(); + + RtlZeroMemory( &sysVersion, + sizeof( RTL_OSVERSIONINFOW)); + + sysVersion.dwOSVersionInfoSize = sizeof( RTL_OSVERSIONINFOW); + + RtlGetVersion( &sysVersion); + + RtlInitUnicodeString( &uniRoutine, + L"ZwSetInformationToken"); + + AFSSetInformationToken = (PAFSSetInformationToken)MmGetSystemRoutineAddress( &uniRoutine); + + if( AFSSetInformationToken == NULL) + { +#ifndef AMD64 + AFSSrvcTableEntry *pServiceTable = NULL; + + pServiceTable = (AFSSrvcTableEntry *)KeServiceDescriptorTable; + + // + // Only perform this lookup for Windows XP. + // + + if( pServiceTable != NULL && + sysVersion.dwMajorVersion == 5 && + sysVersion.dwMinorVersion == 1) + { + AFSSetInformationToken = (PAFSSetInformationToken)pServiceTable->ServiceTable[ 0xE6]; + } +#endif + } + + // + // And the global root share name + // + + RtlInitUnicodeString( &AFSGlobalRootName, + AFS_GLOBAL_ROOT_SHARE_NAME); + + RtlZeroMemory( &AFSNoPAGAuthGroup, + sizeof( GUID)); + + // + // Our backdoor to not let the driver load + // + + if( bExit) + { + try_return( ntStatus); + } + + // + // Perform some initialization + // + + AFSDriverObject = DriverObject; + + ntStatus = AFSReadRegistry( RegistryPath); + + if( !NT_SUCCESS( ntStatus)) + { + + DbgPrint("AFS DriverEntry: Failed to read registry Status %08lX\n", ntStatus); + + ntStatus = STATUS_SUCCESS; + } + + // + // Initialize the debug log and dump file interface + // + + AFSInitializeDbgLog(); + + AFSInitializeDumpFile(); + +#if DBG + + if( BooleanFlagOn( AFSDebugFlags, AFS_DBG_FLAG_BREAK_ON_ENTRY)) + { + + DbgPrint("AFSRedirFs DriverEntry - Break on entry\n"); + + AFSBreakPoint(); + + if ( bExit) + { + // + // Just as above + // + try_return( ntStatus = STATUS_UNSUCCESSFUL); + } + } +#endif + + if( BooleanFlagOn( AFSDebugFlags, AFS_DBG_REQUIRE_CLEAN_SHUTDOWN) && + !BooleanFlagOn( AFSDebugFlags, AFS_DBG_CLEAN_SHUTDOWN)) + { + + AFSPrint("AFS DriverEntry: Failed to shutdown clean, exiting\n"); + + try_return( ntStatus = STATUS_UNSUCCESSFUL); + } + + // + // Setup the registry string + // + + AFSRegistryPath.MaximumLength = RegistryPath->MaximumLength; + AFSRegistryPath.Length = RegistryPath->Length; + + AFSRegistryPath.Buffer = (PWSTR)ExAllocatePoolWithTag( PagedPool, + AFSRegistryPath.Length, + AFS_GENERIC_MEMORY_18_TAG); + + if( AFSRegistryPath.Buffer == NULL) + { + + DbgPrint("AFSRedirFs DriverEntry Failed to allocate registry path buffer\n"); + + try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES); + } + + RtlCopyMemory( AFSRegistryPath.Buffer, + RegistryPath->Buffer, + RegistryPath->Length); + + if( BooleanFlagOn( AFSDebugFlags, AFS_DBG_REQUIRE_CLEAN_SHUTDOWN)) + { + + // + // Update the shutdown flag + // + + ulValue = (ULONG)-1; + + RtlInitUnicodeString( &uniValueName, + AFS_REG_SHUTDOWN_STATUS); + + AFSUpdateRegistryParameter( &uniValueName, + REG_DWORD, + &ulValue, + sizeof( ULONG)); + } + + RtlInitUnicodeString( &uniDeviceName, + AFS_CONTROL_DEVICE_NAME); + + ntStatus = IoCreateDeviceSecure( DriverObject, + sizeof( AFSDeviceExt), + &uniDeviceName, + FILE_DEVICE_NETWORK_FILE_SYSTEM, + 0, + FALSE, + &SDDL_DEVOBJ_SYS_ALL_ADM_RWX_WORLD_RWX_RES_RWX, + (LPCGUID)&GUID_SD_AFS_REDIRECTOR_CONTROL_OBJECT, + &AFSDeviceObject); + + if( !NT_SUCCESS( ntStatus)) + { + + DbgPrint("AFS DriverEntry - Failed to allocate device control object Status %08lX\n", ntStatus); + + try_return( ntStatus); + } + + // + // Setup the device extension + // + + pDeviceExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension; + + InitializeListHead( &pDeviceExt->Specific.Control.DirNotifyList); + FsRtlNotifyInitializeSync( &pDeviceExt->Specific.Control.NotifySync); + + // + // Now initialize the control device + // + + ntStatus = AFSInitializeControlDevice(); + + if( !NT_SUCCESS( ntStatus)) + { + + try_return( ntStatus); + } + + // + // Allocate our symbolic link for service communication + // + + RtlInitUnicodeString( &uniSymLinkName, + AFS_SYMLINK_NAME); + + ntStatus = IoCreateSymbolicLink( &uniSymLinkName, + &uniDeviceName); + + if( !NT_SUCCESS( ntStatus)) + { + + DbgPrint("AFS DriverEntry - Failed to create symbolic link Status %08lX\n", ntStatus); + + // + // OK, no one can communicate with us so fail + // + + try_return( ntStatus); + } + + // + // Fill in the dispatch table + // + + for( ulIndex = 0; ulIndex <= IRP_MJ_MAXIMUM_FUNCTION; ulIndex++) + { + + DriverObject->MajorFunction[ ulIndex] = AFSDefaultDispatch; + } + + DriverObject->MajorFunction[IRP_MJ_CREATE] = AFSCreate; + DriverObject->MajorFunction[IRP_MJ_CLOSE] = AFSClose; + DriverObject->MajorFunction[IRP_MJ_READ] = AFSRead; + DriverObject->MajorFunction[IRP_MJ_WRITE] = AFSWrite; + DriverObject->MajorFunction[IRP_MJ_QUERY_INFORMATION] = AFSQueryFileInfo; + DriverObject->MajorFunction[IRP_MJ_SET_INFORMATION] = AFSSetFileInfo; + DriverObject->MajorFunction[IRP_MJ_QUERY_EA] = AFSQueryEA; + DriverObject->MajorFunction[IRP_MJ_SET_EA] = AFSSetEA; + DriverObject->MajorFunction[IRP_MJ_FLUSH_BUFFERS] = AFSFlushBuffers; + DriverObject->MajorFunction[IRP_MJ_QUERY_VOLUME_INFORMATION] = AFSQueryVolumeInfo; + DriverObject->MajorFunction[IRP_MJ_SET_VOLUME_INFORMATION] = AFSSetVolumeInfo; + DriverObject->MajorFunction[IRP_MJ_DIRECTORY_CONTROL] = AFSDirControl; + DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] = AFSFSControl; + DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = AFSDevControl; + DriverObject->MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] = AFSInternalDevControl; + DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = AFSShutdown; + DriverObject->MajorFunction[IRP_MJ_LOCK_CONTROL] = AFSLockControl; + DriverObject->MajorFunction[IRP_MJ_CLEANUP] = AFSCleanup; + DriverObject->MajorFunction[IRP_MJ_QUERY_SECURITY] = AFSQuerySecurity; + DriverObject->MajorFunction[IRP_MJ_SET_SECURITY] = AFSSetSecurity; + DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = AFSSystemControl; + //DriverObject->MajorFunction[IRP_MJ_QUERY_QUOTA] = AFSQueryQuota; + //DriverObject->MajorFunction[IRP_MJ_SET_QUOTA] = AFSSetQuota; + + // + // Since we are not a true FSD then we are not controlling a device and hence these will not be needed + // + +#ifdef FSD_NOT_USED + + DriverObject->MajorFunction[IRP_MJ_POWER] = AFSPower; + DriverObject->MajorFunction[IRP_MJ_PNP] = AFSPnP; + +#endif + + // + // Fast IO Dispatch table + // + + DriverObject->FastIoDispatch = &AFSFastIoDispatch; + + RtlZeroMemory( &AFSFastIoDispatch, + sizeof( AFSFastIoDispatch)); + + // + // Again, since we are not a registered FSD many of these are not going to be called. They are here + // for completeness. + // + + AFSFastIoDispatch.SizeOfFastIoDispatch = sizeof(FAST_IO_DISPATCH); + AFSFastIoDispatch.FastIoCheckIfPossible = AFSFastIoCheckIfPossible; // CheckForFastIo + AFSFastIoDispatch.FastIoRead = AFSFastIoRead; // Read + AFSFastIoDispatch.FastIoWrite = AFSFastIoWrite; // Write + AFSFastIoDispatch.FastIoQueryBasicInfo = AFSFastIoQueryBasicInfo; // QueryBasicInfo + AFSFastIoDispatch.FastIoQueryStandardInfo = AFSFastIoQueryStandardInfo; // QueryStandardInfo + AFSFastIoDispatch.FastIoLock = AFSFastIoLock; // Lock + AFSFastIoDispatch.FastIoUnlockSingle = AFSFastIoUnlockSingle; // UnlockSingle + AFSFastIoDispatch.FastIoUnlockAll = AFSFastIoUnlockAll; // UnlockAll + AFSFastIoDispatch.FastIoUnlockAllByKey = AFSFastIoUnlockAllByKey; // UnlockAllByKey + AFSFastIoDispatch.FastIoQueryNetworkOpenInfo = AFSFastIoQueryNetworkOpenInfo; + AFSFastIoDispatch.AcquireForCcFlush = AFSFastIoAcquireForCCFlush; + AFSFastIoDispatch.ReleaseForCcFlush = AFSFastIoReleaseForCCFlush; + AFSFastIoDispatch.FastIoDeviceControl = AFSFastIoDevCtrl; + AFSFastIoDispatch.AcquireFileForNtCreateSection = AFSFastIoAcquireFile; + AFSFastIoDispatch.ReleaseFileForNtCreateSection = AFSFastIoReleaseFile; + AFSFastIoDispatch.FastIoDetachDevice = AFSFastIoDetachDevice; + //AFSFastIoDispatch.AcquireForModWrite = AFSFastIoAcquireForModWrite; + //AFSFastIoDispatch.ReleaseForModWrite = AFSFastIoReleaseForModWrite; + AFSFastIoDispatch.MdlRead = AFSFastIoMdlRead; + AFSFastIoDispatch.MdlReadComplete = AFSFastIoMdlReadComplete; + AFSFastIoDispatch.PrepareMdlWrite = AFSFastIoPrepareMdlWrite; + AFSFastIoDispatch.MdlWriteComplete = AFSFastIoMdlWriteComplete; + AFSFastIoDispatch.FastIoReadCompressed = AFSFastIoReadCompressed; + AFSFastIoDispatch.FastIoWriteCompressed = AFSFastIoWriteCompressed; + AFSFastIoDispatch.MdlReadCompleteCompressed = AFSFastIoMdlReadCompleteCompressed; + AFSFastIoDispatch.MdlWriteCompleteCompressed = AFSFastIoMdlWriteCompleteCompressed; + AFSFastIoDispatch.FastIoQueryOpen = AFSFastIoQueryOpen; + + // + // Cache manager callback routines. + // + + AFSCacheManagerCallbacks.AcquireForLazyWrite = &AFSAcquireFcbForLazyWrite; + AFSCacheManagerCallbacks.ReleaseFromLazyWrite = &AFSReleaseFcbFromLazyWrite; + AFSCacheManagerCallbacks.AcquireForReadAhead = &AFSAcquireFcbForReadAhead; + AFSCacheManagerCallbacks.ReleaseFromReadAhead = &AFSReleaseFcbFromReadAhead; + + // + // System process. + // + + AFSSysProcess = PsGetCurrentProcessId(); + + // + // Register for shutdown notification + // + + IoRegisterShutdownNotification( AFSDeviceObject); + + // + // Initialize the system process cb + // + + AFSInitializeProcessCB( 0, + (ULONGLONG)AFSSysProcess); + + // + // Initialize the redirector device + // + + ntStatus = AFSInitRDRDevice(); + + if( !NT_SUCCESS( ntStatus)) + { + + DbgPrint("AFS DriverEntry Failed to initialize redirector device Status %08lX\n"); + + try_return( ntStatus); + } + + // + // Initialize some server name based strings + // + + AFSInitServerStrings(); + + // + // Register the call back for process creation and tear down + // + + PsSetCreateProcessNotifyRoutine( AFSProcessNotify, + FALSE); + +try_exit: + + if( !NT_SUCCESS( ntStatus)) + { + + DbgPrint("AFSRedirFs DriverEntry failed to initialize %08lX\n", ntStatus); + + if( AFSRegistryPath.Buffer != NULL) + { + + ExFreePool( AFSRegistryPath.Buffer); + } + + if( uniSymLinkName.Buffer != NULL) + { + + IoDeleteSymbolicLink( &uniSymLinkName); + } + + if( AFSDeviceObject != NULL) + { + + AFSRemoveControlDevice(); + + FsRtlNotifyUninitializeSync( &pDeviceExt->Specific.Control.NotifySync); + + IoUnregisterShutdownNotification( AFSDeviceObject); + + IoDeleteDevice( AFSDeviceObject); + } + + AFSTearDownDbgLog(); + + ExDeleteResourceLite( &AFSDbgLogLock); + } + } + __except( AFSExceptionFilter( GetExceptionCode(), GetExceptionInformation()) ) + { + + AFSDbgLogMsg( 0, + 0, + "EXCEPTION - AFSRedirFs DriverEntry\n"); + } + + return ntStatus; +} diff --git a/src/WINNT/afsrdr/kernel/fs/AFSInternalDevControl.cpp b/src/WINNT/afsrdr/kernel/fs/AFSInternalDevControl.cpp new file mode 100644 index 0000000000..1853912e5b --- /dev/null +++ b/src/WINNT/afsrdr/kernel/fs/AFSInternalDevControl.cpp @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC. + * Copyright (c) 2009, 2010, 2011 Your File System, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, + * this list of conditions and the following disclaimer in the + * documentation + * and/or other materials provided with the distribution. + * - Neither the names of Kernel Drivers, LLC and Your File System, Inc. + * nor the names of their contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission from Kernel Drivers, LLC and Your File System, Inc. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +// +// File: AFSInternalDevControl.cpp +// + +#include "AFSCommon.h" + +NTSTATUS +AFSInternalDevControl( IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + + NTSTATUS ntStatus = STATUS_NOT_IMPLEMENTED; + IO_STACK_LOCATION *pIrpSp; + + pIrpSp = IoGetCurrentIrpStackLocation( Irp); + + __try + { + + AFSCompleteRequest( Irp, + ntStatus); + + } + __except( AFSExceptionFilter( GetExceptionCode(), GetExceptionInformation()) ) + { + + AFSDbgLogMsg( 0, + 0, + "EXCEPTION - AFSInternalDevControl\n"); + } + + return ntStatus; +} diff --git a/src/WINNT/afsrdr/kernel/fs/AFSLibrarySupport.cpp b/src/WINNT/afsrdr/kernel/fs/AFSLibrarySupport.cpp new file mode 100644 index 0000000000..23320baa20 --- /dev/null +++ b/src/WINNT/afsrdr/kernel/fs/AFSLibrarySupport.cpp @@ -0,0 +1,923 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC. + * Copyright (c) 2009, 2010, 2011 Your File System, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, + * this list of conditions and the following disclaimer in the + * documentation + * and/or other materials provided with the distribution. + * - Neither the names of Kernel Drivers, LLC and Your File System, Inc. + * nor the names of their contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission from Kernel Drivers, LLC and Your File System, Inc. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +// +// File: AFSLibrarySupport.cpp +// + +#include "AFSCommon.h" + +NTSTATUS +AFSLoadLibrary( IN ULONG Flags, + IN UNICODE_STRING *ServicePath) +{ + + NTSTATUS ntStatus = STATUS_SUCCESS; + AFSDeviceExt *pDevExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension; + UNICODE_STRING uniLibraryName; + AFSDeviceExt *pLibDevExt = NULL; + PFILE_OBJECT pLibraryFileObject = NULL; + PDEVICE_OBJECT pLibraryDeviceObject = NULL; + + __Enter + { + + // + // Wait on the load library event so we don't race with any + // other requests coming through + // + + AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY, + AFS_TRACE_LEVEL_VERBOSE, + "%s Start load library\n", + __FUNCTION__); + + ntStatus = KeWaitForSingleObject( &pDevExt->Specific.Control.LoadLibraryEvent, + Executive, + KernelMode, + FALSE, + NULL); + + if( !NT_SUCCESS( ntStatus)) + { + + AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING, + AFS_TRACE_LEVEL_ERROR, + "AFSLoadLibrary Wait for LoadLibraryEvent failure %08lX\n", + ntStatus); + + try_return( ntStatus); + } + + // + // Check our current state to ensure we currently do not have a library loaded + // + + if( BooleanFlagOn( pDevExt->Specific.Control.LibraryState, AFS_LIBRARY_LOADED)) + { + + AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "%s Library already loaded\n", + __FUNCTION__); + + try_return( ntStatus = STATUS_DEVICE_NOT_READY); + } + + pDevExt->Specific.Control.LibraryServicePath.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool, + ServicePath->Length, + AFS_GENERIC_MEMORY_25_TAG); + + if( pDevExt->Specific.Control.LibraryServicePath.Buffer == NULL) + { + + AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING, + AFS_TRACE_LEVEL_ERROR, + "AFSLoadLibrary AFS_GENERIC_MEMORY_25_TAG allocation error\n"); + + try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES); + } + + RtlZeroMemory( pDevExt->Specific.Control.LibraryServicePath.Buffer, + ServicePath->Length); + + pDevExt->Specific.Control.LibraryServicePath.Length = ServicePath->Length; + pDevExt->Specific.Control.LibraryServicePath.MaximumLength = pDevExt->Specific.Control.LibraryServicePath.Length; + + RtlCopyMemory( pDevExt->Specific.Control.LibraryServicePath.Buffer, + ServicePath->Buffer, + pDevExt->Specific.Control.LibraryServicePath.Length); + + // + // Load the library + // + + ntStatus = ZwLoadDriver( ServicePath); + + if( !NT_SUCCESS( ntStatus)) + { + + AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING, + AFS_TRACE_LEVEL_ERROR, + "%s Failed to load library Status %08lX\n", + __FUNCTION__, + ntStatus); + + try_return( ntStatus); + } + + // + // Open up the control device and grab teh entry points for the library + // + + RtlInitUnicodeString( &uniLibraryName, + AFS_LIBRARY_CONTROL_DEVICE_NAME); + + ntStatus = IoGetDeviceObjectPointer( &uniLibraryName, + FILE_ALL_ACCESS, + &pLibraryFileObject, + &pLibraryDeviceObject); + + if( !NT_SUCCESS( ntStatus)) + { + AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING, + AFS_TRACE_LEVEL_ERROR, + "AFSLoadLibrary IoGetDeviceObjectPointer failure %08lX\n", + ntStatus); + + try_return( ntStatus); + } + + // + // We have our reference to the library device object. Grab the + // device extension and setup our callbacks + // + + pLibDevExt = (AFSDeviceExt *)pLibraryDeviceObject->DeviceExtension; + + // + // Save off our references + // + + pDevExt->Specific.Control.LibraryFileObject = pLibraryFileObject; + + pDevExt->Specific.Control.LibraryDeviceObject = pLibraryDeviceObject; + + // + // Reset the state for our library + // + + AFSAcquireExcl( &pDevExt->Specific.Control.LibraryStateLock, + TRUE); + + SetFlag( pDevExt->Specific.Control.LibraryState, AFS_LIBRARY_LOADED); + + ClearFlag( pDevExt->Specific.Control.LibraryState, AFS_LIBRARY_QUEUE_CANCELLED); + + AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "%s Completed load library, processing queued requests\n", + __FUNCTION__); + + AFSReleaseResource( &pDevExt->Specific.Control.LibraryStateLock); + + // + // Process the queued requests + // + + AFSProcessQueuedResults( FALSE); + +try_exit: + + AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY | AFS_SUBSYSTEM_INIT_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "%s Library load complete Status %08lX\n", + __FUNCTION__, + ntStatus); + + if( !NT_SUCCESS( ntStatus)) + { + + if( pDevExt->Specific.Control.LibraryServicePath.Buffer != NULL) + { + + ZwUnloadDriver( &pDevExt->Specific.Control.LibraryServicePath); + + ExFreePool( pDevExt->Specific.Control.LibraryServicePath.Buffer); + + pDevExt->Specific.Control.LibraryServicePath.Buffer = NULL; + pDevExt->Specific.Control.LibraryServicePath.Length = 0; + pDevExt->Specific.Control.LibraryServicePath.MaximumLength = 0; + } + } + + KeSetEvent( &pDevExt->Specific.Control.LoadLibraryEvent, + 0, + FALSE); + } + + return ntStatus; +} + +NTSTATUS +AFSUnloadLibrary( IN BOOLEAN CancelQueue) +{ + + NTSTATUS ntStatus = STATUS_SUCCESS; + AFSDeviceExt *pDevExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension; + LARGE_INTEGER liTimeout; + + __Enter + { + + // + // Wait on the load library event so we don't race with any + // other requests coming through + // + + AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY, + AFS_TRACE_LEVEL_VERBOSE, + "%s Start unload library\n", + __FUNCTION__); + + ntStatus = KeWaitForSingleObject( &pDevExt->Specific.Control.LoadLibraryEvent, + Executive, + KernelMode, + FALSE, + NULL); + + if( !NT_SUCCESS( ntStatus)) + { + try_return( ntStatus); + } + + if( !BooleanFlagOn( pDevExt->Specific.Control.LibraryState, AFS_LIBRARY_LOADED)) + { + try_return( ntStatus = STATUS_DEVICE_NOT_READY); + } + + // + // Clear all outstanding requests + // + + AFSAcquireExcl( &pDevExt->Specific.Control.LibraryStateLock, + TRUE); + + ClearFlag( pDevExt->Specific.Control.LibraryState, AFS_LIBRARY_LOADED); + + if( CancelQueue) + { + SetFlag( pDevExt->Specific.Control.LibraryState, AFS_LIBRARY_QUEUE_CANCELLED); + } + + // + // We'll wait on the inflight event to be set, checking for the inflight + // request count to reach zero + // + + while( pDevExt->Specific.Control.InflightLibraryRequests > 0) + { + + liTimeout.QuadPart = -(AFS_ONE_SECOND); + + // + // If the count is non-zero make sure the event is cleared + // + + KeClearEvent( &pDevExt->Specific.Control.InflightLibraryEvent); + + AFSReleaseResource( &pDevExt->Specific.Control.LibraryStateLock); + + ntStatus = KeWaitForSingleObject( &pDevExt->Specific.Control.InflightLibraryEvent, + Executive, + KernelMode, + FALSE, + &liTimeout); + + AFSAcquireExcl( &pDevExt->Specific.Control.LibraryStateLock, + TRUE); + + if( ntStatus != STATUS_TIMEOUT && + ntStatus != STATUS_SUCCESS) + { + + AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY, + AFS_TRACE_LEVEL_VERBOSE, + "%s Failed request event Status %08lX\n", + __FUNCTION__, + ntStatus); + + SetFlag( pDevExt->Specific.Control.LibraryState, AFS_LIBRARY_LOADED); + + AFSReleaseResource( &pDevExt->Specific.Control.LibraryStateLock); + + AFSProcessQueuedResults( TRUE); + + try_return( ntStatus); + } + + AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY, + AFS_TRACE_LEVEL_VERBOSE, + "%s Wait for inflight requests to complete %08lX\n", + __FUNCTION__, + pDevExt->Specific.Control.InflightLibraryRequests); + } + + AFSReleaseResource( &pDevExt->Specific.Control.LibraryStateLock); + + AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY, + AFS_TRACE_LEVEL_VERBOSE, + "%s Processing queued results\n", + __FUNCTION__); + + AFSProcessQueuedResults( TRUE); + + // + // Unload the current library implementation + // + + if( pDevExt->Specific.Control.LibraryFileObject != NULL) + { + ObDereferenceObject( pDevExt->Specific.Control.LibraryFileObject); + } + + pDevExt->Specific.Control.LibraryFileObject = NULL; + + pDevExt->Specific.Control.LibraryDeviceObject = NULL; + + ZwUnloadDriver( &pDevExt->Specific.Control.LibraryServicePath); + + ExFreePool( pDevExt->Specific.Control.LibraryServicePath.Buffer); + + pDevExt->Specific.Control.LibraryServicePath.Length = 0; + + pDevExt->Specific.Control.LibraryServicePath.MaximumLength = 0; + + pDevExt->Specific.Control.LibraryServicePath.Buffer = NULL; + +try_exit: + + AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY, + AFS_TRACE_LEVEL_VERBOSE, + "%s Library unload complete Status %08lX\n", + __FUNCTION__, + ntStatus); + + KeSetEvent( &pDevExt->Specific.Control.LoadLibraryEvent, + 0, + FALSE); + } + + return ntStatus; +} + +NTSTATUS +AFSCheckLibraryState( IN PIRP Irp) +{ + + NTSTATUS ntStatus = STATUS_SUCCESS; + AFSDeviceExt *pDevExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension; + AFSDeviceExt *pRDRDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension; + PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp); + + __Enter + { + + AFSAcquireShared( &pDevExt->Specific.Control.LibraryStateLock, + TRUE); + + AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY, + AFS_TRACE_LEVEL_VERBOSE, + "%s Entry State %08lX Irp %p Function %08lX\n", + __FUNCTION__, + pRDRDevExt->DeviceFlags, + Irp, + pIrpSp->MajorFunction); + + if( BooleanFlagOn( pRDRDevExt->DeviceFlags, AFS_DEVICE_FLAG_REDIRECTOR_SHUTDOWN)) + { + + try_return( ntStatus = STATUS_DEVICE_NOT_READY); + } + + if( !BooleanFlagOn( pDevExt->Specific.Control.LibraryState, AFS_LIBRARY_LOADED)) + { + + if( Irp != NULL) + { + + AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY, + AFS_TRACE_LEVEL_VERBOSE, + "%s Queuing request %p\n", + __FUNCTION__, + Irp); + + ntStatus = AFSQueueLibraryRequest( Irp); + + AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY, + AFS_TRACE_LEVEL_VERBOSE, + "%s Queued request %p Status %08lX\n", + __FUNCTION__, + Irp, + ntStatus); + } + else + { + + ntStatus = STATUS_TOO_LATE; + + AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY, + AFS_TRACE_LEVEL_VERBOSE, + "%s Failing request %p\n", + __FUNCTION__, + Irp); + } + + try_return( ntStatus); + } + + if( InterlockedIncrement( &pDevExt->Specific.Control.InflightLibraryRequests) == 1) + { + KeClearEvent( &pDevExt->Specific.Control.InflightLibraryEvent); + } + +try_exit: + + AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY, + AFS_TRACE_LEVEL_VERBOSE, + "%s Completed Irp %p Status %08lX Inflight Count %08lX\n", + __FUNCTION__, + Irp, + ntStatus, + pDevExt->Specific.Control.InflightLibraryRequests); + + AFSReleaseResource( &pDevExt->Specific.Control.LibraryStateLock); + } + + return ntStatus; +} + +NTSTATUS +AFSClearLibraryRequest() +{ + + NTSTATUS ntStatus = STATUS_SUCCESS; + AFSDeviceExt *pDevExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension; + + __Enter + { + + if( InterlockedDecrement( &pDevExt->Specific.Control.InflightLibraryRequests) == 0) + { + + KeSetEvent( &pDevExt->Specific.Control.InflightLibraryEvent, + 0, + FALSE); + } + + AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY, + AFS_TRACE_LEVEL_VERBOSE, + "%s Inflight Count %08lX\n", + __FUNCTION__, + pDevExt->Specific.Control.InflightLibraryRequests); + } + + return ntStatus; +} + +NTSTATUS +AFSQueueLibraryRequest( IN PIRP Irp) +{ + + NTSTATUS ntStatus = STATUS_SUCCESS; + AFSDeviceExt *pDevExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension; + AFSDeviceExt *pRDRDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension; + AFSLibraryQueueRequestCB *pRequest = NULL; + PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp); + + __Enter + { + + AFSAcquireExcl( &pDevExt->Specific.Control.LibraryQueueLock, + TRUE); + + AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY, + AFS_TRACE_LEVEL_VERBOSE, + "%s Entry for Irp %p Function %08lX\n", + __FUNCTION__, + Irp, + pIrpSp->MajorFunction); + + // + // Has the load processing timed out and we are no longer + // queuing requests? + // + + if( BooleanFlagOn( pDevExt->Specific.Control.LibraryState, AFS_LIBRARY_QUEUE_CANCELLED) || + BooleanFlagOn( pRDRDevExt->DeviceFlags, AFS_DEVICE_FLAG_REDIRECTOR_SHUTDOWN)) + { + + AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY, + AFS_TRACE_LEVEL_ERROR, + "%s Library not loaded for Irp %p\n", + __FUNCTION__, + Irp); + + try_return( ntStatus = STATUS_DEVICE_NOT_READY); + } + + pRequest = (AFSLibraryQueueRequestCB *)AFSExAllocatePoolWithTag( PagedPool, + sizeof( AFSLibraryQueueRequestCB), + AFS_LIBRARY_QUEUE_TAG); + + if( pRequest == NULL) + { + try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES); + } + + RtlZeroMemory( pRequest, + sizeof( AFSLibraryQueueRequestCB)); + + pRequest->Irp = Irp; + + if( pDevExt->Specific.Control.LibraryQueueHead == NULL) + { + pDevExt->Specific.Control.LibraryQueueHead = pRequest; + } + else + { + pDevExt->Specific.Control.LibraryQueueTail->fLink = pRequest; + } + + pDevExt->Specific.Control.LibraryQueueTail = pRequest; + + IoMarkIrpPending( Irp); + + ntStatus = STATUS_PENDING; + +try_exit: + + AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY, + AFS_TRACE_LEVEL_VERBOSE, + "%s Completed for Irp %p Status %08lX\n", + __FUNCTION__, + Irp, + ntStatus); + + AFSReleaseResource( &pDevExt->Specific.Control.LibraryQueueLock); + } + + return ntStatus; +} + +NTSTATUS +AFSProcessQueuedResults( IN BOOLEAN CancelRequest) +{ + + NTSTATUS ntStatus = STATUS_SUCCESS; + AFSLibraryQueueRequestCB *pRequest = NULL; + AFSDeviceExt *pDevExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension; + + __Enter + { + + AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY, + AFS_TRACE_LEVEL_VERBOSE, + "%s Entry\n", + __FUNCTION__); + + // + // Loop through the queue either resubmitting requests or cancelling them + // + + while( TRUE) + { + + AFSAcquireExcl( &pDevExt->Specific.Control.LibraryQueueLock, + TRUE); + + if( pDevExt->Specific.Control.LibraryQueueHead == NULL) + { + + AFSReleaseResource( &pDevExt->Specific.Control.LibraryQueueLock); + + break; + } + + pRequest = pDevExt->Specific.Control.LibraryQueueHead; + + pDevExt->Specific.Control.LibraryQueueHead = pRequest->fLink; + + if( pDevExt->Specific.Control.LibraryQueueHead == NULL) + { + + pDevExt->Specific.Control.LibraryQueueTail = NULL; + } + + AFSReleaseResource( &pDevExt->Specific.Control.LibraryQueueLock); + + if( CancelRequest) + { + + pRequest->Irp->IoStatus.Status = STATUS_CANCELLED; + + AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY, + AFS_TRACE_LEVEL_VERBOSE, + "%s Cancelling request Irp %p\n", + __FUNCTION__, + pRequest->Irp); + + IoCompleteRequest( pRequest->Irp, + IO_NO_INCREMENT); + } + else + { + + AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY, + AFS_TRACE_LEVEL_VERBOSE, + "%s Resubmitting request Irp %p\n", + __FUNCTION__, + pRequest->Irp); + + AFSSubmitLibraryRequest( pRequest->Irp); + } + + ExFreePool( pRequest); + } + + AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY, + AFS_TRACE_LEVEL_VERBOSE, + "%s Completed\n", + __FUNCTION__); + } + + return ntStatus; +} + +NTSTATUS +AFSSubmitLibraryRequest( IN PIRP Irp) +{ + + NTSTATUS ntStatus = STATUS_SUCCESS; + IO_STACK_LOCATION *pIrpSp = IoGetCurrentIrpStackLocation( Irp); + + __Enter + { + + AFSDbgLogMsg( AFS_SUBSYSTEM_LOAD_LIBRARY, + AFS_TRACE_LEVEL_VERBOSE, + "%s Submitting Irp %p Function %08lX\n", + __FUNCTION__, + Irp, + pIrpSp->MajorFunction); + + switch( pIrpSp->MajorFunction) + { + + case IRP_MJ_CREATE: + { + AFSCreate( AFSRDRDeviceObject, + Irp); + break; + } + + case IRP_MJ_CLOSE: + { + AFSClose( AFSRDRDeviceObject, + Irp); + break; + } + + case IRP_MJ_READ: + { + AFSRead( AFSRDRDeviceObject, + Irp); + break; + } + + case IRP_MJ_WRITE: + { + AFSWrite( AFSRDRDeviceObject, + Irp); + break; + } + + case IRP_MJ_QUERY_INFORMATION: + { + AFSQueryFileInfo( AFSRDRDeviceObject, + Irp); + break; + } + + case IRP_MJ_SET_INFORMATION: + { + AFSSetFileInfo( AFSRDRDeviceObject, + Irp); + break; + } + + case IRP_MJ_QUERY_EA: + { + AFSQueryEA( AFSRDRDeviceObject, + Irp); + break; + } + + case IRP_MJ_SET_EA: + { + AFSSetEA( AFSRDRDeviceObject, + Irp); + break; + } + + case IRP_MJ_FLUSH_BUFFERS: + { + AFSFlushBuffers( AFSRDRDeviceObject, + Irp); + break; + } + + case IRP_MJ_QUERY_VOLUME_INFORMATION: + { + AFSQueryVolumeInfo( AFSRDRDeviceObject, + Irp); + break; + } + + case IRP_MJ_SET_VOLUME_INFORMATION: + { + AFSSetVolumeInfo( AFSRDRDeviceObject, + Irp); + break; + } + + case IRP_MJ_DIRECTORY_CONTROL: + { + AFSDirControl( AFSRDRDeviceObject, + Irp); + break; + } + + case IRP_MJ_FILE_SYSTEM_CONTROL: + { + AFSFSControl( AFSRDRDeviceObject, + Irp); + break; + } + + case IRP_MJ_DEVICE_CONTROL: + { + AFSDevControl( AFSRDRDeviceObject, + Irp); + break; + } + + case IRP_MJ_INTERNAL_DEVICE_CONTROL: + { + AFSInternalDevControl( AFSRDRDeviceObject, + Irp); + break; + } + + case IRP_MJ_SHUTDOWN: + { + AFSShutdown( AFSRDRDeviceObject, + Irp); + break; + } + + case IRP_MJ_LOCK_CONTROL: + { + AFSLockControl( AFSRDRDeviceObject, + Irp); + break; + } + + case IRP_MJ_CLEANUP: + { + AFSCleanup( AFSRDRDeviceObject, + Irp); + break; + } + + case IRP_MJ_QUERY_SECURITY: + { + AFSQuerySecurity( AFSRDRDeviceObject, + Irp); + break; + } + + case IRP_MJ_SET_SECURITY: + { + AFSSetSecurity( AFSRDRDeviceObject, + Irp); + break; + } + + case IRP_MJ_SYSTEM_CONTROL: + { + AFSSystemControl( AFSRDRDeviceObject, + Irp); + break; + } + + default: + { + AFSDefaultDispatch( AFSRDRDeviceObject, + Irp); + break; + } + } + } + + return ntStatus; +} + +NTSTATUS +AFSInitializeLibrary( IN AFSFileID *GlobalRootFid, + IN BOOLEAN QueueRootEnumeration) +{ + + NTSTATUS ntStatus = STATUS_SUCCESS; + AFSLibraryInitCB stInitLib; + AFSDeviceExt *pDevExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension; + AFSDeviceExt *pRDRDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension; + + __Enter + { + + RtlZeroMemory( &stInitLib, + sizeof( AFSLibraryInitCB)); + + // + // Initialize the parameters to pass to the library + // + + stInitLib.AFSControlDeviceObject = AFSDeviceObject; + + stInitLib.AFSRDRDeviceObject = AFSRDRDeviceObject; + + stInitLib.AFSServerName = AFSServerName; + + stInitLib.AFSDebugFlags = AFSDebugFlags; + + if( GlobalRootFid != NULL) + { + stInitLib.GlobalRootFid = *GlobalRootFid; + } + + stInitLib.AFSCacheManagerCallbacks = &AFSCacheManagerCallbacks; + + stInitLib.AFSCacheBaseAddress = pRDRDevExt->Specific.RDR.CacheBaseAddress; + + stInitLib.AFSCacheLength = pRDRDevExt->Specific.RDR.CacheLength; + + // + // Initialize the callback functions for the library + // + + stInitLib.AFSProcessRequest = AFSProcessRequest; + + stInitLib.AFSDbgLogMsg = AFSDbgLogMsg; + + stInitLib.AFSAddConnectionEx = AFSAddConnectionEx; + + stInitLib.AFSExAllocatePoolWithTag = AFSExAllocatePoolWithTag; + + stInitLib.AFSExFreePool = AFSExFreePool; + + stInitLib.AFSDumpTraceFiles = AFSDumpTraceFiles; + + stInitLib.AFSRetrieveAuthGroup = AFSRetrieveAuthGroup; + + ntStatus = AFSSendDeviceIoControl( pDevExt->Specific.Control.LibraryDeviceObject, + IOCTL_AFS_INITIALIZE_LIBRARY_DEVICE, + &stInitLib, + sizeof( AFSLibraryInitCB), + NULL, + 0, + NULL); + + if ( !NT_SUCCESS( ntStatus)) + { + + AFSDbgLogMsg( AFS_SUBSYSTEM_INIT_PROCESSING, + AFS_TRACE_LEVEL_ERROR, + "AFSInitializeLibrary AFSSendDeviceIoControl failure %08lX\n", + ntStatus); + } + } + + return ntStatus; +} diff --git a/src/WINNT/afsrdr/kernel/fs/AFSLockControl.cpp b/src/WINNT/afsrdr/kernel/fs/AFSLockControl.cpp new file mode 100644 index 0000000000..c4a6184289 --- /dev/null +++ b/src/WINNT/afsrdr/kernel/fs/AFSLockControl.cpp @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC. + * Copyright (c) 2009, 2010, 2011 Your File System, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, + * this list of conditions and the following disclaimer in the + * documentation + * and/or other materials provided with the distribution. + * - Neither the names of Kernel Drivers, LLC and Your File System, Inc. + * nor the names of their contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission from Kernel Drivers, LLC and Your File System, Inc. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +// +// File: AFSLockControl.cpp +// + +#include "AFSCommon.h" + +NTSTATUS +AFSLockControl( IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + + NTSTATUS ntStatus = STATUS_SUCCESS; + AFSDeviceExt *pControlDeviceExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension; + + __try + { + + if( DeviceObject == AFSDeviceObject) + { + + ntStatus = STATUS_INVALID_DEVICE_REQUEST; + + AFSCompleteRequest( Irp, + ntStatus); + + try_return( ntStatus); + } + + // + // Check the state of the library + // + + ntStatus = AFSCheckLibraryState( Irp); + + if( !NT_SUCCESS( ntStatus) || + ntStatus == STATUS_PENDING) + { + + if( ntStatus != STATUS_PENDING) + { + AFSCompleteRequest( Irp, ntStatus); + } + + try_return( ntStatus); + } + + IoSkipCurrentIrpStackLocation( Irp); + + ntStatus = IoCallDriver( pControlDeviceExt->Specific.Control.LibraryDeviceObject, + Irp); + + // + // Indicate the library is done with the request + // + + AFSClearLibraryRequest(); + +try_exit: + + NOTHING; + } + __except( AFSExceptionFilter( (ntStatus = GetExceptionCode()), GetExceptionInformation())) + { + + AFSDbgLogMsg( 0, + 0, + "EXCEPTION - AFSLockControl\n"); + + AFSCompleteRequest( Irp, + ntStatus); + } + + return ntStatus; +} diff --git a/src/WINNT/afsrdr/kernel/fs/AFSLogSupport.cpp b/src/WINNT/afsrdr/kernel/fs/AFSLogSupport.cpp new file mode 100644 index 0000000000..549b57f65d --- /dev/null +++ b/src/WINNT/afsrdr/kernel/fs/AFSLogSupport.cpp @@ -0,0 +1,756 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC. + * Copyright (c) 2009, 2010, 2011 Your File System, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, + * this list of conditions and the following disclaimer in the + * documentation + * and/or other materials provided with the distribution. + * - Neither the names of Kernel Drivers, LLC and Your File System, Inc. + * nor the names of their contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission from Kernel Drivers, LLC and Your File System, Inc. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "AFSCommon.h" + +NTSTATUS +AFSDbgLogMsg( IN ULONG Subsystem, + IN ULONG Level, + IN PCCH Format, + ...) +{ + + NTSTATUS ntStatus = STATUS_SUCCESS; + va_list va_args; + ULONG ulBytesWritten = 0; + BOOLEAN bReleaseLock = FALSE; + char *pCurrentTrace = NULL; + + __Enter + { + + if( AFSDbgBuffer == NULL) + { + + try_return( ntStatus = STATUS_DEVICE_NOT_READY); + } + + if( Subsystem > 0 && + (Subsystem & AFSTraceComponent) == 0) + { + + // + // Not tracing this subsystem + // + + try_return( ntStatus); + } + + if( Level > 0 && + Level > AFSTraceLevel) + { + + // + // Not tracing this level + // + + try_return( ntStatus); + } + + AFSAcquireExcl( &AFSDbgLogLock, + TRUE); + + bReleaseLock = TRUE; + + // + // Check again under lock + // + + if( AFSDbgBuffer == NULL) + { + + try_return( ntStatus = STATUS_DEVICE_NOT_READY); + } + + if( AFSDbgLogRemainingLength < 255) + { + + AFSDbgLogRemainingLength = AFSDbgBufferLength; + + AFSDbgCurrentBuffer = AFSDbgBuffer; + + SetFlag( AFSDbgLogFlags, AFS_DBG_LOG_WRAPPED); + } + + pCurrentTrace = AFSDbgCurrentBuffer; + + RtlStringCchPrintfA( AFSDbgCurrentBuffer, + 10, + "%08lX:", + AFSDbgLogCounter++); + + AFSDbgCurrentBuffer += 9; + + AFSDbgLogRemainingLength -= 9; + + va_start( va_args, Format); + + ntStatus = RtlStringCbVPrintfA( AFSDbgCurrentBuffer, + AFSDbgLogRemainingLength, + Format, + va_args); + + if( ntStatus == STATUS_BUFFER_OVERFLOW) + { + + RtlZeroMemory( AFSDbgCurrentBuffer, + AFSDbgLogRemainingLength); + + AFSDbgLogRemainingLength = AFSDbgBufferLength; + + AFSDbgCurrentBuffer = AFSDbgBuffer; + + SetFlag( AFSDbgLogFlags, AFS_DBG_LOG_WRAPPED); + + pCurrentTrace = AFSDbgCurrentBuffer; + + RtlStringCchPrintfA( AFSDbgCurrentBuffer, + 10, + "%08lX:", + AFSDbgLogCounter++); + + AFSDbgCurrentBuffer += 9; + + AFSDbgLogRemainingLength -= 9; + + ntStatus = RtlStringCbVPrintfA( AFSDbgCurrentBuffer, + AFSDbgLogRemainingLength, + Format, + va_args); + } + + if( NT_SUCCESS( ntStatus)) + { + + RtlStringCbLengthA( AFSDbgCurrentBuffer, + AFSDbgLogRemainingLength, + (size_t *)&ulBytesWritten); + + AFSDbgCurrentBuffer += ulBytesWritten; + + AFSDbgLogRemainingLength -= ulBytesWritten; + } + + va_end( va_args); + + if( BooleanFlagOn( AFSDebugFlags, AFS_DBG_TRACE_TO_DEBUGGER) && + pCurrentTrace != NULL) + { + + DbgPrint( pCurrentTrace); + } + +try_exit: + + if( bReleaseLock) + { + + AFSReleaseResource( &AFSDbgLogLock); + } + } + + return ntStatus; +} + +NTSTATUS +AFSInitializeDbgLog() +{ + + NTSTATUS ntStatus = STATUS_INSUFFICIENT_RESOURCES; + + AFSAcquireExcl( &AFSDbgLogLock, + TRUE); + + if( AFSDbgBufferLength > 0) + { + + AFSDbgBuffer = (char *)AFSExAllocatePoolWithTag( NonPagedPool, + AFSDbgBufferLength, + AFS_GENERIC_MEMORY_19_TAG); + + if( AFSDbgBuffer != NULL) + { + + AFSDbgCurrentBuffer = AFSDbgBuffer; + + AFSDbgLogRemainingLength = AFSDbgBufferLength; + + ntStatus = STATUS_SUCCESS; + } + } + + AFSReleaseResource( &AFSDbgLogLock); + + if( NT_SUCCESS( ntStatus)) + { + AFSTagInitialLogEntry(); + } + + return ntStatus; +} + +NTSTATUS +AFSTearDownDbgLog() +{ + + NTSTATUS ntStatus = STATUS_SUCCESS; + + AFSAcquireExcl( &AFSDbgLogLock, + TRUE); + + if( AFSDbgBuffer != NULL) + { + + ExFreePool( AFSDbgBuffer); + } + + AFSDbgBuffer = NULL; + + AFSDbgCurrentBuffer = NULL; + + AFSDbgLogRemainingLength = 0; + + AFSReleaseResource( &AFSDbgLogLock); + + return ntStatus; +} + +NTSTATUS +AFSConfigureTrace( IN AFSTraceConfigCB *TraceInfo) +{ + + NTSTATUS ntStatus = STATUS_SUCCESS; + UNICODE_STRING uniString; + + __Enter + { + + AFSAcquireExcl( &AFSDbgLogLock, + TRUE); + + if( TraceInfo->TraceLevel == AFSTraceLevel && + TraceInfo->TraceBufferLength == AFSDbgBufferLength && + TraceInfo->Subsystem == AFSTraceComponent) + { + + // + // Nothing to do + // + + try_return( ntStatus); + } + + // + // Go update the registry with the new entries + // + + if( TraceInfo->TraceLevel != (ULONG)-1 && + TraceInfo->TraceLevel != AFSTraceLevel) + { + + AFSTraceLevel = TraceInfo->TraceLevel; + + RtlInitUnicodeString( &uniString, + AFS_REG_TRACE_LEVEL); + + ntStatus = AFSUpdateRegistryParameter( &uniString, + REG_DWORD, + &TraceInfo->TraceLevel, + sizeof( ULONG)); + + if( !NT_SUCCESS( ntStatus)) + { + + DbgPrint("AFSConfigureTrace Failed to set debug level in registry Status %08lX\n", ntStatus); + } + } + + if( TraceInfo->Subsystem != (ULONG)-1 && + TraceInfo->Subsystem != AFSTraceComponent) + { + + AFSTraceComponent = TraceInfo->Subsystem; + + RtlInitUnicodeString( &uniString, + AFS_REG_TRACE_SUBSYSTEM); + + ntStatus = AFSUpdateRegistryParameter( &uniString, + REG_DWORD, + &TraceInfo->Subsystem, + sizeof( ULONG)); + + if( !NT_SUCCESS( ntStatus)) + { + + DbgPrint("AFSConfigureTrace Failed to set debug subsystem in registry Status %08lX\n", ntStatus); + } + } + + if( TraceInfo->DebugFlags != (ULONG)-1 && + TraceInfo->DebugFlags != AFSDebugFlags) + { + + AFSDebugFlags = TraceInfo->DebugFlags; + + RtlInitUnicodeString( &uniString, + AFS_REG_DEBUG_FLAGS); + + ntStatus = AFSUpdateRegistryParameter( &uniString, + REG_DWORD, + &TraceInfo->DebugFlags, + sizeof( ULONG)); + + if( !NT_SUCCESS( ntStatus)) + { + + DbgPrint("AFSConfigureTrace Failed to set debug flags in registry Status %08lX\n", ntStatus); + } + } + + if( TraceInfo->TraceBufferLength != (ULONG)-1 && + TraceInfo->TraceBufferLength != AFSDbgBufferLength) + { + + RtlInitUnicodeString( &uniString, + AFS_REG_TRACE_BUFFER_LENGTH); + + ntStatus = AFSUpdateRegistryParameter( &uniString, + REG_DWORD, + &TraceInfo->TraceBufferLength, + sizeof( ULONG)); + + if( !NT_SUCCESS( ntStatus)) + { + + DbgPrint("AFSConfigureTrace Failed to set debug buffer length in registry Status %08lX\n", ntStatus); + } + + AFSDbgBufferLength = TraceInfo->TraceBufferLength * 1024; + + ClearFlag( AFSDbgLogFlags, AFS_DBG_LOG_WRAPPED); + + if( AFSDbgBuffer != NULL) + { + + ExFreePool( AFSDbgBuffer); + + AFSDbgBuffer = NULL; + + AFSDbgCurrentBuffer = NULL; + + AFSDbgLogRemainingLength = 0; + } + + if( AFSDbgBufferLength > 0) + { + + AFSDbgBuffer = (char *)AFSExAllocatePoolWithTag( NonPagedPool, + AFSDbgBufferLength, + AFS_GENERIC_MEMORY_20_TAG); + + if( AFSDbgBuffer == NULL) + { + + AFSDbgBufferLength = 0; + + try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES); + } + + AFSDbgCurrentBuffer = AFSDbgBuffer; + + AFSDbgLogRemainingLength = AFSDbgBufferLength; + + AFSTagInitialLogEntry(); + } + } + +try_exit: + + AFSReleaseResource( &AFSDbgLogLock); + } + + return ntStatus; +} + +NTSTATUS +AFSGetTraceBuffer( IN ULONG TraceBufferLength, + OUT void *TraceBuffer, + OUT ULONG_PTR *CopiedLength) +{ + + NTSTATUS ntStatus = STATUS_SUCCESS; + ULONG ulCopyLength = 0; + char *pCurrentLocation = NULL; + + __Enter + { + + AFSAcquireShared( &AFSDbgLogLock, + TRUE); + + if( TraceBufferLength < AFSDbgBufferLength) + { + + try_return( ntStatus = STATUS_INVALID_PARAMETER); + } + + // + // If we have wrapped then copy in the remaining portion + // + + pCurrentLocation = (char *)TraceBuffer; + + *CopiedLength = 0; + + if( BooleanFlagOn( AFSDbgLogFlags, AFS_DBG_LOG_WRAPPED)) + { + + ulCopyLength = AFSDbgLogRemainingLength; + + RtlCopyMemory( pCurrentLocation, + AFSDbgCurrentBuffer, + ulCopyLength); + + pCurrentLocation[ 0] = '0'; // The buffer is NULL terminated ... + + pCurrentLocation += ulCopyLength; + + *CopiedLength = ulCopyLength; + } + + ulCopyLength = AFSDbgBufferLength - AFSDbgLogRemainingLength; + + if( ulCopyLength > 0) + { + + RtlCopyMemory( pCurrentLocation, + AFSDbgBuffer, + ulCopyLength); + + *CopiedLength += ulCopyLength; + } + +try_exit: + + AFSReleaseResource( &AFSDbgLogLock); + } + + return ntStatus; +} + +void +AFSTagInitialLogEntry() +{ + + LARGE_INTEGER liTime, liLocalTime; + TIME_FIELDS timeFields; + + KeQuerySystemTime( &liTime); + + ExSystemTimeToLocalTime( &liTime, + &liLocalTime); + + RtlTimeToTimeFields( &liLocalTime, + &timeFields); + + AFSDbgLogMsg( 0, + 0, + "AFS Log Initialized %d-%d-%d %d:%d Level %d Subsystems %08lX\n", + timeFields.Month, + timeFields.Day, + timeFields.Year, + timeFields.Hour, + timeFields.Minute, + AFSTraceLevel, + AFSTraceComponent); + + return; +} + +void +AFSDumpTraceFiles() +{ + + NTSTATUS ntStatus = STATUS_SUCCESS; + HANDLE hDirectory = NULL; + OBJECT_ATTRIBUTES stObjectAttribs; + IO_STATUS_BLOCK stIoStatus; + LARGE_INTEGER liTime, liLocalTime; + TIME_FIELDS timeFields; + ULONG ulBytesWritten = 0; + HANDLE hDumpFile = NULL; + ULONG ulBytesProcessed, ulCopyLength; + LARGE_INTEGER liOffset; + ULONG ulDumpLength = 0; + BOOLEAN bSetEvent = FALSE; + + __Enter + { + + AFSAcquireShared( &AFSDbgLogLock, + TRUE); + + ulDumpLength = AFSDbgBufferLength - AFSDbgLogRemainingLength; + + AFSReleaseResource( &AFSDbgLogLock); + + if( AFSDumpFileLocation.Length == 0 || + AFSDumpFileLocation.Buffer == NULL || + AFSDbgBufferLength == 0 || + ulDumpLength == 0 || + AFSDumpFileName.MaximumLength == 0 || + AFSDumpFileName.Buffer == NULL || + AFSDumpBuffer == NULL) + { + try_return( ntStatus); + } + + // + // Go open the cache file + // + + InitializeObjectAttributes( &stObjectAttribs, + &AFSDumpFileLocation, + OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, + NULL, + NULL); + + ntStatus = ZwCreateFile( &hDirectory, + GENERIC_READ | GENERIC_WRITE, + &stObjectAttribs, + &stIoStatus, + NULL, + 0, + FILE_SHARE_READ | FILE_SHARE_WRITE, + FILE_OPEN, + FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT, + NULL, + 0); + + if( !NT_SUCCESS( ntStatus)) + { + + try_return( ntStatus); + } + + ntStatus = KeWaitForSingleObject( &AFSDumpFileEvent, + Executive, + KernelMode, + FALSE, + NULL); + + if( !NT_SUCCESS( ntStatus)) + { + + try_return( ntStatus); + } + + bSetEvent = TRUE; + + AFSDumpFileName.Length = 0; + + RtlZeroMemory( AFSDumpFileName.Buffer, + AFSDumpFileName.MaximumLength); + + KeQuerySystemTime( &liTime); + + ExSystemTimeToLocalTime( &liTime, + &liLocalTime); + + RtlTimeToTimeFields( &liLocalTime, + &timeFields); + + ntStatus = RtlStringCchPrintfW( AFSDumpFileName.Buffer, + AFSDumpFileName.MaximumLength/sizeof( WCHAR), + L"AFSDumpFile %d.%d.%d %d.%d.%d.log", + timeFields.Month, + timeFields.Day, + timeFields.Year, + timeFields.Hour, + timeFields.Minute, + timeFields.Second); + + if( !NT_SUCCESS( ntStatus)) + { + try_return( ntStatus); + } + + RtlStringCbLengthW( AFSDumpFileName.Buffer, + AFSDumpFileName.MaximumLength, + (size_t *)&ulBytesWritten); + + AFSDumpFileName.Length = (USHORT)ulBytesWritten; + + InitializeObjectAttributes( &stObjectAttribs, + &AFSDumpFileName, + OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, + hDirectory, + NULL); + + ntStatus = ZwCreateFile( &hDumpFile, + GENERIC_READ | GENERIC_WRITE, + &stObjectAttribs, + &stIoStatus, + NULL, + 0, + FILE_SHARE_READ | FILE_SHARE_WRITE, + FILE_CREATE, + FILE_SYNCHRONOUS_IO_NONALERT, + NULL, + 0); + + if( !NT_SUCCESS( ntStatus)) + { + try_return( ntStatus); + } + + // + // Write out the trace buffer + // + + liOffset.QuadPart = 0; + + ulBytesProcessed = 0; + + while( ulBytesProcessed < ulDumpLength) + { + + ulCopyLength = AFSDumpBufferLength; + + if( ulCopyLength > ulDumpLength - ulBytesProcessed) + { + ulCopyLength = ulDumpLength - ulBytesProcessed; + } + + RtlCopyMemory( AFSDumpBuffer, + (void *)((char *)AFSDbgBuffer + ulBytesProcessed), + ulCopyLength); + + ntStatus = ZwWriteFile( hDumpFile, + NULL, + NULL, + NULL, + &stIoStatus, + AFSDumpBuffer, + ulCopyLength, + &liOffset, + NULL); + + if( !NT_SUCCESS( ntStatus)) + { + break; + } + + liOffset.QuadPart += ulCopyLength; + + ulBytesProcessed += ulCopyLength; + } + +try_exit: + + if( hDumpFile != NULL) + { + ZwClose( hDumpFile); + } + + if( hDirectory != NULL) + { + ZwClose( hDirectory); + } + + if( bSetEvent) + { + KeSetEvent( &AFSDumpFileEvent, + 0, + FALSE); + } + } + + return; +} + +NTSTATUS +AFSInitializeDumpFile() +{ + + NTSTATUS ntStatus = STATUS_SUCCESS; + + __Enter + { + + KeInitializeEvent( &AFSDumpFileEvent, + SynchronizationEvent, + TRUE); + + AFSDumpFileName.Length = 0; + AFSDumpFileName.Buffer = NULL; + AFSDumpFileName.MaximumLength = PAGE_SIZE; + + AFSDumpFileName.Buffer = (WCHAR *)ExAllocatePoolWithTag( PagedPool, + AFSDumpFileName.MaximumLength, + AFS_GENERIC_MEMORY_28_TAG); + + if( AFSDumpFileName.Buffer == NULL) + { + AFSDumpFileName.MaximumLength = 0; + + try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES); + } + + AFSDumpBufferLength = 64 * 1024; + + AFSDumpBuffer = ExAllocatePoolWithTag( PagedPool, + AFSDumpBufferLength, + AFS_GENERIC_MEMORY_28_TAG); + + if( AFSDumpBuffer == NULL) + { + + ExFreePool( AFSDumpFileName.Buffer); + + AFSDumpFileName.Buffer = NULL; + AFSDumpFileName.MaximumLength = 0; + + AFSDumpBufferLength = 0; + + try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES); + } + +try_exit: + + NOTHING; + } + + return ntStatus; +} diff --git a/src/WINNT/afsrdr/kernel/fs/AFSNetworkProviderSupport.cpp b/src/WINNT/afsrdr/kernel/fs/AFSNetworkProviderSupport.cpp new file mode 100644 index 0000000000..2611259b5e --- /dev/null +++ b/src/WINNT/afsrdr/kernel/fs/AFSNetworkProviderSupport.cpp @@ -0,0 +1,456 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC. + * Copyright (c) 2009, 2010, 2011 Your File System, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, + * this list of conditions and the following disclaimer in the + * documentation + * and/or other materials provided with the distribution. + * - Neither the names of Kernel Drivers, LLC and Your File System, Inc. + * nor the names of their contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission from Kernel Drivers, LLC and Your File System, Inc. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +// +// File: AFSNetworkProviderSupport.cpp +// + +#include "AFSCommon.h" + +NTSTATUS +AFSAddConnectionEx( IN UNICODE_STRING *RemoteName, + IN ULONG DisplayType, + IN ULONG Flags) +{ + + NTSTATUS ntStatus = STATUS_SUCCESS; + AFSProviderConnectionCB *pConnection = NULL, *pLastConnection = NULL, *pServerConnection = NULL; + UNICODE_STRING uniRemoteName; + AFSDeviceExt *pRDRDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension; + + __Enter + { + + AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "AFSAddConnectionEx Acquiring AFSProviderListLock lock %08lX EXCL %08lX\n", + &pRDRDevExt->Specific.RDR.ProviderListLock, + PsGetCurrentThread()); + + AFSAcquireExcl( &pRDRDevExt->Specific.RDR.ProviderListLock, + TRUE); + + + AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER, + AFS_TRACE_LEVEL_VERBOSE, + "AFSAddConnectionEx remote name %wZ display type %08lX flags %08lX\n", + RemoteName, + DisplayType, + Flags); + + // + // If this is a server, start in the enum list, otherwise + // locate the server node + // + + if( DisplayType == RESOURCEDISPLAYTYPE_SERVER) + { + + pConnection = pRDRDevExt->Specific.RDR.ProviderEnumerationList; + } + else + { + + pServerConnection = pRDRDevExt->Specific.RDR.ProviderEnumerationList; // For now we have only one server ... + + if( pServerConnection == NULL) + { + + try_return( ntStatus); + } + + pConnection = pServerConnection->EnumerationList; + } + + // + // Look for the connection + // + + uniRemoteName.Length = RemoteName->Length; + uniRemoteName.MaximumLength = RemoteName->Length; + + uniRemoteName.Buffer = RemoteName->Buffer; + + while( pConnection != NULL) + { + + if( RtlCompareUnicodeString( &uniRemoteName, + &pConnection->RemoteName, + TRUE) == 0) + { + + break; + } + + pConnection = pConnection->fLink; + } + + if( pConnection != NULL) + { + + try_return( ntStatus); + } + + // + // Strip off any trailing slashes + // + + if( uniRemoteName.Buffer[ (uniRemoteName.Length/sizeof( WCHAR)) - 1] == L'\\') + { + + uniRemoteName.Buffer[ (uniRemoteName.Length/sizeof( WCHAR)) - 1] = L'\0'; + + uniRemoteName.Length -= sizeof( WCHAR); + } + + AFSDbgLogMsg( AFS_SUBSYSTEM_NETWORK_PROVIDER, + AFS_TRACE_LEVEL_VERBOSE, + "AFSAddConnectionEx Inserting remote name %wZ\n", &uniRemoteName); + + // + // Allocate a new node and add it to our list + // + + pConnection = (AFSProviderConnectionCB *)AFSExAllocatePoolWithTag( PagedPool, + sizeof( AFSProviderConnectionCB) + + uniRemoteName.Length, + AFS_PROVIDER_CB); + + if( pConnection == NULL) + { + + try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES); + } + + RtlZeroMemory( pConnection, + sizeof( AFSProviderConnectionCB) + uniRemoteName.Length); + + pConnection->LocalName = L'\0'; + + pConnection->RemoteName.Length = uniRemoteName.Length; + pConnection->RemoteName.MaximumLength = pConnection->RemoteName.Length; + + pConnection->RemoteName.Buffer = (WCHAR *)((char *)pConnection + sizeof( AFSProviderConnectionCB)); + + RtlCopyMemory( pConnection->RemoteName.Buffer, + uniRemoteName.Buffer, + pConnection->RemoteName.Length); + + // + // Point to the component portion of the name + // + + pConnection->ComponentName.Length = 0; + pConnection->ComponentName.MaximumLength = 0; + + pConnection->ComponentName.Buffer = &pConnection->RemoteName.Buffer[ (pConnection->RemoteName.Length/sizeof( WCHAR)) - 1]; + + while( pConnection->ComponentName.Length <= pConnection->RemoteName.Length) + { + + if( pConnection->ComponentName.Buffer[ 0] == L'\\') + { + + pConnection->ComponentName.Buffer++; + + break; + } + + pConnection->ComponentName.Length += sizeof( WCHAR); + pConnection->ComponentName.MaximumLength += sizeof( WCHAR); + + pConnection->ComponentName.Buffer--; + } + + // + // Go initialize the information about the connection + // + + AFSInitializeConnectionInfo( pConnection, + DisplayType); + + // + // Store away the flags for the connection + // + + pConnection->Flags = Flags; + + // + // Insert the entry into our list. If this is a server + // connection then add it to the enumeration list, otherwise + // find the server name for this connection + // + + if( DisplayType == RESOURCEDISPLAYTYPE_SERVER) + { + + if( pRDRDevExt->Specific.RDR.ProviderEnumerationList == NULL) + { + + pRDRDevExt->Specific.RDR.ProviderEnumerationList = pConnection; + } + else + { + + // + // Get the end of the list + // + + pLastConnection = pRDRDevExt->Specific.RDR.ProviderEnumerationList; + + while( pLastConnection->fLink != NULL) + { + + pLastConnection = pLastConnection->fLink; + } + + pLastConnection->fLink = pConnection; + } + } + else if( pServerConnection != NULL) + { + + if( pServerConnection->EnumerationList == NULL) + { + + pServerConnection->EnumerationList = pConnection; + } + else + { + + // + // Get the end of the list + // + + pLastConnection = pServerConnection->EnumerationList; + + while( pLastConnection->fLink != NULL) + { + + pLastConnection = pLastConnection->fLink; + } + + pLastConnection->fLink = pConnection; + } + } + +try_exit: + + AFSReleaseResource( &pRDRDevExt->Specific.RDR.ProviderListLock); + } + + return ntStatus; +} + +void +AFSInitializeConnectionInfo( IN AFSProviderConnectionCB *Connection, + IN ULONG DisplayType) +{ + + NTSTATUS ntStatus = STATUS_SUCCESS; + UNICODE_STRING uniName, uniComponentName, uniRemainingName; + + __Enter + { + + uniName = Connection->RemoteName; + + // + // Strip of the double leading slash if there is one + // + + if( uniName.Buffer[ 0] == L'\\' && + uniName.Buffer[ 1] == L'\\') + { + + uniName.Buffer = &uniName.Buffer[ 1]; + + uniName.Length -= sizeof( WCHAR); + } + + + FsRtlDissectName( uniName, + &uniComponentName, + &uniRemainingName); + + // + // Initialize the information for the connection + // First, if this is the server only then mark it accordingly + // + + if( uniRemainingName.Length == 0 || + DisplayType == RESOURCEDISPLAYTYPE_SERVER) + { + + Connection->Type = RESOURCETYPE_DISK; + + Connection->Scope = RESOURCE_GLOBALNET; + + Connection->DisplayType = RESOURCEDISPLAYTYPE_SERVER; + + Connection->Usage = RESOURCEUSAGE_CONTAINER; + + Connection->Comment.Length = 20; + Connection->Comment.MaximumLength = 22; + + Connection->Comment.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool, + Connection->Comment.MaximumLength, + AFS_NETWORK_PROVIDER_7_TAG); + + if( Connection->Comment.Buffer != NULL) + { + + RtlZeroMemory( Connection->Comment.Buffer, + Connection->Comment.MaximumLength); + + RtlCopyMemory( Connection->Comment.Buffer, + L"AFS Root", + 16); + } + else + { + + Connection->Comment.Length = 0; + Connection->Comment.MaximumLength = 0; + } + + try_return( ntStatus); + } + + uniName = uniRemainingName; + + FsRtlDissectName( uniName, + &uniComponentName, + &uniRemainingName); + + if( uniRemainingName.Length == 0 || + uniRemainingName.Buffer == NULL || + DisplayType == RESOURCEDISPLAYTYPE_SHARE) + { + + Connection->Type = RESOURCETYPE_DISK; + + Connection->DisplayType = RESOURCEDISPLAYTYPE_SHARE; + + Connection->Usage = RESOURCEUSAGE_CONNECTABLE; + + if( Connection->LocalName != L'\0') + { + + Connection->Usage |= RESOURCEUSAGE_ATTACHED; + + Connection->Scope = RESOURCE_CONNECTED; + } + else + { + + Connection->Scope = RESOURCE_GLOBALNET; + } + + Connection->Comment.Length = 18; + Connection->Comment.MaximumLength = 20; + + Connection->Comment.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool, + Connection->Comment.MaximumLength, + AFS_NETWORK_PROVIDER_8_TAG); + + if( Connection->Comment.Buffer != NULL) + { + + RtlZeroMemory( Connection->Comment.Buffer, + Connection->Comment.MaximumLength); + + RtlCopyMemory( Connection->Comment.Buffer, + L"AFS Share", + 18); + } + else + { + + Connection->Comment.Length = 0; + Connection->Comment.MaximumLength = 0; + } + + try_return( ntStatus); + } + + // + // This is a sub directory within a share + // + + Connection->Type = RESOURCETYPE_DISK; + + Connection->DisplayType = RESOURCEDISPLAYTYPE_DIRECTORY; + + Connection->Usage = RESOURCEUSAGE_CONNECTABLE; + + if( Connection->LocalName != L'\0') + { + + Connection->Usage |= RESOURCEUSAGE_ATTACHED; + } + + Connection->Scope = RESOURCE_CONNECTED; + + Connection->Comment.Length = 26; + Connection->Comment.MaximumLength = 28; + + Connection->Comment.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool, + Connection->Comment.MaximumLength, + AFS_NETWORK_PROVIDER_9_TAG); + + if( Connection->Comment.Buffer != NULL) + { + + RtlZeroMemory( Connection->Comment.Buffer, + Connection->Comment.MaximumLength); + + RtlCopyMemory( Connection->Comment.Buffer, + L"AFS Directory", + 26); + } + else + { + + Connection->Comment.Length = 0; + Connection->Comment.MaximumLength = 0; + } + +try_exit: + + NOTHING; + } + + return; +} diff --git a/src/WINNT/afsrdr/kernel/fs/AFSProcessSupport.cpp b/src/WINNT/afsrdr/kernel/fs/AFSProcessSupport.cpp new file mode 100644 index 0000000000..5c8e82e17d --- /dev/null +++ b/src/WINNT/afsrdr/kernel/fs/AFSProcessSupport.cpp @@ -0,0 +1,812 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC. + * Copyright (c) 2009, 2010, 2011 Your File System, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, + * this list of conditions and the following disclaimer in the + * documentation + * and/or other materials provided with the distribution. + * - Neither the names of Kernel Drivers, LLC and Your File System, Inc. + * nor the names of their contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission from Kernel Drivers, LLC and Your File System, Inc. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +// +// File: AFSProcessSupport.cpp +// + +#include "AFSCommon.h" + +void +AFSProcessNotify( IN HANDLE ParentId, + IN HANDLE ProcessId, + IN BOOLEAN Create) +{ + + NTSTATUS ntStatus = STATUS_SUCCESS; + AFSProcessCB *pProcessCB = NULL, *pParentProcessCB = NULL; + AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension; + AFSProcessAuthGroupCB *pProcessAuthGroup = NULL, *pLastAuthGroup = NULL; + AFSThreadCB *pThreadCB = NULL, *pNextThreadCB = NULL; + + __Enter + { + + // + // If this is a create notification then update our tree, otherwise remove the + // entry + // + + AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "AFSProcessNotify Acquiring Control ProcessTree.TreeLock lock %08lX EXCL %08lX\n", + pDeviceExt->Specific.Control.ProcessTree.TreeLock, + PsGetCurrentThread()); + + AFSAcquireExcl( pDeviceExt->Specific.Control.ProcessTree.TreeLock, + TRUE); + + if( Create) + { + + AFSDbgLogMsg( AFS_SUBSYSTEM_PROCESS_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "AFSProcessNotify CREATE Parent %08lX Process %08lX %08lX\n", + ParentId, + ProcessId, + PsGetCurrentThread()); + + pProcessCB = AFSInitializeProcessCB( (ULONGLONG)ParentId, + (ULONGLONG)ProcessId); + + if( pProcessCB != NULL) + { + pProcessCB->CreatingThread = (ULONGLONG)PsGetCurrentThreadId(); + } + + try_return( ntStatus); + } + + // + // It's a remove so pull the entry + // + + AFSDbgLogMsg( AFS_SUBSYSTEM_PROCESS_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "AFSProcessNotify DESTROY Process %08lX %08lX\n", + ProcessId, + PsGetCurrentThread()); + + ntStatus = AFSLocateHashEntry( pDeviceExt->Specific.Control.ProcessTree.TreeHead, + (ULONGLONG)ProcessId, + (AFSBTreeEntry **)&pProcessCB); + + if( NT_SUCCESS( ntStatus) && + pProcessCB != NULL) + { + + AFSRemoveHashEntry( &pDeviceExt->Specific.Control.ProcessTree.TreeHead, + (AFSBTreeEntry *)pProcessCB); + + pProcessAuthGroup = pProcessCB->AuthGroupList; + + while( pProcessAuthGroup != NULL) + { + + pLastAuthGroup = pProcessAuthGroup->Next; + + ExFreePool( pProcessAuthGroup); + + pProcessAuthGroup = pLastAuthGroup; + } + + pThreadCB = pProcessCB->ThreadList; + + while( pThreadCB != NULL) + { + + pNextThreadCB = pThreadCB->Next; + + ExFreePool( pThreadCB); + + pThreadCB = pNextThreadCB; + } + + ExDeleteResourceLite( &pProcessCB->Lock); + + ExFreePool( pProcessCB); + } + else + { + AFSDbgLogMsg( AFS_SUBSYSTEM_PROCESS_PROCESSING, + AFS_TRACE_LEVEL_WARNING, + "AFSProcessNotify Process %08lX not found in ProcessTree Status %08lX %08lX\n", + ProcessId, + ntStatus, + PsGetCurrentThread()); + } + +try_exit: + + AFSReleaseResource( pDeviceExt->Specific.Control.ProcessTree.TreeLock); + + } + + return; +} + +// +// AFSValidateProcessEntry verifies the consistency of the current process +// entry which includes assigning an authentication group ACE if one is not +// present. A reference to the active authentication group GUID is returned. +// + +GUID * +AFSValidateProcessEntry( void) +{ + + GUID *pAuthGroup = NULL; + NTSTATUS ntStatus = STATUS_SUCCESS; + AFSProcessCB *pProcessCB = NULL, *pParentProcessCB = NULL; + AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension; + ULONGLONG ullProcessID = (ULONGLONG)PsGetCurrentProcessId(); + UNICODE_STRING uniSIDString; + ULONG ulSIDHash = 0; + AFSSIDEntryCB *pSIDEntryCB = NULL; + ULONG ulSessionId = 0; + ULONGLONG ullTableHash = 0; + AFSThreadCB *pParentThreadCB = NULL; + UNICODE_STRING uniGUID; + BOOLEAN bImpersonation = FALSE; + + __Enter + { + + AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "AFSValidateProcessEntry Acquiring Control ProcessTree.TreeLock lock %08lX SHARED %08lX\n", + pDeviceExt->Specific.Control.ProcessTree.TreeLock, + PsGetCurrentThread()); + + uniSIDString.Length = 0; + uniSIDString.MaximumLength = 0; + uniSIDString.Buffer = NULL; + + AFSAcquireShared( pDeviceExt->Specific.Control.ProcessTree.TreeLock, + TRUE); + + AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "%s Entry for ProcessID %I64X\n", + __FUNCTION__, + ullProcessID); + + ntStatus = AFSLocateHashEntry( pDeviceExt->Specific.Control.ProcessTree.TreeHead, + (ULONGLONG)ullProcessID, + (AFSBTreeEntry **)&pProcessCB); + + if( !NT_SUCCESS( ntStatus) || + pProcessCB == NULL) + { + + AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, + AFS_TRACE_LEVEL_ERROR, + "%s Failed to locate process entry for ProcessID %I64X\n", + __FUNCTION__, + ullProcessID); + + ASSERT( FALSE); + AFSReleaseResource( pDeviceExt->Specific.Control.ProcessTree.TreeLock); + try_return( ntStatus = STATUS_UNSUCCESSFUL); + } + + // + // Locate and lock the ParentProcessCB if we have one + // + + if( pProcessCB->ParentProcessId != 0) + { + + AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "%s Locating process entry for Parent ProcessID %I64X\n", + __FUNCTION__, + pProcessCB->ParentProcessId); + + ntStatus = AFSLocateHashEntry( pDeviceExt->Specific.Control.ProcessTree.TreeHead, + (ULONGLONG)pProcessCB->ParentProcessId, + (AFSBTreeEntry **)&pParentProcessCB); + + if( NT_SUCCESS( ntStatus) && + pParentProcessCB != NULL) + { + AFSAcquireExcl( &pParentProcessCB->Lock, + TRUE); + + AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "%s Located process entry for Parent ProcessID %I64X\n", + __FUNCTION__, + pProcessCB->ParentProcessId); + } + } + else + { + + AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "%s No parent ID for ProcessID %I64X\n", + __FUNCTION__, + ullProcessID); + } + + AFSAcquireExcl( &pProcessCB->Lock, + TRUE); + + AFSReleaseResource( pDeviceExt->Specific.Control.ProcessTree.TreeLock); + + // + // Locate the SID for the caller + // + + ntStatus = AFSGetCallerSID( &uniSIDString, &bImpersonation); + + if( !NT_SUCCESS( ntStatus)) + { + + AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, + AFS_TRACE_LEVEL_ERROR, + "%s Failed to locate callers SID for ProcessID %I64X\n", + __FUNCTION__, + ullProcessID); + + try_return( ntStatus); + } + + ulSessionId = AFSGetSessionId( (HANDLE)ullProcessID, &bImpersonation); + + if( ulSessionId == (ULONG)-1) + { + + AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, + AFS_TRACE_LEVEL_ERROR, + "%s Failed to retrieve session ID for ProcessID %I64X\n", + __FUNCTION__, + ullProcessID); + + try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES); + } + + AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "%s Retrieved callers SID %wZ for ProcessID %I64X Session %08lX\n", + __FUNCTION__, + &uniSIDString, + ullProcessID, + ulSessionId); + + // + // If there is an Auth Group for the current process, + // our job is finished. + // + + if ( bImpersonation == FALSE) + { + pAuthGroup = pProcessCB->ActiveAuthGroup; + + if( pAuthGroup != NULL && + !AFSIsNoPAGAuthGroup( pAuthGroup)) + { + + uniGUID.Buffer = NULL; + + RtlStringFromGUID( *pAuthGroup, + &uniGUID); + + AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "%s Located valid AuthGroup GUID %wZ for SID %wZ ProcessID %I64X Session %08lX\n", + __FUNCTION__, + &uniGUID, + &uniSIDString, + ullProcessID, + ulSessionId); + + if( uniGUID.Buffer != NULL) + { + RtlFreeUnicodeString( &uniGUID); + } + + try_return( ntStatus = STATUS_SUCCESS); + } + + // + // The current process does not yet have an Auth Group. Try to inherit + // one from the parent process thread that created this process. + // + + if( pParentProcessCB != NULL) + { + + for ( pParentThreadCB = pParentProcessCB->ThreadList; + pParentThreadCB != NULL; + pParentThreadCB = pParentThreadCB->Next) + { + + if( pParentThreadCB->ThreadId == pProcessCB->CreatingThread) + { + break; + } + } + + // + // If the creating thread was found and it has a thread specific + // Auth Group, use that even if it is the No PAG + // + + if( pParentThreadCB != NULL && + pParentThreadCB->ActiveAuthGroup != NULL && + !AFSIsNoPAGAuthGroup( pParentThreadCB->ActiveAuthGroup)) + { + pProcessCB->ActiveAuthGroup = pParentThreadCB->ActiveAuthGroup; + + uniGUID.Buffer = NULL; + + RtlStringFromGUID( *(pProcessCB->ActiveAuthGroup), + &uniGUID); + + AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "%s PID %08lX Session %08lX inherited Active AuthGroup %wZ from thread %I64X\n", + __FUNCTION__, + ullProcessID, + ulSessionId, + &uniGUID, + pParentThreadCB->ThreadId); + + if( uniGUID.Buffer != NULL) + { + RtlFreeUnicodeString( &uniGUID); + } + } + + // + // If the parent thread was not found or does not have an auth group + // + + else if( pParentProcessCB->ActiveAuthGroup != NULL && + !AFSIsNoPAGAuthGroup( pParentProcessCB->ActiveAuthGroup)) + { + pProcessCB->ActiveAuthGroup = pParentProcessCB->ActiveAuthGroup; + + uniGUID.Buffer = NULL; + + RtlStringFromGUID( *(pProcessCB->ActiveAuthGroup), + &uniGUID); + + AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "%s PID %08lX Session %08lX inherited Active AuthGroup %wZ from parent PID %I64X\n", + __FUNCTION__, + ullProcessID, + ulSessionId, + &uniGUID, + pParentProcessCB->TreeEntry.HashIndex); + + if( uniGUID.Buffer != NULL) + { + RtlFreeUnicodeString( &uniGUID); + } + } + + // + // If an Auth Group was inherited, set it to be the active group + // + + if( pProcessCB->ActiveAuthGroup != NULL && + !AFSIsNoPAGAuthGroup( pParentProcessCB->ActiveAuthGroup)) + { + pAuthGroup = pProcessCB->ActiveAuthGroup; + + uniGUID.Buffer = NULL; + + RtlStringFromGUID( *(pProcessCB->ActiveAuthGroup), + &uniGUID); + + AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "%s Returning(1) Active AuthGroup %wZ for SID %wZ PID %I64X Session %08lX\n", + __FUNCTION__, + &uniGUID, + &uniSIDString, + ullProcessID, + ulSessionId); + + if( uniGUID.Buffer != NULL) + { + RtlFreeUnicodeString( &uniGUID); + } + + try_return( ntStatus); + } + } + } + + // + // If no Auth Group was inherited, assign one based upon the Session and SID + // + + ntStatus = RtlHashUnicodeString( &uniSIDString, + TRUE, + HASH_STRING_ALGORITHM_DEFAULT, + &ulSIDHash); + + if( !NT_SUCCESS( ntStatus)) + { + + AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, + AFS_TRACE_LEVEL_ERROR, + "%s Failed to hash SID %wZ for PID %I64X Session %08lX Status %08lX\n", + __FUNCTION__, + &uniSIDString, + ullProcessID, + ulSessionId, + ntStatus); + + try_return( ntStatus); + } + + ullTableHash = ( ((ULONGLONG)ulSessionId << 32) | ulSIDHash); + + AFSAcquireShared( pDeviceExt->Specific.Control.AuthGroupTree.TreeLock, + TRUE); + + ntStatus = AFSLocateHashEntry( pDeviceExt->Specific.Control.AuthGroupTree.TreeHead, + (ULONGLONG)ullTableHash, + (AFSBTreeEntry **)&pSIDEntryCB); + + if( !NT_SUCCESS( ntStatus) || + pSIDEntryCB == NULL) + { + + AFSReleaseResource( pDeviceExt->Specific.Control.AuthGroupTree.TreeLock); + + AFSAcquireExcl( pDeviceExt->Specific.Control.AuthGroupTree.TreeLock, + TRUE); + + ntStatus = AFSLocateHashEntry( pDeviceExt->Specific.Control.AuthGroupTree.TreeHead, + (ULONGLONG)ullTableHash, + (AFSBTreeEntry **)&pSIDEntryCB); + + if( !NT_SUCCESS( ntStatus) || + pSIDEntryCB == NULL) + { + + pSIDEntryCB = (AFSSIDEntryCB *)AFSExAllocatePoolWithTag( NonPagedPool, + sizeof( AFSSIDEntryCB), + AFS_AG_ENTRY_CB_TAG); + + if( pSIDEntryCB == NULL) + { + + AFSReleaseResource( pDeviceExt->Specific.Control.AuthGroupTree.TreeLock); + + try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES); + } + + RtlZeroMemory( pSIDEntryCB, + sizeof( AFSSIDEntryCB)); + + pSIDEntryCB->TreeEntry.HashIndex = (ULONGLONG)ullTableHash; + + while( ExUuidCreate( &pSIDEntryCB->AuthGroup) == STATUS_RETRY); + + uniGUID.Buffer = NULL; + + RtlStringFromGUID( pSIDEntryCB->AuthGroup, + &uniGUID); + + AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "%s SID %wZ PID %I64X Session %08lX generated NEW AG %wZ\n", + __FUNCTION__, + &uniSIDString, + ullProcessID, + ulSessionId, + &uniGUID); + + if( uniGUID.Buffer != NULL) + { + RtlFreeUnicodeString( &uniGUID); + } + + if( pDeviceExt->Specific.Control.AuthGroupTree.TreeHead == NULL) + { + pDeviceExt->Specific.Control.AuthGroupTree.TreeHead = (AFSBTreeEntry *)pSIDEntryCB; + } + else + { + AFSInsertHashEntry( pDeviceExt->Specific.Control.AuthGroupTree.TreeHead, + &pSIDEntryCB->TreeEntry); + } + } + + AFSConvertToShared( pDeviceExt->Specific.Control.AuthGroupTree.TreeLock); + } + + + AFSReleaseResource( pDeviceExt->Specific.Control.AuthGroupTree.TreeLock); + + // + // Store the auth group into the process cb + // + + pProcessCB->ActiveAuthGroup = &pSIDEntryCB->AuthGroup; + + uniGUID.Buffer = NULL; + + RtlStringFromGUID( pSIDEntryCB->AuthGroup, + &uniGUID); + + AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "%s SID %wZ PID %I64X Session %08lX assigned AG %wZ\n", + __FUNCTION__, + &uniSIDString, + ullProcessID, + ulSessionId, + &uniGUID); + + if( uniGUID.Buffer != NULL) + { + RtlFreeUnicodeString( &uniGUID); + } + + // + // Set the AFS_PROCESS_LOCAL_SYSTEM_AUTH flag if the process SID + // is LOCAL_SYSTEM + // + + if( AFSIsLocalSystemSID( &uniSIDString)) + { + SetFlag( pProcessCB->Flags, AFS_PROCESS_LOCAL_SYSTEM_AUTH); + + AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "%s Setting PID %I64X Session %08lX with LOCAL SYSTEM AUTHORITY\n", + __FUNCTION__, + ullProcessID, + ulSessionId); + } + + // + // Return the auth group + // + + pAuthGroup = pProcessCB->ActiveAuthGroup; + + uniGUID.Buffer = NULL; + + RtlStringFromGUID( *(pProcessCB->ActiveAuthGroup), + &uniGUID); + + AFSDbgLogMsg( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "%s Returning(2) Active AuthGroup %wZ for SID %wZ PID %I64X Session %08lX\n", + __FUNCTION__, + &uniGUID, + &uniSIDString, + ullProcessID, + ulSessionId); + + if( uniGUID.Buffer != NULL) + { + RtlFreeUnicodeString( &uniGUID); + } + +try_exit: + + if( pProcessCB != NULL) + { + + if( bImpersonation == FALSE && + !BooleanFlagOn( pProcessCB->Flags, AFS_PROCESS_FLAG_ACE_SET) && + NT_SUCCESS( ntStatus)) + { + ntStatus = AFSProcessSetProcessDacl( pProcessCB); + + if( !NT_SUCCESS( ntStatus)) + { + pAuthGroup = NULL; + } + else + { + SetFlag( pProcessCB->Flags, AFS_PROCESS_FLAG_ACE_SET); + } + } + + AFSReleaseResource( &pProcessCB->Lock); + } + + if( pParentProcessCB != NULL) + { + AFSReleaseResource( &pParentProcessCB->Lock); + } + + if( uniSIDString.Length > 0) + { + RtlFreeUnicodeString( &uniSIDString); + } + } + + return pAuthGroup; +} + +BOOLEAN +AFSIs64BitProcess( IN ULONGLONG ProcessId) +{ + + NTSTATUS ntStatus = STATUS_SUCCESS; + BOOLEAN bIs64Bit = FALSE; + AFSProcessCB *pProcessCB = NULL; + AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension; + + __Enter + { + + AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "AFSIs64BitProcess Acquiring Control ProcessTree.TreeLock lock %08lX SHARED %08lX\n", + pDeviceExt->Specific.Control.ProcessTree.TreeLock, + PsGetCurrentThread()); + + AFSAcquireShared( pDeviceExt->Specific.Control.ProcessTree.TreeLock, + TRUE); + + ntStatus = AFSLocateHashEntry( pDeviceExt->Specific.Control.ProcessTree.TreeHead, + (ULONGLONG)ProcessId, + (AFSBTreeEntry **)&pProcessCB); + + if( pProcessCB != NULL) + { + bIs64Bit = BooleanFlagOn( pProcessCB->Flags, AFS_PROCESS_FLAG_IS_64BIT); + } + + AFSReleaseResource( pDeviceExt->Specific.Control.ProcessTree.TreeLock); + } + + return bIs64Bit; +} + +AFSProcessCB * +AFSInitializeProcessCB( IN ULONGLONG ParentProcessId, + IN ULONGLONG ProcessId) +{ + + AFSProcessCB *pProcessCB = NULL; + AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension; + + __Enter + { + + pProcessCB = (AFSProcessCB *)AFSExAllocatePoolWithTag( NonPagedPool, + sizeof( AFSProcessCB), + AFS_PROCESS_CB_TAG); + + if( pProcessCB == NULL) + { + try_return( pProcessCB); + } + + RtlZeroMemory( pProcessCB, + sizeof( AFSProcessCB)); + + pProcessCB->TreeEntry.HashIndex = (ULONGLONG)ProcessId; + + pProcessCB->ParentProcessId = (ULONGLONG)ParentProcessId; + +#if defined(_WIN64) + + if( !IoIs32bitProcess( NULL)) + { + SetFlag( pProcessCB->Flags, AFS_PROCESS_FLAG_IS_64BIT); + } + +#endif + + if( pDeviceExt->Specific.Control.ProcessTree.TreeHead == NULL) + { + pDeviceExt->Specific.Control.ProcessTree.TreeHead = (AFSBTreeEntry *)pProcessCB; + } + else + { + AFSInsertHashEntry( pDeviceExt->Specific.Control.ProcessTree.TreeHead, + &pProcessCB->TreeEntry); + } + + ExInitializeResourceLite( &pProcessCB->Lock); + + pProcessCB->ActiveAuthGroup = &AFSNoPAGAuthGroup; + +try_exit: + + NOTHING; + } + + return pProcessCB; +} + +AFSThreadCB * +AFSInitializeThreadCB( IN AFSProcessCB *ProcessCB, + IN ULONGLONG ThreadId) +{ + + AFSThreadCB *pThreadCB = NULL, *pCurrentThreadCB = NULL; + + __Enter + { + + pThreadCB = (AFSThreadCB *)AFSExAllocatePoolWithTag( NonPagedPool, + sizeof( AFSThreadCB), + AFS_PROCESS_CB_TAG); + + if( pThreadCB == NULL) + { + try_return( pThreadCB); + } + + RtlZeroMemory( pThreadCB, + sizeof( AFSThreadCB)); + + pThreadCB->ThreadId = ThreadId; + + if( ProcessCB->ThreadList == NULL) + { + ProcessCB->ThreadList = pThreadCB; + } + else + { + + pCurrentThreadCB = ProcessCB->ThreadList; + + while( pCurrentThreadCB != NULL) + { + + if( pCurrentThreadCB->Next == NULL) + { + pCurrentThreadCB->Next = pThreadCB; + break; + } + + pCurrentThreadCB = pCurrentThreadCB->Next; + } + } + +try_exit: + + NOTHING; + } + + return pThreadCB; +} diff --git a/src/WINNT/afsrdr/kernel/fs/AFSQuota.cpp b/src/WINNT/afsrdr/kernel/fs/AFSQuota.cpp new file mode 100644 index 0000000000..423f200b60 --- /dev/null +++ b/src/WINNT/afsrdr/kernel/fs/AFSQuota.cpp @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC. + * Copyright (c) 2009, 2010, 2011 Your File System, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, + * this list of conditions and the following disclaimer in the + * documentation + * and/or other materials provided with the distribution. + * - Neither the names of Kernel Drivers, LLC and Your File System, Inc. + * nor the names of their contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission from Kernel Drivers, LLC and Your File System, Inc. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +// +// File: AFSQuota.cpp +// + +#include "AFSCommon.h" + +NTSTATUS +AFSQueryQuota( IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + + NTSTATUS ntStatus = STATUS_NOT_SUPPORTED; + IO_STACK_LOCATION *pIrpSp; + + pIrpSp = IoGetCurrentIrpStackLocation( Irp); + + __try + { + + AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING, + AFS_TRACE_LEVEL_ERROR, + "AFSQueryQuota Entry for FO %08lX\n", + pIrpSp->FileObject); + + AFSCompleteRequest( Irp, + ntStatus); + + } + __except( AFSExceptionFilter( GetExceptionCode(), GetExceptionInformation()) ) + { + + AFSDbgLogMsg( 0, + 0, + "EXCEPTION - AFSQueryQuota\n"); + } + + return ntStatus; +} + +NTSTATUS +AFSSetQuota( IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + + NTSTATUS ntStatus = STATUS_NOT_SUPPORTED; + IO_STACK_LOCATION *pIrpSp; + + pIrpSp = IoGetCurrentIrpStackLocation( Irp); + + __try + { + + AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING, + AFS_TRACE_LEVEL_ERROR, + "AFSSetQuota Entry for FO %08lX\n", + pIrpSp->FileObject); + + AFSCompleteRequest( Irp, + ntStatus); + } + __except( AFSExceptionFilter( GetExceptionCode(), GetExceptionInformation()) ) + { + + AFSDbgLogMsg( 0, + 0, + "EXCEPTION - AFSSetQuota\n"); + } + + return ntStatus; +} diff --git a/src/WINNT/afsrdr/kernel/fs/AFSRDRSupport.cpp b/src/WINNT/afsrdr/kernel/fs/AFSRDRSupport.cpp new file mode 100644 index 0000000000..93354a82fc --- /dev/null +++ b/src/WINNT/afsrdr/kernel/fs/AFSRDRSupport.cpp @@ -0,0 +1,793 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC. + * Copyright (c) 2009, 2010, 2011 Your File System, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, + * this list of conditions and the following disclaimer in the + * documentation + * and/or other materials provided with the distribution. + * - Neither the names of Kernel Drivers, LLC and Your File System, Inc. + * nor the names of their contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission from Kernel Drivers, LLC and Your File System, Inc. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +// +// File: AFSRDRSupport.cpp +// +#include "AFSCommon.h" + +typedef NTSTATUS (*FsRtlRegisterUncProviderEx_t)( PHANDLE MupHandle, PUNICODE_STRING RedirDevName, PDEVICE_OBJECT DeviceObject, ULONG Flags); + +NTSTATUS +AFSInitRDRDevice() +{ + + NTSTATUS ntStatus = STATUS_SUCCESS; + UNICODE_STRING uniDeviceName; + ULONG ulIndex = 0; + AFSDeviceExt *pDeviceExt = NULL; + AFSFileID stRootFid; + UNICODE_STRING uniFsRtlRegisterUncProviderEx; + FsRtlRegisterUncProviderEx_t pFsRtlRegisterUncProviderEx = NULL; + + __Enter + { + + RtlInitUnicodeString( &uniDeviceName, + AFS_RDR_DEVICE_NAME); + + RtlInitUnicodeString( &uniFsRtlRegisterUncProviderEx, + L"FsRtlRegisterUncProviderEx"); + + pFsRtlRegisterUncProviderEx = (FsRtlRegisterUncProviderEx_t)MmGetSystemRoutineAddress(&uniFsRtlRegisterUncProviderEx); + + ntStatus = IoCreateDevice( AFSDriverObject, + sizeof( AFSDeviceExt), + pFsRtlRegisterUncProviderEx ? NULL : &uniDeviceName, + FILE_DEVICE_NETWORK_FILE_SYSTEM, + FILE_REMOTE_DEVICE, + FALSE, + &AFSRDRDeviceObject); + + if( !NT_SUCCESS( ntStatus)) + { + + AFSDbgLogMsg( AFS_SUBSYSTEM_INIT_PROCESSING, + AFS_TRACE_LEVEL_ERROR, + "AFSInitRDRDevice IoCreateDevice failure %08lX\n", + ntStatus); + + try_return( ntStatus); + } + + pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension; + + RtlZeroMemory( pDeviceExt, + sizeof( AFSDeviceExt)); + + // + // Initialize resources + // + + pDeviceExt->Specific.RDR.VolumeTree.TreeLock = &pDeviceExt->Specific.RDR.VolumeTreeLock; + + ExInitializeResourceLite( pDeviceExt->Specific.RDR.VolumeTree.TreeLock); + + pDeviceExt->Specific.RDR.VolumeTree.TreeHead = NULL; + + ExInitializeResourceLite( &pDeviceExt->Specific.RDR.VolumeListLock); + + pDeviceExt->Specific.RDR.VolumeListHead = NULL; + + pDeviceExt->Specific.RDR.VolumeListTail = NULL; + + KeInitializeEvent( &pDeviceExt->Specific.RDR.QueuedReleaseExtentEvent, + NotificationEvent, + TRUE); + + ExInitializeResourceLite( &pDeviceExt->Specific.RDR.RootCellTreeLock); + + pDeviceExt->Specific.RDR.RootCellTree.TreeLock = &pDeviceExt->Specific.RDR.RootCellTreeLock; + + pDeviceExt->Specific.RDR.RootCellTree.TreeHead = NULL; + + ExInitializeResourceLite( &pDeviceExt->Specific.RDR.ProviderListLock); + + // + // Clear the initializing bit + // + + AFSRDRDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING; + + // + // Register this device with MUP with FilterMgr if Vista or above + // + + if( pFsRtlRegisterUncProviderEx) + { + + ntStatus = pFsRtlRegisterUncProviderEx( &AFSMUPHandle, + &uniDeviceName, + AFSRDRDeviceObject, + 0); + if ( !NT_SUCCESS( ntStatus)) + { + AFSDbgLogMsg( AFS_SUBSYSTEM_INIT_PROCESSING, + AFS_TRACE_LEVEL_ERROR, + "AFSInitRDRDevice FsRtlRegisterUncProvider failure %08lX\n", + ntStatus); + } + } + else + { + + ntStatus = FsRtlRegisterUncProvider( &AFSMUPHandle, + &uniDeviceName, + FALSE); + + if ( NT_SUCCESS( ntStatus)) + { + + IoRegisterFileSystem( AFSRDRDeviceObject); + } + else + { + AFSDbgLogMsg( AFS_SUBSYSTEM_INIT_PROCESSING, + AFS_TRACE_LEVEL_ERROR, + "AFSInitRDRDevice FsRtlRegisterUncProvider failure %08lX\n", + ntStatus); + } + } + + if( !NT_SUCCESS( ntStatus)) + { + + // + // Delete our device and bail + // + + ExDeleteResourceLite( pDeviceExt->Specific.RDR.VolumeTree.TreeLock); + + ExDeleteResourceLite( &pDeviceExt->Specific.RDR.VolumeListLock); + + ExDeleteResourceLite( &pDeviceExt->Specific.RDR.RootCellTreeLock); + + ExDeleteResourceLite( &pDeviceExt->Specific.RDR.ProviderListLock); + + IoDeleteDevice( AFSRDRDeviceObject); + + AFSRDRDeviceObject = NULL; + + try_return( ntStatus); + } + + // + // Good to go, all registered and ready to start receiving requests + // + +try_exit: + + if( !NT_SUCCESS( ntStatus)) + { + + } + } + + return ntStatus; +} + +NTSTATUS +AFSRDRDeviceControl( IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + + NTSTATUS ntStatus = STATUS_SUCCESS; + PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp); + PFILE_OBJECT pFileObject = pIrpSp->FileObject; + BOOLEAN bCompleteIrp = TRUE; + + __Enter + { + + switch( pIrpSp->Parameters.DeviceIoControl.IoControlCode) + { + + case IOCTL_REDIR_QUERY_PATH: + { + + QUERY_PATH_REQUEST *pPathRequest = (QUERY_PATH_REQUEST *)pIrpSp->Parameters.DeviceIoControl.Type3InputBuffer; + QUERY_PATH_RESPONSE *pPathResponse = (QUERY_PATH_RESPONSE *)Irp->UserBuffer; + UNICODE_STRING uniPathName; + + ntStatus = STATUS_BAD_NETWORK_PATH; + + uniPathName.Length = (USHORT)pPathRequest->PathNameLength; + uniPathName.MaximumLength = uniPathName.Length; + + uniPathName.Buffer = pPathRequest->FilePathName; + + if( uniPathName.Length >= AFSServerName.Length + sizeof( WCHAR)) + { + + USHORT usLength = uniPathName.Length; + + uniPathName.Length = AFSServerName.Length; + + // + // Skip over the first slash in the name + // + + uniPathName.Buffer = &uniPathName.Buffer[ 1]; + + + // + // Check to see if the first (or only) component + // of the path matches the server name + // + + if( RtlCompareUnicodeString( &AFSServerName, + &uniPathName, + TRUE) == 0 && + ( usLength == AFSServerName.Length + sizeof( WCHAR) || + uniPathName.Buffer[ AFSServerName.Length / sizeof( WCHAR)] == '\\')) + { + + ntStatus = STATUS_SUCCESS; + + pPathResponse->LengthAccepted = AFSServerName.Length + sizeof( WCHAR); + } + } + + break; + } + + case IOCTL_REDIR_QUERY_PATH_EX: + { + + QUERY_PATH_REQUEST_EX *pPathRequest = (QUERY_PATH_REQUEST_EX *)pIrpSp->Parameters.DeviceIoControl.Type3InputBuffer; + QUERY_PATH_RESPONSE *pPathResponse = (QUERY_PATH_RESPONSE *)Irp->UserBuffer; + UNICODE_STRING uniPathName; + + ntStatus = STATUS_BAD_NETWORK_PATH; + + uniPathName.Length = pPathRequest->PathName.Length; + uniPathName.MaximumLength = uniPathName.Length; + + uniPathName.Buffer = pPathRequest->PathName.Buffer; + + if( uniPathName.Length >= AFSServerName.Length + sizeof( WCHAR)) + { + + USHORT usLength = uniPathName.Length; + + uniPathName.Length = AFSServerName.Length; + + // + // Skip over the first slash in the name + // + + uniPathName.Buffer = &uniPathName.Buffer[ 1]; + + + // + // Check to see if the first (or only) component + // of the path matches the server name + // + + if( RtlCompareUnicodeString( &AFSServerName, + &uniPathName, + TRUE) == 0 && + ( usLength == AFSServerName.Length + sizeof( WCHAR) || + uniPathName.Buffer[ AFSServerName.Length / sizeof( WCHAR)] == '\\')) + { + + ntStatus = STATUS_SUCCESS; + + pPathResponse->LengthAccepted = AFSServerName.Length + sizeof( WCHAR); + } + } + + break; + } + + default: + + ntStatus = STATUS_INVALID_DEVICE_REQUEST; + + break; + } + + if (bCompleteIrp) + { + // + // Complete the request + // + + AFSCompleteRequest( Irp, + ntStatus); + } + } + + return ntStatus; +} + +NTSTATUS +AFSInitializeRedirector( IN AFSRedirectorInitInfo *RedirInitInfo) +{ + + NTSTATUS ntStatus = STATUS_SUCCESS; + LARGE_INTEGER cacheSizeBytes; + AFSDeviceExt *pDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension; + AFSDeviceExt *pControlDevExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension; + OBJECT_ATTRIBUTES stObjectAttribs; + IO_STATUS_BLOCK stIoStatus; + UNICODE_STRING uniServiceName; + + __Enter + { + + // + // First this is to load the library + // + + RtlInitUnicodeString( &uniServiceName, + AFS_REDIR_LIBRARY_SERVICE_ENTRY); + + ntStatus = AFSLoadLibrary( 0, + &uniServiceName); + + if( !NT_SUCCESS( ntStatus)) + { + + AFSDbgLogMsg( AFS_SUBSYSTEM_INIT_PROCESSING, + AFS_TRACE_LEVEL_ERROR, + "AFSInitializeRedirector AFSLoadLibrary failure %08lX\n", + ntStatus); + + try_return( ntStatus); + } + + // + // Save off the cache file information + // + + pDevExt->Specific.RDR.CacheBlockSize = RedirInitInfo->CacheBlockSize; + + pDevExt->Specific.RDR.CacheBlockCount = RedirInitInfo->ExtentCount; + + pDevExt->Specific.RDR.MaximumRPCLength = RedirInitInfo->MaximumChunkLength; + + cacheSizeBytes = RedirInitInfo->ExtentCount; + cacheSizeBytes.QuadPart *= RedirInitInfo->CacheBlockSize; + + AFSDumpFileLocation.Length = 0; + + AFSDumpFileLocation.MaximumLength = (USHORT)RedirInitInfo->DumpFileLocationLength + (4 * sizeof( WCHAR)); + + AFSDumpFileLocation.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool, + AFSDumpFileLocation.MaximumLength, + AFS_GENERIC_MEMORY_23_TAG); + + if( AFSDumpFileLocation.Buffer == NULL) + { + + AFSDbgLogMsg( AFS_SUBSYSTEM_INIT_PROCESSING, + AFS_TRACE_LEVEL_ERROR, + "AFSInitializeRedirector AFS_GENERIC_MEMORY_23_TAG allocation error\n"); + + try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES); + } + + RtlCopyMemory( AFSDumpFileLocation.Buffer, + L"\\??\\", + 4 * sizeof( WCHAR)); + + AFSDumpFileLocation.Length = 4 * sizeof( WCHAR); + + RtlCopyMemory( &AFSDumpFileLocation.Buffer[ AFSDumpFileLocation.Length/sizeof( WCHAR)], + (void *)((char *)RedirInitInfo + RedirInitInfo->DumpFileLocationOffset), + RedirInitInfo->DumpFileLocationLength); + + AFSDumpFileLocation.Length += (USHORT)RedirInitInfo->DumpFileLocationLength; + + // + // Be sure the shutdown flag is not set + // + + ClearFlag( pDevExt->DeviceFlags, AFS_DEVICE_FLAG_REDIRECTOR_SHUTDOWN); + + // + // Set up the Throttles. + // + // Max IO is 10% of the cache, or the value in the registry, + // with a minimum of 5Mb (and a maximum of 50% cache size) + // + if( AFSMaxDirectIo) + { + // + // collect what the user + // + pDevExt->Specific.RDR.MaxIo.QuadPart = AFSMaxDirectIo; + pDevExt->Specific.RDR.MaxIo.QuadPart *= (1024 * 1024); + + } + else + { + + pDevExt->Specific.RDR.MaxIo.QuadPart = cacheSizeBytes.QuadPart / 2; + } + + if (pDevExt->Specific.RDR.MaxIo.QuadPart < (5 * 1024 * 1204)) + { + + pDevExt->Specific.RDR.MaxIo.QuadPart = 5 * 1024 * 1204; + + } + + // + // For small cache configurations ... + // + + if (pDevExt->Specific.RDR.MaxIo.QuadPart > cacheSizeBytes.QuadPart / 2) + { + + pDevExt->Specific.RDR.MaxIo.QuadPart = cacheSizeBytes.QuadPart / 2; + } + + // + // Maximum Dirty is 50% of the cache, or the value in the + // registry. No minimum, maximum of 90% of cache size. + // + if (AFSMaxDirtyFile) + { + + pDevExt->Specific.RDR.MaxDirty.QuadPart = AFSMaxDirtyFile; + pDevExt->Specific.RDR.MaxDirty.QuadPart *= (1024 * 1024); + + } + else + { + + pDevExt->Specific.RDR.MaxDirty.QuadPart = cacheSizeBytes.QuadPart/2; + + } + + cacheSizeBytes.QuadPart *= 9; + cacheSizeBytes.QuadPart = cacheSizeBytes.QuadPart / 10; + + if (pDevExt->Specific.RDR.MaxDirty.QuadPart > cacheSizeBytes.QuadPart) + { + pDevExt->Specific.RDR.MaxDirty.QuadPart = cacheSizeBytes.QuadPart; + } + + // + // Store off any flags for the file system + // + + if( BooleanFlagOn( RedirInitInfo->Flags, AFS_REDIR_INIT_FLAG_HIDE_DOT_FILES)) + { + + // + // Hide files which begin with . + // + + SetFlag( pDevExt->DeviceFlags, AFS_DEVICE_FLAG_HIDE_DOT_NAMES); + } + + if( RedirInitInfo->MemoryCacheOffset.QuadPart != 0 && + RedirInitInfo->MemoryCacheLength.QuadPart != 0) + { + + ntStatus = STATUS_INSUFFICIENT_RESOURCES; + +#ifdef AMD64 + pDevExt->Specific.RDR.CacheMdl = MmCreateMdl( NULL, + (void *)RedirInitInfo->MemoryCacheOffset.QuadPart, + RedirInitInfo->MemoryCacheLength.QuadPart); +#else + pDevExt->Specific.RDR.CacheMdl = MmCreateMdl( NULL, + (void *)RedirInitInfo->MemoryCacheOffset.LowPart, + RedirInitInfo->MemoryCacheLength.LowPart); +#endif + + if( pDevExt->Specific.RDR.CacheMdl != NULL) + { + + __try + { + + MmProbeAndLockPages( pDevExt->Specific.RDR.CacheMdl, + KernelMode, + IoModifyAccess); + + pDevExt->Specific.RDR.CacheBaseAddress = MmGetSystemAddressForMdlSafe( pDevExt->Specific.RDR.CacheMdl, + NormalPagePriority); + } + __except( AFSExceptionFilter( GetExceptionCode(), GetExceptionInformation()) ) + { + IoFreeMdl( pDevExt->Specific.RDR.CacheMdl); + pDevExt->Specific.RDR.CacheMdl = NULL; + } + + if( pDevExt->Specific.RDR.CacheMdl != NULL) + { + pDevExt->Specific.RDR.CacheLength = RedirInitInfo->MemoryCacheLength; + ntStatus = STATUS_SUCCESS; + } + + } + } + + if( !NT_SUCCESS( ntStatus) && + RedirInitInfo->CacheFileNameLength == 0) + { + + AFSDbgLogMsg( AFS_SUBSYSTEM_INIT_PROCESSING, + AFS_TRACE_LEVEL_ERROR, + "AFSInitializeRedirector Unable to initialize cache file %08lX\n", + ntStatus); + + try_return( ntStatus); + } + + if( pDevExt->Specific.RDR.CacheMdl == NULL) + { + + if( RedirInitInfo->CacheFileNameLength == 0) + { + + AFSDbgLogMsg( AFS_SUBSYSTEM_INIT_PROCESSING, + AFS_TRACE_LEVEL_ERROR, + "AFSInitializeRedirector CacheMdl == NULL\n"); + + try_return( ntStatus = STATUS_INVALID_PARAMETER); + } + + // + // Go open the cache file + // + + pDevExt->Specific.RDR.CacheFile.Length = 0; + pDevExt->Specific.RDR.CacheFile.MaximumLength = (USHORT)RedirInitInfo->CacheFileNameLength + (4 * sizeof( WCHAR)); + + pDevExt->Specific.RDR.CacheFile.Buffer = (WCHAR *)AFSExAllocatePoolWithTag( PagedPool, + pDevExt->Specific.RDR.CacheFile.MaximumLength, + AFS_GENERIC_MEMORY_24_TAG); + + if( pDevExt->Specific.RDR.CacheFile.Buffer == NULL) + { + + AFSDbgLogMsg( AFS_SUBSYSTEM_INIT_PROCESSING, + AFS_TRACE_LEVEL_ERROR, + "AFSInitializeRedirector AFS_GENERIC_MEMORY_24_TAG allocation failure\n"); + + try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES); + } + + RtlCopyMemory( pDevExt->Specific.RDR.CacheFile.Buffer, + L"\\??\\", + 4 * sizeof( WCHAR)); + + pDevExt->Specific.RDR.CacheFile.Length = 4 * sizeof( WCHAR); + + RtlCopyMemory( &pDevExt->Specific.RDR.CacheFile.Buffer[ pDevExt->Specific.RDR.CacheFile.Length/sizeof( WCHAR)], + RedirInitInfo->CacheFileName, + RedirInitInfo->CacheFileNameLength); + + pDevExt->Specific.RDR.CacheFile.Length += (USHORT)RedirInitInfo->CacheFileNameLength; + + InitializeObjectAttributes( &stObjectAttribs, + &pDevExt->Specific.RDR.CacheFile, + OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, + NULL, + NULL); + + ntStatus = ZwOpenFile( &pDevExt->Specific.RDR.CacheFileHandle, + GENERIC_READ | GENERIC_WRITE, + &stObjectAttribs, + &stIoStatus, + FILE_SHARE_READ | FILE_SHARE_WRITE, + FILE_WRITE_THROUGH | FILE_RANDOM_ACCESS); + + if( !NT_SUCCESS( ntStatus)) + { + + AFSDbgLogMsg( AFS_SUBSYSTEM_INIT_PROCESSING, + AFS_TRACE_LEVEL_ERROR, + "AFSInitializeRedirector ZwOpenFile failure %08lX\n", + ntStatus); + + try_return( ntStatus); + } + + // + // Map to the fileobject + // + + ntStatus = ObReferenceObjectByHandle( pDevExt->Specific.RDR.CacheFileHandle, + SYNCHRONIZE, + NULL, + KernelMode, + (void **)&pDevExt->Specific.RDR.CacheFileObject, + NULL); + + if( !NT_SUCCESS( ntStatus)) + { + + AFSDbgLogMsg( AFS_SUBSYSTEM_INIT_PROCESSING, + AFS_TRACE_LEVEL_ERROR, + "AFSInitializeRedirector ObReferenceObjectByHandle failure %08lX\n", + ntStatus); + + try_return( ntStatus); + } + } + + pDevExt->Specific.RDR.MaxLinkCount = RedirInitInfo->MaxPathLinkCount; + + pDevExt->Specific.RDR.NameArrayLength = RedirInitInfo->NameArrayLength; + + // + // Intialize the library + // + + ntStatus = AFSInitializeLibrary( &RedirInitInfo->GlobalFileId, + TRUE); + + if ( !NT_SUCCESS( ntStatus)) + { + AFSDbgLogMsg( AFS_SUBSYSTEM_INIT_PROCESSING, + AFS_TRACE_LEVEL_ERROR, + "AFSInitializeRedirector AFSInitializeLibrary failure %08lX\n", + ntStatus); + } + +try_exit: + + if( !NT_SUCCESS( ntStatus)) + { + + if( pDevExt->Specific.RDR.CacheMdl != NULL) + { + + MmUnmapLockedPages( pDevExt->Specific.RDR.CacheBaseAddress, + pDevExt->Specific.RDR.CacheMdl); + + MmUnlockPages( pDevExt->Specific.RDR.CacheMdl); + + ExFreePool( pDevExt->Specific.RDR.CacheMdl); + + pDevExt->Specific.RDR.CacheMdl = NULL; + pDevExt->Specific.RDR.CacheBaseAddress = NULL; + pDevExt->Specific.RDR.CacheLength.QuadPart = 0; + } + + if( pDevExt->Specific.RDR.CacheFileHandle != NULL) + { + + ZwClose( pDevExt->Specific.RDR.CacheFileHandle); + + pDevExt->Specific.RDR.CacheFileHandle = NULL; + } + + if( pDevExt->Specific.RDR.CacheFileObject != NULL) + { + + ObDereferenceObject( pDevExt->Specific.RDR.CacheFileObject); + + pDevExt->Specific.RDR.CacheFileObject = NULL; + } + + if( pDevExt->Specific.RDR.CacheFile.Buffer != NULL) + { + + ExFreePool( pDevExt->Specific.RDR.CacheFile.Buffer); + + pDevExt->Specific.RDR.CacheFile.Buffer = NULL; + } + + if( AFSDumpFileLocation.Buffer != NULL) + { + ExFreePool( AFSDumpFileLocation.Buffer); + + AFSDumpFileLocation.Buffer = NULL; + } + + AFSUnloadLibrary( TRUE); + } + } + + return ntStatus; +} + +NTSTATUS +AFSCloseRedirector() +{ + + NTSTATUS ntStatus = STATUS_SUCCESS; + AFSDeviceExt *pDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension; + + __Enter + { + + // + // Unload the library first so we close off any accesses to the cache or underlying + // shared memory + // + + AFSUnloadLibrary( TRUE); + + // + // Close off the cache file or mapping + // + + if( pDevExt->Specific.RDR.CacheMdl != NULL) + { + + MmUnmapLockedPages( pDevExt->Specific.RDR.CacheBaseAddress, + pDevExt->Specific.RDR.CacheMdl); + + MmUnlockPages( pDevExt->Specific.RDR.CacheMdl); + + ExFreePool( pDevExt->Specific.RDR.CacheMdl); + + pDevExt->Specific.RDR.CacheMdl = NULL; + pDevExt->Specific.RDR.CacheBaseAddress = NULL; + pDevExt->Specific.RDR.CacheLength.QuadPart = 0; + } + + if( pDevExt->Specific.RDR.CacheFileHandle != NULL) + { + + ZwClose( pDevExt->Specific.RDR.CacheFileHandle); + + pDevExt->Specific.RDR.CacheFileHandle = NULL; + } + + if( pDevExt->Specific.RDR.CacheFileObject != NULL) + { + + ObDereferenceObject( pDevExt->Specific.RDR.CacheFileObject); + + pDevExt->Specific.RDR.CacheFileObject = NULL; + } + + if( pDevExt->Specific.RDR.CacheFile.Buffer != NULL) + { + + ExFreePool( pDevExt->Specific.RDR.CacheFile.Buffer); + + pDevExt->Specific.RDR.CacheFile.Buffer = NULL; + } + + if( AFSDumpFileLocation.Buffer != NULL) + { + ExFreePool( AFSDumpFileLocation.Buffer); + + AFSDumpFileLocation.Buffer = NULL; + } + } + + return ntStatus; +} diff --git a/src/WINNT/afsrdr/kernel/fs/AFSRead.cpp b/src/WINNT/afsrdr/kernel/fs/AFSRead.cpp new file mode 100644 index 0000000000..877813eb10 --- /dev/null +++ b/src/WINNT/afsrdr/kernel/fs/AFSRead.cpp @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC. + * Copyright (c) 2009, 2010, 2011 Your File System, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, + * this list of conditions and the following disclaimer in the + * documentation + * and/or other materials provided with the distribution. + * - Neither the names of Kernel Drivers, LLC and Your File System, Inc. + * nor the names of their contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission from Kernel Drivers, LLC and Your File System, Inc. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +// +// File: AFSRead.cpp +// + +#include "AFSCommon.h" + +// +// Function: AFSRead +// +// Description: +// +// A shim around AFSCommonRead +// + +NTSTATUS +AFSRead( IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + + NTSTATUS ntStatus = STATUS_SUCCESS; + AFSDeviceExt *pControlDeviceExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension; + + __try + { + + if( DeviceObject == AFSDeviceObject) + { + + ntStatus = STATUS_INVALID_DEVICE_REQUEST; + + AFSCompleteRequest( Irp, + ntStatus); + + try_return( ntStatus); + } + + // + // Check the state of the library + // + + ntStatus = AFSCheckLibraryState( Irp); + + if( !NT_SUCCESS( ntStatus) || + ntStatus == STATUS_PENDING) + { + + if( ntStatus != STATUS_PENDING) + { + AFSCompleteRequest( Irp, ntStatus); + } + + try_return( ntStatus); + } + + IoSkipCurrentIrpStackLocation( Irp); + + ntStatus = IoCallDriver( pControlDeviceExt->Specific.Control.LibraryDeviceObject, + Irp); + + // + // Indicate the library is done with the request + // + + AFSClearLibraryRequest(); + +try_exit: + + NOTHING; + } + __except( AFSExceptionFilter( GetExceptionCode(), GetExceptionInformation()) ) + { + + ntStatus = STATUS_INSUFFICIENT_RESOURCES; + } + + return ntStatus; +} diff --git a/src/WINNT/afsrdr/kernel/fs/AFSRedirInstall.inf b/src/WINNT/afsrdr/kernel/fs/AFSRedirInstall.inf new file mode 100644 index 0000000000..85e2a06436 --- /dev/null +++ b/src/WINNT/afsrdr/kernel/fs/AFSRedirInstall.inf @@ -0,0 +1,84 @@ +;;; +;;; AFS Redirector Installation file +;;; + +[Version] +signature = "$Windows NT$" +Class = "AFSRedirector" +ClassGuid = {63EA509E-71F9-42ec-9C5E-1ECC95E3A1A0} +Provider = %AFS% +DriverVer = 04/20/2006,1.0.0.0 + +[DestinationDirs] +DefaultDestDir = 12 +AFS.DriverFiles = 12 + +;; +;; Default install sections +;; + +[DefaultInstall] +CopyFiles = AFS.DriverFiles + +[SourceDisksNames] +1 = %Disk1% + +[SourceDisksFiles] +AFSRedir.sys = 1 + +[DefaultInstall.Services] +AddService = %AFSServiceName%,,AFS.Service + +;; +;; Default uninstall sections +;; + +[DefaultUninstall] +DelFiles = AFS.DriverFiles +DelReg = AFS.DelRegistry + +; +; Services Section +; + +[AFS.Service] +DisplayName = %AFSServiceName% +Description = %AFSServiceDesc% +ServiceBinary = %12%\AFSRedir.sys +ServiceType = 2 +StartType = 1 +ErrorControl = 1 +LoadOrderGroup = "Filesystem" +AddReg = AFS.AddRegistry + +; +; Registry Modifications +; + +[AFS.AddRegistry] +HKLM,%AFSRegistry%,%AFSTraceLevel%,0x00010001 ,0x0001 +HKLM,%AFSRegistry%,%AFSDebugFlags%,0x00010001 ,0x0000 + +[AFS.DelRegistry] +HKLM,%AFSRegistry%,%AFSTraceLevel% +HKLM,%AFSRegistry%,%AFSDebugFlags% + +; +; Copy Files +; + +[AFS.DriverFiles] +AFSRedir.sys + +;; +;; String Section +;; + +[Strings] +AFS = "OpenAFS" +AFSServiceDesc = "OpenAFS Redirector" +AFSServiceName = "AFSRedirector" +AFSRegistry = "system\currentcontrolset\services\AFSRedirector\Parameters" +AFSTraceLevel = "TraceLevel" +AFSDebugFlags = "DebugFlags" +Disk1 = "OpenAFS Media" diff --git a/src/WINNT/afsrdr/kernel/fs/AFSSecurity.cpp b/src/WINNT/afsrdr/kernel/fs/AFSSecurity.cpp new file mode 100644 index 0000000000..bb43806442 --- /dev/null +++ b/src/WINNT/afsrdr/kernel/fs/AFSSecurity.cpp @@ -0,0 +1,217 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC. + * Copyright (c) 2009, 2010, 2011 Your File System, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, + * this list of conditions and the following disclaimer in the + * documentation + * and/or other materials provided with the distribution. + * - Neither the names of Kernel Drivers, LLC and Your File System, Inc. + * nor the names of their contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission from Kernel Drivers, LLC and Your File System, Inc. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +// +// File: AFSSecurity.cpp +// + +#include "AFSCommon.h" + +NTSTATUS +AFSSetSecurity( IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + + NTSTATUS ntStatus = STATUS_NOT_SUPPORTED; + IO_STACK_LOCATION *pIrpSp; + AFSDeviceExt *pControlDeviceExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension; + + pIrpSp = IoGetCurrentIrpStackLocation( Irp); + + __try + { + + AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "AFSSetSecurity Entry for FO %08lX\n", + pIrpSp->FileObject); + + if( DeviceObject == AFSDeviceObject) + { + + ntStatus = STATUS_INVALID_DEVICE_REQUEST; + + AFSCompleteRequest( Irp, + ntStatus); + + try_return( ntStatus); + } + + if( pIrpSp->FileObject->FsContext == NULL) + { + + // + // Root open + // + + ntStatus = STATUS_INVALID_DEVICE_REQUEST; + + AFSCompleteRequest( Irp, + ntStatus); + + try_return( ntStatus); + } + + // + // Check the state of the library + // + + ntStatus = AFSCheckLibraryState( Irp); + + if( !NT_SUCCESS( ntStatus) || + ntStatus == STATUS_PENDING) + { + + if( ntStatus != STATUS_PENDING) + { + AFSCompleteRequest( Irp, ntStatus); + } + + try_return( ntStatus); + } + + IoSkipCurrentIrpStackLocation( Irp); + + ntStatus = IoCallDriver( pControlDeviceExt->Specific.Control.LibraryDeviceObject, + Irp); + + // + // Indicate the library is done with the request + // + + AFSClearLibraryRequest(); + +try_exit: + + NOTHING; + } + __except( AFSExceptionFilter( GetExceptionCode(), GetExceptionInformation()) ) + { + + AFSDbgLogMsg( 0, + 0, + "EXCEPTION - AFSSetSecurity\n"); + } + + return ntStatus; +} + +NTSTATUS +AFSQuerySecurity( IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + + NTSTATUS ntStatus = STATUS_NOT_SUPPORTED; + IO_STACK_LOCATION *pIrpSp; + AFSDeviceExt *pControlDeviceExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension; + + pIrpSp = IoGetCurrentIrpStackLocation( Irp); + + __try + { + + AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING, + AFS_TRACE_LEVEL_VERBOSE, + "AFSQuerySecurity Entry for FO %08lX\n", + pIrpSp->FileObject); + + if( DeviceObject == AFSDeviceObject) + { + + ntStatus = STATUS_INVALID_DEVICE_REQUEST; + + AFSCompleteRequest( Irp, + ntStatus); + + try_return( ntStatus); + } + + if( pIrpSp->FileObject->FsContext == NULL) + { + + // + // Root open + // + + ntStatus = STATUS_INVALID_DEVICE_REQUEST; + + AFSCompleteRequest( Irp, + ntStatus); + + try_return( ntStatus); + } + + // + // Check the state of the library + // + + ntStatus = AFSCheckLibraryState( Irp); + + if( !NT_SUCCESS( ntStatus) || + ntStatus == STATUS_PENDING) + { + + if( ntStatus != STATUS_PENDING) + { + AFSCompleteRequest( Irp, ntStatus); + } + + try_return( ntStatus); + } + + IoSkipCurrentIrpStackLocation( Irp); + + ntStatus = IoCallDriver( pControlDeviceExt->Specific.Control.LibraryDeviceObject, + Irp); + + // + // Indicate the library is done with the request + // + + AFSClearLibraryRequest(); + +try_exit: + + NOTHING; + } + __except( AFSExceptionFilter( GetExceptionCode(), GetExceptionInformation()) ) + { + + AFSDbgLogMsg( 0, + 0, + "EXCEPTION - AFSQuerySecurity\n"); + } + + return ntStatus; +} diff --git a/src/WINNT/afsrdr/kernel/fs/AFSShutdown.cpp b/src/WINNT/afsrdr/kernel/fs/AFSShutdown.cpp new file mode 100644 index 0000000000..4fb66bf781 --- /dev/null +++ b/src/WINNT/afsrdr/kernel/fs/AFSShutdown.cpp @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC. + * Copyright (c) 2009, 2010, 2011 Your File System, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, + * this list of conditions and the following disclaimer in the + * documentation + * and/or other materials provided with the distribution. + * - Neither the names of Kernel Drivers, LLC and Your File System, Inc. + * nor the names of their contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission from Kernel Drivers, LLC and Your File System, Inc. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +// +// File: AFSShutdown.cpp +// + +#include "AFSCommon.h" + +NTSTATUS +AFSShutdown( IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + + NTSTATUS ntStatus = STATUS_SUCCESS; + IO_STACK_LOCATION *pIrpSp; + UNICODE_STRING uniValueName; + ULONG ulValue = 0; + + __try + { + + pIrpSp = IoGetCurrentIrpStackLocation( Irp); + + if( BooleanFlagOn( AFSDebugFlags, AFS_DBG_REQUIRE_CLEAN_SHUTDOWN)) + { + + ulValue = 1; + + RtlInitUnicodeString( &uniValueName, + AFS_REG_SHUTDOWN_STATUS); + + AFSUpdateRegistryParameter( &uniValueName, + REG_DWORD, + &ulValue, + sizeof( ULONG)); + } + + ntStatus = AFSShutdownFilesystem(); + + if( !NT_SUCCESS( ntStatus)) + { + + ntStatus = STATUS_SUCCESS; + } + + AFSCompleteRequest( Irp, + ntStatus); + } + __except( AFSExceptionFilter( GetExceptionCode(), GetExceptionInformation()) ) + { + + AFSDbgLogMsg( 0, + 0, + "EXCEPTION - AFSShutdown\n"); + } + + return ntStatus; +} + +NTSTATUS +AFSShutdownFilesystem() +{ + + NTSTATUS ntStatus = STATUS_SUCCESS; + + + return ntStatus; +} diff --git a/src/WINNT/afsrdr/kernel/fs/AFSSystemControl.cpp b/src/WINNT/afsrdr/kernel/fs/AFSSystemControl.cpp new file mode 100644 index 0000000000..b80c2adc12 --- /dev/null +++ b/src/WINNT/afsrdr/kernel/fs/AFSSystemControl.cpp @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC. + * Copyright (c) 2009, 2010, 2011 Your File System, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, + * this list of conditions and the following disclaimer in the + * documentation + * and/or other materials provided with the distribution. + * - Neither the names of Kernel Drivers, LLC and Your File System, Inc. + * nor the names of their contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission from Kernel Drivers, LLC and Your File System, Inc. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +// +// File: AFSSystemControl.cpp +// + +#include "AFSCommon.h" + +NTSTATUS +AFSSystemControl( IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + + NTSTATUS ntStatus = STATUS_NOT_IMPLEMENTED; + IO_STACK_LOCATION *pIrpSp; + + pIrpSp = IoGetCurrentIrpStackLocation( Irp); + + __try + { + + AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING, + AFS_TRACE_LEVEL_WARNING, + "AFSSystemControl Entry for FO %08lX\n", + pIrpSp->FileObject); + + AFSCompleteRequest( Irp, + ntStatus); + + } + __except( AFSExceptionFilter( GetExceptionCode(), GetExceptionInformation()) ) + { + + AFSDbgLogMsg( 0, + 0, + "EXCEPTION - AFSSystemControl\n"); + } + + return ntStatus; +} diff --git a/src/WINNT/afsrdr/kernel/fs/AFSVolumeInfo.cpp b/src/WINNT/afsrdr/kernel/fs/AFSVolumeInfo.cpp new file mode 100644 index 0000000000..9abf890ce2 --- /dev/null +++ b/src/WINNT/afsrdr/kernel/fs/AFSVolumeInfo.cpp @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC. + * Copyright (c) 2009, 2010, 2011 Your File System, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, + * this list of conditions and the following disclaimer in the + * documentation + * and/or other materials provided with the distribution. + * - Neither the names of Kernel Drivers, LLC and Your File System, Inc. + * nor the names of their contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission from Kernel Drivers, LLC and Your File System, Inc. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +// +// File: AFSVolumeInfo.cpp +// + +#include "AFSCommon.h" + +NTSTATUS +AFSQueryVolumeInfo( IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + + NTSTATUS ntStatus = STATUS_SUCCESS; + AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)DeviceObject->DeviceExtension; + IO_STACK_LOCATION *pIrpSp; + AFSDeviceExt *pControlDeviceExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension; + + pIrpSp = IoGetCurrentIrpStackLocation( Irp); + + __try + { + + if( DeviceObject == AFSDeviceObject) + { + + ntStatus = STATUS_INVALID_DEVICE_REQUEST; + + AFSCompleteRequest( Irp, + ntStatus); + + try_return( ntStatus); + } + + // + // Check the state of the library + // + + ntStatus = AFSCheckLibraryState( Irp); + + if( !NT_SUCCESS( ntStatus) || + ntStatus == STATUS_PENDING) + { + + if( ntStatus != STATUS_PENDING) + { + AFSCompleteRequest( Irp, ntStatus); + } + + try_return( ntStatus); + } + + IoSkipCurrentIrpStackLocation( Irp); + + ntStatus = IoCallDriver( pControlDeviceExt->Specific.Control.LibraryDeviceObject, + Irp); + + // + // Indicate the library is done with the request + // + + AFSClearLibraryRequest(); + +try_exit: + + NOTHING; + } + __except( AFSExceptionFilter( GetExceptionCode(), GetExceptionInformation()) ) + { + + AFSDbgLogMsg( 0, + 0, + "EXCEPTION - AFSQueryVolumeInfo\n"); + } + + return ntStatus; +} + +NTSTATUS +AFSSetVolumeInfo( IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + + NTSTATUS ntStatus = STATUS_INVALID_DEVICE_REQUEST; + IO_STACK_LOCATION *pIrpSp; + + pIrpSp = IoGetCurrentIrpStackLocation( Irp); + + __try + { + + AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING, + AFS_TRACE_LEVEL_WARNING, + "AFSSetVolumeInfo Entry for FO %08lX\n", pIrpSp->FileObject); + + AFSCompleteRequest( Irp, + ntStatus); + + } + __except( AFSExceptionFilter( GetExceptionCode(), GetExceptionInformation()) ) + { + + AFSDbgLogMsg( 0, + 0, + "EXCEPTION - AFSSetVolumeInfo\n"); + } + + return ntStatus; +} diff --git a/src/WINNT/afsrdr/kernel/fs/AFSWrite.cpp b/src/WINNT/afsrdr/kernel/fs/AFSWrite.cpp new file mode 100644 index 0000000000..d2cfeadb92 --- /dev/null +++ b/src/WINNT/afsrdr/kernel/fs/AFSWrite.cpp @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC. + * Copyright (c) 2009, 2010, 2011 Your File System, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, + * this list of conditions and the following disclaimer in the + * documentation + * and/or other materials provided with the distribution. + * - Neither the names of Kernel Drivers, LLC and Your File System, Inc. + * nor the names of their contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission from Kernel Drivers, LLC and Your File System, Inc. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +// +// File: AFSWrite.cpp +// + +#include "AFSCommon.h" + +// +// Function: AFSWrite +// +// Description: +// +// This is the dispatch handler for the IRP_MJ_WRITE request +// +// Return: +// +// A status is returned for the function +// + +NTSTATUS +AFSWrite( IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp) +{ + + NTSTATUS ntStatus = STATUS_SUCCESS; + AFSDeviceExt *pControlDeviceExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension; + + __try + { + + if( DeviceObject == AFSDeviceObject) + { + + ntStatus = STATUS_INVALID_DEVICE_REQUEST; + + AFSCompleteRequest( Irp, + ntStatus); + + try_return( ntStatus); + } + + // + // Check the state of the library + // + + ntStatus = AFSCheckLibraryState( Irp); + + if( !NT_SUCCESS( ntStatus) || + ntStatus == STATUS_PENDING) + { + + if( ntStatus != STATUS_PENDING) + { + AFSCompleteRequest( Irp, ntStatus); + } + + try_return( ntStatus); + } + + IoSkipCurrentIrpStackLocation( Irp); + + ntStatus = IoCallDriver( pControlDeviceExt->Specific.Control.LibraryDeviceObject, + Irp); + + // + // Indicate the library is done with the request + // + + AFSClearLibraryRequest(); + +try_exit: + + NOTHING; + } + __except( AFSExceptionFilter( GetExceptionCode(), GetExceptionInformation()) ) + { + + ntStatus = STATUS_INSUFFICIENT_RESOURCES; + } + + return ntStatus; +} diff --git a/src/WINNT/afsrdr/kernel/fs/Filesystem.rc b/src/WINNT/afsrdr/kernel/fs/Filesystem.rc new file mode 100644 index 0000000000..8c00a71bd2 --- /dev/null +++ b/src/WINNT/afsrdr/kernel/fs/Filesystem.rc @@ -0,0 +1,15 @@ +/* + * Copyright 2010, Secure Endpoints Inc. + * All Rights Reserved. + * + * This software has been released under the terms of the MIT License. + */ + +/* Define VERSIONINFO resource */ + +#define AFS_VERINFO_FILE_DESCRIPTION "AFS Redirector File System" +#define AFS_VERINFO_NAME "AFSRedir" +#define AFS_VERINFO_FILENAME "AFSRedir.sys" + +#include "..\..\AFS_component_version_number.h" +#include "..\..\..\..\config\NTVersioninfo.rc" diff --git a/src/WINNT/afsrdr/kernel/fs/Include/AFSCommon.h b/src/WINNT/afsrdr/kernel/fs/Include/AFSCommon.h new file mode 100644 index 0000000000..6ab3472a99 --- /dev/null +++ b/src/WINNT/afsrdr/kernel/fs/Include/AFSCommon.h @@ -0,0 +1,809 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC. + * Copyright (c) 2009, 2010, 2011 Your File System, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, + * this list of conditions and the following disclaimer in the + * documentation + * and/or other materials provided with the distribution. + * - Neither the names of Kernel Drivers, LLC and Your File System, Inc. + * nor the names of their contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission from Kernel Drivers, LLC and Your File System, Inc. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _AFS_COMMON_H +#define _AFS_COMMON_H + +// +// File: AFSCommon.h +// + +extern "C" +{ + +#define AFS_KERNEL_MODE + +#include +#include // for IoCreateDeviceSecure +#include + +#include "AFSDefines.h" + +#include "AFSUserDefines.h" + +#include "AFSUserIoctl.h" + +#include "AFSUserStructs.h" + +#include "AFSRedirCommonDefines.h" + +#include "AFSRedirCommonStructs.h" + +#include "AFSStructs.h" + +#include "AFSProvider.h" + +#ifndef NO_EXTERN +#include "AFSExtern.h" +#endif + +#define NTSTRSAFE_LIB +#include "ntstrsafe.h" + +NTSTATUS +ZwQueryInformationProcess( + __in HANDLE ProcessHandle, + __in PROCESSINFOCLASS ProcessInformationClass, + __out PVOID ProcessInformation, + __in ULONG ProcessInformationLength, + __out_opt PULONG ReturnLength +); + +// +// AFSInit.cpp Prototypes +// + +NTSTATUS +DriverEntry( IN PDRIVER_OBJECT DriverObj, + IN PUNICODE_STRING RegPath); + +void +AFSUnload( IN PDRIVER_OBJECT DriverObject); + +// +// AFSAuthGroupSupport.cpp +// + +void +AFSRetrieveAuthGroup( IN ULONGLONG ProcessId, + IN ULONGLONG ThreadId, + OUT GUID *AuthGroup); + +BOOLEAN +AFSIsLocalSystemAuthGroup( IN GUID *AuthGroup); + +BOOLEAN +AFSIsLocalSystemSID( IN UNICODE_STRING *SIDString); + +BOOLEAN +AFSIsNoPAGAuthGroup( IN GUID *AuthGroup); + +NTSTATUS +AFSCreateSetProcessAuthGroup( AFSAuthGroupRequestCB *CreateSetAuthGroup); + +NTSTATUS +AFSQueryProcessAuthGroupList( IN GUID *GUIDList, + IN ULONG BufferLength, + OUT ULONG_PTR *ReturnLength); + +NTSTATUS +AFSSetActiveProcessAuthGroup( IN AFSAuthGroupRequestCB *ActiveAuthGroup); + +NTSTATUS +AFSResetActiveProcessAuthGroup( IN AFSAuthGroupRequestCB *ActiveAuthGroup); + +NTSTATUS +AFSCreateAuthGroupForSIDorLogonSession( IN AFSAuthGroupRequestCB *AuthGroupRequestCB, + IN BOOLEAN bLogonSession); + +NTSTATUS +AFSQueryAuthGroup( IN AFSAuthGroupRequestCB *AuthGroupRequestCB, + OUT GUID *AuthGroupGUID, + OUT ULONG_PTR *ReturnLength); + +// +// AFSBTreeSupport.cpp Prototypes +// + +NTSTATUS +AFSLocateHashEntry( IN AFSBTreeEntry *TopNode, + IN ULONGLONG HashIndex, + IN OUT AFSBTreeEntry **TreeEntry); + +NTSTATUS +AFSInsertHashEntry( IN AFSBTreeEntry *TopNode, + IN AFSBTreeEntry *FileIDEntry); + +NTSTATUS +AFSRemoveHashEntry( IN AFSBTreeEntry **TopNode, + IN AFSBTreeEntry *FileIDEntry); + +// +// AFSCommSupport.cpp Prototypes +// + +NTSTATUS +AFSReleaseFid( IN AFSFileID *FileId); + +NTSTATUS +AFSProcessRequest( IN ULONG RequestType, + IN ULONG RequestFlags, + IN GUID *AuthGroup, + IN PUNICODE_STRING FileName, + IN AFSFileID *FileId, + IN void *Data, + IN ULONG DataLength, + IN OUT void *ResultBuffer, + IN OUT PULONG ResultBufferLength); + +NTSTATUS +AFSProcessControlRequest( IN PIRP Irp); + +NTSTATUS +AFSInitIrpPool( void); + +void +AFSCleanupIrpPool( void); + +NTSTATUS +AFSProcessIrpRequest( IN PIRP Irp); + +NTSTATUS +AFSProcessIrpResult( IN PIRP Irp); + +NTSTATUS +AFSInsertRequest( IN AFSCommSrvcCB *CommSrvc, + IN AFSPoolEntry *Entry); + +// +// AFSCreate.cpp Prototypes +// + +NTSTATUS +AFSCreate( IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp); + +NTSTATUS +AFSCommonCreate( IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp); + +NTSTATUS +AFSControlDeviceCreate( IN PIRP Irp); + +NTSTATUS +AFSOpenRedirector( IN PIRP Irp); + +// +// AFSClose.cpp Prototypes +// + +NTSTATUS +AFSClose( IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp); + +NTSTATUS +AFSCommonClose( IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp); + +// +// AFSNetworkProviderSupport.cpp +// + +NTSTATUS +AFSAddConnectionEx( IN UNICODE_STRING *RemoteName, + IN ULONG DisplayType, + IN ULONG Flags); + +void +AFSInitializeConnectionInfo( IN AFSProviderConnectionCB *Connection, + IN ULONG DisplayType); + +// +// AFSRead.cpp Prototypes +// + +NTSTATUS +AFSRead( IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp); + +// +// AFSWrite.cpp Prototypes +// + +NTSTATUS +AFSWrite( IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp); + +// +// AFSFileInfo.cpp Prototypes +// + +NTSTATUS +AFSQueryFileInfo( IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp); + +NTSTATUS +AFSSetFileInfo( IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp); + +// +// AFSEa.cpp Prototypes +// + +NTSTATUS +AFSQueryEA( IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp); + +NTSTATUS +AFSSetEA( IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp); + +// +// AFSFlushBuffers.cpp Prototypes +// + +NTSTATUS +AFSFlushBuffers( IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp); + +// +// AFSVolumeInfo.cpp Prototypes +// + +NTSTATUS +AFSQueryVolumeInfo( IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp); + +NTSTATUS +AFSSetVolumeInfo( IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp); + +NTSTATUS +AFSSetVolumeInfo( IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp); + +// +// AFSDirControl.cpp Prototypes +// + +NTSTATUS +AFSDirControl( IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp); + +// +// AFSFSControl.cpp Prototypes +// + +NTSTATUS +AFSFSControl( IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp); + +// +// AFSDevControl.cpp Prototypes +// + +NTSTATUS +AFSDevControl( IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp); + +// +// AFSInternalDevControl.cpp Prototypes +// + +NTSTATUS +AFSInternalDevControl( IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp); + +// +// AFSShutdown.cpp Prototypes +// + +NTSTATUS +AFSShutdown( IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp); + + +NTSTATUS +AFSShutdownFilesystem( void); + +// +// AFSLockControl.cpp Prototypes +// + +NTSTATUS +AFSLockControl( IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp); + +// +// AFSCleanup.cpp Prototypes +// + +NTSTATUS +AFSCleanup( IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp); + +NTSTATUS +AFSCommonCleanup( IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp); + +// +// AFSSecurity.cpp Prototypes +// + +NTSTATUS +AFSQuerySecurity( IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp); + +NTSTATUS +AFSSetSecurity( IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp); + +// +// AFSSystemControl.cpp Prototypes +// + +NTSTATUS +AFSSystemControl( IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp); + +// +// AFSQuota.cpp Prototypes +// + +NTSTATUS +AFSQueryQuota( IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp); + +NTSTATUS +AFSSetQuota( IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp); + +// +// AFSGeneric.cpp Prototypes +// + +ULONG +AFSExceptionFilter( IN ULONG Code, + IN PEXCEPTION_POINTERS ExceptPtrs); + +BOOLEAN +AFSAcquireExcl( IN PERESOURCE Resource, + IN BOOLEAN wait); + +BOOLEAN +AFSAcquireSharedStarveExclusive( IN PERESOURCE Resource, + IN BOOLEAN Wait); + +BOOLEAN +AFSAcquireShared( IN PERESOURCE Resource, + IN BOOLEAN wait); + +void +AFSReleaseResource( IN PERESOURCE Resource); + +void +AFSConvertToShared( IN PERESOURCE Resource); + +void +AFSCompleteRequest( IN PIRP Irp, + IN ULONG Status); + +NTSTATUS +AFSReadRegistry( IN PUNICODE_STRING RegistryPath); + +NTSTATUS +AFSUpdateRegistryParameter( IN PUNICODE_STRING ValueName, + IN ULONG ValueType, + IN void *ValueData, + IN ULONG ValueDataLength); + +NTSTATUS +AFSInitializeControlDevice( void); + +NTSTATUS +AFSRemoveControlDevice( void); + +NTSTATUS +AFSDefaultDispatch( IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp); + +NTSTATUS +AFSIrpComplete( IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp, + IN PVOID Context); + +void +AFSInitServerStrings( void); + +NTSTATUS +AFSReadServerName( void); + +NTSTATUS +AFSSetSysNameInformation( IN AFSSysNameNotificationCB *SysNameInfo, + IN ULONG SysNameInfoBufferLength); + +void +AFSResetSysNameList( IN AFSSysNameCB *SysNameList); + +NTSTATUS +AFSSendDeviceIoControl( IN DEVICE_OBJECT *TargetDeviceObject, + IN ULONG IOControl, + IN void *InputBuffer, + IN ULONG InputBufferLength, + IN OUT void *OutputBuffer, + IN ULONG OutputBufferLength, + OUT ULONG *ResultLength); + +void * +AFSExAllocatePoolWithTag( IN POOL_TYPE PoolType, + IN SIZE_T NumberOfBytes, + IN ULONG Tag); + +void +AFSExFreePool( IN void *Buffer); + +NTSTATUS +AFSShutdownRedirector( void); + +BOOLEAN +AFSAcquireFcbForLazyWrite( IN PVOID Fcb, + IN BOOLEAN Wait); + +VOID +AFSReleaseFcbFromLazyWrite( IN PVOID Fcb); + +BOOLEAN +AFSAcquireFcbForReadAhead( IN PVOID Fcb, + IN BOOLEAN Wait); + +VOID +AFSReleaseFcbFromReadAhead( IN PVOID Fcb); + +NTSTATUS +AFSGetCallerSID( OUT UNICODE_STRING *SIDString, + OUT BOOLEAN *pbImpersonation); + +ULONG +AFSGetSessionId( IN HANDLE ProcessId, + OUT BOOLEAN *pbImpersonation); + +NTSTATUS +AFSCheckThreadDacl( OUT GUID *AuthGroup); + +NTSTATUS +AFSProcessSetProcessDacl( IN AFSProcessCB *ProcessCB); + +// +// Prototypes in AFSFastIoSupprt.cpp +// + +BOOLEAN +AFSFastIoCheckIfPossible( IN struct _FILE_OBJECT *FileObject, + IN PLARGE_INTEGER FileOffset, + IN ULONG Length, + IN BOOLEAN Wait, + IN ULONG LockKey, + IN BOOLEAN CheckForReadOperation, + OUT PIO_STATUS_BLOCK IoStatus, + IN struct _DEVICE_OBJECT *DeviceObject); + +BOOLEAN +AFSFastIoRead( IN struct _FILE_OBJECT *FileObject, + IN PLARGE_INTEGER FileOffset, + IN ULONG Length, + IN BOOLEAN Wait, + IN ULONG LockKey, + OUT PVOID Buffer, + OUT PIO_STATUS_BLOCK IoStatus, + IN struct _DEVICE_OBJECT *DeviceObject); + +BOOLEAN +AFSFastIoWrite( IN struct _FILE_OBJECT *FileObject, + IN PLARGE_INTEGER FileOffset, + IN ULONG Length, + IN BOOLEAN Wait, + IN ULONG LockKey, + IN PVOID Buffer, + OUT PIO_STATUS_BLOCK IoStatus, + IN struct _DEVICE_OBJECT *DeviceObject); + +BOOLEAN +AFSFastIoQueryBasicInfo( IN struct _FILE_OBJECT *FileObject, + IN BOOLEAN Wait, + OUT PFILE_BASIC_INFORMATION Buffer, + OUT PIO_STATUS_BLOCK IoStatus, + IN struct _DEVICE_OBJECT *DeviceObject); + +BOOLEAN +AFSFastIoQueryStandardInfo( IN struct _FILE_OBJECT *FileObject, + IN BOOLEAN Wait, + OUT PFILE_STANDARD_INFORMATION Buffer, + OUT PIO_STATUS_BLOCK IoStatus, + IN struct _DEVICE_OBJECT *DeviceObject); + +BOOLEAN +AFSFastIoLock( IN struct _FILE_OBJECT *FileObject, + IN PLARGE_INTEGER FileOffset, + IN PLARGE_INTEGER Length, + IN PEPROCESS ProcessId, + IN ULONG Key, + IN BOOLEAN FailImmediately, + IN BOOLEAN ExclusiveLock, + OUT PIO_STATUS_BLOCK IoStatus, + IN struct _DEVICE_OBJECT *DeviceObject); + +BOOLEAN +AFSFastIoUnlockSingle( IN struct _FILE_OBJECT *FileObject, + IN PLARGE_INTEGER FileOffset, + IN PLARGE_INTEGER Length, + IN PEPROCESS ProcessId, + IN ULONG Key, + OUT PIO_STATUS_BLOCK IoStatus, + IN struct _DEVICE_OBJECT *DeviceObject); + +BOOLEAN +AFSFastIoUnlockAll( IN struct _FILE_OBJECT *FileObject, + IN PEPROCESS ProcessId, + OUT PIO_STATUS_BLOCK IoStatus, + IN struct _DEVICE_OBJECT *DeviceObject); + +BOOLEAN +AFSFastIoUnlockAllByKey( IN struct _FILE_OBJECT *FileObject, + IN PVOID ProcessId, + IN ULONG Key, + OUT PIO_STATUS_BLOCK IoStatus, + IN struct _DEVICE_OBJECT *DeviceObject); + +BOOLEAN +AFSFastIoDevCtrl( IN struct _FILE_OBJECT *FileObject, + IN BOOLEAN Wait, + IN PVOID InputBuffer OPTIONAL, + IN ULONG InputBufferLength, + OUT PVOID OutputBuffer OPTIONAL, + IN ULONG OutputBufferLength, + IN ULONG IoControlCode, + OUT PIO_STATUS_BLOCK IoStatus, + IN struct _DEVICE_OBJECT *DeviceObject); + +VOID +AFSFastIoAcquireFile( IN struct _FILE_OBJECT *FileObject); + +VOID +AFSFastIoReleaseFile( IN struct _FILE_OBJECT *FileObject); + +VOID +AFSFastIoDetachDevice( IN struct _DEVICE_OBJECT *SourceDevice, + IN struct _DEVICE_OBJECT *TargetDevice); + +BOOLEAN +AFSFastIoQueryNetworkOpenInfo( IN struct _FILE_OBJECT *FileObject, + IN BOOLEAN Wait, + OUT struct _FILE_NETWORK_OPEN_INFORMATION *Buffer, + OUT struct _IO_STATUS_BLOCK *IoStatus, + IN struct _DEVICE_OBJECT *DeviceObject); + +BOOLEAN +AFSFastIoMdlRead( IN struct _FILE_OBJECT *FileObject, + IN PLARGE_INTEGER FileOffset, + IN ULONG Length, + IN ULONG LockKey, + OUT PMDL *MdlChain, + OUT PIO_STATUS_BLOCK IoStatus, + IN struct _DEVICE_OBJECT *DeviceObject); + +BOOLEAN +AFSFastIoMdlReadComplete( IN struct _FILE_OBJECT *FileObject, + IN PMDL MdlChain, + IN struct _DEVICE_OBJECT *DeviceObject); + +BOOLEAN +AFSFastIoPrepareMdlWrite( IN struct _FILE_OBJECT *FileObject, + IN PLARGE_INTEGER FileOffset, + IN ULONG Length, + IN ULONG LockKey, + OUT PMDL *MdlChain, + OUT PIO_STATUS_BLOCK IoStatus, + IN struct _DEVICE_OBJECT *DeviceObject); + +BOOLEAN +AFSFastIoMdlWriteComplete( IN struct _FILE_OBJECT *FileObject, + IN PLARGE_INTEGER FileOffset, + IN PMDL MdlChain, + IN struct _DEVICE_OBJECT *DeviceObject); + +NTSTATUS +AFSFastIoAcquireForModWrite( IN struct _FILE_OBJECT *FileObject, + IN PLARGE_INTEGER EndingOffset, + OUT struct _ERESOURCE **ResourceToRelease, + IN struct _DEVICE_OBJECT *DeviceObject); + +NTSTATUS +AFSFastIoReleaseForModWrite( IN struct _FILE_OBJECT *FileObject, + IN struct _ERESOURCE *ResourceToRelease, + IN struct _DEVICE_OBJECT *DeviceObject); + +NTSTATUS +AFSFastIoAcquireForCCFlush( IN struct _FILE_OBJECT *FileObject, + IN struct _DEVICE_OBJECT *DeviceObject); + +NTSTATUS +AFSFastIoReleaseForCCFlush( IN struct _FILE_OBJECT *FileObject, + IN struct _DEVICE_OBJECT *DeviceObject); + +BOOLEAN +AFSFastIoReadCompressed( IN struct _FILE_OBJECT *FileObject, + IN PLARGE_INTEGER FileOffset, + IN ULONG Length, + IN ULONG LockKey, + OUT PVOID Buffer, + OUT PMDL *MdlChain, + OUT PIO_STATUS_BLOCK IoStatus, + OUT struct _COMPRESSED_DATA_INFO *CompressedDataInfo, + IN ULONG CompressedDataInfoLength, + IN struct _DEVICE_OBJECT *DeviceObject); + +BOOLEAN +AFSFastIoWriteCompressed( IN struct _FILE_OBJECT *FileObject, + IN PLARGE_INTEGER FileOffset, + IN ULONG Length, + IN ULONG LockKey, + IN PVOID Buffer, + OUT PMDL *MdlChain, + OUT PIO_STATUS_BLOCK IoStatus, + IN struct _COMPRESSED_DATA_INFO *CompressedDataInfo, + IN ULONG CompressedDataInfoLength, + IN struct _DEVICE_OBJECT *DeviceObject); + +BOOLEAN +AFSFastIoMdlReadCompleteCompressed( IN struct _FILE_OBJECT *FileObject, + IN PMDL MdlChain, + IN struct _DEVICE_OBJECT *DeviceObject); + +BOOLEAN +AFSFastIoMdlWriteCompleteCompressed( IN struct _FILE_OBJECT *FileObject, + IN PLARGE_INTEGER FileOffset, + IN PMDL MdlChain, + IN struct _DEVICE_OBJECT *DeviceObject); + +BOOLEAN +AFSFastIoQueryOpen( IN struct _IRP *Irp, + OUT PFILE_NETWORK_OPEN_INFORMATION NetworkInformation, + IN struct _DEVICE_OBJECT *DeviceObject); + +// +// AFSLibrarySupport.cpp Prototypes +// + +NTSTATUS +AFSLoadLibrary( IN ULONG Flags, + IN UNICODE_STRING *ServicePath); + +NTSTATUS +AFSUnloadLibrary( IN BOOLEAN CancelQueue); + +NTSTATUS +AFSCheckLibraryState( IN PIRP Irp); + +NTSTATUS +AFSClearLibraryRequest( void); + +NTSTATUS +AFSQueueLibraryRequest( IN PIRP Irp); + +NTSTATUS +AFSProcessQueuedResults( IN BOOLEAN CancelRequest); + +NTSTATUS +AFSSubmitLibraryRequest( IN PIRP Irp); + +NTSTATUS +AFSInitializeLibrary( IN AFSFileID *GlobalRootFid, + IN BOOLEAN QueueRootEnumeration); + +// +// AFSRDRSupport.cpp Prototypes +// + +NTSTATUS +AFSInitRDRDevice( void); + +NTSTATUS +AFSRDRDeviceControl( IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp); + +NTSTATUS +AFSInitializeRedirector( IN AFSRedirectorInitInfo *CacheFileInfo); + +NTSTATUS +AFSCloseRedirector( void); + +// +// AFSLogSupport.cpp +// + +NTSTATUS +AFSDbgLogMsg( IN ULONG Subsystem, + IN ULONG Level, + IN PCCH Format, + ...); + +NTSTATUS +AFSInitializeDbgLog( void); + +NTSTATUS +AFSTearDownDbgLog( void); + +NTSTATUS +AFSConfigureTrace( IN AFSTraceConfigCB *TraceInfo); + +NTSTATUS +AFSGetTraceBuffer( IN ULONG TraceBufferLength, + OUT void *TraceBuffer, + OUT ULONG_PTR *CopiedLength); + +void +AFSTagInitialLogEntry( void); + +void +AFSDumpTraceFiles( void); + +NTSTATUS +AFSInitializeDumpFile( void); + +// +// AFSProcessSupport.cpp Prototypes +// + +void +AFSProcessNotify( IN HANDLE ParentId, + IN HANDLE ProcessId, + IN BOOLEAN Create); + +GUID * +AFSValidateProcessEntry( void); + +BOOLEAN +AFSIs64BitProcess( IN ULONGLONG ProcessId); + +AFSProcessCB * +AFSInitializeProcessCB( IN ULONGLONG ParentProcessId, + IN ULONGLONG ProcessId); + +AFSThreadCB * +AFSInitializeThreadCB( IN AFSProcessCB *ProcessCB, + IN ULONGLONG ThreadId); + +}; + +#endif /* _AFS_COMMON_H */ diff --git a/src/WINNT/afsrdr/kernel/fs/Include/AFSDefines.h b/src/WINNT/afsrdr/kernel/fs/Include/AFSDefines.h new file mode 100644 index 0000000000..88851b4e7a --- /dev/null +++ b/src/WINNT/afsrdr/kernel/fs/Include/AFSDefines.h @@ -0,0 +1,348 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC. + * Copyright (c) 2009, 2010, 2011 Your File System, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, + * this list of conditions and the following disclaimer in the + * documentation + * and/or other materials provided with the distribution. + * - Neither the names of Kernel Drivers, LLC and Your File System, Inc. + * nor the names of their contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission from Kernel Drivers, LLC and Your File System, Inc. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _AFS_DEFINES_H +#define _AFS_DEFINES_H +// +// File: AFSDefines.h +// + +// +// Registry names +// + +#define AFS_REG_DEBUG_FLAGS L"DebugFlags" +#define AFS_REG_TRACE_LEVEL L"TraceLevel" +#define AFS_REG_TRACE_SUBSYSTEM L"TraceSubsystem" +#define AFS_REG_TRACE_BUFFER_LENGTH L"TraceBufferSize" // in KB +#define AFS_REG_MAX_DIRTY L"MaxDirtyMb" +#define AFS_REG_MAX_IO L"MaxIOMb" +#define AFS_NETBIOS_NAME L"NetbiosName" +#define AFS_REG_SHUTDOWN_STATUS L"ShutdownStatus" +#define AFS_REG_REQUIRE_CLEAN_SHUTDOWN L"RequireCleanShutdown" + +// +// Control Device name +// + +#define AFS_CONTROL_DEVICE_NAME L"\\Device\\AFSControlDevice" +#define AFS_SYMLINK_NAME L"\\??\\AFSRedirector" + +// +// How big to make the runs +// +#define AFS_MAX_STACK_IO_RUNS 5 + +#ifndef FlagOn +#define FlagOn(_F,_SF) ((_F) & (_SF)) +#endif + +#ifndef BooleanFlagOn +#define BooleanFlagOn(F,SF) ((BOOLEAN)(((F) & (SF)) != 0)) +#endif + +#ifndef SetFlag +#define SetFlag(_F,_SF) ((_F) |= (_SF)) +#endif + +#ifndef ClearFlag +#define ClearFlag(_F,_SF) ((_F) &= ~(_SF)) +#endif + +#define QuadAlign(Ptr) ( \ + ((((ULONG)(Ptr)) + 7) & 0xfffffff8) \ + ) + +#define CRC32_POLYNOMIAL 0xEDB88320L; + +// +// Define one second in terms of 100 nS units +// + +#define AFS_ONE_SECOND 10000000 + +#define AFS_SERVER_FLUSH_DELAY 30 +#define AFS_SERVER_PURGE_DELAY 60 +// +// PURGE_SLEEP is the number of PURGE_DELAYS we wait before we will unilaterally +// give back extents. +// +// If the Service asks us, we will start at PURGE_SLEEP of delays and then work back +// +#define AFS_SERVER_PURGE_SLEEP 6 + +// +// Read ahead granularity +// + +#define READ_AHEAD_GRANULARITY 0x10000 // 64KB + +#define AFS_DIR_ENUM_BUFFER_LEN (16 * 1024) + +// +// IS_BYTE_OFFSET_WRITE_TO_EOF +// liOffset - should be from Irp.StackLocation.Parameters.Write.ByteOffset +// this macro checks to see if the Offset Large_Integer points to the +// special constant value which denotes to start the write at EndOfFile +// +#define IS_BYTE_OFFSET_WRITE_TO_EOF(liOffset) \ + (((liOffset).LowPart == FILE_WRITE_TO_END_OF_FILE) \ + && ((liOffset).HighPart == 0xFFFFFFFF)) + +// +// Ccb Directory enum flags +// + +#define CCB_FLAG_DIR_OF_DIRS_ONLY 0x00000001 +#define CCB_FLAG_FULL_DIRECTORY_QUERY 0x00000002 +#define CCB_FLAG_MASK_CONTAINS_WILD_CARDS 0x00000004 +#define CCB_FLAG_FREE_FULL_PATHNAME 0x00000008 +#define CCB_FLAG_RETURN_RELATIVE_ENTRIES 0x00000010 +#define CCB_FLAGS_DIRECTORY_QUERY_MAPPED 0x00000020 + +// +// DirEntry flags +// + +#define AFS_DIR_RELEASE_NAME_BUFFER 0x00000001 +#define AFS_DIR_ENTRY_CASE_INSENSTIVE_LIST_HEAD 0x00000004 +#define AFS_DIR_ENTRY_NOT_IN_PARENT_TREE 0x00000008 +// Use this entry +#define AFS_DIR_ENTRY_FAKE 0x00000020 +#define AFS_DIR_RELEASE_TARGET_NAME_BUFFER 0x00000040 +#define AFS_DIR_ENTRY_VALID 0x00000080 +#define AFS_DIR_ENTRY_PENDING_DELETE 0x00000100 +#define AFS_DIR_ENTRY_DELETED 0x00000200 +#define AFS_DIR_ENTRY_SERVER_SERVICE 0x00000400 +#define AFS_DIR_ENTRY_WORKSTATION_SERVICE 0x00000800 +#define AFS_DIR_ENTRY_IPC 0x00001000 + +// +// Network provider errors +// + +#define WN_SUCCESS 0L +#define WN_ALREADY_CONNECTED 85L +#define WN_OUT_OF_MEMORY 8L +#define WN_NOT_CONNECTED 2250L +#define WN_BAD_NETNAME 67L + +#define RESOURCE_CONNECTED 0x00000001 +#define RESOURCE_GLOBALNET 0x00000002 +#define RESOURCE_REMEMBERED 0x00000003 +#define RESOURCE_RECENT 0x00000004 +#define RESOURCE_CONTEXT 0x00000005 + +#define RESOURCETYPE_ANY 0x00000000 +#define RESOURCETYPE_DISK 0x00000001 +#define RESOURCETYPE_PRINT 0x00000002 +#define RESOURCETYPE_RESERVED 0x00000008 +#define RESOURCETYPE_UNKNOWN 0xFFFFFFFF + +#define RESOURCEUSAGE_CONNECTABLE 0x00000001 +#define RESOURCEUSAGE_CONTAINER 0x00000002 +#define RESOURCEUSAGE_NOLOCALDEVICE 0x00000004 +#define RESOURCEUSAGE_SIBLING 0x00000008 +#define RESOURCEUSAGE_ATTACHED 0x00000010 +#define RESOURCEUSAGE_ALL (RESOURCEUSAGE_CONNECTABLE | RESOURCEUSAGE_CONTAINER | RESOURCEUSAGE_ATTACHED) +#define RESOURCEUSAGE_RESERVED 0x80000000 + +#define RESOURCEDISPLAYTYPE_GENERIC 0x00000000 +#define RESOURCEDISPLAYTYPE_DOMAIN 0x00000001 +#define RESOURCEDISPLAYTYPE_SERVER 0x00000002 +#define RESOURCEDISPLAYTYPE_SHARE 0x00000003 +#define RESOURCEDISPLAYTYPE_FILE 0x00000004 +#define RESOURCEDISPLAYTYPE_GROUP 0x00000005 +#define RESOURCEDISPLAYTYPE_NETWORK 0x00000006 +#define RESOURCEDISPLAYTYPE_ROOT 0x00000007 +#define RESOURCEDISPLAYTYPE_SHAREADMIN 0x00000008 +#define RESOURCEDISPLAYTYPE_DIRECTORY 0x00000009 +#define RESOURCEDISPLAYTYPE_TREE 0x0000000A +#define RESOURCEDISPLAYTYPE_NDSCONTAINER 0x0000000B + +// +// Method for determining the different control device open requests +// + +#define AFS_CONTROL_INSTANCE 0x00000001 +#define AFS_REDIRECTOR_INSTANCE 0x00000002 + +// +// Extent flags +// + +#define AFS_EXTENT_DIRTY 0x00000001 + +// +// Extent skip list sizes +// +#define AFS_NUM_EXTENT_LISTS 3 + +// +// Extents skip lists +// +// We use constant sizes. +// +#define AFS_EXTENT_SIZE (4*1024) +#define AFS_EXTENTS_LIST 0 +// +// A max of 64 extents in ther first skip list +#define AFS_EXTENT_SKIP1_BITS 6 + +// +// Then 128 bits in the second skip list +#define AFS_EXTENT_SKIP2_BITS 7 + +// +// This means that the top list skips in steps of 2^25 (=12+6+7) which +// is 32 Mb. It is to be expected that files which are massively +// larger that this will not be fully mapped. +// +#define AFS_EXTENT_SKIP1_SIZE (AFS_EXTENT_SIZE << AFS_EXTENT_SKIP1_BITS) +#define AFS_EXTENT_SKIP2_SIZE (AFS_EXTENT_SKIP1_SIZE << AFS_EXTENT_SKIP2_BITS) + +#define AFS_EXTENTS_MASKS { (AFS_EXTENT_SIZE-1), \ + (AFS_EXTENT_SKIP1_SIZE-1), \ + (AFS_EXTENT_SKIP2_SIZE-1) } + +// +// Maximum count to release at a time +// + +#define AFS_MAXIMUM_EXTENT_RELEASE_COUNT 100 + +// {41966169-3FD7-4392-AFE4-E6A9D0A92C72} - generated using guidgen.exe +DEFINE_GUID (GUID_SD_AFS_REDIRECTOR_CONTROL_OBJECT, + 0x41966169, 0x3fd7, 0x4392, 0xaf, 0xe4, 0xe6, 0xa9, 0xd0, 0xa9, 0x2c, 0x72); + +// +// Debug log length +// + +#define AFS_DBG_LOG_LENGTH 256 + +// +// Debug log flags +// + +#define AFS_DBG_LOG_WRAPPED 0x00000001 + +// +// Connection flags +// + +#define AFS_CONNECTION_FLAG_GLOBAL_SHARE 0x00000001 + +// +// Process CB flags +// + +#define AFS_PROCESS_FLAG_IS_64BIT 0x00000001 +#define AFS_PROCESS_FLAG_ACE_SET 0x00000002 +#define AFS_PROCESS_LOCAL_SYSTEM_AUTH 0x00000004 + +// +// Auth group flags +// + +#define AFS_AUTHGROUP_ACTIVE_SESSION 0x00000001 + +// +// Maximum number of special share names +// + +#define AFS_SPECIAL_SHARE_NAME_COUNT_MAX 10 + +// +// Device flags +// + +#define AFS_DEVICE_FLAG_HIDE_DOT_NAMES 0x00000001 +#define AFS_DEVICE_FLAG_REDIRECTOR_SHUTDOWN 0x00000002 + +// +// Reparse tag information +// + +// +// Tag allocated to OpenAFS for DFS by Microsoft +// GUID: EF21A155-5C92-4470-AB3B-370403D96369 +// + +#ifndef IO_REPARSE_TAG_OPENAFS_DFS +#define IO_REPARSE_TAG_OPENAFS_DFS 0x00000037L +#endif + +// {EF21A155-5C92-4470-AB3B-370403D96369} +DEFINE_GUID (GUID_AFS_REPARSE_GUID, + 0xEF21A155, 0x5C92, 0x4470, 0xAB, 0x3B, 0x37, 0x04, 0x03, 0xD9, 0x63, 0x69); + +// +// Enumeration constants +// + +#define AFS_DIR_ENTRY_INITIAL_DIR_INDEX (ULONG)-3 +#define AFS_DIR_ENTRY_INITIAL_ROOT_INDEX (ULONG)-1 + +#define AFS_DIR_ENTRY_DOT_INDEX (ULONG)-2 +#define AFS_DIR_ENTRY_DOT_DOT_INDEX (ULONG)-1 + +// +// Library flags +// + +#define AFS_LIBRARY_LOADED 0x00000001 +#define AFS_LIBRARY_QUEUE_CANCELLED 0x00000002 + +// +// Custom ACE Information +// + +// {7E5D0E2F-7500-45df-857A-C0C8A2CC6BE8} +static const GUID AFSSidGuid = { 0x7f5d0e2f, 0x7500, 0x45df, { 0x85, 0x7a, 0xc0, 0xc8, 0xa2, 0xcc, 0x6b, 0xe8 } }; + +// size of our special DACL SID... S-1-8-GuidDword1-GuidDword2-GuidDword3-GuidDword4-AuthGroupGUIDDword1-AuthGroupGUIDDword2-AuthGroupGUIDDword3-AuthGroupGUIDDword4 +// Revision (1) + SubAuthorityCount (1) + IdentifierAuthority (6) + GUID (16) + AuthGruopGUID( 16) +#define AFS_DACL_SID_LENGTH 40 + +typedef +NTSTATUS +(*PAFSSetInformationToken) ( + __in HANDLE TokenHandle, + __in TOKEN_INFORMATION_CLASS TokenInformationClass, + __in_bcount(TokenInformationLength) PVOID TokenInformation, + __in ULONG TokenInformationLength + ); + +#endif /* _AFS_DEFINES_H */ diff --git a/src/WINNT/afsrdr/kernel/fs/Include/AFSExtern.h b/src/WINNT/afsrdr/kernel/fs/Include/AFSExtern.h new file mode 100644 index 0000000000..9197d584dc --- /dev/null +++ b/src/WINNT/afsrdr/kernel/fs/Include/AFSExtern.h @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC. + * Copyright (c) 2009, 2010, 2011 Your File System, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, + * this list of conditions and the following disclaimer in the + * documentation + * and/or other materials provided with the distribution. + * - Neither the names of Kernel Drivers, LLC and Your File System, Inc. + * nor the names of their contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission from Kernel Drivers, LLC and Your File System, Inc. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _AFS_EXTERN_H +#define _AFS_EXTERN_H +// +// File: AFSExtern.h +// +// + +extern "C" { + +extern PDRIVER_OBJECT AFSDriverObject; + +extern PDEVICE_OBJECT AFSDeviceObject; + +extern PDEVICE_OBJECT AFSRDRDeviceObject; + +extern FAST_IO_DISPATCH AFSFastIoDispatch; + +extern UNICODE_STRING AFSRegistryPath; + +extern ULONG AFSDebugFlags; + +extern ULONG AFSTraceLevel; + +extern ULONG AFSTraceComponent; + +extern ULONG AFSMaxDirectIo; + +extern ULONG AFSMaxDirtyFile; + +extern HANDLE AFSSysProcess; + +extern HANDLE AFSMUPHandle; + +extern UNICODE_STRING AFSServerName; + +extern UNICODE_STRING AFSGlobalRootName; + +extern ERESOURCE AFSDbgLogLock; + +extern ULONG AFSDbgLogRemainingLength; + +extern char *AFSDbgCurrentBuffer; + +extern char *AFSDbgBuffer; + +extern ULONG AFSDbgLogCounter; + +extern ULONG AFSDbgBufferLength; + +extern ULONG AFSDbgLogFlags; + +extern UNICODE_STRING AFSDumpFileLocation; + +extern CACHE_MANAGER_CALLBACKS AFSCacheManagerCallbacks; + +extern ULONG AFSAuthGroupFlags; + +extern GUID AFSActiveAuthGroup; + +extern GUID AFSNoPAGAuthGroup; + +extern PAFSSetInformationToken AFSSetInformationToken; + +extern KEVENT AFSDumpFileEvent; + +extern UNICODE_STRING AFSDumpFileName; + +extern void *AFSDumpBuffer; + +extern ULONG AFSDumpBufferLength; + +} + +#endif /* _AFS_EXTERN_H */ diff --git a/src/WINNT/afsrdr/kernel/fs/Include/AFSStructs.h b/src/WINNT/afsrdr/kernel/fs/Include/AFSStructs.h new file mode 100644 index 0000000000..65d64135b9 --- /dev/null +++ b/src/WINNT/afsrdr/kernel/fs/Include/AFSStructs.h @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC. + * Copyright (c) 2009, 2010, 2011 Your File System, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, + * this list of conditions and the following disclaimer in the + * documentation + * and/or other materials provided with the distribution. + * - Neither the names of Kernel Drivers, LLC and Your File System, Inc. + * nor the names of their contributors may be used to endorse or promote + * products derived from this software without specific prior written + * permission from Kernel Drivers, LLC and Your File System, Inc. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER + * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _AFS_STRUCTS_H +#define _AFS_STRUCTS_H + +// +// File: AFSStructs.h +// + +// +// Library queue request cb +// + +typedef struct _AFS_LIBRARY_QUEUE_REQUEST_CB +{ + + struct _AFS_LIBRARY_QUEUE_REQUEST_CB *fLink; + + PIRP Irp; + +} AFSLibraryQueueRequestCB; + +typedef struct AFS_PROCESS_CB +{ + + AFSBTreeEntry TreeEntry; // HashIndex = ProcessId + + ERESOURCE Lock; + + ULONG Flags; + + ULONGLONG ParentProcessId; + + ULONGLONG CreatingThread; + + GUID *ActiveAuthGroup; + + struct _AFS_PROCESS_AUTH_GROUP_CB *AuthGroupList; + + struct AFS_THREAD_CB *ThreadList; + +} AFSProcessCB; + +typedef struct AFS_THREAD_CB +{ + + struct AFS_THREAD_CB *Next; + + ULONGLONG ThreadId; + + ULONG Flags; + + GUID *ActiveAuthGroup; + +} AFSThreadCB; + +typedef struct _AFS_SID_ENTRY_CB +{ + + AFSBTreeEntry TreeEntry; + + ULONG Flags; + + GUID AuthGroup; + +} AFSSIDEntryCB; + +typedef struct _AFS_PROCESS_AUTH_GROUP_CB +{ + + struct _AFS_PROCESS_AUTH_GROUP_CB *Next; + + ULONG Flags; + + ULONGLONG AuthGroupHash; + + GUID AuthGroup; + +} AFSProcessAuthGroupCB; + +typedef struct _AFS_SET_DACL_CB +{ + + AFSProcessCB *ProcessCB; + + NTSTATUS RequestStatus; + + KEVENT Event; + +} AFSSetDaclRequestCB; + +typedef struct _AFS_SRVTABLE_ENTRY +{ + + PVOID *ServiceTable; + + ULONG LowCall; + + ULONG HiCall; + + PVOID *ArgTable; + +} AFSSrvcTableEntry; + +#endif /* _AFS_STRUCTS_H */ diff --git a/src/WINNT/afsrdr/kernel/fs/MAKEFILE b/src/WINNT/afsrdr/kernel/fs/MAKEFILE new file mode 100644 index 0000000000..6ee4f43fa4 --- /dev/null +++ b/src/WINNT/afsrdr/kernel/fs/MAKEFILE @@ -0,0 +1,6 @@ +# +# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source +# file to this component. This file merely indirects to the real make file +# that is shared by all the components of NT OS/2 +# +!INCLUDE $(NTMAKEENV)\makefile.def diff --git a/src/WINNT/afsrdr/kernel/fs/sources b/src/WINNT/afsrdr/kernel/fs/sources new file mode 100644 index 0000000000..7a612392ab --- /dev/null +++ b/src/WINNT/afsrdr/kernel/fs/sources @@ -0,0 +1,46 @@ + +TARGETNAME=AFSRedir +TARGETPATH=..\..\Build +TARGETTYPE=DRIVER + +DRIVERTYPE=FS +USE_MAPSYM=1 + +INCLUDES=Include;..\..\Common; + +TARGETLIBS=$(DDK_LIB_PATH)\ntstrsafe.lib \ + $(DDK_LIB_PATH)\wdmsec.lib + +TARGETTYPE=DRIVER + +SOURCES= AFSInit.cpp \ + AFSAuthGroupSupport.cpp \ + AFSBTreeSupport.cpp \ + AFSCleanup.cpp \ + AFSClose.cpp \ + AFSCommSupport.cpp \ + AFSCreate.cpp \ + AFSData.cpp \ + AFSDevControl.cpp \ + AFSDirControl.cpp \ + AFSEa.cpp \ + AFSFastIoSupport.cpp \ + AFSFileInfo.cpp \ + AFSFlushBuffers.cpp \ + AFSFSControl.cpp \ + AFSGeneric.cpp \ + AFSInternalDevControl.cpp \ + AFSLibrarySupport.cpp \ + AFSLockControl.cpp \ + AFSLogSupport.cpp \ + AFSNetworkProviderSupport.cpp \ + AFSProcessSupport.cpp \ + AFSQuota.cpp \ + AFSRDRSupport.cpp \ + AFSRead.cpp \ + AFSSecurity.cpp \ + AFSShutdown.cpp \ + AFSSystemControl.cpp \ + AFSVolumeInfo.cpp \ + AFSWrite.cpp \ + FileSystem.rc