Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
c4f4fb7f
Commit
c4f4fb7f
authored
Sep 09, 2023
by
Alex Henrie
Committed by
Alexandre Julliard
Nov 06, 2023
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
winemenubuilder: Create .desktop files for programs that open URIs.
Wine-Bug:
https://bugs.winehq.org/show_bug.cgi?id=22904
parent
e17b7d55
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
98 additions
and
70 deletions
+98
-70
winemenubuilder.c
programs/winemenubuilder/winemenubuilder.c
+98
-70
No files found.
programs/winemenubuilder/winemenubuilder.c
View file @
c4f4fb7f
...
@@ -1831,10 +1831,13 @@ static BOOL has_association_changed(LPCWSTR extensionW, const WCHAR *mimeType, c
...
@@ -1831,10 +1831,13 @@ static BOOL has_association_changed(LPCWSTR extensionW, const WCHAR *mimeType, c
ret
=
TRUE
;
ret
=
TRUE
;
free
(
value
);
free
(
value
);
value
=
reg_get_valW
(
assocKey
,
extensionW
,
L"ProgID"
);
if
(
progId
)
if
(
!
value
||
wcscmp
(
value
,
progId
))
{
ret
=
TRUE
;
value
=
reg_get_valW
(
assocKey
,
extensionW
,
L"ProgID"
);
free
(
value
);
if
(
!
value
||
wcscmp
(
value
,
progId
))
ret
=
TRUE
;
free
(
value
);
}
value
=
reg_get_valW
(
assocKey
,
extensionW
,
L"AppName"
);
value
=
reg_get_valW
(
assocKey
,
extensionW
,
L"AppName"
);
if
(
!
value
||
wcscmp
(
value
,
appName
))
if
(
!
value
||
wcscmp
(
value
,
appName
))
...
@@ -1878,7 +1881,7 @@ static void update_association(LPCWSTR extension, const WCHAR *mimeType, const W
...
@@ -1878,7 +1881,7 @@ static void update_association(LPCWSTR extension, const WCHAR *mimeType, const W
}
}
RegSetValueExW
(
subkey
,
L"MimeType"
,
0
,
REG_SZ
,
(
const
BYTE
*
)
mimeType
,
(
lstrlenW
(
mimeType
)
+
1
)
*
sizeof
(
WCHAR
));
RegSetValueExW
(
subkey
,
L"MimeType"
,
0
,
REG_SZ
,
(
const
BYTE
*
)
mimeType
,
(
lstrlenW
(
mimeType
)
+
1
)
*
sizeof
(
WCHAR
));
RegSetValueExW
(
subkey
,
L"ProgID"
,
0
,
REG_SZ
,
(
const
BYTE
*
)
progId
,
(
lstrlenW
(
progId
)
+
1
)
*
sizeof
(
WCHAR
));
if
(
progId
)
RegSetValueExW
(
subkey
,
L"ProgID"
,
0
,
REG_SZ
,
(
const
BYTE
*
)
progId
,
(
lstrlenW
(
progId
)
+
1
)
*
sizeof
(
WCHAR
));
RegSetValueExW
(
subkey
,
L"AppName"
,
0
,
REG_SZ
,
(
const
BYTE
*
)
appName
,
(
lstrlenW
(
appName
)
+
1
)
*
sizeof
(
WCHAR
));
RegSetValueExW
(
subkey
,
L"AppName"
,
0
,
REG_SZ
,
(
const
BYTE
*
)
appName
,
(
lstrlenW
(
appName
)
+
1
)
*
sizeof
(
WCHAR
));
RegSetValueExW
(
subkey
,
L"DesktopFile"
,
0
,
REG_SZ
,
(
const
BYTE
*
)
desktopFile
,
(
lstrlenW
(
desktopFile
)
+
1
)
*
sizeof
(
WCHAR
));
RegSetValueExW
(
subkey
,
L"DesktopFile"
,
0
,
REG_SZ
,
(
const
BYTE
*
)
desktopFile
,
(
lstrlenW
(
desktopFile
)
+
1
)
*
sizeof
(
WCHAR
));
if
(
openWithIcon
)
if
(
openWithIcon
)
...
@@ -1962,14 +1965,18 @@ static BOOL write_freedesktop_mime_type_entry(const WCHAR *packages_dir, const W
...
@@ -1962,14 +1965,18 @@ static BOOL write_freedesktop_mime_type_entry(const WCHAR *packages_dir, const W
return
ret
;
return
ret
;
}
}
static
BOOL
is_
extension_banned
(
LPCWSTR
extension
)
static
BOOL
is_
type_banned
(
const
WCHAR
*
win_type
)
{
{
/* These are managed through external tools like wine.desktop, to evade malware created file type associations */
/* These are managed through external tools like wine.desktop, to evade malware created file type associations */
if
(
!
wcsicmp
(
extension
,
L".bat"
)
||
if
(
!
wcsicmp
(
win_type
,
L".bat"
)
||
!
wcsicmp
(
extension
,
L".com"
)
||
!
wcsicmp
(
win_type
,
L".com"
)
||
!
wcsicmp
(
extension
,
L".exe"
)
||
!
wcsicmp
(
win_type
,
L".exe"
)
||
!
wcsicmp
(
extension
,
L".msi"
)
||
!
wcsicmp
(
win_type
,
L".msi"
)
||
!
wcsicmp
(
extension
,
L".url"
))
!
wcsicmp
(
win_type
,
L".url"
))
return
TRUE
;
/* Associating a program with the file URI scheme is like associating it with all file types, which is not allowed
* for the same reasons */
if
(
!
wcsicmp
(
win_type
,
L"file"
))
return
TRUE
;
return
TRUE
;
return
FALSE
;
return
FALSE
;
}
}
...
@@ -2043,11 +2050,15 @@ static BOOL write_freedesktop_association_entry(const WCHAR *desktopPath, const
...
@@ -2043,11 +2050,15 @@ static BOOL write_freedesktop_association_entry(const WCHAR *desktopPath, const
if
(
prefix
)
if
(
prefix
)
{
{
char
*
path
=
wine_get_unix_file_name
(
prefix
);
char
*
path
=
wine_get_unix_file_name
(
prefix
);
fprintf
(
desktop
,
"Exec=env WINEPREFIX=
\"
%s
\"
wine start
/ProgIDOpen %s %%f
\n
"
,
path
,
escape
(
progId
)
);
fprintf
(
desktop
,
"Exec=env WINEPREFIX=
\"
%s
\"
wine start
"
,
path
);
heap_free
(
path
);
heap_free
(
path
);
}
}
else
else
fprintf
(
desktop
,
"Exec=wine start /ProgIDOpen %s %%f
\n
"
,
escape
(
progId
));
fprintf
(
desktop
,
"Exec=wine start "
);
if
(
progId
)
/* file association */
fprintf
(
desktop
,
"/ProgIDOpen %s %%f
\n
"
,
escape
(
progId
));
else
/* protocol association */
fprintf
(
desktop
,
"%%u
\n
"
);
fprintf
(
desktop
,
"NoDisplay=true
\n
"
);
fprintf
(
desktop
,
"NoDisplay=true
\n
"
);
fprintf
(
desktop
,
"StartupNotify=true
\n
"
);
fprintf
(
desktop
,
"StartupNotify=true
\n
"
);
if
(
openWithIcon
)
if
(
openWithIcon
)
...
@@ -2075,12 +2086,19 @@ static BOOL generate_associations(const WCHAR *packages_dir, const WCHAR *applic
...
@@ -2075,12 +2086,19 @@ static BOOL generate_associations(const WCHAR *packages_dir, const WCHAR *applic
for
(
i
=
0
;
;
i
++
)
for
(
i
=
0
;
;
i
++
)
{
{
WCHAR
*
extensionW
;
WCHAR
*
winTypeW
;
BOOL
isProtocolType
=
FALSE
;
if
(
!
(
extension
W
=
reg_enum_keyW
(
HKEY_CLASSES_ROOT
,
i
)))
if
(
!
(
winType
W
=
reg_enum_keyW
(
HKEY_CLASSES_ROOT
,
i
)))
break
;
break
;
if
(
extensionW
[
0
]
==
'.'
&&
!
is_extension_banned
(
extensionW
))
if
(
winTypeW
[
0
]
!=
'.'
)
{
if
(
RegGetValueW
(
HKEY_CLASSES_ROOT
,
winTypeW
,
L"URL Protocol"
,
RRF_RT_ANY
,
NULL
,
NULL
,
NULL
)
==
ERROR_SUCCESS
)
isProtocolType
=
TRUE
;
}
if
((
winTypeW
[
0
]
==
'.'
||
isProtocolType
)
&&
!
is_type_banned
(
winTypeW
))
{
{
WCHAR
*
commandW
=
NULL
;
WCHAR
*
commandW
=
NULL
;
WCHAR
*
executableW
=
NULL
;
WCHAR
*
executableW
=
NULL
;
...
@@ -2094,7 +2112,7 @@ static BOOL generate_associations(const WCHAR *packages_dir, const WCHAR *applic
...
@@ -2094,7 +2112,7 @@ static BOOL generate_associations(const WCHAR *packages_dir, const WCHAR *applic
WCHAR
*
mimeProgId
=
NULL
;
WCHAR
*
mimeProgId
=
NULL
;
struct
rb_string_entry
*
entry
;
struct
rb_string_entry
*
entry
;
commandW
=
assoc_query
(
ASSOCSTR_COMMAND
,
extension
W
,
L"open"
);
commandW
=
assoc_query
(
ASSOCSTR_COMMAND
,
winType
W
,
L"open"
);
if
(
commandW
==
NULL
)
if
(
commandW
==
NULL
)
/* no command => no application is associated */
/* no command => no application is associated */
goto
end
;
goto
end
;
...
@@ -2103,78 +2121,88 @@ static BOOL generate_associations(const WCHAR *packages_dir, const WCHAR *applic
...
@@ -2103,78 +2121,88 @@ static BOOL generate_associations(const WCHAR *packages_dir, const WCHAR *applic
/* command is on the exclude list => desktop integration is not desirable */
/* command is on the exclude list => desktop integration is not desirable */
goto
end
;
goto
end
;
wcslwr
(
extensionW
);
iconW
=
assoc_query
(
ASSOCSTR_DEFAULTICON
,
winTypeW
,
NULL
);
friendlyDocNameW
=
assoc_query
(
ASSOCSTR_FRIENDLYDOCNAME
,
extensionW
,
NULL
);
iconW
=
assoc_query
(
ASSOCSTR_DEFAULTICON
,
extensionW
,
NULL
);
if
(
isProtocolType
)
{
mimeType
=
heap_wprintf
(
L"x-scheme-handler/%s"
,
winTypeW
);
}
else
{
wcslwr
(
winTypeW
);
friendlyDocNameW
=
assoc_query
(
ASSOCSTR_FRIENDLYDOCNAME
,
winTypeW
,
NULL
);
contentTypeW
=
assoc_query
(
ASSOCSTR_CONTENTTYPE
,
extension
W
,
NULL
);
contentTypeW
=
assoc_query
(
ASSOCSTR_CONTENTTYPE
,
winType
W
,
NULL
);
if
(
contentTypeW
)
if
(
contentTypeW
)
wcslwr
(
contentTypeW
);
wcslwr
(
contentTypeW
);
mimeType
=
freedesktop_mime_type_for_extension
(
&
nativeMimeTypes
,
extension
W
);
mimeType
=
freedesktop_mime_type_for_extension
(
&
nativeMimeTypes
,
winType
W
);
if
(
mimeType
==
NULL
)
if
(
mimeType
==
NULL
)
{
if
(
contentTypeW
!=
NULL
&&
wcschr
(
contentTypeW
,
'/'
))
mimeType
=
xwcsdup
(
contentTypeW
);
else
if
(
!
(
mimeType
=
get_special_mime_type
(
extensionW
)))
mimeType
=
heap_wprintf
(
L"application/x-wine-extension-%s"
,
&
extensionW
[
1
]);
/* GNOME seems to ignore the <icon> tag in MIME packages,
* and the default name is more intuitive anyway.
*/
if
(
iconW
)
{
{
WCHAR
*
flattened_mime
=
slashes_to_minuses
(
mimeType
);
if
(
contentTypeW
!=
NULL
&&
wcschr
(
contentTypeW
,
'/'
))
int
index
=
0
;
mimeType
=
xwcsdup
(
contentTypeW
);
WCHAR
*
comma
=
wcsrchr
(
iconW
,
','
);
else
if
(
!
(
mimeType
=
get_special_mime_type
(
winTypeW
)))
if
(
comma
)
mimeType
=
heap_wprintf
(
L"application/x-wine-extension-%s"
,
&
winTypeW
[
1
]);
/* GNOME seems to ignore the <icon> tag in MIME packages,
* and the default name is more intuitive anyway.
*/
if
(
iconW
)
{
{
*
comma
=
0
;
WCHAR
*
flattened_mime
=
slashes_to_minuses
(
mimeType
);
index
=
wcstol
(
comma
+
1
,
NULL
,
10
);
int
index
=
0
;
WCHAR
*
comma
=
wcsrchr
(
iconW
,
','
);
if
(
comma
)
{
*
comma
=
0
;
index
=
wcstol
(
comma
+
1
,
NULL
,
10
);
}
extract_icon
(
iconW
,
index
,
flattened_mime
,
FALSE
);
free
(
flattened_mime
);
}
}
extract_icon
(
iconW
,
index
,
flattened_mime
,
FALSE
);
free
(
flattened_mime
);
write_freedesktop_mime_type_entry
(
packages_dir
,
winTypeW
,
mimeType
,
friendlyDocNameW
);
hasChanged
=
TRUE
;
}
}
write_freedesktop_mime_type_entry
(
packages_dir
,
extensionW
,
mimeType
,
friendlyDocNameW
);
progIdW
=
reg_get_valW
(
HKEY_CLASSES_ROOT
,
winTypeW
,
NULL
);
hasChanged
=
TRUE
;
if
(
!
progIdW
)
goto
end
;
/* no progID => not a file type association */
/* Do not allow duplicate ProgIDs for a MIME type, it causes unnecessary duplication in Open dialogs */
mimeProgId
=
heap_wprintf
(
L"%s=>%s"
,
mimeType
,
progIdW
);
if
(
wine_rb_get
(
&
mimeProgidTree
,
mimeProgId
))
{
heap_free
(
mimeProgId
);
goto
end
;
}
entry
=
xmalloc
(
sizeof
(
struct
rb_string_entry
));
entry
->
string
=
mimeProgId
;
if
(
wine_rb_put
(
&
mimeProgidTree
,
mimeProgId
,
&
entry
->
entry
))
{
WINE_ERR
(
"error updating rb tree
\n
"
);
goto
end
;
}
}
}
executableW
=
assoc_query
(
ASSOCSTR_EXECUTABLE
,
extension
W
,
L"open"
);
executableW
=
assoc_query
(
ASSOCSTR_EXECUTABLE
,
winType
W
,
L"open"
);
if
(
executableW
)
if
(
executableW
)
openWithIcon
=
compute_native_identifier
(
0
,
executableW
,
NULL
);
openWithIcon
=
compute_native_identifier
(
0
,
executableW
,
NULL
);
friendlyAppName
=
assoc_query
(
ASSOCSTR_FRIENDLYAPPNAME
,
extension
W
,
L"open"
);
friendlyAppName
=
assoc_query
(
ASSOCSTR_FRIENDLYAPPNAME
,
winType
W
,
L"open"
);
if
(
!
friendlyAppName
)
friendlyAppName
=
L"A Wine application"
;
if
(
!
friendlyAppName
)
friendlyAppName
=
L"A Wine application"
;
progIdW
=
reg_get_valW
(
HKEY_CLASSES_ROOT
,
extensionW
,
NULL
);
if
(
has_association_changed
(
winTypeW
,
mimeType
,
progIdW
,
friendlyAppName
,
openWithIcon
))
if
(
!
progIdW
)
goto
end
;
/* no progID => not a file type association */
/* Do not allow duplicate ProgIDs for a MIME type, it causes unnecessary duplication in Open dialogs */
mimeProgId
=
heap_wprintf
(
L"%s=>%s"
,
mimeType
,
progIdW
);
if
(
wine_rb_get
(
&
mimeProgidTree
,
mimeProgId
))
{
{
free
(
mimeProgId
);
WCHAR
*
desktopPath
;
goto
end
;
if
(
isProtocolType
)
}
desktopPath
=
heap_wprintf
(
L"%s
\\
wine-protocol-%s.desktop"
,
applications_dir
,
winTypeW
);
entry
=
xmalloc
(
sizeof
(
struct
rb_string_entry
));
else
entry
->
string
=
mimeProgId
;
desktopPath
=
heap_wprintf
(
L"%s
\\
wine-extension-%s.desktop"
,
applications_dir
,
winTypeW
+
1
);
if
(
wine_rb_put
(
&
mimeProgidTree
,
mimeProgId
,
&
entry
->
entry
))
{
WINE_ERR
(
"error updating rb tree
\n
"
);
goto
end
;
}
if
(
has_association_changed
(
extensionW
,
mimeType
,
progIdW
,
friendlyAppName
,
openWithIcon
))
{
WCHAR
*
desktopPath
=
heap_wprintf
(
L"%s
\\
wine-extension-%s.desktop"
,
applications_dir
,
extensionW
+
1
);
if
(
write_freedesktop_association_entry
(
desktopPath
,
friendlyAppName
,
mimeType
,
progIdW
,
openWithIcon
))
if
(
write_freedesktop_association_entry
(
desktopPath
,
friendlyAppName
,
mimeType
,
progIdW
,
openWithIcon
))
{
{
hasChanged
=
TRUE
;
hasChanged
=
TRUE
;
update_association
(
extension
W
,
mimeType
,
progIdW
,
friendlyAppName
,
desktopPath
,
openWithIcon
);
update_association
(
winType
W
,
mimeType
,
progIdW
,
friendlyAppName
,
desktopPath
,
openWithIcon
);
}
}
free
(
desktopPath
);
free
(
desktopPath
);
}
}
...
@@ -2191,7 +2219,7 @@ static BOOL generate_associations(const WCHAR *packages_dir, const WCHAR *applic
...
@@ -2191,7 +2219,7 @@ static BOOL generate_associations(const WCHAR *packages_dir, const WCHAR *applic
free
(
mimeType
);
free
(
mimeType
);
free
(
progIdW
);
free
(
progIdW
);
}
}
free
(
extension
W
);
free
(
winType
W
);
}
}
wine_rb_destroy
(
&
mimeProgidTree
,
winemenubuilder_rb_destroy
,
NULL
);
wine_rb_destroy
(
&
mimeProgidTree
,
winemenubuilder_rb_destroy
,
NULL
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment