Exemple #1
0
/* KphOpenProcessTokenEx
 * 
 * Opens the primary token of the specified process.
 */
NTSTATUS KphOpenProcessTokenEx(
    __in HANDLE ProcessHandle,
    __in ACCESS_MASK DesiredAccess,
    __in ULONG ObjectAttributes,
    __out PHANDLE TokenHandle,
    __in KPROCESSOR_MODE AccessMode
    )
{
    NTSTATUS status = STATUS_SUCCESS;
    PEPROCESS processObject;
    PACCESS_TOKEN tokenObject;
    HANDLE tokenHandle;
    ACCESS_STATE accessState;
    CHAR auxData[AUX_ACCESS_DATA_SIZE];
    
    status = SeCreateAccessState(
        &accessState,
        (PAUX_ACCESS_DATA)auxData,
        DesiredAccess,
        (PGENERIC_MAPPING)KVOFF(*SeTokenObjectType, OffOtiGenericMapping)
        );
    
    if (!NT_SUCCESS(status))
    {
        return status;
    }
    
    if (accessState.RemainingDesiredAccess & MAXIMUM_ALLOWED)
        accessState.PreviouslyGrantedAccess |= TOKEN_ALL_ACCESS;
    else
        accessState.PreviouslyGrantedAccess |= accessState.RemainingDesiredAccess;
    
    accessState.RemainingDesiredAccess = 0;
    
    status = ObReferenceObjectByHandle(
        ProcessHandle,
        0,
        *PsProcessType,
        KernelMode,
        &processObject,
        NULL
        );
    
    if (!NT_SUCCESS(status))
    {
        SeDeleteAccessState(&accessState);
        return status;
    }
    
    tokenObject = PsReferencePrimaryToken(processObject);
    ObDereferenceObject(processObject);
    
    status = ObOpenObjectByPointer(
        tokenObject,
        ObjectAttributes,
        &accessState,
        0,
        *SeTokenObjectType,
        AccessMode,
        &tokenHandle
        );
    SeDeleteAccessState(&accessState);
    ObDereferenceObject(tokenObject);
    
    if (NT_SUCCESS(status))
        *TokenHandle = tokenHandle;
    
    return status;
}
Exemple #2
0
NTSTATUS
	IrpCreateFile(
	IN PUNICODE_STRING FileName,
	IN ACCESS_MASK DesiredAccess,
	__out PIO_STATUS_BLOCK IoStatusBlock,
	IN ULONG FileAttributes,
	IN ULONG ShareAccess,
	IN ULONG CreateDisposition,
	IN ULONG CreateOptions,
	IN PDEVICE_OBJECT DeviceObject,
	IN PDEVICE_OBJECT RealDevice,
	OUT PFILE_OBJECT *Object
	)
{
	NTSTATUS status;
	KEVENT event;
	PIRP irp;
	PIO_STACK_LOCATION irpSp;
	IO_SECURITY_CONTEXT securityContext;
	ACCESS_STATE accessState;
	OBJECT_ATTRIBUTES objectAttributes;
	PFILE_OBJECT fileObject;
	AUX_ACCESS_DATA auxData;

	PAGED_CODE();

	RtlZeroMemory(&auxData, sizeof(AUX_ACCESS_DATA));
	
	InitializeObjectAttributes(&objectAttributes, NULL, OBJ_CASE_INSENSITIVE| OBJ_KERNEL_HANDLE, 0, NULL);

	status = ObCreateObject(KernelMode,
		*IoFileObjectType,
		&objectAttributes,
		KernelMode,
		NULL,
		sizeof(FILE_OBJECT),
		0,
		0,
		(PVOID *)&fileObject);

	if (!NT_SUCCESS(status)) {
		return status;
	}

	RtlZeroMemory(fileObject, sizeof(FILE_OBJECT));
	fileObject->Type = IO_TYPE_FILE;
	fileObject->Size = sizeof(FILE_OBJECT);
	fileObject->DeviceObject = RealDevice;
	//	fileObject->RelatedFileObject = NULL;
	fileObject->Flags = FO_SYNCHRONOUS_IO;
	fileObject->FileName.MaximumLength = FileName->MaximumLength;
	fileObject->FileName.Buffer = (PWCH)ExAllocatePoolWithTag(NonPagedPool, FileName->MaximumLength, 'File');
	//fileObject->FileObjectExtension
	if (fileObject->FileName.Buffer == NULL) {
		ObDereferenceObject(fileObject);
		return STATUS_INSUFFICIENT_RESOURCES;
	}

	RtlCopyUnicodeString(&fileObject->FileName, FileName);
	KeInitializeEvent(&fileObject->Lock, SynchronizationEvent, FALSE);
	KeInitializeEvent(&fileObject->Event, NotificationEvent, FALSE);

	irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
	
	if (irp == NULL) {
		ObDereferenceObject(fileObject);
		return STATUS_INSUFFICIENT_RESOURCES;
	}
	KeInitializeEvent(&event, SynchronizationEvent, FALSE);

	irp->MdlAddress = NULL;
	irp->Flags |= IRP_CREATE_OPERATION | IRP_SYNCHRONOUS_API;
	irp->RequestorMode = KernelMode;
	irp->UserIosb = IoStatusBlock;
	////LCXL:CHANGE
	irp->UserEvent = &event;
	//irp->UserEvent = NULL;
	irp->PendingReturned = FALSE;
	irp->Cancel = FALSE;
	irp->CancelRoutine = NULL;
	irp->Tail.Overlay.Thread = (PETHREAD)KeGetCurrentThread();
	irp->Tail.Overlay.AuxiliaryBuffer = NULL;
	irp->Tail.Overlay.OriginalFileObject = fileObject;

	status = SeCreateAccessState(&accessState,
		&auxData,
		DesiredAccess,
		IoGetFileObjectGenericMapping());

	if (!NT_SUCCESS(status)) {
		IoFreeIrp(irp);
		ExFreePool(fileObject->FileName.Buffer);
		ObDereferenceObject(fileObject);
		return status;
	}

	securityContext.SecurityQos = NULL;
	securityContext.AccessState = &accessState;
	securityContext.DesiredAccess = DesiredAccess;
	securityContext.FullCreateOptions = 0;

	irpSp = IoGetNextIrpStackLocation(irp);
	irpSp->MajorFunction = IRP_MJ_CREATE;
	irpSp->DeviceObject = DeviceObject;
	irpSp->FileObject = fileObject;
	irpSp->Parameters.Create.SecurityContext = &securityContext;
	irpSp->Parameters.Create.Options = (CreateDisposition << 24) | CreateOptions;
	irpSp->Parameters.Create.FileAttributes = (USHORT)FileAttributes;
	irpSp->Parameters.Create.ShareAccess = (USHORT)ShareAccess;
	irpSp->Parameters.Create.EaLength = 0;

	IoSetCompletionRoutine(irp, IoCompletionRoutine, NULL, TRUE, TRUE, TRUE);
	status = IoCallDriver(DeviceObject, irp);

	if (status == STATUS_PENDING) {
		KeWaitForSingleObject(&event, Executive, KernelMode, TRUE, NULL);
	}

	status = IoStatusBlock->Status;

	if (!NT_SUCCESS(status)) {
		ExFreePool(fileObject->FileName.Buffer);
		fileObject->FileName.Length = 0;
		fileObject->DeviceObject = NULL;
		ObDereferenceObject(fileObject);
	} else {
		InterlockedIncrement(&fileObject->DeviceObject->ReferenceCount);
		if (fileObject->Vpb) {
			InterlockedIncrement((PLONG)&fileObject->Vpb->ReferenceCount);
		}
		*Object = fileObject;
		KdPrint(("IrpCreateFile:Open file success! object = %x\n", fileObject));
	}

	return status;
}
Exemple #3
0
NTSTATUS
IrpCreateFile(
			  IN PUNICODE_STRING FilePath,
			  IN ACCESS_MASK DesiredAccess,
			  IN ULONG FileAttributes,
			  IN ULONG ShareAccess,
			  IN ULONG CreateDisposition,
			  IN ULONG CreateOptions,
			  IN PDEVICE_OBJECT DeviceObject,
			  IN PDEVICE_OBJECT RealDevice,
			  OUT PFILE_OBJECT *FileObject
			  )
