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 );