From 6cb7ca4177725158984cfe8d998df1601047697c Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Tue, 7 Feb 2006 16:08:19 +0100 Subject: [PATCH] setupapi: Store the full name to the INF file in the inf_file structure (based on a patch by James Hawkins). --- dlls/setupapi/dirid.c | 3 +- dlls/setupapi/parser.c | 63 +++++++++++++++++++++++--------- dlls/setupapi/queue.c | 7 +--- dlls/setupapi/setupapi_private.h | 5 ++- 4 files changed, 52 insertions(+), 26 deletions(-) diff --git a/dlls/setupapi/dirid.c b/dlls/setupapi/dirid.c index 639da022258..60db095de83 100644 --- a/dlls/setupapi/dirid.c +++ b/dlls/setupapi/dirid.c @@ -165,7 +165,7 @@ static const WCHAR *get_csidl_dir( DWORD csidl ) } /* retrieve the string corresponding to a dirid, or NULL if none */ -const WCHAR *DIRID_get_string( HINF hinf, int dirid ) +const WCHAR *DIRID_get_string( int dirid ) { int i; @@ -188,7 +188,6 @@ const WCHAR *DIRID_get_string( HINF hinf, int dirid ) else { if (dirid > MAX_SYSTEM_DIRID) return get_unknown_dirid(); - if (dirid == DIRID_SRCPATH) return PARSER_get_src_root( hinf ); if (!system_dirids[dirid]) system_dirids[dirid] = create_system_dirid( dirid ); return system_dirids[dirid]; } diff --git a/dlls/setupapi/parser.c b/dlls/setupapi/parser.c index 28a5936643a..e6587c7952a 100644 --- a/dlls/setupapi/parser.c +++ b/dlls/setupapi/parser.c @@ -83,7 +83,7 @@ struct inf_file unsigned int alloc_fields; struct field *fields; int strings_section; /* index of [Strings] section or -1 if none */ - WCHAR *src_root; /* source root directory */ + WCHAR *filename; /* filename of the INF */ }; /* parser definitions */ @@ -174,6 +174,15 @@ static void *grow_array( void *array, unsigned int *count, size_t elem ) } +/* get the directory of the inf file (as counted string, not null-terminated) */ +static const WCHAR *get_inf_dir( struct inf_file *file, unsigned int *len ) +{ + const WCHAR *p = strrchrW( file->filename, '\\' ); + *len = p ? (p + 1 - file->filename) : 0; + return file->filename; +} + + /* find a section by name */ static int find_section( struct inf_file *file, const WCHAR *name ) { @@ -294,10 +303,12 @@ static struct field *add_field( struct inf_file *file, const WCHAR *text ) /* retrieve the string substitution for a directory id */ -static const WCHAR *get_dirid_subst( int dirid, unsigned int *len ) +static const WCHAR *get_dirid_subst( struct inf_file *file, int dirid, unsigned int *len ) { - extern const WCHAR *DIRID_get_string( HINF hinf, int dirid ); - const WCHAR *ret = DIRID_get_string( 0, dirid ); + const WCHAR *ret; + + if (dirid == DIRID_SRCPATH) return get_inf_dir( file, len ); + ret = DIRID_get_string( dirid ); if (ret) *len = strlenW(ret); return ret; } @@ -341,7 +352,7 @@ static const WCHAR *get_string_subst( struct inf_file *file, const WCHAR *str, u memcpy( dirid_str, str, *len * sizeof(WCHAR) ); dirid_str[*len] = 0; dirid = strtolW( dirid_str, &end, 10 ); - if (!*end) ret = get_dirid_subst( dirid, len ); + if (!*end) ret = get_dirid_subst( file, dirid, len ); HeapFree( GetProcessHeap(), 0, dirid_str ); return ret; } @@ -988,15 +999,34 @@ static struct inf_file *parse_file( HANDLE handle, const WCHAR *class, UINT *err } +/*********************************************************************** + * PARSER_get_inf_filename + * + * Retrieve the filename of an inf file. + */ +const WCHAR *PARSER_get_inf_filename( HINF hinf ) +{ + struct inf_file *file = hinf; + return file->filename; +} + + /*********************************************************************** * PARSER_get_src_root * * Retrieve the source directory of an inf file. */ -const WCHAR *PARSER_get_src_root( HINF hinf ) +WCHAR *PARSER_get_src_root( HINF hinf ) { - struct inf_file *file = hinf; - return file->src_root; + unsigned int len; + const WCHAR *dir = get_inf_dir( hinf, &len ); + WCHAR *ret = HeapAlloc( GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR) ); + if (ret) + { + memcpy( ret, dir, len * sizeof(WCHAR) ); + ret[len] = 0; + } + return ret; } @@ -1011,15 +1041,15 @@ WCHAR *PARSER_get_dest_dir( INFCONTEXT *context ) const WCHAR *dir; WCHAR *ptr, *ret; INT dirid; - DWORD len1, len2; + unsigned int len1; + DWORD len2; if (!SetupGetIntField( context, 1, &dirid )) return NULL; - if (!(dir = DIRID_get_string( context->Inf, dirid ))) return NULL; - len1 = strlenW(dir) + 1; + if (!(dir = get_dirid_subst( context->Inf, dirid, &len1 ))) return NULL; if (!SetupGetStringFieldW( context, 2, NULL, 0, &len2 )) len2 = 0; - if (!(ret = HeapAlloc( GetProcessHeap(), 0, (len1+len2) * sizeof(WCHAR) ))) return NULL; - strcpyW( ret, dir ); - ptr = ret + strlenW(ret); + if (!(ret = HeapAlloc( GetProcessHeap(), 0, (len1+len2+1) * sizeof(WCHAR) ))) return NULL; + memcpy( ret, dir, len1 * sizeof(WCHAR) ); + ptr = ret + len1; if (len2 && ptr > ret && ptr[-1] != '\\') *ptr++ = '\\'; if (!SetupGetStringFieldW( context, 2, ptr, len2, NULL )) *ptr = 0; return ret; @@ -1106,8 +1136,7 @@ HINF WINAPI SetupOpenInfFileW( PCWSTR name, PCWSTR class, DWORD style, UINT *err return (HINF)INVALID_HANDLE_VALUE; } TRACE( "%s -> %p\n", debugstr_w(path), file ); - file->src_root = path; - if ((p = strrchrW( path, '\\' ))) p[1] = 0; /* remove file name */ + file->filename = path; SetLastError( 0 ); return (HINF)file; } @@ -1185,7 +1214,7 @@ void WINAPI SetupCloseInfFile( HINF hinf ) unsigned int i; for (i = 0; i < file->nb_sections; i++) HeapFree( GetProcessHeap(), 0, file->sections[i] ); - HeapFree( GetProcessHeap(), 0, file->src_root ); + HeapFree( GetProcessHeap(), 0, file->filename ); HeapFree( GetProcessHeap(), 0, file->sections ); HeapFree( GetProcessHeap(), 0, file->fields ); HeapFree( GetProcessHeap(), 0, file->strings ); diff --git a/dlls/setupapi/queue.c b/dlls/setupapi/queue.c index 390fd047ccd..c06a948754f 100644 --- a/dlls/setupapi/queue.c +++ b/dlls/setupapi/queue.c @@ -296,12 +296,9 @@ static void get_src_file_info( HINF hinf, struct file_op *op ) /* find the SourceDisksFiles entry */ if (!SetupFindFirstLineW( hinf, SourceDisksFiles, op->src_file, &file_ctx )) { - const WCHAR *dir; - if ((op->style & (SP_COPY_SOURCE_ABSOLUTE|SP_COPY_SOURCEPATH_ABSOLUTE))) return; /* no specific info, use .inf file source directory */ - if (!op->src_root && (dir = DIRID_get_string( hinf, DIRID_SRCPATH ))) - op->src_root = strdupW( dir ); + if (!op->src_root) op->src_root = PARSER_get_src_root( hinf ); return; } if (!SetupGetIntField( &file_ctx, 1, &diskid )) return; @@ -351,7 +348,7 @@ static void get_src_file_info( HINF hinf, struct file_op *op ) if (!SetupGetStringFieldW( &disk_ctx, 4, ptr, len2, NULL )) *ptr = 0; } } - if (!op->src_root) op->src_root = strdupW( PARSER_get_src_root(hinf) ); + if (!op->src_root) op->src_root = PARSER_get_src_root(hinf); } diff --git a/dlls/setupapi/setupapi_private.h b/dlls/setupapi/setupapi_private.h index 80d1f5559c2..87ee8abc979 100644 --- a/dlls/setupapi/setupapi_private.h +++ b/dlls/setupapi/setupapi_private.h @@ -32,12 +32,13 @@ /* string substitutions */ struct inf_file; -extern const WCHAR *DIRID_get_string( HINF hinf, int dirid ); +extern const WCHAR *DIRID_get_string( int dirid ); extern unsigned int PARSER_string_substA( struct inf_file *file, const WCHAR *text, char *buffer, unsigned int size ); extern unsigned int PARSER_string_substW( struct inf_file *file, const WCHAR *text, WCHAR *buffer, unsigned int size ); -extern const WCHAR *PARSER_get_src_root( HINF hinf ); +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 ); /* support for Ascii queue callback functions */