Esempio n. 1
0
VOID
NTAPI
PspCheckProcessList()
{
    PLIST_ENTRY Entry;

    KeAcquireGuardedMutex(&PspActiveProcessMutex);
    DbgPrint("# checking PsActiveProcessHead @ %p\n", &PsActiveProcessHead);
    for (Entry = PsActiveProcessHead.Flink;
         Entry != &PsActiveProcessHead;
         Entry = Entry->Flink)
    {
        PEPROCESS Process = CONTAINING_RECORD(Entry, EPROCESS, ActiveProcessLinks);
        POBJECT_HEADER Header;
        PVOID Info, HeaderLocation;

        /* Get the header and assume this is what we'll free */
        Header = OBJECT_TO_OBJECT_HEADER(Process);
        HeaderLocation = Header;

        /* To find the header, walk backwards from how we allocated */
        if ((Info = OBJECT_HEADER_TO_CREATOR_INFO(Header)))
        {
            HeaderLocation = Info;
        }
        if ((Info = OBJECT_HEADER_TO_NAME_INFO(Header)))
        {
            HeaderLocation = Info;
        }
        if ((Info = OBJECT_HEADER_TO_HANDLE_INFO(Header)))
        {
            HeaderLocation = Info;
        }
        if ((Info = OBJECT_HEADER_TO_QUOTA_INFO(Header)))
        {
            HeaderLocation = Info;
        }

        ExpCheckPoolAllocation(HeaderLocation, NonPagedPool, 'corP');
    }

    KeReleaseGuardedMutex(&PspActiveProcessMutex);
}
Esempio n. 2
0
VOID
FASTCALL
ObpFreeObject (
    IN PVOID Object
    )

/*++

Routine Description:

    This routine undoes ObpAllocateObject.  It returns the object back to free pool.

Arguments:

    Object - Supplies a pointer to the body of the object being freed.

Return Value:

    None.

--*/

{
    POBJECT_HEADER ObjectHeader;
    POBJECT_TYPE ObjectType;
    POBJECT_HEADER_QUOTA_INFO QuotaInfo;
    POBJECT_HEADER_HANDLE_INFO HandleInfo;
    POBJECT_HEADER_NAME_INFO NameInfo;
    POBJECT_HEADER_CREATOR_INFO CreatorInfo;
    PVOID FreeBuffer;
    ULONG NonPagedPoolCharge;
    ULONG PagedPoolCharge;

    PAGED_CODE();

    //
    //  Get the address of the object header.
    //

    ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object);
    ObjectType = ObjectHeader->Type;

    //
    //  Now from the header determine the start of the allocation.  We need
    //  to backup based on what precedes the header.  The order is very
    //  important and must be the inverse of that used by ObpAllocateObject
    //

    FreeBuffer = ObjectHeader;

    CreatorInfo = OBJECT_HEADER_TO_CREATOR_INFO( ObjectHeader );

    if (CreatorInfo != NULL) {

        FreeBuffer = CreatorInfo;
    }

    NameInfo = OBJECT_HEADER_TO_NAME_INFO( ObjectHeader );

    if (NameInfo != NULL) {

        FreeBuffer = NameInfo;
    }

    HandleInfo = OBJECT_HEADER_TO_HANDLE_INFO( ObjectHeader );

    if (HandleInfo != NULL) {

        FreeBuffer = HandleInfo;
    }

    QuotaInfo = OBJECT_HEADER_TO_QUOTA_INFO( ObjectHeader );

    if (QuotaInfo != NULL) {

        FreeBuffer = QuotaInfo;
    }

#if DBG

    //
    //  On a checked build echo out frees
    //

    if (ObpShowAllocAndFree) {

        DbgPrint( "OB: Free  %lx (%lx) - Type: %wZ\n", ObjectHeader, ObjectHeader, &ObjectType->Name );
    }
