📄 stringtable.c
字号:
/*
* 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 + -