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.

391 lines
11 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1997.
  5. //
  6. // File: I E X T R A C T . C P P
  7. //
  8. // Contents: IExtract implementation for CConnectionFolderExtractIcon
  9. //
  10. // Notes:
  11. //
  12. // Author: jeffspr 7 Oct 1997
  13. //
  14. //----------------------------------------------------------------------------
  15. #include "pch.h"
  16. #pragma hdrstop
  17. #include "foldinc.h" // Standard shell\folder includes
  18. #include <nsres.h>
  19. #include "foldres.h"
  20. #include "iconhandler.h"
  21. static const WCHAR c_szNetShellIcon[] = L"netshellicon";
  22. HRESULT CConnectionFolderExtractIcon::CreateInstance(
  23. IN LPCITEMIDLIST apidl,
  24. IN REFIID riid,
  25. OUT void** ppv)
  26. {
  27. TraceFileFunc(ttidShellFolderIface);
  28. HRESULT hr = E_OUTOFMEMORY;
  29. CConnectionFolderExtractIcon * pObj = NULL;
  30. pObj = new CComObject <CConnectionFolderExtractIcon>;
  31. if (pObj)
  32. {
  33. // Do the standard CComCreator::CreateInstance stuff.
  34. //
  35. pObj->SetVoid (NULL);
  36. pObj->InternalFinalConstructAddRef ();
  37. hr = pObj->FinalConstruct ();
  38. pObj->InternalFinalConstructRelease ();
  39. if (SUCCEEDED(hr))
  40. {
  41. PCONFOLDPIDL pcfp;
  42. hr = pcfp.InitializeFromItemIDList(apidl);
  43. if (SUCCEEDED(hr))
  44. {
  45. hr = pObj->HrInitialize(pcfp);
  46. if (SUCCEEDED(hr))
  47. {
  48. hr = pObj->GetUnknown()->QueryInterface (riid, ppv);
  49. }
  50. }
  51. }
  52. if (FAILED(hr))
  53. {
  54. delete pObj;
  55. }
  56. }
  57. return hr;
  58. }
  59. CConnectionFolderExtractIcon::CConnectionFolderExtractIcon() throw()
  60. {
  61. TraceFileFunc(ttidShellFolderIface);
  62. }
  63. CConnectionFolderExtractIcon::~CConnectionFolderExtractIcon() throw()
  64. {
  65. TraceFileFunc(ttidShellFolderIface);
  66. }
  67. HRESULT CConnectionFolderExtractIcon::HrInitialize(
  68. IN const PCONFOLDPIDL& pidl)
  69. {
  70. TraceFileFunc(ttidShellFolderIface);
  71. HRESULT hr = S_FALSE;
  72. ConnListEntry cle;
  73. if (SUCCEEDED(hr))
  74. {
  75. hr = g_ccl.HrFindConnectionByGuid(&(pidl->guidId), cle);
  76. }
  77. if (hr == S_OK)
  78. {
  79. Assert(!cle.empty());
  80. Assert(!cle.ccfe.empty());
  81. hr = cle.ccfe.ConvertToPidl(m_pidl);
  82. }
  83. else
  84. {
  85. // Couldn't find the icon in the cache.. Good chance that it hasn't been loaded
  86. // yet. That being the case, go ahead and use the persisted pidl data to
  87. // load the icon
  88. //
  89. TraceTag(ttidShellFolderIface, "IExtractIcon - Couldn't find connection in the cache.");
  90. hr = m_pidl.ILClone(pidl);
  91. }
  92. TraceHr(ttidShellFolderIface, FAL, hr, FALSE, "CConnectionFolderExtractIcon::HrInitialize");
  93. return hr;
  94. }
  95. //+---------------------------------------------------------------------------
  96. //
  97. // Member: CConnectionFolderExtractIcon::GetIconLocation
  98. //
  99. // Purpose:
  100. //
  101. // Arguments:
  102. // uFlags [in] Address of a UINT value that receives zero or a
  103. // combination of the following values:
  104. //
  105. // GIL_ASYNC The calling application supports asynchronous
  106. // retrieval of icons.
  107. // GIL_FORSHELL The icon is to be displayed in a shell folder.
  108. //
  109. // wzIconFile [out] Address of the buffer that receives the icon
  110. // location. The icon location is a null-terminated
  111. // string that identifies the file that contains
  112. // the icon.
  113. // cchMax [in] Size of the buffer that receives the icon location.
  114. // piIndex [out] Address of an INT that receives the icon index,
  115. // which further describes the icon location.
  116. // pwFlags [out] Address of a UINT value that receives zero or a
  117. // combination of the following values:
  118. //
  119. // GIL_DONTCACHE Don't cache the physical bits.
  120. // GIL_NOTFILENAME This isn't a filename/index pair. Call
  121. // IExtractIcon::Extract instead
  122. // GIL_PERCLASS (Only internal to the shell)
  123. // GIL_PERINSTANCE Each object of this class has the same icon.
  124. // GIL_FORSHORTCUT The icon is to be used for a shortcut.
  125. //
  126. //
  127. // Returns: S_OK if the function returned a valid location,
  128. // or S_FALSE if the shell should use a default icon.
  129. //
  130. // Author: jeffspr 25 Nov 1998
  131. //
  132. // Notes:
  133. //
  134. STDMETHODIMP CConnectionFolderExtractIcon::GetIconLocation(
  135. IN UINT uFlags,
  136. OUT PWSTR szIconFile,
  137. IN UINT cchMax,
  138. OUT int * piIndex,
  139. OUT UINT * pwFlags)
  140. {
  141. TraceFileFunc(ttidShellFolderIface);
  142. HRESULT hr = S_FALSE;
  143. Assert(pwFlags);
  144. Assert(szIconFile);
  145. Assert(piIndex);
  146. #ifdef DBG
  147. // Easy way to check if certain flags are set
  148. //
  149. BOOL fAsync = (uFlags & GIL_ASYNC);
  150. BOOL fForShell = (uFlags & GIL_FORSHELL);
  151. BOOL fOpenIcon = (uFlags & GIL_OPENICON);
  152. DWORD dwOldpwFlags = *pwFlags;
  153. #endif
  154. BOOL fIsWizard = FALSE;
  155. const PCONFOLDPIDL& pcfp = m_pidl;
  156. Assert(!pcfp.empty());
  157. if (!pcfp.empty())
  158. {
  159. BOOL fCacheThisIcon = TRUE;
  160. CConFoldEntry cfe;
  161. hr = pcfp.ConvertToConFoldEntry(cfe);
  162. if (SUCCEEDED(hr))
  163. {
  164. DWORD dwIcon;
  165. hr = g_pNetConfigIcons->HrGetIconIDForPIDL(uFlags, cfe, dwIcon, &fCacheThisIcon);
  166. if (SUCCEEDED(hr))
  167. {
  168. *piIndex = static_cast<int>(dwIcon);
  169. wcsncpy(szIconFile, c_szNetShellIcon, cchMax);
  170. *pwFlags = GIL_PERINSTANCE | GIL_NOTFILENAME;
  171. if (!fCacheThisIcon)
  172. {
  173. *pwFlags |= GIL_DONTCACHE;
  174. }
  175. }
  176. }
  177. }
  178. #ifdef DBG
  179. TraceTag(ttidIcons, "%S->GetIconLocation(0x%04x/0x%04x,%S,0x%08x,0x%08x)", pcfp->PszGetNamePointer(), uFlags, dwOldpwFlags, szIconFile, *piIndex, *pwFlags);
  180. #endif
  181. return hr;
  182. }
  183. //+---------------------------------------------------------------------------
  184. //
  185. // Member: CConnectionFolderExtractIcon::GetIconLocation
  186. //
  187. // Purpose: ANSI wrapper for the above UNICODE GetIconLocation
  188. //
  189. // Arguments:
  190. // uFlags [] See above
  191. // szIconFile [] See above
  192. // cchMax [] See above
  193. // piIndex [] See above
  194. // pwFlags [] See above
  195. //
  196. // Returns:
  197. //
  198. // Author: jeffspr 6 Apr 1999
  199. //
  200. // Notes:
  201. //
  202. STDMETHODIMP CConnectionFolderExtractIcon::GetIconLocation(
  203. IN UINT uFlags,
  204. OUT PSTR szIconFile,
  205. IN UINT cchMax,
  206. OUT int * piIndex,
  207. OUT UINT * pwFlags)
  208. {
  209. TraceFileFunc(ttidShellFolderIface);
  210. HRESULT hr = S_OK;
  211. WCHAR * pszIconFileW = new WCHAR[cchMax];
  212. if (!pszIconFileW)
  213. {
  214. hr = ERROR_OUTOFMEMORY;
  215. }
  216. else
  217. {
  218. hr = GetIconLocation(uFlags, pszIconFileW, cchMax, piIndex, pwFlags);
  219. if (SUCCEEDED(hr))
  220. {
  221. WideCharToMultiByte(CP_ACP, 0, pszIconFileW, -1, szIconFile, cchMax, NULL, NULL);
  222. }
  223. delete [] pszIconFileW;
  224. }
  225. TraceHr(ttidShellFolder, FAL, hr, FALSE, "CConnectionFolderExtractIcon::GetIconLocation(A)");
  226. return hr;
  227. }
  228. //+---------------------------------------------------------------------------
  229. //
  230. // Member: CConnectionFolderExtractIcon::Extract
  231. //
  232. // Purpose: Grab the actual icon for the caller.
  233. //
  234. // Arguments:
  235. // wzFile [] Filename from where we'll retrieve the icon
  236. // nIconIndex [] Index of the icon (though this is bogus)
  237. // phiconLarge [] Return pointer for the large icon handle
  238. // phiconSmall [] Return pointer for the small icon handle
  239. // nIconSize [] Size of the icon requested.
  240. //
  241. // Returns:
  242. //
  243. // Author: jeffspr 9 Oct 1997
  244. //
  245. // Notes:
  246. //
  247. STDMETHODIMP CConnectionFolderExtractIcon::Extract(
  248. IN PCWSTR wzFile,
  249. IN UINT nIconIndex,
  250. OUT HICON * phiconLarge,
  251. OUT HICON * phiconSmall,
  252. IN UINT nIconSize)
  253. {
  254. TraceFileFunc(ttidShellFolderIface);
  255. HRESULT hr = S_OK;
  256. ConnListEntry cle;
  257. Assert(wzFile);
  258. if (wcscmp(wzFile, c_szNetShellIcon))
  259. {
  260. TraceHr(ttidError, FAL, E_INVALIDARG, FALSE, "This is not my icon.");
  261. return E_INVALIDARG;
  262. }
  263. Assert(!m_pidl.empty());
  264. DWORD dwIconSmallSize = HIWORD(nIconSize);
  265. if (dwIconSmallSize && phiconSmall)
  266. {
  267. hr = g_pNetConfigIcons->HrGetIconFromIconId(dwIconSmallSize, nIconIndex, *phiconSmall);
  268. if (FAILED(hr))
  269. {
  270. if (phiconLarge)
  271. {
  272. *phiconLarge = NULL;
  273. }
  274. *phiconSmall = NULL;
  275. }
  276. }
  277. DWORD dwIconLargeSize = LOWORD(nIconSize);
  278. if (dwIconLargeSize && phiconLarge && SUCCEEDED(hr))
  279. {
  280. hr = g_pNetConfigIcons->HrGetIconFromIconId(dwIconLargeSize, nIconIndex, *phiconLarge);
  281. if (FAILED(hr))
  282. {
  283. if (phiconSmall && *phiconSmall)
  284. {
  285. DestroyIcon(*phiconSmall);
  286. *phiconSmall = NULL;
  287. }
  288. *phiconLarge = NULL;
  289. }
  290. }
  291. TraceTag(ttidIcons, "%S,0x%08x->Extract(%d %d)", wzFile, nIconIndex, dwIconLargeSize, dwIconSmallSize);
  292. return hr;
  293. }
  294. //+---------------------------------------------------------------------------
  295. //
  296. // Member: CConnectionFolderExtractIcon::Extract
  297. //
  298. // Purpose: ANSI version of the above Extract
  299. //
  300. // Arguments:
  301. // pszFile [] Filename from where we'll retrieve the icon
  302. // nIconIndex [] Index of the icon (though this is bogus)
  303. // phiconLarge [] Return pointer for the large icon handle
  304. // phiconSmall [] Return pointer for the small icon handle
  305. // nIconSize [] Size of the icon requested.
  306. //
  307. // Returns:
  308. //
  309. // Author: jeffspr 6 Apr 1999
  310. //
  311. // Notes:
  312. //
  313. STDMETHODIMP CConnectionFolderExtractIcon::Extract(
  314. IN PCSTR pszFile,
  315. IN UINT nIconIndex,
  316. OUT HICON * phiconLarge,
  317. OUT HICON * phiconSmall,
  318. IN UINT nIconSize)
  319. {
  320. TraceFileFunc(ttidShellFolderIface);
  321. HRESULT hr = S_OK;
  322. INT cch = 0;
  323. WCHAR * pszFileW = NULL;
  324. Assert(pszFile);
  325. cch = lstrlenA(pszFile) + 1;
  326. pszFileW = new WCHAR[cch];
  327. if (!pszFileW)
  328. {
  329. hr = ERROR_OUTOFMEMORY;
  330. }
  331. else
  332. {
  333. MultiByteToWideChar(CP_ACP, 0, pszFile, -1, pszFileW, cch);
  334. hr = Extract(pszFileW, nIconIndex, phiconLarge, phiconSmall, nIconSize);
  335. delete [] pszFileW;
  336. }
  337. TraceHr(ttidShellFolder, FAL, hr, FALSE, "CConnectionFolderExtractIcon::Extract(A)");
  338. return hr;
  339. }