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.

437 lines
8.2 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. WiaHelpers.cpp
  5. Abstract:
  6. Author:
  7. Hakki T. Bostanci (hakkib) 06-Apr-2000
  8. Revision History:
  9. --*/
  10. #include "StdAfx.h"
  11. #include "WiaHelpers.h"
  12. //////////////////////////////////////////////////////////////////////////
  13. //
  14. //
  15. //
  16. HRESULT
  17. CMyWiaPropertyStorage::ReadSingle(
  18. const CPropSpec &PropSpec,
  19. CPropVariant *pPropVariant,
  20. VARTYPE vtNew
  21. )
  22. {
  23. HRESULT hr;
  24. hr = ReadSingle(PropSpec, pPropVariant);
  25. if (hr != S_OK)
  26. {
  27. return hr;
  28. }
  29. hr = pPropVariant->ChangeType(vtNew);
  30. if (hr != S_OK)
  31. {
  32. return hr;
  33. }
  34. return S_OK;
  35. }
  36. //////////////////////////////////////////////////////////////////////////
  37. //
  38. //
  39. //
  40. HRESULT
  41. CMyWiaPropertyStorage::WriteVerifySingle(
  42. const CPropSpec &PropSpec,
  43. const CPropVariant &PropVariant,
  44. PROPID propidNameFirst /*= WIA_IPA_FIRST*/
  45. )
  46. {
  47. HRESULT hr;
  48. hr = WriteSingle(PropSpec, PropVariant, propidNameFirst);
  49. if (hr != S_OK)
  50. {
  51. return hr;
  52. }
  53. CPropVariant var;
  54. hr = ReadSingle(PropSpec, &var, PropVariant.vt);
  55. if (hr != S_OK)
  56. {
  57. return hr;
  58. }
  59. if (PropVariant != var)
  60. {
  61. return S_FALSE;
  62. }
  63. return S_OK;
  64. }
  65. //////////////////////////////////////////////////////////////////////////
  66. //
  67. //
  68. //
  69. HRESULT
  70. ReadWiaItemProperty(
  71. IWiaItem *pWiaItem,
  72. const CPropSpec &PropSpec,
  73. CPropVariant *pPropVariant,
  74. VARTYPE vtNew
  75. )
  76. {
  77. CComQIPtr<CMyWiaPropertyStorage, &IID_IWiaPropertyStorage> pProp(pWiaItem);
  78. if (pProp == 0)
  79. {
  80. return E_NOINTERFACE;
  81. }
  82. return pProp->ReadSingle(PropSpec, pPropVariant, vtNew);
  83. }
  84. //////////////////////////////////////////////////////////////////////////
  85. //
  86. //
  87. //
  88. HRESULT
  89. WriteWiaItemProperty(
  90. IWiaItem *pWiaItem,
  91. const CPropSpec &PropSpec,
  92. const CPropVariant &PropVariant
  93. )
  94. {
  95. CComQIPtr<CMyWiaPropertyStorage, &IID_IWiaPropertyStorage> pProp(pWiaItem);
  96. if (pProp == 0)
  97. {
  98. return E_NOINTERFACE;
  99. }
  100. return pProp->WriteSingle(PropSpec, PropVariant);
  101. }
  102. //////////////////////////////////////////////////////////////////////////
  103. //
  104. //
  105. //
  106. bool operator ==(IWiaPropertyStorage &lhs, IWiaPropertyStorage &rhs)
  107. {
  108. // if their interface pointers are equal, the objects are equal
  109. if (&lhs == &rhs)
  110. {
  111. return true;
  112. }
  113. // if not, we'll enumerate and compare each property
  114. HRESULT hr;
  115. CComPtr<IEnumSTATPROPSTG> pEnumSTATPROPSTG;
  116. hr = lhs.Enum(&pEnumSTATPROPSTG);
  117. if (hr != S_OK)
  118. {
  119. return false;
  120. }
  121. while (1)
  122. {
  123. // get next property name
  124. CStatPropStg StatPropStg;
  125. hr = pEnumSTATPROPSTG->Next(1, &StatPropStg, 0);
  126. if (hr != S_OK)
  127. {
  128. break;
  129. }
  130. // read that property from the left object
  131. CPropSpec PropSpec(StatPropStg.propid);
  132. CPropVariant varLhs;
  133. hr = lhs.ReadMultiple(1, &PropSpec, &varLhs);
  134. if (hr != S_OK)
  135. {
  136. return false;
  137. }
  138. // read that property from the right object
  139. CPropVariant varRhs;
  140. hr = rhs.ReadMultiple(1, &PropSpec, &varRhs);
  141. if (hr != S_OK)
  142. {
  143. return false;
  144. }
  145. // those two should be equal
  146. if (varLhs != varRhs)
  147. {
  148. return false;
  149. }
  150. }
  151. // the enumeration should have ended with S_FALSE
  152. if (hr != S_FALSE)
  153. {
  154. return false;
  155. }
  156. // bugbug: this compares each property on the lhs against each one on the rhs
  157. // We should maybe do another pass and compare the other way; each property
  158. // on the rhs against each one on the lhs...
  159. return true;
  160. }
  161. //////////////////////////////////////////////////////////////////////////
  162. //
  163. //
  164. //
  165. bool operator ==(IWiaItem &lhs, IWiaItem &rhs)
  166. {
  167. // if their interface pointers are equal, the objects are equal
  168. if (&lhs == &rhs)
  169. {
  170. return true;
  171. }
  172. // if not, we will compare the properties of the items
  173. // bugbug: is this good enough?
  174. HRESULT hr;
  175. CComPtr<IWiaPropertyStorage> pLhsPropertyStorage;
  176. hr = lhs.QueryInterface(IID_IWiaPropertyStorage, (void **)&pLhsPropertyStorage);
  177. if (hr != S_OK)
  178. {
  179. return false;
  180. }
  181. CComPtr<IWiaPropertyStorage> pRhsPropertyStorage;
  182. hr = rhs.QueryInterface(IID_IWiaPropertyStorage, (void **)&pRhsPropertyStorage);
  183. if (hr != S_OK)
  184. {
  185. return false;
  186. }
  187. return *pLhsPropertyStorage == *pRhsPropertyStorage;
  188. }
  189. //////////////////////////////////////////////////////////////////////////
  190. //
  191. //
  192. //
  193. HRESULT
  194. InstallTestDevice(
  195. IWiaDevMgr *pWiaDevMgr,
  196. PCTSTR pInfFileName,
  197. BSTR *pbstrDeviceId
  198. )
  199. {
  200. try
  201. {
  202. // get the model name of the device
  203. CInf InfFile(pInfFileName);
  204. INFCONTEXT InfContext;
  205. CHECK(SetupFindFirstLine(InfFile, _T("Manufacturer"), 0, &InfContext));
  206. TCHAR szModelsSectionName[MAX_DEVICE_ID_LEN];
  207. CHECK(SetupGetStringField(&InfContext, 1, szModelsSectionName, COUNTOF(szModelsSectionName), 0));
  208. CHECK(SetupFindFirstLine(InfFile, szModelsSectionName, 0, &InfContext));
  209. TCHAR szModelName[MAX_DEVICE_ID_LEN];
  210. CHECK(SetupGetStringField(&InfContext, 0, szModelName, COUNTOF(szModelName), 0));
  211. GUID guid;
  212. CHECK_HR(CoCreateGuid(&guid));
  213. WCHAR szGuid[MAX_GUID_STRING_LEN];
  214. CHECK(StringFromGUID2(guid, szGuid, COUNTOF(szGuid)));
  215. TCHAR szDeviceName[1024]; //bugbug: fixed size buffer
  216. _stprintf(szDeviceName, _T("WIA Stress %ws"), szGuid);
  217. USES_CONVERSION;
  218. PCWSTR pwszDeviceName = T2W(szDeviceName);
  219. // install the device
  220. CHECK(InstallImageDeviceFromInf(pInfFileName, szDeviceName));
  221. BOOL bFoundDeviceInstance = FALSE;
  222. BOOL nRetries = 3;
  223. for (;;)
  224. {
  225. // find this device among the installed WIA devices
  226. CComPtr<IEnumWIA_DEV_INFO> pEnumWIA_DEV_INFO;
  227. CHECK_HR(pWiaDevMgr->EnumDeviceInfo(0, &pEnumWIA_DEV_INFO));
  228. ULONG nDevices = -1;
  229. CHECK_HR(pEnumWIA_DEV_INFO->GetCount(&nDevices));
  230. for (int i = 0; i < nDevices; ++i)
  231. {
  232. CComPtr<CMyWiaPropertyStorage> pProp;
  233. CHECK_HR(pEnumWIA_DEV_INFO->Next(1, (IWiaPropertyStorage **) &pProp, 0));
  234. CPropVariant varDeviceDesc;
  235. CHECK_HR(pProp->ReadSingle(WIA_DIP_DEV_DESC, &varDeviceDesc, VT_BSTR));
  236. if (wcscmp(varDeviceDesc.bstrVal, pwszDeviceName) == 0)
  237. {
  238. bFoundDeviceInstance = TRUE;
  239. if (pbstrDeviceId != 0)
  240. {
  241. CPropVariant varDeviceID;
  242. CHECK_HR(pProp->ReadSingle(WIA_DIP_DEV_ID, &varDeviceID, VT_BSTR));
  243. *pbstrDeviceId = SysAllocString(varDeviceID.bstrVal);
  244. }
  245. }
  246. }
  247. if (bFoundDeviceInstance)
  248. {
  249. return S_OK;
  250. }
  251. if (--nRetries == 0)
  252. {
  253. return E_FAIL;
  254. }
  255. Sleep(2500);
  256. }
  257. }
  258. catch (const CError &Error)
  259. {
  260. return HRESULT_FROM_WIN32(Error.Num());
  261. }
  262. }
  263. //////////////////////////////////////////////////////////////////////////
  264. //
  265. //
  266. //
  267. HRESULT CMyEnumSTATPROPSTG::GetCount(ULONG *pcelt)
  268. {
  269. if (pcelt == 0)
  270. {
  271. return E_INVALIDARG;
  272. }
  273. *pcelt = 0;
  274. HRESULT hr;
  275. CComPtr<CMyEnumSTATPROPSTG> pClone;
  276. hr = Clone(&pClone);
  277. if (hr != S_OK)
  278. {
  279. return hr;
  280. }
  281. hr = pClone->Reset();
  282. if (hr != S_OK)
  283. {
  284. return hr;
  285. }
  286. while (1)
  287. {
  288. CStatPropStg StatPropStg;
  289. hr = pClone->Next(1, &StatPropStg, 0);
  290. if (hr != S_OK)
  291. {
  292. break;
  293. }
  294. ++*pcelt;
  295. }
  296. if (hr != S_FALSE)
  297. {
  298. return hr;
  299. }
  300. return S_OK;
  301. }
  302. //////////////////////////////////////////////////////////////////////////
  303. //
  304. //
  305. //
  306. HRESULT CMyEnumSTATPROPSTG::Clone(CMyEnumSTATPROPSTG **ppenum)
  307. {
  308. return ((IEnumSTATPROPSTG *)this)->Clone((IEnumSTATPROPSTG **)ppenum);
  309. }