/*
 * This file is generated by the automatic RPC Parser generator. (Version 0.21)
 *
 * Created on 04/09/97 at 00:00:13.
 */

#include "precomp.h"
#pragma hdrstop


/* Globals used throughout */
DWORD                        nPropertyLevel  = 1;
BOOL                         fIsFlipped      = FALSE;
BOOL                         fIgnoreFlatPart = FALSE;
BOOL                         fIgnorePointers = FALSE;

DWORD                        Conformance       = 0;
BOOL                         fConformanceIsSet = FALSE;

/* ======================================================================== *
 * Protocol Entry points for Interface IntraCluster
 *          uuid=(e248d0b8-bf15-11cf-8c5e-08002bb49649)
 * ======================================================================== */

VOID   WINAPI IntraCluster_Register(HPROTOCOL);
VOID   WINAPI IntraCluster_Deregister(HPROTOCOL);
LPBYTE WINAPI IntraCluster_RecognizeFrame(HFRAME, LPVOID, LPVOID, DWORD, DWORD, HPROTOCOL,
                  DWORD, LPDWORD, LPHPROTOCOL, LPDWORD);
LPBYTE WINAPI IntraCluster_AttachProperties(HFRAME, LPVOID, LPVOID, DWORD, DWORD, HPROTOCOL, DWORD, DWORD);
DWORD  WINAPI IntraCluster_FormatProperties(HFRAME, LPVOID, LPVOID, DWORD, LPPROPERTYINST);

ENTRYPOINTS IntraCluster_EntryPoints =
{
    IntraCluster_Register,
    IntraCluster_Deregister,
    IntraCluster_RecognizeFrame,
    IntraCluster_AttachProperties,
    IntraCluster_FormatProperties
};

HPROTOCOL hIntraCluster = NULL;

/* ======================================================================== *
 * Protocol Entry points for Interface ExtroCluster
 *          uuid=(e248d0b8-bf15-11cf-8c5e-08002bb49649)
 * ======================================================================== */

VOID   WINAPI ExtroCluster_Register(HPROTOCOL);
VOID   WINAPI ExtroCluster_Deregister(HPROTOCOL);
LPBYTE WINAPI ExtroCluster_RecognizeFrame(HFRAME, LPVOID, LPVOID, DWORD, DWORD, HPROTOCOL,
                  DWORD, LPDWORD, LPHPROTOCOL, LPDWORD);
LPBYTE WINAPI ExtroCluster_AttachProperties(HFRAME, LPVOID, LPVOID, DWORD, DWORD, HPROTOCOL, DWORD, DWORD);
DWORD  WINAPI ExtroCluster_FormatProperties(HFRAME, LPVOID, LPVOID, DWORD, LPPROPERTYINST);

ENTRYPOINTS ExtroCluster_EntryPoints =
{
    ExtroCluster_Register,
    ExtroCluster_Deregister,
    ExtroCluster_RecognizeFrame,
    ExtroCluster_AttachProperties,
    ExtroCluster_FormatProperties
};

HPROTOCOL hExtroCluster = NULL;

/* ======================================================================== *
 * Protocol Entry points for Interface clusapi
 *          uuid=(b97db8b2-4c63-11cf-bff6-08002be23f2f)
 * ======================================================================== */

VOID   WINAPI Clusapi_Register(HPROTOCOL);
VOID   WINAPI Clusapi_Deregister(HPROTOCOL);
LPBYTE WINAPI Clusapi_RecognizeFrame(HFRAME, LPVOID, LPVOID, DWORD, DWORD, HPROTOCOL,
                  DWORD, LPDWORD, LPHPROTOCOL, LPDWORD);
LPBYTE WINAPI Clusapi_AttachProperties(HFRAME, LPVOID, LPVOID, DWORD, DWORD, HPROTOCOL, DWORD, DWORD);
DWORD  WINAPI Clusapi_FormatProperties(HFRAME, LPVOID, LPVOID, DWORD, LPPROPERTYINST);

ENTRYPOINTS Clusapi_EntryPoints =
{
    Clusapi_Register,
    Clusapi_Deregister,
    Clusapi_RecognizeFrame,
    Clusapi_AttachProperties,
    Clusapi_FormatProperties
};

HPROTOCOL hclusapi = NULL;

