示例#1
0
static NTSTATUS
V2vkConnectorProcessInternalSyncTx(V2VK_CONNECTOR_CONTEXT *vcc)
{
    NTSTATUS status;
    unsigned available;
    volatile UCHAR *msg;
    size_t msize;
    V2V_FRAME_HEADER *header;
    V2V_POST_INTERNAL *vpi;

    DbgPrint("%s connector(%p) sending internal message #%d\n", V2VDRV_LOGTAG, vcc, vcc->txCounter + 1);
    available = v2v_nc2_producer_bytes_available(vcc->channel);
    DbgPrint("%s connector(%p) channel indicates minimum bytes available: 0x%x\n", V2VDRV_LOGTAG, vcc, available);

    if ((vcc->flags & V2V_KERNEL_FASTRX) && v2v_nc2_remote_requested_fast_wakeup(vcc->channel))
        msize = MIN(vcc->xferSize, vcc->xferMaxFastRx);
    else
        msize = vcc->xferSize;

    status = v2v_nc2_prep_message(vcc->channel, msize, V2V_MESSAGE_TYPE_INTERNAL, 0, &msg);
    if (!NT_SUCCESS(status)) {
        if (status == STATUS_RETRY) {
            /* No room right now, return and try again later */
            DbgPrint("%s connector(%p) not enough buffer space to send message #%d; retry\n",
                     V2VDRV_LOGTAG, vcc, vcc->txCounter + 1);
            return STATUS_RETRY;
        }
        DbgPrint("%s connector(%p) transmit internal data failure; abort processing - error: 0x%x\n",
                 V2VDRV_LOGTAG, vcc, status);
        return status; /* failure */
    }
    vcc->txCounter++; /* next message */
    header = (V2V_FRAME_HEADER*)msg;
    header->id = (USHORT)vcc->txCounter;
    header->type = V2V_MESSAGE_TYPE_INTERNAL;
    header->cs = 0;
    header->length = vcc->xferSize;
    vpi = (V2V_POST_INTERNAL*)msg;
    status = ExUuidCreate(&vpi->guid);
    if (!NT_SUCCESS(status)) {
        DbgPrint("%s connector(%p) ExUuidCreate() failed - error: 0x%x; using NULL GUID\n",
                 V2VDRV_LOGTAG, vcc, status);
        memset((void*)(msg + sizeof(V2V_FRAME_HEADER)), 0, sizeof(GUID));
    }
    /* Fill it up with some data and send it */
    memset((void*)(msg + sizeof(V2V_POST_INTERNAL)),
           'X',
           (vcc->xferSize - sizeof(V2V_POST_INTERNAL)));
    header->cs = V2vChecksum((const UCHAR*)msg, vcc->xferSize);
    v2v_nc2_send_messages(vcc->channel);

    /* Keep the send loop going by setting the event. If there is no more room, the prep message call
       will return ERROR_RETRY and just land us back in the wait. */
    KeSetEvent(v2v_get_send_event(vcc->channel), IO_NO_INCREMENT, FALSE);

    return STATUS_SUCCESS;
}
示例#2
0
/*
 * @implemented
 */
VOID
CreateNoDriveLetterEntry(IN PMOUNTDEV_UNIQUE_ID UniqueId)
{
    UUID Guid;
    PWCHAR String;
    UNICODE_STRING GuidString;

    /* Entry with no drive letter are made that way:
     * Instead of having a path with the letter,
     * you have GUID with the unique ID.
     */
    if (!NT_SUCCESS(ExUuidCreate(&Guid)))
    {
        return;
    }

    /* Convert to string */
    if (!NT_SUCCESS(RtlStringFromGUID(&Guid, &GuidString)))
    {
        return;
    }

    /* No letter entries must start with #, so allocate a proper string */
    String = AllocatePool(GuidString.Length + 2 * sizeof(WCHAR));
    if (!String)
    {
        ExFreePoolWithTag(GuidString.Buffer, 0);
        return;
    }

    /* Write the complete string */
    String[0] = L'#';
    RtlCopyMemory(String + 1, GuidString.Buffer, GuidString.Length);
    String[GuidString.Length / sizeof(WCHAR)] = UNICODE_NULL;

    /* Don't need that one anymore */
    ExFreePoolWithTag(GuidString.Buffer, 0);

    /* Write the entry */
    RtlWriteRegistryValue(RTL_REGISTRY_ABSOLUTE,
                          DatabasePath,
                          String,
                          REG_BINARY,
                          UniqueId->UniqueId,
                          UniqueId->UniqueIdLength);

    FreePool(String);

    return;
}
示例#3
0
文件: util.c 项目: billziss-gh/winfsp
NTSTATUS FspCreateGuid(GUID *Guid)
{
    PAGED_CODE();

    NTSTATUS Result;

    int Retries = 3;
    do
    {
        Result = ExUuidCreate(Guid);
    } while (!NT_SUCCESS(Result) && 0 < --Retries);

    return Result;
}
示例#4
0
/*
 * @implemented
 */
