Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

362 lines
9.1 KiB

  1. #include "precomp.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. HRESULT _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(SDSPATCH_TYPELIB, 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. ASSERT( 0 != _cRef );
  101. ULONG cRef = InterlockedDecrement(&_cRef);
  102. if ( 0 == cRef )
  103. {
  104. delete this;
  105. }
  106. return cRef;
  107. }
  108. // returns:
  109. // TRUE - every thing OK
  110. // FALSE - don't do it
  111. HRESULT CShortcut::_SecurityCheck()
  112. {
  113. return (_dwSafetyOptions == 0) ? S_OK : E_ACCESSDENIED; // || (IsSafePage(_punkSite) == S_OK);
  114. }
  115. HRESULT _TCharToBSTR(LPCTSTR psz, BSTR *pbs)
  116. {
  117. *pbs = SysAllocStringT(psz);
  118. return *pbs ? S_OK : E_OUTOFMEMORY;
  119. }
  120. LPCTSTR _BSTRToTChar(BSTR bs, TCHAR *psz, UINT cch)
  121. {
  122. if (bs)
  123. SHUnicodeToTChar(bs, psz, cch);
  124. else
  125. psz = NULL;
  126. return psz;
  127. }
  128. STDMETHODIMP CShortcut::get_Path(BSTR *pbs)
  129. {
  130. *pbs = NULL;
  131. HRESULT hr = _SecurityCheck();
  132. if (SUCCEEDED(hr))
  133. {
  134. TCHAR szPath[MAX_PATH];
  135. hr = _psl->GetPath(szPath, ARRAYSIZE(szPath), NULL, 0);
  136. if (SUCCEEDED(hr))
  137. hr = _TCharToBSTR(szPath, pbs);
  138. }
  139. return hr;
  140. }
  141. STDMETHODIMP CShortcut::put_Path(BSTR bs)
  142. {
  143. HRESULT hr = _SecurityCheck();
  144. if (SUCCEEDED(hr))
  145. {
  146. TCHAR szPath[MAX_PATH];
  147. hr = _psl->SetPath(_BSTRToTChar(bs, szPath, ARRAYSIZE(szPath)));
  148. }
  149. return hr;
  150. }
  151. STDMETHODIMP CShortcut::get_Description(BSTR *pbs)
  152. {
  153. *pbs = NULL;
  154. HRESULT hr = _SecurityCheck();
  155. if (SUCCEEDED(hr))
  156. {
  157. TCHAR szDescription[MAX_PATH];
  158. hr = _psl->GetDescription(szDescription, ARRAYSIZE(szDescription));
  159. if (SUCCEEDED(hr))
  160. hr = _TCharToBSTR(szDescription, pbs);
  161. }
  162. return hr;
  163. }
  164. STDMETHODIMP CShortcut::put_Description(BSTR bs)
  165. {
  166. HRESULT hr = _SecurityCheck();
  167. if (SUCCEEDED(hr))
  168. {
  169. TCHAR szDesc[MAX_PATH];
  170. hr = _psl->SetDescription(_BSTRToTChar(bs, szDesc, ARRAYSIZE(szDesc)));
  171. }
  172. return hr;
  173. }
  174. STDMETHODIMP CShortcut::get_WorkingDirectory(BSTR *pbs)
  175. {
  176. *pbs = NULL;
  177. HRESULT hr = _SecurityCheck();
  178. if (SUCCEEDED(hr))
  179. {
  180. TCHAR szWorkingDir[MAX_PATH];
  181. hr = _psl->GetWorkingDirectory(szWorkingDir, ARRAYSIZE(szWorkingDir));
  182. if (SUCCEEDED(hr))
  183. hr = _TCharToBSTR(szWorkingDir, pbs);
  184. }
  185. return hr;
  186. }
  187. STDMETHODIMP CShortcut::put_WorkingDirectory(BSTR bs)
  188. {
  189. HRESULT hr = _SecurityCheck();
  190. if (SUCCEEDED(hr))
  191. {
  192. TCHAR szWorkingDir[MAX_PATH];
  193. hr = _psl->SetWorkingDirectory(_BSTRToTChar(bs, szWorkingDir, ARRAYSIZE(szWorkingDir)));
  194. }
  195. return hr;
  196. }
  197. STDMETHODIMP CShortcut::get_Arguments(BSTR *pbs)
  198. {
  199. *pbs = NULL;
  200. HRESULT hr = _SecurityCheck();
  201. if (SUCCEEDED(hr))
  202. {
  203. TCHAR szArgs[MAX_PATH];
  204. hr = _psl->GetArguments(szArgs, ARRAYSIZE(szArgs));
  205. if (SUCCEEDED(hr))
  206. hr = _TCharToBSTR(szArgs, pbs);
  207. }
  208. return hr;
  209. }
  210. STDMETHODIMP CShortcut::put_Arguments(BSTR bs)
  211. {
  212. HRESULT hr = _SecurityCheck();
  213. if (SUCCEEDED(hr))
  214. {
  215. TCHAR szArgs[MAX_PATH];
  216. hr = _psl->SetArguments(_BSTRToTChar(bs, szArgs, ARRAYSIZE(szArgs)));
  217. }
  218. return hr;
  219. }
  220. STDMETHODIMP CShortcut::get_Hotkey(int *piHK)
  221. {
  222. HRESULT hr = _SecurityCheck();
  223. if (SUCCEEDED(hr))
  224. {
  225. hr = _psl->GetHotkey((WORD*)piHK);
  226. }
  227. return hr;
  228. }
  229. STDMETHODIMP CShortcut::put_Hotkey(int iHK)
  230. {
  231. HRESULT hr = _SecurityCheck();
  232. if (SUCCEEDED(hr))
  233. {
  234. hr = _psl->SetHotkey((WORD)iHK);
  235. }
  236. return hr;
  237. }
  238. STDMETHODIMP CShortcut::get_ShowCommand(int *piShowCommand)
  239. {
  240. HRESULT hr = _SecurityCheck();
  241. if (SUCCEEDED(hr))
  242. {
  243. hr = _psl->GetShowCmd(piShowCommand);
  244. }
  245. return hr;
  246. }
  247. STDMETHODIMP CShortcut::put_ShowCommand(int iShowCommand)
  248. {
  249. HRESULT hr = _SecurityCheck();
  250. if (SUCCEEDED(hr))
  251. {
  252. hr = _psl->SetShowCmd(iShowCommand);
  253. }
  254. return hr;
  255. }
  256. STDMETHODIMP CShortcut::get_Target(FolderItem **ppfi)
  257. {
  258. HRESULT hr = _SecurityCheck();
  259. if (SUCCEEDED(hr))
  260. {
  261. LPITEMIDLIST pidl;
  262. if (S_OK == _psl->GetIDList(&pidl))
  263. {
  264. hr = CFolderItem_CreateFromIDList(NULL, pidl, ppfi);
  265. if (SUCCEEDED(hr) && _dwSafetyOptions)
  266. hr = MakeSafeForScripting((IUnknown**)ppfi);
  267. }
  268. else
  269. hr = E_FAIL;
  270. }
  271. return hr;
  272. }
  273. STDMETHODIMP CShortcut::Resolve(int fFlags)
  274. {
  275. HRESULT hr = _SecurityCheck();
  276. if (SUCCEEDED(hr))
  277. {
  278. hr = _psl->Resolve(_hwnd, (DWORD)fFlags);
  279. }
  280. return hr;
  281. }
  282. STDMETHODIMP CShortcut::GetIconLocation(BSTR *pbs, int *piIcon)
  283. {
  284. *pbs = NULL;
  285. HRESULT hr = _SecurityCheck();
  286. if (SUCCEEDED(hr))
  287. {
  288. TCHAR szIconPath[MAX_PATH];
  289. hr = _psl->GetIconLocation(szIconPath, ARRAYSIZE(szIconPath), piIcon);
  290. if (SUCCEEDED(hr))
  291. hr = _TCharToBSTR(szIconPath, pbs);
  292. }
  293. return hr;
  294. }
  295. STDMETHODIMP CShortcut::SetIconLocation(BSTR bs, int iIcon)
  296. {
  297. HRESULT hr = _SecurityCheck();
  298. if (SUCCEEDED(hr))
  299. {
  300. TCHAR szArgs[MAX_PATH];
  301. hr = _psl->SetIconLocation(_BSTRToTChar(bs, szArgs, ARRAYSIZE(szArgs)), iIcon);
  302. }
  303. return hr;
  304. }
  305. STDMETHODIMP CShortcut::Save(VARIANT vWhere)
  306. {
  307. HRESULT hr = _SecurityCheck();
  308. if (SUCCEEDED(hr))
  309. {
  310. IPersistFile *ppf;
  311. hr = _psl->QueryInterface(IID_IPersistFile, (void **)&ppf);
  312. if (SUCCEEDED(hr))
  313. {
  314. hr = ppf->Save(VariantToStrCast(&vWhere), TRUE);
  315. ppf->Release();
  316. }
  317. }
  318. return hr;
  319. }