Implement StringTableInitializeEx, StringTableGetExtraData and StringTableSetExtraData.
Add StringTableAddStringEx and StringTableLookUpStringEx stubs.
Modified: trunk/reactos/lib/setupapi/setupapi.spec
Modified: trunk/reactos/lib/setupapi/stringtable.c
Modified: trunk/reactos/w32api/include/setupapi.h

Modified: trunk/reactos/lib/setupapi/setupapi.spec
--- trunk/reactos/lib/setupapi/setupapi.spec	2005-08-27 18:13:52 UTC (rev 17572)
+++ trunk/reactos/lib/setupapi/setupapi.spec	2005-08-27 19:14:35 UTC (rev 17573)
@@ -8,7 +8,7 @@
 @ stub CMP_Report_LogOn
 @ stub CMP_UnregisterNotification
 @ stub CMP_WaitNoPendingInstallEvents
-@ stub CMP_WaitServices
+@ stub CMP_WaitServicesAvailable
 @ stub CM_Add_Empty_Log_Conf
 @ stub CM_Add_Empty_Log_Conf_Ex
 @ stub CM_Add_IDA
@@ -516,16 +516,16 @@
 @ stub ShouldDeviceBeExcluded
 @ stdcall StampFileSecurity(wstr ptr)
 @ stdcall StringTableAddString(ptr wstr long)
-@ stub StringTableAddStringEx
+@ stdcall StringTableAddStringEx(ptr wstr long ptr long)
 @ stdcall StringTableDestroy(ptr)
 @ stdcall StringTableDuplicate(ptr)
 @ stub StringTableEnum
-@ stub StringTableGetExtraData
+@ stdcall StringTableGetExtraData(ptr long ptr long)
 @ stdcall StringTableInitialize()
-@ stub StringTableInitializeEx
+@ stdcall StringTableInitializeEx(long long)
 @ stdcall StringTableLookUpString(ptr wstr long)
-@ stub StringTableLookUpStringEx
-@ stub StringTableSetExtraData
+@ stdcall StringTableLookUpStringEx(ptr wstr long ptr ptr)
+@ stdcall StringTableSetExtraData(ptr long ptr long)
 @ stdcall StringTableStringFromId(ptr long)
 @ stdcall StringTableStringFromIdEx(ptr long ptr ptr)
 @ stdcall StringTableTrim(ptr)

Modified: trunk/reactos/lib/setupapi/stringtable.c
--- trunk/reactos/lib/setupapi/stringtable.c	2005-08-27 18:13:52 UTC (rev 17572)
+++ trunk/reactos/lib/setupapi/stringtable.c	2005-08-27 19:14:35 UTC (rev 17573)
@@ -34,11 +34,19 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(setupapi);
 
+typedef struct _TABLE_SLOT
+{
+    LPWSTR pString;
+    LPVOID pData;
+    DWORD dwSize;
+} TABLE_SLOT, *PTABLE_SLOT;
+
 typedef struct _STRING_TABLE
 {
-    LPWSTR *pSlots;
+    PTABLE_SLOT pSlots;
     DWORD dwUsedSlots;
     DWORD dwMaxSlots;
+    DWORD dwMaxDataSize;
 } STRING_TABLE, *PSTRING_TABLE;
 
 
@@ -70,17 +78,18 @@
 
     memset(pStringTable, 0, sizeof(STRING_TABLE));
 
-    pStringTable->pSlots = MyMalloc(sizeof(LPWSTR) * TABLE_DEFAULT_SIZE);
+    pStringTable->pSlots = MyMalloc(sizeof(TABLE_SLOT) * TABLE_DEFAULT_SIZE);
     if (pStringTable->pSlots == NULL)
     {
         MyFree(pStringTable->pSlots);
         return NULL;
     }
 
-    memset(pStringTable->pSlots, 0, sizeof(LPWSTR) * TABLE_DEFAULT_SIZE);
+    memset(pStringTable->pSlots, 0, sizeof(TABLE_SLOT) * TABLE_DEFAULT_SIZE);
 
     pStringTable->dwUsedSlots = 0;
     pStringTable->dwMaxSlots = TABLE_DEFAULT_SIZE;
+    pStringTable->dwMaxDataSize = 0;
 
     TRACE("Done\n");
 
