shell32: Fix the file version string of the version resource.
[wine/multimedia.git] / dlls / setupapi / stringtable.c
blob35d6f402002716cf7f75d325bfad0abbb10908d7
1 /*
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
21 #include "config.h"
22 #include "wine/port.h"
24 #include <stdarg.h>
26 #include "windef.h"
27 #include "winbase.h"
28 #include "wingdi.h"
29 #include "winuser.h"
30 #include "winreg.h"
31 #include "setupapi.h"
33 #include "wine/debug.h"
36 #define TABLE_DEFAULT_SIZE 256
38 WINE_DEFAULT_DEBUG_CHANNEL(setupapi);
40 typedef struct _TABLE_SLOT
42 LPWSTR pString;
43 LPVOID pData;
44 DWORD dwSize;
45 } TABLE_SLOT, *PTABLE_SLOT;
47 typedef struct _STRING_TABLE
49 PTABLE_SLOT pSlots;
50 DWORD dwUsedSlots;
51 DWORD dwMaxSlots;
52 DWORD dwMaxDataSize;
53 } STRING_TABLE, *PSTRING_TABLE;
56 /**************************************************************************
57 * StringTableInitialize [SETUPAPI.@]
59 * Creates a new string table and initializes it.
61 * PARAMS
62 * None
64 * RETURNS
65 * Success: Handle to the string table
66 * Failure: NULL
68 HSTRING_TABLE WINAPI
69 StringTableInitialize(VOID)
71 PSTRING_TABLE pStringTable;
73 TRACE("\n");
75 pStringTable = MyMalloc(sizeof(STRING_TABLE));
76 if (pStringTable == NULL)
78 ERR("Invalid hStringTable!\n");
79 return NULL;
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);
88 return NULL;
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;
97 TRACE("Done\n");
99 return (HSTRING_TABLE)pStringTable;
103 /**************************************************************************
104 * StringTableInitializeEx [SETUPAPI.@]
106 * Creates a new string table and initializes it.
108 * PARAMS
109 * dwMaxExtraDataSize [I] Maximum extra data size
110 * dwReserved [I] Unused
112 * RETURNS
113 * Success: Handle to the string table
114 * Failure: NULL
116 HSTRING_TABLE WINAPI
117 StringTableInitializeEx(DWORD dwMaxExtraDataSize,
118 DWORD dwReserved)
120 PSTRING_TABLE pStringTable;
122 TRACE("\n");
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);
133 return NULL;
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;
142 TRACE("Done\n");
144 return (HSTRING_TABLE)pStringTable;
148 /**************************************************************************
149 * StringTableDestroy [SETUPAPI.@]
151 * Destroys a string table.
153 * PARAMS
154 * hStringTable [I] Handle to the string table to be destroyed
156 * RETURNS
157 * None
159 VOID WINAPI
160 StringTableDestroy(HSTRING_TABLE hStringTable)
162 PSTRING_TABLE pStringTable;
163 DWORD i;
165 TRACE("%p\n", hStringTable);
167 pStringTable = (PSTRING_TABLE)hStringTable;
168 if (pStringTable == NULL)
169 return;
171 if (pStringTable->pSlots != NULL)
173 for (i = 0; i < pStringTable->dwMaxSlots; i++)
175 if (pStringTable->pSlots[i].pString != NULL)
177 MyFree(pStringTable->pSlots[i].pString);
178 pStringTable->pSlots[i].pString = NULL;
181 if (pStringTable->pSlots[i].pData != NULL)
183 MyFree(pStringTable->pSlots[i].pData);
184 pStringTable->pSlots[i].pData = NULL;
185 pStringTable->pSlots[i].dwSize = 0;
189 MyFree(pStringTable->pSlots);
192 MyFree(pStringTable);
196 /**************************************************************************
197 * StringTableAddString [SETUPAPI.@]
199 * Adds a new string to the string table.
201 * PARAMS
202 * hStringTable [I] Handle to the string table
203 * lpString [I] String to be added to the string table
204 * dwFlags [I] Flags
205 * 1: case sensitive compare
207 * RETURNS
208 * Success: String ID
209 * Failure: -1
211 * NOTES
212 * If the given string already exists in the string table it will not
213 * be added again. The ID of the existing string will be returned in
214 * this case.
216 DWORD WINAPI
217 StringTableAddString(HSTRING_TABLE hStringTable,
218 LPWSTR lpString,
219 DWORD dwFlags)
221 PSTRING_TABLE pStringTable;
222 DWORD i;
224 TRACE("%p %s %lx\n", hStringTable, debugstr_w(lpString), dwFlags);
226 pStringTable = (PSTRING_TABLE)hStringTable;
227 if (pStringTable == NULL)
229 ERR("Invalid hStringTable!\n");
230 return (DWORD)-1;
233 /* Search for existing string in the string table */
234 for (i = 0; i < pStringTable->dwMaxSlots; i++)
236 if (pStringTable->pSlots[i].pString != NULL)
238 if (dwFlags & 1)
240 if (!lstrcmpW(pStringTable->pSlots[i].pString, lpString))
242 return i + 1;
245 else
247 if (!lstrcmpiW(pStringTable->pSlots[i].pString, lpString))
249 return i + 1;
255 /* Check for filled slot table */
256 if (pStringTable->dwUsedSlots == pStringTable->dwMaxSlots)
258 FIXME("Resize the string table!\n");
259 return (DWORD)-1;
262 /* Search for an empty slot */
263 for (i = 0; i < pStringTable->dwMaxSlots; i++)
265 if (pStringTable->pSlots[i].pString == NULL)
267 pStringTable->pSlots[i].pString = MyMalloc((lstrlenW(lpString) + 1) * sizeof(WCHAR));
268 if (pStringTable->pSlots[i].pString == NULL)
270 TRACE("Couldn't allocate memory for a new string!\n");
271 return (DWORD)-1;
274 lstrcpyW(pStringTable->pSlots[i].pString, lpString);
276 pStringTable->dwUsedSlots++;
278 return i + 1;
282 TRACE("Couldn't find an empty slot!\n");
284 return (DWORD)-1;
288 /**************************************************************************
289 * StringTableAddStringEx [SETUPAPI.@]
291 * Adds a new string plus extra data to the string table.
293 * PARAMS
294 * hStringTable [I] Handle to the string table
295 * lpString [I] String to be added to the string table
296 * dwFlags [I] Flags
297 * 1: case sensitive compare
298 * lpExtraData [I] Pointer to the extra data
299 * dwExtraDataSize [I] Size of the extra data
301 * RETURNS
302 * Success: String ID
303 * Failure: -1
305 * NOTES
306 * If the given string already exists in the string table it will not
307 * be added again. The ID of the existing string will be returned in
308 * this case.
310 DWORD WINAPI
311 StringTableAddStringEx(HSTRING_TABLE hStringTable,
312 LPWSTR lpString,
313 DWORD dwFlags,
314 LPVOID lpExtraData,
315 DWORD dwExtraDataSize)
317 FIXME("\n");
318 return (DWORD)-1;
322 /**************************************************************************
323 * StringTableDuplicate [SETUPAPI.@]
325 * Duplicates a given string table.
327 * PARAMS
328 * hStringTable [I] Handle to the string table
330 * RETURNS
331 * Success: Handle to the duplicated string table
332 * Failure: NULL
335 HSTRING_TABLE WINAPI
336 StringTableDuplicate(HSTRING_TABLE hStringTable)
338 PSTRING_TABLE pSourceTable;
339 PSTRING_TABLE pDestinationTable;
340 DWORD i;
341 DWORD length;
343 TRACE("%p\n", hStringTable);
345 pSourceTable = (PSTRING_TABLE)hStringTable;
346 if (pSourceTable == NULL)
348 ERR("Invalid hStringTable!\n");
349 return (HSTRING_TABLE)NULL;
352 pDestinationTable = MyMalloc(sizeof(STRING_TABLE));
353 if (pDestinationTable == NULL)
355 ERR("Cound not allocate a new string table!\n");
356 return (HSTRING_TABLE)NULL;
359 memset(pDestinationTable, 0, sizeof(STRING_TABLE));
361 pDestinationTable->pSlots = MyMalloc(sizeof(TABLE_SLOT) * pSourceTable->dwMaxSlots);
362 if (pDestinationTable->pSlots == NULL)
364 MyFree(pDestinationTable);
365 return (HSTRING_TABLE)NULL;
368 memset(pDestinationTable->pSlots, 0, sizeof(TABLE_SLOT) * pSourceTable->dwMaxSlots);
370 pDestinationTable->dwUsedSlots = 0;
371 pDestinationTable->dwMaxSlots = pSourceTable->dwMaxSlots;
373 for (i = 0; i < pSourceTable->dwMaxSlots; i++)
375 if (pSourceTable->pSlots[i].pString != NULL)
377 length = (lstrlenW(pSourceTable->pSlots[i].pString) + 1) * sizeof(WCHAR);
378 pDestinationTable->pSlots[i].pString = MyMalloc(length);
379 if (pDestinationTable->pSlots[i].pString != NULL)
381 memcpy(pDestinationTable->pSlots[i].pString,
382 pSourceTable->pSlots[i].pString,
383 length);
384 pDestinationTable->dwUsedSlots++;
387 if (pSourceTable->pSlots[i].pData != NULL)
389 length = pSourceTable->pSlots[i].dwSize;
390 pDestinationTable->pSlots[i].pData = MyMalloc(length);
391 if (pDestinationTable->pSlots[i].pData)
393 memcpy(pDestinationTable->pSlots[i].pData,
394 pSourceTable->pSlots[i].pData,
395 length);
396 pDestinationTable->pSlots[i].dwSize = length;
402 return (HSTRING_TABLE)pDestinationTable;
406 /**************************************************************************
407 * StringTableGetExtraData [SETUPAPI.@]
409 * Retrieves extra data from a given string table entry.
411 * PARAMS
412 * hStringTable [I] Handle to the string table
413 * dwId [I] String ID
414 * lpExtraData [I] Pointer a buffer that receives the extra data
415 * dwExtraDataSize [I] Size of the buffer
417 * RETURNS
418 * Success: TRUE
419 * Failure: FALSE
421 BOOL WINAPI
422 StringTableGetExtraData(HSTRING_TABLE hStringTable,
423 DWORD dwId,
424 LPVOID lpExtraData,
425 DWORD dwExtraDataSize)
427 PSTRING_TABLE pStringTable;
429 TRACE("%p %lx %p %lu\n",
430 hStringTable, dwId, lpExtraData, dwExtraDataSize);
432 pStringTable = (PSTRING_TABLE)hStringTable;
433 if (pStringTable == NULL)
435 ERR("Invalid hStringTable!\n");
436 return FALSE;
439 if (dwId == 0 || dwId > pStringTable->dwMaxSlots)
441 ERR("Invalid Slot id!\n");
442 return FALSE;
445 if (pStringTable->pSlots[dwId - 1].dwSize < dwExtraDataSize)
447 ERR("Data size is too large!\n");
448 return FALSE;
451 memcpy(lpExtraData,
452 pStringTable->pSlots[dwId - 1].pData,
453 dwExtraDataSize);
455 return TRUE;
459 /**************************************************************************
460 * StringTableLookUpString [SETUPAPI.@]
462 * Searches a string table for a given string.
464 * PARAMS
465 * hStringTable [I] Handle to the string table
466 * lpString [I] String to be searched for
467 * dwFlags [I] Flags
468 * 1: case sensitive compare
470 * RETURNS
471 * Success: String ID
472 * Failure: -1
474 DWORD WINAPI
475 StringTableLookUpString(HSTRING_TABLE hStringTable,
476 LPWSTR lpString,
477 DWORD dwFlags)
479 PSTRING_TABLE pStringTable;
480 DWORD i;
482 TRACE("%p %s %lx\n", hStringTable, debugstr_w(lpString), dwFlags);
484 pStringTable = (PSTRING_TABLE)hStringTable;
485 if (pStringTable == NULL)
487 ERR("Invalid hStringTable!\n");
488 return (DWORD)-1;
491 /* Search for existing string in the string table */
492 for (i = 0; i < pStringTable->dwMaxSlots; i++)
494 if (pStringTable->pSlots[i].pString != NULL)
496 if (dwFlags & 1)
498 if (!lstrcmpW(pStringTable->pSlots[i].pString, lpString))
499 return i + 1;
501 else
503 if (!lstrcmpiW(pStringTable->pSlots[i].pString, lpString))
504 return i + 1;
509 return (DWORD)-1;
513 /**************************************************************************
514 * StringTableLookUpStringEx [SETUPAPI.@]
516 * Searches a string table and extra data for a given string.
518 * PARAMS
519 * hStringTable [I] Handle to the string table
520 * lpString [I] String to be searched for
521 * dwFlags [I] Flags
522 * 1: case sensitive compare
523 * lpExtraData [O] Pointer to the buffer that receives the extra data
524 * lpReserved [I/O] Unused
526 * RETURNS
527 * Success: String ID
528 * Failure: -1
530 DWORD WINAPI
531 StringTableLookUpStringEx(HSTRING_TABLE hStringTable,
532 LPWSTR lpString,
533 DWORD dwFlags,
534 LPVOID lpExtraData,
535 LPDWORD lpReserved)
537 FIXME("\n");
538 return (DWORD)-1;
542 /**************************************************************************
543 * StringTableSetExtraData [SETUPAPI.@]
545 * Sets extra data for a given string table entry.
547 * PARAMS
548 * hStringTable [I] Handle to the string table
549 * dwId [I] String ID
550 * lpExtraData [I] Pointer to the extra data
551 * dwExtraDataSize [I] Size of the extra data
553 * RETURNS
554 * Success: TRUE
555 * Failure: FALSE
557 BOOL WINAPI
558 StringTableSetExtraData(HSTRING_TABLE hStringTable,
559 DWORD dwId,
560 LPVOID lpExtraData,
561 DWORD dwExtraDataSize)
563 PSTRING_TABLE pStringTable;
565 TRACE("%p %lx %p %lu\n",
566 hStringTable, dwId, lpExtraData, dwExtraDataSize);
568 pStringTable = (PSTRING_TABLE)hStringTable;
569 if (pStringTable == NULL)
571 ERR("Invalid hStringTable!\n");
572 return FALSE;
575 if (dwId == 0 || dwId > pStringTable->dwMaxSlots)
577 ERR("Invalid Slot id!\n");
578 return FALSE;
581 if (pStringTable->dwMaxDataSize < dwExtraDataSize)
583 ERR("Data size is too large!\n");
584 return FALSE;
587 pStringTable->pSlots[dwId - 1].pData = MyMalloc(dwExtraDataSize);
588 if (pStringTable->pSlots[dwId - 1].pData == NULL)
590 ERR("\n");
591 return FALSE;
594 memcpy(pStringTable->pSlots[dwId - 1].pData,
595 lpExtraData,
596 dwExtraDataSize);
597 pStringTable->pSlots[dwId - 1].dwSize = dwExtraDataSize;
599 return TRUE;
603 /**************************************************************************
604 * StringTableStringFromId [SETUPAPI.@]
606 * Returns a pointer to a string for the given string ID.
608 * PARAMS
609 * hStringTable [I] Handle to the string table.
610 * dwId [I] String ID
612 * RETURNS
613 * Success: Pointer to the string
614 * Failure: NULL
616 LPWSTR WINAPI
617 StringTableStringFromId(HSTRING_TABLE hStringTable,
618 DWORD dwId)
620 PSTRING_TABLE pStringTable;
621 static WCHAR empty[] = {0};
623 TRACE("%p %lx\n", hStringTable, dwId);
625 pStringTable = (PSTRING_TABLE)hStringTable;
626 if (pStringTable == NULL)
628 ERR("Invalid hStringTable!\n");
629 return NULL;
632 if (dwId == 0 || dwId > pStringTable->dwMaxSlots)
633 return empty;
635 return pStringTable->pSlots[dwId - 1].pString;
639 /**************************************************************************
640 * StringTableStringFromIdEx [SETUPAPI.@]
642 * Returns a string for the given string ID.
644 * PARAMS
645 * hStringTable [I] Handle to the string table
646 * dwId [I] String ID
647 * lpBuffer [I] Pointer to string buffer
648 * lpBufferSize [I/O] Pointer to the size of the string buffer
650 * RETURNS
651 * Success: TRUE
652 * Failure: FALSE
654 BOOL WINAPI
655 StringTableStringFromIdEx(HSTRING_TABLE hStringTable,
656 DWORD dwId,
657 LPWSTR lpBuffer,
658 LPDWORD lpBufferLength)
660 PSTRING_TABLE pStringTable;
661 DWORD dwLength;
662 BOOL bResult = FALSE;
664 TRACE("%p %lx %p %p\n", hStringTable, dwId, lpBuffer, lpBufferLength);
666 pStringTable = (PSTRING_TABLE)hStringTable;
667 if (pStringTable == NULL)
669 ERR("Invalid hStringTable!\n");
670 *lpBufferLength = 0;
671 return FALSE;
674 if (dwId == 0 || dwId > pStringTable->dwMaxSlots ||
675 pStringTable->pSlots[dwId - 1].pString == NULL)
677 WARN("Invalid string ID!\n");
678 *lpBufferLength = 0;
679 return FALSE;
682 dwLength = (lstrlenW(pStringTable->pSlots[dwId - 1].pString) + 1) * sizeof(WCHAR);
683 if (dwLength <= *lpBufferLength)
685 lstrcpyW(lpBuffer, pStringTable->pSlots[dwId - 1].pString);
686 bResult = TRUE;
689 *lpBufferLength = dwLength;
691 return bResult;
695 /**************************************************************************
696 * StringTableTrim [SETUPAPI.@]
698 * ...
700 * PARAMS
701 * hStringTable [I] Handle to the string table
703 * RETURNS
704 * None
706 VOID WINAPI
707 StringTableTrim(HSTRING_TABLE hStringTable)
709 FIXME("%p\n", hStringTable);