atom.c

来自「一个类似windows」· C语言 代码 · 共 417 行 · 第 1/2 页

C
417
字号

    if (!res)
    {
        res = pRtlLookupAtomInAtomTable(AtomTable, testAtom1, &testAtom);
        ok(res == STATUS_OBJECT_NAME_NOT_FOUND, "Didn't get expected retval with querying an empty atom table, retval: %lx\n", res);

        res = pRtlAddAtomToAtomTable(AtomTable, testAtom1, &Atom1);
        ok(!res, "Unable to add atom to atom table, retval %lx\n", res);

        res = pRtlLookupAtomInAtomTable(AtomTable, testAtom1, &testAtom);
        ok(!res, "Can't find previously added atom in table, retval: %lx\n", res);
        ok(testAtom == Atom1, "Found wrong atom! retval: %lx\n", res);

        res = pRtlDeleteAtomFromAtomTable(AtomTable, Atom1);
        ok(!res, "Unable to delete atom from table, retval: %lx\n", res);

        res = pRtlLookupAtomInAtomTable(AtomTable, testAtom1, &testAtom);
        ok(res == STATUS_OBJECT_NAME_NOT_FOUND, "Able to find previously deleted atom in table, retval: %lx\n", res);

        res = pRtlAddAtomToAtomTable(AtomTable, testAtom1, &Atom1);
        ok(!res, "Unable to add atom to atom table, retval: %lx\n", res);

        Len = 0;
        res = pRtlQueryAtomInAtomTable(AtomTable, Atom1, NULL, NULL, Name, &Len);
        ok(res == STATUS_BUFFER_TOO_SMALL, "Got wrong retval, retval: %lx\n", res);
        ok((strlenW(testAtom1) * sizeof(WCHAR)) == Len, "Got wrong length %lx\n", Len);

        res = pRtlQueryAtomInAtomTable(AtomTable, Atom1, NULL, NULL, NULL, &Len);
        ok(!res, "Failed to retrieve atom length, retval: %lx\n", res);
        ok(Len == strlenW(testAtom1) * sizeof(WCHAR), "Invalid atom length got %lu expected %u\n",
           Len, strlenW(testAtom1) * sizeof(WCHAR));

        Len = strlenW(testAtom1) * sizeof(WCHAR);
        Name[strlenW(testAtom1)] = '*';
        res = pRtlQueryAtomInAtomTable(AtomTable, Atom1, NULL, NULL, Name, &Len);
        ok(!res, "Failed with exactly long enough buffer, retval: %lx\n", res);
        ok(Name[strlenW(testAtom1)] == '*', "Writing outside buffer\n");
        ok(0 == memcmp(Name, testAtom1, (strlenW(testAtom1) - 1) * sizeof(WCHAR)),
           "We found wrong atom!!\n");

        res = pRtlPinAtomInAtomTable(AtomTable, Atom1);
        ok(!res, "Unable to pin atom in atom table, retval: %lx\n", res);

        res = pRtlLookupAtomInAtomTable(AtomTable, testAtom1, &testAtom);
        ok(!res, "Unable to find atom in atom table, retval: %lx\n", res);
        ok(testAtom == Atom1, "Wrong atom found\n");

        res = pRtlDeleteAtomFromAtomTable(AtomTable, Atom1);
        ok(res == STATUS_WAS_LOCKED, "Unable to delete atom from table, retval: %lx\n", res);

        res = pRtlLookupAtomInAtomTable(AtomTable, testAtom1, &testAtom);
        ok(!res, "Able to find deleted atom in table\n");

        res = pRtlDestroyAtomTable(AtomTable);
        ok(!res, "Unable to destroy atom table\n");
    }
}

