2 * Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC.
3 * Copyright (c) 2009, 2010, 2011 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
14 * this list of conditions and the following disclaimer in the
16 * and/or other materials provided with the distribution.
17 * - Neither the names of Kernel Drivers, LLC and Your File System, Inc.
18 * nor the names of their contributors may be used to endorse or promote
19 * products derived from this software without specific prior written
20 * permission from Kernel Drivers, LLC and Your File System, Inc.
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
24 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
25 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
26 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 // File: AFSGeneric.cpp
39 #include "AFSCommon.h"
42 // Function: AFSExceptionFilter
46 // This function is the exception handler
50 // A status is returned for the function
54 AFSExceptionFilter( IN CHAR *FunctionString,
56 IN PEXCEPTION_POINTERS ExceptPtrs)
59 PEXCEPTION_RECORD ExceptRec;
65 ExceptRec = ExceptPtrs->ExceptionRecord;
67 Context = ExceptPtrs->ContextRecord;
71 "AFSExceptionFilter (Framework) - EXR %p CXR %p Function %s Code %08lX Address %p Routine %p\n",
75 ExceptRec->ExceptionCode,
76 ExceptRec->ExceptionAddress,
77 (void *)AFSExceptionFilter);
79 DbgPrint("**** Exception Caught in AFS Redirector ****\n");
81 DbgPrint("\n\nPerform the following WnDbg Cmds:\n");
82 DbgPrint("\n\t.exr %p ; .cxr %p\n\n", ExceptRec, Context);
84 DbgPrint("**** Exception Complete from AFS Redirector ****\n");
86 if( BooleanFlagOn( AFSDebugFlags, AFS_DBG_BUGCHECK_EXCEPTION))
89 KeBugCheck( (ULONG)-2);
97 __except( EXCEPTION_EXECUTE_HANDLER)
103 return EXCEPTION_EXECUTE_HANDLER;
107 // Function: AFSAcquireExcl()
109 // Purpose: Called to acquire a resource exclusive with optional wait
112 // PERESOURCE Resource - Resource to acquire
113 // BOOLEAN Wait - Whether to block
116 // BOOLEAN - Whether the mask was acquired
120 AFSAcquireExcl( IN PERESOURCE Resource,
124 BOOLEAN bStatus = FALSE;
127 // Normal kernel APCs must be disabled before calling
128 // ExAcquireResourceExclusiveLite. Otherwise a bugcheck occurs.
131 KeEnterCriticalRegion();
133 bStatus = ExAcquireResourceExclusiveLite( Resource,
139 KeLeaveCriticalRegion();
146 AFSAcquireSharedStarveExclusive( IN PERESOURCE Resource,
150 BOOLEAN bStatus = FALSE;
152 KeEnterCriticalRegion();
154 bStatus = ExAcquireSharedStarveExclusive( Resource,
160 KeLeaveCriticalRegion();
167 // Function: AFSAcquireShared()
169 // Purpose: Called to acquire a resource shared with optional wait
172 // PERESOURCE Resource - Resource to acquire
173 // BOOLEAN Wait - Whether to block
176 // BOOLEAN - Whether the mask was acquired
180 AFSAcquireShared( IN PERESOURCE Resource,
184 BOOLEAN bStatus = FALSE;
186 KeEnterCriticalRegion();
188 bStatus = ExAcquireResourceSharedLite( Resource,
194 KeLeaveCriticalRegion();
201 // Function: AFSReleaseResource()
203 // Purpose: Called to release a resource
206 // PERESOURCE Resource - Resource to release
213 AFSReleaseResource( IN PERESOURCE Resource)
216 if( Resource != &AFSDbgLogLock)
219 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
220 AFS_TRACE_LEVEL_VERBOSE,
221 "AFSReleaseResource Releasing lock %08lX Thread %08lX\n",
223 PsGetCurrentThread());
226 ExReleaseResourceLite( Resource);
228 KeLeaveCriticalRegion();
234 AFSConvertToShared( IN PERESOURCE Resource)
237 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
238 AFS_TRACE_LEVEL_VERBOSE,
239 "AFSConvertToShared Converting lock %08lX Thread %08lX\n",
241 PsGetCurrentThread());
243 ExConvertExclusiveToSharedLite( Resource);
249 // Function: AFSCompleteRequest
253 // This function completes irps
257 // A status is returned for the function
261 AFSCompleteRequest( IN PIRP Irp,
265 Irp->IoStatus.Status = Status;
267 IoCompleteRequest( Irp,
274 AFSReadRegistry( IN PUNICODE_STRING RegistryPath)
277 NTSTATUS ntStatus = STATUS_SUCCESS;
279 UNICODE_STRING paramPath;
281 RTL_QUERY_REGISTRY_TABLE paramTable[2];
282 UNICODE_STRING defaultUnicodeName;
283 WCHAR SubKeyString[] = L"\\Parameters";
286 // Setup the paramPath buffer.
289 paramPath.MaximumLength = RegistryPath->Length + sizeof( SubKeyString);
290 paramPath.Buffer = (PWSTR)AFSExAllocatePoolWithTag( PagedPool,
291 paramPath.MaximumLength,
292 AFS_GENERIC_MEMORY_15_TAG);
294 RtlInitUnicodeString( &defaultUnicodeName,
298 // If it exists, setup the path.
301 if( paramPath.Buffer != NULL)
308 RtlCopyMemory( ¶mPath.Buffer[ 0],
309 &RegistryPath->Buffer[ 0],
310 RegistryPath->Length);
312 RtlCopyMemory( ¶mPath.Buffer[ RegistryPath->Length / 2],
314 sizeof( SubKeyString));
316 paramPath.Length = paramPath.MaximumLength;
318 RtlZeroMemory( paramTable,
319 sizeof( paramTable));
324 // Setup the table to query the registry for the needed value
327 paramTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
328 paramTable[0].Name = AFS_REG_DEBUG_FLAGS;
329 paramTable[0].EntryContext = &Value;
331 paramTable[0].DefaultType = REG_DWORD;
332 paramTable[0].DefaultData = &Default;
333 paramTable[0].DefaultLength = sizeof (ULONG) ;
336 // Query the registry
339 ntStatus = RtlQueryRegistryValues( RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL,
345 if( NT_SUCCESS( ntStatus))
348 AFSDebugFlags = Value;
351 RtlZeroMemory( paramTable,
352 sizeof( paramTable));
357 // Setup the table to query the registry for the needed value
360 paramTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
361 paramTable[0].Name = AFS_REG_TRACE_SUBSYSTEM;
362 paramTable[0].EntryContext = &Value;
364 paramTable[0].DefaultType = REG_DWORD;
365 paramTable[0].DefaultData = &Default;
366 paramTable[0].DefaultLength = sizeof (ULONG) ;
369 // Query the registry
372 ntStatus = RtlQueryRegistryValues( RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL,
378 if( NT_SUCCESS( ntStatus))
381 AFSTraceComponent = Value;
384 RtlZeroMemory( paramTable,
385 sizeof( paramTable));
390 // Setup the table to query the registry for the needed value
393 paramTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
394 paramTable[0].Name = AFS_REG_TRACE_BUFFER_LENGTH;
395 paramTable[0].EntryContext = &Value;
397 paramTable[0].DefaultType = REG_DWORD;
398 paramTable[0].DefaultData = &Default;
399 paramTable[0].DefaultLength = sizeof (ULONG);
402 // Query the registry
405 ntStatus = RtlQueryRegistryValues( RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL,
411 if( NT_SUCCESS( ntStatus) &&
415 AFSDbgBufferLength = Value;
418 // Let's limit things a bit ...
421 if( AFSDbgBufferLength > 10240)
424 AFSDbgBufferLength = 1024;
430 AFSDbgBufferLength = 0;
437 AFSDbgBufferLength *= 1024;
440 // Now get ready to set up for MaxServerDirty
443 paramTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
444 paramTable[0].Name = AFS_REG_MAX_DIRTY;
445 paramTable[0].EntryContext = &Value;
447 paramTable[0].DefaultType = REG_DWORD;
448 paramTable[0].DefaultData = &Default;
449 paramTable[0].DefaultLength = sizeof (ULONG) ;
452 // Query the registry
455 ntStatus = RtlQueryRegistryValues( RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL,
461 if( NT_SUCCESS( ntStatus))
464 AFSMaxDirtyFile = Value;
467 RtlZeroMemory( paramTable,
468 sizeof( paramTable));
473 // Setup the table to query the registry for the needed value
476 paramTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
477 paramTable[0].Name = AFS_REG_TRACE_LEVEL;
478 paramTable[0].EntryContext = &Value;
480 paramTable[0].DefaultType = REG_DWORD;
481 paramTable[0].DefaultData = &Default;
482 paramTable[0].DefaultLength = sizeof (ULONG) ;
485 // Query the registry
488 ntStatus = RtlQueryRegistryValues( RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL,
494 if( NT_SUCCESS( ntStatus))
497 AFSTraceLevel = Value;
504 paramTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
505 paramTable[0].Name = AFS_REG_MAX_IO;
506 paramTable[0].EntryContext = &Value;
508 paramTable[0].DefaultType = REG_DWORD;
509 paramTable[0].DefaultData = &Default;
510 paramTable[0].DefaultLength = sizeof (ULONG) ;
513 // Query the registry
516 ntStatus = RtlQueryRegistryValues( RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL,
522 if( NT_SUCCESS( ntStatus))
525 AFSMaxDirectIo = Value;
529 // Now set up for ShutdownStatus query
532 paramTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
533 paramTable[0].Name = AFS_REG_SHUTDOWN_STATUS;
534 paramTable[0].EntryContext = &Value;
536 paramTable[0].DefaultType = REG_DWORD;
537 paramTable[0].DefaultData = &Default;
538 paramTable[0].DefaultLength = sizeof (ULONG) ;
541 // Query the registry
544 ntStatus = RtlQueryRegistryValues( RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL,
550 if( !NT_SUCCESS( ntStatus) ||
554 SetFlag( AFSDebugFlags, AFS_DBG_CLEAN_SHUTDOWN);
558 // Now set up for RequireCleanShutdown query
561 paramTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
562 paramTable[0].Name = AFS_REG_REQUIRE_CLEAN_SHUTDOWN;
563 paramTable[0].EntryContext = &Value;
565 paramTable[0].DefaultType = REG_DWORD;
566 paramTable[0].DefaultData = &Default;
567 paramTable[0].DefaultLength = sizeof (ULONG) ;
570 // Query the registry
573 ntStatus = RtlQueryRegistryValues( RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL,
579 if( !NT_SUCCESS( ntStatus) ||
583 SetFlag( AFSDebugFlags, AFS_DBG_REQUIRE_CLEAN_SHUTDOWN);
587 // Free up the buffer
590 ExFreePool( paramPath.Buffer);
592 ntStatus = STATUS_SUCCESS;
596 ntStatus = STATUS_INSUFFICIENT_RESOURCES;
603 AFSUpdateRegistryParameter( IN PUNICODE_STRING ValueName,
606 IN ULONG ValueDataLength)
609 NTSTATUS ntStatus = STATUS_SUCCESS;
610 UNICODE_STRING paramPath, uniParamKey;
611 HANDLE hParameters = 0;
612 ULONG ulDisposition = 0;
613 OBJECT_ATTRIBUTES stObjectAttributes;
618 RtlInitUnicodeString( &uniParamKey,
622 // Setup the paramPath buffer.
625 paramPath.MaximumLength = AFSRegistryPath.Length + uniParamKey.Length;
626 paramPath.Buffer = (PWSTR)AFSExAllocatePoolWithTag( PagedPool,
627 paramPath.MaximumLength,
628 AFS_GENERIC_MEMORY_16_TAG);
630 if( paramPath.Buffer == NULL)
633 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
640 RtlCopyMemory( paramPath.Buffer,
641 AFSRegistryPath.Buffer,
642 AFSRegistryPath.Length);
644 paramPath.Length = AFSRegistryPath.Length;
646 RtlCopyMemory( ¶mPath.Buffer[ paramPath.Length / 2],
650 paramPath.Length += uniParamKey.Length;
652 InitializeObjectAttributes( &stObjectAttributes,
654 OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
658 ntStatus = ZwOpenKey( &hParameters,
660 &stObjectAttributes);
662 if( !NT_SUCCESS( ntStatus))
665 try_return( ntStatus);
672 ntStatus = ZwSetValueKey( hParameters,
679 ZwClose( hParameters);
683 if( paramPath.Buffer != NULL)
687 // Free up the buffer
690 ExFreePool( paramPath.Buffer);
698 AFSInitializeControlDevice()
701 NTSTATUS ntStatus = STATUS_SUCCESS;
702 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension;
703 AFSProcessCB *pProcessCB = NULL;
709 // Initialize the comm pool resources
712 ExInitializeResourceLite( &pDeviceExt->Specific.Control.CommServiceCB.IrpPoolLock);
714 ExInitializeResourceLite( &pDeviceExt->Specific.Control.CommServiceCB.ResultPoolLock);
716 ExInitializeResourceLite( &pDeviceExt->Specific.Control.ExtentReleaseResource);
718 ExInitializeResourceLite( &pDeviceExt->Specific.Control.SysName32ListLock);
720 ExInitializeResourceLite( &pDeviceExt->Specific.Control.SysName64ListLock);
726 KeInitializeEvent( &pDeviceExt->Specific.Control.CommServiceCB.IrpPoolHasEntries,
727 SynchronizationEvent,
730 KeInitializeEvent( &pDeviceExt->Specific.Control.CommServiceCB.IrpPoolHasReleaseEntries,
731 SynchronizationEvent,
734 KeInitializeEvent( &pDeviceExt->Specific.Control.ExtentReleaseEvent,
738 pDeviceExt->Specific.Control.ExtentReleaseSequence = 0;
740 KeInitializeEvent( &pDeviceExt->Specific.Control.VolumeWorkerCloseEvent,
745 // Library support information
748 KeInitializeEvent( &pDeviceExt->Specific.Control.LoadLibraryEvent,
749 SynchronizationEvent,
753 // Initialize the library queued as cancelled
756 pDeviceExt->Specific.Control.LibraryState = AFS_LIBRARY_QUEUE_CANCELLED;
758 ExInitializeResourceLite( &pDeviceExt->Specific.Control.LibraryStateLock);
760 pDeviceExt->Specific.Control.InflightLibraryRequests = 0;
762 KeInitializeEvent( &pDeviceExt->Specific.Control.InflightLibraryEvent,
766 pDeviceExt->Specific.Control.ExtentCount = 0;
767 pDeviceExt->Specific.Control.ExtentsHeldLength = 0;
769 KeInitializeEvent( &pDeviceExt->Specific.Control.ExtentsHeldEvent,
773 pDeviceExt->Specific.Control.OutstandingServiceRequestCount = 0;
775 KeInitializeEvent( &pDeviceExt->Specific.Control.OutstandingServiceRequestEvent,
779 pDeviceExt->Specific.Control.WaitingForMemoryCount = 0;
781 KeInitializeEvent( &pDeviceExt->Specific.Control.MemoryAvailableEvent,
785 ExInitializeResourceLite( &pDeviceExt->Specific.Control.LibraryQueueLock);
787 pDeviceExt->Specific.Control.LibraryQueueHead = NULL;
789 pDeviceExt->Specific.Control.LibraryQueueTail = NULL;
792 // Set the initial state of the irp pool
795 pDeviceExt->Specific.Control.CommServiceCB.IrpPoolControlFlag = POOL_INACTIVE;
798 // Initialize our process and sid tree information
801 ExInitializeResourceLite( &pDeviceExt->Specific.Control.ProcessTreeLock);
803 pDeviceExt->Specific.Control.ProcessTree.TreeLock = &pDeviceExt->Specific.Control.ProcessTreeLock;
805 pDeviceExt->Specific.Control.ProcessTree.TreeHead = NULL;
807 ExInitializeResourceLite( &pDeviceExt->Specific.Control.AuthGroupTreeLock);
809 pDeviceExt->Specific.Control.AuthGroupTree.TreeLock = &pDeviceExt->Specific.Control.AuthGroupTreeLock;
811 pDeviceExt->Specific.Control.AuthGroupTree.TreeHead = NULL;
818 AFSRemoveControlDevice()
821 NTSTATUS ntStatus = STATUS_SUCCESS;
822 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension;
823 AFSProcessCB *pProcessCB = NULL;
829 // Initialize the comm pool resources
832 ExDeleteResourceLite( &pDeviceExt->Specific.Control.CommServiceCB.IrpPoolLock);
834 ExDeleteResourceLite( &pDeviceExt->Specific.Control.CommServiceCB.ResultPoolLock);
836 ExDeleteResourceLite( &pDeviceExt->Specific.Control.ExtentReleaseResource);
838 ExDeleteResourceLite( &pDeviceExt->Specific.Control.SysName32ListLock);
840 ExDeleteResourceLite( &pDeviceExt->Specific.Control.SysName64ListLock);
842 ExDeleteResourceLite( &pDeviceExt->Specific.Control.ProcessTreeLock);
844 if( pDeviceExt->Specific.Control.ProcessTree.TreeHead != NULL)
846 ExFreePool( pDeviceExt->Specific.Control.ProcessTree.TreeHead);
849 ExDeleteResourceLite( &pDeviceExt->Specific.Control.AuthGroupTreeLock);
851 ExDeleteResourceLite( &pDeviceExt->Specific.Control.LibraryStateLock);
853 ExDeleteResourceLite( &pDeviceExt->Specific.Control.LibraryQueueLock);
860 AFSInitServerStrings()
863 UNICODE_STRING uniFullName;
864 WCHAR wchBuffer[ 50];
867 // Add the server name into the list of resources
870 uniFullName.Length = (2 * sizeof( WCHAR)) + AFSServerName.Length;
871 uniFullName.MaximumLength = uniFullName.Length + sizeof( WCHAR);
873 uniFullName.Buffer = wchBuffer;
875 wchBuffer[ 0] = L'\\';
876 wchBuffer[ 1] = L'\\';
878 RtlCopyMemory( &wchBuffer[ 2],
879 AFSServerName.Buffer,
880 AFSServerName.Length);
882 AFSAddConnectionEx( &uniFullName,
883 RESOURCEDISPLAYTYPE_SERVER,
887 // Add in the global share name
890 wchBuffer[ uniFullName.Length/sizeof( WCHAR)] = L'\\';
892 uniFullName.Length += sizeof( WCHAR);
894 RtlCopyMemory( &wchBuffer[ uniFullName.Length/sizeof( WCHAR)],
895 AFSGlobalRootName.Buffer,
896 AFSGlobalRootName.Length);
898 uniFullName.Length += AFSGlobalRootName.Length;
900 AFSAddConnectionEx( &uniFullName,
901 RESOURCEDISPLAYTYPE_SHARE,
902 AFS_CONNECTION_FLAG_GLOBAL_SHARE);
911 NTSTATUS ntStatus = STATUS_SUCCESS;
913 UNICODE_STRING paramPath;
914 RTL_QUERY_REGISTRY_TABLE paramTable[2];
920 // Setup the paramPath buffer.
923 paramPath.MaximumLength = PAGE_SIZE;
924 paramPath.Buffer = (PWSTR)AFSExAllocatePoolWithTag( PagedPool,
925 paramPath.MaximumLength,
926 AFS_GENERIC_MEMORY_17_TAG);
929 // If it exists, setup the path.
932 if( paramPath.Buffer == NULL)
935 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
942 RtlZeroMemory( paramPath.Buffer,
943 paramPath.MaximumLength);
945 RtlCopyMemory( ¶mPath.Buffer[ 0],
946 L"\\TransarcAFSDaemon\\Parameters",
949 paramPath.Length = 58;
951 RtlZeroMemory( paramTable,
952 sizeof( paramTable));
955 // Setup the table to query the registry for the needed value
958 AFSServerName.Length = 0;
959 AFSServerName.MaximumLength = 0;
960 AFSServerName.Buffer = NULL;
962 paramTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
963 paramTable[0].Name = AFS_NETBIOS_NAME;
964 paramTable[0].EntryContext = &AFSServerName;
966 paramTable[0].DefaultType = REG_NONE;
967 paramTable[0].DefaultData = NULL;
968 paramTable[0].DefaultLength = 0;
971 // Query the registry
974 ntStatus = RtlQueryRegistryValues( RTL_REGISTRY_SERVICES,
981 // Free up the buffer
984 ExFreePool( paramPath.Buffer);
988 if( !NT_SUCCESS( ntStatus))
991 RtlInitUnicodeString( &AFSServerName,
1000 AFSSetSysNameInformation( IN AFSSysNameNotificationCB *SysNameInfo,
1001 IN ULONG SysNameInfoBufferLength)
1004 NTSTATUS ntStatus = STATUS_SUCCESS;
1005 AFSDeviceExt *pControlDevExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension;
1006 AFSSysNameCB *pSysName = NULL;
1007 ERESOURCE *pSysNameLock = NULL;
1008 AFSSysNameCB **pSysNameListHead = NULL, **pSysNameListTail = NULL;
1014 // Depending on the architecture of the information, set up the lsit
1017 if( SysNameInfo->Architecture == AFS_SYSNAME_ARCH_32BIT)
1020 pSysNameLock = &pControlDevExt->Specific.Control.SysName32ListLock;
1022 pSysNameListHead = &pControlDevExt->Specific.Control.SysName32ListHead;
1024 pSysNameListTail = &pControlDevExt->Specific.Control.SysName32ListTail;
1031 pSysNameLock = &pControlDevExt->Specific.Control.SysName64ListLock;
1033 pSysNameListHead = &pControlDevExt->Specific.Control.SysName64ListHead;
1035 pSysNameListTail = &pControlDevExt->Specific.Control.SysName64ListTail;
1039 try_return( ntStatus = STATUS_INVALID_PARAMETER);
1044 // Process the request
1047 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
1048 AFS_TRACE_LEVEL_VERBOSE,
1049 "AFSSetSysNameInformation Acquiring SysName lock %08lX EXCL %08lX\n",
1051 PsGetCurrentThread());
1053 AFSAcquireExcl( pSysNameLock,
1057 // If we already have a list, then tear it down
1060 if( *pSysNameListHead != NULL)
1063 AFSResetSysNameList( *pSysNameListHead);
1065 *pSysNameListHead = NULL;
1069 // Loop through the entries adding in a node for each
1072 while( ulIndex < SysNameInfo->NumberOfNames)
1075 pSysName = (AFSSysNameCB *)AFSExAllocatePoolWithTag( PagedPool,
1076 sizeof( AFSSysNameCB) +
1077 SysNameInfo->SysNames[ ulIndex].Length +
1079 AFS_SYS_NAME_NODE_TAG);
1081 if( pSysName == NULL)
1085 // Reset the current list
1088 AFSResetSysNameList( *pSysNameListHead);
1090 *pSysNameListHead = NULL;
1092 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1095 RtlZeroMemory( pSysName,
1096 sizeof( AFSSysNameCB) +
1097 SysNameInfo->SysNames[ ulIndex].Length +
1100 pSysName->SysName.Length = (USHORT)SysNameInfo->SysNames[ ulIndex].Length;
1102 pSysName->SysName.MaximumLength = pSysName->SysName.Length + sizeof( WCHAR);
1104 pSysName->SysName.Buffer = (WCHAR *)((char *)pSysName + sizeof( AFSSysNameCB));
1106 RtlCopyMemory( pSysName->SysName.Buffer,
1107 SysNameInfo->SysNames[ ulIndex].String,
1108 pSysName->SysName.Length);
1110 if( *pSysNameListHead == NULL)
1113 *pSysNameListHead = pSysName;
1118 (*pSysNameListTail)->fLink = pSysName;
1121 *pSysNameListTail = pSysName;
1128 AFSReleaseResource( pSysNameLock);
1135 AFSResetSysNameList( IN AFSSysNameCB *SysNameList)
1138 AFSSysNameCB *pNextEntry = NULL, *pCurrentEntry = SysNameList;
1140 while( pCurrentEntry != NULL)
1143 pNextEntry = pCurrentEntry->fLink;
1145 ExFreePool( pCurrentEntry);
1147 pCurrentEntry = pNextEntry;
1154 AFSDefaultDispatch( IN PDEVICE_OBJECT DeviceObject,
1158 NTSTATUS ntStatus = STATUS_INVALID_DEVICE_REQUEST;
1159 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1161 AFSCompleteRequest( Irp,
1168 AFSSendDeviceIoControl( IN DEVICE_OBJECT *TargetDeviceObject,
1170 IN void *InputBuffer,
1171 IN ULONG InputBufferLength,
1172 IN OUT void *OutputBuffer,
1173 IN ULONG OutputBufferLength,
1174 OUT ULONG *ResultLength)
1177 NTSTATUS ntStatus = STATUS_SUCCESS;
1180 PIO_STACK_LOCATION pIoStackLocation = NULL;
1186 // Initialize the event
1189 KeInitializeEvent( &kEvent,
1190 SynchronizationEvent,
1194 // Allocate an irp for this request. This could also come from a
1195 // private pool, for instance.
1198 pIrp = IoAllocateIrp( TargetDeviceObject->StackSize,
1204 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1208 // Build the IRP's main body
1211 pIrp->RequestorMode = KernelMode;
1214 // Set up the I/O stack location.
1217 pIoStackLocation = IoGetNextIrpStackLocation( pIrp);
1218 pIoStackLocation->MajorFunction = IRP_MJ_DEVICE_CONTROL;
1219 pIoStackLocation->DeviceObject = TargetDeviceObject;
1221 pIoStackLocation->Parameters.DeviceIoControl.IoControlCode = IOControl;
1223 pIrp->AssociatedIrp.SystemBuffer = (void *)InputBuffer;
1224 pIoStackLocation->Parameters.DeviceIoControl.InputBufferLength = InputBufferLength;
1227 // Set the completion routine.
1230 IoSetCompletionRoutine( pIrp,
1238 // Send it to the FSD
1241 ntStatus = IoCallDriver( TargetDeviceObject,
1244 if( NT_SUCCESS( ntStatus))
1251 ntStatus = KeWaitForSingleObject( &kEvent,
1257 if( NT_SUCCESS( ntStatus))
1260 ntStatus = pIrp->IoStatus.Status;
1262 if( ResultLength != NULL)
1264 *ResultLength = (ULONG)pIrp->IoStatus.Information;
1274 if( pIrp->MdlAddress != NULL)
1277 if( FlagOn( pIrp->MdlAddress->MdlFlags, MDL_PAGES_LOCKED))
1280 MmUnlockPages( pIrp->MdlAddress);
1283 IoFreeMdl( pIrp->MdlAddress);
1286 pIrp->MdlAddress = NULL;
1300 AFSIrpComplete( IN PDEVICE_OBJECT DeviceObject,
1305 KEVENT *pEvent = (KEVENT *)Context;
1311 return STATUS_MORE_PROCESSING_REQUIRED;
1315 AFSExAllocatePoolWithTag( IN POOL_TYPE PoolType,
1316 IN SIZE_T NumberOfBytes,
1320 AFSDeviceExt *pControlDevExt = NULL;
1321 void *pBuffer = NULL;
1322 BOOLEAN bTimeout = FALSE;
1323 LARGE_INTEGER liTimeout;
1327 // Attempt to allocation memory from the system. If the allocation fails
1328 // wait up to 30 seconds for the AFS redirector to free some memory. As
1329 // long as the wait does not timeout, continue to retry the allocation.
1330 // If the wait does timeout, attempt to allocate one more time in case
1331 // memory was freed by another driver. Otherwise, fail the request.
1334 if ( AFSDeviceObject)
1337 pControlDevExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension;
1340 while( pBuffer == NULL)
1343 pBuffer = ExAllocatePoolWithTag( PoolType,
1347 if( pBuffer == NULL)
1350 if ( bTimeout || pControlDevExt == NULL)
1355 "AFSExAllocatePoolWithTag failure Type %08lX Size %08lX Tag %08lX %08lX\n",
1359 PsGetCurrentThread());
1363 case AFS_GENERIC_MEMORY_21_TAG:
1364 case AFS_GENERIC_MEMORY_22_TAG:
1365 // AFSDumpTraceFiles -- do nothing;
1377 // Wait up to 30 seconds for a memory deallocation
1380 liTimeout.QuadPart = -(30 *AFS_ONE_SECOND);
1382 if( InterlockedIncrement( &pControlDevExt->Specific.Control.WaitingForMemoryCount) == 1)
1384 KeClearEvent( &pControlDevExt->Specific.Control.MemoryAvailableEvent);
1387 ntStatus = KeWaitForSingleObject( &pControlDevExt->Specific.Control.MemoryAvailableEvent,
1393 if( ntStatus == STATUS_TIMEOUT)
1399 InterlockedDecrement( &pControlDevExt->Specific.Control.WaitingForMemoryCount);
1407 AFSExFreePoolWithTag( IN void *Buffer, IN ULONG Tag)
1410 AFSDeviceExt *pControlDevExt = NULL;
1412 if ( AFSDeviceObject)
1415 pControlDevExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension;
1421 ExFreePoolWithTag( Buffer, Tag);
1426 ExFreePool( Buffer);
1429 if ( pControlDevExt)
1432 KeSetEvent( &pControlDevExt->Specific.Control.MemoryAvailableEvent,
1440 AFSShutdownRedirector()
1443 NTSTATUS ntStatus = STATUS_SUCCESS;
1444 AFSDeviceExt *pRDRDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1445 AFSDeviceExt *pControlDevExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension;
1446 LARGE_INTEGER liTimeout;
1451 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1452 AFS_TRACE_LEVEL_VERBOSE,
1453 "%s Shutting down redirector Extent count %08lX Request count %08lX\n",
1455 pControlDevExt->Specific.Control.ExtentCount,
1456 pControlDevExt->Specific.Control.OutstandingServiceRequestCount);
1459 // Set the shutdown flag so the worker is more agressive in tearing down extents
1462 SetFlag( pRDRDevExt->DeviceFlags, AFS_DEVICE_FLAG_REDIRECTOR_SHUTDOWN);
1465 // Wait on any outstanding service requests
1468 liTimeout.QuadPart = -(30 *AFS_ONE_SECOND);
1470 ntStatus = KeWaitForSingleObject( &pControlDevExt->Specific.Control.OutstandingServiceRequestEvent,
1476 if( ntStatus == STATUS_TIMEOUT)
1479 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1480 AFS_TRACE_LEVEL_WARNING,
1481 "AFSShutdownRedirector Failed to complete all service requests Remaining count %08lX\n",
1482 pControlDevExt->Specific.Control.OutstandingServiceRequestCount);
1484 try_return( ntStatus = STATUS_UNSUCCESSFUL);
1487 AFSProcessQueuedResults( TRUE);
1490 // Wait for all extents to be released
1493 liTimeout.QuadPart = -(30 *AFS_ONE_SECOND);
1495 ntStatus = KeWaitForSingleObject( &pControlDevExt->Specific.Control.ExtentsHeldEvent,
1501 if( ntStatus == STATUS_TIMEOUT)
1504 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1505 AFS_TRACE_LEVEL_WARNING,
1506 "AFSShutdownRedirector Failed to purge all extents Remaining count %08lX\n",
1507 pControlDevExt->Specific.Control.ExtentCount);
1509 try_return( ntStatus = STATUS_UNSUCCESSFUL);
1512 ntStatus = AFSUnloadLibrary( TRUE);
1514 if( !NT_SUCCESS( ntStatus))
1517 try_return( ntStatus);
1522 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1523 AFS_TRACE_LEVEL_VERBOSE,
1524 "%s Completed shut down of redirector Extent count %08lX Request count %08lX Status %08lX\n",
1526 pControlDevExt->Specific.Control.ExtentCount,
1527 pControlDevExt->Specific.Control.OutstandingServiceRequestCount,
1535 // Cache manager callback routines
1539 AFSAcquireFcbForLazyWrite( IN PVOID Fcb,
1543 BOOLEAN bStatus = FALSE;
1544 AFSFcb *pFcb = (AFSFcb *)Fcb;
1545 BOOLEAN bReleaseMain = FALSE, bReleasePaging = FALSE;
1548 // Try and acquire the Fcb resource
1551 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
1552 AFS_TRACE_LEVEL_VERBOSE,
1553 "AFSAcquireFcbForLazyWrite Acquiring Fcb %08lX\n",
1556 ASSERT( NULL == pFcb->Specific.File.LazyWriterThread);
1558 pFcb->Specific.File.LazyWriterThread = PsGetCurrentThread();
1560 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
1561 AFS_TRACE_LEVEL_VERBOSE,
1562 "AFSAcquireFcbForLazyWrite Attempt to acquire Fcb lock %08lX SHARED %08lX\n",
1563 &pFcb->NPFcb->Resource,
1564 PsGetCurrentThread());
1566 if( AFSAcquireShared( &pFcb->NPFcb->Resource,
1570 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
1571 AFS_TRACE_LEVEL_VERBOSE,
1572 "AFSAcquireFcbForLazyWrite Acquired Fcb lock %08lX SHARED %08lX\n",
1573 &pFcb->NPFcb->Resource,
1574 PsGetCurrentThread());
1576 bReleaseMain = TRUE;
1579 // Try and grab the paging
1582 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
1583 AFS_TRACE_LEVEL_VERBOSE,
1584 "AFSAcquireFcbForLazyWrite Attempt to acquire Fcb PagingIo lock %08lX SHARED %08lX\n",
1585 &pFcb->NPFcb->PagingResource,
1586 PsGetCurrentThread());
1588 if( AFSAcquireShared( &pFcb->NPFcb->PagingResource,
1592 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
1593 AFS_TRACE_LEVEL_VERBOSE,
1594 "AFSAcquireFcbForLazyWrite Acquired Fcb PagingIo lock %08lX SHARED %08lX\n",
1595 &pFcb->NPFcb->PagingResource,
1596 PsGetCurrentThread());
1598 bReleasePaging = TRUE;
1606 IoSetTopLevelIrp( (PIRP)FSRTL_CACHE_TOP_LEVEL_IRP);
1616 AFSReleaseResource( &pFcb->NPFcb->Resource);
1622 AFSReleaseResource( &pFcb->NPFcb->PagingResource);
1630 AFSReleaseFcbFromLazyWrite( IN PVOID Fcb)
1633 AFSFcb *pFcb = (AFSFcb *)Fcb;
1635 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
1636 AFS_TRACE_LEVEL_VERBOSE,
1637 "AFSReleaseFcbFromLazyWrite Releasing Fcb %08lX\n",
1640 IoSetTopLevelIrp( NULL);
1642 ASSERT( PsGetCurrentThread() == pFcb->Specific.File.LazyWriterThread);
1644 pFcb->Specific.File.LazyWriterThread = NULL;
1647 AFSReleaseResource( &pFcb->NPFcb->PagingResource);
1649 AFSReleaseResource( &pFcb->NPFcb->Resource);
1655 AFSAcquireFcbForReadAhead( IN PVOID Fcb,
1659 BOOLEAN bStatus = FALSE;
1660 AFSFcb *pFcb = (AFSFcb *)Fcb;
1662 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
1663 AFS_TRACE_LEVEL_VERBOSE,
1664 "AFSAcquireFcbForReadAhead Attempt to acquire Fcb lock %08lX SHARED %08lX\n",
1665 &pFcb->NPFcb->Resource,
1666 PsGetCurrentThread());
1668 if( AFSAcquireShared( &pFcb->NPFcb->Resource,
1672 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
1673 AFS_TRACE_LEVEL_VERBOSE,
1674 "AFSAcquireFcbForReadAhead Acquired Fcb lock %08lX SHARED %08lX\n",
1675 &pFcb->NPFcb->Resource,
1676 PsGetCurrentThread());
1680 IoSetTopLevelIrp( (PIRP)FSRTL_CACHE_TOP_LEVEL_IRP);
1687 AFSReleaseFcbFromReadAhead( IN PVOID Fcb)
1690 AFSFcb *pFcb = (AFSFcb *)Fcb;
1692 IoSetTopLevelIrp( NULL);
1694 AFSReleaseResource( &pFcb->NPFcb->Resource);
1700 AFSGetCallerSID( OUT UNICODE_STRING *SIDString, OUT BOOLEAN *pbImpersonation)
1703 NTSTATUS ntStatus = STATUS_SUCCESS;
1704 PACCESS_TOKEN hToken = NULL;
1705 TOKEN_USER *pTokenInfo = NULL;
1706 BOOLEAN bCopyOnOpen = FALSE;
1707 BOOLEAN bEffectiveOnly = FALSE;
1708 BOOLEAN bPrimaryToken = FALSE;
1709 SECURITY_IMPERSONATION_LEVEL stImpersonationLevel;
1710 UNICODE_STRING uniSIDString;
1715 hToken = PsReferenceImpersonationToken( PsGetCurrentThread(),
1718 &stImpersonationLevel);
1723 hToken = PsReferencePrimaryToken( PsGetCurrentProcess());
1728 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1729 AFS_TRACE_LEVEL_ERROR,
1730 "AFSGetCallerSID Failed to retrieve impersonation or primary token\n");
1732 try_return( ntStatus);
1735 bPrimaryToken = TRUE;
1738 ntStatus = SeQueryInformationToken( hToken,
1740 (PVOID *)&pTokenInfo);
1742 if( !NT_SUCCESS( ntStatus))
1745 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1746 AFS_TRACE_LEVEL_ERROR,
1747 "AFSGetCallerSID Failed to retrieve information Status %08lX\n", ntStatus);
1749 try_return( ntStatus);
1752 uniSIDString.Length = 0;
1753 uniSIDString.MaximumLength = 0;
1754 uniSIDString.Buffer = NULL;
1756 ntStatus = RtlConvertSidToUnicodeString( &uniSIDString,
1757 pTokenInfo->User.Sid,
1760 if( !NT_SUCCESS( ntStatus))
1763 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1764 AFS_TRACE_LEVEL_ERROR,
1765 "AFSGetCallerSID Failed to convert sid to string Status %08lX\n", ntStatus);
1767 try_return( ntStatus);
1770 *SIDString = uniSIDString;
1772 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING | AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
1773 AFS_TRACE_LEVEL_VERBOSE_2,
1774 "AFSGetCallerSID Successfully retrieved SID %wZ\n",
1777 if ( bPrimaryToken == FALSE &&
1780 *pbImpersonation = TRUE;
1789 PsDereferencePrimaryToken( hToken);
1793 PsDereferenceImpersonationToken( hToken);
1797 if( pTokenInfo != NULL)
1799 ExFreePool( pTokenInfo); // Allocated by SeQueryInformationToken
1807 AFSGetSessionId( IN HANDLE ProcessId, OUT BOOLEAN *pbImpersonation)
1810 NTSTATUS ntStatus = STATUS_SUCCESS;
1811 PACCESS_TOKEN hToken = NULL;
1812 ULONG ulSessionId = (ULONG)-1;
1813 BOOLEAN bCopyOnOpen = FALSE;
1814 BOOLEAN bEffectiveOnly = FALSE;
1815 BOOLEAN bPrimaryToken = FALSE;
1816 SECURITY_IMPERSONATION_LEVEL stImpersonationLevel;
1821 hToken = PsReferenceImpersonationToken( PsGetCurrentThread(),
1824 &stImpersonationLevel);
1829 hToken = PsReferencePrimaryToken( PsGetCurrentProcess());
1834 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1835 AFS_TRACE_LEVEL_ERROR,
1836 "AFSGetSessionId Failed to retrieve impersonation or primary token\n");
1838 try_return( ntStatus);
1841 bPrimaryToken = TRUE;
1844 ntStatus = SeQueryInformationToken( hToken,
1846 (PVOID *)&ulSessionId);
1848 if( !NT_SUCCESS( ntStatus))
1850 ulSessionId = (ULONG)-1;
1852 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1853 AFS_TRACE_LEVEL_ERROR,
1854 "AFSGetSessionId Failed to retrieve session id Status %08lX\n",
1857 try_return( ntStatus);
1860 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING | AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
1861 AFS_TRACE_LEVEL_VERBOSE_2,
1862 "AFSGetSessionId found %08lX\n",
1865 if ( bPrimaryToken == FALSE &&
1868 *pbImpersonation = TRUE;
1877 PsDereferencePrimaryToken( hToken);
1881 PsDereferenceImpersonationToken( hToken);
1890 AFSCheckThreadDacl( OUT GUID *AuthGroup)
1893 NTSTATUS ntStatus = STATUS_UNSUCCESSFUL;
1895 PACCESS_TOKEN token = NULL;
1896 PTOKEN_DEFAULT_DACL defDacl = NULL;
1898 PACCESS_ALLOWED_ACE adace;
1899 BOOLEAN bCopyOnOpen = FALSE, bEffectiveOnly = FALSE;
1900 SECURITY_IMPERSONATION_LEVEL stImpersonationLevel;
1901 BOOLEAN bLocatedACE = FALSE;
1906 token = PsReferenceImpersonationToken( PsGetCurrentThread(),
1909 &stImpersonationLevel);
1913 try_return( ntStatus);
1916 ntStatus = SeQueryInformationToken( token,
1920 if( ntStatus != STATUS_SUCCESS)
1922 try_return( ntStatus);
1925 // scan through all ACEs in the DACL
1926 for (idx = 0, ace = (PACE_HEADER)((char *)defDacl->DefaultDacl + sizeof(ACL)); idx < defDacl->DefaultDacl->AceCount; idx++)
1928 if (ace->AceType == ACCESS_ALLOWED_ACE_TYPE)
1930 adace = (PACCESS_ALLOWED_ACE)ace;
1932 if (adace->Header.AceSize == (FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + AFS_DACL_SID_LENGTH))
1934 if (RtlCompareMemory( RtlSubAuthoritySid((PSID)&adace->SidStart, 0), &AFSSidGuid, sizeof(GUID)) == sizeof(GUID))
1937 RtlCopyMemory( AuthGroup,
1938 RtlSubAuthoritySid((PSID)&adace->SidStart, 4),
1949 ace = (PACE_HEADER)((char *)ace + ace->AceSize);
1956 PsDereferenceImpersonationToken( token);
1959 if (defDacl != NULL)
1961 ExFreePool(defDacl);
1966 ntStatus = STATUS_UNSUCCESSFUL;
1974 AFSProcessSetProcessDacl( IN AFSProcessCB *ProcessCB)
1977 PTOKEN_DEFAULT_DACL defDacl = NULL;
1978 HANDLE hToken = NULL;
1979 PACE_HEADER ace = NULL;
1980 SID_IDENTIFIER_AUTHORITY sia = SECURITY_NT_AUTHORITY;
1981 PACCESS_ALLOWED_ACE aaace;
1983 ULONG bytesReturned;
1986 NTSTATUS ntStatus = STATUS_SUCCESS;
1991 ntStatus = ZwOpenProcessTokenEx( NtCurrentProcess(),
1996 if( !NT_SUCCESS( ntStatus))
1998 try_return( ntStatus);
2001 // get the size of the current DACL
2002 ntStatus = ZwQueryInformationToken( hToken,
2008 // if we failed to get the buffer size needed
2009 if ((ntStatus != STATUS_SUCCESS) && (ntStatus != STATUS_BUFFER_TOO_SMALL))
2011 try_return( ntStatus);
2014 // tack on enough space for our ACE if we need to add it...
2015 bytesNeeded += FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + AFS_DACL_SID_LENGTH;
2017 // allocate space for the DACL
2018 defDacl = (PTOKEN_DEFAULT_DACL)ExAllocatePoolWithTag( PagedPool, bytesNeeded, AFS_GENERIC_MEMORY_26_TAG);
2020 if (defDacl == NULL)
2022 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2026 ntStatus = ZwQueryInformationToken( hToken,
2032 if( ntStatus != STATUS_SUCCESS)
2034 try_return( ntStatus);
2037 // scan through DACL to see if we have the SID set already...
2038 ace = (PACE_HEADER)((char *)defDacl->DefaultDacl + sizeof(ACL));
2039 for (idx = 0; idx < defDacl->DefaultDacl->AceCount; idx++)
2041 if (ace->AceType == ACCESS_ALLOWED_ACE_TYPE)
2043 aaace = (PACCESS_ALLOWED_ACE)ace;
2045 if (aaace->Header.AceSize == (FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + AFS_DACL_SID_LENGTH))
2047 // if the GUID part matches
2048 if( RtlCompareMemory( RtlSubAuthoritySid((PSID)&aaace->SidStart, 0),
2050 sizeof(GUID)) == sizeof(GUID))
2053 if ( RtlCompareMemory( RtlSubAuthoritySid((PSID)&aaace->SidStart, 4),
2054 ProcessCB->ActiveAuthGroup,
2055 sizeof( GUID)) != sizeof( GUID))
2058 RtlCopyMemory( RtlSubAuthoritySid((PSID)&aaace->SidStart, 4),
2059 ProcessCB->ActiveAuthGroup,
2062 if( AFSSetInformationToken != NULL)
2064 ntStatus = AFSSetInformationToken( hToken,
2071 try_return( ntStatus);
2077 ace = (PACE_HEADER)((char *)ace + ace->AceSize);
2081 // if we made it here we need to add a new ACE to the DACL
2084 aaace = (ACCESS_ALLOWED_ACE *)ace;
2085 aaace->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
2086 aaace->Header.AceFlags = 0;
2087 aaace->Mask = GENERIC_ALL;
2088 psid = (PSID)&aaace->SidStart;
2089 RtlInitializeSid( psid, &sia, 8);
2091 RtlCopyMemory( RtlSubAuthoritySid(psid, 0),
2095 RtlCopyMemory( RtlSubAuthoritySid(psid, 4),
2096 ProcessCB->ActiveAuthGroup,
2099 aaace->Header.AceSize = (USHORT)(FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + RtlLengthSid( psid));
2101 defDacl->DefaultDacl->AclSize += aaace->Header.AceSize;
2102 defDacl->DefaultDacl->AceCount++;
2104 if( AFSSetInformationToken != NULL)
2106 ntStatus = AFSSetInformationToken( hToken,
2109 defDacl->DefaultDacl->AclSize + sizeof(PTOKEN_DEFAULT_DACL));
2119 if (defDacl != NULL)
2121 ExFreePool( defDacl);