// 			  OUT PFILE_OBJECT *FileObject,
// 			  IN ACCESS_MASK DesiredAccess,
// 			  IN PUNICODE_STRING FilePath,
// 			  OUT PIO_STATUS_BLOCK IoStatusBlock,
// 			  IN PLARGE_INTEGER AllocationSize OPTIONAL,
// 			  IN ULONG FileAttributes,
// 			  IN ULONG ShareAccess,
// 			  IN ULONG CreateDisposition,
// 			  IN ULONG CreateOptions,
// 			  IN PVOID EaBuffer OPTIONAL,
// 			  IN ULONG EaLength)
{
	NTSTATUS ntStatus;

	HANDLE hFile;
	PFILE_OBJECT  _FileObject;
	UNICODE_STRING UniDeviceNameString;
	OBJECT_ATTRIBUTES ObjectAttributes;
	IO_STATUS_BLOCK IoStatusBlock;
	WCHAR *FileNameBuffer=NULL;
	WORD FileObjectSize;
	WIN_VER_DETAIL WinVer;

	PIRP Irp;
	KEVENT kEvent;
	PIO_STACK_LOCATION IrpSp;
	ACCESS_STATE AccessState;
	AUX_ACCESS_DATA AuxData;
	IO_SECURITY_CONTEXT SecurityContext;

	InitializeObjectAttributes(&ObjectAttributes, NULL, OBJ_CASE_INSENSITIVE, 0, NULL);
	WinVer=GetWindowsVersion();
	if (WinVer==WINDOWS_VERSION_2K||
		WinVer==WINDOWS_VERSION_XP||
		WinVer==WINDOWS_VERSION_2K3||
		WinVer==WINDOWS_VERSION_2K3_SP1_SP2)
	{
		FileObjectSize=0x70;
	}
	else if (WinVer==WINDOWS_VERSION_VISTA_2008||WinVer==WINDOWS_VERSION_7_7000||WinVer==WINDOWS_VERSION_7_7600_UP)
	{
		FileObjectSize=0x80;
	}
	else
	{
		return STATUS_UNSUCCESSFUL;
	}

	ntStatus = ObCreateObject(KernelMode,
		*IoFileObjectType,
		&ObjectAttributes,
		KernelMode,
		NULL,
		FileObjectSize,
		0,
		0,
		&_FileObject);

	if(!NT_SUCCESS(ntStatus))
	{
		if (DebugOn)
			KdPrint(("[PsVoid] IrpCreateFile: ObCreateObject 0x%X.\n",ntStatus));
		return ntStatus;
	}

	Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
	if(Irp == NULL)
	{
		if (DebugOn)
			KdPrint(("[PsVoid] IrpCreateFile: IoAllocateIrp 0x%X.\n",ntStatus));
		ObDereferenceObject(_FileObject);
		return STATUS_INSUFFICIENT_RESOURCES;
	}

	KeInitializeEvent(&kEvent, SynchronizationEvent, FALSE);

	RtlZeroMemory(_FileObject, FileObjectSize);
	_FileObject->Type = IO_TYPE_FILE;
	_FileObject->Size = FileObjectSize;
	_FileObject->DeviceObject = RealDevice;
	_FileObject->Flags = FO_SYNCHRONOUS_IO;
	FileNameBuffer=ExAllocatePool(NonPagedPool,FilePath->MaximumLength);
	if (FileNameBuffer==NULL)
	{
		ObDereferenceObject(_FileObject);
		return STATUS_INSUFFICIENT_RESOURCES;
	}
	RtlCopyMemory(FileNameBuffer,FilePath->Buffer,FilePath->Length);
    _FileObject->FileName.Buffer=FileNameBuffer;
	_FileObject->FileName.Length=FilePath->Length;
	_FileObject->FileName.MaximumLength=FilePath->MaximumLength;
	if (WinVer==WINDOWS_VERSION_VISTA_2008||WinVer==WINDOWS_VERSION_7_7000||WinVer==WINDOWS_VERSION_7_7600_UP)
	{
		PLIST_ENTRY IrpList;
		IrpList=(PLIST_ENTRY)((DWORD)FileObject+0x74);
		IrpList->Flink=IrpList;
		IrpList->Blink=IrpList;
	}

	KeInitializeEvent(&_FileObject->Lock, SynchronizationEvent, FALSE);
	KeInitializeEvent(&_FileObject->Event, NotificationEvent, FALSE);

	RtlZeroMemory(&AuxData, sizeof(AUX_ACCESS_DATA));
	ntStatus = SeCreateAccessState( &AccessState,
		&AuxData,
		DesiredAccess,
		IoGetFileObjectGenericMapping());

	if (!NT_SUCCESS(ntStatus))
	{
		if (DebugOn)
			KdPrint(("[PsVoid] IrpCreateFile: SeCreateAccessState 0x%X.\n",ntStatus));
		IoFreeIrp(Irp);
		ObDereferenceObject(_FileObject);
		ExFreePool(FileNameBuffer);
		return ntStatus;
	}

	SecurityContext.SecurityQos = NULL;
	SecurityContext.AccessState = &AccessState;
	SecurityContext.DesiredAccess = DesiredAccess;
	SecurityContext.FullCreateOptions = 0;

	Irp->MdlAddress = NULL;
	Irp->AssociatedIrp.SystemBuffer = NULL;
	Irp->Flags = IRP_CREATE_OPERATION|IRP_SYNCHRONOUS_API;
	Irp->RequestorMode = KernelMode;
	Irp->UserIosb = &IoStatusBlock;
	Irp->UserEvent = &kEvent;
	Irp->PendingReturned = FALSE;
	Irp->Cancel = FALSE;
	Irp->CancelRoutine = NULL;
	Irp->Tail.Overlay.Thread = PsGetCurrentThread();
	Irp->Tail.Overlay.AuxiliaryBuffer = NULL;
	Irp->Tail.Overlay.OriginalFileObject = _FileObject;

	IrpSp = IoGetNextIrpStackLocation(Irp);
	IrpSp->MajorFunction = IRP_MJ_CREATE;
	IrpSp->DeviceObject = DeviceObject;
	IrpSp->FileObject = _FileObject;
	IrpSp->Parameters.Create.SecurityContext = &SecurityContext;
	IrpSp->Parameters.Create.Options = (CreateDisposition << 24) | CreateOptions;
	IrpSp->Parameters.Create.FileAttributes = (USHORT)FileAttributes;
	IrpSp->Parameters.Create.ShareAccess = (USHORT)ShareAccess;
	IrpSp->Parameters.Create.EaLength = 0;

	IoSetCompletionRoutine(Irp, IoCompletionRoutine, 0, TRUE, TRUE, TRUE);
	ntStatus = IoCallDriver(DeviceObject, Irp);
	if(ntStatus == STATUS_PENDING)
		KeWaitForSingleObject(&kEvent, Executive, KernelMode, TRUE, 0);

	ntStatus = IoStatusBlock.Status;

	if(!NT_SUCCESS(ntStatus))
	{
		if (DebugOn)
			KdPrint(("[PsVoid] IrpCreateFile: IoCallDriver 0x%X.\n",ntStatus));
		_FileObject->DeviceObject = NULL;
		ObDereferenceObject(_FileObject);

	}
	else
	{
		InterlockedIncrement(&_FileObject->DeviceObject->ReferenceCount);
		if (_FileObject->Vpb)
			InterlockedIncrement(&_FileObject->Vpb->ReferenceCount);
		*FileObject = _FileObject;
	}


	return ntStatus;
}
Exemple #4
0
NTSTATUS
ObInsertObject (
    __in PVOID Object,
    __in_opt PACCESS_STATE AccessState,
    __in_opt ACCESS_MASK DesiredAccess,
    __in ULONG ObjectPointerBias,
    __out_opt PVOID *NewObject,
    __out_opt PHANDLE Handle
    )

