⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 atom.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Unit test suite for Ntdll atom API functions
 *
 * Copyright 2003 Gyorgy 'Nog' Jeney
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 *
 * NOTES
 * We use function pointers here as there is no import library for NTDLL on
 * windows.
 */

#include <stdio.h>
#include <stdarg.h>

#include "ntstatus.h"
/* Define WIN32_NO_STATUS so MSVC does not give us duplicate macro 
 * definition errors when we get to winnt.h
 */
#define WIN32_NO_STATUS

#include "windef.h"
#include "winbase.h"
#include "winreg.h"
#include "winnls.h"
#include "wine/test.h"
#include "winternl.h"

#ifndef __WINE_WINTERNL_H
typedef unsigned short RTL_ATOM, *PRTL_ATOM;
typedef struct atom_table *RTL_ATOM_TABLE, **PRTL_ATOM_TABLE;
#endif

/* Function pointers for ntdll calls */
static HMODULE hntdll = 0;
static NTSTATUS (WINAPI *pRtlCreateAtomTable)(ULONG,PRTL_ATOM_TABLE);
static NTSTATUS (WINAPI *pRtlDestroyAtomTable)(RTL_ATOM_TABLE);
static NTSTATUS (WINAPI *pRtlEmptyAtomTable)(RTL_ATOM_TABLE,BOOLEAN);
static NTSTATUS (WINAPI *pRtlAddAtomToAtomTable)(RTL_ATOM_TABLE,PCWSTR,PRTL_ATOM);
static NTSTATUS (WINAPI *pRtlDeleteAtomFromAtomTable)(RTL_ATOM_TABLE,RTL_ATOM);
static NTSTATUS (WINAPI *pRtlLookupAtomInAtomTable)(RTL_ATOM_TABLE,PCWSTR,PRTL_ATOM);
static NTSTATUS (WINAPI *pRtlPinAtomInAtomTable)(RTL_ATOM_TABLE,RTL_ATOM);
static NTSTATUS (WINAPI *pRtlQueryAtomInAtomTable)(RTL_ATOM_TABLE,RTL_ATOM,PULONG,PULONG,PWSTR,PULONG);

static NTSTATUS (WINAPI* pNtAddAtom)(LPCWSTR,ULONG,RTL_ATOM*);
static NTSTATUS (WINAPI* pNtQueryInformationAtom)(RTL_ATOM,DWORD,void*,ULONG,PULONG);

static const WCHAR EmptyAtom[] = {0};
static const WCHAR testAtom1[] = {'H','e','l','l','o',' ','W','o','r','l','d',0};
static const WCHAR testAtom2[] = {'H','e','l','l','o',' ','W','o','r','l','d','2',0};
static const WCHAR testAtom3[] = {'H','e','l','l','o',' ','W','o','r','l','d','3',0};

static const WCHAR testAtom1Cap[] = {'H','E','L','L','O',' ','W','O','R','L','D',0};
static const WCHAR testAtom1Low[] = {'h','e','l','l','o',' ','w','o','r','l','d',0};

static const WCHAR testAtomInt[] = {'#','1','3','2',0};
static const WCHAR testAtomIntInv[] = {'#','2','3','4','z',0};
static const WCHAR testAtomOTT[] = {'#','1','2','3',0};

static void InitFunctionPtr(void)
{
    hntdll = LoadLibraryA("ntdll.dll");
    ok(hntdll != 0, "Unable to load ntdll.dll\n");

    if (hntdll)
    {
        pRtlCreateAtomTable = (void *)GetProcAddress(hntdll, "RtlCreateAtomTable");
        pRtlDestroyAtomTable = (void *)GetProcAddress(hntdll, "RtlDestroyAtomTable");
        pRtlEmptyAtomTable = (void *)GetProcAddress(hntdll, "RtlEmptyAtomTable");
        pRtlAddAtomToAtomTable = (void *)GetProcAddress(hntdll, "RtlAddAtomToAtomTable");
        pRtlDeleteAtomFromAtomTable = (void *)GetProcAddress(hntdll, "RtlDeleteAtomFromAtomTable");
        pRtlLookupAtomInAtomTable = (void *)GetProcAddress(hntdll, "RtlLookupAtomInAtomTable");
        pRtlPinAtomInAtomTable = (void *)GetProcAddress(hntdll, "RtlPinAtomInAtomTable");
        pRtlQueryAtomInAtomTable = (void *)GetProcAddress(hntdll, "RtlQueryAtomInAtomTable");

        pNtAddAtom = (void *)GetProcAddress(hntdll, "NtAddAtom");
        pNtQueryInformationAtom = (void *)GetProcAddress(hntdll, "NtQueryInformationAtom");
    }
}

static DWORD RtlAtomTestThread(LPVOID Table)
{
    RTL_ATOM_TABLE AtomTable = *(PRTL_ATOM_TABLE)Table;
    RTL_ATOM Atom;
    NTSTATUS res;
    ULONG RefCount = 0, PinCount = 0, Len = 0;
    WCHAR Name[64];

    res = pRtlLookupAtomInAtomTable(AtomTable, testAtom1, &Atom);
    ok(!res, "Unable to find atom from another thread, retval: %lx\n", res);

    res = pRtlLookupAtomInAtomTable(AtomTable, testAtom2, &Atom);
    ok(!res, "Unable to lookup pinned atom in table, retval: %lx\n", res);

    res = pRtlQueryAtomInAtomTable(AtomTable, Atom, &RefCount, &PinCount, Name, &Len);
    ok(res == STATUS_BUFFER_TOO_SMALL, "We got wrong retval: %lx\n", res);

    Len = 64;
    res = pRtlQueryAtomInAtomTable(AtomTable, Atom, &RefCount, &PinCount, Name, &Len);
    ok(!res, "Failed with longenough buffer, retval: %lx\n", res);
    ok(RefCount == 1, "Refcount was not 1 but %lx\n", RefCount);
    ok(PinCount == 1, "Pincount was not 1 but %lx\n", PinCount);
    ok(!lstrcmpW(Name, testAtom2), "We found wrong atom!!\n");
    ok((lstrlenW(testAtom2) * sizeof(WCHAR)) == Len, "Returned wrong length %ld\n", Len);

    Len = 64;
    res = pRtlQueryAtomInAtomTable(AtomTable, Atom, NULL, NULL, Name, &Len);
    ok(!res, "RtlQueryAtomInAtomTable with optional args invalid failed, retval: %lx\n", res);
    ok(!lstrcmpW(Name, testAtom2), "Found Wrong atom!\n");
    ok((lstrlenW(testAtom2) * sizeof(WCHAR)) == Len, "Returned wrong length %ld\n", Len);

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

    return 0;
}

