Commit 6cb7ca41 authored by Alexandre Julliard's avatar Alexandre Julliard

setupapi: Store the full name to the INF file in the inf_file structure

(based on a patch by James Hawkins).
parent 91da64c9
......@@ -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];
}
......
......@@ -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;
}
......@@ -989,14 +1000,33 @@ 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 );
......
......@@ -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);
}
......
......@@ -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 */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment