Reactos
at master 797 lines 22 kB view raw
1/* 2 * Setupapi string table functions 3 * 4 * Copyright 2005 Eric Kohl 5 * 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. 10 * 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. 15 * 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 19 */ 20 21#include "setupapi_private.h" 22 23#define TABLE_DEFAULT_SIZE 256 24 25typedef struct _TABLE_SLOT 26{ 27 LPWSTR pString; 28 LPVOID pData; 29 DWORD dwSize; 30} TABLE_SLOT, *PTABLE_SLOT; 31 32typedef struct _STRING_TABLE 33{ 34 PTABLE_SLOT pSlots; 35 DWORD dwUsedSlots; 36 DWORD dwMaxSlots; 37 DWORD dwMaxDataSize; 38} STRING_TABLE, *PSTRING_TABLE; 39 40 41/************************************************************************** 42 * pSetupStringTableInitialize [SETUPAPI.@] 43 * 44 * Creates a new string table and initializes it. 45 * 46 * PARAMS 47 * None 48 * 49 * RETURNS 50 * Success: Handle to the string table 51 * Failure: NULL 52 */ 53HSTRING_TABLE WINAPI 54pSetupStringTableInitialize(VOID) 55{ 56 PSTRING_TABLE pStringTable; 57 58 TRACE("\n"); 59 60 pStringTable = MyMalloc(sizeof(STRING_TABLE)); 61 if (pStringTable == NULL) 62 { 63 ERR("Invalid hStringTable!\n"); 64 return NULL; 65 } 66 67 memset(pStringTable, 0, sizeof(STRING_TABLE)); 68 69 pStringTable->pSlots = MyMalloc(sizeof(TABLE_SLOT) * TABLE_DEFAULT_SIZE); 70 if (pStringTable->pSlots == NULL) 71 { 72 MyFree(pStringTable); 73 return NULL; 74 } 75 76 memset(pStringTable->pSlots, 0, sizeof(TABLE_SLOT) * TABLE_DEFAULT_SIZE); 77 78 pStringTable->dwUsedSlots = 0; 79 pStringTable->dwMaxSlots = TABLE_DEFAULT_SIZE; 80 pStringTable->dwMaxDataSize = 0; 81 82 TRACE("Done\n"); 83 84 return (HSTRING_TABLE)pStringTable; 85} 86 87 88/************************************************************************** 89 * pSetupStringTableInitializeEx [SETUPAPI.@] 90 * 91 * Creates a new string table and initializes it. 92 * 93 * PARAMS 94 * dwMaxExtraDataSize [I] Maximum extra data size 95 * dwReserved [I] Unused 96 * 97 * RETURNS 98 * Success: Handle to the string table 99 * Failure: NULL 100 */ 101HSTRING_TABLE WINAPI 102pSetupStringTableInitializeEx(DWORD dwMaxExtraDataSize, 103 DWORD dwReserved) 104{ 105 PSTRING_TABLE pStringTable; 106 107 TRACE("\n"); 108 109 pStringTable = MyMalloc(sizeof(STRING_TABLE)); 110 if (pStringTable == NULL) return NULL; 111 112 memset(pStringTable, 0, sizeof(STRING_TABLE)); 113 114 pStringTable->pSlots = MyMalloc(sizeof(TABLE_SLOT) * TABLE_DEFAULT_SIZE); 115 if (pStringTable->pSlots == NULL) 116 { 117 MyFree(pStringTable); 118 return NULL; 119 } 120 121 memset(pStringTable->pSlots, 0, sizeof(TABLE_SLOT) * TABLE_DEFAULT_SIZE); 122 123 pStringTable->dwUsedSlots = 0; 124 pStringTable->dwMaxSlots = TABLE_DEFAULT_SIZE; 125 pStringTable->dwMaxDataSize = dwMaxExtraDataSize; 126 127 TRACE("Done\n"); 128 129 return (HSTRING_TABLE)pStringTable; 130} 131 132 133/************************************************************************** 134 * pSetupStringTableDestroy [SETUPAPI.@] 135 * 136 * Destroys a string table. 137 * 138 * PARAMS 139 * hStringTable [I] Handle to the string table to be destroyed 140 * 141 * RETURNS 142 * None 143 */ 144VOID WINAPI 145pSetupStringTableDestroy(HSTRING_TABLE hStringTable) 146{ 147 PSTRING_TABLE pStringTable; 148 DWORD i; 149 150 TRACE("%p\n", hStringTable); 151 152 pStringTable = (PSTRING_TABLE)hStringTable; 153 if (pStringTable == NULL) 154 return; 155 156 if (pStringTable->pSlots != NULL) 157 { 158 for (i = 0; i < pStringTable->dwMaxSlots; i++) 159 { 160 MyFree(pStringTable->pSlots[i].pString); 161 pStringTable->pSlots[i].pString = NULL; 162 163 MyFree(pStringTable->pSlots[i].pData); 164 pStringTable->pSlots[i].pData = NULL; 165 pStringTable->pSlots[i].dwSize = 0; 166 } 167 168 MyFree(pStringTable->pSlots); 169 } 170 171 MyFree(pStringTable); 172} 173 174 175/************************************************************************** 176 * pSetupStringTableAddString [SETUPAPI.@] 177 * 178 * Adds a new string to the string table. 179 * 180 * PARAMS 181 * hStringTable [I] Handle to the string table 182 * lpString [I] String to be added to the string table 183 * dwFlags [I] Flags 184 * 1: case sensitive compare 185 * 186 * RETURNS 187 * Success: String ID 188 * Failure: -1 189 * 190 * NOTES 191 * If the given string already exists in the string table it will not 192 * be added again. The ID of the existing string will be returned in 193 * this case. 194 */ 195DWORD WINAPI 196pSetupStringTableAddString(HSTRING_TABLE hStringTable, 197 LPWSTR lpString, 198 DWORD dwFlags) 199{ 200 PSTRING_TABLE pStringTable; 201 DWORD i; 202 203 TRACE("%p %s %x\n", hStringTable, debugstr_w(lpString), dwFlags); 204 205 pStringTable = (PSTRING_TABLE)hStringTable; 206 if (pStringTable == NULL) 207 { 208 ERR("Invalid hStringTable!\n"); 209 return (DWORD)-1; 210 } 211 212 /* Search for existing string in the string table */ 213 for (i = 0; i < pStringTable->dwMaxSlots; i++) 214 { 215 if (pStringTable->pSlots[i].pString != NULL) 216 { 217 if (dwFlags & 1) 218 { 219 if (!lstrcmpW(pStringTable->pSlots[i].pString, lpString)) 220 { 221 return i + 1; 222 } 223 } 224 else 225 { 226 if (!lstrcmpiW(pStringTable->pSlots[i].pString, lpString)) 227 { 228 return i + 1; 229 } 230 } 231 } 232 } 233 234 /* Check for filled slot table */ 235 if (pStringTable->dwUsedSlots == pStringTable->dwMaxSlots) 236 { 237 PTABLE_SLOT pNewSlots; 238 DWORD dwNewMaxSlots; 239 240 /* FIXME: not thread safe */ 241 dwNewMaxSlots = pStringTable->dwMaxSlots * 2; 242 pNewSlots = MyMalloc(sizeof(TABLE_SLOT) * dwNewMaxSlots); 243 if (pNewSlots == NULL) 244 return (DWORD)-1; 245 memset(&pNewSlots[pStringTable->dwMaxSlots], 0, sizeof(TABLE_SLOT) * (dwNewMaxSlots - pStringTable->dwMaxSlots)); 246 memcpy(pNewSlots, pStringTable->pSlots, sizeof(TABLE_SLOT) * pStringTable->dwMaxSlots); 247 pNewSlots = InterlockedExchangePointer((PVOID*)&pStringTable->pSlots, pNewSlots); 248 MyFree(pNewSlots); 249 pStringTable->dwMaxSlots = dwNewMaxSlots; 250 251 return pSetupStringTableAddString(hStringTable, lpString, dwFlags); 252 } 253 254 /* Search for an empty slot */ 255 for (i = 0; i < pStringTable->dwMaxSlots; i++) 256 { 257 if (pStringTable->pSlots[i].pString == NULL) 258 { 259 pStringTable->pSlots[i].pString = MyMalloc((lstrlenW(lpString) + 1) * sizeof(WCHAR)); 260 if (pStringTable->pSlots[i].pString == NULL) 261 { 262 TRACE("Couldn't allocate memory for a new string!\n"); 263 return (DWORD)-1; 264 } 265 266 lstrcpyW(pStringTable->pSlots[i].pString, lpString); 267 268 pStringTable->dwUsedSlots++; 269 270 return i + 1; 271 } 272 } 273 274 TRACE("Couldn't find an empty slot!\n"); 275 276 return (DWORD)-1; 277} 278 279 280/************************************************************************** 281 * pSetupStringTableAddStringEx [SETUPAPI.@] 282 * 283 * Adds a new string plus extra data to the string table. 284 * 285 * PARAMS 286 * hStringTable [I] Handle to the string table 287 * lpString [I] String to be added to the string table 288 * dwFlags [I] Flags 289 * 1: case sensitive compare 290 * lpExtraData [I] Pointer to the extra data 291 * dwExtraDataSize [I] Size of the extra data 292 * 293 * RETURNS 294 * Success: String ID 295 * Failure: -1 296 * 297 * NOTES 298 * If the given string already exists in the string table it will not 299 * be added again. The ID of the existing string will be returned in 300 * this case. 301 */ 302DWORD WINAPI 303pSetupStringTableAddStringEx(HSTRING_TABLE hStringTable, 304 LPWSTR lpString, 305 DWORD dwFlags, 306 LPVOID lpExtraData, 307 DWORD dwExtraDataSize) 308{ 309 PSTRING_TABLE pStringTable; 310 DWORD i; 311 312 TRACE("%p %s %lx\n", (PVOID)hStringTable, debugstr_w(lpString), dwFlags); 313 314 pStringTable = (PSTRING_TABLE)hStringTable; 315 if (pStringTable == NULL) 316 { 317 ERR("Invalid hStringTable!\n"); 318 return (DWORD)-1; 319 } 320 321 /* Search for existing string in the string table */ 322 for (i = 0; i < pStringTable->dwMaxSlots; i++) 323 { 324 if (pStringTable->pSlots[i].pString != NULL) 325 { 326 if (dwFlags & 1) 327 { 328 if (!lstrcmpW(pStringTable->pSlots[i].pString, lpString)) 329 { 330 return i + 1; 331 } 332 } 333 else 334 { 335 if (!lstrcmpiW(pStringTable->pSlots[i].pString, lpString)) 336 { 337 return i + 1; 338 } 339 } 340 } 341 } 342 343 /* Check for filled slot table */ 344 if (pStringTable->dwUsedSlots == pStringTable->dwMaxSlots) 345 { 346 FIXME("Resize the string table!\n"); 347 return (DWORD)-1; 348 } 349 350 /* Search for an empty slot */ 351 for (i = 0; i < pStringTable->dwMaxSlots; i++) 352 { 353 if (pStringTable->pSlots[i].pString == NULL) 354 { 355 pStringTable->pSlots[i].pString = MyMalloc((lstrlenW(lpString) + 1) * sizeof(WCHAR)); 356 if (pStringTable->pSlots[i].pString == NULL) 357 { 358 TRACE("Couldn't allocate memory for a new string!\n"); 359 return (DWORD)-1; 360 } 361 362 lstrcpyW(pStringTable->pSlots[i].pString, lpString); 363 364 pStringTable->pSlots[i].pData = MyMalloc(dwExtraDataSize); 365 if (pStringTable->pSlots[i].pData == NULL) 366 { 367 TRACE("Couldn't allocate memory for a new extra data!\n"); 368 MyFree(pStringTable->pSlots[i].pString); 369 pStringTable->pSlots[i].pString = NULL; 370 return (DWORD)-1; 371 } 372 373 memcpy(pStringTable->pSlots[i].pData, 374 lpExtraData, 375 dwExtraDataSize); 376 pStringTable->pSlots[i].dwSize = dwExtraDataSize; 377 378 pStringTable->dwUsedSlots++; 379 380 return i + 1; 381 } 382 } 383 384 TRACE("Couldn't find an empty slot!\n"); 385 386 return (DWORD)-1; 387} 388 389 390/************************************************************************** 391 * pSetupStringTableDuplicate [SETUPAPI.@] 392 * 393 * Duplicates a given string table. 394 * 395 * PARAMS 396 * hStringTable [I] Handle to the string table 397 * 398 * RETURNS 399 * Success: Handle to the duplicated string table 400 * Failure: NULL 401 * 402 */ 403HSTRING_TABLE WINAPI 404pSetupStringTableDuplicate(HSTRING_TABLE hStringTable) 405{ 406 PSTRING_TABLE pSourceTable; 407 PSTRING_TABLE pDestinationTable; 408 DWORD i; 409 DWORD length; 410 411 TRACE("%p\n", hStringTable); 412 413 pSourceTable = (PSTRING_TABLE)hStringTable; 414 if (pSourceTable == NULL) 415 { 416 ERR("Invalid hStringTable!\n"); 417 return (HSTRING_TABLE)NULL; 418 } 419 420 pDestinationTable = MyMalloc(sizeof(STRING_TABLE)); 421 if (pDestinationTable == NULL) 422 { 423 ERR("Could not allocate a new string table!\n"); 424 return (HSTRING_TABLE)NULL; 425 } 426 427 memset(pDestinationTable, 0, sizeof(STRING_TABLE)); 428 429 pDestinationTable->pSlots = MyMalloc(sizeof(TABLE_SLOT) * pSourceTable->dwMaxSlots); 430 if (pDestinationTable->pSlots == NULL) 431 { 432 MyFree(pDestinationTable); 433 return (HSTRING_TABLE)NULL; 434 } 435 436 memset(pDestinationTable->pSlots, 0, sizeof(TABLE_SLOT) * pSourceTable->dwMaxSlots); 437 438 pDestinationTable->dwUsedSlots = 0; 439 pDestinationTable->dwMaxSlots = pSourceTable->dwMaxSlots; 440 441 for (i = 0; i < pSourceTable->dwMaxSlots; i++) 442 { 443 if (pSourceTable->pSlots[i].pString != NULL) 444 { 445 length = (lstrlenW(pSourceTable->pSlots[i].pString) + 1) * sizeof(WCHAR); 446 pDestinationTable->pSlots[i].pString = MyMalloc(length); 447 if (pDestinationTable->pSlots[i].pString != NULL) 448 { 449 memcpy(pDestinationTable->pSlots[i].pString, 450 pSourceTable->pSlots[i].pString, 451 length); 452 pDestinationTable->dwUsedSlots++; 453 } 454 455 if (pSourceTable->pSlots[i].pData != NULL) 456 { 457 length = pSourceTable->pSlots[i].dwSize; 458 pDestinationTable->pSlots[i].pData = MyMalloc(length); 459 if (pDestinationTable->pSlots[i].pData) 460 { 461 memcpy(pDestinationTable->pSlots[i].pData, 462 pSourceTable->pSlots[i].pData, 463 length); 464 pDestinationTable->pSlots[i].dwSize = length; 465 } 466 } 467 } 468 } 469 470 return (HSTRING_TABLE)pDestinationTable; 471} 472 473 474/************************************************************************** 475 * pSetupStringTableGetExtraData [SETUPAPI.@] 476 * 477 * Retrieves extra data from a given string table entry. 478 * 479 * PARAMS 480 * hStringTable [I] Handle to the string table 481 * dwId [I] String ID 482 * lpExtraData [I] Pointer a buffer that receives the extra data 483 * dwExtraDataSize [I] Size of the buffer 484 * 485 * RETURNS 486 * Success: TRUE 487 * Failure: FALSE 488 */ 489BOOL WINAPI 490pSetupStringTableGetExtraData(HSTRING_TABLE hStringTable, 491 DWORD dwId, 492 LPVOID lpExtraData, 493 DWORD dwExtraDataSize) 494{ 495 PSTRING_TABLE pStringTable; 496 497 TRACE("%p %x %p %u\n", 498 hStringTable, dwId, lpExtraData, dwExtraDataSize); 499 500 pStringTable = (PSTRING_TABLE)hStringTable; 501 if (pStringTable == NULL) 502 { 503 ERR("Invalid hStringTable!\n"); 504 return FALSE; 505 } 506 507 if (dwId == 0 || dwId > pStringTable->dwMaxSlots) 508 { 509 ERR("Invalid Slot id!\n"); 510 return FALSE; 511 } 512 513 if (pStringTable->pSlots[dwId - 1].dwSize < dwExtraDataSize) 514 { 515 ERR("Data size is too large!\n"); 516 return FALSE; 517 } 518 519 memcpy(lpExtraData, 520 pStringTable->pSlots[dwId - 1].pData, 521 dwExtraDataSize); 522 523 return TRUE; 524} 525 526 527/************************************************************************** 528 * pSetupStringTableLookUpString [SETUPAPI.@] 529 * 530 * Searches a string table for a given string. 531 * 532 * PARAMS 533 * hStringTable [I] Handle to the string table 534 * lpString [I] String to be searched for 535 * dwFlags [I] Flags 536 * 1: case sensitive compare 537 * 538 * RETURNS 539 * Success: String ID 540 * Failure: -1 541 */ 542DWORD WINAPI 543pSetupStringTableLookUpString(HSTRING_TABLE hStringTable, 544 LPWSTR lpString, 545 DWORD dwFlags) 546{ 547 PSTRING_TABLE pStringTable; 548 DWORD i; 549 550 TRACE("%p %s %x\n", hStringTable, debugstr_w(lpString), dwFlags); 551 552 pStringTable = (PSTRING_TABLE)hStringTable; 553 if (pStringTable == NULL) 554 { 555 ERR("Invalid hStringTable!\n"); 556 return (DWORD)-1; 557 } 558 559 /* Search for existing string in the string table */ 560 for (i = 0; i < pStringTable->dwMaxSlots; i++) 561 { 562 if (pStringTable->pSlots[i].pString != NULL) 563 { 564 if (dwFlags & 1) 565 { 566 if (!lstrcmpW(pStringTable->pSlots[i].pString, lpString)) 567 return i + 1; 568 } 569 else 570 { 571 if (!lstrcmpiW(pStringTable->pSlots[i].pString, lpString)) 572 return i + 1; 573 } 574 } 575 } 576 577 return (DWORD)-1; 578} 579 580 581/************************************************************************** 582 * pSetupStringTableLookUpStringEx [SETUPAPI.@] 583 * 584 * Searches a string table and extra data for a given string. 585 * 586 * PARAMS 587 * hStringTable [I] Handle to the string table 588 * lpString [I] String to be searched for 589 * dwFlags [I] Flags 590 * 1: case sensitive compare 591 * lpExtraData [O] Pointer to the buffer that receives the extra data 592 * lpReserved [I/O] Unused 593 * 594 * RETURNS 595 * Success: String ID 596 * Failure: -1 597 */ 598DWORD WINAPI 599pSetupStringTableLookUpStringEx(HSTRING_TABLE hStringTable, 600 LPWSTR lpString, 601 DWORD dwFlags, 602 LPVOID lpExtraData, 603 DWORD dwReserved) 604{ 605 PSTRING_TABLE pStringTable; 606 DWORD i; 607 608 TRACE("%p %s %x %p, %x\n", hStringTable, debugstr_w(lpString), dwFlags, 609 lpExtraData, dwReserved); 610 611 pStringTable = (PSTRING_TABLE)hStringTable; 612 if (pStringTable == NULL) 613 { 614 ERR("Invalid hStringTable!\n"); 615 return ~0u; 616 } 617 618 /* Search for existing string in the string table */ 619 for (i = 0; i < pStringTable->dwMaxSlots; i++) 620 { 621 if (pStringTable->pSlots[i].pString != NULL) 622 { 623 if (dwFlags & 1) 624 { 625 if (!lstrcmpW(pStringTable->pSlots[i].pString, lpString)) 626 { 627 if (lpExtraData) 628 memcpy(lpExtraData, pStringTable->pSlots[i].pData, dwReserved); 629 return i + 1; 630 } 631 } 632 else 633 { 634 if (!lstrcmpiW(pStringTable->pSlots[i].pString, lpString)) 635 { 636 if (lpExtraData) 637 memcpy(lpExtraData, pStringTable->pSlots[i].pData, dwReserved); 638 return i + 1; 639 } 640 } 641 } 642 } 643 return ~0u; 644} 645 646 647/************************************************************************** 648 * pSetupStringTableSetExtraData [SETUPAPI.@] 649 * 650 * Sets extra data for a given string table entry. 651 * 652 * PARAMS 653 * hStringTable [I] Handle to the string table 654 * dwId [I] String ID 655 * lpExtraData [I] Pointer to the extra data 656 * dwExtraDataSize [I] Size of the extra data 657 * 658 * RETURNS 659 * Success: TRUE 660 * Failure: FALSE 661 */ 662BOOL WINAPI 663pSetupStringTableSetExtraData(HSTRING_TABLE hStringTable, 664 DWORD dwId, 665 LPVOID lpExtraData, 666 DWORD dwExtraDataSize) 667{ 668 PSTRING_TABLE pStringTable; 669 670 TRACE("%p %x %p %u\n", 671 hStringTable, dwId, lpExtraData, dwExtraDataSize); 672 673 pStringTable = (PSTRING_TABLE)hStringTable; 674 if (pStringTable == NULL) 675 { 676 ERR("Invalid hStringTable!\n"); 677 return FALSE; 678 } 679 680 if (dwId == 0 || dwId > pStringTable->dwMaxSlots) 681 { 682 ERR("Invalid Slot id!\n"); 683 return FALSE; 684 } 685 686 if (pStringTable->dwMaxDataSize < dwExtraDataSize) 687 { 688 ERR("Data size is too large!\n"); 689 return FALSE; 690 } 691 692 pStringTable->pSlots[dwId - 1].pData = MyMalloc(dwExtraDataSize); 693 if (pStringTable->pSlots[dwId - 1].pData == NULL) 694 { 695 ERR("\n"); 696 return FALSE; 697 } 698 699 memcpy(pStringTable->pSlots[dwId - 1].pData, 700 lpExtraData, 701 dwExtraDataSize); 702 pStringTable->pSlots[dwId - 1].dwSize = dwExtraDataSize; 703 704 return TRUE; 705} 706 707 708/************************************************************************** 709 * pSetupStringTableStringFromId [SETUPAPI.@] 710 * 711 * Returns a pointer to a string for the given string ID. 712 * 713 * PARAMS 714 * hStringTable [I] Handle to the string table. 715 * dwId [I] String ID 716 * 717 * RETURNS 718 * Success: Pointer to the string 719 * Failure: NULL 720 */ 721LPWSTR WINAPI 722pSetupStringTableStringFromId(HSTRING_TABLE hStringTable, 723 DWORD dwId) 724{ 725 PSTRING_TABLE pStringTable; 726 static WCHAR empty[] = {0}; 727 728 TRACE("%p %x\n", hStringTable, dwId); 729 730 pStringTable = (PSTRING_TABLE)hStringTable; 731 if (pStringTable == NULL) 732 { 733 ERR("Invalid hStringTable!\n"); 734 return NULL; 735 } 736 737 if (dwId == 0 || dwId > pStringTable->dwMaxSlots) 738 return empty; 739 740 return pStringTable->pSlots[dwId - 1].pString; 741} 742 743 744/************************************************************************** 745 * pSetupStringTableStringFromIdEx [SETUPAPI.@] 746 * 747 * Returns a string for the given string ID. 748 * 749 * PARAMS 750 * hStringTable [I] Handle to the string table 751 * dwId [I] String ID 752 * lpBuffer [I] Pointer to string buffer 753 * lpBufferSize [I/O] Pointer to the size of the string buffer 754 * 755 * RETURNS 756 * Success: TRUE 757 * Failure: FALSE 758 */ 759BOOL WINAPI 760pSetupStringTableStringFromIdEx(HSTRING_TABLE hStringTable, 761 DWORD dwId, 762 LPWSTR lpBuffer, 763 LPDWORD lpBufferLength) 764{ 765 PSTRING_TABLE pStringTable; 766 DWORD dwLength; 767 BOOL bResult = FALSE; 768 769 TRACE("%p %x %p %p\n", hStringTable, dwId, lpBuffer, lpBufferLength); 770 771 pStringTable = (PSTRING_TABLE)hStringTable; 772 if (pStringTable == NULL) 773 { 774 ERR("Invalid hStringTable!\n"); 775 *lpBufferLength = 0; 776 return FALSE; 777 } 778 779 if (dwId == 0 || dwId > pStringTable->dwMaxSlots || 780 pStringTable->pSlots[dwId - 1].pString == NULL) 781 { 782 WARN("Invalid string ID!\n"); 783 *lpBufferLength = 0; 784 return FALSE; 785 } 786 787 dwLength = (lstrlenW(pStringTable->pSlots[dwId - 1].pString) + 1); 788 if (dwLength <= *lpBufferLength) 789 { 790 lstrcpyW(lpBuffer, pStringTable->pSlots[dwId - 1].pString); 791 bResult = TRUE; 792 } 793 794 *lpBufferLength = dwLength; 795 796 return bResult; 797}