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.

1231 lines
40 KiB

  1. /****************************************************************************
  2. *
  3. * (C) COPYRIGHT 2000, MICROSOFT CORP.
  4. *
  5. * FILE: wiautil.h
  6. *
  7. * VERSION: 1.0
  8. *
  9. * DATE: 11/17/2000
  10. *
  11. * DESCRIPTION:
  12. * Definitions for WIA driver helper classes and functions.
  13. * NOTE: This header requires wiamindr.h to be included.
  14. *
  15. *****************************************************************************/
  16. #pragma once
  17. /**************************************************************************\
  18. * CWiauFormatConverter
  19. *
  20. * Helper class for converting images to BMP format.
  21. *
  22. \**************************************************************************/
  23. typedef struct _BMP_IMAGE_INFO
  24. {
  25. INT Width; // Width of the image in pixels
  26. INT Height; // Height of the image in lines
  27. INT ByteWidth; // Width of the image in bytes
  28. INT Size; // Total size of the image, including headers
  29. } BMP_IMAGE_INFO, *PBMP_IMAGE_INFO;
  30. typedef enum
  31. {
  32. SKIP_OFF,
  33. SKIP_FILEHDR,
  34. SKIP_BOTHHDR
  35. } SKIP_AMOUNT;
  36. class CWiauFormatConverter
  37. {
  38. public:
  39. CWiauFormatConverter();
  40. ~CWiauFormatConverter();
  41. /**************************************************************************\
  42. * Init
  43. *
  44. * Intializes this class and GDI+ for converting images. This method
  45. * should be called just once.
  46. *
  47. \**************************************************************************/
  48. HRESULT Init();
  49. /**************************************************************************\
  50. * IsFormatSupported
  51. *
  52. * This method will verify that GDI+ supports the image format
  53. * that is to be converted.
  54. *
  55. * Arguments:
  56. *
  57. * pguidFormat - pointer to GUID format from gdiplusimaging.h
  58. *
  59. \**************************************************************************/
  60. BOOL IsFormatSupported(const GUID *pguidFormat);
  61. /**************************************************************************\
  62. * ConvertToBmp
  63. *
  64. * This method will convert an image to BMP format. The caller can pass
  65. * a result buffer in ppDest and the size in piDestSize. Alternatively
  66. * the caller can set *ppDest to NULL and *piDestSize to zero to
  67. * indicate that this method should allocate the memory. The caller is
  68. * responsible for freeing the memory with "delete []".
  69. *
  70. * Arguments:
  71. *
  72. * pSource - pointer to memory location of source image
  73. * iSourceSize - size of source image
  74. * ppDest - location to receive memory location of result image
  75. * piDestSize - location to receive size of result image
  76. * pBmpImageInfo - location to receive stats about the BMP
  77. * iSkipAmt - Indicates how much of the BMP header to skip:
  78. * SKIP_OFF = skip neither header
  79. * SKIP_FILEHDR = skip the file header
  80. * SKIP_BOTHHDR = skip the file and info headers
  81. *
  82. \**************************************************************************/
  83. HRESULT ConvertToBmp(BYTE *pSource, INT iSourceSize, BYTE **ppDest, INT *piDestSize,
  84. BMP_IMAGE_INFO *pBmpImageInfo, SKIP_AMOUNT iSkipAmt = SKIP_OFF);
  85. private:
  86. ULONG_PTR m_Token;
  87. UINT m_EncoderCount;
  88. BYTE *m_pEncoderInfo;
  89. GUID m_guidCodecBmp;
  90. };
  91. /**************************************************************************\
  92. * CWiauPropertyList
  93. *
  94. * Helper class for definining and initializing WIA properties
  95. *
  96. \**************************************************************************/
  97. class CWiauPropertyList
  98. {
  99. private:
  100. int m_NumAlloc; // number of slots allocated
  101. int m_NumProps; // number of properties defined
  102. PROPID *m_pId; // property ids
  103. LPOLESTR *m_pNames; // property names
  104. PROPVARIANT *m_pCurrent; // current value
  105. PROPSPEC *m_pPropSpec; // property spec (used for WriteMultiple)
  106. WIA_PROPERTY_INFO *m_pAttrib; // property attributes
  107. public:
  108. CWiauPropertyList();
  109. ~CWiauPropertyList();
  110. /**************************************************************************\
  111. * Init
  112. *
  113. * Initializes the property info object.
  114. *
  115. * Arguments:
  116. * NumProps - number of properties to reserve space for. This number can
  117. * be larger than the actual number used, but cannot be smaller.
  118. *
  119. \**************************************************************************/
  120. HRESULT Init(INT NumProps);
  121. /**************************************************************************\
  122. * DefineProperty
  123. *
  124. * Adds a property definition to the object.
  125. *
  126. * Arguments:
  127. * index - pointer to an int that will be set to the property index
  128. * within the object, useful for passing to other property
  129. * info methods
  130. * PropId - property ID constant
  131. * PropName - property name string
  132. * Access - determines access to the property, usually either
  133. * WIA_PROP_READ or WIA_PROP_RW
  134. * SubType - indicates subtype of the property, usually either
  135. * WIA_PROP_NONE, WIA_PROP_FLAG, WIA_PROP_RANGE, or WIA_PROP_LIST
  136. *
  137. \**************************************************************************/
  138. HRESULT DefineProperty(int *pIdx, PROPID PropId, LPOLESTR PropName,
  139. ULONG Access, ULONG SubType);
  140. /**************************************************************************\
  141. * SendToWia
  142. *
  143. * Calls the WIA service to define all of the properties currently
  144. * contained in the object. Should be called once after all properties
  145. * are defined and set.
  146. *
  147. * Arguments:
  148. * pWiasContext - pointer to the context passed into drvInitItemProperties
  149. *
  150. \**************************************************************************/
  151. HRESULT SendToWia(BYTE *pWiasContext);
  152. /**************************************************************************\
  153. * SetAccessSubType
  154. *
  155. * Used to reset the access and subtype of a property.
  156. *
  157. * Arguments:
  158. * index - the property index, from DefineProperty
  159. * Access - determines access to the property, usually either
  160. * WIA_PROP_READ or WIA_PROP_RW
  161. * SubType - indicates subtype of the property, usually either
  162. * WIA_PROP_NONE, WIA_PROP_FLAG, WIA_PROP_RANGE, or WIA_PROP_LIST
  163. *
  164. \**************************************************************************/
  165. VOID SetAccessSubType(INT index, ULONG Access, ULONG SubType);
  166. /**************************************************************************\
  167. * SetValidValues (flag)
  168. *
  169. * Sets the type and current, default, and valid values of a property.
  170. * Also sets property type to VT_I4 and subtype to WIA_PROP_FLAG.
  171. *
  172. * Arguments:
  173. * index - the property index, from DefineProperty
  174. * defaultValue - default setting of this property on the device
  175. * currentValue - current setting of this property on the device
  176. * validFlags - combination of all valid flags
  177. *
  178. \**************************************************************************/
  179. VOID SetValidValues(INT index, LONG defaultValue, LONG currentValue, LONG validFlags);
  180. /**************************************************************************\
  181. * SetValidValues (signed long, range)
  182. *
  183. * Sets the type and current, default, and valid values of a property.
  184. * Also sets property type to VT_I4 and subtype to WIA_PROP_RANGE.
  185. *
  186. * Arguments:
  187. * index - the property index, from DefineProperty
  188. * defaultValue - default setting of this property on the device
  189. * currentValue - current setting of this property on the device
  190. * minValue - minimum value for the range
  191. * maxValue - maximum value for the range
  192. * stepValue - step value for the range
  193. *
  194. \**************************************************************************/
  195. VOID SetValidValues(INT index, LONG defaultValue, LONG currentValue,
  196. LONG minValue, LONG maxValue, LONG stepValue);
  197. /**************************************************************************\
  198. * SetValidValues (signed long, list)
  199. *
  200. * Sets the type and current, default, and valid values of a property.
  201. * Also sets property type to VT_I4 and subtype to WIA_PROP_LIST.
  202. *
  203. * Arguments:
  204. * index - the property index, from DefineProperty
  205. * defaultValue - default setting of this property on the device
  206. * currentValue - current setting of this property on the device
  207. * numValues - number of values in the list
  208. * pValues - pointer to the value list (must be valid until SendToWia
  209. * is called)
  210. *
  211. \**************************************************************************/
  212. VOID SetValidValues(INT index, LONG defaultValue, LONG currentValue,
  213. INT numValues, PLONG pValues);
  214. /**************************************************************************\
  215. * SetValidValues (BSTR, list)
  216. *
  217. * Sets the type and current, default, and valid values of a property.
  218. * Also sets property type to VT_BSTR and subtype to WIA_PROP_LIST.
  219. *
  220. * Arguments:
  221. * index - the property index, from DefineProperty
  222. * defaultValue - default setting of this property on the device
  223. * currentValue - current setting of this property on the device
  224. * numValues - number of values in the list
  225. * pValues - pointer to the value list (must be valid until SendToWia
  226. * is called)
  227. *
  228. \**************************************************************************/
  229. VOID SetValidValues(INT index, BSTR defaultValue, BSTR currentValue,
  230. INT numValues, BSTR *pValues);
  231. /**************************************************************************\
  232. * SetValidValues (float, range)
  233. *
  234. * Sets the type and current, default, and valid values of a property.
  235. * Also sets property type to VT_R4 and subtype to WIA_PROP_RANGE.
  236. *
  237. * Arguments:
  238. * index - the property index, from DefineProperty
  239. * defaultValue - default setting of this property on the device
  240. * currentValue - current setting of this property on the device
  241. * minValue - minimum value for the range
  242. * maxValue - maximum value for the range
  243. * stepValue - step value for the range
  244. *
  245. \**************************************************************************/
  246. VOID SetValidValues(INT index, FLOAT defaultValue, FLOAT currentValue,
  247. FLOAT minValue, FLOAT maxValue, FLOAT stepValue);
  248. /**************************************************************************\
  249. * SetValidValues (float, list)
  250. *
  251. * Sets the type and current, default, and valid values of a property.
  252. * Also sets property type to VT_R4 and subtype to WIA_PROP_LIST.
  253. *
  254. * Arguments:
  255. * index - the property index, from DefineProperty
  256. * defaultValue - default setting of this property on the device
  257. * currentValue - current setting of this property on the device
  258. * numValues - number of values in the list
  259. * pValues - pointer to the value list (must be valid until SendToWia
  260. * is called)
  261. *
  262. \**************************************************************************/
  263. VOID SetValidValues(INT index, FLOAT defaultValue, FLOAT currentValue,
  264. INT numValues, PFLOAT pValues);
  265. /**************************************************************************\
  266. * SetValidValues (CLSID, list)
  267. *
  268. * Sets the type and current, default, and valid values of a property.
  269. * Also sets property type to VT_CLSID and subtype to WIA_PROP_LIST.
  270. *
  271. * Arguments:
  272. * index - the property index, from DefineProperty
  273. * defaultValue - default setting of this property on the device
  274. * currentValue - current setting of this property on the device
  275. * numValues - number of values in the list
  276. * pValues - pointer to the value list (must be valid until SendToWia
  277. * is called)
  278. *
  279. \**************************************************************************/
  280. VOID SetValidValues(INT index, CLSID *defaultValue, CLSID *currentValue,
  281. INT numValues, CLSID **pValues);
  282. /**************************************************************************\
  283. * SetCurrentValue (signed long)
  284. *
  285. * Sets the current value for a property. Also sets the type to VT_I4.
  286. *
  287. * Arguments:
  288. * index - the property index, from DefineProperty
  289. * value - current setting of this property on the device
  290. *
  291. \**************************************************************************/
  292. VOID SetCurrentValue(INT index, LONG value);
  293. /**************************************************************************\
  294. * SetCurrentValue (BSTR)
  295. *
  296. * Sets the current value for a property. Also sets the type to VT_BSTR.
  297. *
  298. * Arguments:
  299. * index - the property index, from DefineProperty
  300. * value - current setting of this property on the device
  301. * (must be valid until SendToWia is called)
  302. *
  303. \**************************************************************************/
  304. VOID SetCurrentValue(INT index, BSTR value);
  305. /**************************************************************************\
  306. * SetCurrentValue (float)
  307. *
  308. * Sets the current value for a property. Also sets the type to VT_R4.
  309. *
  310. * Arguments:
  311. * index - the property index, from DefineProperty
  312. * value - current setting of this property on the device
  313. *
  314. \**************************************************************************/
  315. VOID SetCurrentValue(INT index, FLOAT value);
  316. /**************************************************************************\
  317. * SetCurrentValue (CLSID)
  318. *
  319. * Sets the current value for a property. Also sets the type to VT_CLSID.
  320. *
  321. * Arguments:
  322. * index - the property index, from DefineProperty
  323. * value - current setting of this property on the device
  324. * (must be valid until SendToWia is called)
  325. *
  326. \**************************************************************************/
  327. VOID SetCurrentValue(INT index, CLSID *pValue);
  328. /**************************************************************************\
  329. * SetCurrentValue (SYSTEMTIME)
  330. *
  331. * Sets the current value for a property. Also sets the type to
  332. * VT_UI2 | VT_VECTOR.
  333. *
  334. * Arguments:
  335. * index - the property index, from DefineProperty
  336. * value - current setting of this property on the device
  337. * (must be valid until SendToWia is called)
  338. *
  339. \**************************************************************************/
  340. VOID SetCurrentValue(INT index, PSYSTEMTIME value);
  341. /**************************************************************************\
  342. * SetCurrentValue (byte array)
  343. *
  344. * Sets the current value for a property. Also sets the type to
  345. * VT_UI1 | VT_VECTOR.
  346. *
  347. * Arguments:
  348. * index - the property index, from DefineProperty
  349. * value - pointer to current setting of this property on the device
  350. * (must be valid until SendToWia is called)
  351. *
  352. \**************************************************************************/
  353. VOID SetCurrentValue(INT index, BYTE *value, INT size);
  354. /**************************************************************************\
  355. * GetPropId
  356. *
  357. * Returns the property id given a property index.
  358. *
  359. \**************************************************************************/
  360. PROPID GetPropId(INT index) { return m_pId[index]; }
  361. /**************************************************************************\
  362. * LookupPropId
  363. *
  364. * Finds the property index given a property ID.
  365. *
  366. \**************************************************************************/
  367. INT LookupPropId(PROPID PropId);
  368. };
  369. /**************************************************************************\
  370. * wiauGetDrvItemContext
  371. *
  372. * This helper function gets the driver item context, and optionally
  373. * return the driver item
  374. *
  375. * Arguments:
  376. *
  377. * pWiasContext - pointer to the item context
  378. * ppItemCtx - location to store pointer to driver item context
  379. * ppDrvItem - location to store pointer to driver item (can be NULL)
  380. *
  381. \**************************************************************************/
  382. HRESULT wiauGetDrvItemContext(BYTE *pWiasContext, VOID **ppItemCtx, IWiaDrvItem **ppDrvItem = NULL);
  383. /**************************************************************************\
  384. * wiauSetImageItemSize
  385. *
  386. * Calulates the size and width in bytes for an image based on the current
  387. * WIA_IPA_FORMAT setting, and writes the new values to the appropriate
  388. * properties. If the format is not BMP, this function assumes that the
  389. * value passed in lSize is correct for the current format.
  390. *
  391. * Arguments:
  392. *
  393. * pWiasContext - pointer to item context
  394. * lWidth - width of the image in pixels
  395. * lHeight - height of the image in lines
  396. * lDepth - depth of the image in bits
  397. * lSize - size of the image as stored on the device
  398. * pwszExt - optional pointer to the 3 letter extension for the
  399. * item's native format (if this is NULL, the extension
  400. * property won't be updated)
  401. *
  402. \**************************************************************************/
  403. HRESULT wiauSetImageItemSize(BYTE *pWiasContext, LONG lWidth, LONG lHeight, LONG lDepth,
  404. LONG lSize, PWSTR pwszExt = NULL);
  405. /**************************************************************************\
  406. * wiauPropsInPropSpec
  407. *
  408. * Returns true if one or more of the property ids in pProps are
  409. * contained in pPropSpecs.
  410. *
  411. * Arguments:
  412. *
  413. * NumPropSpecs - number of property specs in the array
  414. * pPropSpecs - the property specs array
  415. * NumProps - number of property ids to search for
  416. * pProps - pointer to the array of property ids to search for
  417. *
  418. \**************************************************************************/
  419. BOOL wiauPropsInPropSpec(LONG NumPropSpecs, const PROPSPEC *pPropSpecs, int NumProps, PROPID *pProps);
  420. /**************************************************************************\
  421. * wiauPropInPropSpec
  422. *
  423. * Returns true if the PropId property ID is in the passed pPropSpecs
  424. * array. Optionally will return the index of where the ID was found.
  425. *
  426. * Arguments:
  427. *
  428. * NumPropSpecs - number of property specs in the array
  429. * pPropSpecs - the property specs array
  430. * PropId - property id to search for
  431. * pIdx - optional pointer to the location to store the index
  432. *
  433. \**************************************************************************/
  434. BOOL wiauPropInPropSpec(LONG NumPropSpecs, const PROPSPEC *pPropSpecs, PROPID PropId, int *pIdx = NULL);
  435. /**************************************************************************\
  436. * wiauGetValidFormats
  437. *
  438. * Calls drvGetWiaFormatInfo and makes a list of valid formats given
  439. * a tymed value. Caller is responsible for freeing the format array
  440. * with []delete.
  441. *
  442. * Arguments:
  443. *
  444. * pDrv - Pointer to WIA minidriver object (use "this")
  445. * pWiasContext - WIA service context
  446. * TymedValue - tymed value to search for
  447. * pNumFormats - pointer to value to receive number of formats
  448. * ppFormatArray - pointer to a location to receive array address
  449. *
  450. \**************************************************************************/
  451. HRESULT wiauGetValidFormats(IWiaMiniDrv *pDrv, BYTE *pWiasContext, LONG TymedValue,
  452. int *pNumFormats, GUID **ppFormatArray);
  453. /**************************************************************************\
  454. * wiauGetResourceString
  455. *
  456. * This helper gets a resource string and returns it as a BSTR
  457. *
  458. * Arguments:
  459. *
  460. * hInst - Handle to module instance
  461. * lResourceID - Resource ID of the target BSTR value
  462. * pbstrStr - Location to store the retrieved string (caller must
  463. * free this string with SysFreeString())
  464. *
  465. \**************************************************************************/
  466. HRESULT wiauGetResourceString(HINSTANCE hInst, LONG lResourceID, BSTR *pbstrStr);
  467. /**************************************************************************\
  468. * wiauRegOpenDataW
  469. *
  470. * Opens the DeviceData key. Call this function only in the STI Initialize
  471. * function. Call RegCloseKey when finished.
  472. *
  473. * Arguments:
  474. *
  475. * hkeyAncestor - HKey of parent (use hkey passed into Initialize)
  476. * phkeyDeviceData - Location to store opened hkey
  477. *
  478. \**************************************************************************/
  479. HRESULT wiauRegOpenDataW(HKEY hkeyAncestor, HKEY *phkeyDeviceData);
  480. /**************************************************************************\
  481. * wiauRegOpenDataA
  482. *
  483. * Opens the DeviceData key. Call this function only in the STI Initialize
  484. * function. Call RegCloseKey when finished.
  485. *
  486. * Arguments:
  487. *
  488. * hkeyAncestor - HKey of parent (use hkey passed into Initialize)
  489. * phkeyDeviceData - Location to store opened hkey
  490. *
  491. \**************************************************************************/
  492. HRESULT wiauRegOpenDataA(HKEY hkeyAncestor, HKEY *phkeyDeviceData);
  493. /**************************************************************************\
  494. * wiauRegGetStrW
  495. *
  496. * Use to get string value from the DeviceData section of the registry.
  497. *
  498. * Arguments:
  499. *
  500. * hkey - Use hkey returned from wiauRegOpenData
  501. * pwszValueName - Name of registry entry
  502. * pwszValue - Location to store returned string
  503. * pdwLength - Size of location in bytes
  504. *
  505. \**************************************************************************/
  506. HRESULT wiauRegGetStrW(HKEY hkKey, PCWSTR pwszValueName, PWSTR pwszValue, DWORD *pdwLength);
  507. /**************************************************************************\
  508. * wiauRegGetStrA
  509. *
  510. * Use to get string value from the DeviceData section of the registry.
  511. *
  512. * Arguments:
  513. *
  514. * hkey - Use hkey returned from wiauRegOpenData
  515. * pszValueName - Name of registry entry
  516. * pszValue - Location to store returned string
  517. * pdwLength - Size of location in bytes
  518. *
  519. \**************************************************************************/
  520. HRESULT wiauRegGetStrA(HKEY hkKey, PCSTR pszValueName, PSTR pszValue, DWORD *pdwLength);
  521. /**************************************************************************\
  522. * wiauRegGetDwordW
  523. *
  524. * Use to get DWORD value from the DeviceData section of the registry.
  525. *
  526. * Arguments:
  527. *
  528. * hkey - Use hkey returned from wiauRegOpenData
  529. * pwszValueName - Name of registry entry
  530. * pdwValue - Location to store returned DWORD
  531. *
  532. \**************************************************************************/
  533. HRESULT wiauRegGetDwordW(HKEY hkKey, PCWSTR pwszValueName, DWORD *pdwValue);
  534. /**************************************************************************\
  535. * wiauRegGetDwordA
  536. *
  537. * Use to get DWORD value from the DeviceData section of the registry.
  538. *
  539. * Arguments:
  540. *
  541. * hkey - Use hkey returned from wiauRegOpenData
  542. * pszValueName - Name of registry entry
  543. * pdwValue - Location to store returned DWORD
  544. *
  545. \**************************************************************************/
  546. HRESULT wiauRegGetDwordA(HKEY hkKey, PCSTR pszValueName, DWORD *pdwValue);
  547. /**************************************************************************\
  548. * WiauStrW2C
  549. *
  550. * Converts a wide character string to an ANSI character string
  551. *
  552. * Arguments:
  553. * pwszSrc - wide character string to be converted
  554. * pszDst - location to store the ANSI conversion
  555. * iSize - size of the buffer pointed to by pszDst, in bytes
  556. *
  557. \**************************************************************************/
  558. HRESULT wiauStrW2C(WCHAR *pwszSrc, CHAR *pszDst, INT iSize);
  559. /**************************************************************************\
  560. * WiauStrC2W
  561. *
  562. * Converts an ANSI character string to a wide character string
  563. *
  564. * Arguments:
  565. * pszSrc - ANSI string to convert
  566. * wpszDst - location to store the wide string
  567. * iSize - size of the buffer pointed to by wpszDst, in bytes
  568. *
  569. \**************************************************************************/
  570. HRESULT wiauStrC2W(CHAR *pszSrc, WCHAR *pwszDst, INT iSize);
  571. /**************************************************************************\
  572. * WiauStrW2W
  573. *
  574. * Copies a wide character string to another wide character string
  575. *
  576. * Arguments:
  577. * pwszSrc - wide character string to be copied
  578. * pwszDst - location to copy to
  579. * iSize - size of the buffer pointed to by pwszDst, in bytes
  580. *
  581. \**************************************************************************/
  582. HRESULT wiauStrW2W(WCHAR *pwszSrc, WCHAR *pwszDst, INT iSize);
  583. /**************************************************************************\
  584. * WiauStrC2C
  585. *
  586. * Copies an ANSI character string to another ANSI character string
  587. *
  588. * Arguments:
  589. * pszSrc - ANSI string to be copied
  590. * pszDst - location to copy to
  591. * iSize - size of the buffer pointed to by pszDst, in bytes
  592. *
  593. \**************************************************************************/
  594. HRESULT wiauStrC2C(CHAR *pszSrc, CHAR *pszDst, INT iSize);
  595. #ifdef UNICODE
  596. #define wiauRegOpenData wiauRegOpenDataW
  597. #define wiauRegGetStr wiauRegGetStrW
  598. #define wiauRegGetDword wiauRegGetDwordW
  599. #define wiauStrT2C wiauStrW2C
  600. #define wiauStrC2T wiauStrC2W
  601. #define wiauStrT2W wiauStrW2W
  602. #define wiauStrW2T wiauStrW2W
  603. #define WIAU_DEBUG_TSTR "S"
  604. #else
  605. #define wiauRegOpenData wiauRegOpenDataA
  606. #define wiauRegGetStr wiauRegGetStrA
  607. #define wiauRegGetDword wiauRegGetDwordA
  608. #define wiauStrT2C wiauStrC2C
  609. #define wiauStrC2T wiauStrC2C
  610. #define wiauStrT2W wiauStrC2W
  611. #define wiauStrW2T wiauStrW2C
  612. #define WIAU_DEBUG_TSTR "s"
  613. #endif // UNICODE
  614. /**************************************************************************\
  615. * WIA Debugging
  616. *
  617. * Definitions for debug messages. To use WIA debugging:
  618. * 1. Set registry HKLM\System\CurrentControlSet\Control\StillImage\Debug\<ModuleName>,
  619. * DWORD value "DebugFlags" to the combination of the WIAUDBG_* flags
  620. * desired. The application and possibly the WIA service will need to be
  621. * restarted to pick up the new settings. The key is auto created the
  622. * first time the module is executed. (Note: <ModuleName> above is the
  623. * name of the DLL or EXE, e.g. wiavusd.dll has a registry key of
  624. * "HKLM\System\CurrentControlSet\Control\StillImage\Debug\wiavusd.dll".)
  625. * 2. Or in the debugger, set g_dwDebugFlags to the combination of the
  626. * WIAUDBG_* flags desired. This can be done anytime during the debug
  627. * session.
  628. * 3. From the module, call wiauDbgSetFlags(<flags>), where <flags> is the
  629. * combination of the WIAUDBG_* flags desired.
  630. *
  631. * Messages will be logged to the debugger and the file
  632. * %systemroot%\\wiadebug.log, unless the WIAUDBG_DONT_LOG_* flags are set.
  633. * Setting both flags will turn off all messages.
  634. *
  635. * All strings should be ASCII. Use %S in the format string to print a
  636. * Unicode string.
  637. *
  638. \**************************************************************************/
  639. #define _STIDEBUG_H_ // WIA debugging is incompatible with stidebug.h, so don't include it
  640. //
  641. // Predefined debug flags
  642. //
  643. const DWORD WIAUDBG_ERRORS = 0x00000001;
  644. const DWORD WIAUDBG_WARNINGS = 0x00000002;
  645. const DWORD WIAUDBG_TRACES = 0x00000004;
  646. const DWORD WIAUDBG_FNS = 0x00000008; // Function entry and exit
  647. const DWORD WIAUDBG_DUMP = 0x00000010; // Dump data
  648. const DWORD WIAUDBG_PRINT_TIME = 0x08000000; // Prints time for each message
  649. const DWORD WIAUDBG_PRINT_INFO = 0x10000000; // Turns on thread, file, line info
  650. const DWORD WIAUDBG_DONT_LOG_TO_DEBUGGER = 0x20000000;
  651. const DWORD WIAUDBG_DONT_LOG_TO_FILE = 0x40000000;
  652. const DWORD WIAUDBG_BREAK_ON_ERRORS = 0x80000000; // Do DebugBreak on errors
  653. //
  654. // Don't log at all
  655. //
  656. const DWORD WIAUDBG_DONT_LOG = WIAUDBG_DONT_LOG_TO_FILE | WIAUDBG_DONT_LOG_TO_DEBUGGER;
  657. //
  658. // Set default flags
  659. //
  660. #ifdef DEBUG
  661. const DWORD WIAUDBG_DEFAULT_FLAGS = WIAUDBG_ERRORS;
  662. #else
  663. const DWORD WIAUDBG_DEFAULT_FLAGS = WIAUDBG_DONT_LOG;
  664. #endif
  665. //
  666. // FormatMessage flags
  667. //
  668. const DWORD WIAUDBG_MFMT_FLAGS = FORMAT_MESSAGE_IGNORE_INSERTS |
  669. FORMAT_MESSAGE_FROM_SYSTEM |
  670. FORMAT_MESSAGE_MAX_WIDTH_MASK;
  671. #ifdef __cplusplus
  672. extern "C" {
  673. #endif
  674. //
  675. // WIA Debugging has very little overhead and should be put into retail
  676. // code for drivers. If it's really desired to remove it, define NO_WIA_DEBUG.
  677. //
  678. #ifdef NO_WIA_DEBUG
  679. #define g_dwDebugFlags 0
  680. #define wiauDbgInit(a)
  681. #define wiauDbgHelper(a,b,c,d)
  682. #define wiauDbgHelper2 wiauNull3
  683. #define wiauDbgFlags wiauNull4
  684. #define wiauDbgError wiauNull2
  685. #define wiauDbgErrorHr wiauNull3hr
  686. #define wiauDbgWarning wiauNull2
  687. #define wiauDbgTrace wiauNull2
  688. #define wiauDbgDump wiauNull2
  689. #define wiauDbgSetFlags(a) 0
  690. #define wiauDbgLegacyError wiauNull1
  691. #define wiauDbgLegacyWarning wiauNull1
  692. #define wiauDbgLegacyTrace wiauNull1
  693. #define wiauDbgLegacyError2 wiauNull2h
  694. #define wiauDbgLegacyTrace2 wiauNull2h
  695. #define wiauDbgLegacyHresult2 wiauNullHHr
  696. inline void wiauNull1(LPCSTR a, ...) {}
  697. inline void wiauNull2(LPCSTR a, LPCSTR b,...) {}
  698. inline void wiauNull2h(HINSTANCE hInstance, LPCSTR b,...) {}
  699. inline void wiauNull3(LPCSTR a, LPCSTR b, LPCSTR c, ...) {}
  700. inline void wiauNull3hr(HRESULT a, LPCSTR b, LPCSTR c, ...) {}
  701. inline void wiauNull4(DWORD a, LPCSTR b, LPCSTR c, LPCSTR d, ...) {}
  702. inline void wiauNullHHr(HINSTANCE hInstance, HRESULT hr) {}
  703. #else // NO_WIA_DEBUG
  704. extern DWORD g_dwDebugFlags;
  705. extern HANDLE g_hDebugFile;
  706. extern DWORD g_dwDebugFileSizeLimit;
  707. extern BOOL g_bDebugInited;
  708. /**************************************************************************\
  709. * wiauDbgInit
  710. *
  711. * Call to initialize WIA debugging. If it's not called, all DLLs will
  712. * inherit the debug flags of the process that creates them.
  713. *
  714. * Arguments:
  715. *
  716. * hInstance - DLL instance handle
  717. *
  718. \**************************************************************************/
  719. void __stdcall wiauDbgInit(HINSTANCE hInstance);
  720. void __stdcall wiauDbgHelper(LPCSTR prefix, LPCSTR fname, LPCSTR fmt, va_list marker);
  721. void __stdcall wiauDbgHelper2(LPCSTR prefix, LPCSTR fname, LPCSTR fmt, ...);
  722. inline void __stdcall wiauDbgFlags(DWORD flags, LPCSTR prefix,
  723. LPCSTR fname, LPCSTR fmt, ...)
  724. {
  725. va_list marker;
  726. //
  727. // See if log messages are enabled and the flag is enabled
  728. //
  729. if (((g_dwDebugFlags & WIAUDBG_DONT_LOG) ^ WIAUDBG_DONT_LOG) &&
  730. (g_dwDebugFlags & flags)) {
  731. va_start(marker, fmt);
  732. wiauDbgHelper(prefix, fname, fmt, marker);
  733. va_end(marker);
  734. }
  735. }
  736. inline void __stdcall wiauDbgError(LPCSTR fname, LPCSTR fmt, ...)
  737. {
  738. va_list marker;
  739. //
  740. // See if log messages are enabled and error messages are turned on
  741. //
  742. if (((g_dwDebugFlags & WIAUDBG_DONT_LOG) ^ WIAUDBG_DONT_LOG) &&
  743. (g_dwDebugFlags & WIAUDBG_ERRORS)) {
  744. va_start(marker, fmt);
  745. wiauDbgHelper("ERROR ", fname, fmt, marker);
  746. va_end(marker);
  747. }
  748. if (g_dwDebugFlags & WIAUDBG_BREAK_ON_ERRORS) {
  749. DebugBreak();
  750. }
  751. }
  752. inline void __stdcall wiauDbgErrorHr(HRESULT hr, LPCSTR fname, LPCSTR fmt, ...)
  753. {
  754. va_list marker;
  755. //
  756. // See if log messages are enabled and error messages are turned on
  757. //
  758. if (((g_dwDebugFlags & WIAUDBG_DONT_LOG) ^ WIAUDBG_DONT_LOG) &&
  759. (g_dwDebugFlags & WIAUDBG_ERRORS)) {
  760. va_start(marker, fmt);
  761. wiauDbgHelper("ERROR ", fname, fmt, marker);
  762. va_end(marker);
  763. CHAR szError[MAX_PATH]; \
  764. if(!FormatMessageA(WIAUDBG_MFMT_FLAGS, NULL, hr, 0, szError, MAX_PATH, NULL))
  765. {
  766. strcpy(szError, "Unknown HRESULT");
  767. }
  768. wiauDbgHelper2("ERROR ", fname, "HRESULT = 0x%08x, %s", hr, szError);
  769. }
  770. if (g_dwDebugFlags & WIAUDBG_BREAK_ON_ERRORS) {
  771. DebugBreak();
  772. }
  773. }
  774. inline void __stdcall wiauDbgWarning(LPCSTR fname, LPCSTR fmt, ...)
  775. {
  776. va_list marker;
  777. //
  778. // See if log messages are enabled and warning messages are turned on
  779. //
  780. if (((g_dwDebugFlags & WIAUDBG_DONT_LOG) ^ WIAUDBG_DONT_LOG) &&
  781. (g_dwDebugFlags & WIAUDBG_WARNINGS)) {
  782. va_start(marker, fmt);
  783. wiauDbgHelper("WARN ", fname, fmt, marker);
  784. va_end(marker);
  785. }
  786. }
  787. inline void __stdcall wiauDbgTrace(LPCSTR fname, LPCSTR fmt, ...)
  788. {
  789. va_list marker;
  790. //
  791. // See if log messages are enabled and trace messages are turned on
  792. //
  793. if (((g_dwDebugFlags & WIAUDBG_DONT_LOG) ^ WIAUDBG_DONT_LOG) &&
  794. (g_dwDebugFlags & WIAUDBG_TRACES)) {
  795. va_start(marker, fmt);
  796. wiauDbgHelper(" ", fname, fmt, marker);
  797. va_end(marker);
  798. }
  799. }
  800. inline void __stdcall wiauDbgDump(LPCSTR fname, LPCSTR fmt, ...)
  801. {
  802. va_list marker;
  803. //
  804. // See if log messages are enabled and trace messages are turned on
  805. //
  806. if (((g_dwDebugFlags & WIAUDBG_DONT_LOG) ^ WIAUDBG_DONT_LOG) &&
  807. (g_dwDebugFlags & WIAUDBG_DUMP)) {
  808. va_start(marker, fmt);
  809. wiauDbgHelper(" ", fname, fmt, marker);
  810. va_end(marker);
  811. }
  812. }
  813. inline DWORD __stdcall wiauDbgSetFlags(DWORD flags)
  814. {
  815. DWORD dwOld = g_dwDebugFlags;
  816. g_dwDebugFlags = flags;
  817. return dwOld;
  818. }
  819. inline void __stdcall wiauDbgLegacyError(LPCSTR fmt, ...)
  820. {
  821. va_list marker;
  822. //
  823. // See if log messages are enabled and error messages are turned on
  824. //
  825. if (((g_dwDebugFlags & WIAUDBG_DONT_LOG) ^ WIAUDBG_DONT_LOG) &&
  826. (g_dwDebugFlags & WIAUDBG_ERRORS)) {
  827. va_start(marker, fmt);
  828. wiauDbgHelper("ERROR ", "", fmt, marker);
  829. va_end(marker);
  830. }
  831. if (g_dwDebugFlags & WIAUDBG_BREAK_ON_ERRORS) {
  832. DebugBreak();
  833. }
  834. }
  835. inline void __stdcall wiauDbgLegacyWarning(LPCSTR fmt, ...)
  836. {
  837. va_list marker;
  838. //
  839. // See if log messages are enabled and warning messages are turned on
  840. //
  841. if (((g_dwDebugFlags & WIAUDBG_DONT_LOG) ^ WIAUDBG_DONT_LOG) &&
  842. (g_dwDebugFlags & WIAUDBG_WARNINGS)) {
  843. va_start(marker, fmt);
  844. wiauDbgHelper("WARN ", "", fmt, marker);
  845. va_end(marker);
  846. }
  847. }
  848. inline void __stdcall wiauDbgLegacyTrace(LPCSTR fmt, ...)
  849. {
  850. va_list marker;
  851. //
  852. // See if log messages are enabled and trace messages are turned on
  853. //
  854. if (((g_dwDebugFlags & WIAUDBG_DONT_LOG) ^ WIAUDBG_DONT_LOG) &&
  855. (g_dwDebugFlags & WIAUDBG_TRACES)) {
  856. va_start(marker, fmt);
  857. wiauDbgHelper(" ", "", fmt, marker);
  858. va_end(marker);
  859. }
  860. }
  861. inline void __stdcall wiauDbgLegacyError2(HINSTANCE hInstance, LPCSTR fmt, ...)
  862. {
  863. va_list marker;
  864. //
  865. // See if log messages are enabled and error messages are turned on
  866. //
  867. if (((g_dwDebugFlags & WIAUDBG_DONT_LOG) ^ WIAUDBG_DONT_LOG) &&
  868. (g_dwDebugFlags & WIAUDBG_ERRORS)) {
  869. va_start(marker, fmt);
  870. wiauDbgHelper("ERROR ", "", fmt, marker);
  871. va_end(marker);
  872. }
  873. if (g_dwDebugFlags & WIAUDBG_BREAK_ON_ERRORS) {
  874. DebugBreak();
  875. }
  876. }
  877. inline void __stdcall wiauDbgLegacyTrace2(HINSTANCE hInstance, LPCSTR fmt, ...)
  878. {
  879. va_list marker;
  880. //
  881. // See if log messages are enabled and trace messages are turned on
  882. //
  883. if (((g_dwDebugFlags & WIAUDBG_DONT_LOG) ^ WIAUDBG_DONT_LOG) &&
  884. (g_dwDebugFlags & WIAUDBG_TRACES)) {
  885. va_start(marker, fmt);
  886. wiauDbgHelper(" ", "", fmt, marker);
  887. va_end(marker);
  888. }
  889. }
  890. inline void __stdcall wiauDbgLegacyHresult2(HINSTANCE hInstance, HRESULT hr)
  891. {
  892. wiauDbgErrorHr(hr, "", "");
  893. }
  894. #endif // NO_WIA_DEBUG
  895. //
  896. // Macros for mapping the old WIA logging to the new system
  897. //
  898. #ifdef WIA_MAP_OLD_DEBUG
  899. #define CWiaLogProc
  900. #define WIAS_LOGPROC(x, y, z, fname) CWiauDbgFn __CWiauDbgFnObject(fname)
  901. #define WIAS_LERROR(x,y,params) wiauDbgLegacyError ## params
  902. #define WIAS_LWARNING(x,y,params) wiauDbgLegacyWarning ## params
  903. #define WIAS_LTRACE(x,y,z,params) wiauDbgLegacyTrace ## params
  904. #define WIAS_LHRESULT(x,y) wiauDbgErrorHr(y, "", "")
  905. #define WIAS_TRACE(x) wiauDbgLegacyTrace2 ## x
  906. #define WIAS_ERROR(x) wiauDbgLegacyError2 ## x
  907. #define WIAS_HRESULT(x) wiauDbgLegacyHresult2 ## x
  908. #define WIAS_ASSERT(x, y) \
  909. if (!(y)) { \
  910. WIAS_ERROR((x, (char*) TEXT("ASSERTION FAILED: %hs(%d): %hs"), __FILE__,__LINE__,#x)); \
  911. DebugBreak(); \
  912. }
  913. #endif // WIA_MAP_OLD_DEBUG
  914. //
  915. // Macros for checking return values and common error conditions
  916. //
  917. #define REQUIRE_SUCCESS(hr, fname, msg) \
  918. if (FAILED(hr)) { \
  919. if (g_dwDebugFlags & WIAUDBG_PRINT_INFO) { \
  920. DWORD threadId = GetCurrentThreadId(); \
  921. wiauDbgError(fname, "[%s(%d): Thread 0x%X (%d)]", __FILE__, __LINE__, threadId, threadId); \
  922. } \
  923. wiauDbgErrorHr(hr, fname, msg); \
  924. goto Cleanup; \
  925. }
  926. #define REQUIRE_OK(hr, fname, msg) \
  927. if ((hr) != S_OK) { \
  928. if (g_dwDebugFlags & WIAUDBG_PRINT_INFO) { \
  929. DWORD threadId = GetCurrentThreadId(); \
  930. wiauDbgError(fname, "[%s(%d): Thread 0x%X (%d)]", __FILE__, __LINE__, threadId, threadId); \
  931. } \
  932. wiauDbgErrorHr(hr, fname, msg); \
  933. goto Cleanup; \
  934. }
  935. #define REQUIRE_ARGS(args, hr, fname) \
  936. if (args) { \
  937. if (g_dwDebugFlags & WIAUDBG_PRINT_INFO) { \
  938. DWORD threadId = GetCurrentThreadId(); \
  939. wiauDbgError(fname, "[%s(%d): Thread 0x%X (%d)]", __FILE__, __LINE__, threadId, threadId); \
  940. } \
  941. wiauDbgError(fname, "Invalid arg"); \
  942. hr = E_INVALIDARG; \
  943. goto Cleanup; \
  944. }
  945. #define REQUIRE_ALLOC(var, hr, fname) \
  946. if (!(var)) { \
  947. if (g_dwDebugFlags & WIAUDBG_PRINT_INFO) { \
  948. DWORD threadId = GetCurrentThreadId(); \
  949. wiauDbgError(fname, "[%s(%d): Thread 0x%X (%d)]", __FILE__, __LINE__, threadId, threadId); \
  950. } \
  951. wiauDbgError(fname, "Memory allocation failed on " #var); \
  952. hr = E_OUTOFMEMORY; \
  953. goto Cleanup; \
  954. }
  955. #define REQUIRE_FILEHANDLE(handle, hr, fname, msg) \
  956. if ((handle) == NULL || (handle) == INVALID_HANDLE_VALUE) { \
  957. hr = HRESULT_FROM_WIN32(::GetLastError()); \
  958. if (g_dwDebugFlags & WIAUDBG_PRINT_INFO) { \
  959. DWORD threadId = GetCurrentThreadId(); \
  960. wiauDbgError(fname, "[%s(%d): Thread 0x%X (%d)]", __FILE__, __LINE__, threadId, threadId); \
  961. } \
  962. wiauDbgErrorHr(hr, fname, msg); \
  963. goto Cleanup; \
  964. }
  965. #define REQUIRE_FILEIO(ret, hr, fname, msg) \
  966. if (!(ret)) { \
  967. hr = HRESULT_FROM_WIN32(::GetLastError()); \
  968. if (g_dwDebugFlags & WIAUDBG_PRINT_INFO) { \
  969. DWORD threadId = GetCurrentThreadId(); \
  970. wiauDbgError(fname, "[%s(%d): Thread 0x%X (%d)]", __FILE__, __LINE__, threadId, threadId); \
  971. } \
  972. wiauDbgErrorHr(hr, fname, msg); \
  973. goto Cleanup; \
  974. }
  975. #define REQUIRE_WIN32(err, hr, fname, msg) \
  976. if ((err) != ERROR_SUCCESS) { \
  977. hr = HRESULT_FROM_WIN32(err); \
  978. if (g_dwDebugFlags & WIAUDBG_PRINT_INFO) { \
  979. DWORD threadId = GetCurrentThreadId(); \
  980. wiauDbgError(fname, "[%s(%d): Thread 0x%X (%d)]", __FILE__, __LINE__, threadId, threadId); \
  981. } \
  982. wiauDbgErrorHr(hr, fname, msg); \
  983. goto Cleanup; \
  984. }
  985. //
  986. // Macro and class for entry/exit point tracing
  987. //
  988. #ifdef __cplusplus
  989. #ifdef NO_WIA_DEBUG
  990. #define DBG_FN(fname)
  991. #else // NO_WIA_DEBUG
  992. #define DBG_FN(fname) CWiauDbgFn __CWiauDbgFnObject(fname)
  993. class CWiauDbgFn {
  994. public:
  995. CWiauDbgFn(LPCSTR fname)
  996. {
  997. m_fname = fname;
  998. m_threadId = GetCurrentThreadId();
  999. wiauDbgFlags(WIAUDBG_FNS, " ", m_fname, "Entering, thread 0x%x (%d)",
  1000. m_threadId, m_threadId);
  1001. }
  1002. ~CWiauDbgFn()
  1003. {
  1004. wiauDbgFlags(WIAUDBG_FNS, " ", m_fname, "Exiting, thread 0x%x (%d)",
  1005. m_threadId, m_threadId);
  1006. }
  1007. private:
  1008. LPCSTR m_fname;
  1009. DWORD m_threadId;
  1010. };
  1011. #endif // NO_WIA_DEBUG
  1012. }
  1013. #else // __cplusplus
  1014. #define DBG_FN(fname) wiauDbgFlags(WIAUDBG_FNS, " ", fname, "Entering");
  1015. #endif // __cplusplus