/* * * Copyright (c) 1998,1999 Microsoft Corporation. All rights reserved. * EXEMPT: copyright change only, no build required * */ #ifndef _UNKNOWN_HXX #define _UNKNOWN_HXX #pragma once #include "fusionlastwin32error.h" //=========================================================================== // This template implements the IUnknown portion of a given COM interface. template class _unknown : public I { private: long _refcount; public: _unknown() : _refcount(0) { } virtual ~_unknown() { } virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void ** ppvObject) { if (ppvObject == NULL) return E_POINTER; else *ppvObject = NULL; if (riid == IID_IUnknown) { *ppvObject = static_cast(this); } else if (riid == *I_IID) { *ppvObject = static_cast(this); } if (*ppvObject) { reinterpret_cast(*ppvObject)->AddRef(); return S_OK; } else { return E_NOINTERFACE; } } virtual ULONG STDMETHODCALLTYPE AddRef( void) { return InterlockedIncrement(&_refcount); } virtual ULONG STDMETHODCALLTYPE Release( void) { DWORD dwError = ::FusionpGetLastWin32Error(); if (InterlockedDecrement(&_refcount) == 0) { delete this; ::FusionpSetLastWin32Error( dwError ); return 0; } ::FusionpSetLastWin32Error( dwError ); return _refcount; } }; #endif _UNKNOWN_HXX