Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

270 lines
6.2 KiB

//
// virtualdefs.h
//
// Contains definitions for pure virtual functions which must defined via
// the IDispatch. This header is used in CTBGlobal.cpp and CTBShell.cpp
//
// WHY did I do it this way instead of object inheritance?
//
// OLE Automation requires the IDL file objects to inherit
// IDispatch members. The IDispatch object contains pure virtual
// functions as a layout, which must be defined by me, the user of it.
// The problem is, I have two objects which need to define identical code.
// To prevent this, I just included the source.
//
// Object inheritance will not work in this case because if I define
// an object which defines the pure virtual functions, and eventually
// inherit them through CTBShell and CTBGlobal, it will still not work
// because I also inherited the automatic IDL generated header which
// makes a second path to undefined pure virtual function. I COULD
// make two objects with two names (to have two different parents) but
// I would end up duplicating code again.. It looks like this:
//
// pure virtual methods
// |
// / \
// / \
// / \
// / \
// / \
// OLE Obj 1 OLE Obj 2
// | |
// | <-1-- | <-2------ including this file at this layer
// | |
// My Obj 1 My Obj 2
//
//
// Copyright (C) 2001 Microsoft Corporation
//
// Author: a-devjen (Devin Jenson)
//
// CTBOBJECT::Init
//
// Initializes the TypeInfo and RefIID.
//
// No return value.
void CTBOBJECT::Init(REFIID RefIID)
{
RefCount = 0;
ObjRefIID = RefIID;
// Load actual "code" into memory.. its referenced as ITypeInfo,
// but think of it as like a DLL, but you can't access it the
// same way.
if (FAILED(SCPLoadTypeInfoFromThisModule(RefIID, &TypeInfo))) {
_ASSERT(FALSE);
TypeInfo = NULL;
}
else
TypeInfo->AddRef();
}
// CTBOBJECT::UnInit
//
// Releases the type info.
//
// No return value.
void CTBOBJECT::UnInit(void)
{
// Release the TypeInfo if we have it
if(TypeInfo != NULL)
TypeInfo->Release();
TypeInfo = NULL;
}
//
//
// Begin the IUnknown inherited interface
//
//
// CTBOBJECT::QueryInterface
//
// This is a COM exported method used for retrieving the interface.
//
// Returns S_OK on success, or E_NOINTERFACE on failure.
STDMETHODIMP CTBOBJECT::QueryInterface(REFIID RefIID, void **vObject)
{
// This interface is either IID_ITBGlobal, IID_ITBShell,
// IID_IUnknown, or IID_IDispatch to get the TypeInfo...
if (RefIID == ObjRefIID || RefIID == IID_IDispatch ||
RefIID == IID_IUnknown)
*vObject = TypeInfo != NULL ? this : NULL;
// We received an unsupported RefIID
else {
// De-reference the passed in pointer and error out
*vObject = NULL;
return E_NOINTERFACE;
}
// Add a reference
if (*vObject != NULL)
((IUnknown*)*vObject)->AddRef();
return S_OK;
}
// CTBOBJECT::AddRef
//
// Simply increments a number indicating the number of objects that contain
// a reference to this object.
//
// Returns the new reference count.
STDMETHODIMP_(ULONG) CTBOBJECT::AddRef(void)
{
return InterlockedIncrement(&RefCount);
}
// CTBOBJECT::Release
//
// Simply decrements a number indicating the number of objects that contain
// a reference to this object. If the resulting reference count is zero,
// no objects contain a reference handle, therefore delete itself from
// memory as it is no longer used.
//
// Returns the new reference count.
STDMETHODIMP_(ULONG) CTBOBJECT::Release(void)
{
// Decrememt
if (InterlockedDecrement(&RefCount) != 0)
// Return the new value
return RefCount;
// It is 0, so delete itself
delete this;
return 0;
}
//
//
// Begin the IDispatch inherited interface
//
//
// CTBOBJECT::GetTypeInfoCount
//
// Retrieves the number of TypeInfo's we have.
//
// Returns S_OK on success, or E_POINTER on failure.
STDMETHODIMP CTBOBJECT::GetTypeInfoCount(UINT *TypeInfoCount)
{
__try {
// We never have more than 1 type info per object
*TypeInfoCount = 1;
}
__except (EXCEPTION_EXECUTE_HANDLER) {
// This really should never happen...
_ASSERT(FALSE);
return E_POINTER;
}
return S_OK;
}
// CTBOBJECT::GetTypeInfo
//
// Retrieves a pointer to the specified TypeInfo.
//
// Returns S_OK on success, or E_POINTER on failure.
STDMETHODIMP CTBOBJECT::GetTypeInfo(UINT TypeInfoNum, LCID Lcid, ITypeInfo **TypeInfoPtr)
{
// Check our interface first
_ASSERT(TypeInfo != NULL);
__try {
// The only TypeInfo we have is the one in this object...
*TypeInfoPtr = TypeInfo;
TypeInfo->AddRef();
}
__except (EXCEPTION_EXECUTE_HANDLER) {
// This really should never happen...
_ASSERT(FALSE);
return E_POINTER;
}
return S_OK;
}
// CTBOBJECT::GetIDsOfNames
//
// Get ID's of the specified names in our TypeInfo.
//
// Returns any HRESULT value.
STDMETHODIMP CTBOBJECT::GetIDsOfNames(REFIID RefIID, OLECHAR **NamePtrList,
UINT NameCount, LCID Lcid, DISPID *DispID)
{
HRESULT Result;
// Check our pointer first
_ASSERT(TypeInfo != NULL);
// Use the TypeInfo of this function instead
Result = TypeInfo->GetIDsOfNames(NamePtrList, NameCount, DispID);
// Assert uncommon return values
_ASSERT(Result == S_OK || Result == DISP_E_UNKNOWNNAME);
return Result;
}
// CTBOBJECT::Invoke
//
// Invokes a method in the TypeInfo.
//
// Returns any HRESULT value.
STDMETHODIMP CTBOBJECT::Invoke(DISPID DispID, REFIID RefIID, LCID Lcid,
WORD Flags, DISPPARAMS *DispParms, VARIANT *Variant,
EXCEPINFO *ExceptionInfo, UINT *ArgErr)
{
HRESULT Result;
// Check our pointer first
_ASSERT(TypeInfo != NULL);
// Invoke the method
Result = TypeInfo->Invoke(this, DispID, Flags,
DispParms, Variant, ExceptionInfo, ArgErr);
_ASSERT(Result == S_OK);
return Result;
}