* in that string is parsed an stored.
*/
-#define COBJMACROS
-#define NONAMELESSUNION
-
-#include "wine/debug.h"
-#include "winerror.h"
-#include "windef.h"
-#include "winbase.h"
-#include "winnls.h"
-#include "winreg.h"
-
-#include "winuser.h"
-#include "wingdi.h"
-#include "shlobj.h"
-#include "undocshell.h"
-
-#include "pidl.h"
-#include "shell32_main.h"
-#include "shlguid.h"
-#include "shlwapi.h"
-#include "msi.h"
-#include "appmgmt.h"
-#include "prsht.h"
-#include "initguid.h"
-#include "shresdef.h"
+#include <precomp.h>
WINE_DEFAULT_DEBUG_CHANNEL(shell);
-DEFINE_GUID( SHELL32_AdvtShortcutProduct,
- 0x9db1186f,0x40df,0x11d1,0xaa,0x8c,0x00,0xc0,0x4f,0xb6,0x78,0x63);
-DEFINE_GUID( SHELL32_AdvtShortcutComponent,
- 0x9db1186e,0x40df,0x11d1,0xaa,0x8c,0x00,0xc0,0x4f,0xb6,0x78,0x63);
-
/* link file formats */
#include "pshpack1.h"
static const IShellExtInitVtbl eivt;
static const IContextMenuVtbl cmvt;
static const IObjectWithSiteVtbl owsvt;
+static const IShellPropSheetExtVtbl pse;
/* IShellLink Implementation */
const IShellExtInitVtbl *lpvtblShellExtInit;
const IContextMenuVtbl *lpvtblContextMenu;
const IObjectWithSiteVtbl *lpvtblObjectWithSite;
+ const IShellPropSheetExtVtbl * lpvtblPropSheetExt;
LONG ref;
LPWSTR sComponent;
volume_info volume;
LPWSTR sLinkPath;
+ LPWSTR sCurFile;
BOOL bRunAs;
BOOL bDirty;
INT iIdOpen; /* id of the "Open" entry in the context menu */
- INT iIdProperties; /* id of the "Properties" entry in the context menu */
IUnknown *site;
-} IShellLinkImpl;
+} IShellLinkImpl, *LPIShellLinkImpl;
-static inline IShellLinkImpl *impl_from_IShellLinkW( IShellLinkW *iface )
+static LPIShellLinkImpl __inline impl_from_IShellLinkW( IShellLinkW *iface )
{
return (IShellLinkImpl *)((char*)iface - FIELD_OFFSET(IShellLinkImpl, lpvtblw));
}
-static inline IShellLinkImpl *impl_from_IPersistFile( IPersistFile *iface )
+static LPIShellLinkImpl __inline impl_from_IPersistFile( IPersistFile *iface )
{
return (IShellLinkImpl *)((char*)iface - FIELD_OFFSET(IShellLinkImpl, lpvtblPersistFile));
}
-static inline IShellLinkImpl *impl_from_IPersistStream( IPersistStream *iface )
+static LPIShellLinkImpl __inline impl_from_IPersistStream( IPersistStream *iface )
{
return (IShellLinkImpl *)((char*)iface - FIELD_OFFSET(IShellLinkImpl, lpvtblPersistStream));
}
-static inline IShellLinkImpl *impl_from_IShellLinkDataList( IShellLinkDataList *iface )
+static LPIShellLinkImpl __inline impl_from_IShellLinkDataList( IShellLinkDataList *iface )
{
return (IShellLinkImpl *)((char*)iface - FIELD_OFFSET(IShellLinkImpl, lpvtblShellLinkDataList));
}
-static inline IShellLinkImpl *impl_from_IShellExtInit( IShellExtInit *iface )
+static LPIShellLinkImpl __inline impl_from_IShellExtInit( IShellExtInit *iface )
{
return (IShellLinkImpl *)((char*)iface - FIELD_OFFSET(IShellLinkImpl, lpvtblShellExtInit));
}
-static inline IShellLinkImpl *impl_from_IContextMenu( IContextMenu *iface )
+static LPIShellLinkImpl __inline impl_from_IContextMenu( IContextMenu *iface )
{
return (IShellLinkImpl *)((char*)iface - FIELD_OFFSET(IShellLinkImpl, lpvtblContextMenu));
}
-static inline IShellLinkImpl *impl_from_IObjectWithSite( IObjectWithSite *iface )
+static LPIShellLinkImpl __inline impl_from_IObjectWithSite( IObjectWithSite *iface )
{
return (IShellLinkImpl *)((char*)iface - FIELD_OFFSET(IShellLinkImpl, lpvtblObjectWithSite));
}
+static LPIShellLinkImpl __inline impl_from_IShellPropSheetExt( IShellPropSheetExt *iface )
+{
+ return (IShellLinkImpl *)((char*)iface - FIELD_OFFSET(IShellLinkImpl, lpvtblPropSheetExt));
+}
+
+
static HRESULT ShellLink_UpdatePath(LPCWSTR sPathRel, LPCWSTR path, LPCWSTR sWorkDir, LPWSTR* psPath);
/* strdup on the process heap */
-static inline LPWSTR HEAP_strdupAtoW( HANDLE heap, DWORD flags, LPCSTR str)
+static LPWSTR __inline HEAP_strdupAtoW( HANDLE heap, DWORD flags, LPCSTR str)
{
+ assert(str);
INT len = MultiByteToWideChar( CP_ACP, 0, str, -1, NULL, 0 );
LPWSTR p = HeapAlloc( heap, flags, len*sizeof (WCHAR) );
if( !p )
return p;
}
-static inline LPWSTR strdupW( LPCWSTR src )
+static LPWSTR __inline strdupW( LPCWSTR src )
{
LPWSTR dest;
if (!src) return NULL;
- dest = HeapAlloc( GetProcessHeap(), 0, (lstrlenW(src)+1)*sizeof(WCHAR) );
+ dest = HeapAlloc( GetProcessHeap(), 0, (wcslen(src)+1)*sizeof(WCHAR) );
if (dest)
- lstrcpyW(dest, src);
+ wcscpy(dest, src);
return dest;
}
{
*ppvObj = &(This->lpvtblObjectWithSite);
}
+ else if(IsEqualIID(riid, &IID_IShellPropSheetExt))
+ {
+ *ppvObj = &(This->lpvtblPropSheetExt);
+ }
if(*ppvObj)
{
if (This->pPidl)
ILFree(This->pPidl);
- LocalFree((HANDLE)This);
+ LocalFree(This);
return 0;
}
{
TRACE("%p %p\n", This, pclsid);
- memcpy( pclsid, &CLSID_ShellLink, sizeof (CLSID) );
+ *pclsid = CLSID_ShellLink;
return S_OK;
}
PROCESS_INFORMATION pi;
BOOL ret;
- len = sizeof(szFormat) + lstrlenW( szLink ) * sizeof(WCHAR);
+ len = sizeof(szFormat) + wcslen( szLink ) * sizeof(WCHAR);
buffer = HeapAlloc( GetProcessHeap(), 0, len );
if( !buffer )
return FALSE;
- wsprintfW( buffer, szFormat, szLink );
+ swprintf( buffer, szFormat, szLink );
TRACE("starting %s\n",debugstr_w(buffer));
IStream_Release( stm );
if( SUCCEEDED( r ) )
- {
+ {
+ if ( This->sLinkPath )
+ {
+ HeapFree(GetProcessHeap(), 0, This->sLinkPath);
+ }
+ This->sLinkPath = HeapAlloc(GetProcessHeap(), 0, (wcslen(pszFileName)+1) * sizeof(WCHAR));
+ if ( This->sLinkPath )
+ {
+ wcscpy(This->sLinkPath, pszFileName);
+ }
+
StartLinkProcessor( pszFileName );
This->bDirty = FALSE;
}
- else
+ else
{
DeleteFileW( pszFileName );
WARN("Failed to create shortcut %s\n", debugstr_w(pszFileName) );
static HRESULT WINAPI IPersistFile_fnGetCurFile(IPersistFile* iface, LPOLESTR *ppszFileName)
{
- IShellLinkImpl *This = impl_from_IPersistFile(iface);
- FIXME("(%p)\n",This);
- return NOERROR;
+ IShellLinkImpl *This = impl_from_IPersistFile(iface);
+
+ *ppszFileName = NULL;
+
+ if ( !This->sLinkPath)
+ {
+ /* IPersistFile::GetCurFile called before IPersistFile::Save */
+ return S_FALSE;
+ }
+
+ *ppszFileName = CoTaskMemAlloc((wcslen(This->sLinkPath)+1) * sizeof(WCHAR));
+ if (!*ppszFileName)
+ {
+ /* out of memory */
+ return E_OUTOFMEMORY;
+ }
+
+ /* copy last saved filename */
+ wcscpy(*ppszFileName, This->sLinkPath);
+
+ return NOERROR;
}
static const IPersistFileVtbl pfvt =
/* convert to unicode if necessary */
if( !unicode )
{
- count = MultiByteToWideChar( CP_ACP, 0, (LPSTR) temp, len, NULL, 0 );
+ count = MultiByteToWideChar( CP_ACP, 0, temp, len, NULL, 0 );
str = HeapAlloc( GetProcessHeap(), 0, (count+1)*sizeof (WCHAR) );
if( !str )
{
HeapFree( GetProcessHeap(), 0, temp );
return E_OUTOFMEMORY;
}
- MultiByteToWideChar( CP_ACP, 0, (LPSTR) temp, len, str, count );
+ MultiByteToWideChar( CP_ACP, 0, temp, len, str, count );
HeapFree( GetProcessHeap(), 0, temp );
}
else
{
count /= 2;
- str = (LPWSTR) temp;
+ str = temp;
}
str[count] = 0;
TRACE("Read %d bytes\n",chunk->size);
- *data = (LPVOID) chunk;
+ *data = chunk;
return S_OK;
}
char *p = NULL;
LOCATION_INFO *loc;
HRESULT r;
- int n;
+ DWORD n;
r = Stream_ReadChunk( stm, (LPVOID*) &p );
if( FAILED(r) )
}
*str = HeapAlloc( GetProcessHeap(), 0,
- (lstrlenW(buffer.szwDarwinID)+1) * sizeof(WCHAR) );
- lstrcpyW( *str, buffer.szwDarwinID );
+ (wcslen(buffer.szwDarwinID)+1) * sizeof(WCHAR) );
+ wcscpy( *str, buffer.szwDarwinID );
return S_OK;
}
if( FAILED( r ) )
goto end;
+#if (NTDDI_VERSION < NTDDI_LONGHORN)
if( hdr.dwFlags & SLDF_HAS_LOGO3ID )
{
r = Stream_LoadAdvertiseInfo( stm, &This->sProduct );
}
if( FAILED( r ) )
goto end;
+#endif
if( hdr.dwFlags & SLDF_HAS_DARWINID )
{
*/
static HRESULT Stream_WriteString( IStream* stm, LPCWSTR str )
{
- USHORT len = lstrlenW( str ) + 1;
+ USHORT len = wcslen( str ) + 1;
DWORD count;
HRESULT r;
LOCATION_INFO *loc;
LPSTR szLabel, szPath, szFinalPath;
ULONG count = 0;
+ HRESULT hr;
TRACE("%p %s %p\n", stm, debugstr_w(path), volume);
szPath, path_size, NULL, NULL );
szFinalPath[0] = 0;
- return IStream_Write( stm, loc, total_size, &count );
+ hr = IStream_Write( stm, loc, total_size, &count );
+ HeapFree(GetProcessHeap(), 0, loc);
+
+ return hr;
}
static EXP_DARWIN_LINK* shelllink_build_darwinid( LPCWSTR string, DWORD magic )
memset(&header, 0, sizeof(header));
header.dwSize = sizeof(header);
header.fStartup = This->iShowCmd;
- memcpy(&header.MagicGuid, &CLSID_ShellLink, sizeof(header.MagicGuid) );
+ header.MagicGuid = CLSID_ShellLink;
header.wHotKey = This->wHotKey;
header.nIcon = This->iIcoNdx;
header.dwFlags |= SLDF_HAS_ARGS;
if( This->sIcoPath )
header.dwFlags |= SLDF_HAS_ICONLOCATION;
+#if (NTDDI_VERSION < NTDDI_LONGHORN)
if( This->sProduct )
header.dwFlags |= SLDF_HAS_LOGO3ID;
+#endif
if( This->sComponent )
header.dwFlags |= SLDF_HAS_DARWINID;
if( This->bRunAs )
sl->lpvtblShellExtInit = &eivt;
sl->lpvtblContextMenu = &cmvt;
sl->lpvtblObjectWithSite = &owsvt;
+ sl->lpvtblPropSheetExt = &pse;
sl->iShowCmd = SW_SHOWNORMAL;
sl->bDirty = FALSE;
sl->iIdOpen = -1;
GetFullPathNameW( path, MAX_PATH*2, buffer, &final );
if( !final )
final = buffer;
- lstrcpyW(final, sPathRel);
+ wcscpy(final, sPathRel);
*abs_path = '\0';
if (SHELL_ExistsFileW(buffer)) {
if (!GetFullPathNameW(buffer, MAX_PATH, abs_path, &final))
- lstrcpyW(abs_path, buffer);
+ wcscpy(abs_path, buffer);
} else {
/* try if [working directory] + [relative path] finds an existing file */
if (sWorkDir) {
- lstrcpyW(buffer, sWorkDir);
- lstrcpyW(PathAddBackslashW(buffer), sPathRel);
+ wcscpy(buffer, sWorkDir);
+ wcscpy(PathAddBackslashW(buffer), sPathRel);
if (SHELL_ExistsFileW(buffer))
if (!GetFullPathNameW(buffer, MAX_PATH, abs_path, &final))
- lstrcpyW(abs_path, buffer);
+ wcscpy(abs_path, buffer);
}
}
/* FIXME: This is even not enough - not all shell links can be resolved using this algorithm. */
if (!*abs_path)
- lstrcpyW(abs_path, sPathRel);
+ wcscpy(abs_path, sPathRel);
- *psPath = HeapAlloc(GetProcessHeap(), 0, (lstrlenW(abs_path)+1)*sizeof(WCHAR));
+ *psPath = HeapAlloc(GetProcessHeap(), 0, (wcslen(abs_path)+1)*sizeof(WCHAR));
if (!*psPath)
return E_OUTOFMEMORY;
- lstrcpyW(*psPath, abs_path);
+ wcscpy(*psPath, abs_path);
}
return S_OK;
hr = E_FAIL;
if (SUCCEEDED(hr))
- *ppv = (IUnknown*) psl;
+ *ppv = psl;
IPersistFile_Release(ppf);
}
TRACE("(%p)->(pfile=%p len=%u find_data=%p flags=%u)(%s)\n",
This, pszFile, cchMaxPath, pfd, fFlags, debugstr_w(This->sPath));
- if (This->sComponent || This->sProduct)
- return S_FALSE;
-
if (cchMaxPath)
pszFile[0] = 0;
if (This->sPath)
TRACE("(%p)->(pName=%s)\n", This, pszName);
HeapFree(GetProcessHeap(), 0, This->sDescription);
- This->sDescription = HEAP_strdupAtoW( GetProcessHeap(), 0, pszName);
- if ( !This->sDescription )
- return E_OUTOFMEMORY;
+ This->sDescription = NULL;
+ if ( pszName ) {
+ This->sDescription = HEAP_strdupAtoW( GetProcessHeap(), 0, pszName);
+ if ( !This->sDescription )
+ return E_OUTOFMEMORY;
+ }
This->bDirty = TRUE;
return S_OK;
TRACE("(%p)->(dir=%s)\n",This, pszDir);
HeapFree(GetProcessHeap(), 0, This->sWorkDir);
- This->sWorkDir = HEAP_strdupAtoW( GetProcessHeap(), 0, pszDir);
- if ( !This->sWorkDir )
- return E_OUTOFMEMORY;
+ This->sWorkDir = NULL;
+ if ( pszDir ) {
+ This->sWorkDir = HEAP_strdupAtoW( GetProcessHeap(), 0, pszDir);
+ if ( !This->sWorkDir )
+ return E_OUTOFMEMORY;
+ }
This->bDirty = TRUE;
return S_OK;
TRACE("(%p)->(args=%s)\n",This, pszArgs);
HeapFree(GetProcessHeap(), 0, This->sArgs);
- This->sArgs = HEAP_strdupAtoW( GetProcessHeap(), 0, pszArgs);
- if( !This->sArgs )
- return E_OUTOFMEMORY;
+ This->sArgs = NULL;
+
+ if ( pszArgs ) {
+ This->sArgs = HEAP_strdupAtoW( GetProcessHeap(), 0, pszArgs);
+ if( !This->sArgs )
+ return E_OUTOFMEMORY;
+ }
This->bDirty = TRUE;
if (SUCCEEDED(hr)) {
IExtractIconA* pei;
- hr = IShellFolder_GetUIObjectOf(psf, 0, 1, (LPCITEMIDLIST*)&pidlLast, &IID_IExtractIconA, NULL, (LPVOID*)&pei);
+ hr = IShellFolder_GetUIObjectOf(psf, 0, 1, &pidlLast, &IID_IExtractIconA, NULL, (LPVOID*)&pei);
if (SUCCEEDED(hr)) {
hr = IExtractIconA_GetIconLocation(pei, 0, pszIconPath, MAX_PATH, piIcon, NULL);
TRACE("(%p)->(path=%s iicon=%u)\n",This, pszIconPath, iIcon);
HeapFree(GetProcessHeap(), 0, This->sIcoPath);
- This->sIcoPath = HEAP_strdupAtoW(GetProcessHeap(), 0, pszIconPath);
- if ( !This->sIcoPath )
- return E_OUTOFMEMORY;
+ This->sIcoPath = NULL;
+
+ if ( pszIconPath ) {
+ This->sIcoPath = HEAP_strdupAtoW(GetProcessHeap(), 0, pszIconPath);
+ if ( !This->sIcoPath )
+ return E_OUTOFMEMORY;
+ }
This->iIcoNdx = iIcon;
This->bDirty = TRUE;
TRACE("(%p)->(path=%s %x)\n",This, pszPathRel, dwReserved);
HeapFree(GetProcessHeap(), 0, This->sPathRel);
- This->sPathRel = HEAP_strdupAtoW(GetProcessHeap(), 0, pszPathRel);
+ This->sPathRel = NULL;
+
+ if ( pszPathRel ) {
+ This->sPathRel = HEAP_strdupAtoW(GetProcessHeap(), 0, pszPathRel);
+
+ if ( !This->sPathRel )
+ return E_OUTOFMEMORY;
+ }
+
This->bDirty = TRUE;
return ShellLink_UpdatePath(This->sPathRel, This->sPath, This->sWorkDir, &This->sPath);
TRACE("(%p)->(path=%s)\n",This, pszFile);
+ if (!pszFile) return E_INVALIDARG;
+
str = HEAP_strdupAtoW(GetProcessHeap(), 0, pszFile);
if( !str )
return E_OUTOFMEMORY;
HeapFree(GetProcessHeap(), 0, This->sDescription);
This->sDescription = HeapAlloc( GetProcessHeap(), 0,
- (lstrlenW( pszName )+1)*sizeof(WCHAR) );
+ (wcslen( pszName )+1)*sizeof(WCHAR) );
if ( !This->sDescription )
return E_OUTOFMEMORY;
- lstrcpyW( This->sDescription, pszName );
+ wcscpy( This->sDescription, pszName );
This->bDirty = TRUE;
return S_OK;
HeapFree(GetProcessHeap(), 0, This->sWorkDir);
This->sWorkDir = HeapAlloc( GetProcessHeap(), 0,
- (lstrlenW( pszDir )+1)*sizeof (WCHAR) );
+ (wcslen( pszDir )+1)*sizeof (WCHAR) );
if ( !This->sWorkDir )
return E_OUTOFMEMORY;
- lstrcpyW( This->sWorkDir, pszDir );
+ wcscpy( This->sWorkDir, pszDir );
This->bDirty = TRUE;
return S_OK;
HeapFree(GetProcessHeap(), 0, This->sArgs);
This->sArgs = HeapAlloc( GetProcessHeap(), 0,
- (lstrlenW( pszArgs )+1)*sizeof (WCHAR) );
+ (wcslen( pszArgs )+1)*sizeof (WCHAR) );
if ( !This->sArgs )
return E_OUTOFMEMORY;
- lstrcpyW( This->sArgs, pszArgs );
+ wcscpy( This->sArgs, pszArgs );
This->bDirty = TRUE;
return S_OK;
if (SUCCEEDED(hr)) {
IExtractIconW* pei;
- hr = IShellFolder_GetUIObjectOf(psf, 0, 1, (LPCITEMIDLIST*)&pidlLast, &IID_IExtractIconW, NULL, (LPVOID*)&pei);
+ hr = IShellFolder_GetUIObjectOf(psf, 0, 1, &pidlLast, &IID_IExtractIconW, NULL, (LPVOID*)&pei);
if (SUCCEEDED(hr)) {
hr = IExtractIconW_GetIconLocation(pei, 0, pszIconPath, MAX_PATH, piIcon, &wFlags);
HeapFree(GetProcessHeap(), 0, This->sIcoPath);
This->sIcoPath = HeapAlloc( GetProcessHeap(), 0,
- (lstrlenW( pszIconPath )+1)*sizeof (WCHAR) );
+ (wcslen( pszIconPath )+1)*sizeof (WCHAR) );
if ( !This->sIcoPath )
return E_OUTOFMEMORY;
- lstrcpyW( This->sIcoPath, pszIconPath );
+ wcscpy( This->sIcoPath, pszIconPath );
This->iIcoNdx = iIcon;
This->bDirty = TRUE;
HeapFree(GetProcessHeap(), 0, This->sPathRel);
This->sPathRel = HeapAlloc( GetProcessHeap(), 0,
- (lstrlenW( pszPathRel )+1) * sizeof (WCHAR) );
+ (wcslen( pszPathRel )+1) * sizeof (WCHAR) );
if ( !This->sPathRel )
return E_OUTOFMEMORY;
- lstrcpyW( This->sPathRel, pszPathRel );
+ wcscpy( This->sPathRel, pszPathRel );
This->bDirty = TRUE;
return ShellLink_UpdatePath(This->sPathRel, This->sPath, This->sWorkDir, &This->sPath);
bSuccess = SHGetPathFromIDListW(This->pPidl, buffer);
if (bSuccess && *buffer) {
- This->sPath = HeapAlloc(GetProcessHeap(), 0, (lstrlenW(buffer)+1)*sizeof(WCHAR));
+ This->sPath = HeapAlloc(GetProcessHeap(), 0, (wcslen(buffer)+1)*sizeof(WCHAR));
if (!This->sPath)
return E_OUTOFMEMORY;
- lstrcpyW(This->sPath, buffer);
+ wcscpy(This->sPath, buffer);
This->bDirty = TRUE;
} else
}
if (!This->sIcoPath && This->sPath) {
- This->sIcoPath = HeapAlloc(GetProcessHeap(), 0, (lstrlenW(This->sPath)+1)*sizeof(WCHAR));
+ This->sIcoPath = HeapAlloc(GetProcessHeap(), 0, (wcslen(This->sPath)+1)*sizeof(WCHAR));
if (!This->sIcoPath)
return E_OUTOFMEMORY;
- lstrcpyW(This->sIcoPath, This->sPath);
+ wcscpy(This->sIcoPath, This->sPath);
This->iIcoNdx = 0;
This->bDirty = TRUE;
if( !str )
return NULL;
- p = strchrW( str, ':' );
+ p = wcschr( str, ':' );
if( !p )
return NULL;
len = p - str;
str += 2;
/* there must be a colon straight after a guid */
- p = strchrW( str, ':' );
+ p = wcschr( str, ':' );
if( !p )
return E_FAIL;
len = p - str;
return E_FAIL;
/* skip to the next field */
- str = strchrW( str, ':' );
+ str = wcschr( str, ':' );
if( !str )
return E_FAIL;
}
TRACE("(%p)->(path=%s)\n",This, debugstr_w(pszFile));
+ if (!pszFile) return E_INVALIDARG;
+
/* quotes at the ends of the string are stripped */
- len = lstrlenW(pszFile);
+ len = wcslen(pszFile);
if (pszFile[0] == '"' && pszFile[len-1] == '"')
{
unquoted = strdupW(pszFile);
}
/* any other quote marks are invalid */
- if (strchrW(pszFile, '"'))
+ if (wcschr(pszFile, '"'))
+ {
+ HeapFree(GetProcessHeap(), 0, unquoted);
return S_FALSE;
+ }
HeapFree(GetProcessHeap(), 0, This->sPath);
This->sPath = NULL;
ShellLink_GetVolumeInfo(buffer, &This->volume);
This->sPath = HeapAlloc( GetProcessHeap(), 0,
- (lstrlenW( buffer )+1) * sizeof (WCHAR) );
+ (wcslen( buffer )+1) * sizeof (WCHAR) );
if (!This->sPath)
return E_OUTOFMEMORY;
- lstrcpyW(This->sPath, buffer);
+ wcscpy(This->sPath, buffer);
}
This->bDirty = TRUE;
HeapFree(GetProcessHeap(), 0, unquoted);
flags |= SLDF_HAS_DARWINID;
if (This->sIcoPath)
flags |= SLDF_HAS_ICONLOCATION;
+#if (NTDDI_VERSION < NTDDI_LONGHORN)
if (This->sProduct)
flags |= SLDF_HAS_LOGO3ID;
+#endif
if (This->pPidl)
flags |= SLDF_HAS_ID_LIST;
UINT idCmdFirst, UINT idCmdLast, UINT uFlags )
{
IShellLinkImpl *This = impl_from_IContextMenu(iface);
- static WCHAR szOpen[] = { 'O','p','e','n',0 };
- static WCHAR szProperties[] = { 'P','r','o','p','e','r','t','i','e','s',0 };
+ WCHAR szOpen[20];
MENUITEMINFOW mii;
int id = 1;
if ( !hmenu )
return E_INVALIDARG;
+ if (!LoadStringW(shell32_hInstance, IDS_OPEN_VERB, szOpen, sizeof(szOpen)/sizeof(WCHAR)))
+ szOpen[0] = L'\0';
+ else
+ szOpen[(sizeof(szOpen)/sizeof(WCHAR))-1] = L'\0';
+
memset( &mii, 0, sizeof(mii) );
mii.cbSize = sizeof (mii);
mii.fMask = MIIM_TYPE | MIIM_ID | MIIM_STATE;
mii.dwTypeData = (LPWSTR)szOpen;
- mii.cch = strlenW( mii.dwTypeData );
+ mii.cch = wcslen( mii.dwTypeData );
mii.wID = idCmdFirst + id++;
mii.fState = MFS_DEFAULT | MFS_ENABLED;
mii.fType = MFT_STRING;
if (!InsertMenuItemW( hmenu, indexMenu, TRUE, &mii ))
return E_FAIL;
- This->iIdOpen = 0;
-
- mii.fState = MFS_ENABLED;
- mii.dwTypeData = (LPWSTR)szProperties;
- mii.cch = strlenW( mii.dwTypeData );
- mii.wID = idCmdFirst + id++;
- if (!InsertMenuItemW( hmenu, idCmdLast, TRUE, &mii ))
- {
- TRACE("ShellLink_QueryContextMenu failed to insert item properties");
- return E_FAIL;
- }
- This->iIdProperties = 1;
- id++;
+ This->iIdOpen = 1;
return MAKE_HRESULT( SEVERITY_SUCCESS, 0, id );
}
{
//FIXME load localized error msg
MessageBoxW( hwndDlg, L"file not existing", szBuffer, MB_OK );
- SetWindowLong( hwndDlg, DWL_MSGRESULT, PSNRET_INVALID_NOCHANGEPAGE );
+ SetWindowLongPtr( hwndDlg, DWL_MSGRESULT, PSNRET_INVALID_NOCHANGEPAGE );
return TRUE;
}
ptr = wcsrchr(szBuffer, L'.');
- if (ptr && !wcsnicmp(ptr, L".lnk", 4))
+ if (ptr && !_wcsnicmp(ptr, L".lnk", 4))
{
// FIXME load localized error msg
MessageBoxW( hwndDlg, L"You cannot create a link to a shortcut", L"Error", MB_ICONERROR );
- SetWindowLong( hwndDlg, DWL_MSGRESULT, PSNRET_INVALID_NOCHANGEPAGE );
+ SetWindowLongPtr( hwndDlg, DWL_MSGRESULT, PSNRET_INVALID_NOCHANGEPAGE );
return TRUE;
}
TRACE("This %p sLinkPath %S\n", This, This->sLinkPath);
IPersistFile_fnSave( (IPersistFile*)&This->lpvtblPersistFile, This->sLinkPath, TRUE );
- SetWindowLong( hwndDlg, DWL_MSGRESULT, PSNRET_NOERROR );
+ SetWindowLongPtr( hwndDlg, DWL_MSGRESULT, PSNRET_NOERROR );
return TRUE;
}
break;
///
return TRUE;
case 14021:
+ if (This->sIcoPath)
+ wcscpy(szBuffer, This->sIcoPath);
+ else
+ wcscpy(szBuffer, This->sPath);
+
+ IconIndex = This->iIcoNdx;
if (PickIconDlg(hwndDlg, szBuffer, MAX_PATH, &IconIndex))
{
IShellLinkW_fnSetIconLocation((IShellLinkW*)&This->lpvtblw, szBuffer, IconIndex);
}
/**************************************************************************
- * ShellLink_ShortcutDialog [Internal]
- *
- * creates a shortcut property dialog
+ * ShellLink_IShellPropSheetExt interface
*/
static HRESULT WINAPI
-ShellLink_ShowProperties( IShellLinkImpl *This )
+ ShellLink_IShellPropSheetExt_QueryInterface( IShellPropSheetExt* iface, REFIID riid, void** ppvObject )
{
- PROPSHEETHEADERW pinfo;
- HPROPSHEETPAGE hppages[MAX_PROPERTY_SHEET_PAGE];
- HPROPSHEETPAGE hpage;
- UINT numpages = 0;
+ IShellLinkImpl *This = impl_from_IShellPropSheetExt(iface);
+ return ShellLink_QueryInterface( This, riid, ppvObject );
+}
- TRACE("ShellLink_ShortcutDialog entered\n");
+static ULONG WINAPI
+ ShellLink_IShellPropSheetExt_AddRef( IShellPropSheetExt* iface )
+{
+ IShellLinkImpl *This = impl_from_IShellPropSheetExt(iface);
+ return ShellLink_AddRef( This );
+}
- memset(hppages, 0x0, sizeof(HPROPSHEETPAGE) * MAX_PROPERTY_SHEET_PAGE);
+static ULONG WINAPI
+ ShellLink_IShellPropSheetExt_Release( IShellPropSheetExt* iface )
+{
+ IShellLinkImpl *This = impl_from_IShellPropSheetExt(iface);
+ return ShellLink_Release( This );
+}
- hpage = SH_CreatePropertySheetPage("SHELL_FILE_GENERAL_DLG", SH_FileGeneralDlgProc, (LPARAM)This->sLinkPath, NULL);
- if ( hpage == NULL )
- return E_FAIL;
- else
- hppages[numpages++] = hpage;
+static HRESULT WINAPI
+ ShellLink_IShellPropSheetExt_AddPages( IShellPropSheetExt *iface, LPFNADDPROPSHEETPAGE pfnAddPage, LPARAM lParam)
+{
+ HPROPSHEETPAGE hPage;
+ BOOL bRet;
+ IShellLinkImpl *This = impl_from_IShellPropSheetExt(iface);
- hpage = SH_CreatePropertySheetPage("SHELL_GENERAL_SHORTCUT_DLG", SH_ShellLinkDlgProc, (LPARAM)This, NULL);
- if ( hpage == NULL )
+ hPage = SH_CreatePropertySheetPage("SHELL_GENERAL_SHORTCUT_DLG", SH_ShellLinkDlgProc, (LPARAM)This, NULL);
+ if (hPage == NULL)
{
- ERR("SH_CreatePropertySheetPage failed\n");
- DestroyPropertySheetPage(hppages[0]);
- return E_FAIL;
- }
- hppages[numpages++] = hpage;
-
- ///FIXME
- /// load extensions
+ ERR("failed to create property sheet page\n");
+ return E_FAIL;
+ }
- memset(&pinfo, 0x0, sizeof(PROPSHEETHEADERW));
- pinfo.dwSize = sizeof(PROPSHEETHEADERW);
- pinfo.dwFlags = PSH_NOCONTEXTHELP | PSH_PROPTITLE;
- pinfo.nPages = numpages;
- pinfo.u3.phpage = hppages;
- pinfo.pszCaption = This->sDescription;
- pinfo.u2.nStartPage = 1;
+ bRet = pfnAddPage(hPage, lParam);
+ if (bRet)
+ return S_OK;
+ else
+ return E_FAIL;
+}
- if ( PropertySheetW(&pinfo) < 0 )
- return E_FAIL;
- else
- return S_OK;
+static HRESULT WINAPI
+ ShellLink_IShellPropSheetExt_ReplacePages( IShellPropSheetExt *iface, UINT uPageID, LPFNADDPROPSHEETPAGE pfnReplacePage, LPARAM lParam)
+{
+ IShellLinkImpl *This = impl_from_IShellPropSheetExt(iface);
+ TRACE("(%p) (uPageID %u, pfnReplacePage %p lParam %p\n", This, uPageID, pfnReplacePage, lParam);
+ return E_NOTIMPL;
}
+static const IShellPropSheetExtVtbl pse =
+{
+ ShellLink_IShellPropSheetExt_QueryInterface,
+ ShellLink_IShellPropSheetExt_AddRef,
+ ShellLink_IShellPropSheetExt_Release,
+ ShellLink_IShellPropSheetExt_AddPages,
+ ShellLink_IShellPropSheetExt_ReplacePages
+};
+
static HRESULT WINAPI
ShellLink_InvokeCommand( IContextMenu* iface, LPCMINVOKECOMMANDINFO lpici )
{
IShellLinkImpl *This = impl_from_IContextMenu(iface);
- static const WCHAR szOpen[] = { 'O','p','e','n',0 };
+ static const WCHAR szOpen[] = { 'o','p','e','n',0 };
+ static const WCHAR szCplOpen[] = { 'c','p','l','o','p','e','n',0 };
SHELLEXECUTEINFOW sei;
HWND hwnd = NULL; /* FIXME: get using interface set from IObjectWithSite */
LPWSTR args = NULL;
if ( lpici->cbSize < sizeof (CMINVOKECOMMANDINFO) )
return E_INVALIDARG;
- if ( lpici->lpVerb == MAKEINTRESOURCEA(This->iIdProperties))
- {
- ShellLink_ShowProperties(This);
- return S_OK;
- }
-
- if ( lpici->lpVerb != MAKEINTRESOURCEA(This->iIdOpen) )
- {
- ERR("Unknown id %d != %d\n", (INT)lpici->lpVerb, This->iIdOpen );
- return E_INVALIDARG;
- }
-
r = IShellLinkW_Resolve( (IShellLinkW*)&(This->lpvtblw), hwnd, 0 );
if ( FAILED( r ) )
+ {
+ TRACE("failed to resolve component with error 0x%08x", r);
return r;
-
+ }
if ( This->sComponent )
{
path = shelllink_get_msi_component_path( This->sComponent );
DWORD len = 2;
if ( This->sArgs )
- len += lstrlenW( This->sArgs );
+ len += wcslen( This->sArgs );
if ( iciex->lpParametersW )
- len += lstrlenW( iciex->lpParametersW );
+ len += wcslen( iciex->lpParametersW );
args = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
args[0] = 0;
if ( This->sArgs )
- lstrcatW( args, This->sArgs );
+ wcscat( args, This->sArgs );
if ( iciex->lpParametersW )
{
static const WCHAR space[] = { ' ', 0 };
- lstrcatW( args, space );
- lstrcatW( args, iciex->lpParametersW );
+ wcscat( args, space );
+ wcscat( args, iciex->lpParametersW );
}
}
+ else if (This->sArgs != NULL)
+ {
+ args = strdupW( This->sArgs );
+ }
memset( &sei, 0, sizeof sei );
sei.cbSize = sizeof sei;
- sei.fMask = SEE_MASK_UNICODE | SEE_MASK_NOCLOSEPROCESS;
+ sei.fMask = SEE_MASK_UNICODE | (lpici->fMask & (SEE_MASK_NOASYNC|SEE_MASK_ASYNCOK|SEE_MASK_FLAG_NO_UI));
sei.lpFile = path;
sei.nShow = This->iShowCmd;
- sei.lpIDList = This->pPidl;
sei.lpDirectory = This->sWorkDir;
sei.lpParameters = args;
sei.lpVerb = szOpen;
+ // HACK for ShellExecuteExW
+ if (!wcsstr(This->sPath, L".cpl"))
+ sei.lpVerb = szOpen;
+ else
+ sei.lpVerb = szCplOpen;
+
if( ShellExecuteExW( &sei ) )
r = S_OK;
else