/* ======================================================================== *
 * Protocol Entry points for Interface JoinVersion
 *          uuid=(6e17aaa0-1a47-11d1-98bd-0000f875292e)
 * ======================================================================== */

VOID   WINAPI JoinVersion_Register(HPROTOCOL);
VOID   WINAPI JoinVersion_Deregister(HPROTOCOL);
LPBYTE WINAPI JoinVersion_RecognizeFrame(HFRAME, LPVOID, LPVOID, DWORD, DWORD, HPROTOCOL,
                  DWORD, LPDWORD, LPHPROTOCOL, LPDWORD);
LPBYTE WINAPI JoinVersion_AttachProperties(HFRAME, LPVOID, LPVOID, DWORD, DWORD, HPROTOCOL, DWORD, DWORD);
DWORD  WINAPI JoinVersion_FormatProperties(HFRAME, LPVOID, LPVOID, DWORD, LPPROPERTYINST);

ENTRYPOINTS JoinVersion_EntryPoints =
{
    JoinVersion_Register,
    JoinVersion_Deregister,
    JoinVersion_RecognizeFrame,
    JoinVersion_AttachProperties,
    JoinVersion_FormatProperties
};

HPROTOCOL hJoinVersion = NULL;

/* ======================================================================== *
 * Function DllMain called at loading and unloading time
 * ======================================================================== */

DWORD Attached = 0;

BOOL WINAPI DLLEntry(HANDLE hInstance, ULONG Command, LPVOID Reserved)
{
    if ( Command == DLL_PROCESS_ATTACH )
    {
        if ( Attached++ == 0 )
        {
            hIntraCluster = CreateProtocol("R_INTRACLUSTER", &IntraCluster_EntryPoints, ENTRYPOINTS_SIZE);
            hExtroCluster = CreateProtocol("R_EXTROCLUSTER", &ExtroCluster_EntryPoints, ENTRYPOINTS_SIZE);
            hclusapi = CreateProtocol("R_CLUSAPI", &Clusapi_EntryPoints, ENTRYPOINTS_SIZE);
            hJoinVersion = CreateProtocol("R_JOINVERSION", &JoinVersion_EntryPoints, ENTRYPOINTS_SIZE);
        }
    }

    if ( Command == DLL_PROCESS_DETACH )
    {
        if ( --Attached == 0 )
        {
            DestroyProtocol(hIntraCluster);
            DestroyProtocol(hExtroCluster);
            DestroyProtocol(hclusapi);
            DestroyProtocol(hJoinVersion);
        }
    }
    return TRUE;
}

/* ======================================================================== *
 * Implementation of the entry point functions for each interface
 * ======================================================================== */

/*
 * Interface IntraCluster, protocol RPC_IntraCluster:
 */

VOID   WINAPI IntraCluster_Register(HPROTOCOL hProtocol)
{
    register DWORD i;

    CreatePropertyDatabase(hProtocol, nIntraClusterGenProps + nIntraClusterPrivProps);

    for (i = 0; i < nIntraClusterGenProps; ++i)
    {
        AddProperty(hProtocol, &IntraCluster_GenProps[i]);
    }

    for (i = 0; i < nIntraClusterPrivProps; ++i)
    {
        AddProperty(hProtocol, &IntraCluster_PrivProps[i]);
    }
}

VOID   WINAPI IntraCluster_Deregister(HPROTOCOL hProtocol)
{
    DestroyPropertyDatabase(hProtocol);
}

LPBYTE WINAPI IntraCluster_RecognizeFrame(HFRAME hFrame,
                  LPBYTE          MacFrame,
                  LPBYTE          lpFrame,
                  DWORD           MacType,
                  DWORD           FrameLength,
                  HPROTOCOL       hPreviousProtocol,
                  DWORD           hPreviousProtocolOffset,
                  LPDWORD         ProtocolStatusCode,
                  LPHPROTOCOL     hNextProtocol,
                  LPDWORD         InstData)
{
    HPROTOCOL hNext=NULL;   // next protocol to hand off to...
    WORD nStubLength;

    *ProtocolStatusCode = PROTOCOL_STATUS_CLAIMED;

#ifdef SSP_DECODE
    //  IF MSRPC VERSION == 4 AND AUTHPROTID !=0 THEN PASS OFF TO SSP
    if((*(MacFrame + hPreviousProtocolOffset) == 4) &&
       (*(MacFrame + hPreviousProtocolOffset + 78))) {

        hNext = GetProtocolFromName("SSP");
        if(hNext) {

            *ProtocolStatusCode = PROTOCOL_STATUS_NEXT_PROTOCOL;
            *hNextProtocol = hNext;
            nStubLength = *((LPWORD)(MacFrame + hPreviousProtocolOffset + 74));
            return(lpFrame + nStubLength);
        }
    }
#endif

    return(NULL);
}