#endif

    //
    //  Decrement the number of objects of this type
    //

    InterlockedDecrement((PLONG)&ObjectType->TotalNumberOfObjects);

    //
    //  Check where we were in the object initialization phase.  This
    //  flag really only tests if we have charged quota for this object.
    //  This is because the object create info and the quota block charged
    //  are unioned together.
    //

    if (ObjectHeader->Flags & OB_FLAG_NEW_OBJECT) {

        if (ObjectHeader->ObjectCreateInfo != NULL) {

            ObpFreeObjectCreateInformation( ObjectHeader->ObjectCreateInfo );

            ObjectHeader->ObjectCreateInfo = NULL;
        }

    } else {

        if (ObjectHeader->QuotaBlockCharged != NULL) {

            if (QuotaInfo != NULL) {

                PagedPoolCharge = QuotaInfo->PagedPoolCharge +
                                  QuotaInfo->SecurityDescriptorCharge;

                NonPagedPoolCharge = QuotaInfo->NonPagedPoolCharge;

            } else {

                PagedPoolCharge = ObjectType->TypeInfo.DefaultPagedPoolCharge;

                if (ObjectHeader->Flags & OB_FLAG_DEFAULT_SECURITY_QUOTA ) {

                    PagedPoolCharge += SE_DEFAULT_SECURITY_QUOTA;
                }

                NonPagedPoolCharge = ObjectType->TypeInfo.DefaultNonPagedPoolCharge;
            }

            PsReturnSharedPoolQuota( ObjectHeader->QuotaBlockCharged,
                                     PagedPoolCharge,
                                     NonPagedPoolCharge );

            ObjectHeader->QuotaBlockCharged = NULL;
        }
    }

    if ((HandleInfo != NULL) &&
        ((ObjectHeader->Flags & OB_FLAG_SINGLE_HANDLE_ENTRY) == 0)) {

        //
        //  If a handle database has been allocated, then free the memory.
        //

        ExFreePool( HandleInfo->HandleCountDataBase );

        HandleInfo->HandleCountDataBase = NULL;
    }

    //
    //  If a name string buffer has been allocated, then free the memory.
    //

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

        ExFreePool( NameInfo->Name.Buffer );

        NameInfo->Name.Buffer = NULL;
    }

    PERFINFO_REMOVE_OBJECT_FROM_ALLOCATED_TYPE_LIST(CreatorInfo, ObjectHeader);

    //
    //  Trash type field so we don't get far if we attempt to
    //  use a stale object pointer to this object.
    //
    //  Win64 Note: trash it by zero-extended it. 
    //                sign-extension will create a valid kernel address.


    ObjectHeader->Type = UIntToPtr(0xBAD0B0B0); 
    ExFreePoolWithTag( FreeBuffer,
                       (ObjectType == NULL ? 'TjbO' : ObjectType->Key) |
                            PROTECTED_POOL );

    return;
}
Esempio n. 3
0
BOOLEAN
INIT_FUNCTION
NTAPI
ObInitSystem(VOID)
{
    OBJECT_ATTRIBUTES ObjectAttributes;
    UNICODE_STRING Name;
    OBJECT_TYPE_INITIALIZER ObjectTypeInitializer;
    OBP_LOOKUP_CONTEXT Context;
    HANDLE Handle;
    PKPRCB Prcb = KeGetCurrentPrcb();
    PLIST_ENTRY ListHead, NextEntry;
    POBJECT_HEADER Header;
    POBJECT_HEADER_CREATOR_INFO CreatorInfo;
    POBJECT_HEADER_NAME_INFO NameInfo;
    NTSTATUS Status;

    /* Check if this is actually Phase 1 initialization */
    if (ObpInitializationPhase != 0) goto ObPostPhase0;

    /* Initialize the OBJECT_CREATE_INFORMATION List */
    ExInitializeSystemLookasideList(&ObpCreateInfoLookasideList,
                                    NonPagedPool,
                                    sizeof(OBJECT_CREATE_INFORMATION),
                                    'ICbO',
                                    32,
                                    &ExSystemLookasideListHead);

    /* Set the captured UNICODE_STRING Object Name List */
    ExInitializeSystemLookasideList(&ObpNameBufferLookasideList,
                                    PagedPool,
                                    248,
                                    'MNbO',
                                    16,
                                    &ExSystemLookasideListHead);

    /* Temporarily setup both pointers to the shared list */
    Prcb->PPLookasideList[LookasideCreateInfoList].L = &ObpCreateInfoLookasideList;
    Prcb->PPLookasideList[LookasideCreateInfoList].P = &ObpCreateInfoLookasideList;
    Prcb->PPLookasideList[LookasideNameBufferList].L = &ObpNameBufferLookasideList;
    Prcb->PPLookasideList[LookasideNameBufferList].P = &ObpNameBufferLookasideList;

    /* Initialize the security descriptor cache */
    ObpInitSdCache();

    /* Initialize the Default Event */
    KeInitializeEvent(&ObpDefaultObject, NotificationEvent, TRUE);

    /* Initialize the Dos Device Map mutex */
    KeInitializeGuardedMutex(&ObpDeviceMapLock);

    /* Setup default access for the system process */
    PsGetCurrentProcess()->GrantedAccess = PROCESS_ALL_ACCESS;
    PsGetCurrentThread()->GrantedAccess = THREAD_ALL_ACCESS;

    /* Setup the Object Reaper */
    ExInitializeWorkItem(&ObpReaperWorkItem, ObpReapObject, NULL);

    /* Initialize default Quota block */
    PsInitializeQuotaSystem();

    /* Create kernel handle table */
    PsGetCurrentProcess()->ObjectTable = ExCreateHandleTable(NULL);
    ObpKernelHandleTable = PsGetCurrentProcess()->ObjectTable;

    /* Create the Type Type */
    RtlZeroMemory(&ObjectTypeInitializer, sizeof(ObjectTypeInitializer));
    RtlInitUnicodeString(&Name, L"Type");
    ObjectTypeInitializer.Length = sizeof(ObjectTypeInitializer);
    ObjectTypeInitializer.ValidAccessMask = OBJECT_TYPE_ALL_ACCESS;
    ObjectTypeInitializer.UseDefaultObject = TRUE;
    ObjectTypeInitializer.MaintainTypeList = TRUE;
    ObjectTypeInitializer.PoolType = NonPagedPool;
    ObjectTypeInitializer.GenericMapping = ObpTypeMapping;
    ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(OBJECT_TYPE);
    ObjectTypeInitializer.InvalidAttributes = OBJ_OPENLINK;
    ObjectTypeInitializer.DeleteProcedure = ObpDeleteObjectType;
    ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &ObpTypeObjectType);

    /* Create the Directory Type */
    RtlInitUnicodeString(&Name, L"Directory");
    ObjectTypeInitializer.ValidAccessMask = DIRECTORY_ALL_ACCESS;
    ObjectTypeInitializer.CaseInsensitive = TRUE;
    ObjectTypeInitializer.MaintainTypeList = FALSE;
    ObjectTypeInitializer.GenericMapping = ObpDirectoryMapping;
    ObjectTypeInitializer.DeleteProcedure = NULL;
    ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(OBJECT_DIRECTORY);
    ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &ObDirectoryType);

    /* Create 'symbolic link' object type */
    RtlInitUnicodeString(&Name, L"SymbolicLink");
    ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof(OBJECT_SYMBOLIC_LINK);
    ObjectTypeInitializer.GenericMapping = ObpSymbolicLinkMapping;
    ObjectTypeInitializer.ValidAccessMask = SYMBOLIC_LINK_ALL_ACCESS;
    ObjectTypeInitializer.ParseProcedure = ObpParseSymbolicLink;
    ObjectTypeInitializer.DeleteProcedure = ObpDeleteSymbolicLink;
    ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &ObSymbolicLinkType);

    /* Phase 0 initialization complete */
    ObpInitializationPhase++;
    return TRUE;

ObPostPhase0:

    /* Re-initialize lookaside lists */
    ObInit2();

    /* Initialize Object Types directory attributes */
    RtlInitUnicodeString(&Name, L"\\");
    InitializeObjectAttributes(&ObjectAttributes,
                               &Name,
                               OBJ_CASE_INSENSITIVE | OBJ_PERMANENT,
                               NULL,
                               SePublicDefaultUnrestrictedSd);

    /* Create the directory */
    Status = NtCreateDirectoryObject(&Handle,
                                     DIRECTORY_ALL_ACCESS,
                                     &ObjectAttributes);
    if (!NT_SUCCESS(Status)) return FALSE;

    /* Get a handle to it */
    Status = ObReferenceObjectByHandle(Handle,
                                       0,
                                       ObDirectoryType,
                                       KernelMode,
                                       (PVOID*)&ObpRootDirectoryObject,
                                       NULL);
    if (!NT_SUCCESS(Status)) return FALSE;

    /* Close the extra handle */
    Status = NtClose(Handle);
    if (!NT_SUCCESS(Status)) return FALSE;

    /* Initialize Object Types directory attributes */
    RtlInitUnicodeString(&Name, L"\\KernelObjects");
    InitializeObjectAttributes(&ObjectAttributes,
                               &Name,
                               OBJ_CASE_INSENSITIVE | OBJ_PERMANENT,
                               NULL,
                               NULL);
    
    /* Create the directory */
    Status = NtCreateDirectoryObject(&Handle,
                                     DIRECTORY_ALL_ACCESS,
                                     &ObjectAttributes);
    if (!NT_SUCCESS(Status)) return FALSE;
    
    /* Close the extra handle */
    Status = NtClose(Handle);
    if (!NT_SUCCESS(Status)) return FALSE;

    /* Initialize Object Types directory attributes */
    RtlInitUnicodeString(&Name, L"\\ObjectTypes");
    InitializeObjectAttributes(&ObjectAttributes,
                               &Name,
                               OBJ_CASE_INSENSITIVE | OBJ_PERMANENT,
                               NULL,
                               NULL);

    /* Create the directory */
    Status = NtCreateDirectoryObject(&Handle,
                                     DIRECTORY_ALL_ACCESS,
                                     &ObjectAttributes);
    if (!NT_SUCCESS(Status)) return FALSE;

    /* Get a handle to it */
    Status = ObReferenceObjectByHandle(Handle,
                                       0,
                                       ObDirectoryType,
                                       KernelMode,
                                       (PVOID*)&ObpTypeDirectoryObject,
                                       NULL);
    if (!NT_SUCCESS(Status)) return FALSE;

    /* Close the extra handle */
    Status = NtClose(Handle);
    if (!NT_SUCCESS(Status)) return FALSE;

    /* Initialize lookup context */
    ObpInitializeLookupContext(&Context);

    /* Lock it */
    ObpAcquireDirectoryLockExclusive(ObpTypeDirectoryObject, &Context);

    /* Loop the object types */
    ListHead = &ObpTypeObjectType->TypeList;
    NextEntry = ListHead->Flink;
    while (ListHead != NextEntry)
    {
        /* Get the creator info from the list */
        CreatorInfo = CONTAINING_RECORD(NextEntry,
                                        OBJECT_HEADER_CREATOR_INFO,
                                        TypeList);

        /* Recover the header and the name header from the creator info */
        Header = (POBJECT_HEADER)(CreatorInfo + 1);
        NameInfo = OBJECT_HEADER_TO_NAME_INFO(Header);

        /* Make sure we have a name, and aren't inserted yet */
        if ((NameInfo) && !(NameInfo->Directory))
        {
            /* Do the initial lookup to setup the context */
            if (!ObpLookupEntryDirectory(ObpTypeDirectoryObject,
                                         &NameInfo->Name,
                                         OBJ_CASE_INSENSITIVE,
                                         FALSE,
                                         &Context))
            {
                /* Insert this object type */
                ObpInsertEntryDirectory(ObpTypeDirectoryObject,
                                        &Context,
                                        Header);
            }
        }

        /* Move to the next entry */
        NextEntry = NextEntry->Flink;
    }

    /* Cleanup after lookup */
    ObpReleaseLookupContext(&Context);

    /* Initialize DOS Devices Directory and related Symbolic Links */
    Status = ObpCreateDosDevicesDirectory();
    if (!NT_SUCCESS(Status)) return FALSE;
    return TRUE;
}
Esempio n. 4
0
BOOLEAN
ObInitSystem(
    VOID
    )

