From b70bbe3d29c5a4f151d1a9987f15fdb93490f4f6 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Thu, 1 Oct 2009 19:44:43 +0200 Subject: [PATCH] setupapi: Duplicate the string substitution code to implement GenFormStrWithoutPlaceHolders16. --- dlls/setupapi/infparse.c | 91 ++++++++++++++++++++++++++++++-- dlls/setupapi/parser.c | 4 +- dlls/setupapi/setupapi_private.h | 2 - 3 files changed, 89 insertions(+), 8 deletions(-) diff --git a/dlls/setupapi/infparse.c b/dlls/setupapi/infparse.c index d56e45bae4a..50aca20e08a 100644 --- a/dlls/setupapi/infparse.c +++ b/dlls/setupapi/infparse.c @@ -27,6 +27,7 @@ #include #include +#include #include "windef.h" #include "winbase.h" @@ -96,6 +97,91 @@ static RETERR16 get_last_error(void) } } +/* string substitution support, duplicated from setupapi/parser.c */ + +static const char *get_string_subst( HINF hinf, const char *str, unsigned int *len, + char subst[MAX_INF_STRING_LENGTH], BOOL no_trailing_slash ) +{ + int dirid; + char *end; + INFCONTEXT context; + char buffer[MAX_INF_STRING_LENGTH]; + + if (!*len) /* empty string (%%) is replaced by single percent */ + { + *len = 1; + return "%"; + } + memcpy( buffer, str, *len ); + buffer[*len] = 0; + + if (SetupFindFirstLineA( hinf, "Strings", buffer, &context ) && + SetupGetStringFieldA( &context, 0, subst, MAX_INF_STRING_LENGTH, NULL )) + { + *len = strlen( subst ); + return subst; + } + + /* check for integer id */ + dirid = strtoul( buffer, &end, 10 ); + if (!*end && !CtlGetLddPath16( dirid, subst )) + { + *len = strlen( subst ); + if (no_trailing_slash && *len && subst[*len - 1] == '\\') *len -= 1; + return subst; + } + return NULL; +} + +static unsigned int string_subst( HINF hinf, const char *text, char *buffer ) +{ + const char *start, *subst, *p; + unsigned int len, total = 0; + int inside = 0; + unsigned int size = MAX_INF_STRING_LENGTH; + char tmp[MAX_INF_STRING_LENGTH]; + + for (p = start = text; *p; p++) + { + if (*p != '%') continue; + inside = !inside; + if (inside) /* start of a %xx% string */ + { + len = p - start; + if (len > size - 1) len = size - 1; + if (buffer) memcpy( buffer + total, start, len ); + total += len; + size -= len; + start = p; + } + else /* end of the %xx% string, find substitution */ + { + len = p - start - 1; + subst = get_string_subst( hinf, start + 1, &len, tmp, p[1] == '\\' ); + if (!subst) + { + subst = start; + len = p - start + 1; + } + if (len > size - 1) len = size - 1; + if (buffer) memcpy( buffer + total, subst, len ); + total += len; + size -= len; + start = p + 1; + } + } + + if (start != p) /* unfinished string, copy it */ + { + len = p - start; + if (len > size - 1) len = size - 1; + if (buffer) memcpy( buffer + total, start, len ); + total += len; + } + if (buffer && size) buffer[total] = 0; + return total; +} + /*********************************************************************** * IpOpen (SETUPX.2) @@ -146,14 +232,11 @@ RETERR16 WINAPI IpGetProfileString16( HINF16 hinf16, LPCSTR section, LPCSTR entr */ void WINAPI GenFormStrWithoutPlaceHolders16( LPSTR dst, LPCSTR src, HINF16 hinf16 ) { - UNICODE_STRING srcW; HINF hinf = get_hinf( hinf16 ); if (!hinf) return; - if (!RtlCreateUnicodeStringFromAsciiz( &srcW, src )) return; - PARSER_string_substA( hinf, srcW.Buffer, dst, MAX_INF_STRING_LENGTH ); - RtlFreeUnicodeString( &srcW ); + string_subst( hinf, src, dst ); TRACE( "%s -> %s\n", debugstr_a(src), debugstr_a(dst) ); } diff --git a/dlls/setupapi/parser.c b/dlls/setupapi/parser.c index 65a6a037499..37b900fc225 100644 --- a/dlls/setupapi/parser.c +++ b/dlls/setupapi/parser.c @@ -418,8 +418,8 @@ static unsigned int PARSER_string_substW( const struct inf_file *file, const WCH /* do string substitutions on the specified text */ /* the buffer is assumed to be large enough */ /* returns necessary length not including terminating null */ -unsigned int PARSER_string_substA( const struct inf_file *file, const WCHAR *text, char *buffer, - unsigned int size ) +static unsigned int PARSER_string_substA( const struct inf_file *file, const WCHAR *text, + char *buffer, unsigned int size ) { WCHAR buffW[MAX_STRING_LEN+1]; DWORD ret; diff --git a/dlls/setupapi/setupapi_private.h b/dlls/setupapi/setupapi_private.h index 307dbae18dd..e505503c5f0 100644 --- a/dlls/setupapi/setupapi_private.h +++ b/dlls/setupapi/setupapi_private.h @@ -84,8 +84,6 @@ static inline WCHAR *strdupAtoW( const char *str ) struct inf_file; extern const WCHAR *DIRID_get_string( int dirid ); -extern unsigned int PARSER_string_substA( const struct inf_file *file, const WCHAR *text, - char *buffer, unsigned int size ); extern const WCHAR *PARSER_get_inf_filename( HINF hinf ); extern WCHAR *PARSER_get_src_root( HINF hinf ); extern WCHAR *PARSER_get_dest_dir( INFCONTEXT *context );