[WINESYNC] setupapi: Move strdupW and strdupWtoA to the setupapi_private.h header.

wine commit id 44ab294e0b6f285f1aab5fc8533a36e852be38fa by Alexandre Julliard <julliard@winehq.org>

[WINESYNC] setupapi: Remove unneeded address-of operator from array name.

wine commit id ce2184e2f14e6ace87cd50c938b5e99d35ca80c1 by Andrew Talbot <andrew.talbot@talbotville.com>

[WINESYNC] setupapi: Do not cast NULL.

wine commit id d62b48df2acece81b533a92fbca566cc4023be43 by Michael Stefaniuc <mstefani@redhat.de>

[WINESYNC] setupapi: Implement SetupInstallFile{A, W}.

wine commit id 19764fcf4c7c05d5badbef54be64170c2ebadd83 by Hans Leidekker <hans@codeweavers.com>

NOTE: Already committed in ReactOS in commit 336ef53fa (r37876).
The lost memory cleanup on failure will be recovered by wine commit
4d796458d0ed517d45adc57a1aedaf1c3bdde232

[WINESYNC] setupapi: Implement StringTableAddStringEx.

wine commit id c2f99f30143e1180620980f3d5713456392c8ecf by Hans Leidekker <hans@codeweavers.com>

+ Re-integrate existing ReactOS bug fixes
+ Add missing dwExtraDataSize && lpExtraData zero/NULL checks in StringTableAddStringEx

Co-authored-by: Hermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>

[WINESYNC] setupapi: Fix typo in StringTableGetExtraData.

wine commit id d8dad22c9783e1868ec4bb72d8051dd0a5f4f0a7 by Hans Leidekker <hans@codeweavers.com>

[WINESYNC] setupapi: Implement StringTableLookUpStringEx.

wine commit id 18b5366c35f95eb6e7fc6e19c50c371a81d5a980 by Hans Leidekker <hans@codeweavers.com>

[WINESYNC] setupapi: Add some tests for StringTableLookUpStringEx. Make them pass.

wine commit id 601870a4351753555bfa351a23328b2e1109c7b0 by Hans Leidekker <hans@codeweavers.com>

[WINESYNC] setupapi: Fix the StringTableLookUpStringEx() prototype.

wine commit id 916d6a44500735b3fecf0e7c485c2aa7e8025644 by Francois Gouget <fgouget@free.fr>

These commits have been grouped together, since all of these were
partially already present in the forked stringtable.c code.

[WINESYNC] setupapi: Implement SetupInstallFileExA/W.

wine commit id bd9c265cc26a4cf2c9141a99dadb2f9ccf4b6f8c by Hans Leidekker <hans@codeweavers.com>

[WINESYNC] setupapi: Remove superfluous pointer casts.

wine commit id ffae0123ac46ba6dfac74d7c84422073fd53b580 by Michael Stefaniuc <mstefani@redhat.de>

[WINESYNC] setupapi: Fix memory leak.

Found by Valgrind.

wine commit id 63231be8044441218fb82899e748900e1ace3d0d by Huw Davies <huw@codeweavers.com>

NOTE: Some of the code was already present as part of ReactOS-specific
changes. It has been slightly adapted to suit Wine changes.

Co-authored-by: Hermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>

[WINESYNC] setupapi: Destination directory defaults to system directory.

wine commit id 1b8ba2537111f0d691d2592bb4ffb6bc4fe4f20e by Hans Leidekker <hans@codeweavers.com>

[WINESYNC] setupapi: Avoid hardcoding the Unicode string literal lengths.

wine commit id 9097fa132e56cc542fa3ea77706fea79353d2f4a by Francois Gouget <fgouget@free.fr>

[WINESYNC] setupapi: Avoid memory leaks (coverity).

wine commit id 4d796458d0ed517d45adc57a1aedaf1c3bdde232 by André Hentschel <nerv@dawncrow.de>

[WINESYNC]: setupapi/stringtable.c is now in sync with wine-staging wine-1.7.18
This commit is contained in:
winesync 2023-09-28 17:44:59 +02:00 committed by Hermès Bélusca-Maïto
parent e087c1ab10
commit 56ece9b185
No known key found for this signature in database
GPG key ID: 3B2539C65E7B93D0
6 changed files with 173 additions and 241 deletions

