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.

248 lines
6.6 KiB

  1. #include "shellprv.h"
  2. #pragma hdrstop
  3. #include "xiconwrap.h"
  4. class CExtractIcon : public CExtractIconBase
  5. {
  6. public:
  7. HRESULT _GetIconLocationW(UINT uFlags, LPWSTR pszIconFile, UINT cchMax, int *piIndex, UINT *pwFlags);
  8. HRESULT _ExtractW(LPCWSTR pszFile, UINT nIconIndex, HICON *phiconLarge, HICON *phiconSmall, UINT nIconSize);
  9. HRESULT _Init(LPCWSTR pszModule, LPCWSTR pszModuleOpen);
  10. CExtractIcon(int iIcon, int iIconOpen, int iDefIcon, int iShortcutIcon, UINT uFlags);
  11. private:
  12. ~CExtractIcon();
  13. private:
  14. int _iIcon;
  15. int _iIconOpen;
  16. int _iDefIcon;
  17. int _iShortcutIcon;
  18. UINT _uFlags; // GIL_SIMULATEDOC/PERINSTANCE/PERCLASS
  19. LPWSTR _pszModule;
  20. LPWSTR _pszModuleOpen;
  21. };
  22. CExtractIcon::CExtractIcon(int iIcon, int iIconOpen, int iDefIcon, int iShortcutIcon, UINT uFlags) :
  23. CExtractIconBase(),
  24. _iIcon(iIcon), _iIconOpen(iIconOpen),_iDefIcon(iDefIcon), _iShortcutIcon(iShortcutIcon),
  25. _uFlags(uFlags), _pszModule(NULL), _pszModuleOpen(NULL)
  26. {
  27. }
  28. CExtractIcon::~CExtractIcon()
  29. {
  30. LocalFree((HLOCAL)_pszModule); // accpets NULL
  31. if (_pszModuleOpen != _pszModule)
  32. LocalFree((HLOCAL)_pszModuleOpen); // accpets NULL
  33. }
  34. HRESULT CExtractIcon::_Init(LPCWSTR pszModule, LPCWSTR pszModuleOpen)
  35. {
  36. HRESULT hr = S_OK;
  37. _pszModule = StrDup(pszModule);
  38. if (_pszModule)
  39. {
  40. if (pszModuleOpen)
  41. {
  42. _pszModuleOpen = StrDup(pszModuleOpen);
  43. if (!_pszModuleOpen)
  44. {
  45. LocalFree((HLOCAL)_pszModule);
  46. _pszModule = NULL;
  47. hr = E_OUTOFMEMORY;
  48. }
  49. }
  50. else
  51. {
  52. _pszModuleOpen = _pszModule;
  53. }
  54. }
  55. else
  56. {
  57. hr = E_OUTOFMEMORY;
  58. }
  59. return hr;
  60. }
  61. STDAPI SHCreateDefExtIcon(LPCWSTR pszModule, int iIcon, int iIconOpen, UINT uFlags, int iDefIcon, REFIID riid, void** ppv)
  62. {
  63. return SHCreateDefExtIconKey(NULL, pszModule, iIcon, iIconOpen, iDefIcon, iIcon, uFlags, riid, ppv);
  64. }
  65. // returns S_FALSE to mean "The hkey didn't have an icon so I created a default one"
  66. STDAPI SHCreateDefExtIconKey(HKEY hkey, LPCWSTR pszModule, int iIcon, int iIconOpen, int iDefIcon, int iShortcutIcon, UINT uFlags, REFIID riid, void **ppv)
  67. {
  68. WCHAR szModule[MAX_PATH];
  69. WCHAR szModuleOpen[MAX_PATH];
  70. HRESULT hr;
  71. HRESULT hrSuccess = S_OK;
  72. LPWSTR pszModuleOpen = NULL;
  73. if (hkey)
  74. {
  75. HKEY hkChild;
  76. if (RegOpenKeyEx(hkey, c_szDefaultIcon, 0, KEY_QUERY_VALUE,
  77. &hkChild) == ERROR_SUCCESS)
  78. {
  79. DWORD cb = sizeof(szModule);
  80. if (SHQueryValueEx(hkChild, NULL, NULL, NULL, szModule, &cb) ==
  81. ERROR_SUCCESS && szModule[0])
  82. {
  83. iIcon = PathParseIconLocation(szModule);
  84. iIconOpen = iIcon;
  85. pszModule = szModule;
  86. cb = sizeof(szModuleOpen);
  87. if (SHQueryValueEx(hkChild, TEXT("OpenIcon"), NULL, NULL,
  88. szModuleOpen, &cb) == ERROR_SUCCESS && szModuleOpen[0])
  89. {
  90. iIconOpen = PathParseIconLocation(szModuleOpen);
  91. pszModuleOpen = szModuleOpen;
  92. }
  93. }
  94. else
  95. {
  96. hrSuccess = S_FALSE;
  97. }
  98. RegCloseKey(hkChild);
  99. }
  100. else
  101. {
  102. hrSuccess = S_FALSE;
  103. }
  104. }
  105. if ((NULL == pszModule) || (0 == *pszModule))
  106. {
  107. // REVIEW: We should be able to make it faster!
  108. GetModuleFileName(HINST_THISDLL, szModule, ARRAYSIZE(szModule));
  109. pszModule = szModule;
  110. }
  111. CExtractIcon* pdeib = new CExtractIcon(iIcon, iIconOpen, iDefIcon, iShortcutIcon, uFlags);
  112. if (pdeib)
  113. {
  114. hr = pdeib->_Init(pszModule, pszModuleOpen);
  115. if (SUCCEEDED(hr))
  116. {
  117. hr = pdeib->QueryInterface(riid, ppv);
  118. }
  119. pdeib->Release();
  120. }
  121. else
  122. {
  123. hr = E_OUTOFMEMORY;
  124. }
  125. if (SUCCEEDED(hr))
  126. {
  127. hr = hrSuccess;
  128. }
  129. return hr;
  130. }
  131. HRESULT CExtractIcon::_GetIconLocationW(UINT uFlags, LPWSTR pszIconFile, UINT cchMax, int *piIndex, UINT *pwFlags)
  132. {
  133. HRESULT hr = S_FALSE;
  134. pszIconFile[0] = 0;
  135. if (uFlags & GIL_DEFAULTICON)
  136. {
  137. if (-1 != _iDefIcon)
  138. {
  139. hr = StringCchCopy(pszIconFile, cchMax, c_szShell32Dll);
  140. if (SUCCEEDED(hr))
  141. {
  142. *piIndex = _iDefIcon;
  143. *pwFlags = _uFlags;
  144. // Make sure our default icon makes it to the cache
  145. Shell_GetCachedImageIndex(pszIconFile, *piIndex, *pwFlags);
  146. }
  147. }
  148. }
  149. else
  150. {
  151. int iIcon;
  152. if ((uFlags & GIL_FORSHORTCUT) && (-1 != _iShortcutIcon))
  153. {
  154. iIcon = _iShortcutIcon;
  155. }
  156. else if (uFlags & GIL_OPENICON)
  157. {
  158. iIcon = _iIconOpen;
  159. }
  160. else
  161. {
  162. iIcon = _iIcon;
  163. }
  164. if ((UINT)-1 != iIcon)
  165. {
  166. hr = StringCchCopy(pszIconFile, cchMax, (uFlags & GIL_OPENICON) ? _pszModuleOpen : _pszModule);
  167. if (SUCCEEDED(hr))
  168. {
  169. *piIndex = iIcon;
  170. *pwFlags = _uFlags;
  171. }
  172. }
  173. }
  174. return hr;
  175. }
  176. HRESULT CExtractIcon::_ExtractW(LPCWSTR pszFile, UINT nIconIndex, HICON *phiconLarge, HICON *phiconSmall, UINT nIconSize)
  177. {
  178. HRESULT hr = S_FALSE;
  179. if (_uFlags & GIL_NOTFILENAME)
  180. {
  181. // "*" as the file name means iIndex is already a system
  182. // icon index, we are done.
  183. //
  184. // defview never calls us in this case, but external people will.
  185. if ((L'*' == pszFile[0]) && (0 == pszFile[1]))
  186. {
  187. DebugMsg(DM_TRACE, TEXT("DefExtIcon::_Extract handling '*' for backup"));
  188. HIMAGELIST himlLarge, himlSmall;
  189. Shell_GetImageLists(&himlLarge, &himlSmall);
  190. if (phiconLarge)
  191. *phiconLarge = ImageList_GetIcon(himlLarge, nIconIndex, 0);
  192. if (phiconSmall)
  193. *phiconSmall = ImageList_GetIcon(himlSmall, nIconIndex,
  194. 0);
  195. hr = S_OK;
  196. }
  197. // this is the case where nIconIndex is a unique id for the
  198. // file. always get the first icon.
  199. nIconIndex = 0;
  200. }
  201. if (S_FALSE == hr)
  202. {
  203. hr = SHDefExtractIcon(pszFile, nIconIndex, _uFlags, phiconLarge, phiconSmall, nIconSize);
  204. }
  205. return hr;
  206. }