--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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;
+
+}
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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;
+}
+
+
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+;;;
+;;; 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"
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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"
--- /dev/null
+/*
+ * 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 <ntifs.h>
+#include <wdmsec.h> // for IoCreateDeviceSecure
+#include <initguid.h>
+
+#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 */
--- /dev/null
+/*
+ * 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 */
--- /dev/null
+/*
+ * 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 */
--- /dev/null
+/*
+ * 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 */
--- /dev/null
+#
+# 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
--- /dev/null
+
+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