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.

237 lines
6.7 KiB

  1. //+----------------------------------------------------------------------------
  2. //
  3. // File: ShellDll.cpp
  4. //
  5. // Module: Common Code
  6. //
  7. // Synopsis: Implements the class CShellDll, a shell32.dll wrapper.
  8. //
  9. // Copyright (c) 1999 Microsoft Corporation
  10. //
  11. // Author: fengsun Created 01/12/98
  12. //
  13. //+----------------------------------------------------------------------------
  14. //+----------------------------------------------------------------------------
  15. //
  16. // Function: CShellDll::CShellDll
  17. //
  18. // Synopsis: Constructor
  19. //
  20. // Arguments: None
  21. //
  22. // Returns: Nothing
  23. //
  24. // History: Created Header 2/17/98
  25. //
  26. //+----------------------------------------------------------------------------
  27. CShellDll::CShellDll(BOOL fKeepDllLoaded)
  28. {
  29. m_hInstShell = NULL;
  30. m_fnShellExecuteEx = NULL;
  31. m_fnShell_NotifyIcon = NULL;
  32. m_pfnSHGetSpecialFolderLocation = NULL;
  33. m_pfnSHGetPathFromIDList = NULL;
  34. m_pfnSHGetMalloc = NULL;
  35. m_KeepDllLoaded = fKeepDllLoaded;
  36. }
  37. //+----------------------------------------------------------------------------
  38. //
  39. // Function: CShellDll::~CShellDl
  40. //
  41. // Synopsis: Destructor
  42. //
  43. // Arguments: None
  44. //
  45. // Returns: Nothing
  46. //
  47. // History: Created Header 2/17/98
  48. //
  49. //+----------------------------------------------------------------------------
  50. CShellDll::~CShellDll()
  51. {
  52. Unload();
  53. }
  54. //+----------------------------------------------------------------------------
  55. //
  56. // Function: CShellDll::Load
  57. //
  58. // Synopsis: Load shell32.dll
  59. // It works even if the dll is already loaded, but we do not keep a referrence
  60. // count here, any unload call will unload the dll
  61. //
  62. // Arguments: None
  63. //
  64. // Returns: BOOL - Whether the dll is successfully loaded
  65. //
  66. // History: fengsun Created Header 1/12/98
  67. //
  68. //+----------------------------------------------------------------------------
  69. BOOL CShellDll::Load()
  70. {
  71. //
  72. // Simply return, if already loaded
  73. //
  74. LPSTR pszShellExecuteEx;
  75. LPSTR pszShellNotifyIcon;
  76. LPSTR pszSHGetPathFromIDList;
  77. LPSTR pszSHGetSpecialFolderLocation;
  78. LPSTR pszSHGetMalloc;
  79. if (m_hInstShell == NULL)
  80. {
  81. if (OS_NT)
  82. {
  83. m_hInstShell = LoadLibraryExA("Shell32.dll", NULL, 0);
  84. pszShellExecuteEx = "ShellExecuteExW";
  85. pszShellNotifyIcon = "Shell_NotifyIconW";
  86. pszSHGetPathFromIDList = "SHGetPathFromIDListW";
  87. pszSHGetSpecialFolderLocation = "SHGetSpecialFolderLocation"; // no A or W version
  88. pszSHGetMalloc = "SHGetMalloc"; // no A or W version
  89. }
  90. else
  91. {
  92. m_hInstShell = LoadLibraryExA("cmutoa.dll", NULL, 0);
  93. pszShellExecuteEx = "ShellExecuteExUA";
  94. pszShellNotifyIcon = "Shell_NotifyIconUA";
  95. pszSHGetPathFromIDList = "SHGetPathFromIDListUA";
  96. pszSHGetSpecialFolderLocation = "SHGetSpecialFolderLocationUA"; // no actual A or W version
  97. pszSHGetMalloc = "SHGetMallocUA"; // but this class only
  98. // allows one dll
  99. }
  100. if (m_hInstShell == NULL)
  101. {
  102. return FALSE;
  103. }
  104. m_pfnSHGetMalloc = (SHGetMallocSpec)GetProcAddress(m_hInstShell, pszSHGetMalloc);
  105. m_pfnSHGetSpecialFolderLocation = (SHGetSpecialFolderLocationSpec)GetProcAddress(m_hInstShell, pszSHGetSpecialFolderLocation);
  106. m_pfnSHGetPathFromIDList = (SHGetPathFromIDListSpec)GetProcAddress(m_hInstShell, pszSHGetPathFromIDList);
  107. m_fnShellExecuteEx = (SHELLEXECUTEEXPROC)GetProcAddress(m_hInstShell, pszShellExecuteEx);
  108. m_fnShell_NotifyIcon = (SHELL_NOTIFYICONPROC)GetProcAddress(m_hInstShell, pszShellNotifyIcon);
  109. if (NULL == m_fnShellExecuteEx || NULL == m_fnShell_NotifyIcon ||
  110. NULL == m_pfnSHGetSpecialFolderLocation || NULL == m_pfnSHGetPathFromIDList ||
  111. NULL == m_pfnSHGetMalloc)
  112. {
  113. FreeLibrary(m_hInstShell);
  114. m_hInstShell = NULL;
  115. return FALSE;
  116. }
  117. }
  118. return TRUE;
  119. }
  120. //+----------------------------------------------------------------------------
  121. //
  122. // Function: CShellDll::Unload
  123. //
  124. // Synopsis: Unload the shell32.dll
  125. //
  126. // Arguments: None
  127. //
  128. // Returns: Nothing
  129. //
  130. // History: fengsun Created Header 1/12/98
  131. //
  132. //+----------------------------------------------------------------------------
  133. void CShellDll::Unload()
  134. {
  135. if (m_hInstShell == NULL)
  136. {
  137. return;
  138. }
  139. //
  140. // Don't release library because of shell bug #289463 + #371836
  141. // ShellExecute fires a thread which wakes up after the release
  142. // of the library and crashes us. Ugly but real, we have no choice
  143. // but to stay linked to the Shell DLL.
  144. //
  145. if (!m_KeepDllLoaded)
  146. {
  147. FreeLibrary(m_hInstShell);
  148. m_hInstShell = NULL;
  149. }
  150. }
  151. //+----------------------------------------------------------------------------
  152. //
  153. // Function: CShellDll::ShellGetSpecialFolderLocation
  154. //
  155. // Synopsis: Wrapper function for SHGetSpecialFolderLocation. Please note the
  156. // returned pidl must be freed with the Shell's Malloc pointer (use SHGetMalloc).
  157. //
  158. // Arguments: Please see the api definition for SHGetSpecialFolderLocation
  159. //
  160. // Returns: HRESULT - standard COM error codes
  161. //
  162. // History: quintinb Created 5/21/99
  163. //
  164. //+----------------------------------------------------------------------------
  165. HRESULT CShellDll::ShellGetSpecialFolderLocation(HWND hwnd, int csidl, LPITEMIDLIST *ppidl)
  166. {
  167. if (!Load())
  168. {
  169. return E_FAIL;
  170. }
  171. return m_pfnSHGetSpecialFolderLocation(hwnd, csidl, ppidl);
  172. }
  173. //+----------------------------------------------------------------------------
  174. //
  175. // Function: CShellDll::ShellGetPathFromIDList
  176. //
  177. // Synopsis: Wrapper function for SHGetPathFromIDList.
  178. //
  179. // Arguments: Please see the api definition for SHGetPathFromIDList
  180. //
  181. // Returns: BOOL - TRUE on success
  182. //
  183. // History: quintinb Created 5/21/99
  184. //
  185. //+----------------------------------------------------------------------------
  186. BOOL CShellDll::ShellGetPathFromIDList(LPCITEMIDLIST pidl, LPTSTR pszPath)
  187. {
  188. if (!Load())
  189. {
  190. return FALSE;
  191. }
  192. return m_pfnSHGetPathFromIDList(pidl, pszPath);
  193. }
  194. //+----------------------------------------------------------------------------
  195. //
  196. // Function: CShellDll::ShellGetMalloc
  197. //
  198. // Synopsis: Wrapper function for SHGetMalloc.
  199. //
  200. // Arguments: Please see the api definition for SHGetMalloc
  201. //
  202. // Returns: HRESULT - Standard COM Error Codes
  203. //
  204. // History: quintinb Created 5/21/99
  205. //
  206. //+----------------------------------------------------------------------------
  207. HRESULT CShellDll::ShellGetMalloc(LPMALLOC * ppMalloc)
  208. {
  209. if (!Load())
  210. {
  211. return E_FAIL;
  212. }
  213. return m_pfnSHGetMalloc(ppMalloc);
  214. }