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 / dllserve / factory.cpp < prev    next >
C/C++ Source or Header  |  1997-08-30  |  60KB  |  1,815 lines

  1. /*+==========================================================================
  2.   File:      FACTORY.CPP
  3.  
  4.   Summary:   Implementation file for the ClassFactories of the DLLSERVE
  5.              server.  This server provides several Car-related COM
  6.              Components: Car, UtilityCar, and CruiseCar.  For each of
  7.              these components, IClassFactory is implemented in
  8.              appropriate ClassFactory COM objects: CFCar, CFUtilityCar,
  9.              and CFCruiseCar.  In addition a CFCarSample class factory
  10.              is included to provide a component with the Code Sample
  11.              utility interface (ISample).  This interface is primarily
  12.              for use within the code samples for the purposes of setting
  13.              them up as samples (eg, setting up the server so that it
  14.              trace logs to the client's trace log facility).  The COM
  15.              Components that can be manufactured by this server are
  16.              known outside the server by their respective CLSIDs:
  17.              CLSID_DllCar, CLSID_DllUtilityCar, CLSID_DllCruiseCar, and
  18.              CLSID_DllCarSample.
  19.  
  20.              For a comprehensive tutorial code tour of this module's
  21.              contents and offerings see the tutorial DLLSERVE.HTM file.
  22.              For more specific technical details on the internal workings
  23.              see the comments dispersed throughout the module's source code.
  24.  
  25.   Classes:   CFCar, CFUtilityCar, CFCruiseCar, CFCarSample.
  26.  
  27.   Functions: .
  28.  
  29.   Origin:    9-11-95: atrent - Editor-inheritance from CAR.CPP in
  30.                the COMOBJ Tutorial Code Sample.
  31.  
  32. ----------------------------------------------------------------------------
  33.   This file is part of the Microsoft COM Tutorial Code Samples.
  34.  
  35.   Copyright (C) Microsoft Corporation, 1997.  All rights reserved.
  36.  
  37.   This source code is intended only as a supplement to Microsoft
  38.   Development Tools and/or on-line documentation.  See these other
  39.   materials for detailed information regarding Microsoft code samples.
  40.  
  41.   THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
  42.   KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  43.   IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
  44.   PARTICULAR PURPOSE.
  45. ==========================================================================+*/
  46.  
  47. /*---------------------------------------------------------------------------
  48.   We include WINDOWS.H for all Win32 applications.
  49.   We include OLE2.H because we will be calling the COM/OLE Libraries.
  50.   We include APPUTIL.H because we will be building this DLL using
  51.     the convenient Virtual Window and Dialog classes and other
  52.     utility functions in the APPUTIL Library (ie, APPUTIL.LIB).
  53.   We include ICARS.H and CARGUIDS.H for the common car-related Interface
  54.     class, GUID, and CLSID specifications.
  55.   We include SERVER.H because it has the necessary internal class and
  56.     resource definitions for this DLL.
  57.   We include FACTORY.H because it has the necessary internal class factory
  58.     declarations for this DLL component server.  Those factories we will be
  59.     implementing in this module.
  60.   We include CAR.H, UTILCAR,H, and, CRUCAR.H for the object class
  61.     declarations for the COCar, COUtilityCar, and COCruiseCar COM objects.
  62.   We include SAMPLE.H for the utility Sample class COCarSample.
  63. ---------------------------------------------------------------------------*/
  64. #include <windows.h>
  65. #include <ole2.h>
  66. #include <apputil.h>
  67. #include <icars.h>
  68. #include <carguids.h>
  69. #include "server.h"
  70. #include "factory.h"
  71. #include "car.h"
  72. #include "utilcar.h"
  73. #include "crucar.h"
  74. #include "sample.h"
  75.  
  76. /*---------------------------------------------------------------------------
  77.   Implementation the CFCar Class Factory.  CFCar is the COM
  78.   object class for the Class Factory that can manufacture COCar
  79.   COM Components.
  80. ---------------------------------------------------------------------------*/
  81.  
  82. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  83.   Method:   CFCar::CFCar
  84.  
  85.   Summary:  CFCar Constructor. Note the member initializer:
  86.             "m_ImpIClassFactory(this, pUnkOuter, pServer)" which is used
  87.             to pass the 'this', pUnkOuter, and pServer pointers of this
  88.             constructor function to the constructor executed in the
  89.             instantiation of the CImpIClassFactory interface whose
  90.             implementation is nested inside this present object class.
  91.  
  92.   Args:     IUnknown* pUnkOuter,
  93.               Pointer to the the outer Unknown.  NULL means this COM Object
  94.               is not being Aggregated.  Non NULL means it is being created
  95.               on behalf of an outside COM object that is reusing it via
  96.               aggregation.
  97.             CServer* pServer)
  98.               Pointer to the server's control object.
  99.  
  100.   Modifies: m_cRefs, m_pUnkOuter.
  101.  
  102.   Returns:  void
  103. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  104. CFCar::CFCar(
  105.   IUnknown* pUnkOuter,
  106.   CServer* pServer) :
  107.   m_ImpIClassFactory(this, pUnkOuter, pServer)
  108. {
  109.   // Zero the COM object's reference count.
  110.   m_cRefs = 0;
  111.  
  112.   // No AddRef necessary if non-NULL, as we're nested.
  113.   m_pUnkOuter = pUnkOuter;
  114.  
  115.   // Init the pointer to the server control object.
  116.   m_pServer = pServer;
  117.  
  118.   LOGF1("S: CFCar Constructor. m_pUnkOuter=0x%X.", m_pUnkOuter);
  119.  
  120.   return;
  121. }
  122.  
  123.  
  124. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  125.   Method:   CFCar::~CFCar
  126.  
  127.   Summary:  CFCar Destructor.
  128.  
  129.   Args:     void
  130.  
  131.   Modifies: .
  132.  
  133.   Returns:  void
  134. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  135. CFCar::~CFCar(void)
  136. {
  137.   LOG("S: CFCar::Destructor.");
  138.  
  139.   return;
  140. }
  141.  
  142.  
  143. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  144.   Method:   CFCar::QueryInterface
  145.  
  146.   Summary:  QueryInterface of the CFCar non-delegating
  147.             IUnknown implementation.
  148.  
  149.   Args:     REFIID riid,
  150.               [in] GUID of the Interface being requested.
  151.             PPVOID ppv)
  152.               [out] Address of the caller's pointer variable that will
  153.               receive the requested interface pointer.
  154.  
  155.   Returns:  HRESULT
  156.               Standard result code. NOERROR for success.
  157. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  158. STDMETHODIMP CFCar::QueryInterface(
  159.                REFIID riid,
  160.                PPVOID ppv)
  161. {
  162.   HRESULT hr = E_NOINTERFACE;
  163.   *ppv = NULL;
  164.  
  165.   if (IID_IUnknown == riid)
  166.   {
  167.     *ppv = this;
  168.     LOG("S: CFCar::QueryInterface. 'this' pIUnknown returned.");
  169.   }
  170.   else if (IID_IClassFactory == riid)
  171.   {
  172.     *ppv = &m_ImpIClassFactory;
  173.     LOG("S: CFCar::QueryInterface. pIClassFactory returned.");
  174.   }
  175.  
  176.   if (NULL != *ppv)
  177.   {
  178.     // We've handed out a pointer to the interface so obey the COM rules
  179.     // and AddRef the reference count.
  180.     ((LPUNKNOWN)*ppv)->AddRef();
  181.     hr = NOERROR;
  182.   }
  183.  
  184.   return (hr);
  185. }
  186.  
  187.  
  188. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  189.   Method:   CFCar::AddRef
  190.  
  191.   Summary:  AddRef of the CFCar non-delegating IUnknown implementation.
  192.  
  193.   Args:     void
  194.  
  195.   Modifies: m_cRefs.
  196.  
  197.   Returns:  ULONG
  198.               New value of m_cRefs (COM object's reference count).
  199. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  200. STDMETHODIMP_(ULONG) CFCar::AddRef(void)
  201. {
  202.   m_cRefs++;
  203.  
  204.   LOGF1("S: CFCar::AddRef. New cRefs=%i.", m_cRefs);
  205.  
  206.   return m_cRefs;
  207. }
  208.  
  209.  
  210. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  211.   Method:   CFCar::Release
  212.  
  213.   Summary:  Release of the CFCar non-delegating IUnknown implementation.
  214.  
  215.   Args:     void
  216.  
  217.   Modifies: m_cRefs.
  218.  
  219.   Returns:  ULONG
  220.               New value of m_cRefs (COM object's reference count).
  221. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  222. STDMETHODIMP_(ULONG) CFCar::Release(void)
  223. {
  224.   m_cRefs--;
  225.  
  226.   LOGF1("S: CFCar::Release. New cRefs=%i.", m_cRefs);
  227.  
  228.   if (0 == m_cRefs)
  229.   {
  230.     // We've reached a zero reference count for this COM object.
  231.     // So we tell the server housing to decrement its global object
  232.     // count so that the server will be unloaded if appropriate.
  233.     if (NULL != m_pServer)
  234.       m_pServer->ObjectsDown();
  235.  
  236.     // We artificially bump the main ref count to prevent reentrancy
  237.     // via the main object destructor.  Not really needed in this
  238.     // CFCar but a good practice because we are aggregatable and
  239.     // may at some point in the future add something entertaining like
  240.     // some Releases to the CFCar destructor.
  241.     m_cRefs++;
  242.     delete this;
  243.   }
  244.  
  245.   return m_cRefs;
  246. }
  247.  
  248.  
  249. /*---------------------------------------------------------------------------
  250.   CFCar's nested implementation of the IClassFactory interface
  251.   including Constructor, Destructor, QueryInterface, AddRef, Release,
  252.   CreateInstance, and LockServer methods.
  253. ---------------------------------------------------------------------------*/
  254.  
  255. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  256.   Method:   CFCar::CImpIClassFactory::CImpIClassFactory
  257.  
  258.   Summary:  Constructor for the CImpIClassFactory interface instantiation.
  259.  
  260.   Args:     CFCar* pBackObj,
  261.               Back pointer to the parent outer object.
  262.             IUnknown* pUnkOuter,
  263.               Pointer to the outer Unknown.  For delegation.
  264.             CServer* pServer)
  265.               Pointer to the server's control object.
  266.  
  267.   Modifies: m_cRefI, m_pBackObj, m_pUnkOuter, m_pServer.
  268.  
  269.   Returns:  void
  270. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  271. CFCar::CImpIClassFactory::CImpIClassFactory(
  272.   CFCar* pBackObj,
  273.   IUnknown* pUnkOuter,
  274.   CServer* pServer)
  275. {
  276.   // Init the Interface Ref Count (used for debugging only).
  277.   m_cRefI = 0;
  278.  
  279.   // Init the Back Object Pointer to point to the parent object.
  280.   m_pBackObj = pBackObj;
  281.  
  282.   // Init the pointer to the server control object.
  283.   m_pServer = pServer;
  284.  
  285.   // Init the CImpIClassFactory interface's delegating Unknown pointer.
  286.   // We use the Back Object pointer for IUnknown delegation here if we are
  287.   // not being aggregated.  If we are being aggregated we use the supplied
  288.   // pUnkOuter for IUnknown delegation.  In either case the pointer
  289.   // assignment requires no AddRef because the CImpIClassFactory lifetime is
  290.   // quaranteed by the lifetime of the parent object in which
  291.   // CImpIClassFactory is nested.
  292.   if (NULL == pUnkOuter)
  293.   {
  294.     m_pUnkOuter = pBackObj;
  295.     LOG("S: CFCar::CImpIClassFactory Constructor. Non-Aggregating.");
  296.   }
  297.   else
  298.   {
  299.     m_pUnkOuter = pUnkOuter;
  300.     LOG("S: CFCar::CImpIClassFactory Constructor. Aggregating.");
  301.   }
  302.  
  303.   return;
  304. }
  305.  
  306.  
  307. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  308.   Method:   CFCar::CImpIClassFactory::~CImpIClassFactory
  309.  
  310.   Summary:  Destructor for the CImpIClassFactory interface instantiation.
  311.  
  312.   Args:     void
  313.  
  314.   Modifies: .
  315.  
  316.   Returns:  void
  317. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  318. CFCar::CImpIClassFactory::~CImpIClassFactory(void)
  319. {
  320.   LOG("S: CFCar::CImpIClassFactory Destructor.");
  321.  
  322.   return;
  323. }
  324.  
  325.  
  326. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  327.   Method:   CFCar::CImpIClassFactory::QueryInterface
  328.  
  329.   Summary:  The QueryInterface IUnknown member of this IClassFactory
  330.             interface implementation that delegates to m_pUnkOuter,
  331.             whatever it is.
  332.  
  333.   Args:     REFIID riid,
  334.               [in] GUID of the Interface being requested.
  335.             PPVOID ppv)
  336.               [out] Address of the caller's pointer variable that will
  337.               receive the requested interface pointer.
  338.  
  339.   Returns:  HRESULT
  340.               Standard result code. NOERROR for success.
  341.               Returned by the delegated outer QueryInterface call.
  342. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  343. STDMETHODIMP CFCar::CImpIClassFactory::QueryInterface(
  344.                REFIID riid,
  345.                PPVOID ppv)
  346. {
  347.   LOG("S: CFCar::CImpIClassFactory::QueryInterface. Delegating.");
  348.  
  349.   // Delegate this call to the outer object's QueryInterface.
  350.   return m_pUnkOuter->QueryInterface(riid, ppv);
  351. }
  352.  
  353.  
  354. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  355.   Method:   CFCar::CImpIClassFactory::AddRef
  356.  
  357.   Summary:  The AddRef IUnknown member of this IClassFactory interface
  358.             implementation that delegates to m_pUnkOuter, whatever it is.
  359.  
  360.   Args:     void
  361.  
  362.   Modifies: m_cRefI.
  363.  
  364.   Returns:  ULONG
  365.               Returned by the delegated outer AddRef call.
  366. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  367. STDMETHODIMP_(ULONG) CFCar::CImpIClassFactory::AddRef(void)
  368. {
  369.   // Increment the Interface Reference Count.
  370.   ++m_cRefI;
  371.  
  372.   LOGF1("S: CFCar::CImpIClassFactory::Addref. Delegating. New cI=%i.",m_cRefI);
  373.  
  374.   // Delegate this call to the outer object's AddRef.
  375.   return m_pUnkOuter->AddRef();
  376. }
  377.  
  378.  
  379. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  380.   Method:   CFCar::CImpIClassFactory::Release
  381.  
  382.   Summary:  The Release IUnknown member of this IClassFactory interface
  383.             implementation that delegates to m_pUnkOuter, whatever it is.
  384.  
  385.   Args:     void
  386.  
  387.   Modifies: .
  388.  
  389.   Returns:  ULONG
  390.               Returned by the delegated outer Release call.
  391. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  392. STDMETHODIMP_(ULONG) CFCar::CImpIClassFactory::Release(void)
  393. {
  394.   // Decrement the Interface Reference Count.
  395.   --m_cRefI;
  396.  
  397.   LOGF1("S: CFCar::CImpIClassFactory::Release. Delegating. New cI=%i.",m_cRefI);
  398.  
  399.   // Delegate this call to the outer object's Release.
  400.   return m_pUnkOuter->Release();
  401. }
  402.  
  403.  
  404. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  405.   Method:   CFCar::CImpIClassFactory::CreateInstance
  406.  
  407.   Summary:  The CreateInstance member method of this IClassFactory interface
  408.             implementation.  Creates an instance of the COCar COM
  409.             component.
  410.  
  411.   Args:     IUnknown* pUnkOuter,
  412.               [in] Pointer to the controlling IUnknown.
  413.             REFIID riid,
  414.               [in] GUID of the Interface being requested.
  415.             PPVOID ppvCob)
  416.               [out] Address of the caller's pointer variable that will
  417.               receive the requested interface pointer.
  418.  
  419.   Returns:  HRESULT
  420.               Standard result code. NOERROR for success.
  421. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  422. STDMETHODIMP CFCar::CImpIClassFactory::CreateInstance(
  423.                IUnknown* pUnkOuter,
  424.                REFIID riid,
  425.                PPVOID ppv)
  426. {
  427.   HRESULT hr = E_FAIL;
  428.   COCar* pCob = NULL;
  429.  
  430.   LOGF1("S: CFCar::CImpIClassFactory::CreateInstance. pUnkOuter=0x%X.",pUnkOuter);
  431.  
  432.   // NULL the output pointer.
  433.   *ppv = NULL;
  434.  
  435.   // If the creation call is requesting aggregation (pUnkOuter != NULL),
  436.   // the COM rules state the IUnknown interface MUST also be concomitantly
  437.   // be requested.  If it is not so requested (riid != IID_IUnknown) then
  438.   // an error must be returned indicating that no aggregate creation of
  439.   // the CFCar COM Object can be performed.
  440.   if (NULL != pUnkOuter && riid != IID_IUnknown)
  441.     hr = CLASS_E_NOAGGREGATION;
  442.   else
  443.   {
  444.     // Instantiate a COCar COM Object.
  445.     pCob = new COCar(pUnkOuter, m_pServer);
  446.     if (NULL != pCob)
  447.     {
  448.       // We initially created the new COM object so tell the server
  449.       // to increment its global server object count to help ensure
  450.       // that the server remains loaded until this partial creation
  451.       // of a COM component is completed.
  452.       m_pServer->ObjectsUp();
  453.  
  454.       // We QueryInterface this new COM Object not only to deposit the
  455.       // main interface pointer to the caller's pointer variable, but to
  456.       // also automatically bump the Reference Count on the new COM
  457.       // Object after handing out this reference to it.
  458.       hr = pCob->QueryInterface(riid, (PPVOID)ppv);
  459.       if (FAILED(hr))
  460.       {
  461.         m_pServer->ObjectsDown();
  462.         delete pCob;
  463.       }
  464.     }
  465.     else
  466.       hr = E_OUTOFMEMORY;
  467.   }
  468.  
  469.   if (SUCCEEDED(hr))
  470.   {
  471.     LOGF1("S: CFCar::CImpIClassFactory::CreateInstance Succeeded. *ppv=0x%X.",*ppv);
  472.   }
  473.   else
  474.   {
  475.     LOG("S: CFCar::CImpIClassFactory::CreateInstance Failed.");
  476.   }
  477.  
  478.   return hr;
  479. }
  480.  
  481.  
  482. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  483.   Method:   CFCar::CImpIClassFactory::LockServer
  484.  
  485.   Summary:  The LockServer member method of this IClassFactory interface
  486.             implementation.
  487.  
  488.   Args:     BOOL fLock)
  489.               [in] Flag determining whether to Lock or Unlock the server.
  490.  
  491.   Returns:  HRESULT
  492.               Standard result code. NOERROR for success.
  493. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  494. STDMETHODIMP CFCar::CImpIClassFactory::LockServer(
  495.                BOOL fLock)
  496. {
  497.   HRESULT hr = NOERROR;
  498.  
  499.   LOG("S: CFCar::CImpIClassFactory::LockServer.");
  500.  
  501.   if (fLock)
  502.     m_pServer->Lock();
  503.   else
  504.     m_pServer->Unlock();
  505.  
  506.   return hr;
  507. }
  508.  
  509.  
  510. /*---------------------------------------------------------------------------
  511.   Implementation the CFUtilityCar Class Factory.  CFUtilityCar is the COM
  512.   object class for the Class Factory that can manufacture COUtilityCar
  513.   COM Components.
  514. ---------------------------------------------------------------------------*/
  515.  
  516. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  517.   Method:   CFUtilityCar::CFUtilityCar
  518.  
  519.   Summary:  CFUtilityCar Constructor. Note the member initializer:
  520.             "m_ImpIClassFactory(this, pUnkOuter, pServer)" which is used
  521.             to pass the 'this', pUnkOuter, and pServer pointers of this
  522.             constructor function to the constructor executed in the
  523.             instantiation of the CImpIClassFactory interface whose
  524.             implementation is nested inside this present object class.
  525.  
  526.   Args:     IUnknown* pUnkOuter,
  527.               Pointer to the the outer Unknown.  NULL means this COM Object
  528.               is not being Aggregated.  Non NULL means it is being created
  529.               on behalf of an outside COM object that is reusing it via
  530.               aggregation.
  531.             CServer* pServer)
  532.               Pointer to the server's control object.
  533.  
  534.   Modifies: m_cRefs, m_pUnkOuter.
  535.  
  536.   Returns:  void
  537. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  538. CFUtilityCar::CFUtilityCar(
  539.   IUnknown* pUnkOuter,
  540.   CServer* pServer) :
  541.   m_ImpIClassFactory(this, pUnkOuter, pServer)
  542. {
  543.   // Zero the COM object's reference count.
  544.   m_cRefs = 0;
  545.  
  546.   // No AddRef necessary if non-NULL, as we're nested.
  547.   m_pUnkOuter = pUnkOuter;
  548.  
  549.   // Init the pointer to the server control object.
  550.   m_pServer = pServer;
  551.  
  552.   LOGF1("S: CFUtilityCar Constructor. m_pUnkOuter=0x%X.", m_pUnkOuter);
  553.  
  554.   return;
  555. }
  556.  
  557.  
  558. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  559.   Method:   CFUtilityCar::~CFUtilityCar
  560.  
  561.   Summary:  CFUtilityCar Destructor.
  562.  
  563.   Args:     void
  564.  
  565.   Modifies: .
  566.  
  567.   Returns:  void
  568. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  569. CFUtilityCar::~CFUtilityCar(void)
  570. {
  571.   LOG("S: CFUtilityCar::Destructor.");
  572.  
  573.   return;
  574. }
  575.  
  576.  
  577. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  578.   Method:   CFUtilityCar::QueryInterface
  579.  
  580.   Summary:  QueryInterface of the CFUtilityCar non-delegating
  581.             IUnknown implementation.
  582.  
  583.   Args:     REFIID riid,
  584.               [in] GUID of the Interface being requested.
  585.             PPVOID ppv)
  586.               [out] Address of the caller's pointer variable that will
  587.               receive the requested interface pointer.
  588.  
  589.   Returns:  HRESULT
  590.               Standard result code. NOERROR for success.
  591. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  592. STDMETHODIMP CFUtilityCar::QueryInterface(
  593.                REFIID riid,
  594.                PPVOID ppv)
  595. {
  596.   HRESULT hr = E_NOINTERFACE;
  597.   *ppv = NULL;
  598.  
  599.   if (IID_IUnknown == riid)
  600.   {
  601.     *ppv = this;
  602.     LOG("S: CFUtilityCar::QueryInterface. 'this' pIUnknown returned.");
  603.   }
  604.   else if (IID_IClassFactory == riid)
  605.   {
  606.     *ppv = &m_ImpIClassFactory;
  607.     LOG("S: CFUtilityCar::QueryInterface. pIClassFactory returned.");
  608.   }
  609.  
  610.   if (NULL != *ppv)
  611.   {
  612.     // We've handed out a pointer to the interface so obey the COM rules
  613.     //   and AddRef the reference count.
  614.     ((LPUNKNOWN)*ppv)->AddRef();
  615.     hr = NOERROR;
  616.   }
  617.  
  618.   return (hr);
  619. }
  620.  
  621.  
  622. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  623.   Method:   CFUtilityCar::AddRef
  624.  
  625.   Summary:  AddRef of the CFUtilityCar non-delegating IUnknown implementation.
  626.  
  627.   Args:     void
  628.  
  629.   Modifies: m_cRefs.
  630.  
  631.   Returns:  ULONG
  632.               New value of m_cRefs (COM object's reference count).
  633. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  634. STDMETHODIMP_(ULONG) CFUtilityCar::AddRef(void)
  635. {
  636.   m_cRefs++;
  637.  
  638.   LOGF1("S: CFUtilityCar::AddRef. New cRefs=%i.", m_cRefs);
  639.  
  640.   return m_cRefs;
  641. }
  642.  
  643.  
  644. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  645.   Method:   CFUtilityCar::Release
  646.  
  647.   Summary:  Release of the CFUtilityCar non-delegating IUnknown implementation.
  648.  
  649.   Args:     void
  650.  
  651.   Modifies: m_cRefs.
  652.  
  653.   Returns:  ULONG
  654.               New value of m_cRefs (COM object's reference count).
  655. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  656. STDMETHODIMP_(ULONG) CFUtilityCar::Release(void)
  657. {
  658.   m_cRefs--;
  659.  
  660.   LOGF1("S: CFUtilityCar::Release. New cRefs=%i.", m_cRefs);
  661.  
  662.   if (0 == m_cRefs)
  663.   {
  664.     // We've reached a zero reference count for this COM object.
  665.     // So we tell the server housing to decrement its global object
  666.     // count so that the server will be unloaded if appropriate.
  667.     if (NULL != m_pServer)
  668.       m_pServer->ObjectsDown();
  669.  
  670.     // We artificially bump the main ref count to prevent reentrancy
  671.     // via the main object destructor.  Not really needed in this
  672.     // CFUtilityCar but a good practice because we are aggregatable and
  673.     // may at some point in the future add something entertaining like
  674.     // some Releases to the CFUtilityCar destructor.
  675.     m_cRefs++;
  676.     delete this;
  677.   }
  678.  
  679.   return m_cRefs;
  680. }
  681.  
  682.  
  683. /*---------------------------------------------------------------------------
  684.   CFUtilityCar's nested implementation of the IClassFactory interface
  685.   including Constructor, Destructor, QueryInterface, AddRef, Release,
  686.   CreateInstance, and LockServer methods.
  687. ---------------------------------------------------------------------------*/
  688.  
  689. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  690.   Method:   CFUtilityCar::CImpIClassFactory::CImpIClassFactory
  691.  
  692.   Summary:  Constructor for the CImpIClassFactory interface instantiation.
  693.  
  694.   Args:     CFUtilityCar* pBackObj,
  695.               Back pointer to the parent outer object.
  696.             IUnknown* pUnkOuter,
  697.               Pointer to the outer Unknown.  For delegation.
  698.             CServer* pServer)
  699.               Pointer to the server's control object.
  700.  
  701.   Modifies: m_cRefI, m_pBackObj, m_pUnkOuter, m_pServer.
  702.  
  703.   Returns:  void
  704. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  705. CFUtilityCar::CImpIClassFactory::CImpIClassFactory(
  706.   CFUtilityCar* pBackObj,
  707.   IUnknown* pUnkOuter,
  708.   CServer* pServer)
  709. {
  710.   // Init the Interface Ref Count (used for debugging only).
  711.   m_cRefI = 0;
  712.  
  713.   // Init the Back Object Pointer to point to the parent object.
  714.   m_pBackObj = pBackObj;
  715.  
  716.   // Init the pointer to the server control object.
  717.   m_pServer = pServer;
  718.  
  719.   // Init the CImpIClassFactory interface's delegating Unknown pointer.
  720.   // We use the Back Object pointer for IUnknown delegation here if we are
  721.   // not being aggregated.  If we are being aggregated we use the supplied
  722.   // pUnkOuter for IUnknown delegation.  In either case the pointer
  723.   // assignment requires no AddRef because the CImpIClassFactory lifetime is
  724.   // quaranteed by the lifetime of the parent object in which
  725.   // CImpIClassFactory is nested.
  726.   if (NULL == pUnkOuter)
  727.   {
  728.     m_pUnkOuter = pBackObj;
  729.     LOG("S: CFUtilityCar::CImpIClassFactory Constructor. Non-Aggregating.");
  730.   }
  731.   else
  732.   {
  733.     m_pUnkOuter = pUnkOuter;
  734.     LOG("S: CFUtilityCar::CImpIClassFactory Constructor. Aggregating.");
  735.   }
  736.  
  737.   return;
  738. }
  739.  
  740.  
  741. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  742.   Method:   CFUtilityCar::CImpIClassFactory::~CImpIClassFactory
  743.  
  744.   Summary:  Destructor for the CImpIClassFactory interface instantiation.
  745.  
  746.   Args:     void
  747.  
  748.   Modifies: .
  749.  
  750.   Returns:  void
  751. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  752. CFUtilityCar::CImpIClassFactory::~CImpIClassFactory(void)
  753. {
  754.   LOG("S: CFUtilityCar::CImpIClassFactory Destructor.");
  755.  
  756.   return;
  757. }
  758.  
  759.  
  760. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  761.   Method:   CFUtilityCar::CImpIClassFactory::QueryInterface
  762.  
  763.   Summary:  The QueryInterface IUnknown member of this IClassFactory
  764.             interface implementation that delegates to m_pUnkOuter,
  765.             whatever it is.
  766.  
  767.   Args:     REFIID riid,
  768.               [in] GUID of the Interface being requested.
  769.             PPVOID ppv)
  770.               [out] Address of the caller's pointer variable that will
  771.               receive the requested interface pointer.
  772.  
  773.   Returns:  HRESULT
  774.               Standard result code. NOERROR for success.
  775.               Returned by the delegated outer QueryInterface call.
  776. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  777. STDMETHODIMP CFUtilityCar::CImpIClassFactory::QueryInterface(
  778.                REFIID riid,
  779.                PPVOID ppv)
  780. {
  781.   LOG("S: CFUtilityCar::CImpIClassFactory::QueryInterface. Delegating.");
  782.  
  783.   // Delegate this call to the outer object's QueryInterface.
  784.   return m_pUnkOuter->QueryInterface(riid, ppv);
  785. }
  786.  
  787.  
  788. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  789.   Method:   CFUtilityCar::CImpIClassFactory::AddRef
  790.  
  791.   Summary:  The AddRef IUnknown member of this IClassFactory interface
  792.             implementation that delegates to m_pUnkOuter, whatever it is.
  793.  
  794.   Args:     void
  795.  
  796.   Modifies: m_cRefI.
  797.  
  798.   Returns:  ULONG
  799.               Returned by the delegated outer AddRef call.
  800. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  801. STDMETHODIMP_(ULONG) CFUtilityCar::CImpIClassFactory::AddRef(void)
  802. {
  803.   // Increment the Interface Reference Count.
  804.   ++m_cRefI;
  805.  
  806.   LOGF1("S: CFUtilityCar::CImpIClassFactory::Addref. Delegating. New cI=%i.",m_cRefI);
  807.  
  808.   // Delegate this call to the outer object's AddRef.
  809.   return m_pUnkOuter->AddRef();
  810. }
  811.  
  812.  
  813. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  814.   Method:   CFUtilityCar::CImpIClassFactory::Release
  815.  
  816.   Summary:  The Release IUnknown member of this IClassFactory interface
  817.             implementation that delegates to m_pUnkOuter, whatever it is.
  818.  
  819.   Args:     void
  820.  
  821.   Modifies: .
  822.  
  823.   Returns:  ULONG
  824.               Returned by the delegated outer Release call.
  825. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  826. STDMETHODIMP_(ULONG) CFUtilityCar::CImpIClassFactory::Release(void)
  827. {
  828.   // Decrement the Interface Reference Count.
  829.   --m_cRefI;
  830.  
  831.   LOGF1("S: CFUtilityCar::CImpIClassFactory::Release. Delegating. New cI=%i.",m_cRefI);
  832.  
  833.   // Delegate this call to the outer object's Release.
  834.   return m_pUnkOuter->Release();
  835. }
  836.  
  837.  
  838. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  839.   Method:   CFUtilityCar::CImpIClassFactory::CreateInstance
  840.  
  841.   Summary:  The CreateInstance member method of this IClassFactory interface
  842.             implementation.  Creates an instance of the COUtilityCar COM
  843.             component.
  844.  
  845.   Args:     IUnknown* pUnkOuter,
  846.               [in] Pointer to the controlling IUnknown.
  847.             REFIID riid,
  848.               [in] GUID of the Interface being requested.
  849.             PPVOID ppvCob)
  850.               [out] Address of the caller's pointer variable that will
  851.               receive the requested interface pointer.
  852.  
  853.   Returns:  HRESULT
  854.               Standard result code. NOERROR for success.
  855. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  856. STDMETHODIMP CFUtilityCar::CImpIClassFactory::CreateInstance(
  857.                IUnknown* pUnkOuter,
  858.                REFIID riid,
  859.                PPVOID ppv)
  860. {
  861.   HRESULT hr = E_FAIL;
  862.   COUtilityCar* pCob = NULL;
  863.  
  864.   LOGF1("S: CFUtilityCar::CImpIClassFactory::CreateInstance. pUnkOuter=0x%X.",pUnkOuter);
  865.  
  866.   // If the creation call is requesting aggregation (pUnkOuter != NULL),
  867.   // the COM rules state the IUnknown interface MUST also be concomitantly
  868.   // be requested.  If it is not so requested ( riid != IID_IUnknown) then
  869.   // an error must be returned indicating that no aggregate creation of
  870.   // the COUtilityCar COM Object can be performed.
  871.   if (NULL != pUnkOuter && riid != IID_IUnknown)
  872.     hr = CLASS_E_NOAGGREGATION;
  873.   else
  874.   {
  875.     // Instantiate a COUtilityCar COM Object.
  876.     pCob = new COUtilityCar(pUnkOuter, m_pServer);
  877.     if (NULL != pCob)
  878.     {
  879.       // We initially created the new COM object so tell the server
  880.       // to increment its global server object count to help ensure
  881.       // that the server remains loaded until this partial creation
  882.       // of a COM component is completed.
  883.       m_pServer->ObjectsUp();
  884.  
  885.       // If we have succeeded in instantiating the COM object we
  886.       // initialize it to set up any subordinate objects.
  887.       hr = pCob->Init();
  888.       if (SUCCEEDED(hr))
  889.       {
  890.         // We QueryInterface this new COM Object not only to deposit the
  891.         // main interface pointer to the caller's pointer variable, but to
  892.         // also automatically bump the Reference Count on the new COM
  893.         // Object after handing out this reference to it.
  894.         hr = pCob->QueryInterface(riid, (PPVOID)ppv);
  895.       }
  896.  
  897.       if (FAILED(hr))
  898.       {
  899.         m_pServer->ObjectsDown();
  900.         delete pCob;
  901.       }
  902.     }
  903.     else
  904.       hr = E_OUTOFMEMORY;
  905.   }
  906.  
  907.   if (SUCCEEDED(hr))
  908.   {
  909.     LOGF1("S: CFUtilityCar::CImpIClassFactory::CreateInstance Succeeded. *ppv=0x%X.",*ppv);
  910.   }
  911.   else
  912.   {
  913.     LOG("S: CFUtilityCar::CImpIClassFactory::CreateInstance Failed.");
  914.   }
  915.  
  916.   return hr;
  917. }
  918.  
  919.  
  920. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  921.   Method:   CFUtilityCar::CImpIClassFactory::LockServer
  922.  
  923.   Summary:  The LockServer member method of this IClassFactory interface
  924.             implementation.
  925.  
  926.   Args:     BOOL fLock)
  927.               [in] Flag determining whether to Lock or Unlock the server.
  928.  
  929.   Returns:  HRESULT
  930.               Standard result code. NOERROR for success.
  931. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  932. STDMETHODIMP CFUtilityCar::CImpIClassFactory::LockServer(
  933.                BOOL fLock)
  934. {
  935.   HRESULT hr = NOERROR;
  936.  
  937.   LOG("S: CFUtilityCar::CImpIClassFactory::LockServer.");
  938.  
  939.   if (fLock)
  940.     m_pServer->Lock();
  941.   else
  942.     m_pServer->Unlock();
  943.  
  944.   return hr;
  945. }
  946.  
  947.  
  948. /*---------------------------------------------------------------------------
  949.   Implementation the CFCruiseCar Class Factory.  CFCruiseCar is the COM
  950.   object class for the Class Factory that can manufacture COCruiseCar
  951.   COM Components.
  952. ---------------------------------------------------------------------------*/
  953.  
  954. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  955.   Method:   CFCruiseCar::CFCruiseCar
  956.  
  957.   Summary:  CFCruiseCar Constructor. Note the member initializer:
  958.             "m_ImpIClassFactory(this, pUnkOuter, pServer)" which is used
  959.             to pass the 'this', pUnkOuter, and pServer pointers of this
  960.             constructor function to the constructor executed in the
  961.             instantiation of the CImpIClassFactory interface whose
  962.             implementation is nested inside this present object class.
  963.  
  964.   Args:     IUnknown* pUnkOuter,
  965.               Pointer to the the outer Unknown.  NULL means this COM Object
  966.               is not being Aggregated.  Non NULL means it is being created
  967.               on behalf of an outside COM object that is reusing it via
  968.               aggregation.
  969.             CServer* pServer)
  970.               Pointer to the server's control object.
  971.  
  972.   Modifies: m_cRefs, m_pUnkOuter, m_pServer.
  973.  
  974.   Returns:  void
  975. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  976. CFCruiseCar::CFCruiseCar(
  977.   IUnknown* pUnkOuter,
  978.   CServer* pServer) :
  979.   m_ImpIClassFactory(this, pUnkOuter, pServer)
  980. {
  981.   // Zero the COM object's reference count.
  982.   m_cRefs = 0;
  983.  
  984.   // No AddRef necessary if non-NULL, as we're nested.
  985.   m_pUnkOuter = pUnkOuter;
  986.  
  987.   // Init the pointer to the server control object.
  988.   m_pServer = pServer;
  989.  
  990.   LOGF1("S: CFCruiseCar Constructor. m_pUnkOuter=0x%X.", m_pUnkOuter);
  991.  
  992.   return;
  993. }
  994.  
  995.  
  996. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  997.   Method:   CFCruiseCar::~CFCruiseCar
  998.  
  999.   Summary:  CFCruiseCar Destructor.
  1000.  
  1001.   Args:     void
  1002.  
  1003.   Modifies: .
  1004.  
  1005.   Returns:  void
  1006. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  1007. CFCruiseCar::~CFCruiseCar(void)
  1008. {
  1009.   LOG("S: CFCruiseCar::Destructor.");
  1010.  
  1011.   return;
  1012. }
  1013.  
  1014.  
  1015. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  1016.   Method:   CFCruiseCar::QueryInterface
  1017.  
  1018.   Summary:  QueryInterface of the CFCruiseCar non-delegating
  1019.             IUnknown implementation.
  1020.  
  1021.   Args:     REFIID riid,
  1022.               [in] GUID of the Interface being requested.
  1023.             PPVOID ppv)
  1024.               [out] Address of the caller's pointer variable that will
  1025.               receive the requested interface pointer.
  1026.  
  1027.   Returns:  HRESULT
  1028.               Standard result code. NOERROR for success.
  1029. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  1030. STDMETHODIMP CFCruiseCar::QueryInterface(
  1031.                REFIID riid,
  1032.                PPVOID ppv)
  1033. {
  1034.   HRESULT hr = E_NOINTERFACE;
  1035.   *ppv = NULL;
  1036.  
  1037.   if (IID_IUnknown == riid)
  1038.   {
  1039.     *ppv = this;
  1040.     LOG("S: CFCruiseCar::QueryInterface. 'this' pIUnknown returned.");
  1041.   }
  1042.   else if (IID_IClassFactory == riid)
  1043.   {
  1044.     *ppv = &m_ImpIClassFactory;
  1045.     LOG("S: CFCruiseCar::QueryInterface. pIClassFactory returned.");
  1046.   }
  1047.  
  1048.   if (NULL != *ppv)
  1049.   {
  1050.     // We've handed out a pointer to the interface so obey the COM rules
  1051.     //   and AddRef the reference count.
  1052.     ((LPUNKNOWN)*ppv)->AddRef();
  1053.     hr = NOERROR;
  1054.   }
  1055.  
  1056.   return (hr);
  1057. }
  1058.  
  1059.  
  1060. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  1061.   Method:   CFCruiseCar::AddRef
  1062.  
  1063.   Summary:  AddRef of the CFCruiseCar non-delegating IUnknown implementation.
  1064.  
  1065.   Args:     void
  1066.  
  1067.   Modifies: m_cRefs.
  1068.  
  1069.   Returns:  ULONG
  1070.               New value of m_cRefs (COM object's reference count).
  1071. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  1072. STDMETHODIMP_(ULONG) CFCruiseCar::AddRef(void)
  1073. {
  1074.   m_cRefs++;
  1075.  
  1076.   LOGF1("S: CFCruiseCar::AddRef. New cRefs=%i.", m_cRefs);
  1077.  
  1078.   return m_cRefs;
  1079. }
  1080.  
  1081.  
  1082. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  1083.   Method:   CFCruiseCar::Release
  1084.  
  1085.   Summary:  Release of the CFCruiseCar non-delegating IUnknown implementation.
  1086.  
  1087.   Args:     void
  1088.  
  1089.   Modifies: m_cRefs.
  1090.  
  1091.   Returns:  ULONG
  1092.               New value of m_cRefs (COM object's reference count).
  1093. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  1094. STDMETHODIMP_(ULONG) CFCruiseCar::Release(void)
  1095. {
  1096.   m_cRefs--;
  1097.  
  1098.   LOGF1("S: CFCruiseCar::Release. New cRefs=%i.", m_cRefs);
  1099.  
  1100.   if (0 == m_cRefs)
  1101.   {
  1102.     // We've reached a zero reference count for this COM object.
  1103.     // So we tell the server housing to decrement its global object
  1104.     // count so that the server will be unloaded if appropriate.
  1105.     if (NULL != m_pServer)
  1106.       m_pServer->ObjectsDown();
  1107.  
  1108.     // We artificially bump the main ref count to prevent reentrancy
  1109.     // via the main object destructor.  Not really needed in this
  1110.     // CFCruiseCar but a good practice because we are aggregatable and
  1111.     // may at some point in the future add something entertaining like
  1112.     // some Releases to the CFCruiseCar destructor.
  1113.     m_cRefs++;
  1114.     delete this;
  1115.   }
  1116.  
  1117.   return m_cRefs;
  1118. }
  1119.  
  1120.  
  1121. /*---------------------------------------------------------------------------
  1122.   CFCruiseCar's nested implementation of the IClassFactory interface
  1123.   including Constructor, Destructor, QueryInterface, AddRef, Release,
  1124.   CreateInstance, and LockServer methods.
  1125. ---------------------------------------------------------------------------*/
  1126.  
  1127. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  1128.   Method:   CFCruiseCar::CImpIClassFactory::CImpIClassFactory
  1129.  
  1130.   Summary:  Constructor for the CImpIClassFactory interface instantiation.
  1131.  
  1132.   Args:     CFCruiseCar* pBackObj,
  1133.               Back pointer to the parent outer object.
  1134.             IUnknown* pUnkOuter,
  1135.               Pointer to the outer Unknown.  For delegation.
  1136.             CServer* pServer)
  1137.               Pointer to the server's control object.
  1138.  
  1139.   Modifies: m_cRefI, m_pBackObj, m_pUnkOuter, m_pServer.
  1140.  
  1141.   Returns:  void
  1142. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  1143. CFCruiseCar::CImpIClassFactory::CImpIClassFactory(
  1144.   CFCruiseCar* pBackObj,
  1145.   IUnknown* pUnkOuter,
  1146.   CServer* pServer)
  1147. {
  1148.   // Init the Interface Ref Count (used for debugging only).
  1149.   m_cRefI = 0;
  1150.  
  1151.   // Init the Back Object Pointer to point to the parent object.
  1152.   m_pBackObj = pBackObj;
  1153.  
  1154.   // Init the pointer to the server control object.
  1155.   m_pServer = pServer;
  1156.  
  1157.   // Init the CImpIClassFactory interface's delegating Unknown pointer.
  1158.   // We use the Back Object pointer for IUnknown delegation here if we are
  1159.   // not being aggregated.  If we are being aggregated we use the supplied
  1160.   // pUnkOuter for IUnknown delegation.  In either case the pointer
  1161.   // assignment requires no AddRef because the CImpIClassFactory lifetime is
  1162.   // quaranteed by the lifetime of the parent object in which
  1163.   // CImpIClassFactory is nested.
  1164.   if (NULL == pUnkOuter)
  1165.   {
  1166.     m_pUnkOuter = pBackObj;
  1167.     LOG("S: CFCruiseCar::CImpIClassFactory Constructor. Non-Aggregating.");
  1168.   }
  1169.   else
  1170.   {
  1171.     m_pUnkOuter = pUnkOuter;
  1172.     LOG("S: CFCruiseCar::CImpIClassFactory Constructor. Aggregating.");
  1173.   }
  1174.  
  1175.   return;
  1176. }
  1177.  
  1178.  
  1179. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  1180.   Method:   CFCruiseCar::CImpIClassFactory::~CImpIClassFactory
  1181.  
  1182.   Summary:  Destructor for the CImpIClassFactory interface instantiation.
  1183.  
  1184.   Args:     void
  1185.  
  1186.   Modifies: .
  1187.  
  1188.   Returns:  void
  1189. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  1190. CFCruiseCar::CImpIClassFactory::~CImpIClassFactory(void)
  1191. {
  1192.   LOG("S: CFCruiseCar::CImpIClassFactory Destructor.");
  1193.  
  1194.   return;
  1195. }
  1196.  
  1197.  
  1198. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  1199.   Method:   CFCruiseCar::CImpIClassFactory::QueryInterface
  1200.  
  1201.   Summary:  The QueryInterface IUnknown member of this IClassFactory
  1202.             interface implementation that delegates to m_pUnkOuter,
  1203.             whatever it is.
  1204.  
  1205.   Args:     REFIID riid,
  1206.               [in] GUID of the Interface being requested.
  1207.             PPVOID ppv)
  1208.               [out] Address of the caller's pointer variable that will
  1209.               receive the requested interface pointer.
  1210.  
  1211.   Returns:  HRESULT
  1212.               Standard result code. NOERROR for success.
  1213.               Returned by the delegated outer QueryInterface call.
  1214. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  1215. STDMETHODIMP CFCruiseCar::CImpIClassFactory::QueryInterface(
  1216.                REFIID riid,
  1217.                PPVOID ppv)
  1218. {
  1219.   LOG("S: CFCruiseCar::CImpIClassFactory::QueryInterface. Delegating.");
  1220.  
  1221.   // Delegate this call to the outer object's QueryInterface.
  1222.   return m_pUnkOuter->QueryInterface(riid, ppv);
  1223. }
  1224.  
  1225.  
  1226. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  1227.   Method:   CFCruiseCar::CImpIClassFactory::AddRef
  1228.  
  1229.   Summary:  The AddRef IUnknown member of this IClassFactory interface
  1230.             implementation that delegates to m_pUnkOuter, whatever it is.
  1231.  
  1232.   Args:     void
  1233.  
  1234.   Modifies: m_cRefI.
  1235.  
  1236.   Returns:  ULONG
  1237.               Returned by the delegated outer AddRef call.
  1238. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  1239. STDMETHODIMP_(ULONG) CFCruiseCar::CImpIClassFactory::AddRef(void)
  1240. {
  1241.   // Increment the Interface Reference Count.
  1242.   ++m_cRefI;
  1243.  
  1244.   LOGF1("S: CFCruiseCar::CImpIClassFactory::Addref. Delegating. New cI=%i.",m_cRefI);
  1245.  
  1246.   // Delegate this call to the outer object's AddRef.
  1247.   return m_pUnkOuter->AddRef();
  1248. }
  1249.  
  1250.  
  1251. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  1252.   Method:   CFCruiseCar::CImpIClassFactory::Release
  1253.  
  1254.   Summary:  The Release IUnknown member of this IClassFactory interface
  1255.             implementation that delegates to m_pUnkOuter, whatever it is.
  1256.  
  1257.   Args:     void
  1258.  
  1259.   Modifies: .
  1260.  
  1261.   Returns:  ULONG
  1262.               Returned by the delegated outer Release call.
  1263. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  1264. STDMETHODIMP_(ULONG) CFCruiseCar::CImpIClassFactory::Release(void)
  1265. {
  1266.   // Decrement the Interface Reference Count.
  1267.   --m_cRefI;
  1268.  
  1269.   LOGF1("S: CFCruiseCar::CImpIClassFactory::Release. Delegating. New cI=%i.",m_cRefI);
  1270.  
  1271.   // Delegate this call to the outer object's Release.
  1272.   return m_pUnkOuter->Release();
  1273. }
  1274.  
  1275.  
  1276. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  1277.   Method:   CFCruiseCar::CImpIClassFactory::CreateInstance
  1278.  
  1279.   Summary:  The CreateInstance member method of this IClassFactory interface
  1280.             implementation.  Creates an instance of the COCruiseCar COM
  1281.             component.
  1282.  
  1283.   Args:     IUnknown* pUnkOuter,
  1284.               [in] Pointer to the controlling IUnknown.
  1285.             REFIID riid,
  1286.               [in] GUID of the Interface being requested.
  1287.             PPVOID ppvCob)
  1288.               [out] Address of the caller's pointer variable that will
  1289.               receive the requested interface pointer.
  1290.  
  1291.   Returns:  HRESULT
  1292.               Standard result code. NOERROR for success.
  1293. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  1294. STDMETHODIMP CFCruiseCar::CImpIClassFactory::CreateInstance(
  1295.                IUnknown* pUnkOuter,
  1296.                REFIID riid,
  1297.                PPVOID ppv)
  1298. {
  1299.   HRESULT hr = E_FAIL;
  1300.   COCruiseCar* pCob = NULL;
  1301.  
  1302.   LOGF1("S: CFCruiseCar::CImpIClassFactory::CreateInstance. pUnkOuter=0x%X.",pUnkOuter);
  1303.  
  1304.   // If the creation call is requesting aggregation (pUnkOuter != NULL),
  1305.   // the COM rules state the IUnknown interface MUST also be concomitantly
  1306.   // be requested.  If it is not so requested ( riid != IID_IUnknown) then
  1307.   // an error must be returned indicating that no aggregate creation of
  1308.   // the COCruiseCarFactory COM Object can be performed.
  1309.   if (NULL != pUnkOuter && riid != IID_IUnknown)
  1310.     hr = CLASS_E_NOAGGREGATION;
  1311.   else
  1312.   {
  1313.     // Instantiate a COCruiseCar COM Object.
  1314.     pCob = new COCruiseCar(pUnkOuter, m_pServer);
  1315.     if (NULL != pCob)
  1316.     {
  1317.       // We initially created the new COM object so tell the server
  1318.       // to increment its global server object count to help ensure
  1319.       // that the server remains loaded until this partial creation
  1320.       // of a COM component is completed.
  1321.       m_pServer->ObjectsUp();
  1322.  
  1323.       // If we have succeeded in instantiating the COM object we
  1324.       // initialize it to set up any subordinate objects.
  1325.       hr = pCob->Init();
  1326.       if (SUCCEEDED(hr))
  1327.       {
  1328.         // We QueryInterface this new COM Object not only to deposit the
  1329.         // main interface pointer to the caller's pointer variable, but to
  1330.         // also automatically bump the Reference Count on the new COM
  1331.         // Object after handing out this reference to it.
  1332.         hr = pCob->QueryInterface(riid, (PPVOID)ppv);
  1333.       }
  1334.  
  1335.       if (FAILED(hr))
  1336.       {
  1337.         m_pServer->ObjectsDown();
  1338.         delete pCob;
  1339.       }
  1340.     }
  1341.     else
  1342.       hr = E_OUTOFMEMORY;
  1343.   }
  1344.  
  1345.   if (SUCCEEDED(hr))
  1346.   {
  1347.     LOGF1("S: CFCruiseCar::CImpIClassFactory::CreateInstance Succeeded. *ppv=0x%X.",*ppv);
  1348.   }
  1349.   else
  1350.   {
  1351.     LOG("S: CFCruiseCar::CImpIClassFactory::CreateInstance Failed.");
  1352.   }
  1353.  
  1354.   return hr;
  1355. }
  1356.  
  1357.  
  1358. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  1359.   Method:   CFCruiseCar::CImpIClassFactory::LockServer
  1360.  
  1361.   Summary:  The LockServer member method of this IClassFactory interface
  1362.             implementation.
  1363.  
  1364.   Args:     BOOL fLock)
  1365.               [in] Flag determining whether to Lock or Unlock the server.
  1366.  
  1367.   Returns:  HRESULT
  1368.               Standard result code. NOERROR for success.
  1369. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  1370. STDMETHODIMP CFCruiseCar::CImpIClassFactory::LockServer(
  1371.                BOOL fLock)
  1372. {
  1373.   HRESULT hr = NOERROR;
  1374.  
  1375.   LOG("S: CFCruiseCar::CImpIClassFactory::LockServer.");
  1376.  
  1377.   if (fLock)
  1378.     m_pServer->Lock();
  1379.   else
  1380.     m_pServer->Unlock();
  1381.  
  1382.   return hr;
  1383. }
  1384.  
  1385.  
  1386. /*---------------------------------------------------------------------------
  1387.   Implementation the CFCarSample Class Factory.  CFCarSample is the COM
  1388.   object class for the Class Factory that can manufacture COCarSample
  1389.   COM Components.
  1390. ---------------------------------------------------------------------------*/
  1391.  
  1392. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  1393.   Method:   CFCarSample::CFCarSample
  1394.  
  1395.   Summary:  CFCruiseCar Constructor. Note the member initializer:
  1396.             "m_ImpIClassFactory(this, pUnkOuter, pServer)" which is used
  1397.             to pass the 'this', pUnkOuter, and pServer pointers of this
  1398.             constructor function to the constructor executed in the
  1399.             instantiation of the CImpIClassFactory interface whose
  1400.             implementation is nested inside this present object class.
  1401.  
  1402.   Args:     IUnknown* pUnkOuter,
  1403.               Pointer to the the outer Unknown.  NULL means this COM Object
  1404.               is not being Aggregated.  Non NULL means it is being created
  1405.               on behalf of an outside COM object that is reusing it via
  1406.               aggregation.
  1407.             CServer* pServer)
  1408.               Pointer to the server's control object.
  1409.  
  1410.   Modifies: m_cRefs, m_pUnkOuter.
  1411.  
  1412.   Returns:  void
  1413. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  1414. CFCarSample::CFCarSample(
  1415.   IUnknown* pUnkOuter,
  1416.   CServer* pServer) :
  1417.   m_ImpIClassFactory(this, pUnkOuter, pServer)
  1418. {
  1419.   // Zero the COM object's reference count.
  1420.   m_cRefs = 0;
  1421.  
  1422.   // No AddRef necessary if non-NULL, as we're nested.
  1423.   m_pUnkOuter = pUnkOuter;
  1424.  
  1425.   // Init the pointer to the server control object.
  1426.   m_pServer = pServer;
  1427.  
  1428.   LOGF1("S: CFCarSample Constructor. m_pUnkOuter=0x%X.", m_pUnkOuter);
  1429.  
  1430.   return;
  1431. }
  1432.  
  1433.  
  1434. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  1435.   Method:   CFCarSample::~CFCarSample
  1436.  
  1437.   Summary:  CFCarSample Destructor.
  1438.  
  1439.   Args:     void
  1440.  
  1441.   Modifies: .
  1442.  
  1443.   Returns:  void
  1444. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  1445. CFCarSample::~CFCarSample(void)
  1446. {
  1447.   LOG("S: CFCarSample::Destructor.");
  1448.  
  1449.   return;
  1450. }
  1451.  
  1452.  
  1453. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  1454.   Method:   CFCarSample::QueryInterface
  1455.  
  1456.   Summary:  QueryInterface of the CFCarSample non-delegating
  1457.             IUnknown implementation.
  1458.  
  1459.   Args:     REFIID riid,
  1460.               [in] GUID of the Interface being requested.
  1461.             PPVOID ppv)
  1462.               [out] Address of the caller's pointer variable that will
  1463.               receive the requested interface pointer.
  1464.  
  1465.   Returns:  HRESULT
  1466.               Standard result code. NOERROR for success.
  1467. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  1468. STDMETHODIMP CFCarSample::QueryInterface(
  1469.                REFIID riid,
  1470.                PPVOID ppv)
  1471. {
  1472.   HRESULT hr = E_NOINTERFACE;
  1473.   *ppv = NULL;
  1474.  
  1475.   if (IID_IUnknown == riid)
  1476.   {
  1477.     *ppv = this;
  1478.     LOG("S: CFCarSample::QueryInterface. 'this' pIUnknown returned.");
  1479.   }
  1480.   else if (IID_IClassFactory == riid)
  1481.   {
  1482.     *ppv = &m_ImpIClassFactory;
  1483.     LOG("S: CFCarSample::QueryInterface. pIClassFactory returned.");
  1484.   }
  1485.  
  1486.   if (NULL != *ppv)
  1487.   {
  1488.     // We've handed out a pointer to the interface so obey the COM rules
  1489.     //   and AddRef the reference count.
  1490.     ((LPUNKNOWN)*ppv)->AddRef();
  1491.     hr = NOERROR;
  1492.   }
  1493.  
  1494.   return (hr);
  1495. }
  1496.  
  1497.  
  1498. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  1499.   Method:   CFCarSample::AddRef
  1500.  
  1501.   Summary:  AddRef of the CFCarSample non-delegating IUnknown implementation.
  1502.  
  1503.   Args:     void
  1504.  
  1505.   Modifies: m_cRefs.
  1506.  
  1507.   Returns:  ULONG
  1508.               New value of m_cRefs (COM object's reference count).
  1509. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  1510. STDMETHODIMP_(ULONG) CFCarSample::AddRef(void)
  1511. {
  1512.   m_cRefs++;
  1513.  
  1514.   LOGF1("S: CFCarSample::AddRef. New cRefs=%i.", m_cRefs);
  1515.  
  1516.   return m_cRefs;
  1517. }
  1518.  
  1519.  
  1520. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  1521.   Method:   CFCarSample::Release
  1522.  
  1523.   Summary:  Release of the CFCarSample non-delegating IUnknown implementation.
  1524.  
  1525.   Args:     void
  1526.  
  1527.   Modifies: m_cRefs.
  1528.  
  1529.   Returns:  ULONG
  1530.               New value of m_cRefs (COM object's reference count).
  1531. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  1532. STDMETHODIMP_(ULONG) CFCarSample::Release(void)
  1533. {
  1534.   m_cRefs--;
  1535.  
  1536.   LOGF1("S: CFCarSample::Release. New cRefs=%i.", m_cRefs);
  1537.  
  1538.   if (0 == m_cRefs)
  1539.   {
  1540.     // We've reached a zero reference count for this COM object.
  1541.     // So we tell the server housing to decrement its global object
  1542.     // count so that the server will be unloaded if appropriate.
  1543.     if (NULL != m_pServer)
  1544.       m_pServer->ObjectsDown();
  1545.  
  1546.     // We artificially bump the main ref count to prevent reentrancy
  1547.     // via the main object destructor.  Not really needed in this
  1548.     // CFCarSample but a good practice because we are aggregatable and
  1549.     // may at some point in the future add something entertaining like
  1550.     // some Releases to the CFCarSample destructor.
  1551.     m_cRefs++;
  1552.     delete this;
  1553.   }
  1554.  
  1555.   return m_cRefs;
  1556. }
  1557.  
  1558.  
  1559. /*---------------------------------------------------------------------------
  1560.   CFCarSample's nested implementation of the IClassFactory interface
  1561.   including Constructor, Destructor, QueryInterface, AddRef, Release,
  1562.   CreateInstance, and LockServer methods.
  1563. ---------------------------------------------------------------------------*/
  1564.  
  1565. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  1566.   Method:   CFCarSample::CImpIClassFactory::CImpIClassFactory
  1567.  
  1568.   Summary:  Constructor for the CImpIClassFactory interface instantiation.
  1569.  
  1570.   Args:     CFCarSample* pBackObj,
  1571.               Back pointer to the parent outer object.
  1572.             IUnknown* pUnkOuter,
  1573.               Pointer to the outer Unknown.  For delegation.
  1574.             CServer* pServer)
  1575.               Pointer to the server's control object.
  1576.  
  1577.   Modifies: m_cRefI, m_pBackObj, m_pUnkOuter, m_pServer.
  1578.  
  1579.   Returns:  void
  1580. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  1581. CFCarSample::CImpIClassFactory::CImpIClassFactory(
  1582.   CFCarSample* pBackObj,
  1583.   IUnknown* pUnkOuter,
  1584.   CServer* pServer)
  1585. {
  1586.   // Init the Interface Ref Count (used for debugging only).
  1587.   m_cRefI = 0;
  1588.  
  1589.   // Init the Back Object Pointer to point to the parent object.
  1590.   m_pBackObj = pBackObj;
  1591.  
  1592.   // Init the pointer to the server control object.
  1593.   m_pServer = pServer;
  1594.  
  1595.   // Init the CImpIClassFactory interface's delegating Unknown pointer.
  1596.   // We use the Back Object pointer for IUnknown delegation here if we are
  1597.   // not being aggregated.  If we are being aggregated we use the supplied
  1598.   // pUnkOuter for IUnknown delegation.  In either case the pointer
  1599.   // assignment requires no AddRef because the CImpIClassFactory lifetime is
  1600.   // quaranteed by the lifetime of the parent object in which
  1601.   // CImpIClassFactory is nested.
  1602.   if (NULL == pUnkOuter)
  1603.   {
  1604.     m_pUnkOuter = pBackObj;
  1605.     LOG("S: CFCarSample::CImpIClassFactory Constructor. Non-Aggregating.");
  1606.   }
  1607.   else
  1608.   {
  1609.     m_pUnkOuter = pUnkOuter;
  1610.     LOG("S: CFCarSample::CImpIClassFactory Constructor. Aggregating.");
  1611.   }
  1612.  
  1613.   return;
  1614. }
  1615.  
  1616.  
  1617. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  1618.   Method:   CFCarSample::CImpIClassFactory::~CImpIClassFactory
  1619.  
  1620.   Summary:  Destructor for the CImpIClassFactory interface instantiation.
  1621.  
  1622.   Args:     void
  1623.  
  1624.   Modifies: .
  1625.  
  1626.   Returns:  void
  1627. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  1628. CFCarSample::CImpIClassFactory::~CImpIClassFactory(void)
  1629. {
  1630.   LOG("S: CFCarSample::CImpIClassFactory Destructor.");
  1631.  
  1632.   return;
  1633. }
  1634.  
  1635.  
  1636. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  1637.   Method:   CFCarSample::CImpIClassFactory::QueryInterface
  1638.  
  1639.   Summary:  The QueryInterface IUnknown member of this IClassFactory
  1640.             interface implementation that delegates to m_pUnkOuter,
  1641.             whatever it is.
  1642.  
  1643.   Args:     REFIID riid,
  1644.               [in] GUID of the Interface being requested.
  1645.             PPVOID ppv)
  1646.               [out] Address of the caller's pointer variable that will
  1647.               receive the requested interface pointer.
  1648.  
  1649.   Returns:  HRESULT
  1650.               Standard result code. NOERROR for success.
  1651.               Returned by the delegated outer QueryInterface call.
  1652. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  1653. STDMETHODIMP CFCarSample::CImpIClassFactory::QueryInterface(
  1654.                REFIID riid,
  1655.                PPVOID ppv)
  1656. {
  1657.   LOG("S: CFCarSample::CImpIClassFactory::QueryInterface. Delegating.");
  1658.  
  1659.   // Delegate this call to the outer object's QueryInterface.
  1660.   return m_pUnkOuter->QueryInterface(riid, ppv);
  1661. }
  1662.  
  1663.  
  1664. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  1665.   Method:   CFCarSample::CImpIClassFactory::AddRef
  1666.  
  1667.   Summary:  The AddRef IUnknown member of this IClassFactory interface
  1668.             implementation that delegates to m_pUnkOuter, whatever it is.
  1669.  
  1670.   Args:     void
  1671.  
  1672.   Modifies: m_cRefI.
  1673.  
  1674.   Returns:  ULONG
  1675.               Returned by the delegated outer AddRef call.
  1676. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  1677. STDMETHODIMP_(ULONG) CFCarSample::CImpIClassFactory::AddRef(void)
  1678. {
  1679.   // Increment the Interface Reference Count.
  1680.   ++m_cRefI;
  1681.  
  1682.   LOGF1("S: CFCarSample::CImpIClassFactory::Addref. Delegating. New cI=%i.",m_cRefI);
  1683.  
  1684.   // Delegate this call to the outer object's AddRef.
  1685.   return m_pUnkOuter->AddRef();
  1686. }
  1687.  
  1688.  
  1689. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  1690.   Method:   CFCarSample::CImpIClassFactory::Release
  1691.  
  1692.   Summary:  The Release IUnknown member of this IClassFactory interface
  1693.             implementation that delegates to m_pUnkOuter, whatever it is.
  1694.  
  1695.   Args:     void
  1696.  
  1697.   Modifies: .
  1698.  
  1699.   Returns:  ULONG
  1700.               Returned by the delegated outer Release call.
  1701. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  1702. STDMETHODIMP_(ULONG) CFCarSample::CImpIClassFactory::Release(void)
  1703. {
  1704.   // Decrement the Interface Reference Count.
  1705.   --m_cRefI;
  1706.  
  1707.   LOGF1("S: CFCarSample::CImpIClassFactory::Release. Delegating. New cI=%i.",m_cRefI);
  1708.  
  1709.   // Delegate this call to the outer object's Release.
  1710.   return m_pUnkOuter->Release();
  1711. }
  1712.  
  1713.  
  1714. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  1715.   Method:   CFCarSample::CImpIClassFactory::CreateInstance
  1716.  
  1717.   Summary:  The CreateInstance member method of this IClassFactory
  1718.             interface implementation.  Creates an instance of the
  1719.             COCarSample COM component.
  1720.  
  1721.   Args:     IUnknown* pUnkOuter,
  1722.               [in] Pointer to the controlling IUnknown.
  1723.             REFIID riid,
  1724.               [in] GUID of the Interface being requested.
  1725.             PPVOID ppv)
  1726.               [out] Address of the caller's pointer variable that will
  1727.               receive the requested interface pointer.
  1728.  
  1729.   Returns:  HRESULT
  1730.               Standard result code. NOERROR for success.
  1731. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  1732. STDMETHODIMP CFCarSample::CImpIClassFactory::CreateInstance(
  1733.                IUnknown* pUnkOuter,
  1734.                REFIID riid,
  1735.                PPVOID ppv)
  1736. {
  1737.   HRESULT hr = E_FAIL;
  1738.   COCarSample* pCob = NULL;
  1739.  
  1740.   LOGF1("S: CFCarSample::CImpIClassFactory::CreateInstance. pUnkOuter=0x%X.",pUnkOuter);
  1741.  
  1742.   // If the creation call is requesting aggregation (pUnkOuter != NULL),
  1743.   // the COM rules state the IUnknown interface MUST also be concomitantly
  1744.   // be requested.  If it is not so requested ( riid != IID_IUnknown) then
  1745.   // an error must be returned indicating that no aggregate creation of
  1746.   // the CFCarSample COM Object can be performed.
  1747.   if (NULL != pUnkOuter && riid != IID_IUnknown)
  1748.     hr = CLASS_E_NOAGGREGATION;
  1749.   else
  1750.   {
  1751.     // Instantiate a COCarSample COM Object.
  1752.     pCob = new COCarSample(pUnkOuter, m_pServer);
  1753.     if (NULL != pCob)
  1754.     {
  1755.       // We initially created the new COM object so tell the server
  1756.       // to increment its global server object count to help ensure
  1757.       // that the server remains loaded until this partial creation
  1758.       // of a COM component is completed.
  1759.       m_pServer->ObjectsUp();
  1760.  
  1761.       // We QueryInterface this new COM Object not only to deposit the
  1762.       // main interface pointer to the caller's pointer variable, but to
  1763.       // also automatically bump the Reference Count on the new COM
  1764.       // Object after handing out this reference to it.
  1765.       hr = pCob->QueryInterface(riid, (PPVOID)ppv);
  1766.       if (FAILED(hr))
  1767.       {
  1768.         m_pServer->ObjectsDown();
  1769.         delete pCob;
  1770.       }
  1771.     }
  1772.     else
  1773.       hr = E_OUTOFMEMORY;
  1774.   }
  1775.  
  1776.   if (SUCCEEDED(hr))
  1777.   {
  1778.     LOGF1("S: CFCarSample::CImpIClassFactory::CreateInstance Succeeded. *ppv=0x%X.",*ppv);
  1779.   }
  1780.   else
  1781.   {
  1782.     LOG("S: CFCarSample::CImpIClassFactory::CreateInstance Failed.");
  1783.   }
  1784.  
  1785.   return hr;
  1786. }
  1787.  
  1788.  
  1789. /*M+M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M+++M
  1790.   Method:   CFCarSample::CImpIClassFactory::LockServer
  1791.  
  1792.   Summary:  The LockServer member method of this IClassFactory interface
  1793.             implementation.
  1794.  
  1795.   Args:     BOOL fLock)
  1796.               [in] Flag determining whether to Lock or Unlock the server.
  1797.  
  1798.   Returns:  HRESULT
  1799.               Standard result code. NOERROR for success.
  1800. M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M---M-M*/
  1801. STDMETHODIMP CFCarSample::CImpIClassFactory::LockServer(
  1802.                BOOL fLock)
  1803. {
  1804.   HRESULT hr = NOERROR;
  1805.  
  1806.   LOG("S: CFCarSample::CImpIClassFactory::LockServer.");
  1807.  
  1808.   if (fLock)
  1809.     m_pServer->Lock();
  1810.   else
  1811.     m_pServer->Unlock();
  1812.  
  1813.   return hr;
  1814. }
  1815.