/*++

Routine Description:

    This routine inserts an object into the current processes handle table.

    The Object header includes a pointer to a SecurityDescriptor passed in
    an object creation call.  This SecurityDescriptor is not assumed to have
    been captured.  This routine is responsible for making an appropriate
    SecurityDescriptor and removing the reference in the object header.

Arguments:

    Object - Supplies a pointer to the new object body

    AccessState - Optionally supplies the access state for the new
        handle

    DesiredAccess - Optionally supplies the desired access we want for the
        new handle

    ObjectPointerBias - Supplies a bias to apply for the pointer count for the
        object

    NewObject - Optionally receives the pointer to the new object that we've
        created a handle for

    Handle - Receives the new handle, If NULL then no handle is created.
             Objects that don't have handles created must be unnamed and
             have an object bias of zero.

Return Value:

    An appropriate NTSTATUS value.

--*/

{
    POBJECT_CREATE_INFORMATION ObjectCreateInfo;
    POBJECT_HEADER ObjectHeader;
    PUNICODE_STRING ObjectName;
    POBJECT_TYPE ObjectType;
    POBJECT_HEADER_NAME_INFO NameInfo;
    PSECURITY_DESCRIPTOR ParentDescriptor = NULL;
    PVOID InsertObject;
    HANDLE NewHandle;
    OB_OPEN_REASON OpenReason;
    NTSTATUS Status = STATUS_SUCCESS;
    ACCESS_STATE LocalAccessState;
    AUX_ACCESS_DATA AuxData;
    BOOLEAN SecurityDescriptorAllocated;
    KPROCESSOR_MODE PreviousMode;
    NTSTATUS ReturnStatus;
    PVOID DirObject = NULL;
    OBP_LOOKUP_CONTEXT LookupContext;

    PAGED_CODE();

    ObpValidateIrql("ObInsertObject");

    //
    //  Get the address of the object header, the object create information,
    //  the object type, and the address of the object name descriptor, if
    //  specified.
    //

    ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object);

