sdlink.cpp
Upload User: xhy777
Upload Date: 2007-02-14
Package Size: 24088k
Code Size: 9k
Category:

Windows Kernel

Development Platform:

Visual C++

  1. #include "stdafx.h"
  2. #pragma hdrstop
  3. class CShortcut : 
  4.     public IShellLinkDual2, 
  5.     public CObjectSafety, 
  6.     protected CImpIDispatch
  7. {
  8. public:
  9.     CShortcut();
  10.     HRESULT Init(HWND hwnd, IShellFolder *psf, LPCITEMIDLIST pidl);
  11.     // IUnknown
  12.     STDMETHODIMP QueryInterface(REFIID riid, void **ppv);
  13.     STDMETHODIMP_(ULONG) AddRef(void);
  14.     STDMETHODIMP_(ULONG) Release(void);
  15.     // IDispatch
  16.     virtual STDMETHODIMP GetTypeInfoCount(UINT *pctinfo)
  17.         { return CImpIDispatch::GetTypeInfoCount(pctinfo); }
  18.     virtual STDMETHODIMP GetTypeInfo(UINT itinfo, LCID lcid, ITypeInfo **pptinfo)
  19.         { return CImpIDispatch::GetTypeInfo(itinfo, lcid, pptinfo); }
  20.     virtual STDMETHODIMP GetIDsOfNames(REFIID riid, OLECHAR **rgszNames, UINT cNames, LCID lcid, DISPID *rgdispid)
  21.         { return CImpIDispatch::GetIDsOfNames(riid, rgszNames, cNames, lcid, rgdispid); }
  22.     virtual STDMETHODIMP Invoke(DISPID dispidMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pdispparams, VARIANT *pvarResult, EXCEPINFO *pexcepinfo, UINT *puArgErr)
  23.         { return CImpIDispatch::Invoke(dispidMember, riid, lcid, wFlags, pdispparams, pvarResult, pexcepinfo, puArgErr); }
  24.     // IShellLinkDual
  25.     STDMETHODIMP get_Path(BSTR *pbs);
  26.     STDMETHODIMP put_Path(BSTR bs);
  27.     STDMETHODIMP get_Description(BSTR *pbs);
  28.     STDMETHODIMP put_Description(BSTR bs);
  29.     STDMETHODIMP get_WorkingDirectory(BSTR *pbs);
  30.     STDMETHODIMP put_WorkingDirectory(BSTR bs);
  31.     STDMETHODIMP get_Arguments(BSTR *pbs);
  32.     STDMETHODIMP put_Arguments(BSTR bs);
  33.     STDMETHODIMP get_Hotkey(int *piHK);
  34.     STDMETHODIMP put_Hotkey(int iHK);
  35.     STDMETHODIMP get_ShowCommand(int *piShowCommand);
  36.     STDMETHODIMP put_ShowCommand(int iShowCommand);
  37.     STDMETHODIMP Resolve(int fFlags);
  38.     STDMETHODIMP GetIconLocation(BSTR *pbs, int *piIcon);
  39.     STDMETHODIMP SetIconLocation(BSTR bs, int iIcon);
  40.     STDMETHODIMP Save(VARIANT vWhere);
  41.     // IShellLinkDual2
  42.     STDMETHODIMP get_Target(FolderItem **ppfi);
  43. private:
  44.     ~CShortcut();
  45.     BOOL _SecurityCheck();
  46.     LONG            _cRef;
  47.     HWND            _hwnd;              // Hwnd of the main folder window
  48.     IShellLink      *_psl;
  49. };
  50. HRESULT CShortcut_CreateIDispatch(HWND hwnd, IShellFolder *psf, LPCITEMIDLIST pidl, IDispatch ** ppid)
  51. {
  52.     HRESULT hr = E_OUTOFMEMORY;
  53.     *ppid = NULL;
  54.     CShortcut* psdf = new CShortcut();
  55.     if (psdf)
  56.     {
  57.         hr = psdf->Init(hwnd, psf, pidl);
  58.         if (SUCCEEDED(hr))
  59.              hr = psdf->QueryInterface(IID_IDispatch, (void **)ppid);
  60.         psdf->Release();
  61.     }
  62.     return hr;
  63. }
  64. CShortcut::CShortcut() :
  65.         CImpIDispatch(&LIBID_Shell32, 1, 0, &IID_IShellLinkDual2)
  66. {
  67.     DllAddRef();
  68.     _cRef = 1;
  69.     _hwnd = NULL;
  70.     _psl = NULL;
  71. }
  72. CShortcut::~CShortcut(void)
  73. {
  74.     if (_psl)
  75.         _psl->Release();
  76.     DllRelease();
  77. }
  78. HRESULT CShortcut::Init(HWND hwnd, IShellFolder *psf, LPCITEMIDLIST pidl)
  79. {
  80.     _hwnd = hwnd;
  81.     return psf->GetUIObjectOf(hwnd, 1, &pidl, IID_IShellLink, NULL, (void **)&_psl);
  82. }
  83. STDMETHODIMP CShortcut::QueryInterface(REFIID riid, void **ppv)
  84. {
  85.     static const QITAB qit[] = {
  86.         QITABENT(CShortcut, IShellLinkDual2),
  87.         QITABENTMULTI(CShortcut, IShellLinkDual, IShellLinkDual2),
  88.         QITABENTMULTI(CShortcut, IDispatch, IShellLinkDual2),
  89.         QITABENT(CShortcut, IObjectSafety),
  90.         { 0 },
  91.     };
  92.     return QISearch(this, qit, riid, ppv);
  93. }
  94. STDMETHODIMP_(ULONG) CShortcut::AddRef(void)
  95. {
  96.     return InterlockedIncrement(&_cRef);
  97. }
  98. STDMETHODIMP_(ULONG) CShortcut::Release(void)
  99. {
  100.     if (InterlockedDecrement(&_cRef))
  101.         return _cRef;
  102.     delete this;
  103.     return 0;
  104. }
  105. // returns:
  106. //      TRUE    - every thing OK
  107. //      FALSE   - don't do it
  108. BOOL CShortcut::_SecurityCheck()
  109. {
  110.     return _dwSafetyOptions == 0; // || (IsSafePage(_punkSite) == S_OK);
  111. }
  112. HRESULT _TCharToBSTR(LPCTSTR psz, BSTR *pbs)
  113. {
  114.     *pbs = SysAllocStringT(psz);
  115.     return *pbs ? S_OK : E_OUTOFMEMORY;
  116. }
  117. LPCTSTR _BSTRToTChar(BSTR bs, TCHAR *psz, UINT cch)
  118. {
  119.     if (bs)
  120.         SHUnicodeToTChar(bs, psz, cch);
  121.     else
  122.         psz = NULL;
  123.     return psz;
  124. }
  125. STDMETHODIMP CShortcut::get_Path(BSTR *pbs)
  126. {
  127.     *pbs = NULL;
  128.     TCHAR szPath[MAX_PATH];
  129.     HRESULT hr = _psl->GetPath(szPath, ARRAYSIZE(szPath), NULL, 0);
  130.     if (SUCCEEDED(hr))
  131.         hr = _TCharToBSTR(szPath, pbs);
  132.     return hr;
  133. }
  134. STDMETHODIMP CShortcut::put_Path(BSTR bs)
  135. {
  136.     HRESULT hr;
  137.     if (_SecurityCheck())
  138.     {
  139.         TCHAR szPath[MAX_PATH];
  140.         hr = _psl->SetPath(_BSTRToTChar(bs, szPath, ARRAYSIZE(szPath)));
  141.     }
  142.     else
  143.         hr = E_ACCESSDENIED;
  144.     return hr;
  145. }
  146. STDMETHODIMP CShortcut::get_Description(BSTR *pbs)
  147. {
  148.     *pbs = NULL;
  149.     TCHAR szDescription[MAX_PATH];
  150.     HRESULT hr = _psl->GetDescription(szDescription, ARRAYSIZE(szDescription));
  151.     if (SUCCEEDED(hr))
  152.         hr = _TCharToBSTR(szDescription, pbs);
  153.     return hr;
  154. }
  155. STDMETHODIMP CShortcut::put_Description(BSTR bs)
  156. {
  157.     HRESULT hr;
  158.     if (_SecurityCheck())
  159.     {
  160.         TCHAR szDesc[MAX_PATH];
  161.         hr = _psl->SetDescription(_BSTRToTChar(bs, szDesc, ARRAYSIZE(szDesc)));
  162.     }
  163.     else
  164.         hr = E_ACCESSDENIED;
  165.     return hr;
  166. }
  167. STDMETHODIMP CShortcut::get_WorkingDirectory(BSTR *pbs)
  168. {
  169.     *pbs = NULL;
  170.     TCHAR szWorkingDir[MAX_PATH];
  171.     HRESULT hr = _psl->GetWorkingDirectory(szWorkingDir, ARRAYSIZE(szWorkingDir));
  172.     if (SUCCEEDED(hr))
  173.         hr = _TCharToBSTR(szWorkingDir, pbs);
  174.     return hr;
  175. }
  176. STDMETHODIMP CShortcut::put_WorkingDirectory(BSTR bs)
  177. {
  178.     HRESULT hr;
  179.     if (_SecurityCheck())
  180.     {
  181.         TCHAR szWorkingDir[MAX_PATH];
  182.         hr = _psl->SetWorkingDirectory(_BSTRToTChar(bs, szWorkingDir, ARRAYSIZE(szWorkingDir)));
  183.     }
  184.     else
  185.         hr = E_ACCESSDENIED;
  186.     return hr;
  187. }
  188. STDMETHODIMP CShortcut::get_Arguments(BSTR *pbs)
  189. {
  190.     *pbs = NULL;
  191.     TCHAR szArgs[MAX_PATH];
  192.     HRESULT hr = _psl->GetArguments(szArgs, ARRAYSIZE(szArgs));
  193.     if (SUCCEEDED(hr))
  194.         hr = _TCharToBSTR(szArgs, pbs);
  195.     return hr;
  196. }
  197. STDMETHODIMP CShortcut::put_Arguments(BSTR bs)
  198. {
  199.     HRESULT hr;
  200.     if (_SecurityCheck())
  201.     {
  202.         TCHAR szArgs[MAX_PATH];
  203.         hr = _psl->SetArguments(_BSTRToTChar(bs, szArgs, ARRAYSIZE(szArgs)));
  204.     }
  205.     else
  206.         hr = E_ACCESSDENIED;
  207.     return hr;
  208. }
  209. STDMETHODIMP CShortcut::get_Hotkey(int *piHK)
  210. {
  211.     return _psl->GetHotkey((WORD*)piHK);
  212. }
  213. STDMETHODIMP CShortcut::put_Hotkey(int iHK)
  214. {
  215.     HRESULT hr;
  216.     if (_SecurityCheck())
  217.     {
  218.         hr = _psl->SetHotkey((WORD)iHK);
  219.     }
  220.     else
  221.         hr = E_ACCESSDENIED;
  222.     return hr;
  223. }
  224. STDMETHODIMP CShortcut::get_ShowCommand(int *piShowCommand)
  225. {
  226.     return _psl->GetShowCmd(piShowCommand);
  227. }
  228. STDMETHODIMP CShortcut::put_ShowCommand(int iShowCommand)
  229. {
  230.     HRESULT hr;
  231.     if (_SecurityCheck())
  232.     {
  233.         hr = _psl->SetShowCmd(iShowCommand);
  234.     }
  235.     else
  236.         hr = E_ACCESSDENIED;
  237.     return hr;
  238. }
  239. STDMETHODIMP CShortcut::get_Target(FolderItem **ppfi)
  240. {
  241.     HRESULT hr;
  242.     LPITEMIDLIST pidl;
  243.     if (S_OK == _psl->GetIDList(&pidl))
  244.     {
  245.         hr = CFolderItem_CreateFromIDList(NULL, pidl, ppfi);
  246.         if (SUCCEEDED(hr) && _dwSafetyOptions)
  247.             hr = MakeSafeForScripting((IUnknown**)ppfi);
  248.     }
  249.     else
  250.         hr = E_FAIL;
  251.     return hr;
  252. }
  253. STDMETHODIMP CShortcut::Resolve(int fFlags)
  254. {
  255.     HRESULT hr;
  256.     if (_SecurityCheck())
  257.     {
  258.         hr = _psl->Resolve(_hwnd, (DWORD)fFlags);
  259.     }
  260.     else
  261.         hr = E_ACCESSDENIED;
  262.     return hr;
  263. }
  264. STDMETHODIMP CShortcut::GetIconLocation(BSTR *pbs, int *piIcon)
  265. {
  266.     *pbs = NULL;
  267.     TCHAR szIconPath[MAX_PATH];
  268.     HRESULT hr = _psl->GetIconLocation(szIconPath, ARRAYSIZE(szIconPath), piIcon);
  269.     if (SUCCEEDED(hr))
  270.         hr = _TCharToBSTR(szIconPath, pbs);
  271.     return hr;
  272. }
  273. STDMETHODIMP CShortcut::SetIconLocation(BSTR bs, int iIcon)
  274. {
  275.     HRESULT hr;
  276.     if (_SecurityCheck())
  277.     {
  278.         TCHAR szArgs[MAX_PATH];
  279.         hr = _psl->SetIconLocation(_BSTRToTChar(bs, szArgs, ARRAYSIZE(szArgs)), iIcon);
  280.     }
  281.     else
  282.         hr = E_ACCESSDENIED;
  283.     return hr;
  284. }
  285. STDMETHODIMP CShortcut::Save(VARIANT vWhere)
  286. {
  287.     HRESULT hr;
  288.     if (_SecurityCheck())
  289.     {
  290.         IPersistFile *ppf;
  291.         hr = _psl->QueryInterface(IID_IPersistFile, (void **)&ppf);
  292.         if (SUCCEEDED(hr))
  293.         {
  294.             hr = ppf->Save(VariantToStrW(&vWhere), TRUE);
  295.             ppf->Release();
  296.         }
  297.     }
  298.     else
  299.         hr = E_ACCESSDENIED;
  300.     return hr;
  301. }