Implement basic string table functions
Modified: trunk/reactos/include/wine/setupapi.h
Modified: trunk/reactos/lib/setupapi/Makefile.in
Modified: trunk/reactos/lib/setupapi/setupapi.spec
Modified: trunk/reactos/lib/setupapi/setupapi.xml
Added: trunk/reactos/lib/setupapi/stringtable.c
Modified: trunk/reactos/w32api/include/setupapi.h

Modified: trunk/reactos/include/wine/setupapi.h
--- trunk/reactos/include/wine/setupapi.h	2005-06-18 08:04:30 UTC (rev 16024)
+++ trunk/reactos/include/wine/setupapi.h	2005-06-18 11:30:49 UTC (rev 16025)
@@ -39,6 +39,8 @@
 
 typedef PVOID HDSKSPC;
 
+typedef PVOID HSTRING_TABLE;
+
 /* inf structure. */
 typedef struct _INFCONTEXT
 {
@@ -665,7 +667,11 @@
 #define SPDRP_MAXIMUM_PROPERTY            0x00000023
 
 
-LONG     WINAPI AddTagToGroupOrderList(PCWSTR lpGroupName, DWORD dwUnknown2, DWORD dwUnknown3);
+/* Flags for StringTableAddString and StringTableLookUpString */
+#define ST_CASE_SENSITIVE_COMPARE 0x00000001
+
+
+LONG     WINAPI AddTagToGroupOrderList(PCWSTR, DWORD, DWORD);
 VOID     WINAPI AssertFail(LPSTR, UINT, LPSTR);
 DWORD    WINAPI CaptureAndConvertAnsiArg(PCSTR lpSrc, PWSTR *lpDst);
 DWORD    WINAPI CaptureStringArg(PCWSTR lpSrc, PWSTR *lpDst);
@@ -827,6 +833,15 @@
 BOOL     WINAPI SetupSetFileQueueFlags( HSPFILEQ, DWORD, DWORD );
 void     WINAPI SetupTermDefaultQueueCallback( PVOID );
 DWORD    WINAPI StampFileSecurity(PCWSTR, PSECURITY_DESCRIPTOR);
+
+DWORD    WINAPI StringTableAddString(HSTRING_TABLE, LPWSTR, DWORD);
+VOID     WINAPI StringTableDestroy(HSTRING_TABLE);
+HSTRING_TABLE WINAPI StringTableInitialize(VOID);
+DWORD    WINAPI StringTableLookUpString(HSTRING_TABLE, LPWSTR, DWORD);
+LPWSTR   WINAPI StringTableStringFromId(HSTRING_TABLE, DWORD);
+BOOL     WINAPI StringTableStringFromIdEx(HSTRING_TABLE, DWORD, LPWSTR, LPDWORD);
+VOID     WINAPI StringTableTrim(HSTRING_TABLE);
+
 DWORD    WINAPI TakeOwnershipOfFile(PCWSTR);
 PSTR     WINAPI UnicodeToMultiByte(PCWSTR lpUnicodeStr, UINT uCodePage);
 BOOL     WINAPI UnmapAndCloseFile(HANDLE, HANDLE, PVOID);

Modified: trunk/reactos/lib/setupapi/Makefile.in
--- trunk/reactos/lib/setupapi/Makefile.in	2005-06-18 08:04:30 UTC (rev 16024)
+++ trunk/reactos/lib/setupapi/Makefile.in	2005-06-18 11:30:49 UTC (rev 16025)
@@ -20,6 +20,7 @@
 	parser.c \
 	queue.c \
 	setupcab.c \
+	stringtable.c \
 	stubs.c \
 	rpc.c
 

Modified: trunk/reactos/lib/setupapi/setupapi.spec
--- trunk/reactos/lib/setupapi/setupapi.spec	2005-06-18 08:04:30 UTC (rev 16024)
+++ trunk/reactos/lib/setupapi/setupapi.spec	2005-06-18 11:30:49 UTC (rev 16025)
@@ -513,20 +513,20 @@
 @ stdcall SetupTerminateFileLog(long)
 @ stub ShouldDeviceBeExcluded
 @ stdcall StampFileSecurity(wstr ptr)
-@ stub StringTableAddString
+@ stdcall StringTableAddString(ptr wstr long)
 @ stub StringTableAddStringEx
-@ stub StringTableDestroy
+@ stdcall StringTableDestroy(ptr)
 @ stub StringTableDuplicate
 @ stub StringTableEnum
 @ stub StringTableGetExtraData
-@ stub StringTableInitialize
+@ stdcall StringTableInitialize()
 @ stub StringTableInitializeEx
-@ stub StringTableLookUpString
+@ stdcall StringTableLookUpString(ptr wstr long)
 @ stub StringTableLookUpStringEx
 @ stub StringTableSetExtraData
-@ stub StringTableStringFromId
-@ stub StringTableStringFromIdEx
-@ stub StringTableTrim
+@ stdcall StringTableStringFromId(ptr long)
+@ stdcall StringTableStringFromIdEx(ptr long ptr ptr)
+@ stdcall StringTableTrim(ptr)
 @ stdcall TakeOwnershipOfFile(wstr)
 @ stdcall UnicodeToMultiByte(wstr long)
 @ stdcall UnmapAndCloseFile(long long ptr)

Modified: trunk/reactos/lib/setupapi/setupapi.xml
--- trunk/reactos/lib/setupapi/setupapi.xml	2005-06-18 08:04:30 UTC (rev 16024)
+++ trunk/reactos/lib/setupapi/setupapi.xml	2005-06-18 11:30:49 UTC (rev 16025)
@@ -29,6 +29,7 @@
 	<file>parser.c</file>
 	<file>queue.c</file>
 	<file>setupcab.c</file>
+	<file>stringtable.c</file>
 	<file>stubs.c</file>
 	<file>rpc.c</file>
 	<file>setupapi.rc</file>

Added: trunk/reactos/lib/setupapi/stringtable.c
--- trunk/reactos/lib/setupapi/stringtable.c	2005-06-18 08:04:30 UTC (rev 16024)
+++ trunk/reactos/lib/setupapi/stringtable.c	2005-06-18 11:30:49 UTC (rev 16025)
@@ -0,0 +1,389 @@
+/*
+ * Setupapi string table functions
+ *
+ * Copyright 2005 Eric Kohl
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <stdarg.h>
+
+#include "windef.h"
+#include "winbase.h"
+#include "wingdi.h"
+#include "winuser.h"
+#include "winreg.h"
+#include "setupapi.h"
+
+#include "wine/debug.h"
+
+
+#define TABLE_DEFAULT_SIZE 256
+
+WINE_DEFAULT_DEBUG_CHANNEL(setupapi);
+
+typedef struct _STRING_TABLE
+{
+    LPWSTR *pSlots;     /* 0x00 */
+    DWORD dwUsedSlots;  /* 0x04 */
+    DWORD dwMaxSlots;   /* 0x08 */
+} STRING_TABLE, *PSTRING_TABLE;
+
+
+/**************************************************************************
+ * StringTableInitialize [SETUPAPI.@]
+ *
+ * Creates a new string table and initializes it.
+ *
+ * PARAMS
+ *     None
+ *
+ * RETURNS
+ *     Success: Handle to the string table
+ *     Failure: NULL
+ */
+HSTRING_TABLE WINAPI
+StringTableInitialize(VOID)
+{
+    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(LPWSTR) * TABLE_DEFAULT_SIZE);
+    if (pStringTable->pSlots == NULL)
+    {
+        MyFree(pStringTable->pSlots);
+        return NULL;
+    }
+
+    memset(pStringTable->pSlots, 0, sizeof(LPWSTR) * TABLE_DEFAULT_SIZE);
+
+    pStringTable->dwUsedSlots = 0;
+    pStringTable->dwMaxSlots = TABLE_DEFAULT_SIZE;
+
+    TRACE("Done\n");
+
+    return (HSTRING_TABLE)pStringTable;
+}
+
+
+/**************************************************************************
+ * StringTableDestroy [SETUPAPI.@]
+ *
+ * Destroys a string table.
+ *
+ * PARAMS
+ *     hStringTable [I] Handle to the string table to be destroyed
+ *
+ * RETURNS
+ *     None
+ */
+VOID WINAPI
+StringTableDestroy(HSTRING_TABLE hStringTable)
+{
+    PSTRING_TABLE pStringTable;
+    DWORD i;
+
+    TRACE("%p\n", (PVOID)hStringTable);
+
+    pStringTable = (PSTRING_TABLE)hStringTable;
+    if (pStringTable == NULL)
+        return;
+
+    if (pStringTable->pSlots != NULL)
+    {
+        for (i = 0; i < pStringTable->dwMaxSlots; i++)
+        {
+            if (pStringTable->pSlots[i] != NULL)
+            {
+                MyFree(pStringTable->pSlots[i]);
+                pStringTable->pSlots[i] = NULL;
+            }
+        }
+
+        MyFree(pStringTable->pSlots);
+    }
+
+    MyFree(pStringTable);
+}
+
+
+/**************************************************************************
+ * StringTableAddString [SETUPAPI.@]
+ *
+ * Adds a new string 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
+ *
+ * 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
+StringTableAddString(HSTRING_TABLE hStringTable,
+                     LPWSTR lpString,
+                     DWORD dwFlags)
+{
+    PSTRING_TABLE pStringTable;
+    DWORD i;
+
+    TRACE("%p %s %lx\n", (PVOID)hStringTable, debugstr_w(lpString), dwFlags);
+
+    pStringTable = (PSTRING_TABLE)hStringTable;
+    if (pStringTable == NULL)
+    {
+        ERR("Invalid hStringTable!\n");
+        return (DWORD)-1;
+    }
+
+    /* Search for existing string in the string table */
+    for (i = 0; i < pStringTable->dwMaxSlots; i++)
+    {
+        if (pStringTable->pSlots[i] != NULL)
+        {
+            if (dwFlags & 1)
+            {
+                if (!lstrcmpW(pStringTable->pSlots[i], lpString))
+                {
+                    return i;
+                }
+            }
+            else
+            {
+                if (!lstrcmpiW(pStringTable->pSlots[i], lpString))
+                {
+                    return i;
+                }
+            }
+        }
+    }
+
+    /* Check for filled slot table */
+    if (pStringTable->dwUsedSlots == pStringTable->dwMaxSlots)
+    {
+        FIXME("Resize the string table!\n");
+        return (DWORD)-1;
+    }
+
+    /* Search for an empty slot */
+    for (i = 0; i < pStringTable->dwMaxSlots; i++)
+    {
+        if (pStringTable->pSlots[i] == NULL)
+        {
+            pStringTable->pSlots[i] = MyMalloc(lstrlenW(lpString) + sizeof(WCHAR));
+            if (pStringTable->pSlots[i] == NULL)
+            {
+                TRACE("Couldn't allocate memory for a new string!\n");
+                return (DWORD)-1;
+            }
+
+            lstrcpyW(pStringTable->pSlots[i], lpString);
+
+            pStringTable->dwUsedSlots++;
+
+            return i;
+        }
+    }
+
+    TRACE("Couldn't find an empty slot!\n");
+
+    return (DWORD)-1;
+}
+
+
+/**************************************************************************
+ * StringTableLookUpString [SETUPAPI.@]
+ *
+ * Searches a string table 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
+ *
+ * RETURNS
+ *     Success: String ID
+ *     Failure: -1
+ */
+DWORD WINAPI
+StringTableLookUpString(HSTRING_TABLE hStringTable,
+                        LPWSTR lpString,
+                        DWORD dwFlags)
+{
+    PSTRING_TABLE pStringTable;
+    DWORD i;
+
+    TRACE("%p %s %lx\n", (PVOID)hStringTable, debugstr_w(lpString), dwFlags);
+
+    pStringTable = (PSTRING_TABLE)hStringTable;
+    if (pStringTable == NULL)
+    {
+        ERR("Invalid hStringTable!\n");
+        return (DWORD)-1;
+    }
+
+    /* Search for existing string in the string table */
+    for (i = 0; i < pStringTable->dwMaxSlots; i++)
+    {
+        if (pStringTable->pSlots[i] != NULL)
+        {
+            if (dwFlags & 1)
+            {
+                if (!lstrcmpW(pStringTable->pSlots[i], lpString))
+                {
+                    return i;
+                }
+            }
+            else
+            {
+                if (!lstrcmpiW(pStringTable->pSlots[i], lpString))
+                {
+                    return i;
+                }
+            }
+        }
+    }
+
+    return (DWORD)-1;
+}
+
+
+/**************************************************************************
+ * StringTableStringFromId [SETUPAPI.@]
+ *
+ * Returns a pointer to a string for the given string ID.
+ *
+ * PARAMS
+ *     hStringTable [I] Handle to the string table.
+ *     dwId         [I] String ID
+ *
+ * RETURNS
+ *     Success: Pointer to the string
+ *     Failure: NULL
+ */
+LPWSTR WINAPI
+StringTableStringFromId(HSTRING_TABLE hStringTable,
+                        DWORD dwId)
+{
+    PSTRING_TABLE pStringTable;
+
+    TRACE("%p %lx\n", (PVOID)hStringTable, dwId);
+
+    pStringTable = (PSTRING_TABLE)hStringTable;
+    if (pStringTable == NULL)
+    {
+        ERR("Invalid hStringTable!\n");
+        return NULL;
+    }
+
+    if (dwId >= pStringTable->dwMaxSlots)
+        return NULL;
+
+    return pStringTable->pSlots[dwId];
+}
+
+
+/**************************************************************************
+ * StringTableStringFromIdEx [SETUPAPI.@]
+ *
+ * Returns a string for the given string ID.
+ *
+ * PARAMS
+ *     hStringTable [I] Handle to the string table
+ *     dwId         [I] String ID
+ *     lpBuffer     [I] Pointer to string buffer
+ *     lpBufferSize [I/O] Pointer to the size of the string buffer
+ *
+ * RETURNS
+ *     Success: TRUE
+ *     Failure: FALSE
+ */
+BOOL WINAPI
+StringTableStringFromIdEx(HSTRING_TABLE hStringTable,
+                          DWORD dwId,
+                          LPWSTR lpBuffer,
+                          LPDWORD lpBufferLength)
+{
+    PSTRING_TABLE pStringTable;
+    DWORD dwLength;
+    BOOL bResult = FALSE;
+
+    TRACE("%p %lx %p %p\n",
+          (PVOID)hStringTable, dwId, lpBuffer, lpBufferLength);
+
+    pStringTable = (PSTRING_TABLE)hStringTable;
+    if (pStringTable == NULL)
+    {
+        ERR("Invalid hStringTable!\n");
+        *lpBufferLength = 0;
+        return FALSE;
+    }
+
+    if (dwId >= pStringTable->dwMaxSlots ||
+        pStringTable->pSlots[dwId] == NULL)
+    {
+        WARN("Invalid string ID!\n");
+        *lpBufferLength = 0;
+        return FALSE;
+    }
+
+    dwLength = lstrlenW(pStringTable->pSlots[dwId]) + sizeof(WCHAR);
+    if (dwLength <= *lpBufferLength)
+    {
+        lstrcpyW(lpBuffer, pStringTable->pSlots[dwId]);
+        bResult = TRUE;
+    }
+
+    *lpBufferLength = dwLength;
+
+    return bResult;
+}
+
+
+/**************************************************************************
+ * StringTableTrim [SETUPAPI.@]
+ *
+ * ...
+ *
+ * PARAMS
+ *     hStringTable [I] Handle to the string table
+ *
+ * RETURNS
+ *     None
+ */
+VOID WINAPI
+StringTableTrim(HSTRING_TABLE hStringTable)
+{
+    FIXME("%p\n", (PVOID)hStringTable);
+}

