winemenubuilder: Use DOS path names to create associations.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
0428292fc7
commit
2f89d63bb9
|
@ -190,7 +190,6 @@ struct rb_string_entry
|
|||
DEFINE_GUID(CLSID_WICIcnsEncoder, 0x312fb6f1,0xb767,0x409d,0x8a,0x6d,0x0f,0xc1,0x54,0xd4,0xf0,0x5c);
|
||||
|
||||
static WCHAR *xdg_menu_dir;
|
||||
static char *xdg_data_dir_unix;
|
||||
static WCHAR *xdg_data_dir;
|
||||
static WCHAR xdg_desktop_dir[MAX_PATH];
|
||||
|
||||
|
@ -323,27 +322,7 @@ static void winemenubuilder_rb_destroy(struct wine_rb_entry *entry, void *contex
|
|||
heap_free(t);
|
||||
}
|
||||
|
||||
static BOOL create_directories(char *directory)
|
||||
{
|
||||
BOOL ret = TRUE;
|
||||
int i;
|
||||
|
||||
for (i = 0; directory[i]; i++)
|
||||
{
|
||||
if (i > 0 && directory[i] == '/')
|
||||
{
|
||||
directory[i] = 0;
|
||||
mkdir(directory, 0777);
|
||||
directory[i] = '/';
|
||||
}
|
||||
}
|
||||
if (mkdir(directory, 0777) && errno != EEXIST)
|
||||
ret = FALSE;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL create_directoriesW(WCHAR *directory)
|
||||
static BOOL create_directories(WCHAR *directory)
|
||||
{
|
||||
WCHAR *p = PathSkipRootW( directory );
|
||||
|
||||
|
@ -1325,7 +1304,7 @@ static HRESULT platform_write_icon(IStream *icoStream, ICONDIRENTRY *iconDirEntr
|
|||
w = iconDirEntries[bestIndex].bWidth ? iconDirEntries[bestIndex].bWidth : 256;
|
||||
h = iconDirEntries[bestIndex].bHeight ? iconDirEntries[bestIndex].bHeight : 256;
|
||||
iconDir = heap_wprintf(fmt2W, iconsDir, w, h);
|
||||
create_directoriesW(iconDir);
|
||||
create_directories(iconDir);
|
||||
pngPath = heap_wprintf(fmt3W, iconDir, *nativeIdentifier);
|
||||
zero.QuadPart = 0;
|
||||
hr = IStream_Seek(icoStream, zero, STREAM_SEEK_SET, NULL);
|
||||
|
@ -1636,7 +1615,7 @@ static BOOL write_menu_entry(const WCHAR *windows_link, const WCHAR *link, const
|
|||
desktopPath = heap_wprintf(fmtW, xdg_data_dir, link);
|
||||
desktopDir = strrchrW(desktopPath, '\\');
|
||||
*desktopDir = 0;
|
||||
if (!create_directoriesW(desktopPath))
|
||||
if (!create_directories(desktopPath))
|
||||
{
|
||||
WINE_WARN("couldn't make parent directories for %s\n", wine_dbgstr_w(desktopPath));
|
||||
ret = FALSE;
|
||||
|
@ -1875,14 +1854,15 @@ static BOOL next_line(FILE *file, char **line, int *size)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
static BOOL add_mimes(const char *xdg_data_dir, struct list *mime_types)
|
||||
static BOOL add_mimes(const WCHAR *dir, struct list *mime_types)
|
||||
{
|
||||
char *globs_filename = NULL;
|
||||
static const WCHAR fmtW[] = {'%','s','\\','m','i','m','e','\\','g','l','o','b','s',0};
|
||||
WCHAR *globs_filename;
|
||||
BOOL ret = TRUE;
|
||||
FILE *globs_file;
|
||||
|
||||
globs_filename = heap_printf("%s/mime/globs", xdg_data_dir);
|
||||
globs_file = fopen(globs_filename, "r");
|
||||
globs_filename = heap_wprintf(fmtW, dir);
|
||||
globs_file = fopen(wine_get_unix_file_name(globs_filename), "r");
|
||||
if (globs_file) /* doesn't have to exist */
|
||||
{
|
||||
char *line = NULL;
|
||||
|
@ -1920,11 +1900,12 @@ static void free_native_mime_types(struct list *native_mime_types)
|
|||
}
|
||||
}
|
||||
|
||||
static BOOL build_native_mime_types(const char *xdg_data_home, struct list *mime_types)
|
||||
static BOOL build_native_mime_types(struct list *mime_types)
|
||||
{
|
||||
char *xdg_data_dirs;
|
||||
const char *begin;
|
||||
char *end;
|
||||
WCHAR *dos_name;
|
||||
BOOL ret;
|
||||
|
||||
xdg_data_dirs = getenv("XDG_DATA_DIRS");
|
||||
|
@ -1933,19 +1914,26 @@ static BOOL build_native_mime_types(const char *xdg_data_home, struct list *mime
|
|||
else
|
||||
xdg_data_dirs = xstrdup(xdg_data_dirs);
|
||||
|
||||
ret = add_mimes(xdg_data_home, mime_types);
|
||||
ret = add_mimes(xdg_data_dir, mime_types);
|
||||
if (ret)
|
||||
{
|
||||
for (begin = xdg_data_dirs; (end = strchr(begin, ':')); begin = end + 1)
|
||||
{
|
||||
*end = '\0';
|
||||
ret = add_mimes(begin, mime_types);
|
||||
if ((dos_name = wine_get_dos_file_name( begin )))
|
||||
{
|
||||
ret = add_mimes(dos_name, mime_types);
|
||||
heap_free( dos_name );
|
||||
}
|
||||
*end = ':';
|
||||
if (!ret)
|
||||
break;
|
||||
}
|
||||
if (ret)
|
||||
ret = add_mimes(begin, mime_types);
|
||||
if (ret && (dos_name = wine_get_dos_file_name( begin )))
|
||||
{
|
||||
ret = add_mimes(dos_name, mime_types);
|
||||
heap_free( dos_name );
|
||||
}
|
||||
}
|
||||
heap_free(xdg_data_dirs);
|
||||
|
||||
|
@ -1992,18 +1980,6 @@ static WCHAR* reg_get_valW(HKEY key, LPCWSTR subkey, LPCWSTR name)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static CHAR* reg_get_val_utf8(HKEY key, LPCWSTR subkey, LPCWSTR name)
|
||||
{
|
||||
WCHAR *valW = reg_get_valW(key, subkey, name);
|
||||
if (valW)
|
||||
{
|
||||
char *val = wchars_to_utf8_chars(valW);
|
||||
heap_free(valW);
|
||||
return val;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static HKEY open_associations_reg_key(void)
|
||||
{
|
||||
static const WCHAR Software_Wine_FileOpenAssociationsW[] = {
|
||||
|
@ -2063,7 +2039,7 @@ static BOOL has_association_changed(LPCWSTR extensionW, const WCHAR *mimeType, c
|
|||
}
|
||||
|
||||
static void update_association(LPCWSTR extension, const WCHAR *mimeType, const WCHAR *progId,
|
||||
const WCHAR *appName, LPCSTR desktopFile, const WCHAR *openWithIcon)
|
||||
const WCHAR *appName, const WCHAR *desktopFile, const WCHAR *openWithIcon)
|
||||
{
|
||||
static const WCHAR ProgIDW[] = {'P','r','o','g','I','D',0};
|
||||
static const WCHAR MimeTypeW[] = {'M','i','m','e','T','y','p','e',0};
|
||||
|
@ -2072,7 +2048,6 @@ static void update_association(LPCWSTR extension, const WCHAR *mimeType, const W
|
|||
static const WCHAR OpenWithIconW[] = {'O','p','e','n','W','i','t','h','I','c','o','n',0};
|
||||
HKEY assocKey = NULL;
|
||||
HKEY subkey = NULL;
|
||||
WCHAR *desktopFileW = NULL;
|
||||
|
||||
assocKey = open_associations_reg_key();
|
||||
if (assocKey == NULL)
|
||||
|
@ -2087,12 +2062,10 @@ static void update_association(LPCWSTR extension, const WCHAR *mimeType, const W
|
|||
goto done;
|
||||
}
|
||||
|
||||
desktopFileW = utf8_chars_to_wchars(desktopFile);
|
||||
|
||||
RegSetValueExW(subkey, MimeTypeW, 0, REG_SZ, (const BYTE*) mimeType, (lstrlenW(mimeType) + 1) * sizeof(WCHAR));
|
||||
RegSetValueExW(subkey, ProgIDW, 0, REG_SZ, (const BYTE*) progId, (lstrlenW(progId) + 1) * sizeof(WCHAR));
|
||||
RegSetValueExW(subkey, AppNameW, 0, REG_SZ, (const BYTE*) appName, (lstrlenW(appName) + 1) * sizeof(WCHAR));
|
||||
RegSetValueExW(subkey, DesktopFileW, 0, REG_SZ, (const BYTE*) desktopFileW, (lstrlenW(desktopFileW) + 1) * sizeof(WCHAR));
|
||||
RegSetValueExW(subkey, DesktopFileW, 0, REG_SZ, (const BYTE*) desktopFile, (lstrlenW(desktopFile) + 1) * sizeof(WCHAR));
|
||||
if (openWithIcon)
|
||||
RegSetValueExW(subkey, OpenWithIconW, 0, REG_SZ, (const BYTE*) openWithIcon, (lstrlenW(openWithIcon) + 1) * sizeof(WCHAR));
|
||||
else
|
||||
|
@ -2101,7 +2074,6 @@ static void update_association(LPCWSTR extension, const WCHAR *mimeType, const W
|
|||
done:
|
||||
RegCloseKey(assocKey);
|
||||
RegCloseKey(subkey);
|
||||
heap_free(desktopFileW);
|
||||
}
|
||||
|
||||
static BOOL cleanup_associations(void)
|
||||
|
@ -2134,11 +2106,11 @@ static BOOL cleanup_associations(void)
|
|||
command = assoc_query(ASSOCSTR_COMMAND, extensionW, openW);
|
||||
if (command == NULL)
|
||||
{
|
||||
char *desktopFile = reg_get_val_utf8(assocKey, extensionW, DesktopFileW);
|
||||
WCHAR *desktopFile = reg_get_valW(assocKey, extensionW, DesktopFileW);
|
||||
if (desktopFile)
|
||||
{
|
||||
WINE_TRACE("removing file type association for %s\n", wine_dbgstr_w(extensionW));
|
||||
remove(desktopFile);
|
||||
DeleteFileW(desktopFile);
|
||||
}
|
||||
RegDeleteKeyW(assocKey, extensionW);
|
||||
hasChanged = TRUE;
|
||||
|
@ -2163,18 +2135,19 @@ static BOOL cleanup_associations(void)
|
|||
return hasChanged;
|
||||
}
|
||||
|
||||
static BOOL write_freedesktop_mime_type_entry(const char *packages_dir, const WCHAR *dot_extension,
|
||||
static BOOL write_freedesktop_mime_type_entry(const WCHAR *packages_dir, const WCHAR *dot_extension,
|
||||
const WCHAR *mime_type, const WCHAR *comment)
|
||||
{
|
||||
static const WCHAR fmtW[] = {'%','s','\\','x','-','w','i','n','e','-','e','x','t','e','n','s','i','o','n','-','%','s','.','x','m','l',0};
|
||||
BOOL ret = FALSE;
|
||||
char *filename;
|
||||
WCHAR *filename;
|
||||
FILE *packageFile;
|
||||
|
||||
WINE_TRACE("writing MIME type %s, extension=%s, comment=%s\n", wine_dbgstr_w(mime_type),
|
||||
wine_dbgstr_w(dot_extension), wine_dbgstr_w(comment));
|
||||
|
||||
filename = heap_printf("%s/x-wine-extension-%s.xml", packages_dir, wchars_to_utf8_chars(dot_extension + 1));
|
||||
packageFile = fopen(filename, "w");
|
||||
filename = heap_wprintf(fmtW, packages_dir, dot_extension + 1);
|
||||
packageFile = fopen(wine_get_unix_file_name(filename), "w");
|
||||
if (packageFile)
|
||||
{
|
||||
fprintf(packageFile, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
|
||||
|
@ -2188,7 +2161,7 @@ static BOOL write_freedesktop_mime_type_entry(const char *packages_dir, const WC
|
|||
fclose(packageFile);
|
||||
}
|
||||
else
|
||||
WINE_ERR("error writing file %s\n", filename);
|
||||
WINE_ERR("error writing file %s\n", debugstr_w(filename));
|
||||
heap_free(filename);
|
||||
return ret;
|
||||
}
|
||||
|
@ -2216,7 +2189,7 @@ static WCHAR *get_special_mime_type(LPCWSTR extension)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static BOOL write_freedesktop_association_entry(const char *desktopPath, const WCHAR *friendlyAppName,
|
||||
static BOOL write_freedesktop_association_entry(const WCHAR *desktopPath, const WCHAR *friendlyAppName,
|
||||
const WCHAR *mimeType, const WCHAR *progId,
|
||||
const WCHAR *openWithIcon)
|
||||
{
|
||||
|
@ -2227,9 +2200,9 @@ static BOOL write_freedesktop_association_entry(const char *desktopPath, const W
|
|||
|
||||
WINE_TRACE("friendlyAppName=%s, MIME type %s, progID=%s, icon=%s to file %s\n",
|
||||
wine_dbgstr_w(friendlyAppName), wine_dbgstr_w(mimeType),
|
||||
wine_dbgstr_w(progId), wine_dbgstr_w(openWithIcon), wine_dbgstr_a(desktopPath));
|
||||
wine_dbgstr_w(progId), wine_dbgstr_w(openWithIcon), wine_dbgstr_w(desktopPath));
|
||||
|
||||
desktop = fopen(desktopPath, "w");
|
||||
desktop = fopen(wine_get_unix_file_name(desktopPath), "w");
|
||||
if (desktop)
|
||||
{
|
||||
fprintf(desktop, "[Desktop Entry]\n");
|
||||
|
@ -2250,11 +2223,11 @@ static BOOL write_freedesktop_association_entry(const char *desktopPath, const W
|
|||
fclose(desktop);
|
||||
}
|
||||
else
|
||||
WINE_ERR("error writing association file %s\n", wine_dbgstr_a(desktopPath));
|
||||
WINE_ERR("error writing association file %s\n", wine_dbgstr_w(desktopPath));
|
||||
return ret;
|
||||
}
|
||||
|
||||
static BOOL generate_associations(const char *xdg_data_home, const char *packages_dir, const char *applications_dir)
|
||||
static BOOL generate_associations(const WCHAR *packages_dir, const WCHAR *applications_dir)
|
||||
{
|
||||
static const WCHAR wine_appW[] = {'A',' ','W','i','n','e',' ','a','p','p','l','i','c','a','t','i','o','n',0};
|
||||
static const WCHAR progidfmtW[] = {'%','s','=','>','%','s',0};
|
||||
|
@ -2265,7 +2238,7 @@ static BOOL generate_associations(const char *xdg_data_home, const char *package
|
|||
int i;
|
||||
BOOL hasChanged = FALSE;
|
||||
|
||||
if (!build_native_mime_types(xdg_data_home, &nativeMimeTypes))
|
||||
if (!build_native_mime_types(&nativeMimeTypes))
|
||||
{
|
||||
WINE_ERR("could not build native MIME types\n");
|
||||
return FALSE;
|
||||
|
@ -2371,7 +2344,8 @@ static BOOL generate_associations(const char *xdg_data_home, const char *package
|
|||
|
||||
if (has_association_changed(extensionW, mimeType, progIdW, friendlyAppName, openWithIcon))
|
||||
{
|
||||
char *desktopPath = heap_printf("%s/wine-extension-%s.desktop", applications_dir, wchars_to_utf8_chars(&extensionW[1]));
|
||||
static const WCHAR fmtW[] = {'%','s','\\','w','i','n','e','-','e','x','t','e','n','s','i','o','n','-','%','s','.','d','e','s','k','t','o','p',0};
|
||||
WCHAR *desktopPath = heap_wprintf(fmtW, applications_dir, extensionW + 1 );
|
||||
if (write_freedesktop_association_entry(desktopPath, friendlyAppName, mimeType, progIdW, openWithIcon))
|
||||
{
|
||||
hasChanged = TRUE;
|
||||
|
@ -2797,10 +2771,13 @@ static BOOL Process_URL( LPCWSTR urlname, BOOL bWait )
|
|||
|
||||
static void RefreshFileTypeAssociations(void)
|
||||
{
|
||||
static const WCHAR fmtW[] = {'%','s','\\','m','i','m','e',0};
|
||||
static const WCHAR fmt2W[] = {'%','s','\\','p','a','c','k','a','g','e','s',0};
|
||||
static const WCHAR fmt3W[] = {'%','s','\\','a','p','p','l','i','c','a','t','i','o','n','s',0};
|
||||
HANDLE hSem = NULL;
|
||||
char *mime_dir = NULL;
|
||||
char *packages_dir = NULL;
|
||||
char *applications_dir = NULL;
|
||||
WCHAR *mime_dir;
|
||||
WCHAR *packages_dir;
|
||||
WCHAR *applications_dir;
|
||||
BOOL hasChanged;
|
||||
|
||||
hSem = CreateSemaphoreA( NULL, 1, 1, "winemenubuilder_semaphore");
|
||||
|
@ -2808,41 +2785,34 @@ static void RefreshFileTypeAssociations(void)
|
|||
{
|
||||
WINE_ERR("failed wait for semaphore\n");
|
||||
CloseHandle(hSem);
|
||||
hSem = NULL;
|
||||
goto end;
|
||||
return;
|
||||
}
|
||||
|
||||
mime_dir = heap_printf("%s/mime", xdg_data_dir_unix);
|
||||
create_directories(mime_dir);
|
||||
|
||||
packages_dir = heap_printf("%s/packages", mime_dir);
|
||||
mime_dir = heap_wprintf(fmtW, xdg_data_dir);
|
||||
packages_dir = heap_wprintf(fmt2W, mime_dir);
|
||||
create_directories(packages_dir);
|
||||
|
||||
applications_dir = heap_printf("%s/applications", xdg_data_dir_unix);
|
||||
applications_dir = heap_wprintf(fmt3W, xdg_data_dir);
|
||||
create_directories(applications_dir);
|
||||
|
||||
hasChanged = generate_associations(xdg_data_dir_unix, packages_dir, applications_dir);
|
||||
hasChanged = generate_associations(packages_dir, applications_dir);
|
||||
hasChanged |= cleanup_associations();
|
||||
if (hasChanged)
|
||||
{
|
||||
const char *argv[3];
|
||||
|
||||
argv[0] = "update-mime-database";
|
||||
argv[1] = mime_dir;
|
||||
argv[1] = wine_get_unix_file_name(mime_dir);
|
||||
argv[2] = NULL;
|
||||
_spawnvp( _P_DETACH, argv[0], argv );
|
||||
|
||||
argv[0] = "update-desktop-database";
|
||||
argv[1] = applications_dir;
|
||||
argv[1] = wine_get_unix_file_name(applications_dir);
|
||||
_spawnvp( _P_DETACH, argv[0], argv );
|
||||
}
|
||||
|
||||
end:
|
||||
if (hSem)
|
||||
{
|
||||
ReleaseSemaphore(hSem, 1, NULL);
|
||||
CloseHandle(hSem);
|
||||
}
|
||||
ReleaseSemaphore(hSem, 1, NULL);
|
||||
CloseHandle(hSem);
|
||||
heap_free(mime_dir);
|
||||
heap_free(packages_dir);
|
||||
heap_free(applications_dir);
|
||||
|
@ -3031,16 +3001,16 @@ static BOOL init_xdg(void)
|
|||
else
|
||||
dir = heap_printf("%s/.config/menus/applications-merged", getenv("HOME"));
|
||||
xdg_menu_dir = wine_get_dos_file_name( dir );
|
||||
create_directoriesW(xdg_menu_dir);
|
||||
create_directories(xdg_menu_dir);
|
||||
|
||||
if (getenv("XDG_DATA_HOME"))
|
||||
xdg_data_dir_unix = xstrdup(getenv("XDG_DATA_HOME"));
|
||||
dir = xstrdup(getenv("XDG_DATA_HOME"));
|
||||
else
|
||||
xdg_data_dir_unix = heap_printf("%s/.local/share", getenv("HOME"));
|
||||
xdg_data_dir = wine_get_dos_file_name( xdg_data_dir_unix );
|
||||
dir = heap_printf("%s/.local/share", getenv("HOME"));
|
||||
xdg_data_dir = wine_get_dos_file_name( dir );
|
||||
|
||||
buffer = heap_wprintf(fmtW, xdg_data_dir);
|
||||
create_directoriesW(buffer);
|
||||
create_directories(buffer);
|
||||
heap_free(buffer);
|
||||
return TRUE;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue