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 typedef struct _TABLE_SLOT
45 } TABLE_SLOT, *PTABLE_SLOT;
47 typedef struct _STRING_TABLE
53 } STRING_TABLE, *PSTRING_TABLE;
56 /**************************************************************************
57 * StringTableInitialize [SETUPAPI.@]
59 * Creates a new string table and initializes it.
65 * Success: Handle to the string table
69 StringTableInitialize(VOID)
71 PSTRING_TABLE pStringTable;
75 pStringTable = MyMalloc(sizeof(STRING_TABLE));
76 if (pStringTable == NULL)
78 ERR("Invalid hStringTable!\n");
82 memset(pStringTable, 0, sizeof(STRING_TABLE));
84 pStringTable->pSlots = MyMalloc(sizeof(TABLE_SLOT) * TABLE_DEFAULT_SIZE);
85 if (pStringTable->pSlots == NULL)
87 MyFree(pStringTable->pSlots);
91 memset(pStringTable->pSlots, 0, sizeof(TABLE_SLOT) * TABLE_DEFAULT_SIZE);
93 pStringTable->dwUsedSlots = 0;
94 pStringTable->dwMaxSlots = TABLE_DEFAULT_SIZE;
95 pStringTable->dwMaxDataSize = 0;
99 return (HSTRING_TABLE)pStringTable;
103 /**************************************************************************
104 * StringTableInitializeEx [SETUPAPI.@]
106 * Creates a new string table and initializes it.
109 * dwMaxExtraDataSize [I] Maximum extra data size
110 * dwReserved [I] Unused
113 * Success: Handle to the string table
117 StringTableInitializeEx(DWORD dwMaxExtraDataSize,
120 PSTRING_TABLE pStringTable;
124 pStringTable = MyMalloc(sizeof(STRING_TABLE));
125 if (pStringTable == NULL) return NULL;
127 memset(pStringTable, 0, sizeof(STRING_TABLE));
129 pStringTable->pSlots = MyMalloc(sizeof(TABLE_SLOT) * TABLE_DEFAULT_SIZE);
130 if (pStringTable->pSlots == NULL)
132 MyFree(pStringTable->pSlots);
136 memset(pStringTable->pSlots, 0, sizeof(TABLE_SLOT) * TABLE_DEFAULT_SIZE);
138 pStringTable->dwUsedSlots = 0;
139 pStringTable->dwMaxSlots = TABLE_DEFAULT_SIZE;
140 pStringTable->dwMaxDataSize = dwMaxExtraDataSize;
144 return (HSTRING_TABLE)pStringTable;
148 /**************************************************************************
149 * StringTableDestroy [SETUPAPI.@]
151 * Destroys a string table.
154 * hStringTable [I] Handle to the string table to be destroyed
160 StringTableDestroy(HSTRING_TABLE hStringTable)
162 PSTRING_TABLE pStringTable;
165 TRACE("%p\n", hStringTable);
167 pStringTable = (PSTRING_TABLE)hStringTable;
168 if (pStringTable == NULL)
171 if (pStringTable->pSlots != NULL)
173 for (i = 0; i < pStringTable->dwMaxSlots; i++)
175 MyFree(pStringTable->pSlots[i].pString);
176 pStringTable->pSlots[i].pString = NULL;
178 MyFree(pStringTable->pSlots[i].pData);
179 pStringTable->pSlots[i].pData = NULL;
180 pStringTable->pSlots[i].dwSize = 0;
183 MyFree(pStringTable->pSlots);
186 MyFree(pStringTable);
190 /**************************************************************************
191 * StringTableAddString [SETUPAPI.@]
193 * Adds a new string to the string table.
196 * hStringTable [I] Handle to the string table
197 * lpString [I] String to be added to the string table
199 * 1: case sensitive compare
206 * If the given string already exists in the string table it will not
207 * be added again. The ID of the existing string will be returned in
211 StringTableAddString(HSTRING_TABLE hStringTable,
215 PSTRING_TABLE pStringTable;
218 TRACE("%p %s %lx\n", hStringTable, debugstr_w(lpString), dwFlags);
220 pStringTable = (PSTRING_TABLE)hStringTable;
221 if (pStringTable == NULL)
223 ERR("Invalid hStringTable!\n");
227 /* Search for existing string in the string table */
228 for (i = 0; i < pStringTable->dwMaxSlots; i++)
230 if (pStringTable->pSlots[i].pString != NULL)
234 if (!lstrcmpW(pStringTable->pSlots[i].pString, lpString))
241 if (!lstrcmpiW(pStringTable->pSlots[i].pString, lpString))
249 /* Check for filled slot table */
250 if (pStringTable->dwUsedSlots == pStringTable->dwMaxSlots)
252 FIXME("Resize the string table!\n");
256 /* Search for an empty slot */
257 for (i = 0; i < pStringTable->dwMaxSlots; i++)
259 if (pStringTable->pSlots[i].pString == NULL)
261 pStringTable->pSlots[i].pString = MyMalloc((lstrlenW(lpString) + 1) * sizeof(WCHAR));
262 if (pStringTable->pSlots[i].pString == NULL)
264 TRACE("Couldn't allocate memory for a new string!\n");
268 lstrcpyW(pStringTable->pSlots[i].pString, lpString);
270 pStringTable->dwUsedSlots++;
276 TRACE("Couldn't find an empty slot!\n");
282 /**************************************************************************
283 * StringTableAddStringEx [SETUPAPI.@]
285 * Adds a new string plus extra data to the string table.
288 * hStringTable [I] Handle to the string table
289 * lpString [I] String to be added to the string table
291 * 1: case sensitive compare
292 * lpExtraData [I] Pointer to the extra data
293 * dwExtraDataSize [I] Size of the extra data
300 * If the given string already exists in the string table it will not
301 * be added again. The ID of the existing string will be returned in
305 StringTableAddStringEx(HSTRING_TABLE hStringTable,
309 DWORD dwExtraDataSize)
316 /**************************************************************************
317 * StringTableDuplicate [SETUPAPI.@]
319 * Duplicates a given string table.
322 * hStringTable [I] Handle to the string table
325 * Success: Handle to the duplicated string table
330 StringTableDuplicate(HSTRING_TABLE hStringTable)
332 PSTRING_TABLE pSourceTable;
333 PSTRING_TABLE pDestinationTable;
337 TRACE("%p\n", hStringTable);
339 pSourceTable = (PSTRING_TABLE)hStringTable;
340 if (pSourceTable == NULL)
342 ERR("Invalid hStringTable!\n");
343 return (HSTRING_TABLE)NULL;
346 pDestinationTable = MyMalloc(sizeof(STRING_TABLE));
347 if (pDestinationTable == NULL)
349 ERR("Cound not allocate a new string table!\n");
350 return (HSTRING_TABLE)NULL;
353 memset(pDestinationTable, 0, sizeof(STRING_TABLE));
355 pDestinationTable->pSlots = MyMalloc(sizeof(TABLE_SLOT) * pSourceTable->dwMaxSlots);
356 if (pDestinationTable->pSlots == NULL)
358 MyFree(pDestinationTable);
359 return (HSTRING_TABLE)NULL;
362 memset(pDestinationTable->pSlots, 0, sizeof(TABLE_SLOT) * pSourceTable->dwMaxSlots);
364 pDestinationTable->dwUsedSlots = 0;
365 pDestinationTable->dwMaxSlots = pSourceTable->dwMaxSlots;
367 for (i = 0; i < pSourceTable->dwMaxSlots; i++)
369 if (pSourceTable->pSlots[i].pString != NULL)
371 length = (lstrlenW(pSourceTable->pSlots[i].pString) + 1) * sizeof(WCHAR);
372 pDestinationTable->pSlots[i].pString = MyMalloc(length);
373 if (pDestinationTable->pSlots[i].pString != NULL)
375 memcpy(pDestinationTable->pSlots[i].pString,
376 pSourceTable->pSlots[i].pString,
378 pDestinationTable->dwUsedSlots++;
381 if (pSourceTable->pSlots[i].pData != NULL)
383 length = pSourceTable->pSlots[i].dwSize;
384 pDestinationTable->pSlots[i].pData = MyMalloc(length);
385 if (pDestinationTable->pSlots[i].pData)
387 memcpy(pDestinationTable->pSlots[i].pData,
388 pSourceTable->pSlots[i].pData,
390 pDestinationTable->pSlots[i].dwSize = length;
396 return (HSTRING_TABLE)pDestinationTable;
400 /**************************************************************************
401 * StringTableGetExtraData [SETUPAPI.@]
403 * Retrieves extra data from a given string table entry.
406 * hStringTable [I] Handle to the string table
408 * lpExtraData [I] Pointer a buffer that receives the extra data
409 * dwExtraDataSize [I] Size of the buffer
416 StringTableGetExtraData(HSTRING_TABLE hStringTable,
419 DWORD dwExtraDataSize)
421 PSTRING_TABLE pStringTable;
423 TRACE("%p %lx %p %lu\n",
424 hStringTable, dwId, lpExtraData, dwExtraDataSize);
426 pStringTable = (PSTRING_TABLE)hStringTable;
427 if (pStringTable == NULL)
429 ERR("Invalid hStringTable!\n");
433 if (dwId == 0 || dwId > pStringTable->dwMaxSlots)
435 ERR("Invalid Slot id!\n");
439 if (pStringTable->pSlots[dwId - 1].dwSize < dwExtraDataSize)
441 ERR("Data size is too large!\n");
446 pStringTable->pSlots[dwId - 1].pData,
453 /**************************************************************************
454 * StringTableLookUpString [SETUPAPI.@]
456 * Searches a string table for a given string.
459 * hStringTable [I] Handle to the string table
460 * lpString [I] String to be searched for
462 * 1: case sensitive compare
469 StringTableLookUpString(HSTRING_TABLE hStringTable,
473 PSTRING_TABLE pStringTable;
476 TRACE("%p %s %lx\n", hStringTable, debugstr_w(lpString), dwFlags);
478 pStringTable = (PSTRING_TABLE)hStringTable;
479 if (pStringTable == NULL)
481 ERR("Invalid hStringTable!\n");
485 /* Search for existing string in the string table */
486 for (i = 0; i < pStringTable->dwMaxSlots; i++)
488 if (pStringTable->pSlots[i].pString != NULL)
492 if (!lstrcmpW(pStringTable->pSlots[i].pString, lpString))
497 if (!lstrcmpiW(pStringTable->pSlots[i].pString, lpString))
507 /**************************************************************************
508 * StringTableLookUpStringEx [SETUPAPI.@]
510 * Searches a string table and extra data for a given string.
513 * hStringTable [I] Handle to the string table
514 * lpString [I] String to be searched for
516 * 1: case sensitive compare
517 * lpExtraData [O] Pointer to the buffer that receives the extra data
518 * lpReserved [I/O] Unused
525 StringTableLookUpStringEx(HSTRING_TABLE hStringTable,
536 /**************************************************************************
537 * StringTableSetExtraData [SETUPAPI.@]
539 * Sets extra data for a given string table entry.
542 * hStringTable [I] Handle to the string table
544 * lpExtraData [I] Pointer to the extra data
545 * dwExtraDataSize [I] Size of the extra data
552 StringTableSetExtraData(HSTRING_TABLE hStringTable,
555 DWORD dwExtraDataSize)
557 PSTRING_TABLE pStringTable;
559 TRACE("%p %lx %p %lu\n",
560 hStringTable, dwId, lpExtraData, dwExtraDataSize);
562 pStringTable = (PSTRING_TABLE)hStringTable;
563 if (pStringTable == NULL)
565 ERR("Invalid hStringTable!\n");
569 if (dwId == 0 || dwId > pStringTable->dwMaxSlots)
571 ERR("Invalid Slot id!\n");
575 if (pStringTable->dwMaxDataSize < dwExtraDataSize)
577 ERR("Data size is too large!\n");
581 pStringTable->pSlots[dwId - 1].pData = MyMalloc(dwExtraDataSize);
582 if (pStringTable->pSlots[dwId - 1].pData == NULL)
588 memcpy(pStringTable->pSlots[dwId - 1].pData,
591 pStringTable->pSlots[dwId - 1].dwSize = dwExtraDataSize;
597 /**************************************************************************
598 * StringTableStringFromId [SETUPAPI.@]
600 * Returns a pointer to a string for the given string ID.
603 * hStringTable [I] Handle to the string table.
607 * Success: Pointer to the string
611 StringTableStringFromId(HSTRING_TABLE hStringTable,
614 PSTRING_TABLE pStringTable;
615 static WCHAR empty[] = {0};
617 TRACE("%p %lx\n", hStringTable, dwId);
619 pStringTable = (PSTRING_TABLE)hStringTable;
620 if (pStringTable == NULL)
622 ERR("Invalid hStringTable!\n");
626 if (dwId == 0 || dwId > pStringTable->dwMaxSlots)
629 return pStringTable->pSlots[dwId - 1].pString;
633 /**************************************************************************
634 * StringTableStringFromIdEx [SETUPAPI.@]
636 * Returns a string for the given string ID.
639 * hStringTable [I] Handle to the string table
641 * lpBuffer [I] Pointer to string buffer
642 * lpBufferSize [I/O] Pointer to the size of the string buffer
649 StringTableStringFromIdEx(HSTRING_TABLE hStringTable,
652 LPDWORD lpBufferLength)
654 PSTRING_TABLE pStringTable;
656 BOOL bResult = FALSE;
658 TRACE("%p %lx %p %p\n", hStringTable, dwId, lpBuffer, lpBufferLength);
660 pStringTable = (PSTRING_TABLE)hStringTable;
661 if (pStringTable == NULL)
663 ERR("Invalid hStringTable!\n");
668 if (dwId == 0 || dwId > pStringTable->dwMaxSlots ||
669 pStringTable->pSlots[dwId - 1].pString == NULL)
671 WARN("Invalid string ID!\n");
676 dwLength = (lstrlenW(pStringTable->pSlots[dwId - 1].pString) + 1) * sizeof(WCHAR);
677 if (dwLength <= *lpBufferLength)
679 lstrcpyW(lpBuffer, pStringTable->pSlots[dwId - 1].pString);
683 *lpBufferLength = dwLength;
689 /**************************************************************************
690 * StringTableTrim [SETUPAPI.@]
695 * hStringTable [I] Handle to the string table
701 StringTableTrim(HSTRING_TABLE hStringTable)
703 FIXME("%p\n", hStringTable);