winemenubuilder: Build with msvcrt.

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Alexandre Julliard 2021-10-01 10:46:39 +02:00
parent 2f89d63bb9
commit f1d4dd7cc8
2 changed files with 89 additions and 135 deletions

View File

@ -1,7 +1,7 @@
MODULE = winemenubuilder.exe MODULE = winemenubuilder.exe
IMPORTS = uuid windowscodecs shell32 shlwapi ole32 user32 advapi32 IMPORTS = uuid windowscodecs shell32 shlwapi ole32 user32 advapi32
EXTRADLLFLAGS = -mwindows -municode -mcygwin EXTRADLLFLAGS = -mwindows -municode
C_SRCS = \ C_SRCS = \
winemenubuilder.c winemenubuilder.c

View File

@ -62,15 +62,9 @@
* that write associations there won't associate (#17019). * that write associations there won't associate (#17019).
*/ */
#include "config.h"
#include "wine/port.h"
#include <ctype.h> #include <ctype.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <errno.h> #include <errno.h>
#include <stdarg.h> #include <stdarg.h>
@ -78,6 +72,7 @@
#define NONAMELESSUNION #define NONAMELESSUNION
#include <windows.h> #include <windows.h>
#include <winternl.h>
#include <shlobj.h> #include <shlobj.h>
#include <objidl.h> #include <objidl.h>
#include <shlguid.h> #include <shlguid.h>
@ -88,7 +83,6 @@
#include <initguid.h> #include <initguid.h>
#include <wincodec.h> #include <wincodec.h>
#include "wine/unicode.h"
#include "wine/debug.h" #include "wine/debug.h"
#include "wine/list.h" #include "wine/list.h"
#include "wine/rbtree.h" #include "wine/rbtree.h"
@ -237,23 +231,13 @@ static void *xrealloc( void *ptr, size_t size )
return ptr; return ptr;
} }
static char *xstrdup( const char *str )
{
char *ret;
if (!str) return NULL;
ret = xmalloc( strlen(str) + 1 );
strcpy( ret, str );
return ret;
}
static WCHAR *xwcsdup( const WCHAR *str ) static WCHAR *xwcsdup( const WCHAR *str )
{ {
WCHAR *ret; WCHAR *ret;
if (!str) return NULL; if (!str) return NULL;
ret = xmalloc( (strlenW(str) + 1) * sizeof(WCHAR) ); ret = xmalloc( (lstrlenW(str) + 1) * sizeof(WCHAR) );
strcpyW( ret, str ); lstrcpyW( ret, str );
return ret; return ret;
} }
@ -262,29 +246,6 @@ static void heap_free( void *ptr )
HeapFree( GetProcessHeap(), 0, ptr ); HeapFree( GetProcessHeap(), 0, ptr );
} }
static char* heap_printf(const char *format, ...)
{
va_list args;
int size = 4096;
char *buffer;
int n;
while (1)
{
buffer = xmalloc(size);
va_start(args, format);
n = vsnprintf(buffer, size, format, args);
va_end(args);
if (n == -1)
size *= 2;
else if (n >= size)
size = n + 1;
else
return buffer;
heap_free(buffer);
}
}
static WCHAR * WINAPIV heap_wprintf(const WCHAR *format, ...) static WCHAR * WINAPIV heap_wprintf(const WCHAR *format, ...)
{ {
__ms_va_list args; __ms_va_list args;
@ -312,7 +273,7 @@ static int winemenubuilder_rb_string_compare(const void *key, const struct wine_
{ {
const struct rb_string_entry *t = WINE_RB_ENTRY_VALUE(entry, const struct rb_string_entry, entry); const struct rb_string_entry *t = WINE_RB_ENTRY_VALUE(entry, const struct rb_string_entry, entry);
return strcmpW((WCHAR *)key, t->string); return wcscmp((WCHAR *)key, t->string);
} }
static void winemenubuilder_rb_destroy(struct wine_rb_entry *entry, void *context) static void winemenubuilder_rb_destroy(struct wine_rb_entry *entry, void *context)
@ -1034,18 +995,18 @@ static HRESULT open_file_type_icon(LPCWSTR szFileName, IStream **ppStream)
int index = 0; int index = 0;
HRESULT hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND); HRESULT hr = HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
extension = strrchrW(szFileName, '.'); extension = wcsrchr(szFileName, '.');
if (extension == NULL) if (extension == NULL)
goto end; goto end;
icon = assoc_query(ASSOCSTR_DEFAULTICON, extension, NULL); icon = assoc_query(ASSOCSTR_DEFAULTICON, extension, NULL);
if (icon) if (icon)
{ {
comma = strrchrW(icon, ','); comma = wcsrchr(icon, ',');
if (comma) if (comma)
{ {
*comma = 0; *comma = 0;
index = atoiW(comma + 1); index = wcstol(comma + 1, NULL, 10);
} }
hr = open_module_icon(icon, index, ppStream); hr = open_module_icon(icon, index, ppStream);
} }
@ -1115,11 +1076,11 @@ static WCHAR *compute_native_identifier(int exeIndex, LPCWSTR icoPathW, LPCWSTR
if (filename) return xwcsdup( filename ); if (filename) return xwcsdup( filename );
crc = crc16(icoPathW); crc = crc16(icoPathW);
basename = strrchrW(icoPathW, '\\'); basename = wcsrchr(icoPathW, '\\');
if (basename == NULL) basename = icoPathW; if (basename == NULL) basename = icoPathW;
else basename++; else basename++;
ext = strrchrW(basename, '.'); ext = wcsrchr(basename, '.');
if (!ext) ext = basename + strlenW(basename); if (!ext) ext = basename + lstrlenW(basename);
return heap_wprintf(fmtW, crc, (int)(ext - basename), basename, exeIndex); return heap_wprintf(fmtW, crc, (int)(ext - basename), basename, exeIndex);
} }
@ -1375,7 +1336,7 @@ static DWORD register_menus_entry(const WCHAR *menu_file, const WCHAR *windows_f
if (hkey) if (hkey)
{ {
ret = RegSetValueExW(hkey, menu_file, 0, REG_SZ, (const BYTE*)windows_file, ret = RegSetValueExW(hkey, menu_file, 0, REG_SZ, (const BYTE*)windows_file,
(strlenW(windows_file) + 1) * sizeof(WCHAR)); (lstrlenW(windows_file) + 1) * sizeof(WCHAR));
RegCloseKey(hkey); RegCloseKey(hkey);
} }
else else
@ -1390,7 +1351,7 @@ static LPSTR escape(LPCWSTR arg)
WCHAR *escaped_string; WCHAR *escaped_string;
char *utf8_string; char *utf8_string;
escaped_string = xmalloc((4 * strlenW(arg) + 1) * sizeof(WCHAR)); escaped_string = xmalloc((4 * lstrlenW(arg) + 1) * sizeof(WCHAR));
for (i = j = 0; arg[i]; i++) for (i = j = 0; arg[i]; i++)
{ {
switch (arg[i]) switch (arg[i])
@ -1439,11 +1400,9 @@ static BOOL write_desktop_entry(const WCHAR *link, const WCHAR *location, const
{ {
FILE *file; FILE *file;
char *workdir_unix; char *workdir_unix;
char *dest_name;
int needs_chmod = FALSE; int needs_chmod = FALSE;
const WCHAR *name; const WCHAR *name;
const char *prefix = getenv("WINEPREFIX"); const WCHAR *prefix = _wgetenv( L"WINECONFIGDIR" );
const char *home = getenv("HOME");
WINE_TRACE("(%s,%s,%s,%s,%s,%s,%s,%s,%s)\n", wine_dbgstr_w(link), wine_dbgstr_w(location), WINE_TRACE("(%s,%s,%s,%s,%s,%s,%s,%s,%s)\n", wine_dbgstr_w(link), wine_dbgstr_w(location),
wine_dbgstr_w(linkname), wine_dbgstr_w(path), wine_dbgstr_w(args), wine_dbgstr_w(linkname), wine_dbgstr_w(path), wine_dbgstr_w(args),
@ -1457,9 +1416,8 @@ static BOOL write_desktop_entry(const WCHAR *link, const WCHAR *location, const
location = heap_wprintf(fmtW, xdg_desktop_dir, name); location = heap_wprintf(fmtW, xdg_desktop_dir, name);
needs_chmod = TRUE; needs_chmod = TRUE;
} }
dest_name = wine_get_unix_file_name( location );
file = fopen(dest_name, "w"); file = _wfopen( location, L"wb" );
if (file == NULL) if (file == NULL)
return FALSE; return FALSE;
@ -1467,9 +1425,11 @@ static BOOL write_desktop_entry(const WCHAR *link, const WCHAR *location, const
fprintf(file, "Name=%s\n", wchars_to_utf8_chars(name)); fprintf(file, "Name=%s\n", wchars_to_utf8_chars(name));
fprintf(file, "Exec=" ); fprintf(file, "Exec=" );
if (prefix) if (prefix)
fprintf(file, "env WINEPREFIX=\"%s\" ", prefix); {
else if (home) char *path = wine_get_unix_file_name( prefix );
fprintf(file, "env WINEPREFIX=\"%s/.wine\" ", home); fprintf(file, "env WINEPREFIX=\"%s\" ", path);
heap_free( path );
}
fprintf(file, "wine %s", escape(path)); fprintf(file, "wine %s", escape(path));
if (args) fprintf(file, " %s", escape(args) ); if (args) fprintf(file, " %s", escape(args) );
fputc( '\n', file ); fputc( '\n', file );
@ -1486,7 +1446,11 @@ static BOOL write_desktop_entry(const WCHAR *link, const WCHAR *location, const
fclose(file); fclose(file);
if (needs_chmod) chmod( dest_name, 0755 ); if (needs_chmod)
{
const char *argv[] = { "chmod", "+x", wine_get_unix_file_name(location), NULL };
__wine_unix_spawnvp( (char **)argv, FALSE );
}
if (link) if (link)
{ {
@ -1505,13 +1469,13 @@ static BOOL write_directory_entry(const WCHAR *directory, const WCHAR *location)
WINE_TRACE("(%s,%s)\n", wine_dbgstr_w(directory), wine_dbgstr_w(location)); WINE_TRACE("(%s,%s)\n", wine_dbgstr_w(directory), wine_dbgstr_w(location));
file = fopen(wine_get_unix_file_name(location), "w"); file = _wfopen( location, L"wb" );
if (file == NULL) if (file == NULL)
return FALSE; return FALSE;
fprintf(file, "[Desktop Entry]\n"); fprintf(file, "[Desktop Entry]\n");
fprintf(file, "Type=Directory\n"); fprintf(file, "Type=Directory\n");
if (strcmpW(directory, wineW) == 0) if (wcscmp(directory, wineW) == 0)
{ {
fprintf(file, "Name=Wine\n"); fprintf(file, "Name=Wine\n");
fprintf(file, "Icon=wine\n"); fprintf(file, "Icon=wine\n");
@ -1545,7 +1509,7 @@ static BOOL write_menu_file(const WCHAR *windows_link, const WCHAR *link)
WINE_TRACE("(%s)\n", wine_dbgstr_w(link)); WINE_TRACE("(%s)\n", wine_dbgstr_w(link));
GetTempFileNameW( xdg_menu_dir, mnuW, 0, tempfilename ); GetTempFileNameW( xdg_menu_dir, mnuW, 0, tempfilename );
if (!(tempfile = fopen( wine_get_unix_file_name( tempfilename ), "w" ))) return FALSE; if (!(tempfile = _wfopen( tempfilename, L"wb" ))) return FALSE;
fprintf(tempfile, "<!DOCTYPE Menu PUBLIC \"-//freedesktop//DTD Menu 1.0//EN\"\n"); fprintf(tempfile, "<!DOCTYPE Menu PUBLIC \"-//freedesktop//DTD Menu 1.0//EN\"\n");
fprintf(tempfile, "\"http://www.freedesktop.org/standards/menu-spec/menu-1.0.dtd\">\n"); fprintf(tempfile, "\"http://www.freedesktop.org/standards/menu-spec/menu-1.0.dtd\">\n");
@ -1586,7 +1550,7 @@ static BOOL write_menu_file(const WCHAR *windows_link, const WCHAR *link)
fprintf(tempfile, "</Menu>\n"); fprintf(tempfile, "</Menu>\n");
menuPath = heap_wprintf(fmtW, xdg_menu_dir, filename); menuPath = heap_wprintf(fmtW, xdg_menu_dir, filename);
strcpyW(menuPath + strlenW(menuPath) - strlen(".desktop"), menuW); lstrcpyW(menuPath + lstrlenW(menuPath) - strlen(".desktop"), menuW);
fclose(tempfile); fclose(tempfile);
ret = MoveFileExW( tempfilename, menuPath, MOVEFILE_REPLACE_EXISTING ); ret = MoveFileExW( tempfilename, menuPath, MOVEFILE_REPLACE_EXISTING );
@ -1613,7 +1577,7 @@ static BOOL write_menu_entry(const WCHAR *windows_link, const WCHAR *link, const
wine_dbgstr_w(workdir), wine_dbgstr_w(icon), wine_dbgstr_w(wmclass)); wine_dbgstr_w(workdir), wine_dbgstr_w(icon), wine_dbgstr_w(wmclass));
desktopPath = heap_wprintf(fmtW, xdg_data_dir, link); desktopPath = heap_wprintf(fmtW, xdg_data_dir, link);
desktopDir = strrchrW(desktopPath, '\\'); desktopDir = wcsrchr(desktopPath, '\\');
*desktopDir = 0; *desktopDir = 0;
if (!create_directories(desktopPath)) if (!create_directories(desktopPath))
{ {
@ -1685,7 +1649,7 @@ static BOOL get_link_location( LPCWSTR linkfile, DWORD *loc, WCHAR **relative )
if (len > filelen || filename[len]!='\\') if (len > filelen || filename[len]!='\\')
continue; continue;
if (strncmpiW( filename, buffer, len )) continue; if (wcsnicmp( filename, buffer, len )) continue;
/* return the remainder of the string and link type */ /* return the remainder of the string and link type */
*loc = locations[i]; *loc = locations[i];
@ -1862,7 +1826,7 @@ static BOOL add_mimes(const WCHAR *dir, struct list *mime_types)
FILE *globs_file; FILE *globs_file;
globs_filename = heap_wprintf(fmtW, dir); globs_filename = heap_wprintf(fmtW, dir);
globs_file = fopen(wine_get_unix_file_name(globs_filename), "r"); globs_file = _wfopen( globs_filename, L"r" );
if (globs_file) /* doesn't have to exist */ if (globs_file) /* doesn't have to exist */
{ {
char *line = NULL; char *line = NULL;
@ -1902,40 +1866,29 @@ static void free_native_mime_types(struct list *native_mime_types)
static BOOL build_native_mime_types(struct list *mime_types) static BOOL build_native_mime_types(struct list *mime_types)
{ {
char *xdg_data_dirs; WCHAR *dirs, *dir, *dos_name, *ctx, *p;
const char *begin;
char *end;
WCHAR *dos_name;
BOOL ret; BOOL ret;
xdg_data_dirs = getenv("XDG_DATA_DIRS"); if (_wgetenv( L"XDG_DATA_DIRS" ))
if (xdg_data_dirs == NULL) dirs = xwcsdup( _wgetenv( L"XDG_DATA_DIRS" ));
xdg_data_dirs = xstrdup("/usr/local/share/:/usr/share/");
else else
xdg_data_dirs = xstrdup(xdg_data_dirs); dirs = xwcsdup( L"/usr/local/share/:/usr/share/" );
ret = add_mimes(xdg_data_dir, mime_types); ret = add_mimes(xdg_data_dir, mime_types);
if (ret) if (ret)
{ {
for (begin = xdg_data_dirs; (end = strchr(begin, ':')); begin = end + 1) for (dir = wcstok( dirs, L":", &ctx ); dir; dir = wcstok( NULL, L":", &ctx ))
{ {
*end = '\0'; dos_name = heap_wprintf( L"\\\\?\\unix%s", dir );
if ((dos_name = wine_get_dos_file_name( begin ))) for (p = dos_name; *p; p++) if (*p == '/') *p = '\\';
{ if (p > dos_name + 9 && p[-1] == '\\') p[-1] = 0;
ret = add_mimes(dos_name, mime_types); ret = add_mimes(dos_name, mime_types);
heap_free( dos_name ); heap_free( dos_name );
}
*end = ':';
if (!ret) if (!ret)
break; break;
} }
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); heap_free(dirs);
if (!ret) if (!ret)
free_native_mime_types(mime_types); free_native_mime_types(mime_types);
@ -1955,10 +1908,10 @@ static BOOL freedesktop_mime_type_for_extension(struct list *native_mime_types,
{ {
if (PathMatchSpecW( extensionW, mime_type_entry->glob )) if (PathMatchSpecW( extensionW, mime_type_entry->glob ))
{ {
if (*match == NULL || matchLength < strlenW(mime_type_entry->glob)) if (*match == NULL || matchLength < lstrlenW(mime_type_entry->glob))
{ {
*match = mime_type_entry->mimeType; *match = mime_type_entry->mimeType;
matchLength = strlenW(mime_type_entry->glob); matchLength = lstrlenW(mime_type_entry->glob);
} }
} }
} }
@ -2007,24 +1960,24 @@ static BOOL has_association_changed(LPCWSTR extensionW, const WCHAR *mimeType, c
ret = FALSE; ret = FALSE;
value = reg_get_valW(assocKey, extensionW, MimeTypeW); value = reg_get_valW(assocKey, extensionW, MimeTypeW);
if (!value || strcmpW(value, mimeType)) if (!value || wcscmp(value, mimeType))
ret = TRUE; ret = TRUE;
heap_free(value); heap_free(value);
value = reg_get_valW(assocKey, extensionW, ProgIDW); value = reg_get_valW(assocKey, extensionW, ProgIDW);
if (!value || strcmpW(value, progId)) if (!value || wcscmp(value, progId))
ret = TRUE; ret = TRUE;
heap_free(value); heap_free(value);
value = reg_get_valW(assocKey, extensionW, AppNameW); value = reg_get_valW(assocKey, extensionW, AppNameW);
if (!value || strcmpW(value, appName)) if (!value || wcscmp(value, appName))
ret = TRUE; ret = TRUE;
heap_free(value); heap_free(value);
value = reg_get_valW(assocKey, extensionW, OpenWithIconW); value = reg_get_valW(assocKey, extensionW, OpenWithIconW);
if ((openWithIcon && !value) || if ((openWithIcon && !value) ||
(!openWithIcon && value) || (!openWithIcon && value) ||
(openWithIcon && value && strcmpW(value, openWithIcon))) (openWithIcon && value && wcscmp(value, openWithIcon)))
ret = TRUE; ret = TRUE;
heap_free(value); heap_free(value);
@ -2147,7 +2100,7 @@ static BOOL write_freedesktop_mime_type_entry(const WCHAR *packages_dir, const W
wine_dbgstr_w(dot_extension), wine_dbgstr_w(comment)); wine_dbgstr_w(dot_extension), wine_dbgstr_w(comment));
filename = heap_wprintf(fmtW, packages_dir, dot_extension + 1); filename = heap_wprintf(fmtW, packages_dir, dot_extension + 1);
packageFile = fopen(wine_get_unix_file_name(filename), "w"); packageFile = _wfopen( filename, L"wb" );
if (packageFile) if (packageFile)
{ {
fprintf(packageFile, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"); fprintf(packageFile, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
@ -2173,9 +2126,9 @@ static BOOL is_extension_banned(LPCWSTR extension)
static const WCHAR exeW[] = {'.','e','x','e',0}; static const WCHAR exeW[] = {'.','e','x','e',0};
static const WCHAR msiW[] = {'.','m','s','i',0}; static const WCHAR msiW[] = {'.','m','s','i',0};
if (!strcmpiW(extension, comW) || if (!wcsicmp(extension, comW) ||
!strcmpiW(extension, exeW) || !wcsicmp(extension, exeW) ||
!strcmpiW(extension, msiW)) !wcsicmp(extension, msiW))
return TRUE; return TRUE;
return FALSE; return FALSE;
} }
@ -2184,7 +2137,7 @@ static WCHAR *get_special_mime_type(LPCWSTR extension)
{ {
static const WCHAR lnkW[] = {'.','l','n','k',0}; static const WCHAR lnkW[] = {'.','l','n','k',0};
static const WCHAR shortcutW[] = {'a','p','p','l','i','c','a','t','i','o','n','/','x','-','m','s','-','s','h','o','r','t','c','u','t',0}; static const WCHAR shortcutW[] = {'a','p','p','l','i','c','a','t','i','o','n','/','x','-','m','s','-','s','h','o','r','t','c','u','t',0};
if (!strcmpiW(extension, lnkW)) if (!wcsicmp(extension, lnkW))
return xwcsdup(shortcutW); return xwcsdup(shortcutW);
return NULL; return NULL;
} }
@ -2195,14 +2148,13 @@ static BOOL write_freedesktop_association_entry(const WCHAR *desktopPath, const
{ {
BOOL ret = FALSE; BOOL ret = FALSE;
FILE *desktop; FILE *desktop;
const char *prefix = getenv("WINEPREFIX"); const WCHAR *prefix = _wgetenv( L"WINECONFIGDIR" );
const char *home = getenv("HOME");
WINE_TRACE("friendlyAppName=%s, MIME type %s, progID=%s, icon=%s to file %s\n", 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(friendlyAppName), wine_dbgstr_w(mimeType),
wine_dbgstr_w(progId), wine_dbgstr_w(openWithIcon), wine_dbgstr_w(desktopPath)); wine_dbgstr_w(progId), wine_dbgstr_w(openWithIcon), wine_dbgstr_w(desktopPath));
desktop = fopen(wine_get_unix_file_name(desktopPath), "w"); desktop = _wfopen( desktopPath, L"wb" );
if (desktop) if (desktop)
{ {
fprintf(desktop, "[Desktop Entry]\n"); fprintf(desktop, "[Desktop Entry]\n");
@ -2210,9 +2162,11 @@ static BOOL write_freedesktop_association_entry(const WCHAR *desktopPath, const
fprintf(desktop, "Name=%s\n", wchars_to_utf8_chars(friendlyAppName)); fprintf(desktop, "Name=%s\n", wchars_to_utf8_chars(friendlyAppName));
fprintf(desktop, "MimeType=%s;\n", wchars_to_utf8_chars(mimeType)); fprintf(desktop, "MimeType=%s;\n", wchars_to_utf8_chars(mimeType));
if (prefix) if (prefix)
fprintf(desktop, "Exec=env WINEPREFIX=\"%s\" wine start /ProgIDOpen %s %%f\n", prefix, escape(progId)); {
else if (home) char *path = wine_get_unix_file_name( prefix );
fprintf(desktop, "Exec=env WINEPREFIX=\"%s/.wine\" wine start /ProgIDOpen %s %%f\n", home, escape(progId)); fprintf(desktop, "Exec=env WINEPREFIX=\"%s\" wine start /ProgIDOpen %s %%f\n", path, escape(progId));
heap_free( path );
}
else else
fprintf(desktop, "Exec=wine start /ProgIDOpen %s %%f\n", escape(progId)); fprintf(desktop, "Exec=wine start /ProgIDOpen %s %%f\n", escape(progId));
fprintf(desktop, "NoDisplay=true\n"); fprintf(desktop, "NoDisplay=true\n");
@ -2271,14 +2225,14 @@ 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;
strlwrW(extensionW); wcslwr(extensionW);
friendlyDocNameW = assoc_query(ASSOCSTR_FRIENDLYDOCNAME, extensionW, NULL); friendlyDocNameW = assoc_query(ASSOCSTR_FRIENDLYDOCNAME, extensionW, NULL);
iconW = assoc_query(ASSOCSTR_DEFAULTICON, extensionW, NULL); iconW = assoc_query(ASSOCSTR_DEFAULTICON, extensionW, NULL);
contentTypeW = assoc_query(ASSOCSTR_CONTENTTYPE, extensionW, NULL); contentTypeW = assoc_query(ASSOCSTR_CONTENTTYPE, extensionW, NULL);
if (contentTypeW) if (contentTypeW)
strlwrW(contentTypeW); wcslwr(contentTypeW);
if (!freedesktop_mime_type_for_extension(&nativeMimeTypes, extensionW, &mimeType)) if (!freedesktop_mime_type_for_extension(&nativeMimeTypes, extensionW, &mimeType))
goto end; goto end;
@ -2286,7 +2240,7 @@ static BOOL generate_associations(const WCHAR *packages_dir, const WCHAR *applic
if (mimeType == NULL) if (mimeType == NULL)
{ {
static const WCHAR extW[] = {'a','p','p','l','i','c','a','t','i','o','n','/','x','-','w','i','n','e','-','e','x','t','e','n','s','i','o','n','-','%','s',0}; static const WCHAR extW[] = {'a','p','p','l','i','c','a','t','i','o','n','/','x','-','w','i','n','e','-','e','x','t','e','n','s','i','o','n','-','%','s',0};
if (contentTypeW != NULL && strchrW(contentTypeW, '/')) if (contentTypeW != NULL && wcschr(contentTypeW, '/'))
mimeType = xwcsdup(contentTypeW); mimeType = xwcsdup(contentTypeW);
else if (!(mimeType = get_special_mime_type(extensionW))) else if (!(mimeType = get_special_mime_type(extensionW)))
mimeType = heap_wprintf(extW, &extensionW[1]); mimeType = heap_wprintf(extW, &extensionW[1]);
@ -2298,11 +2252,11 @@ static BOOL generate_associations(const WCHAR *packages_dir, const WCHAR *applic
{ {
WCHAR *flattened_mime = slashes_to_minuses(mimeType); WCHAR *flattened_mime = slashes_to_minuses(mimeType);
int index = 0; int index = 0;
WCHAR *comma = strrchrW(iconW, ','); WCHAR *comma = wcsrchr(iconW, ',');
if (comma) if (comma)
{ {
*comma = 0; *comma = 0;
index = atoiW(comma + 1); index = wcstol(comma + 1, NULL, 10);
} }
extract_icon(iconW, index, flattened_mime, FALSE); extract_icon(iconW, index, flattened_mime, FALSE);
heap_free(flattened_mime); heap_free(flattened_mime);
@ -2804,11 +2758,11 @@ static void RefreshFileTypeAssociations(void)
argv[0] = "update-mime-database"; argv[0] = "update-mime-database";
argv[1] = wine_get_unix_file_name(mime_dir); argv[1] = wine_get_unix_file_name(mime_dir);
argv[2] = NULL; argv[2] = NULL;
_spawnvp( _P_DETACH, argv[0], argv ); __wine_unix_spawnvp( (char **)argv, FALSE );
argv[0] = "update-desktop-database"; argv[0] = "update-desktop-database";
argv[1] = wine_get_unix_file_name(applications_dir); argv[1] = wine_get_unix_file_name(applications_dir);
_spawnvp( _P_DETACH, argv[0], argv ); __wine_unix_spawnvp( (char **)argv, FALSE );
} }
ReleaseSemaphore(hSem, 1, NULL); ReleaseSemaphore(hSem, 1, NULL);
@ -2968,7 +2922,7 @@ static WCHAR *next_token( LPWSTR *p )
case '"': case '"':
/* unquote the token */ /* unquote the token */
token = ++t; token = ++t;
t = strchrW( token, '"' ); t = wcschr( token, '"' );
if( t ) if( t )
*t++ = 0; *t++ = 0;
break; break;
@ -2977,7 +2931,7 @@ static WCHAR *next_token( LPWSTR *p )
break; break;
default: default:
token = t; token = t;
t = strchrW( token, ' ' ); t = wcschr( token, ' ' );
if( t ) if( t )
*t++ = 0; *t++ = 0;
break; break;
@ -2989,29 +2943,29 @@ static WCHAR *next_token( LPWSTR *p )
static BOOL init_xdg(void) static BOOL init_xdg(void)
{ {
static const WCHAR fmtW[] = {'%','s','\\','d','e','s','k','t','o','p','-','d','i','r','e','c','t','o','r','i','e','s',0}; WCHAR *p;
WCHAR *buffer;
char *dir;
HRESULT hr = SHGetFolderPathW(NULL, CSIDL_DESKTOP, NULL, SHGFP_TYPE_CURRENT, xdg_desktop_dir); HRESULT hr = SHGetFolderPathW(NULL, CSIDL_DESKTOP, NULL, SHGFP_TYPE_CURRENT, xdg_desktop_dir);
if (FAILED(hr)) return FALSE; if (FAILED(hr)) return FALSE;
if (getenv("XDG_CONFIG_HOME")) if ((p = _wgetenv( L"XDG_CONFIG_HOME" )))
dir = heap_printf("%s/menus/applications-merged", getenv("XDG_CONFIG_HOME")); xdg_menu_dir = heap_wprintf( L"\\??\\unix%s/menus/applications-merged", p );
else else
dir = heap_printf("%s/.config/menus/applications-merged", getenv("HOME")); xdg_menu_dir = heap_wprintf( L"%s/.config/menus/applications-merged", _wgetenv(L"WINEHOMEDIR") );
xdg_menu_dir = wine_get_dos_file_name( dir ); for (p = xdg_menu_dir; *p; p++) if (*p == '/') *p = '\\';
xdg_menu_dir[1] = '\\'; /* change \??\ to \\?\ */
create_directories(xdg_menu_dir); create_directories(xdg_menu_dir);
if (getenv("XDG_DATA_HOME")) if ((p = _wgetenv( L"XDG_DATA_HOME" )))
dir = xstrdup(getenv("XDG_DATA_HOME")); xdg_data_dir = heap_wprintf( L"\\??\\unix%s", p );
else else
dir = heap_printf("%s/.local/share", getenv("HOME")); xdg_data_dir = heap_wprintf( L"%s/.local/share", _wgetenv(L"WINEHOMEDIR") );
xdg_data_dir = wine_get_dos_file_name( dir ); for (p = xdg_data_dir; *p; p++) if (*p == '/') *p = '\\';
xdg_data_dir[1] = '\\'; /* change \??\ to \\?\ */
buffer = heap_wprintf(fmtW, xdg_data_dir); p = heap_wprintf( L"%s\\desktop-directories", xdg_data_dir );
create_directories(buffer); create_directories(p);
heap_free(buffer); heap_free(p);
return TRUE; return TRUE;
} }
@ -3066,22 +3020,22 @@ int PASCAL wWinMain (HINSTANCE hInstance, HINSTANCE prev, LPWSTR cmdline, int sh
token = next_token( &p ); token = next_token( &p );
if( !token ) if( !token )
break; break;
if( !strcmpW( token, dash_aW ) ) if( !wcscmp( token, dash_aW ) )
{ {
if (associations_enabled()) if (associations_enabled())
RefreshFileTypeAssociations(); RefreshFileTypeAssociations();
continue; continue;
} }
if( !strcmpW( token, dash_rW ) ) if( !wcscmp( token, dash_rW ) )
{ {
cleanup_menus(); cleanup_menus();
continue; continue;
} }
if( !strcmpW( token, dash_wW ) ) if( !wcscmp( token, dash_wW ) )
bWait = TRUE; bWait = TRUE;
else if ( !strcmpW( token, dash_uW ) ) else if ( !wcscmp( token, dash_uW ) )
bURL = TRUE; bURL = TRUE;
else if ( !strcmpW( token, dash_tW ) ) else if ( !wcscmp( token, dash_tW ) )
{ {
WCHAR *lnkFile = next_token( &p ); WCHAR *lnkFile = next_token( &p );
if (lnkFile) if (lnkFile)