ntos_ob.c

来自「winNT技术操作系统,国外开放的原代码和LIUX一样」· C语言 代码 · 共 525 行 · 第 1/2 页

C
525
字号
        "Failed to create object with status=0x%lX", Status);

    // save counters
    OpenSave=OpenCount; CloseSave=CloseCount; DeleteSave=DeleteCount;
    ParseSave=ParseCount; OkayToCloseSave=OkayToCloseCount;
    QueryNameSave=QueryNameCount;

    // Insert them
    Status = ObInsertObject(ObBody[0], NULL, STANDARD_RIGHTS_ALL, 0,
        &ObBody[0], &ObHandle1[0]);
    ok(Status == STATUS_SUCCESS,
        "Failed to insert object 0 with status=0x%lX", Status);
    ok(ObBody[0] != NULL, "Object body = NULL");
    ok(ObHandle1[0] != NULL, "Handle = NULL");

    // check counters
    ok(OpenSave+1 == OpenCount, "Open method calls mismatch\n");
    ok(CloseSave == CloseCount, "Excessive Close method call\n");
    ok(DeleteSave == DeleteCount, "Excessive Delete method call\n");
    ok(ParseSave == ParseCount, "Excessive Parse method call\n");

    // save counters
    OpenSave=OpenCount; CloseSave=CloseCount; DeleteSave=DeleteCount;
    ParseSave=ParseCount; OkayToCloseSave=OkayToCloseCount;
    QueryNameSave=QueryNameCount;

    Status = ObInsertObject(ObBody[1], NULL, GENERIC_ALL, 0,
        &ObBody[1], &ObHandle1[1]); 
    ok(Status == STATUS_SUCCESS,
        "Failed to insert object 1 with status=0x%lX", Status);
    ok(ObBody[1] != NULL, "Object body = NULL");
    ok(ObHandle1[1] != NULL, "Handle = NULL");

    // check counters
    ok(OpenSave+1 == OpenCount, "Open method calls mismatch\n");
    ok(CloseSave == CloseCount, "Excessive Close method call\n");
    ok(DeleteSave == DeleteCount, "Excessive Delete method call\n");
    ok(ParseSave == ParseCount, "Excessive Parse method call\n");

    // save counters
    OpenSave=OpenCount; CloseSave=CloseCount; DeleteSave=DeleteCount;
    ParseSave=ParseCount; OkayToCloseSave=OkayToCloseCount;
    QueryNameSave=QueryNameCount;

    // Now create an object of type 0, of the same name and expect it to fail
    // inserting, but success creation
    RtlInitUnicodeString(&ObName[0], L"\\ObtDirectory\\MyObject1");
    InitializeObjectAttributes(&ObAttributes[0], &ObName[0], OBJ_OPENIF,
        NULL, NULL);

    Status = ObCreateObject(KernelMode, ObTypes[0], &ObAttributes[0], KernelMode,
        NULL, (ULONG)sizeof(MY_OBJECT1), 0L, 0L, (PVOID *)&ObBody1[0]);
    ok(Status == STATUS_SUCCESS,
        "Failed to create object with status=0x%lX", Status);

    // check counters
    ok(OpenSave == OpenCount, "Excessive Open method call\n");
    ok(CloseSave == CloseCount, "Excessive Close method call\n");
    ok(DeleteSave == DeleteCount, "Excessive Delete method call\n");
    ok(ParseSave == ParseCount, "Excessive Parse method call\n");

    Status = ObInsertObject(ObBody1[0], NULL, GENERIC_ALL, 0,
        &ObBody1[1], &ObHandle2[0]);
    ok(Status == STATUS_OBJECT_NAME_EXISTS,
        "Object insertion should have failed, but got 0x%lX", Status);
    ok(ObBody[0] == ObBody1[1],
        "Object bodies doesn't match, 0x%p != 0x%p", ObBody[0], ObBody1[1]);
    ok(ObHandle2[0] != NULL, "Bad handle returned 0x%lX", (ULONG)ObHandle2[0]);

    DPRINT1("%d %d %d %d %d %d %d\n", DumpCount, OpenCount, // deletecount+1
        CloseCount, DeleteCount, ParseCount, OkayToCloseCount, QueryNameCount);

    // check counters and then save
    ok(OpenSave+1 == OpenCount, "Excessive Open method call\n");
    ok(CloseSave == CloseCount, "Excessive Close method call\n");
    ok(DeleteSave+1 == DeleteCount, "Delete method call mismatch\n");
    ok(ParseSave == ParseCount, "Excessive Parse method call\n");
    OpenSave=OpenCount; CloseSave=CloseCount; DeleteSave=DeleteCount;
    ParseSave=ParseCount; OkayToCloseSave=OkayToCloseCount;
    QueryNameSave=QueryNameCount;

    // Close its handle
    Status = ZwClose(ObHandle2[0]);
    ok(Status == STATUS_SUCCESS,
        "Failed to close handle status=0x%lX", Status);

    // check counters and then save
    ok(OpenSave == OpenCount, "Excessive Open method call\n");
    ok(CloseSave+1 == CloseCount, "Close method call mismatch\n");
    ok(DeleteSave == DeleteCount, "Excessive Delete method call\n");
    ok(ParseSave == ParseCount, "Excessive Parse method call\n");
    OpenSave=OpenCount; CloseSave=CloseCount; DeleteSave=DeleteCount;
    ParseSave=ParseCount; OkayToCloseSave=OkayToCloseCount;
    QueryNameSave=QueryNameCount;


    // Object referenced 2 times:
    // 1) ObInsertObject
    // 2) AdditionalReferences
    ObDereferenceObject(ObBody1[1]);

    //DPRINT1("%d %d %d %d %d %d %d\n", DumpCount, OpenCount, // no change
    //    CloseCount, DeleteCount, ParseCount, OkayToCloseCount, QueryNameCount);
    ok(OpenSave == OpenCount, "Open method call mismatch\n");
    ok(CloseSave == CloseCount, "Close method call mismatch\n");
    ok(DeleteSave == DeleteCount, "Delete method call mismatch\n");
    ok(ParseSave == ParseCount, "Parse method call mismatch\n");
}

