Convert winemenubuilder to unicode.
This commit is contained in:
parent
50e9c0145d
commit
9074f257e0
|
@ -1281,7 +1281,7 @@ static HRESULT WINAPI IShellLinkA_fnSetRelativePath(IShellLinkA * iface, LPCSTR
|
||||||
{
|
{
|
||||||
IShellLinkImpl *This = (IShellLinkImpl *)iface;
|
IShellLinkImpl *This = (IShellLinkImpl *)iface;
|
||||||
|
|
||||||
FIXME("(%p)->(path=%s %lx)\n",This, pszPathRel, dwReserved);
|
TRACE("(%p)->(path=%s %lx)\n",This, pszPathRel, dwReserved);
|
||||||
|
|
||||||
HeapFree(GetProcessHeap(), 0, This->sPathRel);
|
HeapFree(GetProcessHeap(), 0, This->sPathRel);
|
||||||
This->sPathRel = HEAP_strdupAtoW(GetProcessHeap(), 0, pszPathRel);
|
This->sPathRel = HEAP_strdupAtoW(GetProcessHeap(), 0, pszPathRel);
|
||||||
|
@ -1296,7 +1296,7 @@ static HRESULT WINAPI IShellLinkA_fnResolve(IShellLinkA * iface, HWND hwnd, DWOR
|
||||||
|
|
||||||
IShellLinkImpl *This = (IShellLinkImpl *)iface;
|
IShellLinkImpl *This = (IShellLinkImpl *)iface;
|
||||||
|
|
||||||
FIXME("(%p)->(hwnd=%p flags=%lx)\n",This, hwnd, fFlags);
|
TRACE("(%p)->(hwnd=%p flags=%lx)\n",This, hwnd, fFlags);
|
||||||
|
|
||||||
/*FIXME: use IResolveShellLink interface */
|
/*FIXME: use IResolveShellLink interface */
|
||||||
|
|
||||||
|
@ -1721,7 +1721,7 @@ static HRESULT WINAPI IShellLinkW_fnResolve(IShellLinkW * iface, HWND hwnd, DWOR
|
||||||
|
|
||||||
_ICOM_THIS_From_IShellLinkW(IShellLinkImpl, iface);
|
_ICOM_THIS_From_IShellLinkW(IShellLinkImpl, iface);
|
||||||
|
|
||||||
FIXME("(%p)->(hwnd=%p flags=%lx)\n",This, hwnd, fFlags);
|
TRACE("(%p)->(hwnd=%p flags=%lx)\n",This, hwnd, fFlags);
|
||||||
|
|
||||||
/*FIXME: use IResolveShellLink interface */
|
/*FIXME: use IResolveShellLink interface */
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
* Copyright 1997 Marcus Meissner
|
* Copyright 1997 Marcus Meissner
|
||||||
* Copyright 1998 Juergen Schmied
|
* Copyright 1998 Juergen Schmied
|
||||||
* Copyright 2003 Mike McCormack for CodeWeavers
|
* Copyright 2003 Mike McCormack for CodeWeavers
|
||||||
|
* Copyright 2004 Dmitry Timoshkov
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
@ -54,6 +55,7 @@
|
||||||
#include <objidl.h>
|
#include <objidl.h>
|
||||||
#include <shlguid.h>
|
#include <shlguid.h>
|
||||||
|
|
||||||
|
#include "wine/unicode.h"
|
||||||
#include "wine/debug.h"
|
#include "wine/debug.h"
|
||||||
#include "wine.xpm"
|
#include "wine.xpm"
|
||||||
|
|
||||||
|
@ -123,7 +125,7 @@ typedef struct
|
||||||
* FIXME: should not use stdio
|
* FIXME: should not use stdio
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static BOOL SaveIconResAsXPM(const BITMAPINFO *pIcon, const char *szXPMFileName, const char *comment)
|
static BOOL SaveIconResAsXPM(const BITMAPINFO *pIcon, const char *szXPMFileName, LPCWSTR commentW)
|
||||||
{
|
{
|
||||||
FILE *fXPMFile;
|
FILE *fXPMFile;
|
||||||
int nHeight;
|
int nHeight;
|
||||||
|
@ -136,6 +138,7 @@ static BOOL SaveIconResAsXPM(const BITMAPINFO *pIcon, const char *szXPMFileName,
|
||||||
BOOL aColorUsed[256] = {0};
|
BOOL aColorUsed[256] = {0};
|
||||||
int nColorsUsed = 0;
|
int nColorsUsed = 0;
|
||||||
int i,j;
|
int i,j;
|
||||||
|
char *comment;
|
||||||
|
|
||||||
if (!((pIcon->bmiHeader.biBitCount == 4) || (pIcon->bmiHeader.biBitCount == 8)))
|
if (!((pIcon->bmiHeader.biBitCount == 4) || (pIcon->bmiHeader.biBitCount == 8)))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -143,6 +146,10 @@ static BOOL SaveIconResAsXPM(const BITMAPINFO *pIcon, const char *szXPMFileName,
|
||||||
if (!(fXPMFile = fopen(szXPMFileName, "w")))
|
if (!(fXPMFile = fopen(szXPMFileName, "w")))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
i = WideCharToMultiByte(CP_UNIXCP, 0, commentW, -1, NULL, 0, NULL, NULL);
|
||||||
|
comment = malloc(i);
|
||||||
|
WideCharToMultiByte(CP_UNIXCP, 0, commentW, -1, comment, i, NULL, NULL);
|
||||||
|
|
||||||
nHeight = pIcon->bmiHeader.biHeight / 2;
|
nHeight = pIcon->bmiHeader.biHeight / 2;
|
||||||
nXORWidthBytes = 4 * ((pIcon->bmiHeader.biWidth * pIcon->bmiHeader.biBitCount / 32)
|
nXORWidthBytes = 4 * ((pIcon->bmiHeader.biWidth * pIcon->bmiHeader.biBitCount / 32)
|
||||||
+ ((pIcon->bmiHeader.biWidth * pIcon->bmiHeader.biBitCount % 32) > 0));
|
+ ((pIcon->bmiHeader.biWidth * pIcon->bmiHeader.biBitCount % 32) > 0));
|
||||||
|
@ -206,33 +213,35 @@ static BOOL SaveIconResAsXPM(const BITMAPINFO *pIcon, const char *szXPMFileName,
|
||||||
#undef MASK
|
#undef MASK
|
||||||
#undef COLOR
|
#undef COLOR
|
||||||
|
|
||||||
|
free(comment);
|
||||||
fclose(fXPMFile);
|
fclose(fXPMFile);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
|
free(comment);
|
||||||
fclose(fXPMFile);
|
fclose(fXPMFile);
|
||||||
unlink( szXPMFileName );
|
unlink( szXPMFileName );
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL CALLBACK EnumResNameProc(HMODULE hModule, LPCSTR lpszType, LPSTR lpszName, LONG lParam)
|
static BOOL CALLBACK EnumResNameProc(HMODULE hModule, LPCWSTR lpszType, LPWSTR lpszName, LONG_PTR lParam)
|
||||||
{
|
{
|
||||||
ENUMRESSTRUCT *sEnumRes = (ENUMRESSTRUCT *) lParam;
|
ENUMRESSTRUCT *sEnumRes = (ENUMRESSTRUCT *) lParam;
|
||||||
|
|
||||||
if (!sEnumRes->nIndex--)
|
if (!sEnumRes->nIndex--)
|
||||||
{
|
{
|
||||||
*sEnumRes->pResInfo = FindResourceA(hModule, lpszName, (LPSTR)RT_GROUP_ICON);
|
*sEnumRes->pResInfo = FindResourceW(hModule, lpszName, (LPCWSTR)RT_GROUP_ICON);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL ExtractFromEXEDLL(const char *szFileName, int nIndex, const char *szXPMFileName)
|
static BOOL extract_icon32(LPCWSTR szFileName, int nIndex, const char *szXPMFileName)
|
||||||
{
|
{
|
||||||
HMODULE hModule;
|
HMODULE hModule;
|
||||||
HRSRC hResInfo;
|
HRSRC hResInfo;
|
||||||
char *lpName = NULL;
|
LPCWSTR lpName = NULL;
|
||||||
HGLOBAL hResData;
|
HGLOBAL hResData;
|
||||||
GRPICONDIR *pIconDir;
|
GRPICONDIR *pIconDir;
|
||||||
BITMAPINFO *pIcon;
|
BITMAPINFO *pIcon;
|
||||||
|
@ -240,106 +249,92 @@ static BOOL ExtractFromEXEDLL(const char *szFileName, int nIndex, const char *sz
|
||||||
int nMax = 0;
|
int nMax = 0;
|
||||||
int nMaxBits = 0;
|
int nMaxBits = 0;
|
||||||
int i;
|
int i;
|
||||||
|
BOOL ret = FALSE;
|
||||||
|
|
||||||
hModule = LoadLibraryExA(szFileName, 0, LOAD_LIBRARY_AS_DATAFILE);
|
hModule = LoadLibraryExW(szFileName, 0, LOAD_LIBRARY_AS_DATAFILE);
|
||||||
if (!hModule)
|
if (!hModule)
|
||||||
{
|
{
|
||||||
WINE_ERR("LoadLibraryExA (%s) failed, error %ld\n", szFileName, GetLastError());
|
WINE_ERR("LoadLibraryExW (%s) failed, error %ld\n",
|
||||||
|
wine_dbgstr_w(szFileName), GetLastError());
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nIndex < 0)
|
if (nIndex < 0)
|
||||||
{
|
{
|
||||||
hResInfo = FindResourceA(hModule, MAKEINTRESOURCEA(-nIndex), (LPSTR)RT_GROUP_ICON);
|
hResInfo = FindResourceW(hModule, MAKEINTRESOURCEW(-nIndex), (LPCWSTR)RT_GROUP_ICON);
|
||||||
WINE_TRACE("FindResourceA (%s) called, return %p, error %ld\n",
|
WINE_TRACE("FindResourceW (%s) called, return %p, error %ld\n",
|
||||||
szFileName, hResInfo, GetLastError());
|
wine_dbgstr_w(szFileName), hResInfo, GetLastError());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
hResInfo=NULL;
|
hResInfo=NULL;
|
||||||
sEnumRes.pResInfo = &hResInfo;
|
sEnumRes.pResInfo = &hResInfo;
|
||||||
sEnumRes.nIndex = nIndex;
|
sEnumRes.nIndex = nIndex;
|
||||||
EnumResourceNamesA(hModule, (LPSTR)RT_GROUP_ICON, &EnumResNameProc, (LONG) &sEnumRes);
|
EnumResourceNamesW(hModule, (LPCWSTR)RT_GROUP_ICON, EnumResNameProc, (LONG_PTR)&sEnumRes);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!hResInfo)
|
if (hResInfo)
|
||||||
|
{
|
||||||
|
if ((hResData = LoadResource(hModule, hResInfo)))
|
||||||
|
{
|
||||||
|
if ((pIconDir = LockResource(hResData)))
|
||||||
|
{
|
||||||
|
for (i = 0; i < pIconDir->idCount; i++)
|
||||||
|
{
|
||||||
|
if ((pIconDir->idEntries[i].wBitCount >= nMaxBits) && (pIconDir->idEntries[i].wBitCount <= 8))
|
||||||
|
{
|
||||||
|
if (pIconDir->idEntries[i].wBitCount > nMaxBits)
|
||||||
|
{
|
||||||
|
nMaxBits = pIconDir->idEntries[i].wBitCount;
|
||||||
|
nMax = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((pIconDir->idEntries[i].bHeight * pIconDir->idEntries[i].bWidth) > nMax)
|
||||||
|
{
|
||||||
|
lpName = MAKEINTRESOURCEW(pIconDir->idEntries[i].nID);
|
||||||
|
nMax = pIconDir->idEntries[i].bHeight * pIconDir->idEntries[i].bWidth;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FreeResource(hResData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
WINE_ERR("ExtractFromEXEDLL failed, error %ld\n", GetLastError());
|
WINE_ERR("ExtractFromEXEDLL failed, error %ld\n", GetLastError());
|
||||||
goto error2;
|
FreeLibrary(hModule);
|
||||||
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(hResData = LoadResource(hModule, hResInfo)))
|
if ((hResInfo = FindResourceW(hModule, lpName, (LPCWSTR)RT_ICON)))
|
||||||
{
|
{
|
||||||
WINE_ERR("LoadResource failed, error %ld\n", GetLastError());
|
if ((hResData = LoadResource(hModule, hResInfo)))
|
||||||
goto error2;
|
|
||||||
}
|
|
||||||
if (!(pIconDir = LockResource(hResData)))
|
|
||||||
{
|
|
||||||
WINE_ERR("LockResource failed, error %ld\n", GetLastError());
|
|
||||||
goto error3;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < pIconDir->idCount; i++)
|
|
||||||
if ((pIconDir->idEntries[i].wBitCount >= nMaxBits) && (pIconDir->idEntries[i].wBitCount <= 8))
|
|
||||||
{
|
{
|
||||||
if (pIconDir->idEntries[i].wBitCount > nMaxBits)
|
if ((pIcon = LockResource(hResData)))
|
||||||
{
|
{
|
||||||
nMaxBits = pIconDir->idEntries[i].wBitCount;
|
if(SaveIconResAsXPM(pIcon, szXPMFileName, szFileName))
|
||||||
nMax = 0;
|
ret = TRUE;
|
||||||
}
|
}
|
||||||
if ((pIconDir->idEntries[i].bHeight * pIconDir->idEntries[i].bWidth) > nMax)
|
|
||||||
{
|
FreeResource(hResData);
|
||||||
lpName = MAKEINTRESOURCEA(pIconDir->idEntries[i].nID);
|
|
||||||
nMax = pIconDir->idEntries[i].bHeight * pIconDir->idEntries[i].bWidth;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FreeResource(hResData);
|
|
||||||
|
|
||||||
if (!(hResInfo = FindResourceA(hModule, lpName, (LPSTR)RT_ICON)))
|
|
||||||
{
|
|
||||||
WINE_ERR("Second FindResourceA failed, error %ld\n", GetLastError());
|
|
||||||
goto error2;
|
|
||||||
}
|
|
||||||
if (!(hResData = LoadResource(hModule, hResInfo)))
|
|
||||||
{
|
|
||||||
WINE_ERR("Second LoadResource failed, error %ld\n", GetLastError());
|
|
||||||
goto error2;
|
|
||||||
}
|
|
||||||
if (!(pIcon = LockResource(hResData)))
|
|
||||||
{
|
|
||||||
WINE_ERR("Second LockResource failed, error %ld\n", GetLastError());
|
|
||||||
goto error3;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!SaveIconResAsXPM(pIcon, szXPMFileName, szFileName))
|
|
||||||
{
|
|
||||||
WINE_ERR("Failed saving icon as XPM, error %ld\n", GetLastError());
|
|
||||||
goto error3;
|
|
||||||
}
|
|
||||||
|
|
||||||
FreeResource(hResData);
|
|
||||||
FreeLibrary(hModule);
|
FreeLibrary(hModule);
|
||||||
|
return ret;
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
error3:
|
|
||||||
FreeResource(hResData);
|
|
||||||
error2:
|
|
||||||
FreeLibrary(hModule);
|
|
||||||
return FALSE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get the Unix file name for a given path, allocating the string */
|
static BOOL ExtractFromEXEDLL(LPCWSTR szFileName, int nIndex, const char *szXPMFileName)
|
||||||
inline static char *get_unix_file_name( LPCSTR dos )
|
|
||||||
{
|
{
|
||||||
WCHAR dosW[MAX_PATH];
|
if (!extract_icon32(szFileName, nIndex, szXPMFileName) /*&&
|
||||||
|
!extract_icon16(szFileName, szXPMFileName)*/)
|
||||||
MultiByteToWideChar(CP_ACP, 0, dos, -1, dosW, MAX_PATH);
|
return FALSE;
|
||||||
return wine_get_unix_file_name( dosW );
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ExtractFromICO(const char *szFileName, const char *szXPMFileName)
|
static int ExtractFromICO(LPCWSTR szFileName, const char *szXPMFileName)
|
||||||
{
|
{
|
||||||
FILE *fICOFile;
|
FILE *fICOFile;
|
||||||
ICONDIR iconDir;
|
ICONDIR iconDir;
|
||||||
|
@ -350,7 +345,7 @@ static int ExtractFromICO(const char *szFileName, const char *szXPMFileName)
|
||||||
int i;
|
int i;
|
||||||
char *filename;
|
char *filename;
|
||||||
|
|
||||||
filename = get_unix_file_name(szFileName);
|
filename = wine_get_unix_file_name(szFileName);
|
||||||
if (!(fICOFile = fopen(filename, "r")))
|
if (!(fICOFile = fopen(filename, "r")))
|
||||||
goto error1;
|
goto error1;
|
||||||
|
|
||||||
|
@ -383,7 +378,7 @@ static int ExtractFromICO(const char *szFileName, const char *szXPMFileName)
|
||||||
free(pIcon);
|
free(pIcon);
|
||||||
free(pIconDirEntry);
|
free(pIconDirEntry);
|
||||||
fclose(fICOFile);
|
fclose(fICOFile);
|
||||||
|
HeapFree(GetProcessHeap(), 0, filename);
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
error4:
|
error4:
|
||||||
|
@ -440,47 +435,57 @@ static unsigned short crc16(const char* string)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* extract an icon from an exe or icon file; helper for IPersistFile_fnSave */
|
/* extract an icon from an exe or icon file; helper for IPersistFile_fnSave */
|
||||||
static char *extract_icon( const char *path, int index)
|
static char *extract_icon( LPCWSTR path, int index)
|
||||||
{
|
{
|
||||||
int nodefault = 1;
|
int nodefault = 1;
|
||||||
unsigned short crc;
|
unsigned short crc;
|
||||||
char *iconsdir, *ico_path, *ico_name, *xpm_path;
|
char *iconsdir, *ico_path, *ico_name, *xpm_path;
|
||||||
char* s;
|
char* s;
|
||||||
HKEY hkey;
|
HKEY hkey;
|
||||||
|
int n;
|
||||||
|
|
||||||
/* Where should we save the icon? */
|
/* Where should we save the icon? */
|
||||||
WINE_TRACE("path=[%s] index=%d\n",path,index);
|
WINE_TRACE("path=[%s] index=%d\n", wine_dbgstr_w(path), index);
|
||||||
iconsdir=NULL; /* Default is no icon */
|
iconsdir=NULL; /* Default is no icon */
|
||||||
if (!RegOpenKeyA( HKEY_LOCAL_MACHINE, "Software\\Wine\\Wine\\Config\\Wine", &hkey ))
|
if (!RegOpenKeyA( HKEY_LOCAL_MACHINE, "Software\\Wine\\Wine\\Config\\Wine", &hkey ))
|
||||||
{
|
{
|
||||||
|
static const WCHAR IconsDirW[] = {'I','c','o','n','s','D','i','r',0};
|
||||||
|
LPWSTR iconsdirW;
|
||||||
DWORD size = 0;
|
DWORD size = 0;
|
||||||
|
|
||||||
if (RegQueryValueExA(hkey, "IconsDir", 0, NULL, NULL, &size)==0)
|
if (!RegQueryValueExW(hkey, IconsDirW, 0, NULL, NULL, &size))
|
||||||
{
|
{
|
||||||
iconsdir = HeapAlloc(GetProcessHeap(), 0, size);
|
iconsdirW = HeapAlloc(GetProcessHeap(), 0, size);
|
||||||
RegQueryValueExA(hkey, "IconsDir", 0, NULL, iconsdir, &size);
|
RegQueryValueExW(hkey, IconsDirW, 0, NULL, (LPBYTE)iconsdirW, &size);
|
||||||
|
|
||||||
s = get_unix_file_name(iconsdir);
|
s = wine_get_unix_file_name(iconsdirW);
|
||||||
if (s)
|
if (s)
|
||||||
|
iconsdir = s;
|
||||||
|
else
|
||||||
{
|
{
|
||||||
HeapFree(GetProcessHeap(), 0, iconsdir);
|
int n = WideCharToMultiByte(CP_UNIXCP, 0, iconsdirW, -1, NULL, 0, NULL, NULL);
|
||||||
iconsdir=s;
|
iconsdir = HeapAlloc(GetProcessHeap(), 0, n);
|
||||||
|
WideCharToMultiByte(CP_UNIXCP, 0, iconsdirW, -1, iconsdir, n, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
HeapFree(GetProcessHeap(), 0, iconsdirW);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
char path[MAX_PATH];
|
WCHAR path[MAX_PATH];
|
||||||
|
|
||||||
if (GetTempPath(sizeof(path),path))
|
if (GetTempPathW(MAX_PATH, path))
|
||||||
{
|
{
|
||||||
s = get_unix_file_name(path);
|
s = wine_get_unix_file_name(path);
|
||||||
if (s)
|
if (s)
|
||||||
iconsdir = s;
|
iconsdir = s;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
RegCloseKey( hkey );
|
RegCloseKey( hkey );
|
||||||
}
|
}
|
||||||
if (iconsdir==NULL || *iconsdir=='\0')
|
if (!iconsdir)
|
||||||
|
return NULL; /* No icon created */
|
||||||
|
|
||||||
|
if (!*iconsdir)
|
||||||
{
|
{
|
||||||
HeapFree(GetProcessHeap(), 0, iconsdir);
|
HeapFree(GetProcessHeap(), 0, iconsdir);
|
||||||
return NULL; /* No icon created */
|
return NULL; /* No icon created */
|
||||||
|
@ -494,8 +499,9 @@ static char *extract_icon( const char *path, int index)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Determine the icon base name */
|
/* Determine the icon base name */
|
||||||
ico_path=HeapAlloc(GetProcessHeap(), 0, lstrlenA(path)+1);
|
n = WideCharToMultiByte(CP_UNIXCP, 0, path, -1, NULL, 0, NULL, NULL);
|
||||||
strcpy(ico_path, path);
|
ico_path = HeapAlloc(GetProcessHeap(), 0, n);
|
||||||
|
WideCharToMultiByte(CP_UNIXCP, 0, path, -1, ico_path, n, NULL, NULL);
|
||||||
s=ico_name=ico_path;
|
s=ico_name=ico_path;
|
||||||
while (*s!='\0') {
|
while (*s!='\0') {
|
||||||
if (*s=='/' || *s=='\\') {
|
if (*s=='/' || *s=='\\') {
|
||||||
|
@ -524,7 +530,7 @@ static char *extract_icon( const char *path, int index)
|
||||||
if (ExtractFromICO( path, xpm_path))
|
if (ExtractFromICO( path, xpm_path))
|
||||||
goto end;
|
goto end;
|
||||||
if (!nodefault)
|
if (!nodefault)
|
||||||
if (create_default_icon( xpm_path, path ))
|
if (create_default_icon( xpm_path, ico_path ))
|
||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
HeapFree( GetProcessHeap(), 0, xpm_path );
|
HeapFree( GetProcessHeap(), 0, xpm_path );
|
||||||
|
@ -577,15 +583,27 @@ static BOOL DeferToRunOnce(LPWSTR link)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This escapes \ in filenames */
|
/* This escapes \ in filenames */
|
||||||
static LPSTR escape(LPCSTR arg)
|
static LPSTR escape(LPCWSTR arg)
|
||||||
{
|
{
|
||||||
LPSTR narg, x;
|
LPSTR narg, x;
|
||||||
|
LPCWSTR esc;
|
||||||
|
int len = 0, n;
|
||||||
|
|
||||||
narg = HeapAlloc(GetProcessHeap(),0,2*strlen(arg)+2);
|
esc = arg;
|
||||||
x = narg;
|
while((esc = strchrW(esc, '\\')))
|
||||||
while (*arg)
|
|
||||||
{
|
{
|
||||||
*x++ = *arg;
|
esc++;
|
||||||
|
len++;
|
||||||
|
}
|
||||||
|
|
||||||
|
len += WideCharToMultiByte(CP_UNIXCP, 0, arg, -1, NULL, 0, NULL, NULL);
|
||||||
|
narg = HeapAlloc(GetProcessHeap(), 0, len);
|
||||||
|
|
||||||
|
x = narg;
|
||||||
|
while (*arg) {
|
||||||
|
n = WideCharToMultiByte(CP_UNIXCP, 0, arg, 1, x, len, NULL, NULL);
|
||||||
|
x += n;
|
||||||
|
len -= n;
|
||||||
if (*arg == '\\')
|
if (*arg == '\\')
|
||||||
*x++='\\'; /* escape \ */
|
*x++='\\'; /* escape \ */
|
||||||
arg++;
|
arg++;
|
||||||
|
@ -643,25 +661,30 @@ static int fork_and_wait( char *linker, char *link_name, char *path,
|
||||||
|
|
||||||
static char *cleanup_link( LPCWSTR link )
|
static char *cleanup_link( LPCWSTR link )
|
||||||
{
|
{
|
||||||
|
char *unix_file_name;
|
||||||
char *p, *link_name;
|
char *p, *link_name;
|
||||||
int len;
|
|
||||||
|
|
||||||
/* make link name a Unix name -
|
unix_file_name = wine_get_unix_file_name(link);
|
||||||
strip leading slashes & remove extension */
|
if (!unix_file_name)
|
||||||
while ( (*link == '\\') || (*link == '/' ) )
|
{
|
||||||
link++;
|
WINE_ERR("target link %s not found\n", wine_dbgstr_w(link));
|
||||||
len = WideCharToMultiByte( CP_ACP, 0, link, -1, NULL, 0, NULL, NULL);
|
return NULL;
|
||||||
link_name = HeapAlloc( GetProcessHeap(), 0, len*sizeof (WCHAR) );
|
}
|
||||||
if( ! link_name )
|
|
||||||
return link_name;
|
link_name = unix_file_name;
|
||||||
len = WideCharToMultiByte( CP_ACP, 0, link, -1, link_name, len, NULL, NULL);
|
p = strrchr( link_name, '/' );
|
||||||
for (p = link_name; *p; p++)
|
if (p)
|
||||||
if (*p == '\\')
|
link_name = p + 1;
|
||||||
*p = '/';
|
|
||||||
p = strrchr( link_name, '.' );
|
p = strrchr( link_name, '.' );
|
||||||
if (p)
|
if (p)
|
||||||
*p = 0;
|
*p = 0;
|
||||||
return link_name;
|
|
||||||
|
p = HeapAlloc(GetProcessHeap(), 0, strlen(link_name) + 1);
|
||||||
|
strcpy(p, link_name);
|
||||||
|
HeapFree(GetProcessHeap(), 0, unix_file_name);
|
||||||
|
|
||||||
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
|
@ -671,7 +694,7 @@ static char *cleanup_link( LPCWSTR link )
|
||||||
* returns TRUE if successful
|
* returns TRUE if successful
|
||||||
* *loc will contain CS_DESKTOPDIRECTORY, CS_STARTMENU, CS_STARTUP
|
* *loc will contain CS_DESKTOPDIRECTORY, CS_STARTMENU, CS_STARTUP
|
||||||
*/
|
*/
|
||||||
static BOOL GetLinkLocation( LPCWSTR linkfile, DWORD *ofs, DWORD *loc )
|
static BOOL GetLinkLocation( LPCWSTR linkfile, DWORD *loc )
|
||||||
{
|
{
|
||||||
WCHAR filename[MAX_PATH], buffer[MAX_PATH];
|
WCHAR filename[MAX_PATH], buffer[MAX_PATH];
|
||||||
DWORD len, i, r, filelen;
|
DWORD len, i, r, filelen;
|
||||||
|
@ -685,6 +708,8 @@ static BOOL GetLinkLocation( LPCWSTR linkfile, DWORD *ofs, DWORD *loc )
|
||||||
if (filelen==0 || filelen>MAX_PATH)
|
if (filelen==0 || filelen>MAX_PATH)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
WINE_TRACE("%s\n", wine_dbgstr_w(filename));
|
||||||
|
|
||||||
for( i=0; i<sizeof(locations)/sizeof(locations[0]); i++ )
|
for( i=0; i<sizeof(locations)/sizeof(locations[0]); i++ )
|
||||||
{
|
{
|
||||||
if (!SHGetSpecialFolderPathW( 0, buffer, locations[i], FALSE ))
|
if (!SHGetSpecialFolderPathW( 0, buffer, locations[i], FALSE ))
|
||||||
|
@ -704,7 +729,6 @@ static BOOL GetLinkLocation( LPCWSTR linkfile, DWORD *ofs, DWORD *loc )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* return the remainder of the string and link type */
|
/* return the remainder of the string and link type */
|
||||||
*ofs = len;
|
|
||||||
*loc = locations[i];
|
*loc = locations[i];
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -712,14 +736,14 @@ static BOOL GetLinkLocation( LPCWSTR linkfile, DWORD *ofs, DWORD *loc )
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL InvokeShellLinker( IShellLinkA *sl, LPCWSTR link )
|
static BOOL InvokeShellLinker( IShellLinkW *sl, LPCWSTR link )
|
||||||
{
|
{
|
||||||
char *link_name, *p, *icon_name = NULL, *work_dir = NULL;
|
char *link_name = NULL, *icon_name = NULL, *work_dir = NULL;
|
||||||
char *escaped_path = NULL, *escaped_args = NULL;
|
char *escaped_path = NULL, *escaped_args = NULL, *escaped_description = NULL;
|
||||||
CHAR szDescription[INFOTIPSIZE], szPath[MAX_PATH], szWorkDir[MAX_PATH];
|
WCHAR szDescription[INFOTIPSIZE], szPath[MAX_PATH], szWorkDir[MAX_PATH];
|
||||||
CHAR szArgs[INFOTIPSIZE], szIconPath[MAX_PATH];
|
WCHAR szArgs[INFOTIPSIZE], szIconPath[MAX_PATH];
|
||||||
int iIconId = 0, r;
|
int iIconId = 0, r;
|
||||||
DWORD csidl = -1, ofs = 0;
|
DWORD csidl = -1;
|
||||||
|
|
||||||
if ( !link )
|
if ( !link )
|
||||||
{
|
{
|
||||||
|
@ -727,7 +751,7 @@ static BOOL InvokeShellLinker( IShellLinkA *sl, LPCWSTR link )
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !GetLinkLocation( link, &ofs, &csidl ) )
|
if( !GetLinkLocation( link, &csidl ) )
|
||||||
{
|
{
|
||||||
WINE_WARN("Unknown link location '%s'. Ignoring.\n",wine_dbgstr_w(link));
|
WINE_WARN("Unknown link location '%s'. Ignoring.\n",wine_dbgstr_w(link));
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@ -739,31 +763,31 @@ static BOOL InvokeShellLinker( IShellLinkA *sl, LPCWSTR link )
|
||||||
}
|
}
|
||||||
|
|
||||||
szWorkDir[0] = 0;
|
szWorkDir[0] = 0;
|
||||||
IShellLinkA_GetWorkingDirectory( sl, szWorkDir, MAX_PATH );
|
IShellLinkW_GetWorkingDirectory(sl, szWorkDir, MAX_PATH);
|
||||||
WINE_TRACE("workdir : %s\n", szWorkDir);
|
WINE_TRACE("workdir : %s\n", wine_dbgstr_w(szWorkDir));
|
||||||
|
|
||||||
szDescription[0] = 0;
|
szDescription[0] = 0;
|
||||||
IShellLinkA_GetDescription( sl, szDescription, INFOTIPSIZE );
|
IShellLinkW_GetDescription( sl, szDescription, INFOTIPSIZE );
|
||||||
WINE_TRACE("description: %s\n", szDescription);
|
WINE_TRACE("description: %s\n", wine_dbgstr_w(szDescription));
|
||||||
|
|
||||||
szPath[0] = 0;
|
szPath[0] = 0;
|
||||||
IShellLinkA_GetPath( sl, szPath, MAX_PATH, NULL, SLGP_RAWPATH );
|
IShellLinkW_GetPath( sl, szPath, MAX_PATH, NULL, SLGP_RAWPATH );
|
||||||
WINE_TRACE("path : %s\n", szPath);
|
WINE_TRACE("path : %s\n", wine_dbgstr_w(szPath));
|
||||||
|
|
||||||
szArgs[0] = 0;
|
szArgs[0] = 0;
|
||||||
IShellLinkA_GetArguments( sl, szArgs, INFOTIPSIZE );
|
IShellLinkW_GetArguments( sl, szArgs, INFOTIPSIZE );
|
||||||
WINE_TRACE("args : %s\n", szArgs);
|
WINE_TRACE("args : %s\n", wine_dbgstr_w(szArgs));
|
||||||
|
|
||||||
szIconPath[0] = 0;
|
szIconPath[0] = 0;
|
||||||
IShellLinkA_GetIconLocation( sl, szIconPath, MAX_PATH, &iIconId );
|
IShellLinkW_GetIconLocation( sl, szIconPath, MAX_PATH, &iIconId );
|
||||||
WINE_TRACE("icon file : %s\n", szIconPath );
|
WINE_TRACE("icon file : %s\n", wine_dbgstr_w(szIconPath) );
|
||||||
|
|
||||||
if( !szPath[0] )
|
if( !szPath[0] )
|
||||||
{
|
{
|
||||||
LPITEMIDLIST pidl = NULL;
|
LPITEMIDLIST pidl = NULL;
|
||||||
IShellLinkA_GetIDList( sl, &pidl );
|
IShellLinkW_GetIDList( sl, &pidl );
|
||||||
if( pidl && SHGetPathFromIDListA( pidl, szPath ) );
|
if( pidl && SHGetPathFromIDListW( pidl, szPath ) );
|
||||||
WINE_TRACE("pidl path : %s\n", szPath );
|
WINE_TRACE("pidl path : %s\n", wine_dbgstr_w(szPath));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* extract the icon */
|
/* extract the icon */
|
||||||
|
@ -782,45 +806,48 @@ static BOOL InvokeShellLinker( IShellLinkA *sl, LPCWSTR link )
|
||||||
/* check the path */
|
/* check the path */
|
||||||
if( szPath[0] )
|
if( szPath[0] )
|
||||||
{
|
{
|
||||||
|
static const WCHAR exeW[] = {'.','e','x','e',0};
|
||||||
|
WCHAR *p;
|
||||||
/* check for .exe extension */
|
/* check for .exe extension */
|
||||||
if (!(p = strrchr( szPath, '.' ))) return FALSE;
|
if (!(p = strrchrW( szPath, '.' ))) return FALSE;
|
||||||
if (strchr( p, '\\' ) || strchr( p, '/' )) return FALSE;
|
if (strchrW( p, '\\' ) || strchrW( p, '/' )) return FALSE;
|
||||||
if (strcasecmp( p, ".exe" )) return FALSE;
|
if (lstrcmpiW( p, exeW )) return FALSE;
|
||||||
|
|
||||||
/* convert app working dir */
|
/* convert app working dir */
|
||||||
if (szWorkDir[0])
|
if (szWorkDir[0])
|
||||||
work_dir = get_unix_file_name( szWorkDir );
|
work_dir = wine_get_unix_file_name( szWorkDir );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
static const WCHAR startW[] = {'\\','c','o','m','m','a','n','d','\\','s','t','a','r','t','.','e','x','e',0};
|
||||||
/* if there's no path... try run the link itself */
|
/* if there's no path... try run the link itself */
|
||||||
WideCharToMultiByte( CP_ACP, 0, link, -1, szArgs, MAX_PATH, NULL, NULL );
|
lstrcpynW(szArgs, link, MAX_PATH);
|
||||||
GetWindowsDirectoryA(szPath, MAX_PATH);
|
GetWindowsDirectoryW(szPath, MAX_PATH);
|
||||||
strncat(szPath, "\\command\\start.exe",
|
lstrcatW(szPath, startW);
|
||||||
MAX_PATH - GetWindowsDirectoryA(NULL, 0));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
link_name = cleanup_link( &link[ofs] );
|
link_name = cleanup_link( link );
|
||||||
if( !link_name )
|
if( !link_name )
|
||||||
{
|
{
|
||||||
WINE_ERR("Couldn't clean up link name\n");
|
WINE_ERR("Couldn't clean up link name %s\n", wine_dbgstr_w(link));
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* escape the path and parameters */
|
/* escape the path and parameters */
|
||||||
escaped_path = escape(szPath);
|
escaped_path = escape(szPath);
|
||||||
if (szArgs)
|
escaped_args = escape(szArgs);
|
||||||
escaped_args = escape(szArgs);
|
escaped_description = escape(szDescription);
|
||||||
|
|
||||||
r = fork_and_wait("wineshelllink", link_name, escaped_path,
|
r = fork_and_wait("wineshelllink", link_name, escaped_path,
|
||||||
in_desktop_dir(csidl), escaped_args, icon_name,
|
in_desktop_dir(csidl), escaped_args, icon_name,
|
||||||
work_dir ? work_dir : "", szDescription );
|
work_dir ? work_dir : "", escaped_description);
|
||||||
|
|
||||||
HeapFree( GetProcessHeap(), 0, icon_name );
|
HeapFree( GetProcessHeap(), 0, icon_name );
|
||||||
HeapFree( GetProcessHeap(), 0, work_dir );
|
HeapFree( GetProcessHeap(), 0, work_dir );
|
||||||
HeapFree( GetProcessHeap(), 0, link_name );
|
HeapFree( GetProcessHeap(), 0, link_name );
|
||||||
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 );
|
||||||
|
|
||||||
if (r)
|
if (r)
|
||||||
{
|
{
|
||||||
|
@ -832,9 +859,9 @@ static BOOL InvokeShellLinker( IShellLinkA *sl, LPCWSTR link )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static BOOL Process_Link( LPWSTR linkname, BOOL bAgain )
|
static BOOL Process_Link( LPCWSTR linkname, BOOL bAgain )
|
||||||
{
|
{
|
||||||
IShellLinkA *sl;
|
IShellLinkW *sl;
|
||||||
IPersistFile *pf;
|
IPersistFile *pf;
|
||||||
HRESULT r;
|
HRESULT r;
|
||||||
WCHAR fullname[MAX_PATH];
|
WCHAR fullname[MAX_PATH];
|
||||||
|
@ -863,14 +890,14 @@ static BOOL Process_Link( LPWSTR linkname, BOOL bAgain )
|
||||||
}
|
}
|
||||||
|
|
||||||
r = CoCreateInstance( &CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
|
r = CoCreateInstance( &CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
|
||||||
&IID_IShellLink, (LPVOID *) &sl );
|
&IID_IShellLinkW, (LPVOID *) &sl );
|
||||||
if( FAILED( r ) )
|
if( FAILED( r ) )
|
||||||
{
|
{
|
||||||
WINE_ERR("No IID_IShellLink\n");
|
WINE_ERR("No IID_IShellLink\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
r = IShellLinkA_QueryInterface( sl, &IID_IPersistFile, (LPVOID*) &pf );
|
r = IShellLinkW_QueryInterface( sl, &IID_IPersistFile, (LPVOID*) &pf );
|
||||||
if( FAILED( r ) )
|
if( FAILED( r ) )
|
||||||
{
|
{
|
||||||
WINE_ERR("No IID_IPersistFile\n");
|
WINE_ERR("No IID_IPersistFile\n");
|
||||||
|
@ -890,7 +917,7 @@ static BOOL Process_Link( LPWSTR linkname, BOOL bAgain )
|
||||||
}
|
}
|
||||||
|
|
||||||
IPersistFile_Release( pf );
|
IPersistFile_Release( pf );
|
||||||
IShellLinkA_Release( sl );
|
IShellLinkW_Release( sl );
|
||||||
|
|
||||||
CoUninitialize();
|
CoUninitialize();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue