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.

985 lines
33 KiB

  1. /*******************************************************************************
  2. *
  3. * (C) COPYRIGHT MICROSOFT CORPORATION, 2000
  4. *
  5. * TITLE: DUMPPROP.CPP
  6. *
  7. * VERSION: 1.0
  8. *
  9. * AUTHOR: ShaunIv
  10. *
  11. * DATE: 9/27/2000
  12. *
  13. * DESCRIPTION: Display the properties associated with a IWiaItem, either to the
  14. * debugger, or to a log file.
  15. *
  16. *******************************************************************************/
  17. #include "precomp.h"
  18. #pragma hdrstop
  19. #include "dumpprop.h"
  20. //
  21. // Change this to limit the width of individual strings (for avoiding ugliness)
  22. //
  23. #define MAX_DUMP_STRING 160
  24. CWiaDebugDump::CWiaDebugDump(void)
  25. {
  26. }
  27. CWiaDebugDump::~CWiaDebugDump(void)
  28. {
  29. }
  30. CWiaDebugDumpToFileHandle::CWiaDebugDumpToFileHandle( HANDLE hFile )
  31. : m_hFile(hFile)
  32. {
  33. }
  34. CWiaDebugDumpToFileHandle::~CWiaDebugDumpToFileHandle(void)
  35. {
  36. }
  37. void CWiaDebugDumpToFileHandle::Print( LPCTSTR pszString )
  38. {
  39. if (m_hFile && pszString)
  40. {
  41. DWORD dwWritten;
  42. WriteFile( m_hFile, pszString, lstrlen(pszString)*sizeof(TCHAR), &dwWritten, NULL );
  43. WriteFile( m_hFile, TEXT("\r\n"), 2*sizeof(TCHAR), &dwWritten, NULL );
  44. }
  45. }
  46. CWiaDebugDumpToFile::CWiaDebugDumpToFile( LPCTSTR pszFilename, bool bOverwrite )
  47. : m_hFile(INVALID_HANDLE_VALUE)
  48. {
  49. if (pszFilename && lstrlen(pszFilename))
  50. {
  51. m_hFile = CreateFile( pszFilename, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ, NULL, bOverwrite ? CREATE_ALWAYS : OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
  52. if (!bOverwrite && m_hFile)
  53. {
  54. SetFilePointer( m_hFile, 0, NULL, FILE_END );
  55. }
  56. }
  57. }
  58. CWiaDebugDumpToFile::~CWiaDebugDumpToFile(void)
  59. {
  60. if (INVALID_HANDLE_VALUE != m_hFile)
  61. {
  62. CloseHandle(m_hFile);
  63. m_hFile = INVALID_HANDLE_VALUE;
  64. }
  65. }
  66. void CWiaDebugDumpToFile::Print( LPCTSTR pszString )
  67. {
  68. if (m_hFile && pszString)
  69. {
  70. DWORD dwWritten;
  71. WriteFile( m_hFile, pszString, lstrlen(pszString)*sizeof(TCHAR), &dwWritten, NULL );
  72. WriteFile( m_hFile, TEXT("\r\n"), 2*sizeof(TCHAR), &dwWritten, NULL );
  73. }
  74. }
  75. CSimpleString CWiaDebugDump::GetTymedString( LONG tymed )
  76. {
  77. switch (tymed)
  78. {
  79. case TYMED_CALLBACK:
  80. return TEXT("TYMED_CALLBACK");
  81. case TYMED_FILE:
  82. return TEXT("TYMED_FILE");
  83. case TYMED_MULTIPAGE_CALLBACK:
  84. return TEXT("TYMED_MULTIPAGE_CALLBACK");
  85. case TYMED_MULTIPAGE_FILE:
  86. return TEXT("TYMED_MULTIPAGE_FILE");
  87. }
  88. return CSimpleString().Format( TEXT("0x%08X"), tymed );
  89. }
  90. CSimpleString CWiaDebugDump::GetPropVariantTypeString( VARTYPE vt )
  91. {
  92. CSimpleString strResult;
  93. static const struct
  94. {
  95. VARTYPE vt;
  96. LPCTSTR pszName;
  97. }
  98. s_VarTypes[] =
  99. {
  100. { VT_I2, TEXT("VT_I2") },
  101. { VT_I4, TEXT("VT_I4") },
  102. { VT_R4, TEXT("VT_R4") },
  103. { VT_R8, TEXT("VT_R8") },
  104. { VT_CY, TEXT("VT_CY") },
  105. { VT_DATE, TEXT("VT_DATE") },
  106. { VT_BSTR, TEXT("VT_BSTR") },
  107. { VT_DISPATCH, TEXT("VT_DISPATCH") },
  108. { VT_ERROR, TEXT("VT_ERROR") },
  109. { VT_BOOL, TEXT("VT_BOOL") },
  110. { VT_VARIANT, TEXT("VT_VARIANT") },
  111. { VT_UNKNOWN, TEXT("VT_UNKNOWN") },
  112. { VT_DECIMAL, TEXT("VT_DECIMAL") },
  113. { VT_I1, TEXT("VT_I1") },
  114. { VT_UI1, TEXT("VT_UI1") },
  115. { VT_UI2, TEXT("VT_UI2") },
  116. { VT_UI4, TEXT("VT_UI4") },
  117. { VT_I8, TEXT("VT_I8") },
  118. { VT_UI8, TEXT("VT_UI8") },
  119. { VT_INT, TEXT("VT_INT") },
  120. { VT_UINT, TEXT("VT_UINT") },
  121. { VT_VOID, TEXT("VT_VOID") },
  122. { VT_HRESULT, TEXT("VT_HRESULT") },
  123. { VT_PTR, TEXT("VT_PTR") },
  124. { VT_SAFEARRAY, TEXT("VT_SAFEARRAY") },
  125. { VT_CARRAY, TEXT("VT_CARRAY") },
  126. { VT_USERDEFINED, TEXT("VT_USERDEFINED") },
  127. { VT_LPSTR, TEXT("VT_LPSTR") },
  128. { VT_LPWSTR, TEXT("VT_LPWSTR") },
  129. { VT_RECORD, TEXT("VT_RECORD") },
  130. { VT_INT_PTR, TEXT("VT_INT_PTR") },
  131. { VT_UINT_PTR, TEXT("VT_UINT_PTR") },
  132. { VT_FILETIME, TEXT("VT_FILETIME") },
  133. { VT_BLOB, TEXT("VT_BLOB") },
  134. { VT_STREAM, TEXT("VT_STREAM") },
  135. { VT_STORAGE, TEXT("VT_STORAGE") },
  136. { VT_STREAMED_OBJECT, TEXT("VT_STREAMED_OBJECT") },
  137. { VT_STORED_OBJECT, TEXT("VT_STORED_OBJECT") },
  138. { VT_BLOB_OBJECT, TEXT("VT_BLOB_OBJECT") },
  139. { VT_CF, TEXT("VT_CF") },
  140. { VT_CLSID, TEXT("VT_CLSID") },
  141. { VT_VERSIONED_STREAM, TEXT("VT_VERSIONED_STREAM") }
  142. },
  143. s_ExtendedTypes[] =
  144. {
  145. { VT_VECTOR, TEXT("VT_VECTOR") },
  146. { VT_ARRAY, TEXT("VT_ARRAY") },
  147. { VT_BYREF, TEXT("VT_BYREF") },
  148. { VT_RESERVED, TEXT("VT_RESERVED") }
  149. };
  150. for (int i=0;i<ARRAYSIZE(s_ExtendedTypes);i++)
  151. {
  152. if (vt & s_ExtendedTypes[i].vt)
  153. {
  154. if (strResult.Length())
  155. {
  156. strResult += TEXT(" | ");
  157. }
  158. strResult += s_ExtendedTypes[i].pszName;
  159. }
  160. }
  161. for (int i=0;i<ARRAYSIZE(s_VarTypes);i++)
  162. {
  163. if ((vt & VT_TYPEMASK) == s_VarTypes[i].vt)
  164. {
  165. if (strResult.Length())
  166. {
  167. strResult += TEXT(" | ");
  168. }
  169. strResult += s_VarTypes[i].pszName;
  170. }
  171. }
  172. if (!strResult.Length())
  173. {
  174. strResult.Format( TEXT("Unknown variant type: 0x%04X"), vt );
  175. }
  176. return strResult;
  177. }
  178. CSimpleString CWiaDebugDump::GetPrintableValue( PROPVARIANT &PropVariant )
  179. {
  180. TCHAR szValue[1024] = TEXT("");
  181. switch (PropVariant.vt)
  182. {
  183. case VT_I1:
  184. wsprintf(szValue,TEXT("%d, (0x%08X)"),PropVariant.cVal,PropVariant.cVal);
  185. break;
  186. case VT_UI1:
  187. wsprintf(szValue,TEXT("%u, (0x%08X)"),PropVariant.bVal,PropVariant.bVal);
  188. break;
  189. case VT_I2:
  190. wsprintf(szValue,TEXT("%d, (0x%08X)"),PropVariant.iVal,PropVariant.iVal);
  191. break;
  192. case VT_UI2:
  193. wsprintf(szValue,TEXT("%u, (0x%08X)"),PropVariant.uiVal,PropVariant.uiVal);
  194. break;
  195. case VT_I4:
  196. wsprintf(szValue,TEXT("%ld, (0x%08X)"),PropVariant.lVal,PropVariant.lVal);
  197. break;
  198. case VT_UI4:
  199. wsprintf(szValue,TEXT("%lu, (0x%08X)"),PropVariant.ulVal,PropVariant.ulVal);
  200. break;
  201. case VT_BSTR:
  202. lstrcpyn( szValue, CSimpleStringConvert::NaturalString(CSimpleStringWide(PropVariant.bstrVal)), ARRAYSIZE(szValue));
  203. break;
  204. case VT_LPWSTR:
  205. lstrcpyn( szValue, CSimpleStringConvert::NaturalString(CSimpleStringWide(PropVariant.pwszVal)), ARRAYSIZE(szValue));
  206. break;
  207. case VT_CLSID:
  208. lstrcpyn( szValue, PropVariant.puuid ? GetStringFromGuid(*PropVariant.puuid).String() : TEXT("NULL"), ARRAYSIZE(szValue));
  209. break;
  210. case VT_VECTOR|VT_I1:
  211. {
  212. wsprintf(szValue+lstrlen(szValue), TEXT("Length: [%d] "), PropVariant.cac.cElems );
  213. for (int i=0;i<(int)PropVariant.cac.cElems;i++)
  214. {
  215. if (lstrlen(szValue) >= MAX_DUMP_STRING)
  216. {
  217. lstrcat( szValue, TEXT("...") );
  218. break;
  219. }
  220. wsprintf(szValue+lstrlen(szValue), TEXT("%02X"), (ULONG)PropVariant.cac.pElems[i] );
  221. if (i < (int)PropVariant.cal.cElems-1 && i % 4 == 3)
  222. {
  223. wsprintf(szValue+lstrlen(szValue),TEXT(" "));
  224. }
  225. }
  226. }
  227. break;
  228. case VT_VECTOR|VT_UI1:
  229. {
  230. wsprintf(szValue+lstrlen(szValue), TEXT("Length: [%d] "), PropVariant.caub.cElems );
  231. for (int i=0;i<(int)PropVariant.caub.cElems;i++)
  232. {
  233. if (lstrlen(szValue) >= MAX_DUMP_STRING)
  234. {
  235. lstrcat( szValue, TEXT("...") );
  236. break;
  237. }
  238. wsprintf(szValue+lstrlen(szValue), TEXT("%02X"), (ULONG)PropVariant.caub.pElems[i] );
  239. if (i < (int)PropVariant.cal.cElems-1 && i % 4 == 3)
  240. {
  241. wsprintf(szValue+lstrlen(szValue),TEXT(" "));
  242. }
  243. }
  244. }
  245. break;
  246. case VT_VECTOR|VT_I2:
  247. {
  248. wsprintf(szValue+lstrlen(szValue), TEXT("Length: [%d] "), PropVariant.cai.cElems );
  249. for (int i=0;i<(int)PropVariant.cai.cElems;i++)
  250. {
  251. if (lstrlen(szValue) >= MAX_DUMP_STRING)
  252. {
  253. lstrcat( szValue, TEXT("...") );
  254. break;
  255. }
  256. wsprintf(szValue+lstrlen(szValue),TEXT("%04X"),(ULONG)PropVariant.cai.pElems[i]);
  257. if (i < (int)PropVariant.cal.cElems-1)
  258. {
  259. wsprintf(szValue+lstrlen(szValue),TEXT(" "));
  260. }
  261. }
  262. }
  263. break;
  264. case VT_VECTOR|VT_UI2:
  265. {
  266. wsprintf(szValue+lstrlen(szValue), TEXT("Length: [%d] "), PropVariant.caui.cElems );
  267. for (int i=0;i<(int)PropVariant.caui.cElems;i++)
  268. {
  269. if (lstrlen(szValue) >= MAX_DUMP_STRING)
  270. {
  271. lstrcat( szValue, TEXT("...") );
  272. break;
  273. }
  274. wsprintf(szValue+lstrlen(szValue),TEXT("%04X"),(ULONG)PropVariant.caui.pElems[i]);
  275. if (i < (int)PropVariant.cal.cElems-1)
  276. {
  277. wsprintf(szValue+lstrlen(szValue),TEXT(" "));
  278. }
  279. }
  280. }
  281. break;
  282. case VT_VECTOR|VT_I4:
  283. {
  284. wsprintf(szValue+lstrlen(szValue), TEXT("Length: [%d] "), PropVariant.cal.cElems );
  285. for (int i=0;i<(int)PropVariant.cal.cElems;i++)
  286. {
  287. if (lstrlen(szValue) >= MAX_DUMP_STRING)
  288. {
  289. lstrcat( szValue, TEXT("...") );
  290. break;
  291. }
  292. wsprintf(szValue+lstrlen(szValue),TEXT("%08X"),(ULONG)PropVariant.cal.pElems[i]);
  293. if (i < (int)PropVariant.cal.cElems-1)
  294. {
  295. wsprintf(szValue+lstrlen(szValue),TEXT(" "));
  296. }
  297. }
  298. }
  299. break;
  300. case VT_VECTOR|VT_UI4:
  301. {
  302. wsprintf(szValue+lstrlen(szValue), TEXT("Length: [%d] "), PropVariant.caul.cElems );
  303. for (int i=0;i<(int)PropVariant.caul.cElems;i++)
  304. {
  305. if (lstrlen(szValue) >= MAX_DUMP_STRING)
  306. {
  307. lstrcat( szValue, TEXT("...") );
  308. break;
  309. }
  310. wsprintf(szValue+lstrlen(szValue),TEXT("%08X"),(ULONG)PropVariant.caul.pElems[i]);
  311. if (i < (int)PropVariant.cal.cElems-1)
  312. {
  313. wsprintf(szValue+lstrlen(szValue),TEXT(" "));
  314. }
  315. }
  316. }
  317. break;
  318. default:
  319. wsprintf(szValue,TEXT("Unknown Type %d (0x%08X)"),PropVariant.vt,PropVariant.vt);
  320. }
  321. return szValue;
  322. }
  323. CSimpleString CWiaDebugDump::GetPrintableValue( VARIANT &Variant )
  324. {
  325. TCHAR szValue[1024] = TEXT("");
  326. switch (Variant.vt)
  327. {
  328. case VT_I1:
  329. wsprintf(szValue,TEXT("%d, (0x%08X)"),Variant.cVal,Variant.cVal);
  330. break;
  331. case VT_UI1:
  332. wsprintf(szValue,TEXT("%u, (0x%08X)"),Variant.bVal,Variant.bVal);
  333. break;
  334. case VT_I2:
  335. wsprintf(szValue,TEXT("%d, (0x%08X)"),Variant.iVal,Variant.iVal);
  336. break;
  337. case VT_UI2:
  338. wsprintf(szValue,TEXT("%u, (0x%08X)"),Variant.uiVal,Variant.uiVal);
  339. break;
  340. case VT_I4:
  341. wsprintf(szValue,TEXT("%ld, (0x%08X)"),Variant.lVal,Variant.lVal);
  342. break;
  343. case VT_UI4:
  344. wsprintf(szValue,TEXT("%lu, (0x%08X)"),Variant.ulVal,Variant.ulVal);
  345. break;
  346. case VT_BSTR:
  347. lstrcpyn( szValue, CSimpleStringConvert::NaturalString(CSimpleStringWide(Variant.bstrVal)), ARRAYSIZE(szValue));
  348. break;
  349. default:
  350. wsprintf(szValue,TEXT("Unknown Type %d (0x%08X)"),Variant.vt,Variant.vt);
  351. }
  352. return szValue;
  353. }
  354. CSimpleString CWiaDebugDump::GetPrintableName( const STATPROPSTG &StatPropStg )
  355. {
  356. CSimpleString strResult;
  357. //
  358. // Get the name
  359. //
  360. strResult += TEXT("[");
  361. if (StatPropStg.lpwstrName)
  362. {
  363. strResult += CSimpleStringConvert::NaturalString(CSimpleStringWide(StatPropStg.lpwstrName));
  364. }
  365. else
  366. {
  367. strResult += TEXT("*No Property Name*");
  368. }
  369. //
  370. // Get the propid
  371. //
  372. strResult += CSimpleString().Format( TEXT("], propid: %d"), StatPropStg.propid );
  373. return strResult;
  374. }
  375. CSimpleString CWiaDebugDump::GetPrintableAccessFlags( ULONG nAccessFlags )
  376. {
  377. CSimpleString strResult;
  378. static const struct
  379. {
  380. ULONG nFlag;
  381. LPCTSTR pszName;
  382. }
  383. s_Flags[] =
  384. {
  385. { WIA_PROP_READ, TEXT("WIA_PROP_READ") },
  386. { WIA_PROP_WRITE, TEXT("WIA_PROP_WRITE") },
  387. { WIA_PROP_SYNC_REQUIRED, TEXT("WIA_PROP_SYNC_REQUIRED") },
  388. { WIA_PROP_NONE, TEXT("WIA_PROP_NONE") },
  389. { WIA_PROP_RANGE, TEXT("WIA_PROP_RANGE") },
  390. { WIA_PROP_LIST, TEXT("WIA_PROP_LIST") },
  391. { WIA_PROP_FLAG, TEXT("WIA_PROP_FLAG") },
  392. { WIA_PROP_CACHEABLE, TEXT("WIA_PROP_CACHEABLE") }
  393. };
  394. for (int i=0;i<ARRAYSIZE(s_Flags);i++)
  395. {
  396. if (nAccessFlags & s_Flags[i].nFlag)
  397. {
  398. if (strResult.Length())
  399. {
  400. strResult += TEXT(" | ");
  401. }
  402. strResult += s_Flags[i].pszName;
  403. }
  404. }
  405. if (!strResult.Length())
  406. {
  407. strResult = TEXT("*none*");
  408. }
  409. return strResult;
  410. }
  411. CSimpleString CWiaDebugDump::GetPrintableLegalValues( ULONG nAccessFlags, const PROPVARIANT &PropVariantAttributes )
  412. {
  413. CSimpleString strResult;
  414. if ((nAccessFlags & WIA_PROP_RANGE) && (PropVariantAttributes.vt & VT_VECTOR))
  415. {
  416. CSimpleString strMin, strMax, strStep;
  417. switch (PropVariantAttributes.vt & VT_TYPEMASK)
  418. {
  419. case VT_I1:
  420. strMin.Format(TEXT("%d"), PropVariantAttributes.cac.pElems[WIA_RANGE_MIN] );
  421. strMax.Format(TEXT("%d"), PropVariantAttributes.cac.pElems[WIA_RANGE_MAX] );
  422. strStep.Format(TEXT("%d"), PropVariantAttributes.cac.pElems[WIA_RANGE_STEP] );
  423. break;
  424. case VT_UI1:
  425. strMin.Format(TEXT("%u"), PropVariantAttributes.caub.pElems[WIA_RANGE_MIN] );
  426. strMax.Format(TEXT("%u"), PropVariantAttributes.caub.pElems[WIA_RANGE_MAX] );
  427. strStep.Format(TEXT("%u"), PropVariantAttributes.caub.pElems[WIA_RANGE_STEP] );
  428. break;
  429. case VT_I2:
  430. strMin.Format(TEXT("%d"), PropVariantAttributes.cai.pElems[WIA_RANGE_MIN] );
  431. strMax.Format(TEXT("%d"), PropVariantAttributes.cai.pElems[WIA_RANGE_MAX] );
  432. strStep.Format(TEXT("%d"), PropVariantAttributes.cai.pElems[WIA_RANGE_STEP] );
  433. break;
  434. case VT_UI2:
  435. strMin.Format(TEXT("%u"), PropVariantAttributes.caui.pElems[WIA_RANGE_MIN] );
  436. strMax.Format(TEXT("%u"), PropVariantAttributes.caui.pElems[WIA_RANGE_MAX] );
  437. strStep.Format(TEXT("%u"), PropVariantAttributes.caui.pElems[WIA_RANGE_STEP] );
  438. break;
  439. case VT_I4:
  440. strMin.Format(TEXT("%d"), PropVariantAttributes.cal.pElems[WIA_RANGE_MIN] );
  441. strMax.Format(TEXT("%d"), PropVariantAttributes.cal.pElems[WIA_RANGE_MAX] );
  442. strStep.Format(TEXT("%d"), PropVariantAttributes.cal.pElems[WIA_RANGE_STEP] );
  443. break;
  444. case VT_UI4:
  445. strMin.Format(TEXT("%u"), PropVariantAttributes.caul.pElems[WIA_RANGE_MIN] );
  446. strMax.Format(TEXT("%u"), PropVariantAttributes.caul.pElems[WIA_RANGE_MAX] );
  447. strStep.Format(TEXT("%u"), PropVariantAttributes.caul.pElems[WIA_RANGE_STEP] );
  448. break;
  449. case VT_I8:
  450. strMin.Format(TEXT("%d"), PropVariantAttributes.cah.pElems[WIA_RANGE_MIN].LowPart );
  451. strMax.Format(TEXT("%d"), PropVariantAttributes.cah.pElems[WIA_RANGE_MAX].LowPart );
  452. strStep.Format(TEXT("%d"), PropVariantAttributes.cah.pElems[WIA_RANGE_STEP].LowPart );
  453. break;
  454. case VT_UI8:
  455. strMin.Format(TEXT("%u"), PropVariantAttributes.cauh.pElems[WIA_RANGE_MIN].LowPart );
  456. strMax.Format(TEXT("%u"), PropVariantAttributes.cauh.pElems[WIA_RANGE_MAX].LowPart );
  457. strStep.Format(TEXT("%u"), PropVariantAttributes.cauh.pElems[WIA_RANGE_STEP].LowPart );
  458. break;
  459. }
  460. strResult.Format( TEXT("%s...%s, Step: %s"), strMin.String(), strMax.String(), strStep.String() );
  461. }
  462. else if (nAccessFlags & WIA_PROP_LIST && (PropVariantAttributes.vt & VT_VECTOR))
  463. {
  464. if (((PropVariantAttributes.vt & VT_TYPEMASK) == VT_I4) || ((PropVariantAttributes.vt & VT_TYPEMASK) == VT_UI4))
  465. {
  466. for (ULONG i=0;i<PropVariantAttributes.cal.cElems - WIA_LIST_VALUES;i++)
  467. {
  468. if (strResult.Length())
  469. {
  470. strResult += TEXT(",");
  471. }
  472. if (strResult.Length() >= MAX_DUMP_STRING)
  473. {
  474. strResult += TEXT("...");
  475. break;
  476. }
  477. strResult += CSimpleString().Format( TEXT("%d"), PropVariantAttributes.cal.pElems[WIA_LIST_VALUES + i] );
  478. }
  479. }
  480. else if ((PropVariantAttributes.vt & VT_TYPEMASK) == VT_CLSID)
  481. {
  482. for (ULONG i=0;i<PropVariantAttributes.cauuid.cElems - WIA_LIST_VALUES;i++)
  483. {
  484. if (strResult.Length())
  485. {
  486. strResult += TEXT(",");
  487. }
  488. if (strResult.Length() >= MAX_DUMP_STRING)
  489. {
  490. strResult += TEXT("...");
  491. break;
  492. }
  493. strResult += CSimpleString().Format( TEXT("%s"), GetStringFromGuid(PropVariantAttributes.cauuid.pElems[WIA_LIST_VALUES + i]).String() );
  494. }
  495. }
  496. }
  497. else if (nAccessFlags & WIA_PROP_FLAG)
  498. {
  499. strResult.Format( TEXT("0x%08X"), PropVariantAttributes.caul.pElems[WIA_FLAG_VALUES] );
  500. }
  501. return strResult;
  502. }
  503. CSimpleString CWiaDebugDump::GetWiaItemTypeFlags( IUnknown *pUnknown )
  504. {
  505. CSimpleString strResult;
  506. if (pUnknown)
  507. {
  508. CComPtr<IWiaItem> pWiaItem;
  509. HRESULT hr = pUnknown->QueryInterface( IID_IWiaItem, (void**)&pWiaItem );
  510. if (SUCCEEDED(hr))
  511. {
  512. LONG nItemType = 0;
  513. hr = pWiaItem->GetItemType(&nItemType);
  514. if (SUCCEEDED(hr))
  515. {
  516. static const struct
  517. {
  518. ULONG nFlag;
  519. LPCTSTR pszName;
  520. }
  521. s_Flags[] =
  522. {
  523. { WiaItemTypeFree, TEXT("WiaItemTypeFree") },
  524. { WiaItemTypeImage, TEXT("WiaItemTypeImage") },
  525. { WiaItemTypeFile, TEXT("WiaItemTypeFile") },
  526. { WiaItemTypeFolder, TEXT("WiaItemTypeFolder") },
  527. { WiaItemTypeRoot, TEXT("WiaItemTypeRoot") },
  528. { WiaItemTypeAnalyze, TEXT("WiaItemTypeAnalyze") },
  529. { WiaItemTypeAudio, TEXT("WiaItemTypeAudio") },
  530. { WiaItemTypeDevice, TEXT("WiaItemTypeDevice") },
  531. { WiaItemTypeDeleted, TEXT("WiaItemTypeDeleted") },
  532. { WiaItemTypeDisconnected, TEXT("WiaItemTypeDisconnected") },
  533. { WiaItemTypeHPanorama, TEXT("WiaItemTypeHPanorama") },
  534. { WiaItemTypeVPanorama, TEXT("WiaItemTypeVPanorama") },
  535. { WiaItemTypeBurst, TEXT("WiaItemTypeBurst") },
  536. { WiaItemTypeStorage, TEXT("WiaItemTypeStorage") },
  537. { WiaItemTypeTransfer, TEXT("WiaItemTypeTransfer") },
  538. { WiaItemTypeGenerated, TEXT("WiaItemTypeGenerated") },
  539. { WiaItemTypeHasAttachments, TEXT("WiaItemTypeHasAttachments") },
  540. { WiaItemTypeVideo, TEXT("WiaItemTypeVideo") }
  541. };
  542. for (int i=0;i<ARRAYSIZE(s_Flags);i++)
  543. {
  544. if (nItemType & s_Flags[i].nFlag)
  545. {
  546. if (strResult.Length())
  547. {
  548. strResult += TEXT(" | ");
  549. }
  550. strResult += s_Flags[i].pszName;
  551. }
  552. }
  553. }
  554. }
  555. }
  556. return strResult;
  557. }
  558. CSimpleString CWiaDebugDump::GetStringFromGuid( const GUID &guid )
  559. {
  560. static HINSTANCE s_WiaDebugInstance = NULL;
  561. static GetStringFromGuidProc s_pfnGetStringFromGuid = NULL;
  562. if (!s_pfnGetStringFromGuid)
  563. {
  564. if (!s_WiaDebugInstance)
  565. {
  566. s_WiaDebugInstance = LoadLibrary(TEXT("wiadebug.dll"));
  567. }
  568. if (s_WiaDebugInstance)
  569. {
  570. s_pfnGetStringFromGuid = reinterpret_cast<GetStringFromGuidProc>(GetProcAddress( s_WiaDebugInstance, GET_STRING_FROM_GUID_NAME ));
  571. }
  572. }
  573. if (s_pfnGetStringFromGuid)
  574. {
  575. TCHAR szString[MAX_PATH];
  576. s_pfnGetStringFromGuid( &guid, szString, ARRAYSIZE(szString) );
  577. return szString;
  578. }
  579. else
  580. {
  581. CSimpleString strResult;
  582. LPOLESTR pszGuid = NULL;
  583. HRESULT hr = StringFromCLSID( guid, &pszGuid );
  584. if (SUCCEEDED(hr) && pszGuid)
  585. {
  586. strResult = CSimpleStringConvert::NaturalString(CSimpleStringWide(pszGuid));
  587. CoTaskMemFree(pszGuid);
  588. }
  589. return strResult;
  590. }
  591. }
  592. void CWiaDebugDump::DumpWiaPropertyStorage( IUnknown *pUnknown )
  593. {
  594. if (OK())
  595. {
  596. //
  597. // Make sure we have a non-NULL interface pointer
  598. //
  599. if (pUnknown)
  600. {
  601. //
  602. // Get the proper interface
  603. //
  604. CComPtr<IWiaPropertyStorage> pWiaPropertyStorage;
  605. HRESULT hr = pUnknown->QueryInterface( IID_IWiaPropertyStorage, (void**)&pWiaPropertyStorage );
  606. if (SUCCEEDED(hr))
  607. {
  608. //
  609. // Get information about this property storage
  610. //
  611. CComPtr<IEnumSTATPROPSTG> pEnumStatPropStorage;
  612. hr = pWiaPropertyStorage->Enum(&pEnumStatPropStorage);
  613. if (SUCCEEDED(hr))
  614. {
  615. //
  616. // Enumerate the properties
  617. //
  618. STATPROPSTG StatPropStg = {0};
  619. while ((hr = pEnumStatPropStorage->Next(1,&StatPropStg,NULL)) == S_OK)
  620. {
  621. //
  622. // Prepare the propspec
  623. //
  624. PROPSPEC PropSpec = {0};
  625. PropSpec.ulKind = PRSPEC_PROPID;
  626. PropSpec.propid = StatPropStg.propid;
  627. //
  628. // Prepare the propvariant
  629. //
  630. PROPVARIANT PropVariant = {0};
  631. //
  632. // Get the property
  633. //
  634. hr = pWiaPropertyStorage->ReadMultiple( 1, &PropSpec, &PropVariant );
  635. if (SUCCEEDED(hr))
  636. {
  637. //
  638. // Get the property attributes
  639. //
  640. ULONG nAccessFlags = 0;
  641. PROPVARIANT PropVariantAttributes = {0};
  642. hr = pWiaPropertyStorage->GetPropertyAttributes( 1, &PropSpec, &nAccessFlags, &PropVariantAttributes );
  643. if (SUCCEEDED(hr))
  644. {
  645. //
  646. // Print out the properties
  647. //
  648. CSimpleString strName = GetPrintableName( StatPropStg );
  649. Print( CSimpleString().Format(TEXT(" %s"), strName.String() ));
  650. CSimpleString strType = GetPropVariantTypeString( PropVariant.vt );
  651. Print( CSimpleString().Format(TEXT(" Type: %s"), strType.String()) );
  652. CSimpleString strAccess = GetPrintableAccessFlags( nAccessFlags );
  653. Print( CSimpleString().Format(TEXT(" Access: %s"), strAccess.String()) );
  654. CSimpleString strValue = GetPrintableValue( PropVariant );
  655. Print( CSimpleString().Format(TEXT(" Curr: %s"), strValue.String()) );
  656. CSimpleString strLegalValues = GetPrintableLegalValues( nAccessFlags, PropVariantAttributes );
  657. if (strLegalValues.Length())
  658. {
  659. Print( CSimpleString().Format(TEXT(" Legal: %s"), strLegalValues.String()) );
  660. }
  661. //
  662. // Free the attributes
  663. //
  664. PropVariantClear(&PropVariantAttributes);
  665. }
  666. //
  667. // Free the property
  668. //
  669. PropVariantClear(&PropVariant);
  670. }
  671. //
  672. // Clean up the STATPROPSTG
  673. //
  674. if (StatPropStg.lpwstrName)
  675. {
  676. CoTaskMemFree(StatPropStg.lpwstrName);
  677. }
  678. ZeroMemory(&StatPropStg,sizeof(StatPropStg));
  679. }
  680. }
  681. }
  682. }
  683. }
  684. }
  685. void CWiaDebugDump::Print( LPCTSTR pszString )
  686. {
  687. WIA_TRACE((TEXT("%s"), pszString ));
  688. }
  689. void CWiaDebugDump::PrintAndDestroyWiaDevCap( WIA_DEV_CAP &WiaDevCap, LPCTSTR pszType )
  690. {
  691. if (OK())
  692. {
  693. Print( CSimpleString().Format(TEXT(" %s: %s"), pszType, GetStringFromGuid( WiaDevCap.guid ).String()));
  694. Print( CSimpleString().Format(TEXT(" Flags: %08X"), WiaDevCap.ulFlags) );
  695. if (WiaDevCap.bstrName)
  696. {
  697. Print( CSimpleString().Format(TEXT(" Name: %ws"), WiaDevCap.bstrName) );
  698. SysFreeString(WiaDevCap.bstrName);
  699. WiaDevCap.bstrName = NULL;
  700. }
  701. if (WiaDevCap.bstrDescription)
  702. {
  703. Print( CSimpleString().Format(TEXT(" Description: %ws"), WiaDevCap.bstrDescription) );
  704. SysFreeString(WiaDevCap.bstrDescription);
  705. WiaDevCap.bstrDescription = NULL;
  706. }
  707. if (WiaDevCap.bstrIcon)
  708. {
  709. Print( CSimpleString().Format(TEXT(" Icon: %ws"), WiaDevCap.bstrIcon));
  710. SysFreeString(WiaDevCap.bstrIcon);
  711. WiaDevCap.bstrIcon = NULL;
  712. }
  713. if (WiaDevCap.bstrCommandline)
  714. {
  715. Print( CSimpleString().Format(TEXT(" bstrCommandline: %ws"), WiaDevCap.bstrCommandline));
  716. SysFreeString(WiaDevCap.bstrCommandline);
  717. WiaDevCap.bstrCommandline = NULL;
  718. }
  719. }
  720. }
  721. void CWiaDebugDump::DumpCaps( IUnknown *pUnknown )
  722. {
  723. if (pUnknown)
  724. {
  725. //
  726. // Get the item
  727. //
  728. CComPtr<IWiaItem> pWiaItem;
  729. HRESULT hr = pUnknown->QueryInterface( IID_IWiaItem, (void**)&pWiaItem );
  730. if (SUCCEEDED(hr))
  731. {
  732. //
  733. // Get the format enumerator
  734. //
  735. CComPtr<IEnumWIA_DEV_CAPS> pEnumWIA_DEV_CAPS;
  736. hr = pWiaItem->EnumDeviceCapabilities(WIA_DEVICE_COMMANDS,&pEnumWIA_DEV_CAPS);
  737. if (SUCCEEDED(hr))
  738. {
  739. //
  740. // Start at the beginning
  741. //
  742. hr = pEnumWIA_DEV_CAPS->Reset();
  743. while (hr == S_OK)
  744. {
  745. //
  746. // Get the next item
  747. //
  748. WIA_DEV_CAP WiaDevCap = {0};
  749. hr = pEnumWIA_DEV_CAPS->Next(1, &WiaDevCap, NULL);
  750. if (hr == S_OK)
  751. {
  752. PrintAndDestroyWiaDevCap( WiaDevCap, TEXT("Capability") );
  753. }
  754. }
  755. }
  756. }
  757. }
  758. }
  759. void CWiaDebugDump::DumpEvents( IUnknown *pUnknown )
  760. {
  761. if (pUnknown)
  762. {
  763. //
  764. // Get the item
  765. //
  766. CComPtr<IWiaItem> pWiaItem;
  767. HRESULT hr = pUnknown->QueryInterface( IID_IWiaItem, (void**)&pWiaItem );
  768. if (SUCCEEDED(hr))
  769. {
  770. //
  771. // Get the format enumerator
  772. //
  773. CComPtr<IEnumWIA_DEV_CAPS> pEnumWIA_DEV_CAPS;
  774. hr = pWiaItem->EnumDeviceCapabilities(WIA_DEVICE_EVENTS,&pEnumWIA_DEV_CAPS);
  775. if (SUCCEEDED(hr))
  776. {
  777. //
  778. // Start at the beginning
  779. //
  780. hr = pEnumWIA_DEV_CAPS->Reset();
  781. while (hr == S_OK)
  782. {
  783. //
  784. // Get the next item
  785. //
  786. WIA_DEV_CAP WiaDevCap = {0};
  787. hr = pEnumWIA_DEV_CAPS->Next(1, &WiaDevCap, NULL);
  788. if (hr == S_OK)
  789. {
  790. PrintAndDestroyWiaDevCap( WiaDevCap, TEXT("Event") );
  791. }
  792. }
  793. }
  794. }
  795. }
  796. }
  797. void CWiaDebugDump::DumpFormatInfo( IUnknown *pUnknown )
  798. {
  799. if (OK())
  800. {
  801. if (pUnknown)
  802. {
  803. //
  804. // Get the data transfer interface
  805. //
  806. CComPtr<IWiaDataTransfer> pWiaDataTransfer;
  807. HRESULT hr = pUnknown->QueryInterface( IID_IWiaDataTransfer, (void**)&pWiaDataTransfer );
  808. if (SUCCEEDED(hr))
  809. {
  810. //
  811. // Get the format enumerator
  812. //
  813. CComPtr<IEnumWIA_FORMAT_INFO> pEnumWIA_FORMAT_INFO;
  814. hr = pWiaDataTransfer->idtEnumWIA_FORMAT_INFO(&pEnumWIA_FORMAT_INFO);
  815. if (SUCCEEDED(hr))
  816. {
  817. //
  818. // Start at the beginning
  819. //
  820. hr = pEnumWIA_FORMAT_INFO->Reset();
  821. while (hr == S_OK)
  822. {
  823. //
  824. // Get the next item
  825. //
  826. WIA_FORMAT_INFO WiaFormatInfo = {0};
  827. hr = pEnumWIA_FORMAT_INFO->Next(1, &WiaFormatInfo, NULL);
  828. if (hr == S_OK)
  829. {
  830. Print(CSimpleString().Format( TEXT(" Supported format: %s, TYMED: %s"), GetStringFromGuid( WiaFormatInfo.guidFormatID ).String(), GetTymedString( WiaFormatInfo.lTymed ).String() ));
  831. }
  832. }
  833. }
  834. }
  835. }
  836. }
  837. }
  838. void CWiaDebugDump::DumpWiaItem( IUnknown *pUnknown )
  839. {
  840. if (OK() && pUnknown)
  841. {
  842. CSimpleStringWide strFullItemName;
  843. PropStorageHelpers::GetProperty( pUnknown, WIA_IPA_FULL_ITEM_NAME, strFullItemName );
  844. Print( CSimpleString().Format( TEXT("[Dumping %ws]"), strFullItemName.String() ) );
  845. CSimpleString strItemType = GetWiaItemTypeFlags( pUnknown );
  846. Print( CSimpleString().Format(TEXT(" Item Type: %s"), strItemType.String()) );
  847. DumpFormatInfo( pUnknown );
  848. DumpCaps( pUnknown );
  849. DumpEvents( pUnknown );
  850. DumpWiaPropertyStorage( pUnknown );
  851. Print( TEXT("") );
  852. }
  853. }
  854. void CWiaDebugDump::DumpRecursive( IUnknown *pUnknown )
  855. {
  856. if (OK() && pUnknown)
  857. {
  858. //
  859. // Get an item pointer
  860. //
  861. CComPtr<IWiaItem> pWiaItem;
  862. HRESULT hr = pUnknown->QueryInterface( IID_IWiaItem, (void**)&pWiaItem );
  863. if (SUCCEEDED(hr))
  864. {
  865. //
  866. // Dump this one
  867. //
  868. DumpWiaItem(pWiaItem);
  869. //
  870. // Recurse into this item's children
  871. //
  872. CComPtr <IEnumWiaItem> pEnumChildItem;
  873. hr = pWiaItem->EnumChildItems(&pEnumChildItem);
  874. if (SUCCEEDED(hr))
  875. {
  876. //
  877. // Start at the beginning
  878. //
  879. hr = pEnumChildItem->Reset();
  880. while (hr == S_OK)
  881. {
  882. //
  883. // Get the next item
  884. //
  885. CComPtr<IWiaItem> pChildItem;
  886. hr = pEnumChildItem->Next(1, &pChildItem, NULL);
  887. if (hr == S_OK)
  888. {
  889. DumpRecursive( pChildItem );
  890. }
  891. }
  892. }
  893. }
  894. }
  895. }