VOID
ObtClose()
{
    PVOID DirObject;
    NTSTATUS Status;
    //PVOID TypeObject;
    USHORT i;
    //UNICODE_STRING ObPathName[NUM_OBTYPES];

    // Close what we have opened and free what we allocated
    ZwClose(ObHandle1[0]);
    ZwClose(ObHandle1[1]);
    ZwClose(ObHandle2[0]);
    ZwClose(ObHandle2[1]);

    // Now we have to get rid of a directory object
    // Since it is permanent, we have to firstly make it temporary
    // and only then kill
    // (this procedure is described in DDK)
    Status = ObReferenceObjectByHandle(DirectoryHandle, 0L, NULL,
        KernelMode, &DirObject, NULL);
    ok(Status == STATUS_SUCCESS,
        "Failed to reference object by handle with status=0x%lX", Status);

    // Dereference 2 times - first for just previous referencing
    // and 2nd time for creation of permanent object itself
    ObDereferenceObject(DirObject);
    ObDereferenceObject(DirObject);

    Status = ZwMakeTemporaryObject(DirectoryHandle);
    ok(Status == STATUS_SUCCESS,
        "Failed to make temp object with status=0x%lX", Status);

    // Close the handle now and we are done
    Status = ZwClose(DirectoryHandle);
    ok(Status == STATUS_SUCCESS,
        "Failed to close handle with status=0x%lX", Status);

    // Now delete the last piece - object types
    // In fact, it's weird to get rid of object types, especially the way,
    // how it's done in the commented section below
    for (i=0; i<NUM_OBTYPES; i++)
        ObDereferenceObject(ObTypes[i]);
/*
    RtlInitUnicodeString(&ObPathName[0], L"\\ObjectTypes\\MyObjectType1");
    RtlInitUnicodeString(&ObPathName[1], L"\\ObjectTypes\\MyObjectType2");

    for (i=0; i<NUM_OBTYPES; i++)
    {
        Status = ObReferenceObjectByName(&ObPathName[i],
            OBJ_CASE_INSENSITIVE, NULL, 0L, NULL, KernelMode, NULL,
            &TypeObject);

        ObDereferenceObject(TypeObject);
        ObDereferenceObject(TypeObject);
        DPRINT("Reference Name %S = %p, ObTypes[%d] = %p\n",
            ObPathName[i], TypeObject, i, ObTypes[i]);
    }
*/
}

