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.

339 lines
9.8 KiB

  1. /*******************************************************************************
  2. *
  3. * (C) COPYRIGHT MICROSOFT CORP., 1997
  4. *
  5. * TITLE: DevDlg.Cpp
  6. *
  7. * VERSION: 2.0
  8. *
  9. * AUTHOR: ReedB
  10. *
  11. * DATE: 3 Apr, 1998
  12. *
  13. * DESCRIPTION:
  14. * Implements device dialog UI for WIA devices. These methods execute
  15. * only on the client side.
  16. *
  17. *******************************************************************************/
  18. #include <objbase.h>
  19. #include <stdio.h>
  20. #include <tchar.h>
  21. #include "wia.h"
  22. #include "sti.h"
  23. #include "wiadevd.h"
  24. #include <initguid.h>
  25. #include "wiadevdp.h"
  26. HRESULT GetDeviceExtensionClassID( LPCWSTR pwszUiClassId, LPCTSTR pszCategory, IID &iidClassID )
  27. {
  28. HRESULT hr = E_FAIL;
  29. //
  30. // Make sure all of the parameters are valid
  31. //
  32. if (pwszUiClassId && pszCategory && lstrlenW(pwszUiClassId) && lstrlen(pszCategory))
  33. {
  34. //
  35. // Construct the key name
  36. //
  37. TCHAR szRootKeyName[1024] = {0};
  38. _sntprintf( szRootKeyName, (sizeof(szRootKeyName)/sizeof(szRootKeyName[0])) - 1, TEXT("CLSID\\%ws\\shellex\\%s"), pwszUiClassId, pszCategory );
  39. //
  40. // open the reg key
  41. //
  42. HKEY hKeyRoot = NULL;
  43. DWORD dwResult = RegOpenKeyEx( HKEY_CLASSES_ROOT, szRootKeyName, 0, KEY_READ, &hKeyRoot );
  44. if (ERROR_SUCCESS == dwResult)
  45. {
  46. //
  47. // Get the buffer size
  48. //
  49. TCHAR szClassID[MAX_PATH] = {0};
  50. DWORD dwLength = sizeof(szClassID)/sizeof(szClassID[0]);
  51. //
  52. // Note that we only take the first registry key
  53. //
  54. dwResult = RegEnumKeyEx( hKeyRoot, 0, szClassID, &dwLength, NULL, NULL, NULL, NULL );
  55. if (ERROR_SUCCESS == dwResult)
  56. {
  57. //
  58. // Convert the registry string to a CLSID
  59. //
  60. #if defined(UNICODE)
  61. hr = CLSIDFromString( szClassID, &iidClassID );
  62. #else
  63. WCHAR wszClassID[MAX_PATH] = {0};
  64. MultiByteToWideChar( CP_ACP, 0, szClassID, -1, wszClassID, MAX_PATH );
  65. hr = CLSIDFromString( wszClassID, &iidClassID );
  66. #endif
  67. }
  68. else hr = HRESULT_FROM_WIN32(dwResult);
  69. //
  70. // Close the registry key
  71. //
  72. RegCloseKey(hKeyRoot);
  73. }
  74. else
  75. {
  76. hr = HRESULT_FROM_WIN32(dwResult);
  77. }
  78. }
  79. else
  80. {
  81. hr = E_INVALIDARG;
  82. }
  83. return hr;
  84. }
  85. HRESULT CreateDeviceExtension( LPCWSTR pwszUiClassId, LPCTSTR pszCategory, const IID &iid, void **ppvObject )
  86. {
  87. IID iidClassID = {0};
  88. HRESULT hr = GetDeviceExtensionClassID( pwszUiClassId, pszCategory, iidClassID );
  89. if (SUCCEEDED(hr))
  90. {
  91. hr = CoCreateInstance( iidClassID, NULL, CLSCTX_INPROC_SERVER, iid, ppvObject );
  92. }
  93. return hr;
  94. }
  95. HRESULT GetUiGuidFromWiaItem( IWiaItem *pWiaItem, LPWSTR pwszGuid, size_t nMaxLen )
  96. {
  97. HRESULT hr;
  98. if (pWiaItem && pwszGuid)
  99. {
  100. IWiaPropertyStorage *pWiaPropertyStorage = NULL;
  101. hr = pWiaItem->QueryInterface( IID_IWiaPropertyStorage, (void**)&pWiaPropertyStorage );
  102. if (SUCCEEDED(hr))
  103. {
  104. PROPSPEC ps[1];
  105. PROPVARIANT pv[1];
  106. ps[0].ulKind = PRSPEC_PROPID;
  107. ps[0].propid = WIA_DIP_UI_CLSID;
  108. hr = pWiaPropertyStorage->ReadMultiple(sizeof(ps)/sizeof(ps[0]), ps, pv );
  109. if (SUCCEEDED(hr))
  110. {
  111. if (VT_LPWSTR == pv[0].vt || VT_BSTR == pv[0].vt)
  112. {
  113. lstrcpynW( pwszGuid, pv[0].bstrVal, nMaxLen );
  114. hr = S_OK;
  115. }
  116. FreePropVariantArray( sizeof(pv)/sizeof(pv[0]), pv );
  117. }
  118. pWiaPropertyStorage->Release();
  119. }
  120. }
  121. else
  122. {
  123. hr = E_INVALIDARG;
  124. }
  125. return hr;
  126. }
  127. HRESULT GetDeviceExtensionClassID( IWiaItem *pWiaItem, LPCTSTR pszCategory, IID &iidClassID )
  128. {
  129. WCHAR wszGuid[MAX_PATH] = {0};
  130. HRESULT hr = GetUiGuidFromWiaItem(pWiaItem,wszGuid,sizeof(wszGuid)/sizeof(wszGuid[0]));
  131. if (SUCCEEDED(hr))
  132. {
  133. hr = GetDeviceExtensionClassID( wszGuid, pszCategory, iidClassID );
  134. }
  135. return hr;
  136. }
  137. HRESULT CreateDeviceExtension( IWiaItem *pWiaItem, LPCTSTR pszCategory, const IID &iid, void **ppvObject )
  138. {
  139. WCHAR wszGuid[MAX_PATH] = {0};
  140. HRESULT hr = GetUiGuidFromWiaItem(pWiaItem,wszGuid,sizeof(wszGuid)/sizeof(wszGuid[0]));
  141. if (SUCCEEDED(hr))
  142. {
  143. hr = CreateDeviceExtension( wszGuid, pszCategory, iid, ppvObject );
  144. }
  145. return hr;
  146. }
  147. /*******************************************************************************
  148. *
  149. * InvokeVendorDeviceDlg
  150. *
  151. * DESCRIPTION:
  152. * Helper function which displays the system-supplied device dlg
  153. *
  154. * PARAMETERS:
  155. *
  156. *******************************************************************************/
  157. static HRESULT InvokeSystemDeviceDlg(
  158. IWiaItem __RPC_FAR *This,
  159. DEVICEDIALOGDATA &DeviceDialogData )
  160. {
  161. IWiaUIExtension *pIWiaUIExtension = NULL;
  162. HRESULT hr = CoCreateInstance( CLSID_WiaDefaultUi, NULL, CLSCTX_INPROC_SERVER, IID_IWiaUIExtension, (void**)(&pIWiaUIExtension) );
  163. if (SUCCEEDED(hr))
  164. {
  165. //
  166. // The following call will return E_NOTIMPL if it is a device type
  167. // we don't handle in the system UI
  168. //
  169. hr = pIWiaUIExtension->DeviceDialog(&DeviceDialogData);
  170. pIWiaUIExtension->Release();
  171. }
  172. return hr;
  173. }
  174. /*******************************************************************************
  175. *
  176. * InvokeVendorDeviceDlg
  177. *
  178. * DESCRIPTION:
  179. * Helper function which displays the IHV-supplied device dlg
  180. *
  181. * PARAMETERS:
  182. *
  183. *******************************************************************************/
  184. static HRESULT InvokeVendorDeviceDlg(
  185. IWiaItem __RPC_FAR *This,
  186. DEVICEDIALOGDATA &DeviceDialogData )
  187. {
  188. IWiaUIExtension *pIWiaUIExtension = NULL;
  189. HRESULT hr = CreateDeviceExtension( This, SHELLEX_WIAUIEXTENSION_NAME, IID_IWiaUIExtension, (void**)(&pIWiaUIExtension) );
  190. if (SUCCEEDED(hr))
  191. {
  192. //
  193. // The following call will return E_NOTIMPL if the IHV has
  194. // not implemented a custom UI
  195. //
  196. hr = pIWiaUIExtension->DeviceDialog(&DeviceDialogData);
  197. pIWiaUIExtension->Release();
  198. }
  199. else
  200. {
  201. //
  202. // We want to override this return value, so we can
  203. // handle it by showing the system UI as a fallback.
  204. // Basically, we are going to assume a failure to create
  205. // the extension means that the extension doesn't exist.
  206. // We don't do that for the system UI, because if it can't
  207. // load, that is considered a catastrophic failure.
  208. //
  209. hr = E_NOTIMPL;
  210. }
  211. return hr;
  212. }
  213. /*******************************************************************************
  214. *
  215. * IWiaItem_DeviceDlg_Proxy
  216. *
  217. * DESCRIPTION:
  218. * Display device data acquistion UI.
  219. *
  220. * PARAMETERS:
  221. *
  222. *******************************************************************************/
  223. HRESULT _stdcall IWiaItem_DeviceDlg_Proxy(
  224. IWiaItem __RPC_FAR *This,
  225. HWND hwndParent,
  226. LONG lFlags,
  227. LONG lIntent,
  228. LONG *plItemCount,
  229. IWiaItem ***ppIWiaItems)
  230. {
  231. HRESULT hr = E_FAIL;
  232. //
  233. // Make sure we have valid pointer arguments
  234. //
  235. if (!plItemCount || !ppIWiaItems)
  236. {
  237. return E_POINTER;
  238. }
  239. //
  240. // Initialize the OUT arguments
  241. //
  242. *plItemCount = 0;
  243. *ppIWiaItems = NULL;
  244. //
  245. // Verify that this is a root item.
  246. //
  247. LONG lItemType = 0;
  248. hr = This->GetItemType(&lItemType);
  249. if ((FAILED(hr)) || !(lItemType & WiaItemTypeRoot))
  250. {
  251. return E_INVALIDARG;
  252. }
  253. //
  254. // Prepare the struct we will be passing to the function
  255. //
  256. DEVICEDIALOGDATA DeviceDialogData = {0};
  257. DeviceDialogData.cbSize = sizeof(DeviceDialogData);
  258. DeviceDialogData.hwndParent = hwndParent;
  259. DeviceDialogData.pIWiaItemRoot = This;
  260. DeviceDialogData.dwFlags = lFlags;
  261. DeviceDialogData.lIntent = lIntent;
  262. DeviceDialogData.ppWiaItems = *ppIWiaItems;
  263. //
  264. // If the client wants to use the system UI, the order we try to do it in is:
  265. // System UI --> IHV UI
  266. // Otherwise, we do:
  267. // IHV UI --> System UI
  268. //
  269. if (0 == (lFlags & WIA_DEVICE_DIALOG_USE_COMMON_UI))
  270. {
  271. hr = InvokeVendorDeviceDlg( This, DeviceDialogData );
  272. if (E_NOTIMPL == hr)
  273. {
  274. hr = InvokeSystemDeviceDlg( This, DeviceDialogData );
  275. }
  276. }
  277. else
  278. {
  279. hr = InvokeSystemDeviceDlg( This, DeviceDialogData );
  280. if (E_NOTIMPL == hr)
  281. {
  282. hr = InvokeVendorDeviceDlg( This, DeviceDialogData );
  283. }
  284. }
  285. //
  286. // It should return S_OK for success, but who knows?
  287. //
  288. if (SUCCEEDED(hr) && hr != S_FALSE)
  289. {
  290. *ppIWiaItems = DeviceDialogData.ppWiaItems;
  291. *plItemCount = DeviceDialogData.lItemCount;
  292. }
  293. return(hr);
  294. }
  295. /*******************************************************************************
  296. *
  297. * IWiaItem_DeviceDlg_Stub
  298. *
  299. * DESCRIPTION:
  300. * Never called.
  301. *
  302. * PARAMETERS:
  303. *
  304. *******************************************************************************/
  305. HRESULT _stdcall IWiaItem_DeviceDlg_Stub(
  306. IWiaItem __RPC_FAR *This,
  307. HWND hwndParent,
  308. LONG lFlags,
  309. LONG lIntent,
  310. LONG *plItemCount,
  311. IWiaItem ***pIWiaItems)
  312. {
  313. return(S_OK);
  314. }