#if !defined(__COREFOUNDATION_CFPLUGINCOM__)
#define __COREFOUNDATION_CFPLUGINCOM__ 1

#ifndef CFPLUGINCOM_H
#define  CFPLUGINCOM_H

//#include <Windows.h>
#include <CoreFoundation/CFPlugIn.h>
#include  <APPLE/CoreFoundation/CFPlugInCOM.h>

//hys added

//#include <wine/windows/windef.h>//LPVOID
//#include <wine/windows/winnt.h>//ULONG
//#ifndef __WINE_WINDOWS_H
//#include <wine/windows/windows.h> //hys
//#endif

#if defined(__cplusplus)
extern "C" {
#endif




/*The CFPlugin Project Source Code

Now that the project settings are out of the way, let's dive into the source code. The good news is that there is only one source file with less than a dozen functions in it. The bad news is that it can be very confusing, so put on your thinking cap.

The CFPlugin architecture is based on Microsoft's COM (Component Object Model) technology. This means that, in theory, you can write plug-ins that are cross-platform and compatible with any host that supports COM. We are not going to worry about that right now though; we're going to concentrate on getting one working under OS X first.
The Plug-in Interface

The first thing a plug-in needs is an interface (see Listing 5.2). The plug-in interface is used by the application to access the plug-in's functionality. It also defines the UUIDs for the types, factories, and the interface itself. Notice that the definitions are made using the HEX format of the UUID, beginning with a NULL.
Listing 5.2 Plug-in Interface in MyCFPluginInterface.h
// Define the UUID for the type
#define kMyTypeID (CFUUIDGetConstantUUIDWithBytes(NULL, 0xDC, 0x83, 0xB5,
0xC8, 0xDD, 0x18, 0x11, 0xD6, 0xB3, 0xD0, 0x00, 0x03, 0x93, 0x0E, 0xDB, 0x36))

// The UUID for the factory function
#define kMyFactoryID (CFUUIDGetConstantUUIDWithBytes(NULL, 0xDC, 0x3F, 0x0D,
0x89, 0xDD, 0x19, 0x11, 0xD6, 0xB3, 0xD0, 0x00, 0x03, 0x93, 0x0E, 0xDB, 0x36))

// Define the UUID for the interface
// MyType objects must implement MyInterface
#define kMyInterfaceID (CFUUIDGetConstantUUIDWithBytes(NULL, 0x07, 0x1D, 0x88,
0x1D, 0xDD, 0x1A, 0x11, 0xD6, 0xB3, 0xD0, 0x00, 0x03, 0x93, 0x0E, 0xDB, 0x36))

// The function table for the interface
typedef struct MyInterfaceStruct {
    IUNKNOWN_C_GUTS;
    void (*myPluginFunction)(void *this, Boolean flag);
} MyInterfaceStruct;

Also in the interface is a structure that defines the functions in our plug-in. In this case, we only have one function, myPluginFunction, which returns void and accepts two parameters. The first parameter, this, is a pointer to the interface itself. The second parameter, flag, is a Boolean that is displayed in the dialog box that the plug-in displays. You can define as many functions as you need using whatever parameters you require.

Also in the interface structure is something called IUNKNOWN_C_GUTS. IUNKNOWN_C_GUTS is a macro defined in CFPluginCOM.h. It defines the bare minimum needed in the function table structure MyInterfaceStruct. IUnknown can be considered the "base" interface that all COM objects are modeled on (the super class if you will). This means that all COM objects are really IUnknown objects at heart and all start with the three functions QueryInterface, AddRef, and Release as shown in Listing 5.3.
Listing 5.3 IUNKNOWN_C_GUTS in CFPluginCOM.h
#define IUNKNOWN_C_GUTS \
    void *_reserved; \
    HRESULT (STDMETHODCALLTYPE *QueryInterface) \
    (void *thisPointer, REFIID iid, LPVOID *ppv); \
    ULONG (STDMETHODCALLTYPE *AddRef)(void *thisPointer); \
    ULONG (STDMETHODCALLTYPE *Release)(void *thisPointer)

Note

To gain more insight into the magic of COM, be sure to browse the header file CFPluginCOM.h. This is where IUnknown is defined, as well as many other useful tidbits.

The Plug-in Main Function

Let's look at the source code that is our Carbon plug-in. Everything in this section can be found in main.c in the CFPlugin project, as shown in Figure 5.5.

You've seen the function table for our plug-in interface in Listing 5.2. The interface needs a type to implement it. Our type could be considered an object because it contains both data and functions (via the interface). When we ultimately allocate and initialize our type of object, we want to return a complete unit as shown in Listing 5.4.
Listing 5.4 MyType Definition in main.c
// The layout for an instance of MyType
typedef struct _MyType {
    MyInterfaceStruct*    myInterface;
    CFUUIDRef             factoryID;
    UInt32                refCount;
 } MyType;

The first function that will be called in our plug-in is our factory function (see Listing 5.5). Shortly after creating the plug-in, the host application will find all factories in the plug-in that pertain to a particular object type that the application is interested in. The factory functions returned are directly related to the definitions in the Info.plist entries in Figure 5.7.
Listing 5.5 myFactoryFunction in main.c
// Implementation of the factory function for this type
void *myFactoryFunction(CFAllocatorRef allocator, CFUUIDRef typeID)
{
    printf("myFactoryFunction\n");

    // If correct type is being requested,
    // allocate an instance of MyType and return the IUnknown interface
    if (CFEqual(typeID, kMyTypeID)) {
        MyType *result = _allocMyType(kMyFactoryID);
        return result;
    } else {
        // If the requested type is incorrect, return NULL
        return NULL;
    }
}

When the host application calls CFPlugInInstanceCreate and causes our factory function to be called, we verify that the caller wants to create a type that we know about. Once validated, we create the type by calling the private _allocMyType function and return the result, which will be a pointer to a MyType structure as shown in Listing 5.4. Note the printf function used for debugging purposes and to help trace our code at runtime.
Listing 5.6 _allocMyType in main.c
// Utility function that allocates a new instance
static MyType *_allocMyType(CFUUIDRef factoryID)
{
    // Allocate memory for the new instance
    MyType *newOne = (MyType*)malloc(sizeof(MyType));

    // Point to the function table
    newOne->_myInterface = &myInterfaceFtbl;

    // Retain and keep an open instance refcount for each factory
    newOne->_factoryID = CFRetain(factoryID);
    CFPlugInAddInstanceForFactory(factoryID);

    // This function returns the IUnknown interface so set the refCount to one
    newOne->_refCount = 1;
    return newOne;
}

Listing 5.6 shows the _allocMyType function that actually allocates and initializes our type structure. Note that it fills the myInterface variable with a pointer to myInterfaceFtbl, shown in Listing 5.7. myInterfaceFtbl is a static declaration of MyInterfaceStruct that contains a NULL pad, the "my" versions of the standard IUnknown functions (QueryInterface, AddRef, and Release), and the pointer to our one and only unique plug-in function, myPluginFunction. Note that this static declaration mirrors the MyInterfaceStruct in Listing 5.2 and the IUNKNOWN_C_GUTS in Listing 5.3. We also keep track of the factory UUID so that we can follow the usage status of our type.
Listing 5.7 myInterfaceFtbl in main.c
// The MyInterface function table
static MyInterfaceStruct myInterfaceFtbl = {
        NULL,               // Required padding for COM
        myQueryInterface,   // These three are the required COM functions
        myAddRef,
        myRelease,
        myPluginFunction }; // Interface implementation (specific to my plugin)

At this point, the host will have a copy of the IUnknown interface and can use the QueryInterface function to obtain the interface that is my "subclass" of IUnknown—the "my" interface. When QueryInterface is called, my plug-in's myQueryInterface function (see Listing 5.8) is subsequently executed.
Listing 5.8 myQueryInterface in main.c
// Implementation of the IUnknown QueryInterface function
static HRESULT myQueryInterface(void *this, REFIID iid, LPVOID *ppv)
{
    HRESULT hResult = E_NOINTERFACE;

    printf("myQueryInterface\n");

    // Create a CoreFoundation UUIDRef for the requested interface
    CFUUIDRef interfaceID = CFUUIDCreateFromUUIDBytes(NULL, iid);

    // Test the requested ID against the valid interfaces
    if (CFEqual(interfaceID, kMyInterfaceID)) {

        // If the MyInterface was requested, bump the ref count,
        // set the ppv parameter equal to the instance, and return good status
        // This calls through to myAddRef
        ((MyType*)this)->_myInterface->AddRef(this);
    *ppv = this;
        hResult = S_OK;

    } else if (CFEqual(interfaceID, IUnknownUUID)) {

        // If the IUnknown interface was requested, bump the ref count,
        // set the ppv parameter equal to the instance, and return good status
        // This calls through to myAddRef
    ((MyType*)this)->_myInterface->AddRef(this);
        *ppv = this;
        hResult = S_OK;

    } else {

        // Requested interface unknown, bail with error
        *ppv = NULL;
        hResult = E_NOINTERFACE;

    }

    // Release interface
    CFRelease(interfaceID);
    return hResult;
}

The myQueryInterface function converts the incoming interface UUID to a format that it can easily compare against using the CFUUIDCreateFromUUIDBytes function. It then validates if the requested interface is one that is supported here. If so, we increment the reference count by calling AddRef (which really calls through to myAddRef in Listing 5.9) and return the this pointer, the actual plug-in interface.
Listing 5.9 myAddRef in main.c
// Implementation of reference counting for this type
// Whenever an interface is requested, bump the refCount for
// the instance NOTE: returning the refcount is a convention
// but is not required so don't rely on it
static ULONG myAddRef(void *this)
{
        printf("myAddRef\n");

        return ((MyType*)this)->_refCount++;
}

At this point, the host application will release the IUnknown interface by calling Release, which will subsequently call our myRelease function in Listing 5.10.
Listing 5.10 myRelease in main.c
// When an interface is released, decrement the refCount
// If the refCount goes to zero, deallocate the instance
static ULONG myRelease(void *this)
{
        printf("myRelease\n");

        ((MyType*)this)->_refCount—;
        if (((MyType*)this)->_refCount == 0) {
            _deallocMyType((MyType*)this);
            return 0;
        } else
            return ((MyType*)this)->_refCount;
}

After decrementing the reference count, if it is zero, the type is deallocated by calling the private mirrored function of _allocMyType, _deallocMyType (see Listing 5.11).
Listing 5.11 _deallocMyType in main.c
// Utility function that deallocates the instance
// when the refCount goes to zero
static void _deallocMyType(MyType *this)
{
        CFUUIDRef factoryID = this->_factoryID;
        free(this);
        if (factoryID) {
            CFPlugInRemoveInstanceForFactory(factoryID);
            CFRelease(factoryID);
        }
}

The only thing left to do at this point is actually call the function that is unique to our type and interface. It's amazing how 95% of the source code is the setup of the mechanism to call this one simple function. The function in Listing 5.12 is the entire reason for this chapter. When called, it will display a standard alert with the value of the flag variable displayed as flag = YES or flag = NO. The host application will ultimately release this interface as well when it is done with it.
Listing 5.12 myPlugInFunction in main.c
// The implementation of the MyInterface function
static void myPluginFunction(void *this, Boolean flag)
{
    SInt16 outItemHit;
    StandardAlert(kAlertNoteAlert,
        flag ? "\pCFPlugin (flag = YES)" : "\pCFPlugin (flag = NO)",
        "\pThis alert is being called from myPluginFunction in CFPlugin.",
        NULL, &outItemHit);
}

Before you move on to see how the Carbon application makes this all come together, take a short break. Stretch, go look out a window, walk the dog, or play with the cat. When you return, we'll dive into the application source code. It's only one function, so it should be easy enough.

[ Team LiB ]	 */

#define IUNKNOWN_C_GUTS \
    void *_reserved; \
    HRESULT (STDMETHODCALLTYPE *QueryInterface) \
    (void *thisPointer, REFIID iid, LPVOID *ppv); \
    ULONG (STDMETHODCALLTYPE *AddRef)(void *thisPointer); \
    ULONG (STDMETHODCALLTYPE *Release)(void *thisPointer)


#include  <APPLE/CoreFoundation/CFPlugInCOM_E.h>
#ifdef __cplusplus
}
#endif

#endif
#endif