NTSTATUS
CreateNewVolumeName(OUT PUNICODE_STRING VolumeName,
                    IN PGUID VolumeGuid OPTIONAL)
{
    GUID Guid;
    NTSTATUS Status;
    UNICODE_STRING GuidString;

    /* If no GUID was provided, then create one */
    if (!VolumeGuid)
    {
        Status = ExUuidCreate(&Guid);
        if (!NT_SUCCESS(Status))
        {
            return Status;
        }
    }
    else
    {
        RtlCopyMemory(&Guid, VolumeGuid, sizeof(GUID));
    }

    /* Convert GUID to string */
    Status = RtlStringFromGUID(&Guid, &GuidString);
    if (!NT_SUCCESS(Status))
    {
        return Status;
    }

    /* Size for volume namespace, litteral GUID, and null char */
    VolumeName->MaximumLength = 0x14 + 0x4C + sizeof(UNICODE_NULL);
    VolumeName->Buffer = AllocatePool(0x14 + 0x4C + sizeof(UNICODE_NULL));
    if (!VolumeName->Buffer)
    {
        Status = STATUS_INSUFFICIENT_RESOURCES;
    }
    else
    {
        RtlCopyUnicodeString(VolumeName, &Volume);
        RtlAppendUnicodeStringToString(VolumeName, &GuidString);
        VolumeName->Buffer[VolumeName->Length / sizeof(WCHAR)] = UNICODE_NULL;
        Status = STATUS_SUCCESS;
    }

    ExFreePoolWithTag(GuidString.Buffer, 0);

    return Status;
}
示例#5
0
void rnd_reseed_now()
{
	seed_data seed;

	KeQuerySystemTime(&seed.seed20);
	
	seed.seed1  = PsGetCurrentProcess();
	seed.seed2  = PsGetCurrentProcessId();
	seed.seed3  = KeGetCurrentThread();
	seed.seed4  = PsGetCurrentThreadId();
	seed.seed5  = KeGetCurrentProcessorNumber();
	seed.seed6  = KeQueryInterruptTime();
	seed.seed10 = KeQueryPerformanceCounter(NULL);
	seed.seed11 = __rdtsc();
	seed.seed12 = ExGetPreviousMode();	
	seed.seed14 = IoGetTopLevelIrp();
	seed.seed15 = MmQuerySystemSize();
	seed.seed24 = KeGetCurrentIrql();
	
	if (KeGetCurrentIrql() == PASSIVE_LEVEL) {
		seed.seed7  = KeQueryPriorityThread(seed.seed3);
		seed.seed17 = ExUuidCreate(&seed.seed18);
		seed.seed19 = RtlRandom(&seed.seed8);
	}
	if (KeGetCurrentIrql() <= APC_LEVEL) {
		seed.seed13 = IoGetInitialStack();
		seed.seed16 = PsGetProcessExitTime();
		IoGetStackLimits(&seed.seed22, &seed.seed23);
	}	
	KeQueryTickCount(&seed.seed21);
	
	rnd_add_buff(&seed, sizeof(seed));
	
	/* Prevent leaks */	
	zeroauto(&seed, sizeof(seed));
}
示例#6
0
NTSTATUS
NTAPI
IntCreateNewRegistryPath(
    PVIDEO_PORT_DEVICE_EXTENSION DeviceExtension)
{
    static UNICODE_STRING VideoIdValueName = RTL_CONSTANT_STRING(L"VideoId");
    static UNICODE_STRING ControlVideoPathName =
        RTL_CONSTANT_STRING(L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Video\\");
    HANDLE DevInstRegKey, SettingsKey, NewKey;
    UCHAR VideoIdBuffer[sizeof(KEY_VALUE_PARTIAL_INFORMATION) + GUID_STRING_LENGTH];
    UNICODE_STRING VideoIdString;
    UUID VideoId;
    PKEY_VALUE_PARTIAL_INFORMATION ValueInformation ;
    NTSTATUS Status;
    ULONG ResultLength;
    USHORT KeyMaxLength;
    OBJECT_ATTRIBUTES ObjectAttributes;

    /* Open the hardware key: HKLM\System\CurrentControlSet\Enum\... */
    Status = IoOpenDeviceRegistryKey(DeviceExtension->PhysicalDeviceObject,
                                     PLUGPLAY_REGKEY_DEVICE,
                                     KEY_ALL_ACCESS,
                                     &DevInstRegKey);
    if (Status != STATUS_SUCCESS)
    {
        ERR_(VIDEOPRT, "IoOpenDeviceRegistryKey failed: status 0x%lx\n", Status);
        return Status;
    }

    /* Query the VideoId value */
    ValueInformation = (PKEY_VALUE_PARTIAL_INFORMATION)VideoIdBuffer;
    Status = ZwQueryValueKey(DevInstRegKey,
                             &VideoIdValueName,
                             KeyValuePartialInformation,
                             ValueInformation,
                             sizeof(VideoIdBuffer),
                             &ResultLength);
    if (!NT_SUCCESS(Status))
    {
        /* Create a new video Id */
        Status = ExUuidCreate(&VideoId);
        if (!NT_SUCCESS(Status))
        {
            ERR_(VIDEOPRT, "ExUuidCreate failed: status 0x%lx\n", Status);
            ObCloseHandle(DevInstRegKey, KernelMode);
            return Status;
        }

        /* Convert the GUID into a string */
        Status = RtlStringFromGUID(&VideoId, &VideoIdString);
        if (!NT_SUCCESS(Status))
        {
            ERR_(VIDEOPRT, "RtlStringFromGUID failed: status 0x%lx\n", Status);
            ObCloseHandle(DevInstRegKey, KernelMode);
            return Status;
        }

        /* Copy the GUID String to our buffer */
        ValueInformation->DataLength = min(VideoIdString.Length, GUID_STRING_LENGTH);
        RtlCopyMemory(ValueInformation->Data,
                      VideoIdString.Buffer,
                      ValueInformation->DataLength);

        /* Free the GUID string */
        RtlFreeUnicodeString(&VideoIdString);

        /* Write the VideoId registry value */
        Status = ZwSetValueKey(DevInstRegKey,
                               &VideoIdValueName,
                               0,
                               REG_SZ,
                               ValueInformation->Data,
                               ValueInformation->DataLength);
        if (!NT_SUCCESS(Status))
        {
            ERR_(VIDEOPRT, "ZwSetValueKey failed: status 0x%lx\n", Status);
            ObCloseHandle(DevInstRegKey, KernelMode);
            return Status;
        }
    }

    /* Initialize the VideoId string from the registry data */
    VideoIdString.Buffer = (PWCHAR)ValueInformation->Data;
    VideoIdString.Length = (USHORT)ValueInformation->DataLength;
    VideoIdString.MaximumLength = VideoIdString.Length;

    /* Close the hardware key */
    ObCloseHandle(DevInstRegKey, KernelMode);

    /* Calculate the size needed for the new registry path name */
    KeyMaxLength = ControlVideoPathName.Length +
                   VideoIdString.Length +
                   sizeof(L"\\0000");

    /* Allocate the path name buffer */
    DeviceExtension->NewRegistryPath.Length = 0;
    DeviceExtension->NewRegistryPath.MaximumLength = KeyMaxLength;
    DeviceExtension->NewRegistryPath.Buffer = ExAllocatePoolWithTag(PagedPool,
                                                                    KeyMaxLength,
                                                                    TAG_VIDEO_PORT);
    if (DeviceExtension->NewRegistryPath.Buffer == NULL)
    {
        ERR_(VIDEOPRT, "Failed to allocate key name buffer.\n");
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    /* Copy the root key name and append the VideoId string */
    RtlCopyUnicodeString(&DeviceExtension->NewRegistryPath,
                         &ControlVideoPathName);
    RtlAppendUnicodeStringToString(&DeviceExtension->NewRegistryPath,
                                   &VideoIdString);

    /* Check if we have the key already */
    Status = RtlCheckRegistryKey(RTL_REGISTRY_ABSOLUTE,
                                 DeviceExtension->NewRegistryPath.Buffer);
    if (Status != STATUS_SUCCESS)
    {
        /* Try to create the new key */
        Status = RtlCreateRegistryKey(RTL_REGISTRY_ABSOLUTE,
                                      DeviceExtension->NewRegistryPath.Buffer);
    }

    /* Append a the instance path */ /// \todo HACK
    RtlAppendUnicodeToString(&DeviceExtension->NewRegistryPath, L"\\");
    RtlAppendUnicodeToString(&DeviceExtension->NewRegistryPath, L"0000");

    /* Check this key again */
    Status = RtlCheckRegistryKey(RTL_REGISTRY_ABSOLUTE,
                                 DeviceExtension->NewRegistryPath.Buffer);
    if (Status != STATUS_SUCCESS)
    {
        /* Try to create the new key */
        Status = RtlCreateRegistryKey(RTL_REGISTRY_ABSOLUTE,
                                      DeviceExtension->NewRegistryPath.Buffer);
        if (!NT_SUCCESS(Status))
        {
            ERR_(VIDEOPRT, "Failed create key '%wZ'\n", &DeviceExtension->NewRegistryPath);
            return Status;
        }

        /* Open the new key */
        InitializeObjectAttributes(&ObjectAttributes,
                                   &DeviceExtension->NewRegistryPath,
                                   OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE,
                                   NULL,
                                   NULL);
        Status = ZwOpenKey(&NewKey, KEY_READ, &ObjectAttributes);
        if (!NT_SUCCESS(Status))
        {
            ERR_(VIDEOPRT, "Failed to open settings key. Status 0x%lx\n", Status);
            return Status;
        }

        /* Open the device profile key */
        InitializeObjectAttributes(&ObjectAttributes,
                                   &DeviceExtension->RegistryPath,
                                   OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE,
                                   NULL,
                                   NULL);
        Status = ZwOpenKey(&SettingsKey, KEY_READ, &ObjectAttributes);
        if (!NT_SUCCESS(Status))
        {
            ERR_(VIDEOPRT, "Failed to open settings key. Status 0x%lx\n", Status);
            ObCloseHandle(NewKey, KernelMode);
            return Status;
        }

        /* Copy the registry data from the legacy key */
        Status = IntCopyRegistryKey(SettingsKey, NewKey);
    }


    return Status;
}
示例#7
0
文件: txrutil.c 项目: kcrazy/winekit
NTSTATUS
CreateKTMResourceManager(
    __in PTM_RM_NOTIFICATION CallbackRoutine,
    __in_opt PVOID RMKey
    )
/*++

Routine Description:

    This method will create a volatile Transaction Manager (TM) and a volatile
    Resource Manager (RM) and enable callback notification through them.
    The RM created here is used to enlist onto a transaction so that the 
    RMCallback routine will be called when the transaction commits or aborts. 

Arguments:

    CallbackRoutine - Pointer to a ResourceManagerNotification Routine

    RMKey - A caller-defined context value that uniquely identifies the 
            resource manager. The callback routine receives this value as 
            input.
            Note: When you are enlisting to a transaction, you can pass in a 
            context that is specific to that particular enlistment.

Return Value:

    NTSTATUS

--*/
{
    OBJECT_ATTRIBUTES ObjAttributes;
    PKRESOURCEMANAGER RMObject;
    NTSTATUS Status = STATUS_SUCCESS;
    HANDLE TMHandle = NULL;
    HANDLE RMHandle = NULL;
    GUID RMGuid;

    InfoPrint("Creating KTM Resource Manager");

    //
    // Create the volatile TM
    //
    
    InitializeObjectAttributes(&ObjAttributes,
                               NULL,
                               OBJ_KERNEL_HANDLE,
                               NULL,
                               NULL);

    Status = ZwCreateTransactionManager(&TMHandle,
                                        TRANSACTIONMANAGER_ALL_ACCESS,
                                        &ObjAttributes,
                                        NULL,
                                        TRANSACTION_MANAGER_VOLATILE,
                                        0);

    if (!NT_SUCCESS(Status)) {
        ErrorPrint("CreateTransactionManager failed. Status 0x%x", Status);
        goto Exit;
    }

    //
    // Create the volatile RM
    //
    
    Status = ExUuidCreate(&RMGuid);

    if (!NT_SUCCESS(Status)) {
        ErrorPrint("ExUuidCreate failed. Status 0x%x", Status);
        goto Exit;
    }

    InitializeObjectAttributes(&ObjAttributes,
                               NULL,
                               OBJ_KERNEL_HANDLE,
                               NULL,
                               NULL);

    Status = ZwCreateResourceManager(&RMHandle,
                                     RESOURCEMANAGER_ALL_ACCESS,
                                     TMHandle,
                                     &RMGuid,
                                     &ObjAttributes,
                                     RESOURCE_MANAGER_VOLATILE,
                                     NULL);

    if (!NT_SUCCESS(Status)) {
        ErrorPrint("CreateResourceManager failed. Status 0x%x", Status);
        goto Exit;
    }

    //
    // Grab the RM object from the handle
    //

    Status = ObReferenceObjectByHandle(RMHandle,
                                       0,
                                       NULL,
                                       KernelMode,
                                       (PVOID *) &RMObject,
                                       NULL);
    
    if (!NT_SUCCESS(Status)) {
        ErrorPrint("ObReferenceObjectbyHandle failed. Status 0x%x", Status);
        goto Exit;
    }

    //
    // Enable callbacks and pass in our notification routine
    //
    
    Status = TmEnableCallbacks(RMObject,
                               CallbackRoutine,
                               RMKey);

    ObDereferenceObject(RMObject);
    
    if (!NT_SUCCESS(Status)) {
        ErrorPrint("TmEnableCallbacks failed. Status 0x%x", Status);
        goto Exit;
    }

  Exit:

    if (!NT_SUCCESS(Status)) {
        if (RMHandle != NULL) {
            ZwClose(RMHandle);
        }
        if (TMHandle!= NULL) {
            ZwClose(TMHandle);
        }
    } else {
        ResourceManager = RMHandle;
        TransactionManager = TMHandle;
    }
    
    return Status;    
}
示例#8
0
GUID *
AFSValidateProcessEntry( IN HANDLE  ProcessId,
                         IN BOOLEAN bProcessTreeLocked)
{

    GUID *pAuthGroup = NULL;
    NTSTATUS ntStatus = STATUS_SUCCESS;
    AFSProcessCB *pProcessCB = NULL, *pParentProcessCB = NULL;
    AFSDeviceExt *pDeviceExt = (AFSDeviceExt *)AFSDeviceObject->DeviceExtension;
    ULONGLONG ullProcessID = (ULONGLONG)ProcessId;
    UNICODE_STRING uniSIDString;
    ULONG ulSIDHash = 0;
    AFSSIDEntryCB *pSIDEntryCB = NULL;
    ULONG ulSessionId = 0;
    ULONGLONG ullTableHash = 0;
    AFSThreadCB *pParentThreadCB = NULL;
    UNICODE_STRING uniGUID;
    BOOLEAN bImpersonation = FALSE;

    __Enter
    {

        uniSIDString.Length = 0;
        uniSIDString.MaximumLength = 0;
        uniSIDString.Buffer = NULL;

        if ( !bProcessTreeLocked)
        {

            AFSDbgTrace(( AFS_SUBSYSTEM_LOCK_PROCESSING,
                          AFS_TRACE_LEVEL_VERBOSE,
                          "AFSValidateProcessEntry Acquiring Control ProcessTree.TreeLock lock %p SHARED %08lX\n",
                          pDeviceExt->Specific.Control.ProcessTree.TreeLock,
                          PsGetCurrentThread()));

            AFSAcquireShared( pDeviceExt->Specific.Control.ProcessTree.TreeLock,
                              TRUE);
        }

        AFSDbgTrace(( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
                      AFS_TRACE_LEVEL_VERBOSE,
                      "%s Entry for ProcessID %I64X\n",
                      __FUNCTION__,
                      ullProcessID));

        ntStatus = AFSLocateHashEntry( pDeviceExt->Specific.Control.ProcessTree.TreeHead,
                                       ullProcessID,
                                       (AFSBTreeEntry **)&pProcessCB);

        if( !NT_SUCCESS( ntStatus) ||
            pProcessCB == NULL)
        {

            if ( !bProcessTreeLocked)
            {

                AFSReleaseResource( pDeviceExt->Specific.Control.ProcessTree.TreeLock);

                AFSAcquireExcl( pDeviceExt->Specific.Control.ProcessTree.TreeLock,
                                TRUE);
            }

            ntStatus = AFSLocateHashEntry( pDeviceExt->Specific.Control.ProcessTree.TreeHead,
                                           ullProcessID,
                                           (AFSBTreeEntry **)&pProcessCB);

            if( !NT_SUCCESS( ntStatus) ||
                pProcessCB == NULL)
            {

                AFSProcessCreate( 0,
                                  ProcessId,
                                  0,
                                  0);
            }

            if( !NT_SUCCESS( ntStatus) ||
                pProcessCB == NULL)
            {

                AFSDbgTrace(( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
                              AFS_TRACE_LEVEL_ERROR,
                              "%s Failed to locate process entry for ProcessID %I64X\n",
                              __FUNCTION__,
                              ullProcessID));

                try_return( ntStatus = STATUS_UNSUCCESSFUL);
            }

            if ( !bProcessTreeLocked)
            {

                AFSConvertToShared( pDeviceExt->Specific.Control.ProcessTree.TreeLock);
            }
        }

        //
        // Locate and lock the ParentProcessCB if we have one
        //

        if( pProcessCB->ParentProcessId != 0)
        {

            AFSDbgTrace(( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
                          AFS_TRACE_LEVEL_VERBOSE,
                          "%s Locating process entry for Parent ProcessID %I64X\n",
                          __FUNCTION__,
                          pProcessCB->ParentProcessId));

            ntStatus = AFSLocateHashEntry( pDeviceExt->Specific.Control.ProcessTree.TreeHead,
                                           (ULONGLONG)pProcessCB->ParentProcessId,
                                           (AFSBTreeEntry **)&pParentProcessCB);

            if( NT_SUCCESS( ntStatus) &&
                pParentProcessCB != NULL)
            {
                AFSAcquireExcl( &pParentProcessCB->Lock,
                                TRUE);

                AFSDbgTrace(( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
                              AFS_TRACE_LEVEL_VERBOSE,
                              "%s Located process entry for Parent ProcessID %I64X\n",
                              __FUNCTION__,
                              pProcessCB->ParentProcessId));
            }
        }
        else
        {

            AFSDbgTrace(( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
                          AFS_TRACE_LEVEL_VERBOSE,
                          "%s No parent ID for ProcessID %I64X\n",
                          __FUNCTION__,
                          ullProcessID));
        }

        AFSAcquireExcl( &pProcessCB->Lock,
                        TRUE);

#if defined(_WIN64)

        //
        // Mark the process as 64-bit if it is.
        //

        if( !IoIs32bitProcess( NULL))
        {

            SetFlag( pProcessCB->Flags, AFS_PROCESS_FLAG_IS_64BIT);
        }
        else
        {

            ClearFlag( pProcessCB->Flags, AFS_PROCESS_FLAG_IS_64BIT);
        }
#endif

        //
        // Locate the SID for the caller
        //

        ntStatus = AFSGetCallerSID( &uniSIDString, &bImpersonation);

        if( !NT_SUCCESS( ntStatus))
        {

            AFSDbgTrace(( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
                          AFS_TRACE_LEVEL_ERROR,
                          "%s Failed to locate callers SID for ProcessID %I64X\n",
                          __FUNCTION__,
                          ullProcessID));

            try_return( ntStatus);
        }

        ulSessionId = AFSGetSessionId( (HANDLE)ullProcessID, &bImpersonation);

        if( ulSessionId == (ULONG)-1)
        {

            AFSDbgTrace(( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
                          AFS_TRACE_LEVEL_ERROR,
                          "%s Failed to retrieve session ID for ProcessID %I64X\n",
                          __FUNCTION__,
                          ullProcessID));

            try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
        }

        AFSDbgTrace(( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
                      AFS_TRACE_LEVEL_VERBOSE,
                      "%s Retrieved callers SID %wZ for ProcessID %I64X Session %08lX\n",
                      __FUNCTION__,
                      &uniSIDString,
                      ullProcessID,
                      ulSessionId));

        //
        // If there is an Auth Group for the current process,
        // our job is finished.
        //

        if ( bImpersonation == FALSE)
        {
            pAuthGroup = pProcessCB->ActiveAuthGroup;

            if( pAuthGroup != NULL &&
                !AFSIsNoPAGAuthGroup( pAuthGroup))
            {

                uniGUID.Buffer = NULL;

                RtlStringFromGUID( *pAuthGroup,
                                   &uniGUID);

                AFSDbgTrace(( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
                              AFS_TRACE_LEVEL_VERBOSE,
                              "%s Located valid AuthGroup GUID %wZ for SID %wZ ProcessID %I64X Session %08lX\n",
                              __FUNCTION__,
                              &uniGUID,
                              &uniSIDString,
                              ullProcessID,
                              ulSessionId));

                if( uniGUID.Buffer != NULL)
                {
                    RtlFreeUnicodeString( &uniGUID);
                }

                try_return( ntStatus = STATUS_SUCCESS);
            }

            //
            // The current process does not yet have an Auth Group.  Try to inherit
            // one from the parent process thread that created this process.
            //

            if( pParentProcessCB != NULL)
            {

                for ( pParentThreadCB = pParentProcessCB->ThreadList;
                      pParentThreadCB != NULL;
                      pParentThreadCB = pParentThreadCB->Next)
                {

                    if( pParentThreadCB->ThreadId == pProcessCB->CreatingThreadId)
                    {
                        break;
                    }
                }

                //
                // If the creating thread was found and it has a thread specific
                // Auth Group, use that even if it is the No PAG
                //

                if( pParentThreadCB != NULL &&
                    pParentThreadCB->ActiveAuthGroup != NULL &&
                    !AFSIsNoPAGAuthGroup( pParentThreadCB->ActiveAuthGroup))
                {
                    pProcessCB->ActiveAuthGroup = pParentThreadCB->ActiveAuthGroup;

                    uniGUID.Buffer = NULL;

                    RtlStringFromGUID( *(pProcessCB->ActiveAuthGroup),
                                       &uniGUID);

                    AFSDbgTrace(( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
                                  AFS_TRACE_LEVEL_VERBOSE,
                                  "%s PID %I64X Session %08lX inherited Active AuthGroup %wZ from thread %I64X\n",
                                  __FUNCTION__,
                                  ullProcessID,
                                  ulSessionId,
                                  &uniGUID,
                                  pParentThreadCB->ThreadId));

                    if( uniGUID.Buffer != NULL)
                    {
                        RtlFreeUnicodeString( &uniGUID);
                    }
                }

                //
                // If the parent thread was not found or does not have an auth group
                //

                else if( pParentProcessCB->ActiveAuthGroup != NULL &&
                         !AFSIsNoPAGAuthGroup( pParentProcessCB->ActiveAuthGroup))
                {
                    pProcessCB->ActiveAuthGroup = pParentProcessCB->ActiveAuthGroup;

                    uniGUID.Buffer = NULL;

                    RtlStringFromGUID( *(pProcessCB->ActiveAuthGroup),
                                       &uniGUID);

                    AFSDbgTrace(( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
                                  AFS_TRACE_LEVEL_VERBOSE,
                                  "%s PID %I64X Session %08lX inherited Active AuthGroup %wZ from parent PID %I64X\n",
                                  __FUNCTION__,
                                  ullProcessID,
                                  ulSessionId,
                                  &uniGUID,
                                  pParentProcessCB->TreeEntry.HashIndex));

                    if( uniGUID.Buffer != NULL)
                    {
                        RtlFreeUnicodeString( &uniGUID);
                    }
                }

                //
                // If an Auth Group was inherited, set it to be the active group
                //

                if( pProcessCB->ActiveAuthGroup != NULL &&
                    !AFSIsNoPAGAuthGroup( pParentProcessCB->ActiveAuthGroup))
                {
                    pAuthGroup = pProcessCB->ActiveAuthGroup;

                    uniGUID.Buffer = NULL;

                    RtlStringFromGUID( *(pProcessCB->ActiveAuthGroup),
                                       &uniGUID);

                    AFSDbgTrace(( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
                                  AFS_TRACE_LEVEL_VERBOSE,
                                  "%s Returning(1) Active AuthGroup %wZ for SID %wZ PID %I64X Session %08lX\n",
                                  __FUNCTION__,
                                  &uniGUID,
                                  &uniSIDString,
                                  ullProcessID,
                                  ulSessionId));

                    if( uniGUID.Buffer != NULL)
                    {
                        RtlFreeUnicodeString( &uniGUID);
                    }

                    try_return( ntStatus);
                }
            }
        }

        //
        // If no Auth Group was inherited, assign one based upon the Session and SID
        //

        ntStatus = RtlHashUnicodeString( &uniSIDString,
                                         TRUE,
                                         HASH_STRING_ALGORITHM_DEFAULT,
                                         &ulSIDHash);

        if( !NT_SUCCESS( ntStatus))
        {

            AFSDbgTrace(( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
                          AFS_TRACE_LEVEL_ERROR,
                          "%s Failed to hash SID %wZ for PID %I64X Session %08lX Status %08lX\n",
                          __FUNCTION__,
                          &uniSIDString,
                          ullProcessID,
                          ulSessionId,
                          ntStatus));

            try_return( ntStatus);
        }

        ullTableHash = ( ((ULONGLONG)ulSessionId << 32) | ulSIDHash);

        AFSAcquireShared( pDeviceExt->Specific.Control.AuthGroupTree.TreeLock,
                          TRUE);

        ntStatus = AFSLocateHashEntry( pDeviceExt->Specific.Control.AuthGroupTree.TreeHead,
                                       (ULONGLONG)ullTableHash,
                                       (AFSBTreeEntry **)&pSIDEntryCB);

        if( !NT_SUCCESS( ntStatus) ||
            pSIDEntryCB == NULL)
        {

            AFSReleaseResource( pDeviceExt->Specific.Control.AuthGroupTree.TreeLock);

            AFSAcquireExcl( pDeviceExt->Specific.Control.AuthGroupTree.TreeLock,
                            TRUE);

            ntStatus = AFSLocateHashEntry( pDeviceExt->Specific.Control.AuthGroupTree.TreeHead,
                                           (ULONGLONG)ullTableHash,
                                           (AFSBTreeEntry **)&pSIDEntryCB);

            if( !NT_SUCCESS( ntStatus) ||
                pSIDEntryCB == NULL)
            {

                pSIDEntryCB = (AFSSIDEntryCB *)AFSExAllocatePoolWithTag( NonPagedPool,
                                                                         sizeof( AFSSIDEntryCB),
                                                                         AFS_AG_ENTRY_CB_TAG);

                if( pSIDEntryCB == NULL)
                {

                    AFSReleaseResource( pDeviceExt->Specific.Control.AuthGroupTree.TreeLock);

                    try_return( ntStatus = STATUS_INSUFFICIENT_RESOURCES);
                }

                RtlZeroMemory( pSIDEntryCB,
                               sizeof( AFSSIDEntryCB));

                pSIDEntryCB->TreeEntry.HashIndex = (ULONGLONG)ullTableHash;

                while( ExUuidCreate( &pSIDEntryCB->AuthGroup) == STATUS_RETRY);

                uniGUID.Buffer = NULL;

                RtlStringFromGUID( pSIDEntryCB->AuthGroup,
                                   &uniGUID);

                AFSDbgTrace(( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
                              AFS_TRACE_LEVEL_VERBOSE,
                              "%s  SID %wZ PID %I64X Session %08lX generated NEW AG %wZ\n",
                              __FUNCTION__,
                              &uniSIDString,
                              ullProcessID,
                              ulSessionId,
                              &uniGUID));

                if( uniGUID.Buffer != NULL)
                {
                    RtlFreeUnicodeString( &uniGUID);
                }

                if( pDeviceExt->Specific.Control.AuthGroupTree.TreeHead == NULL)
                {
                    pDeviceExt->Specific.Control.AuthGroupTree.TreeHead = (AFSBTreeEntry *)pSIDEntryCB;
                }
                else
                {
                    AFSInsertHashEntry( pDeviceExt->Specific.Control.AuthGroupTree.TreeHead,
                                        &pSIDEntryCB->TreeEntry);
                }
            }

            AFSConvertToShared( pDeviceExt->Specific.Control.AuthGroupTree.TreeLock);
        }


        AFSReleaseResource( pDeviceExt->Specific.Control.AuthGroupTree.TreeLock);

        //
        // Store the auth group into the process cb
        //

        pProcessCB->ActiveAuthGroup = &pSIDEntryCB->AuthGroup;

        uniGUID.Buffer = NULL;

        RtlStringFromGUID( pSIDEntryCB->AuthGroup,
                           &uniGUID);

        AFSDbgTrace(( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
                      AFS_TRACE_LEVEL_VERBOSE,
                      "%s SID %wZ PID %I64X Session %08lX assigned AG %wZ\n",
                      __FUNCTION__,
                      &uniSIDString,
                      ullProcessID,
                      ulSessionId,
                      &uniGUID));

        if( uniGUID.Buffer != NULL)
        {
            RtlFreeUnicodeString( &uniGUID);
        }

        //
        // Set the AFS_PROCESS_LOCAL_SYSTEM_AUTH flag if the process SID
        // is LOCAL_SYSTEM
        //

        if( AFSIsLocalSystemSID( &uniSIDString))
        {
            SetFlag( pProcessCB->Flags, AFS_PROCESS_LOCAL_SYSTEM_AUTH);

            AFSDbgTrace(( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
                          AFS_TRACE_LEVEL_VERBOSE,
                          "%s Setting PID %I64X Session %08lX with LOCAL SYSTEM AUTHORITY\n",
                          __FUNCTION__,
                          ullProcessID,
                          ulSessionId));
        }

        //
        // Return the auth group
        //

        pAuthGroup = pProcessCB->ActiveAuthGroup;

        uniGUID.Buffer = NULL;

        RtlStringFromGUID( *(pProcessCB->ActiveAuthGroup),
                           &uniGUID);

        AFSDbgTrace(( AFS_SUBSYSTEM_AUTHGROUP_PROCESSING,
                      AFS_TRACE_LEVEL_VERBOSE,
                      "%s Returning(2) Active AuthGroup %wZ for SID %wZ PID %I64X Session %08lX\n",
                      __FUNCTION__,
                      &uniGUID,
                      &uniSIDString,
                      ullProcessID,
                      ulSessionId));

        if( uniGUID.Buffer != NULL)
        {
            RtlFreeUnicodeString( &uniGUID);
        }

try_exit:

        if( pProcessCB != NULL)
        {

            if( bImpersonation == FALSE &&
                !BooleanFlagOn( pProcessCB->Flags, AFS_PROCESS_FLAG_ACE_SET) &&
                NT_SUCCESS( ntStatus))
            {
                ntStatus = AFSProcessSetProcessDacl( pProcessCB);

                if( !NT_SUCCESS( ntStatus))
                {
                    pAuthGroup = NULL;
                }
                else
                {
                    SetFlag( pProcessCB->Flags, AFS_PROCESS_FLAG_ACE_SET);
                }
            }

            AFSReleaseResource( &pProcessCB->Lock);
        }

        if( pParentProcessCB != NULL)
        {
            AFSReleaseResource( &pParentProcessCB->Lock);
        }

        if( uniSIDString.Length > 0)
        {
            RtlFreeUnicodeString( &uniSIDString);
        }

        if ( !bProcessTreeLocked)
        {

            AFSReleaseResource( pDeviceExt->Specific.Control.ProcessTree.TreeLock);
        }
    }

    return pAuthGroup;
}