Modified: trunk/reactos/w32api/include/setupapi.h
--- trunk/reactos/w32api/include/setupapi.h	2005-06-18 08:04:30 UTC (rev 16024)
+++ trunk/reactos/w32api/include/setupapi.h	2005-06-18 11:30:49 UTC (rev 16025)
@@ -577,6 +577,9 @@
 #define SRCLIST_APPEND	0x00000200
 #define SRCLIST_NOSTRIPPLATFORM	0x00000400
 
+/* Flags for StringTableAddString and StringTableLookUpString */
+#define ST_CASE_SENSITIVE_COMPARE	0x00000001
+
 #ifndef RC_INVOKED
 typedef PVOID HINF;
 typedef PVOID HDSKSPC;
@@ -585,6 +588,8 @@
 typedef PVOID HSPFILELOG;
 typedef UINT DI_FUNCTION;
 
+typedef PVOID HSTRING_TABLE;
+
 typedef enum {
     SetupFileLogSourceFilename,
     SetupFileLogChecksum,
@@ -1326,6 +1331,15 @@
 WINSETUPAPI VOID WINAPI SetupTermDefaultQueueCallback(PVOID);
 WINSETUPAPI BOOL WINAPI SetupTerminateFileLog(HSPFILELOG);
 
+WINSETUPAPI DWORD  WINAPI StringTableAddString(HSTRING_TABLE, LPWSTR, DWORD);
+WINSETUPAPI VOID   WINAPI StringTableDestroy(HSTRING_TABLE);
+WINSETUPAPI HSTRING_TABLE WINAPI StringTableInitialize(VOID);
+WINSETUPAPI DWORD  WINAPI StringTableLookUpString(HSTRING_TABLE, LPWSTR, DWORD);
+WINSETUPAPI LPWSTR WINAPI StringTableStringFromId(HSTRING_TABLE, DWORD);
+WINSETUPAPI BOOL   WINAPI StringTableStringFromIdEx(HSTRING_TABLE, DWORD, LPWSTR, LPDWORD);
+WINSETUPAPI VOID   WINAPI StringTableTrim(HSTRING_TABLE);
+
+
 /* for backward compatability */
 #define SetupDiCreateInterfaceDeviceW	SetupDiCreateDeviceInterfaceW
 #define SetupDiCreateInterfaceDeviceRegKeyW	SetupDiCreateDeviceInterfaceRegKeyW