@@ -89,6 +98,55 @@
 
 
 /**************************************************************************
+ * StringTableInitializeEx [SETUPAPI.@]
+ *
+ * Creates a new string table and initializes it.
+ *
+ * PARAMS
+ *     dwMaxExtraDataSize [I] Maximum extra data size
+ *     dwReserved         [I] Unused
+ *
+ * RETURNS
+ *     Success: Handle to the string table
+ *     Failure: NULL
+ */
+HSTRING_TABLE WINAPI
+StringTableInitializeEx(DWORD dwMaxExtraDataSize,
+                        DWORD dwReserved)
+{
+    PSTRING_TABLE pStringTable;
+
+    TRACE("\n");
+
+    pStringTable = MyMalloc(sizeof(STRING_TABLE));
+    if (pStringTable == NULL)
+    {
+        ERR("Invalid hStringTable!\n");
+        return NULL;
+    }
+
+    memset(pStringTable, 0, sizeof(STRING_TABLE));
+
+    pStringTable->pSlots = MyMalloc(sizeof(TABLE_SLOT) * TABLE_DEFAULT_SIZE);
+    if (pStringTable->pSlots == NULL)
+    {
+        MyFree(pStringTable->pSlots);
+        return NULL;
+    }
+
+    memset(pStringTable->pSlots, 0, sizeof(TABLE_SLOT) * TABLE_DEFAULT_SIZE);
+
+    pStringTable->dwUsedSlots = 0;
+    pStringTable->dwMaxSlots = TABLE_DEFAULT_SIZE;
+    pStringTable->dwMaxDataSize = dwMaxExtraDataSize;
+
+    TRACE("Done\n");
+
+    return (HSTRING_TABLE)pStringTable;
+}
+
+
+/**************************************************************************
  * StringTableDestroy [SETUPAPI.@]
  *
  * Destroys a string table.
@@ -115,11 +173,18 @@
     {
         for (i = 0; i < pStringTable->dwMaxSlots; i++)
         {
-            if (pStringTable->pSlots[i] != NULL)
+            if (pStringTable->pSlots[i].pString != NULL)
             {
-                MyFree(pStringTable->pSlots[i]);
-                pStringTable->pSlots[i] = NULL;
+                MyFree(pStringTable->pSlots[i].pString);
+                pStringTable->pSlots[i].pString = NULL;
             }
+
+            if (pStringTable->pSlots[i].pData != NULL)
+            {
+                MyFree(pStringTable->pSlots[i].pData);
+                pStringTable->pSlots[i].pData = NULL;
+                pStringTable->pSlots[i].dwSize = 0;
+            }
         }
 
         MyFree(pStringTable->pSlots);
@@ -169,18 +234,18 @@
     /* Search for existing string in the string table */
     for (i = 0; i < pStringTable->dwMaxSlots; i++)
     {
-        if (pStringTable->pSlots[i] != NULL)
+        if (pStringTable->pSlots[i].pString != NULL)
         {
             if (dwFlags & 1)
             {
-                if (!lstrcmpW(pStringTable->pSlots[i], lpString))
+                if (!lstrcmpW(pStringTable->pSlots[i].pString, lpString))
                 {
                     return i;
                 }
             }
             else
             {
-                if (!lstrcmpiW(pStringTable->pSlots[i], lpString))
+                if (!lstrcmpiW(pStringTable->pSlots[i].pString, lpString))
                 {
                     return i;
                 }
@@ -198,16 +263,16 @@
     /* Search for an empty slot */
     for (i = 0; i < pStringTable->dwMaxSlots; i++)
     {
-        if (pStringTable->pSlots[i] == NULL)
+        if (pStringTable->pSlots[i].pString == NULL)
         {
-            pStringTable->pSlots[i] = MyMalloc((lstrlenW(lpString) + 1) * sizeof(WCHAR));
-            if (pStringTable->pSlots[i] == NULL)
+            pStringTable->pSlots[i].pString = MyMalloc((lstrlenW(lpString) + 1) * sizeof(WCHAR));
+            if (pStringTable->pSlots[i].pString == NULL)
             {
                 TRACE("Couldn't allocate memory for a new string!\n");
                 return (DWORD)-1;
             }
 
-            lstrcpyW(pStringTable->pSlots[i], lpString);
+            lstrcpyW(pStringTable->pSlots[i].pString, lpString);
 
             pStringTable->dwUsedSlots++;
 
@@ -222,6 +287,40 @@
 
 
 /**************************************************************************
+ * StringTableAddStringEx [SETUPAPI.@]
+ *
+ * Adds a new string plus extra data to the string table.
+ *
+ * PARAMS
+ *     hStringTable    [I] Handle to the string table
+ *     lpString        [I] String to be added to the string table
+ *     dwFlags         [I] Flags
+ *                           1: case sensitive compare
+ *     lpExtraData     [I] Pointer to the extra data
+ *     dwExtraDataSize [I] Size of the extra data
+ *
+ * RETURNS
+ *     Success: String ID
+ *     Failure: -1
+ *
+ * NOTES
+ *     If the given string already exists in the string table it will not
+ *     be added again. The ID of the existing string will be returned in
+ *     this case.
+ */
+DWORD WINAPI
+StringTableAddStringEx(HSTRING_TABLE hStringTable,
+                       LPWSTR lpString,
+                       DWORD dwFlags,
+                       LPVOID lpExtraData,
+                       DWORD dwExtraDataSize)
+{
+    FIXME("\n");
+    return (DWORD)-1;
+}
+
+
+/**************************************************************************
  * StringTableDuplicate [SETUPAPI.@]
  *
  * Duplicates a given string table.
@@ -260,31 +359,44 @@
 
     memset(pDestinationTable, 0, sizeof(STRING_TABLE));
 
-    pDestinationTable->pSlots = MyMalloc(sizeof(LPWSTR) * pSourceTable->dwMaxSlots);
+    pDestinationTable->pSlots = MyMalloc(sizeof(TABLE_SLOT) * pSourceTable->dwMaxSlots);
     if (pDestinationTable->pSlots == NULL)
     {
         MyFree(pDestinationTable);
         return (HSTRING_TABLE)NULL;
     }
 
-    memset(pDestinationTable->pSlots, 0, sizeof(LPWSTR) * pSourceTable->dwMaxSlots);
+    memset(pDestinationTable->pSlots, 0, sizeof(TABLE_SLOT) * pSourceTable->dwMaxSlots);
 
     pDestinationTable->dwUsedSlots = 0;
     pDestinationTable->dwMaxSlots = pSourceTable->dwMaxSlots;
 
     for (i = 0; i < pSourceTable->dwMaxSlots; i++)
     {
-        if (pSourceTable->pSlots[i] != NULL)
+        if (pSourceTable->pSlots[i].pString != NULL)
         {
-            length = (lstrlenW(pSourceTable->pSlots[i]) + 1) * sizeof(WCHAR);
-            pDestinationTable->pSlots[i] = MyMalloc(length);
-            if (pDestinationTable->pSlots[i] != NULL)
+            length = (lstrlenW(pSourceTable->pSlots[i].pString) + 1) * sizeof(WCHAR);
+            pDestinationTable->pSlots[i].pString = MyMalloc(length);
+            if (pDestinationTable->pSlots[i].pString != NULL)
             {
-                memcpy(pDestinationTable->pSlots[i],
-                       pSourceTable->pSlots[i],
+                memcpy(pDestinationTable->pSlots[i].pString,
+                       pSourceTable->pSlots[i].pString,
                        length);
                 pDestinationTable->dwUsedSlots++;
             }
+
+            if (pSourceTable->pSlots[i].pData != NULL)
+            {
+                length = pSourceTable->pSlots[i].dwSize;
+                pDestinationTable->pSlots[i].pData = MyMalloc(length);
+                if (pDestinationTable->pSlots[i].pData)
+                {
+                    memcpy(pDestinationTable->pSlots[i].pData,
+                           pSourceTable->pSlots[i].pData,
+                           length);
+                    pDestinationTable->pSlots[i].dwSize = length;
+                }
+            }
         }
     }
 
@@ -293,6 +405,59 @@
 
 
 /**************************************************************************
+ * StringTableGetExtraData [SETUPAPI.@]
+ *
+ * Retrieves extra data from a given string table entry.
+ *
+ * PARAMS
+ *     hStringTable    [I] Handle to the string table
+ *     dwId            [I] String ID
+ *     lpExtraData     [I] Pointer a buffer that receives the extra data
+ *     dwExtraDataSize [I] Size of the buffer
+ *
+ * RETURNS
+ *     Success: TRUE
+ *     Failure: FALSE
+ */
+BOOL WINAPI
+StringTableGetExtraData(HSTRING_TABLE hStringTable,
+                        DWORD dwId,
+                        LPVOID lpExtraData,
+                        DWORD dwExtraDataSize)
+{
+    PSTRING_TABLE pStringTable;
+
+    TRACE("%p %lx %p %lu\n",
+          (PVOID)hStringTable, dwId, lpExtraData, dwExtraDataSize);
+
+    pStringTable = (PSTRING_TABLE)hStringTable;
+    if (pStringTable == NULL)
+    {
+        ERR("Invalid hStringTable!\n");
+        return FALSE;
+    }
+
+    if (dwId >= pStringTable->dwMaxSlots)
+    {
+        ERR("Invalid Slot id!\n");
+        return FALSE;
+    }
+
+    if (pStringTable->pSlots[dwId].dwSize < dwExtraDataSize)
+    {
+        ERR("Data size is too large!\n");
+        return FALSE;
+    }
+
+    memcpy(lpExtraData,
+           pStringTable->pSlots[dwId].pData,
+           dwExtraDataSize);
+
+    return TRUE;
+}
+
+
+/**************************************************************************
  * StringTableLookUpString [SETUPAPI.@]
  *
  * Searches a string table for a given string.
@@ -327,21 +492,17 @@
     /* Search for existing string in the string table */
     for (i = 0; i < pStringTable->dwMaxSlots; i++)
     {
-        if (pStringTable->pSlots[i] != NULL)
+        if (pStringTable->pSlots[i].pString != NULL)
         {
             if (dwFlags & 1)
             {
-                if (!lstrcmpW(pStringTable->pSlots[i], lpString))
-                {
+                if (!lstrcmpW(pStringTable->pSlots[i].pString, lpString))
                     return i;
-                }
             }
             else
             {
-                if (!lstrcmpiW(pStringTable->pSlots[i], lpString))
-                {
+                if (!lstrcmpiW(pStringTable->pSlots[i].pString, lpString))
                     return i;
-                }
             }
         }
     }
@@ -351,6 +512,96 @@
 
 
 /**************************************************************************
+ * StringTableLookUpStringEx [SETUPAPI.@]
+ *
+ * Searches a string table and extra data for a given string.
+ *
+ * PARAMS
+ *     hStringTable [I] Handle to the string table
+ *     lpString     [I] String to be searched for
+ *     dwFlags      [I] Flags
+ *                        1: case sensitive compare
+ *     lpExtraData  [O] Pointer to the buffer that receives the extra data
+ *     lpReserved   [I/O] Unused
+ *
+ * RETURNS
+ *     Success: String ID
+ *     Failure: -1
+ */
+DWORD WINAPI
+StringTableLookUpStringEx(HSTRING_TABLE hStringTable,
+                          LPWSTR lpString,
+                          DWORD dwFlags,
+                          LPVOID lpExtraData,
+                          LPDWORD lpReserved)
+{
+    FIXME("\n");
+    return (DWORD)-1;
+}
+
+
+/**************************************************************************
+ * StringTableSetExtraData [SETUPAPI.@]
+ *
+ * Sets extra data for a given string table entry.
+ *
+ * PARAMS
+ *     hStringTable    [I] Handle to the string table
+ *     dwId            [I] String ID
+ *     lpExtraData     [I] Pointer to the extra data
+ *     dwExtraDataSize [I] Size of the extra data
+ *
+ * RETURNS
+ *     Success: TRUE
+ *     Failure: FALSE
+ */
+BOOL WINAPI
+StringTableSetExtraData(HSTRING_TABLE hStringTable,
+                        DWORD dwId,
+                        LPVOID lpExtraData,
+                        DWORD dwExtraDataSize)
+{
+    PSTRING_TABLE pStringTable;
+
+    TRACE("%p %lx %p %lu\n",
+          (PVOID)hStringTable, dwId, lpExtraData, dwExtraDataSize);
+
+    pStringTable = (PSTRING_TABLE)hStringTable;
+    if (pStringTable == NULL)
+    {
+        ERR("Invalid hStringTable!\n");
+        return FALSE;
+    }
+
+    if (dwId >= pStringTable->dwMaxSlots)
+    {
+        ERR("Invalid Slot id!\n");
+        return FALSE;
+    }
+
+    if (pStringTable->dwMaxDataSize < dwExtraDataSize)
+    {
+        ERR("Data size is too large!\n");
+        return FALSE;
+    }
+
+    pStringTable->pSlots[dwId].pData = MyMalloc(dwExtraDataSize);
+    if (pStringTable->pSlots[dwId].pData == NULL)
+    {
+        ERR("\n");
+        return FALSE;
+    }
+
+    memcpy(pStringTable->pSlots[dwId].pData,
+           lpExtraData,
+           dwExtraDataSize);
+    pStringTable->pSlots[dwId].dwSize = dwExtraDataSize;
+
+    return TRUE;
+}
+
+
+/**************************************************************************
  * StringTableStringFromId [SETUPAPI.@]
  *
  * Returns a pointer to a string for the given string ID.
@@ -381,7 +632,7 @@
     if (dwId >= pStringTable->dwMaxSlots)
         return NULL;
 
-    return pStringTable->pSlots[dwId];
+    return pStringTable->pSlots[dwId].pString;
 }
 
 
@@ -422,17 +673,17 @@
     }
 
     if (dwId >= pStringTable->dwMaxSlots ||
-        pStringTable->pSlots[dwId] == NULL)
+        pStringTable->pSlots[dwId].pString == NULL)
     {
         WARN("Invalid string ID!\n");
         *lpBufferLength = 0;
         return FALSE;
     }
 
-    dwLength = (lstrlenW(pStringTable->pSlots[dwId]) + 1) * sizeof(WCHAR);
+    dwLength = (lstrlenW(pStringTable->pSlots[dwId].pString) + 1) * sizeof(WCHAR);
     if (dwLength <= *lpBufferLength)
     {
-        lstrcpyW(lpBuffer, pStringTable->pSlots[dwId]);
+        lstrcpyW(lpBuffer, pStringTable->pSlots[dwId].pString);
         bResult = TRUE;
     }
 

Modified: trunk/reactos/w32api/include/setupapi.h
--- trunk/reactos/w32api/include/setupapi.h	2005-08-27 18:13:52 UTC (rev 17572)
+++ trunk/reactos/w32api/include/setupapi.h	2005-08-27 19:14:35 UTC (rev 17573)
@@ -1382,10 +1382,15 @@
 WINSETUPAPI DWORD WINAPI StampFileSecurity(PCWSTR, PSECURITY_DESCRIPTOR);
 
 WINSETUPAPI DWORD  WINAPI StringTableAddString(HSTRING_TABLE, LPWSTR, DWORD);
+WINSETUPAPI DWORD  WINAPI StringTableAddStringEx(HSTRING_TABLE, LPWSTR, DWORD, LPVOID, DWORD);
 WINSETUPAPI VOID   WINAPI StringTableDestroy(HSTRING_TABLE);
 WINSETUPAPI HSTRING_TABLE WINAPI StringTableDuplicate(HSTRING_TABLE);
+WINSETUPAPI BOOL   WINAPI StringTableGetExtraData(HSTRING_TABLE, DWORD, LPVOID, DWORD);
 WINSETUPAPI HSTRING_TABLE WINAPI StringTableInitialize(VOID);
+WINSETUPAPI HSTRING_TABLE WINAPI StringTableInitializeEx(DWORD, DWORD);
 WINSETUPAPI DWORD  WINAPI StringTableLookUpString(HSTRING_TABLE, LPWSTR, DWORD);
+WINSETUPAPI DWORD  WINAPI StringTableLookUpStringEx(HSTRING_TABLE, LPWSTR, DWORD, LPVOID, LPDWORD);
+WINSETUPAPI BOOL   WINAPI StringTableSetExtraData(HSTRING_TABLE, DWORD, LPVOID, DWORD);
 WINSETUPAPI LPWSTR WINAPI StringTableStringFromId(HSTRING_TABLE, DWORD);
 WINSETUPAPI BOOL   WINAPI StringTableStringFromIdEx(HSTRING_TABLE, DWORD, LPWSTR, LPDWORD);
 WINSETUPAPI VOID   WINAPI StringTableTrim(HSTRING_TABLE);