winemenubuilder: Log where freedesktop menu files are created, and provide an option to clean them up.
This commit is contained in:
parent
31e5093555
commit
267858b4c2
|
@ -50,7 +50,8 @@
|
||||||
* shared location for an "All Users" entry then do so. As a suggestion the
|
* shared location for an "All Users" entry then do so. As a suggestion the
|
||||||
* shared menu Wine base could be writable to the wine group, or a wineadm
|
* shared menu Wine base could be writable to the wine group, or a wineadm
|
||||||
* group.
|
* group.
|
||||||
* Clean up fd.o menus when they are deleted in Windows.
|
* Clean up fd.o menu icons and .directory files when the menu is deleted
|
||||||
|
* in Windows.
|
||||||
* Generate icons for file open handlers to go into the "Open with..."
|
* Generate icons for file open handlers to go into the "Open with..."
|
||||||
* list. What does Windows use, the default icon for the .EXE file? It's
|
* list. What does Windows use, the default icon for the .EXE file? It's
|
||||||
* not in the registry.
|
* not in the registry.
|
||||||
|
@ -809,13 +810,23 @@ static char *extract_icon( LPCWSTR path, int index, BOOL bWait )
|
||||||
return xpm_path;
|
return xpm_path;
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL write_desktop_entry(const char *location, const char *linkname, const char *path,
|
static HKEY open_menus_reg_key(void)
|
||||||
const char *args, const char *descr, const char *workdir,
|
{
|
||||||
const char *icon)
|
static const WCHAR Software_Wine_FileOpenAssociationsW[] = {
|
||||||
|
'S','o','f','t','w','a','r','e','\\','W','i','n','e','\\','M','e','n','u','F','i','l','e','s',0};
|
||||||
|
HKEY assocKey;
|
||||||
|
if (RegCreateKeyW(HKEY_CURRENT_USER, Software_Wine_FileOpenAssociationsW, &assocKey) == ERROR_SUCCESS)
|
||||||
|
return assocKey;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static BOOL write_desktop_entry(const char *unix_link, const char *location, const char *linkname,
|
||||||
|
const char *path, const char *args, const char *descr,
|
||||||
|
const char *workdir, const char *icon)
|
||||||
{
|
{
|
||||||
FILE *file;
|
FILE *file;
|
||||||
|
|
||||||
WINE_TRACE("(%s,%s,%s,%s,%s,%s,%s)\n", wine_dbgstr_a(location),
|
WINE_TRACE("(%s,%s,%s,%s,%s,%s,%s,%s)\n", wine_dbgstr_a(unix_link), wine_dbgstr_a(location),
|
||||||
wine_dbgstr_a(linkname), wine_dbgstr_a(path), wine_dbgstr_a(args),
|
wine_dbgstr_a(linkname), wine_dbgstr_a(path), wine_dbgstr_a(args),
|
||||||
wine_dbgstr_a(descr), wine_dbgstr_a(workdir), wine_dbgstr_a(icon));
|
wine_dbgstr_a(descr), wine_dbgstr_a(workdir), wine_dbgstr_a(icon));
|
||||||
|
|
||||||
|
@ -837,6 +848,19 @@ static BOOL write_desktop_entry(const char *location, const char *linkname, cons
|
||||||
fprintf(file, "Icon=%s\n", icon);
|
fprintf(file, "Icon=%s\n", icon);
|
||||||
|
|
||||||
fclose(file);
|
fclose(file);
|
||||||
|
|
||||||
|
if (unix_link)
|
||||||
|
{
|
||||||
|
HKEY hkey = open_menus_reg_key();
|
||||||
|
if (hkey)
|
||||||
|
{
|
||||||
|
RegSetValueExA(hkey, location, 0, REG_SZ, (BYTE*) unix_link, lstrlenA(unix_link) + 1);
|
||||||
|
RegCloseKey(hkey);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -867,7 +891,7 @@ static BOOL write_directory_entry(const char *directory, const char *location)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL write_menu_file(const char *filename)
|
static BOOL write_menu_file(const char *unix_link, const char *filename)
|
||||||
{
|
{
|
||||||
char *tempfilename;
|
char *tempfilename;
|
||||||
FILE *tempfile = NULL;
|
FILE *tempfile = NULL;
|
||||||
|
@ -958,12 +982,21 @@ end:
|
||||||
if (!ret && tempfilename)
|
if (!ret && tempfilename)
|
||||||
remove(tempfilename);
|
remove(tempfilename);
|
||||||
free(tempfilename);
|
free(tempfilename);
|
||||||
|
if (ret)
|
||||||
|
{
|
||||||
|
HKEY hkey = open_menus_reg_key();
|
||||||
|
if (hkey)
|
||||||
|
{
|
||||||
|
RegSetValueExA(hkey, menuPath, 0, REG_SZ, (BYTE*) unix_link, lstrlenA(unix_link) + 1);
|
||||||
|
RegCloseKey(hkey);
|
||||||
|
}
|
||||||
|
}
|
||||||
HeapFree(GetProcessHeap(), 0, name);
|
HeapFree(GetProcessHeap(), 0, name);
|
||||||
HeapFree(GetProcessHeap(), 0, menuPath);
|
HeapFree(GetProcessHeap(), 0, menuPath);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL write_menu_entry(const char *link, const char *path, const char *args,
|
static BOOL write_menu_entry(const char *unix_link, const char *link, const char *path, const char *args,
|
||||||
const char *descr, const char *workdir, const char *icon)
|
const char *descr, const char *workdir, const char *icon)
|
||||||
{
|
{
|
||||||
const char *linkname;
|
const char *linkname;
|
||||||
|
@ -972,9 +1005,9 @@ static BOOL write_menu_entry(const char *link, const char *path, const char *arg
|
||||||
char *filename = NULL;
|
char *filename = NULL;
|
||||||
BOOL ret = TRUE;
|
BOOL ret = TRUE;
|
||||||
|
|
||||||
WINE_TRACE("(%s, %s, %s, %s, %s, %s)\n", wine_dbgstr_a(link), wine_dbgstr_a(path),
|
WINE_TRACE("(%s, %s, %s, %s, %s, %s, %s)\n", wine_dbgstr_a(unix_link), wine_dbgstr_a(link),
|
||||||
wine_dbgstr_a(args), wine_dbgstr_a(descr), wine_dbgstr_a(workdir),
|
wine_dbgstr_a(path), wine_dbgstr_a(args), wine_dbgstr_a(descr),
|
||||||
wine_dbgstr_a(icon));
|
wine_dbgstr_a(workdir), wine_dbgstr_a(icon));
|
||||||
|
|
||||||
linkname = strrchr(link, '/');
|
linkname = strrchr(link, '/');
|
||||||
if (linkname == NULL)
|
if (linkname == NULL)
|
||||||
|
@ -998,7 +1031,7 @@ static BOOL write_menu_entry(const char *link, const char *path, const char *arg
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
*desktopDir = '/';
|
*desktopDir = '/';
|
||||||
if (!write_desktop_entry(desktopPath, linkname, path, args, descr, workdir, icon))
|
if (!write_desktop_entry(unix_link, desktopPath, linkname, path, args, descr, workdir, icon))
|
||||||
{
|
{
|
||||||
WINE_WARN("couldn't make desktop entry %s\n", wine_dbgstr_a(desktopPath));
|
WINE_WARN("couldn't make desktop entry %s\n", wine_dbgstr_a(desktopPath));
|
||||||
ret = FALSE;
|
ret = FALSE;
|
||||||
|
@ -1006,7 +1039,7 @@ static BOOL write_menu_entry(const char *link, const char *path, const char *arg
|
||||||
}
|
}
|
||||||
|
|
||||||
filename = heap_printf("wine/%s.desktop", link);
|
filename = heap_printf("wine/%s.desktop", link);
|
||||||
if (!filename || !write_menu_file(filename))
|
if (!filename || !write_menu_file(unix_link, filename))
|
||||||
{
|
{
|
||||||
WINE_WARN("couldn't make menu file %s\n", wine_dbgstr_a(filename));
|
WINE_WARN("couldn't make menu file %s\n", wine_dbgstr_a(filename));
|
||||||
ret = FALSE;
|
ret = FALSE;
|
||||||
|
@ -2014,6 +2047,7 @@ static BOOL InvokeShellLinker( IShellLinkW *sl, LPCWSTR link, BOOL bWait )
|
||||||
int iIconId = 0, r = -1;
|
int iIconId = 0, r = -1;
|
||||||
DWORD csidl = -1;
|
DWORD csidl = -1;
|
||||||
HANDLE hsem = NULL;
|
HANDLE hsem = NULL;
|
||||||
|
char *unix_link = NULL;
|
||||||
|
|
||||||
if ( !link )
|
if ( !link )
|
||||||
{
|
{
|
||||||
|
@ -2078,6 +2112,13 @@ static BOOL InvokeShellLinker( IShellLinkW *sl, LPCWSTR link, BOOL bWait )
|
||||||
wine_dbgstr_w( szIconPath[0] ? szIconPath : szPath ));
|
wine_dbgstr_w( szIconPath[0] ? szIconPath : szPath ));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unix_link = wine_get_unix_file_name(link);
|
||||||
|
if (unix_link == NULL)
|
||||||
|
{
|
||||||
|
WINE_WARN("couldn't find unix path of %s\n", wine_dbgstr_w(link));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
/* check the path */
|
/* check the path */
|
||||||
if( szPath[0] )
|
if( szPath[0] )
|
||||||
{
|
{
|
||||||
|
@ -2145,12 +2186,12 @@ static BOOL InvokeShellLinker( IShellLinkW *sl, LPCWSTR link, BOOL bWait )
|
||||||
location = heap_printf("%s/%s.desktop", xdg_desktop_dir, lastEntry);
|
location = heap_printf("%s/%s.desktop", xdg_desktop_dir, lastEntry);
|
||||||
if (location)
|
if (location)
|
||||||
{
|
{
|
||||||
r = !write_desktop_entry(location, lastEntry, escaped_path, escaped_args, escaped_description, work_dir, icon_name);
|
r = !write_desktop_entry(NULL, location, lastEntry, escaped_path, escaped_args, escaped_description, work_dir, icon_name);
|
||||||
HeapFree(GetProcessHeap(), 0, location);
|
HeapFree(GetProcessHeap(), 0, location);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
r = !write_menu_entry(link_name, escaped_path, escaped_args, escaped_description, work_dir, icon_name);
|
r = !write_menu_entry(unix_link, link_name, escaped_path, escaped_args, escaped_description, work_dir, icon_name);
|
||||||
|
|
||||||
ReleaseSemaphore( hsem, 1, NULL );
|
ReleaseSemaphore( hsem, 1, NULL );
|
||||||
|
|
||||||
|
@ -2162,6 +2203,7 @@ cleanup:
|
||||||
HeapFree( GetProcessHeap(), 0, escaped_args );
|
HeapFree( GetProcessHeap(), 0, escaped_args );
|
||||||
HeapFree( GetProcessHeap(), 0, escaped_path );
|
HeapFree( GetProcessHeap(), 0, escaped_path );
|
||||||
HeapFree( GetProcessHeap(), 0, escaped_description );
|
HeapFree( GetProcessHeap(), 0, escaped_description );
|
||||||
|
HeapFree( GetProcessHeap(), 0, unix_link);
|
||||||
|
|
||||||
if (r && !bWait)
|
if (r && !bWait)
|
||||||
WINE_ERR("failed to build the menu\n" );
|
WINE_ERR("failed to build the menu\n" );
|
||||||
|
@ -2179,6 +2221,7 @@ static BOOL InvokeShellLinkerForURL( IUniformResourceLocatorW *url, LPCWSTR link
|
||||||
HANDLE hSem = NULL;
|
HANDLE hSem = NULL;
|
||||||
BOOL ret = TRUE;
|
BOOL ret = TRUE;
|
||||||
int r = -1;
|
int r = -1;
|
||||||
|
char *unix_link = NULL;
|
||||||
|
|
||||||
if ( !link )
|
if ( !link )
|
||||||
{
|
{
|
||||||
|
@ -2207,6 +2250,13 @@ static BOOL InvokeShellLinkerForURL( IUniformResourceLocatorW *url, LPCWSTR link
|
||||||
}
|
}
|
||||||
WINE_TRACE("path : %s\n", wine_dbgstr_w(urlPath));
|
WINE_TRACE("path : %s\n", wine_dbgstr_w(urlPath));
|
||||||
|
|
||||||
|
unix_link = wine_get_unix_file_name(link);
|
||||||
|
if (unix_link == NULL)
|
||||||
|
{
|
||||||
|
WINE_WARN("couldn't find unix path of %s\n", wine_dbgstr_w(link));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
escaped_urlPath = escape(urlPath);
|
escaped_urlPath = escape(urlPath);
|
||||||
|
|
||||||
hSem = CreateSemaphoreA( NULL, 1, 1, "winemenubuilder_semaphore");
|
hSem = CreateSemaphoreA( NULL, 1, 1, "winemenubuilder_semaphore");
|
||||||
|
@ -2227,12 +2277,12 @@ static BOOL InvokeShellLinkerForURL( IUniformResourceLocatorW *url, LPCWSTR link
|
||||||
location = heap_printf("%s/%s.desktop", xdg_desktop_dir, lastEntry);
|
location = heap_printf("%s/%s.desktop", xdg_desktop_dir, lastEntry);
|
||||||
if (location)
|
if (location)
|
||||||
{
|
{
|
||||||
r = !write_desktop_entry(location, lastEntry, "winebrowser", escaped_urlPath, NULL, NULL, NULL);
|
r = !write_desktop_entry(NULL, location, lastEntry, "winebrowser", escaped_urlPath, NULL, NULL, NULL);
|
||||||
HeapFree(GetProcessHeap(), 0, location);
|
HeapFree(GetProcessHeap(), 0, location);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
r = !write_menu_entry(link_name, "winebrowser", escaped_urlPath, NULL, NULL, NULL);
|
r = !write_menu_entry(unix_link, link_name, "winebrowser", escaped_urlPath, NULL, NULL, NULL);
|
||||||
ret = (r != 0);
|
ret = (r != 0);
|
||||||
ReleaseSemaphore(hSem, 1, NULL);
|
ReleaseSemaphore(hSem, 1, NULL);
|
||||||
|
|
||||||
|
@ -2242,6 +2292,7 @@ cleanup:
|
||||||
HeapFree(GetProcessHeap(), 0, link_name);
|
HeapFree(GetProcessHeap(), 0, link_name);
|
||||||
CoTaskMemFree( urlPath );
|
CoTaskMemFree( urlPath );
|
||||||
HeapFree(GetProcessHeap(), 0, escaped_urlPath);
|
HeapFree(GetProcessHeap(), 0, escaped_urlPath);
|
||||||
|
HeapFree(GetProcessHeap(), 0, unix_link);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2508,6 +2559,62 @@ end:
|
||||||
HeapFree(GetProcessHeap(), 0, applications_dir);
|
HeapFree(GetProcessHeap(), 0, applications_dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void cleanup_menus(void)
|
||||||
|
{
|
||||||
|
HKEY hkey;
|
||||||
|
|
||||||
|
hkey = open_menus_reg_key();
|
||||||
|
if (hkey)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
LSTATUS lret = ERROR_SUCCESS;
|
||||||
|
for (i = 0; lret == ERROR_SUCCESS; )
|
||||||
|
{
|
||||||
|
char *value = NULL;
|
||||||
|
char *data = NULL;
|
||||||
|
DWORD valueSize = 4096;
|
||||||
|
DWORD dataSize = 4096;
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
lret = ERROR_OUTOFMEMORY;
|
||||||
|
value = HeapAlloc(GetProcessHeap(), 0, valueSize);
|
||||||
|
if (value == NULL)
|
||||||
|
break;
|
||||||
|
data = HeapAlloc(GetProcessHeap(), 0, dataSize);
|
||||||
|
if (data == NULL)
|
||||||
|
break;
|
||||||
|
lret = RegEnumValueA(hkey, i, value, &valueSize, NULL, NULL, (BYTE*)data, &dataSize);
|
||||||
|
if (lret == ERROR_SUCCESS || lret != ERROR_MORE_DATA)
|
||||||
|
break;
|
||||||
|
valueSize *= 2;
|
||||||
|
dataSize *= 2;
|
||||||
|
HeapFree(GetProcessHeap(), 0, value);
|
||||||
|
HeapFree(GetProcessHeap(), 0, data);
|
||||||
|
value = data = NULL;
|
||||||
|
}
|
||||||
|
if (lret == ERROR_SUCCESS)
|
||||||
|
{
|
||||||
|
struct stat filestats;
|
||||||
|
if (stat(data, &filestats) < 0 && errno == ENOENT)
|
||||||
|
{
|
||||||
|
WINE_TRACE("removing menu related file %s\n", value);
|
||||||
|
remove(value);
|
||||||
|
RegDeleteValueA(hkey, value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
else if (lret != ERROR_NO_MORE_ITEMS)
|
||||||
|
WINE_WARN("error %d reading registry\n", lret);
|
||||||
|
HeapFree(GetProcessHeap(), 0, value);
|
||||||
|
HeapFree(GetProcessHeap(), 0, data);
|
||||||
|
}
|
||||||
|
RegCloseKey(hkey);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
WINE_ERR("error opening registry key, menu cleanup failed\n");
|
||||||
|
}
|
||||||
|
|
||||||
static CHAR *next_token( LPSTR *p )
|
static CHAR *next_token( LPSTR *p )
|
||||||
{
|
{
|
||||||
LPSTR token = NULL, t = *p;
|
LPSTR token = NULL, t = *p;
|
||||||
|
@ -2609,6 +2716,11 @@ int PASCAL WinMain (HINSTANCE hInstance, HINSTANCE prev, LPSTR cmdline, int show
|
||||||
RefreshFileTypeAssociations();
|
RefreshFileTypeAssociations();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if( !lstrcmpA( token, "-r" ) )
|
||||||
|
{
|
||||||
|
cleanup_menus();
|
||||||
|
break;
|
||||||
|
}
|
||||||
if( !lstrcmpA( token, "-w" ) )
|
if( !lstrcmpA( token, "-w" ) )
|
||||||
bWait = TRUE;
|
bWait = TRUE;
|
||||||
else if ( !lstrcmpA( token, "-u" ) )
|
else if ( !lstrcmpA( token, "-u" ) )
|
||||||
|
|
Loading…
Reference in New Issue