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 AFSDbgLogMsg( 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 AFSDbgLogMsg( 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;
817 AFSRemoveControlDevice()
820 NTSTATUS ntStatus = STATUS_SUCCESS;
821 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension;
827 // Initialize the comm pool resources
830 ExDeleteResourceLite( &pDeviceExt->Specific.Control.CommServiceCB.IrpPoolLock);
832 ExDeleteResourceLite( &pDeviceExt->Specific.Control.CommServiceCB.ResultPoolLock);
834 ExDeleteResourceLite( &pDeviceExt->Specific.Control.ExtentReleaseResource);
836 ExDeleteResourceLite( &pDeviceExt->Specific.Control.SysName32ListLock);
838 ExDeleteResourceLite( &pDeviceExt->Specific.Control.SysName64ListLock);
840 ExDeleteResourceLite( &pDeviceExt->Specific.Control.ProcessTreeLock);
842 if( pDeviceExt->Specific.Control.ProcessTree.TreeHead != NULL)
844 ExFreePool( pDeviceExt->Specific.Control.ProcessTree.TreeHead);
847 ExDeleteResourceLite( &pDeviceExt->Specific.Control.AuthGroupTreeLock);
849 ExDeleteResourceLite( &pDeviceExt->Specific.Control.LibraryStateLock);
851 ExDeleteResourceLite( &pDeviceExt->Specific.Control.LibraryQueueLock);
858 AFSInitServerStrings()
861 UNICODE_STRING uniFullName;
862 WCHAR wchBuffer[ 50];
865 // Add the server name into the list of resources
868 uniFullName.Length = (2 * sizeof( WCHAR)) + AFSServerName.Length;
869 uniFullName.MaximumLength = uniFullName.Length + sizeof( WCHAR);
871 uniFullName.Buffer = wchBuffer;
873 wchBuffer[ 0] = L'\\';
874 wchBuffer[ 1] = L'\\';
876 RtlCopyMemory( &wchBuffer[ 2],
877 AFSServerName.Buffer,
878 AFSServerName.Length);
880 AFSAddConnectionEx( &uniFullName,
881 RESOURCEDISPLAYTYPE_SERVER,
885 // Add in the global share name
888 wchBuffer[ uniFullName.Length/sizeof( WCHAR)] = L'\\';
890 uniFullName.Length += sizeof( WCHAR);
892 RtlCopyMemory( &wchBuffer[ uniFullName.Length/sizeof( WCHAR)],
893 AFSGlobalRootName.Buffer,
894 AFSGlobalRootName.Length);
896 uniFullName.Length += AFSGlobalRootName.Length;
898 AFSAddConnectionEx( &uniFullName,
899 RESOURCEDISPLAYTYPE_SHARE,
900 AFS_CONNECTION_FLAG_GLOBAL_SHARE);
909 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_REG_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 AFSReadMountRootName()
1000 NTSTATUS ntStatus = STATUS_SUCCESS;
1001 UNICODE_STRING paramPath;
1002 RTL_QUERY_REGISTRY_TABLE paramTable[2];
1008 // Setup the paramPath buffer.
1011 paramPath.MaximumLength = PAGE_SIZE;
1012 paramPath.Buffer = (PWSTR)AFSExAllocatePoolWithTag( PagedPool,
1013 paramPath.MaximumLength,
1014 AFS_GENERIC_MEMORY_17_TAG);
1017 // If it exists, setup the path.
1020 if( paramPath.Buffer == NULL)
1023 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1027 // Move in the paths
1030 RtlZeroMemory( paramPath.Buffer,
1031 paramPath.MaximumLength);
1033 RtlCopyMemory( ¶mPath.Buffer[ 0],
1034 L"\\TransarcAFSDaemon\\Parameters",
1037 paramPath.Length = 58;
1039 RtlZeroMemory( paramTable,
1040 sizeof( paramTable));
1043 // Setup the table to query the registry for the needed value
1046 AFSMountRootName.Length = 0;
1047 AFSMountRootName.MaximumLength = 0;
1048 AFSMountRootName.Buffer = NULL;
1050 paramTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
1051 paramTable[0].Name = AFS_REG_MOUNT_ROOT;
1052 paramTable[0].EntryContext = &AFSMountRootName;
1054 paramTable[0].DefaultType = REG_NONE;
1055 paramTable[0].DefaultData = NULL;
1056 paramTable[0].DefaultLength = 0;
1059 // Query the registry
1062 ntStatus = RtlQueryRegistryValues( RTL_REGISTRY_SERVICES,
1068 if ( NT_SUCCESS( ntStatus))
1070 if ( AFSMountRootName.Buffer[0] == L'/')
1073 AFSMountRootName.Buffer[0] = L'\\';
1078 // Free up the buffer
1081 ExFreePool( paramPath.Buffer);
1085 if( !NT_SUCCESS( ntStatus))
1088 RtlInitUnicodeString( &AFSMountRootName,
1097 AFSSetSysNameInformation( IN AFSSysNameNotificationCB *SysNameInfo,
1098 IN ULONG SysNameInfoBufferLength)
1100 UNREFERENCED_PARAMETER(SysNameInfoBufferLength);
1102 NTSTATUS ntStatus = STATUS_SUCCESS;
1103 AFSDeviceExt *pControlDevExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension;
1104 AFSSysNameCB *pSysName = NULL;
1105 ERESOURCE *pSysNameLock = NULL;
1106 AFSSysNameCB **pSysNameListHead = NULL, **pSysNameListTail = NULL;
1112 // Depending on the architecture of the information, set up the lsit
1115 if( SysNameInfo->Architecture == AFS_SYSNAME_ARCH_32BIT)
1118 pSysNameLock = &pControlDevExt->Specific.Control.SysName32ListLock;
1120 pSysNameListHead = &pControlDevExt->Specific.Control.SysName32ListHead;
1122 pSysNameListTail = &pControlDevExt->Specific.Control.SysName32ListTail;
1129 pSysNameLock = &pControlDevExt->Specific.Control.SysName64ListLock;
1131 pSysNameListHead = &pControlDevExt->Specific.Control.SysName64ListHead;
1133 pSysNameListTail = &pControlDevExt->Specific.Control.SysName64ListTail;
1137 try_return( ntStatus = STATUS_INVALID_PARAMETER);
1142 // Process the request
1145 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
1146 AFS_TRACE_LEVEL_VERBOSE,
1147 "AFSSetSysNameInformation Acquiring SysName lock %p EXCL %08lX\n",
1149 PsGetCurrentThread());
1151 AFSAcquireExcl( pSysNameLock,
1155 // If we already have a list, then tear it down
1158 if( *pSysNameListHead != NULL)
1161 AFSResetSysNameList( *pSysNameListHead);
1163 *pSysNameListHead = NULL;
1167 // Loop through the entries adding in a node for each
1170 while( ulIndex < SysNameInfo->NumberOfNames)
1173 pSysName = (AFSSysNameCB *)AFSExAllocatePoolWithTag( PagedPool,
1174 sizeof( AFSSysNameCB) +
1175 SysNameInfo->SysNames[ ulIndex].Length +
1177 AFS_SYS_NAME_NODE_TAG);
1179 if( pSysName == NULL)
1183 // Reset the current list
1186 AFSResetSysNameList( *pSysNameListHead);
1188 *pSysNameListHead = NULL;
1190 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1193 RtlZeroMemory( pSysName,
1194 sizeof( AFSSysNameCB) +
1195 SysNameInfo->SysNames[ ulIndex].Length +
1198 pSysName->SysName.Length = (USHORT)SysNameInfo->SysNames[ ulIndex].Length;
1200 pSysName->SysName.MaximumLength = pSysName->SysName.Length + sizeof( WCHAR);
1202 pSysName->SysName.Buffer = (WCHAR *)((char *)pSysName + sizeof( AFSSysNameCB));
1204 RtlCopyMemory( pSysName->SysName.Buffer,
1205 SysNameInfo->SysNames[ ulIndex].String,
1206 pSysName->SysName.Length);
1208 if( *pSysNameListHead == NULL)
1211 *pSysNameListHead = pSysName;
1216 (*pSysNameListTail)->fLink = pSysName;
1219 *pSysNameListTail = pSysName;
1226 AFSReleaseResource( pSysNameLock);
1233 AFSResetSysNameList( IN AFSSysNameCB *SysNameList)
1236 AFSSysNameCB *pNextEntry = NULL, *pCurrentEntry = SysNameList;
1238 while( pCurrentEntry != NULL)
1241 pNextEntry = pCurrentEntry->fLink;
1243 ExFreePool( pCurrentEntry);
1245 pCurrentEntry = pNextEntry;
1252 AFSDefaultDispatch( IN PDEVICE_OBJECT DeviceObject,
1255 UNREFERENCED_PARAMETER(DeviceObject);
1257 NTSTATUS ntStatus = STATUS_INVALID_DEVICE_REQUEST;
1259 AFSCompleteRequest( Irp,
1266 AFSSendDeviceIoControl( IN DEVICE_OBJECT *TargetDeviceObject,
1268 IN void *InputBuffer,
1269 IN ULONG InputBufferLength,
1270 IN OUT void *OutputBuffer,
1271 IN ULONG OutputBufferLength,
1272 OUT ULONG *ResultLength)
1274 UNREFERENCED_PARAMETER(OutputBuffer);
1275 UNREFERENCED_PARAMETER(OutputBufferLength);
1277 NTSTATUS ntStatus = STATUS_SUCCESS;
1280 PIO_STACK_LOCATION pIoStackLocation = NULL;
1286 // Initialize the event
1289 KeInitializeEvent( &kEvent,
1290 SynchronizationEvent,
1294 // Allocate an irp for this request. This could also come from a
1295 // private pool, for instance.
1298 pIrp = IoAllocateIrp( TargetDeviceObject->StackSize,
1304 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1308 // Build the IRP's main body
1311 pIrp->RequestorMode = KernelMode;
1314 // Set up the I/O stack location.
1317 pIoStackLocation = IoGetNextIrpStackLocation( pIrp);
1318 pIoStackLocation->MajorFunction = IRP_MJ_DEVICE_CONTROL;
1319 pIoStackLocation->DeviceObject = TargetDeviceObject;
1321 pIoStackLocation->Parameters.DeviceIoControl.IoControlCode = IOControl;
1323 pIrp->AssociatedIrp.SystemBuffer = (void *)InputBuffer;
1324 pIoStackLocation->Parameters.DeviceIoControl.InputBufferLength = InputBufferLength;
1327 // Set the completion routine.
1330 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
1331 AFS_TRACE_LEVEL_VERBOSE,
1332 "Setting AFSIrpComplete as IoCompletion Routine Irp %p\n",
1335 IoSetCompletionRoutine( pIrp,
1343 // Send it to the FSD
1346 ntStatus = IoCallDriver( TargetDeviceObject,
1349 if( NT_SUCCESS( ntStatus))
1356 ntStatus = KeWaitForSingleObject( &kEvent,
1362 if( NT_SUCCESS( ntStatus))
1365 ntStatus = pIrp->IoStatus.Status;
1367 if( ResultLength != NULL)
1369 *ResultLength = (ULONG)pIrp->IoStatus.Information;
1379 if( pIrp->MdlAddress != NULL)
1382 if( FlagOn( pIrp->MdlAddress->MdlFlags, MDL_PAGES_LOCKED))
1385 MmUnlockPages( pIrp->MdlAddress);
1388 IoFreeMdl( pIrp->MdlAddress);
1391 pIrp->MdlAddress = NULL;
1405 AFSIrpComplete( IN PDEVICE_OBJECT DeviceObject,
1409 UNREFERENCED_PARAMETER(DeviceObject);
1410 UNREFERENCED_PARAMETER(Irp);
1412 KEVENT *pEvent = (KEVENT *)Context;
1418 return STATUS_MORE_PROCESSING_REQUIRED;
1422 AFSExAllocatePoolWithTag( IN POOL_TYPE PoolType,
1423 IN SIZE_T NumberOfBytes,
1427 AFSDeviceExt *pControlDevExt = NULL;
1428 void *pBuffer = NULL;
1429 BOOLEAN bTimeout = FALSE;
1430 LARGE_INTEGER liTimeout;
1434 // Attempt to allocation memory from the system. If the allocation fails
1435 // wait up to 30 seconds for the AFS redirector to free some memory. As
1436 // long as the wait does not timeout, continue to retry the allocation.
1437 // If the wait does timeout, attempt to allocate one more time in case
1438 // memory was freed by another driver. Otherwise, fail the request.
1441 if ( AFSDeviceObject)
1444 pControlDevExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension;
1447 while( pBuffer == NULL)
1450 pBuffer = ExAllocatePoolWithTag( PoolType,
1454 if( pBuffer == NULL)
1457 if ( bTimeout || pControlDevExt == NULL)
1462 "AFSExAllocatePoolWithTag failure Type %08lX Size %08lX Tag %08lX %08lX\n",
1466 PsGetCurrentThread());
1470 case AFS_GENERIC_MEMORY_21_TAG:
1471 case AFS_GENERIC_MEMORY_22_TAG:
1472 // AFSDumpTraceFiles -- do nothing;
1484 // Wait up to 30 seconds for a memory deallocation
1487 liTimeout.QuadPart = -(30 *AFS_ONE_SECOND);
1489 if( InterlockedIncrement( &pControlDevExt->Specific.Control.WaitingForMemoryCount) == 1)
1491 KeClearEvent( &pControlDevExt->Specific.Control.MemoryAvailableEvent);
1494 ntStatus = KeWaitForSingleObject( &pControlDevExt->Specific.Control.MemoryAvailableEvent,
1500 if( ntStatus == STATUS_TIMEOUT)
1506 InterlockedDecrement( &pControlDevExt->Specific.Control.WaitingForMemoryCount);
1514 AFSExFreePoolWithTag( IN void *Buffer, IN ULONG Tag)
1517 AFSDeviceExt *pControlDevExt = NULL;
1519 if ( AFSDeviceObject)
1522 pControlDevExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension;
1528 ExFreePoolWithTag( Buffer, Tag);
1533 ExFreePool( Buffer);
1536 if ( pControlDevExt)
1539 KeSetEvent( &pControlDevExt->Specific.Control.MemoryAvailableEvent,
1547 AFSShutdownRedirector()
1550 NTSTATUS ntStatus = STATUS_SUCCESS;
1551 AFSDeviceExt *pRDRDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1552 AFSDeviceExt *pControlDevExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension;
1553 LARGE_INTEGER liTimeout;
1558 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1559 AFS_TRACE_LEVEL_VERBOSE,
1560 "%s Shutting down redirector Extent count %08lX Request count %08lX\n",
1562 pControlDevExt->Specific.Control.ExtentCount,
1563 pControlDevExt->Specific.Control.OutstandingServiceRequestCount);
1566 // Set the shutdown flag so the worker is more agressive in tearing down extents
1569 SetFlag( pRDRDevExt->DeviceFlags, AFS_DEVICE_FLAG_REDIRECTOR_SHUTDOWN);
1572 // Wait on any outstanding service requests
1575 liTimeout.QuadPart = -(30 *AFS_ONE_SECOND);
1577 ntStatus = KeWaitForSingleObject( &pControlDevExt->Specific.Control.OutstandingServiceRequestEvent,
1583 if( ntStatus == STATUS_TIMEOUT)
1586 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1587 AFS_TRACE_LEVEL_WARNING,
1588 "AFSShutdownRedirector Failed to complete all service requests Remaining count %08lX\n",
1589 pControlDevExt->Specific.Control.OutstandingServiceRequestCount);
1591 try_return( ntStatus = STATUS_UNSUCCESSFUL);
1594 AFSProcessQueuedResults( TRUE);
1597 // Wait for all extents to be released
1600 liTimeout.QuadPart = -(30 *AFS_ONE_SECOND);
1602 ntStatus = KeWaitForSingleObject( &pControlDevExt->Specific.Control.ExtentsHeldEvent,
1608 if( ntStatus == STATUS_TIMEOUT)
1611 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1612 AFS_TRACE_LEVEL_WARNING,
1613 "AFSShutdownRedirector Failed to purge all extents Remaining count %08lX\n",
1614 pControlDevExt->Specific.Control.ExtentCount);
1616 try_return( ntStatus = STATUS_UNSUCCESSFUL);
1619 ntStatus = AFSUnloadLibrary( TRUE);
1621 if( !NT_SUCCESS( ntStatus))
1624 try_return( ntStatus);
1629 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1630 AFS_TRACE_LEVEL_VERBOSE,
1631 "%s Completed shut down of redirector Extent count %08lX Request count %08lX Status %08lX\n",
1633 pControlDevExt->Specific.Control.ExtentCount,
1634 pControlDevExt->Specific.Control.OutstandingServiceRequestCount,
1642 // Cache manager callback routines
1646 AFSAcquireFcbForLazyWrite( IN PVOID Fcb,
1650 BOOLEAN bStatus = FALSE;
1651 AFSFcb *pFcb = (AFSFcb *)Fcb;
1652 BOOLEAN bReleaseSectionObject = FALSE, bReleasePaging = FALSE;
1655 // Try and acquire the Fcb resource
1658 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
1659 AFS_TRACE_LEVEL_VERBOSE,
1660 "AFSAcquireFcbForLazyWrite Acquiring Fcb %p\n",
1664 // Try and grab the paging
1667 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
1668 AFS_TRACE_LEVEL_VERBOSE,
1669 "AFSAcquireFcbForLazyWrite Attempt to acquire Fcb PagingIo lock %p SHARED %08lX\n",
1670 &pFcb->NPFcb->PagingResource,
1671 PsGetCurrentThread());
1673 if( AFSAcquireShared( &pFcb->NPFcb->PagingResource,
1677 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
1678 AFS_TRACE_LEVEL_VERBOSE,
1679 "AFSAcquireFcbForLazyWrite Acquired Fcb PagingIo lock %p SHARED %08lX\n",
1680 &pFcb->NPFcb->PagingResource,
1681 PsGetCurrentThread());
1683 bReleasePaging = TRUE;
1685 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
1686 AFS_TRACE_LEVEL_VERBOSE,
1687 "AFSAcquireFcbForLazyWrite Attempt to acquire Fcb SectionObject lock %p SHARED %08lX\n",
1688 &pFcb->NPFcb->SectionObjectResource,
1689 PsGetCurrentThread());
1691 if( AFSAcquireShared( &pFcb->NPFcb->SectionObjectResource,
1695 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
1696 AFS_TRACE_LEVEL_VERBOSE,
1697 "AFSAcquireFcbForLazyWrite Acquired Fcb SectionObject lock %p SHARED %08lX\n",
1698 &pFcb->NPFcb->SectionObjectResource,
1699 PsGetCurrentThread());
1701 bReleaseSectionObject = TRUE;
1709 IoSetTopLevelIrp( (PIRP)FSRTL_CACHE_TOP_LEVEL_IRP);
1716 if( bReleaseSectionObject)
1719 AFSReleaseResource( &pFcb->NPFcb->SectionObjectResource);
1725 AFSReleaseResource( &pFcb->NPFcb->PagingResource);
1733 AFSReleaseFcbFromLazyWrite( IN PVOID Fcb)
1736 AFSFcb *pFcb = (AFSFcb *)Fcb;
1738 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
1739 AFS_TRACE_LEVEL_VERBOSE,
1740 "AFSReleaseFcbFromLazyWrite Releasing Fcb %p\n",
1743 IoSetTopLevelIrp( NULL);
1745 AFSReleaseResource( &pFcb->NPFcb->SectionObjectResource);
1747 AFSReleaseResource( &pFcb->NPFcb->PagingResource);
1753 AFSAcquireFcbForReadAhead( IN PVOID Fcb,
1757 BOOLEAN bStatus = FALSE;
1758 AFSFcb *pFcb = (AFSFcb *)Fcb;
1760 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
1761 AFS_TRACE_LEVEL_VERBOSE,
1762 "AFSAcquireFcbForReadAhead Attempt to acquire Fcb SectionObject lock %p SHARED %08lX\n",
1763 &pFcb->NPFcb->SectionObjectResource,
1764 PsGetCurrentThread());
1766 if( AFSAcquireShared( &pFcb->NPFcb->SectionObjectResource,
1770 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
1771 AFS_TRACE_LEVEL_VERBOSE,
1772 "AFSAcquireFcbForReadAhead Acquired Fcb SectionObject lock %p SHARED %08lX\n",
1773 &pFcb->NPFcb->SectionObjectResource,
1774 PsGetCurrentThread());
1778 IoSetTopLevelIrp( (PIRP)FSRTL_CACHE_TOP_LEVEL_IRP);
1785 AFSReleaseFcbFromReadAhead( IN PVOID Fcb)
1788 AFSFcb *pFcb = (AFSFcb *)Fcb;
1790 IoSetTopLevelIrp( NULL);
1792 AFSReleaseResource( &pFcb->NPFcb->SectionObjectResource);
1798 AFSGetCallerSID( OUT UNICODE_STRING *SIDString, OUT BOOLEAN *pbImpersonation)
1801 NTSTATUS ntStatus = STATUS_SUCCESS;
1802 PACCESS_TOKEN hToken = NULL;
1803 TOKEN_USER *pTokenInfo = NULL;
1804 BOOLEAN bCopyOnOpen = FALSE;
1805 BOOLEAN bEffectiveOnly = FALSE;
1806 BOOLEAN bPrimaryToken = FALSE;
1807 SECURITY_IMPERSONATION_LEVEL stImpersonationLevel;
1808 UNICODE_STRING uniSIDString;
1813 hToken = PsReferenceImpersonationToken( PsGetCurrentThread(),
1816 &stImpersonationLevel);
1821 hToken = PsReferencePrimaryToken( PsGetCurrentProcess());
1826 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1827 AFS_TRACE_LEVEL_ERROR,
1828 "AFSGetCallerSID Failed to retrieve impersonation or primary token\n");
1830 try_return( ntStatus);
1833 bPrimaryToken = TRUE;
1836 ntStatus = SeQueryInformationToken( hToken,
1838 (PVOID *)&pTokenInfo);
1840 if( !NT_SUCCESS( ntStatus))
1843 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1844 AFS_TRACE_LEVEL_ERROR,
1845 "AFSGetCallerSID Failed to retrieve information Status %08lX\n", ntStatus);
1847 try_return( ntStatus);
1850 uniSIDString.Length = 0;
1851 uniSIDString.MaximumLength = 0;
1852 uniSIDString.Buffer = NULL;
1854 ntStatus = RtlConvertSidToUnicodeString( &uniSIDString,
1855 pTokenInfo->User.Sid,
1858 if( !NT_SUCCESS( ntStatus))
1861 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1862 AFS_TRACE_LEVEL_ERROR,
1863 "AFSGetCallerSID Failed to convert sid to string Status %08lX\n", ntStatus);
1865 try_return( ntStatus);
1868 *SIDString = uniSIDString;
1870 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING | AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
1871 AFS_TRACE_LEVEL_VERBOSE_2,
1872 "AFSGetCallerSID Successfully retrieved SID %wZ\n",
1875 if ( bPrimaryToken == FALSE &&
1878 *pbImpersonation = TRUE;
1887 PsDereferencePrimaryToken( hToken);
1891 PsDereferenceImpersonationToken( hToken);
1895 if( pTokenInfo != NULL)
1897 ExFreePool( pTokenInfo); // Allocated by SeQueryInformationToken
1905 AFSGetSessionId( IN HANDLE ProcessId, OUT BOOLEAN *pbImpersonation)
1907 UNREFERENCED_PARAMETER(ProcessId);
1909 NTSTATUS ntStatus = STATUS_SUCCESS;
1910 PACCESS_TOKEN hToken = NULL;
1911 ULONG ulSessionId = (ULONG)-1;
1912 BOOLEAN bCopyOnOpen = FALSE;
1913 BOOLEAN bEffectiveOnly = FALSE;
1914 BOOLEAN bPrimaryToken = FALSE;
1915 SECURITY_IMPERSONATION_LEVEL stImpersonationLevel;
1920 hToken = PsReferenceImpersonationToken( PsGetCurrentThread(),
1923 &stImpersonationLevel);
1928 hToken = PsReferencePrimaryToken( PsGetCurrentProcess());
1933 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1934 AFS_TRACE_LEVEL_ERROR,
1935 "AFSGetSessionId Failed to retrieve impersonation or primary token\n");
1937 try_return( ntStatus);
1940 bPrimaryToken = TRUE;
1943 ntStatus = SeQueryInformationToken( hToken,
1945 (PVOID *)&ulSessionId);
1947 if( !NT_SUCCESS( ntStatus))
1949 ulSessionId = (ULONG)-1;
1951 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1952 AFS_TRACE_LEVEL_ERROR,
1953 "AFSGetSessionId Failed to retrieve session id Status %08lX\n",
1956 try_return( ntStatus);
1959 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING | AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
1960 AFS_TRACE_LEVEL_VERBOSE_2,
1961 "AFSGetSessionId found %08lX\n",
1964 if ( bPrimaryToken == FALSE &&
1967 *pbImpersonation = TRUE;
1976 PsDereferencePrimaryToken( hToken);
1980 PsDereferenceImpersonationToken( hToken);
1989 AFSCheckThreadDacl( OUT GUID *AuthGroup)
1992 NTSTATUS ntStatus = STATUS_UNSUCCESSFUL;
1994 PACCESS_TOKEN token = NULL;
1995 PTOKEN_DEFAULT_DACL defDacl = NULL;
1997 PACCESS_ALLOWED_ACE adace;
1998 BOOLEAN bCopyOnOpen = FALSE, bEffectiveOnly = FALSE;
1999 SECURITY_IMPERSONATION_LEVEL stImpersonationLevel;
2000 BOOLEAN bLocatedACE = FALSE;
2005 token = PsReferenceImpersonationToken( PsGetCurrentThread(),
2008 &stImpersonationLevel);
2012 try_return( ntStatus);
2015 ntStatus = SeQueryInformationToken( token,
2019 if( ntStatus != STATUS_SUCCESS)
2021 try_return( ntStatus);
2024 // scan through all ACEs in the DACL
2025 for (idx = 0, ace = (PACE_HEADER)((char *)defDacl->DefaultDacl + sizeof(ACL)); idx < defDacl->DefaultDacl->AceCount; idx++)
2027 if (ace->AceType == ACCESS_ALLOWED_ACE_TYPE)
2029 adace = (PACCESS_ALLOWED_ACE)ace;
2031 if (adace->Header.AceSize == (FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + AFS_DACL_SID_LENGTH))
2033 if (RtlCompareMemory( RtlSubAuthoritySid((PSID)&adace->SidStart, 0), &AFSSidGuid, sizeof(GUID)) == sizeof(GUID))
2036 RtlCopyMemory( AuthGroup,
2037 RtlSubAuthoritySid((PSID)&adace->SidStart, 4),
2048 ace = (PACE_HEADER)((char *)ace + ace->AceSize);
2055 PsDereferenceImpersonationToken( token);
2058 if (defDacl != NULL)
2060 ExFreePool(defDacl);
2065 ntStatus = STATUS_UNSUCCESSFUL;
2073 AFSProcessSetProcessDacl( IN AFSProcessCB *ProcessCB)
2076 PTOKEN_DEFAULT_DACL defDacl = NULL;
2077 HANDLE hToken = NULL;
2078 PACE_HEADER ace = NULL;
2079 SID_IDENTIFIER_AUTHORITY sia = SECURITY_NT_AUTHORITY;
2080 PACCESS_ALLOWED_ACE aaace;
2082 ULONG bytesReturned;
2085 NTSTATUS ntStatus = STATUS_SUCCESS;
2090 ntStatus = ZwOpenProcessTokenEx( NtCurrentProcess(),
2095 if( !NT_SUCCESS( ntStatus))
2097 try_return( ntStatus);
2100 // get the size of the current DACL
2101 ntStatus = ZwQueryInformationToken( hToken,
2107 // if we failed to get the buffer size needed
2108 if ((ntStatus != STATUS_SUCCESS) && (ntStatus != STATUS_BUFFER_TOO_SMALL))
2110 try_return( ntStatus);
2113 // tack on enough space for our ACE if we need to add it...
2114 bytesNeeded += FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + AFS_DACL_SID_LENGTH;
2116 // allocate space for the DACL
2117 defDacl = (PTOKEN_DEFAULT_DACL)ExAllocatePoolWithTag( PagedPool, bytesNeeded, AFS_GENERIC_MEMORY_26_TAG);
2119 if (defDacl == NULL)
2121 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2125 ntStatus = ZwQueryInformationToken( hToken,
2131 if( ntStatus != STATUS_SUCCESS)
2133 try_return( ntStatus);
2136 // scan through DACL to see if we have the SID set already...
2137 ace = (PACE_HEADER)((char *)defDacl->DefaultDacl + sizeof(ACL));
2138 for (idx = 0; idx < defDacl->DefaultDacl->AceCount; idx++)
2140 if (ace->AceType == ACCESS_ALLOWED_ACE_TYPE)
2142 aaace = (PACCESS_ALLOWED_ACE)ace;
2144 if (aaace->Header.AceSize == (FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + AFS_DACL_SID_LENGTH))
2146 // if the GUID part matches
2147 if( RtlCompareMemory( RtlSubAuthoritySid((PSID)&aaace->SidStart, 0),
2149 sizeof(GUID)) == sizeof(GUID))
2152 if ( RtlCompareMemory( RtlSubAuthoritySid((PSID)&aaace->SidStart, 4),
2153 ProcessCB->ActiveAuthGroup,
2154 sizeof( GUID)) != sizeof( GUID))
2157 RtlCopyMemory( RtlSubAuthoritySid((PSID)&aaace->SidStart, 4),
2158 ProcessCB->ActiveAuthGroup,
2161 if( AFSSetInformationToken != NULL)
2163 ntStatus = AFSSetInformationToken( hToken,
2170 try_return( ntStatus);
2176 ace = (PACE_HEADER)((char *)ace + ace->AceSize);
2180 // if we made it here we need to add a new ACE to the DACL
2183 aaace = (ACCESS_ALLOWED_ACE *)ace;
2184 aaace->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
2185 aaace->Header.AceFlags = 0;
2186 aaace->Mask = GENERIC_ALL;
2187 psid = (PSID)&aaace->SidStart;
2188 RtlInitializeSid( psid, &sia, 8);
2190 RtlCopyMemory( RtlSubAuthoritySid(psid, 0),
2194 RtlCopyMemory( RtlSubAuthoritySid(psid, 4),
2195 ProcessCB->ActiveAuthGroup,
2198 aaace->Header.AceSize = (USHORT)(FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + RtlLengthSid( psid));
2200 defDacl->DefaultDacl->AclSize += aaace->Header.AceSize;
2201 defDacl->DefaultDacl->AceCount++;
2203 if( AFSSetInformationToken != NULL)
2205 ntStatus = AFSSetInformationToken( hToken,
2208 defDacl->DefaultDacl->AclSize + sizeof(PTOKEN_DEFAULT_DACL));
2218 if (defDacl != NULL)
2220 ExFreePool( defDacl);