DWORD  WINAPI IntraCluster_FormatProperties(HFRAME hFrame,
                  LPBYTE          MacFrame,
                  LPBYTE          lpFrame,
                  DWORD           nPropertyInsts,
                  LPPROPERTYINST  lpInst)
{
    while (nPropertyInsts--)
    {
        ((FORMAT)lpInst->lpPropertyInfo->InstanceData)(lpInst);
        lpInst++;
    }

    return(NMERR_SUCCESS);
}

LPBYTE WINAPI IntraCluster_AttachProperties(HFRAME hFrame,
                  LPBYTE          MacFrame,
                  LPBYTE          lpFrame,
                  DWORD           MacType,
                  DWORD           FrameLength,
                  HPROTOCOL       hPreviousProtocol,
                  DWORD           hPreviousProtocolOffset,
                  DWORD           InstData)
{
    CHAR    AuthenticationProtocolID = 0;
    WORD    nRPCLength;
    CHAR    AuthenticationLevel;
    DWORD   procedureNum = InstData & PROCNUM_MASK;

    //  IF THE MSRPC VERSION IS 4 LOOK FOR SECURITY TRAILER
    if(*(MacFrame + hPreviousProtocolOffset) == 4) {
        AuthenticationProtocolID = *(MacFrame + hPreviousProtocolOffset + 78);
        nRPCLength = *((LPWORD)(MacFrame + hPreviousProtocolOffset + 74));
        AuthenticationLevel = *(lpFrame + nRPCLength);
    }

    //  CHECK FOR ENCRYPTION
    if(AuthenticationProtocolID && (AuthenticationLevel == 6)) {
        AttachPropertyInstance(hFrame, 
                               IntraCluster_GenProps[GENPROP_ENCRYPTED].hProperty,
                               nRPCLength,
                               lpFrame, 0, 0, 0);
    }
    else if ( procedureNum < NUM_INTRACLUSTERPROCS ) {
        BOOL    isRequest = ((InstData & RPC_REQUEST_MASK) != 0);
        DWORD   summaryDataSize = sizeof(DWORD);
        PDWORD  frameData = (PDWORD)lpFrame;
        DWORD   summaryData[2];
        LPSTR   callNameString;

        dprintf("INTRA: procNum = %d, isReq = %d, instdata = %08X\n", procedureNum, isRequest, InstData );

        InstData &= ( RPC_REQUEST_MASK | PROCNUM_MASK );
        InstData |= ( INTRACLUSTER_INDEX << INTERFACE_INDEX_SHIFT );
        summaryData[0] = InstData;

        //
        // mild hack to get Gum sequence number into summary data
        //
        switch ( procedureNum ) {
        case GUMQUEUELOCKINGUPDATE_PROC:
            if ( !isRequest ) {
                dprintf("GumQueueLockingUpdate resp: %d\n", frameData[0]);
                summaryData[1] = frameData[0];
                summaryDataSize += sizeof( DWORD );
            }
            break;

        case GUMATTEMPTJOINUPDATE_PROC:
            if ( isRequest ) {
                dprintf("GumAttemptJoinUpdate req: %d\n", frameData[3]);
                summaryData[1] = frameData[3];
                summaryDataSize += sizeof( DWORD );
            }
            break;

        case GUMUNLOCKUPDATE_PROC:
            if ( isRequest ) {
                dprintf("GumUnlockUpdate req: %d\n", frameData[1]);
                summaryData[1] = frameData[1];
                summaryDataSize += sizeof( DWORD );
            }
            break;

        case GUMUPDATENODE_PROC:
            if ( isRequest ) {
                dprintf("GumUpdateNode req: %d\n", frameData[2]);
                summaryData[1] = frameData[2];
                summaryDataSize += sizeof( DWORD );
            }
            break;

        case GUMJOINUPDATENODE_PROC:
            if ( isRequest ) {
                dprintf("GumJoinUpdateNode req: %d\n", frameData[3]);
                summaryData[1] = frameData[3];
                summaryDataSize += sizeof( DWORD );
            }
            break;

        case GUMGETNODESEQUENCE_PROC:
            if ( !isRequest ) {
                dprintf("GumGetNodeSequence resp: %d\n", frameData[0]);
                summaryData[1] = frameData[0];
                summaryDataSize += sizeof( DWORD );
            }
            break;

        case GUMATTEMPTLOCKINGUPDATE_PROC:
            if ( isRequest ) {
                dprintf("GumAttemptLockingUpdate req: %d\n", frameData[3]);
                summaryData[1] = frameData[3];
                summaryDataSize += sizeof( DWORD );
            }
            break;
        }

        AttachPropertyInstanceEx(hFrame,
                                 IntraCluster_GenProps[GENPROP_SUMMARY].hProperty,
                                 FrameLength, lpFrame, summaryDataSize, &summaryData, 0, 0, 0);

        //
        // get the name of the interface and attach it as a hidden property
        //
        callNameString = GET_PROCEDURE_NAME( INTRACLUSTER_INDEX, procedureNum );
            
        AttachPropertyInstanceEx(hFrame,
                                 IntraCluster_GenProps[GENPROP_CALLNAME].hProperty,
                                 FrameLength, lpFrame, strlen( callNameString ), callNameString, 0, 15, 0);

        if ( summaryDataSize > sizeof( DWORD )) {
            AttachPropertyInstanceEx(hFrame,
                                     IntraCluster_PrivProps[INTRACLUS_PROP_SEQNUMBER].hProperty,
                                     FrameLength,   
                                     lpFrame,
                                     sizeof( DWORD ),
                                     &summaryData[1],
                                     0, 1, 0);
        }
    }
    else {
        AttachPropertyInstance(hFrame,
                               IntraCluster_GenProps[GENPROP_ERROR_BAD_OPCODE].hProperty,
                               FrameLength,
                               lpFrame, 0, 0, 0);
    }
    return(NULL);
}


/*
 * Interface ExtroCluster, protocol RPC_ExtroCluster:
 */

VOID   WINAPI ExtroCluster_Register(HPROTOCOL hProtocol)
{
    register DWORD i;

    CreatePropertyDatabase(hProtocol, nExtroClusterGenProps);

    for (i = 0; i < nExtroClusterGenProps; ++i)
    {
        AddProperty(hProtocol, &ExtroCluster_GenProps[i]);
    }
}

VOID   WINAPI ExtroCluster_Deregister(HPROTOCOL hProtocol)
{
    DestroyPropertyDatabase(hProtocol);
}

LPBYTE WINAPI ExtroCluster_RecognizeFrame(HFRAME hFrame,
                  LPBYTE          MacFrame,
                  LPBYTE          lpFrame,
                  DWORD           MacType,
                  DWORD           FrameLength,
                  HPROTOCOL       hPreviousProtocol,
                  DWORD           hPreviousProtocolOffset,
                  LPDWORD         ProtocolStatusCode,
                  LPHPROTOCOL     hNextProtocol,
                  LPDWORD         InstData)
{
    HPROTOCOL hNext=NULL;   // next protocol to hand off to...
    WORD nStubLength;

    *ProtocolStatusCode = PROTOCOL_STATUS_CLAIMED;

#ifdef SSP_DECODE
    //  IF MSRPC VERSION == 4 AND AUTHPROTID !=0 THEN PASS OFF TO SSP
    if((*(MacFrame + hPreviousProtocolOffset) == 4) &&
       (*(MacFrame + hPreviousProtocolOffset + 78))) {

        hNext = GetProtocolFromName("SSP");

        if(hNext) {
            *ProtocolStatusCode = PROTOCOL_STATUS_NEXT_PROTOCOL;
            *hNextProtocol = hNext;
            nStubLength = *((LPWORD)(MacFrame + hPreviousProtocolOffset + 74));
            return(lpFrame + nStubLength);
        }
    }
#endif

    return(NULL);
}

DWORD  WINAPI ExtroCluster_FormatProperties(HFRAME hFrame,
                  LPBYTE          MacFrame,
                  LPBYTE          lpFrame,
                  DWORD           nPropertyInsts,
                  LPPROPERTYINST  lpInst)
{
    while (nPropertyInsts--) {
        ((FORMAT)lpInst->lpPropertyInfo->InstanceData)(lpInst);
        lpInst++;
    }

    return(NMERR_SUCCESS);
}

