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.

869 lines
24 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. TestIWiaPropertyStorage.cpp
  5. Abstract:
  6. Author:
  7. Hakki T. Bostanci (hakkib) 06-Apr-2000
  8. Revision History:
  9. --*/
  10. #include "stdafx.h"
  11. #ifdef DEFINE_TEMPLATES
  12. template <class T, class U>
  13. void
  14. SubTestValidValuesRange(
  15. CMyWiaPropertyStorage *pProp,
  16. const CPropSpec &rPropSpec,
  17. VARTYPE vt,
  18. T &Range,
  19. U &CurrentValue,
  20. BOOL bReadOnly
  21. )
  22. {
  23. if (LOG_CMP(Range.cElems, ==, WIA_RANGE_NUM_ELEMS))
  24. {
  25. // minimum value must be lower than the maximum value
  26. LOG_CMP(Range.pElems[WIA_RANGE_MIN], <, Range.pElems[WIA_RANGE_MAX]);
  27. // nominal value must be in the given range
  28. LOG_CMP(Range.pElems[WIA_RANGE_NOM], >=, Range.pElems[WIA_RANGE_MIN]);
  29. LOG_CMP(Range.pElems[WIA_RANGE_NOM], <=, Range.pElems[WIA_RANGE_MAX]);
  30. // current value must be in the given range
  31. LOG_CMP(CurrentValue, >=, Range.pElems[WIA_RANGE_MIN]);
  32. LOG_CMP(CurrentValue, <=, Range.pElems[WIA_RANGE_MAX]);
  33. // the step must be greater than zero
  34. LOG_CMP(Range.pElems[WIA_RANGE_STEP], >, 0);
  35. // skip changing values if another thread is in image transfer mode
  36. if (!bReadOnly && s_PropWriteCritSect.TryEnter())
  37. {
  38. // try to write the min, max, nom values and a random value
  39. LOG_HR(pProp->WriteVerifySingle(
  40. rPropSpec,
  41. CPropVariant(Range.pElems[WIA_RANGE_MIN])
  42. ), == S_OK);
  43. LOG_HR(pProp->WriteVerifySingle(
  44. rPropSpec,
  45. CPropVariant(Range.pElems[WIA_RANGE_MAX])
  46. ), == S_OK);
  47. LOG_HR(pProp->WriteVerifySingle(
  48. rPropSpec,
  49. CPropVariant(Range.pElems[WIA_RANGE_NOM])
  50. ), == S_OK);
  51. LOG_HR(pProp->WriteVerifySingle(
  52. rPropSpec,
  53. CPropVariant(Range.pElems[WIA_RANGE_MIN] + Range.pElems[WIA_RANGE_STEP])
  54. ), == S_OK);
  55. LOG_HR(pProp->WriteVerifySingle(
  56. rPropSpec,
  57. CPropVariant(Range.pElems[WIA_RANGE_MAX] - Range.pElems[WIA_RANGE_STEP])
  58. ), == S_OK);
  59. LOG_HR(pProp->WriteVerifySingle(
  60. rPropSpec,
  61. CPropVariant(Range.pElems[WIA_RANGE_MIN] - Range.pElems[WIA_RANGE_STEP])
  62. ), != S_OK);
  63. LOG_HR(pProp->WriteVerifySingle(
  64. rPropSpec,
  65. CPropVariant(Range.pElems[WIA_RANGE_MAX] + Range.pElems[WIA_RANGE_STEP])
  66. ), != S_OK);
  67. if (Range.pElems[WIA_RANGE_STEP] > 1)
  68. {
  69. LOG_HR(pProp->WriteVerifySingle(
  70. rPropSpec,
  71. CPropVariant(Range.pElems[WIA_RANGE_MIN] + 1)
  72. ), != S_OK);
  73. LOG_HR(pProp->WriteVerifySingle(
  74. rPropSpec,
  75. CPropVariant(Range.pElems[WIA_RANGE_MAX] - 1)
  76. ), != S_OK);
  77. }
  78. // write back the current value
  79. LOG_HR(pProp->WriteVerifySingle(
  80. rPropSpec,
  81. CPropVariant(CurrentValue)
  82. ), == S_OK);
  83. s_PropWriteCritSect.Leave();
  84. }
  85. }
  86. }
  87. template <class T, class U>
  88. void
  89. SubTestValidValuesList(
  90. CMyWiaPropertyStorage *pProp,
  91. const CPropSpec &rPropSpec,
  92. VARTYPE vt,
  93. T &List,
  94. U &CurrentValue,
  95. BOOL bReadOnly
  96. )
  97. {
  98. if (LOG_CMP(List.cElems, >=, WIA_LIST_NUM_ELEMS))
  99. {
  100. // compare WIA_LIST_COUNT entry against the value we expect
  101. ULONG ulNumValues = List.cElems - WIA_LIST_NUM_ELEMS;
  102. //LOG_CMP((ULONG) List.pElems[WIA_LIST_COUNT], ==, ulNumValues);
  103. // search the list for any duplicates and find the indices of
  104. // the nominal value and the current value
  105. ULONG nNomIndex = -1;
  106. ULONG nCurIndex = -1;
  107. for (int i = WIA_LIST_VALUES; i < ulNumValues + WIA_LIST_VALUES; ++i)
  108. {
  109. for (int j = i + 1; j < ulNumValues + WIA_LIST_VALUES; ++j)
  110. {
  111. LOG_CMP(List.pElems[i], !=, List.pElems[j]);
  112. }
  113. if (IsEqual(List.pElems[i], List.pElems[WIA_LIST_NOM]))
  114. {
  115. nNomIndex = i;
  116. }
  117. if (IsEqual(List.pElems[i], CurrentValue))
  118. {
  119. nCurIndex = i;
  120. }
  121. }
  122. // the nominal value must be one of the legal values
  123. if (nNomIndex == -1)
  124. {
  125. LOG_ERROR(
  126. _T("List.pElems[WIA_LIST_NOM] == (%s) %s not found in list"),
  127. (PCTSTR) VarTypeToStr(vt),
  128. (PCTSTR) ToStr((PVOID) &List.pElems[WIA_LIST_NOM], vt)
  129. );
  130. }
  131. // the current value must be set to one of the legal values
  132. if (nCurIndex == -1)
  133. {
  134. LOG_ERROR(
  135. _T("Current value == (%s) %s not found in list"),
  136. (PCTSTR) VarTypeToStr(vt),
  137. (PCTSTR) ToStr((PVOID) &CurrentValue, vt)
  138. );
  139. }
  140. // skip changing values if another thread is in image transfer mode
  141. if (!bReadOnly && s_PropWriteCritSect.TryEnter())
  142. {
  143. // try to write each property in the list
  144. for (int j = WIA_LIST_VALUES; j < ulNumValues + WIA_LIST_VALUES; ++j)
  145. {
  146. LOG_HR(pProp->WriteVerifySingle(
  147. rPropSpec,
  148. CPropVariant(List.pElems[j])
  149. ), == S_OK);
  150. }
  151. // write back the current value
  152. LOG_HR(pProp->WriteVerifySingle(
  153. rPropSpec,
  154. CPropVariant(CurrentValue)
  155. ), == S_OK);
  156. s_PropWriteCritSect.Leave();
  157. }
  158. }
  159. }
  160. template <class T, class U>
  161. void
  162. SubTestValidValuesFlags(
  163. CMyWiaPropertyStorage *pProp,
  164. const CPropSpec &rPropSpec,
  165. VARTYPE vt,
  166. T &Flags,
  167. U &CurrentValue,
  168. BOOL bReadOnly
  169. )
  170. {
  171. if (LOG_CMP(Flags.cElems, ==, WIA_FLAG_NUM_ELEMS))
  172. {
  173. // the nominal and current values should have no unallowed bits set
  174. LOG_CMP(Flags.pElems[WIA_FLAG_NOM] & ~Flags.pElems[WIA_FLAG_VALUES], ==, 0);
  175. LOG_CMP(CurrentValue & ~Flags.pElems[WIA_FLAG_VALUES], ==, 0);
  176. // skip changing values if another thread is in image transfer mode
  177. if (!bReadOnly && s_PropWriteCritSect.TryEnter())
  178. {
  179. // try to write all allowed flags, no flags
  180. LOG_HR(pProp->WriteVerifySingle(
  181. rPropSpec,
  182. CPropVariant(Flags.pElems[WIA_FLAG_VALUES])
  183. ), == S_OK);
  184. LOG_HR(pProp->WriteVerifySingle(
  185. rPropSpec,
  186. CPropVariant(0)
  187. ), == S_OK);
  188. if (~Flags.pElems[WIA_FLAG_VALUES] != 0)
  189. {
  190. LOG_HR(pProp->WriteVerifySingle(
  191. rPropSpec,
  192. CPropVariant(~Flags.pElems[WIA_FLAG_VALUES])
  193. ), != S_OK);
  194. }
  195. // write back the current value
  196. LOG_HR(pProp->WriteVerifySingle(
  197. rPropSpec,
  198. CPropVariant(CurrentValue)
  199. ), == S_OK);
  200. s_PropWriteCritSect.Leave();
  201. }
  202. }
  203. }
  204. #else //DEFINE_TEMPLATES
  205. #include "WiaStress.h"
  206. //////////////////////////////////////////////////////////////////////////
  207. //
  208. //
  209. //
  210. void
  211. CWiaStressThread::TestValidValuesRange(
  212. CMyWiaPropertyStorage *pProp,
  213. const CPropSpec &rPropSpec,
  214. CPropVariant &varRange,
  215. CPropVariant &varValue,
  216. BOOL bReadOnly
  217. )
  218. {
  219. switch (varRange.vt)
  220. {
  221. case VT_VECTOR | VT_I1:
  222. SubTestValidValuesRange(pProp, rPropSpec, VT_I1, varRange.cac, varValue.cVal, bReadOnly);
  223. break;
  224. case VT_VECTOR | VT_UI1:
  225. SubTestValidValuesRange(pProp, rPropSpec, VT_UI1, varRange.caub, varValue.bVal, bReadOnly);
  226. break;
  227. case VT_VECTOR | VT_I2:
  228. SubTestValidValuesRange(pProp, rPropSpec, VT_I2, varRange.cai, varValue.iVal, bReadOnly);
  229. break;
  230. case VT_VECTOR | VT_UI2:
  231. SubTestValidValuesRange(pProp, rPropSpec, VT_UI2, varRange.caui, varValue.uiVal, bReadOnly);
  232. break;
  233. case VT_VECTOR | VT_I4:
  234. SubTestValidValuesRange(pProp, rPropSpec, VT_I4, varRange.cal, varValue.lVal, bReadOnly);
  235. break;
  236. case VT_VECTOR | VT_UI4:
  237. SubTestValidValuesRange(pProp, rPropSpec, VT_UI4, varRange.caul, varValue.ulVal, bReadOnly);
  238. break;
  239. case VT_VECTOR | VT_R4:
  240. SubTestValidValuesRange(pProp, rPropSpec, VT_R4, varRange.caflt, varValue.fltVal, bReadOnly);
  241. break;
  242. case VT_VECTOR | VT_R8:
  243. SubTestValidValuesRange(pProp, rPropSpec, VT_R8, varRange.cadbl, varValue.dblVal, bReadOnly);
  244. break;
  245. default:
  246. LOG_ERROR(_T("Illegal values type %d for WIA_PROP_RANGE"), varValue.vt);
  247. break;
  248. }
  249. }
  250. //////////////////////////////////////////////////////////////////////////
  251. //
  252. //
  253. //
  254. void
  255. CWiaStressThread::TestValidValuesList(
  256. CMyWiaPropertyStorage *pProp,
  257. const CPropSpec &rPropSpec,
  258. CPropVariant &varList,
  259. CPropVariant &varValue,
  260. BOOL bReadOnly
  261. )
  262. {
  263. switch (varList.vt)
  264. {
  265. case VT_VECTOR | VT_I1:
  266. SubTestValidValuesList(pProp, rPropSpec, VT_I1, varList.cac, varValue.cVal, bReadOnly);
  267. break;
  268. case VT_VECTOR | VT_UI1:
  269. SubTestValidValuesList(pProp, rPropSpec, VT_UI1, varList.caub, varValue.bVal, bReadOnly);
  270. break;
  271. case VT_VECTOR | VT_I2:
  272. SubTestValidValuesList(pProp, rPropSpec, VT_I2, varList.cai, varValue.iVal, bReadOnly);
  273. break;
  274. case VT_VECTOR | VT_UI2:
  275. SubTestValidValuesList(pProp, rPropSpec, VT_UI2, varList.caui, varValue.uiVal, bReadOnly);
  276. break;
  277. case VT_VECTOR | VT_I4:
  278. SubTestValidValuesList(pProp, rPropSpec, VT_I4, varList.cal, varValue.lVal, bReadOnly);
  279. break;
  280. case VT_VECTOR | VT_UI4:
  281. SubTestValidValuesList(pProp, rPropSpec, VT_UI4, varList.caul, varValue.ulVal, bReadOnly);
  282. break;
  283. case VT_VECTOR | VT_R4:
  284. SubTestValidValuesList(pProp, rPropSpec, VT_R4, varList.caflt, varValue.fltVal, bReadOnly);
  285. break;
  286. case VT_VECTOR | VT_R8:
  287. SubTestValidValuesList(pProp, rPropSpec, VT_R8, varList.cadbl, varValue.dblVal, bReadOnly);
  288. break;
  289. case VT_VECTOR | VT_BSTR:
  290. SubTestValidValuesList(pProp, rPropSpec, VT_BSTR, varList.cabstr, varValue.bstrVal, bReadOnly);
  291. break;
  292. case VT_VECTOR | VT_LPSTR:
  293. SubTestValidValuesList(pProp, rPropSpec, VT_LPSTR, varList.calpstr, varValue.pszVal, bReadOnly);
  294. break;
  295. case VT_VECTOR | VT_LPWSTR:
  296. SubTestValidValuesList(pProp, rPropSpec, VT_LPWSTR, varList.calpwstr, varValue.pwszVal, bReadOnly);
  297. break;
  298. case VT_VECTOR | VT_CLSID:
  299. SubTestValidValuesList(pProp, rPropSpec, VT_CLSID, varList.cauuid, *varValue.puuid, bReadOnly);
  300. break;
  301. default:
  302. LOG_ERROR(_T("Illegal values type %d for WIA_PROP_LIST"), varValue.vt);
  303. break;
  304. }
  305. }
  306. //////////////////////////////////////////////////////////////////////////
  307. //
  308. //
  309. //
  310. void
  311. CWiaStressThread::TestValidValuesFlags(
  312. CMyWiaPropertyStorage *pProp,
  313. const CPropSpec &rPropSpec,
  314. CPropVariant &varFlags,
  315. CPropVariant &varValue,
  316. BOOL bReadOnly
  317. )
  318. {
  319. switch (varFlags.vt)
  320. {
  321. case VT_VECTOR | VT_I1:
  322. SubTestValidValuesFlags(pProp, rPropSpec, VT_I1, varFlags.cac, varValue.cVal, bReadOnly);
  323. break;
  324. case VT_VECTOR | VT_UI1:
  325. SubTestValidValuesFlags(pProp, rPropSpec, VT_UI1, varFlags.caub, varValue.bVal, bReadOnly);
  326. break;
  327. case VT_VECTOR | VT_I2:
  328. SubTestValidValuesFlags(pProp, rPropSpec, VT_I2, varFlags.cai, varValue.iVal, bReadOnly);
  329. break;
  330. case VT_VECTOR | VT_UI2:
  331. SubTestValidValuesFlags(pProp, rPropSpec, VT_UI2, varFlags.caui, varValue.uiVal, bReadOnly);
  332. break;
  333. case VT_VECTOR | VT_I4:
  334. SubTestValidValuesFlags(pProp, rPropSpec, VT_I4, varFlags.cal, varValue.lVal, bReadOnly);
  335. break;
  336. case VT_VECTOR | VT_UI4:
  337. SubTestValidValuesFlags(pProp, rPropSpec, VT_UI4, varFlags.caul, varValue.ulVal, bReadOnly);
  338. break;
  339. default:
  340. LOG_ERROR(_T("Illegal values type %d for WIA_PROP_FLAG"), varFlags.vt);
  341. break;
  342. }
  343. }
  344. //////////////////////////////////////////////////////////////////////////
  345. //
  346. // test GetPropertyAttributes, ReadMultiple, WriteMultiple
  347. //
  348. void CWiaStressThread::TestPropStorage(CWiaItemData *pItemData)
  349. {
  350. LOG_INFO(_T("Testing IWiaPropertyStorage on %ws"), pItemData->bstrFullName);
  351. CComQIPtr<CMyWiaPropertyStorage, &IID_IWiaPropertyStorage> pProp(pItemData->pWiaItem);
  352. CComPtr<CMyEnumSTATPROPSTG> pEnumSTATPROPSTG;
  353. CHECK_HR(pProp->Enum((IEnumSTATPROPSTG **) &pEnumSTATPROPSTG));
  354. // find the number of properties
  355. ULONG ulNumProps = -1;
  356. CHECK_HR(pProp->GetCount(&ulNumProps));
  357. if (ulNumProps == 0)
  358. {
  359. return;
  360. }
  361. // read the property names
  362. CCppMem<CStatPropStg> pStatPropStg(ulNumProps);
  363. ULONG celtFetched = -1;
  364. CHECK_HR(pEnumSTATPROPSTG->Next(ulNumProps, pStatPropStg, &celtFetched));
  365. //
  366. CCppMem<CPropSpec> pPropSpec(ulNumProps);
  367. for (int i = 0; i < ulNumProps; ++i)
  368. {
  369. if (rand() % 8 < 4) // bugbug: cover all str, all propid and mixed cases...
  370. {
  371. pPropSpec[i] = pStatPropStg[i].lpwstrName;
  372. }
  373. else
  374. {
  375. pPropSpec[i] = pStatPropStg[i].propid;
  376. }
  377. }
  378. //
  379. CPropSpec InvalidPropSpec = L"invalid property name";
  380. //
  381. CCppMem<ULONG> pulAccessRights(ulNumProps);
  382. CCppMem<CPropVariant> pvarValidValues(ulNumProps);
  383. if (LOG_HR(pProp->GetPropertyAttributes(ulNumProps, pPropSpec, pulAccessRights, pvarValidValues), == S_OK))
  384. {
  385. CCppMem<CPropVariant> pvarValue(ulNumProps);
  386. if (LOG_HR(pProp->ReadMultiple(ulNumProps, pPropSpec, pvarValue), == S_OK))
  387. {
  388. FOR_SELECTED(i, ulNumProps)
  389. {
  390. USES_CONVERSION;
  391. m_pszContext = W2T(pStatPropStg[i].lpwstrName);
  392. // examine R/W rights and legal values separately
  393. ULONG ulReadWriteRights =
  394. pulAccessRights[i] & (WIA_PROP_READ | WIA_PROP_WRITE);
  395. ULONG ulLegalValues =
  396. pulAccessRights[i] & (WIA_PROP_NONE | WIA_PROP_RANGE | WIA_PROP_LIST | WIA_PROP_FLAG);
  397. // at least one of the R/W rights should be set
  398. if (ulReadWriteRights == 0)
  399. {
  400. LOG_ERROR(_T("WIA_PROP_READ and/or WIA_PROP_WRITE should be specified"));
  401. }
  402. // if this is a read only item, a list of legal values is not necessary
  403. BOOL bReadOnly = !(ulReadWriteRights & WIA_PROP_WRITE);
  404. // check that the type of the returned value is the same as the advertised
  405. LOG_CMP(pvarValue[i].vt, ==, pStatPropStg[i].vt);
  406. // check that the type of the legal values are the same as the advertised
  407. if (ulLegalValues != WIA_PROP_NONE)
  408. {
  409. LOG_CMP(pvarValidValues[i].vt, ==, VT_VECTOR | pStatPropStg[i].vt);
  410. }
  411. switch (ulLegalValues)
  412. {
  413. case WIA_PROP_NONE:
  414. break;
  415. case WIA_PROP_RANGE:
  416. TestValidValuesRange(pProp, pPropSpec[i], pvarValidValues[i], pvarValue[i], bReadOnly);
  417. break;
  418. case WIA_PROP_LIST:
  419. TestValidValuesList(pProp, pPropSpec[i], pvarValidValues[i], pvarValue[i], bReadOnly);
  420. break;
  421. case WIA_PROP_FLAG:
  422. TestValidValuesFlags(pProp, pPropSpec[i], pvarValidValues[i], pvarValue[i], bReadOnly);
  423. break;
  424. default:
  425. LOG_ERROR(_T("Unrecognized legal values flag 0x%p"), ulLegalValues);
  426. break;
  427. }
  428. m_pszContext = 0;
  429. }
  430. }
  431. // bad parameter tests for ReadMultiple
  432. if (m_bRunBadParamTests)
  433. {
  434. // pass NULL propspecs
  435. FreePropVariantArray(ulNumProps, pvarValue);
  436. LOG_HR(pProp->ReadMultiple(ulNumProps, 0, pvarValue), != S_OK);
  437. for (i = 0; i < ulNumProps; ++i)
  438. {
  439. LOG_CMP(pvarValue[i].vt, ==, VT_EMPTY);
  440. }
  441. // pass invalid propspec
  442. FreePropVariantArray(ulNumProps, pvarValue);
  443. LOG_HR(pProp->ReadMultiple(1, &InvalidPropSpec, pvarValue), != S_OK);
  444. for (i = 0; i < ulNumProps; ++i)
  445. {
  446. LOG_CMP(pvarValue[i].vt, ==, VT_EMPTY);
  447. }
  448. // pass NULL pvarValue
  449. LOG_HR(pProp->ReadMultiple(ulNumProps, pPropSpec, 0), != S_OK);
  450. for (i = 0; i < ulNumProps; ++i)
  451. {
  452. LOG_CMP(pvarValue[i].vt, ==, VT_EMPTY);
  453. }
  454. // bad parameter test for WriteMultiple
  455. FreePropVariantArray(ulNumProps, pvarValue);
  456. // pass NULL propspecs
  457. LOG_HR(pProp->WriteMultiple(ulNumProps, 0, pvarValue, WIA_IPA_FIRST), != S_OK);
  458. // pass NULL pvarValue
  459. LOG_HR(pProp->WriteMultiple(ulNumProps, pPropSpec, 0, WIA_IPA_FIRST), != S_OK);
  460. }
  461. }
  462. // bad parameter tests for GetPropertyAttributes
  463. if (m_bRunBadParamTests)
  464. {
  465. // try to read 0 properties
  466. FreePropVariantArray(ulNumProps, pvarValidValues);
  467. LOG_HR(pProp->GetPropertyAttributes(0, pPropSpec, pulAccessRights, pvarValidValues), == S_FALSE);
  468. for (i = 0; i < ulNumProps; ++i)
  469. {
  470. LOG_CMP(pvarValidValues[i].vt, ==, VT_EMPTY);
  471. }
  472. // pass NULL propspecs
  473. FreePropVariantArray(ulNumProps, pvarValidValues);
  474. LOG_HR(pProp->GetPropertyAttributes(ulNumProps, 0, pulAccessRights, pvarValidValues), != S_OK);
  475. for (i = 0; i < ulNumProps; ++i)
  476. {
  477. LOG_CMP(pvarValidValues[i].vt, ==, VT_EMPTY);
  478. }
  479. // pass invalid propspec
  480. FreePropVariantArray(ulNumProps, pvarValidValues);
  481. LOG_HR(pProp->GetPropertyAttributes(1, &InvalidPropSpec, pulAccessRights, pvarValidValues), == S_FALSE);
  482. for (i = 0; i < ulNumProps; ++i)
  483. {
  484. LOG_CMP(pvarValidValues[i].vt, ==, VT_EMPTY);
  485. }
  486. // pass NULL access rights array
  487. FreePropVariantArray(ulNumProps, pvarValidValues);
  488. LOG_HR(pProp->GetPropertyAttributes(ulNumProps, pPropSpec, 0, pvarValidValues), != S_OK);
  489. for (i = 0; i < ulNumProps; ++i)
  490. {
  491. LOG_CMP(pvarValidValues[i].vt, ==, VT_EMPTY);
  492. }
  493. }
  494. }
  495. //////////////////////////////////////////////////////////////////////////
  496. //
  497. //
  498. //
  499. void CWiaStressThread::TestPropGetCount(CWiaItemData *pItemData)
  500. {
  501. LOG_INFO(_T("Testing GetCount() on %ws"), pItemData->bstrFullName);
  502. CComQIPtr<IWiaPropertyStorage> pProp(pItemData->pWiaItem);
  503. CHECK(pProp != 0);
  504. CComPtr<IEnumSTATPROPSTG> pEnum;
  505. CHECK_HR(pProp->Enum(&pEnum));
  506. // First, get the item count using GetCount()
  507. ULONG cItemsFromGetCount = 0;
  508. if (LOG_HR(pProp->GetCount(&cItemsFromGetCount), == S_OK))
  509. {
  510. // Now, find the item count by first resetting the enumerator
  511. // and then querying for each item one by one using Next()
  512. ULONG cItemsFromNext = 0;
  513. CHECK_HR(pEnum->Reset());
  514. HRESULT hr;
  515. do
  516. {
  517. // verify that GetCount returns the same result after a Next or Reset
  518. ULONG cItemsFromGetCountNow = 0;
  519. LOG_HR(pProp->GetCount(&cItemsFromGetCountNow), == S_OK);
  520. LOG_CMP(cItemsFromGetCountNow, ==, cItemsFromGetCount);
  521. // get the next item
  522. CStatPropStg Item;
  523. ULONG cFetched = 0;
  524. hr = pEnum->Next(1, &Item, &cFetched);
  525. cItemsFromNext += cFetched;
  526. }
  527. while (hr == S_OK);
  528. LOG_HR(hr, == S_FALSE);
  529. // verify that the two counts are equal
  530. LOG_CMP(cItemsFromNext, ==, cItemsFromGetCount);
  531. }
  532. // test bad param
  533. if (m_bRunBadParamTests)
  534. {
  535. LOG_HR(pProp->GetCount(0), != S_OK);
  536. }
  537. }
  538. //////////////////////////////////////////////////////////////////////////
  539. //
  540. //
  541. //
  542. void CWiaStressThread::TestReadPropertyNames(CWiaItemData *pItemData)
  543. {
  544. LOG_INFO(_T("Testing ReadPropertyNames() on %ws"), pItemData->bstrFullName);
  545. int i;
  546. CComQIPtr<CMyWiaPropertyStorage, &IID_IWiaPropertyStorage> pProp(pItemData->pWiaItem);
  547. CComPtr<CMyEnumSTATPROPSTG> pEnumSTATPROPSTG;
  548. CHECK_HR(pProp->Enum((IEnumSTATPROPSTG **) &pEnumSTATPROPSTG));
  549. // find the number of properties
  550. ULONG ulNumProps = -1;
  551. CHECK_HR(pProp->GetCount(&ulNumProps));
  552. if (ulNumProps == 0)
  553. {
  554. return;
  555. }
  556. // read the property names and id's using the enum interface
  557. CCppMem<CStatPropStg> pStatPropStg(ulNumProps);
  558. ULONG celtFetched = -1;
  559. CHECK_HR(pEnumSTATPROPSTG->Next(ulNumProps, pStatPropStg, &celtFetched));
  560. // test legal case
  561. CCppMem<PROPID> pPropId(ulNumProps);
  562. CCppMem<LPOLESTR> ppwstrName(ulNumProps, TRUE);
  563. for (i = 0; i < ulNumProps; ++i)
  564. {
  565. pPropId[i] = pStatPropStg[i].propid;
  566. }
  567. LOG_HR(pProp->ReadPropertyNames(ulNumProps, pPropId, ppwstrName), == S_OK);
  568. // cross check the results
  569. for (i = 0; i < ulNumProps; ++i)
  570. {
  571. if (wcssafecmp(ppwstrName[i], pStatPropStg[i].lpwstrName) != 0)
  572. {
  573. LOG_ERROR(
  574. _T("ReadPropertyNames() %ws != Enum() %ws for PROPID=%d"),
  575. ppwstrName[i],
  576. pStatPropStg[i].lpwstrName,
  577. pPropId[i]
  578. );
  579. }
  580. }
  581. for (i = 0; i < ulNumProps; ++i)
  582. {
  583. CoTaskMemFree(ppwstrName[i]);
  584. ppwstrName[i] = 0;
  585. }
  586. // test illegal cases
  587. // if we try to read 0 properties, ReadPropertyNames() should
  588. // return S_FALSE and should not touch ppwstrName
  589. LOG_HR(pProp->ReadPropertyNames(0, pPropId, ppwstrName), == S_FALSE);
  590. for (i = 0; i < ulNumProps; ++i)
  591. {
  592. if (ppwstrName[i] != 0)
  593. {
  594. LOG_ERROR(_T("ReadPropertyNames() hr == S_FALSE but ppwstrName[%d]=%ws"), i, ppwstrName[i]);
  595. }
  596. }
  597. // pass invalid ppwstrName pointer
  598. LOG_HR(pProp->ReadPropertyNames(ulNumProps, pPropId, 0), != S_OK);
  599. // pass invalid pPropId pointer
  600. LOG_HR(pProp->ReadPropertyNames(ulNumProps, 0, ppwstrName), != S_OK);
  601. // try to read non-existent name
  602. PROPID PropId = -1;
  603. LPOLESTR pwstrName = 0;
  604. LOG_HR(pProp->ReadPropertyNames(1, &PropId, &pwstrName), == S_FALSE);
  605. }
  606. //////////////////////////////////////////////////////////////////////////
  607. //
  608. //
  609. //
  610. void CWiaStressThread::TestEnumSTATPROPSTG(CWiaItemData *pItemData)
  611. {
  612. LOG_INFO(_T("Testing EnumSTATPROPSTG() on %ws"), pItemData->bstrFullName);
  613. CComQIPtr<IWiaPropertyStorage> pProp(pItemData->pWiaItem);
  614. CHECK(pProp != 0);
  615. // test valid cases
  616. CComPtr<CMyEnumSTATPROPSTG> pEnumSTATPROPSTG;
  617. if (LOG_HR(pProp->Enum((IEnumSTATPROPSTG **) &pEnumSTATPROPSTG), == S_OK))
  618. {
  619. TestEnum(pEnumSTATPROPSTG, _T("EnumSTATPROPSTG"));
  620. }
  621. // test invalid cases
  622. LOG_HR(pProp->Enum(0), != S_OK);
  623. }
  624. //////////////////////////////////////////////////////////////////////////
  625. //
  626. //
  627. //
  628. #endif //DEFINE_TEMPLATES