VOID
ObtReferenceTests()
{
    USHORT i;
    NTSTATUS Status;
    UNICODE_STRING ObPathName[NUM_OBTYPES];

    // Reference them by handle
    for (i=0; i<NUM_OBTYPES; i++)
    {
        Status = ObReferenceObjectByHandle(ObHandle1[i], 0L, ObTypes[i],
            KernelMode, &ObBody[i], NULL);
        ok(Status == STATUS_SUCCESS,
            "Failed to reference object by handle, status=0x%lX", Status);
        DPRINT("Ref by handle %lx = %p\n", ObHandle1[i], ObBody[i]);
    }

    // Reference them by pointer
    for (i=0; i<NUM_OBTYPES; i++)
    {
        Status = ObReferenceObjectByPointer(ObBody[i], 0L, ObTypes[i], KernelMode);
        ok(Status == STATUS_SUCCESS,
            "Failed to reference object by pointer, status=0x%lX", Status);
    }

    // Reference them by name
    RtlInitUnicodeString(&ObPathName[0], L"\\ObtDirectory\\MyObject1");
    RtlInitUnicodeString(&ObPathName[1], L"\\ObtDirectory\\MyObject2");

    for (i=0; i<NUM_OBTYPES; i++)
    {
        Status = ObReferenceObjectByName(&ObPathName[i],
            OBJ_CASE_INSENSITIVE, NULL, 0L, ObTypes[i], KernelMode, NULL,
            &ObBody[0]);

        DPRINT("Ref by name %wZ = %p\n", &ObPathName[i], ObBody[i]);
    }

    // Dereference now all of them

    // For ObInsertObject, AdditionalReference
    ObDereferenceObject(ObBody[0]);
    ObDereferenceObject(ObBody[1]);

    // For ByHandle
    ObDereferenceObject(ObBody[0]);
    ObDereferenceObject(ObBody[1]);

    // For ByPointer
    ObDereferenceObject(ObBody[0]);
    ObDereferenceObject(ObBody[1]);

    // For ByName
    ObDereferenceObject(ObBody[0]);
    ObDereferenceObject(ObBody[1]);
}

/* PUBLIC FUNCTIONS ***********************************************************/

VOID
FASTCALL
NtoskrnlObTest()
{
    StartTest();

    DumpCount = 0; OpenCount = 0; CloseCount = 0;
    DeleteCount = 0; ParseCount = 0;

    // Create object-types to use in tests
    ObtCreateObjectTypes();
    DPRINT("ObtCreateObjectTypes() done\n");

    // Create Directory
    ObtCreateDirectory();
    DPRINT("ObtCreateDirectory() done\n");

    // Create and insert objects
    ObtCreateObjects();
    DPRINT("ObtCreateObjects() done\n");

    // Reference them in a variety of ways
    //ObtReferenceTests();

    // Clean up
    // FIXME: Disable to see results of creating objects in usermode.
    //        Also it has problems with object types removal
    ObtClose();
    DPRINT("Cleanup done\n");

    FinishTest("NTOSKRNL Ob Manager");
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?