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 IoSetCompletionRoutine( pIrp,
1338 // Send it to the FSD
1341 ntStatus = IoCallDriver( TargetDeviceObject,
1344 if( NT_SUCCESS( ntStatus))
1351 ntStatus = KeWaitForSingleObject( &kEvent,
1357 if( NT_SUCCESS( ntStatus))
1360 ntStatus = pIrp->IoStatus.Status;
1362 if( ResultLength != NULL)
1364 *ResultLength = (ULONG)pIrp->IoStatus.Information;
1374 if( pIrp->MdlAddress != NULL)
1377 if( FlagOn( pIrp->MdlAddress->MdlFlags, MDL_PAGES_LOCKED))
1380 MmUnlockPages( pIrp->MdlAddress);
1383 IoFreeMdl( pIrp->MdlAddress);
1386 pIrp->MdlAddress = NULL;
1400 AFSIrpComplete( IN PDEVICE_OBJECT DeviceObject,
1404 UNREFERENCED_PARAMETER(DeviceObject);
1405 UNREFERENCED_PARAMETER(Irp);
1407 KEVENT *pEvent = (KEVENT *)Context;
1413 return STATUS_MORE_PROCESSING_REQUIRED;
1417 AFSExAllocatePoolWithTag( IN POOL_TYPE PoolType,
1418 IN SIZE_T NumberOfBytes,
1422 AFSDeviceExt *pControlDevExt = NULL;
1423 void *pBuffer = NULL;
1424 BOOLEAN bTimeout = FALSE;
1425 LARGE_INTEGER liTimeout;
1429 // Attempt to allocation memory from the system. If the allocation fails
1430 // wait up to 30 seconds for the AFS redirector to free some memory. As
1431 // long as the wait does not timeout, continue to retry the allocation.
1432 // If the wait does timeout, attempt to allocate one more time in case
1433 // memory was freed by another driver. Otherwise, fail the request.
1436 if ( AFSDeviceObject)
1439 pControlDevExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension;
1442 while( pBuffer == NULL)
1445 pBuffer = ExAllocatePoolWithTag( PoolType,
1449 if( pBuffer == NULL)
1452 if ( bTimeout || pControlDevExt == NULL)
1457 "AFSExAllocatePoolWithTag failure Type %08lX Size %08lX Tag %08lX %08lX\n",
1461 PsGetCurrentThread());
1465 case AFS_GENERIC_MEMORY_21_TAG:
1466 case AFS_GENERIC_MEMORY_22_TAG:
1467 // AFSDumpTraceFiles -- do nothing;
1479 // Wait up to 30 seconds for a memory deallocation
1482 liTimeout.QuadPart = -(30 *AFS_ONE_SECOND);
1484 if( InterlockedIncrement( &pControlDevExt->Specific.Control.WaitingForMemoryCount) == 1)
1486 KeClearEvent( &pControlDevExt->Specific.Control.MemoryAvailableEvent);
1489 ntStatus = KeWaitForSingleObject( &pControlDevExt->Specific.Control.MemoryAvailableEvent,
1495 if( ntStatus == STATUS_TIMEOUT)
1501 InterlockedDecrement( &pControlDevExt->Specific.Control.WaitingForMemoryCount);
1509 AFSExFreePoolWithTag( IN void *Buffer, IN ULONG Tag)
1512 AFSDeviceExt *pControlDevExt = NULL;
1514 if ( AFSDeviceObject)
1517 pControlDevExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension;
1523 ExFreePoolWithTag( Buffer, Tag);
1528 ExFreePool( Buffer);
1531 if ( pControlDevExt)
1534 KeSetEvent( &pControlDevExt->Specific.Control.MemoryAvailableEvent,
1542 AFSShutdownRedirector()
1545 NTSTATUS ntStatus = STATUS_SUCCESS;
1546 AFSDeviceExt *pRDRDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1547 AFSDeviceExt *pControlDevExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension;
1548 LARGE_INTEGER liTimeout;
1553 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1554 AFS_TRACE_LEVEL_VERBOSE,
1555 "%s Shutting down redirector Extent count %08lX Request count %08lX\n",
1557 pControlDevExt->Specific.Control.ExtentCount,
1558 pControlDevExt->Specific.Control.OutstandingServiceRequestCount);
1561 // Set the shutdown flag so the worker is more agressive in tearing down extents
1564 SetFlag( pRDRDevExt->DeviceFlags, AFS_DEVICE_FLAG_REDIRECTOR_SHUTDOWN);
1567 // Wait on any outstanding service requests
1570 liTimeout.QuadPart = -(30 *AFS_ONE_SECOND);
1572 ntStatus = KeWaitForSingleObject( &pControlDevExt->Specific.Control.OutstandingServiceRequestEvent,
1578 if( ntStatus == STATUS_TIMEOUT)
1581 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1582 AFS_TRACE_LEVEL_WARNING,
1583 "AFSShutdownRedirector Failed to complete all service requests Remaining count %08lX\n",
1584 pControlDevExt->Specific.Control.OutstandingServiceRequestCount);
1586 try_return( ntStatus = STATUS_UNSUCCESSFUL);
1589 AFSProcessQueuedResults( TRUE);
1592 // Wait for all extents to be released
1595 liTimeout.QuadPart = -(30 *AFS_ONE_SECOND);
1597 ntStatus = KeWaitForSingleObject( &pControlDevExt->Specific.Control.ExtentsHeldEvent,
1603 if( ntStatus == STATUS_TIMEOUT)
1606 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1607 AFS_TRACE_LEVEL_WARNING,
1608 "AFSShutdownRedirector Failed to purge all extents Remaining count %08lX\n",
1609 pControlDevExt->Specific.Control.ExtentCount);
1611 try_return( ntStatus = STATUS_UNSUCCESSFUL);
1614 ntStatus = AFSUnloadLibrary( TRUE);
1616 if( !NT_SUCCESS( ntStatus))
1619 try_return( ntStatus);
1624 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1625 AFS_TRACE_LEVEL_VERBOSE,
1626 "%s Completed shut down of redirector Extent count %08lX Request count %08lX Status %08lX\n",
1628 pControlDevExt->Specific.Control.ExtentCount,
1629 pControlDevExt->Specific.Control.OutstandingServiceRequestCount,
1637 // Cache manager callback routines
1641 AFSAcquireFcbForLazyWrite( IN PVOID Fcb,
1645 BOOLEAN bStatus = FALSE;
1646 AFSFcb *pFcb = (AFSFcb *)Fcb;
1647 BOOLEAN bReleaseSectionObject = FALSE, bReleasePaging = FALSE;
1650 // Try and acquire the Fcb resource
1653 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
1654 AFS_TRACE_LEVEL_VERBOSE,
1655 "AFSAcquireFcbForLazyWrite Acquiring Fcb %p\n",
1659 // Try and grab the paging
1662 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
1663 AFS_TRACE_LEVEL_VERBOSE,
1664 "AFSAcquireFcbForLazyWrite Attempt to acquire Fcb PagingIo lock %p SHARED %08lX\n",
1665 &pFcb->NPFcb->PagingResource,
1666 PsGetCurrentThread());
1668 if( AFSAcquireShared( &pFcb->NPFcb->PagingResource,
1672 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
1673 AFS_TRACE_LEVEL_VERBOSE,
1674 "AFSAcquireFcbForLazyWrite Acquired Fcb PagingIo lock %p SHARED %08lX\n",
1675 &pFcb->NPFcb->PagingResource,
1676 PsGetCurrentThread());
1678 bReleasePaging = TRUE;
1680 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
1681 AFS_TRACE_LEVEL_VERBOSE,
1682 "AFSAcquireFcbForLazyWrite Attempt to acquire Fcb SectionObject lock %p SHARED %08lX\n",
1683 &pFcb->NPFcb->SectionObjectResource,
1684 PsGetCurrentThread());
1686 if( AFSAcquireShared( &pFcb->NPFcb->SectionObjectResource,
1690 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
1691 AFS_TRACE_LEVEL_VERBOSE,
1692 "AFSAcquireFcbForLazyWrite Acquired Fcb SectionObject lock %p SHARED %08lX\n",
1693 &pFcb->NPFcb->SectionObjectResource,
1694 PsGetCurrentThread());
1696 bReleaseSectionObject = TRUE;
1704 IoSetTopLevelIrp( (PIRP)FSRTL_CACHE_TOP_LEVEL_IRP);
1711 if( bReleaseSectionObject)
1714 AFSReleaseResource( &pFcb->NPFcb->SectionObjectResource);
1720 AFSReleaseResource( &pFcb->NPFcb->PagingResource);
1728 AFSReleaseFcbFromLazyWrite( IN PVOID Fcb)
1731 AFSFcb *pFcb = (AFSFcb *)Fcb;
1733 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
1734 AFS_TRACE_LEVEL_VERBOSE,
1735 "AFSReleaseFcbFromLazyWrite Releasing Fcb %p\n",
1738 IoSetTopLevelIrp( NULL);
1740 AFSReleaseResource( &pFcb->NPFcb->SectionObjectResource);
1742 AFSReleaseResource( &pFcb->NPFcb->PagingResource);
1748 AFSAcquireFcbForReadAhead( IN PVOID Fcb,
1752 BOOLEAN bStatus = FALSE;
1753 AFSFcb *pFcb = (AFSFcb *)Fcb;
1755 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
1756 AFS_TRACE_LEVEL_VERBOSE,
1757 "AFSAcquireFcbForReadAhead Attempt to acquire Fcb SectionObject lock %p SHARED %08lX\n",
1758 &pFcb->NPFcb->SectionObjectResource,
1759 PsGetCurrentThread());
1761 if( AFSAcquireShared( &pFcb->NPFcb->SectionObjectResource,
1765 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
1766 AFS_TRACE_LEVEL_VERBOSE,
1767 "AFSAcquireFcbForReadAhead Acquired Fcb SectionObject lock %p SHARED %08lX\n",
1768 &pFcb->NPFcb->SectionObjectResource,
1769 PsGetCurrentThread());
1773 IoSetTopLevelIrp( (PIRP)FSRTL_CACHE_TOP_LEVEL_IRP);
1780 AFSReleaseFcbFromReadAhead( IN PVOID Fcb)
1783 AFSFcb *pFcb = (AFSFcb *)Fcb;
1785 IoSetTopLevelIrp( NULL);
1787 AFSReleaseResource( &pFcb->NPFcb->SectionObjectResource);
1793 AFSGetCallerSID( OUT UNICODE_STRING *SIDString, OUT BOOLEAN *pbImpersonation)
1796 NTSTATUS ntStatus = STATUS_SUCCESS;
1797 PACCESS_TOKEN hToken = NULL;
1798 TOKEN_USER *pTokenInfo = NULL;
1799 BOOLEAN bCopyOnOpen = FALSE;
1800 BOOLEAN bEffectiveOnly = FALSE;
1801 BOOLEAN bPrimaryToken = FALSE;
1802 SECURITY_IMPERSONATION_LEVEL stImpersonationLevel;
1803 UNICODE_STRING uniSIDString;
1808 hToken = PsReferenceImpersonationToken( PsGetCurrentThread(),
1811 &stImpersonationLevel);
1816 hToken = PsReferencePrimaryToken( PsGetCurrentProcess());
1821 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1822 AFS_TRACE_LEVEL_ERROR,
1823 "AFSGetCallerSID Failed to retrieve impersonation or primary token\n");
1825 try_return( ntStatus);
1828 bPrimaryToken = TRUE;
1831 ntStatus = SeQueryInformationToken( hToken,
1833 (PVOID *)&pTokenInfo);
1835 if( !NT_SUCCESS( ntStatus))
1838 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1839 AFS_TRACE_LEVEL_ERROR,
1840 "AFSGetCallerSID Failed to retrieve information Status %08lX\n", ntStatus);
1842 try_return( ntStatus);
1845 uniSIDString.Length = 0;
1846 uniSIDString.MaximumLength = 0;
1847 uniSIDString.Buffer = NULL;
1849 ntStatus = RtlConvertSidToUnicodeString( &uniSIDString,
1850 pTokenInfo->User.Sid,
1853 if( !NT_SUCCESS( ntStatus))
1856 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1857 AFS_TRACE_LEVEL_ERROR,
1858 "AFSGetCallerSID Failed to convert sid to string Status %08lX\n", ntStatus);
1860 try_return( ntStatus);
1863 *SIDString = uniSIDString;
1865 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING | AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
1866 AFS_TRACE_LEVEL_VERBOSE_2,
1867 "AFSGetCallerSID Successfully retrieved SID %wZ\n",
1870 if ( bPrimaryToken == FALSE &&
1873 *pbImpersonation = TRUE;
1882 PsDereferencePrimaryToken( hToken);
1886 PsDereferenceImpersonationToken( hToken);
1890 if( pTokenInfo != NULL)
1892 ExFreePool( pTokenInfo); // Allocated by SeQueryInformationToken
1900 AFSGetSessionId( IN HANDLE ProcessId, OUT BOOLEAN *pbImpersonation)
1902 UNREFERENCED_PARAMETER(ProcessId);
1904 NTSTATUS ntStatus = STATUS_SUCCESS;
1905 PACCESS_TOKEN hToken = NULL;
1906 ULONG ulSessionId = (ULONG)-1;
1907 BOOLEAN bCopyOnOpen = FALSE;
1908 BOOLEAN bEffectiveOnly = FALSE;
1909 BOOLEAN bPrimaryToken = FALSE;
1910 SECURITY_IMPERSONATION_LEVEL stImpersonationLevel;
1915 hToken = PsReferenceImpersonationToken( PsGetCurrentThread(),
1918 &stImpersonationLevel);
1923 hToken = PsReferencePrimaryToken( PsGetCurrentProcess());
1928 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1929 AFS_TRACE_LEVEL_ERROR,
1930 "AFSGetSessionId Failed to retrieve impersonation or primary token\n");
1932 try_return( ntStatus);
1935 bPrimaryToken = TRUE;
1938 ntStatus = SeQueryInformationToken( hToken,
1940 (PVOID *)&ulSessionId);
1942 if( !NT_SUCCESS( ntStatus))
1944 ulSessionId = (ULONG)-1;
1946 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1947 AFS_TRACE_LEVEL_ERROR,
1948 "AFSGetSessionId Failed to retrieve session id Status %08lX\n",
1951 try_return( ntStatus);
1954 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING | AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
1955 AFS_TRACE_LEVEL_VERBOSE_2,
1956 "AFSGetSessionId found %08lX\n",
1959 if ( bPrimaryToken == FALSE &&
1962 *pbImpersonation = TRUE;
1971 PsDereferencePrimaryToken( hToken);
1975 PsDereferenceImpersonationToken( hToken);
1984 AFSCheckThreadDacl( OUT GUID *AuthGroup)
1987 NTSTATUS ntStatus = STATUS_UNSUCCESSFUL;
1989 PACCESS_TOKEN token = NULL;
1990 PTOKEN_DEFAULT_DACL defDacl = NULL;
1992 PACCESS_ALLOWED_ACE adace;
1993 BOOLEAN bCopyOnOpen = FALSE, bEffectiveOnly = FALSE;
1994 SECURITY_IMPERSONATION_LEVEL stImpersonationLevel;
1995 BOOLEAN bLocatedACE = FALSE;
2000 token = PsReferenceImpersonationToken( PsGetCurrentThread(),
2003 &stImpersonationLevel);
2007 try_return( ntStatus);
2010 ntStatus = SeQueryInformationToken( token,
2014 if( ntStatus != STATUS_SUCCESS)
2016 try_return( ntStatus);
2019 // scan through all ACEs in the DACL
2020 for (idx = 0, ace = (PACE_HEADER)((char *)defDacl->DefaultDacl + sizeof(ACL)); idx < defDacl->DefaultDacl->AceCount; idx++)
2022 if (ace->AceType == ACCESS_ALLOWED_ACE_TYPE)
2024 adace = (PACCESS_ALLOWED_ACE)ace;
2026 if (adace->Header.AceSize == (FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + AFS_DACL_SID_LENGTH))
2028 if (RtlCompareMemory( RtlSubAuthoritySid((PSID)&adace->SidStart, 0), &AFSSidGuid, sizeof(GUID)) == sizeof(GUID))
2031 RtlCopyMemory( AuthGroup,
2032 RtlSubAuthoritySid((PSID)&adace->SidStart, 4),
2043 ace = (PACE_HEADER)((char *)ace + ace->AceSize);
2050 PsDereferenceImpersonationToken( token);
2053 if (defDacl != NULL)
2055 ExFreePool(defDacl);
2060 ntStatus = STATUS_UNSUCCESSFUL;
2068 AFSProcessSetProcessDacl( IN AFSProcessCB *ProcessCB)
2071 PTOKEN_DEFAULT_DACL defDacl = NULL;
2072 HANDLE hToken = NULL;
2073 PACE_HEADER ace = NULL;
2074 SID_IDENTIFIER_AUTHORITY sia = SECURITY_NT_AUTHORITY;
2075 PACCESS_ALLOWED_ACE aaace;
2077 ULONG bytesReturned;
2080 NTSTATUS ntStatus = STATUS_SUCCESS;
2085 ntStatus = ZwOpenProcessTokenEx( NtCurrentProcess(),
2090 if( !NT_SUCCESS( ntStatus))
2092 try_return( ntStatus);
2095 // get the size of the current DACL
2096 ntStatus = ZwQueryInformationToken( hToken,
2102 // if we failed to get the buffer size needed
2103 if ((ntStatus != STATUS_SUCCESS) && (ntStatus != STATUS_BUFFER_TOO_SMALL))
2105 try_return( ntStatus);
2108 // tack on enough space for our ACE if we need to add it...
2109 bytesNeeded += FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + AFS_DACL_SID_LENGTH;
2111 // allocate space for the DACL
2112 defDacl = (PTOKEN_DEFAULT_DACL)ExAllocatePoolWithTag( PagedPool, bytesNeeded, AFS_GENERIC_MEMORY_26_TAG);
2114 if (defDacl == NULL)
2116 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2120 ntStatus = ZwQueryInformationToken( hToken,
2126 if( ntStatus != STATUS_SUCCESS)
2128 try_return( ntStatus);
2131 // scan through DACL to see if we have the SID set already...
2132 ace = (PACE_HEADER)((char *)defDacl->DefaultDacl + sizeof(ACL));
2133 for (idx = 0; idx < defDacl->DefaultDacl->AceCount; idx++)
2135 if (ace->AceType == ACCESS_ALLOWED_ACE_TYPE)
2137 aaace = (PACCESS_ALLOWED_ACE)ace;
2139 if (aaace->Header.AceSize == (FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + AFS_DACL_SID_LENGTH))
2141 // if the GUID part matches
2142 if( RtlCompareMemory( RtlSubAuthoritySid((PSID)&aaace->SidStart, 0),
2144 sizeof(GUID)) == sizeof(GUID))
2147 if ( RtlCompareMemory( RtlSubAuthoritySid((PSID)&aaace->SidStart, 4),
2148 ProcessCB->ActiveAuthGroup,
2149 sizeof( GUID)) != sizeof( GUID))
2152 RtlCopyMemory( RtlSubAuthoritySid((PSID)&aaace->SidStart, 4),
2153 ProcessCB->ActiveAuthGroup,
2156 if( AFSSetInformationToken != NULL)
2158 ntStatus = AFSSetInformationToken( hToken,
2165 try_return( ntStatus);
2171 ace = (PACE_HEADER)((char *)ace + ace->AceSize);
2175 // if we made it here we need to add a new ACE to the DACL
2178 aaace = (ACCESS_ALLOWED_ACE *)ace;
2179 aaace->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
2180 aaace->Header.AceFlags = 0;
2181 aaace->Mask = GENERIC_ALL;
2182 psid = (PSID)&aaace->SidStart;
2183 RtlInitializeSid( psid, &sia, 8);
2185 RtlCopyMemory( RtlSubAuthoritySid(psid, 0),
2189 RtlCopyMemory( RtlSubAuthoritySid(psid, 4),
2190 ProcessCB->ActiveAuthGroup,
2193 aaace->Header.AceSize = (USHORT)(FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + RtlLengthSid( psid));
2195 defDacl->DefaultDacl->AclSize += aaace->Header.AceSize;
2196 defDacl->DefaultDacl->AceCount++;
2198 if( AFSSetInformationToken != NULL)
2200 ntStatus = AFSSetInformationToken( hToken,
2203 defDacl->DefaultDacl->AclSize + sizeof(PTOKEN_DEFAULT_DACL));
2213 if (defDacl != NULL)
2215 ExFreePool( defDacl);