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.

1252 lines
20 KiB

  1. /*++
  2. Copyright (c) 1996-1999 Microsoft Corporation
  3. Module Name:
  4. comoem.cpp
  5. Abstract:
  6. Windows NT Universal Printer Driver OEM Plug-in Sample
  7. Environment:
  8. Windows NT Unidrv driver
  9. Revision History:
  10. Created it.
  11. --*/
  12. #include "pdev.h"
  13. #include "name.h"
  14. #include <initguid.h>
  15. #include <prcomoem.h>
  16. #include "comoem.h"
  17. #include <assert.h>
  18. #include "code.c"
  19. ///////////////////////////////////////////////////////////
  20. //
  21. // Globals
  22. //
  23. static HANDLE ghInstance = NULL ;
  24. static long g_cComponents = 0 ;
  25. static long g_cServerLocks = 0 ;
  26. ///////////////////////////////////////////////////////////
  27. //
  28. // Export functions
  29. //
  30. BOOL APIENTRY
  31. DllMain(
  32. HANDLE hInst,
  33. DWORD dwReason,
  34. void* lpReserved)
  35. /*++
  36. Routine Description:
  37. Dll entry point for initializatoin.
  38. Arguments:
  39. hInst - Dll instance handle
  40. wReason - The reason DllMain was called.
  41. Initialization or termination, for a process or a thread.
  42. lpreserved - Reserved for the system's use
  43. Return Value:
  44. TRUE if successful, FALSE if there is an error
  45. Note:
  46. --*/
  47. {
  48. switch(dwReason)
  49. {
  50. case DLL_PROCESS_ATTACH:
  51. DebugMsg(DLLTEXT("DLLMain: Process attach.\r\n"));
  52. //
  53. // Save DLL instance for use later.
  54. //
  55. ghInstance = hInst;
  56. break;
  57. case DLL_THREAD_ATTACH:
  58. DebugMsg(DLLTEXT("DLLMain: Thread attach.\r\n"));
  59. break;
  60. case DLL_PROCESS_DETACH:
  61. DebugMsg(DLLTEXT("DLLMain: Process detach.\r\n"));
  62. break;
  63. case DLL_THREAD_DETACH:
  64. DebugMsg(DLLTEXT("DLLMain: Thread detach.\r\n"));
  65. break;
  66. }
  67. return TRUE;
  68. }
  69. STDAPI
  70. DllCanUnloadNow()
  71. /*++
  72. Routine Description:
  73. Function to return the status that this dll can be unloaded.
  74. Arguments:
  75. Return Value:
  76. S_OK if it's ok to unload it, S_FALSE if it is used.
  77. Note:
  78. --*/
  79. {
  80. if ((g_cComponents == 0) && (g_cServerLocks == 0))
  81. {
  82. return S_OK ;
  83. }
  84. else
  85. {
  86. return S_FALSE ;
  87. }
  88. }
  89. STDAPI
  90. DllGetClassObject(
  91. const CLSID& clsid,
  92. const IID& iid,
  93. void** ppv)
  94. /*++
  95. Routine Description:
  96. Function to return class factory object
  97. Arguments:
  98. clsid - CLSID for the class object
  99. iid - Reference to the identifier of the interface that communic
  100. ppv - Indirect pointer to the communicating interface
  101. Note:
  102. --*/
  103. {
  104. DebugMsg(DLLTEXT("DllGetClassObject:\tCreate class factory.")) ;
  105. //
  106. // Can we create this component?
  107. //
  108. if (clsid != CLSID_OEMRENDER)
  109. {
  110. return CLASS_E_CLASSNOTAVAILABLE ;
  111. }
  112. //
  113. // Create class factory.
  114. //
  115. IOemCF* pClassFactory = new IOemCF ; // Reference count set to 1
  116. // in constructor
  117. if (pClassFactory == NULL)
  118. {
  119. return E_OUTOFMEMORY ;
  120. }
  121. //
  122. // Get requested interface.
  123. //
  124. HRESULT hr = pClassFactory->QueryInterface(iid, ppv) ;
  125. pClassFactory->Release() ;
  126. return hr ;
  127. }
  128. ////////////////////////////////////////////////////////////////////////////////
  129. //
  130. // Interface Oem CallBack (IPrintOemUNI) body
  131. //
  132. STDMETHODIMP
  133. IOemCB::QueryInterface(
  134. const IID& iid,
  135. void** ppv)
  136. /*++
  137. Routine Description:
  138. IUnknow QueryInterface
  139. Arguments:
  140. iid - Reference to the identifier of the interface that communic
  141. ppv - Indirect pointer to the communicating interface
  142. Note:
  143. --*/
  144. {
  145. DebugMsg(DLLTEXT("IOemCB: QueryInterface entry\n"));
  146. if (iid == IID_IUnknown)
  147. {
  148. *ppv = static_cast<IUnknown*>(this);
  149. DebugMsg(DLLTEXT("IOemCB:Return pointer to IUnknown.\n")) ;
  150. }
  151. else if (iid == IID_IPrintOemUni)
  152. {
  153. *ppv = static_cast<IPrintOemUni*>(this) ;
  154. DebugMsg(DLLTEXT("IOemCB:Return pointer to IPrintOemUni.\n")) ;
  155. }
  156. else
  157. {
  158. *ppv = NULL ;
  159. DebugMsg(DLLTEXT("IOemCB:Return NULL.\n")) ;
  160. return E_NOINTERFACE ;
  161. }
  162. reinterpret_cast<IUnknown*>(*ppv)->AddRef() ;
  163. return S_OK ;
  164. }
  165. STDMETHODIMP_(ULONG)
  166. IOemCB::AddRef()
  167. /*++
  168. Routine Description:
  169. IUnknow AddRef interface
  170. Arguments:
  171. Increment a reference count
  172. Return Value:
  173. Reference count
  174. Note:
  175. --*/
  176. {
  177. DebugMsg(DLLTEXT("IOemCB::AddRef() entry.\r\n"));
  178. return InterlockedIncrement(&m_cRef) ;
  179. }
  180. STDMETHODIMP_(ULONG)
  181. IOemCB::Release()
  182. /*++
  183. Routine Description:
  184. IUnknown Release interface
  185. Arguments:
  186. Decrement a reference count
  187. Return Value:
  188. Reference count
  189. Note:
  190. --*/
  191. {
  192. DebugMsg(DLLTEXT("IOemCB::Release() entry.\r\n"));
  193. if (InterlockedDecrement(&m_cRef) == 0)
  194. {
  195. delete this ;
  196. return 0 ;
  197. }
  198. return m_cRef ;
  199. }
  200. STDMETHODIMP
  201. IOemCB::EnableDriver(
  202. DWORD dwDriverVersion,
  203. DWORD cbSize,
  204. PDRVENABLEDATA pded)
  205. /*++
  206. Routine Description:
  207. Arguments:
  208. Return Value:
  209. Note:
  210. --*/
  211. {
  212. DebugMsg(DLLTEXT("IOemCB::EnableDriver() entry.\r\n"));
  213. return E_NOTIMPL;
  214. }
  215. STDMETHODIMP
  216. IOemCB::DisableDriver(VOID)
  217. /*++
  218. Routine Description:
  219. IPrintOemUni DisableDriver interface
  220. Free all resources, and get prepared to be unloaded.
  221. Arguments:
  222. Return Value:
  223. Note:
  224. --*/
  225. {
  226. DebugMsg(DLLTEXT("IOemCB::DisaleDriver() entry.\r\n"));
  227. return E_NOTIMPL;
  228. }
  229. STDMETHODIMP
  230. IOemCB::PublishDriverInterface(
  231. IUnknown *pIUnknown)
  232. /*++
  233. Routine Description:
  234. IPrintOemUni PublishDriverInterface interface
  235. Arguments:
  236. Return Value:
  237. Note:
  238. --*/
  239. {
  240. DebugMsg(DLLTEXT("IOemCB::PublishDriverInterface() entry.\r\n"));
  241. // Need to store pointer to Driver Helper functions, if we already haven't.
  242. if (this->pOEMHelp == NULL)
  243. {
  244. HRESULT hResult;
  245. // Get Interface to Helper Functions.
  246. hResult = pIUnknown->QueryInterface(IID_IPrintOemDriverUni, (void** ) &(this->pOEMHelp));
  247. if(!SUCCEEDED(hResult))
  248. {
  249. // Make sure that interface pointer reflects interface query failure.
  250. this->pOEMHelp = NULL;
  251. return E_FAIL;
  252. }
  253. }
  254. return S_OK;
  255. }
  256. STDMETHODIMP
  257. IOemCB::EnablePDEV(
  258. PDEVOBJ pdevobj,
  259. PWSTR pPrinterName,
  260. ULONG cPatterns,
  261. HSURF *phsurfPatterns,
  262. ULONG cjGdiInfo,
  263. GDIINFO *pGdiInfo,
  264. ULONG cjDevInfo,
  265. DEVINFO *pDevInfo,
  266. DRVENABLEDATA *pded,
  267. OUT PDEVOEM *pDevOem)
  268. /*++
  269. Routine Description:
  270. IPrintOemUni EnablePDEV interface
  271. Construct its own PDEV. At this time, the driver also passes a function
  272. table which contains its own implementation of DDI entrypoints
  273. Arguments:
  274. pdevobj - pointer to a DEVOBJ structure. pdevobj->pdevOEM is undefined.
  275. pPrinterName - name of the current printer.
  276. Cpatterns -
  277. phsurfPatterns -
  278. cjGdiInfo - size of GDIINFO
  279. pGdiInfo - a pointer to GDIINFO
  280. cjDevInfo - size of DEVINFO
  281. pDevInfo - These parameters are identical to what39s passed into DrvEnablePDEV.
  282. pded: points to a function table which contains the system driver39s
  283. implementation of DDI entrypoints.
  284. Return Value:
  285. --*/
  286. {
  287. DebugMsg(DLLTEXT("IOemCB::EnablePDEV() entry.\r\n"));
  288. return E_NOTIMPL;
  289. }
  290. STDMETHODIMP
  291. IOemCB::ResetPDEV(
  292. PDEVOBJ pdevobjOld,
  293. PDEVOBJ pdevobjNew)
  294. /*++
  295. Routine Description:
  296. IPrintOemUni ResetPDEV interface
  297. OEMResetPDEV transfers the state of the driver from the old PDEVOBJ to the
  298. new PDEVOBJ when an application calls ResetDC.
  299. Arguments:
  300. pdevobjOld - pdevobj containing Old PDEV
  301. pdevobjNew - pdevobj containing New PDEV
  302. Return Value:
  303. Note:
  304. --*/
  305. {
  306. DebugMsg(DLLTEXT("IOemCB::ResetPDEV entry.\r\n"));
  307. return E_NOTIMPL;
  308. }
  309. STDMETHODIMP
  310. IOemCB::DisablePDEV(
  311. PDEVOBJ pdevobj)
  312. /*++
  313. Routine Description:
  314. IPrintOemUni DisablePDEV interface
  315. Free resources allocated for the PDEV.
  316. Arguments:
  317. pdevobj -
  318. Return Value:
  319. Note:
  320. --*/
  321. {
  322. DebugMsg(DLLTEXT("IOemCB::DisablePDEV() entry.\r\n"));
  323. return E_NOTIMPL;
  324. };
  325. STDMETHODIMP
  326. IOemCB::GetInfo (
  327. DWORD dwMode,
  328. PVOID pBuffer,
  329. DWORD cbSize,
  330. PDWORD pcbNeeded)
  331. /*++
  332. Routine Description:
  333. IPrintOemUni GetInfo interface
  334. Arguments:
  335. Return Value:
  336. Note:
  337. --*/
  338. {
  339. LPTSTR OEM_INFO[] = { __TEXT("Bad Index"),
  340. __TEXT("OEMGI_GETSIGNATURE"),
  341. __TEXT("OEMGI_GETINTERFACEVERSION"),
  342. __TEXT("OEMGI_GETVERSION"),
  343. };
  344. DebugMsg(DLLTEXT("IOemCB::GetInfo(%s) entry.\r\n"), OEM_INFO[dwMode]);
  345. //
  346. // Validate parameters.
  347. //
  348. if( ( (OEMGI_GETSIGNATURE != dwMode) &&
  349. (OEMGI_GETINTERFACEVERSION != dwMode) &&
  350. (OEMGI_GETVERSION != dwMode) ) ||
  351. (NULL == pcbNeeded)
  352. )
  353. {
  354. DebugMsg(ERRORTEXT("OEMGetInfo() ERROR_INVALID_PARAMETER.\r\n"));
  355. //
  356. // Did not write any bytes.
  357. //
  358. if(NULL != pcbNeeded)
  359. *pcbNeeded = 0;
  360. return E_FAIL;
  361. }
  362. //
  363. // Need/wrote 4 bytes.
  364. //
  365. *pcbNeeded = 4;
  366. //
  367. // Validate buffer size. Minimum size is four bytes.
  368. //
  369. if( (NULL == pBuffer) || (4 > cbSize) )
  370. {
  371. DebugMsg(ERRORTEXT("OEMGetInfo() ERROR_INSUFFICIENT_BUFFER.\r\n"));
  372. return E_FAIL;
  373. }
  374. //
  375. // Write information to buffer.
  376. //
  377. switch(dwMode)
  378. {
  379. case OEMGI_GETSIGNATURE:
  380. *(LPDWORD)pBuffer = OEM_SIGNATURE;
  381. break;
  382. case OEMGI_GETINTERFACEVERSION:
  383. *(LPDWORD)pBuffer = PRINTER_OEMINTF_VERSION;
  384. break;
  385. case OEMGI_GETVERSION:
  386. *(LPDWORD)pBuffer = OEM_VERSION;
  387. break;
  388. }
  389. return S_OK;
  390. }
  391. STDMETHODIMP
  392. IOemCB::GetImplementedMethod(
  393. PSTR pMethodName)
  394. /*++
  395. Routine Description:
  396. IPrintOemUni GetImplementedMethod interface
  397. Arguments:
  398. Return Value:
  399. Note:
  400. --*/
  401. {
  402. LONG lReturn;
  403. DebugMsg(DLLTEXT("IOemCB::GetImplementedMethod() entry.\r\n"));
  404. DebugMsg(DLLTEXT(" Function:%s:"),pMethodName);
  405. lReturn = FALSE;
  406. if (pMethodName != NULL)
  407. {
  408. switch (*pMethodName)
  409. {
  410. case (WCHAR)'F':
  411. if (!strcmp(pstrFilterGraphics, pMethodName))
  412. lReturn = TRUE;
  413. break;
  414. case (WCHAR)'G':
  415. if (!strcmp(pstrGetInfo, pMethodName))
  416. lReturn = TRUE;
  417. break;
  418. }
  419. }
  420. if (lReturn)
  421. {
  422. DebugMsg(__TEXT("Supported\r\n"));
  423. return S_OK;
  424. }
  425. else
  426. {
  427. DebugMsg(__TEXT("NOT supported\r\n"));
  428. return E_FAIL;
  429. }
  430. }
  431. STDMETHODIMP
  432. IOemCB::DevMode(
  433. DWORD dwMode,
  434. POEMDMPARAM pOemDMParam)
  435. /*++
  436. Routine Description:
  437. IPrintOemUni DevMode interface
  438. Arguments:
  439. Return Value:
  440. Note:
  441. --*/
  442. {
  443. DebugMsg(DLLTEXT("IOemCB::DevMode() entry.\r\n"));
  444. return E_NOTIMPL;
  445. }
  446. STDMETHODIMP
  447. IOemCB::CommandCallback(
  448. PDEVOBJ pdevobj,
  449. DWORD dwCallbackID,
  450. DWORD dwCount,
  451. PDWORD pdwParams,
  452. OUT INT *piResult)
  453. /*++
  454. Routine Description:
  455. IPrintOemUni CommandCallback interface
  456. Arguments:
  457. Return Value:
  458. Note:
  459. --*/
  460. {
  461. DebugMsg(DLLTEXT("IOemCB::CommandCallback() entry.\r\n"));
  462. DebugMsg(DLLTEXT(" dwCallbackID = %d\r\n"), dwCallbackID);
  463. DebugMsg(DLLTEXT(" dwCount = %d\r\n"), dwCount);
  464. return E_NOTIMPL;
  465. }
  466. STDMETHODIMP
  467. IOemCB::ImageProcessing(
  468. PDEVOBJ pdevobj,
  469. PBYTE pSrcBitmap,
  470. PBITMAPINFOHEADER pBitmapInfoHeader,
  471. PBYTE pColorTable,
  472. DWORD dwCallbackID,
  473. PIPPARAMS pIPParams,
  474. OUT PBYTE *ppbResult)
  475. /*++
  476. Routine Description:
  477. IPrintOemUni ImageProcessing interface
  478. Arguments:
  479. Return Value:
  480. Note:
  481. --*/
  482. {
  483. DebugMsg(DLLTEXT("IOemCB::ImageProcessing() entry.\r\n"));
  484. return E_NOTIMPL;
  485. }
  486. STDMETHODIMP
  487. IOemCB::FilterGraphics(
  488. PDEVOBJ pdevobj,
  489. PBYTE pBuf,
  490. DWORD dwLen)
  491. /*++
  492. Routine Description:
  493. IPrintOemUni FilterGraphics interface
  494. Arguments:
  495. Return Value:
  496. Note:
  497. --*/
  498. {
  499. DWORD dwResult;
  500. DebugMsg(DLLTEXT("IOemCB::FilterGraphis() entry.\r\n"));
  501. /*
  502. * Easy to do - translate the input using FlipTable, then call the
  503. * Unidrv function DrvWriteSpoolBuf.
  504. */
  505. BYTE *pb;
  506. DWORD i;
  507. for( pb = pBuf, i = 0; i < dwLen; i++, pb++ )
  508. {
  509. *pb = FlipTable[ *pb ];
  510. }
  511. if(!SUCCEEDED(pOEMHelp->DrvWriteSpoolBuf( pdevobj, pBuf, dwLen, &dwResult )) || dwResult != dwLen)
  512. return E_FAIL;
  513. else
  514. return S_OK;
  515. }
  516. STDMETHODIMP
  517. IOemCB::Compression(
  518. PDEVOBJ pdevobj,
  519. PBYTE pInBuf,
  520. PBYTE pOutBuf,
  521. DWORD dwInLen,
  522. DWORD dwOutLen,
  523. OUT INT *piResult)
  524. /*++
  525. Routine Description:
  526. IPrintOemUni Compression interface
  527. Arguments:
  528. Return Value:
  529. Note:
  530. --*/
  531. {
  532. DebugMsg(DLLTEXT("IOemCB::Compression() entry.\r\n"));
  533. return E_NOTIMPL;
  534. }
  535. STDMETHODIMP
  536. IOemCB::HalftonePattern(
  537. PDEVOBJ pdevobj,
  538. PBYTE pHTPattern,
  539. DWORD dwHTPatternX,
  540. DWORD dwHTPatternY,
  541. DWORD dwHTNumPatterns,
  542. DWORD dwCallbackID,
  543. PBYTE pResource,
  544. DWORD dwResourceSize)
  545. /*++
  546. Routine Description:
  547. IPrintOemUni HalftonePattern interface
  548. Arguments:
  549. Return Value:
  550. Note:
  551. --*/
  552. {
  553. DebugMsg(DLLTEXT("IOemCB::HalftonePattern() entry.\r\n"));
  554. return E_NOTIMPL;
  555. }
  556. STDMETHODIMP
  557. IOemCB::MemoryUsage(
  558. PDEVOBJ pdevobj,
  559. POEMMEMORYUSAGE pMemoryUsage)
  560. /*++
  561. Routine Description:
  562. IPrintOemUni MemoryUsage interface
  563. Arguments:
  564. Return Value:
  565. Note:
  566. --*/
  567. {
  568. DebugMsg(DLLTEXT("IOemCB::MemoryUsage() entry.\r\n"));
  569. return E_NOTIMPL;
  570. }
  571. STDMETHODIMP
  572. IOemCB::DownloadFontHeader(
  573. PDEVOBJ pdevobj,
  574. PUNIFONTOBJ pUFObj,
  575. OUT DWORD *pdwResult)
  576. /*++
  577. Routine Description:
  578. IPrintOemUni DownloadFontHeader interface
  579. Arguments:
  580. Return Value:
  581. Note:
  582. --*/
  583. {
  584. DebugMsg(DLLTEXT("IOemCB::DownloadFontHeader() entry.\r\n"));
  585. return E_NOTIMPL;
  586. }
  587. STDMETHODIMP
  588. IOemCB::DownloadCharGlyph(
  589. PDEVOBJ pdevobj,
  590. PUNIFONTOBJ pUFObj,
  591. HGLYPH hGlyph,
  592. PDWORD pdwWidth,
  593. OUT DWORD *pdwResult)
  594. /*++
  595. Routine Description:
  596. IPrintOemUni DownloadCharGlyph interface
  597. Arguments:
  598. Return Value:
  599. Note:
  600. --*/
  601. {
  602. DebugMsg(DLLTEXT("IOemCB::DownloadCharGlyph() entry.\r\n"));
  603. return E_NOTIMPL;
  604. }
  605. STDMETHODIMP
  606. IOemCB::TTDownloadMethod(
  607. PDEVOBJ pdevobj,
  608. PUNIFONTOBJ pUFObj,
  609. OUT DWORD *pdwResult)
  610. /*++
  611. Routine Description:
  612. IPrintOemUni TTDownloadMethod interface
  613. Arguments:
  614. Return Value:
  615. Note:
  616. --*/
  617. {
  618. DebugMsg(DLLTEXT("IOemCB::TTDownloadMethod() entry.\r\n"));
  619. return E_NOTIMPL;
  620. }
  621. STDMETHODIMP
  622. IOemCB::OutputCharStr(
  623. PDEVOBJ pdevobj,
  624. PUNIFONTOBJ pUFObj,
  625. DWORD dwType,
  626. DWORD dwCount,
  627. PVOID pGlyph)
  628. /*++
  629. Routine Description:
  630. IPrintOemUni OutputCharStr interface
  631. Arguments:
  632. Return Value:
  633. Note:
  634. --*/
  635. {
  636. DebugMsg(DLLTEXT("IOemCB::OutputCharStr() entry.\r\n"));
  637. return E_NOTIMPL;
  638. }
  639. STDMETHODIMP
  640. IOemCB::SendFontCmd(
  641. PDEVOBJ pdevobj,
  642. PUNIFONTOBJ pUFObj,
  643. PFINVOCATION pFInv)
  644. /*++
  645. Routine Description:
  646. IPrintOemUni SendFontCmd interface
  647. Arguments:
  648. Return Value:
  649. Note:
  650. --*/
  651. {
  652. DebugMsg(DLLTEXT("IOemCB::SendFontCmd() entry.\r\n"));
  653. return E_NOTIMPL;
  654. }
  655. STDMETHODIMP
  656. IOemCB::DriverDMS(
  657. PVOID pDevObj,
  658. PVOID pBuffer,
  659. DWORD cbSize,
  660. PDWORD pcbNeeded)
  661. /*++
  662. Routine Description:
  663. IPrintOemUni DriverDMS interface
  664. Arguments:
  665. Return Value:
  666. Note:
  667. --*/
  668. {
  669. DebugMsg(DLLTEXT("IOemCB::DriverDMS() entry.\r\n"));
  670. return E_NOTIMPL;
  671. }
  672. STDMETHODIMP
  673. IOemCB::TextOutAsBitmap(
  674. SURFOBJ *pso,
  675. STROBJ *pstro,
  676. FONTOBJ *pfo,
  677. CLIPOBJ *pco,
  678. RECTL *prclExtra,
  679. RECTL *prclOpaque,
  680. BRUSHOBJ *pboFore,
  681. BRUSHOBJ *pboOpaque,
  682. POINTL *pptlOrg,
  683. MIX mix)
  684. /*++
  685. Routine Description:
  686. IPrintOemUni TextOutAsBitmap interface
  687. Arguments:
  688. Return Value:
  689. Note:
  690. --*/
  691. {
  692. DebugMsg(DLLTEXT("IOemCB::TextOutAsBitmap() entry.\r\n"));
  693. return E_NOTIMPL;
  694. }
  695. STDMETHODIMP
  696. IOemCB::TTYGetInfo(
  697. PDEVOBJ pdevobj,
  698. DWORD dwInfoIndex,
  699. PVOID pOutputBuf,
  700. DWORD dwSize,
  701. DWORD *pcbcNeeded)
  702. /*++
  703. Routine Description:
  704. IPrintOemUni TTYGetInfo interface
  705. Arguments:
  706. Return Value:
  707. Note:
  708. --*/
  709. {
  710. DebugMsg(DLLTEXT("IOemCB::TTYGetInfo() entry.\r\n"));
  711. return E_NOTIMPL;
  712. }
  713. ///////////////////////////////////////////////////////////
  714. //
  715. // Interface Oem Class factory body
  716. //
  717. STDMETHODIMP
  718. IOemCF::QueryInterface(
  719. const IID& iid,
  720. void** ppv)
  721. /*++
  722. Routine Description:
  723. Class Factory QueryInterface interface
  724. Arguments:
  725. Return Value:
  726. Note:
  727. --*/
  728. {
  729. if ((iid == IID_IUnknown) || (iid == IID_IClassFactory))
  730. {
  731. *ppv = static_cast<IOemCF*>(this) ;
  732. }
  733. else
  734. {
  735. *ppv = NULL ;
  736. return E_NOINTERFACE ;
  737. }
  738. reinterpret_cast<IUnknown*>(*ppv)->AddRef() ;
  739. return S_OK ;
  740. }
  741. STDMETHODIMP_(ULONG)
  742. IOemCF::AddRef()
  743. /*++
  744. Routine Description:
  745. IPrintOemUni AddRef interface
  746. Arguments:
  747. Return Value:
  748. Note:
  749. --*/
  750. {
  751. return InterlockedIncrement(&m_cRef) ;
  752. }
  753. STDMETHODIMP_(ULONG)
  754. IOemCF::Release()
  755. /*++
  756. Routine Description:
  757. IPrintOemUni Release interface
  758. Arguments:
  759. Return Value:
  760. Note:
  761. --*/
  762. {
  763. if (InterlockedDecrement(&m_cRef) == 0)
  764. {
  765. delete this ;
  766. return 0 ;
  767. }
  768. return m_cRef ;
  769. }
  770. STDMETHODIMP
  771. IOemCF::CreateInstance(
  772. IUnknown* pUnknownOuter,
  773. const IID& iid,
  774. void** ppv)
  775. /*++
  776. Routine Description:
  777. IPrintOemUni CreateInstance interface
  778. Arguments:
  779. Return Value:
  780. Note:
  781. --*/
  782. {
  783. DebugMsg(DLLTEXT("Class factory:\t\tCreate component.")) ;
  784. //
  785. // Cannot aggregate.
  786. //
  787. if (pUnknownOuter != NULL)
  788. {
  789. return CLASS_E_NOAGGREGATION ;
  790. }
  791. //
  792. // Create component.
  793. //
  794. IOemCB* pOemCB = new IOemCB ;
  795. if (pOemCB == NULL)
  796. {
  797. return E_OUTOFMEMORY ;
  798. }
  799. //
  800. // Get the requested interface.
  801. //
  802. HRESULT hr = pOemCB->QueryInterface(iid, ppv) ;
  803. //
  804. // Release the IUnknown pointer.
  805. // (If QueryInterface failed, component will delete itself.)
  806. //
  807. pOemCB->Release() ;
  808. return hr ;
  809. }
  810. STDMETHODIMP
  811. IOemCF::LockServer(
  812. BOOL bLock)
  813. /*++
  814. Routine Description:
  815. Class Factory LockServer interface
  816. Arguments:
  817. Return Value:
  818. Note:
  819. --*/
  820. {
  821. if (bLock)
  822. {
  823. InterlockedIncrement(&g_cServerLocks) ;
  824. }
  825. else
  826. {
  827. InterlockedDecrement(&g_cServerLocks) ;
  828. }
  829. return S_OK ;
  830. }
  831. IOemCB::~IOemCB()
  832. {
  833. // Make sure that driver's helper function interface is released.
  834. if(NULL != pOEMHelp)
  835. {
  836. pOEMHelp->Release();
  837. pOEMHelp = NULL;
  838. }
  839. // If this instance of the object is being deleted, then the reference
  840. // count should be zero.
  841. assert(0 == m_cRef);
  842. }