* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
+/* Partially synced with Wine Staging 2.2 */
+
#include "setupapi_private.h"
#include <ndk/obfuncs.h>
int cur_section; /* index of section being parsed*/
struct line *line; /* current line */
unsigned int line_pos; /* current line position in file */
+ unsigned int broken_line; /* first line containing invalid data (if any) */
unsigned int error; /* error code */
unsigned int token_len; /* current token len */
WCHAR token[MAX_FIELD_LEN+1]; /* current token */
if (new_count < 32) new_count = 32;
if (array)
- new_array = HeapReAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, array, new_count * elem );
+ new_array = HeapReAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, array, new_count * elem );
else
- new_array = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, new_count * elem );
+ new_array = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, new_count * elem );
if (new_array)
*count = new_count;
{
struct section *section;
struct line *line;
- int i;
+ unsigned int i;
if (section_index < 0 || section_index >= file->nb_sections) return NULL;
section = file->sections[section_index];
struct section *strings_section;
struct line *line;
struct field *field;
- unsigned int i,j;
+ unsigned int i, j;
int dirid;
WCHAR *dirid_str, *end;
const WCHAR *ret = NULL;
if (j == strings_section->nb_lines || !line->nb_fields) goto not_found;
field = &file->fields[line->first_field];
GetLocaleInfo(LOCALE_SYSTEM_DEFAULT, LOCALE_ILANGUAGE, Lang, sizeof(Lang)/sizeof(TCHAR)); // get the current system locale for translated strings
- strcatW(StringLangId, Lang); // append the Language identifier from GetLocaleInfo
+
+ strcpyW(StringLangId + 8, Lang + 2);
+ // now you have e.g. Strings.07 for german neutral translations
+ for (i = 0; i < file->nb_sections; i++) // search in all sections
+ {
+ if (!strcmpiW(file->sections[i]->name,StringLangId)) // if the section is a Strings.* section
+ {
+ strings_section = file->sections[i]; // select this section for further use
+ for (j = 0, line = strings_section->lines; j < strings_section->nb_lines; j++, line++) // process all lines in this section
+ {
+ if (line->key_field == -1) continue; // if no key then skip
+ if (strncmpiW( str, file->fields[line->key_field].text, *len )) continue; // if wrong key name, then skip
+ if (!file->fields[line->key_field].text[*len]) // if value exist
+ {
+ field = &file->fields[line->first_field]; // then extract value and
+ break; // no more search necessary
+ }
+ }
+ }
+ }
+
+ strcpyW(StringLangId + 8, Lang); // append the Language identifier from GetLocaleInfo
// now you have e.g. Strings.0407 for german translations
for (i = 0; i < file->nb_sections; i++) // search in all sections
{
/* 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_substW( const struct inf_file *file, const WCHAR *text, WCHAR *buffer,
- unsigned int size )
+static unsigned int PARSER_string_substW( const struct inf_file *file, const WCHAR *text,
+ WCHAR *buffer, unsigned int size )
{
const WCHAR *start, *subst, *p;
unsigned int len, total = 0;
- int inside = 0;
+ BOOL inside = FALSE;
if (!buffer) size = MAX_STRING_LEN + 1;
for (p = start = text; *p; p++)
/* 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;
/* check if the pointer points to an end of file */
-static inline int is_eof( const struct parser *parser, const WCHAR *ptr )
+static inline BOOL is_eof( const struct parser *parser, const WCHAR *ptr )
{
return (ptr >= parser->end || *ptr == CONTROL_Z);
}
/* check if the pointer points to an end of line */
-static inline int is_eol( const struct parser *parser, const WCHAR *ptr )
+static inline BOOL is_eol( const struct parser *parser, const WCHAR *ptr )
{
return (ptr >= parser->end || *ptr == CONTROL_Z || *ptr == '\n');
}
/* add a field containing the current token to the current line */
-static struct field *add_field_from_token( struct parser *parser, int is_key )
+static struct field *add_field_from_token( struct parser *parser, BOOL is_key )
{
struct field *field;
WCHAR *text;
set_state( parser, SECTION_NAME );
return p + 1;
default:
- if (!isspaceW(*p))
+ if (isspaceW(*p)) break;
+ if (parser->cur_section != -1)
{
parser->start = p;
set_state( parser, KEY_NAME );
return p;
}
+ if (!parser->broken_line)
+ parser->broken_line = parser->line_pos;
break;
}
}
case '=':
push_token( parser, token_end );
- if (!add_field_from_token( parser, 1 )) return NULL;
+ if (!add_field_from_token( parser, TRUE )) return NULL;
parser->start = p + 1;
push_state( parser, VALUE_NAME );
set_state( parser, LEADING_SPACES );
return p + 1;
case ';':
push_token( parser, token_end );
- if (!add_field_from_token( parser, 0 )) return NULL;
+ if (!add_field_from_token( parser, FALSE )) return NULL;
push_state( parser, LINE_START );
set_state( parser, COMMENT );
return p + 1;
{
case ';':
push_token( parser, token_end );
- if (!add_field_from_token( parser, 0 )) return NULL;
+ if (!add_field_from_token( parser, FALSE )) return NULL;
push_state( parser, LINE_START );
set_state( parser, COMMENT );
return p + 1;
case ',':
push_token( parser, token_end );
- if (!add_field_from_token( parser, 0 )) return NULL;
+ if (!add_field_from_token( parser, FALSE )) return NULL;
parser->start = p + 1;
push_state( parser, VALUE_NAME );
set_state( parser, LEADING_SPACES );
}
}
push_token( parser, token_end );
- if (!add_field_from_token( parser, 0 )) return NULL;
+ if (!add_field_from_token( parser, FALSE )) return NULL;
set_state( parser, LINE_START );
return p;
}
/* handler for parser QUOTES state */
static const WCHAR *quotes_state( struct parser *parser, const WCHAR *pos )
{
- const WCHAR *p, *token_end = parser->start;
+ const WCHAR *p;
for (p = pos; !is_eol( parser, p ); p++)
{
if (p+1 < parser->end && p[1] == '"') /* double quotes */
{
push_token( parser, p + 1 );
- parser->start = token_end = p + 2;
+ parser->start = p + 2;
p++;
}
else /* end of quotes */
}
+static void free_inf_file( struct inf_file *file )
+{
+ unsigned int i;
+
+ for (i = 0; i < file->nb_sections; i++) HeapFree( GetProcessHeap(), 0, file->sections[i] );
+ HeapFree( GetProcessHeap(), 0, file->filename );
+ HeapFree( GetProcessHeap(), 0, file->sections );
+ HeapFree( GetProcessHeap(), 0, file->fields );
+ HeapFree( GetProcessHeap(), 0, file->strings );
+ HeapFree( GetProcessHeap(), 0, file );
+}
+
+
/* parse a complete buffer */
static DWORD parse_buffer( struct inf_file *file, const WCHAR *buffer, const WCHAR *end,
UINT *error_line )
parser.stack_pos = 0;
parser.cur_section = -1;
parser.line_pos = 1;
+ parser.broken_line = 0;
parser.error = 0;
parser.token_len = 0;
/* find the [strings] section */
file->strings_section = find_section( file, Strings );
+
+ if (file->strings_section == -1 && parser.broken_line)
+ {
+ if (error_line) *error_line = parser.broken_line;
+ return ERROR_EXPECTED_SECTION_NAME;
+ }
+
return 0;
}
}
else
{
- WCHAR *new_buff = (WCHAR *)buffer;
+ WCHAR *new_buff = buffer;
/* UCS-16 files should start with the Unicode BOM; we should skip it */
if (*new_buff == 0xfeff)
new_buff++;
UnmapViewOfFile( buffer );
if (err)
{
- HeapFree( GetProcessHeap(), 0, file );
+ if (file) free_inf_file( file );
SetLastError( err );
file = NULL;
}
if (handle != INVALID_HANDLE_VALUE)
{
- file = parse_file( handle, error, style );
+ file = parse_file( handle, error, style);
CloseHandle( handle );
}
if (!file)
}
SetLastError( 0 );
- return (HINF)file;
+ return file;
}
void WINAPI SetupCloseInfFile( HINF hinf )
{
struct inf_file *file = hinf;
- unsigned int i;
if (!hinf || (hinf == INVALID_HANDLE_VALUE)) return;
- for (i = 0; i < file->nb_sections; i++) HeapFree( GetProcessHeap(), 0, file->sections[i] );
- HeapFree( GetProcessHeap(), 0, file->filename );
- HeapFree( GetProcessHeap(), 0, file->sections );
- HeapFree( GetProcessHeap(), 0, file->fields );
- HeapFree( GetProcessHeap(), 0, file->strings );
- HeapFree( GetProcessHeap(), 0, file );
+ free_inf_file( file );
}
}
len = strlenW(wfdFileInfo.cFileName) + 1;
- requiredSize += (DWORD)(len * sizeof(WCHAR));
+ requiredSize += (DWORD)len;
if (requiredSize <= ReturnBufferSize)
{
strcpyW(pBuffer, wfdFileInfo.cFileName);
} while (FindNextFileW(hSearch, &wfdFileInfo));
FindClose(hSearch);
- requiredSize += sizeof(WCHAR); /* Final NULL char */
+ requiredSize += 1; /* Final NULL char */
if (requiredSize <= ReturnBufferSize)
{
*pBuffer = '\0';
unsigned int i;
for (i = 0; i < file->nb_sections; i++)
+ {
if (strncmpiW(pStr, file->sections[i]->name, len) == 0)
{
if (!Callback(file->sections[i]->name, Context))
return FALSE;
}
+ }
return TRUE;
}