/*++

Routine Description:

    This function performs the system initialization for the object
    manager.  The object manager data structures are self describing
    with the exception of the root directory, the type object type and
    the directory object type.  The initialization code then constructs
    these objects by hand to get the ball rolling.

Arguments:

    None.

Return Value:

    TRUE if successful and FALSE if an error occurred.

    The following errors can occur:

    - insufficient memory

--*/

{

    USHORT CreateInfoMaxDepth;
    USHORT NameBufferMaxDepth;
    ULONG RegionSegmentSize;
    OBJECT_TYPE_INITIALIZER ObjectTypeInitializer;
    UNICODE_STRING TypeTypeName;
    UNICODE_STRING SymbolicLinkTypeName;
    UNICODE_STRING DosDevicesDirectoryName;
    UNICODE_STRING DirectoryTypeName;
    UNICODE_STRING RootDirectoryName;
    UNICODE_STRING TypeDirectoryName;
    NTSTATUS Status;
    OBJECT_ATTRIBUTES ObjectAttributes;
    HANDLE RootDirectoryHandle;
    HANDLE TypeDirectoryHandle;
    PLIST_ENTRY Next, Head;
    POBJECT_HEADER ObjectTypeHeader;
    POBJECT_HEADER_CREATOR_INFO CreatorInfo;
    POBJECT_HEADER_NAME_INFO NameInfo;
    MM_SYSTEMSIZE SystemSize;
    SECURITY_DESCRIPTOR AuditSd;
    PSECURITY_DESCRIPTOR EffectiveSd;
    PACL    AuditAllAcl;
    UCHAR   AuditAllBuffer[250];  // Ample room for the ACL
    ULONG   AuditAllLength;
    PACE_HEADER Ace;

    //
    // PHASE 0 Initialization
    //

    if (InitializationPhase == 0) {

        //
        // Determine the the size of the object creation and the name buffer
        // lookaside lists.
        //

        SystemSize = MmQuerySystemSize();
        if (SystemSize == MmLargeSystem) {
            if (MmIsThisAnNtAsSystem()) {
                CreateInfoMaxDepth = 64;
                NameBufferMaxDepth = 32;

            } else {
                CreateInfoMaxDepth = 32;
                NameBufferMaxDepth = 16;
            }

        } else {
            CreateInfoMaxDepth = 3;
            NameBufferMaxDepth = 3;
        }

        //
        // Initialize the object creation lookaside list.
        //

        ExInitializeNPagedLookasideList(&ObpCreateInfoLookasideList,
                                        NULL,
                                        NULL,
                                        0,
                                        sizeof(OBJECT_CREATE_INFORMATION),
                                        'iCbO',
                                        CreateInfoMaxDepth);

        //
        // Initialize the name buffer lookaside list.
        //

        ExInitializeNPagedLookasideList(&ObpNameBufferLookasideList,
                                        NULL,
                                        NULL,
                                        0,
                                        OBJECT_NAME_BUFFER_SIZE,
                                        'mNbO',
                                        NameBufferMaxDepth);

        InitializeListHead( &ObpRemoveObjectQueue );

        //
        // Initialize security descriptor cache
        //

        ObpInitSecurityDescriptorCache();

        KeInitializeMutant( &ObpInitKillMutant, FALSE );
        KeInitializeEvent( &ObpDefaultObject, NotificationEvent, TRUE );
        KeInitializeSpinLock( &ObpLock );
        PsGetCurrentProcess()->GrantedAccess = PROCESS_ALL_ACCESS;
        PsGetCurrentThread()->GrantedAccess = THREAD_ALL_ACCESS;

        //
        // Initialize the quota block
        //

        KeInitializeSpinLock(&PspDefaultQuotaBlock.QuotaLock);
        PspDefaultQuotaBlock.ReferenceCount = 1;
        PspDefaultQuotaBlock.QuotaPoolLimit[PagedPool] = (ULONG)-1;
        PspDefaultQuotaBlock.QuotaPoolLimit[NonPagedPool] = (ULONG)-1;
        PspDefaultQuotaBlock.PagefileLimit = (ULONG)-1;

        PsGetCurrentProcess()->QuotaBlock = &PspDefaultQuotaBlock;

        PsGetCurrentProcess()->ObjectTable =
            ExCreateHandleTable( NULL,
                                 0,
                                 0
                               );

        RtlZeroMemory( &ObjectTypeInitializer, sizeof( ObjectTypeInitializer ) );
        ObjectTypeInitializer.Length = sizeof( ObjectTypeInitializer );
        ObjectTypeInitializer.InvalidAttributes = OBJ_OPENLINK;
        ObjectTypeInitializer.PoolType = NonPagedPool;

        RtlInitUnicodeString( &TypeTypeName, L"Type" );
        ObjectTypeInitializer.ValidAccessMask = OBJECT_TYPE_ALL_ACCESS;
        ObjectTypeInitializer.GenericMapping = ObpTypeMapping;
        ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof( OBJECT_TYPE );
        ObjectTypeInitializer.MaintainTypeList = TRUE;
        ObjectTypeInitializer.UseDefaultObject = TRUE;
        ObCreateObjectType( &TypeTypeName,
                            &ObjectTypeInitializer,
                            (PSECURITY_DESCRIPTOR)NULL,
                            &ObpTypeObjectType
                          );

        RtlInitUnicodeString( &DirectoryTypeName, L"Directory" );
        ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof( OBJECT_DIRECTORY );
        ObjectTypeInitializer.ValidAccessMask = DIRECTORY_ALL_ACCESS;
        ObjectTypeInitializer.GenericMapping = ObpDirectoryMapping;
        ObjectTypeInitializer.MaintainTypeList = FALSE;
        ObCreateObjectType( &DirectoryTypeName,
                            &ObjectTypeInitializer,
                            (PSECURITY_DESCRIPTOR)NULL,
                            &ObpDirectoryObjectType
                          );

        RtlInitUnicodeString( &SymbolicLinkTypeName, L"SymbolicLink" );
        ObjectTypeInitializer.DefaultNonPagedPoolCharge = sizeof( OBJECT_SYMBOLIC_LINK );
        ObjectTypeInitializer.ValidAccessMask = SYMBOLIC_LINK_ALL_ACCESS;
        ObjectTypeInitializer.GenericMapping = ObpSymbolicLinkMapping;
        ObjectTypeInitializer.DeleteProcedure = ObpDeleteSymbolicLink;
        ObjectTypeInitializer.ParseProcedure = ObpParseSymbolicLink;
        ObCreateObjectType( &SymbolicLinkTypeName,
                            &ObjectTypeInitializer,
                            (PSECURITY_DESCRIPTOR)NULL,
                            &ObpSymbolicLinkObjectType
                          );

        ExInitializeResourceLite( &ObpRootDirectoryMutex );

#if i386 && !FPO
        ObpCurCachedGrantedAccessIndex = 0;
        ObpMaxCachedGrantedAccessIndex = PAGE_SIZE / sizeof( ACCESS_MASK );
        ObpCachedGrantedAccesses = ExAllocatePoolWithTag( NonPagedPool, PAGE_SIZE, 'gAbO' );
#endif // i386 && !FPO

#if DBG
        ObpCreateObjectEventId = RtlCreateEventId( NULL,
                                                   0,
                                                   "CreateObject",
                                                   6,
                                                   RTL_EVENT_ULONG_PARAM, "Object", 0,
                                                   RTL_EVENT_PUNICODE_STRING_PARAM, "Type", 0,
                                                   RTL_EVENT_ULONG_PARAM, "PagedPool", 0,
                                                   RTL_EVENT_ULONG_PARAM, "NonPagedPool", 0,
                                                   RTL_EVENT_PUNICODE_STRING_PARAM, "Name", 0,
                                                   RTL_EVENT_FLAGS_PARAM, "", 5,
                                                     OBJ_INHERIT, "Inherit",
                                                     OBJ_PERMANENT, "Permanent",
                                                     OBJ_OPENIF, "OpenIf",
                                                     OBJ_CASE_INSENSITIVE, "CaseInsenitive",
                                                     OBJ_EXCLUSIVE, "Exclusive"
                                                 );
        ObpFreeObjectEventId = RtlCreateEventId( NULL,
                                                 0,
                                                 "FreeObject",
                                                 3,
                                                 RTL_EVENT_ULONG_PARAM, "Object", 0,
                                                 RTL_EVENT_ULONG_PARAM, "Type", 0,
                                                 RTL_EVENT_PUNICODE_STRING_PARAM, "Name", 0
                                               );
#endif // DBG

        }             // End of Phase 0 Initializtion


    //
    // PHASE 1 Initialization
    //

    if (InitializationPhase == 1) {


        EffectiveSd = SePublicDefaultSd;

        //
        // This code is only executed if base auditing is turned on.
        //

        if ((ObpAuditBaseDirectories != 0) || (ObpAuditBaseObjects != 0)) {

            //
            // build an SACL to audit
            //
            AuditAllAcl = (PACL)AuditAllBuffer;
            AuditAllLength = (ULONG)sizeof(ACL) +
                               ((ULONG)sizeof(SYSTEM_AUDIT_ACE)) +
                               SeLengthSid(SeWorldSid);
            ASSERT( sizeof(AuditAllBuffer)   >   AuditAllLength );
            Status = RtlCreateAcl( AuditAllAcl, AuditAllLength, ACL_REVISION2);
            ASSERT( NT_SUCCESS(Status) );
            Status = RtlAddAuditAccessAce (
                         AuditAllAcl,
                         ACL_REVISION2,
                         GENERIC_ALL,
                         SeWorldSid,
                         TRUE,  TRUE        //Audit success and failure
                         );
            ASSERT( NT_SUCCESS(Status) );

            Status = RtlGetAce( AuditAllAcl, 0,  (PVOID)&Ace );
            ASSERT( NT_SUCCESS(Status) );

            if (ObpAuditBaseDirectories != 0) {
                Ace->AceFlags |= (CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE);
                }

            if (ObpAuditBaseObjects != 0) {
                Ace->AceFlags |= (OBJECT_INHERIT_ACE    |
                                  CONTAINER_INHERIT_ACE |
                                  INHERIT_ONLY_ACE);
                }



            //
            // Now create a security descriptor that looks just like
            // the public default, but has auditing in it as well.

            EffectiveSd = (PSECURITY_DESCRIPTOR)&AuditSd;
            Status = RtlCreateSecurityDescriptor( EffectiveSd,
                                                  SECURITY_DESCRIPTOR_REVISION1 );
            ASSERT( NT_SUCCESS(Status) );

            Status = RtlSetDaclSecurityDescriptor( EffectiveSd,
                                                   TRUE,        // DaclPresent
                                                   SePublicDefaultDacl,
                                                   FALSE        // DaclDefaulted
                                                   );
            ASSERT( NT_SUCCESS(Status) );
            Status = RtlSetSaclSecurityDescriptor( EffectiveSd,
                                                   TRUE,        // DaclPresent
                                                   AuditAllAcl,
                                                   FALSE        // DaclDefaulted
                                                   );
            ASSERT( NT_SUCCESS(Status) );
            }


        //
        // We only need to use the EffectiveSd on the root.  The SACL
        // will be inherited by all other objects.
        //

        RtlInitUnicodeString( &RootDirectoryName, L"\\" );
        InitializeObjectAttributes( &ObjectAttributes,
                                    &RootDirectoryName,
                                    OBJ_CASE_INSENSITIVE |
                                    OBJ_PERMANENT,
                                    NULL,
                                    EffectiveSd
                                  );
        Status = NtCreateDirectoryObject( &RootDirectoryHandle,
                                          DIRECTORY_ALL_ACCESS,
                                          &ObjectAttributes
                                        );
        if (!NT_SUCCESS( Status )) {
            return( FALSE );
            }

        Status = ObReferenceObjectByHandle( RootDirectoryHandle,
                                            0,
                                            ObpDirectoryObjectType,
                                            KernelMode,
                                            (PVOID *)&ObpRootDirectoryObject,
                                            NULL
                                          );
        if (!NT_SUCCESS( Status )) {
            return( FALSE );
            }

        Status = NtClose( RootDirectoryHandle );
        if (!NT_SUCCESS( Status )) {
            return( FALSE );
            }

        RtlInitUnicodeString( &TypeDirectoryName, L"\\ObjectTypes" );
        InitializeObjectAttributes( &ObjectAttributes,
                                    &TypeDirectoryName,
                                    OBJ_CASE_INSENSITIVE |
                                    OBJ_PERMANENT,
                                    NULL,
                                    NULL
                                  );
        Status = NtCreateDirectoryObject( &TypeDirectoryHandle,
                                          DIRECTORY_ALL_ACCESS,
                                          &ObjectAttributes
                                        );
        if (!NT_SUCCESS( Status )) {
            return( FALSE );
            }

        Status = ObReferenceObjectByHandle( TypeDirectoryHandle,
                                            0,
                                            ObpDirectoryObjectType,
                                            KernelMode,
                                            (PVOID *)&ObpTypeDirectoryObject,
                                            NULL
                                          );
        if (!NT_SUCCESS( Status )) {
            return( FALSE );
            }

        Status = NtClose( TypeDirectoryHandle );
        if (!NT_SUCCESS( Status )) {
            return( FALSE );
            }

        ObpEnterRootDirectoryMutex();

        Head = &ObpTypeObjectType->TypeList;
        Next = Head->Flink;
        while (Next != Head) {
            CreatorInfo = CONTAINING_RECORD( Next,
                                             OBJECT_HEADER_CREATOR_INFO,
                                             TypeList
                                           );
            ObjectTypeHeader = (POBJECT_HEADER)(CreatorInfo+1);
            NameInfo = OBJECT_HEADER_TO_NAME_INFO( ObjectTypeHeader );
            if (NameInfo != NULL && NameInfo->Directory == NULL) {
                if (!ObpLookupDirectoryEntry( ObpTypeDirectoryObject,
                                              &NameInfo->Name,
                                              OBJ_CASE_INSENSITIVE
                                            )
                   ) {
                    ObpInsertDirectoryEntry( ObpTypeDirectoryObject,
                                             &ObjectTypeHeader->Body
                                           );
                    }
                }

            Next = Next->Flink;
            }

        ObpLeaveRootDirectoryMutex();

        //
        // Create \DosDevices object directory for drive letters and Win32 device names
        //
        Status = ObpCreateDosDevicesDirectory();
        if (!NT_SUCCESS( Status )) {
            return FALSE;
            }
        }

    return TRUE;
}
Esempio n. 5
0
VOID
ObpHandleDosDeviceName(
    POBJECT_SYMBOLIC_LINK SymbolicLink
    )

