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.

311 lines
8.0 KiB

  1. //
  2. // CPifFile class
  3. //
  4. // supports:
  5. //
  6. // IPersistFile - "load" a PIF file
  7. // IExtractIcon - extract a icon from a PIF file.
  8. //
  9. #define NO_INCLUDE_UNION
  10. #include "shellprv.h"
  11. ////////////////////////////////////////////////////////////////////////
  12. // PifFile class
  13. ////////////////////////////////////////////////////////////////////////
  14. class PifFile : IShellExtInit, IExtractIcon, IPersistFile
  15. #ifdef UNICODE
  16. , IExtractIconA
  17. #endif
  18. {
  19. public:
  20. // *** IUnknown methods ***
  21. STDMETHODIMP QueryInterface(REFIID riid, void **ppvObject);
  22. STDMETHODIMP_(ULONG) AddRef(void);
  23. STDMETHODIMP_(ULONG) Release(void);
  24. // *** IShellExtInit methods ***
  25. STDMETHODIMP Initialize(LPCITEMIDLIST pidlFolder,LPDATAOBJECT lpdobj, HKEY hkeyProgID);
  26. // *** IPersist methods ***
  27. STDMETHODIMP GetClassID(CLSID *pClassID);
  28. // *** IPersistFile methods ***
  29. STDMETHODIMP IsDirty(void);
  30. STDMETHODIMP Load(LPCOLESTR pszFileName, DWORD dwMode);
  31. STDMETHODIMP Save(LPCOLESTR pszFileName, BOOL fRemember);
  32. STDMETHODIMP SaveCompleted(LPCOLESTR pszFileName);
  33. STDMETHODIMP GetCurFile(LPOLESTR *ppszFileName);
  34. // *** IExtractIcon methods ***
  35. STDMETHODIMP GetIconLocation(UINT uFlags,LPTSTR szIconFile,UINT cchMax,int *piIndex,UINT * pwFlags);
  36. STDMETHODIMP ExtractIcon(LPCTSTR pszFile,UINT nIconIndex,HICON *phiconLarge,HICON *phiconSmall,UINT nIcons);
  37. #ifdef UNICODE
  38. // *** IExtractIconA methods ***
  39. STDMETHODIMP GetIconLocation(UINT uFlags,LPSTR szIconFile,UINT cchMax,int *piIndex,UINT * pwFlags);
  40. STDMETHODIMP ExtractIcon(LPCSTR pszFile,UINT nIconIndex,HICON *phiconLarge,HICON *phiconSmall,UINT nIcons);
  41. #endif
  42. PifFile();
  43. ~PifFile();
  44. //
  45. // data
  46. //
  47. private:
  48. UINT cRef;
  49. int hPifProps;
  50. };
  51. ////////////////////////////////////////////////////////////////////////
  52. //
  53. // CPifFile_CreateInstance
  54. //
  55. // public function to create a instance of a CPifFile
  56. //
  57. ////////////////////////////////////////////////////////////////////////
  58. STDAPI CPifFile_CreateInstance(LPUNKNOWN punkOuter, REFIID riid, LPVOID * ppvOut)
  59. {
  60. HRESULT hres;
  61. PifFile *p;
  62. // does not support aggregation.
  63. if (punkOuter)
  64. return CLASS_E_NOAGGREGATION;
  65. p = new PifFile();
  66. if (p == NULL)
  67. return E_FAIL;
  68. //
  69. // Note that the Release member will free the object, if QueryInterface
  70. // failed.
  71. //
  72. hres = p->QueryInterface(riid, ppvOut);
  73. p->Release();
  74. return hres; // S_OK or E_NOINTERFACE
  75. }
  76. ////////////////////////////////////////////////////////////////////////
  77. // constuct/destruct
  78. ////////////////////////////////////////////////////////////////////////
  79. PifFile::PifFile()
  80. {
  81. this->cRef = 1;
  82. }
  83. PifFile::~PifFile()
  84. {
  85. if (hPifProps)
  86. PifMgr_CloseProperties(hPifProps, 0);
  87. hPifProps=0;
  88. }
  89. ////////////////////////////////////////////////////////////////////////
  90. // IUnknown
  91. ////////////////////////////////////////////////////////////////////////
  92. STDMETHODIMP PifFile::QueryInterface(REFIID riid, LPVOID *ppvObj)
  93. {
  94. if (IsEqualIID(riid, IID_IUnknown))
  95. {
  96. DebugMsg(DM_TRACE, TEXT("PifFile::QueryInterface(IUnknown)"));
  97. *ppvObj = (IUnknown *)this;
  98. }
  99. else if (IsEqualIID(riid, IID_IShellExtInit))
  100. {
  101. DebugMsg(DM_TRACE, TEXT("PifFile::QueryInterface(IShellExtInit)"));
  102. *ppvObj = (IShellExtInit*)this;
  103. }
  104. else if (IsEqualIID(riid, IID_IPersistFile))
  105. {
  106. DebugMsg(DM_TRACE, TEXT("PifFile::QueryInterface(IPersistFile)"));
  107. *ppvObj = (IPersistFile*)this;
  108. }
  109. else if (IsEqualIID(riid, IID_IExtractIcon))
  110. {
  111. DebugMsg(DM_TRACE, TEXT("PifFile::QueryInterface(IExtractIcon)"));
  112. *ppvObj = (IExtractIcon*)this;
  113. }
  114. #ifdef UNICODE
  115. else if (IsEqualIID(riid, IID_IExtractIconA))
  116. {
  117. DebugMsg(DM_TRACE, TEXT("PifFile::QueryInterface(IExtractIconA)"));
  118. *ppvObj = (IExtractIconA*)this;
  119. }
  120. #endif
  121. else
  122. {
  123. *ppvObj = NULL;
  124. return E_NOINTERFACE;
  125. }
  126. AddRef();
  127. return NOERROR;
  128. }
  129. STDMETHODIMP_(ULONG) PifFile::AddRef()
  130. {
  131. DebugMsg(DM_TRACE, TEXT("PifFile::AddRef() ==> %d"), this->cRef+1);
  132. this->cRef++;
  133. return this->cRef;
  134. }
  135. STDMETHODIMP_(ULONG) PifFile::Release()
  136. {
  137. DebugMsg(DM_TRACE, TEXT("PifFile::Release() ==> %d"), this->cRef-1);
  138. this->cRef--;
  139. if (this->cRef>0)
  140. {
  141. return this->cRef;
  142. }
  143. delete this;
  144. return 0;
  145. }
  146. ////////////////////////////////////////////////////////////////////////
  147. // IShellExtInit
  148. ////////////////////////////////////////////////////////////////////////
  149. STDMETHODIMP PifFile::Initialize(LPCITEMIDLIST pidlFolder,LPDATAOBJECT lpdobj, HKEY hkeyProgID)
  150. {
  151. DebugMsg(DM_TRACE, TEXT("PifFile::Initialize()"));
  152. return S_OK;
  153. }
  154. ////////////////////////////////////////////////////////////////////////
  155. // IPersistFile
  156. ////////////////////////////////////////////////////////////////////////
  157. STDMETHODIMP PifFile::GetClassID(LPCLSID lpClassID)
  158. {
  159. DebugMsg(DM_TRACE, TEXT("PifFile::GetClass()"));
  160. *lpClassID = CLSID_PifFile;
  161. return NOERROR;
  162. }
  163. STDMETHODIMP PifFile::IsDirty()
  164. {
  165. DebugMsg(DM_TRACE, TEXT("PifFile::IsDirty()"));
  166. return S_FALSE;
  167. }
  168. STDMETHODIMP PifFile::Load(LPCOLESTR pwszFile, DWORD grfMode)
  169. {
  170. TCHAR szPath[MAX_PATH];
  171. SHUnicodeToTChar(pwszFile, szPath, ARRAYSIZE(szPath));
  172. DebugMsg(DM_TRACE, TEXT("PifFile::Load(%s)"), szPath);
  173. if (hPifProps)
  174. PifMgr_CloseProperties(hPifProps, 0);
  175. hPifProps = PifMgr_OpenProperties(szPath, NULL, 0, 0);
  176. return hPifProps == 0 ? E_FAIL : S_OK;
  177. }
  178. STDMETHODIMP PifFile::Save(LPCOLESTR pwszFile, BOOL fRemember)
  179. {
  180. return E_NOTIMPL;
  181. }
  182. STDMETHODIMP PifFile::SaveCompleted(LPCOLESTR pwszFile)
  183. {
  184. return E_NOTIMPL;
  185. }
  186. STDMETHODIMP PifFile::GetCurFile(LPOLESTR * lplpszFileName)
  187. {
  188. return E_NOTIMPL;
  189. }
  190. ////////////////////////////////////////////////////////////////////////
  191. // IExtractIcon
  192. ////////////////////////////////////////////////////////////////////////
  193. STDMETHODIMP PifFile::GetIconLocation(UINT uFlags, LPTSTR szIconFile,UINT cchMax,int *piIndex,UINT * pwFlags)
  194. {
  195. PROPPRG ProgramProps;
  196. VDATEINPUTBUF(szIconFile, TCHAR, cchMax);
  197. if (hPifProps == 0)
  198. return E_FAIL;
  199. if (!PifMgr_GetProperties(hPifProps,MAKEINTATOM(GROUP_PRG), &ProgramProps, SIZEOF(ProgramProps), 0))
  200. {
  201. DebugMsg(DM_TRACE, TEXT("PifFile::GetIconLocation() PifMgr_GetProperties *failed*"));
  202. return E_FAIL;
  203. }
  204. if (ProgramProps.achIconFile[0] == 0)
  205. {
  206. lstrcpy(szIconFile, ICONFILE_DEFAULT);
  207. *piIndex = ICONINDEX_DEFAULT;
  208. }
  209. else
  210. {
  211. lstrcpy(szIconFile, ProgramProps.achIconFile);
  212. *piIndex = ProgramProps.wIconIndex;
  213. }
  214. *pwFlags = 0;
  215. DebugMsg(DM_TRACE, TEXT("PifFile::GetIconLocation() ==> %s!%d"), szIconFile, *piIndex);
  216. return S_OK;
  217. }
  218. STDMETHODIMP PifFile::ExtractIcon(LPCTSTR pszFile,UINT nIconIndex,HICON *phiconLarge,HICON *phiconSmall,UINT nIcons)
  219. {
  220. DebugMsg(DM_TRACE, TEXT("PifFile::ExtractIcon()"));
  221. return E_NOTIMPL;
  222. }
  223. #ifdef UNICODE
  224. ////////////////////////////////////////////////////////////////////////
  225. // IExtractIconA
  226. ////////////////////////////////////////////////////////////////////////
  227. STDMETHODIMP PifFile::GetIconLocation(UINT uFlags, LPSTR pszIconFile, UINT cchMax,int *piIndex, UINT * pwFlags)
  228. {
  229. WCHAR szIconFile[MAX_PATH];
  230. HRESULT hres;
  231. VDATEINPUTBUF(pszIconFile, TCHAR, cchMax);
  232. DebugMsg(DM_TRACE, TEXT("PifFile::IExtractIconA::GetIconLocation()"));
  233. hres = this->GetIconLocation(uFlags,szIconFile,ARRAYSIZE(szIconFile), piIndex, pwFlags);
  234. //
  235. // We don't want to copy the icon file name on the S_FALSE case
  236. //
  237. if (SUCCEEDED(hres) && hres != S_FALSE)
  238. {
  239. SHUnicodeToAnsi(szIconFile, pszIconFile, cchMax);
  240. }
  241. return hres;
  242. }
  243. STDMETHODIMP PifFile::ExtractIcon(LPCSTR pszFile,UINT nIconIndex,HICON *phiconLarge,HICON *phiconSmall,UINT nIcons)
  244. {
  245. DebugMsg(DM_TRACE, TEXT("PifFile::IExtractIconA::ExtractIcon()"));
  246. return E_NOTIMPL;
  247. }
  248. #endif