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

📄 stringtable.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 * Setupapi string table functions
 *
 * Copyright 2005 Eric Kohl
 *
 * 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
 */

#include "setupapi_private.h"

#define TABLE_DEFAULT_SIZE 256

WINE_DEFAULT_DEBUG_CHANNEL(setupapi);

typedef struct _TABLE_SLOT
{
    LPWSTR pString;
    LPVOID pData;
    DWORD dwSize;
} TABLE_SLOT, *PTABLE_SLOT;

typedef struct _STRING_TABLE
{
    PTABLE_SLOT pSlots;
    DWORD dwUsedSlots;
    DWORD dwMaxSlots;
    DWORD dwMaxDataSize;
} STRING_TABLE, *PSTRING_TABLE;

WCHAR empty[] = {0};


/**************************************************************************
 * StringTableInitialize [SETUPAPI.@]
 *
 * Creates a new string table and initializes it.
 *
 * PARAMS
 *     None
 *
 * RETURNS
 *     Success: Handle to the string table
 *     Failure: NULL
 */
HSTRING_TABLE WINAPI
StringTableInitialize(VOID)
{
    PSTRING_TABLE pStringTable;

    TRACE("\n");

    pStringTable = MyMalloc(sizeof(STRING_TABLE));
    if (pStringTable == NULL)
    {
        ERR("Invalid hStringTable!\n");
        return NULL;
    }

    memset(pStringTable, 0, sizeof(STRING_TABLE));

    pStringTable->pSlots = MyMalloc(sizeof(TABLE_SLOT) * TABLE_DEFAULT_SIZE);
    if (pStringTable->pSlots == NULL)
    {
        MyFree(pStringTable->pSlots);
        return NULL;
    }

    memset(pStringTable->pSlots, 0, sizeof(TABLE_SLOT) * TABLE_DEFAULT_SIZE);

    pStringTable->dwUsedSlots = 0;
    pStringTable->dwMaxSlots = TABLE_DEFAULT_SIZE;
    pStringTable->dwMaxDataSize = 0;

    TRACE("Done\n");

    return (HSTRING_TABLE)pStringTable;
}


/**************************************************************************
 * StringTableInitializeEx [SETUPAPI.@]
 *
 * Creates a new string table and initializes it.
 *
 * PARAMS
 *     dwMaxExtraDataSize [I] Maximum extra data size
 *     dwReserved         [I] Unused
 *
 * RETURNS
 *     Success: Handle to the string table
 *     Failure: NULL
 */
HSTRING_TABLE WINAPI
StringTableInitializeEx(DWORD dwMaxExtraDataSize,
                        DWORD dwReserved)
{
    PSTRING_TABLE pStringTable;

    TRACE("\n");

    pStringTable = MyMalloc(sizeof(STRING_TABLE));
    if (pStringTable == NULL)
    {
        ERR("Invalid hStringTable!\n");
        return NULL;
    }

    memset(pStringTable, 0, sizeof(STRING_TABLE));

    pStringTable->pSlots = MyMalloc(sizeof(TABLE_SLOT) * TABLE_DEFAULT_SIZE);
    if (pStringTable->pSlots == NULL)
    {
        MyFree(pStringTable->pSlots);
        return NULL;
    }

    memset(pStringTable->pSlots, 0, sizeof(TABLE_SLOT) * TABLE_DEFAULT_SIZE);

    pStringTable->dwUsedSlots = 0;
    pStringTable->dwMaxSlots = TABLE_DEFAULT_SIZE;
    pStringTable->dwMaxDataSize = dwMaxExtraDataSize;

    TRACE("Done\n");

    return (HSTRING_TABLE)pStringTable;
}


/**************************************************************************
 * StringTableDestroy [SETUPAPI.@]
 *
 * Destroys a string table.
 *
 * PARAMS
 *     hStringTable [I] Handle to the string table to be destroyed
 *
 * RETURNS
 *     None
 */
VOID WINAPI
StringTableDestroy(HSTRING_TABLE hStringTable)
{
    PSTRING_TABLE pStringTable;
    DWORD i;

    TRACE("%p\n", (PVOID)hStringTable);

    pStringTable = (PSTRING_TABLE)hStringTable;
    if (pStringTable == NULL)
        return;

    if (pStringTable->pSlots != NULL)
    {
        for (i = 0; i < pStringTable->dwMaxSlots; i++)
        {
            if (pStringTable->pSlots[i].pString != NULL)
            {
                MyFree(pStringTable->pSlots[i].pString);
                pStringTable->pSlots[i].pString = NULL;
            }

            if (pStringTable->pSlots[i].pData != NULL)
            {
                MyFree(pStringTable->pSlots[i].pData);
                pStringTable->pSlots[i].pData = NULL;
                pStringTable->pSlots[i].dwSize = 0;
            }
        }

        MyFree(pStringTable->pSlots);
    }

    MyFree(pStringTable);
}


/**************************************************************************
 * StringTableAddString [SETUPAPI.@]
 *
 * Adds a new string to the string table.
 *
 * PARAMS
 *     hStringTable [I] Handle to the string table
 *     lpString     [I] String to be added to the string table
 *     dwFlags      [I] Flags
 *                        1: case sensitive compare
 *
 * RETURNS
 *     Success: String ID
 *     Failure: -1
 *
 * NOTES
 *     If the given string already exists in the string table it will not
 *     be added again. The ID of the existing string will be returned in
 *     this case.
 */
