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 ULONG Code,
55 IN PEXCEPTION_POINTERS ExceptPtrs)
58 PEXCEPTION_RECORD ExceptRec;
64 ExceptRec = ExceptPtrs->ExceptionRecord;
66 Context = ExceptPtrs->ContextRecord;
70 "AFSExceptionFilter (Framework) - EXR %p CXR %p Code %08lX Address %p\n",
73 ExceptRec->ExceptionCode,
74 ExceptRec->ExceptionAddress);
76 DbgPrint("**** Exception Caught in AFS Redirector ****\n");
78 DbgPrint("\n\nPerform the following WnDbg Cmds:\n");
79 DbgPrint("\n\t.exr %p ; .cxr %p\n\n", ExceptRec, Context);
81 DbgPrint("**** Exception Complete from AFS Redirector ****\n");
83 if( BooleanFlagOn( AFSDebugFlags, AFS_DBG_BUGCHECK_EXCEPTION))
86 KeBugCheck( (ULONG)-2);
94 __except( EXCEPTION_EXECUTE_HANDLER)
100 return EXCEPTION_EXECUTE_HANDLER;
104 // Function: AFSAcquireExcl()
106 // Purpose: Called to acquire a resource exclusive with optional wait
109 // PERESOURCE Resource - Resource to acquire
110 // BOOLEAN Wait - Whether to block
113 // BOOLEAN - Whether the mask was acquired
117 AFSAcquireExcl( IN PERESOURCE Resource,
121 BOOLEAN bStatus = FALSE;
124 // Normal kernel APCs must be disabled before calling
125 // ExAcquireResourceExclusiveLite. Otherwise a bugcheck occurs.
128 KeEnterCriticalRegion();
130 bStatus = ExAcquireResourceExclusiveLite( Resource,
136 KeLeaveCriticalRegion();
143 AFSAcquireSharedStarveExclusive( IN PERESOURCE Resource,
147 BOOLEAN bStatus = FALSE;
149 KeEnterCriticalRegion();
151 bStatus = ExAcquireSharedStarveExclusive( Resource,
157 KeLeaveCriticalRegion();
164 // Function: AFSAcquireShared()
166 // Purpose: Called to acquire a resource shared with optional wait
169 // PERESOURCE Resource - Resource to acquire
170 // BOOLEAN Wait - Whether to block
173 // BOOLEAN - Whether the mask was acquired
177 AFSAcquireShared( IN PERESOURCE Resource,
181 BOOLEAN bStatus = FALSE;
183 KeEnterCriticalRegion();
185 bStatus = ExAcquireResourceSharedLite( Resource,
191 KeLeaveCriticalRegion();
198 // Function: AFSReleaseResource()
200 // Purpose: Called to release a resource
203 // PERESOURCE Resource - Resource to release
210 AFSReleaseResource( IN PERESOURCE Resource)
213 if( Resource != &AFSDbgLogLock)
216 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
217 AFS_TRACE_LEVEL_VERBOSE,
218 "AFSReleaseResource Releasing lock %08lX Thread %08lX\n",
220 PsGetCurrentThread());
223 ExReleaseResourceLite( Resource);
225 KeLeaveCriticalRegion();
231 AFSConvertToShared( IN PERESOURCE Resource)
234 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
235 AFS_TRACE_LEVEL_VERBOSE,
236 "AFSConvertToShared Converting lock %08lX Thread %08lX\n",
238 PsGetCurrentThread());
240 ExConvertExclusiveToSharedLite( Resource);
246 // Function: AFSCompleteRequest
250 // This function completes irps
254 // A status is returned for the function
258 AFSCompleteRequest( IN PIRP Irp,
262 Irp->IoStatus.Status = Status;
264 IoCompleteRequest( Irp,
271 AFSReadRegistry( IN PUNICODE_STRING RegistryPath)
274 NTSTATUS ntStatus = STATUS_SUCCESS;
276 UNICODE_STRING paramPath;
278 RTL_QUERY_REGISTRY_TABLE paramTable[2];
279 UNICODE_STRING defaultUnicodeName;
280 WCHAR SubKeyString[] = L"\\Parameters";
283 // Setup the paramPath buffer.
286 paramPath.MaximumLength = RegistryPath->Length + sizeof( SubKeyString);
287 paramPath.Buffer = (PWSTR)AFSExAllocatePoolWithTag( PagedPool,
288 paramPath.MaximumLength,
289 AFS_GENERIC_MEMORY_15_TAG);
291 RtlInitUnicodeString( &defaultUnicodeName,
295 // If it exists, setup the path.
298 if( paramPath.Buffer != NULL)
305 RtlCopyMemory( ¶mPath.Buffer[ 0],
306 &RegistryPath->Buffer[ 0],
307 RegistryPath->Length);
309 RtlCopyMemory( ¶mPath.Buffer[ RegistryPath->Length / 2],
311 sizeof( SubKeyString));
313 paramPath.Length = paramPath.MaximumLength;
315 RtlZeroMemory( paramTable,
316 sizeof( paramTable));
321 // Setup the table to query the registry for the needed value
324 paramTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
325 paramTable[0].Name = AFS_REG_DEBUG_FLAGS;
326 paramTable[0].EntryContext = &Value;
328 paramTable[0].DefaultType = REG_DWORD;
329 paramTable[0].DefaultData = &Default;
330 paramTable[0].DefaultLength = sizeof (ULONG) ;
333 // Query the registry
336 ntStatus = RtlQueryRegistryValues( RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL,
342 if( NT_SUCCESS( ntStatus))
345 AFSDebugFlags = Value;
348 RtlZeroMemory( paramTable,
349 sizeof( paramTable));
354 // Setup the table to query the registry for the needed value
357 paramTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
358 paramTable[0].Name = AFS_REG_TRACE_SUBSYSTEM;
359 paramTable[0].EntryContext = &Value;
361 paramTable[0].DefaultType = REG_DWORD;
362 paramTable[0].DefaultData = &Default;
363 paramTable[0].DefaultLength = sizeof (ULONG) ;
366 // Query the registry
369 ntStatus = RtlQueryRegistryValues( RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL,
375 if( NT_SUCCESS( ntStatus))
378 AFSTraceComponent = Value;
381 RtlZeroMemory( paramTable,
382 sizeof( paramTable));
387 // Setup the table to query the registry for the needed value
390 paramTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
391 paramTable[0].Name = AFS_REG_TRACE_BUFFER_LENGTH;
392 paramTable[0].EntryContext = &Value;
394 paramTable[0].DefaultType = REG_DWORD;
395 paramTable[0].DefaultData = &Default;
396 paramTable[0].DefaultLength = sizeof (ULONG);
399 // Query the registry
402 ntStatus = RtlQueryRegistryValues( RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL,
408 if( NT_SUCCESS( ntStatus) &&
412 AFSDbgBufferLength = Value;
415 // Let's limit things a bit ...
418 if( AFSDbgBufferLength > 10240)
421 AFSDbgBufferLength = 1024;
427 AFSDbgBufferLength = 0;
434 AFSDbgBufferLength *= 1024;
437 // Now get ready to set up for MaxServerDirty
440 paramTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
441 paramTable[0].Name = AFS_REG_MAX_DIRTY;
442 paramTable[0].EntryContext = &Value;
444 paramTable[0].DefaultType = REG_DWORD;
445 paramTable[0].DefaultData = &Default;
446 paramTable[0].DefaultLength = sizeof (ULONG) ;
449 // Query the registry
452 ntStatus = RtlQueryRegistryValues( RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL,
458 if( NT_SUCCESS( ntStatus))
461 AFSMaxDirtyFile = Value;
464 RtlZeroMemory( paramTable,
465 sizeof( paramTable));
470 // Setup the table to query the registry for the needed value
473 paramTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
474 paramTable[0].Name = AFS_REG_TRACE_LEVEL;
475 paramTable[0].EntryContext = &Value;
477 paramTable[0].DefaultType = REG_DWORD;
478 paramTable[0].DefaultData = &Default;
479 paramTable[0].DefaultLength = sizeof (ULONG) ;
482 // Query the registry
485 ntStatus = RtlQueryRegistryValues( RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL,
491 if( NT_SUCCESS( ntStatus))
494 AFSTraceLevel = Value;
501 paramTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
502 paramTable[0].Name = AFS_REG_MAX_IO;
503 paramTable[0].EntryContext = &Value;
505 paramTable[0].DefaultType = REG_DWORD;
506 paramTable[0].DefaultData = &Default;
507 paramTable[0].DefaultLength = sizeof (ULONG) ;
510 // Query the registry
513 ntStatus = RtlQueryRegistryValues( RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL,
519 if( NT_SUCCESS( ntStatus))
522 AFSMaxDirectIo = Value;
526 // Now set up for ShutdownStatus query
529 paramTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
530 paramTable[0].Name = AFS_REG_SHUTDOWN_STATUS;
531 paramTable[0].EntryContext = &Value;
533 paramTable[0].DefaultType = REG_DWORD;
534 paramTable[0].DefaultData = &Default;
535 paramTable[0].DefaultLength = sizeof (ULONG) ;
538 // Query the registry
541 ntStatus = RtlQueryRegistryValues( RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL,
547 if( !NT_SUCCESS( ntStatus) ||
551 SetFlag( AFSDebugFlags, AFS_DBG_CLEAN_SHUTDOWN);
555 // Now set up for RequireCleanShutdown query
558 paramTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
559 paramTable[0].Name = AFS_REG_REQUIRE_CLEAN_SHUTDOWN;
560 paramTable[0].EntryContext = &Value;
562 paramTable[0].DefaultType = REG_DWORD;
563 paramTable[0].DefaultData = &Default;
564 paramTable[0].DefaultLength = sizeof (ULONG) ;
567 // Query the registry
570 ntStatus = RtlQueryRegistryValues( RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL,
576 if( !NT_SUCCESS( ntStatus) ||
580 SetFlag( AFSDebugFlags, AFS_DBG_REQUIRE_CLEAN_SHUTDOWN);
584 // Free up the buffer
587 ExFreePool( paramPath.Buffer);
589 ntStatus = STATUS_SUCCESS;
593 ntStatus = STATUS_INSUFFICIENT_RESOURCES;
600 AFSUpdateRegistryParameter( IN PUNICODE_STRING ValueName,
603 IN ULONG ValueDataLength)
606 NTSTATUS ntStatus = STATUS_SUCCESS;
607 UNICODE_STRING paramPath, uniParamKey;
608 HANDLE hParameters = 0;
609 ULONG ulDisposition = 0;
610 OBJECT_ATTRIBUTES stObjectAttributes;
615 RtlInitUnicodeString( &uniParamKey,
619 // Setup the paramPath buffer.
622 paramPath.MaximumLength = AFSRegistryPath.Length + uniParamKey.Length;
623 paramPath.Buffer = (PWSTR)AFSExAllocatePoolWithTag( PagedPool,
624 paramPath.MaximumLength,
625 AFS_GENERIC_MEMORY_16_TAG);
627 if( paramPath.Buffer == NULL)
630 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
637 RtlCopyMemory( paramPath.Buffer,
638 AFSRegistryPath.Buffer,
639 AFSRegistryPath.Length);
641 paramPath.Length = AFSRegistryPath.Length;
643 RtlCopyMemory( ¶mPath.Buffer[ paramPath.Length / 2],
647 paramPath.Length += uniParamKey.Length;
649 InitializeObjectAttributes( &stObjectAttributes,
651 OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
655 ntStatus = ZwOpenKey( &hParameters,
657 &stObjectAttributes);
659 if( !NT_SUCCESS( ntStatus))
662 try_return( ntStatus);
669 ntStatus = ZwSetValueKey( hParameters,
676 ZwClose( hParameters);
680 if( paramPath.Buffer != NULL)
684 // Free up the buffer
687 ExFreePool( paramPath.Buffer);
695 AFSInitializeControlDevice()
698 NTSTATUS ntStatus = STATUS_SUCCESS;
699 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension;
700 AFSProcessCB *pProcessCB = NULL;
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;
815 AFSRemoveControlDevice()
818 NTSTATUS ntStatus = STATUS_SUCCESS;
819 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension;
820 AFSProcessCB *pProcessCB = NULL;
826 // Initialize the comm pool resources
829 ExDeleteResourceLite( &pDeviceExt->Specific.Control.CommServiceCB.IrpPoolLock);
831 ExDeleteResourceLite( &pDeviceExt->Specific.Control.CommServiceCB.ResultPoolLock);
833 ExDeleteResourceLite( &pDeviceExt->Specific.Control.ExtentReleaseResource);
835 ExDeleteResourceLite( &pDeviceExt->Specific.Control.SysName32ListLock);
837 ExDeleteResourceLite( &pDeviceExt->Specific.Control.SysName64ListLock);
839 ExDeleteResourceLite( &pDeviceExt->Specific.Control.ProcessTreeLock);
841 if( pDeviceExt->Specific.Control.ProcessTree.TreeHead != NULL)
843 ExFreePool( pDeviceExt->Specific.Control.ProcessTree.TreeHead);
846 ExDeleteResourceLite( &pDeviceExt->Specific.Control.AuthGroupTreeLock);
848 ExDeleteResourceLite( &pDeviceExt->Specific.Control.LibraryStateLock);
850 ExDeleteResourceLite( &pDeviceExt->Specific.Control.LibraryQueueLock);
857 AFSInitServerStrings()
860 UNICODE_STRING uniFullName;
861 WCHAR wchBuffer[ 50];
864 // Add the server name into the list of resources
867 uniFullName.Length = (2 * sizeof( WCHAR)) + AFSServerName.Length;
868 uniFullName.MaximumLength = uniFullName.Length + sizeof( WCHAR);
870 uniFullName.Buffer = wchBuffer;
872 wchBuffer[ 0] = L'\\';
873 wchBuffer[ 1] = L'\\';
875 RtlCopyMemory( &wchBuffer[ 2],
876 AFSServerName.Buffer,
877 AFSServerName.Length);
879 AFSAddConnectionEx( &uniFullName,
880 RESOURCEDISPLAYTYPE_SERVER,
884 // Add in the global share name
887 wchBuffer[ uniFullName.Length/sizeof( WCHAR)] = L'\\';
889 uniFullName.Length += sizeof( WCHAR);
891 RtlCopyMemory( &wchBuffer[ uniFullName.Length/sizeof( WCHAR)],
892 AFSGlobalRootName.Buffer,
893 AFSGlobalRootName.Length);
895 uniFullName.Length += AFSGlobalRootName.Length;
897 AFSAddConnectionEx( &uniFullName,
898 RESOURCEDISPLAYTYPE_SHARE,
899 AFS_CONNECTION_FLAG_GLOBAL_SHARE);
908 NTSTATUS ntStatus = STATUS_SUCCESS;
910 UNICODE_STRING paramPath;
911 RTL_QUERY_REGISTRY_TABLE paramTable[2];
917 // Setup the paramPath buffer.
920 paramPath.MaximumLength = PAGE_SIZE;
921 paramPath.Buffer = (PWSTR)AFSExAllocatePoolWithTag( PagedPool,
922 paramPath.MaximumLength,
923 AFS_GENERIC_MEMORY_17_TAG);
926 // If it exists, setup the path.
929 if( paramPath.Buffer == NULL)
932 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
939 RtlZeroMemory( paramPath.Buffer,
940 paramPath.MaximumLength);
942 RtlCopyMemory( ¶mPath.Buffer[ 0],
943 L"\\TransarcAFSDaemon\\Parameters",
946 paramPath.Length = 58;
948 RtlZeroMemory( paramTable,
949 sizeof( paramTable));
952 // Setup the table to query the registry for the needed value
955 AFSServerName.Length = 0;
956 AFSServerName.MaximumLength = 0;
957 AFSServerName.Buffer = NULL;
959 paramTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
960 paramTable[0].Name = AFS_NETBIOS_NAME;
961 paramTable[0].EntryContext = &AFSServerName;
963 paramTable[0].DefaultType = REG_NONE;
964 paramTable[0].DefaultData = NULL;
965 paramTable[0].DefaultLength = 0;
968 // Query the registry
971 ntStatus = RtlQueryRegistryValues( RTL_REGISTRY_SERVICES,
978 // Free up the buffer
981 ExFreePool( paramPath.Buffer);
985 if( !NT_SUCCESS( ntStatus))
988 RtlInitUnicodeString( &AFSServerName,
997 AFSSetSysNameInformation( IN AFSSysNameNotificationCB *SysNameInfo,
998 IN ULONG SysNameInfoBufferLength)
1001 NTSTATUS ntStatus = STATUS_SUCCESS;
1002 AFSDeviceExt *pControlDevExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension;
1003 AFSSysNameCB *pSysName = NULL;
1004 ERESOURCE *pSysNameLock = NULL;
1005 AFSSysNameCB **pSysNameListHead = NULL, **pSysNameListTail = NULL;
1011 // Depending on the architecture of the information, set up the lsit
1014 if( SysNameInfo->Architecture == AFS_SYSNAME_ARCH_32BIT)
1017 pSysNameLock = &pControlDevExt->Specific.Control.SysName32ListLock;
1019 pSysNameListHead = &pControlDevExt->Specific.Control.SysName32ListHead;
1021 pSysNameListTail = &pControlDevExt->Specific.Control.SysName32ListTail;
1028 pSysNameLock = &pControlDevExt->Specific.Control.SysName64ListLock;
1030 pSysNameListHead = &pControlDevExt->Specific.Control.SysName64ListHead;
1032 pSysNameListTail = &pControlDevExt->Specific.Control.SysName64ListTail;
1036 try_return( ntStatus = STATUS_INVALID_PARAMETER);
1041 // Process the request
1044 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
1045 AFS_TRACE_LEVEL_VERBOSE,
1046 "AFSSetSysNameInformation Acquiring SysName lock %08lX EXCL %08lX\n",
1048 PsGetCurrentThread());
1050 AFSAcquireExcl( pSysNameLock,
1054 // If we already have a list, then tear it down
1057 if( *pSysNameListHead != NULL)
1060 AFSResetSysNameList( *pSysNameListHead);
1062 *pSysNameListHead = NULL;
1066 // Loop through the entries adding in a node for each
1069 while( ulIndex < SysNameInfo->NumberOfNames)
1072 pSysName = (AFSSysNameCB *)AFSExAllocatePoolWithTag( PagedPool,
1073 sizeof( AFSSysNameCB) +
1074 SysNameInfo->SysNames[ ulIndex].Length +
1076 AFS_SYS_NAME_NODE_TAG);
1078 if( pSysName == NULL)
1082 // Reset the current list
1085 AFSResetSysNameList( *pSysNameListHead);
1087 *pSysNameListHead = NULL;
1089 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1092 RtlZeroMemory( pSysName,
1093 sizeof( AFSSysNameCB) +
1094 SysNameInfo->SysNames[ ulIndex].Length +
1097 pSysName->SysName.Length = (USHORT)SysNameInfo->SysNames[ ulIndex].Length;
1099 pSysName->SysName.MaximumLength = pSysName->SysName.Length + sizeof( WCHAR);
1101 pSysName->SysName.Buffer = (WCHAR *)((char *)pSysName + sizeof( AFSSysNameCB));
1103 RtlCopyMemory( pSysName->SysName.Buffer,
1104 SysNameInfo->SysNames[ ulIndex].String,
1105 pSysName->SysName.Length);
1107 if( *pSysNameListHead == NULL)
1110 *pSysNameListHead = pSysName;
1115 (*pSysNameListTail)->fLink = pSysName;
1118 *pSysNameListTail = pSysName;
1125 AFSReleaseResource( pSysNameLock);
1132 AFSResetSysNameList( IN AFSSysNameCB *SysNameList)
1135 AFSSysNameCB *pNextEntry = NULL, *pCurrentEntry = SysNameList;
1137 while( pCurrentEntry != NULL)
1140 pNextEntry = pCurrentEntry->fLink;
1142 ExFreePool( pCurrentEntry);
1144 pCurrentEntry = pNextEntry;
1151 AFSDefaultDispatch( IN PDEVICE_OBJECT DeviceObject,
1155 NTSTATUS ntStatus = STATUS_INVALID_DEVICE_REQUEST;
1156 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1158 AFSCompleteRequest( Irp,
1165 AFSSendDeviceIoControl( IN DEVICE_OBJECT *TargetDeviceObject,
1167 IN void *InputBuffer,
1168 IN ULONG InputBufferLength,
1169 IN OUT void *OutputBuffer,
1170 IN ULONG OutputBufferLength,
1171 OUT ULONG *ResultLength)
1174 NTSTATUS ntStatus = STATUS_SUCCESS;
1177 PIO_STACK_LOCATION pIoStackLocation = NULL;
1183 // Initialize the event
1186 KeInitializeEvent( &kEvent,
1187 SynchronizationEvent,
1191 // Allocate an irp for this request. This could also come from a
1192 // private pool, for instance.
1195 pIrp = IoAllocateIrp( TargetDeviceObject->StackSize,
1201 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1205 // Build the IRP's main body
1208 pIrp->RequestorMode = KernelMode;
1211 // Set up the I/O stack location.
1214 pIoStackLocation = IoGetNextIrpStackLocation( pIrp);
1215 pIoStackLocation->MajorFunction = IRP_MJ_DEVICE_CONTROL;
1216 pIoStackLocation->DeviceObject = TargetDeviceObject;
1218 pIoStackLocation->Parameters.DeviceIoControl.IoControlCode = IOControl;
1220 pIrp->AssociatedIrp.SystemBuffer = (void *)InputBuffer;
1221 pIoStackLocation->Parameters.DeviceIoControl.InputBufferLength = InputBufferLength;
1224 // Set the completion routine.
1227 IoSetCompletionRoutine( pIrp,
1235 // Send it to the FSD
1238 ntStatus = IoCallDriver( TargetDeviceObject,
1241 if( NT_SUCCESS( ntStatus))
1248 ntStatus = KeWaitForSingleObject( &kEvent,
1254 if( NT_SUCCESS( ntStatus))
1257 ntStatus = pIrp->IoStatus.Status;
1259 if( ResultLength != NULL)
1261 *ResultLength = (ULONG)pIrp->IoStatus.Information;
1271 if( pIrp->MdlAddress != NULL)
1274 if( FlagOn( pIrp->MdlAddress->MdlFlags, MDL_PAGES_LOCKED))
1277 MmUnlockPages( pIrp->MdlAddress);
1280 IoFreeMdl( pIrp->MdlAddress);
1283 pIrp->MdlAddress = NULL;
1297 AFSIrpComplete( IN PDEVICE_OBJECT DeviceObject,
1302 KEVENT *pEvent = (KEVENT *)Context;
1308 return STATUS_MORE_PROCESSING_REQUIRED;
1312 AFSExAllocatePoolWithTag( IN POOL_TYPE PoolType,
1313 IN SIZE_T NumberOfBytes,
1317 AFSDeviceExt *pControlDevExt = NULL;
1318 void *pBuffer = NULL;
1319 BOOLEAN bTimeout = FALSE;
1320 LARGE_INTEGER liTimeout;
1324 // Attempt to allocation memory from the system. If the allocation fails
1325 // wait up to 30 seconds for the AFS redirector to free some memory. As
1326 // long as the wait does not timeout, continue to retry the allocation.
1327 // If the wait does timeout, attempt to allocate one more time in case
1328 // memory was freed by another driver. Otherwise, fail the request.
1331 if ( AFSDeviceObject)
1334 pControlDevExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension;
1337 while( pBuffer == NULL)
1340 pBuffer = ExAllocatePoolWithTag( PoolType,
1344 if( pBuffer == NULL)
1347 if ( bTimeout || pControlDevExt == NULL)
1352 "AFSExAllocatePoolWithTag failure Type %08lX Size %08lX Tag %08lX %08lX\n",
1356 PsGetCurrentThread());
1360 case AFS_GENERIC_MEMORY_21_TAG:
1361 case AFS_GENERIC_MEMORY_22_TAG:
1362 // AFSDumpTraceFiles -- do nothing;
1374 // Wait up to 30 seconds for a memory deallocation
1377 liTimeout.QuadPart = -(30 *AFS_ONE_SECOND);
1379 if( InterlockedIncrement( &pControlDevExt->Specific.Control.WaitingForMemoryCount) == 1)
1381 KeClearEvent( &pControlDevExt->Specific.Control.MemoryAvailableEvent);
1384 ntStatus = KeWaitForSingleObject( &pControlDevExt->Specific.Control.MemoryAvailableEvent,
1390 if( ntStatus == STATUS_TIMEOUT)
1396 InterlockedDecrement( &pControlDevExt->Specific.Control.WaitingForMemoryCount);
1404 AFSExFreePool( IN void *Buffer)
1407 AFSDeviceExt *pControlDevExt = NULL;
1409 if ( AFSDeviceObject)
1412 pControlDevExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension;
1415 ExFreePool( Buffer);
1417 if ( pControlDevExt)
1420 KeSetEvent( &pControlDevExt->Specific.Control.MemoryAvailableEvent,
1428 AFSShutdownRedirector()
1431 NTSTATUS ntStatus = STATUS_SUCCESS;
1432 AFSDeviceExt *pRDRDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1433 AFSDeviceExt *pControlDevExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension;
1434 LARGE_INTEGER liTimeout;
1439 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1440 AFS_TRACE_LEVEL_VERBOSE,
1441 "%s Shutting down redirector Extent count %08lX Request count %08lX\n",
1443 pControlDevExt->Specific.Control.ExtentCount,
1444 pControlDevExt->Specific.Control.OutstandingServiceRequestCount);
1447 // Set the shutdown flag so the worker is more agressive in tearing down extents
1450 SetFlag( pRDRDevExt->DeviceFlags, AFS_DEVICE_FLAG_REDIRECTOR_SHUTDOWN);
1453 // Wait on any outstanding service requests
1456 liTimeout.QuadPart = -(30 *AFS_ONE_SECOND);
1458 ntStatus = KeWaitForSingleObject( &pControlDevExt->Specific.Control.OutstandingServiceRequestEvent,
1464 if( ntStatus == STATUS_TIMEOUT)
1467 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1468 AFS_TRACE_LEVEL_WARNING,
1469 "AFSShutdownRedirector Failed to complete all service requests Remaining count %08lX\n",
1470 pControlDevExt->Specific.Control.OutstandingServiceRequestCount);
1472 try_return( ntStatus = STATUS_UNSUCCESSFUL);
1475 AFSProcessQueuedResults( TRUE);
1478 // Wait for all extents to be released
1481 liTimeout.QuadPart = -(30 *AFS_ONE_SECOND);
1483 ntStatus = KeWaitForSingleObject( &pControlDevExt->Specific.Control.ExtentsHeldEvent,
1489 if( ntStatus == STATUS_TIMEOUT)
1492 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1493 AFS_TRACE_LEVEL_WARNING,
1494 "AFSShutdownRedirector Failed to purge all extents Remaining count %08lX\n",
1495 pControlDevExt->Specific.Control.ExtentCount);
1497 try_return( ntStatus = STATUS_UNSUCCESSFUL);
1500 ntStatus = AFSUnloadLibrary( TRUE);
1502 if( !NT_SUCCESS( ntStatus))
1505 try_return( ntStatus);
1510 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1511 AFS_TRACE_LEVEL_VERBOSE,
1512 "%s Completed shut down of redirector Extent count %08lX Request count %08lX Status %08lX\n",
1514 pControlDevExt->Specific.Control.ExtentCount,
1515 pControlDevExt->Specific.Control.OutstandingServiceRequestCount,
1523 // Cache manager callback routines
1527 AFSAcquireFcbForLazyWrite( IN PVOID Fcb,
1531 BOOLEAN bStatus = FALSE;
1532 AFSFcb *pFcb = (AFSFcb *)Fcb;
1533 BOOLEAN bReleaseMain = FALSE, bReleasePaging = FALSE;
1536 // Try and acquire the Fcb resource
1539 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
1540 AFS_TRACE_LEVEL_VERBOSE,
1541 "AFSAcquireFcbForLazyWrite Acquiring Fcb %08lX\n",
1544 ASSERT( NULL == pFcb->Specific.File.LazyWriterThread);
1546 pFcb->Specific.File.LazyWriterThread = PsGetCurrentThread();
1548 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
1549 AFS_TRACE_LEVEL_VERBOSE,
1550 "AFSAcquireFcbForLazyWrite Attempt to acquire Fcb lock %08lX SHARED %08lX\n",
1551 &pFcb->NPFcb->Resource,
1552 PsGetCurrentThread());
1554 if( AFSAcquireShared( &pFcb->NPFcb->Resource,
1558 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
1559 AFS_TRACE_LEVEL_VERBOSE,
1560 "AFSAcquireFcbForLazyWrite Acquired Fcb lock %08lX SHARED %08lX\n",
1561 &pFcb->NPFcb->Resource,
1562 PsGetCurrentThread());
1564 bReleaseMain = TRUE;
1567 // Try and grab the paging
1570 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
1571 AFS_TRACE_LEVEL_VERBOSE,
1572 "AFSAcquireFcbForLazyWrite Attempt to acquire Fcb PagingIo lock %08lX SHARED %08lX\n",
1573 &pFcb->NPFcb->PagingResource,
1574 PsGetCurrentThread());
1576 if( AFSAcquireShared( &pFcb->NPFcb->PagingResource,
1580 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
1581 AFS_TRACE_LEVEL_VERBOSE,
1582 "AFSAcquireFcbForLazyWrite Acquired Fcb PagingIo lock %08lX SHARED %08lX\n",
1583 &pFcb->NPFcb->PagingResource,
1584 PsGetCurrentThread());
1586 bReleasePaging = TRUE;
1594 IoSetTopLevelIrp( (PIRP)FSRTL_CACHE_TOP_LEVEL_IRP);
1604 AFSReleaseResource( &pFcb->NPFcb->Resource);
1610 AFSReleaseResource( &pFcb->NPFcb->PagingResource);
1618 AFSReleaseFcbFromLazyWrite( IN PVOID Fcb)
1621 AFSFcb *pFcb = (AFSFcb *)Fcb;
1623 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
1624 AFS_TRACE_LEVEL_VERBOSE,
1625 "AFSReleaseFcbFromLazyWrite Releasing Fcb %08lX\n",
1628 IoSetTopLevelIrp( NULL);
1630 ASSERT( PsGetCurrentThread() == pFcb->Specific.File.LazyWriterThread);
1632 pFcb->Specific.File.LazyWriterThread = NULL;
1635 AFSReleaseResource( &pFcb->NPFcb->PagingResource);
1637 AFSReleaseResource( &pFcb->NPFcb->Resource);
1643 AFSAcquireFcbForReadAhead( IN PVOID Fcb,
1647 BOOLEAN bStatus = FALSE;
1648 AFSFcb *pFcb = (AFSFcb *)Fcb;
1650 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
1651 AFS_TRACE_LEVEL_VERBOSE,
1652 "AFSAcquireFcbForReadAhead Attempt to acquire Fcb lock %08lX SHARED %08lX\n",
1653 &pFcb->NPFcb->Resource,
1654 PsGetCurrentThread());
1656 if( AFSAcquireShared( &pFcb->NPFcb->Resource,
1660 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
1661 AFS_TRACE_LEVEL_VERBOSE,
1662 "AFSAcquireFcbForReadAhead Acquired Fcb lock %08lX SHARED %08lX\n",
1663 &pFcb->NPFcb->Resource,
1664 PsGetCurrentThread());
1668 IoSetTopLevelIrp( (PIRP)FSRTL_CACHE_TOP_LEVEL_IRP);
1675 AFSReleaseFcbFromReadAhead( IN PVOID Fcb)
1678 AFSFcb *pFcb = (AFSFcb *)Fcb;
1680 IoSetTopLevelIrp( NULL);
1682 AFSReleaseResource( &pFcb->NPFcb->Resource);
1688 AFSGetCallerSID( OUT UNICODE_STRING *SIDString, OUT BOOLEAN *pbImpersonation)
1691 NTSTATUS ntStatus = STATUS_SUCCESS;
1692 PACCESS_TOKEN hToken = NULL;
1693 TOKEN_USER *pTokenInfo = NULL;
1694 BOOLEAN bCopyOnOpen = FALSE;
1695 BOOLEAN bEffectiveOnly = FALSE;
1696 BOOLEAN bPrimaryToken = FALSE;
1697 SECURITY_IMPERSONATION_LEVEL stImpersonationLevel;
1698 UNICODE_STRING uniSIDString;
1703 hToken = PsReferenceImpersonationToken( PsGetCurrentThread(),
1706 &stImpersonationLevel);
1711 hToken = PsReferencePrimaryToken( PsGetCurrentProcess());
1716 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1717 AFS_TRACE_LEVEL_ERROR,
1718 "AFSGetCallerSID Failed to retrieve impersonation or primary token\n");
1720 try_return( ntStatus);
1723 bPrimaryToken = TRUE;
1726 ntStatus = SeQueryInformationToken( hToken,
1728 (PVOID *)&pTokenInfo);
1730 if( !NT_SUCCESS( ntStatus))
1733 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1734 AFS_TRACE_LEVEL_ERROR,
1735 "AFSGetCallerSID Failed to retrieve information Status %08lX\n", ntStatus);
1737 try_return( ntStatus);
1740 uniSIDString.Length = 0;
1741 uniSIDString.MaximumLength = 0;
1742 uniSIDString.Buffer = NULL;
1744 ntStatus = RtlConvertSidToUnicodeString( &uniSIDString,
1745 pTokenInfo->User.Sid,
1748 if( !NT_SUCCESS( ntStatus))
1751 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1752 AFS_TRACE_LEVEL_ERROR,
1753 "AFSGetCallerSID Failed to convert sid to string Status %08lX\n", ntStatus);
1755 try_return( ntStatus);
1758 *SIDString = uniSIDString;
1760 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING | AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
1761 AFS_TRACE_LEVEL_VERBOSE_2,
1762 "AFSGetCallerSID Successfully retrieved SID %wZ\n",
1765 if ( bPrimaryToken == FALSE &&
1768 *pbImpersonation = TRUE;
1777 PsDereferencePrimaryToken( hToken);
1781 PsDereferenceImpersonationToken( hToken);
1785 if( pTokenInfo != NULL)
1787 AFSExFreePool( pTokenInfo);
1795 AFSGetSessionId( IN HANDLE ProcessId, OUT BOOLEAN *pbImpersonation)
1798 NTSTATUS ntStatus = STATUS_SUCCESS;
1799 PACCESS_TOKEN hToken = NULL;
1800 ULONG ulSessionId = (ULONG)-1;
1801 BOOLEAN bCopyOnOpen = FALSE;
1802 BOOLEAN bEffectiveOnly = FALSE;
1803 BOOLEAN bPrimaryToken = FALSE;
1804 SECURITY_IMPERSONATION_LEVEL stImpersonationLevel;
1809 hToken = PsReferenceImpersonationToken( PsGetCurrentThread(),
1812 &stImpersonationLevel);
1817 hToken = PsReferencePrimaryToken( PsGetCurrentProcess());
1822 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1823 AFS_TRACE_LEVEL_ERROR,
1824 "AFSGetSessionId Failed to retrieve impersonation or primary token\n");
1826 try_return( ntStatus);
1829 bPrimaryToken = TRUE;
1832 ntStatus = SeQueryInformationToken( hToken,
1834 (PVOID *)&ulSessionId);
1836 if( !NT_SUCCESS( ntStatus))
1838 ulSessionId = (ULONG)-1;
1840 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1841 AFS_TRACE_LEVEL_ERROR,
1842 "AFSGetSessionId Failed to retrieve session id Status %08lX\n",
1845 try_return( ntStatus);
1848 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING | AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
1849 AFS_TRACE_LEVEL_VERBOSE_2,
1850 "AFSGetSessionId found %08lX\n",
1853 if ( bPrimaryToken == FALSE &&
1856 *pbImpersonation = TRUE;
1865 PsDereferencePrimaryToken( hToken);
1869 PsDereferenceImpersonationToken( hToken);
1878 AFSCheckThreadDacl( OUT GUID *AuthGroup)
1881 NTSTATUS ntStatus = STATUS_UNSUCCESSFUL;
1883 PACCESS_TOKEN token = NULL;
1884 PTOKEN_DEFAULT_DACL defDacl = NULL;
1886 PACCESS_ALLOWED_ACE adace;
1887 BOOLEAN bCopyOnOpen = FALSE, bEffectiveOnly = FALSE;
1888 SECURITY_IMPERSONATION_LEVEL stImpersonationLevel;
1889 BOOLEAN bLocatedACE = FALSE;
1894 token = PsReferenceImpersonationToken( PsGetCurrentThread(),
1897 &stImpersonationLevel);
1901 try_return( ntStatus);
1904 ntStatus = SeQueryInformationToken( token,
1908 if( ntStatus != STATUS_SUCCESS)
1910 try_return( ntStatus);
1913 // scan through all ACEs in the DACL
1914 for (idx = 0, ace = (PACE_HEADER)((char *)defDacl->DefaultDacl + sizeof(ACL)); idx < defDacl->DefaultDacl->AceCount; idx++)
1916 if (ace->AceType == ACCESS_ALLOWED_ACE_TYPE)
1918 adace = (PACCESS_ALLOWED_ACE)ace;
1920 if (adace->Header.AceSize == (FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + AFS_DACL_SID_LENGTH))
1922 if (RtlCompareMemory( RtlSubAuthoritySid((PSID)&adace->SidStart, 0), &AFSSidGuid, sizeof(GUID)) == sizeof(GUID))
1925 RtlCopyMemory( AuthGroup,
1926 RtlSubAuthoritySid((PSID)&adace->SidStart, 4),
1937 ace = (PACE_HEADER)((char *)ace + ace->AceSize);
1944 PsDereferenceImpersonationToken( token);
1947 if (defDacl != NULL)
1949 ExFreePool(defDacl);
1954 ntStatus = STATUS_UNSUCCESSFUL;
1962 AFSProcessSetProcessDacl( IN AFSProcessCB *ProcessCB)
1965 PTOKEN_DEFAULT_DACL defDacl = NULL;
1966 HANDLE hToken = NULL;
1967 PACE_HEADER ace = NULL;
1968 SID_IDENTIFIER_AUTHORITY sia = SECURITY_NT_AUTHORITY;
1969 PACCESS_ALLOWED_ACE aaace;
1971 ULONG bytesReturned;
1974 NTSTATUS ntStatus = STATUS_SUCCESS;
1979 ntStatus = ZwOpenProcessTokenEx( NtCurrentProcess(),
1984 if( !NT_SUCCESS( ntStatus))
1986 try_return( ntStatus);
1989 // get the size of the current DACL
1990 ntStatus = ZwQueryInformationToken( hToken,
1996 // if we failed to get the buffer size needed
1997 if ((ntStatus != STATUS_SUCCESS) && (ntStatus != STATUS_BUFFER_TOO_SMALL))
1999 try_return( ntStatus);
2002 // tack on enough space for our ACE if we need to add it...
2003 bytesNeeded += FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + AFS_DACL_SID_LENGTH;
2005 // allocate space for the DACL
2006 defDacl = (PTOKEN_DEFAULT_DACL)ExAllocatePoolWithTag( PagedPool, bytesNeeded, AFS_GENERIC_MEMORY_26_TAG);
2008 if (defDacl == NULL)
2010 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2014 ntStatus = ZwQueryInformationToken( hToken,
2020 if( ntStatus != STATUS_SUCCESS)
2022 try_return( ntStatus);
2025 // scan through DACL to see if we have the SID set already...
2026 ace = (PACE_HEADER)((char *)defDacl->DefaultDacl + sizeof(ACL));
2027 for (idx = 0; idx < defDacl->DefaultDacl->AceCount; idx++)
2029 if (ace->AceType == ACCESS_ALLOWED_ACE_TYPE)
2031 aaace = (PACCESS_ALLOWED_ACE)ace;
2033 if (aaace->Header.AceSize == (FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + AFS_DACL_SID_LENGTH))
2035 // if the GUID part matches
2036 if( RtlCompareMemory( RtlSubAuthoritySid((PSID)&aaace->SidStart, 0),
2038 sizeof(GUID)) == sizeof(GUID))
2041 if ( RtlCompareMemory( RtlSubAuthoritySid((PSID)&aaace->SidStart, 4),
2042 ProcessCB->ActiveAuthGroup,
2043 sizeof( GUID)) != sizeof( GUID))
2046 RtlCopyMemory( RtlSubAuthoritySid((PSID)&aaace->SidStart, 4),
2047 ProcessCB->ActiveAuthGroup,
2050 if( AFSSetInformationToken != NULL)
2052 ntStatus = AFSSetInformationToken( hToken,
2059 try_return( ntStatus);
2065 ace = (PACE_HEADER)((char *)ace + ace->AceSize);
2069 // if we made it here we need to add a new ACE to the DACL
2072 aaace = (ACCESS_ALLOWED_ACE *)ace;
2073 aaace->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
2074 aaace->Header.AceFlags = 0;
2075 aaace->Mask = GENERIC_ALL;
2076 psid = (PSID)&aaace->SidStart;
2077 RtlInitializeSid( psid, &sia, 8);
2079 RtlCopyMemory( RtlSubAuthoritySid(psid, 0),
2083 RtlCopyMemory( RtlSubAuthoritySid(psid, 4),
2084 ProcessCB->ActiveAuthGroup,
2087 aaace->Header.AceSize = (USHORT)(FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + RtlLengthSid( psid));
2089 defDacl->DefaultDacl->AclSize += aaace->Header.AceSize;
2090 defDacl->DefaultDacl->AceCount++;
2092 if( AFSSetInformationToken != NULL)
2094 ntStatus = AFSSetInformationToken( hToken,
2097 defDacl->DefaultDacl->AclSize + sizeof(PTOKEN_DEFAULT_DACL));
2107 if (defDacl != NULL)
2109 ExFreePool( defDacl);