[FORMATTING]

* No code changes.

svn path=/branches/shell32_new-bringup/; revision=53546
This commit is contained in:
Amine Khaldi 2011-09-03 15:37:09 +00:00
parent 8af812d602
commit 26f6b8c7f7
4 changed files with 580 additions and 586 deletions

View file

@ -47,45 +47,45 @@ WINE_DEFAULT_DEBUG_CHANNEL(shell);
struct LINK_HEADER struct LINK_HEADER
{ {
DWORD dwSize; /* 0x00 size of the header - 0x4c */ DWORD dwSize; /* 0x00 size of the header - 0x4c */
GUID MagicGuid; /* 0x04 is CLSID_ShellLink */ GUID MagicGuid; /* 0x04 is CLSID_ShellLink */
DWORD dwFlags; /* 0x14 describes elements following */ DWORD dwFlags; /* 0x14 describes elements following */
DWORD dwFileAttr; /* 0x18 attributes of the target file */ DWORD dwFileAttr; /* 0x18 attributes of the target file */
FILETIME Time1; /* 0x1c */ FILETIME Time1; /* 0x1c */
FILETIME Time2; /* 0x24 */ FILETIME Time2; /* 0x24 */
FILETIME Time3; /* 0x2c */ FILETIME Time3; /* 0x2c */
DWORD dwFileLength; /* 0x34 File length */ DWORD dwFileLength; /* 0x34 File length */
DWORD nIcon; /* 0x38 icon number */ DWORD nIcon; /* 0x38 icon number */
DWORD fStartup; /* 0x3c startup type */ DWORD fStartup; /* 0x3c startup type */
DWORD wHotKey; /* 0x40 hotkey */ DWORD wHotKey; /* 0x40 hotkey */
DWORD Unknown5; /* 0x44 */ DWORD Unknown5; /* 0x44 */
DWORD Unknown6; /* 0x48 */ DWORD Unknown6; /* 0x48 */
}; };
struct LOCATION_INFO struct LOCATION_INFO
{ {
DWORD dwTotalSize; DWORD dwTotalSize;
DWORD dwHeaderSize; DWORD dwHeaderSize;
DWORD dwFlags; DWORD dwFlags;
DWORD dwVolTableOfs; DWORD dwVolTableOfs;
DWORD dwLocalPathOfs; DWORD dwLocalPathOfs;
DWORD dwNetworkVolTableOfs; DWORD dwNetworkVolTableOfs;
DWORD dwFinalPathOfs; DWORD dwFinalPathOfs;
}; };
struct LOCAL_VOLUME_INFO struct LOCAL_VOLUME_INFO
{ {
DWORD dwSize; DWORD dwSize;
DWORD dwType; DWORD dwType;
DWORD dwVolSerial; DWORD dwVolSerial;
DWORD dwVolLabelOfs; DWORD dwVolLabelOfs;
}; };
struct volume_info struct volume_info
{ {
DWORD type; DWORD type;
DWORD serial; DWORD serial;
WCHAR label[12]; /* assume 8.3 */ WCHAR label[12]; /* assume 8.3 */
}; };
#include "poppack.h" #include "poppack.h"
@ -122,26 +122,26 @@ static LPWSTR __inline strdupW( LPCWSTR src )
ShellLink::ShellLink() ShellLink::ShellLink()
{ {
pPidl = NULL; pPidl = NULL;
wHotKey = 0; wHotKey = 0;
memset(&time1, 0, sizeof(time1)); memset(&time1, 0, sizeof(time1));
memset(&time2, 0, sizeof(time2)); memset(&time2, 0, sizeof(time2));
memset(&time3, 0, sizeof(time3)); memset(&time3, 0, sizeof(time3));
iShowCmd = SW_SHOWNORMAL; iShowCmd = SW_SHOWNORMAL;
sIcoPath = NULL; sIcoPath = NULL;
iIcoNdx = 0; iIcoNdx = 0;
sPath = NULL; sPath = NULL;
sArgs = NULL; sArgs = NULL;
sWorkDir = NULL; sWorkDir = NULL;
sDescription = NULL; sDescription = NULL;
sPathRel = NULL; sPathRel = NULL;
sProduct = NULL; sProduct = NULL;
sComponent = NULL; sComponent = NULL;
memset(&volume, 0, sizeof(volume)); memset(&volume, 0, sizeof(volume));
sLinkPath = NULL; sLinkPath = NULL;
bRunAs = FALSE; bRunAs = FALSE;
bDirty = FALSE; bDirty = FALSE;
iIdOpen = -1; iIdOpen = -1;
} }
ShellLink::~ShellLink() ShellLink::~ShellLink()
@ -163,42 +163,42 @@ HRESULT WINAPI ShellLink::GetClassID(CLSID *pclsid )
{ {
TRACE("%p %p\n", this, pclsid); TRACE("%p %p\n", this, pclsid);
if (pclsid == NULL) if (pclsid == NULL)
return E_POINTER; return E_POINTER;
*pclsid = CLSID_ShellLink; *pclsid = CLSID_ShellLink;
return S_OK; return S_OK;
} }
HRESULT WINAPI ShellLink::IsDirty() HRESULT WINAPI ShellLink::IsDirty()
{ {
TRACE("(%p)\n",this); TRACE("(%p)\n",this);
if (bDirty) if (bDirty)
return S_OK; return S_OK;
return S_FALSE; return S_FALSE;
} }
HRESULT WINAPI ShellLink::Load(LPCOLESTR pszFileName, DWORD dwMode) HRESULT WINAPI ShellLink::Load(LPCOLESTR pszFileName, DWORD dwMode)
{ {
HRESULT r; HRESULT r;
CComPtr<IStream> stm; CComPtr<IStream> stm;
TRACE("(%p, %s, %x)\n",this, debugstr_w(pszFileName), dwMode); TRACE("(%p, %s, %x)\n",this, debugstr_w(pszFileName), dwMode);
if (dwMode == 0) if (dwMode == 0)
dwMode = STGM_READ | STGM_SHARE_DENY_WRITE; dwMode = STGM_READ | STGM_SHARE_DENY_WRITE;
r = SHCreateStreamOnFileW(pszFileName, dwMode, &stm); r = SHCreateStreamOnFileW(pszFileName, dwMode, &stm);
if (SUCCEEDED(r)) if (SUCCEEDED(r))
{ {
HeapFree(GetProcessHeap(), 0, sLinkPath); HeapFree(GetProcessHeap(), 0, sLinkPath);
sLinkPath = strdupW(pszFileName); sLinkPath = strdupW(pszFileName);
r = Load(stm); r = Load(stm);
ShellLink_UpdatePath(sPathRel, pszFileName, sWorkDir, &sPath); ShellLink_UpdatePath(sPathRel, pszFileName, sWorkDir, &sPath);
bDirty = FALSE; bDirty = FALSE;
} }
TRACE("-- returning hr %08x\n", r); TRACE("-- returning hr %08x\n", r);
return r; return r;
} }
static BOOL StartLinkProcessor( LPCOLESTR szLink ) static BOOL StartLinkProcessor( LPCOLESTR szLink )
@ -239,21 +239,21 @@ static BOOL StartLinkProcessor( LPCOLESTR szLink )
HRESULT WINAPI ShellLink::Save(LPCOLESTR pszFileName, BOOL fRemember) HRESULT WINAPI ShellLink::Save(LPCOLESTR pszFileName, BOOL fRemember)
{ {
HRESULT r; HRESULT r;
CComPtr<IStream> stm; CComPtr<IStream> stm;
TRACE("(%p)->(%s)\n", this, debugstr_w(pszFileName)); TRACE("(%p)->(%s)\n", this, debugstr_w(pszFileName));
if (!pszFileName) if (!pszFileName)
return E_FAIL; return E_FAIL;
r = SHCreateStreamOnFileW( pszFileName, STGM_READWRITE | STGM_CREATE | STGM_SHARE_EXCLUSIVE, &stm ); r = SHCreateStreamOnFileW( pszFileName, STGM_READWRITE | STGM_CREATE | STGM_SHARE_EXCLUSIVE, &stm );
if( SUCCEEDED( r ) ) if( SUCCEEDED( r ) )
{ {
r = Save(stm, FALSE); r = Save(stm, FALSE);
if( SUCCEEDED( r ) ) if( SUCCEEDED( r ) )
{ {
if ( sLinkPath ) if ( sLinkPath )
{ {
HeapFree(GetProcessHeap(), 0, sLinkPath); HeapFree(GetProcessHeap(), 0, sLinkPath);
@ -264,24 +264,24 @@ HRESULT WINAPI ShellLink::Save(LPCOLESTR pszFileName, BOOL fRemember)
wcscpy(sLinkPath, pszFileName); wcscpy(sLinkPath, pszFileName);
} }
StartLinkProcessor( pszFileName ); StartLinkProcessor( pszFileName );
bDirty = FALSE; bDirty = FALSE;
} }
else else
{ {
DeleteFileW( pszFileName ); DeleteFileW( pszFileName );
WARN("Failed to create shortcut %s\n", debugstr_w(pszFileName) ); WARN("Failed to create shortcut %s\n", debugstr_w(pszFileName) );
} }
} }
return r; return r;
} }
HRESULT WINAPI ShellLink::SaveCompleted(LPCOLESTR pszFileName) HRESULT WINAPI ShellLink::SaveCompleted(LPCOLESTR pszFileName)
{ {
FIXME("(%p)->(%s)\n", this, debugstr_w(pszFileName)); FIXME("(%p)->(%s)\n", this, debugstr_w(pszFileName));
return NOERROR; return NOERROR;
} }
HRESULT WINAPI ShellLink::GetCurFile(LPOLESTR *ppszFileName) HRESULT WINAPI ShellLink::GetCurFile(LPOLESTR *ppszFileName)
@ -442,7 +442,7 @@ static LPWSTR Stream_LoadPath( LPCSTR p, DWORD maxlen )
} }
static HRESULT Stream_LoadLocation( IStream *stm, static HRESULT Stream_LoadLocation( IStream *stm,
ShellLink::volume_info *volume, LPWSTR *path ) ShellLink::volume_info *volume, LPWSTR *path )
{ {
char *p = NULL; char *p = NULL;
LOCATION_INFO *loc; LOCATION_INFO *loc;
@ -922,9 +922,9 @@ HRESULT WINAPI ShellLink::Save(IStream *stm, BOOL fClearDirty)
*/ */
HRESULT WINAPI ShellLink::GetSizeMax(ULARGE_INTEGER *pcbSize) HRESULT WINAPI ShellLink::GetSizeMax(ULARGE_INTEGER *pcbSize)
{ {
TRACE("(%p)\n", this); TRACE("(%p)\n", this);
return E_NOTIMPL; return E_NOTIMPL;
} }
static BOOL SHELL_ExistsFileW(LPCWSTR path) static BOOL SHELL_ExistsFileW(LPCWSTR path)
@ -936,50 +936,50 @@ static BOOL SHELL_ExistsFileW(LPCWSTR path)
/************************************************************************** /**************************************************************************
* ShellLink_UpdatePath * ShellLink_UpdatePath
* update absolute path in sPath using relative path in sPathRel * update absolute path in sPath using relative path in sPathRel
*/ */
static HRESULT ShellLink_UpdatePath(LPCWSTR sPathRel, LPCWSTR path, LPCWSTR sWorkDir, LPWSTR* psPath) static HRESULT ShellLink_UpdatePath(LPCWSTR sPathRel, LPCWSTR path, LPCWSTR sWorkDir, LPWSTR* psPath)
{ {
if (!path || !psPath) if (!path || !psPath)
return E_INVALIDARG; return E_INVALIDARG;
if (!*psPath && sPathRel) { if (!*psPath && sPathRel) {
WCHAR buffer[2*MAX_PATH], abs_path[2*MAX_PATH]; WCHAR buffer[2*MAX_PATH], abs_path[2*MAX_PATH];
LPWSTR final = NULL; LPWSTR final = NULL;
/* first try if [directory of link file] + [relative path] finds an existing file */ /* first try if [directory of link file] + [relative path] finds an existing file */
GetFullPathNameW( path, MAX_PATH*2, buffer, &final ); GetFullPathNameW( path, MAX_PATH*2, buffer, &final );
if( !final ) if( !final )
final = buffer; final = buffer;
wcscpy(final, sPathRel); wcscpy(final, sPathRel);
*abs_path = '\0'; *abs_path = '\0';
if (SHELL_ExistsFileW(buffer)) { if (SHELL_ExistsFileW(buffer)) {
if (!GetFullPathNameW(buffer, MAX_PATH, abs_path, &final)) if (!GetFullPathNameW(buffer, MAX_PATH, abs_path, &final))
wcscpy(abs_path, buffer); wcscpy(abs_path, buffer);
} else { } else {
/* try if [working directory] + [relative path] finds an existing file */ /* try if [working directory] + [relative path] finds an existing file */
if (sWorkDir) { if (sWorkDir) {
wcscpy(buffer, sWorkDir); wcscpy(buffer, sWorkDir);
wcscpy(PathAddBackslashW(buffer), sPathRel); wcscpy(PathAddBackslashW(buffer), sPathRel);
if (SHELL_ExistsFileW(buffer)) if (SHELL_ExistsFileW(buffer))
if (!GetFullPathNameW(buffer, MAX_PATH, abs_path, &final)) if (!GetFullPathNameW(buffer, MAX_PATH, abs_path, &final))
wcscpy(abs_path, buffer); wcscpy(abs_path, buffer);
} }
} }
/* FIXME: This is even not enough - not all shell links can be resolved using this algorithm. */ /* FIXME: This is even not enough - not all shell links can be resolved using this algorithm. */
if (!*abs_path) if (!*abs_path)
wcscpy(abs_path, sPathRel); wcscpy(abs_path, sPathRel);
*psPath = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, (wcslen(abs_path)+1)*sizeof(WCHAR)); *psPath = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, (wcslen(abs_path)+1)*sizeof(WCHAR));
if (!*psPath) if (!*psPath)
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
wcscpy(*psPath, abs_path); wcscpy(*psPath, abs_path);
} }
return S_OK; return S_OK;
@ -1010,7 +1010,7 @@ HRESULT WINAPI ShellLink::GetIDList(LPITEMIDLIST * ppidl)
if (!pPidl) if (!pPidl)
{ {
*ppidl = NULL; *ppidl = NULL;
return S_FALSE; return S_FALSE;
} }
*ppidl = ILClone(pPidl); *ppidl = ILClone(pPidl);
@ -1040,7 +1040,7 @@ HRESULT WINAPI ShellLink::GetDescription(LPSTR pszName,INT cchMaxName)
pszName[0] = 0; pszName[0] = 0;
if( sDescription ) if( sDescription )
WideCharToMultiByte( CP_ACP, 0, sDescription, -1, WideCharToMultiByte( CP_ACP, 0, sDescription, -1,
pszName, cchMaxName, NULL, NULL); pszName, cchMaxName, NULL, NULL);
return S_OK; return S_OK;
} }
@ -1167,15 +1167,15 @@ static HRESULT SHELL_PidlGeticonLocationA(IShellFolder* psf, LPCITEMIDLIST pidl,
HRESULT hr = SHBindToParent(pidl, IID_IShellFolder, (LPVOID*)&psf, &pidlLast); HRESULT hr = SHBindToParent(pidl, IID_IShellFolder, (LPVOID*)&psf, &pidlLast);
if (SUCCEEDED(hr)) { if (SUCCEEDED(hr)) {
CComPtr<IExtractIconA> pei; CComPtr<IExtractIconA> pei;
hr = psf->GetUIObjectOf(0, 1, &pidlLast, IID_IExtractIconA, NULL, (LPVOID*)&pei); hr = psf->GetUIObjectOf(0, 1, &pidlLast, IID_IExtractIconA, NULL, (LPVOID*)&pei);
if (SUCCEEDED(hr)) { if (SUCCEEDED(hr)) {
hr = pei->GetIconLocation(0, pszIconPath, MAX_PATH, piIcon, NULL); hr = pei->GetIconLocation(0, pszIconPath, MAX_PATH, piIcon, NULL);
} }
psf->Release(); psf->Release();
} }
return hr; return hr;
@ -1191,40 +1191,40 @@ HRESULT WINAPI ShellLink::GetIconLocation(LPSTR pszIconPath,INT cchIconPath,INT
if (sIcoPath) if (sIcoPath)
{ {
WideCharToMultiByte(CP_ACP, 0, sIcoPath, -1, pszIconPath, cchIconPath, NULL, NULL); WideCharToMultiByte(CP_ACP, 0, sIcoPath, -1, pszIconPath, cchIconPath, NULL, NULL);
return S_OK; return S_OK;
} }
if (pPidl || sPath) if (pPidl || sPath)
{ {
CComPtr<IShellFolder> pdsk; CComPtr<IShellFolder> pdsk;
HRESULT hr = SHGetDesktopFolder(&pdsk); HRESULT hr = SHGetDesktopFolder(&pdsk);
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
/* first look for an icon using the PIDL (if present) */ /* first look for an icon using the PIDL (if present) */
if (pPidl) if (pPidl)
hr = SHELL_PidlGeticonLocationA(pdsk, pPidl, pszIconPath, cchIconPath, piIcon); hr = SHELL_PidlGeticonLocationA(pdsk, pPidl, pszIconPath, cchIconPath, piIcon);
else else
hr = E_FAIL; hr = E_FAIL;
/* if we couldn't find an icon yet, look for it using the file system path */ /* if we couldn't find an icon yet, look for it using the file system path */
if (FAILED(hr) && sPath) if (FAILED(hr) && sPath)
{ {
LPITEMIDLIST pidl; LPITEMIDLIST pidl;
hr = pdsk->ParseDisplayName(0, NULL, sPath, NULL, &pidl, NULL); hr = pdsk->ParseDisplayName(0, NULL, sPath, NULL, &pidl, NULL);
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
hr = SHELL_PidlGeticonLocationA(pdsk, pidl, pszIconPath, cchIconPath, piIcon); hr = SHELL_PidlGeticonLocationA(pdsk, pidl, pszIconPath, cchIconPath, piIcon);
SHFree(pidl); SHFree(pidl);
} }
} }
} }
return hr; return hr;
} }
return S_OK; return S_OK;
} }
@ -1276,36 +1276,36 @@ HRESULT WINAPI ShellLink::Resolve(HWND hwnd, DWORD fFlags)
if (!sPath && pPidl) if (!sPath && pPidl)
{ {
WCHAR buffer[MAX_PATH]; WCHAR buffer[MAX_PATH];
bSuccess = SHGetPathFromIDListW(pPidl, buffer); bSuccess = SHGetPathFromIDListW(pPidl, buffer);
if (bSuccess && *buffer) if (bSuccess && *buffer)
{ {
sPath = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, (wcslen(buffer)+1)*sizeof(WCHAR)); sPath = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, (wcslen(buffer)+1)*sizeof(WCHAR));
if (!sPath) if (!sPath)
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
wcscpy(sPath, buffer); wcscpy(sPath, buffer);
bDirty = TRUE; bDirty = TRUE;
} }
else else
hr = S_OK; /* don't report an error occurred while just caching information */ hr = S_OK; /* don't report an error occurred while just caching information */
} }
if (!sIcoPath && sPath) if (!sIcoPath && sPath)
{ {
sIcoPath = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, (wcslen(sPath)+1)*sizeof(WCHAR)); sIcoPath = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, (wcslen(sPath)+1)*sizeof(WCHAR));
if (!sIcoPath) if (!sIcoPath)
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
wcscpy(sIcoPath, sPath); wcscpy(sIcoPath, sPath);
iIcoNdx = 0; iIcoNdx = 0;
bDirty = TRUE; bDirty = TRUE;
} }
return hr; return hr;
@ -1317,8 +1317,8 @@ HRESULT WINAPI ShellLink::SetPath(LPCSTR pszFile)
LPWSTR str; LPWSTR str;
TRACE("(%p)->(path=%s)\n",this, pszFile); TRACE("(%p)->(path=%s)\n",this, pszFile);
if (pszFile == NULL) if (pszFile == NULL)
return E_INVALIDARG; return E_INVALIDARG;
str = HEAP_strdupAtoW(GetProcessHeap(), 0, pszFile); str = HEAP_strdupAtoW(GetProcessHeap(), 0, pszFile);
if (!str) if (!str)
@ -1439,15 +1439,15 @@ static HRESULT SHELL_PidlGeticonLocationW(IShellFolder* psf, LPCITEMIDLIST pidl,
HRESULT hr = SHBindToParent(pidl, IID_IShellFolder, (LPVOID*)&psf, &pidlLast); HRESULT hr = SHBindToParent(pidl, IID_IShellFolder, (LPVOID*)&psf, &pidlLast);
if (SUCCEEDED(hr)) { if (SUCCEEDED(hr)) {
CComPtr<IExtractIconW> pei; CComPtr<IExtractIconW> pei;
hr = psf->GetUIObjectOf(0, 1, &pidlLast, IID_IExtractIconW, NULL, (LPVOID*)&pei); hr = psf->GetUIObjectOf(0, 1, &pidlLast, IID_IExtractIconW, NULL, (LPVOID*)&pei);
if (SUCCEEDED(hr)) { if (SUCCEEDED(hr)) {
hr = pei->GetIconLocation(0, pszIconPath, MAX_PATH, piIcon, &wFlags); hr = pei->GetIconLocation(0, pszIconPath, MAX_PATH, piIcon, &wFlags);
} }
psf->Release(); psf->Release();
} }
return hr; return hr;
@ -1462,40 +1462,40 @@ HRESULT WINAPI ShellLink::GetIconLocation(LPWSTR pszIconPath,INT cchIconPath,INT
if (sIcoPath) if (sIcoPath)
{ {
lstrcpynW(pszIconPath, sIcoPath, cchIconPath); lstrcpynW(pszIconPath, sIcoPath, cchIconPath);
return S_OK; return S_OK;
} }
if (pPidl || sPath) if (pPidl || sPath)
{ {
CComPtr<IShellFolder> pdsk; CComPtr<IShellFolder> pdsk;
HRESULT hr = SHGetDesktopFolder(&pdsk); HRESULT hr = SHGetDesktopFolder(&pdsk);
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
/* first look for an icon using the PIDL (if present) */ /* first look for an icon using the PIDL (if present) */
if (pPidl) if (pPidl)
hr = SHELL_PidlGeticonLocationW(pdsk, pPidl, pszIconPath, cchIconPath, piIcon); hr = SHELL_PidlGeticonLocationW(pdsk, pPidl, pszIconPath, cchIconPath, piIcon);
else else
hr = E_FAIL; hr = E_FAIL;
/* if we couldn't find an icon yet, look for it using the file system path */ /* if we couldn't find an icon yet, look for it using the file system path */
if (FAILED(hr) && sPath) if (FAILED(hr) && sPath)
{ {
LPITEMIDLIST pidl; LPITEMIDLIST pidl;
hr = pdsk->ParseDisplayName(0, NULL, sPath, NULL, &pidl, NULL); hr = pdsk->ParseDisplayName(0, NULL, sPath, NULL, &pidl, NULL);
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
hr = SHELL_PidlGeticonLocationW(pdsk, pidl, pszIconPath, cchIconPath, piIcon); hr = SHELL_PidlGeticonLocationW(pdsk, pidl, pszIconPath, cchIconPath, piIcon);
SHFree(pidl); SHFree(pidl);
} }
} }
} }
return hr; return hr;
} }
return S_OK; return S_OK;
} }
@ -1523,7 +1523,7 @@ HRESULT WINAPI ShellLink::SetRelativePath(LPCWSTR pszPathRel, DWORD dwReserved)
HeapFree(GetProcessHeap(), 0, sPathRel); HeapFree(GetProcessHeap(), 0, sPathRel);
sPathRel = (LPWSTR)HeapAlloc( GetProcessHeap(), 0, sPathRel = (LPWSTR)HeapAlloc( GetProcessHeap(), 0,
(wcslen( pszPathRel )+1) * sizeof (WCHAR) ); (wcslen( pszPathRel )+1) * sizeof (WCHAR) );
if ( !sPathRel ) if ( !sPathRel )
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
wcscpy( sPathRel, pszPathRel ); wcscpy( sPathRel, pszPathRel );
@ -1670,10 +1670,10 @@ HRESULT WINAPI ShellLink::SetPath(LPCWSTR pszFile)
if (*pszFile == '\0') if (*pszFile == '\0')
*buffer = '\0'; *buffer = '\0';
else if (!GetFullPathNameW(pszFile, MAX_PATH, buffer, &fname)) else if (!GetFullPathNameW(pszFile, MAX_PATH, buffer, &fname))
return E_FAIL; return E_FAIL;
else if(!PathFileExistsW(buffer) && else if(!PathFileExistsW(buffer) &&
!SearchPathW(NULL, pszFile, NULL, MAX_PATH, buffer, NULL)) !SearchPathW(NULL, pszFile, NULL, MAX_PATH, buffer, NULL))
hr = S_FALSE; hr = S_FALSE;
pPidl = SHSimpleIDListFromPathW(pszFile); pPidl = SHSimpleIDListFromPathW(pszFile);
ShellLink_GetVolumeInfo(buffer, &volume); ShellLink_GetVolumeInfo(buffer, &volume);
@ -1706,21 +1706,21 @@ HRESULT WINAPI ShellLink::CopyDataBlock(DWORD dwSig, void** ppDataBlock )
switch (dwSig) switch (dwSig)
{ {
case EXP_DARWIN_ID_SIG: case EXP_DARWIN_ID_SIG:
if (!sComponent) if (!sComponent)
break;
block = shelllink_build_darwinid( sComponent, dwSig );
r = S_OK;
break; break;
block = shelllink_build_darwinid( sComponent, dwSig ); case EXP_SZ_LINK_SIG:
r = S_OK; case NT_CONSOLE_PROPS_SIG:
break; case NT_FE_CONSOLE_PROPS_SIG:
case EXP_SZ_LINK_SIG: case EXP_SPECIAL_FOLDER_SIG:
case NT_CONSOLE_PROPS_SIG: case EXP_SZ_ICON_SIG:
case NT_FE_CONSOLE_PROPS_SIG: FIXME("valid but unhandled datablock %08x\n", dwSig);
case EXP_SPECIAL_FOLDER_SIG: break;
case EXP_SZ_ICON_SIG: default:
FIXME("valid but unhandled datablock %08x\n", dwSig); ERR("unknown datablock %08x\n", dwSig);
break;
default:
ERR("unknown datablock %08x\n", dwSig);
} }
*ppDataBlock = block; *ppDataBlock = block;
return r; return r;
@ -1955,47 +1955,42 @@ HRESULT WINAPI ShellLink::GetCommandString(UINT_PTR idCmd, UINT uType, UINT* pwR
return E_NOTIMPL; return E_NOTIMPL;
} }
INT_PTR CALLBACK ExtendedShortcutProc( INT_PTR CALLBACK ExtendedShortcutProc(HWND hwndDlg, UINT uMsg,
HWND hwndDlg, WPARAM wParam, LPARAM lParam)
UINT uMsg,
WPARAM wParam,
LPARAM lParam
)
{ {
HWND hDlgCtrl; HWND hDlgCtrl;
switch(uMsg) switch(uMsg)
{ {
case WM_INITDIALOG: case WM_INITDIALOG:
if (lParam) if (lParam)
{ {
hDlgCtrl = GetDlgItem(hwndDlg, 14000);
SendMessage(hDlgCtrl, BM_SETCHECK, BST_CHECKED, 0);
}
return TRUE;
case WM_COMMAND:
hDlgCtrl = GetDlgItem(hwndDlg, 14000); hDlgCtrl = GetDlgItem(hwndDlg, 14000);
SendMessage(hDlgCtrl, BM_SETCHECK, BST_CHECKED, 0); if (LOWORD(wParam) == IDOK)
} {
return TRUE; if ( SendMessage(hDlgCtrl, BM_GETCHECK, 0, 0) == BST_CHECKED )
case WM_COMMAND: EndDialog(hwndDlg, 1);
hDlgCtrl = GetDlgItem(hwndDlg, 14000); else
if (LOWORD(wParam) == IDOK) EndDialog(hwndDlg, 0);
{ }
if ( SendMessage(hDlgCtrl, BM_GETCHECK, 0, 0) == BST_CHECKED ) else if (LOWORD(wParam) == IDCANCEL)
EndDialog(hwndDlg, 1); {
else EndDialog(hwndDlg, -1);
EndDialog(hwndDlg, 0); }
} else if (LOWORD(wParam) == 14000)
else if (LOWORD(wParam) == IDCANCEL) {
{ if ( SendMessage(hDlgCtrl, BM_GETCHECK, 0, 0) == BST_CHECKED)
EndDialog(hwndDlg, -1); SendMessage(hDlgCtrl, BM_SETCHECK, BST_UNCHECKED, 0);
} else
else if (LOWORD(wParam) == 14000) SendMessage(hDlgCtrl, BM_SETCHECK, BST_CHECKED, 0);
{ }
if ( SendMessage(hDlgCtrl, BM_GETCHECK, 0, 0) == BST_CHECKED) }
SendMessage(hDlgCtrl, BM_SETCHECK, BST_UNCHECKED, 0); return FALSE;
else
SendMessage(hDlgCtrl, BM_SETCHECK, BST_CHECKED, 0);
}
}
return FALSE;
} }
/************************************************************************** /**************************************************************************
@ -2019,113 +2014,113 @@ INT_PTR CALLBACK ShellLink::SH_ShellLinkDlgProc(HWND hwndDlg, UINT uMsg, WPARAM
switch(uMsg) switch(uMsg)
{ {
case WM_INITDIALOG: case WM_INITDIALOG:
ppsp = (LPPROPSHEETPAGEW)lParam; ppsp = (LPPROPSHEETPAGEW)lParam;
if (ppsp == NULL) if (ppsp == NULL)
break; break;
TRACE("ShellLink_DlgProc (WM_INITDIALOG hwnd %p lParam %p ppsplParam %x)\n",hwndDlg, lParam, ppsp->lParam); TRACE("ShellLink_DlgProc (WM_INITDIALOG hwnd %p lParam %p ppsplParam %x)\n",hwndDlg, lParam, ppsp->lParam);
pThis = (ShellLink *)ppsp->lParam; pThis = (ShellLink *)ppsp->lParam;
SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pThis); SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pThis);
TRACE("sArgs: %S sComponent: %S sDescription: %S sIcoPath: %S sPath: %S sPathRel: %S sProduct: %S sWorkDir: %S\n", pThis->sArgs, pThis->sComponent, pThis->sDescription, TRACE("sArgs: %S sComponent: %S sDescription: %S sIcoPath: %S sPath: %S sPathRel: %S sProduct: %S sWorkDir: %S\n", pThis->sArgs, pThis->sComponent, pThis->sDescription,
pThis->sIcoPath, pThis->sPath, pThis->sPathRel, pThis->sProduct, pThis->sWorkDir); pThis->sIcoPath, pThis->sPath, pThis->sPathRel, pThis->sProduct, pThis->sWorkDir);
/* target path */ /* target path */
hDlgCtrl = GetDlgItem( hwndDlg, 14009 );
if ( hDlgCtrl != NULL )
SendMessageW( hDlgCtrl, WM_SETTEXT, (WPARAM)NULL, (LPARAM)pThis->sPath );
/* working dir */
hDlgCtrl = GetDlgItem( hwndDlg, 14011 );
if ( hDlgCtrl != NULL )
SendMessageW( hDlgCtrl, WM_SETTEXT, (WPARAM)NULL, (LPARAM)pThis->sWorkDir );
/* description */
hDlgCtrl = GetDlgItem( hwndDlg, 14019 );
if ( hDlgCtrl != NULL )
SendMessageW( hDlgCtrl, WM_SETTEXT, (WPARAM)NULL, (LPARAM)pThis->sDescription );
return TRUE;
case WM_NOTIFY:
lppsn = (LPPSHNOTIFY) lParam;
if ( lppsn->hdr.code == PSN_APPLY )
{
/* set working directory */
hDlgCtrl = GetDlgItem( hwndDlg, 14011 );
SendMessageW( hDlgCtrl, WM_GETTEXT, (WPARAM)MAX_PATH, (LPARAM)szBuffer );
pThis->SetWorkingDirectory(szBuffer);
/* set link destination */
hDlgCtrl = GetDlgItem( hwndDlg, 14009 ); hDlgCtrl = GetDlgItem( hwndDlg, 14009 );
SendMessageW( hDlgCtrl, WM_GETTEXT, (WPARAM)MAX_PATH, (LPARAM)szBuffer); if ( hDlgCtrl != NULL )
if ( !SHELL_ExistsFileW(szBuffer) ) SendMessageW( hDlgCtrl, WM_SETTEXT, (WPARAM)NULL, (LPARAM)pThis->sPath );
{
//FIXME load localized error msg
MessageBoxW( hwndDlg, L"file not existing", szBuffer, MB_OK );
SetWindowLongPtr( hwndDlg, DWL_MSGRESULT, PSNRET_INVALID_NOCHANGEPAGE );
return TRUE;
}
ptr = wcsrchr(szBuffer, L'.');
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 );
SetWindowLongPtr( hwndDlg, DWL_MSGRESULT, PSNRET_INVALID_NOCHANGEPAGE );
return TRUE;
}
pThis->SetPath(szBuffer); /* working dir */
hDlgCtrl = GetDlgItem( hwndDlg, 14011 );
if ( hDlgCtrl != NULL )
SendMessageW( hDlgCtrl, WM_SETTEXT, (WPARAM)NULL, (LPARAM)pThis->sWorkDir );
TRACE("This %p sLinkPath %S\n", pThis, pThis->sLinkPath); /* description */
pThis->Save(pThis->sLinkPath, TRUE ); hDlgCtrl = GetDlgItem( hwndDlg, 14019 );
SetWindowLongPtr( hwndDlg, DWL_MSGRESULT, PSNRET_NOERROR ); if ( hDlgCtrl != NULL )
SendMessageW( hDlgCtrl, WM_SETTEXT, (WPARAM)NULL, (LPARAM)pThis->sDescription );
return TRUE; return TRUE;
} case WM_NOTIFY:
break; lppsn = (LPPSHNOTIFY) lParam;
case WM_COMMAND: if ( lppsn->hdr.code == PSN_APPLY )
switch(LOWORD(wParam)) {
{ /* set working directory */
case 14020: hDlgCtrl = GetDlgItem( hwndDlg, 14011 );
/// SendMessageW( hDlgCtrl, WM_GETTEXT, (WPARAM)MAX_PATH, (LPARAM)szBuffer );
/// FIXME pThis->SetWorkingDirectory(szBuffer);
/// open target directory /* set link destination */
/// hDlgCtrl = GetDlgItem( hwndDlg, 14009 );
return TRUE; SendMessageW( hDlgCtrl, WM_GETTEXT, (WPARAM)MAX_PATH, (LPARAM)szBuffer);
case 14021: if ( !SHELL_ExistsFileW(szBuffer) )
if (pThis->sIcoPath) {
wcscpy(szBuffer, pThis->sIcoPath); //FIXME load localized error msg
IconIndex = pThis->iIcoNdx; MessageBoxW( hwndDlg, L"file not existing", szBuffer, MB_OK );
if (PickIconDlg(hwndDlg, szBuffer, MAX_PATH, &IconIndex)) SetWindowLongPtr( hwndDlg, DWL_MSGRESULT, PSNRET_INVALID_NOCHANGEPAGE );
{ return TRUE;
pThis->SetIconLocation(szBuffer, IconIndex); }
/// ptr = wcsrchr(szBuffer, L'.');
/// FIXME redraw icon if (ptr && !_wcsnicmp(ptr, L".lnk", 4))
} {
return TRUE; // FIXME load localized error msg
case 14022: MessageBoxW( hwndDlg, L"You cannot create a link to a shortcut", L"Error", MB_ICONERROR );
result = DialogBoxParamW(shell32_hInstance, MAKEINTRESOURCEW(SHELL_EXTENDED_SHORTCUT_DLG), hwndDlg, ExtendedShortcutProc, (LPARAM)pThis->bRunAs); SetWindowLongPtr( hwndDlg, DWL_MSGRESULT, PSNRET_INVALID_NOCHANGEPAGE );
if (result == 1 || result == 0) return TRUE;
{ }
if (pThis->bRunAs != result )
{
PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
}
pThis->bRunAs = result; pThis->SetPath(szBuffer);
}
return TRUE; TRACE("This %p sLinkPath %S\n", pThis, pThis->sLinkPath);
} pThis->Save(pThis->sLinkPath, TRUE );
switch(HIWORD(wParam)) SetWindowLongPtr( hwndDlg, DWL_MSGRESULT, PSNRET_NOERROR );
{ return TRUE;
case EN_CHANGE: }
PropSheet_Changed(GetParent(hwndDlg), hwndDlg); break;
break; case WM_COMMAND:
} switch(LOWORD(wParam))
break; {
default: case 14020:
break; ///
} /// FIXME
return FALSE; /// open target directory
///
return TRUE;
case 14021:
if (pThis->sIcoPath)
wcscpy(szBuffer, pThis->sIcoPath);
IconIndex = pThis->iIcoNdx;
if (PickIconDlg(hwndDlg, szBuffer, MAX_PATH, &IconIndex))
{
pThis->SetIconLocation(szBuffer, IconIndex);
///
/// FIXME redraw icon
}
return TRUE;
case 14022:
result = DialogBoxParamW(shell32_hInstance, MAKEINTRESOURCEW(SHELL_EXTENDED_SHORTCUT_DLG), hwndDlg, ExtendedShortcutProc, (LPARAM)pThis->bRunAs);
if (result == 1 || result == 0)
{
if (pThis->bRunAs != result )
{
PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
}
pThis->bRunAs = result;
}
return TRUE;
}
switch(HIWORD(wParam))
{
case EN_CHANGE:
PropSheet_Changed(GetParent(hwndDlg), hwndDlg);
break;
}
break;
default:
break;
}
return FALSE;
} }
/************************************************************************** /**************************************************************************
@ -2176,35 +2171,35 @@ HRESULT WINAPI ShellLink::GetSite(REFIID iid, void ** ppvSite)
} }
/************************************************************************** /**************************************************************************
* IShellLink_ConstructFromFile * IShellLink_ConstructFromFile
*/ */
HRESULT WINAPI IShellLink_ConstructFromFile(IUnknown *pUnkOuter, REFIID riid, LPCITEMIDLIST pidl, LPVOID *ppv) HRESULT WINAPI IShellLink_ConstructFromFile(IUnknown *pUnkOuter, REFIID riid, LPCITEMIDLIST pidl, LPVOID *ppv)
{ {
CComPtr<IUnknown> psl; CComPtr<IUnknown> psl;
HRESULT hr = ShellLink::_CreatorClass::CreateInstance(NULL, riid, (void**)&psl); HRESULT hr = ShellLink::_CreatorClass::CreateInstance(NULL, riid, (void**)&psl);
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
CComPtr<IPersistFile> ppf; CComPtr<IPersistFile> ppf;
*ppv = NULL; *ppv = NULL;
hr = psl->QueryInterface(IID_IPersistFile, (LPVOID*)&ppf); hr = psl->QueryInterface(IID_IPersistFile, (LPVOID*)&ppf);
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
WCHAR path[MAX_PATH]; WCHAR path[MAX_PATH];
if (SHGetPathFromIDListW(pidl, path)) if (SHGetPathFromIDListW(pidl, path))
hr = ppf->Load(path, 0); hr = ppf->Load(path, 0);
else else
hr = E_FAIL; hr = E_FAIL;
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
*ppv = psl.Detach(); *ppv = psl.Detach();
} }
} }
return hr; return hr;
} }

View file

@ -1,5 +1,5 @@
/* /*
* Shell Library Functions * Shell Library Functions
* *
* Copyright 1998 Marcus Meissner * Copyright 1998 Marcus Meissner
* Copyright 2002 Eric Pouech * Copyright 2002 Eric Pouech
@ -153,31 +153,31 @@ static void ParseTildeEffect(PWSTR &res, LPCWSTR &args, DWORD &len, DWORD &used,
} }
/*********************************************************************** /***********************************************************************
* SHELL_ArgifyW [Internal] * SHELL_ArgifyW [Internal]
* *
* this function is supposed to expand the escape sequences found in the registry * this function is supposed to expand the escape sequences found in the registry
* some diving reported that the following were used: * some diving reported that the following were used:
* + %1, %2... seem to report to parameter of index N in ShellExecute pmts * + %1, %2... seem to report to parameter of index N in ShellExecute pmts
* %1 file * %1 file
* %2 printer * %2 printer
* %3 driver * %3 driver
* %4 port * %4 port
* %I address of a global item ID (explorer switch /idlist) * %I address of a global item ID (explorer switch /idlist)
* %L seems to be %1 as long filename followed by the 8+3 variation * %L seems to be %1 as long filename followed by the 8+3 variation
* %S ??? * %S ???
* %* all following parameters (see batfile) * %* all following parameters (see batfile)
* *
* The way we parse the command line arguments was determined through extensive * The way we parse the command line arguments was determined through extensive
* testing and can be summed up by the following rules" * testing and can be summed up by the following rules"
* *
* - %2 * - %2
* - if first letter is " break on first non literal " and include any white spaces * - if first letter is " break on first non literal " and include any white spaces
* - if first letter is NOT " break on first " or white space * - if first letter is NOT " break on first " or white space
* - if " is opened any pair of consecutive " results in ONE literal " * - if " is opened any pair of consecutive " results in ONE literal "
* *
* - %~2 * - %~2
* - use rules from here http://www.autohotkey.net/~deleyd/parameters/parameters.htm * - use rules from here http://www.autohotkey.net/~deleyd/parameters/parameters.htm
*/ */
static BOOL SHELL_ArgifyW(WCHAR* out, DWORD len, const WCHAR* fmt, const WCHAR* lpFile, LPITEMIDLIST pidl, LPCWSTR args, DWORD* out_len) static BOOL SHELL_ArgifyW(WCHAR* out, DWORD len, const WCHAR* fmt, const WCHAR* lpFile, LPITEMIDLIST pidl, LPCWSTR args, DWORD* out_len)
{ {
@ -285,47 +285,47 @@ static BOOL SHELL_ArgifyW(WCHAR* out, DWORD len, const WCHAR* fmt, const WCHAR*
*/ */
case 'l': case 'l':
case 'L': case 'L':
if (lpFile) if (lpFile)
{ {
used += wcslen(lpFile); used += wcslen(lpFile);
if (used < len) if (used < len)
{ {
wcscpy(res, lpFile); wcscpy(res, lpFile);
res += wcslen(lpFile); res += wcslen(lpFile);
} }
} }
found_p1 = TRUE; found_p1 = TRUE;
break; break;
case 'i': case 'i':
case 'I': case 'I':
if (pidl) if (pidl)
{ {
DWORD chars = 0; DWORD chars = 0;
/* %p should not exceed 8, maybe 16 when looking forward to 64bit. /* %p should not exceed 8, maybe 16 when looking forward to 64bit.
* allowing a buffer of 100 should more than exceed all needs */ * allowing a buffer of 100 should more than exceed all needs */
WCHAR buf[100]; WCHAR buf[100];
LPVOID pv; LPVOID pv;
HGLOBAL hmem = SHAllocShared(pidl, ILGetSize(pidl), 0); HGLOBAL hmem = SHAllocShared(pidl, ILGetSize(pidl), 0);
pv = SHLockShared(hmem, 0); pv = SHLockShared(hmem, 0);
chars = swprintf(buf, wszILPtr, pv); chars = swprintf(buf, wszILPtr, pv);
if (chars >= sizeof(buf)/sizeof(WCHAR)) if (chars >= sizeof(buf)/sizeof(WCHAR))
ERR("pidl format buffer too small!\n"); ERR("pidl format buffer too small!\n");
used += chars; used += chars;
if (used < len) if (used < len)
{ {
wcscpy(res,buf); wcscpy(res,buf);
res += chars; res += chars;
} }
SHUnlockShared(pv); SHUnlockShared(pv);
} }
found_p1 = TRUE; found_p1 = TRUE;
break; break;
default: default:
/* /*
* Check if this is an env-variable here... * Check if this is an env-variable here...
*/ */
@ -403,23 +403,23 @@ static HRESULT SHELL_GetPathFromIDListForExecuteW(LPCITEMIDLIST pidl, LPWSTR psz
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
hr = desktop->GetDisplayNameOf(pidl, SHGDN_FORPARSING, &strret); hr = desktop->GetDisplayNameOf(pidl, SHGDN_FORPARSING, &strret);
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
StrRetToStrNW(pszPath, uOutSize, &strret, pidl); StrRetToStrNW(pszPath, uOutSize, &strret, pidl);
desktop->Release(); desktop->Release();
} }
return hr; return hr;
} }
/************************************************************************* /*************************************************************************
* SHELL_ExecuteW [Internal] * SHELL_ExecuteW [Internal]
* *
*/ */
static UINT_PTR SHELL_ExecuteW(const WCHAR *lpCmd, WCHAR *env, BOOL shWait, static UINT_PTR SHELL_ExecuteW(const WCHAR *lpCmd, WCHAR *env, BOOL shWait,
const SHELLEXECUTEINFOW *psei, LPSHELLEXECUTEINFOW psei_out) const SHELLEXECUTEINFOW *psei, LPSHELLEXECUTEINFOW psei_out)
{ {
STARTUPINFOW startup; STARTUPINFOW startup;
PROCESS_INFORMATION info; PROCESS_INFORMATION info;
@ -494,7 +494,7 @@ static UINT_PTR SHELL_ExecuteW(const WCHAR *lpCmd, WCHAR *env, BOOL shWait,
/*********************************************************************** /***********************************************************************
* SHELL_BuildEnvW [Internal] * SHELL_BuildEnvW [Internal]
* *
* Build the environment for the new process, adding the specified * Build the environment for the new process, adding the specified
* path to the PATH variable. Returned pointer must be freed by caller. * path to the PATH variable. Returned pointer must be freed by caller.
@ -552,7 +552,7 @@ static LPWSTR SHELL_BuildEnvW( const WCHAR *path )
/*********************************************************************** /***********************************************************************
* SHELL_TryAppPathW [Internal] * SHELL_TryAppPathW [Internal]
* *
* Helper function for SHELL_FindExecutable * Helper function for SHELL_FindExecutable
* @param lpResult - pointer to a buffer of size MAX_PATH * @param lpResult - pointer to a buffer of size MAX_PATH
@ -562,7 +562,7 @@ static LPWSTR SHELL_BuildEnvW( const WCHAR *path )
static BOOL SHELL_TryAppPathW( LPCWSTR szName, LPWSTR lpResult, WCHAR **env) static BOOL SHELL_TryAppPathW( LPCWSTR szName, LPWSTR lpResult, WCHAR **env)
{ {
static const WCHAR wszKeyAppPaths[] = {'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s', static const WCHAR wszKeyAppPaths[] = {'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\','W','i','n','d','o','w','s',
'\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\','A','p','p',' ','P','a','t','h','s','\\',0}; '\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\','A','p','p',' ','P','a','t','h','s','\\',0};
static const WCHAR wPath[] = {'P','a','t','h',0}; static const WCHAR wPath[] = {'P','a','t','h',0};
HKEY hkApp = 0; HKEY hkApp = 0;
WCHAR buffer[1024]; WCHAR buffer[1024];
@ -613,12 +613,12 @@ static UINT SHELL_FindExecutableByOperation(LPCWSTR lpOperation, LPWSTR key, LPW
if (RegQueryValueW(HKEY_CLASSES_ROOT, filetype, command, if (RegQueryValueW(HKEY_CLASSES_ROOT, filetype, command,
&commandlen) == ERROR_SUCCESS) &commandlen) == ERROR_SUCCESS)
{ {
commandlen /= sizeof(WCHAR); commandlen /= sizeof(WCHAR);
if (key) wcscpy(key, filetype); if (key) wcscpy(key, filetype);
#if 0 #if 0
LPWSTR tmp; LPWSTR tmp;
WCHAR param[256]; WCHAR param[256];
LONG paramlen = sizeof(param); LONG paramlen = sizeof(param);
static const WCHAR wSpace[] = {' ',0}; static const WCHAR wSpace[] = {' ',0};
/* FIXME: it seems all Windows version don't behave the same here. /* FIXME: it seems all Windows version don't behave the same here.
@ -626,31 +626,31 @@ static UINT SHELL_FindExecutableByOperation(LPCWSTR lpOperation, LPWSTR key, LPW
* the exec names. * the exec names.
* on Win98, it doesn't appear, but I think it does on Win2k * on Win98, it doesn't appear, but I think it does on Win2k
*/ */
/* Get the parameters needed by the application /* Get the parameters needed by the application
from the associated ddeexec key */ from the associated ddeexec key */
tmp = strstrW(filetype, wCommand); tmp = strstrW(filetype, wCommand);
tmp[0] = '\0'; tmp[0] = '\0';
wcscat(filetype, wDdeexec); wcscat(filetype, wDdeexec);
if (RegQueryValueW(HKEY_CLASSES_ROOT, filetype, param, if (RegQueryValueW(HKEY_CLASSES_ROOT, filetype, param,
&paramlen) == ERROR_SUCCESS) &paramlen) == ERROR_SUCCESS)
{ {
paramlen /= sizeof(WCHAR); paramlen /= sizeof(WCHAR);
wcscat(command, wSpace); wcscat(command, wSpace);
wcscat(command, param); wcscat(command, param);
commandlen += paramlen; commandlen += paramlen;
} }
#endif #endif
command[commandlen] = '\0'; command[commandlen] = '\0';
return 33; /* FIXME see SHELL_FindExecutable() */ return 33; /* FIXME see SHELL_FindExecutable() */
} }
return SE_ERR_NOASSOC; return SE_ERR_NOASSOC;
} }
/************************************************************************* /*************************************************************************
* SHELL_FindExecutable [Internal] * SHELL_FindExecutable [Internal]
* *
* Utility for code sharing between FindExecutable and ShellExecute * Utility for code sharing between FindExecutable and ShellExecute
* in: * in:
@ -664,7 +664,7 @@ static UINT SHELL_FindExecutableByOperation(LPCWSTR lpOperation, LPWSTR key, LPW
* on the operation) * on the operation)
*/ */
static UINT SHELL_FindExecutable(LPCWSTR lpPath, LPCWSTR lpFile, LPCWSTR lpOperation, static UINT SHELL_FindExecutable(LPCWSTR lpPath, LPCWSTR lpFile, LPCWSTR lpOperation,
LPWSTR lpResult, DWORD resultLen, LPWSTR key, WCHAR **env, LPITEMIDLIST pidl, LPCWSTR args) LPWSTR lpResult, DWORD resultLen, LPWSTR key, WCHAR **env,LPITEMIDLIST pidl, LPCWSTR args)
{ {
static const WCHAR wWindows[] = {'w','i','n','d','o','w','s',0}; static const WCHAR wWindows[] = {'w','i','n','d','o','w','s',0};
static const WCHAR wPrograms[] = {'p','r','o','g','r','a','m','s',0}; static const WCHAR wPrograms[] = {'p','r','o','g','r','a','m','s',0};
@ -778,8 +778,8 @@ static UINT SHELL_FindExecutable(LPCWSTR lpPath, LPCWSTR lpFile, LPCWSTR lpOpera
&filetypelen) == ERROR_SUCCESS) &filetypelen) == ERROR_SUCCESS)
{ {
filetypelen /= sizeof(WCHAR); filetypelen /= sizeof(WCHAR);
if (filetypelen == sizeof(filetype)/sizeof(WCHAR)) if (filetypelen == sizeof(filetype)/sizeof(WCHAR))
filetypelen--; filetypelen--;
filetype[filetypelen] = '\0'; filetype[filetypelen] = '\0';
TRACE("File type: %s\n", debugstr_w(filetype)); TRACE("File type: %s\n", debugstr_w(filetype));
@ -797,41 +797,41 @@ static UINT SHELL_FindExecutable(LPCWSTR lpPath, LPCWSTR lpFile, LPCWSTR lpOpera
filetype[filetypelen] = '\0'; filetype[filetypelen] = '\0';
retval = SHELL_FindExecutableByOperation(lpOperation, key, filetype, command, sizeof(command)); retval = SHELL_FindExecutableByOperation(lpOperation, key, filetype, command, sizeof(command));
if (retval > 32) if (retval > 32)
{ {
DWORD finishedLen; DWORD finishedLen;
SHELL_ArgifyW(lpResult, resultLen, command, xlpFile, pidl, args, &finishedLen); SHELL_ArgifyW(lpResult, resultLen, command, xlpFile, pidl, args, &finishedLen);
if (finishedLen > resultLen) if (finishedLen > resultLen)
ERR("Argify buffer not large enough.. truncated\n"); ERR("Argify buffer not large enough.. truncated\n");
DbgPrint("[shell32, SHELL_FindExecutable] Remove double quotation marks and command line arguments\n"); DbgPrint("[shell32, SHELL_FindExecutable] Remove double quotation marks and command line arguments\n");
/* Remove double quotation marks and command line arguments */ /* Remove double quotation marks and command line arguments */
if (*lpResult == '"') if (*lpResult == '"')
{ {
WCHAR *p = lpResult; WCHAR *p = lpResult;
while (*(p + 1) != '"') while (*(p + 1) != '"')
{ {
*p = *(p + 1); *p = *(p + 1);
p++; p++;
} }
*p = '\0'; *p = '\0';
} }
else else
{ {
/* Truncate on first space */ /* Truncate on first space */
WCHAR *p = lpResult; WCHAR *p = lpResult;
while (*p != ' ' && *p != '\0') while (*p != ' ' && *p != '\0')
p++; p++;
*p='\0'; *p='\0';
} }
} }
} }
else /* Check win.ini */ else /* Check win.ini */
{ {
static const WCHAR wExtensions[] = {'e','x','t','e','n','s','i','o','n','s',0}; static const WCHAR wExtensions[] = {'e','x','t','e','n','s','i','o','n','s',0};
/* Toss the leading dot */ /* Toss the leading dot */
extension++; extension++;
if (GetProfileStringW(wExtensions, extension, wszEmpty, command, sizeof(command)/sizeof(WCHAR)) > 0) if (GetProfileStringW(wExtensions, extension, wszEmpty, command, sizeof(command)/sizeof(WCHAR)) > 0)
{ {
if (wcslen(command) != 0) if (wcslen(command) != 0)
{ {
@ -857,7 +857,7 @@ static UINT SHELL_FindExecutable(LPCWSTR lpPath, LPCWSTR lpFile, LPCWSTR lpOpera
} }
/****************************************************************** /******************************************************************
* dde_cb * dde_cb
* *
* callback for the DDE connection. not really useful * callback for the DDE connection. not really useful
*/ */
@ -871,7 +871,7 @@ static HDDEDATA CALLBACK dde_cb(UINT uType, UINT uFmt, HCONV hConv,
} }
/****************************************************************** /******************************************************************
* dde_connect * dde_connect
* *
* ShellExecute helper. Used to do an operation with a DDE connection * ShellExecute helper. Used to do an operation with a DDE connection
* *
@ -881,7 +881,7 @@ static HDDEDATA CALLBACK dde_cb(UINT uType, UINT uFmt, HCONV hConv,
*/ */
static unsigned dde_connect(const WCHAR* key, const WCHAR* start, WCHAR* ddeexec, static unsigned dde_connect(const WCHAR* key, const WCHAR* start, WCHAR* ddeexec,
const WCHAR* lpFile, WCHAR *env, const WCHAR* lpFile, WCHAR *env,
LPCWSTR szCommandline, LPITEMIDLIST pidl, SHELL_ExecuteW32 execfunc, LPCWSTR szCommandline, LPITEMIDLIST pidl, SHELL_ExecuteW32 execfunc,
const SHELLEXECUTEINFOW *psei, LPSHELLEXECUTEINFOW psei_out) const SHELLEXECUTEINFOW *psei, LPSHELLEXECUTEINFOW psei_out)
{ {
static const WCHAR wApplication[] = {'\\','a','p','p','l','i','c','a','t','i','o','n',0}; static const WCHAR wApplication[] = {'\\','a','p','p','l','i','c','a','t','i','o','n',0};
@ -1011,8 +1011,7 @@ static unsigned dde_connect(const WCHAR* key, const WCHAR* start, WCHAR* ddeexec
* error DMLERR_NOTPROCESSED on XTYP_EXECUTE request. * error DMLERR_NOTPROCESSED on XTYP_EXECUTE request.
*/ */
if (unicode) if (unicode)
hDdeData = DdeClientTransaction((LPBYTE)res, (strlenW(res) + 1) * sizeof(WCHAR), hConv, 0L, 0, hDdeData = DdeClientTransaction((LPBYTE)res, (strlenW(res) + 1) * sizeof(WCHAR), hConv, 0L, 0, XTYP_EXECUTE, 30000, &tid);
XTYP_EXECUTE, 30000, &tid);
else else
{ {
DWORD lenA = WideCharToMultiByte(CP_ACP, 0, res, -1, NULL, 0, NULL, NULL); DWORD lenA = WideCharToMultiByte(CP_ACP, 0, res, -1, NULL, 0, NULL, NULL);
@ -1037,12 +1036,12 @@ static unsigned dde_connect(const WCHAR* key, const WCHAR* start, WCHAR* ddeexec
} }
/************************************************************************* /*************************************************************************
* execute_from_key [Internal] * execute_from_key [Internal]
*/ */
static UINT_PTR execute_from_key(LPCWSTR key, LPCWSTR lpFile, WCHAR *env, LPCWSTR szCommandline, static UINT_PTR execute_from_key(LPCWSTR key, LPCWSTR lpFile, WCHAR *env,
LPCWSTR executable_name, LPCWSTR szCommandline, LPCWSTR executable_name,
SHELL_ExecuteW32 execfunc, SHELL_ExecuteW32 execfunc,
LPSHELLEXECUTEINFOW psei, LPSHELLEXECUTEINFOW psei_out) LPSHELLEXECUTEINFOW psei, LPSHELLEXECUTEINFOW psei_out)
{ {
static const WCHAR wCommand[] = {'c','o','m','m','a','n','d',0}; static const WCHAR wCommand[] = {'c','o','m','m','a','n','d',0};
static const WCHAR wDdeexec[] = {'d','d','e','e','x','e','c',0}; static const WCHAR wDdeexec[] = {'d','d','e','e','x','e','c',0};
@ -1065,8 +1064,8 @@ static UINT_PTR execute_from_key(LPCWSTR key, LPCWSTR lpFile, WCHAR *env, LPCWST
/* Is there a replace() function anywhere? */ /* Is there a replace() function anywhere? */
cmdlen /= sizeof(WCHAR); cmdlen /= sizeof(WCHAR);
if (cmdlen >= sizeof(cmd)/sizeof(WCHAR)) if (cmdlen >= sizeof(cmd)/sizeof(WCHAR))
cmdlen = sizeof(cmd)/sizeof(WCHAR)-1; cmdlen = sizeof(cmd)/sizeof(WCHAR)-1;
cmd[cmdlen] = '\0'; cmd[cmdlen] = '\0';
SHELL_ArgifyW(param, sizeof(param)/sizeof(WCHAR), cmd, lpFile, (LPITEMIDLIST)psei->lpIDList, szCommandline, &resultLen); SHELL_ArgifyW(param, sizeof(param)/sizeof(WCHAR), cmd, lpFile, (LPITEMIDLIST)psei->lpIDList, szCommandline, &resultLen);
if (resultLen > sizeof(param)/sizeof(WCHAR)) if (resultLen > sizeof(param)/sizeof(WCHAR))
@ -1097,7 +1096,7 @@ static UINT_PTR execute_from_key(LPCWSTR key, LPCWSTR lpFile, WCHAR *env, LPCWST
} }
/************************************************************************* /*************************************************************************
* FindExecutableA [SHELL32.@] * FindExecutableA [SHELL32.@]
*/ */
HINSTANCE WINAPI FindExecutableA(LPCSTR lpFile, LPCSTR lpDirectory, LPSTR lpResult) HINSTANCE WINAPI FindExecutableA(LPCSTR lpFile, LPCSTR lpDirectory, LPSTR lpResult)
{ {
@ -1118,7 +1117,7 @@ HINSTANCE WINAPI FindExecutableA(LPCSTR lpFile, LPCSTR lpDirectory, LPSTR lpResu
} }
/************************************************************************* /*************************************************************************
* FindExecutableW [SHELL32.@] * FindExecutableW [SHELL32.@]
* *
* This function returns the executable associated with the specified file * This function returns the executable associated with the specified file
* for the default verb. * for the default verb.
@ -1151,7 +1150,7 @@ HINSTANCE WINAPI FindExecutableW(LPCWSTR lpFile, LPCWSTR lpDirectory, LPWSTR lpR
lpResult[0] = '\0'; /* Start off with an empty return string */ lpResult[0] = '\0'; /* Start off with an empty return string */
if (lpFile == NULL) if (lpFile == NULL)
return (HINSTANCE)SE_ERR_FNF; return (HINSTANCE)SE_ERR_FNF;
if (lpDirectory) if (lpDirectory)
{ {
@ -1378,7 +1377,7 @@ end:
/************************************************************************* /*************************************************************************
* ShellExecute_FromContextMenu [Internal] * ShellExecute_FromContextMenu [Internal]
*/ */
static LONG ShellExecute_FromContextMenu( LPSHELLEXECUTEINFOW sei ) static LONG ShellExecute_FromContextMenu( LPSHELLEXECUTEINFOW sei )
{ {
@ -1605,7 +1604,7 @@ void do_error_dialog( UINT_PTR retval, HWND hwnd, WCHAR* filename)
} }
/************************************************************************* /*************************************************************************
* SHELL_execute [Internal] * SHELL_execute [Internal]
*/ */
BOOL SHELL_execute( LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc ) BOOL SHELL_execute( LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc )
{ {
@ -1625,7 +1624,7 @@ BOOL SHELL_execute( LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc )
DWORD dirLen = sizeof(dirBuffer) / sizeof(WCHAR); DWORD dirLen = sizeof(dirBuffer) / sizeof(WCHAR);
DWORD wcmdLen = sizeof(wcmdBuffer) / sizeof(WCHAR); DWORD wcmdLen = sizeof(wcmdBuffer) / sizeof(WCHAR);
DWORD len; DWORD len;
SHELLEXECUTEINFOW sei_tmp; /* modifiable copy of SHELLEXECUTEINFO struct */ SHELLEXECUTEINFOW sei_tmp; /* modifiable copy of SHELLEXECUTEINFO struct */
WCHAR wfileName[MAX_PATH]; WCHAR wfileName[MAX_PATH];
WCHAR *env; WCHAR *env;
WCHAR lpstrProtocol[256]; WCHAR lpstrProtocol[256];
@ -1683,10 +1682,10 @@ BOOL SHELL_execute( LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc )
wszParameters = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); wszParameters = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
parametersLen = len; parametersLen = len;
} }
strcpyW(wszParameters, sei_tmp.lpParameters); strcpyW(wszParameters, sei_tmp.lpParameters);
} }
else else
*wszParameters = '\0'; *wszParameters = '\0';
wszDir = dirBuffer; wszDir = dirBuffer;
if (sei_tmp.lpDirectory) if (sei_tmp.lpDirectory)
@ -1697,10 +1696,10 @@ BOOL SHELL_execute( LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc )
wszDir = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); wszDir = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
dirLen = len; dirLen = len;
} }
strcpyW(wszDir, sei_tmp.lpDirectory); strcpyW(wszDir, sei_tmp.lpDirectory);
} }
else else
*wszDir = '\0'; *wszDir = '\0';
/* adjust string pointers to point to the new buffers */ /* adjust string pointers to point to the new buffers */
sei_tmp.lpFile = wszApplicationName; sei_tmp.lpFile = wszApplicationName;
@ -1715,26 +1714,26 @@ BOOL SHELL_execute( LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc )
/* process the IDList */ /* process the IDList */
if (sei_tmp.fMask & SEE_MASK_IDLIST) if (sei_tmp.fMask & SEE_MASK_IDLIST)
{ {
IShellExecuteHookW* pSEH; IShellExecuteHookW* pSEH;
HRESULT hr = SHBindToParent((LPCITEMIDLIST)sei_tmp.lpIDList, IID_IShellExecuteHookW, (LPVOID*)&pSEH, NULL); HRESULT hr = SHBindToParent((LPCITEMIDLIST)sei_tmp.lpIDList, IID_IShellExecuteHookW, (LPVOID*)&pSEH, NULL);
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
hr = pSEH->Execute(&sei_tmp); hr = pSEH->Execute(&sei_tmp);
pSEH->Release(); pSEH->Release();
if (hr == S_OK) if (hr == S_OK)
{ {
HeapFree(GetProcessHeap(), 0, wszApplicationName); HeapFree(GetProcessHeap(), 0, wszApplicationName);
if (wszParameters != parametersBuffer) if (wszParameters != parametersBuffer)
HeapFree(GetProcessHeap(), 0, wszParameters); HeapFree(GetProcessHeap(), 0, wszParameters);
if (wszDir != dirBuffer) if (wszDir != dirBuffer)
HeapFree(GetProcessHeap(), 0, wszDir); HeapFree(GetProcessHeap(), 0, wszDir);
return TRUE; return TRUE;
} }
} }
SHGetPathFromIDListW((LPCITEMIDLIST)sei_tmp.lpIDList, wszApplicationName); SHGetPathFromIDListW((LPCITEMIDLIST)sei_tmp.lpIDList, wszApplicationName);
appKnownSingular = TRUE; appKnownSingular = TRUE;
@ -1842,67 +1841,67 @@ BOOL SHELL_execute( LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc )
/* separate out command line arguments from executable file name */ /* separate out command line arguments from executable file name */
if (!*sei_tmp.lpParameters && !appKnownSingular) if (!*sei_tmp.lpParameters && !appKnownSingular)
{ {
/* If the executable path is quoted, handle the rest of the command line as parameters. */ /* If the executable path is quoted, handle the rest of the command line as parameters. */
if (sei_tmp.lpFile[0] == '"') if (sei_tmp.lpFile[0] == '"')
{ {
LPWSTR src = wszApplicationName/*sei_tmp.lpFile*/ + 1; LPWSTR src = wszApplicationName/*sei_tmp.lpFile*/ + 1;
LPWSTR dst = wfileName; LPWSTR dst = wfileName;
LPWSTR end; LPWSTR end;
/* copy the unquoted executable path to 'wfileName' */ /* copy the unquoted executable path to 'wfileName' */
while(*src && *src!='"') while(*src && *src!='"')
*dst++ = *src++; *dst++ = *src++;
*dst = '\0'; *dst = '\0';
if (*src == '"') if (*src == '"')
{ {
end = ++src; end = ++src;
while(isspace(*src)) while(isspace(*src))
++src; ++src;
} }
else else
end = src; end = src;
/* copy the parameter string to 'wszParameters' */ /* copy the parameter string to 'wszParameters' */
strcpyW(wszParameters, src); strcpyW(wszParameters, src);
/* terminate previous command string after the quote character */ /* terminate previous command string after the quote character */
*end = '\0'; *end = '\0';
} }
else else
{ {
/* If the executable name is not quoted, we have to use this search loop here, /* If the executable name is not quoted, we have to use this search loop here,
that in CreateProcess() is not sufficient because it does not handle shell links. */ that in CreateProcess() is not sufficient because it does not handle shell links. */
WCHAR buffer[MAX_PATH], xlpFile[MAX_PATH]; WCHAR buffer[MAX_PATH], xlpFile[MAX_PATH];
LPWSTR space, s; LPWSTR space, s;
LPWSTR beg = wszApplicationName/*sei_tmp.lpFile*/; LPWSTR beg = wszApplicationName/*sei_tmp.lpFile*/;
for(s=beg; (space= const_cast<LPWSTR>(strchrW(s, ' '))); s=space+1) for(s=beg; (space= const_cast<LPWSTR>(strchrW(s, ' '))); s=space+1)
{ {
int idx = space-sei_tmp.lpFile; int idx = space-sei_tmp.lpFile;
memcpy(buffer, sei_tmp.lpFile, idx * sizeof(WCHAR)); memcpy(buffer, sei_tmp.lpFile, idx * sizeof(WCHAR));
buffer[idx] = '\0'; buffer[idx] = '\0';
/*FIXME This finds directory paths if the targeted file name contains spaces. */ /*FIXME This finds directory paths if the targeted file name contains spaces. */
if (SearchPathW(*sei_tmp.lpDirectory? sei_tmp.lpDirectory: NULL, buffer, wszExe, sizeof(xlpFile)/sizeof(xlpFile[0]), xlpFile, NULL)) if (SearchPathW(*sei_tmp.lpDirectory? sei_tmp.lpDirectory: NULL, buffer, wszExe, sizeof(xlpFile)/sizeof(xlpFile[0]), xlpFile, NULL))
{ {
/* separate out command from parameter string */ /* separate out command from parameter string */
LPCWSTR p = space + 1; LPCWSTR p = space + 1;
while(isspaceW(*p)) while(isspaceW(*p))
++p; ++p;
strcpyW(wszParameters, p); strcpyW(wszParameters, p);
*space = '\0'; *space = '\0';
break; break;
} }
} }
lstrcpynW(wfileName, sei_tmp.lpFile,sizeof(wfileName)/sizeof(WCHAR)); lstrcpynW(wfileName, sei_tmp.lpFile,sizeof(wfileName)/sizeof(WCHAR));
} }
} }
else else
lstrcpynW(wfileName, sei_tmp.lpFile,sizeof(wfileName)/sizeof(WCHAR)); lstrcpynW(wfileName, sei_tmp.lpFile,sizeof(wfileName)/sizeof(WCHAR));
@ -2021,7 +2020,7 @@ BOOL SHELL_execute( LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc )
} }
/************************************************************************* /*************************************************************************
* ShellExecuteA [SHELL32.290] * ShellExecuteA [SHELL32.290]
*/ */
HINSTANCE WINAPI ShellExecuteA(HWND hWnd, LPCSTR lpOperation,LPCSTR lpFile, HINSTANCE WINAPI ShellExecuteA(HWND hWnd, LPCSTR lpOperation,LPCSTR lpFile,
LPCSTR lpParameters,LPCSTR lpDirectory, INT iShowCmd) LPCSTR lpParameters,LPCSTR lpDirectory, INT iShowCmd)
@ -2051,7 +2050,7 @@ HINSTANCE WINAPI ShellExecuteA(HWND hWnd, LPCSTR lpOperation,LPCSTR lpFile,
} }
/************************************************************************* /*************************************************************************
* ShellExecuteExA [SHELL32.292] * ShellExecuteExA [SHELL32.292]
* *
*/ */
BOOL WINAPI ShellExecuteExA (LPSHELLEXECUTEINFOA sei) BOOL WINAPI ShellExecuteExA (LPSHELLEXECUTEINFOA sei)
@ -2065,7 +2064,7 @@ BOOL WINAPI ShellExecuteExA (LPSHELLEXECUTEINFOA sei)
memcpy(&seiW, sei, sizeof(SHELLEXECUTEINFOW)); memcpy(&seiW, sei, sizeof(SHELLEXECUTEINFOW));
if (sei->lpVerb) if (sei->lpVerb)
seiW.lpVerb = __SHCloneStrAtoW(&wVerb, sei->lpVerb); seiW.lpVerb = __SHCloneStrAtoW(&wVerb, sei->lpVerb);
if (sei->lpFile) if (sei->lpFile)
seiW.lpFile = __SHCloneStrAtoW(&wFile, sei->lpFile); seiW.lpFile = __SHCloneStrAtoW(&wFile, sei->lpFile);
@ -2098,7 +2097,7 @@ BOOL WINAPI ShellExecuteExA (LPSHELLEXECUTEINFOA sei)
} }
/************************************************************************* /*************************************************************************
* ShellExecuteExW [SHELL32.293] * ShellExecuteExW [SHELL32.293]
* *
*/ */
BOOL WINAPI ShellExecuteExW (LPSHELLEXECUTEINFOW sei) BOOL WINAPI ShellExecuteExW (LPSHELLEXECUTEINFOW sei)
@ -2107,7 +2106,7 @@ BOOL WINAPI ShellExecuteExW (LPSHELLEXECUTEINFOW sei)
} }
/************************************************************************* /*************************************************************************
* ShellExecuteW [SHELL32.294] * ShellExecuteW [SHELL32.294]
* from shellapi.h * from shellapi.h
* WINSHELLAPI HINSTANCE APIENTRY ShellExecuteW(HWND hwnd, LPCWSTR lpOperation, * WINSHELLAPI HINSTANCE APIENTRY ShellExecuteW(HWND hwnd, LPCWSTR lpOperation,
* LPCWSTR lpFile, LPCWSTR lpParameters, LPCWSTR lpDirectory, INT nShowCmd); * LPCWSTR lpFile, LPCWSTR lpParameters, LPCWSTR lpDirectory, INT nShowCmd);
@ -2137,7 +2136,7 @@ HINSTANCE WINAPI ShellExecuteW(HWND hwnd, LPCWSTR lpOperation, LPCWSTR lpFile,
} }
/************************************************************************* /*************************************************************************
* WOWShellExecute [SHELL32.@] * WOWShellExecute [SHELL32.@]
* *
* FIXME: the callback function most likely doesn't work the same way on Windows. * FIXME: the callback function most likely doesn't work the same way on Windows.
*/ */