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.

791 lines
20 KiB

  1. /*****************************************************************************
  2. *
  3. * (C) COPYRIGHT MICROSOFT CORPORATION, 1999-2000
  4. *
  5. * TITLE: WiaUtil.cpp
  6. *
  7. * VERSION: 1.0
  8. *
  9. * AUTHOR: OrenR
  10. *
  11. * DATE: 2000/11/07
  12. *
  13. * DESCRIPTION: Provides support functions for Wia related activities
  14. *
  15. *****************************************************************************/
  16. #include <precomp.h>
  17. #pragma hdrstop
  18. ///////////////////////////////
  19. // Constants
  20. //
  21. const UINT CREATE_DEVICE_RETRY_MAX_COUNT = 5;
  22. const UINT CREATE_DEVICE_RETRY_WAIT = 300;
  23. const TCHAR* WIAVIDEO_REG_KEY = _T("System\\CurrentControlSet\\Control\\StillImage\\WiaVideo");
  24. const TCHAR* WIAVIDEO_REG_VAL_USE_VMR = _T("UseVMR");
  25. const BOOL WIAVIDEO_REG_VAL_DEFAULT_USEVMR = FALSE;
  26. ///////////////////////////////
  27. // CreateRootItem
  28. //
  29. // Static Fn
  30. //
  31. HRESULT CWiaUtil::CreateRootItem(IWiaDevMgr *pDevMgr,
  32. const CSimpleString *pstrWiaDeviceId,
  33. IWiaItem **ppRootItem)
  34. {
  35. HRESULT hr = S_OK;
  36. ASSERT(pDevMgr != NULL);
  37. ASSERT(pstrWiaDeviceId != NULL);
  38. ASSERT(ppRootItem != NULL);
  39. if ((pDevMgr == NULL) ||
  40. (pstrWiaDeviceId == NULL) ||
  41. (ppRootItem == NULL))
  42. {
  43. hr = E_POINTER;
  44. CHECK_S_OK2(hr, ("CWiaUtil::CreateRootItem, received NULL param"));
  45. return hr;
  46. }
  47. if (hr == S_OK)
  48. {
  49. BOOL bRetry = TRUE;
  50. for (UINT uiRetryCount = 0;
  51. (uiRetryCount < CREATE_DEVICE_RETRY_MAX_COUNT) && (bRetry);
  52. ++uiRetryCount)
  53. {
  54. hr = pDevMgr->CreateDevice(CSimpleBStr(*pstrWiaDeviceId),
  55. ppRootItem);
  56. if (SUCCEEDED(hr))
  57. {
  58. //
  59. // Break out of loop
  60. //
  61. bRetry = FALSE;
  62. }
  63. else if (hr == WIA_ERROR_BUSY)
  64. {
  65. //
  66. // Wait a little while before retrying
  67. //
  68. Sleep(CREATE_DEVICE_RETRY_WAIT);
  69. }
  70. else
  71. {
  72. //
  73. // All other errors are considered fatal
  74. //
  75. bRetry = FALSE;
  76. }
  77. }
  78. }
  79. return hr;
  80. }
  81. ///////////////////////////////
  82. // FindWiaIdByDShowId
  83. //
  84. // Static Fn
  85. //
  86. HRESULT CWiaUtil::FindWiaIdByDShowId(const CSimpleString *pstrDShowId,
  87. CSimpleString *pstrWiaId,
  88. IWiaItem **ppRootItem)
  89. {
  90. HRESULT hr = S_OK;
  91. BOOL bFound = FALSE;
  92. CComPtr<IWiaDevMgr> pDevMgr;
  93. CComPtr<IEnumWIA_DEV_INFO> pEnum;
  94. ASSERT(pstrDShowId != NULL);
  95. ASSERT(pstrWiaId != NULL);
  96. if ((pstrDShowId == NULL) ||
  97. (pstrWiaId == NULL))
  98. {
  99. hr = E_POINTER;
  100. CHECK_S_OK2(hr, ("CWiaUtil::FindWiaDeviceGeneric received a "
  101. "NULL param"));
  102. return hr;
  103. }
  104. if (hr == S_OK)
  105. {
  106. hr = CreateWiaDevMgr(&pDevMgr);
  107. }
  108. if (hr == S_OK)
  109. {
  110. hr = pDevMgr->EnumDeviceInfo(0, &pEnum);
  111. }
  112. while ((hr == S_OK) && (!bFound))
  113. {
  114. CComPtr<IWiaItem> pRootItem = NULL;
  115. CComPtr<IWiaPropertyStorage> pPropStorage = NULL;
  116. CSimpleString strDShowDeviceID = TEXT("");
  117. CSimpleString strWiaDeviceID = TEXT("");
  118. //
  119. // Get the next device in the enumeration.
  120. //
  121. hr = pEnum->Next(1, &pPropStorage, NULL);
  122. //
  123. // Get the device's Wia Device ID
  124. //
  125. if (hr == S_OK)
  126. {
  127. hr = GetProperty(pPropStorage, WIA_DIP_DEV_ID, &strWiaDeviceID);
  128. }
  129. //
  130. // Create the new device. We do this because the driver is only
  131. // told by the WIA service to load its DShowDeviceID property
  132. // when it is created.
  133. //
  134. if (hr == S_OK)
  135. {
  136. hr = CreateRootItem(pDevMgr, &strWiaDeviceID, &pRootItem);
  137. }
  138. //
  139. // Attempt to get the DShowDeviceID of the root item.
  140. //
  141. if (hr == S_OK)
  142. {
  143. hr = GetProperty(pPropStorage,
  144. WIA_DPV_DSHOW_DEVICE_PATH,
  145. &strDShowDeviceID);
  146. //
  147. // We got the DShowDeviceID of the WIA device, now check
  148. // to see if it is the one we are looking for.
  149. //
  150. if (hr == S_OK)
  151. {
  152. if (pstrDShowId->CompareNoCase(strDShowDeviceID) == 0)
  153. {
  154. //
  155. // We found our DShow device ID, return the Wia Device ID
  156. //
  157. if (strWiaDeviceID.Length() > 0)
  158. {
  159. bFound = TRUE;
  160. *pstrWiaId = strWiaDeviceID;
  161. if (ppRootItem)
  162. {
  163. *ppRootItem = pRootItem;
  164. (*ppRootItem)->AddRef();
  165. }
  166. }
  167. else
  168. {
  169. bFound = FALSE;
  170. hr = E_FAIL;
  171. CHECK_S_OK2(hr,
  172. ("Found DShow Device ID '%ls', but "
  173. "couldn't get its WIA Device ID, "
  174. "this should never happen",
  175. CSimpleStringConvert::WideString(
  176. strDShowDeviceID).String()));
  177. }
  178. }
  179. }
  180. else
  181. {
  182. //
  183. // we couldn't get the DShowDeviceID property from the
  184. // device, but that's fine since not all imaging devices
  185. // have this property.
  186. hr = S_OK;
  187. }
  188. }
  189. }
  190. return hr;
  191. }
  192. ///////////////////////////////
  193. // CreateWiaDevMgr
  194. //
  195. // Static Fn
  196. //
  197. HRESULT CWiaUtil::CreateWiaDevMgr(IWiaDevMgr **ppDevMgr)
  198. {
  199. HRESULT hr = S_OK;
  200. ASSERT(ppDevMgr != NULL);
  201. if (ppDevMgr == NULL)
  202. {
  203. hr = E_POINTER;
  204. CHECK_S_OK2(hr, ("CWiaUtil::CreateWiaDevMgr received a NULL param"));
  205. return hr;
  206. }
  207. hr = CoCreateInstance(CLSID_WiaDevMgr,
  208. NULL,
  209. CLSCTX_LOCAL_SERVER,
  210. IID_IWiaDevMgr,
  211. (void**) ppDevMgr);
  212. CHECK_S_OK2(hr, ("CWiaUtil::CreateWiaDevMgr, failed to create the Wia "
  213. "Device Manager object"));
  214. return hr;
  215. }
  216. ///////////////////////////////
  217. // SetProperty
  218. //
  219. // Generic
  220. //
  221. HRESULT CWiaUtil::SetProperty(IWiaPropertyStorage *pPropStorage,
  222. PROPID nPropID,
  223. const PROPVARIANT *ppv,
  224. PROPID nNameFirst)
  225. {
  226. DBG_FN("CWiaUtil::SetProperty");
  227. HRESULT hr = 0;
  228. PROPSPEC ps = {0};
  229. ASSERT(pPropStorage != NULL);
  230. ASSERT(ppv != NULL);
  231. if ((pPropStorage == NULL) ||
  232. (ppv == NULL))
  233. {
  234. hr = E_POINTER;
  235. CHECK_S_OK2(hr, ("CWiaUtil::SetProperty received NULL param"));
  236. return hr;
  237. }
  238. ps.ulKind = PRSPEC_PROPID;
  239. ps.propid = nPropID;
  240. if (hr == S_OK)
  241. {
  242. hr = pPropStorage->WriteMultiple(1, &ps, ppv, nNameFirst);
  243. }
  244. return hr;
  245. }
  246. ///////////////////////////////
  247. // SetProperty
  248. //
  249. // For 'long' properties
  250. //
  251. //
  252. HRESULT CWiaUtil::SetProperty(IWiaPropertyStorage *pPropStorage,
  253. PROPID nPropID,
  254. LONG nValue)
  255. {
  256. HRESULT hr = S_OK;
  257. PROPVARIANT pv = {0};
  258. ASSERT(pPropStorage != NULL);
  259. if (pPropStorage == NULL)
  260. {
  261. hr = E_POINTER;
  262. CHECK_S_OK2(hr, ("CWiaUtil::SetProperty received NULL param"));
  263. return hr;
  264. }
  265. pv.vt = VT_I4;
  266. pv.lVal = nValue;
  267. hr = SetProperty(pPropStorage, nPropID, &pv, 2);
  268. return hr;
  269. }
  270. ///////////////////////////////
  271. // SetProperty
  272. //
  273. // For 'string' properties
  274. //
  275. //
  276. HRESULT CWiaUtil::SetProperty(IWiaPropertyStorage *pPropStorage,
  277. PROPID nPropID,
  278. const CSimpleString *pstrPropVal)
  279. {
  280. HRESULT hr = S_OK;
  281. PROPVARIANT pv = {0};
  282. ASSERT(pPropStorage != NULL);
  283. ASSERT(pstrPropVal != NULL);
  284. if ((pPropStorage == NULL) ||
  285. (pstrPropVal == NULL))
  286. {
  287. hr = E_POINTER;
  288. CHECK_S_OK2(hr, ("CWiaUtil::SetProperty received NULL param"));
  289. return hr;
  290. }
  291. pv.vt = VT_BSTR;
  292. pv.bstrVal = CSimpleBStr(*pstrPropVal);
  293. hr = SetProperty(pPropStorage, nPropID, &pv, 2);
  294. return hr;
  295. }
  296. ///////////////////////////////
  297. // GetProperty
  298. //
  299. // Generic
  300. //
  301. HRESULT CWiaUtil::GetProperty(IWiaPropertyStorage *pPropStorage,
  302. PROPID nPropID,
  303. PROPVARIANT *pPropVar)
  304. {
  305. DBG_FN("CWiaUtil::GetProperty");
  306. HRESULT hr = S_OK;
  307. ASSERT(pPropStorage != NULL);
  308. ASSERT(pPropVar != NULL);
  309. if ((pPropStorage == NULL) ||
  310. (pPropVar == NULL))
  311. {
  312. hr = E_POINTER;
  313. CHECK_S_OK2(hr, ("CWiaUtil::GetProperty received NULL param"));
  314. return hr;
  315. }
  316. PropVariantInit(pPropVar);
  317. PROPSPEC ps = {0};
  318. ps.ulKind = PRSPEC_PROPID;
  319. ps.propid = nPropID;
  320. if (SUCCEEDED(hr))
  321. {
  322. hr = pPropStorage->ReadMultiple(1, &ps, pPropVar);
  323. if (hr != S_OK)
  324. {
  325. CHECK_S_OK2(hr, ("CWiaUtil::GetProperty, ReadMultiple failed "
  326. "for prop ID '%lu' (0x%08lx)",
  327. nPropID,
  328. nPropID));
  329. }
  330. }
  331. else
  332. {
  333. CHECK_S_OK2(hr, ("CWiaUtil::GetProperty, QueryInterface failed "
  334. "for IWiaPropertyStorage"));
  335. }
  336. return hr;
  337. }
  338. ///////////////////////////////
  339. // GetProperty
  340. //
  341. // For 'long' properties
  342. //
  343. HRESULT CWiaUtil::GetProperty(IWiaPropertyStorage *pPropStorage,
  344. PROPID nPropID,
  345. LONG *pnValue)
  346. {
  347. HRESULT hr = S_OK;
  348. ASSERT(pPropStorage != NULL);
  349. ASSERT(pnValue != NULL);
  350. if ((pPropStorage == NULL) ||
  351. (pnValue == NULL))
  352. {
  353. hr = E_POINTER;
  354. CHECK_S_OK2(hr, ("CWiaUtil::GetProperty received a NULL param"));
  355. return hr;
  356. }
  357. PROPVARIANT pvPropValue;
  358. *pnValue = 0;
  359. PropVariantInit(&pvPropValue);
  360. hr = GetProperty(pPropStorage, nPropID, &pvPropValue);
  361. if (hr == S_OK)
  362. {
  363. if ((pvPropValue.vt == VT_I4) ||
  364. (pvPropValue.vt == VT_UI4))
  365. {
  366. *pnValue = pvPropValue.lVal;
  367. }
  368. }
  369. PropVariantClear(&pvPropValue);
  370. return hr;
  371. }
  372. ///////////////////////////////
  373. // GetProperty
  374. //
  375. // For 'string' properties
  376. //
  377. HRESULT CWiaUtil::GetProperty(IWiaPropertyStorage *pPropStorage,
  378. PROPID nPropID,
  379. CSimpleStringWide *pstrPropertyValue)
  380. {
  381. HRESULT hr = S_OK;
  382. ASSERT(pPropStorage != NULL);
  383. ASSERT(pstrPropertyValue != NULL);
  384. if ((pPropStorage == NULL) ||
  385. (pstrPropertyValue == NULL))
  386. {
  387. hr = E_POINTER;
  388. CHECK_S_OK2(hr, ("CWiaUtil::GetProperty received a NULL param"));
  389. return hr;
  390. }
  391. PROPVARIANT pvPropValue;
  392. *pstrPropertyValue = L"";
  393. PropVariantInit(&pvPropValue);
  394. hr = GetProperty(pPropStorage, nPropID, &pvPropValue);
  395. if (hr == S_OK)
  396. {
  397. if ((pvPropValue.vt == VT_LPWSTR) ||
  398. (pvPropValue.vt == VT_BSTR))
  399. {
  400. *pstrPropertyValue = pvPropValue.pwszVal;
  401. }
  402. }
  403. PropVariantClear(&pvPropValue);
  404. return hr;
  405. }
  406. ///////////////////////////////
  407. // GetUseVMR
  408. //
  409. HRESULT CWiaUtil::GetUseVMR(BOOL *pbUseVMR)
  410. {
  411. ASSERT(pbUseVMR != NULL);
  412. HRESULT hr = S_OK;
  413. CRegistry Reg(HKEY_LOCAL_MACHINE,
  414. WIAVIDEO_REG_KEY);
  415. if (pbUseVMR == NULL)
  416. {
  417. hr = E_POINTER;
  418. CHECK_S_OK2(hr, ("CWiaUtil::GetUseVMR received a NULL pointer"));
  419. return hr;
  420. }
  421. if (hr == S_OK)
  422. {
  423. *pbUseVMR = WIAVIDEO_REG_VAL_DEFAULT_USEVMR;
  424. hr = Reg.GetDWORD(WIAVIDEO_REG_VAL_USE_VMR,
  425. (DWORD*) pbUseVMR,
  426. TRUE);
  427. }
  428. return hr;
  429. }
  430. ///////////////////////////////
  431. // CRegistry Constructor
  432. //
  433. CRegistry::CRegistry(HKEY hKeyRoot,
  434. const TCHAR *pszKeyPath) :
  435. m_hRootKey(NULL),
  436. m_bReadOnlyKey(FALSE)
  437. {
  438. LRESULT lr = ERROR_SUCCESS;
  439. DWORD dwDisposition = 0;
  440. lr = RegCreateKeyEx(hKeyRoot,
  441. pszKeyPath,
  442. 0,
  443. NULL,
  444. 0,
  445. KEY_ALL_ACCESS,
  446. NULL,
  447. &m_hRootKey,
  448. &dwDisposition);
  449. if (lr != ERROR_SUCCESS)
  450. {
  451. if (lr == ERROR_ACCESS_DENIED)
  452. {
  453. lr = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  454. pszKeyPath,
  455. 0,
  456. KEY_READ,
  457. &m_hRootKey);
  458. if (lr == ERROR_SUCCESS)
  459. {
  460. m_bReadOnlyKey = TRUE;
  461. DBG_TRC(("CRegistry::CRegistry, opened key '%ls' for read-access only, "
  462. "probably logged on as a non-admin.", pszKeyPath));
  463. }
  464. else
  465. {
  466. HRESULT hr = E_FAIL;
  467. CHECK_S_OK2(hr, ("CRegistry::CRegistry, failed to open registry path "
  468. "'%ls', lResult = %d", pszKeyPath, lr));
  469. }
  470. }
  471. else
  472. {
  473. HRESULT hr = E_FAIL;
  474. CHECK_S_OK2(hr, ("CRegistry::CRegistry, failed to create registry path "
  475. "'%ls', lResult = %d", pszKeyPath, lr));
  476. }
  477. }
  478. }
  479. ///////////////////////////////
  480. // CRegistry Destructor
  481. //
  482. CRegistry::~CRegistry()
  483. {
  484. if (m_hRootKey)
  485. {
  486. RegCloseKey(m_hRootKey);
  487. m_hRootKey = NULL;
  488. }
  489. }
  490. ///////////////////////////////
  491. // GetDWORD
  492. //
  493. HRESULT CRegistry::GetDWORD(const TCHAR *pszVarName,
  494. DWORD *pdwValue,
  495. BOOL bSetIfNotExist)
  496. {
  497. ASSERT(m_hRootKey != NULL);
  498. ASSERT(pszVarName != NULL);
  499. ASSERT(pdwValue != NULL);
  500. HRESULT hr = S_OK;
  501. LRESULT lr = ERROR_SUCCESS;
  502. DWORD dwType = REG_DWORD;
  503. DWORD dwSize = sizeof(DWORD);
  504. if ((pszVarName == NULL) ||
  505. (pdwValue == NULL))
  506. {
  507. hr = E_POINTER;
  508. CHECK_S_OK2(hr, ("CRegistry::GetDWORD, received NULL param. "));
  509. return hr;
  510. }
  511. else if (m_hRootKey == NULL)
  512. {
  513. hr = E_FAIL;
  514. CHECK_S_OK2(hr, ("CRegistry::GetDWORD, m_hRootKey is NULL"));
  515. return hr;
  516. }
  517. lr = RegQueryValueEx(m_hRootKey,
  518. pszVarName,
  519. NULL,
  520. &dwType,
  521. (BYTE*) pdwValue,
  522. &dwSize);
  523. if (lr != ERROR_SUCCESS)
  524. {
  525. if (bSetIfNotExist)
  526. {
  527. if (!m_bReadOnlyKey)
  528. {
  529. hr = SetDWORD(pszVarName, *pdwValue);
  530. }
  531. else
  532. {
  533. DBG_TRC(("CRegistry::GetDWORD, key is marked read-only, "
  534. "probably logged on as non-admin, cannot set the "
  535. "key. This is not fatal"));
  536. }
  537. }
  538. else
  539. {
  540. hr = E_FAIL;
  541. }
  542. }
  543. return hr;
  544. }
  545. ///////////////////////////////
  546. // SetDWORD
  547. //
  548. HRESULT CRegistry::SetDWORD(const TCHAR *pszVarName,
  549. DWORD dwValue)
  550. {
  551. ASSERT(m_hRootKey != NULL);
  552. ASSERT(pszVarName != NULL);
  553. HRESULT hr = S_OK;
  554. LRESULT lr = ERROR_SUCCESS;
  555. DWORD dwType = REG_DWORD;
  556. if (pszVarName == NULL)
  557. {
  558. hr = E_POINTER;
  559. CHECK_S_OK2(hr, ("CRegistry::SetDWORD, received NULL param. "));
  560. return hr;
  561. }
  562. else if (m_hRootKey == NULL)
  563. {
  564. hr = E_FAIL;
  565. CHECK_S_OK2(hr, ("CRegistry::SetDWORD, m_hRootKey is NULL"));
  566. return hr;
  567. }
  568. lr = RegSetValueEx(m_hRootKey,
  569. pszVarName,
  570. NULL,
  571. REG_DWORD,
  572. (BYTE*) &dwValue,
  573. sizeof(dwValue));
  574. if (lr != ERROR_SUCCESS)
  575. {
  576. hr = E_FAIL;
  577. }
  578. return hr;
  579. }
  580. ///////////////////////////////
  581. // GetString
  582. //
  583. HRESULT CRegistry::GetString(const TCHAR *pszVarName,
  584. TCHAR *pszValue,
  585. DWORD cchValue,
  586. BOOL bSetIfNotExist)
  587. {
  588. ASSERT(m_hRootKey != NULL);
  589. ASSERT(pszVarName != NULL);
  590. ASSERT(pszValue != NULL);
  591. HRESULT hr = S_OK;
  592. LRESULT lr = ERROR_SUCCESS;
  593. DWORD dwType = REG_SZ;
  594. DWORD dwNumBytes = 0;
  595. if ((pszVarName == NULL) ||
  596. (pszValue == NULL))
  597. {
  598. hr = E_POINTER;
  599. CHECK_S_OK2(hr, ("CRegistry::GetString, received NULL param. "));
  600. return hr;
  601. }
  602. else if (m_hRootKey == NULL)
  603. {
  604. hr = E_FAIL;
  605. CHECK_S_OK2(hr, ("CRegistry::GetString, m_hRootKey is NULL"));
  606. return hr;
  607. }
  608. dwNumBytes = cchValue * sizeof(TCHAR) + 1*sizeof(TCHAR);
  609. lr = RegQueryValueEx(m_hRootKey,
  610. pszVarName,
  611. NULL,
  612. &dwType,
  613. (BYTE*) pszValue,
  614. &dwNumBytes);
  615. if (lr != ERROR_SUCCESS)
  616. {
  617. if (bSetIfNotExist)
  618. {
  619. hr = SetString(pszVarName, pszValue);
  620. }
  621. else
  622. {
  623. hr = E_FAIL;
  624. }
  625. }
  626. return hr;
  627. }
  628. ///////////////////////////////
  629. // SetString
  630. //
  631. HRESULT CRegistry::SetString(const TCHAR *pszVarName,
  632. TCHAR *pszValue)
  633. {
  634. ASSERT(m_hRootKey != NULL);
  635. ASSERT(pszVarName != NULL);
  636. ASSERT(pszValue != NULL);
  637. HRESULT hr = S_OK;
  638. LRESULT lr = ERROR_SUCCESS;
  639. DWORD dwSize = 0;
  640. if ((pszVarName == NULL) ||
  641. (pszValue == NULL))
  642. {
  643. hr = E_POINTER;
  644. CHECK_S_OK2(hr, ("CRegistry::SetString, received NULL param. "));
  645. return hr;
  646. }
  647. else if (m_hRootKey == NULL)
  648. {
  649. hr = E_FAIL;
  650. CHECK_S_OK2(hr, ("CRegistry::SetString, m_hRootKey is NULL"));
  651. return hr;
  652. }
  653. dwSize = (_tcslen(pszValue) * sizeof(TCHAR)) + (1 * sizeof(TCHAR));
  654. lr = RegSetValueEx(m_hRootKey,
  655. pszVarName,
  656. NULL,
  657. REG_SZ,
  658. (BYTE*) pszValue,
  659. dwSize);
  660. if (lr != ERROR_SUCCESS)
  661. {
  662. hr = E_FAIL;
  663. }
  664. return hr;
  665. }