/* Test Adding integer atoms to atom table */
static void test_NtIntAtom(void)
{
    NTSTATUS res;
    RTL_ATOM_TABLE AtomTable;
    RTL_ATOM testAtom;
    ULONG RefCount = 0, PinCount = 0;
    int i;
    WCHAR Name[64];
    ULONG Len;

    AtomTable = NULL;
    res = pRtlCreateAtomTable(37, &AtomTable);
    ok(!res, "Unable to create atom table, %lx\n", res);

    if (!res)
    {
        /* According to the kernel32 functions, integer atoms are only allowd from
         * 0x0001 to 0xbfff and not 0xc000 to 0xffff, which is correct */
        res = pRtlAddAtomToAtomTable(AtomTable, (PWSTR)0, &testAtom);
        ok(res == STATUS_INVALID_PARAMETER, "Didn't get expected result from adding 0 int atom, retval: %lx\n", res);
        for (i = 1; i <= 0xbfff; i++)
        {
            res = pRtlAddAtomToAtomTable(AtomTable, (PWSTR)i, &testAtom);
            ok(!res, "Unable to add valid integer atom %i, retval: %lx\n", i, res);
        }

        for (i = 1; i <= 0xbfff; i++)
        {
            res = pRtlLookupAtomInAtomTable(AtomTable, (PWSTR)i, &testAtom);
            ok(!res, "Unable to find int atom %i, retval: %lx\n", i, res);
            if (!res)
            {
                res = pRtlPinAtomInAtomTable(AtomTable, testAtom);
                ok(!res, "Unable to pin int atom %i, retval: %lx\n", i, res);
            }
        }

        for (i = 0xc000; i <= 0xffff; i++)
        {
            res = pRtlAddAtomToAtomTable(AtomTable, (PWSTR)i, &testAtom);
            ok(res, "Able to illeageal integer atom %i, retval: %lx\n", i, res);
        }

        res = pRtlDestroyAtomTable(AtomTable);
        ok(!res, "Unable to destroy atom table, retval: %lx\n", res);
    }

    AtomTable = NULL;
    res = pRtlCreateAtomTable(37, &AtomTable);
    ok(!res, "Unable to create atom table, %lx\n", res);
    if (!res)
    {
        res = pRtlLookupAtomInAtomTable(AtomTable, (PWSTR)123, &testAtom);
        ok(!res, "Unable to query atom in atom table, retval: %lx\n", res);

        res = pRtlAddAtomToAtomTable(AtomTable, testAtomInt, &testAtom);
        ok(!res, "Unable to add int atom to table, retval: %lx\n", res);

        res = pRtlAddAtomToAtomTable(AtomTable, testAtomIntInv, &testAtom);
        ok(!res, "Unable to add int atom to table, retval: %lx\n", res);

        res = pRtlAddAtomToAtomTable(AtomTable, (PWSTR)123, &testAtom);
        ok(!res, "Unable to add int atom to table, retval: %lx\n", res);

        res = pRtlAddAtomToAtomTable(AtomTable, (PWSTR)123, &testAtom);
        ok(!res, "Unable to re-add int atom to table, retval: %lx\n", res);

        Len = 64;
        res = pRtlQueryAtomInAtomTable(AtomTable, testAtom, &RefCount, &PinCount, Name, &Len);
        ok(!res, "Unable to query atom in atom table, retval: %lx\n", res);
        ok(PinCount == 1, "Expected pincount 1 but got %lx\n", PinCount);
        ok(RefCount == 1, "Expected refcount 1 but got %lx\n", RefCount);
        ok(!strcmpW(testAtomOTT, Name), "Got wrong atom name\n");
        ok((strlenW(testAtomOTT) * sizeof(WCHAR)) == Len, "Got wrong len %ld\n", Len);

        res = pRtlPinAtomInAtomTable(AtomTable, testAtom);
        ok(!res, "Unable to pin int atom, retval: %lx\n", res);

        res = pRtlPinAtomInAtomTable(AtomTable, testAtom);
        ok(!res, "Unable to pin int atom, retval: %lx\n", res);

        res = pRtlQueryAtomInAtomTable(AtomTable, testAtom, &RefCount, &PinCount, NULL, NULL);
        ok(!res, "Unable to query atom in atom table, retval: %lx\n", res);
        ok(PinCount == 1, "Expected pincount 1 but got %lx\n", PinCount);
        ok(RefCount == 1, "Expected refcount 1 but got %lx\n", RefCount);

        res = pRtlDestroyAtomTable(AtomTable);
        ok(!res, "Unable to destroy atom table, retval: %lx\n", res);
    }
}

/* Tests to see how the pincount and refcount actually works */
static void test_NtRefPinAtom(void)
{
    RTL_ATOM_TABLE AtomTable;
    RTL_ATOM Atom;
    ULONG PinCount = 0, RefCount = 0;
    NTSTATUS res;

    AtomTable = NULL;
    res = pRtlCreateAtomTable(37, &AtomTable);
    ok(!res, "Unable to create atom table, %lx\n", res);

    if (!res)
    {
        res = pRtlAddAtomToAtomTable(AtomTable, testAtom1, &Atom);
        ok(!res, "Unable to add our atom to the atom table, retval: %lx\n", res);

        res = pRtlAddAtomToAtomTable(AtomTable, testAtom1, &Atom);
        ok(!res, "Unable to add our atom to the atom table, retval: %lx\n", res);

        res = pRtlAddAtomToAtomTable(AtomTable, testAtom1, &Atom);
        ok(!res, "Unable to add our atom to the atom table, retval: %lx\n", res);

        res = pRtlQueryAtomInAtomTable(AtomTable, Atom, &RefCount, &PinCount, NULL, NULL);
        ok(!res, "Unable to query atom in atom table, retval: %lx\n", res);
        ok(PinCount == 0, "Expected pincount 0 but got %lx\n", PinCount);
        ok(RefCount == 3, "Expected refcount 3 but got %lx\n", RefCount); 

        res = pRtlPinAtomInAtomTable(AtomTable, Atom);
        ok(!res, "Unable to pin atom in atom table, retval: %lx\n", res);

        res = pRtlPinAtomInAtomTable(AtomTable, Atom);
        ok(!res, "Unable to pin atom in atom table, retval: %lx\n", res);

        res = pRtlPinAtomInAtomTable(AtomTable, Atom);
        ok(!res, "Unable to pin atom in atom table, retval: %lx\n", res);

        res = pRtlQueryAtomInAtomTable(AtomTable, Atom, &RefCount, &PinCount, NULL, NULL);
        ok(!res, "Unable to query atom in atom table, retval: %lx\n", res);
        ok(PinCount == 1, "Expected pincount 1 but got %lx\n", PinCount);
        ok(RefCount == 3, "Expected refcount 3 but got %lx\n", RefCount);

        res = pRtlDestroyAtomTable(AtomTable);
        ok(!res, "Unable to destroy atom table, retval: %lx\n", res);
    }
}

START_TEST(atom)
{
    InitFunctionPtr();
    if (pRtlCreateAtomTable)
    {
        test_NtAtom();
        test_NtIntAtom();
        test_NtRefPinAtom();
    }
}

⌨️ 快捷键说明

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