DWORD WINAPI
StringTableAddString(HSTRING_TABLE hStringTable,
                     LPWSTR lpString,
                     DWORD dwFlags)
{
    PSTRING_TABLE pStringTable;
    DWORD i;

    TRACE("%p %s %lx\n", (PVOID)hStringTable, debugstr_w(lpString), dwFlags);

    pStringTable = (PSTRING_TABLE)hStringTable;
    if (pStringTable == NULL)
    {
        ERR("Invalid hStringTable!\n");
        return (DWORD)-1;
    }

    /* Search for existing string in the string table */
    for (i = 0; i < pStringTable->dwMaxSlots; i++)
    {
        if (pStringTable->pSlots[i].pString != NULL)
        {
            if (dwFlags & 1)
            {
                if (!lstrcmpW(pStringTable->pSlots[i].pString, lpString))
                {
                    return i + 1;
                }
            }
            else
            {
                if (!lstrcmpiW(pStringTable->pSlots[i].pString, lpString))
                {
                    return i + 1;
                }
            }
        }
    }

    /* Check for filled slot table */
    if (pStringTable->dwUsedSlots == pStringTable->dwMaxSlots)
    {
        FIXME("Resize the string table!\n");
        return (DWORD)-1;
    }

    /* Search for an empty slot */
    for (i = 0; i < pStringTable->dwMaxSlots; i++)
    {
        if (pStringTable->pSlots[i].pString == NULL)
        {
            pStringTable->pSlots[i].pString = MyMalloc((lstrlenW(lpString) + 1) * sizeof(WCHAR));
            if (pStringTable->pSlots[i].pString == NULL)
            {
                TRACE("Couldn't allocate memory for a new string!\n");
                return (DWORD)-1;
            }

            lstrcpyW(pStringTable->pSlots[i].pString, lpString);

            pStringTable->dwUsedSlots++;

            return i + 1;
        }
    }

    TRACE("Couldn't find an empty slot!\n");

    return (DWORD)-1;
}


/**************************************************************************
 * StringTableAddStringEx [SETUPAPI.@]
 *
 * Adds a new string plus extra data to the string table.
 *
 * PARAMS
 *     hStringTable    [I] Handle to the string table
 *     lpString        [I] String to be added to the string table
 *     dwFlags         [I] Flags
 *                           1: case sensitive compare
 *     lpExtraData     [I] Pointer to the extra data
 *     dwExtraDataSize [I] Size of the extra data
 *
 * RETURNS
 *     Success: String ID
 *     Failure: -1
 *
 * NOTES
 *     If the given string already exists in the string table it will not
 *     be added again. The ID of the existing string will be returned in
 *     this case.
 */
DWORD WINAPI
StringTableAddStringEx(HSTRING_TABLE hStringTable,
                       LPWSTR lpString,
                       DWORD dwFlags,
                       LPVOID lpExtraData,
                       DWORD dwExtraDataSize)
{
    PSTRING_TABLE pStringTable;
    DWORD i;

    TRACE("%p %s %lx\n", (PVOID)hStringTable, debugstr_w(lpString), dwFlags);

    pStringTable = (PSTRING_TABLE)hStringTable;
    if (pStringTable == NULL)
    {
        ERR("Invalid hStringTable!\n");
        return (DWORD)-1;
    }

    /* Search for existing string in the string table */
    for (i = 0; i < pStringTable->dwMaxSlots; i++)
    {
        if (pStringTable->pSlots[i].pString != NULL)
        {
            if (dwFlags & 1)
            {
                if (!lstrcmpW(pStringTable->pSlots[i].pString, lpString))
                {
                    return i + 1;
                }
            }
            else
            {
                if (!lstrcmpiW(pStringTable->pSlots[i].pString, lpString))
                {
                    return i + 1;
                }
            }
        }
    }

    /* Check for filled slot table */
    if (pStringTable->dwUsedSlots == pStringTable->dwMaxSlots)
    {
        FIXME("Resize the string table!\n");
        return (DWORD)-1;
    }

    /* Search for an empty slot */
    for (i = 0; i < pStringTable->dwMaxSlots; i++)
    {
        if (pStringTable->pSlots[i].pString == NULL)
        {
            pStringTable->pSlots[i].pString = MyMalloc((lstrlenW(lpString) + 1) * sizeof(WCHAR));
            if (pStringTable->pSlots[i].pString == NULL)
            {
                TRACE("Couldn't allocate memory for a new string!\n");
                return (DWORD)-1;
            }

            lstrcpyW(pStringTable->pSlots[i].pString, lpString);

            pStringTable->pSlots[i].pData = MyMalloc(dwExtraDataSize);
            if (pStringTable->pSlots[i].pData == NULL)
            {
                TRACE("Couldn't allocate memory for a new extra data!\n");
                MyFree(pStringTable->pSlots[i].pString);
                pStringTable->pSlots[i].pString = NULL;
                return (DWORD)-1;
            }

            memcpy(pStringTable->pSlots[i].pData,
                   lpExtraData,
                   dwExtraDataSize);
            pStringTable->pSlots[i].dwSize = dwExtraDataSize;

            pStringTable->dwUsedSlots++;

            return i + 1;
        }
    }

    TRACE("Couldn't find an empty slot!\n");

    return (DWORD)-1;
}


/**************************************************************************
 * StringTableDuplicate [SETUPAPI.@]
 *
 * Duplicates a given string table.
 *
 * PARAMS
 *     hStringTable [I] Handle to the string table
 *
 * RETURNS
 *     Success: Handle to the duplicated string table
 *     Failure: NULL
 *
 */
HSTRING_TABLE WINAPI
StringTableDuplicate(HSTRING_TABLE hStringTable)
{
    PSTRING_TABLE pSourceTable;
    PSTRING_TABLE pDestinationTable;
    DWORD i;
    DWORD length;

⌨️ 快捷键说明

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