View file

@ -69,29 +69,6 @@ struct file_queue
}; };
static inline WCHAR *strdupW( const WCHAR *str )
{
WCHAR *ret = NULL;
if (str)
{
int len = (strlenW(str) + 1) * sizeof(WCHAR);
if ((ret = HeapAlloc( GetProcessHeap(), 0, len ))) memcpy( ret, str, len );
}
return ret;
}
static inline char *strdupWtoA( const WCHAR *str )
{
char *ret = NULL;
if (str)
{
DWORD len = WideCharToMultiByte( CP_ACP, 0, str, -1, NULL, 0, NULL, NULL );
if ((ret = HeapAlloc( GetProcessHeap(), 0, len )))
WideCharToMultiByte( CP_ACP, 0, str, -1, ret, len, NULL, NULL );
}
return ret;
}
/* append a file operation to a queue */ /* append a file operation to a queue */
static inline void queue_file_op( struct file_op_queue *queue, struct file_op *op ) static inline void queue_file_op( struct file_op_queue *queue, struct file_op *op )
{ {
@ -203,7 +180,7 @@ UINT CALLBACK QUEUE_callback_WtoA( void *context, UINT notification,
switch(notification) switch(notification)
{ {
case SPFILENOTIFY_COPYERROR: case SPFILENOTIFY_COPYERROR:
param2 = (UINT_PTR)&buffer; param2 = (UINT_PTR)buffer;
/* fall through */ /* fall through */
case SPFILENOTIFY_STARTDELETE: case SPFILENOTIFY_STARTDELETE:
case SPFILENOTIFY_ENDDELETE: case SPFILENOTIFY_ENDDELETE:
@ -363,10 +340,17 @@ static WCHAR *get_destination_dir( HINF hinf, const WCHAR *section )
static const WCHAR Dest[] = {'D','e','s','t','i','n','a','t','i','o','n','D','i','r','s',0}; static const WCHAR Dest[] = {'D','e','s','t','i','n','a','t','i','o','n','D','i','r','s',0};
static const WCHAR Def[] = {'D','e','f','a','u','l','t','D','e','s','t','D','i','r',0}; static const WCHAR Def[] = {'D','e','f','a','u','l','t','D','e','s','t','D','i','r',0};
INFCONTEXT context; INFCONTEXT context;
WCHAR systemdir[MAX_PATH], *dir;
BOOL ret;
if (!SetupFindFirstLineW( hinf, Dest, section, &context ) && if (!(ret = SetupFindFirstLineW( hinf, Dest, section, &context )))
!SetupFindFirstLineW( hinf, Dest, Def, &context )) return NULL; ret = SetupFindFirstLineW( hinf, Dest, Def, &context );
return PARSER_get_dest_dir( &context );
if (ret && (dir = PARSER_get_dest_dir( &context )))
return dir;
GetSystemDirectoryW( systemdir, MAX_PATH );
return strdupW( systemdir );
} }
struct extract_cab_ctx struct extract_cab_ctx
@ -798,7 +782,7 @@ BOOL WINAPI SetupQueueCopySectionW( HSPFILEQ queue, PCWSTR src_root, HINF hinf,
INFCONTEXT security_context; INFCONTEXT security_context;
#endif #endif
INFCONTEXT context; INFCONTEXT context;
WCHAR dest[MAX_PATH], src[MAX_PATH]; WCHAR dest[MAX_PATH], src[MAX_PATH], *dest_dir;
INT flags; INT flags;
BOOL ret; BOOL ret;
@ -851,19 +835,20 @@ BOOL WINAPI SetupQueueCopySectionW( HSPFILEQ queue, PCWSTR src_root, HINF hinf,
if (!hlist) hlist = hinf; if (!hlist) hlist = hinf;
if (!hinf) hinf = hlist; if (!hinf) hinf = hlist;
if (!SetupFindFirstLineW( hlist, section, NULL, &context )) goto done; if (!SetupFindFirstLineW( hlist, section, NULL, &context )) goto done;
if (!(params.TargetDirectory = get_destination_dir( hinf, section ))) goto done; if (!(params.TargetDirectory = dest_dir = get_destination_dir( hinf, section ))) goto done;
do do
{ {
if (!SetupGetStringFieldW( &context, 1, dest, sizeof(dest)/sizeof(WCHAR), NULL )) if (!SetupGetStringFieldW( &context, 1, dest, sizeof(dest)/sizeof(WCHAR), NULL ))
goto done; goto end;
if (!SetupGetStringFieldW( &context, 2, src, sizeof(src)/sizeof(WCHAR), NULL )) *src = 0; if (!SetupGetStringFieldW( &context, 2, src, sizeof(src)/sizeof(WCHAR), NULL )) *src = 0;
if (!SetupGetIntField( &context, 4, &flags )) flags = 0; /* FIXME */ if (!SetupGetIntField( &context, 4, &flags )) flags = 0; /* FIXME */
params.SourceFilename = *src ? src : NULL; params.SourceFilename = *src ? src : NULL;
if (!SetupQueueCopyIndirectW( &params )) goto done; if (!SetupQueueCopyIndirectW( &params )) goto end;
} while (SetupFindNextLine( &context, &context )); } while (SetupFindNextLine( &context, &context ));
ret = TRUE; ret = TRUE;
end:
HeapFree(GetProcessHeap(), 0, dest_dir);
done: done:
#ifdef __REACTOS__ #ifdef __REACTOS__
if (security_descriptor) if (security_descriptor)
@ -1163,7 +1148,7 @@ static BOOL do_file_copyW( LPCWSTR source, LPCWSTR target, DWORD style,
VS_FIXEDFILEINFO *TargetInfo; VS_FIXEDFILEINFO *TargetInfo;
VS_FIXEDFILEINFO *SourceInfo; VS_FIXEDFILEINFO *SourceInfo;
UINT length; UINT length;
WCHAR SubBlock[2]={'\\',0}; static const WCHAR SubBlock[]={'\\',0};
DWORD ret; DWORD ret;
VersionSource = HeapAlloc(GetProcessHeap(),0,VersionSizeSource); VersionSource = HeapAlloc(GetProcessHeap(),0,VersionSizeSource);
@ -1263,17 +1248,17 @@ static BOOL do_file_copyW( LPCWSTR source, LPCWSTR target, DWORD style,
} }
/*********************************************************************** /***********************************************************************
* SetupInstallFileA (SETUPAPI.@) * SetupInstallFileExA (SETUPAPI.@)
*/ */
BOOL WINAPI SetupInstallFileA( HINF hinf, PINFCONTEXT inf_context, PCSTR source, PCSTR root, BOOL WINAPI SetupInstallFileExA( HINF hinf, PINFCONTEXT inf_context, PCSTR source, PCSTR root,
PCSTR dest, DWORD style, PSP_FILE_CALLBACK_A handler, PVOID context ) PCSTR dest, DWORD style, PSP_FILE_CALLBACK_A handler, PVOID context, PBOOL in_use )
{ {
BOOL ret = FALSE; BOOL ret = FALSE;
struct callback_WtoA_context ctx; struct callback_WtoA_context ctx;
UNICODE_STRING sourceW, rootW, destW; UNICODE_STRING sourceW, rootW, destW;
TRACE("%p %p %s %s %s %x %p %p\n", hinf, inf_context, debugstr_a(source), debugstr_a(root), TRACE("%p %p %s %s %s %x %p %p %p\n", hinf, inf_context, debugstr_a(source), debugstr_a(root),
debugstr_a(dest), style, handler, context); debugstr_a(dest), style, handler, context, in_use);
sourceW.Buffer = rootW.Buffer = destW.Buffer = NULL; sourceW.Buffer = rootW.Buffer = destW.Buffer = NULL;
if (source && !RtlCreateUnicodeStringFromAsciiz( &sourceW, source )) if (source && !RtlCreateUnicodeStringFromAsciiz( &sourceW, source ))
@ -1295,7 +1280,7 @@ BOOL WINAPI SetupInstallFileA( HINF hinf, PINFCONTEXT inf_context, PCSTR source,
ctx.orig_context = context; ctx.orig_context = context;
ctx.orig_handler = handler; ctx.orig_handler = handler;
ret = SetupInstallFileW( hinf, inf_context, sourceW.Buffer, rootW.Buffer, destW.Buffer, style, QUEUE_callback_WtoA, &ctx ); ret = SetupInstallFileExW( hinf, inf_context, sourceW.Buffer, rootW.Buffer, destW.Buffer, style, QUEUE_callback_WtoA, &ctx, in_use );
exit: exit:
RtlFreeUnicodeString( &sourceW ); RtlFreeUnicodeString( &sourceW );
@ -1305,10 +1290,19 @@ exit:
} }
/*********************************************************************** /***********************************************************************
* SetupInstallFileW (SETUPAPI.@) * SetupInstallFileA (SETUPAPI.@)
*/ */
BOOL WINAPI SetupInstallFileW( HINF hinf, PINFCONTEXT inf_context, PCWSTR source, PCWSTR root, BOOL WINAPI SetupInstallFileA( HINF hinf, PINFCONTEXT inf_context, PCSTR source, PCSTR root,
PCWSTR dest, DWORD style, PSP_FILE_CALLBACK_W handler, PVOID context ) PCSTR dest, DWORD style, PSP_FILE_CALLBACK_A handler, PVOID context )
{
return SetupInstallFileExA( hinf, inf_context, source, root, dest, style, handler, context, NULL );
}
/***********************************************************************
* SetupInstallFileExW (SETUPAPI.@)
*/
BOOL WINAPI SetupInstallFileExW( HINF hinf, PINFCONTEXT inf_context, PCWSTR source, PCWSTR root,
PCWSTR dest, DWORD style, PSP_FILE_CALLBACK_W handler, PVOID context, PBOOL in_use )
{ {
static const WCHAR CopyFiles[] = {'C','o','p','y','F','i','l','e','s',0}; static const WCHAR CopyFiles[] = {'C','o','p','y','F','i','l','e','s',0};
@ -1316,8 +1310,10 @@ BOOL WINAPI SetupInstallFileW( HINF hinf, PINFCONTEXT inf_context, PCWSTR source
WCHAR *buffer, *p, *inf_source = NULL; WCHAR *buffer, *p, *inf_source = NULL;
unsigned int len; unsigned int len;
TRACE("%p %p %s %s %s %x %p %p\n", hinf, inf_context, debugstr_w(source), debugstr_w(root), TRACE("%p %p %s %s %s %x %p %p %p\n", hinf, inf_context, debugstr_w(source), debugstr_w(root),
debugstr_w(dest), style, handler, context); debugstr_w(dest), style, handler, context, in_use);
if (in_use) FIXME("no file in use support\n");
if (hinf) if (hinf)
{ {
@ -1373,6 +1369,15 @@ BOOL WINAPI SetupInstallFileW( HINF hinf, PINFCONTEXT inf_context, PCWSTR source
return ret; return ret;
} }
/***********************************************************************
* SetupInstallFileW (SETUPAPI.@)
*/
BOOL WINAPI SetupInstallFileW( HINF hinf, PINFCONTEXT inf_context, PCWSTR source, PCWSTR root,
PCWSTR dest, DWORD style, PSP_FILE_CALLBACK_W handler, PVOID context )
{
return SetupInstallFileExW( hinf, inf_context, source, root, dest, style, handler, context, NULL );
}
/*********************************************************************** /***********************************************************************
* SetupCommitFileQueueW (SETUPAPI.@) * SetupCommitFileQueueW (SETUPAPI.@)
*/ */
@ -1699,7 +1704,7 @@ UINT WINAPI SetupDefaultQueueCallbackA( PVOID context, UINT notification,
UINT_PTR param1, UINT_PTR param2 ) UINT_PTR param1, UINT_PTR param2 )
{ {
FILEPATHS_A *paths = (FILEPATHS_A *)param1; FILEPATHS_A *paths = (FILEPATHS_A *)param1;
struct default_callback_context *ctx = (struct default_callback_context *)context; struct default_callback_context *ctx = context;
switch(notification) switch(notification)
{ {
@ -1763,7 +1768,7 @@ UINT WINAPI SetupDefaultQueueCallbackW( PVOID context, UINT notification,
UINT_PTR param1, UINT_PTR param2 ) UINT_PTR param1, UINT_PTR param2 )
{ {
FILEPATHS_W *paths = (FILEPATHS_W *)param1; FILEPATHS_W *paths = (FILEPATHS_W *)param1;
struct default_callback_context *ctx = (struct default_callback_context *)context; struct default_callback_context *ctx = context;
switch(notification) switch(notification)
{ {

View file

@ -438,8 +438,8 @@
@ stdcall SetupInitializeFileLogA(str long) @ stdcall SetupInitializeFileLogA(str long)
@ stdcall SetupInitializeFileLogW(wstr long) @ stdcall SetupInitializeFileLogW(wstr long)
@ stdcall SetupInstallFileA(ptr ptr str str str long ptr ptr) @ stdcall SetupInstallFileA(ptr ptr str str str long ptr ptr)
@ stub SetupInstallFileExA @ stdcall SetupInstallFileExA(ptr ptr str str str long ptr ptr ptr)
@ stub SetupInstallFileExW @ stdcall SetupInstallFileExW(ptr ptr wstr wstr wstr long ptr ptr ptr)
@ stdcall SetupInstallFileW(ptr ptr wstr wstr wstr long ptr ptr) @ stdcall SetupInstallFileW(ptr ptr wstr wstr wstr long ptr ptr)
@ stdcall SetupInstallFilesFromInfSectionA(long long long str str long) @ stdcall SetupInstallFilesFromInfSectionA(long long long str str long)
@ stdcall SetupInstallFilesFromInfSectionW(long long long wstr wstr long) @ stdcall SetupInstallFilesFromInfSectionW(long long long wstr wstr long)

View file

@ -268,7 +268,30 @@ extern DWORD GlobalSetupFlags;
#define REGPART_RENAME "\\Rename" #define REGPART_RENAME "\\Rename"
#define REG_VERSIONCONFLICT "Software\\Microsoft\\VersionConflictManager" #define REG_VERSIONCONFLICT "Software\\Microsoft\\VersionConflictManager"
inline static WCHAR *strdupAtoW( const char *str ) static inline WCHAR *strdupW( const WCHAR *str )
{
WCHAR *ret = NULL;
if (str)
{
int len = (strlenW(str) + 1) * sizeof(WCHAR);
if ((ret = HeapAlloc( GetProcessHeap(), 0, len ))) memcpy( ret, str, len );
}
return ret;
}
static inline char *strdupWtoA( const WCHAR *str )
{
char *ret = NULL;
if (str)
{
DWORD len = WideCharToMultiByte( CP_ACP, 0, str, -1, NULL, 0, NULL, NULL );
if ((ret = HeapAlloc( GetProcessHeap(), 0, len )))
WideCharToMultiByte( CP_ACP, 0, str, -1, ret, len, NULL, NULL );
}
return ret;
}
static inline WCHAR *strdupAtoW( const char *str )
{ {
WCHAR *ret = NULL; WCHAR *ret = NULL;
if (str) if (str)

View file

@ -187,110 +187,6 @@ StringTableDestroy(HSTRING_TABLE hStringTable)
MyFree(pStringTable); 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 %x\n", 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].pString != NULL)
{
if (dwFlags & 1)
{
if (!lstrcmpW(pStringTable->pSlots[i].pString, lpString))
{
return i + 1;
}
}
else
{
if (!lstrcmpiW(pStringTable->pSlots[i].pString, lpString))
{
return i + 1;
}
}
}
}
/* Check for filled slot table */
if (pStringTable->dwUsedSlots == pStringTable->dwMaxSlots)
{
PTABLE_SLOT pNewSlots;
DWORD dwNewMaxSlots;
/* FIXME: not thread safe */
dwNewMaxSlots = pStringTable->dwMaxSlots * 2;
pNewSlots = MyMalloc(sizeof(TABLE_SLOT) * dwNewMaxSlots);
if (pNewSlots == NULL)
return (DWORD)-1;
memset(&pNewSlots[pStringTable->dwMaxSlots], 0, sizeof(TABLE_SLOT) * (dwNewMaxSlots - pStringTable->dwMaxSlots));
memcpy(pNewSlots, pStringTable->pSlots, sizeof(TABLE_SLOT) * pStringTable->dwMaxSlots);
pNewSlots = InterlockedExchangePointer((PVOID*)&pStringTable->pSlots, pNewSlots);
MyFree(pNewSlots);
pStringTable->dwMaxSlots = dwNewMaxSlots;
return StringTableAddString(hStringTable, lpString, dwFlags);
}
/* Search for an empty slot */
for (i = 0; i < pStringTable->dwMaxSlots; i++)
{
if (pStringTable->pSlots[i].pString == 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].pString, lpString);
pStringTable->dwUsedSlots++;
return i + 1;
}
}
TRACE("Couldn't find an empty slot!\n");
return (DWORD)-1;
}
/************************************************************************** /**************************************************************************
* StringTableAddStringEx [SETUPAPI.@] * StringTableAddStringEx [SETUPAPI.@]
* *
@ -323,33 +219,30 @@ StringTableAddStringEx(HSTRING_TABLE hStringTable,
PSTRING_TABLE pStringTable; PSTRING_TABLE pStringTable;
DWORD i; DWORD i;
TRACE("%p %s %lx\n", (PVOID)hStringTable, debugstr_w(lpString), dwFlags); TRACE("%p %s %x %p, %u\n", hStringTable, debugstr_w(lpString), dwFlags,
lpExtraData, dwExtraDataSize);
pStringTable = (PSTRING_TABLE)hStringTable; pStringTable = (PSTRING_TABLE)hStringTable;
if (pStringTable == NULL) if (!pStringTable)
{ {
ERR("Invalid hStringTable!\n"); ERR("Invalid hStringTable!\n");
return (DWORD)-1; return ~0u;
} }
/* Search for existing string in the string table */ /* Search for existing string in the string table */
for (i = 0; i < pStringTable->dwMaxSlots; i++) for (i = 0; i < pStringTable->dwMaxSlots; i++)
{ {
if (pStringTable->pSlots[i].pString != NULL) if (pStringTable->pSlots[i].pString)
{ {
if (dwFlags & 1) if (dwFlags & 1)
{ {
if (!lstrcmpW(pStringTable->pSlots[i].pString, lpString)) if (!lstrcmpW(pStringTable->pSlots[i].pString, lpString))
{
return i + 1; return i + 1;
}
} }
else else
{ {
if (!lstrcmpiW(pStringTable->pSlots[i].pString, lpString)) if (!lstrcmpiW(pStringTable->pSlots[i].pString, lpString))
{
return i + 1; return i + 1;
}
} }
} }
} }
@ -357,37 +250,53 @@ StringTableAddStringEx(HSTRING_TABLE hStringTable,
/* Check for filled slot table */ /* Check for filled slot table */
if (pStringTable->dwUsedSlots == pStringTable->dwMaxSlots) if (pStringTable->dwUsedSlots == pStringTable->dwMaxSlots)
{ {
FIXME("Resize the string table!\n"); PTABLE_SLOT pNewSlots;
return (DWORD)-1; DWORD dwNewMaxSlots;
/* FIXME: not thread safe */
dwNewMaxSlots = pStringTable->dwMaxSlots * 2;
pNewSlots = MyMalloc(sizeof(TABLE_SLOT) * dwNewMaxSlots);
if (!pNewSlots)
return ~0u;
memset(&pNewSlots[pStringTable->dwMaxSlots], 0, sizeof(TABLE_SLOT) * (dwNewMaxSlots - pStringTable->dwMaxSlots));
memcpy(pNewSlots, pStringTable->pSlots, sizeof(TABLE_SLOT) * pStringTable->dwMaxSlots);
pNewSlots = InterlockedExchangePointer((PVOID*)&pStringTable->pSlots, pNewSlots);
MyFree(pNewSlots);
pStringTable->dwMaxSlots = dwNewMaxSlots;
return StringTableAddStringEx(hStringTable, lpString, dwFlags, lpExtraData, dwExtraDataSize);
} }
/* Search for an empty slot */ /* Search for an empty slot */
for (i = 0; i < pStringTable->dwMaxSlots; i++) for (i = 0; i < pStringTable->dwMaxSlots; i++)
{ {
if (pStringTable->pSlots[i].pString == NULL) if (!pStringTable->pSlots[i].pString)
{ {
pStringTable->pSlots[i].pString = MyMalloc((lstrlenW(lpString) + 1) * sizeof(WCHAR)); pStringTable->pSlots[i].pString = MyMalloc((lstrlenW(lpString) + 1) * sizeof(WCHAR));
if (pStringTable->pSlots[i].pString == NULL) if (!pStringTable->pSlots[i].pString)
{ {
TRACE("Couldn't allocate memory for a new string!\n"); WARN("Couldn't allocate memory for a new string!\n");
return (DWORD)-1; return ~0u;
} }
lstrcpyW(pStringTable->pSlots[i].pString, lpString); lstrcpyW(pStringTable->pSlots[i].pString, lpString);
pStringTable->pSlots[i].pData = MyMalloc(dwExtraDataSize); if (dwExtraDataSize && lpExtraData)
if (pStringTable->pSlots[i].pData == NULL)
{ {
TRACE("Couldn't allocate memory for a new extra data!\n"); pStringTable->pSlots[i].pData = MyMalloc(dwExtraDataSize);
MyFree(pStringTable->pSlots[i].pString); if (!pStringTable->pSlots[i].pData)
pStringTable->pSlots[i].pString = NULL; {
return (DWORD)-1; TRACE("Couldn't allocate memory for data!\n");
} MyFree(pStringTable->pSlots[i].pString);
pStringTable->pSlots[i].pString = NULL;
return ~0u;
}
memcpy(pStringTable->pSlots[i].pData, memcpy(pStringTable->pSlots[i].pData,
lpExtraData, lpExtraData,
dwExtraDataSize); dwExtraDataSize);
pStringTable->pSlots[i].dwSize = dwExtraDataSize; pStringTable->pSlots[i].dwSize = dwExtraDataSize;
}
pStringTable->dwUsedSlots++; pStringTable->dwUsedSlots++;
@ -396,8 +305,35 @@ StringTableAddStringEx(HSTRING_TABLE hStringTable,
} }
TRACE("Couldn't find an empty slot!\n"); TRACE("Couldn't find an empty slot!\n");
return ~0u;
}
return (DWORD)-1; /**************************************************************************
* 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)
{
return StringTableAddStringEx(hStringTable, lpString, dwFlags, NULL, 0);
} }
/************************************************************************** /**************************************************************************
@ -427,14 +363,14 @@ StringTableDuplicate(HSTRING_TABLE hStringTable)
if (pSourceTable == NULL) if (pSourceTable == NULL)
{ {
ERR("Invalid hStringTable!\n"); ERR("Invalid hStringTable!\n");
return (HSTRING_TABLE)NULL; return NULL;
} }
pDestinationTable = MyMalloc(sizeof(STRING_TABLE)); pDestinationTable = MyMalloc(sizeof(STRING_TABLE));
if (pDestinationTable == NULL) if (pDestinationTable == NULL)
{ {
ERR("Could not allocate a new string table!\n"); ERR("Could not allocate a new string table!\n");
return (HSTRING_TABLE)NULL; return NULL;
} }
memset(pDestinationTable, 0, sizeof(STRING_TABLE)); memset(pDestinationTable, 0, sizeof(STRING_TABLE));
@ -443,7 +379,7 @@ StringTableDuplicate(HSTRING_TABLE hStringTable)
if (pDestinationTable->pSlots == NULL) if (pDestinationTable->pSlots == NULL)
{ {
MyFree(pDestinationTable); MyFree(pDestinationTable);
return (HSTRING_TABLE)NULL; return NULL;
} }
memset(pDestinationTable->pSlots, 0, sizeof(TABLE_SLOT) * pSourceTable->dwMaxSlots); memset(pDestinationTable->pSlots, 0, sizeof(TABLE_SLOT) * pSourceTable->dwMaxSlots);
@ -522,7 +458,7 @@ StringTableGetExtraData(HSTRING_TABLE hStringTable,
return FALSE; return FALSE;
} }
if (pStringTable->pSlots[dwId - 1].dwSize < dwExtraDataSize) if (pStringTable->pSlots[dwId - 1].dwSize > dwExtraDataSize)
{ {
ERR("Data size is too large!\n"); ERR("Data size is too large!\n");
return FALSE; return FALSE;
@ -535,59 +471,6 @@ StringTableGetExtraData(HSTRING_TABLE hStringTable,
return TRUE; return TRUE;
} }
/**************************************************************************
* 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 %x\n", 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].pString != NULL)
{
if (dwFlags & 1)
{
if (!lstrcmpW(pStringTable->pSlots[i].pString, lpString))
return i + 1;
}
else
{
if (!lstrcmpiW(pStringTable->pSlots[i].pString, lpString))
return i + 1;
}
}
}
return (DWORD)-1;
}
/************************************************************************** /**************************************************************************
* StringTableLookUpStringEx [SETUPAPI.@] * StringTableLookUpStringEx [SETUPAPI.@]
* *
@ -599,7 +482,7 @@ StringTableLookUpString(HSTRING_TABLE hStringTable,
* dwFlags [I] Flags * dwFlags [I] Flags
* 1: case sensitive compare * 1: case sensitive compare
* lpExtraData [O] Pointer to the buffer that receives the extra data * lpExtraData [O] Pointer to the buffer that receives the extra data
* lpReserved [I/O] Unused * dwReserved [I/O] Unused
* *
* RETURNS * RETURNS
* Success: String ID * Success: String ID
@ -653,6 +536,29 @@ StringTableLookUpStringEx(HSTRING_TABLE hStringTable,
return ~0u; return ~0u;
} }
/**************************************************************************
* 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)
{
return StringTableLookUpStringEx(hStringTable, lpString, dwFlags, NULL, 0);
}
/************************************************************************** /**************************************************************************
* StringTableSetExtraData [SETUPAPI.@] * StringTableSetExtraData [SETUPAPI.@]
* *

View file

@ -374,6 +374,7 @@ setupapi -
dll/win32/setupapi/dialog.c # Synced to WineStaging-1.9.15 dll/win32/setupapi/dialog.c # Synced to WineStaging-1.9.15
dll/win32/setupapi/query.c # Partially synced to Wine-4.8 dll/win32/setupapi/query.c # Partially synced to Wine-4.8
dll/win32/setupapi/setupcab.c # Synced to WineStaging-1.9.4 dll/win32/setupapi/setupcab.c # Synced to WineStaging-1.9.4
dll/win32/setupapi/stringtable.c # Forked at Wine-1.7.18
win32k - win32k -
win32ss/gdi/ntgdi/bezier.c # Synced to WineStaging-1.9.4 (gdi32/painting.c) win32ss/gdi/ntgdi/bezier.c # Synced to WineStaging-1.9.4 (gdi32/painting.c)

View file

@ -1,9 +1,6 @@
directories: null directories: null
files: files:
dlls/setupapi/queue.c: dll/win32/setupapi/queue.c dlls/setupapi/queue.c: dll/win32/setupapi/queue.c
dlls/setupapi/setupapi.spec: dll/win32/setupapi/setupapi.spec
dlls/setupapi/setupapi_private.h: dll/win32/setupapi/setupapi_private.h
dlls/setupapi/stringtable.c: dll/win32/setupapi/stringtable.c dlls/setupapi/stringtable.c: dll/win32/setupapi/stringtable.c
include/setupapi.h: sdk/include/psdk/setupapi.h
tags: tags:
wine: wine-0.9.59 wine: wine-1.7.18