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.

727 lines
15 KiB

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