#if DBG

    if ((ObjectHeader->Flags & OB_FLAG_NEW_OBJECT) == 0) {

        KdPrint(("OB: Attempting to insert existing object %08x\n", Object));
        KdBreakPoint();

        ObDereferenceObject(Object);

        return STATUS_INVALID_PARAMETER;
    }

#endif

    ObjectCreateInfo = ObjectHeader->ObjectCreateInfo;

    ObjectType = ObjectHeader->Type;

    NameInfo = ObpReferenceNameInfo( ObjectHeader );

    ObjectName = NULL;

    if ((NameInfo != NULL) && (NameInfo->Name.Buffer != NULL)) {

        ObjectName = &NameInfo->Name;
    }

    ASSERT (ARGUMENT_PRESENT (Handle) || (ObjectPointerBias == 0 && ObjectName == NULL &&
                                          ObjectType->TypeInfo.SecurityRequired && NewObject == NULL));

    //
    //  If security checks are not required and an object name is not
    //  specified, insert an unnamed object, biasing the count
    //  by one, dereference the bias, and return to our caller
    //

    PreviousMode = KeGetPreviousMode();

    if (!ObjectType->TypeInfo.SecurityRequired && (ObjectName == NULL)) {

        ObjectHeader->ObjectCreateInfo = NULL;

        *Handle = NULL;

        Status = ObpCreateUnnamedHandle( Object,
                                         DesiredAccess,
                                         1 + ObjectPointerBias,
                                         ObjectCreateInfo->Attributes,
                                         PreviousMode,
                                         NewObject,
                                         Handle );
        //
        //  Free the object creation information and dereference the object.
        //

        ObpFreeObjectCreateInformation(ObjectCreateInfo);

        ObpDereferenceNameInfo( NameInfo );
        ObDereferenceObject(Object);

        return Status;
    }

    //
    //  The object is either named or requires full security checks.  If the
    //  caller hasn't specified an access state then dummy up a local one
    //  using the requested desired access
    //

    if (!ARGUMENT_PRESENT(AccessState)) {

        AccessState = &LocalAccessState;

        Status = SeCreateAccessState( &LocalAccessState,
                                      &AuxData,
                                      DesiredAccess,
                                      &ObjectType->TypeInfo.GenericMapping );

        if (!NT_SUCCESS(Status)) {

            ObpDereferenceNameInfo( NameInfo );
            ObDereferenceObject(Object);

            return Status;
        }
    }

    AccessState->SecurityDescriptor = ObjectCreateInfo->SecurityDescriptor;

    //
    //  Check the desired access mask against the security descriptor
    //

    Status = ObpValidateAccessMask( AccessState );

    if (!NT_SUCCESS( Status )) {

        if (AccessState == &LocalAccessState) {

            SeDeleteAccessState( AccessState );
        }

        ObpDereferenceNameInfo( NameInfo );
        ObDereferenceObject(Object);

        if (AccessState == &LocalAccessState) {

            SeDeleteAccessState( AccessState );
        }

        return( Status );
    }

    //
    //  Set some local state variables
    //

    ObpInitializeLookupContext(&LookupContext);

    InsertObject = Object;
    OpenReason = ObCreateHandle;

    //
    //  Check if we have an object name.  If so then
    //  lookup the name
    //

    if (ObjectName != NULL) {

        Status = ObpLookupObjectName( ObjectCreateInfo->RootDirectory,
                                      ObjectName,
                                      ObjectCreateInfo->Attributes,
                                      ObjectType,
                                      (KPROCESSOR_MODE)(ObjectHeader->Flags & OB_FLAG_KERNEL_OBJECT
                                                            ? KernelMode : UserMode),
                                      ObjectCreateInfo->ParseContext,
                                      ObjectCreateInfo->SecurityQos,
                                      Object,
                                      AccessState,
                                      &LookupContext,
                                      &InsertObject );

        //
        //  We found the name and it is not the object we have as our input.
        //  So we cannot insert the object again so we'll return an
        //  appropriate status
        //

        if (NT_SUCCESS(Status) &&
            (InsertObject != NULL) &&
            (InsertObject != Object)) {

            OpenReason = ObOpenHandle;

            if (ObjectCreateInfo->Attributes & OBJ_OPENIF) {

                if (ObjectType != OBJECT_TO_OBJECT_HEADER(InsertObject)->Type) {

                    Status = STATUS_OBJECT_TYPE_MISMATCH;

                } else {

                    Status = STATUS_OBJECT_NAME_EXISTS;     // Warning only
                }

            } else {

                if (OBJECT_TO_OBJECT_HEADER(InsertObject)->Type == ObpSymbolicLinkObjectType) {

                     ObDereferenceObject(InsertObject);
                }
                
                Status = STATUS_OBJECT_NAME_COLLISION;
            }
        }

        //
        //  We did not find the name so we'll cleanup after ourselves
        //  and return to our caller
        //

        if (!NT_SUCCESS( Status )) {

            ObpReleaseLookupContext( &LookupContext );

            ObpDereferenceNameInfo( NameInfo );
            ObDereferenceObject( Object );

            //
            //  Free security information if we allocated it
            //

            if (AccessState == &LocalAccessState) {

                SeDeleteAccessState( AccessState );
            }

            return( Status );

        } else {

            //
            //  Otherwise we did locate the object name
            //
            //  If we just created a named symbolic link then call out to
            //  handle any Dos Device name semantics.
            //

            if (ObjectType == ObpSymbolicLinkObjectType) {

                ObpCreateSymbolicLinkName( (POBJECT_SYMBOLIC_LINK)InsertObject );
            }
        }
    }

    //
    //  If we are creating a new object, then we need assign security
    //  to it.  A pointer to the captured caller-proposed security
    //  descriptor is contained in the AccessState structure.  The
    //  SecurityDescriptor field in the object header must point to
    //  the final security descriptor, or to NULL if no security is
    //  to be assigned to the object.
    //

    if (InsertObject == Object) {

        //
        //  Only the following objects have security descriptors:
        //
        //       - Named Objects
        //       - Unnamed objects whose object-type information explicitly
        //         indicates a security descriptor is required.
        //

        if ((ObjectName != NULL) || ObjectType->TypeInfo.SecurityRequired) {

            //
            //  Get the parent's descriptor, if there is one...
            //

            if ((NameInfo != NULL) && (NameInfo->Directory != NULL)) {

                //
                //  This will allocate a block of memory and copy
                //  the parent's security descriptor into it, and
                //  return the pointer to the block.
                //
                //  Call ObReleaseObjectSecurity to free up this
                //  memory.
                //

                ObGetObjectSecurity( NameInfo->Directory,
                                     &ParentDescriptor,
                                     &SecurityDescriptorAllocated );
            }
            else {
                SecurityDescriptorAllocated = FALSE;
            }

            //
            //  Take the captured security descriptor in the AccessState,
            //  put it into the proper format, and call the object's
            //  security method to assign the new security descriptor to
            //  the new object.
            //

            Status = ObAssignSecurity( AccessState,
                                       ParentDescriptor,
                                       Object,
                                       ObjectType );

            if (ParentDescriptor != NULL) {

                ObReleaseObjectSecurity( ParentDescriptor,
                                         SecurityDescriptorAllocated );

            } else if (NT_SUCCESS( Status )) {

                SeReleaseSecurityDescriptor( ObjectCreateInfo->SecurityDescriptor,
                                             ObjectCreateInfo->ProbeMode,
                                             TRUE );

                ObjectCreateInfo->SecurityDescriptor = NULL;
                AccessState->SecurityDescriptor = NULL;
            }
        }

        if (!NT_SUCCESS( Status )) {

            //
            //  The attempt to assign the security descriptor to
            //  the object failed.
            //
            
            if (LookupContext.DirectoryLocked) {
                
                //
                //  If ObpLookupObjectName already inserted the 
                //  object into the directory we have to backup this
                //

                //
                //  Capture the object Directory 
                //

                DirObject = NameInfo->Directory;

                ObpDeleteDirectoryEntry( &LookupContext ); 
            }

            ObpReleaseLookupContext( &LookupContext );

            //
            //  If ObpLookupObjectName inserted the object into the directory
            //  it added a reference to the object and to its directory
            //  object. We should remove the extra-references
            //

            if (DirObject) {

                ObDereferenceObject( Object );
                ObDereferenceObject( DirObject );
            }

            //
            //  The first backout logic used ObpDeleteNameCheck
            //  which is wrong because the security descriptor for
            //  the object is not initialized. Actually  ObpDeleteNameCheck
            //  had no effect because the object was removed before from 
            //  the directory
            //

            ObpDereferenceNameInfo( NameInfo );
            ObDereferenceObject( Object );

            //
            //  Free security information if we allocated it
            //

            if (AccessState == &LocalAccessState) {

                SeDeleteAccessState( AccessState );
            }

            return( Status );
        }
    }

    ReturnStatus = Status;

    ObjectHeader->ObjectCreateInfo = NULL;

    //
    //  Create a named handle for the object with a pointer bias
    //  This call also will unlock the directory lock is necessary
    //  on return
    //

    if (ARGUMENT_PRESENT (Handle)) {

        Status = ObpCreateHandle( OpenReason,
                                  InsertObject,
                                  NULL,
                                  AccessState,
                                  1 + ObjectPointerBias,
                                  ObjectCreateInfo->Attributes,
                                  &LookupContext,
                                  PreviousMode,
                                  NewObject,
                                  &NewHandle );

        //
        //  If the insertion failed, the following dereference will cause
        //  the newly created object to be deallocated.
        //

        if (!NT_SUCCESS( Status )) {

            //
            //  Make the name reference go away if an error.
            //

            if (ObjectName != NULL) {

                ObpDeleteNameCheck( Object );
            }

            *Handle = NULL;

            ReturnStatus = Status;

        } else {
            *Handle = NewHandle;
        }

        ObpDereferenceNameInfo( NameInfo );

        ObDereferenceObject( Object );


    } else {

        BOOLEAN IsNewObject;

        //
        //  Charge the user quota for the object.
        //

        ObpLockObject( ObjectHeader );

        ReturnStatus = ObpChargeQuotaForObject( ObjectHeader, ObjectType, &IsNewObject );

        ObpUnlockObject( ObjectHeader );

        if (!NT_SUCCESS (ReturnStatus)) {
            ObDereferenceObject( Object );
        }

        //
        //  N.B. An object cannot be named if no Handle parameter is specified.
        //  The calls to ObpDereferenceNameInfo and ObpReleaseLookupContext are 
        //  not necessary in this path then.
        //
    }

    ObpFreeObjectCreateInformation( ObjectCreateInfo );

    //
    //  Free security information if we allocated it
    //

    if (AccessState == &LocalAccessState) {

        SeDeleteAccessState( AccessState );
    }

    return( ReturnStatus );
}