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.

305 lines
9.0 KiB

  1. /*******************************************************************************
  2. *
  3. * (C) COPYRIGHT MICROSOFT CORPORATION, 1998
  4. *
  5. * TITLE: sysprops.cpp
  6. *
  7. * VERSION: 1.0
  8. *
  9. * AUTHOR: ShaunIv
  10. *
  11. * DATE: 9/24/1999
  12. *
  13. * DESCRIPTION: Implementation of property sheet helpers. Removed from miscutil,
  14. * because it required clients to link to comctl32.dll
  15. *
  16. *******************************************************************************/
  17. #include "precomp.h"
  18. #pragma hdrstop
  19. #include <shellext.h> // for property page functions
  20. #include "devlist.h" // for property page functions
  21. #include <initguid.h>
  22. #include "wiapropui.h"
  23. DEFINE_GUID (CLSID_WiaPropHelp, 0x83bbcbf3,0xb28a,0x4919,0xa5, 0xaa, 0x73, 0x02, 0x74, 0x45, 0xd6, 0x72);
  24. DEFINE_GUID (IID_IWiaPropUI, /* 7eed2e9b-acda-11d2-8080-00805f6596d2 */
  25. 0x7eed2e9b,
  26. 0xacda,
  27. 0x11d2,
  28. 0x80, 0x80, 0x00, 0x80, 0x5f, 0x65, 0x96, 0xd2
  29. );
  30. namespace WiaUiUtil
  31. {
  32. HRESULT SystemPropertySheet( HINSTANCE hInstance, HWND hwndParent, IWiaItem *pWiaItem, LPCTSTR pszCaption )
  33. {
  34. CWaitCursor wc;
  35. CComPtr<IWiaPropUI> pWiaPropUI;
  36. HRESULT hr = CoCreateInstance (CLSID_WiaPropHelp, NULL, CLSCTX_INPROC_SERVER, IID_IWiaPropUI, reinterpret_cast<LPVOID*>(&pWiaPropUI));
  37. if (SUCCEEDED(hr))
  38. {
  39. PROPSHEETHEADER PropSheetHeader = {0};
  40. PropSheetHeader.dwSize = sizeof(PropSheetHeader);
  41. PropSheetHeader.hwndParent = hwndParent;
  42. PropSheetHeader.hInstance = hInstance;
  43. PropSheetHeader.pszCaption = pszCaption;
  44. hr = pWiaPropUI->GetItemPropertyPages( pWiaItem, &PropSheetHeader );
  45. if (SUCCEEDED(hr))
  46. {
  47. if (PropSheetHeader.nPages)
  48. {
  49. //
  50. // Modal property sheets really don't need an apply button...
  51. //
  52. PropSheetHeader.dwFlags |= PSH_NOAPPLYNOW;
  53. INT_PTR nResult = PropertySheet(&PropSheetHeader);
  54. if (PropSheetHeader.phpage)
  55. {
  56. LocalFree(PropSheetHeader.phpage);
  57. }
  58. if (nResult < 0)
  59. {
  60. hr = E_FAIL;
  61. }
  62. else if (IDOK == nResult)
  63. {
  64. hr = S_OK;
  65. }
  66. else hr = S_FALSE;
  67. }
  68. else
  69. {
  70. hr = PROP_SHEET_ERROR_NO_PAGES;
  71. }
  72. }
  73. }
  74. return hr;
  75. }
  76. // Be careful calling this function. It is hideously slow...
  77. HRESULT GetDeviceInfoFromId( LPCWSTR pwszDeviceId, IWiaPropertyStorage **ppWiaPropertyStorage )
  78. {
  79. // Check parameters
  80. if (!pwszDeviceId || !*pwszDeviceId)
  81. {
  82. return E_INVALIDARG;
  83. }
  84. if (!ppWiaPropertyStorage)
  85. {
  86. return E_POINTER;
  87. }
  88. // Initialize the return value
  89. *ppWiaPropertyStorage = NULL;
  90. CSimpleString strDeviceId = CSimpleStringConvert::NaturalString(CSimpleStringWide(pwszDeviceId));
  91. CComPtr<IWiaDevMgr> pWiaDevMgr;
  92. HRESULT hr = CoCreateInstance(CLSID_WiaDevMgr, NULL, CLSCTX_INPROC_SERVER|CLSCTX_LOCAL_SERVER, IID_IWiaDevMgr, (void**)&pWiaDevMgr );
  93. if (SUCCEEDED(hr))
  94. {
  95. // Assume we are going to fail. This will also cover the case where there are no devices.
  96. hr = E_FAIL;
  97. CDeviceList deviceList( pWiaDevMgr );
  98. for (int i=0;i<deviceList.Size();i++)
  99. {
  100. CSimpleStringWide strwCurrDeviceId;
  101. if (PropStorageHelpers::GetProperty(deviceList[i],WIA_DIP_DEV_ID,strwCurrDeviceId))
  102. {
  103. CSimpleString strCurrDeviceId = CSimpleStringConvert::NaturalString(strwCurrDeviceId);
  104. if (strCurrDeviceId == strDeviceId)
  105. {
  106. *ppWiaPropertyStorage = deviceList[i];
  107. if (*ppWiaPropertyStorage)
  108. (*ppWiaPropertyStorage)->AddRef();
  109. hr = S_OK;
  110. break;
  111. }
  112. }
  113. }
  114. }
  115. return hr;
  116. }
  117. // Be careful calling this function. It is hideously slow...
  118. HRESULT GetDeviceTypeFromId( LPCWSTR pwszDeviceId, LONG *pnDeviceType )
  119. {
  120. // Check parameters
  121. if (!pwszDeviceId || !*pwszDeviceId)
  122. {
  123. return E_INVALIDARG;
  124. }
  125. if (!pnDeviceType)
  126. {
  127. return E_POINTER;
  128. }
  129. CComPtr<IWiaPropertyStorage> pWiaPropertyStorage;
  130. HRESULT hr = GetDeviceInfoFromId( pwszDeviceId, &pWiaPropertyStorage );
  131. if (SUCCEEDED(hr))
  132. {
  133. LONG nDeviceType;
  134. if (PropStorageHelpers::GetProperty(pWiaPropertyStorage,WIA_DIP_DEV_TYPE,nDeviceType))
  135. {
  136. *pnDeviceType = nDeviceType;
  137. hr = S_OK;
  138. }
  139. else
  140. {
  141. hr = E_FAIL;
  142. }
  143. }
  144. return hr;
  145. }
  146. // Ask WIA for the default event handler for the device
  147. HRESULT GetDefaultEventHandler (IWiaItem *pItem, const GUID &guidEvent, WIA_EVENT_HANDLER *pwehHandler)
  148. {
  149. HRESULT hr;
  150. IEnumWIA_DEV_CAPS *pEnum;
  151. WIA_EVENT_HANDLER weh;
  152. ZeroMemory (pwehHandler, sizeof(WIA_EVENT_HANDLER));
  153. hr = pItem->EnumRegisterEventInfo (0,
  154. &guidEvent,
  155. &pEnum);
  156. if (SUCCEEDED(hr))
  157. {
  158. ULONG ul;
  159. bool bFound = false;
  160. while (!bFound && NOERROR == pEnum->Next (1, &weh, &ul))
  161. {
  162. if (weh.ulFlags & WIA_IS_DEFAULT_HANDLER)
  163. {
  164. bFound = true;
  165. CopyMemory (pwehHandler, &weh, sizeof(weh));
  166. }
  167. else
  168. {
  169. if (weh.bstrDescription)
  170. {
  171. SysFreeString (weh.bstrDescription);
  172. }
  173. if (weh.bstrIcon)
  174. {
  175. SysFreeString (weh.bstrIcon);
  176. }
  177. if (weh.bstrName)
  178. {
  179. SysFreeString (weh.bstrName);
  180. }
  181. }
  182. }
  183. if (!bFound)
  184. {
  185. hr = E_FAIL;
  186. }
  187. pEnum->Release ();
  188. }
  189. return hr;
  190. }
  191. /******************************************************************************
  192. ItemAndChildrenCount
  193. Returns the number of items, including root + children
  194. ******************************************************************************/
  195. LONG
  196. ItemAndChildrenCount (IWiaItem *pRoot)
  197. {
  198. LONG count = 0;
  199. HRESULT hr = S_OK;
  200. IEnumWiaItem *pEnum;
  201. LONG lType;
  202. if (pRoot)
  203. {
  204. if (SUCCEEDED(pRoot->EnumChildItems(&pEnum)))
  205. {
  206. IWiaItem *pChild;
  207. while (NOERROR == pEnum->Next(1, &pChild, NULL))
  208. {
  209. count++;
  210. pChild->Release ();
  211. }
  212. pEnum->Release ();
  213. }
  214. //
  215. // See if we should count the root item
  216. //
  217. pRoot->GetItemType(&lType);
  218. if (!(lType & WiaItemTypeRoot))
  219. {
  220. count++;
  221. }
  222. }
  223. return count;
  224. }
  225. /******************************************************************************
  226. DeleteItemAndChildren
  227. Deletes all items in the tree under pRoot
  228. ******************************************************************************/
  229. HRESULT
  230. DeleteItemAndChildren (IWiaItem *pRoot)
  231. {
  232. HRESULT hr = S_OK;
  233. IEnumWiaItem *pEnum;
  234. if (pRoot)
  235. {
  236. // Recurse down til we reach a leaf item
  237. if (SUCCEEDED(pRoot->EnumChildItems(&pEnum)))
  238. {
  239. IWiaItem *pChild;
  240. while (SUCCEEDED(hr) && NOERROR == pEnum->Next(1, &pChild, NULL))
  241. {
  242. hr = DeleteItemAndChildren (pChild);
  243. pChild->Release ();
  244. }
  245. pEnum->Release ();
  246. }
  247. // now delete the item itself
  248. // if a delete on a child item failed, stop trying
  249. // to delete because chances are any subsequent delete
  250. // is going to fail as well.
  251. if (SUCCEEDED(hr))
  252. {
  253. // don't delete the very root item
  254. LONG lType;
  255. pRoot->GetItemType(&lType);
  256. if (!(lType & WiaItemTypeRoot))
  257. {
  258. hr = pRoot->DeleteItem(0);
  259. }
  260. }
  261. }
  262. return hr;
  263. }
  264. } // End namespace WiaUiUtil