/*++

Routine Description:

    This routine does extra processing symbolic links being created in the \??
    object directory.  This processing consists of:

    1.  Determine if the name of the symbolic link is of the form \??\x:
        where x can be any upper or lower case letter.  If this is the
        case then we need to set the bit in KUSER_SHARED_DATA.DosDeviceMap
        to indicate that the drive letter exists.  We also set
        KUSER_SHARED_DATA.DosDeviceDriveType to unknown for now.

    2.  Process the link target, trying to resolve it into a pointer to
        an object other than a object directory object.  All object directories
        traversed must grant world traverse access other wise we bail out.
        If we successfully find a non object directory object, then reference
        the object pointer and store it in the symbolic link object, along
        with a remaining string if any.  ObpLookupObjectName will used this
        cache object pointer to short circuit the name lookup directly to
        the cached object's parse routine.  For any object directory objects
        traversed along the way, increment their symbolic link SymbolicLinkUsageCount
        field.  This field is used whenever an object directory is deleted or
        its security is changed such that it no longer grants world traverse
        access.  In either case, if the field is non-zero we walk all the symbolic links
        and resnap them.

Arguments:

    SymbolicLink - pointer to symbolic link object being created.

    Name - pointer to the name of this symbolic link

Return Value:

    None.

--*/