LPBYTE WINAPI ExtroCluster_AttachProperties(HFRAME hFrame,
                  LPBYTE          MacFrame,
                  LPBYTE          lpFrame,
                  DWORD           MacType,
                  DWORD           FrameLength,
                  HPROTOCOL       hPreviousProtocol,
                  DWORD           hPreviousProtocolOffset,
                  DWORD           InstData)
{
    CHAR    AuthenticationProtocolID = 0;
    WORD    nRPCLength;
    CHAR    AuthenticationLevel;
    DWORD   procedureNum = InstData & PROCNUM_MASK;

    //  IF THE MSRPC VERSION IS 4 LOOK FOR SECURITY TRAILER
    if(*(MacFrame + hPreviousProtocolOffset) == 4) {

        AuthenticationProtocolID = *(MacFrame + hPreviousProtocolOffset + 78);
        nRPCLength = *((LPWORD)(MacFrame + hPreviousProtocolOffset + 74));
        AuthenticationLevel = *(lpFrame + nRPCLength);
    }

    //  CHECK FOR ENCRYPTION
    if(AuthenticationProtocolID && (AuthenticationLevel == 6)) {

        AttachPropertyInstance(hFrame, 
                               ExtroCluster_GenProps[GENPROP_ENCRYPTED].hProperty,
                               nRPCLength,
                               lpFrame, 0, 0, 0);
    }
    else if ( procedureNum < NUM_EXTROCLUSTERPROCS ) {
        LPSTR   callNameString;

        InstData &= ( RPC_REQUEST_MASK | PROCNUM_MASK );
        InstData |= ( EXTROCLUSTER_INDEX << INTERFACE_INDEX_SHIFT );

        dprintf("EXTRO: procNum = %d, instdata = %08X\n", procedureNum, InstData );

        AttachPropertyInstanceEx(hFrame,
                                 ExtroCluster_GenProps[GENPROP_SUMMARY].hProperty,
                                 FrameLength, lpFrame, sizeof(DWORD), &InstData, 0, 0, 0);

        //
        // get the name of the interface and attach it as a hidden property
        //
        callNameString = GET_PROCEDURE_NAME( EXTROCLUSTER_INDEX, procedureNum );
            
        AttachPropertyInstanceEx(hFrame,
                                 ExtroCluster_GenProps[GENPROP_CALLNAME].hProperty,
                                 FrameLength, lpFrame, strlen( callNameString ), callNameString, 0, 15, 0);
    } else {
        AttachPropertyInstance(hFrame,
                               ExtroCluster_GenProps[GENPROP_ERROR_BAD_OPCODE].hProperty,
                               FrameLength,
                               lpFrame, 0, 0, 0);
    }
    return(NULL);
}


/*
 * Interface clusapi, protocol RPC_clusapi:
 */

VOID WINAPI
Clusapi_Register(
    HPROTOCOL hProtocol
    )
{
    register DWORD i;

    CreatePropertyDatabase(hProtocol, nClusapiGenProps);

    for (i = 0; i < nClusapiGenProps; ++i)
    {
        AddProperty(hProtocol, &Clusapi_GenProps[i]);
    }
}

VOID WINAPI
Clusapi_Deregister(
    HPROTOCOL hProtocol
    )
{
    DestroyPropertyDatabase(hProtocol);
}

LPBYTE WINAPI
Clusapi_RecognizeFrame(
    HFRAME hFrame,
    LPBYTE          MacFrame,
    LPBYTE          lpFrame,
    DWORD           MacType,
    DWORD           FrameLength,
    HPROTOCOL       hPreviousProtocol,
    DWORD           hPreviousProtocolOffset,
    LPDWORD         ProtocolStatusCode,
    LPHPROTOCOL     hNextProtocol,
    LPDWORD         InstData
    )
{
    HPROTOCOL hNext=NULL;   // next protocol to hand off to...
    WORD nStubLength;

    *ProtocolStatusCode = PROTOCOL_STATUS_CLAIMED;

#ifdef SSP_DECODE
    //  IF MSRPC VERSION == 4 AND AUTHPROTID !=0 THEN PASS OFF TO SSP
    if((*(MacFrame + hPreviousProtocolOffset) == 4) &&
       (*(MacFrame + hPreviousProtocolOffset + 78))) {

        hNext = GetProtocolFromName("SSP");

        if(hNext) {
            *ProtocolStatusCode = PROTOCOL_STATUS_NEXT_PROTOCOL;
            *hNextProtocol = hNext;
            nStubLength = *((LPWORD)(MacFrame + hPreviousProtocolOffset + 74));
            return(lpFrame + nStubLength);
        }
    }
#endif

    return(NULL);
}

