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)
58 UNREFERENCED_PARAMETER(Code);
60 PEXCEPTION_RECORD ExceptRec;
66 ExceptRec = ExceptPtrs->ExceptionRecord;
68 Context = ExceptPtrs->ContextRecord;
72 "AFSExceptionFilter (Framework) - EXR %p CXR %p Function %s Code %08lX Address %p Routine %p\n",
76 ExceptRec->ExceptionCode,
77 ExceptRec->ExceptionAddress,
78 (void *)AFSExceptionFilter));
80 DbgPrint("**** Exception Caught in AFS Redirector ****\n");
82 DbgPrint("\n\nPerform the following WnDbg Cmds:\n");
83 DbgPrint("\n\t.exr %p ; .cxr %p\n\n", ExceptRec, Context);
85 DbgPrint("**** Exception Complete from AFS Redirector ****\n");
87 if( BooleanFlagOn( AFSDebugFlags, AFS_DBG_BUGCHECK_EXCEPTION))
90 KeBugCheck( (ULONG)-2);
98 __except( EXCEPTION_EXECUTE_HANDLER)
104 return EXCEPTION_EXECUTE_HANDLER;
108 // Function: AFSAcquireExcl()
110 // Purpose: Called to acquire a resource exclusive with optional wait
113 // PERESOURCE Resource - Resource to acquire
114 // BOOLEAN Wait - Whether to block
117 // BOOLEAN - Whether the mask was acquired
121 AFSAcquireExcl( IN PERESOURCE Resource,
125 BOOLEAN bStatus = FALSE;
128 // Normal kernel APCs must be disabled before calling
129 // ExAcquireResourceExclusiveLite. Otherwise a bugcheck occurs.
132 KeEnterCriticalRegion();
134 bStatus = ExAcquireResourceExclusiveLite( Resource,
140 KeLeaveCriticalRegion();
147 AFSAcquireSharedStarveExclusive( IN PERESOURCE Resource,
151 BOOLEAN bStatus = FALSE;
153 KeEnterCriticalRegion();
155 bStatus = ExAcquireSharedStarveExclusive( Resource,
161 KeLeaveCriticalRegion();
168 // Function: AFSAcquireShared()
170 // Purpose: Called to acquire a resource shared with optional wait
173 // PERESOURCE Resource - Resource to acquire
174 // BOOLEAN Wait - Whether to block
177 // BOOLEAN - Whether the mask was acquired
181 AFSAcquireShared( IN PERESOURCE Resource,
185 BOOLEAN bStatus = FALSE;
187 KeEnterCriticalRegion();
189 bStatus = ExAcquireResourceSharedLite( Resource,
195 KeLeaveCriticalRegion();
202 // Function: AFSReleaseResource()
204 // Purpose: Called to release a resource
207 // PERESOURCE Resource - Resource to release
214 AFSReleaseResource( IN PERESOURCE Resource)
217 if( Resource != &AFSDbgLogLock)
220 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
221 AFS_TRACE_LEVEL_VERBOSE,
222 "AFSReleaseResource Releasing lock %p Thread %08lX\n",
224 PsGetCurrentThread()));
227 ExReleaseResourceLite( Resource);
229 KeLeaveCriticalRegion();
235 AFSConvertToShared( IN PERESOURCE Resource)
238 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
239 AFS_TRACE_LEVEL_VERBOSE,
240 "AFSConvertToShared Converting lock %p Thread %08lX\n",
242 PsGetCurrentThread()));
244 ExConvertExclusiveToSharedLite( Resource);
250 // Function: AFSCompleteRequest
254 // This function completes irps
258 // A status is returned for the function
262 AFSCompleteRequest( IN PIRP Irp,
266 Irp->IoStatus.Status = Status;
268 IoCompleteRequest( Irp,
275 AFSReadRegistry( IN PUNICODE_STRING RegistryPath)
278 NTSTATUS ntStatus = STATUS_SUCCESS;
280 UNICODE_STRING paramPath;
282 RTL_QUERY_REGISTRY_TABLE paramTable[2];
283 UNICODE_STRING defaultUnicodeName;
284 WCHAR SubKeyString[] = L"\\Parameters";
287 // Setup the paramPath buffer.
290 paramPath.MaximumLength = RegistryPath->Length + sizeof( SubKeyString);
291 paramPath.Buffer = (PWSTR)AFSExAllocatePoolWithTag( PagedPool,
292 paramPath.MaximumLength,
293 AFS_GENERIC_MEMORY_15_TAG);
295 RtlInitUnicodeString( &defaultUnicodeName,
299 // If it exists, setup the path.
302 if( paramPath.Buffer != NULL)
309 RtlCopyMemory( ¶mPath.Buffer[ 0],
310 &RegistryPath->Buffer[ 0],
311 RegistryPath->Length);
313 RtlCopyMemory( ¶mPath.Buffer[ RegistryPath->Length / 2],
315 sizeof( SubKeyString));
317 paramPath.Length = paramPath.MaximumLength;
319 RtlZeroMemory( paramTable,
320 sizeof( paramTable));
325 // Setup the table to query the registry for the needed value
328 paramTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
329 paramTable[0].Name = AFS_REG_DEBUG_FLAGS;
330 paramTable[0].EntryContext = &Value;
332 paramTable[0].DefaultType = REG_DWORD;
333 paramTable[0].DefaultData = &Default;
334 paramTable[0].DefaultLength = sizeof (ULONG) ;
337 // Query the registry
340 ntStatus = RtlQueryRegistryValues( RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL,
346 if( NT_SUCCESS( ntStatus))
349 AFSDebugFlags = Value;
352 RtlZeroMemory( paramTable,
353 sizeof( paramTable));
358 // Setup the table to query the registry for the needed value
361 paramTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
362 paramTable[0].Name = AFS_REG_TRACE_SUBSYSTEM;
363 paramTable[0].EntryContext = &Value;
365 paramTable[0].DefaultType = REG_DWORD;
366 paramTable[0].DefaultData = &Default;
367 paramTable[0].DefaultLength = sizeof (ULONG) ;
370 // Query the registry
373 ntStatus = RtlQueryRegistryValues( RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL,
379 if( NT_SUCCESS( ntStatus))
382 AFSTraceComponent = Value;
385 RtlZeroMemory( paramTable,
386 sizeof( paramTable));
391 // Setup the table to query the registry for the needed value
394 paramTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
395 paramTable[0].Name = AFS_REG_TRACE_BUFFER_LENGTH;
396 paramTable[0].EntryContext = &Value;
398 paramTable[0].DefaultType = REG_DWORD;
399 paramTable[0].DefaultData = &Default;
400 paramTable[0].DefaultLength = sizeof (ULONG);
403 // Query the registry
406 ntStatus = RtlQueryRegistryValues( RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL,
412 if( NT_SUCCESS( ntStatus) &&
416 AFSDbgBufferLength = Value;
419 // Let's limit things a bit ...
422 if( AFSDbgBufferLength > 10240)
425 AFSDbgBufferLength = 1024;
431 AFSDbgBufferLength = 0;
438 AFSDbgBufferLength *= 1024;
441 // Now get ready to set up for MaxServerDirty
444 paramTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
445 paramTable[0].Name = AFS_REG_MAX_DIRTY;
446 paramTable[0].EntryContext = &Value;
448 paramTable[0].DefaultType = REG_DWORD;
449 paramTable[0].DefaultData = &Default;
450 paramTable[0].DefaultLength = sizeof (ULONG) ;
453 // Query the registry
456 ntStatus = RtlQueryRegistryValues( RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL,
462 if( NT_SUCCESS( ntStatus))
465 AFSMaxDirtyFile = Value;
468 RtlZeroMemory( paramTable,
469 sizeof( paramTable));
474 // Setup the table to query the registry for the needed value
477 paramTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
478 paramTable[0].Name = AFS_REG_TRACE_LEVEL;
479 paramTable[0].EntryContext = &Value;
481 paramTable[0].DefaultType = REG_DWORD;
482 paramTable[0].DefaultData = &Default;
483 paramTable[0].DefaultLength = sizeof (ULONG) ;
486 // Query the registry
489 ntStatus = RtlQueryRegistryValues( RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL,
495 if( NT_SUCCESS( ntStatus))
498 AFSTraceLevel = Value;
505 paramTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
506 paramTable[0].Name = AFS_REG_MAX_IO;
507 paramTable[0].EntryContext = &Value;
509 paramTable[0].DefaultType = REG_DWORD;
510 paramTable[0].DefaultData = &Default;
511 paramTable[0].DefaultLength = sizeof (ULONG) ;
514 // Query the registry
517 ntStatus = RtlQueryRegistryValues( RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL,
523 if( NT_SUCCESS( ntStatus))
526 AFSMaxDirectIo = Value;
530 // Now set up for ShutdownStatus query
533 paramTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
534 paramTable[0].Name = AFS_REG_SHUTDOWN_STATUS;
535 paramTable[0].EntryContext = &Value;
537 paramTable[0].DefaultType = REG_DWORD;
538 paramTable[0].DefaultData = &Default;
539 paramTable[0].DefaultLength = sizeof (ULONG) ;
542 // Query the registry
545 ntStatus = RtlQueryRegistryValues( RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL,
551 if( !NT_SUCCESS( ntStatus) ||
555 SetFlag( AFSDebugFlags, AFS_DBG_CLEAN_SHUTDOWN);
559 // Now set up for RequireCleanShutdown query
562 paramTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
563 paramTable[0].Name = AFS_REG_REQUIRE_CLEAN_SHUTDOWN;
564 paramTable[0].EntryContext = &Value;
566 paramTable[0].DefaultType = REG_DWORD;
567 paramTable[0].DefaultData = &Default;
568 paramTable[0].DefaultLength = sizeof (ULONG) ;
571 // Query the registry
574 ntStatus = RtlQueryRegistryValues( RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL,
580 if( !NT_SUCCESS( ntStatus) ||
584 SetFlag( AFSDebugFlags, AFS_DBG_REQUIRE_CLEAN_SHUTDOWN);
588 // Free up the buffer
591 ExFreePool( paramPath.Buffer);
593 ntStatus = STATUS_SUCCESS;
597 ntStatus = STATUS_INSUFFICIENT_RESOURCES;
604 AFSUpdateRegistryParameter( IN PUNICODE_STRING ValueName,
607 IN ULONG ValueDataLength)
610 NTSTATUS ntStatus = STATUS_SUCCESS;
611 UNICODE_STRING paramPath, uniParamKey;
612 HANDLE hParameters = 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;
708 // Initialize the comm pool resources
711 ExInitializeResourceLite( &pDeviceExt->Specific.Control.CommServiceCB.IrpPoolLock);
713 ExInitializeResourceLite( &pDeviceExt->Specific.Control.CommServiceCB.ResultPoolLock);
715 ExInitializeResourceLite( &pDeviceExt->Specific.Control.ExtentReleaseResource);
717 ExInitializeResourceLite( &pDeviceExt->Specific.Control.SysName32ListLock);
719 ExInitializeResourceLite( &pDeviceExt->Specific.Control.SysName64ListLock);
725 KeInitializeEvent( &pDeviceExt->Specific.Control.CommServiceCB.IrpPoolHasEntries,
726 SynchronizationEvent,
729 KeInitializeEvent( &pDeviceExt->Specific.Control.CommServiceCB.IrpPoolHasReleaseEntries,
730 SynchronizationEvent,
733 KeInitializeEvent( &pDeviceExt->Specific.Control.ExtentReleaseEvent,
737 pDeviceExt->Specific.Control.ExtentReleaseSequence = 0;
739 KeInitializeEvent( &pDeviceExt->Specific.Control.VolumeWorkerCloseEvent,
744 // Library support information
747 KeInitializeEvent( &pDeviceExt->Specific.Control.LoadLibraryEvent,
748 SynchronizationEvent,
752 // Initialize the library queued as cancelled
755 pDeviceExt->Specific.Control.LibraryState = AFS_LIBRARY_QUEUE_CANCELLED;
757 ExInitializeResourceLite( &pDeviceExt->Specific.Control.LibraryStateLock);
759 pDeviceExt->Specific.Control.InflightLibraryRequests = 0;
761 KeInitializeEvent( &pDeviceExt->Specific.Control.InflightLibraryEvent,
765 pDeviceExt->Specific.Control.ExtentCount = 0;
766 pDeviceExt->Specific.Control.ExtentsHeldLength = 0;
768 KeInitializeEvent( &pDeviceExt->Specific.Control.ExtentsHeldEvent,
772 pDeviceExt->Specific.Control.OutstandingServiceRequestCount = 0;
774 KeInitializeEvent( &pDeviceExt->Specific.Control.OutstandingServiceRequestEvent,
778 pDeviceExt->Specific.Control.WaitingForMemoryCount = 0;
780 KeInitializeEvent( &pDeviceExt->Specific.Control.MemoryAvailableEvent,
784 ExInitializeResourceLite( &pDeviceExt->Specific.Control.LibraryQueueLock);
786 pDeviceExt->Specific.Control.LibraryQueueHead = NULL;
788 pDeviceExt->Specific.Control.LibraryQueueTail = NULL;
791 // Set the initial state of the irp pool
794 pDeviceExt->Specific.Control.CommServiceCB.IrpPoolControlFlag = POOL_INACTIVE;
797 // Initialize our process and sid tree information
800 ExInitializeResourceLite( &pDeviceExt->Specific.Control.ProcessTreeLock);
802 pDeviceExt->Specific.Control.ProcessTree.TreeLock = &pDeviceExt->Specific.Control.ProcessTreeLock;
804 pDeviceExt->Specific.Control.ProcessTree.TreeHead = NULL;
806 ExInitializeResourceLite( &pDeviceExt->Specific.Control.AuthGroupTreeLock);
808 pDeviceExt->Specific.Control.AuthGroupTree.TreeLock = &pDeviceExt->Specific.Control.AuthGroupTreeLock;
810 pDeviceExt->Specific.Control.AuthGroupTree.TreeHead = NULL;
813 // Increase the StackSize to support the extra stack frame required
814 // for use of IoCompletion routines.
817 AFSDeviceObject->StackSize++;
825 AFSRemoveControlDevice()
828 NTSTATUS ntStatus = STATUS_SUCCESS;
829 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension;
835 // Initialize the comm pool resources
838 ExDeleteResourceLite( &pDeviceExt->Specific.Control.CommServiceCB.IrpPoolLock);
840 ExDeleteResourceLite( &pDeviceExt->Specific.Control.CommServiceCB.ResultPoolLock);
842 ExDeleteResourceLite( &pDeviceExt->Specific.Control.ExtentReleaseResource);
844 ExDeleteResourceLite( &pDeviceExt->Specific.Control.SysName32ListLock);
846 ExDeleteResourceLite( &pDeviceExt->Specific.Control.SysName64ListLock);
848 ExDeleteResourceLite( &pDeviceExt->Specific.Control.ProcessTreeLock);
850 if( pDeviceExt->Specific.Control.ProcessTree.TreeHead != NULL)
852 ExFreePool( pDeviceExt->Specific.Control.ProcessTree.TreeHead);
855 ExDeleteResourceLite( &pDeviceExt->Specific.Control.AuthGroupTreeLock);
857 ExDeleteResourceLite( &pDeviceExt->Specific.Control.LibraryStateLock);
859 ExDeleteResourceLite( &pDeviceExt->Specific.Control.LibraryQueueLock);
866 AFSInitServerStrings()
869 UNICODE_STRING uniFullName;
870 WCHAR wchBuffer[ 50];
873 // Add the server name into the list of resources
876 uniFullName.Length = (2 * sizeof( WCHAR)) + AFSServerName.Length;
877 uniFullName.MaximumLength = uniFullName.Length + sizeof( WCHAR);
879 uniFullName.Buffer = wchBuffer;
881 wchBuffer[ 0] = L'\\';
882 wchBuffer[ 1] = L'\\';
884 RtlCopyMemory( &wchBuffer[ 2],
885 AFSServerName.Buffer,
886 AFSServerName.Length);
888 AFSAddConnectionEx( &uniFullName,
889 RESOURCEDISPLAYTYPE_SERVER,
893 // Add in the global share name
896 wchBuffer[ uniFullName.Length/sizeof( WCHAR)] = L'\\';
898 uniFullName.Length += sizeof( WCHAR);
900 RtlCopyMemory( &wchBuffer[ uniFullName.Length/sizeof( WCHAR)],
901 AFSGlobalRootName.Buffer,
902 AFSGlobalRootName.Length);
904 uniFullName.Length += AFSGlobalRootName.Length;
906 AFSAddConnectionEx( &uniFullName,
907 RESOURCEDISPLAYTYPE_SHARE,
908 AFS_CONNECTION_FLAG_GLOBAL_SHARE);
917 NTSTATUS ntStatus = STATUS_SUCCESS;
918 UNICODE_STRING paramPath;
919 RTL_QUERY_REGISTRY_TABLE paramTable[2];
925 // Setup the paramPath buffer.
928 paramPath.MaximumLength = PAGE_SIZE;
929 paramPath.Buffer = (PWSTR)AFSExAllocatePoolWithTag( PagedPool,
930 paramPath.MaximumLength,
931 AFS_GENERIC_MEMORY_17_TAG);
934 // If it exists, setup the path.
937 if( paramPath.Buffer == NULL)
940 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
947 RtlZeroMemory( paramPath.Buffer,
948 paramPath.MaximumLength);
950 RtlCopyMemory( ¶mPath.Buffer[ 0],
951 L"\\TransarcAFSDaemon\\Parameters",
954 paramPath.Length = 58;
956 RtlZeroMemory( paramTable,
957 sizeof( paramTable));
960 // Setup the table to query the registry for the needed value
963 AFSServerName.Length = 0;
964 AFSServerName.MaximumLength = 0;
965 AFSServerName.Buffer = NULL;
967 paramTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
968 paramTable[0].Name = AFS_REG_NETBIOS_NAME;
969 paramTable[0].EntryContext = &AFSServerName;
971 paramTable[0].DefaultType = REG_NONE;
972 paramTable[0].DefaultData = NULL;
973 paramTable[0].DefaultLength = 0;
976 // Query the registry
979 ntStatus = RtlQueryRegistryValues( RTL_REGISTRY_SERVICES,
986 // Free up the buffer
989 ExFreePool( paramPath.Buffer);
993 if( !NT_SUCCESS( ntStatus))
996 RtlInitUnicodeString( &AFSServerName,
1005 AFSReadMountRootName()
1008 NTSTATUS ntStatus = STATUS_SUCCESS;
1009 UNICODE_STRING paramPath;
1010 RTL_QUERY_REGISTRY_TABLE paramTable[2];
1016 // Setup the paramPath buffer.
1019 paramPath.MaximumLength = PAGE_SIZE;
1020 paramPath.Buffer = (PWSTR)AFSExAllocatePoolWithTag( PagedPool,
1021 paramPath.MaximumLength,
1022 AFS_GENERIC_MEMORY_17_TAG);
1025 // If it exists, setup the path.
1028 if( paramPath.Buffer == NULL)
1031 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1035 // Move in the paths
1038 RtlZeroMemory( paramPath.Buffer,
1039 paramPath.MaximumLength);
1041 RtlCopyMemory( ¶mPath.Buffer[ 0],
1042 L"\\TransarcAFSDaemon\\Parameters",
1045 paramPath.Length = 58;
1047 RtlZeroMemory( paramTable,
1048 sizeof( paramTable));
1051 // Setup the table to query the registry for the needed value
1054 AFSMountRootName.Length = 0;
1055 AFSMountRootName.MaximumLength = 0;
1056 AFSMountRootName.Buffer = NULL;
1058 paramTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
1059 paramTable[0].Name = AFS_REG_MOUNT_ROOT;
1060 paramTable[0].EntryContext = &AFSMountRootName;
1062 paramTable[0].DefaultType = REG_NONE;
1063 paramTable[0].DefaultData = NULL;
1064 paramTable[0].DefaultLength = 0;
1067 // Query the registry
1070 ntStatus = RtlQueryRegistryValues( RTL_REGISTRY_SERVICES,
1076 if ( NT_SUCCESS( ntStatus))
1078 if ( AFSMountRootName.Buffer[0] == L'/')
1081 AFSMountRootName.Buffer[0] = L'\\';
1086 // Free up the buffer
1089 ExFreePool( paramPath.Buffer);
1093 if( !NT_SUCCESS( ntStatus))
1096 RtlInitUnicodeString( &AFSMountRootName,
1105 AFSSetSysNameInformation( IN AFSSysNameNotificationCB *SysNameInfo,
1106 IN ULONG SysNameInfoBufferLength)
1108 UNREFERENCED_PARAMETER(SysNameInfoBufferLength);
1110 NTSTATUS ntStatus = STATUS_SUCCESS;
1111 AFSDeviceExt *pControlDevExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension;
1112 AFSSysNameCB *pSysName = NULL;
1113 ERESOURCE *pSysNameLock = NULL;
1114 AFSSysNameCB **pSysNameListHead = NULL, **pSysNameListTail = NULL;
1120 // Depending on the architecture of the information, set up the lsit
1123 if( SysNameInfo->Architecture == AFS_SYSNAME_ARCH_32BIT)
1126 pSysNameLock = &pControlDevExt->Specific.Control.SysName32ListLock;
1128 pSysNameListHead = &pControlDevExt->Specific.Control.SysName32ListHead;
1130 pSysNameListTail = &pControlDevExt->Specific.Control.SysName32ListTail;
1137 pSysNameLock = &pControlDevExt->Specific.Control.SysName64ListLock;
1139 pSysNameListHead = &pControlDevExt->Specific.Control.SysName64ListHead;
1141 pSysNameListTail = &pControlDevExt->Specific.Control.SysName64ListTail;
1145 try_return( ntStatus = STATUS_INVALID_PARAMETER);
1150 // Process the request
1153 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
1154 AFS_TRACE_LEVEL_VERBOSE,
1155 "AFSSetSysNameInformation Acquiring SysName lock %p EXCL %08lX\n",
1157 PsGetCurrentThread()));
1159 AFSAcquireExcl( pSysNameLock,
1163 // If we already have a list, then tear it down
1166 if( *pSysNameListHead != NULL)
1169 AFSResetSysNameList( *pSysNameListHead);
1171 *pSysNameListHead = NULL;
1175 // Loop through the entries adding in a node for each
1178 while( ulIndex < SysNameInfo->NumberOfNames)
1181 pSysName = (AFSSysNameCB *)AFSExAllocatePoolWithTag( PagedPool,
1182 sizeof( AFSSysNameCB) +
1183 SysNameInfo->SysNames[ ulIndex].Length +
1185 AFS_SYS_NAME_NODE_TAG);
1187 if( pSysName == NULL)
1191 // Reset the current list
1194 AFSResetSysNameList( *pSysNameListHead);
1196 *pSysNameListHead = NULL;
1198 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1201 RtlZeroMemory( pSysName,
1202 sizeof( AFSSysNameCB) +
1203 SysNameInfo->SysNames[ ulIndex].Length +
1206 pSysName->SysName.Length = (USHORT)SysNameInfo->SysNames[ ulIndex].Length;
1208 pSysName->SysName.MaximumLength = pSysName->SysName.Length + sizeof( WCHAR);
1210 pSysName->SysName.Buffer = (WCHAR *)((char *)pSysName + sizeof( AFSSysNameCB));
1212 RtlCopyMemory( pSysName->SysName.Buffer,
1213 SysNameInfo->SysNames[ ulIndex].String,
1214 pSysName->SysName.Length);
1216 if( *pSysNameListHead == NULL)
1219 *pSysNameListHead = pSysName;
1224 (*pSysNameListTail)->fLink = pSysName;
1227 *pSysNameListTail = pSysName;
1234 AFSReleaseResource( pSysNameLock);
1241 AFSResetSysNameList( IN AFSSysNameCB *SysNameList)
1244 AFSSysNameCB *pNextEntry = NULL, *pCurrentEntry = SysNameList;
1246 while( pCurrentEntry != NULL)
1249 pNextEntry = pCurrentEntry->fLink;
1251 ExFreePool( pCurrentEntry);
1253 pCurrentEntry = pNextEntry;
1260 AFSDefaultDispatch( IN PDEVICE_OBJECT DeviceObject,
1263 UNREFERENCED_PARAMETER(DeviceObject);
1265 NTSTATUS ntStatus = STATUS_INVALID_DEVICE_REQUEST;
1267 AFSCompleteRequest( Irp,
1274 AFSSendDeviceIoControl( IN DEVICE_OBJECT *TargetDeviceObject,
1276 IN void *InputBuffer,
1277 IN ULONG InputBufferLength,
1278 IN OUT void *OutputBuffer,
1279 IN ULONG OutputBufferLength,
1280 OUT ULONG *ResultLength)
1282 UNREFERENCED_PARAMETER(OutputBuffer);
1283 UNREFERENCED_PARAMETER(OutputBufferLength);
1285 NTSTATUS ntStatus = STATUS_SUCCESS;
1288 PIO_STACK_LOCATION pIoStackLocation = NULL;
1294 // Initialize the event
1297 KeInitializeEvent( &kEvent,
1298 SynchronizationEvent,
1302 // Allocate an irp for this request. This could also come from a
1303 // private pool, for instance.
1306 pIrp = IoAllocateIrp( TargetDeviceObject->StackSize,
1312 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1316 // Build the IRP's main body
1319 pIrp->RequestorMode = KernelMode;
1322 // Set up the I/O stack location.
1325 pIoStackLocation = IoGetNextIrpStackLocation( pIrp);
1326 pIoStackLocation->MajorFunction = IRP_MJ_DEVICE_CONTROL;
1327 pIoStackLocation->DeviceObject = TargetDeviceObject;
1329 pIoStackLocation->Parameters.DeviceIoControl.IoControlCode = IOControl;
1331 pIrp->AssociatedIrp.SystemBuffer = (void *)InputBuffer;
1332 pIoStackLocation->Parameters.DeviceIoControl.InputBufferLength = InputBufferLength;
1335 // Set the completion routine.
1338 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
1339 AFS_TRACE_LEVEL_VERBOSE,
1340 "Setting AFSIrpComplete as IoCompletion Routine Irp %p\n",
1343 IoSetCompletionRoutine( pIrp,
1351 // Send it to the FSD
1354 ntStatus = IoCallDriver( TargetDeviceObject,
1357 if( NT_SUCCESS( ntStatus))
1364 ntStatus = KeWaitForSingleObject( &kEvent,
1370 if( NT_SUCCESS( ntStatus))
1373 ntStatus = pIrp->IoStatus.Status;
1375 if( ResultLength != NULL)
1377 *ResultLength = (ULONG)pIrp->IoStatus.Information;
1387 if( pIrp->MdlAddress != NULL)
1390 if( FlagOn( pIrp->MdlAddress->MdlFlags, MDL_PAGES_LOCKED))
1393 MmUnlockPages( pIrp->MdlAddress);
1396 IoFreeMdl( pIrp->MdlAddress);
1399 pIrp->MdlAddress = NULL;
1413 AFSIrpComplete( IN PDEVICE_OBJECT DeviceObject,
1417 UNREFERENCED_PARAMETER(DeviceObject);
1418 UNREFERENCED_PARAMETER(Irp);
1420 KEVENT *pEvent = (KEVENT *)Context;
1426 return STATUS_MORE_PROCESSING_REQUIRED;
1430 AFSExAllocatePoolWithTag( IN POOL_TYPE PoolType,
1431 IN SIZE_T NumberOfBytes,
1435 AFSDeviceExt *pControlDevExt = NULL;
1436 void *pBuffer = NULL;
1437 BOOLEAN bTimeout = FALSE;
1438 LARGE_INTEGER liTimeout;
1442 // Attempt to allocation memory from the system. If the allocation fails
1443 // wait up to 30 seconds for the AFS redirector to free some memory. As
1444 // long as the wait does not timeout, continue to retry the allocation.
1445 // If the wait does timeout, attempt to allocate one more time in case
1446 // memory was freed by another driver. Otherwise, fail the request.
1449 if ( AFSDeviceObject)
1452 pControlDevExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension;
1455 while( pBuffer == NULL)
1458 pBuffer = ExAllocatePoolWithTag( PoolType,
1462 if( pBuffer == NULL)
1465 if ( bTimeout || pControlDevExt == NULL)
1470 "AFSExAllocatePoolWithTag failure Type %08lX Size %08lX Tag %08lX %08lX\n",
1474 PsGetCurrentThread()));
1478 case AFS_GENERIC_MEMORY_21_TAG:
1479 case AFS_GENERIC_MEMORY_22_TAG:
1480 // AFSDumpTraceFiles -- do nothing;
1492 // Wait up to 30 seconds for a memory deallocation
1495 liTimeout.QuadPart = -(30 *AFS_ONE_SECOND);
1497 if( InterlockedIncrement( &pControlDevExt->Specific.Control.WaitingForMemoryCount) == 1)
1499 KeClearEvent( &pControlDevExt->Specific.Control.MemoryAvailableEvent);
1502 ntStatus = KeWaitForSingleObject( &pControlDevExt->Specific.Control.MemoryAvailableEvent,
1508 if( ntStatus == STATUS_TIMEOUT)
1514 InterlockedDecrement( &pControlDevExt->Specific.Control.WaitingForMemoryCount);
1522 AFSExFreePoolWithTag( IN void *Buffer, IN ULONG Tag)
1525 AFSDeviceExt *pControlDevExt = NULL;
1527 if ( AFSDeviceObject)
1530 pControlDevExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension;
1536 ExFreePoolWithTag( Buffer, Tag);
1541 ExFreePool( Buffer);
1544 if ( pControlDevExt)
1547 KeSetEvent( &pControlDevExt->Specific.Control.MemoryAvailableEvent,
1555 AFSShutdownRedirector()
1558 NTSTATUS ntStatus = STATUS_SUCCESS;
1559 AFSDeviceExt *pRDRDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1560 AFSDeviceExt *pControlDevExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension;
1561 LARGE_INTEGER liTimeout;
1566 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1567 AFS_TRACE_LEVEL_VERBOSE,
1568 "%s Shutting down redirector Extent count %08lX Request count %08lX\n",
1570 pControlDevExt->Specific.Control.ExtentCount,
1571 pControlDevExt->Specific.Control.OutstandingServiceRequestCount));
1574 // Set the shutdown flag so the worker is more agressive in tearing down extents
1577 SetFlag( pRDRDevExt->DeviceFlags, AFS_DEVICE_FLAG_REDIRECTOR_SHUTDOWN);
1580 // Wait on any outstanding service requests
1583 liTimeout.QuadPart = -(30 *AFS_ONE_SECOND);
1585 ntStatus = KeWaitForSingleObject( &pControlDevExt->Specific.Control.OutstandingServiceRequestEvent,
1591 if( ntStatus == STATUS_TIMEOUT)
1594 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1595 AFS_TRACE_LEVEL_WARNING,
1596 "AFSShutdownRedirector Failed to complete all service requests Remaining count %08lX\n",
1597 pControlDevExt->Specific.Control.OutstandingServiceRequestCount));
1599 try_return( ntStatus = STATUS_UNSUCCESSFUL);
1602 AFSProcessQueuedResults( TRUE);
1605 // Wait for all extents to be released
1608 liTimeout.QuadPart = -(30 *AFS_ONE_SECOND);
1610 ntStatus = KeWaitForSingleObject( &pControlDevExt->Specific.Control.ExtentsHeldEvent,
1616 if( ntStatus == STATUS_TIMEOUT)
1619 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1620 AFS_TRACE_LEVEL_WARNING,
1621 "AFSShutdownRedirector Failed to purge all extents Remaining count %08lX\n",
1622 pControlDevExt->Specific.Control.ExtentCount));
1624 try_return( ntStatus = STATUS_UNSUCCESSFUL);
1627 ntStatus = AFSUnloadLibrary( TRUE);
1629 if( !NT_SUCCESS( ntStatus))
1632 try_return( ntStatus);
1637 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1638 AFS_TRACE_LEVEL_VERBOSE,
1639 "%s Completed shut down of redirector Extent count %08lX Request count %08lX Status %08lX\n",
1641 pControlDevExt->Specific.Control.ExtentCount,
1642 pControlDevExt->Specific.Control.OutstandingServiceRequestCount,
1650 // Cache manager callback routines
1654 AFSAcquireFcbForLazyWrite( IN PVOID Fcb,
1658 BOOLEAN bStatus = FALSE;
1659 AFSFcb *pFcb = (AFSFcb *)Fcb;
1660 BOOLEAN bReleaseSectionObject = FALSE, bReleasePaging = FALSE;
1663 // Try and acquire the Fcb resource
1666 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
1667 AFS_TRACE_LEVEL_VERBOSE,
1668 "AFSAcquireFcbForLazyWrite Acquiring Fcb %p\n",
1672 // Try and grab the paging
1675 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
1676 AFS_TRACE_LEVEL_VERBOSE,
1677 "AFSAcquireFcbForLazyWrite Attempt to acquire Fcb PagingIo lock %p SHARED %08lX\n",
1678 &pFcb->NPFcb->PagingResource,
1679 PsGetCurrentThread()));
1681 if( AFSAcquireShared( &pFcb->NPFcb->PagingResource,
1685 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
1686 AFS_TRACE_LEVEL_VERBOSE,
1687 "AFSAcquireFcbForLazyWrite Acquired Fcb PagingIo lock %p SHARED %08lX\n",
1688 &pFcb->NPFcb->PagingResource,
1689 PsGetCurrentThread()));
1691 bReleasePaging = TRUE;
1693 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
1694 AFS_TRACE_LEVEL_VERBOSE,
1695 "AFSAcquireFcbForLazyWrite Attempt to acquire Fcb SectionObject lock %p SHARED %08lX\n",
1696 &pFcb->NPFcb->SectionObjectResource,
1697 PsGetCurrentThread()));
1699 if( AFSAcquireShared( &pFcb->NPFcb->SectionObjectResource,
1703 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
1704 AFS_TRACE_LEVEL_VERBOSE,
1705 "AFSAcquireFcbForLazyWrite Acquired Fcb SectionObject lock %p SHARED %08lX\n",
1706 &pFcb->NPFcb->SectionObjectResource,
1707 PsGetCurrentThread()));
1709 bReleaseSectionObject = TRUE;
1717 IoSetTopLevelIrp( (PIRP)FSRTL_CACHE_TOP_LEVEL_IRP);
1724 if( bReleaseSectionObject)
1727 AFSReleaseResource( &pFcb->NPFcb->SectionObjectResource);
1733 AFSReleaseResource( &pFcb->NPFcb->PagingResource);
1741 AFSReleaseFcbFromLazyWrite( IN PVOID Fcb)
1744 AFSFcb *pFcb = (AFSFcb *)Fcb;
1746 AFSDbgTrace(( AFS_SUBSYSTEM_IO_PROCESSING,
1747 AFS_TRACE_LEVEL_VERBOSE,
1748 "AFSReleaseFcbFromLazyWrite Releasing Fcb %p\n",
1751 IoSetTopLevelIrp( NULL);
1753 AFSReleaseResource( &pFcb->NPFcb->SectionObjectResource);
1755 AFSReleaseResource( &pFcb->NPFcb->PagingResource);
1761 AFSAcquireFcbForReadAhead( IN PVOID Fcb,
1765 BOOLEAN bStatus = FALSE;
1766 AFSFcb *pFcb = (AFSFcb *)Fcb;
1768 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
1769 AFS_TRACE_LEVEL_VERBOSE,
1770 "AFSAcquireFcbForReadAhead Attempt to acquire Fcb SectionObject lock %p SHARED %08lX\n",
1771 &pFcb->NPFcb->SectionObjectResource,
1772 PsGetCurrentThread()));
1774 if( AFSAcquireShared( &pFcb->NPFcb->SectionObjectResource,
1778 AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
1779 AFS_TRACE_LEVEL_VERBOSE,
1780 "AFSAcquireFcbForReadAhead Acquired Fcb SectionObject lock %p SHARED %08lX\n",
1781 &pFcb->NPFcb->SectionObjectResource,
1782 PsGetCurrentThread()));
1786 IoSetTopLevelIrp( (PIRP)FSRTL_CACHE_TOP_LEVEL_IRP);
1793 AFSReleaseFcbFromReadAhead( IN PVOID Fcb)
1796 AFSFcb *pFcb = (AFSFcb *)Fcb;
1798 IoSetTopLevelIrp( NULL);
1800 AFSReleaseResource( &pFcb->NPFcb->SectionObjectResource);
1806 AFSGetCallerSID( OUT UNICODE_STRING *SIDString, OUT BOOLEAN *pbImpersonation)
1809 NTSTATUS ntStatus = STATUS_SUCCESS;
1810 PACCESS_TOKEN hToken = NULL;
1811 TOKEN_USER *pTokenInfo = NULL;
1812 BOOLEAN bCopyOnOpen = FALSE;
1813 BOOLEAN bEffectiveOnly = FALSE;
1814 BOOLEAN bPrimaryToken = FALSE;
1815 SECURITY_IMPERSONATION_LEVEL stImpersonationLevel;
1816 UNICODE_STRING uniSIDString;
1821 hToken = PsReferenceImpersonationToken( PsGetCurrentThread(),
1824 &stImpersonationLevel);
1829 hToken = PsReferencePrimaryToken( PsGetCurrentProcess());
1834 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1835 AFS_TRACE_LEVEL_ERROR,
1836 "AFSGetCallerSID Failed to retrieve impersonation or primary token\n"));
1838 try_return( ntStatus);
1841 bPrimaryToken = TRUE;
1844 ntStatus = SeQueryInformationToken( hToken,
1846 (PVOID *)&pTokenInfo);
1848 if( !NT_SUCCESS( ntStatus))
1851 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1852 AFS_TRACE_LEVEL_ERROR,
1853 "AFSGetCallerSID Failed to retrieve information Status %08lX\n",
1856 try_return( ntStatus);
1859 uniSIDString.Length = 0;
1860 uniSIDString.MaximumLength = 0;
1861 uniSIDString.Buffer = NULL;
1863 ntStatus = RtlConvertSidToUnicodeString( &uniSIDString,
1864 pTokenInfo->User.Sid,
1867 if( !NT_SUCCESS( ntStatus))
1870 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1871 AFS_TRACE_LEVEL_ERROR,
1872 "AFSGetCallerSID Failed to convert sid to string Status %08lX\n",
1875 try_return( ntStatus);
1878 *SIDString = uniSIDString;
1880 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING | AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
1881 AFS_TRACE_LEVEL_VERBOSE_2,
1882 "AFSGetCallerSID Successfully retrieved SID %wZ\n",
1885 if ( bPrimaryToken == FALSE &&
1888 *pbImpersonation = TRUE;
1897 PsDereferencePrimaryToken( hToken);
1901 PsDereferenceImpersonationToken( hToken);
1905 if( pTokenInfo != NULL)
1907 ExFreePool( pTokenInfo); // Allocated by SeQueryInformationToken
1915 AFSGetSessionId( IN HANDLE ProcessId, OUT BOOLEAN *pbImpersonation)
1917 UNREFERENCED_PARAMETER(ProcessId);
1919 NTSTATUS ntStatus = STATUS_SUCCESS;
1920 PACCESS_TOKEN hToken = NULL;
1921 ULONG ulSessionId = (ULONG)-1;
1922 BOOLEAN bCopyOnOpen = FALSE;
1923 BOOLEAN bEffectiveOnly = FALSE;
1924 BOOLEAN bPrimaryToken = FALSE;
1925 SECURITY_IMPERSONATION_LEVEL stImpersonationLevel;
1930 hToken = PsReferenceImpersonationToken( PsGetCurrentThread(),
1933 &stImpersonationLevel);
1938 hToken = PsReferencePrimaryToken( PsGetCurrentProcess());
1943 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1944 AFS_TRACE_LEVEL_ERROR,
1945 "AFSGetSessionId Failed to retrieve impersonation or primary token\n"));
1947 try_return( ntStatus);
1950 bPrimaryToken = TRUE;
1953 ntStatus = SeQueryInformationToken( hToken,
1955 (PVOID *)&ulSessionId);
1957 if( !NT_SUCCESS( ntStatus))
1959 ulSessionId = (ULONG)-1;
1961 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING,
1962 AFS_TRACE_LEVEL_ERROR,
1963 "AFSGetSessionId Failed to retrieve session id Status %08lX\n",
1966 try_return( ntStatus);
1969 AFSDbgTrace(( AFS_SUBSYSTEM_FILE_PROCESSING | AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
1970 AFS_TRACE_LEVEL_VERBOSE_2,
1971 "AFSGetSessionId found %08lX\n",
1974 if ( bPrimaryToken == FALSE &&
1977 *pbImpersonation = TRUE;
1986 PsDereferencePrimaryToken( hToken);
1990 PsDereferenceImpersonationToken( hToken);
1999 AFSCheckThreadDacl( OUT GUID *AuthGroup)
2002 NTSTATUS ntStatus = STATUS_UNSUCCESSFUL;
2004 PACCESS_TOKEN token = NULL;
2005 PTOKEN_DEFAULT_DACL defDacl = NULL;
2007 PACCESS_ALLOWED_ACE adace;
2008 BOOLEAN bCopyOnOpen = FALSE, bEffectiveOnly = FALSE;
2009 SECURITY_IMPERSONATION_LEVEL stImpersonationLevel;
2010 BOOLEAN bLocatedACE = FALSE;
2015 token = PsReferenceImpersonationToken( PsGetCurrentThread(),
2018 &stImpersonationLevel);
2022 try_return( ntStatus);
2025 ntStatus = SeQueryInformationToken( token,
2029 if( ntStatus != STATUS_SUCCESS)
2031 try_return( ntStatus);
2034 // scan through all ACEs in the DACL
2035 for (idx = 0, ace = (PACE_HEADER)((char *)defDacl->DefaultDacl + sizeof(ACL)); idx < defDacl->DefaultDacl->AceCount; idx++)
2037 if (ace->AceType == ACCESS_ALLOWED_ACE_TYPE)
2039 adace = (PACCESS_ALLOWED_ACE)ace;
2041 if (adace->Header.AceSize == (FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + AFS_DACL_SID_LENGTH))
2043 if (RtlCompareMemory( RtlSubAuthoritySid((PSID)&adace->SidStart, 0), &AFSSidGuid, sizeof(GUID)) == sizeof(GUID))
2046 RtlCopyMemory( AuthGroup,
2047 RtlSubAuthoritySid((PSID)&adace->SidStart, 4),
2058 ace = (PACE_HEADER)((char *)ace + ace->AceSize);
2065 PsDereferenceImpersonationToken( token);
2068 if (defDacl != NULL)
2070 ExFreePool(defDacl);
2075 ntStatus = STATUS_UNSUCCESSFUL;
2083 AFSProcessSetProcessDacl( IN AFSProcessCB *ProcessCB)
2086 PTOKEN_DEFAULT_DACL defDacl = NULL;
2087 HANDLE hToken = NULL;
2088 PACE_HEADER ace = NULL;
2089 SID_IDENTIFIER_AUTHORITY sia = SECURITY_NT_AUTHORITY;
2090 PACCESS_ALLOWED_ACE aaace;
2092 ULONG bytesReturned;
2095 NTSTATUS ntStatus = STATUS_SUCCESS;
2100 ntStatus = ZwOpenProcessTokenEx( NtCurrentProcess(),
2105 if( !NT_SUCCESS( ntStatus))
2107 try_return( ntStatus);
2110 // get the size of the current DACL
2111 ntStatus = ZwQueryInformationToken( hToken,
2117 // if we failed to get the buffer size needed
2118 if ((ntStatus != STATUS_SUCCESS) && (ntStatus != STATUS_BUFFER_TOO_SMALL))
2120 try_return( ntStatus);
2123 // tack on enough space for our ACE if we need to add it...
2124 bytesNeeded += FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + AFS_DACL_SID_LENGTH;
2126 // allocate space for the DACL
2127 defDacl = (PTOKEN_DEFAULT_DACL)ExAllocatePoolWithTag( PagedPool, bytesNeeded, AFS_GENERIC_MEMORY_26_TAG);
2129 if (defDacl == NULL)
2131 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2135 ntStatus = ZwQueryInformationToken( hToken,
2141 if( ntStatus != STATUS_SUCCESS)
2143 try_return( ntStatus);
2146 // scan through DACL to see if we have the SID set already...
2147 ace = (PACE_HEADER)((char *)defDacl->DefaultDacl + sizeof(ACL));
2148 for (idx = 0; idx < defDacl->DefaultDacl->AceCount; idx++)
2150 if (ace->AceType == ACCESS_ALLOWED_ACE_TYPE)
2152 aaace = (PACCESS_ALLOWED_ACE)ace;
2154 if (aaace->Header.AceSize == (FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + AFS_DACL_SID_LENGTH))
2156 // if the GUID part matches
2157 if( RtlCompareMemory( RtlSubAuthoritySid((PSID)&aaace->SidStart, 0),
2159 sizeof(GUID)) == sizeof(GUID))
2162 if ( RtlCompareMemory( RtlSubAuthoritySid((PSID)&aaace->SidStart, 4),
2163 ProcessCB->ActiveAuthGroup,
2164 sizeof( GUID)) != sizeof( GUID))
2167 RtlCopyMemory( RtlSubAuthoritySid((PSID)&aaace->SidStart, 4),
2168 ProcessCB->ActiveAuthGroup,
2171 if( AFSSetInformationToken != NULL)
2173 ntStatus = AFSSetInformationToken( hToken,
2180 try_return( ntStatus);
2186 ace = (PACE_HEADER)((char *)ace + ace->AceSize);
2190 // if we made it here we need to add a new ACE to the DACL
2193 aaace = (ACCESS_ALLOWED_ACE *)ace;
2194 aaace->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
2195 aaace->Header.AceFlags = 0;
2196 aaace->Mask = GENERIC_ALL;
2197 psid = (PSID)&aaace->SidStart;
2198 RtlInitializeSid( psid, &sia, 8);
2200 RtlCopyMemory( RtlSubAuthoritySid(psid, 0),
2204 RtlCopyMemory( RtlSubAuthoritySid(psid, 4),
2205 ProcessCB->ActiveAuthGroup,
2208 aaace->Header.AceSize = (USHORT)(FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + RtlLengthSid( psid));
2210 defDacl->DefaultDacl->AclSize += aaace->Header.AceSize;
2211 defDacl->DefaultDacl->AceCount++;
2213 if( AFSSetInformationToken != NULL)
2215 ntStatus = AFSSetInformationToken( hToken,
2218 defDacl->DefaultDacl->AclSize + sizeof(PTOKEN_DEFAULT_DACL));
2228 if (defDacl != NULL)
2230 ExFreePool( defDacl);