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.

626 lines
14 KiB

  1. /*******************************************************************************
  2. *
  3. * (C) COPYRIGHT MICROSOFT CORP., 2002
  4. *
  5. * TITLE: wiascanr.cpp
  6. *
  7. * VERSION: 1.1
  8. *
  9. * DATE: 05 March, 2002
  10. *
  11. * DESCRIPTION:
  12. * Implementation of the WIA Sample scanner class factory and IUNKNOWN interface.
  13. *
  14. *******************************************************************************/
  15. #include "pch.h"
  16. #ifndef INITGUID
  17. #include <initguid.h>
  18. #endif
  19. #if !defined(dllexp)
  20. #define DLLEXPORT __declspec( dllexport )
  21. #endif
  22. HINSTANCE g_hInst; // DLL module instance.
  23. //
  24. // This IID_IStiUSD GUID will eventually be in uuid.lib, at which point it should be removed
  25. // from here.
  26. //
  27. // {0C9BB460-51AC-11D0-90EA-00AA0060F86C}
  28. DEFINE_GUID(IID_IStiUSD, 0x0C9BB460L, 0x51AC, 0x11D0, 0x90, 0xEA, 0x00, 0xAA, 0x00, 0x60, 0xF8, 0x6C);
  29. // {98B3790C-0D93-4f22-ADAF-51A45B33C998}
  30. DEFINE_GUID(CLSID_SampleWIAScannerDevice,0x98b3790c, 0xd93, 0x4f22, 0xad, 0xaf, 0x51, 0xa4, 0x5b, 0x33, 0xc9, 0x98);
  31. /***************************************************************************\
  32. *
  33. * CWIADeviceClassFactory
  34. *
  35. \****************************************************************************/
  36. class CWIADeviceClassFactory : public IClassFactory {
  37. private:
  38. ULONG m_cRef;
  39. public:
  40. STDMETHODIMP QueryInterface(REFIID riid, LPVOID *ppv);
  41. STDMETHODIMP_(ULONG) AddRef(void);
  42. STDMETHODIMP_(ULONG) Release(void);
  43. STDMETHODIMP CreateInstance(IUnknown __RPC_FAR *pUnkOuter,REFIID riid,void __RPC_FAR *__RPC_FAR *ppvObject);
  44. STDMETHODIMP LockServer(BOOL fLock);
  45. CWIADeviceClassFactory();
  46. ~CWIADeviceClassFactory();
  47. };
  48. /**************************************************************************\
  49. * CWIADeviceClassFactory::CWIADeviceClassFactory(void)
  50. *
  51. *
  52. *
  53. * Arguments:
  54. *
  55. * None
  56. *
  57. * Return Value:
  58. *
  59. * None
  60. *
  61. * History:
  62. *
  63. * 03/05/2002 Original Version
  64. *
  65. \**************************************************************************/
  66. CWIADeviceClassFactory::CWIADeviceClassFactory(void)
  67. {
  68. m_cRef = 0;
  69. }
  70. /**************************************************************************\
  71. * CWIADeviceClassFactory::~CWIADeviceClassFactory(void)
  72. *
  73. *
  74. *
  75. * Arguments:
  76. *
  77. * None
  78. *
  79. * Return Value:
  80. *
  81. * None
  82. *
  83. * History:
  84. *
  85. * 03/05/2002 Original Version
  86. *
  87. \**************************************************************************/
  88. CWIADeviceClassFactory::~CWIADeviceClassFactory(void)
  89. {
  90. }
  91. /**************************************************************************\
  92. * CWIADeviceClassFactory::QueryInterface
  93. *
  94. *
  95. *
  96. * Arguments:
  97. *
  98. * riid -
  99. * ppvObject -
  100. *
  101. * Return Value:
  102. *
  103. * Status.
  104. *
  105. * History:
  106. *
  107. * 03/05/2002 Original Version
  108. *
  109. \**************************************************************************/
  110. STDMETHODIMP CWIADeviceClassFactory::QueryInterface(
  111. REFIID riid,
  112. void __RPC_FAR *__RPC_FAR *ppvObject)
  113. {
  114. if (!ppvObject) {
  115. return E_INVALIDARG;
  116. }
  117. *ppvObject = NULL;
  118. if (IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_IClassFactory)) {
  119. *ppvObject = (LPVOID)this;
  120. AddRef();
  121. return NOERROR;
  122. }
  123. return E_NOINTERFACE;
  124. }
  125. /**************************************************************************\
  126. * CWIADeviceClassFactory::AddRef
  127. *
  128. *
  129. *
  130. * Arguments:
  131. *
  132. * None
  133. *
  134. * Return Value:
  135. *
  136. * Status.
  137. *
  138. * History:
  139. *
  140. * 03/05/2002 Original Version
  141. *
  142. \**************************************************************************/
  143. STDMETHODIMP_(ULONG) CWIADeviceClassFactory::AddRef(void)
  144. {
  145. return InterlockedIncrement((LPLONG)&m_cRef);
  146. }
  147. /**************************************************************************\
  148. * CWIADeviceClassFactory::Release
  149. *
  150. *
  151. *
  152. * Arguments:
  153. *
  154. * None
  155. *
  156. * Return Value:
  157. *
  158. * Status.
  159. *
  160. * History:
  161. *
  162. * 03/05/2002 Original Version
  163. *
  164. \**************************************************************************/
  165. STDMETHODIMP_(ULONG) CWIADeviceClassFactory::Release(void)
  166. {
  167. ULONG ulRef = 0;
  168. ulRef = InterlockedDecrement((LPLONG)&m_cRef);
  169. if (!ulRef) {
  170. delete this;
  171. }
  172. return ulRef;
  173. }
  174. /**************************************************************************\
  175. * CWIADeviceClassFactory::CreateInstance
  176. *
  177. *
  178. *
  179. * Arguments:
  180. *
  181. * punkOuter -
  182. * riid, -
  183. * ppvObject -
  184. *
  185. * Return Value:
  186. *
  187. * Status.
  188. *
  189. * History:
  190. *
  191. * 03/05/2002 Original Version
  192. *
  193. \**************************************************************************/
  194. STDMETHODIMP CWIADeviceClassFactory::CreateInstance(
  195. IUnknown __RPC_FAR *punkOuter,
  196. REFIID riid,
  197. void __RPC_FAR *__RPC_FAR *ppvObject)
  198. {
  199. //
  200. // If the caller is not requesting IID_IUnknown or IID_IStiUsd then
  201. // return E_NOINTERFACE, letting the caller know that interface
  202. // is not supported by this COM component.
  203. //
  204. if ((!IsEqualIID(riid, IID_IStiUSD)) && (!IsEqualIID(riid, IID_IUnknown))) {
  205. return E_NOINTERFACE;
  206. }
  207. //
  208. // If the caller is creating for aggregation, only IID_IUnknown can be requested.
  209. //
  210. if ((punkOuter) && (!IsEqualIID(riid, IID_IUnknown))) {
  211. return CLASS_E_NOAGGREGATION;
  212. }
  213. //
  214. // allocate the CWIAScannerDevce object. This is the WIA minidriver object which
  215. // supports the WIA interfaces. If allocation fails for this object, return an
  216. // E_OUTOFMEMORY error to the caller.
  217. //
  218. CWIADevice *pDev = NULL;
  219. pDev = new CWIADevice(punkOuter);
  220. if (!pDev) {
  221. return E_OUTOFMEMORY;
  222. }
  223. //
  224. // If the allocation is successful, call PrivateInitialize(). This function handles
  225. // all internal initializing of the WIA minidriver object. The implementation of this
  226. // function can be found in wiascanr.cpp. If PrivateInitialize fails, then the WIA
  227. // minidriver object must be destroyed and the entire CreateInstance() muct fail.
  228. //
  229. HRESULT hr = pDev->PrivateInitialize();
  230. if (S_OK != hr) {
  231. delete pDev;
  232. pDev = NULL;
  233. return hr;
  234. }
  235. //
  236. // Call the NonDelegating interface methods to handle nonaggregated requests.
  237. // Do not do this if we are aggregated or the private IUknown interface will be lost.
  238. //
  239. hr = pDev->NonDelegatingQueryInterface(riid,ppvObject);
  240. pDev->NonDelegatingRelease();
  241. return hr;
  242. }
  243. /**************************************************************************\
  244. * CWIADeviceClassFactory::LockServer
  245. *
  246. *
  247. *
  248. * Arguments:
  249. *
  250. * None
  251. *
  252. * Return Value:
  253. *
  254. * Status.
  255. *
  256. * History:
  257. *
  258. * 03/05/2002 Original Version
  259. *
  260. \**************************************************************************/
  261. STDMETHODIMP CWIADeviceClassFactory::LockServer(BOOL fLock)
  262. {
  263. if (fLock) {
  264. //
  265. // The class factory is being locked
  266. //
  267. } else {
  268. //
  269. // The class factory is being unlocked
  270. //
  271. }
  272. return S_OK;
  273. }
  274. /**************************************************************************\
  275. * CWIADevice::NonDelegatingQueryInterface
  276. *
  277. *
  278. *
  279. * Arguments:
  280. *
  281. * None
  282. *
  283. * Return Value:
  284. *
  285. * Status.
  286. *
  287. * History:
  288. *
  289. * 03/05/2002 Original Version
  290. *
  291. \**************************************************************************/
  292. STDMETHODIMP CWIADevice::NonDelegatingQueryInterface(
  293. REFIID riid,
  294. LPVOID *ppvObj)
  295. {
  296. if (!ppvObj) {
  297. return E_INVALIDARG;
  298. }
  299. *ppvObj = NULL;
  300. //
  301. // If the caller is asking for any interfaces supported by this WIA
  302. // minidriver, IID_IUnknown, IID_IStiUSD, or IID_WiaMiniDrv statis_cast
  303. // the "this" pointer to the requested interface.
  304. //
  305. if (IsEqualIID( riid, IID_IUnknown )) {
  306. *ppvObj = static_cast<INonDelegatingUnknown*>(this);
  307. } else if (IsEqualIID( riid, IID_IStiUSD )) {
  308. *ppvObj = static_cast<IStiUSD*>(this);
  309. } else if (IsEqualIID( riid, IID_IWiaMiniDrv )) {
  310. *ppvObj = static_cast<IWiaMiniDrv*>(this);
  311. } else {
  312. return STIERR_NOINTERFACE;
  313. }
  314. (reinterpret_cast<IUnknown*>(*ppvObj))->AddRef();
  315. return S_OK;
  316. }
  317. /**************************************************************************\
  318. * CWIADevice::NonDelegatingAddRef
  319. *
  320. *
  321. *
  322. * Arguments:
  323. *
  324. * None
  325. *
  326. * Return Value:
  327. *
  328. * Object reference count.
  329. *
  330. * History:
  331. *
  332. * 03/05/2002 Original Version
  333. *
  334. \**************************************************************************/
  335. STDMETHODIMP_(ULONG) CWIADevice::NonDelegatingAddRef(void)
  336. {
  337. return InterlockedIncrement((LPLONG)&m_cRef);
  338. }
  339. /**************************************************************************\
  340. * CWIADevice::NonDelegatingRelease
  341. *
  342. *
  343. *
  344. * Arguments:
  345. *
  346. * None
  347. *
  348. * Return Value:
  349. *
  350. * Object reference count.
  351. *
  352. * History:
  353. *
  354. * 03/05/2002 Original Version
  355. *
  356. \**************************************************************************/
  357. STDMETHODIMP_(ULONG) CWIADevice::NonDelegatingRelease(void)
  358. {
  359. ULONG ulRef = InterlockedDecrement((LPLONG)&m_cRef);
  360. if (!ulRef) {
  361. delete this;
  362. }
  363. return ulRef;
  364. }
  365. /**************************************************************************\
  366. * CWIADevice::QueryInterface
  367. *
  368. *
  369. *
  370. * Arguments:
  371. *
  372. * None
  373. *
  374. * Return Value:
  375. *
  376. * Status.
  377. *
  378. * History:
  379. *
  380. * 03/05/2002 Original Version
  381. *
  382. \**************************************************************************/
  383. STDMETHODIMP CWIADevice::QueryInterface(REFIID riid, LPVOID* ppvObj)
  384. {
  385. if(!m_punkOuter){
  386. return E_NOINTERFACE;
  387. }
  388. return m_punkOuter->QueryInterface(riid,ppvObj);
  389. }
  390. /**************************************************************************\
  391. * CWIADevice::AddRef
  392. *
  393. *
  394. *
  395. * Arguments:
  396. *
  397. * None
  398. *
  399. * Return Value:
  400. *
  401. * Status.
  402. *
  403. * History:
  404. *
  405. * 03/05/2002 Original Version
  406. *
  407. \**************************************************************************/
  408. STDMETHODIMP_(ULONG) CWIADevice::AddRef(void)
  409. {
  410. if(!m_punkOuter){
  411. return 0;
  412. }
  413. return m_punkOuter->AddRef();
  414. }
  415. /**************************************************************************\
  416. * CWIADevice::Release
  417. *
  418. *
  419. *
  420. * Arguments:
  421. *
  422. * None
  423. *
  424. * Return Value:
  425. *
  426. * Status.
  427. *
  428. * History:
  429. *
  430. * 03/05/2002 Original Version
  431. *
  432. \**************************************************************************/
  433. STDMETHODIMP_(ULONG) CWIADevice::Release(void)
  434. {
  435. if(!m_punkOuter){
  436. return 0;
  437. }
  438. return m_punkOuter->Release();
  439. }
  440. /**************************************************************************\
  441. * DllEntryPoint
  442. *
  443. * Main library entry point. Receives DLL event notification from OS.
  444. *
  445. * We are not interested in thread attaches and detaches,
  446. * so we disable thread notifications for performance reasons.
  447. *
  448. * Arguments:
  449. *
  450. * hinst -
  451. * dwReason -
  452. * lpReserved -
  453. *
  454. * Return Value:
  455. *
  456. * Returns TRUE to allow the DLL to load.
  457. *
  458. * History:
  459. *
  460. * 03/05/2002 Original Version
  461. *
  462. \**************************************************************************/
  463. extern "C" DLLEXPORT BOOL APIENTRY DllEntryPoint(
  464. HINSTANCE hinst,
  465. DWORD dwReason,
  466. LPVOID lpReserved)
  467. {
  468. switch (dwReason) {
  469. case DLL_PROCESS_ATTACH:
  470. g_hInst = hinst;
  471. DisableThreadLibraryCalls(hinst);
  472. break;
  473. case DLL_PROCESS_DETACH:
  474. break;
  475. }
  476. return TRUE;
  477. }
  478. /**************************************************************************\
  479. * DllCanUnloadNow
  480. *
  481. * Determines whether the DLL has any outstanding interfaces.
  482. *
  483. * Arguments:
  484. *
  485. * None
  486. *
  487. * Return Value:
  488. *
  489. * Returns S_OK if the DLL can unload, S_FALSE if it is not safe to unload.
  490. *
  491. * History:
  492. *
  493. * 03/05/2002 Original Version
  494. *
  495. \**************************************************************************/
  496. extern "C" STDMETHODIMP DllCanUnloadNow(void)
  497. {
  498. return S_OK;
  499. }
  500. /**************************************************************************\
  501. * DllGetClassObject
  502. *
  503. * Retrieves the class object from a DLL object handler or object
  504. * application.
  505. *
  506. * Arguments:
  507. *
  508. * rclsid - The object being requested.
  509. * riid - The desired interface on the object.
  510. * ppv - Output pointer to object.
  511. *
  512. * Return Value:
  513. *
  514. * Status.
  515. *
  516. * History:
  517. *
  518. * 03/05/2002 Original Version
  519. *
  520. \**************************************************************************/
  521. extern "C" STDAPI DllGetClassObject(
  522. REFCLSID rclsid,
  523. REFIID riid,
  524. LPVOID *ppv)
  525. {
  526. if (!ppv) {
  527. return E_INVALIDARG;
  528. }
  529. //
  530. // If the caller is not requesting the proper WIA minidriver class
  531. // then fail the call with CLASS_E_CLASSNOTAVAILABLE.
  532. //
  533. if (!IsEqualCLSID(rclsid, CLSID_SampleWIAScannerDevice) ) {
  534. return CLASS_E_CLASSNOTAVAILABLE;
  535. }
  536. //
  537. // If the caller is not requesting IID_IUnknown or IID_IClassFactory
  538. // then fail the call with E_NOINTERFACE;
  539. //
  540. if ((!IsEqualIID(riid, IID_IUnknown)) && (!IsEqualIID(riid, IID_IClassFactory))) {
  541. return E_NOINTERFACE;
  542. }
  543. //
  544. // Allocate the WIA minidriver class factory that belongs to the WIA minidriver
  545. // COM object.
  546. //
  547. if (IsEqualCLSID(rclsid, CLSID_SampleWIAScannerDevice)) {
  548. CWIADeviceClassFactory *pcf = new CWIADeviceClassFactory;
  549. if (!pcf) {
  550. return E_OUTOFMEMORY;
  551. }
  552. *ppv = (LPVOID)pcf;
  553. }
  554. return S_OK;
  555. }