DWORD WINAPI
Clusapi_FormatProperties(
    HFRAME hFrame,
    LPBYTE          MacFrame,
    LPBYTE          lpFrame,
    DWORD           nPropertyInsts,
    LPPROPERTYINST  lpInst
    )
{
    while (nPropertyInsts--) {
        ((FORMAT)lpInst->lpPropertyInfo->InstanceData)(lpInst);
        lpInst++;
    }

    return(NMERR_SUCCESS);
}

LPBYTE WINAPI
Clusapi_AttachProperties(
    HFRAME hFrame,
    LPBYTE          MacFrame,
    LPBYTE          lpFrame,
    DWORD           MacType,
    DWORD           FrameLength,
    HPROTOCOL       hPreviousProtocol,
    DWORD           hPreviousProtocolOffset,
    DWORD           InstData
    )
{
    CHAR    AuthenticationProtocolID = 0;
    WORD    nRPCLength;
    CHAR    AuthenticationLevel;
    DWORD   procedureNum = InstData & PROCNUM_MASK;

    //  IF THE MSRPC VERSION IS 4 LOOK FOR SECURITY TRAILER
    if(*(MacFrame + hPreviousProtocolOffset) == 4) {

        AuthenticationProtocolID = *(MacFrame + hPreviousProtocolOffset + 78);
        nRPCLength = *((LPWORD)(MacFrame + hPreviousProtocolOffset + 74));
        AuthenticationLevel = *(lpFrame + nRPCLength);
    }

    //  CHECK FOR ENCRYPTION
    if(AuthenticationProtocolID && (AuthenticationLevel == 6)) {

        AttachPropertyInstance(hFrame, 
                               Clusapi_GenProps[GENPROP_ENCRYPTED].hProperty,
                               nRPCLength,
                               lpFrame, 0, 0, 0);
    }
    else if ( procedureNum < NUM_CLUSAPIPROCS ) {
        LPSTR   callNameString;

        InstData &= ( RPC_REQUEST_MASK | PROCNUM_MASK );
        InstData |= ( CLUSAPI_INDEX << INTERFACE_INDEX_SHIFT );

        dprintf("CLUSAPI: procNum = %d, instdata = %08X\n", procedureNum, InstData );

        AttachPropertyInstanceEx(hFrame,
                                 Clusapi_GenProps[GENPROP_SUMMARY].hProperty,
                                 FrameLength, lpFrame, sizeof(DWORD), &InstData, 0, 0, 0);

        //
        // get the name of the interface and attach it as a hidden property
        //
        callNameString = GET_PROCEDURE_NAME( CLUSAPI_INDEX, procedureNum );
            
        AttachPropertyInstanceEx(hFrame,
                                 Clusapi_GenProps[GENPROP_CALLNAME].hProperty,
                                 FrameLength, lpFrame, strlen( callNameString ), callNameString, 0, 15, 0);
    } else {
        AttachPropertyInstance(hFrame,
                               Clusapi_GenProps[GENPROP_ERROR_BAD_OPCODE].hProperty,
                               FrameLength,
                               lpFrame, 0, 0, 0);
    }
    return(NULL);
}

/*
 * Interface JoinVersion, protocol RPC_JoinVersion:
 */

VOID   WINAPI JoinVersion_Register(HPROTOCOL hProtocol)
{
    register DWORD i;

    CreatePropertyDatabase(hProtocol, nJoinVersionGenProps);

    for (i = 0; i < nJoinVersionGenProps; ++i)
    {
        AddProperty(hProtocol, &JoinVersion_GenProps[i]);
    }
}

VOID   WINAPI JoinVersion_Deregister(HPROTOCOL hProtocol)
{
    DestroyPropertyDatabase(hProtocol);
}