static void test_NtAtom(void)
{
    RTL_ATOM_TABLE AtomTable = NULL;
    NTSTATUS res;
    RTL_ATOM Atom1, Atom2, Atom3, testEAtom, testAtom;
    HANDLE testThread;
    ULONG RefCount = 0, PinCount = 0, Len = 0;
    WCHAR Name[64];

    /* If we pass a non-null string to create atom table, then it thinks that we
     * have passed it an already allocated atom table */
    res = pRtlCreateAtomTable(0, &AtomTable);
    ok(!res, "RtlCreateAtomTable should succeed with an atom table size of 0\n");

    if (!res)
    {
        res = pRtlDestroyAtomTable(AtomTable);
        ok(!res, "We could create the atom table, but we couldn't destroy it! retval: %lx\n", res);
    }

    AtomTable = NULL;
    res = pRtlCreateAtomTable(37, &AtomTable);
    ok(!res, "We're unable to create an atom table with a valid table size retval: %lx\n", res);
    if (!res)
    {
        res = pRtlAddAtomToAtomTable(AtomTable, testAtom1, &Atom1);
        ok(!res, "We were unable to add a simple atom to the atom table, retval: %lx\n", res);

        res = pRtlLookupAtomInAtomTable(AtomTable, testAtom1Cap, &testAtom);
        ok(!res, "We were unable to find capital version of the atom, retval: %lx\n", res);
        ok(Atom1 == testAtom, "Found wrong atom in table when querying capital atom\n");

        res = pRtlLookupAtomInAtomTable(AtomTable, testAtom1Low, &testAtom);
        ok(!res, "Unable to find lowercase version of the atom, retval: %lx\n", res);
        ok(testAtom == Atom1, "Found wrong atom when querying lowercase atom\n");

        res = pRtlAddAtomToAtomTable(AtomTable, EmptyAtom, &testEAtom);
        ok(res == STATUS_OBJECT_NAME_INVALID, "Got wrong retval, retval: %lx\n", res);

        res = pRtlLookupAtomInAtomTable(AtomTable, testAtom1, &testAtom);
        ok(!res, "Failed to find totally legitimate atom, retval: %lx\n", res);
        ok(testAtom == Atom1, "Found wrong atom!\n");

        res = pRtlAddAtomToAtomTable(AtomTable, testAtom2, &Atom2);
        ok(!res, "Unable to add other legitimate atom to table, retval: %lx\n", res);

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

        testThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)RtlAtomTestThread, &AtomTable, 0, NULL);
        WaitForSingleObject(testThread, INFINITE);

        Len = 64;
        res = pRtlQueryAtomInAtomTable(AtomTable, Atom2, &RefCount, &PinCount, Name, &Len);
        ok(!res, "Unable to query atom in atom table, retval: %lx\n", res);
        ok(RefCount == 1, "RefCount is not 1 but %lx\n", RefCount);
        ok(PinCount == 1, "PinCount is not 1 but %lx\n", PinCount);
        ok(!lstrcmpW(Name, testAtom2), "We found wrong atom\n");
        ok((lstrlenW(testAtom2) * sizeof(WCHAR)) == Len, "Returned wrong length %ld\n", Len);

        res = pRtlEmptyAtomTable(AtomTable, FALSE);
        ok(!res, "Unable to empty atom table, retval %lx\n", res);

        Len = 64;
        res = pRtlQueryAtomInAtomTable(AtomTable, Atom2, &RefCount, &PinCount, Name, &Len);
        ok(!res, "It seems RtlEmptyAtomTable deleted our pinned atom eaven though we asked it not to, retval: %lx\n", res);
        ok(RefCount == 1, "RefCount is not 1 but %lx\n", RefCount);
        ok(PinCount == 1, "PinCount is not 1 but %lx\n", PinCount);
        ok(!lstrcmpW(Name, testAtom2), "We found wrong atom\n");
        ok((lstrlenW(testAtom2) * sizeof(WCHAR)) == Len, "Returned wrong length %ld\n", Len);

        Len = 8;
        Name[0] = Name[1] = Name[2] = Name[3] = Name[4] = 0x55AA;
        res = pRtlQueryAtomInAtomTable(AtomTable, Atom2, NULL, NULL, Name, &Len);
        ok(!res, "query atom %lx\n", res);
        ok(Len == 6, "wrong length %lu\n", Len);
        ok(!memcmp(Name, testAtom2, Len), "wrong atom string\n");
        ok(!Name[3], "wrong string termination\n");
        ok(Name[4] == 0x55AA, "buffer overwrite\n");

        Len = lstrlenW(testAtom2) * sizeof(WCHAR);
        memset(Name, '.', sizeof(Name));
        res = pRtlQueryAtomInAtomTable( AtomTable, Atom2, NULL, NULL, Name, &Len );
        ok(!res, "query atom %lx\n", res);
        ok(Len == (lstrlenW(testAtom2) - 1) * sizeof(WCHAR), "wrong length %lu\n", Len);
        ok(!memcmp(testAtom2, Name, (lstrlenW(testAtom2) - 1) * sizeof(WCHAR)), "wrong atom name\n");
        ok(Name[lstrlenW(testAtom2) - 1] == '\0', "wrong char\n");
        ok(Name[lstrlenW(testAtom2)] == ('.' << 8) + '.', "wrong char\n");

        res = pRtlLookupAtomInAtomTable(AtomTable, testAtom2, &testAtom);
        ok(!res, "We can't find our pinned atom!! retval: %lx\n", res);
        ok(testAtom == Atom2, "We found wrong atom!!!\n");

        res = pRtlLookupAtomInAtomTable(AtomTable, testAtom1, &testAtom);
        ok(res == STATUS_OBJECT_NAME_NOT_FOUND, "We found the atom in our table eaven though we asked RtlEmptyAtomTable to remove it, retval: %lx\n", res);

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

        res = pRtlEmptyAtomTable(AtomTable, TRUE);
        ok(!res, "Unable to empty atom table, retval: %lx\n", res);

        res = pRtlLookupAtomInAtomTable(AtomTable, testAtom2, &testAtom);
        ok(res == STATUS_OBJECT_NAME_NOT_FOUND, "The pinned atom should be removed, retval: %lx\n", res);

        res = pRtlLookupAtomInAtomTable(AtomTable, testAtom3, &testAtom);
        ok(res == STATUS_OBJECT_NAME_NOT_FOUND, "Non pinned atom should also be removed, retval: %lx\n", res);

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

⌨️ 快捷键说明

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