Notification Port Example

This example show how to display cluster events by creating a notification port in a separate thread.

//////////////////////////////////////////////////////////////////////

#include "ClusDocEx.h"  

//////////////////////////////////////////////////////////////////////

//  Constants and global data

    const DWORD MYAPP_EVENTS = ( CLUSTER_CHANGE_GROUP_ADDED      |
                                 CLUSTER_CHANGE_GROUP_DELETED    |
                                 CLUSTER_CHANGE_GROUP_STATE      |
                                 CLUSTER_CHANGE_RESOURCE_ADDED   |
                                 CLUSTER_CHANGE_RESOURCE_DELETED |
                                 CLUSTER_CHANGE_RESOURCE_STATE   |
                                 CLUSTER_CHANGE_HANDLE_CLOSE );


int main()
{
    HCLUSTER  hCluster        = NULL;
    HGROUP    hGroup          = NULL;
    HRESOURCE hRes            = NULL;
    DWORD     dwEventThreadID = 0;
    DWORD     dwExitCode      = 0;  
    HANDLE    hEventThread    = NULL;
    BOOL      bExit           = FALSE;

    hCluster = ClusDocEx_OpenLocalClusterWithName();

    if ( hCluster )
    {
        hEventThread = CreateThread(
                            NULL, 0, ClusDocEx_EventPort, 
                            (LPVOID) hCluster, 0, &dwEventThreadID );

        hGroup = CreateClusterGroup( hCluster, L"EventDemoGroup" );

        if( hGroup )
        {
            hRes = CreateClusterResource( 
                       hGroup, L"EventDemoShare", L"File Share", 0 );
    
            if( hRes )
            {
                OnlineClusterGroup( hGroup, NULL );
                OfflineClusterGroup( hGroup );
                DeleteClusterResource( hRes );
                CloseClusterResource( hRes );
            }

            DeleteClusterGroup( hGroup );               
            CloseClusterGroup( hGroup );
        }

        CloseCluster( hCluster );
    }

    for( ; ; )
    {
        bExit = GetExitCodeThread( hEventThread, &dwExitCode );
        if( bExit && ( dwExitCode != STILL_ACTIVE ) )
            break;
    }

    if( hEventThread )
        CloseHandle( hEventThread );

    return 0;
}


DWORD WINAPI ClusDocEx_EventPort( LPVOID hCluster )
{
    HCHANGE hChange       = (HCHANGE)INVALID_HANDLE_VALUE ;
    DWORD   dwFilterType;
    DWORD   dwNotifyKey;
    DWORD   dwStatus;
    DWORD   cchNameSize    = ClusDocEx_DEFAULT_CCH;
    LPWSTR  pszObjectName = new WCHAR[cchNameSize];
    bool    bExit = false;
   
    if( hCluster != NULL )
    {
        hChange = CreateClusterNotifyPort( hChange, 
                                           (HCLUSTER) hCluster, 
                                           MYAPP_EVENTS,   //  dwFilter
                                           MYAPP_EVENTS ); //  dwNotifyKey

        while( hChange && !bExit )
        {
        //  Reset name size 

            cchNameSize = ClusDocEx_DEFAULT_CCH;

            dwStatus = GetClusterNotify( hChange, 
                                         &dwNotifyKey,
                                         &dwFilterType,
                                         pszObjectName,
                                         &cchNameSize,
                                         2500);


            if( dwStatus == ERROR_SUCCESS )
            {
                switch( dwFilterType )
                {
                case CLUSTER_CHANGE_RESOURCE_STATE:
                    wprintf( L"Thread: Receiving resource state change event.\n" );
                    break;

                case CLUSTER_CHANGE_GROUP_STATE:
                    wprintf( L"Thread: Receiving group state change event.\n" );
                    break;

                case CLUSTER_CHANGE_RESOURCE_ADDED: 
                    wprintf( L"Thread: Receiving add resource event.\n" );
                    break;

                case CLUSTER_CHANGE_GROUP_ADDED:
                    wprintf( L"Thread: Receiving add group event.\n" );
                    break;

                case CLUSTER_CHANGE_RESOURCE_DELETED: 
                    wprintf( L"Thread: Receiving delete resource event.\n" );
                    break;

                case CLUSTER_CHANGE_GROUP_DELETED:
                   wprintf( L"Thread: Receiving delete group event.\n" );
                    break;
                case CLUSTER_CHANGE_HANDLE_CLOSE:
                    wprintf( L"Thread: Receiving cluster handle close event.\n" );
                    bExit = true;
                    break;
                }
            }
            else if( dwStatus == WAIT_TIMEOUT )
            {
            //  If any call to GetClusterNotify times out
            //  (exceeds dwMilliseconds, which is 2500 in this case)
            //  any code here will be executed.
            }

        }

        if( hChange ) 
            CloseClusterNotifyPort( hChange );
    }

    LocalFree( pszObjectName );
    return dwStatus;
}