2 * Copyright (c) 2008, 2009, 2010, 2011, 2012, 2013 Kernel Drivers, LLC.
3 * Copyright (c) 2009, 2010, 2011, 2012, 2013 Your File System, Inc.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * - Redistributions of source code must retain the above copyright notice,
11 * this list of conditions and the following disclaimer.
12 * - Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * - Neither the names of Kernel Drivers, LLC and Your File System, Inc.
16 * nor the names of their contributors may be used to endorse or promote
17 * products derived from this software without specific prior written
18 * permission from Kernel Drivers, LLC and Your File System, Inc.
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
23 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
24 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 // File: AFSGeneric.cpp
37 #include "AFSCommon.h"
40 // Function: AFSExceptionFilter
44 // This function is the exception handler
48 // A status is returned for the function
52 AFSExceptionFilter( IN CHAR *FunctionString,
54 IN PEXCEPTION_POINTERS ExceptPtrs)
56 UNREFERENCED_PARAMETER(Code);
58 PEXCEPTION_RECORD ExceptRec;
64 ExceptRec = ExceptPtrs->ExceptionRecord;
66 Context = ExceptPtrs->ContextRecord;
70 "AFSExceptionFilter (Framework) - EXR %p CXR %p Function %s Code %08lX Address %p Routine %p\n",
74 ExceptRec->ExceptionCode,
75 ExceptRec->ExceptionAddress,
76 (void *)AFSExceptionFilter));
78 DbgPrint("**** Exception Caught in AFS Redirector ****\n");
80 DbgPrint("\n\nPerform the following WnDbg Cmds:\n");
81 DbgPrint("\n\t.exr %p ; .cxr %p\n\n", ExceptRec, Context);
83 DbgPrint("**** Exception Complete from AFS Redirector ****\n");
85 if( BooleanFlagOn( AFSDebugFlags, AFS_DBG_BUGCHECK_EXCEPTION))
88 KeBugCheck( (ULONG)-2);
96 __except( EXCEPTION_EXECUTE_HANDLER)
102 return EXCEPTION_EXECUTE_HANDLER;
106 // Function: AFSAcquireExcl()
108 // Purpose: Called to acquire a resource exclusive with optional wait
111 // PERESOURCE Resource - Resource to acquire
112 // BOOLEAN Wait - Whether to block
115 // BOOLEAN - Whether the mask was acquired
119 AFSAcquireExcl( IN PERESOURCE Resource,
123 BOOLEAN bStatus = FALSE;
126 // Normal kernel APCs must be disabled before calling
127 // ExAcquireResourceExclusiveLite. Otherwise a bugcheck occurs.
130 KeEnterCriticalRegion();
132 bStatus = ExAcquireResourceExclusiveLite( Resource,
138 KeLeaveCriticalRegion();
145 AFSAcquireSharedStarveExclusive( IN PERESOURCE Resource,
149 BOOLEAN bStatus = FALSE;
151 KeEnterCriticalRegion();
153 bStatus = ExAcquireSharedStarveExclusive( Resource,
159 KeLeaveCriticalRegion();
166 // Function: AFSAcquireShared()
168 // Purpose: Called to acquire a resource shared with optional wait
171 // PERESOURCE Resource - Resource to acquire
172 // BOOLEAN Wait - Whether to block
175 // BOOLEAN - Whether the mask was acquired
179 AFSAcquireShared( IN PERESOURCE Resource,
183 BOOLEAN bStatus = FALSE;
185 KeEnterCriticalRegion();
187 bStatus = ExAcquireResourceSharedLite( Resource,
193 KeLeaveCriticalRegion();
200 // Function: AFSReleaseResource()
202 // Purpose: Called to release a resource
205 // PERESOURCE Resource - Resource to release
212 AFSReleaseResource( IN PERESOURCE Resource)
215 if( Resource != &AFSDbgLogLock)
218 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
219 AFS_TRACE_LEVEL_VERBOSE,
220 "AFSReleaseResource Releasing lock %p Thread %08lX\n",
222 PsGetCurrentThread()));
225 ExReleaseResourceLite( Resource);
227 KeLeaveCriticalRegion();
233 AFSConvertToShared( IN PERESOURCE Resource)
236 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
237 AFS_TRACE_LEVEL_VERBOSE,
238 "AFSConvertToShared Converting lock %p Thread %08lX\n",
240 PsGetCurrentThread()));
242 ExConvertExclusiveToSharedLite( Resource);
248 // Function: AFSCompleteRequest
252 // This function completes irps
256 // A status is returned for the function
260 AFSCompleteRequest( IN PIRP Irp,
264 Irp->IoStatus.Status = Status;
266 IoCompleteRequest( Irp,
273 AFSReadRegistry( IN PUNICODE_STRING RegistryPath)
276 NTSTATUS ntStatus = STATUS_SUCCESS;
278 UNICODE_STRING paramPath;
280 RTL_QUERY_REGISTRY_TABLE paramTable[2];
281 UNICODE_STRING defaultUnicodeName;
282 WCHAR SubKeyString[] = L"\\Parameters";
285 // Setup the paramPath buffer.
288 paramPath.MaximumLength = RegistryPath->Length + sizeof( SubKeyString);
289 paramPath.Buffer = (PWSTR)AFSExAllocatePoolWithTag( PagedPool,
290 paramPath.MaximumLength,
291 AFS_GENERIC_MEMORY_15_TAG);
293 RtlInitUnicodeString( &defaultUnicodeName,
297 // If it exists, setup the path.
300 if( paramPath.Buffer != NULL)
307 RtlCopyMemory( ¶mPath.Buffer[ 0],
308 &RegistryPath->Buffer[ 0],
309 RegistryPath->Length);
311 RtlCopyMemory( ¶mPath.Buffer[ RegistryPath->Length / 2],
313 sizeof( SubKeyString));
315 paramPath.Length = paramPath.MaximumLength;
317 RtlZeroMemory( paramTable,
318 sizeof( paramTable));
323 // Setup the table to query the registry for the needed value
326 paramTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
327 paramTable[0].Name = AFS_REG_DEBUG_FLAGS;
328 paramTable[0].EntryContext = &Value;
330 paramTable[0].DefaultType = REG_DWORD;
331 paramTable[0].DefaultData = &Default;
332 paramTable[0].DefaultLength = sizeof (ULONG) ;
335 // Query the registry
338 ntStatus = RtlQueryRegistryValues( RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL,
344 if( NT_SUCCESS( ntStatus))
347 AFSDebugFlags = Value;
350 RtlZeroMemory( paramTable,
351 sizeof( paramTable));
356 // Setup the table to query the registry for the needed value
359 paramTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
360 paramTable[0].Name = AFS_REG_TRACE_SUBSYSTEM;
361 paramTable[0].EntryContext = &Value;
363 paramTable[0].DefaultType = REG_DWORD;
364 paramTable[0].DefaultData = &Default;
365 paramTable[0].DefaultLength = sizeof (ULONG) ;
368 // Query the registry
371 ntStatus = RtlQueryRegistryValues( RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL,
377 if( NT_SUCCESS( ntStatus))
380 AFSTraceComponent = Value;
383 RtlZeroMemory( paramTable,
384 sizeof( paramTable));
389 // Setup the table to query the registry for the needed value
392 paramTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
393 paramTable[0].Name = AFS_REG_TRACE_BUFFER_LENGTH;
394 paramTable[0].EntryContext = &Value;
396 paramTable[0].DefaultType = REG_DWORD;
397 paramTable[0].DefaultData = &Default;
398 paramTable[0].DefaultLength = sizeof (ULONG);
401 // Query the registry
404 ntStatus = RtlQueryRegistryValues( RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL,
410 if( NT_SUCCESS( ntStatus) &&
414 AFSDbgBufferLength = Value;
417 // Let's limit things a bit ...
420 if( AFSDbgBufferLength > AFS_DBG_LOG_MAXLENGTH)
423 AFSDbgBufferLength = AFS_DBG_LOG_MAXLENGTH;
429 AFSDbgBufferLength = 0;
436 AFSDbgBufferLength *= 1024;
439 // Now get ready to set up for MaxServerDirty
442 paramTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
443 paramTable[0].Name = AFS_REG_MAX_DIRTY;
444 paramTable[0].EntryContext = &Value;
446 paramTable[0].DefaultType = REG_DWORD;
447 paramTable[0].DefaultData = &Default;
448 paramTable[0].DefaultLength = sizeof (ULONG) ;
451 // Query the registry
454 ntStatus = RtlQueryRegistryValues( RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL,
460 if( NT_SUCCESS( ntStatus))
463 AFSMaxDirtyFile = Value;
466 RtlZeroMemory( paramTable,
467 sizeof( paramTable));
472 // Setup the table to query the registry for the needed value
475 paramTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
476 paramTable[0].Name = AFS_REG_TRACE_LEVEL;
477 paramTable[0].EntryContext = &Value;
479 paramTable[0].DefaultType = REG_DWORD;
480 paramTable[0].DefaultData = &Default;
481 paramTable[0].DefaultLength = sizeof (ULONG) ;
484 // Query the registry
487 ntStatus = RtlQueryRegistryValues( RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL,
493 if( NT_SUCCESS( ntStatus))
496 AFSTraceLevel = Value;
503 paramTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
504 paramTable[0].Name = AFS_REG_MAX_IO;
505 paramTable[0].EntryContext = &Value;
507 paramTable[0].DefaultType = REG_DWORD;
508 paramTable[0].DefaultData = &Default;
509 paramTable[0].DefaultLength = sizeof (ULONG) ;
512 // Query the registry
515 ntStatus = RtlQueryRegistryValues( RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL,
521 if( NT_SUCCESS( ntStatus))
524 AFSMaxDirectIo = Value;
528 // Now set up for ShutdownStatus query
531 paramTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
532 paramTable[0].Name = AFS_REG_SHUTDOWN_STATUS;
533 paramTable[0].EntryContext = &Value;
535 paramTable[0].DefaultType = REG_DWORD;
536 paramTable[0].DefaultData = &Default;
537 paramTable[0].DefaultLength = sizeof (ULONG) ;
540 // Query the registry
543 ntStatus = RtlQueryRegistryValues( RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL,
549 if( !NT_SUCCESS( ntStatus) ||
553 SetFlag( AFSDebugFlags, AFS_DBG_CLEAN_SHUTDOWN);
557 // Now set up for RequireCleanShutdown query
560 paramTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
561 paramTable[0].Name = AFS_REG_REQUIRE_CLEAN_SHUTDOWN;
562 paramTable[0].EntryContext = &Value;
564 paramTable[0].DefaultType = REG_DWORD;
565 paramTable[0].DefaultData = &Default;
566 paramTable[0].DefaultLength = sizeof (ULONG) ;
569 // Query the registry
572 ntStatus = RtlQueryRegistryValues( RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL,
578 if( !NT_SUCCESS( ntStatus) ||
582 SetFlag( AFSDebugFlags, AFS_DBG_REQUIRE_CLEAN_SHUTDOWN);
586 // Free up the buffer
589 ExFreePool( paramPath.Buffer);
591 ntStatus = STATUS_SUCCESS;
595 ntStatus = STATUS_INSUFFICIENT_RESOURCES;
602 AFSUpdateRegistryParameter( IN PUNICODE_STRING ValueName,
605 IN ULONG ValueDataLength)
608 NTSTATUS ntStatus = STATUS_SUCCESS;
609 UNICODE_STRING paramPath, uniParamKey;
610 HANDLE hParameters = 0;
611 OBJECT_ATTRIBUTES stObjectAttributes;
616 RtlInitUnicodeString( &uniParamKey,
620 // Setup the paramPath buffer.
623 paramPath.MaximumLength = AFSRegistryPath.Length + uniParamKey.Length;
624 paramPath.Buffer = (PWSTR)AFSExAllocatePoolWithTag( PagedPool,
625 paramPath.MaximumLength,
626 AFS_GENERIC_MEMORY_16_TAG);
628 if( paramPath.Buffer == NULL)
631 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
638 RtlCopyMemory( paramPath.Buffer,
639 AFSRegistryPath.Buffer,
640 AFSRegistryPath.Length);
642 paramPath.Length = AFSRegistryPath.Length;
644 RtlCopyMemory( ¶mPath.Buffer[ paramPath.Length / 2],
648 paramPath.Length += uniParamKey.Length;
650 InitializeObjectAttributes( &stObjectAttributes,
652 OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
656 ntStatus = ZwOpenKey( &hParameters,
658 &stObjectAttributes);
660 if( !NT_SUCCESS( ntStatus))
663 try_return( ntStatus);
670 ntStatus = ZwSetValueKey( hParameters,
677 ZwClose( hParameters);
681 if( paramPath.Buffer != NULL)
685 // Free up the buffer
688 ExFreePool( paramPath.Buffer);
696 AFSInitializeControlDevice()
699 NTSTATUS ntStatus = STATUS_SUCCESS;
700 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension;
706 // Initialize the comm pool resources
709 ExInitializeResourceLite( &pDeviceExt->Specific.Control.CommServiceCB.IrpPoolLock);
711 ExInitializeResourceLite( &pDeviceExt->Specific.Control.CommServiceCB.ResultPoolLock);
713 ExInitializeResourceLite( &pDeviceExt->Specific.Control.ExtentReleaseResource);
715 ExInitializeResourceLite( &pDeviceExt->Specific.Control.SysName32ListLock);
717 ExInitializeResourceLite( &pDeviceExt->Specific.Control.SysName64ListLock);
723 KeInitializeEvent( &pDeviceExt->Specific.Control.CommServiceCB.IrpPoolHasEntries,
724 SynchronizationEvent,
727 KeInitializeEvent( &pDeviceExt->Specific.Control.CommServiceCB.IrpPoolHasReleaseEntries,
728 SynchronizationEvent,
731 KeInitializeEvent( &pDeviceExt->Specific.Control.ExtentReleaseEvent,
735 pDeviceExt->Specific.Control.ExtentReleaseSequence = 0;
737 KeInitializeEvent( &pDeviceExt->Specific.Control.VolumeWorkerCloseEvent,
742 // Library support information
745 KeInitializeEvent( &pDeviceExt->Specific.Control.LoadLibraryEvent,
746 SynchronizationEvent,
750 // Initialize the library queued as cancelled
753 pDeviceExt->Specific.Control.LibraryState = AFS_LIBRARY_QUEUE_CANCELLED;
755 ExInitializeResourceLite( &pDeviceExt->Specific.Control.LibraryStateLock);
757 pDeviceExt->Specific.Control.InflightLibraryRequests = 0;
759 KeInitializeEvent( &pDeviceExt->Specific.Control.InflightLibraryEvent,
763 pDeviceExt->Specific.Control.ExtentCount = 0;
764 pDeviceExt->Specific.Control.ExtentsHeldLength = 0;
766 KeInitializeEvent( &pDeviceExt->Specific.Control.ExtentsHeldEvent,
770 pDeviceExt->Specific.Control.OutstandingServiceRequestCount = 0;
772 KeInitializeEvent( &pDeviceExt->Specific.Control.OutstandingServiceRequestEvent,
776 pDeviceExt->Specific.Control.WaitingForMemoryCount = 0;
778 KeInitializeEvent( &pDeviceExt->Specific.Control.MemoryAvailableEvent,
782 ExInitializeResourceLite( &pDeviceExt->Specific.Control.LibraryQueueLock);
784 pDeviceExt->Specific.Control.LibraryQueueHead = NULL;
786 pDeviceExt->Specific.Control.LibraryQueueTail = NULL;
789 // Set the initial state of the irp pool
792 pDeviceExt->Specific.Control.CommServiceCB.IrpPoolControlFlag = POOL_INACTIVE;
795 // Initialize our process and sid tree information
798 ExInitializeResourceLite( &pDeviceExt->Specific.Control.ProcessTreeLock);
800 pDeviceExt->Specific.Control.ProcessTree.TreeLock = &pDeviceExt->Specific.Control.ProcessTreeLock;
802 pDeviceExt->Specific.Control.ProcessTree.TreeHead = NULL;
804 ExInitializeResourceLite( &pDeviceExt->Specific.Control.AuthGroupTreeLock);
806 pDeviceExt->Specific.Control.AuthGroupTree.TreeLock = &pDeviceExt->Specific.Control.AuthGroupTreeLock;
808 pDeviceExt->Specific.Control.AuthGroupTree.TreeHead = NULL;
811 // Increase the StackSize to support the extra stack frame required
812 // for use of IoCompletion routines.
815 AFSDeviceObject->StackSize++;
823 AFSRemoveControlDevice()
826 NTSTATUS ntStatus = STATUS_SUCCESS;
827 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension;
833 // Initialize the comm pool resources
836 ExDeleteResourceLite( &pDeviceExt->Specific.Control.CommServiceCB.IrpPoolLock);
838 ExDeleteResourceLite( &pDeviceExt->Specific.Control.CommServiceCB.ResultPoolLock);
840 ExDeleteResourceLite( &pDeviceExt->Specific.Control.ExtentReleaseResource);
842 ExDeleteResourceLite( &pDeviceExt->Specific.Control.SysName32ListLock);
844 ExDeleteResourceLite( &pDeviceExt->Specific.Control.SysName64ListLock);
846 ExDeleteResourceLite( &pDeviceExt->Specific.Control.ProcessTreeLock);
848 if( pDeviceExt->Specific.Control.ProcessTree.TreeHead != NULL)
850 ExFreePool( pDeviceExt->Specific.Control.ProcessTree.TreeHead);
853 ExDeleteResourceLite( &pDeviceExt->Specific.Control.AuthGroupTreeLock);
855 ExDeleteResourceLite( &pDeviceExt->Specific.Control.LibraryStateLock);
857 ExDeleteResourceLite( &pDeviceExt->Specific.Control.LibraryQueueLock);
864 AFSInitServerStrings()
867 UNICODE_STRING uniFullName;
868 WCHAR wchBuffer[ 50];
871 // Add the server name into the list of resources
874 uniFullName.Length = (2 * sizeof( WCHAR)) + AFSServerName.Length;
875 uniFullName.MaximumLength = uniFullName.Length + sizeof( WCHAR);
877 uniFullName.Buffer = wchBuffer;
879 wchBuffer[ 0] = L'\\';
880 wchBuffer[ 1] = L'\\';
882 RtlCopyMemory( &wchBuffer[ 2],
883 AFSServerName.Buffer,
884 AFSServerName.Length);
886 AFSAddConnectionEx( &uniFullName,
887 RESOURCEDISPLAYTYPE_SERVER,
891 // Add in the global share name
894 wchBuffer[ uniFullName.Length/sizeof( WCHAR)] = L'\\';
896 uniFullName.Length += sizeof( WCHAR);
898 RtlCopyMemory( &wchBuffer[ uniFullName.Length/sizeof( WCHAR)],
899 AFSGlobalRootName.Buffer,
900 AFSGlobalRootName.Length);
902 uniFullName.Length += AFSGlobalRootName.Length;
904 AFSAddConnectionEx( &uniFullName,
905 RESOURCEDISPLAYTYPE_SHARE,
906 AFS_CONNECTION_FLAG_GLOBAL_SHARE);
915 NTSTATUS ntStatus = STATUS_SUCCESS;
916 UNICODE_STRING paramPath;
917 RTL_QUERY_REGISTRY_TABLE paramTable[2];
923 // Setup the paramPath buffer.
926 paramPath.MaximumLength = PAGE_SIZE;
927 paramPath.Buffer = (PWSTR)AFSExAllocatePoolWithTag( PagedPool,
928 paramPath.MaximumLength,
929 AFS_GENERIC_MEMORY_17_TAG);
932 // If it exists, setup the path.
935 if( paramPath.Buffer == NULL)
938 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
945 RtlZeroMemory( paramPath.Buffer,
946 paramPath.MaximumLength);
948 RtlCopyMemory( ¶mPath.Buffer[ 0],
949 L"\\TransarcAFSDaemon\\Parameters",
952 paramPath.Length = 58;
954 RtlZeroMemory( paramTable,
955 sizeof( paramTable));
958 // Setup the table to query the registry for the needed value
961 AFSServerName.Length = 0;
962 AFSServerName.MaximumLength = 0;
963 AFSServerName.Buffer = NULL;
965 paramTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
966 paramTable[0].Name = AFS_REG_NETBIOS_NAME;
967 paramTable[0].EntryContext = &AFSServerName;
969 paramTable[0].DefaultType = REG_NONE;
970 paramTable[0].DefaultData = NULL;
971 paramTable[0].DefaultLength = 0;
974 // Query the registry
977 ntStatus = RtlQueryRegistryValues( RTL_REGISTRY_SERVICES,
984 // Free up the buffer
987 ExFreePool( paramPath.Buffer);
991 if( !NT_SUCCESS( ntStatus))
994 RtlInitUnicodeString( &AFSServerName,
1003 AFSReadMountRootName()
1006 NTSTATUS ntStatus = STATUS_SUCCESS;
1007 UNICODE_STRING paramPath;
1008 RTL_QUERY_REGISTRY_TABLE paramTable[2];
1014 // Setup the paramPath buffer.
1017 paramPath.MaximumLength = PAGE_SIZE;
1018 paramPath.Buffer = (PWSTR)AFSExAllocatePoolWithTag( PagedPool,
1019 paramPath.MaximumLength,
1020 AFS_GENERIC_MEMORY_17_TAG);
1023 // If it exists, setup the path.
1026 if( paramPath.Buffer == NULL)
1029 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1033 // Move in the paths
1036 RtlZeroMemory( paramPath.Buffer,
1037 paramPath.MaximumLength);
1039 RtlCopyMemory( ¶mPath.Buffer[ 0],
1040 L"\\TransarcAFSDaemon\\Parameters",
1043 paramPath.Length = 58;
1045 RtlZeroMemory( paramTable,
1046 sizeof( paramTable));
1049 // Setup the table to query the registry for the needed value
1052 AFSMountRootName.Length = 0;
1053 AFSMountRootName.MaximumLength = 0;
1054 AFSMountRootName.Buffer = NULL;
1056 paramTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
1057 paramTable[0].Name = AFS_REG_MOUNT_ROOT;
1058 paramTable[0].EntryContext = &AFSMountRootName;
1060 paramTable[0].DefaultType = REG_NONE;
1061 paramTable[0].DefaultData = NULL;
1062 paramTable[0].DefaultLength = 0;
1065 // Query the registry
1068 ntStatus = RtlQueryRegistryValues( RTL_REGISTRY_SERVICES,
1074 if ( NT_SUCCESS( ntStatus))
1076 if ( AFSMountRootName.Buffer[0] == L'/')
1079 AFSMountRootName.Buffer[0] = L'\\';
1084 // Free up the buffer
1087 ExFreePool( paramPath.Buffer);
1091 if( !NT_SUCCESS( ntStatus))
1094 RtlInitUnicodeString( &AFSMountRootName,
1103 AFSSetSysNameInformation( IN AFSSysNameNotificationCB *SysNameInfo,
1104 IN ULONG SysNameInfoBufferLength)
1106 UNREFERENCED_PARAMETER(SysNameInfoBufferLength);
1108 NTSTATUS ntStatus = STATUS_SUCCESS;
1109 AFSDeviceExt *pControlDevExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension;
1110 AFSSysNameCB *pSysName = NULL;
1111 ERESOURCE *pSysNameLock = NULL;
1112 AFSSysNameCB **pSysNameListHead = NULL, **pSysNameListTail = NULL;
1118 // Depending on the architecture of the information, set up the lsit
1121 if( SysNameInfo->Architecture == AFS_SYSNAME_ARCH_32BIT)
1124 pSysNameLock = &pControlDevExt->Specific.Control.SysName32ListLock;
1126 pSysNameListHead = &pControlDevExt->Specific.Control.SysName32ListHead;
1128 pSysNameListTail = &pControlDevExt->Specific.Control.SysName32ListTail;
1135 pSysNameLock = &pControlDevExt->Specific.Control.SysName64ListLock;
1137 pSysNameListHead = &pControlDevExt->Specific.Control.SysName64ListHead;
1139 pSysNameListTail = &pControlDevExt->Specific.Control.SysName64ListTail;
1143 try_return( ntStatus = STATUS_INVALID_PARAMETER);
1148 // Process the request
1151 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
1152 AFS_TRACE_LEVEL_VERBOSE,
1153 "AFSSetSysNameInformation Acquiring SysName lock %p EXCL %08lX\n",
1155 PsGetCurrentThread()));
1157 AFSAcquireExcl( pSysNameLock,
1161 // If we already have a list, then tear it down
1164 if( *pSysNameListHead != NULL)
1167 AFSResetSysNameList( *pSysNameListHead);
1169 *pSysNameListHead = NULL;
1173 // Loop through the entries adding in a node for each
1176 while( ulIndex < SysNameInfo->NumberOfNames)
1179 pSysName = (AFSSysNameCB *)AFSExAllocatePoolWithTag( PagedPool,
1180 sizeof( AFSSysNameCB) +
1181 SysNameInfo->SysNames[ ulIndex].Length +
1183 AFS_SYS_NAME_NODE_TAG);
1185 if( pSysName == NULL)
1189 // Reset the current list
1192 AFSResetSysNameList( *pSysNameListHead);
1194 *pSysNameListHead = NULL;
1196 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1199 RtlZeroMemory( pSysName,
1200 sizeof( AFSSysNameCB) +
1201 SysNameInfo->SysNames[ ulIndex].Length +
1204 pSysName->SysName.Length = (USHORT)SysNameInfo->SysNames[ ulIndex].Length;
1206 pSysName->SysName.MaximumLength = pSysName->SysName.Length + sizeof( WCHAR);
1208 pSysName->SysName.Buffer = (WCHAR *)((char *)pSysName + sizeof( AFSSysNameCB));
1210 RtlCopyMemory( pSysName->SysName.Buffer,
1211 SysNameInfo->SysNames[ ulIndex].String,
1212 pSysName->SysName.Length);
1214 if( *pSysNameListHead == NULL)
1217 *pSysNameListHead = pSysName;
1222 (*pSysNameListTail)->fLink = pSysName;
1225 *pSysNameListTail = pSysName;
1232 AFSReleaseResource( pSysNameLock);
1239 AFSResetSysNameList( IN AFSSysNameCB *SysNameList)
1242 AFSSysNameCB *pNextEntry = NULL, *pCurrentEntry = SysNameList;
1244 while( pCurrentEntry != NULL)
1247 pNextEntry = pCurrentEntry->fLink;
1249 ExFreePool( pCurrentEntry);
1251 pCurrentEntry = pNextEntry;
1258 AFSDefaultDispatch( IN PDEVICE_OBJECT DeviceObject,
1261 UNREFERENCED_PARAMETER(DeviceObject);
1263 NTSTATUS ntStatus = STATUS_INVALID_DEVICE_REQUEST;
1265 AFSCompleteRequest( Irp,
1272 AFSSendDeviceIoControl( IN DEVICE_OBJECT *TargetDeviceObject,
1274 IN void *InputBuffer,
1275 IN ULONG InputBufferLength,
1276 IN OUT void *OutputBuffer,
1277 IN ULONG OutputBufferLength,
1278 OUT ULONG *ResultLength)
1280 UNREFERENCED_PARAMETER(OutputBuffer);
1281 UNREFERENCED_PARAMETER(OutputBufferLength);
1283 NTSTATUS ntStatus = STATUS_SUCCESS;
1286 PIO_STACK_LOCATION pIoStackLocation = NULL;
1292 // Initialize the event
1295 KeInitializeEvent( &kEvent,
1296 SynchronizationEvent,
1300 // Allocate an irp for this request. This could also come from a
1301 // private pool, for instance.
1304 pIrp = IoAllocateIrp( TargetDeviceObject->StackSize,
1310 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1314 // Build the IRP's main body
1317 pIrp->RequestorMode = KernelMode;
1320 // Set up the I/O stack location.
1323 pIoStackLocation = IoGetNextIrpStackLocation( pIrp);
1324 pIoStackLocation->MajorFunction = IRP_MJ_DEVICE_CONTROL;
1325 pIoStackLocation->DeviceObject = TargetDeviceObject;
1327 pIoStackLocation->Parameters.DeviceIoControl.IoControlCode = IOControl;
1329 pIrp->AssociatedIrp.SystemBuffer = (void *)InputBuffer;
1330 pIoStackLocation->Parameters.DeviceIoControl.InputBufferLength = InputBufferLength;
1333 // Set the completion routine.
1336 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
1337 AFS_TRACE_LEVEL_VERBOSE,
1338 "Setting AFSIrpComplete as IoCompletion Routine Irp %p\n",
1341 IoSetCompletionRoutine( pIrp,
1349 // Send it to the FSD
1352 ntStatus = IoCallDriver( TargetDeviceObject,
1355 if( NT_SUCCESS( ntStatus))
1362 ntStatus = KeWaitForSingleObject( &kEvent,
1368 if( NT_SUCCESS( ntStatus))
1371 ntStatus = pIrp->IoStatus.Status;
1373 if( ResultLength != NULL)
1375 *ResultLength = (ULONG)pIrp->IoStatus.Information;
1385 if( pIrp->MdlAddress != NULL)
1388 if( FlagOn( pIrp->MdlAddress->MdlFlags, MDL_PAGES_LOCKED))
1391 MmUnlockPages( pIrp->MdlAddress);
1394 IoFreeMdl( pIrp->MdlAddress);
1397 pIrp->MdlAddress = NULL;
1411 AFSIrpComplete( IN PDEVICE_OBJECT DeviceObject,
1415 UNREFERENCED_PARAMETER(DeviceObject);
1416 UNREFERENCED_PARAMETER(Irp);
1418 KEVENT *pEvent = (KEVENT *)Context;
1424 return STATUS_MORE_PROCESSING_REQUIRED;
1428 AFSExAllocatePoolWithTag( IN POOL_TYPE PoolType,
1429 IN SIZE_T NumberOfBytes,
1433 AFSDeviceExt *pControlDevExt = NULL;
1434 void *pBuffer = NULL;
1435 BOOLEAN bTimeout = FALSE;
1436 LARGE_INTEGER liTimeout;
1440 // Attempt to allocation memory from the system. If the allocation fails
1441 // wait up to 30 seconds for the AFS redirector to free some memory. As
1442 // long as the wait does not timeout, continue to retry the allocation.
1443 // If the wait does timeout, attempt to allocate one more time in case
1444 // memory was freed by another driver. Otherwise, fail the request.
1447 if ( AFSDeviceObject)
1450 pControlDevExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension;
1453 while( pBuffer == NULL)
1456 pBuffer = ExAllocatePoolWithTag( PoolType,
1460 if( pBuffer == NULL)
1463 if ( bTimeout || pControlDevExt == NULL)
1468 "AFSExAllocatePoolWithTag failure Type %08lX Size %08lX Tag %08lX %08lX\n",
1472 PsGetCurrentThread()));
1476 case AFS_GENERIC_MEMORY_21_TAG:
1477 case AFS_GENERIC_MEMORY_22_TAG:
1478 // AFSDumpTraceFiles -- do nothing;
1490 // Wait up to 30 seconds for a memory deallocation
1493 liTimeout.QuadPart = -(30 *AFS_ONE_SECOND);
1495 if( InterlockedIncrement( &pControlDevExt->Specific.Control.WaitingForMemoryCount) == 1)
1497 KeClearEvent( &pControlDevExt->Specific.Control.MemoryAvailableEvent);
1500 ntStatus = KeWaitForSingleObject( &pControlDevExt->Specific.Control.MemoryAvailableEvent,
1506 if( ntStatus == STATUS_TIMEOUT)
1512 InterlockedDecrement( &pControlDevExt->Specific.Control.WaitingForMemoryCount);
1520 AFSExFreePoolWithTag( IN void *Buffer, IN ULONG Tag)
1523 AFSDeviceExt *pControlDevExt = NULL;
1525 if ( AFSDeviceObject)
1528 pControlDevExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension;
1534 ExFreePoolWithTag( Buffer, Tag);
1539 ExFreePool( Buffer);
1542 if ( pControlDevExt)
1545 KeSetEvent( &pControlDevExt->Specific.Control.MemoryAvailableEvent,
1553 AFSShutdownRedirector()
1556 NTSTATUS ntStatus = STATUS_SUCCESS;
1557 AFSDeviceExt *pRDRDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1558 AFSDeviceExt *pControlDevExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension;
1559 LARGE_INTEGER liTimeout;
1564 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1565 AFS_TRACE_LEVEL_VERBOSE,
1566 "%s Shutting down redirector Extent count %08lX Request count %08lX\n",
1568 pControlDevExt->Specific.Control.ExtentCount,
1569 pControlDevExt->Specific.Control.OutstandingServiceRequestCount));
1572 // Set the shutdown flag so the worker is more agressive in tearing down extents
1575 SetFlag( pRDRDevExt->DeviceFlags, AFS_DEVICE_FLAG_REDIRECTOR_SHUTDOWN);
1578 // Wait on any outstanding service requests
1581 liTimeout.QuadPart = -(30 *AFS_ONE_SECOND);
1583 ntStatus = KeWaitForSingleObject( &pControlDevExt->Specific.Control.OutstandingServiceRequestEvent,
1589 if( ntStatus == STATUS_TIMEOUT)
1592 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1593 AFS_TRACE_LEVEL_WARNING,
1594 "AFSShutdownRedirector Failed to complete all service requests Remaining count %08lX\n",
1595 pControlDevExt->Specific.Control.OutstandingServiceRequestCount));
1597 try_return( ntStatus = STATUS_UNSUCCESSFUL);
1600 AFSProcessQueuedResults( TRUE);
1603 // Wait for all extents to be released
1606 liTimeout.QuadPart = -(30 *AFS_ONE_SECOND);
1608 ntStatus = KeWaitForSingleObject( &pControlDevExt->Specific.Control.ExtentsHeldEvent,
1614 if( ntStatus == STATUS_TIMEOUT)
1617 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1618 AFS_TRACE_LEVEL_WARNING,
1619 "AFSShutdownRedirector Failed to purge all extents Remaining count %08lX\n",
1620 pControlDevExt->Specific.Control.ExtentCount));
1622 try_return( ntStatus = STATUS_UNSUCCESSFUL);
1625 ntStatus = AFSUnloadLibrary( TRUE);
1627 if( !NT_SUCCESS( ntStatus))
1630 try_return( ntStatus);
1635 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1636 AFS_TRACE_LEVEL_VERBOSE,
1637 "%s Completed shut down of redirector Extent count %08lX Request count %08lX Status %08lX\n",
1639 pControlDevExt->Specific.Control.ExtentCount,
1640 pControlDevExt->Specific.Control.OutstandingServiceRequestCount,
1648 // Cache manager callback routines
1652 AFSAcquireFcbForLazyWrite( IN PVOID Fcb,
1656 BOOLEAN bStatus = FALSE;
1657 AFSFcb *pFcb = (AFSFcb *)Fcb;
1658 BOOLEAN bReleaseSectionObject = FALSE, bReleasePaging = FALSE;
1661 // Try and acquire the Fcb resource
1664 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
1665 AFS_TRACE_LEVEL_VERBOSE,
1666 "AFSAcquireFcbForLazyWrite Acquiring Fcb %p\n",
1670 // Try and grab the paging
1673 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
1674 AFS_TRACE_LEVEL_VERBOSE,
1675 "AFSAcquireFcbForLazyWrite Attempt to acquire Fcb PagingIo lock %p SHARED %08lX\n",
1676 &pFcb->NPFcb->PagingResource,
1677 PsGetCurrentThread()));
1679 if( AFSAcquireShared( &pFcb->NPFcb->PagingResource,
1683 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
1684 AFS_TRACE_LEVEL_VERBOSE,
1685 "AFSAcquireFcbForLazyWrite Acquired Fcb PagingIo lock %p SHARED %08lX\n",
1686 &pFcb->NPFcb->PagingResource,
1687 PsGetCurrentThread()));
1689 bReleasePaging = TRUE;
1691 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
1692 AFS_TRACE_LEVEL_VERBOSE,
1693 "AFSAcquireFcbForLazyWrite Attempt to acquire Fcb SectionObject lock %p SHARED %08lX\n",
1694 &pFcb->NPFcb->SectionObjectResource,
1695 PsGetCurrentThread()));
1697 if( AFSAcquireShared( &pFcb->NPFcb->SectionObjectResource,
1701 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
1702 AFS_TRACE_LEVEL_VERBOSE,
1703 "AFSAcquireFcbForLazyWrite Acquired Fcb SectionObject lock %p SHARED %08lX\n",
1704 &pFcb->NPFcb->SectionObjectResource,
1705 PsGetCurrentThread()));
1707 bReleaseSectionObject = TRUE;
1715 IoSetTopLevelIrp( (PIRP)FSRTL_CACHE_TOP_LEVEL_IRP);
1722 if( bReleaseSectionObject)
1725 AFSReleaseResource( &pFcb->NPFcb->SectionObjectResource);
1731 AFSReleaseResource( &pFcb->NPFcb->PagingResource);
1739 AFSReleaseFcbFromLazyWrite( IN PVOID Fcb)
1742 AFSFcb *pFcb = (AFSFcb *)Fcb;
1744 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
1745 AFS_TRACE_LEVEL_VERBOSE,
1746 "AFSReleaseFcbFromLazyWrite Releasing Fcb %p\n",
1749 IoSetTopLevelIrp( NULL);
1751 AFSReleaseResource( &pFcb->NPFcb->SectionObjectResource);
1753 AFSReleaseResource( &pFcb->NPFcb->PagingResource);
1759 AFSAcquireFcbForReadAhead( IN PVOID Fcb,
1763 BOOLEAN bStatus = FALSE;
1764 AFSFcb *pFcb = (AFSFcb *)Fcb;
1766 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
1767 AFS_TRACE_LEVEL_VERBOSE,
1768 "AFSAcquireFcbForReadAhead Attempt to acquire Fcb SectionObject lock %p SHARED %08lX\n",
1769 &pFcb->NPFcb->SectionObjectResource,
1770 PsGetCurrentThread()));
1772 if( AFSAcquireShared( &pFcb->NPFcb->SectionObjectResource,
1776 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
1777 AFS_TRACE_LEVEL_VERBOSE,
1778 "AFSAcquireFcbForReadAhead Acquired Fcb SectionObject lock %p SHARED %08lX\n",
1779 &pFcb->NPFcb->SectionObjectResource,
1780 PsGetCurrentThread()));
1784 IoSetTopLevelIrp( (PIRP)FSRTL_CACHE_TOP_LEVEL_IRP);
1791 AFSReleaseFcbFromReadAhead( IN PVOID Fcb)
1794 AFSFcb *pFcb = (AFSFcb *)Fcb;
1796 IoSetTopLevelIrp( NULL);
1798 AFSReleaseResource( &pFcb->NPFcb->SectionObjectResource);
1804 AFSGetCallerSID( OUT UNICODE_STRING *SIDString, OUT BOOLEAN *pbImpersonation)
1807 NTSTATUS ntStatus = STATUS_SUCCESS;
1808 PACCESS_TOKEN hToken = NULL;
1809 TOKEN_USER *pTokenInfo = NULL;
1810 BOOLEAN bCopyOnOpen = FALSE;
1811 BOOLEAN bEffectiveOnly = FALSE;
1812 BOOLEAN bPrimaryToken = FALSE;
1813 SECURITY_IMPERSONATION_LEVEL stImpersonationLevel;
1814 UNICODE_STRING uniSIDString;
1819 hToken = PsReferenceImpersonationToken( PsGetCurrentThread(),
1822 &stImpersonationLevel);
1827 hToken = PsReferencePrimaryToken( PsGetCurrentProcess());
1832 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1833 AFS_TRACE_LEVEL_ERROR,
1834 "AFSGetCallerSID Failed to retrieve impersonation or primary token\n"));
1836 try_return( ntStatus);
1839 bPrimaryToken = TRUE;
1842 ntStatus = SeQueryInformationToken( hToken,
1844 (PVOID *)&pTokenInfo);
1846 if( !NT_SUCCESS( ntStatus))
1849 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1850 AFS_TRACE_LEVEL_ERROR,
1851 "AFSGetCallerSID Failed to retrieve information Status %08lX\n",
1854 try_return( ntStatus);
1857 uniSIDString.Length = 0;
1858 uniSIDString.MaximumLength = 0;
1859 uniSIDString.Buffer = NULL;
1861 ntStatus = RtlConvertSidToUnicodeString( &uniSIDString,
1862 pTokenInfo->User.Sid,
1865 if( !NT_SUCCESS( ntStatus))
1868 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1869 AFS_TRACE_LEVEL_ERROR,
1870 "AFSGetCallerSID Failed to convert sid to string Status %08lX\n",
1873 try_return( ntStatus);
1876 *SIDString = uniSIDString;
1878 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING | AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
1879 AFS_TRACE_LEVEL_VERBOSE_2,
1880 "AFSGetCallerSID Successfully retrieved SID %wZ\n",
1883 if ( bPrimaryToken == FALSE &&
1886 *pbImpersonation = TRUE;
1895 PsDereferencePrimaryToken( hToken);
1899 PsDereferenceImpersonationToken( hToken);
1903 if( pTokenInfo != NULL)
1905 ExFreePool( pTokenInfo); // Allocated by SeQueryInformationToken
1913 AFSGetSessionId( IN HANDLE ProcessId, OUT BOOLEAN *pbImpersonation)
1915 UNREFERENCED_PARAMETER(ProcessId);
1917 NTSTATUS ntStatus = STATUS_SUCCESS;
1918 PACCESS_TOKEN hToken = NULL;
1919 ULONG ulSessionId = (ULONG)-1;
1920 BOOLEAN bCopyOnOpen = FALSE;
1921 BOOLEAN bEffectiveOnly = FALSE;
1922 BOOLEAN bPrimaryToken = FALSE;
1923 SECURITY_IMPERSONATION_LEVEL stImpersonationLevel;
1928 hToken = PsReferenceImpersonationToken( PsGetCurrentThread(),
1931 &stImpersonationLevel);
1936 hToken = PsReferencePrimaryToken( PsGetCurrentProcess());
1941 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1942 AFS_TRACE_LEVEL_ERROR,
1943 "AFSGetSessionId Failed to retrieve impersonation or primary token\n"));
1945 try_return( ntStatus);
1948 bPrimaryToken = TRUE;
1951 ntStatus = SeQueryInformationToken( hToken,
1953 (PVOID *)&ulSessionId);
1955 if( !NT_SUCCESS( ntStatus))
1957 ulSessionId = (ULONG)-1;
1959 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1960 AFS_TRACE_LEVEL_ERROR,
1961 "AFSGetSessionId Failed to retrieve session id Status %08lX\n",
1964 try_return( ntStatus);
1967 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING | AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
1968 AFS_TRACE_LEVEL_VERBOSE_2,
1969 "AFSGetSessionId found %08lX\n",
1972 if ( bPrimaryToken == FALSE &&
1975 *pbImpersonation = TRUE;
1984 PsDereferencePrimaryToken( hToken);
1988 PsDereferenceImpersonationToken( hToken);
1997 AFSCheckThreadDacl( OUT GUID *AuthGroup)
2000 NTSTATUS ntStatus = STATUS_UNSUCCESSFUL;
2002 PACCESS_TOKEN token = NULL;
2003 PTOKEN_DEFAULT_DACL defDacl = NULL;
2005 PACCESS_ALLOWED_ACE adace;
2006 BOOLEAN bCopyOnOpen = FALSE, bEffectiveOnly = FALSE;
2007 SECURITY_IMPERSONATION_LEVEL stImpersonationLevel;
2008 BOOLEAN bLocatedACE = FALSE;
2013 token = PsReferenceImpersonationToken( PsGetCurrentThread(),
2016 &stImpersonationLevel);
2020 try_return( ntStatus);
2023 ntStatus = SeQueryInformationToken( token,
2027 if( ntStatus != STATUS_SUCCESS)
2029 try_return( ntStatus);
2032 // scan through all ACEs in the DACL
2033 for (idx = 0, ace = (PACE_HEADER)((char *)defDacl->DefaultDacl + sizeof(ACL)); idx < defDacl->DefaultDacl->AceCount; idx++)
2035 if (ace->AceType == ACCESS_ALLOWED_ACE_TYPE)
2037 adace = (PACCESS_ALLOWED_ACE)ace;
2039 if (adace->Header.AceSize == (FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + AFS_DACL_SID_LENGTH))
2041 if (RtlCompareMemory( RtlSubAuthoritySid((PSID)&adace->SidStart, 0), &AFSSidGuid, sizeof(GUID)) == sizeof(GUID))
2044 RtlCopyMemory( AuthGroup,
2045 RtlSubAuthoritySid((PSID)&adace->SidStart, 4),
2056 ace = (PACE_HEADER)((char *)ace + ace->AceSize);
2063 PsDereferenceImpersonationToken( token);
2066 if (defDacl != NULL)
2068 ExFreePool(defDacl);
2073 ntStatus = STATUS_UNSUCCESSFUL;
2081 AFSProcessSetProcessDacl( IN AFSProcessCB *ProcessCB)
2084 PTOKEN_DEFAULT_DACL defDacl = NULL;
2085 HANDLE hToken = NULL;
2086 PACE_HEADER ace = NULL;
2087 SID_IDENTIFIER_AUTHORITY sia = SECURITY_NT_AUTHORITY;
2088 PACCESS_ALLOWED_ACE aaace;
2090 ULONG bytesReturned;
2093 NTSTATUS ntStatus = STATUS_SUCCESS;
2098 ntStatus = ZwOpenProcessTokenEx( NtCurrentProcess(),
2103 if( !NT_SUCCESS( ntStatus))
2105 try_return( ntStatus);
2108 // get the size of the current DACL
2109 ntStatus = ZwQueryInformationToken( hToken,
2115 // if we failed to get the buffer size needed
2116 if ((ntStatus != STATUS_SUCCESS) && (ntStatus != STATUS_BUFFER_TOO_SMALL))
2118 try_return( ntStatus);
2121 // tack on enough space for our ACE if we need to add it...
2122 bytesNeeded += FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + AFS_DACL_SID_LENGTH;
2124 // allocate space for the DACL
2125 defDacl = (PTOKEN_DEFAULT_DACL)ExAllocatePoolWithTag( PagedPool, bytesNeeded, AFS_GENERIC_MEMORY_26_TAG);
2127 if (defDacl == NULL)
2129 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2133 ntStatus = ZwQueryInformationToken( hToken,
2139 if( ntStatus != STATUS_SUCCESS)
2141 try_return( ntStatus);
2144 // scan through DACL to see if we have the SID set already...
2145 ace = (PACE_HEADER)((char *)defDacl->DefaultDacl + sizeof(ACL));
2146 for (idx = 0; idx < defDacl->DefaultDacl->AceCount; idx++)
2148 if (ace->AceType == ACCESS_ALLOWED_ACE_TYPE)
2150 aaace = (PACCESS_ALLOWED_ACE)ace;
2152 if (aaace->Header.AceSize == (FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + AFS_DACL_SID_LENGTH))
2154 // if the GUID part matches
2155 if( RtlCompareMemory( RtlSubAuthoritySid((PSID)&aaace->SidStart, 0),
2157 sizeof(GUID)) == sizeof(GUID))
2160 if ( RtlCompareMemory( RtlSubAuthoritySid((PSID)&aaace->SidStart, 4),
2161 ProcessCB->ActiveAuthGroup,
2162 sizeof( GUID)) != sizeof( GUID))
2165 RtlCopyMemory( RtlSubAuthoritySid((PSID)&aaace->SidStart, 4),
2166 ProcessCB->ActiveAuthGroup,
2169 if( AFSSetInformationToken != NULL)
2171 ntStatus = AFSSetInformationToken( hToken,
2178 try_return( ntStatus);
2184 ace = (PACE_HEADER)((char *)ace + ace->AceSize);
2188 // if we made it here we need to add a new ACE to the DACL
2191 aaace = (ACCESS_ALLOWED_ACE *)ace;
2192 aaace->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
2193 aaace->Header.AceFlags = 0;
2194 aaace->Mask = GENERIC_ALL;
2195 psid = (PSID)&aaace->SidStart;
2196 RtlInitializeSid( psid, &sia, 8);
2198 RtlCopyMemory( RtlSubAuthoritySid(psid, 0),
2202 RtlCopyMemory( RtlSubAuthoritySid(psid, 4),
2203 ProcessCB->ActiveAuthGroup,
2206 aaace->Header.AceSize = (USHORT)(FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + RtlLengthSid( psid));
2208 defDacl->DefaultDacl->AclSize += aaace->Header.AceSize;
2209 defDacl->DefaultDacl->AceCount++;
2211 if( AFSSetInformationToken != NULL)
2213 ntStatus = AFSSetInformationToken( hToken,
2216 defDacl->DefaultDacl->AclSize + sizeof(PTOKEN_DEFAULT_DACL));
2226 if (defDacl != NULL)
2228 ExFreePool( defDacl);
2236 AFSSetReparsePointPolicy( IN AFSSetReparsePointPolicyCB *PolicyCB)
2239 NTSTATUS ntStatus = STATUS_SUCCESS;
2240 AFSDeviceExt* pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
2246 ulPolicy = (PolicyCB->Policy & AFS_REPARSE_POINT_VALID_POLICY_FLAGS);
2248 if ( PolicyCB->Scope == AFS_REPARSE_POINT_POLICY_GLOBAL)
2251 pDeviceExt->Specific.RDR.ReparsePointPolicy = ulPolicy;
2253 else if ( PolicyCB->Scope == AFS_REPARSE_POINT_POLICY_AUTHGROUP)
2256 ntStatus = STATUS_NOT_SUPPORTED;
2265 AFSGetReparsePointPolicy( OUT AFSGetReparsePointPolicyCB *PolicyCB)
2268 NTSTATUS ntStatus = STATUS_SUCCESS;
2269 AFSDeviceExt* pDeviceExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
2274 PolicyCB->GlobalPolicy = pDeviceExt->Specific.RDR.ReparsePointPolicy;
2277 // When per-AuthGroup or per-Process policies are permitted
2278 // this function will need to query the policies when determining
2279 // the active policy.
2284 PolicyCB->ActivePolicy = PolicyCB->GlobalPolicy;