FREE Subscription to Dr. Dobb’s Digest: Same Great Content, New Digital Edition
Site Archive (Complete)
Dobbs M-Dev
Email
Print
Reprint

add to:
Del.icio.us
Digg
Google
Furl
Slashdot
Y! MyWeb
Blink
March 01, 1998

Control How COM Marshals Your Data

(Page 18 of 20)
March 1998/Control How COM Marshals Your Data/Listing 6

Listing 6: server.cpp — Simple console-mode server app

// COM Marshalling Sample Server
// Author : Fran Heeran
#define  INC_OLE2
#include <stdio.h>
#include <conio.h>
#include <windows.h>
#include <initguid.h>
#include "marsamp.h"

extern "C" BOOL RegisterServer(LPSTR pszExeName);
extern "C" void UnregisterServer();
HANDLE   hevtDone;

// Standard Class Factory
class CClassFactory : public IClassFactory
{
protected:
   ULONG m_cRef;
public:
   CClassFactory() { m_cRef = 1; }

   STDMETHODIMP QueryInterface (REFIID riid, void** ppv);
   STDMETHODIMP_(ULONG) AddRef(void)  { return ++m_cRef; }
   STDMETHODIMP_(ULONG) Release(void);
   STDMETHODIMP CreateInstance(LPUNKNOWN, REFIID, LPVOID FAR*);
   STDMETHODIMP LockServer(BOOL) { return E_FAIL; }
};

// ISimpleObject Interface
class CSimpleObject : public IUnknown {
   private:
      LONG m_cRef;
   public:
      CSimpleObject() { m_cRef = 1; }
      ~CSimpleObject() { SetEvent(hevtDone); }
      IUNKNOWN_METHODS(IMPL);
      ISIMPLEOBJECT_METHODS(IMPL);
};

CClassFactory  g_ClassFactory;

int __cdecl main(int argc, char *argv[], char *envp[])
{
   HRESULT hr;
   DWORD   dwRegister;

   // Handle register/unregister commands
   if (argc > 1) {
      if (!strcmp(argv[1], "-register")) {
         if (argc != 3) {
            printf("Useage is server -register [path to server \
& proxy/stub]");
            return 0;
         }
         if (!RegisterServer(argv[2]))
            printf("Failed to register Server & Proxy/Stub");
         else
            printf("Successfully registered Server & Proxy/Stub");
         return 0;
      }
      else if (!strcmp(argv[1], "-unregister")) {
         UnregisterServer();
         printf("Unregistered Server & Proxy/Stub");
         return 0;
      }
   }

   // Create the thread which is signaled when the
   // instance is deleted
   hevtDone = CreateEvent(NULL, FALSE, FALSE, NULL);
   if (!hevtDone)
      return 1;

   // Initialize COM
   hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
   RETURNONFAILURE(hr, "CoInitializeEx() failed");

   // Register class-object
   hr = CoRegisterClassObject(CLSID_SimpleObject, &g_ClassFactory,
                  CLSCTX_SERVER, REGCLS_SINGLEUSE, &dwRegister);
   RETURNONFAILURE(hr,"Failed to register class object");

   printf("Waiting...\n");

   // Wait until we have been called to display the array
   WaitForSingleObject(hevtDone, INFINITE);
   CloseHandle(hevtDone);
   CoUninitialize();

   // Wait for a key so the user can view the output
   printf("\nPress Any Key to Exit\n");
   char ch = _getch();

   return 0;
}

STDMETHODIMP CClassFactory::QueryInterface(REFIID riid,
                                           LPVOID FAR *ppvObject)
{
   *ppvObject = NULL;

        if(IsEqualIID(riid, IID_IUnknown))
                *ppvObject = (LPUNKNOWN) (LPCLASSFACTORY) this;
        else if(IsEqualIID(riid, IID_IClassFactory))
                *ppvObject = (LPCLASSFACTORY) this;
        else
                return E_NOINTERFACE;

        ((LPUNKNOWN)*ppvObject)->AddRef();

        return NOERROR;
}

STDMETHODIMP_(ULONG) CClassFactory::Release()
{
   if (--m_cRef)
      return m_cRef;
   delete this;
   return 0;
}

STDMETHODIMP CClassFactory::CreateInstance(LPUNKNOWN  pUnkOuter,
                                           REFIID     riid,
                                           LPVOID FAR *ppvObject)
{
   HRESULT        hr;
   CSimpleObject  *pObj;

   *ppvObject = NULL;
   hr = ResultFromScode(E_OUTOFMEMORY);

   // Verify that a controlling unknown asks for IUnknown
   if (NULL != pUnkOuter)
      return ResultFromScode(CLASS_E_NOAGGREGATION);

   // Create the object telling us to notify us when it's gone.
   pObj = new CSimpleObject();
   if (NULL == pObj)
      return hr;
   hr = pObj->QueryInterface(riid, ppvObject);
   if (FAILED(hr))
      delete pObj;

   pObj->Release();

   return hr;
}

STDMETHODIMP_(ULONG) CSimpleObject::Release()
{
   if (!InterlockedDecrement(&m_cRef)) {
      delete this;
      return 0;
   }
   return m_cRef;
}


STDMETHODIMP_(ULONG) CSimpleObject::AddRef()
{
   return InterlockedIncrement(&m_cRef);
}

STDMETHODIMP CSimpleObject::QueryInterface(REFIID riid, void** ppv)
{
   if (ppv == NULL)
      return E_INVALIDARG;
   if (riid == IID_IUnknown || riid == IID_ISimpleObject) {
      *ppv = (IUnknown *) this;
      AddRef();
      return S_OK;
   }

   *ppv = NULL;
   return E_NOINTERFACE;
}

STDMETHODIMP CSimpleObject::DisplayArray(BOOL *pArr)
{
   printf("Array Length = %d Bytes\r\nCompressed Length = %d \
Bytes\r\n", FLAG_ARRAY_SIZE * sizeof(BOOL), FLAG_ARRAY_SIZE / 8);

   for (int i = 0;i < FLAG_ARRAY_SIZE;i++)
      printf("%d ", *(pArr + i));

   return S_OK;
}
//End of File
Previous Page | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 Next Page
TOP 5 ARTICLES
No Top Articles.



MICROSITES
FEATURED TOPIC

ADDITIONAL TOPICS

INFO-LINK