Service Map Macros


The new home for Visual Studio documentation is Visual Studio 2017 Documentation on

The latest version of this topic can be found at Service Map Macros.

These macros define service maps and entries.

BEGIN_SERVICE_MAPMarks the beginning of an ATL service map.
END_SERVICE_MAPMarks the end of an ATL service map.
SERVICE_ENTRYIndicates that the object supports a specific service ID.
SERVICE_ENTRY_CHAINInstructs IServiceProviderImpl::QueryService to chain to the specified object.

Marks the beginning of the service map.



[in] Specifies the class containing the service map.


Use the service map to implement service provider functionality on your COM object. First, you must derive your class from IServiceProviderImpl. There are two types of entries:


   SERVICE_ENTRY(SID_SBindHost)  // This object supports the SBindHost service
   SERVICE_ENTRY_CHAIN(m_spClientSite) // Everything else, just ask the container

Marks the end of the service map.



See the example for BEGIN_SERVICE_MAP.

Indicates that the object supports the service id specified by SID.

    SID Â)


The service ID.


See the example for BEGIN_SERVICE_MAP.

Instructs IServiceProviderImpl::QueryService to chain to the object specified by punk.

    punk Â)


A pointer to the IUnknown interface to which to chain.


See the example for BEGIN_SERVICE_MAP.

Creates or accesses the specified service and returns an interface pointer to the specified interface for the service.

    REFGUID guidService,
    REFIID riid,
    void** ppvObject);


[IN] guidService
Pointer to a service identifier (SID).

[IN] riid
Identifier of the interface to which the caller is to gain access.

[OUT] ppvObj
Indirect pointer to the requested interface.

Return Value

The returned HRESULT value is one of the following:

Return valueMeaning
S_OKThe service was successfully created or retrieved.
E_INVALIDARGOne or more of the arguments is invalid.
E_OUTOFMEMORYMemory is insufficient to create the service.
E_UNEXPECTEDAn unknown error occurred.
E_NOINTERFACEThe requested interface is not part of this service, or the service is unknown.


QueryService returns an indirect pointer to the requested interface in the specified service. The caller is responsible for releasing this pointer when it is no longer required.

When you call QueryService, you pass both a service identifier ( guidService) and an interface identifier ( riid). The guidService specifies the service to which you want access, and the riid identifies an interface that is part of the service. In return, you receive an indirect pointer to the interface.

The object that implements the interface might also implement interfaces that are part of other services. Consider the following:

  • Some of these interfaces might be optional. Not all interfaces defined in the service description are necessarily present on every implementation of the service or on every returned object.

  • Unlike calls to QueryInterface, passing a different service identifier does not necessarily mean that a different Component Object Model (COM) object is returned.

  • The returned object might have additional interfaces that are not part of the definition of the service.

Two different services, such as SID_SMyService and SID_SYourService, can both specify the use of the same interface, even though the implementation of the interface might have nothing in common between the two services. This works, because a call to QueryService (SID_SMyService, IID_IDispatch) can return a different object than QueryService (SID_SYourService, IID_IDispatch). Object identity is not assumed when you specify a different service identifier.