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.

1035 lines
24 KiB

  1. /*****************************************************************************
  2. *
  3. * (C) COPYRIGHT MICROSOFT CORPORATION, 2000
  4. *
  5. * TITLE: WiaProc.cpp
  6. *
  7. * VERSION: 1.0
  8. *
  9. * DATE: 2000/11/14
  10. *
  11. * DESCRIPTION: Manages Wia side of things
  12. *
  13. *****************************************************************************/
  14. #include <stdafx.h>
  15. #include <mmsystem.h>
  16. #include "wiavideotest.h"
  17. static struct
  18. {
  19. DWORD dwWiaDevMgrCookie;
  20. DWORD dwSelectedDeviceCookie;
  21. IUnknown *pCreateCallback;
  22. IUnknown *pDeleteCallback;
  23. IUnknown *pDisconnectedCallback;
  24. IUnknown *pConnectedCallback;
  25. IGlobalInterfaceTable *pGIT;
  26. CRITICAL_SECTION CritSec;
  27. } LOCAL_GVAR =
  28. {
  29. NULL,
  30. NULL,
  31. NULL,
  32. NULL,
  33. NULL,
  34. NULL,
  35. 0,
  36. FALSE,
  37. NULL
  38. };
  39. /****************************Local Function Prototypes********************/
  40. HRESULT ClearDeviceList();
  41. HRESULT AddItemToList(IWiaPropertyStorage *pItem,
  42. TCHAR *pszFriendlyName,
  43. TCHAR *pszDeviceID);
  44. WPARAM GetNumDevicesInList();
  45. IWiaPropertyStorage* GetWiaStorage(WPARAM uiIndex);
  46. HRESULT CreateWiaDevMgr(IWiaDevMgr **ppDevMgr);
  47. HRESULT GetProperty(IWiaPropertyStorage *pPropStorage,
  48. PROPID nPropID,
  49. LONG *pnValue);
  50. HRESULT GetProperty(IWiaPropertyStorage *pPropStorage,
  51. PROPID nPropID,
  52. TCHAR *pszBuffer,
  53. UINT cbBuffer);
  54. HRESULT SetProperty(IWiaPropertyStorage *pPropStorage,
  55. PROPID nPropID,
  56. const PROPVARIANT *ppv,
  57. PROPID nNameFirst);
  58. HRESULT AppUtil_ConvertToWideString(const TCHAR *pszStringToConvert,
  59. WCHAR *pwszString,
  60. UINT cchString);
  61. HRESULT AppUtil_ConvertToTCHAR(const WCHAR *pwszStringToConvert,
  62. TCHAR *pszString,
  63. UINT cchString);
  64. HRESULT CreateRootItem(IWiaDevMgr *pDevMgr,
  65. const TCHAR *pszWiaDeviceID,
  66. IWiaItem **ppRootItem);
  67. HRESULT RegisterForEvents(IWiaDevMgr *pDevMgr);
  68. ///////////////////////////////
  69. // WiaProc_Init
  70. //
  71. HRESULT WiaProc_Init()
  72. {
  73. HRESULT hr = S_OK;
  74. IWiaDevMgr *pWiaDevMgr = NULL;
  75. if (LOCAL_GVAR.dwWiaDevMgrCookie != 0)
  76. {
  77. return S_OK;
  78. }
  79. __try
  80. {
  81. if (!InitializeCriticalSectionAndSpinCount(&LOCAL_GVAR.CritSec, MINLONG))
  82. {
  83. hr = HRESULT_FROM_WIN32(::GetLastError());
  84. }
  85. }
  86. __except(EXCEPTION_EXECUTE_HANDLER)
  87. {
  88. hr = E_OUTOFMEMORY;
  89. }
  90. if (hr == S_OK)
  91. {
  92. hr = CreateWiaDevMgr(&pWiaDevMgr);
  93. }
  94. if (hr == S_OK)
  95. {
  96. hr = CoCreateInstance(CLSID_StdGlobalInterfaceTable,
  97. NULL,
  98. CLSCTX_INPROC_SERVER,
  99. IID_IGlobalInterfaceTable,
  100. (void **)&LOCAL_GVAR.pGIT);
  101. }
  102. if (hr == S_OK)
  103. {
  104. LOCAL_GVAR.pGIT->RegisterInterfaceInGlobal(pWiaDevMgr,
  105. IID_IWiaDevMgr,
  106. &LOCAL_GVAR.dwWiaDevMgrCookie);
  107. }
  108. if (hr == S_OK)
  109. {
  110. hr = RegisterForEvents(pWiaDevMgr);
  111. }
  112. if (hr == S_OK)
  113. {
  114. WiaProc_PopulateDeviceList();
  115. }
  116. if (pWiaDevMgr)
  117. {
  118. pWiaDevMgr->Release();
  119. pWiaDevMgr = NULL;
  120. }
  121. return hr;
  122. }
  123. ///////////////////////////////
  124. // WiaProc_Term
  125. //
  126. HRESULT WiaProc_Term()
  127. {
  128. HRESULT hr = S_OK;
  129. ClearDeviceList();
  130. if (LOCAL_GVAR.dwSelectedDeviceCookie != 0)
  131. {
  132. LOCAL_GVAR.pGIT->RevokeInterfaceFromGlobal(LOCAL_GVAR.dwSelectedDeviceCookie);
  133. LOCAL_GVAR.dwSelectedDeviceCookie = 0;
  134. }
  135. if (LOCAL_GVAR.dwWiaDevMgrCookie != 0)
  136. {
  137. LOCAL_GVAR.pGIT->RevokeInterfaceFromGlobal(LOCAL_GVAR.dwWiaDevMgrCookie);
  138. LOCAL_GVAR.dwWiaDevMgrCookie = 0;
  139. DeleteCriticalSection(&LOCAL_GVAR.CritSec);
  140. }
  141. if (LOCAL_GVAR.pCreateCallback)
  142. {
  143. LOCAL_GVAR.pCreateCallback->Release();
  144. LOCAL_GVAR.pCreateCallback = NULL;
  145. }
  146. if (LOCAL_GVAR.pDeleteCallback)
  147. {
  148. LOCAL_GVAR.pDeleteCallback->Release();
  149. LOCAL_GVAR.pDeleteCallback = NULL;
  150. }
  151. if (LOCAL_GVAR.pConnectedCallback)
  152. {
  153. LOCAL_GVAR.pConnectedCallback->Release();
  154. LOCAL_GVAR.pConnectedCallback = NULL;
  155. }
  156. if (LOCAL_GVAR.pDisconnectedCallback)
  157. {
  158. LOCAL_GVAR.pDisconnectedCallback->Release();
  159. LOCAL_GVAR.pDisconnectedCallback = NULL;
  160. }
  161. if (LOCAL_GVAR.pGIT)
  162. {
  163. LOCAL_GVAR.pGIT->Release();
  164. LOCAL_GVAR.pGIT = NULL;
  165. }
  166. return hr;
  167. }
  168. ///////////////////////////////
  169. // WiaProc_CreateSelectedDevice
  170. //
  171. HRESULT WiaProc_CreateSelectedDevice(TCHAR *pszDeviceID,
  172. UINT cchDeviceID)
  173. {
  174. HRESULT hr = S_OK;
  175. WPARAM Index = 0;
  176. TCHAR szDeviceID[MAX_PATH] = {0};
  177. IWiaDevMgr *pWiaDevMgr = NULL;
  178. if ((LOCAL_GVAR.dwWiaDevMgrCookie == 0) ||
  179. (LOCAL_GVAR.pGIT == NULL))
  180. {
  181. return E_POINTER;
  182. }
  183. hr = LOCAL_GVAR.pGIT->GetInterfaceFromGlobal(LOCAL_GVAR.dwWiaDevMgrCookie,
  184. IID_IWiaDevMgr,
  185. (void**)&pWiaDevMgr);
  186. if (pWiaDevMgr == NULL)
  187. {
  188. return E_POINTER;
  189. }
  190. LRESULT lResult = 0;
  191. lResult = SendDlgItemMessage(APP_GVAR.hwndMainDlg,
  192. IDC_LIST_WIA_DEVICES,
  193. LB_GETCURSEL,
  194. 0,
  195. 0);
  196. Index = (WPARAM) lResult;
  197. if (Index == LB_ERR)
  198. {
  199. hr = E_FAIL;
  200. }
  201. if (hr == S_OK)
  202. {
  203. IWiaItem *pSelectedDevice = NULL;
  204. LPARAM lParam = 0;
  205. lParam = SendDlgItemMessage(APP_GVAR.hwndMainDlg,
  206. IDC_LIST_WIA_DEVICES,
  207. LB_GETITEMDATA,
  208. Index,
  209. 0);
  210. IWiaPropertyStorage *pItem = (IWiaPropertyStorage*)lParam;
  211. if (pItem)
  212. {
  213. hr = GetProperty(pItem, WIA_DIP_DEV_ID, szDeviceID,
  214. sizeof(szDeviceID)/sizeof(TCHAR));
  215. if (hr == S_OK)
  216. {
  217. hr = CreateRootItem(pWiaDevMgr,
  218. szDeviceID,
  219. &pSelectedDevice);
  220. }
  221. if (hr == S_OK)
  222. {
  223. hr = LOCAL_GVAR.pGIT->RegisterInterfaceInGlobal(pSelectedDevice,
  224. IID_IWiaItem,
  225. &LOCAL_GVAR.dwSelectedDeviceCookie);
  226. }
  227. if (pszDeviceID)
  228. {
  229. _tcsncpy(pszDeviceID, szDeviceID, cchDeviceID);
  230. }
  231. if (pSelectedDevice)
  232. {
  233. pSelectedDevice->Release();
  234. pSelectedDevice = NULL;
  235. }
  236. }
  237. }
  238. if (pWiaDevMgr)
  239. {
  240. pWiaDevMgr->Release();
  241. pWiaDevMgr = NULL;
  242. }
  243. return hr;
  244. }
  245. ///////////////////////////////
  246. // WiaProc_GetImageDirectory
  247. //
  248. HRESULT WiaProc_GetImageDirectory(TCHAR *pszImageDirectory,
  249. UINT cchImageDirectory)
  250. {
  251. HRESULT hr = S_OK;
  252. IWiaPropertyStorage *pStorage = NULL;
  253. IWiaItem *pSelectedDevice = NULL;
  254. if ((LOCAL_GVAR.dwSelectedDeviceCookie == 0) ||
  255. (LOCAL_GVAR.pGIT == NULL) ||
  256. (pszImageDirectory == NULL))
  257. {
  258. return E_POINTER;
  259. }
  260. if (hr == S_OK)
  261. {
  262. hr = LOCAL_GVAR.pGIT->GetInterfaceFromGlobal(LOCAL_GVAR.dwSelectedDeviceCookie,
  263. IID_IWiaItem,
  264. (void**)&pSelectedDevice);
  265. }
  266. if (pSelectedDevice == NULL)
  267. {
  268. hr = E_POINTER;
  269. }
  270. if (hr == S_OK)
  271. {
  272. hr = pSelectedDevice->QueryInterface(IID_IWiaPropertyStorage,
  273. (void**) &pStorage);
  274. }
  275. if (hr == S_OK)
  276. {
  277. hr = GetProperty(pStorage, WIA_DPV_IMAGES_DIRECTORY, pszImageDirectory,
  278. cchImageDirectory);
  279. }
  280. if (pStorage)
  281. {
  282. pStorage->Release();
  283. pStorage = NULL;
  284. }
  285. if (pSelectedDevice)
  286. {
  287. pSelectedDevice->Release();
  288. pSelectedDevice = NULL;
  289. }
  290. return hr;
  291. }
  292. ///////////////////////////////
  293. // WiaProc_DeviceTakePicture
  294. //
  295. HRESULT WiaProc_DeviceTakePicture()
  296. {
  297. HRESULT hr = S_OK;
  298. IWiaItem *pSelectedDevice = NULL;
  299. if ((LOCAL_GVAR.dwSelectedDeviceCookie == 0) ||
  300. (LOCAL_GVAR.pGIT == NULL))
  301. {
  302. return E_POINTER;
  303. }
  304. if (hr == S_OK)
  305. {
  306. hr = LOCAL_GVAR.pGIT->GetInterfaceFromGlobal(LOCAL_GVAR.dwSelectedDeviceCookie,
  307. IID_IWiaItem,
  308. (void**)&pSelectedDevice);
  309. }
  310. if (pSelectedDevice == NULL)
  311. {
  312. hr = E_POINTER;
  313. }
  314. if (hr == S_OK)
  315. {
  316. IWiaItem *pUnused = NULL;
  317. hr = pSelectedDevice->DeviceCommand(0,
  318. &WIA_CMD_TAKE_PICTURE,
  319. &pUnused);
  320. if (pUnused)
  321. {
  322. pUnused->Release();
  323. pUnused = NULL;
  324. }
  325. }
  326. if (pSelectedDevice)
  327. {
  328. pSelectedDevice->Release();
  329. pSelectedDevice = NULL;
  330. }
  331. return hr;
  332. }
  333. ///////////////////////////////
  334. // ClearDeviceList
  335. //
  336. HRESULT ClearDeviceList()
  337. {
  338. HRESULT hr = S_OK;
  339. WPARAM NumDevices = 0;
  340. NumDevices = GetNumDevicesInList();
  341. //
  342. // Free all the IWiaItem pointers we saved in our
  343. // list box.
  344. //
  345. if (NumDevices != LB_ERR)
  346. {
  347. for (WPARAM i = 0; i < NumDevices; i++)
  348. {
  349. IWiaPropertyStorage *pItem = NULL;
  350. pItem = GetWiaStorage(i);
  351. if (pItem)
  352. {
  353. pItem->Release();
  354. }
  355. }
  356. }
  357. //
  358. // Empty the list
  359. //
  360. SendDlgItemMessage(APP_GVAR.hwndMainDlg,
  361. IDC_LIST_WIA_DEVICES,
  362. LB_RESETCONTENT,
  363. 0,
  364. 0);
  365. return hr;
  366. }
  367. ///////////////////////////////
  368. // WiaProc_PopulateDeviceList
  369. //
  370. HRESULT WiaProc_PopulateDeviceList()
  371. {
  372. HRESULT hr = S_OK;
  373. IEnumWIA_DEV_INFO *pEnum = NULL;
  374. IWiaDevMgr *pWiaDevMgr = NULL;
  375. hr = LOCAL_GVAR.pGIT->GetInterfaceFromGlobal(LOCAL_GVAR.dwWiaDevMgrCookie,
  376. IID_IWiaDevMgr,
  377. (void**)&pWiaDevMgr);
  378. if (pWiaDevMgr == NULL)
  379. {
  380. return E_POINTER;
  381. }
  382. //
  383. // Clear out the device list if it has any items in it.
  384. //
  385. ClearDeviceList();
  386. if (hr == S_OK)
  387. {
  388. hr = pWiaDevMgr->EnumDeviceInfo(0, &pEnum);
  389. }
  390. while (hr == S_OK)
  391. {
  392. IWiaItem *pRootItem = NULL;
  393. IWiaPropertyStorage *pPropStorage = NULL;
  394. TCHAR szFriendlyName[MAX_PATH + 1] = {0};
  395. TCHAR szWiaDeviceID[MAX_PATH + 1] = {0};
  396. //
  397. // Get the next device in the enumeration.
  398. //
  399. hr = pEnum->Next(1, &pPropStorage, NULL);
  400. //
  401. // Get the device's Wia Device ID
  402. //
  403. if (hr == S_OK)
  404. {
  405. hr = GetProperty(pPropStorage, WIA_DIP_DEV_ID, szWiaDeviceID,
  406. sizeof(szWiaDeviceID)/sizeof(TCHAR));
  407. }
  408. //
  409. // Get the device's Wia Device Name
  410. //
  411. if (hr == S_OK)
  412. {
  413. hr = GetProperty(pPropStorage, WIA_DIP_DEV_NAME, szFriendlyName,
  414. sizeof(szFriendlyName)/sizeof(TCHAR));
  415. }
  416. //
  417. // We do not relesae the propstorage item because we store the pointer
  418. // in our list until we shutdown the app.
  419. //
  420. if (hr == S_OK)
  421. {
  422. AddItemToList(pPropStorage, szFriendlyName, szWiaDeviceID);
  423. }
  424. }
  425. SendDlgItemMessage(APP_GVAR.hwndMainDlg,
  426. IDC_LIST_WIA_DEVICES,
  427. LB_SETCURSEL,
  428. 0,
  429. 0);
  430. return hr;
  431. }
  432. ///////////////////////////////
  433. // RegisterForEvents
  434. //
  435. HRESULT RegisterForEvents(IWiaDevMgr *pWiaDevMgr)
  436. {
  437. HRESULT hr = S_OK;
  438. CWiaEvent *pWiaEvent = NULL;
  439. IWiaEventCallback *pIWiaEvent = NULL;
  440. if (pWiaDevMgr == NULL)
  441. {
  442. return E_POINTER;
  443. }
  444. //
  445. // Register our callback events
  446. //
  447. if (hr == S_OK)
  448. {
  449. // create the WiaEvent
  450. pWiaEvent = new CWiaEvent();
  451. if (pWiaEvent == NULL)
  452. {
  453. hr = E_OUTOFMEMORY;
  454. }
  455. }
  456. if (hr == S_OK)
  457. {
  458. hr = pWiaEvent->QueryInterface(IID_IWiaEventCallback,
  459. (void**)&pIWiaEvent);
  460. }
  461. if (hr == S_OK)
  462. {
  463. hr = pWiaDevMgr->RegisterEventCallbackInterface(WIA_REGISTER_EVENT_CALLBACK,
  464. NULL,
  465. &WIA_EVENT_DEVICE_CONNECTED,
  466. pIWiaEvent,
  467. &LOCAL_GVAR.pConnectedCallback);
  468. hr = pWiaDevMgr->RegisterEventCallbackInterface(WIA_REGISTER_EVENT_CALLBACK,
  469. NULL,
  470. &WIA_EVENT_DEVICE_DISCONNECTED,
  471. pIWiaEvent,
  472. &LOCAL_GVAR.pDisconnectedCallback);
  473. hr = pWiaDevMgr->RegisterEventCallbackInterface(WIA_REGISTER_EVENT_CALLBACK,
  474. NULL,
  475. &WIA_EVENT_ITEM_CREATED,
  476. pIWiaEvent,
  477. &LOCAL_GVAR.pCreateCallback);
  478. hr = pWiaDevMgr->RegisterEventCallbackInterface(WIA_REGISTER_EVENT_CALLBACK,
  479. NULL,
  480. &WIA_EVENT_ITEM_DELETED,
  481. pIWiaEvent,
  482. &LOCAL_GVAR.pDeleteCallback);
  483. }
  484. //
  485. // We don't need to delete pWiaEvent since we are releasing it.
  486. //
  487. if (pIWiaEvent)
  488. {
  489. pIWiaEvent->Release();
  490. pIWiaEvent = NULL;
  491. }
  492. return hr;
  493. }
  494. ///////////////////////////////
  495. // AddItemToList
  496. //
  497. HRESULT AddItemToList(IWiaPropertyStorage *pItem,
  498. TCHAR *pszFriendlyName,
  499. TCHAR *pszDeviceID)
  500. {
  501. HRESULT hr = S_OK;
  502. WPARAM Index = 0;
  503. if ((pItem == NULL) ||
  504. (pszFriendlyName == NULL) ||
  505. (pszDeviceID == NULL))
  506. {
  507. hr = E_POINTER;
  508. return hr;
  509. }
  510. TCHAR szNewItem[MAX_PATH * 2] = {0};
  511. _sntprintf(szNewItem, sizeof(szNewItem)/sizeof(TCHAR),
  512. TEXT("%s (%s)"), pszFriendlyName, pszDeviceID);
  513. LRESULT lResult = 0;
  514. lResult = SendDlgItemMessage(APP_GVAR.hwndMainDlg,
  515. IDC_LIST_WIA_DEVICES,
  516. LB_ADDSTRING,
  517. 0,
  518. (LPARAM) szNewItem);
  519. Index = (WPARAM) lResult;
  520. //
  521. // pItem already has an AddRef on it.
  522. //
  523. SendDlgItemMessage(APP_GVAR.hwndMainDlg,
  524. IDC_LIST_WIA_DEVICES,
  525. LB_SETITEMDATA,
  526. Index,
  527. (LPARAM) pItem);
  528. return hr;
  529. }
  530. ///////////////////////////////
  531. // GetNumDevicesInList
  532. //
  533. WPARAM GetNumDevicesInList()
  534. {
  535. LRESULT lResult = 0;
  536. WPARAM NumItems = 0;
  537. lResult = SendDlgItemMessage(APP_GVAR.hwndMainDlg,
  538. IDC_LIST_WIA_DEVICES,
  539. LB_GETCOUNT,
  540. 0,
  541. 0);
  542. NumItems = (WPARAM) lResult;
  543. return NumItems;
  544. }
  545. ///////////////////////////////
  546. // GetWiaStorage
  547. //
  548. IWiaPropertyStorage* GetWiaStorage(WPARAM Index)
  549. {
  550. LPARAM lParam = 0;
  551. IWiaPropertyStorage *pItem = NULL;
  552. lParam = SendDlgItemMessage(APP_GVAR.hwndMainDlg,
  553. IDC_LIST_WIA_DEVICES,
  554. LB_GETITEMDATA,
  555. Index,
  556. 0);
  557. pItem = (IWiaPropertyStorage*)lParam;
  558. return pItem;
  559. }
  560. ///////////////////////////////
  561. // CreateWiaDevMgr
  562. //
  563. HRESULT CreateWiaDevMgr(IWiaDevMgr **ppDevMgr)
  564. {
  565. HRESULT hr = S_OK;
  566. if (ppDevMgr == NULL)
  567. {
  568. hr = E_POINTER;
  569. return hr;
  570. }
  571. hr = CoCreateInstance(CLSID_WiaDevMgr,
  572. NULL,
  573. CLSCTX_LOCAL_SERVER,
  574. IID_IWiaDevMgr,
  575. (void**) ppDevMgr);
  576. return hr;
  577. }
  578. ///////////////////////////////
  579. // WiaProc_GetProperty
  580. //
  581. // Generic
  582. //
  583. HRESULT WiaProc_GetProperty(IWiaPropertyStorage *pPropStorage,
  584. PROPID nPropID,
  585. PROPVARIANT *pPropVar)
  586. {
  587. HRESULT hr = S_OK;
  588. if ((pPropStorage == NULL) ||
  589. (pPropVar == NULL))
  590. {
  591. hr = E_POINTER;
  592. return hr;
  593. }
  594. PropVariantInit(pPropVar);
  595. PROPSPEC ps = {0};
  596. ps.ulKind = PRSPEC_PROPID;
  597. ps.propid = nPropID;
  598. if (SUCCEEDED(hr))
  599. {
  600. hr = pPropStorage->ReadMultiple(1, &ps, pPropVar);
  601. }
  602. return hr;
  603. }
  604. ///////////////////////////////
  605. // GetProperty
  606. //
  607. // For 'long' properties
  608. //
  609. HRESULT GetProperty(IWiaPropertyStorage *pPropStorage,
  610. PROPID nPropID,
  611. LONG *pnValue)
  612. {
  613. HRESULT hr = S_OK;
  614. if ((pPropStorage == NULL) ||
  615. (pnValue == NULL))
  616. {
  617. hr = E_POINTER;
  618. return hr;
  619. }
  620. PROPVARIANT pvPropValue;
  621. *pnValue = 0;
  622. PropVariantInit(&pvPropValue);
  623. hr = WiaProc_GetProperty(pPropStorage, nPropID, &pvPropValue);
  624. if (hr == S_OK)
  625. {
  626. if ((pvPropValue.vt == VT_I4) ||
  627. (pvPropValue.vt == VT_UI4))
  628. {
  629. *pnValue = pvPropValue.lVal;
  630. }
  631. }
  632. PropVariantClear(&pvPropValue);
  633. return hr;
  634. }
  635. ///////////////////////////////
  636. // GetProperty
  637. //
  638. // For 'string' properties
  639. //
  640. HRESULT GetProperty(IWiaPropertyStorage *pPropStorage,
  641. PROPID nPropID,
  642. TCHAR *pszBuffer,
  643. UINT cbBuffer)
  644. {
  645. HRESULT hr = S_OK;
  646. if ((pPropStorage == NULL) ||
  647. (pszBuffer == NULL))
  648. {
  649. hr = E_POINTER;
  650. return hr;
  651. }
  652. PROPVARIANT pvPropValue;
  653. PropVariantInit(&pvPropValue);
  654. hr = WiaProc_GetProperty(pPropStorage, nPropID, &pvPropValue);
  655. if (hr == S_OK)
  656. {
  657. if ((pvPropValue.vt == VT_LPWSTR) ||
  658. (pvPropValue.vt == VT_BSTR))
  659. {
  660. AppUtil_ConvertToTCHAR(pvPropValue.pwszVal, pszBuffer, cbBuffer);
  661. }
  662. }
  663. //
  664. // This frees the BSTR
  665. //
  666. PropVariantClear(&pvPropValue);
  667. return hr;
  668. }
  669. ///////////////////////////////
  670. // CreateRootItem
  671. //
  672. HRESULT CreateRootItem(IWiaDevMgr *pDevMgr,
  673. const TCHAR *pszWiaDeviceID,
  674. IWiaItem **ppRootItem)
  675. {
  676. HRESULT hr = S_OK;
  677. if ((pDevMgr == NULL) ||
  678. (pszWiaDeviceID == NULL) ||
  679. (ppRootItem == NULL))
  680. {
  681. hr = E_POINTER;
  682. return hr;
  683. }
  684. if (hr == S_OK)
  685. {
  686. BOOL bRetry = TRUE;
  687. BSTR bstrDeviceID = NULL;
  688. WCHAR wszWiaDeviceID[MAX_PATH] = {0};
  689. AppUtil_ConvertToWideString(pszWiaDeviceID, wszWiaDeviceID,
  690. sizeof(wszWiaDeviceID) / sizeof(WCHAR));
  691. bstrDeviceID = SysAllocString(wszWiaDeviceID);
  692. for (UINT uiRetryCount = 0;
  693. (uiRetryCount < 5) && (bRetry);
  694. ++uiRetryCount)
  695. {
  696. hr = pDevMgr->CreateDevice(bstrDeviceID,
  697. ppRootItem);
  698. if (SUCCEEDED(hr))
  699. {
  700. //
  701. // Break out of loop
  702. //
  703. bRetry = FALSE;
  704. }
  705. else if (hr == WIA_ERROR_BUSY)
  706. {
  707. //
  708. // Wait a little while before retrying
  709. //
  710. Sleep(200);
  711. }
  712. else
  713. {
  714. //
  715. // All other errors are considered fatal
  716. //
  717. bRetry = FALSE;
  718. }
  719. }
  720. if (bstrDeviceID)
  721. {
  722. SysFreeString(bstrDeviceID);
  723. bstrDeviceID = NULL;
  724. }
  725. }
  726. return hr;
  727. }
  728. ///////////////////////////////
  729. // SetProperty
  730. //
  731. // Generic
  732. //
  733. HRESULT SetProperty(IWiaPropertyStorage *pPropStorage,
  734. PROPID nPropID,
  735. const PROPVARIANT *ppv,
  736. PROPID nNameFirst)
  737. {
  738. HRESULT hr = 0;
  739. PROPSPEC ps = {0};
  740. if ((pPropStorage == NULL) ||
  741. (ppv == NULL))
  742. {
  743. return E_POINTER;
  744. }
  745. ps.ulKind = PRSPEC_PROPID;
  746. ps.propid = nPropID;
  747. if (hr == S_OK)
  748. {
  749. hr = pPropStorage->WriteMultiple(1, &ps, ppv, nNameFirst);
  750. }
  751. return hr;
  752. }
  753. ///////////////////////////////
  754. // WiaProc_SetLastSavedImage
  755. //
  756. // For 'string' properties
  757. //
  758. HRESULT WiaProc_SetLastSavedImage(BSTR bstrLastSavedImage)
  759. {
  760. HRESULT hr = S_OK;
  761. IWiaItem *pSelectedDevice = NULL;
  762. IWiaPropertyStorage *pStorage = NULL;
  763. PROPVARIANT pv = {0};
  764. if ((LOCAL_GVAR.dwSelectedDeviceCookie == 0) ||
  765. (LOCAL_GVAR.pGIT == NULL))
  766. {
  767. return E_POINTER;
  768. }
  769. EnterCriticalSection(&LOCAL_GVAR.CritSec);
  770. if (hr == S_OK)
  771. {
  772. hr = LOCAL_GVAR.pGIT->GetInterfaceFromGlobal(LOCAL_GVAR.dwSelectedDeviceCookie,
  773. IID_IWiaItem,
  774. (void**)&pSelectedDevice);
  775. }
  776. if (pSelectedDevice == NULL)
  777. {
  778. hr = E_POINTER;
  779. }
  780. if (hr == S_OK)
  781. {
  782. hr = pSelectedDevice->QueryInterface(IID_IWiaPropertyStorage,
  783. (void**)&pStorage);
  784. }
  785. if (hr == S_OK)
  786. {
  787. PropVariantInit(&pv);
  788. pv.vt = VT_BSTR;
  789. pv.bstrVal = bstrLastSavedImage;
  790. hr = SetProperty(pStorage, WIA_DPV_LAST_PICTURE_TAKEN, &pv, 2);
  791. }
  792. if (pStorage)
  793. {
  794. pStorage->Release();
  795. pStorage = NULL;
  796. }
  797. if (pSelectedDevice)
  798. {
  799. pSelectedDevice->Release();
  800. pSelectedDevice = NULL;
  801. }
  802. LeaveCriticalSection(&LOCAL_GVAR.CritSec);
  803. return hr;
  804. }
  805. ///////////////////////////////
  806. // WiaProc_PopulateItemList
  807. //
  808. HRESULT WiaProc_PopulateItemList()
  809. {
  810. HRESULT hr = S_OK;
  811. if (LOCAL_GVAR.dwSelectedDeviceCookie == 0)
  812. {
  813. return E_POINTER;
  814. }
  815. hr = ImageLst_PopulateWiaItemList(LOCAL_GVAR.pGIT,
  816. LOCAL_GVAR.dwSelectedDeviceCookie);
  817. return hr;
  818. }
  819. ///////////////////////////////
  820. // WiaProc_DestroySelectedDevice
  821. //
  822. HRESULT WiaProc_DestroySelectedDevice()
  823. {
  824. HRESULT hr = S_OK;
  825. if (LOCAL_GVAR.dwSelectedDeviceCookie == 0)
  826. {
  827. return E_POINTER;
  828. }
  829. ImageLst_CancelLoadAndWait(5000);
  830. if ((LOCAL_GVAR.dwSelectedDeviceCookie != 0) &&
  831. (LOCAL_GVAR.pGIT != NULL))
  832. {
  833. LOCAL_GVAR.pGIT->RevokeInterfaceFromGlobal(LOCAL_GVAR.dwSelectedDeviceCookie);
  834. LOCAL_GVAR.dwSelectedDeviceCookie = 0;
  835. }
  836. ImageLst_Clear();
  837. return hr;
  838. }