home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / com / inole2 / chap14 / beeper3 / dbeeper.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1996-05-21  |  4.6 KB  |  245 lines

  1. /*
  2.  * DBEEPER.CPP
  3.  * Beeper Automation Object Chapter 14
  4.  *
  5.  * Server module code for the Beeper object.
  6.  *
  7.  * Copyright (c)1993-1995 Microsoft Corporation, All Rights Reserved
  8.  *
  9.  * Kraig Brockschmidt, Microsoft
  10.  * Internet  :  kraigb@microsoft.com
  11.  * Compuserve:  >INTERNET:kraigb@microsoft.com
  12.  */
  13.  
  14.  
  15. #define INITGUIDS
  16. #include "dbeeper.h"
  17.  
  18.  
  19. //Count number of objects and number of locks.
  20. ULONG       g_cObj=0;
  21. ULONG       g_cLock=0;
  22. HINSTANCE   g_hInst=NULL;   //For LoadString
  23.  
  24. #ifdef WIN32
  25. DWORD       g_dwTLS;        //For thread-local storage
  26. #endif
  27.  
  28. /*
  29.  * LibMain(32)
  30.  *
  31.  * Purpose:
  32.  *  Entry point conditionally compiled for Win32 and Windows
  33.  *  3.1.  Provides the proper structure for each environment.
  34.  */
  35.  
  36. #ifdef WIN32
  37. BOOL WINAPI LibMain32(HINSTANCE hInstance, ULONG ulReason
  38.     , LPVOID pvReserved)
  39.     {
  40.     g_hInst=hInstance;
  41.  
  42.     if (DLL_PROCESS_DETACH==ulReason)
  43.         {
  44.         TlsFree(g_dwTLS);
  45.         return TRUE;
  46.         }
  47.     else
  48.         {
  49.         if (DLL_PROCESS_ATTACH!=ulReason)
  50.             return TRUE;
  51.  
  52.         g_dwTLS=TlsAlloc();
  53.         }
  54.  
  55.     return TRUE;
  56.     }
  57. #else
  58. int PASCAL LibMain(HINSTANCE hInstance, WORD wDataSeg
  59.     , WORD cbHeapSize, LPSTR lpCmdLine)
  60.     {
  61.     if (0!=cbHeapSize)
  62.         UnlockData(0);
  63.  
  64.     g_hInst=hInstance;
  65.     return (int)hInstance;
  66.     }
  67. #endif
  68.  
  69.  
  70.  
  71. /*
  72.  * DllGetClassObject
  73.  * DllCanUnloadNow
  74.  * Standard COM exports for DLL servers.
  75.  */
  76.  
  77. HRESULT APIENTRY DllGetClassObject(REFCLSID rclsid, REFIID riid
  78.     , PPVOID ppv)
  79.     {
  80.     CBeeperFactory *pBF;
  81.     HRESULT         hr;
  82.  
  83.     if (CLSID_Beeper!=rclsid)
  84.         return ResultFromScode(E_FAIL);
  85.  
  86.     //Check that we can provide the interface
  87.     if (IID_IUnknown!=riid && IID_IClassFactory!=riid)
  88.         return ResultFromScode(E_NOINTERFACE);
  89.  
  90.     //Return our beeper factory's IClassFactory
  91.     pBF=new CBeeperFactory();
  92.  
  93.     if (NULL==pBF)
  94.         return ResultFromScode(E_OUTOFMEMORY);
  95.  
  96.     //If the factory hasn't the interface, delete it
  97.     hr=pBF->QueryInterface(riid, ppv);
  98.  
  99.     if (FAILED(hr))
  100.         delete pBF;
  101.     else
  102.         g_cObj++;
  103.  
  104.     return hr;
  105.     }
  106.  
  107.  
  108. STDAPI DllCanUnloadNow(void)
  109.     {
  110.     SCODE   sc;
  111.  
  112.     //Our answer is whether there are any object or locks
  113.     sc=(0L==g_cObj && 0L==g_cLock) ? S_OK : S_FALSE;
  114.     return ResultFromScode(sc);
  115.     }
  116.  
  117.  
  118.  
  119. /*
  120.  * ObjectDestroyed
  121.  *
  122.  * Purpose:
  123.  *  Function for the object to call when it gets destroyed.  Since
  124.  *  we're in a DLL we only track the number of objects here, letting
  125.  *  DllCanUnloadNow take care of the rest.
  126.  */
  127.  
  128. void ObjectDestroyed(void)
  129.     {
  130.     g_cObj--;
  131.     return;
  132.     }
  133.  
  134.  
  135.  
  136. /*
  137.  * CBeeperFactory::CBeeperFactory
  138.  * CBeeperFactory::~CBeeperFactory
  139.  */
  140.  
  141. CBeeperFactory::CBeeperFactory(void)
  142.     {
  143.     m_cRef=0L;
  144.     return;
  145.     }
  146.  
  147.  
  148. CBeeperFactory::~CBeeperFactory(void)
  149.     {
  150.     return;
  151.     }
  152.  
  153.  
  154.  
  155.  
  156.  
  157.  
  158. /*
  159.  * CBeeperFactory::QueryInterface
  160.  * CBeeperFactory::AddRef
  161.  * CBeeperFactory::Release
  162.  */
  163.  
  164. STDMETHODIMP CBeeperFactory::QueryInterface(REFIID riid, PPVOID ppv)
  165.     {
  166.     *ppv=NULL;
  167.  
  168.     if (IID_IUnknown==riid || IID_IClassFactory==riid)
  169.         *ppv=this;
  170.  
  171.     if (NULL!=*ppv)
  172.         {
  173.         ((LPUNKNOWN)*ppv)->AddRef();
  174.         return NOERROR;
  175.         }
  176.  
  177.     return ResultFromScode(E_NOINTERFACE);
  178.     }
  179.  
  180.  
  181. STDMETHODIMP_(ULONG) CBeeperFactory::AddRef(void)
  182.     {
  183.     return ++m_cRef;
  184.     }
  185.  
  186.  
  187. STDMETHODIMP_(ULONG) CBeeperFactory::Release(void)
  188.     {
  189.     if (0!=--m_cRef)
  190.         return m_cRef;
  191.  
  192.     delete this;
  193.     ObjectDestroyed();
  194.     return 0;
  195.     }
  196.  
  197.  
  198.  
  199. /*
  200.  * CBeeperFactory::CreateInstance
  201.  * CBeeperFactory::LockServer
  202.  */
  203.  
  204. STDMETHODIMP CBeeperFactory::CreateInstance(LPUNKNOWN pUnkOuter
  205.     , REFIID riid, PPVOID ppvObj)
  206.     {
  207.     PCBeeper            pObj;
  208.     HRESULT             hr;
  209.  
  210.     *ppvObj=NULL;
  211.     hr=ResultFromScode(E_OUTOFMEMORY);
  212.  
  213.     //Verify that a controlling unknown asks for IUnknown
  214.     if (NULL!=pUnkOuter && IID_IUnknown!=riid)
  215.         return ResultFromScode(CLASS_E_NOAGGREGATION);
  216.  
  217.     //Create the object passing function to notify on destruction.
  218.     pObj=new CBeeper(pUnkOuter, ObjectDestroyed);
  219.  
  220.     if (NULL==pObj)
  221.         return hr;
  222.  
  223.     if (pObj->Init())
  224.         hr=pObj->QueryInterface(riid, ppvObj);
  225.  
  226.     //Kill the object if initial creation or Init failed.
  227.     if (FAILED(hr))
  228.         delete pObj;
  229.     else
  230.         g_cObj++;
  231.  
  232.     return hr;
  233.     }
  234.  
  235.  
  236. STDMETHODIMP CBeeperFactory::LockServer(BOOL fLock)
  237.     {
  238.     if (fLock)
  239.         g_cLock++;
  240.     else
  241.         g_cLock--;
  242.  
  243.     return NOERROR;
  244.     }
  245.