LPBYTE WINAPI
JoinVersion_RecognizeFrame(
    HFRAME          hFrame,
    LPBYTE          MacFrame,
    LPBYTE          lpFrame,
    DWORD           MacType,
    DWORD           FrameLength,
    HPROTOCOL       hPreviousProtocol,
    DWORD           hPreviousProtocolOffset,
    LPDWORD         ProtocolStatusCode,
    LPHPROTOCOL     hNextProtocol,
    LPDWORD         InstData
    )
{
    HPROTOCOL hNext=NULL;   // next protocol to hand off to...
    WORD nStubLength;

    *ProtocolStatusCode = PROTOCOL_STATUS_CLAIMED;

#ifdef SSP_DECODE
    //  IF MSRPC VERSION == 4 AND AUTHPROTID !=0 THEN PASS OFF TO SSP
    if((*(MacFrame + hPreviousProtocolOffset) == 4) &&
       (*(MacFrame + hPreviousProtocolOffset + 78))) {

        hNext = GetProtocolFromName("SSP");

        if(hNext) {
            *ProtocolStatusCode = PROTOCOL_STATUS_NEXT_PROTOCOL;
            *hNextProtocol = hNext;
            nStubLength = *((LPWORD)(MacFrame + hPreviousProtocolOffset + 74));
            return(lpFrame + nStubLength);
        }
    }
#endif

    return(NULL);
}

DWORD  WINAPI
JoinVersion_FormatProperties(
    HFRAME hFrame,
    LPBYTE          MacFrame,
    LPBYTE          lpFrame,
    DWORD           nPropertyInsts,
    LPPROPERTYINST  lpInst
    )
{
    while (nPropertyInsts--) {
        ((FORMAT)lpInst->lpPropertyInfo->InstanceData)(lpInst);
        lpInst++;
    }

    return(NMERR_SUCCESS);
}

LPBYTE WINAPI
JoinVersion_AttachProperties(
    HFRAME hFrame,
    LPBYTE          MacFrame,
    LPBYTE          lpFrame,
    DWORD           MacType,
    DWORD           FrameLength,
    HPROTOCOL       hPreviousProtocol,
    DWORD           hPreviousProtocolOffset,
    DWORD           InstData
    )
{
    CHAR    AuthenticationProtocolID = 0;
    WORD    nRPCLength;
    CHAR    AuthenticationLevel;
    DWORD   procedureNum = InstData & PROCNUM_MASK;

    //  IF THE MSRPC VERSION IS 4 LOOK FOR SECURITY TRAILER
    if(*(MacFrame + hPreviousProtocolOffset) == 4) {

        AuthenticationProtocolID = *(MacFrame + hPreviousProtocolOffset + 78);
        nRPCLength = *((LPWORD)(MacFrame + hPreviousProtocolOffset + 74));
        AuthenticationLevel = *(lpFrame + nRPCLength);
    }

    //  CHECK FOR ENCRYPTION
    if(AuthenticationProtocolID && (AuthenticationLevel == 6)) {

        AttachPropertyInstance(hFrame, 
                               JoinVersion_GenProps[GENPROP_ENCRYPTED].hProperty,
                               nRPCLength,
                               lpFrame, 0, 0, 0);
    }
    else if ( procedureNum < NUM_JOINVERSIONPROCS ) {
        LPSTR  callNameString;

        InstData &= ( RPC_REQUEST_MASK | PROCNUM_MASK );
        InstData |= ( JOINVERSION_INDEX << INTERFACE_INDEX_SHIFT );

        dprintf("JOINVERSION: procNum = %d, instdata = %08X\n", procedureNum, InstData );

        AttachPropertyInstanceEx(hFrame,
                                 JoinVersion_GenProps[GENPROP_SUMMARY].hProperty,
                                 FrameLength, lpFrame, sizeof(DWORD), &InstData, 0, 0, 0);
        //
        // get the name of the interface and attach it as a hidden property
        //
        callNameString = GET_PROCEDURE_NAME( JOINVERSION_INDEX, procedureNum );
            
        AttachPropertyInstanceEx(hFrame,
                                 JoinVersion_GenProps[GENPROP_CALLNAME].hProperty,
                                 FrameLength, lpFrame, strlen( callNameString ), callNameString, 0, 15, 0);
    } else {
        AttachPropertyInstance(hFrame,
                               JoinVersion_GenProps[GENPROP_ERROR_BAD_OPCODE].hProperty,
                               FrameLength,
                               lpFrame, 0, 0, 0);
    }
    return(NULL);
}