2 * Setupapi string table functions
4 * Copyright 2005 Eric Kohl
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #include "wine/port.h"
33 #include "wine/debug.h"
36 #define TABLE_DEFAULT_SIZE 256
38 WINE_DEFAULT_DEBUG_CHANNEL(setupapi);
40 DECLARE_HANDLE(HSTRING_TABLE);
42 typedef struct _TABLE_SLOT
47 } TABLE_SLOT, *PTABLE_SLOT;
49 typedef struct _STRING_TABLE
55 } STRING_TABLE, *PSTRING_TABLE;
58 /**************************************************************************
59 * StringTableInitialize [SETUPAPI.@]
61 * Creates a new string table and initializes it.
67 * Success: Handle to the string table
71 StringTableInitialize(VOID)
73 PSTRING_TABLE pStringTable;
77 pStringTable = MyMalloc(sizeof(STRING_TABLE));
78 if (pStringTable == NULL)
80 ERR("Invalid hStringTable!\n");
84 memset(pStringTable, 0, sizeof(STRING_TABLE));
86 pStringTable->pSlots = MyMalloc(sizeof(TABLE_SLOT) * TABLE_DEFAULT_SIZE);
87 if (pStringTable->pSlots == NULL)
93 memset(pStringTable->pSlots, 0, sizeof(TABLE_SLOT) * TABLE_DEFAULT_SIZE);
95 pStringTable->dwUsedSlots = 0;
96 pStringTable->dwMaxSlots = TABLE_DEFAULT_SIZE;
97 pStringTable->dwMaxDataSize = 0;
101 return (HSTRING_TABLE)pStringTable;
105 /**************************************************************************
106 * StringTableInitializeEx [SETUPAPI.@]
108 * Creates a new string table and initializes it.
111 * dwMaxExtraDataSize [I] Maximum extra data size
112 * dwReserved [I] Unused
115 * Success: Handle to the string table
119 StringTableInitializeEx(DWORD dwMaxExtraDataSize,
122 PSTRING_TABLE pStringTable;
126 pStringTable = MyMalloc(sizeof(STRING_TABLE));
127 if (pStringTable == NULL) return NULL;
129 memset(pStringTable, 0, sizeof(STRING_TABLE));
131 pStringTable->pSlots = MyMalloc(sizeof(TABLE_SLOT) * TABLE_DEFAULT_SIZE);
132 if (pStringTable->pSlots == NULL)
134 MyFree(pStringTable);
138 memset(pStringTable->pSlots, 0, sizeof(TABLE_SLOT) * TABLE_DEFAULT_SIZE);
140 pStringTable->dwUsedSlots = 0;
141 pStringTable->dwMaxSlots = TABLE_DEFAULT_SIZE;
142 pStringTable->dwMaxDataSize = dwMaxExtraDataSize;
146 return (HSTRING_TABLE)pStringTable;
150 /**************************************************************************
151 * StringTableDestroy [SETUPAPI.@]
153 * Destroys a string table.
156 * hStringTable [I] Handle to the string table to be destroyed
162 StringTableDestroy(HSTRING_TABLE hStringTable)
164 PSTRING_TABLE pStringTable;
167 TRACE("%p\n", hStringTable);
169 pStringTable = (PSTRING_TABLE)hStringTable;
170 if (pStringTable == NULL)
173 if (pStringTable->pSlots != NULL)
175 for (i = 0; i < pStringTable->dwMaxSlots; i++)
177 MyFree(pStringTable->pSlots[i].pString);
178 pStringTable->pSlots[i].pString = NULL;
180 MyFree(pStringTable->pSlots[i].pData);
181 pStringTable->pSlots[i].pData = NULL;
182 pStringTable->pSlots[i].dwSize = 0;
185 MyFree(pStringTable->pSlots);
188 MyFree(pStringTable);
192 /**************************************************************************
193 * StringTableAddString [SETUPAPI.@]
195 * Adds a new string to the string table.
198 * hStringTable [I] Handle to the string table
199 * lpString [I] String to be added to the string table
201 * 1: case sensitive compare
208 * If the given string already exists in the string table it will not
209 * be added again. The ID of the existing string will be returned in
213 StringTableAddString(HSTRING_TABLE hStringTable,
217 PSTRING_TABLE pStringTable;
220 TRACE("%p %s %x\n", hStringTable, debugstr_w(lpString), dwFlags);
222 pStringTable = (PSTRING_TABLE)hStringTable;
223 if (pStringTable == NULL)
225 ERR("Invalid hStringTable!\n");
229 /* Search for existing string in the string table */
230 for (i = 0; i < pStringTable->dwMaxSlots; i++)
232 if (pStringTable->pSlots[i].pString != NULL)
236 if (!lstrcmpW(pStringTable->pSlots[i].pString, lpString))
243 if (!lstrcmpiW(pStringTable->pSlots[i].pString, lpString))
251 /* Check for filled slot table */
252 if (pStringTable->dwUsedSlots == pStringTable->dwMaxSlots)
254 FIXME("Resize the string table!\n");
258 /* Search for an empty slot */
259 for (i = 0; i < pStringTable->dwMaxSlots; i++)
261 if (pStringTable->pSlots[i].pString == NULL)
263 pStringTable->pSlots[i].pString = MyMalloc((lstrlenW(lpString) + 1) * sizeof(WCHAR));
264 if (pStringTable->pSlots[i].pString == NULL)
266 TRACE("Couldn't allocate memory for a new string!\n");
270 lstrcpyW(pStringTable->pSlots[i].pString, lpString);
272 pStringTable->dwUsedSlots++;
278 TRACE("Couldn't find an empty slot!\n");
284 /**************************************************************************
285 * StringTableAddStringEx [SETUPAPI.@]
287 * Adds a new string plus extra data to the string table.
290 * hStringTable [I] Handle to the string table
291 * lpString [I] String to be added to the string table
293 * 1: case sensitive compare
294 * lpExtraData [I] Pointer to the extra data
295 * dwExtraDataSize [I] Size of the extra data
302 * If the given string already exists in the string table it will not
303 * be added again. The ID of the existing string will be returned in
307 StringTableAddStringEx(HSTRING_TABLE hStringTable,
311 DWORD dwExtraDataSize)
318 /**************************************************************************
319 * StringTableDuplicate [SETUPAPI.@]
321 * Duplicates a given string table.
324 * hStringTable [I] Handle to the string table
327 * Success: Handle to the duplicated string table
332 StringTableDuplicate(HSTRING_TABLE hStringTable)
334 PSTRING_TABLE pSourceTable;
335 PSTRING_TABLE pDestinationTable;
339 TRACE("%p\n", hStringTable);
341 pSourceTable = (PSTRING_TABLE)hStringTable;
342 if (pSourceTable == NULL)
344 ERR("Invalid hStringTable!\n");
345 return (HSTRING_TABLE)NULL;
348 pDestinationTable = MyMalloc(sizeof(STRING_TABLE));
349 if (pDestinationTable == NULL)
351 ERR("Cound not allocate a new string table!\n");
352 return (HSTRING_TABLE)NULL;
355 memset(pDestinationTable, 0, sizeof(STRING_TABLE));
357 pDestinationTable->pSlots = MyMalloc(sizeof(TABLE_SLOT) * pSourceTable->dwMaxSlots);
358 if (pDestinationTable->pSlots == NULL)
360 MyFree(pDestinationTable);
361 return (HSTRING_TABLE)NULL;
364 memset(pDestinationTable->pSlots, 0, sizeof(TABLE_SLOT) * pSourceTable->dwMaxSlots);
366 pDestinationTable->dwUsedSlots = 0;
367 pDestinationTable->dwMaxSlots = pSourceTable->dwMaxSlots;
369 for (i = 0; i < pSourceTable->dwMaxSlots; i++)
371 if (pSourceTable->pSlots[i].pString != NULL)
373 length = (lstrlenW(pSourceTable->pSlots[i].pString) + 1) * sizeof(WCHAR);
374 pDestinationTable->pSlots[i].pString = MyMalloc(length);
375 if (pDestinationTable->pSlots[i].pString != NULL)
377 memcpy(pDestinationTable->pSlots[i].pString,
378 pSourceTable->pSlots[i].pString,
380 pDestinationTable->dwUsedSlots++;
383 if (pSourceTable->pSlots[i].pData != NULL)
385 length = pSourceTable->pSlots[i].dwSize;
386 pDestinationTable->pSlots[i].pData = MyMalloc(length);
387 if (pDestinationTable->pSlots[i].pData)
389 memcpy(pDestinationTable->pSlots[i].pData,
390 pSourceTable->pSlots[i].pData,
392 pDestinationTable->pSlots[i].dwSize = length;
398 return (HSTRING_TABLE)pDestinationTable;
402 /**************************************************************************
403 * StringTableGetExtraData [SETUPAPI.@]
405 * Retrieves extra data from a given string table entry.
408 * hStringTable [I] Handle to the string table
410 * lpExtraData [I] Pointer a buffer that receives the extra data
411 * dwExtraDataSize [I] Size of the buffer
418 StringTableGetExtraData(HSTRING_TABLE hStringTable,
421 DWORD dwExtraDataSize)
423 PSTRING_TABLE pStringTable;
425 TRACE("%p %x %p %u\n",
426 hStringTable, dwId, lpExtraData, dwExtraDataSize);
428 pStringTable = (PSTRING_TABLE)hStringTable;
429 if (pStringTable == NULL)
431 ERR("Invalid hStringTable!\n");
435 if (dwId == 0 || dwId > pStringTable->dwMaxSlots)
437 ERR("Invalid Slot id!\n");
441 if (pStringTable->pSlots[dwId - 1].dwSize < dwExtraDataSize)
443 ERR("Data size is too large!\n");
448 pStringTable->pSlots[dwId - 1].pData,
455 /**************************************************************************
456 * StringTableLookUpString [SETUPAPI.@]
458 * Searches a string table for a given string.
461 * hStringTable [I] Handle to the string table
462 * lpString [I] String to be searched for
464 * 1: case sensitive compare
471 StringTableLookUpString(HSTRING_TABLE hStringTable,
475 PSTRING_TABLE pStringTable;
478 TRACE("%p %s %x\n", hStringTable, debugstr_w(lpString), dwFlags);
480 pStringTable = (PSTRING_TABLE)hStringTable;
481 if (pStringTable == NULL)
483 ERR("Invalid hStringTable!\n");
487 /* Search for existing string in the string table */
488 for (i = 0; i < pStringTable->dwMaxSlots; i++)
490 if (pStringTable->pSlots[i].pString != NULL)
494 if (!lstrcmpW(pStringTable->pSlots[i].pString, lpString))
499 if (!lstrcmpiW(pStringTable->pSlots[i].pString, lpString))
509 /**************************************************************************
510 * StringTableLookUpStringEx [SETUPAPI.@]
512 * Searches a string table and extra data for a given string.
515 * hStringTable [I] Handle to the string table
516 * lpString [I] String to be searched for
518 * 1: case sensitive compare
519 * lpExtraData [O] Pointer to the buffer that receives the extra data
520 * lpReserved [I/O] Unused
527 StringTableLookUpStringEx(HSTRING_TABLE hStringTable,
538 /**************************************************************************
539 * StringTableSetExtraData [SETUPAPI.@]
541 * Sets extra data for a given string table entry.
544 * hStringTable [I] Handle to the string table
546 * lpExtraData [I] Pointer to the extra data
547 * dwExtraDataSize [I] Size of the extra data
554 StringTableSetExtraData(HSTRING_TABLE hStringTable,
557 DWORD dwExtraDataSize)
559 PSTRING_TABLE pStringTable;
561 TRACE("%p %x %p %u\n",
562 hStringTable, dwId, lpExtraData, dwExtraDataSize);
564 pStringTable = (PSTRING_TABLE)hStringTable;
565 if (pStringTable == NULL)
567 ERR("Invalid hStringTable!\n");
571 if (dwId == 0 || dwId > pStringTable->dwMaxSlots)
573 ERR("Invalid Slot id!\n");
577 if (pStringTable->dwMaxDataSize < dwExtraDataSize)
579 ERR("Data size is too large!\n");
583 pStringTable->pSlots[dwId - 1].pData = MyMalloc(dwExtraDataSize);
584 if (pStringTable->pSlots[dwId - 1].pData == NULL)
590 memcpy(pStringTable->pSlots[dwId - 1].pData,
593 pStringTable->pSlots[dwId - 1].dwSize = dwExtraDataSize;
599 /**************************************************************************
600 * StringTableStringFromId [SETUPAPI.@]
602 * Returns a pointer to a string for the given string ID.
605 * hStringTable [I] Handle to the string table.
609 * Success: Pointer to the string
613 StringTableStringFromId(HSTRING_TABLE hStringTable,
616 PSTRING_TABLE pStringTable;
617 static WCHAR empty[] = {0};
619 TRACE("%p %x\n", hStringTable, dwId);
621 pStringTable = (PSTRING_TABLE)hStringTable;
622 if (pStringTable == NULL)
624 ERR("Invalid hStringTable!\n");
628 if (dwId == 0 || dwId > pStringTable->dwMaxSlots)
631 return pStringTable->pSlots[dwId - 1].pString;
635 /**************************************************************************
636 * StringTableStringFromIdEx [SETUPAPI.@]
638 * Returns a string for the given string ID.
641 * hStringTable [I] Handle to the string table
643 * lpBuffer [I] Pointer to string buffer
644 * lpBufferSize [I/O] Pointer to the size of the string buffer
651 StringTableStringFromIdEx(HSTRING_TABLE hStringTable,
654 LPDWORD lpBufferLength)
656 PSTRING_TABLE pStringTable;
658 BOOL bResult = FALSE;
660 TRACE("%p %x %p %p\n", hStringTable, dwId, lpBuffer, lpBufferLength);
662 pStringTable = (PSTRING_TABLE)hStringTable;
663 if (pStringTable == NULL)
665 ERR("Invalid hStringTable!\n");
670 if (dwId == 0 || dwId > pStringTable->dwMaxSlots ||
671 pStringTable->pSlots[dwId - 1].pString == NULL)
673 WARN("Invalid string ID!\n");
678 dwLength = (lstrlenW(pStringTable->pSlots[dwId - 1].pString) + 1) * sizeof(WCHAR);
679 if (dwLength <= *lpBufferLength)
681 lstrcpyW(lpBuffer, pStringTable->pSlots[dwId - 1].pString);
685 *lpBufferLength = dwLength;
691 /**************************************************************************
692 * StringTableTrim [SETUPAPI.@]
697 * hStringTable [I] Handle to the string table
703 StringTableTrim(HSTRING_TABLE hStringTable)
705 FIXME("%p\n", hStringTable);