home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / com / tutsamp / licserve / factory.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1997-08-30  |  38.1 KB  |  1,145 lines

  1. /*+==========================================================================
  2.   File:      FACTORY.CPP
  3.  
  4.   Summary:   Implementation file for the Class Factories of the LICSERVE
  5.              server.  This server provides a licensed factory for the
  6.              LicCruiseCar COM component. Thus this COM object factory
  7.              implements IClassFactory2. In addition, a non-licensed
  8.              CFLicCarSample class factory is included to provide a
  9.              component with the Code Sample utility interface ISample.
  10.              This interface is primarily for use within the code samples
  11.              for the purposes of setting them up as samples (eg, setting
  12.              up the server so that it trace logs to the client's trace log
  13.              facility).  The COM Components that can be manufactured by
  14.              this server are known outside the server by their respective
  15.              CLSIDs: CLSID_LicCruiseCar and CLSID_LicCarSample.
  16.  
  17.              For a comprehensive tutorial code tour of this module's
  18.              contents and offerings see the tutorial LICSERVE.HTM file.
  19.              For more specific technical details on the internal workings
  20.              see the comments dispersed throughout the module's source code.
  21.  
  22.   Classes:   CFLicCruiseCar, CFLicCarSample.
  23.  
  24.   Functions: .
  25.  
  26.   Origin:    10-5-95: atrent - Editor-inheritance from FACTORY.CPP in
  27.                the DLLSERVE Tutorial Code Sample.
  28.  
  29. ----------------------------------------------------------------------------
  30.   This file is part of the Microsoft COM Tutorial Code Samples.
  31.  
  32.   Copyright (C) Microsoft Corporation, 1997.  All rights reserved.
  33.  
  34.   This source code is intended only as a supplement to Microsoft
  35.   Development Tools and/or on-line documentation.  See these other
  36.   materials for detailed information regarding Microsoft code samples.
  37.  
  38.   THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
  39.   KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  40.   IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
  41.   PARTICULAR PURPOSE.
  42. ==========================================================================+*/
  43.  
  44. /*---------------------------------------------------------------------------
  45.   We include WINDOWS.H for all Win32 applications.
  46.   We include OLE2.H because we will be calling the COM/OLE Libraries
  47.     in future exploitation of this DLL skeleton.
  48.   We include OLECTL.H because we will be using IClassFactory2.
  49.   We include APPUTIL.H because we will be building this DLL using
  50.     the convenient Virtual Window and Dialog classes and other
  51.     utility functions in the APPUTIL Library (ie, APPUTIL.LIB).
  52.   We include ICARS.H and CARGUIDS.H for the common car-related Interface
  53.     class, GUID, and CLSID specifications.
  54.   We include SERVER.H because it has the necessary internal class and
  55.     resource definitions for this DLL.
  56.   We include FACTORY.H because it has the necessary internal class factory
  57.     declarations for this DLL component server.  Those factories we will be
  58.     implementing in this module.
  59.   We include CRUCAR.H for the object class declarations for the
  60.     COLicCruiseCar COM object.
  61.   We include SAMPLE.H for the utility Sample class COLicCarSample.
  62. ---------------------------------------------------------------------------*/
  63. #include <windows.h>
  64. #include <ole2.h>
  65. #include <olectl.h>
  66. #include <apputil.h>
  67. #include <icars.h>
  68. #include <carguids.h>
  69. #include "server.h"
  70. #include "factory.h"
  71. #include "crucar.h"
  72. #include "sample.h"
  73.  
  74.  
  75. /*---------------------------------------------------------------------------
  76.   Implementation the CFLicCruiseCar Class Factory.  CFLicCruiseCar is the
  77.   COM object class for the Class Factory that can manufacture
  78.   COLicCruiseCar COM Components.  As part of the LICSERVE code sample
  79.   CFLicCruiseCar implements the IClassFactory2 interface to provide
  80.   licensing services.
  81. ---------------------------------------------------------------------------*/
  82.  
  83. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  84.   Method:   CFLicCruiseCar::CFLicCruiseCar
  85.  
  86.   Summary:  CFLicCruiseCar Constructor. Note the member initializer:
  87.             "m_ImpIClassFactory(this, pUnkOuter, pServer)" which is used
  88.             to pass the 'this', pUnkOuter, and pServer pointers of this
  89.             constructor function to the constructor executed in the
  90.             instantiation of the CImpIClassFactory interface whose
  91.             implementation is nested inside this present object class.
  92.  
  93.   Args:     IUnknown* pUnkOuter,
  94.               Pointer to the the outer Unknown.  NULL means this COM Object
  95.               is not being Aggregated.  Non NULL means it is being created
  96.               on behalf of an outside COM object that is reusing it via
  97.               aggregation.
  98.             CServer* pServer)
  99.               Pointer to the server's control object.
  100.  
  101.   Modifies: m_cRefs, m_pUnkOuter, m_pServer.
  102.  
  103.   Returns:  void
  104. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  105. CFLicCruiseCar::CFLicCruiseCar(
  106.   IUnknown* pUnkOuter,
  107.   CServer* pServer) :
  108.   m_ImpIClassFactory(this, pUnkOuter, pServer)
  109. {
  110.   // Zero the COM object's reference count.
  111.   m_cRefs = 0;
  112.  
  113.   // No AddRef necessary if non-NULL, as we're nested.
  114.   m_pUnkOuter = pUnkOuter;
  115.  
  116.   // Init the pointer to the server control object.
  117.   m_pServer = pServer;
  118.  
  119.   LOGF1("P: CFLicCruiseCar Constructor. m_pUnkOuter=0x%X.", m_pUnkOuter);
  120.  
  121.   return;
  122. }
  123.  
  124.  
  125. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  126.   Method:   CFLicCruiseCar::~CFLicCruiseCar
  127.  
  128.   Summary:  CFLicCruiseCar Destructor.
  129.  
  130.   Args:     void
  131.  
  132.   Modifies: .
  133.  
  134.   Returns:  void
  135. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  136. CFLicCruiseCar::~CFLicCruiseCar(void)
  137. {
  138.   LOG("P: CFLicCruiseCar::Destructor.");
  139.  
  140.   return;
  141. }
  142.  
  143.  
  144. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  145.   Method:   CFLicCruiseCar::QueryInterface
  146.  
  147.   Summary:  QueryInterface of the CFLicCruiseCar non-delegating
  148.             IUnknown implementation.
  149.  
  150.   Args:     REFIID riid,
  151.               [in] GUID of the Interface being requested.
  152.             PPVOID ppv)
  153.               [out] Address of the caller's pointer variable that will
  154.               receive the requested interface pointer.
  155.  
  156.   Returns:  HRESULT
  157.               Standard result code. NOERROR for success.
  158. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  159. STDMETHODIMP CFLicCruiseCar::QueryInterface(
  160.                REFIID riid,
  161.                PPVOID ppv)
  162. {
  163.   HRESULT hr = E_NOINTERFACE;
  164.   *ppv = NULL;
  165.  
  166.   if (IID_IUnknown == riid)
  167.   {
  168.     *ppv = this;
  169.     LOG("P: CFLicCruiseCar::QueryInterface. 'this' pIUnknown returned.");
  170.   }
  171.   else if (IID_IClassFactory == riid)
  172.   {
  173.     *ppv = &m_ImpIClassFactory;
  174.     LOG("P: CFLicCruiseCar::QueryInterface. pIClassFactory returned.");
  175.   }
  176.   else if (IID_IClassFactory2 == riid)
  177.   {
  178.     *ppv = &m_ImpIClassFactory;
  179.     LOG("P: CFLicCruiseCar::QueryInterface. pIClassFactory2 returned.");
  180.   }
  181.  
  182.   if (NULL != *ppv)
  183.   {
  184.     // We've handed out a pointer to the interface so obey the COM rules
  185.     // and AddRef the reference count.
  186.     ((LPUNKNOWN)*ppv)->AddRef();
  187.     hr = NOERROR;
  188.   }
  189.  
  190.   return (hr);
  191. }
  192.  
  193.  
  194. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  195.   Method:   CFLicCruiseCar::AddRef
  196.  
  197.   Summary:  AddRef of the CFLicCruiseCar non-delegating IUnknown
  198.             implementation.
  199.  
  200.   Args:     void
  201.  
  202.   Modifies: m_cRefs.
  203.  
  204.   Returns:  ULONG
  205.               New value of m_cRefs (COM object's reference count).
  206. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  207. STDMETHODIMP_(ULONG) CFLicCruiseCar::AddRef(void)
  208. {
  209.   m_cRefs++;
  210.  
  211.   LOGF1("P: CFLicCruiseCar::AddRef. New cRefs=%i.", m_cRefs);
  212.  
  213.   return m_cRefs;
  214. }
  215.  
  216.  
  217. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  218.   Method:   CFLicCruiseCar::Release
  219.  
  220.   Summary:  Release of the CFLicCruiseCar non-delegating IUnknown
  221.             implementation.
  222.  
  223.   Args:     void
  224.  
  225.   Modifies: m_cRefs.
  226.  
  227.   Returns:  ULONG
  228.               New value of m_cRefs (COM object's reference count).
  229. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  230. STDMETHODIMP_(ULONG) CFLicCruiseCar::Release(void)
  231. {
  232.   m_cRefs--;
  233.  
  234.   LOGF1("P: CFLicCruiseCar::Release. New cRefs=%i.", m_cRefs);
  235.  
  236.   if (0 == m_cRefs)
  237.   {
  238.     // We've reached a zero reference count for this COM object.
  239.     // So we tell the server housing to decrement its global object
  240.     // count so that the server will be unloaded if appropriate.
  241.     if (NULL != m_pServer)
  242.       m_pServer->ObjectsDown();
  243.  
  244.     // We artificially bump the main ref count to prevent reentrancy
  245.     // via the main object destructor.  Not really needed in this
  246.     // CFLicCruiseCar but a good practice because we are aggregatable and
  247.     // may at some point in the future add something entertaining like
  248.     // some Releases to the CFLicCruiseCar destructor.
  249.     m_cRefs++;
  250.     delete this;
  251.   }
  252.  
  253.   return m_cRefs;
  254. }
  255.  
  256.  
  257. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  258.   Method:   CFLicCruiseCar::CreateLicCruiseCar
  259.  
  260.   Summary:  Unconditionally create a LicCruiseCar COM object.  Called
  261.             internally in this class from CreateInstance and
  262.             CreateInstanceLic.
  263.  
  264.   Args:     IUnknown* pUnkOuter,
  265.               [in] Pointer to the aggregation controlling outer IUnknown.
  266.             REFIID riid,
  267.               [in] The GUID of the interface that is being requested.
  268.             PPVOID ppvCob)
  269.               [out] Address of the caller's pointer variable that will
  270.               receive the requested interface pointer.
  271.  
  272.   Returns:  HRESULT
  273.               Standard result code. NOERROR for success.
  274.               Returned by a QueryInterface call.
  275. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  276. STDMETHODIMP CFLicCruiseCar::CreateLicCruiseCar(
  277.                IUnknown* pUnkOuter,
  278.                REFIID riid,
  279.                PPVOID ppvCob)
  280. {
  281.   HRESULT hr = E_FAIL;
  282.   COLicCruiseCar* pCob = NULL;
  283.  
  284.   LOGF1("P: CFLicCruiseCar::CreateLicCruiseCar. pUnkOuter=0x%X.",pUnkOuter);
  285.  
  286.   // If the creation call is requesting aggregation (pUnkOuter != NULL),
  287.   // the COM rules state the IUnknown interface MUST also be concomitantly
  288.   // be requested.  If it is not so requested ( riid != IID_IUnknown) then
  289.   // an error must be returned indicating that no aggregate creation of
  290.   // the COLicCruiseCarFactory COM Object can be performed.
  291.   if (NULL != pUnkOuter && riid != IID_IUnknown)
  292.     hr = CLASS_E_NOAGGREGATION;
  293.   else
  294.   {
  295.     // Instantiate a COLicCruiseCar COM Object.
  296.     pCob = new COLicCruiseCar(pUnkOuter, m_pServer);
  297.     if (NULL != pCob)
  298.     {
  299.       // We initially created the new COM object so tell the server
  300.       // to increment its global server object count to help ensure
  301.       // that the server remains loaded until this partial creation
  302.       // of a COM component is completed.
  303.       m_pServer->ObjectsUp();
  304.  
  305.       // If we have succeeded in instantiating the COM object we
  306.       // initialize it to set up any subordinate objects.
  307.       hr = pCob->Init();
  308.       if (SUCCEEDED(hr))
  309.       {
  310.         // We QueryInterface this new COM Object not only to deposit the
  311.         // main interface pointer to the caller's pointer variable, but to
  312.         // also automatically bump the Reference Count on the new COM
  313.         // Object after handing out this reference to it.
  314.         hr = pCob->QueryInterface(riid, (PPVOID)ppvCob);
  315.       }
  316.  
  317.       if (FAILED(hr))
  318.       {
  319.         m_pServer->ObjectsDown();
  320.         delete pCob;
  321.       }
  322.     }
  323.     else
  324.       hr = E_OUTOFMEMORY;
  325.   }
  326.  
  327.   if (SUCCEEDED(hr))
  328.   {
  329.     LOGF1("P: CFLicCruiseCar::CreateLicCruiseCar Succeeded. *ppv=0x%X.",*ppvCob);
  330.   }
  331.   else
  332.   {
  333.     LOG("P: CFLicCruiseCar::CreateLicCruiseCar Failed.");
  334.   }
  335.  
  336.   return hr;
  337. }
  338.  
  339.  
  340. /*---------------------------------------------------------------------------
  341.   CFLicCruiseCar's nested implementation of the IClassFactory2 interface
  342.   including Constructor, Destructor, QueryInterface, AddRef, Release,
  343.   CreateInstance, LockServer, CreateInstanceLic, RequestLicKey, and
  344.   GetLicInfo methods.
  345. ---------------------------------------------------------------------------*/
  346.  
  347. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  348.   Method:   CFLicCruiseCar::CImpIClassFactory::CImpIClassFactory
  349.  
  350.   Summary:  Constructor for the CImpIClassFactory interface instantiation.
  351.  
  352.   Args:     CFLicCruiseCar* pBackObj,
  353.               Back pointer to the parent outer object.
  354.             IUnknown* pUnkOuter,
  355.               Pointer to the outer Unknown.  For delegation.
  356.             CServer* pServer)
  357.               Pointer to the server's control object.
  358.  
  359.   Modifies: m_cRefI, m_pBackObj, m_pUnkOuter, m_pServer.
  360.  
  361.   Returns:  void
  362. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  363. CFLicCruiseCar::CImpIClassFactory::CImpIClassFactory(
  364.   CFLicCruiseCar* pBackObj,
  365.   IUnknown* pUnkOuter,
  366.   CServer* pServer)
  367. {
  368.   // Init the Interface Ref Count (used for debugging only).
  369.   m_cRefI = 0;
  370.  
  371.   // Init the Back Object Pointer to point to the parent object.
  372.   m_pBackObj = pBackObj;
  373.  
  374.   // Init the pointer to the server control object.
  375.   m_pServer = pServer;
  376.  
  377.   // Init the CImpIClassFactory interface's delegating Unknown pointer.
  378.   // We use the Back Object pointer for IUnknown delegation here if we are
  379.   // not being aggregated.  If we are being aggregated we use the supplied
  380.   // pUnkOuter for IUnknown delegation.  In either case the pointer
  381.   // assignment requires no AddRef because the CImpIClassFactory lifetime
  382.   // is quaranteed by the lifetime of the parent object in which
  383.   // CImpIClassFactory is nested.
  384.   if (NULL == pUnkOuter)
  385.   {
  386.     m_pUnkOuter = pBackObj;
  387.     LOG("P: CFLicCruiseCar::CImpIClassFactory Constructor. Non-Aggregating.");
  388.   }
  389.   else
  390.   {
  391.     m_pUnkOuter = pUnkOuter;
  392.     LOG("P: CFLicCruiseCar::CImpIClassFactory Constructor. Aggregating.");
  393.   }
  394.  
  395.   return;
  396. }
  397.  
  398.  
  399. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  400.   Method:   CFLicCruiseCar::CImpIClassFactory::~CImpIClassFactory
  401.  
  402.   Summary:  Destructor for the CImpIClassFactory interface instantiation.
  403.  
  404.   Args:     void
  405.  
  406.   Modifies: .
  407.  
  408.   Returns:  void
  409. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  410. CFLicCruiseCar::CImpIClassFactory::~CImpIClassFactory(void)
  411. {
  412.   LOG("P: CFLicCruiseCar::CImpIClassFactory Destructor.");
  413.  
  414.   return;
  415. }
  416.  
  417.  
  418. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  419.   Method:   CFLicCruiseCar::CImpIClassFactory::QueryInterface
  420.  
  421.   Summary:  The QueryInterface IUnknown member of this IClassFactory
  422.             interface implementation that delegates to m_pUnkOuter,
  423.             whatever it is.
  424.  
  425.   Args:     REFIID riid,
  426.               [in] GUID of the Interface being requested.
  427.             PPVOID ppv)
  428.               [out] Address of the caller's pointer variable that will
  429.               receive the requested interface pointer.
  430.  
  431.   Returns:  HRESULT
  432.               Standard result code. NOERROR for success.
  433.               Returned by the delegated outer QueryInterface call.
  434. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  435. STDMETHODIMP CFLicCruiseCar::CImpIClassFactory::QueryInterface(
  436.                REFIID riid,
  437.                PPVOID ppv)
  438. {
  439.   LOG("P: CFLicCruiseCar::CImpIClassFactory::QueryInterface. Delegating.");
  440.  
  441.   // Delegate this call to the outer object's QueryInterface.
  442.   return m_pUnkOuter->QueryInterface(riid, ppv);
  443. }
  444.  
  445.  
  446. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  447.   Method:   CFLicCruiseCar::CImpIClassFactory::AddRef
  448.  
  449.   Summary:  The AddRef IUnknown member of this IClassFactory interface
  450.             implementation that delegates to m_pUnkOuter, whatever it is.
  451.  
  452.   Args:     void
  453.  
  454.   Modifies: m_cRefI.
  455.  
  456.   Returns:  ULONG
  457.               Returned by the delegated outer AddRef call.
  458. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  459. STDMETHODIMP_(ULONG) CFLicCruiseCar::CImpIClassFactory::AddRef(void)
  460. {
  461.   // Increment the Interface Reference Count.
  462.   ++m_cRefI;
  463.  
  464.   LOGF1("P: CFLicCruiseCar::CImpIClassFactory::Addref. Delegating. New cI=%i.",m_cRefI);
  465.  
  466.   // Delegate this call to the outer object's AddRef.
  467.   return m_pUnkOuter->AddRef();
  468. }
  469.  
  470.  
  471. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  472.   Method:   CFLicCruiseCar::CImpIClassFactory::Release
  473.  
  474.   Summary:  The Release IUnknown member of this IClassFactory interface
  475.             implementation that delegates to m_pUnkOuter, whatever it is.
  476.  
  477.   Args:     void
  478.  
  479.   Modifies: .
  480.  
  481.   Returns:  ULONG
  482.               Returned by the delegated outer Release call.
  483. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  484. STDMETHODIMP_(ULONG) CFLicCruiseCar::CImpIClassFactory::Release(void)
  485. {
  486.   // Decrement the Interface Reference Count.
  487.   --m_cRefI;
  488.  
  489.   LOGF1("P: CFLicCruiseCar::CImpIClassFactory::Release. Delegating. New cI=%i.",m_cRefI);
  490.  
  491.   // Delegate this call to the outer object's Release.
  492.   return m_pUnkOuter->Release();
  493. }
  494.  
  495.  
  496. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  497.   Method:   CFLicCruiseCar::CImpIClassFactory::CreateInstance
  498.  
  499.   Summary:  The CreateInstance member method of this IClassFactory
  500.             interface implementation.  Creates an instance of the
  501.             COLicCruiseCar COM component.  Pays due heed to licensing and
  502.             only completes the create if the server was confirmed as
  503.             licensed.
  504.  
  505.   Args:     IUnknown* pUnkOuter,
  506.               [in] Pointer to the controlling IUnknown.
  507.             REFIID riid,
  508.               [in] GUID of the Interface being requested.
  509.             PPVOID ppvCob)
  510.               [out] Address of the caller's pointer variable that will
  511.               receive the requested interface pointer.
  512.  
  513.   Returns:  HRESULT
  514.               Standard result code. NOERROR for success.
  515. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  516. STDMETHODIMP CFLicCruiseCar::CImpIClassFactory::CreateInstance(
  517.                IUnknown* pUnkOuter,
  518.                REFIID riid,
  519.                PPVOID ppv)
  520. {
  521.   HRESULT hr = CLASS_E_NOTLICENSED;
  522.  
  523.   LOGF1("P: CFLicCruiseCar::CImpIClassFactory::CreateInstance. pUnkOuter=0x%X.",pUnkOuter);
  524.  
  525.   if (g_pServer->m_bLicensed)
  526.     hr = m_pBackObj->CreateLicCruiseCar(pUnkOuter, riid, ppv);
  527.   else
  528.   {
  529.     LOG("P: CFLicCruiseCar::CImpIClassFactory::CreateInstance. No Machine License.");
  530.   }
  531.  
  532.   if (SUCCEEDED(hr))
  533.   {
  534.     LOGF1("P: CFLicCruiseCar::CImpIClassFactory::CreateInstance Succeeded. *ppv=0x%X.",*ppv);
  535.   }
  536.   else
  537.   {
  538.     LOG("P: CFLicCruiseCar::CImpIClassFactory::CreateInstance Failed.");
  539.   }
  540.  
  541.   return hr;
  542. }
  543.  
  544.  
  545. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  546.   Method:   CFLicCruiseCar::CImpIClassFactory::LockServer
  547.  
  548.   Summary:  The LockServer member method of this IClassFactory interface
  549.             implementation.
  550.  
  551.   Args:     BOOL fLock)
  552.               [in] Flag determining whether to Lock or Unlock the server.
  553.  
  554.   Returns:  HRESULT
  555.               Standard result code. NOERROR for success.
  556. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  557. STDMETHODIMP CFLicCruiseCar::CImpIClassFactory::LockServer(
  558.                BOOL fLock)
  559. {
  560.   HRESULT hr = NOERROR;
  561.  
  562.   LOG("P: CFLicCruiseCar::CImpIClassFactory::LockServer.");
  563.  
  564.   if (fLock)
  565.     m_pServer->Lock();
  566.   else
  567.     m_pServer->Unlock();
  568.  
  569.   return hr;
  570. }
  571.  
  572.  
  573. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  574.   Method:   CFLicCruiseCar::CImpIClassFactory::GetLicInfo
  575.  
  576.  
  577.   Summary:  The GetLicInfo member method of the IClassFactory2 interface
  578.             implementation.
  579.  
  580.   Args:     LPLICINFO lpLicInfo
  581.               Pointer to the license info structure to fill.
  582.  
  583.   Returns:  HRESULT
  584.               Standard result code. NOERROR for success.
  585. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  586. STDMETHODIMP CFLicCruiseCar::CImpIClassFactory::GetLicInfo(
  587.                LPLICINFO pLicInfo)
  588. {
  589.   HRESULT hr = NOERROR;
  590.  
  591.   LOG("P: CFLicCruiseCar::CImpIClassFactory::GetLicInfo.");
  592.  
  593.   if (NULL != pLicInfo)
  594.   {
  595.     pLicInfo->cbLicInfo = sizeof(LICINFO);
  596.  
  597.     // Inform whether RequestLicKey will work.
  598.     pLicInfo->fRuntimeKeyAvail = g_pServer->m_bLicensed;
  599.  
  600.     // Inform whether the standard CreateInstance will work.
  601.     pLicInfo->fLicVerified = g_pServer->m_bLicensed;
  602.   }
  603.   else
  604.     hr = E_POINTER;
  605.  
  606.   return hr;
  607. }
  608.  
  609.  
  610. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  611.   Method:   CFLicCruiseCar::CImpIClassFactory::RequestLicKey
  612.  
  613.  
  614.   Summary:  The RequestLicKey member method of the IClassFactory2
  615.             interface implementation.  Returns a license key string
  616.             for this Class Factory.  The key string is used in calls
  617.             to the CreateInstanceLic IClassFactory2 method.
  618.  
  619.   Args:     DWORD dwReserved,
  620.               Reserved for future use with multiple licenses.
  621.             BSTR* pbstrKey
  622.               Pointer to the buffer in which to return the key string.
  623.  
  624.   Returns:  HRESULT
  625.               Standard result code. NOERROR for success.
  626. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  627. STDMETHODIMP CFLicCruiseCar::CImpIClassFactory::RequestLicKey(
  628.                DWORD dwReserved,
  629.                BSTR* pbstrKey)
  630. {
  631.   HRESULT hr = CLASS_E_NOTLICENSED;
  632.   OLECHAR szLicKey[MAX_LICENSEKEY];
  633.  
  634.   LOG("P: CFLicCruiseCar::CImpIClassFactory::RequestLicKey.");
  635.  
  636.   // Only return the license key if the server machine license was verified.
  637.   if (g_pServer->m_bLicensed)
  638.   {
  639.     // Convert our ANSI license string to Wide Char and then alloc as BSTR.
  640.     mbstowcs(szLicKey, g_pServer->m_szLicenseKey, g_pServer->m_cLicenseLen);
  641.     *pbstrKey = SysAllocString(szLicKey);
  642.     hr = (NULL != *pbstrKey) ? NOERROR : E_OUTOFMEMORY;
  643.   }
  644.  
  645.   return hr;
  646. }
  647.  
  648.  
  649. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  650.   Method:   CFLicCruiseCar::CImpIClassFactory::CreateInstanceLic
  651.  
  652.   Summary:  The CreateInstanceLic member method of the IClassFactory2
  653.             interface implementation.  Creates an instance of the managed
  654.             COM object given a proper license key string.
  655.  
  656.   Args:     IUnknown* pUnkOuter,
  657.               Pointer to the aggregation controlling IUnknown.
  658.             IUnknown* pUnkReserved,
  659.               Reserved.
  660.             REFIID riid,
  661.               A reference to the GUID of the interface requested on the
  662.               new object.
  663.             BSTR bstrKey,
  664.               The license key string.
  665.             PPVOID ppvCob
  666.               Address of the caller's pointer variable that will
  667.               receive the requested interface pointer.
  668.  
  669.   Returns:  HRESULT
  670.               Standard result code. NOERROR for success.
  671. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  672. STDMETHODIMP CFLicCruiseCar::CImpIClassFactory::CreateInstanceLic(
  673.                IUnknown* pUnkOuter,
  674.                IUnknown* pUnkReserved,
  675.                REFIID riid,
  676.                BSTR bstrKey,
  677.                PPVOID ppvCob)
  678. {
  679.   HRESULT hr;
  680.   BOOL    bMatch = FALSE;
  681.   BSTR    bstrTemp;
  682.   UINT    cch = g_pServer->m_cLicenseLen;
  683.   OLECHAR szLicKey[MAX_LICENSEKEY];
  684.  
  685.   LOG("P: CFLicCruiseCar::CImpIClassFactory::CreateInstanceLic.");
  686.  
  687.   *ppvCob = NULL;
  688.  
  689.   // Convert our ANSI license string to Wide Char and then alloc as BSTR.
  690.   mbstowcs(szLicKey, g_pServer->m_szLicenseKey, cch);
  691.   bstrTemp = SysAllocString(szLicKey);
  692.   if (NULL != bstrTemp)
  693.   {
  694.     if (NULL != bstrKey)
  695.       bMatch = (0 == memcmp(bstrTemp, bstrKey, cch * sizeof(OLECHAR)));
  696.  
  697.     SysFreeString(bstrTemp);
  698.  
  699.     if (bMatch)
  700.       hr = m_pBackObj->CreateLicCruiseCar(pUnkOuter, riid, ppvCob);
  701.     else
  702.     {
  703.       LOG("P: CFLicCruiseCar::CImpIClassFactory::CreateInstanceLic. No Runtime License.");
  704.       hr = CLASS_E_NOTLICENSED;
  705.     }
  706.   }
  707.   else
  708.     hr = E_OUTOFMEMORY;
  709.  
  710.   return hr;
  711. }
  712.  
  713.  
  714. /*---------------------------------------------------------------------------
  715.   Implementation the CFLicCarSample Class Factory (IClassFactory).
  716.   CFLicCarSample is the COM object class for the Class Factory that can
  717.   manufacture COLicCarSample COM Components.
  718. ---------------------------------------------------------------------------*/
  719.  
  720. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  721.   Method:   CFLicCarSample::CFLicCarSample
  722.  
  723.   Summary:  CFLicCruiseCar Constructor. Note the member initializer:
  724.             "m_ImpIClassFactory(this, pUnkOuter, pServer)" which is used
  725.             to pass the 'this', pUnkOuter, and pServer pointers of this
  726.             constructor function to the constructor executed in the
  727.             instantiation of the CImpIClassFactory interface whose
  728.             implementation is nested inside this present object class.
  729.  
  730.   Args:     IUnknown* pUnkOuter,
  731.               Pointer to the the outer Unknown.  NULL means this COM Object
  732.               is not being Aggregated.  Non NULL means it is being created
  733.               on behalf of an outside COM object that is reusing it via
  734.               aggregation.
  735.             CServer* pServer)
  736.               Pointer to the server's control object.
  737.  
  738.   Modifies: m_cRefs, m_pUnkOuter.
  739.  
  740.   Returns:  void
  741. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  742. CFLicCarSample::CFLicCarSample(
  743.   IUnknown* pUnkOuter,
  744.   CServer* pServer) :
  745.   m_ImpIClassFactory(this, pUnkOuter, pServer)
  746. {
  747.   // Zero the COM object's reference count.
  748.   m_cRefs = 0;
  749.  
  750.   // No AddRef necessary if non-NULL, as we're nested.
  751.   m_pUnkOuter = pUnkOuter;
  752.  
  753.   // Init the pointer to the server control object.
  754.   m_pServer = pServer;
  755.  
  756.   LOGF1("P: CFLicCarSample Constructor. m_pUnkOuter=0x%X.", m_pUnkOuter);
  757.  
  758.   return;
  759. }
  760.  
  761.  
  762. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  763.   Method:   CFLicCarSample::~CFLicCarSample
  764.  
  765.   Summary:  CFLicCarSample Destructor.
  766.  
  767.   Args:     void
  768.  
  769.   Modifies: .
  770.  
  771.   Returns:  void
  772. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  773. CFLicCarSample::~CFLicCarSample(void)
  774. {
  775.   LOG("P: CFLicCarSample::Destructor.");
  776.  
  777.   return;
  778. }
  779.  
  780.  
  781. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  782.   Method:   CFLicCarSample::QueryInterface
  783.  
  784.   Summary:  QueryInterface of the CFLicCarSample non-delegating
  785.             IUnknown implementation.
  786.  
  787.   Args:     REFIID riid,
  788.               [in] GUID of the Interface being requested.
  789.             PPVOID ppv)
  790.               [out] Address of the caller's pointer variable that will
  791.               receive the requested interface pointer.
  792.  
  793.   Returns:  HRESULT
  794.               Standard result code. NOERROR for success.
  795. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  796. STDMETHODIMP CFLicCarSample::QueryInterface(
  797.                REFIID riid,
  798.                PPVOID ppv)
  799. {
  800.   HRESULT hr = E_NOINTERFACE;
  801.   *ppv = NULL;
  802.  
  803.   if (IID_IUnknown == riid)
  804.   {
  805.     *ppv = this;
  806.     LOG("P: CFLicCarSample::QueryInterface. 'this' pIUnknown returned.");
  807.   }
  808.   else if (IID_IClassFactory == riid)
  809.   {
  810.     *ppv = &m_ImpIClassFactory;
  811.     LOG("P: CFLicCarSample::QueryInterface. pIClassFactory returned.");
  812.   }
  813.  
  814.   if (NULL != *ppv)
  815.   {
  816.     // We've handed out a pointer to the interface so obey the COM rules
  817.     //   and AddRef the reference count.
  818.     ((LPUNKNOWN)*ppv)->AddRef();
  819.     hr = NOERROR;
  820.   }
  821.  
  822.   return (hr);
  823. }
  824.  
  825.  
  826. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  827.   Method:   CFLicCarSample::AddRef
  828.  
  829.   Summary:  AddRef of the CFLicCarSample non-delegating IUnknown
  830.             implementation.
  831.  
  832.   Args:     void
  833.  
  834.   Modifies: m_cRefs.
  835.  
  836.   Returns:  ULONG
  837.               New value of m_cRefs (COM object's reference count).
  838. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  839. STDMETHODIMP_(ULONG) CFLicCarSample::AddRef(void)
  840. {
  841.   m_cRefs++;
  842.  
  843.   LOGF1("P: CFLicCarSample::AddRef. New cRefs=%i.", m_cRefs);
  844.  
  845.   return m_cRefs;
  846. }
  847.  
  848.  
  849. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  850.   Method:   CFLicCarSample::Release
  851.  
  852.   Summary:  Release of the CFLicCarSample non-delegating IUnknown
  853.             implementation.
  854.  
  855.   Args:     void
  856.  
  857.   Modifies: m_cRefs.
  858.  
  859.   Returns:  ULONG
  860.               New value of m_cRefs (COM object's reference count).
  861. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  862. STDMETHODIMP_(ULONG) CFLicCarSample::Release(void)
  863. {
  864.   m_cRefs--;
  865.  
  866.   LOGF1("P: CFLicCarSample::Release. New cRefs=%i.", m_cRefs);
  867.  
  868.   if (0 == m_cRefs)
  869.   {
  870.     // We've reached a zero reference count for this COM object.
  871.     // So we tell the server housing to decrement its global object
  872.     // count so that the server will be unloaded if appropriate.
  873.     if (NULL != m_pServer)
  874.       m_pServer->ObjectsDown();
  875.  
  876.     // We artificially bump the main ref count to prevent reentrancy
  877.     // via the main object destructor.  Not really needed in this
  878.     // CFLicCarSample but a good practice because we are aggregatable and
  879.     // may at some point in the future add something entertaining like
  880.     // some Releases to the CFLicCarSample destructor.
  881.     m_cRefs++;
  882.     delete this;
  883.   }
  884.  
  885.   return m_cRefs;
  886. }
  887.  
  888.  
  889. /*---------------------------------------------------------------------------
  890.   CFLicCarSample's nested implementation of the IClassFactory interface
  891.   including Constructor, Destructor, QueryInterface, AddRef, Release,
  892.   CreateInstance, and LockServer methods.
  893. ---------------------------------------------------------------------------*/
  894.  
  895. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  896.   Method:   CFLicCarSample::CImpIClassFactory::CImpIClassFactory
  897.  
  898.   Summary:  Constructor for the CImpIClassFactory interface instantiation.
  899.  
  900.   Args:     CFLicCarSample* pBackObj,
  901.               Back pointer to the parent outer object.
  902.             IUnknown* pUnkOuter,
  903.               Pointer to the outer Unknown.  For delegation.
  904.             CServer* pServer)
  905.               Pointer to the server's control object.
  906.  
  907.   Modifies: m_cRefI, m_pBackObj, m_pUnkOuter, m_pServer.
  908.  
  909.   Returns:  void
  910. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  911. CFLicCarSample::CImpIClassFactory::CImpIClassFactory(
  912.   CFLicCarSample* pBackObj,
  913.   IUnknown* pUnkOuter,
  914.   CServer* pServer)
  915. {
  916.   // Init the Interface Ref Count (used for debugging only).
  917.   m_cRefI = 0;
  918.  
  919.   // Init the Back Object Pointer to point to the parent object.
  920.   m_pBackObj = pBackObj;
  921.  
  922.   // Init the pointer to the server control object.
  923.   m_pServer = pServer;
  924.  
  925.   // Init the CImpIClassFactory interface's delegating Unknown pointer.
  926.   // We use the Back Object pointer for IUnknown delegation here if we are
  927.   // not being aggregated.  If we are being aggregated we use the supplied
  928.   // pUnkOuter for IUnknown delegation.  In either case the pointer
  929.   // assignment requires no AddRef because the CImpIClassFactory lifetime
  930.   // is quaranteed by the lifetime of the parent object in which
  931.   // CImpIClassFactory is nested.
  932.   if (NULL == pUnkOuter)
  933.   {
  934.     m_pUnkOuter = pBackObj;
  935.     LOG("P: CFLicCarSample::CImpIClassFactory Constructor. Non-Aggregating.");
  936.   }
  937.   else
  938.   {
  939.     m_pUnkOuter = pUnkOuter;
  940.     LOG("P: CFLicCarSample::CImpIClassFactory Constructor. Aggregating.");
  941.   }
  942.  
  943.   return;
  944. }
  945.  
  946.  
  947. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  948.   Method:   CFLicCarSample::CImpIClassFactory::~CImpIClassFactory
  949.  
  950.   Summary:  Destructor for the CImpIClassFactory interface instantiation.
  951.  
  952.   Args:     void
  953.  
  954.   Modifies: .
  955.  
  956.   Returns:  void
  957. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  958. CFLicCarSample::CImpIClassFactory::~CImpIClassFactory(void)
  959. {
  960.   LOG("P: CFLicCarSample::CImpIClassFactory Destructor.");
  961.  
  962.   return;
  963. }
  964.  
  965.  
  966. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  967.   Method:   CFLicCarSample::CImpIClassFactory::QueryInterface
  968.  
  969.   Summary:  The QueryInterface IUnknown member of this IClassFactory
  970.             interface implementation that delegates to m_pUnkOuter,
  971.             whatever it is.
  972.  
  973.   Args:     REFIID riid,
  974.               [in] GUID of the Interface being requested.
  975.             PPVOID ppv)
  976.               [out] Address of the caller's pointer variable that will
  977.               receive the requested interface pointer.
  978.  
  979.   Returns:  HRESULT
  980.               Standard result code. NOERROR for success.
  981.               Returned by the delegated outer QueryInterface call.
  982. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  983. STDMETHODIMP CFLicCarSample::CImpIClassFactory::QueryInterface(
  984.                REFIID riid,
  985.                PPVOID ppv)
  986. {
  987.   LOG("P: CFLicCarSample::CImpIClassFactory::QueryInterface. Delegating.");
  988.  
  989.   // Delegate this call to the outer object's QueryInterface.
  990.   return m_pUnkOuter->QueryInterface(riid, ppv);
  991. }
  992.  
  993.  
  994. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  995.   Method:   CFLicCarSample::CImpIClassFactory::AddRef
  996.  
  997.   Summary:  The AddRef IUnknown member of this IClassFactory interface
  998.             implementation that delegates to m_pUnkOuter, whatever it is.
  999.  
  1000.   Args:     void
  1001.  
  1002.   Modifies: m_cRefI.
  1003.  
  1004.   Returns:  ULONG
  1005.               Returned by the delegated outer AddRef call.
  1006. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  1007. STDMETHODIMP_(ULONG) CFLicCarSample::CImpIClassFactory::AddRef(void)
  1008. {
  1009.   // Increment the Interface Reference Count.
  1010.   ++m_cRefI;
  1011.  
  1012.   LOGF1("P: CFLicCarSample::CImpIClassFactory::Addref. Delegating. New cI=%i.",m_cRefI);
  1013.  
  1014.   // Delegate this call to the outer object's AddRef.
  1015.   return m_pUnkOuter->AddRef();
  1016. }
  1017.  
  1018.  
  1019. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  1020.   Method:   CFLicCarSample::CImpIClassFactory::Release
  1021.  
  1022.   Summary:  The Release IUnknown member of this IClassFactory interface
  1023.             implementation that delegates to m_pUnkOuter, whatever it is.
  1024.  
  1025.   Args:     void
  1026.  
  1027.   Modifies: .
  1028.  
  1029.   Returns:  ULONG
  1030.               Returned by the delegated outer Release call.
  1031. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  1032. STDMETHODIMP_(ULONG) CFLicCarSample::CImpIClassFactory::Release(void)
  1033. {
  1034.   // Decrement the Interface Reference Count.
  1035.   --m_cRefI;
  1036.  
  1037.   LOGF1("P: CFLicCarSample::CImpIClassFactory::Release. Delegating. New cI=%i.",m_cRefI);
  1038.  
  1039.   // Delegate this call to the outer object's Release.
  1040.   return m_pUnkOuter->Release();
  1041. }
  1042.  
  1043.  
  1044. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  1045.   Method:   CFLicCarSample::CImpIClassFactory::CreateInstance
  1046.  
  1047.   Summary:  The CreateInstance member method of this IClassFactory
  1048.             interface implementation.  Creates an instance of the
  1049.             COLicCarSample COM component.
  1050.  
  1051.   Args:     IUnknown* pUnkOuter,
  1052.               [in] Pointer to the controlling IUnknown.
  1053.             REFIID riid,
  1054.               [in] GUID of the Interface being requested.
  1055.             PPVOID ppv)
  1056.               [out] Address of the caller's pointer variable that will
  1057.               receive the requested interface pointer.
  1058.  
  1059.   Returns:  HRESULT
  1060.               Standard result code. NOERROR for success.
  1061. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  1062. STDMETHODIMP CFLicCarSample::CImpIClassFactory::CreateInstance(
  1063.                IUnknown* pUnkOuter,
  1064.                REFIID riid,
  1065.                PPVOID ppv)
  1066. {
  1067.   HRESULT hr = E_FAIL;
  1068.   COLicCarSample* pCob = NULL;
  1069.  
  1070.   LOGF1("P: CFLicCarSample::CImpIClassFactory::CreateInstance. pUnkOuter=0x%X.",pUnkOuter);
  1071.  
  1072.   // If the creation call is requesting aggregation (pUnkOuter != NULL),
  1073.   // the COM rules state the IUnknown interface MUST also be concomitantly
  1074.   // be requested.  If it is not so requested ( riid != IID_IUnknown) then
  1075.   // an error must be returned indicating that no aggregate creation of
  1076.   // the CFLicCarSample COM Object can be performed.
  1077.   if (NULL != pUnkOuter && riid != IID_IUnknown)
  1078.     hr = CLASS_E_NOAGGREGATION;
  1079.   else
  1080.   {
  1081.     // Instantiate a COLicCarSample COM Object.
  1082.     pCob = new COLicCarSample(pUnkOuter, m_pServer);
  1083.     if (NULL != pCob)
  1084.     {
  1085.       // We initially created the new COM object so tell the server
  1086.       // to increment its global server object count to help ensure
  1087.       // that the server remains loaded until this partial creation
  1088.       // of a COM component is completed.
  1089.       m_pServer->ObjectsUp();
  1090.  
  1091.       // We QueryInterface this new COM Object not only to deposit the
  1092.       // main interface pointer to the caller's pointer variable, but to
  1093.       // also automatically bump the Reference Count on the new COM
  1094.       // Object after handing out this reference to it.
  1095.       hr = pCob->QueryInterface(riid, (PPVOID)ppv);
  1096.       if (FAILED(hr))
  1097.       {
  1098.         m_pServer->ObjectsDown();
  1099.         delete pCob;
  1100.       }
  1101.     }
  1102.     else
  1103.       hr = E_OUTOFMEMORY;
  1104.   }
  1105.  
  1106.   if (SUCCEEDED(hr))
  1107.   {
  1108.     LOGF1("P: CFLicCarSample::CImpIClassFactory::CreateInstance Succeeded. *ppv=0x%X.",*ppv);
  1109.   }
  1110.   else
  1111.   {
  1112.     LOG("P: CFLicCarSample::CImpIClassFactory::CreateInstance Failed.");
  1113.   }
  1114.  
  1115.   return hr;
  1116. }
  1117.  
  1118.  
  1119. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  1120.   Method:   CFLicCarSample::CImpIClassFactory::LockServer
  1121.  
  1122.   Summary:  The LockServer member method of this IClassFactory interface
  1123.             implementation.
  1124.  
  1125.   Args:     BOOL fLock)
  1126.               [in] Flag determining whether to Lock or Unlock the server.
  1127.  
  1128.   Returns:  HRESULT
  1129.               Standard result code. NOERROR for success.
  1130. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  1131. STDMETHODIMP CFLicCarSample::CImpIClassFactory::LockServer(
  1132.                BOOL fLock)
  1133. {
  1134.   HRESULT hr = NOERROR;
  1135.  
  1136.   LOG("P: CFLicCarSample::CImpIClassFactory::LockServer.");
  1137.  
  1138.   if (fLock)
  1139.     m_pServer->Lock();
  1140.   else
  1141.     m_pServer->Unlock();
  1142.  
  1143.   return hr;
  1144. }
  1145.