ANSC_STATUS
AnscLpccoCancel
    (
        ANSC_HANDLE                 hThisObject
    )
{
    ANSC_STATUS                     returnStatus  = ANSC_STATUS_SUCCESS;
    PANSC_LPC_CONNECTOR_OBJECT      pMyObject     = (PANSC_LPC_CONNECTOR_OBJECT   )hThisObject;
    PANSC_TIMER_DESCRIPTOR_OBJECT   pConnTimerObj = (PANSC_TIMER_DESCRIPTOR_OBJECT)pMyObject->hConnTimerObj;

    if ( !pMyObject->bActive )
    {
        return  ANSC_STATUS_SUCCESS;
    }
    else
    {
        pMyObject->bActive = FALSE;
    }

    if ( TRUE )
    {
        pConnTimerObj->Stop((ANSC_HANDLE)pConnTimerObj);
    }

    returnStatus = pMyObject->Unbind((ANSC_HANDLE)pMyObject);

    return  returnStatus;
}
ANSC_STATUS
SlapLsoCancel
    (
        ANSC_HANDLE                 hThisObject
    )
{
    ANSC_STATUS                     returnStatus      = ANSC_STATUS_SUCCESS;
    PSLAP_LOAM_SERVER_OBJECT        pMyObject         = (PSLAP_LOAM_SERVER_OBJECT  )hThisObject;
    PANSC_LPC_CONNECTOR_OBJECT      pAnscLpcConnector = (PANSC_LPC_CONNECTOR_OBJECT)pMyObject->hAnscLpcConnector;

    if ( !pMyObject->bActive )
    {
        return  ANSC_STATUS_SUCCESS;
    }
    else
    {
        pMyObject->bActive = FALSE;
    }

    if ( pAnscLpcConnector )
    {
        pAnscLpcConnector->SetAnscCpcIf((ANSC_HANDLE)pAnscLpcConnector, (ANSC_HANDLE)NULL);
    }

    return  ANSC_STATUS_SUCCESS;
}
ANSC_STATUS
AnscLpccoImcCancel
    (
        ANSC_HANDLE                 hThisObject
    )
{
    ANSC_STATUS                     returnStatus = ANSC_STATUS_SUCCESS;
    PANSC_LPC_CONNECTOR_OBJECT      pMyObject    = (PANSC_LPC_CONNECTOR_OBJECT)hThisObject;

    returnStatus = pMyObject->Cancel((ANSC_HANDLE)pMyObject);

    return  returnStatus;
}
ANSC_STATUS
AnscLpccoAddPartyAddr
    (
        ANSC_HANDLE                 hThisObject,
        ANSC_HANDLE                 party_addr
    )
{
    ANSC_STATUS                     returnStatus = ANSC_STATUS_SUCCESS;
    PANSC_LPC_CONNECTOR_OBJECT      pMyObject    = (PANSC_LPC_CONNECTOR_OBJECT)hThisObject;
    PANSC_LPC_PARTY_ADDR            pPartyAddr   = (PANSC_LPC_PARTY_ADDR      )party_addr;
    char*                           pPartyName   = (char*                     )pPartyAddr->PartyName;
    ULONG                           ulHashIndex  = AnscHashString(pPartyName, AnscSizeOfString(pPartyName), ANSC_LPCCO_PARTY_TABLE_SIZE);

    if ( pMyObject->GetPartyAddr
            (
                (ANSC_HANDLE)pMyObject,
                pPartyName
            ) != (ANSC_HANDLE)NULL )
    {
        AnscTrace
            (
                "[AnscLpccoAddPartyAddr] collison found, failed to add party <%s> from %d.%d.%d.%d (%d)\n",
                pPartyAddr->PartyName,
                pPartyAddr->PartyAddr.Dot[0],
                pPartyAddr->PartyAddr.Dot[1],
                pPartyAddr->PartyAddr.Dot[2],
                pPartyAddr->PartyAddr.Dot[3],
                pPartyAddr->PartyPort
            );

        return  ANSC_STATUS_COLLISION;
    }

    AnscAcquireLock   (&pMyObject->PartyTableLock);
    AnscQueuePushEntry(&pMyObject->PartyTable[ulHashIndex], &pPartyAddr->Linkage);
    AnscReleaseLock   (&pMyObject->PartyTableLock);

    AnscTrace
        (
            "[AnscLpccoAddPartyAddr] party <%s> from %d.%d.%d.%d (%d) has been added.\n",
            pPartyAddr->PartyName,
            pPartyAddr->PartyAddr.Dot[0],
            pPartyAddr->PartyAddr.Dot[1],
            pPartyAddr->PartyAddr.Dot[2],
            pPartyAddr->PartyAddr.Dot[3],
            pPartyAddr->PartyPort
        );

    return  ANSC_STATUS_SUCCESS;
}
ANSC_STATUS
AnscLpccoRemove
    (
        ANSC_HANDLE                 hThisObject
    )
{
    ANSC_STATUS                     returnStatus  = ANSC_STATUS_SUCCESS;
    PANSC_LPC_CONNECTOR_OBJECT      pMyObject     = (PANSC_LPC_CONNECTOR_OBJECT   )hThisObject;
    PANSC_IMC_INTERFACE             pAnscImcIf    = (PANSC_IMC_INTERFACE          )pMyObject->hAnscImcIf;
    PANSC_CPC_INTERFACE             pAnscCpcIf    = (PANSC_CPC_INTERFACE          )pMyObject->hAnscCpcIf;
    PANSC_TIMER_DESCRIPTOR_OBJECT   pConnTimerObj = (PANSC_TIMER_DESCRIPTOR_OBJECT)pMyObject->hConnTimerObj;
    PANSC_TDO_CLIENT_OBJECT         pConnTimerIf  = (PANSC_TDO_CLIENT_OBJECT      )pMyObject->hConnTimerIf;

    pMyObject->Cancel((ANSC_HANDLE)pMyObject);
    pMyObject->Reset ((ANSC_HANDLE)pMyObject);

    if ( pAnscImcIf )
    {
        AnscFreeMemory(pAnscImcIf);

        pMyObject->hAnscImcIf = (ANSC_HANDLE)NULL;
    }

    if ( pAnscCpcIf )
    {
        AnscFreeMemory(pAnscCpcIf);

        pMyObject->hAnscCpcIf = (ANSC_HANDLE)NULL;
    }

    if ( pConnTimerObj )
    {
        pConnTimerObj->Remove((ANSC_HANDLE)pConnTimerObj);
    }

    if ( pConnTimerIf )
    {
        AnscFreeMemory(pConnTimerIf);
    }

    AnscFreeLock(&pMyObject->AccessLock    );
    AnscFreeLock(&pMyObject->PartyTableLock);
    AnscFreeLock(&pMyObject->PcallQueueLock);
    AnscCoRemove((ANSC_HANDLE)pMyObject    );

    return  ANSC_STATUS_SUCCESS;
}
BOOL
AnscLpccoImcIsPartyConnected
    (
        ANSC_HANDLE                 hThisObject,
        char*                       party_name,
        BOOL                        bOutgoingConn
    )
{
    ANSC_STATUS                     returnStatus = ANSC_STATUS_SUCCESS;
    PANSC_LPC_CONNECTOR_OBJECT      pMyObject    = (PANSC_LPC_CONNECTOR_OBJECT)hThisObject;
    PANSC_LPC_PARTY_ADDR            pPartyAddr   = (PANSC_LPC_PARTY_ADDR      )NULL;

    pPartyAddr =
        (PANSC_LPC_PARTY_ADDR)pMyObject->GetPartyAddr
            (
                (ANSC_HANDLE)pMyObject,
                party_name
            );

    if ( !pPartyAddr )
    {
        return  FALSE;
    }
    else if ( bOutgoingConn )
    {
        if ( pPartyAddr->PartyState & ANSC_LPC_PARTY_STATE_connectedOut )
        {
            return  TRUE;
        }
    }
    else
    {
        if ( pPartyAddr->PartyState & ANSC_LPC_PARTY_STATE_connectedIn )
        {
            return  TRUE;
        }
    }

    return  FALSE;
}
ANSC_STATUS
SlapLsoSetAnscLpcConnector
    (
        ANSC_HANDLE                 hThisObject,
        ANSC_HANDLE                 hLpcConnector
    )
{
    ANSC_STATUS                     returnStatus      = ANSC_STATUS_SUCCESS;
    PSLAP_LOAM_SERVER_OBJECT        pMyObject         = (PSLAP_LOAM_SERVER_OBJECT  )hThisObject;
    PSLAP_LOAM_SERVER_PROPERTY      pProperty         = (PSLAP_LOAM_SERVER_PROPERTY)&pMyObject->Property;
    PANSC_LPC_CONNECTOR_OBJECT      pAnscLpcConnector = (PANSC_LPC_CONNECTOR_OBJECT)pMyObject->hAnscLpcConnector;

    pMyObject->hAnscLpcConnector = hLpcConnector;
    pAnscLpcConnector            = (PANSC_LPC_CONNECTOR_OBJECT)pMyObject->hAnscLpcConnector;

    if ( pAnscLpcConnector )
    {
        pAnscLpcConnector->SetAnscCpcIf((ANSC_HANDLE)pAnscLpcConnector, pMyObject->hAnscCpcIf);
    }

    return  ANSC_STATUS_SUCCESS;
}
ANSC_STATUS
SlapLsoEngage
    (
        ANSC_HANDLE                 hThisObject
    )
{
    ANSC_STATUS                     returnStatus      = ANSC_STATUS_SUCCESS;
    PSLAP_LOAM_SERVER_OBJECT        pMyObject         = (PSLAP_LOAM_SERVER_OBJECT  )hThisObject;
    PANSC_LPC_CONNECTOR_OBJECT      pAnscLpcConnector = (PANSC_LPC_CONNECTOR_OBJECT)pMyObject->hAnscLpcConnector;
    PSLAP_UOA_INTERFACE             pSlapUoaIf        = (PSLAP_UOA_INTERFACE       )pMyObject->hSlapUoaIf;

    if ( pMyObject->bActive )
    {
        return  ANSC_STATUS_SUCCESS;
    }
    else if ( !pAnscLpcConnector || !pSlapUoaIf )
    {
        return  ANSC_STATUS_NOT_READY;
    }

    if ( pAnscLpcConnector )
    {
        pAnscLpcConnector->SetAnscCpcIf((ANSC_HANDLE)pAnscLpcConnector, pMyObject->hAnscCpcIf);
    }

    returnStatus = pMyObject->SetupEnv((ANSC_HANDLE)pMyObject);

    if ( returnStatus != ANSC_STATUS_SUCCESS )
    {
        return  returnStatus;
    }
    else
    {
        pMyObject->bActive = TRUE;
    }

    return  ANSC_STATUS_SUCCESS;
}
ANSC_STATUS
AnscLpccoEngage
    (
        ANSC_HANDLE                 hThisObject
    )
{
    ANSC_STATUS                     returnStatus  = ANSC_STATUS_SUCCESS;
    PANSC_LPC_CONNECTOR_OBJECT      pMyObject     = (PANSC_LPC_CONNECTOR_OBJECT   )hThisObject;
    PANSC_TIMER_DESCRIPTOR_OBJECT   pConnTimerObj = (PANSC_TIMER_DESCRIPTOR_OBJECT)pMyObject->hConnTimerObj;

    if ( pMyObject->bActive )
    {
        return  ANSC_STATUS_SUCCESS;
    }
    else if ( !pMyObject->PartyName )
    {
        return  ANSC_STATUS_NOT_READY;
    }

    /*
     * We first need to add the local address information into the party table. The upper layer
     * MUST configure the 'party_name' before engaging the IMC. We then initiate contact to the
     * central LPC manager. No, wait! It seems that we cannot determine the local address infor-
     * mation until the LPC manager assigns one.
     */
    returnStatus = pMyObject->Enroll((ANSC_HANDLE)pMyObject);

    if ( returnStatus != ANSC_STATUS_SUCCESS )
    {
        return  returnStatus;
    }

    pMyObject->bActive = TRUE;

    return  ANSC_STATUS_SUCCESS;
}
ANSC_STATUS
AnscLpccoConnTimerInvoke
    (
        ANSC_HANDLE                 hThisObject
    )
{
    ANSC_STATUS                     returnStatus = ANSC_STATUS_SUCCESS;
    PANSC_LPC_CONNECTOR_OBJECT      pMyObject    = (PANSC_LPC_CONNECTOR_OBJECT)hThisObject;
    PANSC_CPC_INTERFACE             pAnscCpcIf   = (PANSC_CPC_INTERFACE       )pMyObject->hAnscCpcIf;
    PANSC_LPC_PARTY_ADDR            pPartyAddr   = (PANSC_LPC_PARTY_ADDR      )NULL;
    PSINGLE_LINK_ENTRY              pSLinkEntry  = (PSINGLE_LINK_ENTRY        )NULL;
    ULONG                           i            = 0;

    if ( !pMyObject->bActive )
    {
        return  ANSC_STATUS_SUCCESS;
    }

    AnscAcquireLock(&pMyObject->PartyTableLock);

    for ( i = 0; i < ANSC_LPCCO_PARTY_TABLE_SIZE; i++ )
    {
        pSLinkEntry = AnscQueueGetFirstEntry(&pMyObject->PartyTable[i]);

        while ( pSLinkEntry )
        {
            pPartyAddr  = ACCESS_ANSC_LPC_PARTY_ADDR(pSLinkEntry);
            pSLinkEntry = AnscQueueGetNextEntry(pSLinkEntry);

            if ( pPartyAddr->Timestamp == 0 )
            {
                continue;
            }
            else if ( (pPartyAddr->PartyState & ANSC_LPC_PARTY_STATE_connectedIn ) ||
                      (pPartyAddr->PartyState & ANSC_LPC_PARTY_STATE_connectedOut) )
            {
                continue;
            }
            else if ( pPartyAddr->PartyType == ANSC_LPC_PARTY_TYPE_manager )
            {
                if ( (pMyObject->LpcOpmode  == ANSC_LPC_OPMODE_CLIENT) &&
                     (pMyObject->bConnected == TRUE                  ) )
                {
                    pMyObject->bConnected = FALSE;
                }

                continue;
            }
            else if ( pPartyAddr->PartyType != ANSC_LPC_PARTY_TYPE_client )
            {
                continue;
            }
            else if ( pPartyAddr->RefCount > 0 )
            {
                continue;
            }

            AnscQueuePopEntryByLink(&pMyObject->PartyTable[i], &pPartyAddr->Linkage);

            if ( TRUE )
            {
                returnStatus =
                    pAnscCpcIf->NotifyEvent
                        (
                            pAnscCpcIf->hOwnerContext,
                            ANSC_CPC_EVENT_DISCONNECTED,
                            (ANSC_HANDLE)pPartyAddr
                        );
            }

            AnscFreeMemory(pPartyAddr);
        }
    }

    AnscReleaseLock(&pMyObject->PartyTableLock);

    if ( (pMyObject->LpcOpmode  == ANSC_LPC_OPMODE_CLIENT) &&
         (pMyObject->bConnected == FALSE                 ) )
    {
        returnStatus = pMyObject->ConnectToManager((ANSC_HANDLE)pMyObject);
    }

    return  ANSC_STATUS_SUCCESS;
}
ANSC_STATUS
SlapAmoCancel
    (
        ANSC_HANDLE                 hThisObject
    )
{
    ANSC_STATUS                     returnStatus       = ANSC_STATUS_SUCCESS;
    PSLAP_ACCESS_MANAGER_OBJECT     pMyObject          = (PSLAP_ACCESS_MANAGER_OBJECT  )hThisObject;
    PSLAP_ACCESS_MANAGER_PROPERTY   pProperty          = (PSLAP_ACCESS_MANAGER_PROPERTY)&pMyObject->Property;
    PSLAP_GOA_INTERFACE             pSlapGoaIf         = (PSLAP_GOA_INTERFACE          )pMyObject->hSlapGoaIf;
    PSLAP_ENV_CONTROLLER_OBJECT     pSlapEnvController = (PSLAP_ENV_CONTROLLER_OBJECT  )pMyObject->hSlapEnvController;
    PSLAP_LOAM_CLIENT_OBJECT        pSlapLoamClient    = (PSLAP_LOAM_CLIENT_OBJECT     )pMyObject->hSlapLoamClient;
    PSLAP_LOAM_SERVER_OBJECT        pSlapLoamServer    = (PSLAP_LOAM_SERVER_OBJECT     )pMyObject->hSlapLoamServer;
    PANSC_LPC_CONNECTOR_OBJECT      pAnscLpcConnector  = (PANSC_LPC_CONNECTOR_OBJECT   )pMyObject->hAnscLpcConnector;

    if ( !pMyObject->bActive )
    {
        return  ANSC_STATUS_SUCCESS;
    }
    else
    {
        pMyObject->bActive = FALSE;
    }


    #ifdef  _ANSC_SLAP_LPC_

    if ( pSlapLoamClient )
    {
        pSlapLoamClient->Cancel((ANSC_HANDLE)pSlapLoamClient);
        pSlapLoamClient->Remove((ANSC_HANDLE)pSlapLoamClient);

        pMyObject->hSlapLoamClient = (ANSC_HANDLE)NULL;
    }

    if ( pSlapLoamServer )
    {
        pSlapLoamServer->Cancel((ANSC_HANDLE)pSlapLoamServer);
        pSlapLoamServer->Remove((ANSC_HANDLE)pSlapLoamServer);

        pMyObject->hSlapLoamServer = (ANSC_HANDLE)NULL;
    }

    if ( pAnscLpcConnector )
    {
        pAnscLpcConnector->Cancel((ANSC_HANDLE)pAnscLpcConnector);
        pAnscLpcConnector->Remove((ANSC_HANDLE)pAnscLpcConnector);

        pMyObject->hAnscLpcConnector = (ANSC_HANDLE)NULL;
    }

    #endif

    if ( pSlapEnvController )
    {
        pSlapEnvController->Cancel((ANSC_HANDLE)pSlapEnvController);
    }


    return  ANSC_STATUS_SUCCESS;
}
ANSC_STATUS
SlapAmoEngage
    (
        ANSC_HANDLE                 hThisObject
    )
{
    ANSC_STATUS                     returnStatus       = ANSC_STATUS_SUCCESS;
    PSLAP_ACCESS_MANAGER_OBJECT     pMyObject          = (PSLAP_ACCESS_MANAGER_OBJECT  )hThisObject;
    PSLAP_ACCESS_MANAGER_PROPERTY   pProperty          = (PSLAP_ACCESS_MANAGER_PROPERTY)&pMyObject->Property;
    PSLAP_GOA_INTERFACE             pSlapGoaIf         = (PSLAP_GOA_INTERFACE          )pMyObject->hSlapGoaIf;
    PSLAP_ENV_CONTROLLER_OBJECT     pSlapEnvController = (PSLAP_ENV_CONTROLLER_OBJECT  )pMyObject->hSlapEnvController;
    PSLAP_LOAM_CLIENT_OBJECT        pSlapLoamClient    = (PSLAP_LOAM_CLIENT_OBJECT     )pMyObject->hSlapLoamClient;
    PSLAP_LOAM_SERVER_OBJECT        pSlapLoamServer    = (PSLAP_LOAM_SERVER_OBJECT     )pMyObject->hSlapLoamServer;
    PANSC_LPC_CONNECTOR_OBJECT      pAnscLpcConnector  = (PANSC_LPC_CONNECTOR_OBJECT   )pMyObject->hAnscLpcConnector;
#ifdef   _SLAP_IPC_USE_TCP_SOCKET
    PANSC_LPCCO_TCP_OBJECT          pAnscLpccoTcp      = (PANSC_LPCCO_TCP_OBJECT       )pAnscLpcConnector;
#else
    PANSC_LPCCO_UDP_OBJECT          pAnscLpccoUdp      = (PANSC_LPCCO_UDP_OBJECT       )pAnscLpcConnector;
#endif
    PSLAP_UOA_INTERFACE             pSlapUoaIf         = (PSLAP_UOA_INTERFACE          )pSlapEnvController->GetSlapUoaIf((ANSC_HANDLE)pSlapEnvController);
    char                            lpcPartyName[64];

    if ( pMyObject->bActive )
    {
        return  ANSC_STATUS_SUCCESS;
    }
    else if (  (pProperty->AggregationMode & SLAP_GOA_MODE_imcpServer ) &&
              !(pProperty->AggregationMode & SLAP_GOA_MODE_thisProcess) )
    {
        return  ANSC_STATUS_BAD_PARAMETER;
    }

    if ( TRUE )
    {
        if ( pProperty->AggregationMode & SLAP_GOA_MODE_enablePooling )
        {
            pSlapEnvController->BssSetPoolingFlag((ANSC_HANDLE)pSlapEnvController, TRUE);
        }
        else
        {
            pSlapEnvController->BssSetPoolingFlag((ANSC_HANDLE)pSlapEnvController, FALSE);
        }

        pSlapEnvController->Engage((ANSC_HANDLE)pSlapEnvController);
    }


    #ifdef  _ANSC_SLAP_LPC_

    if ( (pProperty->AggregationMode & SLAP_GOA_MODE_imcpClient) ||
         (pProperty->AggregationMode & SLAP_GOA_MODE_imcpServer) )
    {
        if ( !pAnscLpcConnector )
        {
#ifdef   _SLAP_IPC_USE_TCP_SOCKET
            pAnscLpcConnector =
                (PANSC_LPC_CONNECTOR_OBJECT)AnscCreateLpccoTcp
                    (
                        pMyObject->hContainerContext,
                        (ANSC_HANDLE)pMyObject,
                        (ANSC_HANDLE)NULL
                    );
#else
            pAnscLpcConnector =
                (PANSC_LPC_CONNECTOR_OBJECT)AnscCreateLpccoUdp
                    (
                        pMyObject->hContainerContext,
                        (ANSC_HANDLE)pMyObject,
                        (ANSC_HANDLE)NULL
                    );
#endif

            if ( !pAnscLpcConnector )
            {
                return  ANSC_STATUS_RESOURCES;
            }
            else
            {
                pMyObject->hAnscLpcConnector = (ANSC_HANDLE           )pAnscLpcConnector;
#ifdef   _SLAP_IPC_USE_TCP_SOCKET
                pAnscLpccoTcp                = (PANSC_LPCCO_TCP_OBJECT)pAnscLpcConnector;
#else
                pAnscLpccoUdp                = (PANSC_LPCCO_UDP_OBJECT)pAnscLpcConnector;
#endif
            }
        }

        if ( TRUE )
        {
            AnscZeroMemory(lpcPartyName, 64);

            _ansc_sprintf
                (
                    lpcPartyName,
                    "slapAccessManager-0x%x-0x%x@%d.%d.%d.%d",
                    (ULONG)AnscGetProcessId    (),
                    (ULONG)AnscGetCurTaskHandle(),
                    pProperty->MyAddress.Dot[0],
                    pProperty->MyAddress.Dot[1],
                    pProperty->MyAddress.Dot[2],
                    pProperty->MyAddress.Dot[3]
                );
        }

        pAnscLpcConnector->ImcSetLpcOpmode  ((ANSC_HANDLE)pAnscLpcConnector, ANSC_LPC_OPMODE_CLIENT       );
        pAnscLpcConnector->ImcSetPartyName  ((ANSC_HANDLE)pAnscLpcConnector, lpcPartyName                 );
#ifdef   _SLAP_IPC_USE_TCP_SOCKET
        pAnscLpccoTcp    ->SetMyPort        ((ANSC_HANDLE)pAnscLpccoTcp,     pProperty->LpcPartyPort      );
        pAnscLpccoTcp    ->SetMyAddress     ((ANSC_HANDLE)pAnscLpccoTcp,     pProperty->MyAddress.Dot     );
        pAnscLpccoTcp    ->SetManagerAddress((ANSC_HANDLE)pAnscLpccoTcp,     pProperty->ManagerAddress.Dot);
#else
        pAnscLpccoUdp    ->SetMyPort        ((ANSC_HANDLE)pAnscLpccoUdp,     pProperty->LpcPartyPort      );
        pAnscLpccoUdp    ->SetMyAddress     ((ANSC_HANDLE)pAnscLpccoUdp,     pProperty->MyAddress.Dot     );
        pAnscLpccoUdp    ->SetManagerAddress((ANSC_HANDLE)pAnscLpccoUdp,     pProperty->ManagerAddress.Dot);
#endif
        pAnscLpcConnector->Engage           ((ANSC_HANDLE)pAnscLpcConnector);
    }

    if ( pProperty->AggregationMode & SLAP_GOA_MODE_imcpClient )
    {
        if ( !pSlapLoamClient )
        {
            pSlapLoamClient =
                (PSLAP_LOAM_CLIENT_OBJECT)SlapCreateLoamClient
                    (
                        pMyObject->hContainerContext,
                        (ANSC_HANDLE)pMyObject,
                        (ANSC_HANDLE)NULL
                    );

            if ( !pSlapLoamClient )
            {
                return  ANSC_STATUS_RESOURCES;
            }
            else
            {
                pMyObject->hSlapLoamClient = (ANSC_HANDLE)pSlapLoamClient;
            }
        }

        if ( pProperty->AggregationMode & SLAP_GOA_MODE_mobilitySupport )
        {
            pSlapLoamClient->SetMobilityOn((ANSC_HANDLE)pSlapLoamClient, TRUE);
        }
        else
        {
            pSlapLoamClient->SetMobilityOn((ANSC_HANDLE)pSlapLoamClient, FALSE);
        }

        pSlapLoamClient->SetAnscLpcConnector((ANSC_HANDLE)pSlapLoamClient, (ANSC_HANDLE)pAnscLpcConnector);
        pSlapLoamClient->Engage             ((ANSC_HANDLE)pSlapLoamClient);
    }

    if ( pProperty->AggregationMode & SLAP_GOA_MODE_imcpServer )
    {
        if ( !pSlapLoamServer )
        {
            pSlapLoamServer =
                (PSLAP_LOAM_SERVER_OBJECT)SlapCreateLoamServer
                    (
                        pMyObject->hContainerContext,
                        (ANSC_HANDLE)pMyObject,
                        (ANSC_HANDLE)NULL
                    );

            if ( !pSlapLoamServer )
            {
                return  ANSC_STATUS_RESOURCES;
            }
            else
            {
                pMyObject->hSlapLoamServer = (ANSC_HANDLE)pSlapLoamServer;
            }
        }

        if ( pProperty->AggregationMode & SLAP_GOA_MODE_autoExport )
        {
            pSlapLoamServer->SetMobilityOn((ANSC_HANDLE)pSlapLoamServer, TRUE);
        }
        else
        {
            pSlapLoamServer->SetMobilityOn((ANSC_HANDLE)pSlapLoamServer, FALSE);
        }

        pSlapLoamServer->SetAnscLpcConnector((ANSC_HANDLE)pSlapLoamServer, (ANSC_HANDLE)pAnscLpcConnector);
        pSlapLoamServer->SetSlapUoaIf       ((ANSC_HANDLE)pSlapLoamServer, (ANSC_HANDLE)pSlapUoaIf       );
        pSlapLoamServer->Engage             ((ANSC_HANDLE)pSlapLoamServer);
    }

    #endif


    pMyObject->bActive = TRUE;

    return  ANSC_STATUS_SUCCESS;
}
ANSC_STATUS
AnscLpccoGetPartyArray
    (
        ANSC_HANDLE                 hThisObject,
        ANSC_HANDLE*                pPartyArray,
        PULONG                      pulCount
    )
{
    ANSC_STATUS                     returnStatus    = ANSC_STATUS_SUCCESS;
    PANSC_LPC_CONNECTOR_OBJECT      pMyObject       = (PANSC_LPC_CONNECTOR_OBJECT)hThisObject;
    PANSC_LPC_PARTY_ADDR            pPartyAddrArray = (PANSC_LPC_PARTY_ADDR      )NULL;
    PANSC_LPC_PARTY_ADDR            pPartyAddr      = (PANSC_LPC_PARTY_ADDR      )NULL;
    PSINGLE_LINK_ENTRY              pSLinkEntry     = (PSINGLE_LINK_ENTRY        )NULL;
    ULONG                           ulPartyMaxCount = (ULONG                     )pMyObject->GetPartyCount   ((ANSC_HANDLE)pMyObject);
    ULONG                           ulPartyAddrSize = (ULONG                     )pMyObject->GetPartyAddrSize((ANSC_HANDLE)pMyObject);
    ULONG                           ulPartyCount    = 0;
    ULONG                           i               = 0;

    if ( ulPartyMaxCount == 0 )
    {
        *pPartyArray = (ANSC_HANDLE)NULL;
        *pulCount    = 0;

        return  ANSC_STATUS_SUCCESS;
    }
    else
    {
        pPartyAddrArray = (PANSC_LPC_PARTY_ADDR)AnscAllocateMemory(ulPartyAddrSize * ulPartyMaxCount);

        if ( !pPartyAddrArray )
        {
            return  ANSC_STATUS_RESOURCES;
        }
    }

    AnscAcquireLock(&pMyObject->PartyTableLock);

    for ( i = 0; i < ANSC_LPCCO_PARTY_TABLE_SIZE; i++ )
    {
        pSLinkEntry = AnscQueueGetFirstEntry(&pMyObject->PartyTable[i]);

        while ( pSLinkEntry )
        {
            pPartyAddr  = ACCESS_ANSC_LPC_PARTY_ADDR(pSLinkEntry);
            pSLinkEntry = AnscQueueGetNextEntry(pSLinkEntry);

            AnscCopyMemory
                (
                    (void*)((ULONG)pPartyAddrArray + ulPartyCount * ulPartyAddrSize),
                    pPartyAddr,
                    pPartyAddr->StructSize
                );

            ulPartyCount++;

            if ( ulPartyCount >= ulPartyMaxCount )
            {
                break;
            }
        }

        if ( ulPartyCount >= ulPartyMaxCount )
        {
            break;
        }
    }

    AnscReleaseLock(&pMyObject->PartyTableLock);

    *pPartyArray = (ANSC_HANDLE)pPartyAddrArray;
    *pulCount    = ulPartyCount;

    return  ANSC_STATUS_SUCCESS;
}