Source code of Windows XP (NT5)
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.

255 lines
6.3 KiB

  1. /*****************************************************************************
  2. *
  3. * ftpicon.cpp - IExtractIcon interface
  4. *
  5. *****************************************************************************/
  6. #include "priv.h"
  7. #include "ftpicon.h"
  8. #include "ftpurl.h"
  9. INT GetFtpIcon(UINT uFlags, BOOL fIsRoot)
  10. {
  11. INT nIcon = (uFlags & GIL_OPENICON) ? IDI_FTPOPENFOLDER : IDI_FTPFOLDER;
  12. if (fIsRoot)
  13. nIcon = IDI_FTPSERVER; // This is an FTP Server Icon.
  14. return nIcon;
  15. }
  16. #ifndef UNICODE
  17. #define PathFindExtensionA PathFindExtension
  18. #endif
  19. //===========================
  20. // *** IExtractIconA Interface ***
  21. //===========================
  22. /*****************************************************************************\
  23. FUNCTION: GetIconLocation
  24. DESCRIPTION:
  25. Get the icon location from the registry.
  26. _UNDOCUMENTED_: Not mentioned is that if you return GIL_NOTFILENAME,
  27. you should take steps to ensure uniqueness of the non-filename
  28. return value, to avoid colliding with non-filenames from other
  29. shell extensions.
  30. _UNDOCUMENTED_: The inability of SHGetFileInfo to work properly
  31. on "magic internal" cached association icons like "*23" is not
  32. documented. As a result of this "feature", the SHGFI_ICONLOCATION
  33. flag is useless.
  34. Actually, we can still use SHGetFileInfo; we'll use the shell's own
  35. feature against it. We'll do a SHGFI_SYSICONINDEX and return that
  36. as the icon index, with "*" as the GIL_NOTFILENAME.
  37. We don't handle the cases where we ought to use GIL_SIMULATEDOC.
  38. \*****************************************************************************/
  39. HRESULT CFtpIcon::GetIconLocation(UINT uFlags, LPSTR szIconFile, UINT cchMax, int *piIndex, UINT *pwFlags)
  40. {
  41. static CHAR szMSIEFTP[MAX_PATH] = "";
  42. if (0 == szMSIEFTP[0])
  43. GetModuleFileNameA(HINST_THISDLL, szMSIEFTP, ARRAYSIZE(szMSIEFTP));
  44. // NOTE: This is negative because it's a resource index.
  45. *piIndex = (0 - GetFtpIcon(uFlags, m_nRoot));
  46. if (pwFlags)
  47. *pwFlags = GIL_PERCLASS; //(uFlags & GIL_OPENICON);
  48. StrCpyNA(szIconFile, szMSIEFTP, cchMax);
  49. return S_OK;
  50. }
  51. //===========================
  52. // *** IExtractIconW Interface ***
  53. //===========================
  54. HRESULT CFtpIcon::GetIconLocation(UINT uFlags, LPWSTR wzIconFile, UINT cchMax, int *piIndex, UINT *pwFlags)
  55. {
  56. HRESULT hres;
  57. CHAR szIconFile[MAX_PATH];
  58. ASSERT_SINGLE_THREADED;
  59. hres = GetIconLocation(uFlags, szIconFile, ARRAYSIZE(szIconFile), piIndex, pwFlags);
  60. if (EVAL(SUCCEEDED(hres)))
  61. SHAnsiToUnicode(szIconFile, wzIconFile, cchMax);
  62. return hres;
  63. }
  64. //===========================
  65. // *** IQueryInfo Interface ***
  66. //===========================
  67. HRESULT CFtpIcon::GetInfoTip(DWORD dwFlags, WCHAR **ppwszTip)
  68. {
  69. ASSERT_SINGLE_THREADED;
  70. if (ppwszTip) // The shell doesn't check the return value
  71. *ppwszTip = NULL; // so we always have to NULL the output pointer.
  72. // SHStrDupW(L"", ppwszTip);
  73. return E_NOTIMPL;
  74. /**************
  75. // This InfoTip will appear when the user hovers over an item in defview.
  76. // We don't want to support this now because it isn't needed and looks different
  77. // than the shell.
  78. HRESULT hr = E_FAIL;
  79. LPITEMIDLIST pidl;
  80. if (!ppwszTip)
  81. return E_INVALIDARG;
  82. *ppwszTip = NULL;
  83. if (m_pflHfpl && (pidl = m_pflHfpl->GetPidl(0)))
  84. {
  85. WCHAR wzToolTip[MAX_URL_STRING];
  86. hr = FtpPidl_GetDisplayName(pidl, wzItemName, ARRAYSIZE(wzItemName));
  87. if (EVAL(SUCCEEDED(hr)))
  88. hr = SHStrDupW(wzToolTip, ppwszTip);
  89. }
  90. return hr;
  91. ***********/
  92. }
  93. HRESULT CFtpIcon::GetInfoFlags(DWORD *pdwFlags)
  94. {
  95. *pdwFlags = 0;
  96. return S_OK;
  97. }
  98. /*****************************************************************************
  99. * CFtpIcon_Create
  100. *
  101. * We just stash away the pflHfpl; the real work happens on the
  102. * GetIconLocation call.
  103. *
  104. * _HACKHACK_: psf = 0 if we are being called by the property sheet code.
  105. *****************************************************************************/
  106. HRESULT CFtpIcon_Create(CFtpFolder * pff, CFtpPidlList * pflHfpl, REFIID riid, LPVOID * ppvObj)
  107. {
  108. HRESULT hres;
  109. CFtpIcon * pfi;
  110. *ppvObj = NULL;
  111. hres = CFtpIcon_Create(pff, pflHfpl, &pfi);
  112. if (SUCCEEDED(hres))
  113. {
  114. hres = pfi->QueryInterface(riid, ppvObj);
  115. pfi->Release();
  116. }
  117. return hres;
  118. }
  119. /*****************************************************************************
  120. * CFtpIcon_Create
  121. *
  122. * We just stash away the m_pflHfpl; the real work happens on the
  123. * GetIconLocation call.
  124. *
  125. * _HACKHACK_: psf = 0 if we are being called by the property sheet code.
  126. *****************************************************************************/
  127. HRESULT CFtpIcon_Create(CFtpFolder * pff, CFtpPidlList * pflHfpl, CFtpIcon ** ppfi)
  128. {
  129. HRESULT hres= E_OUTOFMEMORY;
  130. *ppfi = new CFtpIcon();
  131. if (*ppfi)
  132. {
  133. IUnknown_Set(&(*ppfi)->m_pflHfpl, pflHfpl);
  134. if (pff && pff->IsRoot())
  135. {
  136. (*ppfi)->m_nRoot++;
  137. }
  138. hres = S_OK;
  139. }
  140. return hres;
  141. }
  142. /****************************************************\
  143. Constructor
  144. \****************************************************/
  145. CFtpIcon::CFtpIcon() : m_cRef(1)
  146. {
  147. DllAddRef();
  148. // This needs to be allocated in Zero Inited Memory.
  149. // Assert that all Member Variables are inited to Zero.
  150. ASSERT(!m_pflHfpl);
  151. ASSERT(!m_nRoot);
  152. INIT_SINGLE_THREADED_ASSERT;
  153. LEAK_ADDREF(LEAK_CFtpIcon);
  154. }
  155. /****************************************************\
  156. Destructor
  157. \****************************************************/
  158. CFtpIcon::~CFtpIcon()
  159. {
  160. ATOMICRELEASE(m_pflHfpl);
  161. DllRelease();
  162. LEAK_DELREF(LEAK_CFtpIcon);
  163. }
  164. //===========================
  165. // *** IUnknown Interface ***
  166. //===========================
  167. ULONG CFtpIcon::AddRef()
  168. {
  169. m_cRef++;
  170. return m_cRef;
  171. }
  172. ULONG CFtpIcon::Release()
  173. {
  174. ASSERT(m_cRef > 0);
  175. m_cRef--;
  176. if (m_cRef > 0)
  177. return m_cRef;
  178. delete this;
  179. return 0;
  180. }
  181. HRESULT CFtpIcon::QueryInterface(REFIID riid, void **ppvObj)
  182. {
  183. static const QITAB qit[] = {
  184. QITABENT(CFtpIcon, IExtractIconW),
  185. QITABENT(CFtpIcon, IExtractIconA),
  186. QITABENT(CFtpIcon, IQueryInfo),
  187. { 0 },
  188. };
  189. return QISearch(this, qit, riid, ppvObj);
  190. }