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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #include "setupapi_private.h"
23 #define TABLE_DEFAULT_SIZE 256
25 WINE_DEFAULT_DEBUG_CHANNEL(setupapi
);
27 typedef struct _TABLE_SLOT
32 } TABLE_SLOT
, *PTABLE_SLOT
;
34 typedef struct _STRING_TABLE
40 } STRING_TABLE
, *PSTRING_TABLE
;
45 /**************************************************************************
46 * StringTableInitialize [SETUPAPI.@]
48 * Creates a new string table and initializes it.
54 * Success: Handle to the string table
58 StringTableInitialize(VOID
)
60 PSTRING_TABLE pStringTable
;
64 pStringTable
= MyMalloc(sizeof(STRING_TABLE
));
65 if (pStringTable
== NULL
)
67 ERR("Invalid hStringTable!\n");
71 memset(pStringTable
, 0, sizeof(STRING_TABLE
));
73 pStringTable
->pSlots
= MyMalloc(sizeof(TABLE_SLOT
) * TABLE_DEFAULT_SIZE
);
74 if (pStringTable
->pSlots
== NULL
)
76 MyFree(pStringTable
->pSlots
);
80 memset(pStringTable
->pSlots
, 0, sizeof(TABLE_SLOT
) * TABLE_DEFAULT_SIZE
);
82 pStringTable
->dwUsedSlots
= 0;
83 pStringTable
->dwMaxSlots
= TABLE_DEFAULT_SIZE
;
84 pStringTable
->dwMaxDataSize
= 0;
88 return (HSTRING_TABLE
)pStringTable
;
92 /**************************************************************************
93 * StringTableInitializeEx [SETUPAPI.@]
95 * Creates a new string table and initializes it.
98 * dwMaxExtraDataSize [I] Maximum extra data size
99 * dwReserved [I] Unused
102 * Success: Handle to the string table
106 StringTableInitializeEx(DWORD dwMaxExtraDataSize
,
109 PSTRING_TABLE pStringTable
;
113 pStringTable
= MyMalloc(sizeof(STRING_TABLE
));
114 if (pStringTable
== NULL
)
116 ERR("Invalid hStringTable!\n");
120 memset(pStringTable
, 0, sizeof(STRING_TABLE
));
122 pStringTable
->pSlots
= MyMalloc(sizeof(TABLE_SLOT
) * TABLE_DEFAULT_SIZE
);
123 if (pStringTable
->pSlots
== NULL
)
125 MyFree(pStringTable
->pSlots
);
129 memset(pStringTable
->pSlots
, 0, sizeof(TABLE_SLOT
) * TABLE_DEFAULT_SIZE
);
131 pStringTable
->dwUsedSlots
= 0;
132 pStringTable
->dwMaxSlots
= TABLE_DEFAULT_SIZE
;
133 pStringTable
->dwMaxDataSize
= dwMaxExtraDataSize
;
137 return (HSTRING_TABLE
)pStringTable
;
141 /**************************************************************************
142 * StringTableDestroy [SETUPAPI.@]
144 * Destroys a string table.
147 * hStringTable [I] Handle to the string table to be destroyed
153 StringTableDestroy(HSTRING_TABLE hStringTable
)
155 PSTRING_TABLE pStringTable
;
158 TRACE("%p\n", (PVOID
)hStringTable
);
160 pStringTable
= (PSTRING_TABLE
)hStringTable
;
161 if (pStringTable
== NULL
)
164 if (pStringTable
->pSlots
!= NULL
)
166 for (i
= 0; i
< pStringTable
->dwMaxSlots
; i
++)
168 if (pStringTable
->pSlots
[i
].pString
!= NULL
)
170 MyFree(pStringTable
->pSlots
[i
].pString
);
171 pStringTable
->pSlots
[i
].pString
= NULL
;
174 if (pStringTable
->pSlots
[i
].pData
!= NULL
)
176 MyFree(pStringTable
->pSlots
[i
].pData
);
177 pStringTable
->pSlots
[i
].pData
= NULL
;
178 pStringTable
->pSlots
[i
].dwSize
= 0;
182 MyFree(pStringTable
->pSlots
);
185 MyFree(pStringTable
);
189 /**************************************************************************
190 * StringTableAddString [SETUPAPI.@]
192 * Adds a new string to the string table.
195 * hStringTable [I] Handle to the string table
196 * lpString [I] String to be added to the string table
198 * 1: case sensitive compare
205 * If the given string already exists in the string table it will not
206 * be added again. The ID of the existing string will be returned in
210 StringTableAddString(HSTRING_TABLE hStringTable
,
214 PSTRING_TABLE pStringTable
;
217 TRACE("%p %s %lx\n", (PVOID
)hStringTable
, debugstr_w(lpString
), dwFlags
);
219 pStringTable
= (PSTRING_TABLE
)hStringTable
;
220 if (pStringTable
== NULL
)
222 ERR("Invalid hStringTable!\n");
226 /* Search for existing string in the string table */
227 for (i
= 0; i
< pStringTable
->dwMaxSlots
; i
++)
229 if (pStringTable
->pSlots
[i
].pString
!= NULL
)
233 if (!lstrcmpW(pStringTable
->pSlots
[i
].pString
, lpString
))
240 if (!lstrcmpiW(pStringTable
->pSlots
[i
].pString
, lpString
))
248 /* Check for filled slot table */
249 if (pStringTable
->dwUsedSlots
== pStringTable
->dwMaxSlots
)
251 FIXME("Resize the string table!\n");
255 /* Search for an empty slot */
256 for (i
= 0; i
< pStringTable
->dwMaxSlots
; i
++)
258 if (pStringTable
->pSlots
[i
].pString
== NULL
)
260 pStringTable
->pSlots
[i
].pString
= MyMalloc((lstrlenW(lpString
) + 1) * sizeof(WCHAR
));
261 if (pStringTable
->pSlots
[i
].pString
== NULL
)
263 TRACE("Couldn't allocate memory for a new string!\n");
267 lstrcpyW(pStringTable
->pSlots
[i
].pString
, lpString
);
269 pStringTable
->dwUsedSlots
++;
275 TRACE("Couldn't find an empty slot!\n");
281 /**************************************************************************
282 * StringTableAddStringEx [SETUPAPI.@]
284 * Adds a new string plus extra data to the string table.
287 * hStringTable [I] Handle to the string table
288 * lpString [I] String to be added to the string table
290 * 1: case sensitive compare
291 * lpExtraData [I] Pointer to the extra data
292 * dwExtraDataSize [I] Size of the extra data
299 * If the given string already exists in the string table it will not
300 * be added again. The ID of the existing string will be returned in
304 StringTableAddStringEx(HSTRING_TABLE hStringTable
,
308 DWORD dwExtraDataSize
)
310 PSTRING_TABLE pStringTable
;
313 TRACE("%p %s %lx\n", (PVOID
)hStringTable
, debugstr_w(lpString
), dwFlags
);
315 pStringTable
= (PSTRING_TABLE
)hStringTable
;
316 if (pStringTable
== NULL
)
318 ERR("Invalid hStringTable!\n");
322 /* Search for existing string in the string table */
323 for (i
= 0; i
< pStringTable
->dwMaxSlots
; i
++)
325 if (pStringTable
->pSlots
[i
].pString
!= NULL
)
329 if (!lstrcmpW(pStringTable
->pSlots
[i
].pString
, lpString
))
336 if (!lstrcmpiW(pStringTable
->pSlots
[i
].pString
, lpString
))
344 /* Check for filled slot table */
345 if (pStringTable
->dwUsedSlots
== pStringTable
->dwMaxSlots
)
347 FIXME("Resize the string table!\n");
351 /* Search for an empty slot */
352 for (i
= 0; i
< pStringTable
->dwMaxSlots
; i
++)
354 if (pStringTable
->pSlots
[i
].pString
== NULL
)
356 pStringTable
->pSlots
[i
].pString
= MyMalloc((lstrlenW(lpString
) + 1) * sizeof(WCHAR
));
357 if (pStringTable
->pSlots
[i
].pString
== NULL
)
359 TRACE("Couldn't allocate memory for a new string!\n");
363 lstrcpyW(pStringTable
->pSlots
[i
].pString
, lpString
);
365 pStringTable
->pSlots
[i
].pData
= MyMalloc(dwExtraDataSize
);
366 if (pStringTable
->pSlots
[i
].pData
== NULL
)
368 TRACE("Couldn't allocate memory for a new extra data!\n");
369 MyFree(pStringTable
->pSlots
[i
].pString
);
370 pStringTable
->pSlots
[i
].pString
= NULL
;
374 memcpy(pStringTable
->pSlots
[i
].pData
,
377 pStringTable
->pSlots
[i
].dwSize
= dwExtraDataSize
;
379 pStringTable
->dwUsedSlots
++;
385 TRACE("Couldn't find an empty slot!\n");
391 /**************************************************************************
392 * StringTableDuplicate [SETUPAPI.@]
394 * Duplicates a given string table.
397 * hStringTable [I] Handle to the string table
400 * Success: Handle to the duplicated string table
405 StringTableDuplicate(HSTRING_TABLE hStringTable
)
407 PSTRING_TABLE pSourceTable
;
408 PSTRING_TABLE pDestinationTable
;
412 TRACE("%p\n", (PVOID
)hStringTable
);
414 pSourceTable
= (PSTRING_TABLE
)hStringTable
;
415 if (pSourceTable
== NULL
)
417 ERR("Invalid hStringTable!\n");
418 return (HSTRING_TABLE
)NULL
;
421 pDestinationTable
= MyMalloc(sizeof(STRING_TABLE
));
422 if (pDestinationTable
== NULL
)
424 ERR("Cound not allocate a new string table!\n");
425 return (HSTRING_TABLE
)NULL
;
428 memset(pDestinationTable
, 0, sizeof(STRING_TABLE
));
430 pDestinationTable
->pSlots
= MyMalloc(sizeof(TABLE_SLOT
) * pSourceTable
->dwMaxSlots
);
431 if (pDestinationTable
->pSlots
== NULL
)
433 MyFree(pDestinationTable
);
434 return (HSTRING_TABLE
)NULL
;
437 memset(pDestinationTable
->pSlots
, 0, sizeof(TABLE_SLOT
) * pSourceTable
->dwMaxSlots
);
439 pDestinationTable
->dwUsedSlots
= 0;
440 pDestinationTable
->dwMaxSlots
= pSourceTable
->dwMaxSlots
;
442 for (i
= 0; i
< pSourceTable
->dwMaxSlots
; i
++)
444 if (pSourceTable
->pSlots
[i
].pString
!= NULL
)
446 length
= (lstrlenW(pSourceTable
->pSlots
[i
].pString
) + 1) * sizeof(WCHAR
);
447 pDestinationTable
->pSlots
[i
].pString
= MyMalloc(length
);
448 if (pDestinationTable
->pSlots
[i
].pString
!= NULL
)
450 memcpy(pDestinationTable
->pSlots
[i
].pString
,
451 pSourceTable
->pSlots
[i
].pString
,
453 pDestinationTable
->dwUsedSlots
++;
456 if (pSourceTable
->pSlots
[i
].pData
!= NULL
)
458 length
= pSourceTable
->pSlots
[i
].dwSize
;
459 pDestinationTable
->pSlots
[i
].pData
= MyMalloc(length
);
460 if (pDestinationTable
->pSlots
[i
].pData
)
462 memcpy(pDestinationTable
->pSlots
[i
].pData
,
463 pSourceTable
->pSlots
[i
].pData
,
465 pDestinationTable
->pSlots
[i
].dwSize
= length
;
471 return (HSTRING_TABLE
)pDestinationTable
;
475 /**************************************************************************
476 * StringTableGetExtraData [SETUPAPI.@]
478 * Retrieves extra data from a given string table entry.
481 * hStringTable [I] Handle to the string table
483 * lpExtraData [I] Pointer a buffer that receives the extra data
484 * dwExtraDataSize [I] Size of the buffer
491 StringTableGetExtraData(HSTRING_TABLE hStringTable
,
494 DWORD dwExtraDataSize
)
496 PSTRING_TABLE pStringTable
;
498 TRACE("%p %lx %p %lu\n",
499 (PVOID
)hStringTable
, dwId
, lpExtraData
, dwExtraDataSize
);
501 pStringTable
= (PSTRING_TABLE
)hStringTable
;
502 if (pStringTable
== NULL
)
504 ERR("Invalid hStringTable!\n");
508 if (dwId
== 0 || dwId
> pStringTable
->dwMaxSlots
)
510 ERR("Invalid Slot id!\n");
514 if (pStringTable
->pSlots
[dwId
- 1].dwSize
< dwExtraDataSize
)
516 ERR("Data size is too large!\n");
521 pStringTable
->pSlots
[dwId
- 1].pData
,
528 /**************************************************************************
529 * StringTableLookUpString [SETUPAPI.@]
531 * Searches a string table for a given string.
534 * hStringTable [I] Handle to the string table
535 * lpString [I] String to be searched for
537 * 1: case sensitive compare
544 StringTableLookUpString(HSTRING_TABLE hStringTable
,
548 PSTRING_TABLE pStringTable
;
551 TRACE("%p %s %lx\n", (PVOID
)hStringTable
, debugstr_w(lpString
), dwFlags
);
553 pStringTable
= (PSTRING_TABLE
)hStringTable
;
554 if (pStringTable
== NULL
)
556 ERR("Invalid hStringTable!\n");
560 /* Search for existing string in the string table */
561 for (i
= 0; i
< pStringTable
->dwMaxSlots
; i
++)
563 if (pStringTable
->pSlots
[i
].pString
!= NULL
)
567 if (!lstrcmpW(pStringTable
->pSlots
[i
].pString
, lpString
))
572 if (!lstrcmpiW(pStringTable
->pSlots
[i
].pString
, lpString
))
582 /**************************************************************************
583 * StringTableLookUpStringEx [SETUPAPI.@]
585 * Searches a string table and extra data for a given string.
588 * hStringTable [I] Handle to the string table
589 * lpString [I] String to be searched for
591 * 1: case sensitive compare
592 * lpExtraData [O] Pointer to the buffer that receives the extra data
593 * lpReserved [I/O] Unused
600 StringTableLookUpStringEx(HSTRING_TABLE hStringTable
,
606 PSTRING_TABLE pStringTable
;
609 TRACE("%p %s %lx\n", (PVOID
)hStringTable
, debugstr_w(lpString
), dwFlags
);
611 pStringTable
= (PSTRING_TABLE
)hStringTable
;
612 if (pStringTable
== NULL
)
614 ERR("Invalid hStringTable!\n");
618 /* Search for existing string in the string table */
619 for (i
= 0; i
< pStringTable
->dwMaxSlots
; i
++)
621 if (pStringTable
->pSlots
[i
].pString
!= NULL
)
625 if (!lstrcmpW(pStringTable
->pSlots
[i
].pString
, lpString
))
628 pStringTable
->pSlots
[i
].pData
,
629 pStringTable
->pSlots
[i
].dwSize
);
636 if (!lstrcmpiW(pStringTable
->pSlots
[i
].pString
, lpString
))
639 pStringTable
->pSlots
[i
].pData
,
640 pStringTable
->pSlots
[i
].dwSize
);
652 /**************************************************************************
653 * StringTableSetExtraData [SETUPAPI.@]
655 * Sets extra data for a given string table entry.
658 * hStringTable [I] Handle to the string table
660 * lpExtraData [I] Pointer to the extra data
661 * dwExtraDataSize [I] Size of the extra data
668 StringTableSetExtraData(HSTRING_TABLE hStringTable
,
671 DWORD dwExtraDataSize
)
673 PSTRING_TABLE pStringTable
;
675 TRACE("%p %lx %p %lu\n",
676 (PVOID
)hStringTable
, dwId
, lpExtraData
, dwExtraDataSize
);
678 pStringTable
= (PSTRING_TABLE
)hStringTable
;
679 if (pStringTable
== NULL
)
681 ERR("Invalid hStringTable!\n");
685 if (dwId
== 0 || dwId
> pStringTable
->dwMaxSlots
)
687 ERR("Invalid Slot id!\n");
691 if (pStringTable
->dwMaxDataSize
< dwExtraDataSize
)
693 ERR("Data size is too large!\n");
697 pStringTable
->pSlots
[dwId
- 1].pData
= MyMalloc(dwExtraDataSize
);
698 if (pStringTable
->pSlots
[dwId
- 1].pData
== NULL
)
704 memcpy(pStringTable
->pSlots
[dwId
- 1].pData
,
707 pStringTable
->pSlots
[dwId
- 1].dwSize
= dwExtraDataSize
;
713 /**************************************************************************
714 * StringTableStringFromId [SETUPAPI.@]
716 * Returns a pointer to a string for the given string ID.
719 * hStringTable [I] Handle to the string table.
723 * Success: Pointer to the string
727 StringTableStringFromId(HSTRING_TABLE hStringTable
,
730 PSTRING_TABLE pStringTable
;
732 TRACE("%p %lx\n", (PVOID
)hStringTable
, dwId
);
734 pStringTable
= (PSTRING_TABLE
)hStringTable
;
735 if (pStringTable
== NULL
)
737 ERR("Invalid hStringTable!\n");
741 if (dwId
== 0 || dwId
> pStringTable
->dwMaxSlots
)
744 return pStringTable
->pSlots
[dwId
- 1].pString
;
748 /**************************************************************************
749 * StringTableStringFromIdEx [SETUPAPI.@]
751 * Returns a string for the given string ID.
754 * hStringTable [I] Handle to the string table
756 * lpBuffer [I] Pointer to string buffer
757 * lpBufferSize [I/O] Pointer to the size of the string buffer
764 StringTableStringFromIdEx(HSTRING_TABLE hStringTable
,
767 LPDWORD lpBufferLength
)
769 PSTRING_TABLE pStringTable
;
771 BOOL bResult
= FALSE
;
773 TRACE("%p %lx %p %p\n",
774 (PVOID
)hStringTable
, dwId
, lpBuffer
, lpBufferLength
);
776 pStringTable
= (PSTRING_TABLE
)hStringTable
;
777 if (pStringTable
== NULL
)
779 ERR("Invalid hStringTable!\n");
784 if (dwId
== 0 || dwId
> pStringTable
->dwMaxSlots
||
785 pStringTable
->pSlots
[dwId
- 1].pString
== NULL
)
787 WARN("Invalid string ID!\n");
792 dwLength
= (lstrlenW(pStringTable
->pSlots
[dwId
- 1].pString
) + 1) * sizeof(WCHAR
);
793 if (dwLength
<= *lpBufferLength
)
795 lstrcpyW(lpBuffer
, pStringTable
->pSlots
[dwId
- 1].pString
);
799 *lpBufferLength
= dwLength
;
805 /**************************************************************************
806 * StringTableTrim [SETUPAPI.@]
811 * hStringTable [I] Handle to the string table
817 StringTableTrim(HSTRING_TABLE hStringTable
)
819 FIXME("%p\n", (PVOID
)hStringTable
);