setupapi: Store the full name to the INF file in the inf_file structure
(based on a patch by James Hawkins).
diff --git a/dlls/setupapi/parser.c b/dlls/setupapi/parser.c
index 28a5936..e6587c7 100644
--- a/dlls/setupapi/parser.c
+++ b/dlls/setupapi/parser.c
@@ -83,7 +83,7 @@
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 @@
}
+/* 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 @@
/* 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 @@
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 @@
/***********************************************************************
+ * 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 @@
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 @@
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 @@
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 );