|
|
/*
* shlink.cpp - IShellLink implementation for InternetShortcut class. */
/* Headers
**********/
#include "project.hpp"
#pragma hdrstop
/* Types
********/
typedef enum isl_getpath_flags { // flag combinations
ALL_ISL_GETPATH_FLAGS = (SLGP_SHORTPATH | SLGP_UNCPRIORITY) } ISL_GETPATH_FLAGS;
typedef enum isl_resolve_flags { // flag combinations
ALL_ISL_RESOLVE_FLAGS = (SLR_NO_UI | SLR_ANY_MATCH | SLR_UPDATE) } ISL_RESOLVE_FLAGS;
/********************************** Methods **********************************/
HRESULT STDMETHODCALLTYPE InternetShortcut::SetPath(PCSTR pcszPath) { HRESULT hr;
DebugEntry(InternetShortcut::SetPath);
ASSERT(IS_VALID_STRUCT_PTR(this, CInternetShortcut)); ASSERT(IS_VALID_STRING_PTR(pcszPath, CSTR));
// Treat path as literal URL.
hr = SetURL(pcszPath, 0);
ASSERT(IS_VALID_STRUCT_PTR(this, CInternetShortcut));
DebugExitHRESULT(InternetShortcut::SetPath, hr);
return(hr); }
#pragma warning(disable:4100) /* "unreferenced formal parameter" warning */
HRESULT STDMETHODCALLTYPE InternetShortcut::GetPath(PSTR pszFile, int ncFileBufLen, PWIN32_FIND_DATA pwfd, DWORD dwFlags) { HRESULT hr;
DebugEntry(InternetShortcut::GetPath);
ASSERT(IS_VALID_STRUCT_PTR(this, CInternetShortcut)); ASSERT(IS_VALID_WRITE_BUFFER_PTR(pszFile, STR, ncFileBufLen)); ASSERT(NULL == pwfd || IS_VALID_STRUCT_PTR(pwfd, CWIN32_FIND_DATA)); ASSERT(FLAGS_ARE_VALID(dwFlags, ALL_ISL_GETPATH_FLAGS));
// Ignore dwFlags.
if (pwfd) ZeroMemory(pwfd, sizeof(*pwfd));
if (m_pszURL) { lstrcpyn(pszFile, m_pszURL, ncFileBufLen);
hr = S_OK; } else { // No URL.
if (ncFileBufLen > 0) *pszFile = '\0';
hr = S_FALSE; }
ASSERT(IS_VALID_STRUCT_PTR(this, CInternetShortcut)); ASSERT((hr == S_OK && (ncFileBufLen < 1 || IS_VALID_STRING_PTR(pszFile, STR))) || (hr == S_FALSE && (ncFileBufLen < 1 || ! *pszFile)));
DebugExitHRESULT(InternetShortcut::GetPath, hr);
return(hr); }
HRESULT STDMETHODCALLTYPE InternetShortcut::SetRelativePath( PCSTR pcszRelativePath, DWORD dwReserved) { HRESULT hr;
DebugEntry(InternetShortcut::SetRelativePath);
// dwReserved may be any value.
ASSERT(IS_VALID_STRUCT_PTR(this, CInternetShortcut)); ASSERT(IS_VALID_STRING_PTR(pcszRelativePath, CSTR));
hr = E_NOTIMPL;
ASSERT(IS_VALID_STRUCT_PTR(this, CInternetShortcut));
DebugExitHRESULT(InternetShortcut::SetRelativePath, hr);
return(hr); }
HRESULT STDMETHODCALLTYPE InternetShortcut::SetIDList(LPCITEMIDLIST pcidl) { HRESULT hr;
DebugEntry(InternetShortcut::SetIDList);
ASSERT(IS_VALID_STRUCT_PTR(this, CInternetShortcut)); ASSERT(IS_VALID_STRUCT_PTR(pcidl, CITEMIDLIST));
hr = E_NOTIMPL;
ASSERT(IS_VALID_STRUCT_PTR(this, CInternetShortcut));
DebugExitHRESULT(InternetShortcut::SetIDList, hr);
return(hr); }
#pragma warning(default:4100) /* "unreferenced formal parameter" warning */
HRESULT STDMETHODCALLTYPE InternetShortcut::GetIDList(LPITEMIDLIST *ppidl) { HRESULT hr;
DebugEntry(InternetShortcut::GetIDList);
ASSERT(IS_VALID_STRUCT_PTR(this, CInternetShortcut)); ASSERT(IS_VALID_WRITE_PTR(ppidl, PITEMIDLIST));
*ppidl = NULL;
hr = E_NOTIMPL;
ASSERT(IS_VALID_STRUCT_PTR(this, CInternetShortcut));
DebugExitHRESULT(InternetShortcut::GetIDList, hr);
return(hr); }
HRESULT STDMETHODCALLTYPE InternetShortcut::SetDescription( PCSTR pcszDescription) { HRESULT hr; BOOL bDifferent; PSTR pszFileCopy;
DebugEntry(InternetShortcut::SetDescription);
ASSERT(IS_VALID_STRUCT_PTR(this, CInternetShortcut)); ASSERT(IS_VALID_STRING_PTR(pcszDescription, CSTR));
// Set m_pszFile to description.
bDifferent = (! m_pszFile || lstrcmp(pcszDescription, m_pszFile) != 0);
if (StringCopy(pcszDescription, &pszFileCopy)) { if (m_pszFile) { delete m_pszFile; m_pszFile = NULL; }
m_pszFile = pszFileCopy;
if (bDifferent) Dirty(TRUE);
hr = S_OK; } else hr = E_OUTOFMEMORY;
ASSERT(IS_VALID_STRUCT_PTR(this, CInternetShortcut));
DebugExitHRESULT(InternetShortcut::SetDescription, hr);
return(hr); }
HRESULT STDMETHODCALLTYPE InternetShortcut::GetDescription( PSTR pszDescription, int ncDesciptionBufLen) { HRESULT hr;
DebugEntry(InternetShortcut::GetDescription);
ASSERT(IS_VALID_STRUCT_PTR(this, CInternetShortcut)); ASSERT(IS_VALID_WRITE_BUFFER_PTR(pszDescription, STR, ncDesciptionBufLen));
// Get description from m_pszFile.
if (m_pszFile) lstrcpyn(pszDescription, m_pszFile, ncDesciptionBufLen); else { if (ncDesciptionBufLen > 0) pszDescription = '\0'; }
hr = S_OK;
ASSERT(IS_VALID_STRUCT_PTR(this, CInternetShortcut)); ASSERT(hr == S_OK && (ncDesciptionBufLen <= 0 || (IS_VALID_STRING_PTR(pszDescription, STR) && EVAL(lstrlen(pszDescription) < ncDesciptionBufLen))));
DebugExitHRESULT(InternetShortcut::GetDescription, hr);
return(hr); }
#pragma warning(disable:4100) /* "unreferenced formal parameter" warning */
HRESULT STDMETHODCALLTYPE InternetShortcut::SetArguments(PCSTR pcszArgs) { HRESULT hr;
DebugEntry(InternetShortcut::SetArguments);
ASSERT(IS_VALID_STRUCT_PTR(this, CInternetShortcut)); ASSERT(IS_VALID_STRING_PTR(pcszArgs, CSTR));
hr = E_NOTIMPL;
ASSERT(IS_VALID_STRUCT_PTR(this, CInternetShortcut));
DebugExitHRESULT(InternetShortcut::SetArguments, hr);
return(hr); }
#pragma warning(default:4100) /* "unreferenced formal parameter" warning */
HRESULT STDMETHODCALLTYPE InternetShortcut::GetArguments(PSTR pszArgs, int ncArgsBufLen) { HRESULT hr;
DebugEntry(InternetShortcut::GetArguments);
ASSERT(IS_VALID_STRUCT_PTR(this, CInternetShortcut)); ASSERT(IS_VALID_WRITE_BUFFER_PTR(pszArgs, STR, ncArgsBufLen));
if (ncArgsBufLen > 0) *pszArgs = '\0';
hr = E_NOTIMPL;
WARNING_OUT(("InternetShortcut::GetArguments(): Arguments not maintained for CLSID_InternetShortcut."));
ASSERT(IS_VALID_STRUCT_PTR(this, CInternetShortcut));
DebugExitHRESULT(InternetShortcut::GetArguments, hr);
return(hr); }
HRESULT STDMETHODCALLTYPE InternetShortcut::SetWorkingDirectory( PCSTR pcszWorkingDirectory) { HRESULT hr = S_OK; char rgchNewPath[MAX_PATH_LEN]; BOOL bChanged = FALSE; PSTR pszNewWorkingDirectory = NULL;
DebugEntry(InternetShortcut::SetWorkingDirectory);
ASSERT(IS_VALID_STRUCT_PTR(this, CInternetShortcut)); ASSERT(! pcszWorkingDirectory || IS_VALID_STRING_PTR(pcszWorkingDirectory, CSTR));
if (! AnyMeat(pcszWorkingDirectory)) pcszWorkingDirectory = NULL;
if (pcszWorkingDirectory) { PSTR pszFileName;
if (GetFullPathName(pcszWorkingDirectory, sizeof(rgchNewPath), rgchNewPath, &pszFileName) > 0) pcszWorkingDirectory = rgchNewPath; else hr = E_PATH_NOT_FOUND; }
if (hr == S_OK) { bChanged = ! ((! pcszWorkingDirectory && ! m_pszWorkingDirectory) || (pcszWorkingDirectory && m_pszWorkingDirectory && ! lstrcmp(pcszWorkingDirectory, m_pszWorkingDirectory)));
if (bChanged && pcszWorkingDirectory) { // (+ 1) for null terminator.
pszNewWorkingDirectory = new(char[lstrlen(pcszWorkingDirectory) + 1]);
if (pszNewWorkingDirectory) lstrcpy(pszNewWorkingDirectory, pcszWorkingDirectory); else hr = E_OUTOFMEMORY; } }
if (hr == S_OK) { if (bChanged) { if (m_pszWorkingDirectory) delete m_pszWorkingDirectory;
m_pszWorkingDirectory = pszNewWorkingDirectory;
Dirty(TRUE);
TRACE_OUT(("InternetShortcut::SetWorkingDirectory(): Set working directory to %s.", CHECK_STRING(m_pszWorkingDirectory))); } else TRACE_OUT(("InternetShortcut::SetWorkingDirectory(): Working directory already %s.", CHECK_STRING(m_pszWorkingDirectory))); }
ASSERT(IS_VALID_STRUCT_PTR(this, CInternetShortcut)); ASSERT(hr == S_OK || hr == E_OUTOFMEMORY || hr == E_PATH_NOT_FOUND);
DebugExitHRESULT(InternetShortcut::SetWorkingDirectory, hr);
return(hr); }
HRESULT STDMETHODCALLTYPE InternetShortcut::GetWorkingDirectory( PSTR pszWorkingDirectory, int ncbWorkingDirectoryBufLen) { HRESULT hr;
DebugEntry(InternetShortcut::GetWorkingDirectory);
ASSERT(IS_VALID_STRUCT_PTR(this, CInternetShortcut)); ASSERT(IS_VALID_WRITE_BUFFER_PTR(pszWorkingDirectory, STR, ncbWorkingDirectoryBufLen));
if (m_pszWorkingDirectory) { lstrcpyn(pszWorkingDirectory, m_pszWorkingDirectory, ncbWorkingDirectoryBufLen);
hr = S_OK; } else { if (ncbWorkingDirectoryBufLen > 0) *pszWorkingDirectory = '\0';
hr = S_FALSE; }
ASSERT(IS_VALID_STRUCT_PTR(this, CInternetShortcut)); ASSERT(IsValidPathResult(hr, pszWorkingDirectory, ncbWorkingDirectoryBufLen)); ASSERT(hr == S_OK || hr == S_FALSE);
DebugExitHRESULT(InternetShortcut::GetWorkingDirectory, hr);
return(hr); }
HRESULT STDMETHODCALLTYPE InternetShortcut::SetHotkey(WORD wHotkey) { HRESULT hr;
DebugEntry(InternetShortcut::SetHotkey);
ASSERT(IS_VALID_STRUCT_PTR(this, CInternetShortcut)); ASSERT(! wHotkey || EVAL(IsValidHotkey(wHotkey)));
if (wHotkey != m_wHotkey) Dirty(TRUE);
m_wHotkey = wHotkey;
hr = S_OK;
ASSERT(IS_VALID_STRUCT_PTR(this, CInternetShortcut));
DebugExitHRESULT(InternetShortcut::SetHotkey, hr);
return(hr); }
HRESULT STDMETHODCALLTYPE InternetShortcut::GetHotkey(PWORD pwHotkey) { HRESULT hr;
DebugEntry(InternetShortcut::GetHotkey);
ASSERT(IS_VALID_STRUCT_PTR(this, CInternetShortcut)); ASSERT(IS_VALID_WRITE_PTR(pwHotkey, WORD));
*pwHotkey = m_wHotkey;
hr = S_OK;
ASSERT(IS_VALID_STRUCT_PTR(this, CInternetShortcut)); ASSERT(! *pwHotkey || EVAL(IsValidHotkey(*pwHotkey)));
DebugExitHRESULT(InternetShortcut::GetHotkey, hr);
return(hr); }
HRESULT STDMETHODCALLTYPE InternetShortcut::SetShowCmd(int nShowCmd) { HRESULT hr;
DebugEntry(InternetShortcut::SetShowCmd);
ASSERT(IS_VALID_STRUCT_PTR(this, CInternetShortcut)); ASSERT(IsValidShowCmd(nShowCmd));
if (nShowCmd != m_nShowCmd) { m_nShowCmd = nShowCmd;
Dirty(TRUE);
TRACE_OUT(("InternetShortcut::SetShowCmd(): Set show command to %d.", m_nShowCmd)); } else TRACE_OUT(("InternetShortcut::SetShowCmd(): Show command already %d.", m_nShowCmd));
hr = S_OK;
ASSERT(IS_VALID_STRUCT_PTR(this, CInternetShortcut)); ASSERT(hr == S_OK);
DebugExitHRESULT(InternetShortcut::SetShowCmd, hr);
return(hr); }
HRESULT STDMETHODCALLTYPE InternetShortcut::GetShowCmd(PINT pnShowCmd) { HRESULT hr;
DebugEntry(InternetShortcut::GetShowCmd);
ASSERT(IS_VALID_STRUCT_PTR(this, CInternetShortcut)); ASSERT(IS_VALID_WRITE_PTR(pnShowCmd, INT));
*pnShowCmd = m_nShowCmd;
hr = S_OK;
ASSERT(IsValidShowCmd(m_nShowCmd));
DebugExitHRESULT(InternetShortcut::GetShowCmd, hr);
return(hr); }
HRESULT STDMETHODCALLTYPE InternetShortcut::SetIconLocation(PCSTR pcszIconFile, int niIcon) { HRESULT hr = S_OK; BOOL bNewMeat; char rgchNewPath[MAX_PATH_LEN];
DebugEntry(InternetShortcut::SetIconLocation);
ASSERT(IS_VALID_STRUCT_PTR(this, CInternetShortcut)); ASSERT(IsValidIconIndex(pcszIconFile ? S_OK : S_FALSE, pcszIconFile, MAX_PATH_LEN, niIcon));
bNewMeat = AnyMeat(pcszIconFile);
if (bNewMeat) hr = FullyQualifyPath(pcszIconFile, rgchNewPath, sizeof(rgchNewPath));
if (hr == S_OK) { char rgchOldPath[MAX_PATH_LEN]; int niOldIcon; UINT uFlags;
hr = GetIconLocation(0, rgchOldPath, sizeof(rgchOldPath), &niOldIcon, &uFlags);
if (SUCCEEDED(hr)) { BOOL bOldMeat; BOOL bChanged = FALSE; PSTR pszNewIconFile = NULL; int niNewIcon = 0;
bOldMeat = AnyMeat(rgchOldPath);
ASSERT(! *rgchOldPath || bOldMeat);
bChanged = ((! bOldMeat && bNewMeat) || (bOldMeat && ! bNewMeat) || (bOldMeat && bNewMeat && (lstrcmp(rgchOldPath, rgchNewPath) != 0 || niIcon != niOldIcon)));
if (bChanged && bNewMeat) { // (+ 1) for null terminator.
pszNewIconFile = new(char[lstrlen(rgchNewPath) + 1]);
if (pszNewIconFile) { lstrcpy(pszNewIconFile, rgchNewPath); niNewIcon = niIcon;
hr = S_OK; } else hr = E_OUTOFMEMORY; } else hr = S_OK;
if (hr == S_OK) { if (bChanged) { if (m_pszIconFile) delete m_pszIconFile;
m_pszIconFile = pszNewIconFile; m_niIcon = niNewIcon;
Dirty(TRUE);
TRACE_OUT(("InternetShortcut::SetIconLocation(): Set icon location to %d in %s.", m_niIcon, CHECK_STRING(m_pszIconFile))); } else TRACE_OUT(("InternetShortcut::SetIconLocation(): Icon location already %d in %s.", m_niIcon, CHECK_STRING(m_pszIconFile))); } } }
ASSERT(IS_VALID_STRUCT_PTR(this, CInternetShortcut)); ASSERT(hr == S_OK || hr == E_OUTOFMEMORY || hr == E_FILE_NOT_FOUND);
DebugExitHRESULT(InternetShortcut::SetIconLocation, hr);
return(hr); }
HRESULT STDMETHODCALLTYPE InternetShortcut::GetIconLocation( PSTR pszIconFile, int ncbIconFileBufLen, PINT pniIcon) { HRESULT hr;
DebugEntry(InternetShortcut::GetIconLocation);
ASSERT(IS_VALID_STRUCT_PTR(this, CInternetShortcut)); ASSERT(IS_VALID_WRITE_BUFFER_PTR(pszIconFile, STR, ncbIconFileBufLen)); ASSERT(IS_VALID_WRITE_PTR(pniIcon, int));
if (m_pszIconFile) { lstrcpyn(pszIconFile, m_pszIconFile, ncbIconFileBufLen); *pniIcon = m_niIcon;
hr = S_OK; } else { if (ncbIconFileBufLen > 0) *pszIconFile = '\0'; *pniIcon = 0;
hr = S_FALSE; }
ASSERT(IS_VALID_STRUCT_PTR(this, CInternetShortcut)); ASSERT(IsValidIconIndex(hr, pszIconFile, ncbIconFileBufLen, *pniIcon));
DebugExitHRESULT(InternetShortcut::GetIconLocation, hr);
return(hr); }
#pragma warning(disable:4100) /* "unreferenced formal parameter" warning */
HRESULT STDMETHODCALLTYPE InternetShortcut::Resolve(HWND hwnd, DWORD dwFlags) { HRESULT hr;
DebugEntry(InternetShortcut::Resolve);
ASSERT(IS_VALID_STRUCT_PTR(this, CInternetShortcut)); ASSERT(IS_VALID_HANDLE(hwnd, WND)); ASSERT(FLAGS_ARE_VALID(dwFlags, ALL_ISL_RESOLVE_FLAGS));
hr = S_OK;
WARNING_OUT(("InternetShortcut::Resolve(): This method is a NOP for CLSID_InternetShortcut."));
ASSERT(IS_VALID_STRUCT_PTR(this, CInternetShortcut));
DebugExitHRESULT(InternetShortcut::Resolve, hr);
return(hr); }
#pragma warning(default:4100) /* "unreferenced formal parameter" warning */
|