{
    POBJECT_HEADER ObjectHeader;
    POBJECT_HEADER_NAME_INFO NameInfo;
    WCHAR DosDeviceDriveLetter;
    ULONG DosDeviceDriveIndex;

    //
    // Now see if this symbolic link is being created in the \?? object directory
    // Since we are only called from NtCreateSymbolicLinkObject, after the handle
    // to this symbolic link has been created but before it is returned to the caller
    // the handle can't be closed while we are executing, unless via a random close
    // So no need to hold the type specific mutex while we look at the name.
    //
    ObjectHeader = OBJECT_TO_OBJECT_HEADER( SymbolicLink );
    NameInfo = OBJECT_HEADER_TO_NAME_INFO( ObjectHeader );
    if (NameInfo == NULL || NameInfo->Directory != ObpDosDevicesDirectoryObject) {
        return;
        }

    //
    // Here if we are creating a symbolic link in the \?? object directory
    // See if this is a drive letter definition.  If so set the bit in
    // KUSER_SHARED_DATA.DosDeviceMap
    //
    DosDeviceDriveIndex = 0;
    if (NameInfo->Name.Length == 2 * sizeof( WCHAR ) &&
        NameInfo->Name.Buffer[ 1 ] == L':'
       ) {
        DosDeviceDriveLetter = RtlUpcaseUnicodeChar( NameInfo->Name.Buffer[ 0 ] );
        if (DosDeviceDriveLetter >= L'A' && DosDeviceDriveLetter <= L'Z') {
            DosDeviceDriveIndex = DosDeviceDriveLetter - L'A';
            DosDeviceDriveIndex += 1;
            SymbolicLink->DosDeviceDriveIndex = DosDeviceDriveIndex;
            }
        }

    //
    // Now traverse the target path seeing if we can snap the link now.
    //

    ObpEnterRootDirectoryMutex();
    ObpEnterObjectTypeMutex( ObpSymbolicLinkObjectType );

    ObpProcessDosDeviceSymbolicLink( SymbolicLink, CREATE_SYMBOLIC_LINK );

    ObpLeaveRootDirectoryMutex();
    ObpLeaveObjectTypeMutex( ObpSymbolicLinkObjectType );
    return;
}