2 * Copyright (c) 2008, 2009, 2010, 2011 Kernel Drivers, LLC.
3 * Copyright (c) 2009, 2010, 2011 Your File System, Inc.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * - Redistributions of source code must retain the above copyright notice,
11 * this list of conditions and the following disclaimer.
12 * - Redistributions in binary form must reproduce the above copyright
14 * this list of conditions and the following disclaimer in the
16 * and/or other materials provided with the distribution.
17 * - Neither the names of Kernel Drivers, LLC and Your File System, Inc.
18 * nor the names of their contributors may be used to endorse or promote
19 * products derived from this software without specific prior written
20 * permission from Kernel Drivers, LLC and Your File System, Inc.
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
24 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
25 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
26 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
27 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
28 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 // File: AFSGeneric.cpp
39 #include "AFSCommon.h"
42 // Function: AFSExceptionFilter
46 // This function is the exception handler
50 // A status is returned for the function
54 AFSExceptionFilter( IN CHAR *FunctionString,
56 IN PEXCEPTION_POINTERS ExceptPtrs)
59 PEXCEPTION_RECORD ExceptRec;
65 ExceptRec = ExceptPtrs->ExceptionRecord;
67 Context = ExceptPtrs->ContextRecord;
71 "AFSExceptionFilter (Framework) - EXR %p CXR %p Function %s Code %08lX Address %p Routine %p\n",
75 ExceptRec->ExceptionCode,
76 ExceptRec->ExceptionAddress,
77 (void *)AFSExceptionFilter);
79 DbgPrint("**** Exception Caught in AFS Redirector ****\n");
81 DbgPrint("\n\nPerform the following WnDbg Cmds:\n");
82 DbgPrint("\n\t.exr %p ; .cxr %p\n\n", ExceptRec, Context);
84 DbgPrint("**** Exception Complete from AFS Redirector ****\n");
86 if( BooleanFlagOn( AFSDebugFlags, AFS_DBG_BUGCHECK_EXCEPTION))
89 KeBugCheck( (ULONG)-2);
97 __except( EXCEPTION_EXECUTE_HANDLER)
103 return EXCEPTION_EXECUTE_HANDLER;
107 // Function: AFSAcquireExcl()
109 // Purpose: Called to acquire a resource exclusive with optional wait
112 // PERESOURCE Resource - Resource to acquire
113 // BOOLEAN Wait - Whether to block
116 // BOOLEAN - Whether the mask was acquired
120 AFSAcquireExcl( IN PERESOURCE Resource,
124 BOOLEAN bStatus = FALSE;
127 // Normal kernel APCs must be disabled before calling
128 // ExAcquireResourceExclusiveLite. Otherwise a bugcheck occurs.
131 KeEnterCriticalRegion();
133 bStatus = ExAcquireResourceExclusiveLite( Resource,
139 KeLeaveCriticalRegion();
146 AFSAcquireSharedStarveExclusive( IN PERESOURCE Resource,
150 BOOLEAN bStatus = FALSE;
152 KeEnterCriticalRegion();
154 bStatus = ExAcquireSharedStarveExclusive( Resource,
160 KeLeaveCriticalRegion();
167 // Function: AFSAcquireShared()
169 // Purpose: Called to acquire a resource shared with optional wait
172 // PERESOURCE Resource - Resource to acquire
173 // BOOLEAN Wait - Whether to block
176 // BOOLEAN - Whether the mask was acquired
180 AFSAcquireShared( IN PERESOURCE Resource,
184 BOOLEAN bStatus = FALSE;
186 KeEnterCriticalRegion();
188 bStatus = ExAcquireResourceSharedLite( Resource,
194 KeLeaveCriticalRegion();
201 // Function: AFSReleaseResource()
203 // Purpose: Called to release a resource
206 // PERESOURCE Resource - Resource to release
213 AFSReleaseResource( IN PERESOURCE Resource)
216 if( Resource != &AFSDbgLogLock)
219 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
220 AFS_TRACE_LEVEL_VERBOSE,
221 "AFSReleaseResource Releasing lock %08lX Thread %08lX\n",
223 PsGetCurrentThread());
226 ExReleaseResourceLite( Resource);
228 KeLeaveCriticalRegion();
234 AFSConvertToShared( IN PERESOURCE Resource)
237 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
238 AFS_TRACE_LEVEL_VERBOSE,
239 "AFSConvertToShared Converting lock %08lX Thread %08lX\n",
241 PsGetCurrentThread());
243 ExConvertExclusiveToSharedLite( Resource);
249 // Function: AFSCompleteRequest
253 // This function completes irps
257 // A status is returned for the function
261 AFSCompleteRequest( IN PIRP Irp,
265 Irp->IoStatus.Status = Status;
267 IoCompleteRequest( Irp,
274 AFSReadRegistry( IN PUNICODE_STRING RegistryPath)
277 NTSTATUS ntStatus = STATUS_SUCCESS;
279 UNICODE_STRING paramPath;
281 RTL_QUERY_REGISTRY_TABLE paramTable[2];
282 UNICODE_STRING defaultUnicodeName;
283 WCHAR SubKeyString[] = L"\\Parameters";
286 // Setup the paramPath buffer.
289 paramPath.MaximumLength = RegistryPath->Length + sizeof( SubKeyString);
290 paramPath.Buffer = (PWSTR)AFSExAllocatePoolWithTag( PagedPool,
291 paramPath.MaximumLength,
292 AFS_GENERIC_MEMORY_15_TAG);
294 RtlInitUnicodeString( &defaultUnicodeName,
298 // If it exists, setup the path.
301 if( paramPath.Buffer != NULL)
308 RtlCopyMemory( ¶mPath.Buffer[ 0],
309 &RegistryPath->Buffer[ 0],
310 RegistryPath->Length);
312 RtlCopyMemory( ¶mPath.Buffer[ RegistryPath->Length / 2],
314 sizeof( SubKeyString));
316 paramPath.Length = paramPath.MaximumLength;
318 RtlZeroMemory( paramTable,
319 sizeof( paramTable));
324 // Setup the table to query the registry for the needed value
327 paramTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
328 paramTable[0].Name = AFS_REG_DEBUG_FLAGS;
329 paramTable[0].EntryContext = &Value;
331 paramTable[0].DefaultType = REG_DWORD;
332 paramTable[0].DefaultData = &Default;
333 paramTable[0].DefaultLength = sizeof (ULONG) ;
336 // Query the registry
339 ntStatus = RtlQueryRegistryValues( RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL,
345 if( NT_SUCCESS( ntStatus))
348 AFSDebugFlags = Value;
351 RtlZeroMemory( paramTable,
352 sizeof( paramTable));
357 // Setup the table to query the registry for the needed value
360 paramTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
361 paramTable[0].Name = AFS_REG_TRACE_SUBSYSTEM;
362 paramTable[0].EntryContext = &Value;
364 paramTable[0].DefaultType = REG_DWORD;
365 paramTable[0].DefaultData = &Default;
366 paramTable[0].DefaultLength = sizeof (ULONG) ;
369 // Query the registry
372 ntStatus = RtlQueryRegistryValues( RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL,
378 if( NT_SUCCESS( ntStatus))
381 AFSTraceComponent = Value;
384 RtlZeroMemory( paramTable,
385 sizeof( paramTable));
390 // Setup the table to query the registry for the needed value
393 paramTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
394 paramTable[0].Name = AFS_REG_TRACE_BUFFER_LENGTH;
395 paramTable[0].EntryContext = &Value;
397 paramTable[0].DefaultType = REG_DWORD;
398 paramTable[0].DefaultData = &Default;
399 paramTable[0].DefaultLength = sizeof (ULONG);
402 // Query the registry
405 ntStatus = RtlQueryRegistryValues( RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL,
411 if( NT_SUCCESS( ntStatus) &&
415 AFSDbgBufferLength = Value;
418 // Let's limit things a bit ...
421 if( AFSDbgBufferLength > 10240)
424 AFSDbgBufferLength = 1024;
430 AFSDbgBufferLength = 0;
437 AFSDbgBufferLength *= 1024;
440 // Now get ready to set up for MaxServerDirty
443 paramTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
444 paramTable[0].Name = AFS_REG_MAX_DIRTY;
445 paramTable[0].EntryContext = &Value;
447 paramTable[0].DefaultType = REG_DWORD;
448 paramTable[0].DefaultData = &Default;
449 paramTable[0].DefaultLength = sizeof (ULONG) ;
452 // Query the registry
455 ntStatus = RtlQueryRegistryValues( RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL,
461 if( NT_SUCCESS( ntStatus))
464 AFSMaxDirtyFile = Value;
467 RtlZeroMemory( paramTable,
468 sizeof( paramTable));
473 // Setup the table to query the registry for the needed value
476 paramTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
477 paramTable[0].Name = AFS_REG_TRACE_LEVEL;
478 paramTable[0].EntryContext = &Value;
480 paramTable[0].DefaultType = REG_DWORD;
481 paramTable[0].DefaultData = &Default;
482 paramTable[0].DefaultLength = sizeof (ULONG) ;
485 // Query the registry
488 ntStatus = RtlQueryRegistryValues( RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL,
494 if( NT_SUCCESS( ntStatus))
497 AFSTraceLevel = Value;
504 paramTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
505 paramTable[0].Name = AFS_REG_MAX_IO;
506 paramTable[0].EntryContext = &Value;
508 paramTable[0].DefaultType = REG_DWORD;
509 paramTable[0].DefaultData = &Default;
510 paramTable[0].DefaultLength = sizeof (ULONG) ;
513 // Query the registry
516 ntStatus = RtlQueryRegistryValues( RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL,
522 if( NT_SUCCESS( ntStatus))
525 AFSMaxDirectIo = Value;
529 // Now set up for ShutdownStatus query
532 paramTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
533 paramTable[0].Name = AFS_REG_SHUTDOWN_STATUS;
534 paramTable[0].EntryContext = &Value;
536 paramTable[0].DefaultType = REG_DWORD;
537 paramTable[0].DefaultData = &Default;
538 paramTable[0].DefaultLength = sizeof (ULONG) ;
541 // Query the registry
544 ntStatus = RtlQueryRegistryValues( RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL,
550 if( !NT_SUCCESS( ntStatus) ||
554 SetFlag( AFSDebugFlags, AFS_DBG_CLEAN_SHUTDOWN);
558 // Now set up for RequireCleanShutdown query
561 paramTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
562 paramTable[0].Name = AFS_REG_REQUIRE_CLEAN_SHUTDOWN;
563 paramTable[0].EntryContext = &Value;
565 paramTable[0].DefaultType = REG_DWORD;
566 paramTable[0].DefaultData = &Default;
567 paramTable[0].DefaultLength = sizeof (ULONG) ;
570 // Query the registry
573 ntStatus = RtlQueryRegistryValues( RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL,
579 if( !NT_SUCCESS( ntStatus) ||
583 SetFlag( AFSDebugFlags, AFS_DBG_REQUIRE_CLEAN_SHUTDOWN);
587 // Free up the buffer
590 ExFreePool( paramPath.Buffer);
592 ntStatus = STATUS_SUCCESS;
596 ntStatus = STATUS_INSUFFICIENT_RESOURCES;
603 AFSUpdateRegistryParameter( IN PUNICODE_STRING ValueName,
606 IN ULONG ValueDataLength)
609 NTSTATUS ntStatus = STATUS_SUCCESS;
610 UNICODE_STRING paramPath, uniParamKey;
611 HANDLE hParameters = 0;
612 ULONG ulDisposition = 0;
613 OBJECT_ATTRIBUTES stObjectAttributes;
618 RtlInitUnicodeString( &uniParamKey,
622 // Setup the paramPath buffer.
625 paramPath.MaximumLength = AFSRegistryPath.Length + uniParamKey.Length;
626 paramPath.Buffer = (PWSTR)AFSExAllocatePoolWithTag( PagedPool,
627 paramPath.MaximumLength,
628 AFS_GENERIC_MEMORY_16_TAG);
630 if( paramPath.Buffer == NULL)
633 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
640 RtlCopyMemory( paramPath.Buffer,
641 AFSRegistryPath.Buffer,
642 AFSRegistryPath.Length);
644 paramPath.Length = AFSRegistryPath.Length;
646 RtlCopyMemory( ¶mPath.Buffer[ paramPath.Length / 2],
650 paramPath.Length += uniParamKey.Length;
652 InitializeObjectAttributes( &stObjectAttributes,
654 OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
658 ntStatus = ZwOpenKey( &hParameters,
660 &stObjectAttributes);
662 if( !NT_SUCCESS( ntStatus))
665 try_return( ntStatus);
672 ntStatus = ZwSetValueKey( hParameters,
679 ZwClose( hParameters);
683 if( paramPath.Buffer != NULL)
687 // Free up the buffer
690 ExFreePool( paramPath.Buffer);
698 AFSInitializeControlDevice()
701 NTSTATUS ntStatus = STATUS_SUCCESS;
702 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension;
703 AFSProcessCB *pProcessCB = NULL;
709 // Initialize the comm pool resources
712 ExInitializeResourceLite( &pDeviceExt->Specific.Control.CommServiceCB.IrpPoolLock);
714 ExInitializeResourceLite( &pDeviceExt->Specific.Control.CommServiceCB.ResultPoolLock);
716 ExInitializeResourceLite( &pDeviceExt->Specific.Control.ExtentReleaseResource);
718 ExInitializeResourceLite( &pDeviceExt->Specific.Control.SysName32ListLock);
720 ExInitializeResourceLite( &pDeviceExt->Specific.Control.SysName64ListLock);
726 KeInitializeEvent( &pDeviceExt->Specific.Control.CommServiceCB.IrpPoolHasEntries,
727 SynchronizationEvent,
730 KeInitializeEvent( &pDeviceExt->Specific.Control.CommServiceCB.IrpPoolHasReleaseEntries,
731 SynchronizationEvent,
734 KeInitializeEvent( &pDeviceExt->Specific.Control.ExtentReleaseEvent,
738 pDeviceExt->Specific.Control.ExtentReleaseSequence = 0;
740 KeInitializeEvent( &pDeviceExt->Specific.Control.VolumeWorkerCloseEvent,
745 // Library support information
748 KeInitializeEvent( &pDeviceExt->Specific.Control.LoadLibraryEvent,
749 SynchronizationEvent,
753 // Initialize the library queued as cancelled
756 pDeviceExt->Specific.Control.LibraryState = AFS_LIBRARY_QUEUE_CANCELLED;
758 ExInitializeResourceLite( &pDeviceExt->Specific.Control.LibraryStateLock);
760 pDeviceExt->Specific.Control.InflightLibraryRequests = 0;
762 KeInitializeEvent( &pDeviceExt->Specific.Control.InflightLibraryEvent,
766 pDeviceExt->Specific.Control.ExtentCount = 0;
767 pDeviceExt->Specific.Control.ExtentsHeldLength = 0;
769 KeInitializeEvent( &pDeviceExt->Specific.Control.ExtentsHeldEvent,
773 pDeviceExt->Specific.Control.OutstandingServiceRequestCount = 0;
775 KeInitializeEvent( &pDeviceExt->Specific.Control.OutstandingServiceRequestEvent,
779 pDeviceExt->Specific.Control.WaitingForMemoryCount = 0;
781 KeInitializeEvent( &pDeviceExt->Specific.Control.MemoryAvailableEvent,
785 ExInitializeResourceLite( &pDeviceExt->Specific.Control.LibraryQueueLock);
787 pDeviceExt->Specific.Control.LibraryQueueHead = NULL;
789 pDeviceExt->Specific.Control.LibraryQueueTail = NULL;
792 // Set the initial state of the irp pool
795 pDeviceExt->Specific.Control.CommServiceCB.IrpPoolControlFlag = POOL_INACTIVE;
798 // Initialize our process and sid tree information
801 ExInitializeResourceLite( &pDeviceExt->Specific.Control.ProcessTreeLock);
803 pDeviceExt->Specific.Control.ProcessTree.TreeLock = &pDeviceExt->Specific.Control.ProcessTreeLock;
805 pDeviceExt->Specific.Control.ProcessTree.TreeHead = NULL;
807 ExInitializeResourceLite( &pDeviceExt->Specific.Control.AuthGroupTreeLock);
809 pDeviceExt->Specific.Control.AuthGroupTree.TreeLock = &pDeviceExt->Specific.Control.AuthGroupTreeLock;
811 pDeviceExt->Specific.Control.AuthGroupTree.TreeHead = NULL;
818 AFSRemoveControlDevice()
821 NTSTATUS ntStatus = STATUS_SUCCESS;
822 AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension;
823 AFSProcessCB *pProcessCB = NULL;
829 // Initialize the comm pool resources
832 ExDeleteResourceLite( &pDeviceExt->Specific.Control.CommServiceCB.IrpPoolLock);
834 ExDeleteResourceLite( &pDeviceExt->Specific.Control.CommServiceCB.ResultPoolLock);
836 ExDeleteResourceLite( &pDeviceExt->Specific.Control.ExtentReleaseResource);
838 ExDeleteResourceLite( &pDeviceExt->Specific.Control.SysName32ListLock);
840 ExDeleteResourceLite( &pDeviceExt->Specific.Control.SysName64ListLock);
842 ExDeleteResourceLite( &pDeviceExt->Specific.Control.ProcessTreeLock);
844 if( pDeviceExt->Specific.Control.ProcessTree.TreeHead != NULL)
846 ExFreePool( pDeviceExt->Specific.Control.ProcessTree.TreeHead);
849 ExDeleteResourceLite( &pDeviceExt->Specific.Control.AuthGroupTreeLock);
851 ExDeleteResourceLite( &pDeviceExt->Specific.Control.LibraryStateLock);
853 ExDeleteResourceLite( &pDeviceExt->Specific.Control.LibraryQueueLock);
860 AFSInitServerStrings()
863 UNICODE_STRING uniFullName;
864 WCHAR wchBuffer[ 50];
867 // Add the server name into the list of resources
870 uniFullName.Length = (2 * sizeof( WCHAR)) + AFSServerName.Length;
871 uniFullName.MaximumLength = uniFullName.Length + sizeof( WCHAR);
873 uniFullName.Buffer = wchBuffer;
875 wchBuffer[ 0] = L'\\';
876 wchBuffer[ 1] = L'\\';
878 RtlCopyMemory( &wchBuffer[ 2],
879 AFSServerName.Buffer,
880 AFSServerName.Length);
882 AFSAddConnectionEx( &uniFullName,
883 RESOURCEDISPLAYTYPE_SERVER,
887 // Add in the global share name
890 wchBuffer[ uniFullName.Length/sizeof( WCHAR)] = L'\\';
892 uniFullName.Length += sizeof( WCHAR);
894 RtlCopyMemory( &wchBuffer[ uniFullName.Length/sizeof( WCHAR)],
895 AFSGlobalRootName.Buffer,
896 AFSGlobalRootName.Length);
898 uniFullName.Length += AFSGlobalRootName.Length;
900 AFSAddConnectionEx( &uniFullName,
901 RESOURCEDISPLAYTYPE_SHARE,
902 AFS_CONNECTION_FLAG_GLOBAL_SHARE);
911 NTSTATUS ntStatus = STATUS_SUCCESS;
913 UNICODE_STRING paramPath;
914 RTL_QUERY_REGISTRY_TABLE paramTable[2];
920 // Setup the paramPath buffer.
923 paramPath.MaximumLength = PAGE_SIZE;
924 paramPath.Buffer = (PWSTR)AFSExAllocatePoolWithTag( PagedPool,
925 paramPath.MaximumLength,
926 AFS_GENERIC_MEMORY_17_TAG);
929 // If it exists, setup the path.
932 if( paramPath.Buffer == NULL)
935 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
942 RtlZeroMemory( paramPath.Buffer,
943 paramPath.MaximumLength);
945 RtlCopyMemory( ¶mPath.Buffer[ 0],
946 L"\\TransarcAFSDaemon\\Parameters",
949 paramPath.Length = 58;
951 RtlZeroMemory( paramTable,
952 sizeof( paramTable));
955 // Setup the table to query the registry for the needed value
958 AFSServerName.Length = 0;
959 AFSServerName.MaximumLength = 0;
960 AFSServerName.Buffer = NULL;
962 paramTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
963 paramTable[0].Name = AFS_REG_NETBIOS_NAME;
964 paramTable[0].EntryContext = &AFSServerName;
966 paramTable[0].DefaultType = REG_NONE;
967 paramTable[0].DefaultData = NULL;
968 paramTable[0].DefaultLength = 0;
971 // Query the registry
974 ntStatus = RtlQueryRegistryValues( RTL_REGISTRY_SERVICES,
981 // Free up the buffer
984 ExFreePool( paramPath.Buffer);
988 if( !NT_SUCCESS( ntStatus))
991 RtlInitUnicodeString( &AFSServerName,
1000 AFSReadMountRootName()
1003 NTSTATUS ntStatus = STATUS_SUCCESS;
1005 UNICODE_STRING paramPath;
1006 RTL_QUERY_REGISTRY_TABLE paramTable[2];
1012 // Setup the paramPath buffer.
1015 paramPath.MaximumLength = PAGE_SIZE;
1016 paramPath.Buffer = (PWSTR)AFSExAllocatePoolWithTag( PagedPool,
1017 paramPath.MaximumLength,
1018 AFS_GENERIC_MEMORY_17_TAG);
1021 // If it exists, setup the path.
1024 if( paramPath.Buffer == NULL)
1027 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1031 // Move in the paths
1034 RtlZeroMemory( paramPath.Buffer,
1035 paramPath.MaximumLength);
1037 RtlCopyMemory( ¶mPath.Buffer[ 0],
1038 L"\\TransarcAFSDaemon\\Parameters",
1041 paramPath.Length = 58;
1043 RtlZeroMemory( paramTable,
1044 sizeof( paramTable));
1047 // Setup the table to query the registry for the needed value
1050 AFSMountRootName.Length = 0;
1051 AFSMountRootName.MaximumLength = 0;
1052 AFSMountRootName.Buffer = NULL;
1054 paramTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
1055 paramTable[0].Name = AFS_REG_MOUNT_ROOT;
1056 paramTable[0].EntryContext = &AFSMountRootName;
1058 paramTable[0].DefaultType = REG_NONE;
1059 paramTable[0].DefaultData = NULL;
1060 paramTable[0].DefaultLength = 0;
1063 // Query the registry
1066 ntStatus = RtlQueryRegistryValues( RTL_REGISTRY_SERVICES,
1072 if ( NT_SUCCESS( ntStatus))
1074 if ( AFSMountRootName.Buffer[0] == L'/')
1077 AFSMountRootName.Buffer[0] = L'\\';
1082 // Free up the buffer
1085 ExFreePool( paramPath.Buffer);
1089 if( !NT_SUCCESS( ntStatus))
1092 RtlInitUnicodeString( &AFSMountRootName,
1101 AFSSetSysNameInformation( IN AFSSysNameNotificationCB *SysNameInfo,
1102 IN ULONG SysNameInfoBufferLength)
1105 NTSTATUS ntStatus = STATUS_SUCCESS;
1106 AFSDeviceExt *pControlDevExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension;
1107 AFSSysNameCB *pSysName = NULL;
1108 ERESOURCE *pSysNameLock = NULL;
1109 AFSSysNameCB **pSysNameListHead = NULL, **pSysNameListTail = NULL;
1115 // Depending on the architecture of the information, set up the lsit
1118 if( SysNameInfo->Architecture == AFS_SYSNAME_ARCH_32BIT)
1121 pSysNameLock = &pControlDevExt->Specific.Control.SysName32ListLock;
1123 pSysNameListHead = &pControlDevExt->Specific.Control.SysName32ListHead;
1125 pSysNameListTail = &pControlDevExt->Specific.Control.SysName32ListTail;
1132 pSysNameLock = &pControlDevExt->Specific.Control.SysName64ListLock;
1134 pSysNameListHead = &pControlDevExt->Specific.Control.SysName64ListHead;
1136 pSysNameListTail = &pControlDevExt->Specific.Control.SysName64ListTail;
1140 try_return( ntStatus = STATUS_INVALID_PARAMETER);
1145 // Process the request
1148 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
1149 AFS_TRACE_LEVEL_VERBOSE,
1150 "AFSSetSysNameInformation Acquiring SysName lock %08lX EXCL %08lX\n",
1152 PsGetCurrentThread());
1154 AFSAcquireExcl( pSysNameLock,
1158 // If we already have a list, then tear it down
1161 if( *pSysNameListHead != NULL)
1164 AFSResetSysNameList( *pSysNameListHead);
1166 *pSysNameListHead = NULL;
1170 // Loop through the entries adding in a node for each
1173 while( ulIndex < SysNameInfo->NumberOfNames)
1176 pSysName = (AFSSysNameCB *)AFSExAllocatePoolWithTag( PagedPool,
1177 sizeof( AFSSysNameCB) +
1178 SysNameInfo->SysNames[ ulIndex].Length +
1180 AFS_SYS_NAME_NODE_TAG);
1182 if( pSysName == NULL)
1186 // Reset the current list
1189 AFSResetSysNameList( *pSysNameListHead);
1191 *pSysNameListHead = NULL;
1193 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1196 RtlZeroMemory( pSysName,
1197 sizeof( AFSSysNameCB) +
1198 SysNameInfo->SysNames[ ulIndex].Length +
1201 pSysName->SysName.Length = (USHORT)SysNameInfo->SysNames[ ulIndex].Length;
1203 pSysName->SysName.MaximumLength = pSysName->SysName.Length + sizeof( WCHAR);
1205 pSysName->SysName.Buffer = (WCHAR *)((char *)pSysName + sizeof( AFSSysNameCB));
1207 RtlCopyMemory( pSysName->SysName.Buffer,
1208 SysNameInfo->SysNames[ ulIndex].String,
1209 pSysName->SysName.Length);
1211 if( *pSysNameListHead == NULL)
1214 *pSysNameListHead = pSysName;
1219 (*pSysNameListTail)->fLink = pSysName;
1222 *pSysNameListTail = pSysName;
1229 AFSReleaseResource( pSysNameLock);
1236 AFSResetSysNameList( IN AFSSysNameCB *SysNameList)
1239 AFSSysNameCB *pNextEntry = NULL, *pCurrentEntry = SysNameList;
1241 while( pCurrentEntry != NULL)
1244 pNextEntry = pCurrentEntry->fLink;
1246 ExFreePool( pCurrentEntry);
1248 pCurrentEntry = pNextEntry;
1255 AFSDefaultDispatch( IN PDEVICE_OBJECT DeviceObject,
1259 NTSTATUS ntStatus = STATUS_INVALID_DEVICE_REQUEST;
1260 PIO_STACK_LOCATION pIrpSp = IoGetCurrentIrpStackLocation( Irp);
1262 AFSCompleteRequest( Irp,
1269 AFSSendDeviceIoControl( IN DEVICE_OBJECT *TargetDeviceObject,
1271 IN void *InputBuffer,
1272 IN ULONG InputBufferLength,
1273 IN OUT void *OutputBuffer,
1274 IN ULONG OutputBufferLength,
1275 OUT ULONG *ResultLength)
1278 NTSTATUS ntStatus = STATUS_SUCCESS;
1281 PIO_STACK_LOCATION pIoStackLocation = NULL;
1287 // Initialize the event
1290 KeInitializeEvent( &kEvent,
1291 SynchronizationEvent,
1295 // Allocate an irp for this request. This could also come from a
1296 // private pool, for instance.
1299 pIrp = IoAllocateIrp( TargetDeviceObject->StackSize,
1305 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
1309 // Build the IRP's main body
1312 pIrp->RequestorMode = KernelMode;
1315 // Set up the I/O stack location.
1318 pIoStackLocation = IoGetNextIrpStackLocation( pIrp);
1319 pIoStackLocation->MajorFunction = IRP_MJ_DEVICE_CONTROL;
1320 pIoStackLocation->DeviceObject = TargetDeviceObject;
1322 pIoStackLocation->Parameters.DeviceIoControl.IoControlCode = IOControl;
1324 pIrp->AssociatedIrp.SystemBuffer = (void *)InputBuffer;
1325 pIoStackLocation->Parameters.DeviceIoControl.InputBufferLength = InputBufferLength;
1328 // Set the completion routine.
1331 IoSetCompletionRoutine( pIrp,
1339 // Send it to the FSD
1342 ntStatus = IoCallDriver( TargetDeviceObject,
1345 if( NT_SUCCESS( ntStatus))
1352 ntStatus = KeWaitForSingleObject( &kEvent,
1358 if( NT_SUCCESS( ntStatus))
1361 ntStatus = pIrp->IoStatus.Status;
1363 if( ResultLength != NULL)
1365 *ResultLength = (ULONG)pIrp->IoStatus.Information;
1375 if( pIrp->MdlAddress != NULL)
1378 if( FlagOn( pIrp->MdlAddress->MdlFlags, MDL_PAGES_LOCKED))
1381 MmUnlockPages( pIrp->MdlAddress);
1384 IoFreeMdl( pIrp->MdlAddress);
1387 pIrp->MdlAddress = NULL;
1401 AFSIrpComplete( IN PDEVICE_OBJECT DeviceObject,
1406 KEVENT *pEvent = (KEVENT *)Context;
1412 return STATUS_MORE_PROCESSING_REQUIRED;
1416 AFSExAllocatePoolWithTag( IN POOL_TYPE PoolType,
1417 IN SIZE_T NumberOfBytes,
1421 AFSDeviceExt *pControlDevExt = NULL;
1422 void *pBuffer = NULL;
1423 BOOLEAN bTimeout = FALSE;
1424 LARGE_INTEGER liTimeout;
1428 // Attempt to allocation memory from the system. If the allocation fails
1429 // wait up to 30 seconds for the AFS redirector to free some memory. As
1430 // long as the wait does not timeout, continue to retry the allocation.
1431 // If the wait does timeout, attempt to allocate one more time in case
1432 // memory was freed by another driver. Otherwise, fail the request.
1435 if ( AFSDeviceObject)
1438 pControlDevExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension;
1441 while( pBuffer == NULL)
1444 pBuffer = ExAllocatePoolWithTag( PoolType,
1448 if( pBuffer == NULL)
1451 if ( bTimeout || pControlDevExt == NULL)
1456 "AFSExAllocatePoolWithTag failure Type %08lX Size %08lX Tag %08lX %08lX\n",
1460 PsGetCurrentThread());
1464 case AFS_GENERIC_MEMORY_21_TAG:
1465 case AFS_GENERIC_MEMORY_22_TAG:
1466 // AFSDumpTraceFiles -- do nothing;
1478 // Wait up to 30 seconds for a memory deallocation
1481 liTimeout.QuadPart = -(30 *AFS_ONE_SECOND);
1483 if( InterlockedIncrement( &pControlDevExt->Specific.Control.WaitingForMemoryCount) == 1)
1485 KeClearEvent( &pControlDevExt->Specific.Control.MemoryAvailableEvent);
1488 ntStatus = KeWaitForSingleObject( &pControlDevExt->Specific.Control.MemoryAvailableEvent,
1494 if( ntStatus == STATUS_TIMEOUT)
1500 InterlockedDecrement( &pControlDevExt->Specific.Control.WaitingForMemoryCount);
1508 AFSExFreePoolWithTag( IN void *Buffer, IN ULONG Tag)
1511 AFSDeviceExt *pControlDevExt = NULL;
1513 if ( AFSDeviceObject)
1516 pControlDevExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension;
1522 ExFreePoolWithTag( Buffer, Tag);
1527 ExFreePool( Buffer);
1530 if ( pControlDevExt)
1533 KeSetEvent( &pControlDevExt->Specific.Control.MemoryAvailableEvent,
1541 AFSShutdownRedirector()
1544 NTSTATUS ntStatus = STATUS_SUCCESS;
1545 AFSDeviceExt *pRDRDevExt = (AFSDeviceExt *)AFSRDRDeviceObject->DeviceExtension;
1546 AFSDeviceExt *pControlDevExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension;
1547 LARGE_INTEGER liTimeout;
1552 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1553 AFS_TRACE_LEVEL_VERBOSE,
1554 "%s Shutting down redirector Extent count %08lX Request count %08lX\n",
1556 pControlDevExt->Specific.Control.ExtentCount,
1557 pControlDevExt->Specific.Control.OutstandingServiceRequestCount);
1560 // Set the shutdown flag so the worker is more agressive in tearing down extents
1563 SetFlag( pRDRDevExt->DeviceFlags, AFS_DEVICE_FLAG_REDIRECTOR_SHUTDOWN);
1566 // Wait on any outstanding service requests
1569 liTimeout.QuadPart = -(30 *AFS_ONE_SECOND);
1571 ntStatus = KeWaitForSingleObject( &pControlDevExt->Specific.Control.OutstandingServiceRequestEvent,
1577 if( ntStatus == STATUS_TIMEOUT)
1580 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1581 AFS_TRACE_LEVEL_WARNING,
1582 "AFSShutdownRedirector Failed to complete all service requests Remaining count %08lX\n",
1583 pControlDevExt->Specific.Control.OutstandingServiceRequestCount);
1585 try_return( ntStatus = STATUS_UNSUCCESSFUL);
1588 AFSProcessQueuedResults( TRUE);
1591 // Wait for all extents to be released
1594 liTimeout.QuadPart = -(30 *AFS_ONE_SECOND);
1596 ntStatus = KeWaitForSingleObject( &pControlDevExt->Specific.Control.ExtentsHeldEvent,
1602 if( ntStatus == STATUS_TIMEOUT)
1605 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1606 AFS_TRACE_LEVEL_WARNING,
1607 "AFSShutdownRedirector Failed to purge all extents Remaining count %08lX\n",
1608 pControlDevExt->Specific.Control.ExtentCount);
1610 try_return( ntStatus = STATUS_UNSUCCESSFUL);
1613 ntStatus = AFSUnloadLibrary( TRUE);
1615 if( !NT_SUCCESS( ntStatus))
1618 try_return( ntStatus);
1623 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1624 AFS_TRACE_LEVEL_VERBOSE,
1625 "%s Completed shut down of redirector Extent count %08lX Request count %08lX Status %08lX\n",
1627 pControlDevExt->Specific.Control.ExtentCount,
1628 pControlDevExt->Specific.Control.OutstandingServiceRequestCount,
1636 // Cache manager callback routines
1640 AFSAcquireFcbForLazyWrite( IN PVOID Fcb,
1644 BOOLEAN bStatus = FALSE;
1645 AFSFcb *pFcb = (AFSFcb *)Fcb;
1646 BOOLEAN bReleaseMain = FALSE, bReleasePaging = FALSE;
1649 // Try and acquire the Fcb resource
1652 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
1653 AFS_TRACE_LEVEL_VERBOSE,
1654 "AFSAcquireFcbForLazyWrite Acquiring Fcb %08lX\n",
1657 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
1658 AFS_TRACE_LEVEL_VERBOSE,
1659 "AFSAcquireFcbForLazyWrite Attempt to acquire Fcb lock %08lX SHARED %08lX\n",
1660 &pFcb->NPFcb->Resource,
1661 PsGetCurrentThread());
1663 if( AFSAcquireShared( &pFcb->NPFcb->Resource,
1667 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
1668 AFS_TRACE_LEVEL_VERBOSE,
1669 "AFSAcquireFcbForLazyWrite Acquired Fcb lock %08lX SHARED %08lX\n",
1670 &pFcb->NPFcb->Resource,
1671 PsGetCurrentThread());
1673 bReleaseMain = TRUE;
1676 // Try and grab the paging
1679 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
1680 AFS_TRACE_LEVEL_VERBOSE,
1681 "AFSAcquireFcbForLazyWrite Attempt to acquire Fcb PagingIo lock %08lX SHARED %08lX\n",
1682 &pFcb->NPFcb->PagingResource,
1683 PsGetCurrentThread());
1685 if( AFSAcquireShared( &pFcb->NPFcb->PagingResource,
1689 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
1690 AFS_TRACE_LEVEL_VERBOSE,
1691 "AFSAcquireFcbForLazyWrite Acquired Fcb PagingIo lock %08lX SHARED %08lX\n",
1692 &pFcb->NPFcb->PagingResource,
1693 PsGetCurrentThread());
1695 bReleasePaging = TRUE;
1703 IoSetTopLevelIrp( (PIRP)FSRTL_CACHE_TOP_LEVEL_IRP);
1713 AFSReleaseResource( &pFcb->NPFcb->Resource);
1719 AFSReleaseResource( &pFcb->NPFcb->PagingResource);
1727 AFSReleaseFcbFromLazyWrite( IN PVOID Fcb)
1730 AFSFcb *pFcb = (AFSFcb *)Fcb;
1732 AFSDbgLogMsg( AFS_SUBSYSTEM_IO_PROCESSING,
1733 AFS_TRACE_LEVEL_VERBOSE,
1734 "AFSReleaseFcbFromLazyWrite Releasing Fcb %08lX\n",
1737 IoSetTopLevelIrp( NULL);
1739 AFSReleaseResource( &pFcb->NPFcb->PagingResource);
1741 AFSReleaseResource( &pFcb->NPFcb->Resource);
1747 AFSAcquireFcbForReadAhead( IN PVOID Fcb,
1751 BOOLEAN bStatus = FALSE;
1752 AFSFcb *pFcb = (AFSFcb *)Fcb;
1754 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
1755 AFS_TRACE_LEVEL_VERBOSE,
1756 "AFSAcquireFcbForReadAhead Attempt to acquire Fcb lock %08lX SHARED %08lX\n",
1757 &pFcb->NPFcb->Resource,
1758 PsGetCurrentThread());
1760 if( AFSAcquireShared( &pFcb->NPFcb->Resource,
1764 AFSDbgLogMsg( AFS_SUBSYSTEM_LOCK_PROCESSING,
1765 AFS_TRACE_LEVEL_VERBOSE,
1766 "AFSAcquireFcbForReadAhead Acquired Fcb lock %08lX SHARED %08lX\n",
1767 &pFcb->NPFcb->Resource,
1768 PsGetCurrentThread());
1772 IoSetTopLevelIrp( (PIRP)FSRTL_CACHE_TOP_LEVEL_IRP);
1779 AFSReleaseFcbFromReadAhead( IN PVOID Fcb)
1782 AFSFcb *pFcb = (AFSFcb *)Fcb;
1784 IoSetTopLevelIrp( NULL);
1786 AFSReleaseResource( &pFcb->NPFcb->Resource);
1792 AFSGetCallerSID( OUT UNICODE_STRING *SIDString, OUT BOOLEAN *pbImpersonation)
1795 NTSTATUS ntStatus = STATUS_SUCCESS;
1796 PACCESS_TOKEN hToken = NULL;
1797 TOKEN_USER *pTokenInfo = NULL;
1798 BOOLEAN bCopyOnOpen = FALSE;
1799 BOOLEAN bEffectiveOnly = FALSE;
1800 BOOLEAN bPrimaryToken = FALSE;
1801 SECURITY_IMPERSONATION_LEVEL stImpersonationLevel;
1802 UNICODE_STRING uniSIDString;
1807 hToken = PsReferenceImpersonationToken( PsGetCurrentThread(),
1810 &stImpersonationLevel);
1815 hToken = PsReferencePrimaryToken( PsGetCurrentProcess());
1820 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1821 AFS_TRACE_LEVEL_ERROR,
1822 "AFSGetCallerSID Failed to retrieve impersonation or primary token\n");
1824 try_return( ntStatus);
1827 bPrimaryToken = TRUE;
1830 ntStatus = SeQueryInformationToken( hToken,
1832 (PVOID *)&pTokenInfo);
1834 if( !NT_SUCCESS( ntStatus))
1837 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1838 AFS_TRACE_LEVEL_ERROR,
1839 "AFSGetCallerSID Failed to retrieve information Status %08lX\n", ntStatus);
1841 try_return( ntStatus);
1844 uniSIDString.Length = 0;
1845 uniSIDString.MaximumLength = 0;
1846 uniSIDString.Buffer = NULL;
1848 ntStatus = RtlConvertSidToUnicodeString( &uniSIDString,
1849 pTokenInfo->User.Sid,
1852 if( !NT_SUCCESS( ntStatus))
1855 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1856 AFS_TRACE_LEVEL_ERROR,
1857 "AFSGetCallerSID Failed to convert sid to string Status %08lX\n", ntStatus);
1859 try_return( ntStatus);
1862 *SIDString = uniSIDString;
1864 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING | AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
1865 AFS_TRACE_LEVEL_VERBOSE_2,
1866 "AFSGetCallerSID Successfully retrieved SID %wZ\n",
1869 if ( bPrimaryToken == FALSE &&
1872 *pbImpersonation = TRUE;
1881 PsDereferencePrimaryToken( hToken);
1885 PsDereferenceImpersonationToken( hToken);
1889 if( pTokenInfo != NULL)
1891 ExFreePool( pTokenInfo); // Allocated by SeQueryInformationToken
1899 AFSGetSessionId( IN HANDLE ProcessId, OUT BOOLEAN *pbImpersonation)
1902 NTSTATUS ntStatus = STATUS_SUCCESS;
1903 PACCESS_TOKEN hToken = NULL;
1904 ULONG ulSessionId = (ULONG)-1;
1905 BOOLEAN bCopyOnOpen = FALSE;
1906 BOOLEAN bEffectiveOnly = FALSE;
1907 BOOLEAN bPrimaryToken = FALSE;
1908 SECURITY_IMPERSONATION_LEVEL stImpersonationLevel;
1913 hToken = PsReferenceImpersonationToken( PsGetCurrentThread(),
1916 &stImpersonationLevel);
1921 hToken = PsReferencePrimaryToken( PsGetCurrentProcess());
1926 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1927 AFS_TRACE_LEVEL_ERROR,
1928 "AFSGetSessionId Failed to retrieve impersonation or primary token\n");
1930 try_return( ntStatus);
1933 bPrimaryToken = TRUE;
1936 ntStatus = SeQueryInformationToken( hToken,
1938 (PVOID *)&ulSessionId);
1940 if( !NT_SUCCESS( ntStatus))
1942 ulSessionId = (ULONG)-1;
1944 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING,
1945 AFS_TRACE_LEVEL_ERROR,
1946 "AFSGetSessionId Failed to retrieve session id Status %08lX\n",
1949 try_return( ntStatus);
1952 AFSDbgLogMsg( AFS_SUBSYSTEM_FILE_PROCESSING | AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
1953 AFS_TRACE_LEVEL_VERBOSE_2,
1954 "AFSGetSessionId found %08lX\n",
1957 if ( bPrimaryToken == FALSE &&
1960 *pbImpersonation = TRUE;
1969 PsDereferencePrimaryToken( hToken);
1973 PsDereferenceImpersonationToken( hToken);
1982 AFSCheckThreadDacl( OUT GUID *AuthGroup)
1985 NTSTATUS ntStatus = STATUS_UNSUCCESSFUL;
1987 PACCESS_TOKEN token = NULL;
1988 PTOKEN_DEFAULT_DACL defDacl = NULL;
1990 PACCESS_ALLOWED_ACE adace;
1991 BOOLEAN bCopyOnOpen = FALSE, bEffectiveOnly = FALSE;
1992 SECURITY_IMPERSONATION_LEVEL stImpersonationLevel;
1993 BOOLEAN bLocatedACE = FALSE;
1998 token = PsReferenceImpersonationToken( PsGetCurrentThread(),
2001 &stImpersonationLevel);
2005 try_return( ntStatus);
2008 ntStatus = SeQueryInformationToken( token,
2012 if( ntStatus != STATUS_SUCCESS)
2014 try_return( ntStatus);
2017 // scan through all ACEs in the DACL
2018 for (idx = 0, ace = (PACE_HEADER)((char *)defDacl->DefaultDacl + sizeof(ACL)); idx < defDacl->DefaultDacl->AceCount; idx++)
2020 if (ace->AceType == ACCESS_ALLOWED_ACE_TYPE)
2022 adace = (PACCESS_ALLOWED_ACE)ace;
2024 if (adace->Header.AceSize == (FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + AFS_DACL_SID_LENGTH))
2026 if (RtlCompareMemory( RtlSubAuthoritySid((PSID)&adace->SidStart, 0), &AFSSidGuid, sizeof(GUID)) == sizeof(GUID))
2029 RtlCopyMemory( AuthGroup,
2030 RtlSubAuthoritySid((PSID)&adace->SidStart, 4),
2041 ace = (PACE_HEADER)((char *)ace + ace->AceSize);
2048 PsDereferenceImpersonationToken( token);
2051 if (defDacl != NULL)
2053 ExFreePool(defDacl);
2058 ntStatus = STATUS_UNSUCCESSFUL;
2066 AFSProcessSetProcessDacl( IN AFSProcessCB *ProcessCB)
2069 PTOKEN_DEFAULT_DACL defDacl = NULL;
2070 HANDLE hToken = NULL;
2071 PACE_HEADER ace = NULL;
2072 SID_IDENTIFIER_AUTHORITY sia = SECURITY_NT_AUTHORITY;
2073 PACCESS_ALLOWED_ACE aaace;
2075 ULONG bytesReturned;
2078 NTSTATUS ntStatus = STATUS_SUCCESS;
2083 ntStatus = ZwOpenProcessTokenEx( NtCurrentProcess(),
2088 if( !NT_SUCCESS( ntStatus))
2090 try_return( ntStatus);
2093 // get the size of the current DACL
2094 ntStatus = ZwQueryInformationToken( hToken,
2100 // if we failed to get the buffer size needed
2101 if ((ntStatus != STATUS_SUCCESS) && (ntStatus != STATUS_BUFFER_TOO_SMALL))
2103 try_return( ntStatus);
2106 // tack on enough space for our ACE if we need to add it...
2107 bytesNeeded += FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + AFS_DACL_SID_LENGTH;
2109 // allocate space for the DACL
2110 defDacl = (PTOKEN_DEFAULT_DACL)ExAllocatePoolWithTag( PagedPool, bytesNeeded, AFS_GENERIC_MEMORY_26_TAG);
2112 if (defDacl == NULL)
2114 try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
2118 ntStatus = ZwQueryInformationToken( hToken,
2124 if( ntStatus != STATUS_SUCCESS)
2126 try_return( ntStatus);
2129 // scan through DACL to see if we have the SID set already...
2130 ace = (PACE_HEADER)((char *)defDacl->DefaultDacl + sizeof(ACL));
2131 for (idx = 0; idx < defDacl->DefaultDacl->AceCount; idx++)
2133 if (ace->AceType == ACCESS_ALLOWED_ACE_TYPE)
2135 aaace = (PACCESS_ALLOWED_ACE)ace;
2137 if (aaace->Header.AceSize == (FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + AFS_DACL_SID_LENGTH))
2139 // if the GUID part matches
2140 if( RtlCompareMemory( RtlSubAuthoritySid((PSID)&aaace->SidStart, 0),
2142 sizeof(GUID)) == sizeof(GUID))
2145 if ( RtlCompareMemory( RtlSubAuthoritySid((PSID)&aaace->SidStart, 4),
2146 ProcessCB->ActiveAuthGroup,
2147 sizeof( GUID)) != sizeof( GUID))
2150 RtlCopyMemory( RtlSubAuthoritySid((PSID)&aaace->SidStart, 4),
2151 ProcessCB->ActiveAuthGroup,
2154 if( AFSSetInformationToken != NULL)
2156 ntStatus = AFSSetInformationToken( hToken,
2163 try_return( ntStatus);
2169 ace = (PACE_HEADER)((char *)ace + ace->AceSize);
2173 // if we made it here we need to add a new ACE to the DACL
2176 aaace = (ACCESS_ALLOWED_ACE *)ace;
2177 aaace->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
2178 aaace->Header.AceFlags = 0;
2179 aaace->Mask = GENERIC_ALL;
2180 psid = (PSID)&aaace->SidStart;
2181 RtlInitializeSid( psid, &sia, 8);
2183 RtlCopyMemory( RtlSubAuthoritySid(psid, 0),
2187 RtlCopyMemory( RtlSubAuthoritySid(psid, 4),
2188 ProcessCB->ActiveAuthGroup,
2191 aaace->Header.AceSize = (USHORT)(FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + RtlLengthSid( psid));
2193 defDacl->DefaultDacl->AclSize += aaace->Header.AceSize;
2194 defDacl->DefaultDacl->AceCount++;
2196 if( AFSSetInformationToken != NULL)
2198 ntStatus = AFSSetInformationToken( hToken,
2201 defDacl->DefaultDacl->AclSize + sizeof(PTOKEN_DEFAULT_DACL));
2211 if (defDacl != NULL)
2213 ExFreePool( defDacl);