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.

907 lines
28 KiB

  1. /*******************************************************************************
  2. *
  3. * (C) COPYRIGHT MICROSOFT CORPORATION, 1998
  4. *
  5. * TITLE: WIAUIEXT.CPP
  6. *
  7. * VERSION: 1.0
  8. *
  9. * AUTHOR: ShaunIv
  10. *
  11. * DATE: 5/17/1999
  12. *
  13. * DESCRIPTION:
  14. *
  15. *******************************************************************************/
  16. #include "precomp.h"
  17. #pragma hdrstop
  18. #include <atlimpl.cpp>
  19. #include "wiauiext.h"
  20. #include "wiadefui.h"
  21. #include "wiascand.h"
  22. #include "wiacamd.h"
  23. #include "wiavidd.h"
  24. #include "wiaffmt.h"
  25. CWiaDefaultUI::~CWiaDefaultUI(void)
  26. {
  27. WIA_PUSHFUNCTION(TEXT("CWiaDefaultUI::~CWiaDefaultUI"));
  28. DllRelease();
  29. }
  30. CWiaDefaultUI::CWiaDefaultUI()
  31. : m_cRef(1),
  32. m_pSecondaryCallback(NULL),
  33. m_nDefaultFormat(0),
  34. m_hWndProgress(NULL)
  35. {
  36. WIA_PUSHFUNCTION(TEXT("CWiaDefaultUI::CWiaDefaultUI"));
  37. DllAddRef();
  38. }
  39. STDMETHODIMP CWiaDefaultUI::QueryInterface( REFIID riid, LPVOID *ppvObject )
  40. {
  41. WIA_PUSHFUNCTION(TEXT("CWiaDefaultUI::QueryInterface"));
  42. if (IsEqualIID( riid, IID_IUnknown ))
  43. {
  44. *ppvObject = static_cast<IWiaUIExtension*>(this);
  45. }
  46. else if (IsEqualIID( riid, IID_IWiaUIExtension ))
  47. {
  48. *ppvObject = static_cast<IWiaUIExtension*>(this);
  49. }
  50. else if (IsEqualIID( riid, IID_IWiaTransferHelper ))
  51. {
  52. *ppvObject = static_cast<IWiaTransferHelper*>(this);
  53. }
  54. else if (IsEqualIID( riid, IID_IWiaDataCallback ))
  55. {
  56. *ppvObject = static_cast<IWiaDataCallback*>(this);
  57. }
  58. else if (IsEqualIID( riid, IID_IWiaSupportedFormats ))
  59. {
  60. *ppvObject = static_cast<IWiaSupportedFormats*>(this);
  61. }
  62. else if (IsEqualIID( riid, IID_IShellExtInit ))
  63. {
  64. *ppvObject = static_cast<IShellExtInit*>(this);
  65. }
  66. else if (IsEqualIID( riid, IID_IShellPropSheetExt ))
  67. {
  68. *ppvObject = static_cast<IShellPropSheetExt*>(this);
  69. }
  70. else if (IsEqualIID( riid, IID_IWiaMiscellaneousHelpers ))
  71. {
  72. *ppvObject = static_cast<IWiaMiscellaneousHelpers*>(this);
  73. }
  74. else if (IsEqualIID( riid, IID_IWiaGetImageDlg ))
  75. {
  76. *ppvObject = static_cast<IWiaGetImageDlg*>(this);
  77. }
  78. else if (IsEqualIID( riid, IID_IWiaProgressDialog ))
  79. {
  80. *ppvObject = static_cast<IWiaProgressDialog*>(this);
  81. }
  82. else if (IsEqualIID( riid, IID_IWiaAnnotationHelpers ))
  83. {
  84. *ppvObject = static_cast<IWiaAnnotationHelpers*>(this);
  85. }
  86. else if (IsEqualIID( riid, IID_IWiaScannerPaperSizes))
  87. {
  88. *ppvObject = static_cast<IWiaScannerPaperSizes*>(this);
  89. }
  90. else
  91. {
  92. *ppvObject = NULL;
  93. return (E_NOINTERFACE);
  94. }
  95. reinterpret_cast<IUnknown*>(*ppvObject)->AddRef();
  96. return(S_OK);
  97. }
  98. STDMETHODIMP_(ULONG) CWiaDefaultUI::AddRef()
  99. {
  100. WIA_PUSHFUNCTION(TEXT("CWiaDefaultUI::AddRef"));
  101. return(InterlockedIncrement(&m_cRef));
  102. }
  103. STDMETHODIMP_(ULONG) CWiaDefaultUI::Release()
  104. {
  105. WIA_PUSHFUNCTION(TEXT("CWiaDefaultUI::Release"));
  106. LONG nRefCount = InterlockedDecrement(&m_cRef);
  107. if (!nRefCount)
  108. {
  109. delete this;
  110. }
  111. return(nRefCount);
  112. }
  113. STDMETHODIMP CWiaDefaultUI::DeviceDialog( PDEVICEDIALOGDATA pDeviceDialogData )
  114. {
  115. WIA_PUSHFUNCTION(TEXT("CWiaDefaultUI::DeviceDialog"));
  116. if (!pDeviceDialogData)
  117. {
  118. return (E_INVALIDARG);
  119. }
  120. if (IsBadWritePtr(pDeviceDialogData,sizeof(DEVICEDIALOGDATA)))
  121. {
  122. return (E_INVALIDARG);
  123. }
  124. if (pDeviceDialogData->cbSize != sizeof(DEVICEDIALOGDATA))
  125. {
  126. return (E_INVALIDARG);
  127. }
  128. if (!pDeviceDialogData->pIWiaItemRoot)
  129. {
  130. return (E_INVALIDARG);
  131. }
  132. LONG nDeviceType;
  133. if (!PropStorageHelpers::GetProperty( pDeviceDialogData->pIWiaItemRoot, WIA_DIP_DEV_TYPE, nDeviceType ))
  134. {
  135. return (E_INVALIDARG);
  136. }
  137. // In case there is some new device for which we don't have UI
  138. HRESULT hr = E_NOTIMPL;
  139. if (StiDeviceTypeDigitalCamera==GET_STIDEVICE_TYPE(nDeviceType))
  140. {
  141. hr = CameraDeviceDialog( pDeviceDialogData );
  142. }
  143. else if (StiDeviceTypeScanner==GET_STIDEVICE_TYPE(nDeviceType))
  144. {
  145. hr = ScannerDeviceDialog( pDeviceDialogData );
  146. }
  147. else if (StiDeviceTypeStreamingVideo==GET_STIDEVICE_TYPE(nDeviceType))
  148. {
  149. hr = VideoDeviceDialog( pDeviceDialogData );
  150. }
  151. return (hr);
  152. }
  153. STDMETHODIMP CWiaDefaultUI::GetDeviceIcon( LONG nDeviceType, HICON *phIcon, int nSize )
  154. {
  155. // Check args
  156. if (!phIcon)
  157. {
  158. return E_POINTER;
  159. }
  160. //
  161. // Supply a default icon size if none is specified
  162. //
  163. if (!nSize)
  164. {
  165. nSize = GetSystemMetrics( SM_CXICON );
  166. }
  167. //
  168. // Initialize the returned icon
  169. //
  170. *phIcon = NULL;
  171. // Assume a generic device
  172. int nIconId = IDI_GENERICDEVICE;
  173. //
  174. // Get device-specific icon
  175. //
  176. if (StiDeviceTypeScanner==GET_STIDEVICE_TYPE(nDeviceType))
  177. {
  178. nIconId = IDI_SCANNER;
  179. }
  180. else if (StiDeviceTypeDigitalCamera==GET_STIDEVICE_TYPE(nDeviceType))
  181. {
  182. nIconId = IDI_CAMERA;
  183. }
  184. else if (StiDeviceTypeStreamingVideo==GET_STIDEVICE_TYPE(nDeviceType))
  185. {
  186. nIconId = IDI_VIDEODEVICE;
  187. }
  188. //
  189. // Load the icon
  190. //
  191. *phIcon = reinterpret_cast<HICON>(LoadImage( g_hInstance, MAKEINTRESOURCE(nIconId), IMAGE_ICON, nSize, nSize, LR_DEFAULTCOLOR ));
  192. if (!*phIcon)
  193. {
  194. return HRESULT_FROM_WIN32(GetLastError());
  195. }
  196. //
  197. // It worked ok
  198. //
  199. return (S_OK);
  200. }
  201. STDMETHODIMP CWiaDefaultUI::GetAnnotationOverlayIcon( CAnnotationType AnnotationType, HICON *phIcon, int nSize )
  202. {
  203. if (!phIcon)
  204. {
  205. return E_INVALIDARG;
  206. }
  207. HICON hIcon = NULL;
  208. *phIcon = NULL;
  209. switch (AnnotationType)
  210. {
  211. case AnnotationAudio:
  212. hIcon = reinterpret_cast<HICON>(LoadImage( g_hInstance, MAKEINTRESOURCE(IDI_ANNOTATION_AUDIO), IMAGE_ICON, nSize, nSize, LR_DEFAULTCOLOR ));
  213. break;
  214. case AnnotationUnknown:
  215. hIcon = reinterpret_cast<HICON>(LoadImage( g_hInstance, MAKEINTRESOURCE(IDI_ANNOTATION_UNKNOWN), IMAGE_ICON, nSize, nSize, LR_DEFAULTCOLOR ));
  216. break;
  217. }
  218. if (hIcon)
  219. {
  220. *phIcon = CopyIcon(hIcon);
  221. }
  222. return *phIcon ? S_OK : E_FAIL;
  223. }
  224. STDMETHODIMP CWiaDefaultUI::GetAnnotationType( IUnknown *pUnknown, CAnnotationType &AnnotationType )
  225. {
  226. WIA_PUSHFUNCTION(TEXT("CWiaDefaultUI::GetAnnotationType"));
  227. if (!pUnknown)
  228. {
  229. return E_INVALIDARG;
  230. }
  231. //
  232. // Assume no annotations
  233. //
  234. AnnotationType = AnnotationNone;
  235. //
  236. // Get an IWiaItem*
  237. //
  238. CComPtr<IWiaItem> pWiaItem;
  239. HRESULT hr = pUnknown->QueryInterface( IID_IWiaItem, (void**)&pWiaItem );
  240. if (SUCCEEDED(hr))
  241. {
  242. //
  243. // Low-hanging fruit: audio stored as a property--just return audio. It is unlikely that a driver would
  244. // have both types of annotation.
  245. //
  246. LONG nAudioAvailable = FALSE;
  247. if (PropStorageHelpers::GetProperty( pWiaItem, WIA_IPC_AUDIO_AVAILABLE, nAudioAvailable ) && nAudioAvailable)
  248. {
  249. AnnotationType = AnnotationAudio;
  250. return S_OK;
  251. }
  252. //
  253. // Get the item type
  254. //
  255. LONG nItemType = 0;
  256. hr = pWiaItem->GetItemType(&nItemType);
  257. if (SUCCEEDED(hr))
  258. {
  259. //
  260. // If an item has the WiaItemTypeHasAttachments item type flag set, we know it has some attachments...
  261. //
  262. if (nItemType & WiaItemTypeHasAttachments)
  263. {
  264. //
  265. // Assume we don't have any audio attachments
  266. //
  267. AnnotationType = AnnotationUnknown;
  268. //
  269. // Enumerate the children and look at the item types
  270. //
  271. CComPtr<IEnumWiaItem> pEnumWiaItem;
  272. hr = pWiaItem->EnumChildItems( &pEnumWiaItem );
  273. if (SUCCEEDED(hr))
  274. {
  275. //
  276. // We will break out of the enumeration loop as soon as we find an audio file
  277. //
  278. bool bDone = false;
  279. CComPtr<IWiaItem> pWiaItem;
  280. while (S_OK == pEnumWiaItem->Next(1,&pWiaItem,NULL) && !bDone)
  281. {
  282. //
  283. // Get the preferred format for this item.
  284. //
  285. GUID guidDefaultFormat = IID_NULL;
  286. if (PropStorageHelpers::GetProperty( pWiaItem, WIA_IPA_PREFERRED_FORMAT, guidDefaultFormat ))
  287. {
  288. WIA_PRINTGUID((guidDefaultFormat,TEXT("guidDefaultFormat")));
  289. //
  290. // If we find even one audio attachment, we will promote this to
  291. // be the default for UI purposes.
  292. //
  293. if (CWiaFileFormat::IsKnownAudioFormat(guidDefaultFormat))
  294. {
  295. //
  296. // Save the annotation type
  297. //
  298. AnnotationType = AnnotationAudio;
  299. //
  300. // This will cause the while loop to exit
  301. //
  302. bDone = true;
  303. }
  304. }
  305. //
  306. // Release this interface
  307. //
  308. pWiaItem = NULL;
  309. }
  310. }
  311. else
  312. {
  313. WIA_PRINTHRESULT((hr,TEXT("EnumChildItems failed")));
  314. }
  315. }
  316. else
  317. {
  318. WIA_TRACE((TEXT("This item has no attachments. ItemType: %08X"), nItemType ));
  319. }
  320. }
  321. else
  322. {
  323. WIA_PRINTHRESULT((hr,TEXT("Unable to get the item type")));
  324. }
  325. }
  326. else
  327. {
  328. WIA_PRINTHRESULT((hr,TEXT("Can't get an IWiaItem*")));
  329. }
  330. WIA_TRACE((TEXT("Returning an annotation type of %d"), AnnotationType ));
  331. return hr;
  332. }
  333. STDMETHODIMP CWiaDefaultUI::GetAnnotationFormat( IUnknown *pUnknown, GUID &guidFormat )
  334. {
  335. WIA_PUSHFUNCTION(TEXT("CWiaDefaultUI::GetAnnotationFormat"));
  336. //
  337. // Validate args
  338. //
  339. if (!pUnknown)
  340. {
  341. return E_INVALIDARG;
  342. }
  343. //
  344. // Assume this is not a valid annotation
  345. //
  346. guidFormat = IID_NULL;
  347. //
  348. // Get an IWiaItem*
  349. //
  350. CComPtr<IWiaItem> pWiaItem;
  351. HRESULT hr = pUnknown->QueryInterface( IID_IWiaItem, (void**)&pWiaItem );
  352. if (SUCCEEDED(hr))
  353. {
  354. //
  355. // First, check to see if this item is an image with an audio annotation property
  356. //
  357. LONG nAudioAvailable = FALSE;
  358. if (PropStorageHelpers::GetProperty( pWiaItem, WIA_IPC_AUDIO_AVAILABLE, nAudioAvailable ) && nAudioAvailable)
  359. {
  360. //
  361. // If the driver supplied the format, use this
  362. //
  363. GUID guidAudioDataFormat = IID_NULL;
  364. if (PropStorageHelpers::GetProperty( pWiaItem, WIA_IPC_AUDIO_DATA_FORMAT, guidAudioDataFormat ))
  365. {
  366. guidFormat = guidAudioDataFormat;
  367. }
  368. //
  369. // Otherwise, assume it is WAV data
  370. //
  371. else
  372. {
  373. guidFormat = WiaAudFmt_WAV;
  374. }
  375. }
  376. else
  377. {
  378. //
  379. // Otherwise, this must be an attachment item. Use the helper interface to get the default format
  380. //
  381. CComPtr<IWiaSupportedFormats> pWiaSupportedFormats;
  382. hr = CoCreateInstance( CLSID_WiaDefaultUi, NULL, CLSCTX_INPROC_SERVER, IID_IWiaSupportedFormats, (void**)&pWiaSupportedFormats );
  383. if (SUCCEEDED(hr))
  384. {
  385. //
  386. // This is always for file output
  387. //
  388. hr = pWiaSupportedFormats->Initialize( pWiaItem, TYMED_FILE );
  389. if (SUCCEEDED(hr))
  390. {
  391. //
  392. // Get the default format
  393. //
  394. GUID guidDefaultFormat = IID_NULL;
  395. hr = pWiaSupportedFormats->GetDefaultClipboardFileFormat( &guidDefaultFormat );
  396. if (SUCCEEDED(hr))
  397. {
  398. guidFormat = guidDefaultFormat;
  399. }
  400. else
  401. {
  402. WIA_PRINTHRESULT((hr,TEXT("pWiaSupportedFormats->GetDefaultClipboardFileFormat failed")));
  403. }
  404. }
  405. else
  406. {
  407. WIA_PRINTHRESULT((hr,TEXT("pWiaSupportedFormats->Initialize failed")));
  408. }
  409. }
  410. else
  411. {
  412. WIA_PRINTHRESULT((hr,TEXT("CoCreateInstance on CLSID_WiaDefaultUi, IID_IWiaSupportedFormats failed")));
  413. }
  414. }
  415. }
  416. else
  417. {
  418. WIA_PRINTHRESULT((hr,TEXT("Can't get an IWiaItem*")));
  419. }
  420. //
  421. // If this is not a valid annotation, make sure we return an error.
  422. //
  423. if (SUCCEEDED(hr) && IID_NULL == guidFormat)
  424. {
  425. hr = E_FAIL;
  426. WIA_PRINTHRESULT((hr,TEXT("guidFormat was IID_NULL")));
  427. }
  428. return hr;
  429. }
  430. STDMETHODIMP CWiaDefaultUI::GetAnnotationSize( IUnknown *pUnknown, LONG &nSize, LONG nMediaType )
  431. {
  432. WIA_PUSHFUNCTION(TEXT("CWiaDefaultUI::GetAnnotationSize"));
  433. //
  434. // Validate args
  435. //
  436. if (!pUnknown)
  437. {
  438. return E_INVALIDARG;
  439. }
  440. //
  441. // Assume this is not a valid annotation
  442. //
  443. nSize = 0;
  444. //
  445. // Get an IWiaItem*
  446. //
  447. CComPtr<IWiaItem> pWiaItem;
  448. HRESULT hr = pUnknown->QueryInterface( IID_IWiaItem, (void**)&pWiaItem );
  449. if (SUCCEEDED(hr))
  450. {
  451. //
  452. // First, check to see if this item is an image with an audio annotation property
  453. //
  454. LONG nAudioAvailable = FALSE;
  455. if (PropStorageHelpers::GetProperty( pWiaItem, WIA_IPC_AUDIO_AVAILABLE, nAudioAvailable ) && nAudioAvailable)
  456. {
  457. //
  458. // Get the sound property to obtain its size
  459. //
  460. CComPtr<IWiaPropertyStorage> pWiaPropertyStorage;
  461. hr = pWiaItem->QueryInterface( IID_IWiaPropertyStorage, (void**)(&pWiaPropertyStorage) );
  462. if (SUCCEEDED(hr))
  463. {
  464. PROPVARIANT PropVar[1];
  465. PROPSPEC PropSpec[1];
  466. PropSpec[0].ulKind = PRSPEC_PROPID;
  467. PropSpec[0].propid = WIA_IPC_AUDIO_DATA;
  468. hr = pWiaPropertyStorage->ReadMultiple( ARRAYSIZE(PropSpec), PropSpec, PropVar );
  469. if (SUCCEEDED(hr))
  470. {
  471. nSize = PropVar[0].caub.cElems;
  472. }
  473. FreePropVariantArray( ARRAYSIZE(PropVar), PropVar );
  474. }
  475. }
  476. else
  477. {
  478. //
  479. // Save the old media type
  480. //
  481. LONG nOldMediaType = 0;
  482. if (PropStorageHelpers::GetProperty( pWiaItem, WIA_IPA_TYMED, nOldMediaType ))
  483. {
  484. //
  485. // Set the requested media type
  486. //
  487. if (PropStorageHelpers::SetProperty( pWiaItem, WIA_IPA_TYMED, nMediaType ))
  488. {
  489. //
  490. // Get the item size
  491. //
  492. PropStorageHelpers::GetProperty( pWiaItem, WIA_IPA_ITEM_SIZE, nSize );
  493. }
  494. //
  495. // Restore the old media type
  496. //
  497. PropStorageHelpers::SetProperty( pWiaItem, WIA_IPA_TYMED, nOldMediaType );
  498. }
  499. }
  500. }
  501. else
  502. {
  503. WIA_PRINTHRESULT((hr,TEXT("Can't get a IWiaItem*")));
  504. }
  505. //
  506. // If this is not a valid annotation, make sure we return an error.
  507. //
  508. if (SUCCEEDED(hr) && nSize == 0)
  509. {
  510. hr = E_FAIL;
  511. WIA_PRINTHRESULT((hr,TEXT("nSize was 0")));
  512. }
  513. return hr;
  514. }
  515. class CAttachmentMemoryCallback : public IWiaDataCallback
  516. {
  517. private:
  518. PBYTE m_pBuffer;
  519. DWORD m_dwSize;
  520. DWORD m_dwCurr;
  521. private:
  522. //
  523. // Not implemented
  524. //
  525. CAttachmentMemoryCallback(void);
  526. CAttachmentMemoryCallback( const CAttachmentMemoryCallback & );
  527. CAttachmentMemoryCallback &operator=( const CAttachmentMemoryCallback & );
  528. public:
  529. CAttachmentMemoryCallback( PBYTE pBuffer, DWORD dwSize )
  530. : m_pBuffer(pBuffer),
  531. m_dwSize(dwSize),
  532. m_dwCurr(0)
  533. {
  534. }
  535. ~CAttachmentMemoryCallback(void)
  536. {
  537. m_pBuffer = NULL;
  538. m_dwSize = NULL;
  539. }
  540. STDMETHODIMP QueryInterface(const IID& iid, void** ppvObject)
  541. {
  542. if ((iid==IID_IUnknown) || (iid==IID_IWiaDataCallback))
  543. {
  544. *ppvObject = static_cast<LPVOID>(this);
  545. }
  546. else
  547. {
  548. *ppvObject = NULL;
  549. return(E_NOINTERFACE);
  550. }
  551. reinterpret_cast<IUnknown*>(*ppvObject)->AddRef();
  552. return(S_OK);
  553. }
  554. STDMETHODIMP_(ULONG) AddRef()
  555. {
  556. return 1;
  557. }
  558. STDMETHODIMP_(ULONG) Release()
  559. {
  560. return 1;
  561. }
  562. STDMETHODIMP BandedDataCallback( LONG lReason, LONG lStatus, LONG lPercentComplete, LONG lOffset, LONG lLength, LONG lReserved, LONG lResLength, PBYTE pbBuffer )
  563. {
  564. WIA_PUSH_FUNCTION((TEXT("CAttachmentMemoryCallback::BandedDataCallback( lReason: %08X, lStatus: %08X, lPercentComplete: %08X, lOffset: %08X, lLength: %08X, lReserved: %08X, lResLength: %08X, pbBuffer: %p )"), lReason, lStatus, lPercentComplete, lOffset, lLength, lReserved, lResLength, pbBuffer ));
  565. if (lReason == IT_MSG_DATA)
  566. {
  567. if (lStatus & IT_STATUS_TRANSFER_TO_CLIENT)
  568. {
  569. if (lLength + m_dwCurr <= m_dwSize)
  570. {
  571. CopyMemory( m_pBuffer+m_dwCurr, pbBuffer, lLength );
  572. m_dwCurr += lLength;
  573. }
  574. }
  575. }
  576. return S_OK;
  577. }
  578. };
  579. STDMETHODIMP CWiaDefaultUI::TransferAttachmentToMemory( IUnknown *pUnknown, GUID &guidFormat, HWND hWndProgressParent, PBYTE *ppBuffer, DWORD *pdwSize )
  580. {
  581. //
  582. // Validate args
  583. //
  584. if (!pUnknown || !ppBuffer || !pdwSize)
  585. {
  586. return E_INVALIDARG;
  587. }
  588. //
  589. // Initialize args
  590. //
  591. *ppBuffer = NULL;
  592. *pdwSize = 0;
  593. CComPtr<IWiaItem> pWiaItem;
  594. HRESULT hr = pUnknown->QueryInterface( IID_IWiaItem, (void**)&pWiaItem );
  595. if (SUCCEEDED(hr))
  596. {
  597. //
  598. // First, check to see if this item is an image with an audio annotation property
  599. //
  600. LONG nAudioAvailable = FALSE;
  601. if (PropStorageHelpers::GetProperty( pWiaItem, WIA_IPC_AUDIO_AVAILABLE, nAudioAvailable ) && nAudioAvailable)
  602. {
  603. //
  604. // Get the sound property to obtain its size
  605. //
  606. CComPtr<IWiaPropertyStorage> pWiaPropertyStorage;
  607. hr = pWiaItem->QueryInterface( IID_IWiaPropertyStorage, (void**)(&pWiaPropertyStorage) );
  608. if (SUCCEEDED(hr))
  609. {
  610. //
  611. // Get the audio data itself
  612. //
  613. PROPVARIANT PropVar[1];
  614. PROPSPEC PropSpec[1];
  615. PropSpec[0].ulKind = PRSPEC_PROPID;
  616. PropSpec[0].propid = WIA_IPC_AUDIO_DATA;
  617. hr = pWiaPropertyStorage->ReadMultiple( ARRAYSIZE(PropSpec), PropSpec, PropVar );
  618. if (SUCCEEDED(hr))
  619. {
  620. //
  621. // Allocate memory to hold the data and copy it over
  622. //
  623. *ppBuffer = reinterpret_cast<PBYTE>(CoTaskMemAlloc(PropVar[0].caub.cElems));
  624. if (*ppBuffer)
  625. {
  626. CopyMemory( *ppBuffer, PropVar[0].caub.pElems, PropVar[0].caub.cElems );
  627. *pdwSize = static_cast<DWORD>(PropVar[0].caub.cElems);
  628. hr = S_OK;
  629. }
  630. else
  631. {
  632. hr = E_OUTOFMEMORY;
  633. }
  634. }
  635. //
  636. // Release the original memory
  637. //
  638. FreePropVariantArray( ARRAYSIZE(PropVar), PropVar );
  639. }
  640. }
  641. //
  642. // This is an attachment, not a property
  643. //
  644. else
  645. {
  646. //
  647. // Get the size of the annotation
  648. //
  649. LONG nSize = 0;
  650. hr = GetAnnotationSize( pUnknown, nSize, TYMED_CALLBACK );
  651. if (SUCCEEDED(hr))
  652. {
  653. //
  654. // Allocate some memory for it
  655. //
  656. PBYTE pData = reinterpret_cast<PBYTE>(CoTaskMemAlloc( nSize ));
  657. if (pData)
  658. {
  659. //
  660. // Zero the memory
  661. //
  662. ZeroMemory( pData, nSize );
  663. //
  664. // Prepare the callback class
  665. //
  666. CAttachmentMemoryCallback AttachmentMemoryCallback( pData, nSize );
  667. //
  668. // Get the callback interface
  669. //
  670. CComPtr<IWiaDataCallback> pWiaDataCallback;
  671. hr = AttachmentMemoryCallback.QueryInterface( IID_IWiaDataCallback, (void**)&pWiaDataCallback );
  672. if (SUCCEEDED(hr))
  673. {
  674. //
  675. // Create the transfer helper
  676. //
  677. CComPtr<IWiaTransferHelper> pWiaTransferHelper;
  678. hr = CoCreateInstance( CLSID_WiaDefaultUi, NULL, CLSCTX_INPROC_SERVER, IID_IWiaTransferHelper, (void**)&pWiaTransferHelper );
  679. if (SUCCEEDED(hr))
  680. {
  681. //
  682. // Transfer the data
  683. //
  684. hr = pWiaTransferHelper->TransferItemBanded( pWiaItem, hWndProgressParent, hWndProgressParent?0:WIA_TRANSFERHELPER_NOPROGRESS, guidFormat, 0, pWiaDataCallback );
  685. if (S_OK == hr)
  686. {
  687. //
  688. // Save the buffer and the size
  689. //
  690. *ppBuffer = pData;
  691. *pdwSize = static_cast<DWORD>(nSize);
  692. //
  693. // NULL out the data pointer so we don't free it below. The caller will free it with CoTaskMemFree.
  694. //
  695. pData = NULL;
  696. }
  697. }
  698. }
  699. if (pData)
  700. {
  701. CoTaskMemFree(pData);
  702. }
  703. }
  704. else
  705. {
  706. hr = E_OUTOFMEMORY;
  707. }
  708. }
  709. }
  710. }
  711. return hr;
  712. }
  713. // Calling this function can be horribly slow, because it has to search the whole device list to
  714. // find the correct icon. You should use IWiaMiscellaneousHelpers::GetDeviceIcon( nDeviceType, ... )
  715. // instead, if the device type is known.
  716. STDMETHODIMP CWiaDefaultUI::GetDeviceIcon( BSTR bstrDeviceId, HICON *phIcon, ULONG nSize )
  717. {
  718. WIA_PUSHFUNCTION(TEXT("CWiaDefaultUI::GetDeviceIcon"));
  719. // Sanity check the device id
  720. if (!bstrDeviceId || !lstrlenW(bstrDeviceId))
  721. {
  722. return E_INVALIDARG;
  723. }
  724. // Get the device type
  725. LONG nDeviceType = 0;
  726. WiaUiUtil::GetDeviceTypeFromId(bstrDeviceId,&nDeviceType);
  727. // Return the device icon
  728. return GetDeviceIcon( nDeviceType, phIcon, nSize );
  729. }
  730. STDMETHODIMP CWiaDefaultUI::GetDeviceBitmapLogo( BSTR bstrDeviceId, HBITMAP *phBitmap, ULONG nMaxWidth, ULONG nMaxHeight )
  731. {
  732. WIA_PUSHFUNCTION(TEXT("CWiaDefaultUI::GetDeviceBitmapLogo"));
  733. return (E_NOTIMPL);
  734. }
  735. // IWiaGetImageDlg
  736. STDMETHODIMP CWiaDefaultUI::GetImageDlg(
  737. IWiaDevMgr *pIWiaDevMgr,
  738. HWND hwndParent,
  739. LONG lDeviceType,
  740. LONG lFlags,
  741. LONG lIntent,
  742. IWiaItem *pSuppliedItemRoot,
  743. BSTR bstrFilename,
  744. GUID *pguidFormat )
  745. {
  746. HRESULT hr;
  747. CComPtr<IWiaItem> pRootItem;
  748. // Put up a wait cursor
  749. CWaitCursor wc;
  750. if (!pIWiaDevMgr || !pguidFormat || !bstrFilename)
  751. {
  752. WIA_ERROR((TEXT("GetImageDlg: Invalid pIWiaDevMgr, pguidFormat or bstrFilename")));
  753. return(E_POINTER);
  754. }
  755. // If a root item wasn't passed, select the device.
  756. if (pSuppliedItemRoot == NULL)
  757. {
  758. hr = pIWiaDevMgr->SelectDeviceDlg( hwndParent, lDeviceType, lFlags, NULL, &pRootItem );
  759. if (FAILED(hr))
  760. {
  761. WIA_ERROR((TEXT("GetImageDlg, SelectDeviceDlg failed")));
  762. return(hr);
  763. }
  764. if (hr != S_OK)
  765. {
  766. WIA_ERROR((TEXT("GetImageDlg, DeviceDlg cancelled")));
  767. return(hr);
  768. }
  769. }
  770. else
  771. {
  772. pRootItem = pSuppliedItemRoot;
  773. }
  774. // Put up the device UI.
  775. LONG nItemCount;
  776. IWiaItem **ppIWiaItem;
  777. hr = pRootItem->DeviceDlg( hwndParent, lFlags, lIntent, &nItemCount, &ppIWiaItem );
  778. if (SUCCEEDED(hr) && hr == S_OK)
  779. {
  780. if (ppIWiaItem && nItemCount)
  781. {
  782. CComPtr<IWiaTransferHelper> pWiaTransferHelper;
  783. hr = CoCreateInstance( CLSID_WiaDefaultUi, NULL, CLSCTX_INPROC_SERVER, IID_IWiaTransferHelper, (void**)&pWiaTransferHelper );
  784. if (SUCCEEDED(hr))
  785. {
  786. hr = pWiaTransferHelper->TransferItemFile( ppIWiaItem[0], hwndParent, 0, *pguidFormat, bstrFilename, NULL, TYMED_FILE );
  787. }
  788. }
  789. // Release the items and free the array memory
  790. for (int i=0; ppIWiaItem && i<nItemCount; i++)
  791. {
  792. if (ppIWiaItem[i])
  793. {
  794. ppIWiaItem[i]->Release();
  795. }
  796. }
  797. if (ppIWiaItem)
  798. {
  799. CoTaskMemFree(ppIWiaItem);
  800. }
  801. }
  802. return(hr);
  803. }
  804. STDMETHODIMP CWiaDefaultUI::SelectDeviceDlg(
  805. HWND hwndParent,
  806. BSTR bstrInitialDeviceId,
  807. LONG lDeviceType,
  808. LONG lFlags,
  809. BSTR *pbstrDeviceID,
  810. IWiaItem **ppWiaItemRoot )
  811. {
  812. SELECTDEVICEDLG SelectDeviceDlgData;
  813. ZeroMemory( &SelectDeviceDlgData, sizeof(SELECTDEVICEDLG) );
  814. SelectDeviceDlgData.cbSize = sizeof(SELECTDEVICEDLG);
  815. SelectDeviceDlgData.hwndParent = hwndParent;
  816. SelectDeviceDlgData.pwszInitialDeviceId = NULL;
  817. SelectDeviceDlgData.nDeviceType = lDeviceType;
  818. SelectDeviceDlgData.nFlags = lFlags;
  819. SelectDeviceDlgData.ppWiaItemRoot = ppWiaItemRoot;
  820. SelectDeviceDlgData.pbstrDeviceID = pbstrDeviceID;
  821. return ::SelectDeviceDlg( &SelectDeviceDlgData );
  822. }