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.

291 lines
10 KiB

  1. /*******************************************************************************
  2. *
  3. * (C) COPYRIGHT MICROSOFT CORPORATION, 1998
  4. *
  5. * TITLE: UIEXTHLP.CPP
  6. *
  7. * VERSION: 1.0
  8. *
  9. * AUTHOR: ShaunIv
  10. *
  11. * DATE: 7/8/1999
  12. *
  13. * DESCRIPTION: Helper functions for loading UI extensions for WIA devices
  14. *
  15. *******************************************************************************/
  16. #include "precomp.h"
  17. #pragma hdrstop
  18. #include <initguid.h>
  19. #include "uiexthlp.h"
  20. #include "wiadevd.h"
  21. #include "wiadevdp.h"
  22. #include "itranhlp.h"
  23. #include "isuppfmt.h"
  24. #include "wiaffmt.h"
  25. namespace WiaUiExtensionHelper
  26. {
  27. /*
  28. * Get the clsid of the DLL that implements the interface in the given category
  29. * Example: GetDeviceExtensionClassID( L"{5d8ef5a3-ac13-11d2-a093-00c04f72dc3c}", TEXT("WiaDialogExtensionHandlers"), iid );
  30. * where:
  31. * L"{5d8ef5a3-ac13-11d2-a093-00c04f72dc3c}" is the GUID stored in the WIA property WIA_DIP_UI_CLSID
  32. * TEXT("WiaDialogExtensionHandlers") is the category of extension
  33. * iid is a reference to the CLSID of the in process COM object
  34. */
  35. HRESULT GetDeviceExtensionClassID( LPCWSTR pwszUiClassId, LPCTSTR pszCategory, IID &iidClassID )
  36. {
  37. TCHAR szRootKeyName[1024];
  38. HRESULT hr = E_FAIL;
  39. // Make sure all of the parameters are valid
  40. if (pwszUiClassId && pszCategory && lstrlenW(pwszUiClassId) && lstrlen(pszCategory))
  41. {
  42. // construct the key name
  43. wsprintf( szRootKeyName, TEXT("CLSID\\%ws\\shellex\\%s"), pwszUiClassId, pszCategory );
  44. HKEY hKeyRoot;
  45. // open the reg key
  46. DWORD dwResult = RegOpenKeyEx( HKEY_CLASSES_ROOT, szRootKeyName, 0, KEY_READ, &hKeyRoot );
  47. if (ERROR_SUCCESS == dwResult)
  48. {
  49. TCHAR szClassID[MAX_PATH];
  50. DWORD dwLength = ARRAYSIZE(szClassID);
  51. // Note that we only take the first one
  52. dwResult = RegEnumKeyEx( hKeyRoot, 0, szClassID, &dwLength, NULL, NULL, NULL, NULL );
  53. if (ERROR_SUCCESS == dwResult)
  54. {
  55. #if defined(UNICODE)
  56. hr = CLSIDFromString(szClassID, &iidClassID);
  57. #else
  58. WCHAR wszClassID[MAX_PATH];
  59. MultiByteToWideChar (CP_ACP, 0, szClassID, -1, wszClassID, MAX_PATH );
  60. hr = CLSIDFromString (wszClassID, &iidClassID);
  61. #endif
  62. }
  63. else hr = HRESULT_FROM_WIN32(dwResult);
  64. RegCloseKey(hKeyRoot);
  65. }
  66. else hr = HRESULT_FROM_WIN32(dwResult);
  67. }
  68. else hr = E_INVALIDARG;
  69. return hr;
  70. }
  71. HRESULT CreateDeviceExtension( LPCWSTR pwszUiClassId, LPCTSTR pszCategory, const IID &iid, void **ppvObject )
  72. {
  73. IID iidClassID;
  74. HRESULT hr = GetDeviceExtensionClassID( pwszUiClassId, pszCategory, iidClassID );
  75. if (SUCCEEDED(hr))
  76. {
  77. WIA_PRINTGUID((iidClassID,TEXT("Calling CoCreateInstance on")));
  78. WIA_PRINTGUID((iid,TEXT("Attempting to get an interface pointer for")));
  79. hr = CoCreateInstance( iidClassID, NULL, CLSCTX_INPROC_SERVER, iid, ppvObject );
  80. }
  81. return hr;
  82. }
  83. HRESULT GetUiGuidFromWiaItem( IWiaItem *pWiaItem, LPWSTR pwszGuid )
  84. {
  85. IWiaPropertyStorage *pPropertyStorage = NULL;
  86. HRESULT hr;
  87. if (pWiaItem && pwszGuid)
  88. {
  89. hr = pWiaItem->QueryInterface( IID_IWiaPropertyStorage, (void**)&pPropertyStorage );
  90. if (SUCCEEDED(hr))
  91. {
  92. PROPSPEC ps[1];
  93. PROPVARIANT pv[1];
  94. ps[0].ulKind = PRSPEC_PROPID;
  95. ps[0].propid = WIA_DIP_UI_CLSID;
  96. hr = pPropertyStorage->ReadMultiple(sizeof(ps)/sizeof(ps[0]), ps, pv);
  97. if (SUCCEEDED(hr))
  98. {
  99. if (VT_LPWSTR == pv[0].vt || VT_BSTR == pv[0].vt)
  100. {
  101. lstrcpyW( pwszGuid, pv[0].bstrVal );
  102. hr = S_OK;
  103. }
  104. FreePropVariantArray( sizeof(pv)/sizeof(pv[0]), pv );
  105. }
  106. pPropertyStorage->Release();
  107. }
  108. }
  109. else hr = E_INVALIDARG;
  110. return hr;
  111. }
  112. HRESULT GetDeviceExtensionClassID( IWiaItem *pWiaItem, LPCTSTR pszCategory, IID &iidClassID )
  113. {
  114. WCHAR wszGuid[MAX_PATH];
  115. HRESULT hr = GetUiGuidFromWiaItem(pWiaItem,wszGuid);
  116. if (SUCCEEDED(hr))
  117. {
  118. hr = GetDeviceExtensionClassID( wszGuid, pszCategory, iidClassID );
  119. }
  120. return hr;
  121. }
  122. HRESULT CreateDeviceExtension( IWiaItem *pWiaItem, LPCTSTR pszCategory, const IID &iid, void **ppvObject )
  123. {
  124. WCHAR wszGuid[MAX_PATH];
  125. HRESULT hr = GetUiGuidFromWiaItem(pWiaItem,wszGuid);
  126. if (SUCCEEDED(hr))
  127. {
  128. hr = CreateDeviceExtension( wszGuid, pszCategory, iid, ppvObject );
  129. }
  130. return hr;
  131. }
  132. HRESULT GetDeviceIcons( IWiaUIExtension *pWiaUIExtension, BSTR bstrDeviceId, HICON *phIconSmall, HICON *phIconLarge, UINT nIconSize )
  133. {
  134. if (!pWiaUIExtension || !bstrDeviceId || !lstrlenW(bstrDeviceId))
  135. return E_INVALIDARG;
  136. // Assume success
  137. HRESULT hr = S_OK;
  138. // Get the small icon, if requested. Return on failure
  139. if (phIconSmall)
  140. {
  141. hr = pWiaUIExtension->GetDeviceIcon(bstrDeviceId,phIconSmall,HIWORD(nIconSize));
  142. if (FAILED(hr))
  143. {
  144. return hr;
  145. }
  146. }
  147. // Get the large icon, if requested. Return on failure
  148. if (phIconLarge)
  149. {
  150. hr = pWiaUIExtension->GetDeviceIcon(bstrDeviceId,phIconLarge,LOWORD(nIconSize));
  151. if (FAILED(hr))
  152. {
  153. return hr;
  154. }
  155. }
  156. return hr;
  157. }
  158. HRESULT GetDeviceIcons( BSTR bstrDeviceId, LONG nDeviceType, HICON *phIconSmall, HICON *phIconLarge, UINT nIconSize )
  159. {
  160. WIA_PUSH_FUNCTION((TEXT("GetDeviceIcons( %ws, %08X, %p, %p, %d )"), bstrDeviceId, nDeviceType, phIconSmall, phIconLarge, nIconSize ));
  161. // Check args
  162. if (!bstrDeviceId || !lstrlenW(bstrDeviceId))
  163. {
  164. return E_INVALIDARG;
  165. }
  166. // Initialize the icons, if necessary
  167. if (phIconSmall)
  168. {
  169. *phIconSmall = NULL;
  170. }
  171. if (phIconLarge)
  172. {
  173. *phIconLarge = NULL;
  174. }
  175. if (!nIconSize)
  176. {
  177. int iLarge = GetSystemMetrics(SM_CXICON);
  178. int iSmall = GetSystemMetrics(SM_CXSMICON);
  179. nIconSize = (UINT)MAKELONG(iLarge, iSmall);
  180. }
  181. // Assume we'll use our own icons
  182. bool bUseDefaultUI = true;
  183. // Try to load device ui extension
  184. CComPtr<IWiaUIExtension> pWiaUIExtension;
  185. HRESULT hr = WiaUiExtensionHelper::CreateDeviceExtension( bstrDeviceId, SHELLEX_WIAUIEXTENSION_NAME, IID_IWiaUIExtension, (void **)&pWiaUIExtension );
  186. if (SUCCEEDED(hr))
  187. {
  188. hr = GetDeviceIcons( pWiaUIExtension, bstrDeviceId, phIconSmall, phIconLarge, nIconSize );
  189. if (SUCCEEDED(hr) || hr != E_NOTIMPL)
  190. {
  191. bUseDefaultUI = false;
  192. }
  193. WIA_PRINTHRESULT((hr,TEXT("GetDeviceIcons returned")));
  194. }
  195. else
  196. {
  197. WIA_PRINTHRESULT((hr,TEXT("WiaUiExtensionHelper::CreateDeviceExtension failed")));
  198. }
  199. WIA_TRACE((TEXT("bUseDefaultUI: %d"), bUseDefaultUI ));
  200. // Use our own extensions (the default UI). We use IWiaMiscellaneousHelpers::GetDeviceIcon, because
  201. // finding the device type given only a device id is horribly slow, since we have to create a device
  202. // manager AND enumerate devices until we find a match. Ugh.
  203. if (bUseDefaultUI)
  204. {
  205. CComPtr<IWiaMiscellaneousHelpers> pWiaMiscellaneousHelpers;
  206. hr = CoCreateInstance( CLSID_WiaDefaultUi, NULL, CLSCTX_INPROC_SERVER, IID_IWiaMiscellaneousHelpers, (void**)(&pWiaMiscellaneousHelpers) );
  207. if (SUCCEEDED(hr) && phIconSmall)
  208. {
  209. hr = pWiaMiscellaneousHelpers->GetDeviceIcon( nDeviceType, phIconSmall, HIWORD(nIconSize));
  210. }
  211. if (SUCCEEDED(hr) && phIconLarge)
  212. {
  213. hr = pWiaMiscellaneousHelpers->GetDeviceIcon( nDeviceType, phIconLarge, LOWORD(nIconSize) );
  214. }
  215. if (FAILED(hr))
  216. {
  217. if (phIconSmall && *phIconSmall)
  218. {
  219. DestroyIcon(*phIconSmall);
  220. }
  221. if (phIconLarge && *phIconLarge)
  222. {
  223. DestroyIcon(*phIconLarge);
  224. }
  225. }
  226. }
  227. return hr;
  228. }
  229. CSimpleString GetExtensionFromGuid( IWiaItem *pWiaItem, const GUID &guidFormat )
  230. {
  231. //
  232. // Use the supplied format to get the extension
  233. //
  234. GUID guidFormatToUse = guidFormat;
  235. //
  236. // If we don't have a supplied format, get the default format and use that
  237. //
  238. if (IID_NULL == guidFormatToUse)
  239. {
  240. //
  241. // Get the IWiaSupportedFormats interface
  242. //
  243. CComPtr<IWiaSupportedFormats> pWiaSupportedFormats;
  244. HRESULT hr = CoCreateInstance( CLSID_WiaDefaultUi, NULL, CLSCTX_INPROC_SERVER, IID_IWiaSupportedFormats, (void**)&pWiaSupportedFormats );
  245. if (SUCCEEDED(hr))
  246. {
  247. //
  248. // Tell it we want file information for pWiaItem
  249. //
  250. hr = pWiaSupportedFormats->Initialize( pWiaItem, TYMED_FILE );
  251. if (SUCCEEDED(hr))
  252. {
  253. //
  254. // Get the default format
  255. //
  256. GUID guidDefFormat;
  257. hr = pWiaSupportedFormats->GetDefaultClipboardFileFormat( &guidDefFormat );
  258. if (SUCCEEDED(hr))
  259. {
  260. //
  261. // Save this format and use it.
  262. //
  263. guidFormatToUse = guidDefFormat;
  264. }
  265. }
  266. }
  267. }
  268. return CWiaFileFormat::GetExtension( guidFormatToUse, TYMED_FILE, pWiaItem );
  269. }
  270. }