implement "App Paths" support

Andreas Mohr andi at rhlx01.fht-esslingen.de
Fri Feb 15 18:59:35 CST 2002


Hi all,

this implements "App Paths" registry key support for SearchPath(),
which is sort of undocumented, it seems.

Several Microsoft apps make use of this, and from the list of entries
in this registry key it sounds like it's many more apps, too.

(if you got a "couldn't load/find dll" error, chances are that it
just might work now due to app specific paths being searched, too)

-- 
Andreas Mohr                        Stauferstr. 6, D-71272 Renningen, Germany
Tel. +49 7159 800604                http://home.nexgo.de/andi.mohr/
-------------- next part --------------
Determining best CVS host...
Using CVSROOT :pserver:cvs at rhlx01.fht-esslingen.de:/home/wine
Index: files/directory.c
===================================================================
RCS file: /home/wine/wine/files/directory.c,v
retrieving revision 1.43
diff -u -r1.43 directory.c
--- files/directory.c	18 Jan 2002 18:53:11 -0000	1.43
+++ files/directory.c	16 Feb 2002 00:54:01 -0000
@@ -24,6 +24,7 @@
 #include "wingdi.h"
 #include "wine/winuser16.h"
 #include "winerror.h"
+#include "winreg.h"
 #include "drive.h"
 #include "file.h"
 #include "heap.h"
@@ -513,6 +514,37 @@
     return TRUE;
 }
 
+static BOOL DIR_SearchSemicolonedPaths(LPCSTR name, DOS_FULL_NAME *full_name, LPSTR pathlist)
+{
+    LPSTR next, buffer = NULL;
+    INT len = strlen(name), newlen, currlen = 0;
+    BOOL ret = FALSE;
+   
+    next = pathlist;
+    while (!ret && next)
+    {
+        LPSTR cur = next;
+        while (*cur == ';') cur++;
+        if (!*cur) break;
+        next = strchr( cur, ';' );
+        if (next) *next++ = '\0';
+	newlen = strlen(cur) + len + 2;
+	if (newlen > currlen)
+	{
+            if (!(buffer = HeapReAlloc( GetProcessHeap(), 0, buffer, newlen)))
+                goto done;
+	    currlen = newlen;
+	}
+        strcpy( buffer, cur );
+        strcat( buffer, "\\" );
+        strcat( buffer, name );
+        ret = DOSFS_GetFullName( buffer, TRUE, full_name );
+    }
+done:
+    HeapFree( GetProcessHeap(), 0, buffer );
+    return ret;
+}
+
 
 /***********************************************************************
  *           DIR_TryEnvironmentPath
@@ -522,9 +554,8 @@
  */
 static BOOL DIR_TryEnvironmentPath( LPCSTR name, DOS_FULL_NAME *full_name, LPCSTR envpath )
 {
-    LPSTR path, next, buffer;
+    LPSTR path;
     BOOL ret = FALSE;
-    INT len = strlen(name);
     DWORD size;
 
     size = envpath ? strlen(envpath)+1 : GetEnvironmentVariableA( "PATH", NULL, 0 );
@@ -532,22 +563,8 @@
     if (!(path = HeapAlloc( GetProcessHeap(), 0, size ))) return FALSE;
     if (envpath) strcpy( path, envpath );
     else if (!GetEnvironmentVariableA( "PATH", path, size )) goto done;
-    next = path;
-    while (!ret && next)
-    {
-        LPSTR cur = next;
-        while (*cur == ';') cur++;
-        if (!*cur) break;
-        next = strchr( cur, ';' );
-        if (next) *next++ = '\0';
-        if (!(buffer = HeapAlloc( GetProcessHeap(), 0, strlen(cur) + len + 2)))
-            goto done;
-        strcpy( buffer, cur );
-        strcat( buffer, "\\" );
-        strcat( buffer, name );
-        ret = DOSFS_GetFullName( buffer, TRUE, full_name );
-        HeapFree( GetProcessHeap(), 0, buffer );
-    }
+
+    ret = DIR_SearchSemicolonedPaths(name, full_name, path);
 
 done:
     HeapFree( GetProcessHeap(), 0, path );
@@ -585,6 +602,47 @@
 
 
 /***********************************************************************
+ *           DIR_TryAppPath
+ *
+ * Helper function for DIR_SearchPath.
+ */
+static BOOL DIR_TryAppPath( LPCSTR name, DOS_FULL_NAME *full_name )
+{
+    HKEY hkAppPaths, hkApp;
+    char lpAppName[MAX_PATHNAME_LEN], lpAppPaths[MAX_PATHNAME_LEN];
+    LPSTR lpFileName;
+    BOOL res = FALSE;
+    DWORD type, count;
+
+    if (RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Microsoft\\Windows\\CurrentVersion\\App Paths", &hkAppPaths) != ERROR_SUCCESS)
+	return FALSE;
+
+    if (GetModuleFileNameA(0, lpAppName, sizeof(lpAppName)) == 0)
+    {
+	WARN("huh, module not found ??\n");
+	goto end;
+    }
+    lpFileName = strrchr(lpAppName, '\\');
+    if (!lpFileName)
+	goto end;
+    else lpFileName++; /* skip '\\' */
+    if (RegOpenKeyA(hkAppPaths, lpFileName, &hkApp) != ERROR_SUCCESS)
+	goto end;
+    count = sizeof(lpAppPaths);
+    if (RegQueryValueExA(hkApp, "Path", 0, &type, (LPBYTE)lpAppPaths, &count) != ERROR_SUCCESS)
+        goto end;
+    TRACE("successfully opened App Paths for '%s'\n", lpFileName);
+
+    res = DIR_SearchSemicolonedPaths(name, full_name, lpAppPaths);
+end:
+    if (hkApp)
+	RegCloseKey(hkApp);
+    if (hkAppPaths)
+	RegCloseKey(hkAppPaths);
+    return res;
+}
+
+/***********************************************************************
  *           DIR_SearchPath
  *
  * Implementation of SearchPathA. 'win32' specifies whether the search
@@ -661,6 +719,10 @@
 
     if (!win32 && DIR_TryModulePath( name, full_name, win32 )) goto done;
 
+    /* Try the "App Paths" entry if existing (undocumented ??) */
+    if (DIR_TryAppPath(name, full_name))
+	goto done;
+    
     /* Try all directories in path */
 
     ret = DIR_TryEnvironmentPath( name, full_name, NULL );


More information about the wine-patches mailing list