home *** CD-ROM | disk | FTP | other *** search
/ PC Press 1997 July / Sezamfile97_2.iso / windows / program / activex / axtsamp.exe / TSBRANCH.EXE / LOCSERVE / FACTORY.CPP < prev    next >
C/C++ Source or Header  |  1996-12-29  |  45KB  |  1,394 lines

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