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.

730 lines
14 KiB

  1. //------------------------------------------------------------------------------
  2. //
  3. // Copyright (C) Microsoft Corporation, 1999
  4. //
  5. // TITLE: ircamera.cpp
  6. //
  7. // VERSION: 1.0
  8. //
  9. // AUTHOR:
  10. //
  11. // EdwardR 22/Jul/99 Original coding.
  12. //
  13. // DESCRIPTION:
  14. //
  15. // Implementation of the WIA IrTran-P USD.
  16. //
  17. //------------------------------------------------------------------------------
  18. #define INITGUID
  19. #include "ircamera.h"
  20. #include "resource.h"
  21. #include "wiamindr_i.c"
  22. #if !defined(dllexp)
  23. #define DLLEXPORT __declspec( dllexport )
  24. #endif
  25. /*****************************************************************************
  26. *
  27. * Globals
  28. *
  29. *****************************************************************************/
  30. DWORD g_cRef; // USD reference counter.
  31. HINSTANCE g_hInst; // DLL module instance.
  32. CRITICAL_SECTION g_csCOM; // COM initialize syncronization.
  33. // Can we use UNICODE APIs
  34. //BOOL g_NoUnicodePlatform = TRUE;
  35. // Is COM initialized
  36. BOOL g_COMInitialized = FALSE;
  37. // Debugging interface, has IrUsdClassFactory lifetime.
  38. WIA_DECLARE_DEBUGGER();
  39. /**************************************************************************\
  40. * DllAddRef
  41. *
  42. *
  43. *
  44. * Arguments:
  45. *
  46. * None
  47. *
  48. * Return Value:
  49. *
  50. * Status.
  51. *
  52. * History:
  53. *
  54. * 9/11/1998 Original Version
  55. *
  56. \**************************************************************************/
  57. void DllAddRef(void)
  58. {
  59. InterlockedIncrement((LPLONG)&g_cRef);
  60. }
  61. /**************************************************************************\
  62. * DllRelease
  63. *
  64. *
  65. *
  66. * Arguments:
  67. *
  68. * None
  69. *
  70. * Return Value:
  71. *
  72. * Status.
  73. *
  74. * History:
  75. *
  76. * 9/11/1998 Original Version
  77. *
  78. \**************************************************************************/
  79. void DllRelease(void)
  80. {
  81. InterlockedDecrement((LPLONG)&g_cRef);
  82. }
  83. /**************************************************************************\
  84. * DllInitializeCOM
  85. *
  86. *
  87. *
  88. * Arguments:
  89. *
  90. * None
  91. *
  92. * Return Value:
  93. *
  94. * Status.
  95. *
  96. * History:
  97. *
  98. * 9/11/1998 Original Version
  99. *
  100. \**************************************************************************/
  101. BOOL DllInitializeCOM(void)
  102. {
  103. EnterCriticalSection(&g_csCOM);
  104. if (!g_COMInitialized) {
  105. if(SUCCEEDED(CoInitialize(NULL))) {
  106. g_COMInitialized = TRUE;
  107. }
  108. }
  109. LeaveCriticalSection(&g_csCOM);
  110. return g_COMInitialized;
  111. }
  112. /**************************************************************************\
  113. * DllUnInitializeCOM
  114. *
  115. *
  116. *
  117. * Arguments:
  118. *
  119. * None
  120. *
  121. * Return Value:
  122. *
  123. * Status.
  124. *
  125. * History:
  126. *
  127. * 9/11/1998 Original Version
  128. *
  129. \**************************************************************************/
  130. BOOL DllUnInitializeCOM(void)
  131. {
  132. EnterCriticalSection(&g_csCOM);
  133. if(g_COMInitialized) {
  134. CoUninitialize();
  135. g_COMInitialized = FALSE;
  136. }
  137. LeaveCriticalSection(&g_csCOM);
  138. return TRUE;
  139. }
  140. /***************************************************************************\
  141. *
  142. * IrUsdClassFactory
  143. *
  144. \****************************************************************************/
  145. class IrUsdClassFactory : public IClassFactory
  146. {
  147. private:
  148. ULONG m_cRef;
  149. public:
  150. STDMETHODIMP QueryInterface(REFIID riid, LPVOID *ppv);
  151. STDMETHODIMP_(ULONG) AddRef(void);
  152. STDMETHODIMP_(ULONG) Release(void);
  153. STDMETHODIMP CreateInstance(
  154. /* [unique][in] */ IUnknown __RPC_FAR *pUnkOuter,
  155. /* [in] */ REFIID riid,
  156. /* [out] */ void __RPC_FAR *__RPC_FAR *ppvObject);
  157. STDMETHODIMP LockServer(
  158. /* [in] */ BOOL fLock);
  159. IrUsdClassFactory();
  160. ~IrUsdClassFactory();
  161. };
  162. /**************************************************************************\
  163. * IrUsdClassFactory::IrUsdClassFactory(void)
  164. *
  165. *
  166. *
  167. * Arguments:
  168. *
  169. * None
  170. *
  171. * Return Value:
  172. *
  173. * None
  174. *
  175. * History:
  176. *
  177. * 9/11/1998 Original Version
  178. *
  179. \**************************************************************************/
  180. IrUsdClassFactory::IrUsdClassFactory(void)
  181. {
  182. // Constructor logic
  183. m_cRef = 0;
  184. WIAS_TRACE((g_hInst,"Creating IrUsdClassFactory"));
  185. }
  186. /**************************************************************************\
  187. * IrUsdClassFactory::~IrUsdClassFactory(void)
  188. *
  189. *
  190. *
  191. * Arguments:
  192. *
  193. * None
  194. *
  195. * Return Value:
  196. *
  197. * None
  198. *
  199. * History:
  200. *
  201. * 9/11/1998 Original Version
  202. *
  203. \**************************************************************************/
  204. IrUsdClassFactory::~IrUsdClassFactory(void)
  205. {
  206. // Destructor logic
  207. WIAS_TRACE((g_hInst,"Destroying IrUsdClassFactory"));
  208. }
  209. /**************************************************************************\
  210. * IrUsdClassFactory::QueryInterface
  211. *
  212. *
  213. *
  214. * Arguments:
  215. *
  216. * riid -
  217. * ppvObject -
  218. *
  219. * Return Value:
  220. *
  221. * Status.
  222. *
  223. * History:
  224. *
  225. * 9/11/1998 Original Version
  226. *
  227. \**************************************************************************/
  228. STDMETHODIMP IrUsdClassFactory::QueryInterface(
  229. REFIID riid,
  230. void __RPC_FAR *__RPC_FAR *ppvObject)
  231. {
  232. *ppvObject = NULL;
  233. if (IsEqualIID(riid, IID_IUnknown) ||
  234. IsEqualIID(riid, IID_IClassFactory)) {
  235. *ppvObject = (LPVOID)this;
  236. AddRef();
  237. return NOERROR;
  238. }
  239. return ResultFromScode(E_NOINTERFACE);
  240. }
  241. /**************************************************************************\
  242. * IrUsdClassFactory::AddRef
  243. *
  244. *
  245. *
  246. * Arguments:
  247. *
  248. * None
  249. *
  250. * Return Value:
  251. *
  252. * Status.
  253. *
  254. * History:
  255. *
  256. * 9/11/1998 Original Version
  257. *
  258. \**************************************************************************/
  259. STDMETHODIMP_(ULONG) IrUsdClassFactory::AddRef(void)
  260. {
  261. DllAddRef();
  262. return ++m_cRef;
  263. }
  264. /**************************************************************************\
  265. * IrUsdClassFactory::Release
  266. *
  267. *
  268. *
  269. * Arguments:
  270. *
  271. * None
  272. *
  273. * Return Value:
  274. *
  275. * Status.
  276. *
  277. * History:
  278. *
  279. * 9/11/1998 Original Version
  280. *
  281. \**************************************************************************/
  282. STDMETHODIMP_(ULONG) IrUsdClassFactory::Release(void)
  283. {
  284. DllRelease();
  285. if (--m_cRef == 0) {
  286. delete this;
  287. return 0;
  288. }
  289. return m_cRef;
  290. }
  291. /**************************************************************************\
  292. * IrUsdClassFactory::CreateInstance
  293. *
  294. *
  295. *
  296. * Arguments:
  297. *
  298. * punkOuter -
  299. * riid, -
  300. * ppvObject -
  301. *
  302. * Return Value:
  303. *
  304. * Status.
  305. *
  306. * History:
  307. *
  308. * 9/11/1998 Original Version
  309. *
  310. \**************************************************************************/
  311. STDMETHODIMP IrUsdClassFactory::CreateInstance(
  312. IUnknown __RPC_FAR *punkOuter,
  313. REFIID riid,
  314. void __RPC_FAR *__RPC_FAR *ppvObject)
  315. {
  316. if (!IsEqualIID(riid, IID_IStiUSD) &&
  317. !IsEqualIID(riid, IID_IWiaItem) &&
  318. !IsEqualIID(riid, IID_IUnknown)) {
  319. return STIERR_NOINTERFACE;
  320. }
  321. // When created for aggregation, only IUnknown can be requested.
  322. if (punkOuter && !IsEqualIID(riid, IID_IUnknown)) {
  323. return CLASS_E_NOAGGREGATION;
  324. }
  325. IrUsdDevice *pDev = NULL;
  326. HRESULT hres;
  327. pDev = new IrUsdDevice(punkOuter);
  328. if (!pDev) {
  329. return STIERR_OUTOFMEMORY;
  330. }
  331. hres = pDev->PrivateInitialize();
  332. if(hres != S_OK) {
  333. delete pDev;
  334. return hres;
  335. }
  336. // Move to the requested interface if we aren't aggregated.
  337. // Don't do this if aggregated, or we will lose the private
  338. // IUnknown and then the caller will be hosed.
  339. hres = pDev->NonDelegatingQueryInterface(riid,ppvObject);
  340. pDev->NonDelegatingRelease();
  341. return hres;
  342. }
  343. /**************************************************************************\
  344. * IrUsdClassFactory::LockServer
  345. *
  346. *
  347. *
  348. * Arguments:
  349. *
  350. * None
  351. *
  352. * Return Value:
  353. *
  354. * Status.
  355. *
  356. * History:
  357. *
  358. * 9/11/1998 Original Version
  359. *
  360. \**************************************************************************/
  361. STDMETHODIMP IrUsdClassFactory::LockServer(BOOL fLock)
  362. {
  363. if (fLock) {
  364. DllAddRef();
  365. } else {
  366. DllRelease();
  367. }
  368. return NOERROR;
  369. }
  370. /**************************************************************************\
  371. * IrUsdDevice::NonDelegatingQueryInterface
  372. *
  373. *
  374. *
  375. * Arguments:
  376. *
  377. * None
  378. *
  379. * Return Value:
  380. *
  381. * Status.
  382. *
  383. * History:
  384. *
  385. * 9/11/1998 Original Version
  386. *
  387. \**************************************************************************/
  388. STDMETHODIMP IrUsdDevice::NonDelegatingQueryInterface(
  389. REFIID riid,
  390. LPVOID *ppvObj)
  391. {
  392. HRESULT hres = S_OK;
  393. if (!IsValid() || !ppvObj) {
  394. return STIERR_INVALID_PARAM;
  395. }
  396. *ppvObj = NULL;
  397. if (IsEqualIID( riid, IID_IUnknown )) {
  398. *ppvObj = static_cast<INonDelegatingUnknown*>(this);
  399. }
  400. else if (IsEqualIID( riid, IID_IStiUSD )) {
  401. *ppvObj = static_cast<IStiUSD*>(this);
  402. }
  403. else if (IsEqualIID( riid, IID_IWiaMiniDrv )) {
  404. *ppvObj = static_cast<IWiaMiniDrv*>(this);
  405. }
  406. else {
  407. hres = STIERR_NOINTERFACE;
  408. }
  409. if (SUCCEEDED(hres)) {
  410. (reinterpret_cast<IUnknown*>(*ppvObj))->AddRef();
  411. }
  412. return hres;
  413. }
  414. /**************************************************************************\
  415. * IrUsdDevice::NonDelegatingAddRef
  416. *
  417. *
  418. *
  419. * Arguments:
  420. *
  421. * None
  422. *
  423. * Return Value:
  424. *
  425. * Object reference count.
  426. *
  427. * History:
  428. *
  429. * 9/11/1998 Original Version
  430. *
  431. \**************************************************************************/
  432. STDMETHODIMP_(ULONG) IrUsdDevice::NonDelegatingAddRef(void)
  433. {
  434. return InterlockedIncrement((LPLONG)&m_cRef);
  435. }
  436. /**************************************************************************\
  437. * IrUsdDevice::NonDelegatingRelease
  438. *
  439. *
  440. *
  441. * Arguments:
  442. *
  443. * None
  444. *
  445. * Return Value:
  446. *
  447. * Object reference count.
  448. *
  449. * History:
  450. *
  451. * 9/11/1998 Original Version
  452. *
  453. \**************************************************************************/
  454. STDMETHODIMP_(ULONG) IrUsdDevice::NonDelegatingRelease(void)
  455. {
  456. ULONG ulRef;
  457. ulRef = InterlockedDecrement((LPLONG)&m_cRef);
  458. if (!ulRef) {
  459. delete this;
  460. }
  461. return ulRef;
  462. }
  463. /**************************************************************************\
  464. * IrUsdDevice::QueryInterface
  465. *
  466. *
  467. *
  468. * Arguments:
  469. *
  470. * None
  471. *
  472. * Return Value:
  473. *
  474. * Status.
  475. *
  476. * History:
  477. *
  478. * 9/11/1998 Original Version
  479. *
  480. \**************************************************************************/
  481. STDMETHODIMP IrUsdDevice::QueryInterface(REFIID riid, LPVOID *ppvObj)
  482. {
  483. return m_punkOuter->QueryInterface(riid,ppvObj);
  484. }
  485. /**************************************************************************\
  486. * IrUsdDevice::AddRef
  487. *
  488. *
  489. *
  490. * Arguments:
  491. *
  492. * None
  493. *
  494. * Return Value:
  495. *
  496. * Status.
  497. *
  498. * History:
  499. *
  500. * 9/11/1998 Original Version
  501. *
  502. \**************************************************************************/
  503. STDMETHODIMP_(ULONG) IrUsdDevice::AddRef(void)
  504. {
  505. return m_punkOuter->AddRef();
  506. }
  507. /**************************************************************************\
  508. * IrUsdDevice::Release
  509. *
  510. *
  511. *
  512. * Arguments:
  513. *
  514. * None
  515. *
  516. * Return Value:
  517. *
  518. * Status.
  519. *
  520. * History:
  521. *
  522. * 9/11/1998 Original Version
  523. *
  524. \**************************************************************************/
  525. STDMETHODIMP_(ULONG) IrUsdDevice::Release(void)
  526. {
  527. return m_punkOuter->Release();
  528. }
  529. /**************************************************************************\
  530. * DllEntryPoint
  531. *
  532. * Main library entry point. Receives DLL event notification from OS.
  533. *
  534. * We are not interested in thread attaches and detaches,
  535. * so we disable thread notifications for performance reasons.
  536. *
  537. * Arguments:
  538. *
  539. * hinst -
  540. * dwReason -
  541. * lpReserved -
  542. *
  543. * Return Value:
  544. *
  545. * Returns TRUE to allow the DLL to load.
  546. *
  547. * History:
  548. *
  549. * 9/11/1998 Original Version
  550. *
  551. \**************************************************************************/
  552. extern "C"
  553. BOOL APIENTRY
  554. DllEntryPoint(
  555. HINSTANCE hinst,
  556. DWORD dwReason,
  557. LPVOID lpReserved)
  558. {
  559. switch (dwReason) {
  560. case DLL_PROCESS_ATTACH:
  561. g_hInst = hinst;
  562. DisableThreadLibraryCalls(hinst);
  563. __try {
  564. if(!InitializeCriticalSectionAndSpinCount(&g_csCOM, MINLONG)) {
  565. return FALSE;
  566. }
  567. }
  568. __except(EXCEPTION_EXECUTE_HANDLER) {
  569. return FALSE;
  570. }
  571. break;
  572. case DLL_PROCESS_DETACH:
  573. if (g_cRef) {
  574. OutputDebugStringA("IrUsd: Unloaded before all objects releaseed!\n");
  575. }
  576. DeleteCriticalSection(&g_csCOM);
  577. break;
  578. }
  579. return TRUE;
  580. }
  581. /**************************************************************************\
  582. * DllCanUnloadNow
  583. *
  584. * Determines whether the DLL has any outstanding interfaces.
  585. *
  586. * Arguments:
  587. *
  588. * None
  589. *
  590. * Return Value:
  591. *
  592. * Returns S_OK if the DLL can unload, S_FALSE if it is not safe to unload.
  593. *
  594. * History:
  595. *
  596. * 9/11/1998 Original Version
  597. *
  598. \**************************************************************************/
  599. extern "C" STDMETHODIMP DllCanUnloadNow(void)
  600. {
  601. return g_cRef ? S_FALSE : S_OK;
  602. }
  603. /**************************************************************************\
  604. * DllGetClassObject
  605. *
  606. * Create an IClassFactory instance for this DLL. We support only one
  607. * class of objects, so this function does not need to go through a table
  608. * of supported classes, looking for the proper constructor.
  609. *
  610. * Arguments:
  611. *
  612. * rclsid - The object being requested.
  613. * riid - The desired interface on the object.
  614. * ppv - Output pointer to object.
  615. *
  616. * Return Value:
  617. *
  618. * Status.
  619. *
  620. * History:
  621. *
  622. * 9/11/1998 Original Version
  623. *
  624. \**************************************************************************/
  625. extern "C" STDAPI DllGetClassObject(
  626. REFCLSID rclsid,
  627. REFIID riid,
  628. LPVOID *ppv)
  629. {
  630. if (!ppv) {
  631. return ResultFromScode(E_FAIL);
  632. }
  633. if (!IsEqualCLSID(rclsid, CLSID_IrUsd) ) {
  634. return ResultFromScode(E_FAIL);
  635. }
  636. if (!IsEqualIID(riid, IID_IUnknown) &&
  637. !IsEqualIID(riid, IID_IClassFactory)) {
  638. return ResultFromScode(E_NOINTERFACE);
  639. }
  640. if (IsEqualCLSID(rclsid, CLSID_IrUsd)) {
  641. IrUsdClassFactory *pcf = new IrUsdClassFactory;
  642. if (pcf) {
  643. *ppv = (LPVOID)pcf;
  644. }
  645. }
  646. return NOERROR;
  647. }