WINEMENUBUILDER: fix memory leaks, escape the workdir

Mike McCormack mike at codeweavers.com
Tue Feb 22 09:05:53 CST 2005


ChangeLog:
<martin at codeweavers.com>
<fgouget at codeweavers.com>
<dmitry at codeweavers.com>
* fix memory leaks
* escape the workdir
* try again when icon extraction fails
-------------- next part --------------
Index: programs/winemenubuilder/winemenubuilder.c
===================================================================
RCS file: /home/wine/wine/programs/winemenubuilder/winemenubuilder.c,v
retrieving revision 1.25
diff -u -p -r1.25 winemenubuilder.c
--- programs/winemenubuilder/winemenubuilder.c	18 Feb 2005 12:52:33 -0000	1.25
+++ programs/winemenubuilder/winemenubuilder.c	22 Feb 2005 14:20:45 -0000
@@ -660,7 +660,7 @@ static int fork_and_wait( char *linker, 
     return retcode;
 }
 
-static char *cleanup_link( LPCWSTR link )
+static char *cleanup_link( LPCWSTR link, DWORD ofs )
 {
     char *unix_file_name;
     char  *p, *link_name;
@@ -672,8 +672,8 @@ static char *cleanup_link( LPCWSTR link 
         return NULL;
     }
 
-    link_name = unix_file_name;
-    p = strrchr( link_name, '/' );
+    link_name = &unix_file_name[strlen(unix_file_name)-ofs];
+    p = strchr( link_name, '/' );
     if (p)
         link_name = p + 1;
 
@@ -695,10 +695,11 @@ static char *cleanup_link( LPCWSTR link 
  * returns TRUE if successful
  * *loc will contain CS_DESKTOPDIRECTORY, CS_STARTMENU, CS_STARTUP
  */
-static BOOL GetLinkLocation( LPCWSTR linkfile, DWORD *loc )
+static BOOL GetLinkLocation( LPCWSTR linkfile, DWORD *ofs, DWORD *loc )
 {
     WCHAR filename[MAX_PATH], buffer[MAX_PATH];
     DWORD len, i, r, filelen;
+    char *ufilename,*ubuffer;
     const DWORD locations[] = {
         CSIDL_STARTUP, CSIDL_DESKTOPDIRECTORY, CSIDL_STARTMENU,
         CSIDL_COMMON_STARTUP, CSIDL_COMMON_DESKTOPDIRECTORY,
@@ -731,20 +732,26 @@ static BOOL GetLinkLocation( LPCWSTR lin
 
         /* return the remainder of the string and link type */
         *loc = locations[i];
+        ufilename = wine_get_unix_file_name(filename);
+        ubuffer = wine_get_unix_file_name(buffer);
+        *ofs = strlen(ufilename)-strlen(ubuffer);
+        HeapFree(GetProcessHeap(), 0, ufilename);
+        HeapFree(GetProcessHeap(), 0, ubuffer);
         return TRUE;
     }
 
     return FALSE;
 }
 
-static BOOL InvokeShellLinker( IShellLinkW *sl, LPCWSTR link )
+static BOOL InvokeShellLinker( IShellLinkW *sl, LPCWSTR link, BOOL bAgain )
 {
-    char *link_name = NULL, *icon_name = NULL, *work_dir = NULL;
+    char *link_name = NULL, *icon_name = NULL;
+    char *escaped_workdir = NULL;
     char *escaped_path = NULL, *escaped_args = NULL, *escaped_description = NULL;
     WCHAR szDescription[INFOTIPSIZE], szPath[MAX_PATH], szWorkDir[MAX_PATH];
     WCHAR szArgs[INFOTIPSIZE], szIconPath[MAX_PATH];
     int iIconId = 0, r = -1;
-    DWORD csidl = -1;
+    DWORD csidl = -1, ofs = 0;
 
     if ( !link )
     {
@@ -752,7 +759,7 @@ static BOOL InvokeShellLinker( IShellLin
         return FALSE;
     }
 
-    if( !GetLinkLocation( link, &csidl ) )
+    if( !GetLinkLocation( link, &ofs, &csidl ) )
     {
         WINE_WARN("Unknown link location '%s'. Ignoring.\n",wine_dbgstr_w(link));
         return TRUE;
@@ -800,8 +807,12 @@ static BOOL InvokeShellLinker( IShellLin
     /* fail - try once again at reboot time */
     if( !icon_name )
     {
+        if (bAgain)
+        {
+            WINE_WARN("Unable to extract icon, deferring.\n");
+            goto cleanup;
+        }
         WINE_ERR("failed to extract icon.\n");
-        return FALSE;
     }
 
     /* check the path */
@@ -814,10 +825,6 @@ static BOOL InvokeShellLinker( IShellLin
         if (!(p = strrchrW( szPath, '.' ))) return FALSE;
         if (strchrW( p, '\\' ) || strchrW( p, '/' )) return FALSE;
         if (lstrcmpiW( p, exeW )) return FALSE;
-
-        /* convert app working dir */
-        if (szWorkDir[0])
-            work_dir = wine_get_unix_file_name( szWorkDir );
     }
     else
     {
@@ -831,27 +838,29 @@ static BOOL InvokeShellLinker( IShellLin
         lstrcatW(szPath, startW);
     }
 
-    link_name = cleanup_link( link );
+    link_name = cleanup_link( link, ofs );
     if( !link_name )
     {
         WINE_ERR("Couldn't clean up link name %s\n", wine_dbgstr_w(link));
-        return FALSE;
+        goto cleanup;
     }
 
     /* escape the path and parameters */
     escaped_path = escape(szPath);
     escaped_args = escape(szArgs);
+    escaped_workdir = escape(szWorkDir);
     escaped_description = escape(szDescription);
 
     r = fork_and_wait("wineshelllink", link_name, escaped_path,
                       in_desktop_dir(csidl), escaped_args, icon_name,
-                      work_dir ? work_dir : "", escaped_description);
+                      escaped_workdir, escaped_description);
 
+cleanup:
     HeapFree( GetProcessHeap(), 0, icon_name );
-    HeapFree( GetProcessHeap(), 0, work_dir );
     HeapFree( GetProcessHeap(), 0, link_name );
     HeapFree( GetProcessHeap(), 0, escaped_args );
     HeapFree( GetProcessHeap(), 0, escaped_path );
+    HeapFree( GetProcessHeap(), 0, escaped_workdir );
     HeapFree( GetProcessHeap(), 0, escaped_description );
 
     if (r)
@@ -915,7 +924,7 @@ static BOOL Process_Link( LPCWSTR linkna
         /* If something fails (eg. Couldn't extract icon)
          * defer this menu entry to reboot via runonce
          */
-        if( ! InvokeShellLinker( sl, fullname ) && bAgain )
+        if( ! InvokeShellLinker( sl, fullname, bAgain ) && bAgain )
             DeferToRunOnce( fullname );
         else
             WINE_TRACE("Success.\n");


More information about the wine-patches mailing list